```
function el(elementName, { cls, css, ev, html, text, ...props }, children) {
  // Create the element
  const elem = document.createElement(elementName);
  if (cls) {
    elem.className = cls;
  }

  if (html) {
    elem.innerHTML = html;
  }

  if (text) {
    elem.textContent = text;
  }

  if (css) {
    Object.assign(elem.style, css);
  }

  Object.assign(elem, props);

  if (ev) {
    for (const eventName in ev) {
      elem.addEventListener(eventName, ev[eventName].bind(elem));
    }
  }

  if (children) {
    for (const child of children) {
      if (typeof child === "string") {
        elem.appendChild(document.createTextNode(child));
      } else if (child instanceof Node) {
        elem.appendChild(child);
      }
    }
  }
  return elem;
}

/**
 * Toolbar Class
 *
 * A customizable toolbar that can be positioned on the screen with predefined or custom positions.
 * It supports adding regular and toggle buttons, both before and after initialization.
 */
export default class Toolbar {
  /**
   * Predefined CSS styles for the toolbar and its buttons.
   *
   * @private
   * @type {string}
   */
  predefinedCSS = `
    /* Toolbar Styles */
    .custom-toolbar {
      position: fixed;
      background-color: #ffffff;
      border: 1px solid #e0e0e0;
      border-radius: 8px;
      box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
      padding: 10px;
      display: flex;
      gap: 10px;
      z-index: 1000;
      transition: opacity 0.3s ease, visibility 0.3s ease;
      opacity: 0;
      visibility: hidden;
    }

    .custom-toolbar.show {
      opacity: 1;
      visibility: visible;
    }

    .custom-toolbar .hidden{
      display: none;
    }

    .custom-toolbar .toolbar-button {
      display: flex;
      align-items: center;
      gap: 5px;
      padding: 8px 12px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 14px;
      transition: background-color 0.2s ease;
      background-color: transparent;
    }

    .custom-toolbar .toolbar-button:hover {
      background-color: rgba(0,0,0, 0.05);
    }
    
    .custom-toolbar .toolbar-button:active {
      background-color: rgba(0,0,0, 0.1);
    }

    .custom-toolbar img,
    .custom-toolbar .toolbar-icon-svg {
      width: 20px;
      height: 20px;
    }

    .custom-toolbar .toolbar-label-container {
      display: inline-block;
    }

    /* Hide icon container if empty to prevent occupying space */
    .custom-toolbar .toolbar-icon-container:empty {
      display: none;
    }
  `;

  /**
   * Predefined positions with default offsets.
   * These configurations can be used by any instance of the Toolbar class.
   *
   * @private
   * @static
   * @type {Object}
   */
  static predefinedPositions = {
    "top-left": { top: "20px", left: "20px" },
    "top-right": { top: "20px", right: "20px" },
    "top-center": { top: "20px", left: "50%", transform: "translateX(-50%)" },
    "bottom-left": { bottom: "20px", left: "20px" },
    "bottom-right": { bottom: "20px", right: "20px" },
    "bottom-center": {
      bottom: "20px",
      left: "50%",
      transform: "translateX(-50%)",
    },
  };

  /**
   * Creates an instance of Toolbar.
   *
   * @param {Object} [options={}] - Configuration options for the toolbar.
   * @param {string|Object} [options.position='top-right'] -
   *   - If a string, it should be one of the predefined positions:
   *     - "top-left"
   *     - "top-right"
   *     - "top-center"
   *     - "bottom-left"
   *     - "bottom-right"
   *     - "bottom-center"
   *   - If an object, it can specify a preset with optional custom offsets or entirely custom CSS positioning.
   *     - `{ preset: 'top-left', offsets: { top: '30px', left: '25px' } }`
   *     - `{ top: '50px', right: '100px' }` (completely custom)
   * @param {Object} [options.style] - Additional CSS styles to apply to the toolbar container.
   */
  constructor(options = {}) {
    this.toolbar = null;
    this.isInitialized = false;
    this.isVisible = false;
    this.buttonDataList = [];
    this.options = options;
    this.styleElement = null; // To keep track of injected CSS
    this._objectUrls = []; // To keep track of Object URLs from Blob icons
  }

  /**
   * Initializes the toolbar by creating the container, injecting CSS, applying positioning,
   * adding any pre-initialized buttons, and appending it to the document body.
   *
   * @returns {void}
   */
  init() {
    if (this.isInitialized) return;

    // Inject CSS specific to this instance

    this.styleElement = el("style", { type: "text/css" });
    this.styleElement.appendChild(document.createTextNode(this.predefinedCSS));
    document.head.appendChild(this.styleElement);

    // Create toolbar container
    this.toolbar = el("div", { cls: "custom-toolbar" });

    // Apply positioning based on options
    this.applyPosition();

    // Apply additional styling if provided
    if (this.options.style) {
      Object.assign(this.toolbar.style, this.options.style);
    }

    // Append to body
    document.body.appendChild(this.toolbar);
    this.isInitialized = true;

    // Append buttons
    for (const buttonData of this.buttonDataList) {
      this.#renderButton(buttonData);
      this.toolbar.appendChild(buttonData.button);
    }
  }

  /**
   * Applies positioning to the toolbar based on the provided options.
   * Supports predefined positions with optional custom offsets and completely custom positioning.
   *
   * @private
   * @returns {void}
   */
  applyPosition() {
    const { position } = this.options;
    const { predefinedPositions } = Toolbar;

    let styles = predefinedPositions["top-right"];

    if (typeof position === "string") {
      // Use predefined position
      if (position in predefinedPositions) {
        styles = predefinedPositions[position];
      } else {
        console.warn(
          `Toolbar: Unknown predefined position "${position}". Falling back to "top-right".`
        );
      }
    } else if (typeof position === "object") {
      if (predefinedPositions[position.preset]) {
        styles = {
          ...predefinedPositions[position.preset],
          ...position.offsets,
        };
      } else {
        styles = position;
      }
    }

    Object.assign(this.toolbar.style, styles);
  }

  /**
   * Displays the toolbar on the screen. Initializes it if not already initialized.
   *
   * @returns {void}
   */
  start() {
    if (!this.isInitialized) {
      this.init();
    }

    this.toolbar.classList.add("show");
    this.isVisible = true;
  }

  /**
   * Hides the toolbar from the screen without destroying it.
   *
   * @returns {void}
   */
  stop() {
    if (this.toolbar) {
      this.toolbar.classList.remove("show");
      this.isVisible = false;
    }
  }

  /**
   * Destroys the toolbar by removing it and its injected CSS from the DOM,
   * revoking any Object URLs created from Blob icons, and clearing all buttons and event listeners.
   *
   * @returns {void}
   */
  destroy() {
    if (!this.isInitialized) return;

    // Remove all event listeners from buttons
    for (const { button, clickHandler } of this.buttonDataList) {
      button.removeEventListener("click", clickHandler);
      button.remove();
    }
    this.buttonDataList.length = 0;

    // Remove toolbar from DOM
    this.toolbar?.parentNode?.removeChild(this.toolbar);
    this.toolbar = null;

    // Remove injected CSS
    this.styleElement?.parentNode?.removeChild(this.styleElement);
    this.styleElement = null;

    // Revoke all Object URLs created from Blob icons
    this._objectUrls.forEach((url) => {
      URL.revokeObjectURL(url);
    });
    this._objectUrls.length = 0;

    // Reset state
    this.isInitialized = false;
    this.isVisible = false;
  }

  /**
   * Adds a button to the toolbar.
   *
   * @param {Object} config - Configuration for the toggle button.
   * @param {string} [config.label] - The common text label of the toggle button.
   * @param {string|HTMLElement|Blob} [config.icon] - The common icon of the toggle button.
   * @param {Object} [config.css] - Common CSS styles to apply to the toggle button.
   * @param {Object} [config.attributes] - Common HTML attributes to set on the toggle button element.
   * @param {boolean|Function} [config.initialState] - True for active, false for inactive
   * @param {Object} [config.active] - Overrides for the active state.
   * @param {string} [config.active.label] - Override label when active.
   * @param {string|HTMLElement|Blob} [config.active.icon] - Override icon when active.
   * @param {Object} [config.active.css] - Override CSS styles when active.
   * @param {Object} [config.active.attributes] - Override HTML attributes when active.
   * @param {Object} [config.inactive] - Overrides for the inactive state.
   * @param {string} [config.inactive.label] - Override label when inactive.
   * @param {string|HTMLElement|Blob} [config.inactive.icon] - Override icon when inactive.
   * @param {Object} [config.inactive.css] - Override CSS styles when inactive.
   * @param {Object} [config.inactive.attributes] - Override HTML attributes when inactive.
   * @param {Function} [config.onClick] - Callback function when button is clicked. Receives the new state as a parameter.
   *
   * @returns {void}
   *
   * @example
   * // Using a Base64 string (without Data URL prefix)
   * const base64Image = 'iVBORw0KGgoAAAANSUhEUgAAAAUA...'; // Truncated for brevity
   * toolbar.addButton({
   *   label: 'Base64 Icon',
   *   icon: base64Image,
   *   css: {
   *     backgroundColor: 'rgba(255, 0, 0, 0.5)', // Semi-transparent red
   *     color: '#ffffff', // White text
   *   },
   *   attributes: { 'data-action': 'alert' },
   * }, () => {
   *   console.log('Base64 Icon button clicked!');
   * });
   *
   * @example
   * // Using a Blob object
   * const imageBlob = new Blob([/* binary data * /], { type: 'image/png' });
   * toolbar.addButton({
   *   label: 'Blob Icon',
   *   icon: imageBlob,
   *   active: {
   *     label: 'Active State',
   *     icon: 'https://example.com/active-icon.png',
   *     css: {
   *       backgroundColor: '#4caf50', // Green when active
   *       color: '#ffffff', // White text when active
   *     },
   *     attributes: { 'aria-pressed': 'true' },
   *   },
   *   inactive: {
   *     label: 'Inactive State',
   *     icon: 'https://example.com/inactive-icon.png',
   *     css: {
   *       backgroundColor: '#f44336', // Red when inactive
   *       color: '#ffffff', // White text when inactive
   *     },
   *     attributes: { 'aria-pressed': 'false' },
   *   },
   *   css: {
   *     backgroundColor: '#ffeb3b', // Default Yellow background
   *     color: '#000000', // Default Black text
   *   },
   *   attributes: { 'data-toggle': 'feature' },
   * }, (isActive) => {
   *   console.log(`Blob Icon Toggle is now ${isActive ? 'ON' : 'OFF'}`);
   * });
   */
  addButton(config) {
    const buttonData = this.#createButton(config);

    if (this.isInitialized) {
      this.#renderButton(buttonData);
      this.toolbar.appendChild(button);
    }
  }

  #renderButton(buttonData, prevState = null) {
    const { button, currentState, buttonStates } = buttonData;
    const newState = buttonStates[currentState ? 1 : 0] ?? {};
    const prevButtonState = buttonStates[prevState ? 1 : 0] ?? {};

    const { label, icon, css = {}, attr = {} } = newState;
    const { css: prevCss = {}, attr: prevAttr = {} } = prevButtonState;

    // Update button children only if the label or icon changed
    const children = [];
    if (icon) children.push(icon);
    if (label) children.push(label);

    if (children.length > 0) {
      button.replaceChildren(...children);
    }

    // Update button styles
    for (const property in prevCss) {
      if (!(property in css)) {
        button.style[property] = ""; // Remove previous styles that are no longer present
      }
    }
    Object.assign(button.style, css); // Apply new styles

    // Update button attributes
    for (const property in prevAttr) {
      if (!(property in attr)) {
        button.removeAttribute(property); // Remove previous attributes that are no longer present
      }
    }
    for (const property in attr) {
      button.setAttribute(property, attr[property]); // Set new or updated attributes
    }
  }

  #createButton(buttonConfig) {
    const { active, inactive, initialState } = buttonConfig;
    const isToggleButton = !!active;
    const buttonStates = [this.#parseButtonConfig(buttonConfig, inactive)];
    if (isToggleButton) {
      buttonStates.push(this.#parseButtonConfig(buttonConfig, active));
    }

    const buttonData = { currentState: !!initialState, buttonStates };

    const clickHandler = this.#createClickHandler(
      buttonData,
      buttonConfig,
      isToggleButton
    );
    const button = el("button", {
      cls: "toolbar-button",
      ...(clickHandler ? { ev: { click: clickHandler } } : null),
    });

    Object.assign(buttonData, { button, clickHandler });
    this.buttonDataList.push(buttonData);
    return buttonData;
  }

  #createClickHandler(buttonData, { onClick }, isToggleButton) {
    if (typeof onClick !== "function") {
      return null;
    }
    const $this = this;

    return isToggleButton
      ? function (ev) {
          const button = this;
          const prevState = buttonData.currentState;
          const currentState = (buttonData.currentState =
            !buttonData.currentState);
          $this.#renderButton(buttonData, prevState);
          return onClick.call(button, ev, currentState);
        }
      : onClick;
  }

  #parseButtonConfig(commonConfig, stateSpecificConfig) {
    const {
      label: commonLabel,
      icon: commonIcon,
      css: commonCss,
      attr: commonAttr,
    } = commonConfig;
    const {
      label = commonLabel,
      icon = commonIcon,
      css,
      attr,
    } = stateSpecificConfig || {};
    return {
      label:
        typeof label === "string"
          ? el("span", { cls: "toolbar-label-container", text: label })
          : null,
      icon: this.#createIconElement(icon),
      css: { ...commonCss, ...css },
      attr: { ...commonAttr, ...attr },
    };
  }

  /**
   * Creates an icon element based on the provided icon data.
   * Supports URLs, Data URLs, Base64 strings, Blob objects, SVG strings, emojis, and HTMLElements.
   *
   * @private
   * @param {string|HTMLElement|Blob} stateIcon - The icon data for the current state.
   * @param {string|HTMLElement|Blob} [commonIcon] - The common icon data (fallback).
   * @returns {HTMLElement|null} - The created icon element or null if no icon is provided.
   */
  #createIconElement(iconData) {
    if (!iconData) {
      return null; // Return null if no icon is provided
    }

    let iconElement;

    if (typeof iconData === "string") {
      // Check if it's a valid URL (including data URLs)
      if (this.#isUrl(iconData)) {
        iconElement = el("img", {
          src: iconData,
          alt: "",
        });
      } else if (/^\s*<svg/.test(iconData)) {
        iconElement = el("span", {
          html: iconData,
          cls: "toolbar-icon-svg",
        });
      } else {
        iconElement = el("span", {
          text: iconData,
          cls: "toolbar-icon-text",
        });
      }
    } else if (iconData instanceof Blob) {
      const objectUrl = URL.createObjectURL(iconData);
      this._objectUrls.push(objectUrl); // Track the Object URL for later revocation
      iconElement = el("img", {
        src: objectUrl,
        alt: "",
      });
    } else if (iconData instanceof HTMLElement) {
      iconElement = iconData.cloneNode(true);
    } else {
      iconElement = null;
    }

    return iconElement;
  }

  /**
   * Checks if a given string is a valid URL (including Data URLs).
   *
   * @private
   * @param {string} string - The string to validate.
   * @returns {boolean} - True if the string is a valid URL, false otherwise.
   */
  #isUrl(string) {
    try {
      new URL(string);
      return true;
    } catch (_) {
      return false;
    }
  }
}

```
turn toolbar into shadow dom with in-shadow stylesheet