```
/**
 * 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;
    }

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

    .toolbar-button:hover,
    .toolbar-toggle-button:hover {
      background-color: #1565c0;
    }

    .toolbar-toggle-button.active {
      background-color: #388e3c;
    }

    .toolbar-button img,
    .toolbar-toggle-button img,
    .toolbar-icon-svg {
      max-width: 20px;
      max-height: 20px;
    }

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

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

    /* Optional: SVG Icon Styling */
    .toolbar-icon-svg {
      width: 20px;
      height: 20px;
    }
  `;

  /**
   * 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", right: "auto", bottom: "auto" },
    "top-right": { top: "20px", right: "20px", left: "auto", bottom: "auto" },
    "top-center": {
      top: "20px",
      left: "50%",
      right: "auto",
      bottom: "auto",
      transform: "translateX(-50%)",
    },
    "bottom-left": {
      bottom: "20px",
      left: "20px",
      top: "auto",
      right: "auto",
    },
    "bottom-right": {
      bottom: "20px",
      right: "20px",
      top: "auto",
      left: "auto",
    },
    "bottom-center": {
      bottom: "20px",
      left: "50%",
      right: "auto",
      top: "auto",
      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.buttons = [];
    this.toggleButtons = [];
    this.options = options;
    this.styleElement = null; // To keep track of injected CSS
    this._objectUrls = []; // To keep track of Object URLs from Blob icons

    // Store buttons added before initialization
    this._preInitButtons = [];
    this._preInitToggleButtons = [];
  }

  /**
   * 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 = document.createElement("style");
    this.styleElement.type = "text/css";
    this.styleElement.appendChild(document.createTextNode(this.predefinedCSS));
    document.head.appendChild(this.styleElement);

    // Create toolbar container
    this.toolbar = document.createElement("div");
    this.toolbar.className = "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 pre-initialized buttons
    this._preInitButtons.forEach(({ options, onClick }) => {
      this._createButton(false, options, onClick);
    });
    this._preInitToggleButtons.forEach(({ options, onToggle }) => {
      this._createButton(true, options, onToggle);
    });

    // Clear pre-init arrays
    this._preInitButtons = [];
    this._preInitToggleButtons = [];
  }

  /**
   * 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 styles = {};

    if (typeof position === "string") {
      // Use predefined position
      if (Toolbar.predefinedPositions[position]) {
        Object.assign(styles, Toolbar.predefinedPositions[position]);
        // Retain transform if present (e.g., top-center)
      } else {
        console.warn(
          `Toolbar: Unknown predefined position "${position}". Falling back to "top-right".`
        );
        Object.assign(styles, Toolbar.predefinedPositions["top-right"]);
      }
    } else if (typeof position === "object") {
      if (position.preset && Toolbar.predefinedPositions[position.preset]) {
        Object.assign(styles, Toolbar.predefinedPositions[position.preset]);
        // Apply custom offsets if provided
        if (position.offsets && typeof position.offsets === "object") {
          Object.assign(styles, position.offsets);
        }
        // If transform is provided in offsets, apply it
        if (position.offsets && position.offsets.transform) {
          styles.transform = position.offsets.transform;
        }
      } else {
        // Assume custom positioning
        Object.assign(styles, position);
      }
    } else {
      // Default to top-right if position is not specified correctly
      Object.assign(styles, Toolbar.predefinedPositions["top-right"]);
    }

    // Apply styles to the toolbar
    for (const [prop, value] of Object.entries(styles)) {
      this.toolbar.style[prop] = value;
    }
  }

  /**
   * 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
    this.buttons.forEach((button) => {
      if (button._handleClick) {
        button.removeEventListener("click", button._handleClick);
      }
    });

    this.toggleButtons.forEach((button) => {
      if (button._handleClick) {
        button.removeEventListener("click", button._handleClick);
      }
    });

    // 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 = [];

    // Reset state
    this.isInitialized = false;
    this.isVisible = false;
    this.buttons = [];
    this.toggleButtons = [];
    this._preInitButtons = [];
    this._preInitToggleButtons = [];
  }

  /**
   * Adds a regular button to the toolbar.
   *
   * @param {Object} options - Configuration for the button.
   * @param {string} [options.label] - The text label of the button.
   * @param {string|HTMLElement|Blob} [options.icon] - The icon for the button (URL, Data URL, Blob, SVG string, emoji, or HTMLElement).
   * @param {Object} [options.attributes] - Additional HTML attributes to set on the button element.
   * @param {Function} onClick - Callback function when the button is clicked.
   *
   * @returns {void}
   *
   * @example
   * // Using a Base64 string (without Data URL prefix)
   * const base64Image = 'iVBORw0KGgoAAAANSUhEUgAAAAUA...'; // Truncated for brevity
   * toolbar.addButton({
   *   label: 'Base64 Icon',
   *   icon: base64Image,
   * }, () => {
   *   console.log('Base64 Icon button clicked!');
   * });
   */
  addButton(options, onClick) {
    if (this.isInitialized) {
      this._createButton(false, options, onClick);
    } else {
      this._preInitButtons.push({ options, onClick });
    }
  }

  /**
   * Adds a toggle button to the toolbar.
   *
   * @param {Object} options - Configuration for the toggle button.
   * @param {string} [options.label] - The default text label of the toggle button.
   * @param {string} [options.activeLabel] - The text label when the toggle button is active.
   * @param {string} [options.inactiveLabel] - The text label when the toggle button is inactive.
   * @param {string|HTMLElement|Blob} [options.icon] - The default icon of the toggle button.
   * @param {string|HTMLElement|Blob} [options.activeIcon] - The icon when the toggle button is active.
   * @param {string|HTMLElement|Blob} [options.inactiveIcon] - The icon when the toggle button is inactive.
   * @param {boolean} [options.initialState=false] - The initial toggled state of the button.
   * @param {Object} [options.attributes] - Common HTML attributes to set on the toggle button element.
   * @param {Object} [options.activeAttributes] - HTML attributes when the toggle button is active.
   * @param {Object} [options.inactiveAttributes] - HTML attributes when the toggle button is inactive.
   * @param {Function} onToggle - Callback function when the toggle state changes. Receives the new state as a parameter.
   *
   * @returns {void}
   *
   * @example
   * // Using a Blob object
   * const imageBlob = new Blob([/* binary data * /], { type: 'image/png' });
   * toolbar.addToggleButton({
   *   label: 'Blob Icon',
   *   icon: imageBlob,
   *   activeLabel: 'Active State',
   *   inactiveLabel: 'Inactive State',
   *   activeIcon: 'https://example.com/active-icon.png',
   *   inactiveIcon: 'https://example.com/inactive-icon.png',
   *   initialState: true,
   *   attributes: { 'data-toggle': 'feature' },
   *   activeAttributes: { 'aria-pressed': 'true' },
   *   inactiveAttributes: { 'aria-pressed': 'false' },
   * }, (isActive) => {
   *   console.log(`Blob Icon Toggle is now ${isActive ? 'ON' : 'OFF'}`);
   * });
   */
  addToggleButton(options, onToggle) {
    if (this.isInitialized) {
      this._createButton(true, options, onToggle);
    } else {
      this._preInitToggleButtons.push({ options, onToggle });
    }
  }

  /**
   * Creates a button or toggle button and appends it to the toolbar.
   *
   * @private
   * @param {boolean} isToggle - Determines if the button is a toggle button.
   * @param {Object} options - Button configuration options.
   * @param {Function} callback - Callback function for click or toggle events.
   *
   * @returns {void}
   */
  _createButton(isToggle, options, callback) {
    const button = this._createButtonElement(isToggle);
    this._applyAttributes(button, options.attributes);

    if (isToggle) {
      this._setupToggleButton(button, options, callback);
    } else {
      this._setupRegularButton(button, options, callback);
    }

    this._appendButtonToToolbar(button, isToggle);
  }

  _createButtonElement(isToggle) {
    const button = document.createElement("button");
    button.className = isToggle ? "toolbar-toggle-button" : "toolbar-button";
    return button;
  }

  _setupToggleButton(button, options, callback) {
    const initialState = !!options.initialState;
    this._setInitialToggleState(button, initialState, options);

    const iconElement = this._createIconElement(
      initialState ? options.activeIcon : options.inactiveIcon,
      options.icon
    );
    const labelElement = this._createLabelElement(initialState, options);

    this._appendIconAndLabel(button, iconElement, labelElement);

    const handleToggle = () => {
      const newState = !button.classList.contains("active");
      this._toggleButtonState(
        button,
        newState,
        options,
        iconElement,
        labelElement
      );
      callback(newState);
    };
    this._addClickEventListener(button, handleToggle);
  }

  _setInitialToggleState(button, initialState, options) {
    button.classList.toggle("active", initialState);
    this._applyAttributes(
      button,
      initialState ? options.activeAttributes : options.inactiveAttributes
    );
  }

  _setupRegularButton(button, options, callback) {
    const iconElement = this._createIconElement(options.icon);
    const labelElement = this._createLabelElement(false, options);

    this._appendIconAndLabel(button, iconElement, labelElement);

    const handleClick = (event) => callback(event);
    this._addClickEventListener(button, handleClick);
  }

  _appendIconAndLabel(button, iconElement, labelElement) {
    if (iconElement) {
      const iconContainer = document.createElement("span");
      iconContainer.className = "toolbar-icon-container";
      iconContainer.appendChild(iconElement);
      button.appendChild(iconContainer);
    }
    button.appendChild(labelElement);
  }

  _addClickEventListener(button, handler) {
    button.addEventListener("click", handler);
    button._handleClick = handler; // Reference for later removal
  }

  _appendButtonToToolbar(button, isToggle) {
    this.toolbar.appendChild(button);
    if (isToggle) {
      this.toggleButtons.push(button);
    } else {
      this.buttons.push(button);
    }
  }

  /**
   * Applies a set of attributes to a DOM element.
   *
   * @private
   * @param {HTMLElement} element - The element to which attributes will be applied.
   * @param {Object} [attributes={}] - The attributes to apply.
   */
  _applyAttributes(element, attributes = {}) {
    if (attributes && typeof attributes === "object") {
      for (const [attr, value] of Object.entries(attributes)) {
        element.setAttribute(attr, value);
      }
    }
  }

  /**
   * Removes a set of attributes from a DOM element.
   *
   * @private
   * @param {HTMLElement} element - The element from which attributes will be removed.
   * @param {Object} [attributes={}] - The attributes to remove.
   */
  _removeAttributes(element, attributes = {}) {
    if (attributes && typeof attributes === "object") {
      for (const attr of Object.keys(attributes)) {
        element.removeAttribute(attr);
      }
    }
  }

  /**
   * Creates a label element based on the toggle state and provided options.
   *
   * @private
   * @param {boolean} isActive - The current state of the toggle button.
   * @param {Object} options - Button configuration options.
   * @returns {HTMLElement} - The created label element.
   */
  _createLabelElement(isActive, options) {
    const labelElement = document.createElement("span");
    labelElement.className = "toolbar-label-container";

    if (isActive) {
      labelElement.textContent = options.activeLabel || options.label || "";
    } else {
      labelElement.textContent = options.inactiveLabel || options.label || "";
    }

    return labelElement;
  }

  /**
   * Toggles the state of a toggle button, updating its icon, label, and attributes accordingly.
   *
   * @private
   * @param {HTMLElement} button - The toggle button element.
   * @param {boolean} newState - The new state to set.
   * @param {Object} options - Button configuration options.
   * @param {HTMLElement} iconElement - The icon element inside the button.
   * @param {HTMLElement} labelElement - The label element inside the button.
   */
  _toggleButtonState(button, newState, options, iconElement, labelElement) {
    button.classList.toggle("active", newState);

    // Update icon if applicable
    if (options.activeIcon || options.inactiveIcon || options.icon) {
      const newIcon = newState ? options.activeIcon : options.inactiveIcon;
      const updatedIconElement = this._createIconElement(newIcon, options.icon);

      if (updatedIconElement) {
        // Clear existing icon container
        const iconContainer = button.querySelector(".toolbar-icon-container");
        if (iconContainer) {
          iconContainer.innerHTML = "";
          iconContainer.appendChild(updatedIconElement);
        } else {
          // If icon container doesn't exist, create and append it
          const newIconContainer = document.createElement("span");
          newIconContainer.className = "toolbar-icon-container";
          newIconContainer.appendChild(updatedIconElement);
          // Insert at the beginning to maintain order
          button.insertBefore(newIconContainer, labelElement);
        }
      }
    }

    // Update label
    if (options.activeLabel || options.inactiveLabel || options.label) {
      labelElement.textContent = newState
        ? options.activeLabel || options.label || ""
        : options.inactiveLabel || options.label || "";
    }

    // Update attributes
    if (newState) {
      // Apply active attributes
      this._applyAttributes(button, options.activeAttributes);
      // Remove inactive attributes
      this._removeAttributes(button, options.inactiveAttributes);
    } else {
      // Apply inactive attributes
      this._applyAttributes(button, options.inactiveAttributes);
      // Remove active attributes
      this._removeAttributes(button, options.activeAttributes);
    }
  }

  /**
   * 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(stateIcon, commonIcon) {
    const iconData = stateIcon || commonIcon;
    if (!iconData) {
      return null; // Return null if no icon is provided
    }

    let iconElement;

    if (typeof iconData === "string") {
      // data url included
      if (this._isValidUrl(iconData)) {
        const img = (iconElement = document.createElement("img"));
        img.src = iconData;
        img.alt = "";
      } else if (this._isSVG(iconData)) {
        const span = (iconElement = document.createElement("span"));
        span.innerHTML = iconData;
        span.className = "toolbar-icon-svg";
      } else {
        const span = (iconElement = document.createElement("span"));
        span.textContent = iconData;
        span.className = "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 = this._createImgElement(objectUrl);
    } else if (iconData instanceof HTMLElement) {
      iconElement = iconData.cloneNode(true);
    } else {
      iconElement = document.createElement("span"); // Fallback: empty span
    }

    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.
   */
  _isValidUrl(string) {
    try {
      new URL(string);
      return true;
    } catch (_) {
      return false;
    }
  }

  /**
   * Checks if a given string is an SVG.
   *
   * @private
   * @param {string} string - The string to check.
   * @returns {boolean} - True if the string starts with '<svg', false otherwise.
   */
  _isSVG(string) {
    return string.trim().startsWith("<svg");
  }
}

```
1. amend the class to allow each button to have custom background color(even transparent)
2. for each toggle state, if label/icon is empty/doesnt exist, hide it, otherwise, change the content. instead of removing/regenerating label/icon element. reason for hiding is due to flex gap would be rendered if not hidden for empty icon/label.