Skip to content

UI Components

The @likhaeditor/ui package provides reusable UI components for building editor toolbars and menus.

Toolbar

Create customizable toolbars with buttons, dropdowns, and separators.

typescript
import { Toolbar } from '@likhaeditor/ui';

const toolbar = new Toolbar({
  container: HTMLElement,
  buttons: ButtonConfig[],
  theme?: 'light' | 'dark'
});

Button Config

typescript
interface ButtonConfig {
  /** Button ID */
  id: string;
  
  /** Button label/icon */
  label: string;
  
  /** Button type */
  type: 'button' | 'dropdown' | 'separator' | 'color-picker';
  
  /** Tooltip text */
  title?: string;
  
  /** Click handler */
  onClick?: () => void;
  
  /** Check if button is active */
  isActive?: () => boolean;
  
  /** Check if button is disabled */
  isDisabled?: () => boolean;
  
  /** Dropdown options (for type: 'dropdown') */
  options?: DropdownOption[];
  
  /** Icon SVG */
  icon?: string;
}

Example

typescript
import { Toolbar } from '@likhaeditor/ui';
import { Editor } from '@likhaeditor/core';

const editor = new Editor({ element: document.getElementById('editor') });

const toolbar = new Toolbar({
  container: document.getElementById('toolbar'),
  buttons: [
    {
      id: 'bold',
      label: 'Bold',
      type: 'button',
      title: 'Bold (Ctrl+B)',
      icon: '<svg>...</svg>',
      onClick: () => editor.executeCommand('bold'),
      isActive: () => editor.isActive('strong')
    },
    {
      id: 'heading',
      label: 'Heading',
      type: 'dropdown',
      title: 'Heading',
      options: [
        { value: '0', label: 'Paragraph' },
        { value: '1', label: 'Heading 1' },
        { value: '2', label: 'Heading 2' }
      ],
      onClick: (value) => {
        if (value === '0') editor.executeCommand('setParagraph');
        else editor.executeCommand('toggleHeading', parseInt(value));
      }
    }
  ]
});

Create menu bars with dropdown menus.

typescript
import { MenuBar } from '@likhaeditor/ui';

const menuBar = new MenuBar({
  container: HTMLElement,
  menus: MenuConfig[]
});
typescript
interface MenuConfig {
  label: string;
  items: MenuItem[];
}

interface MenuItem {
  label: string;
  shortcut?: string;
  onClick: () => void;
  isActive?: () => boolean;
  isDisabled?: () => boolean;
  separator?: boolean;
}

Example

typescript
const menuBar = new MenuBar({
  container: document.getElementById('menubar'),
  menus: [
    {
      label: 'Edit',
      items: [
        {
          label: 'Undo',
          shortcut: 'Ctrl+Z',
          onClick: () => editor.executeCommand('undo')
        },
        {
          label: 'Redo',
          shortcut: 'Ctrl+Y',
          onClick: () => editor.executeCommand('redo')
        },
        { separator: true },
        {
          label: 'Cut',
          shortcut: 'Ctrl+X',
          onClick: () => document.execCommand('cut')
        }
      ]
    },
    {
      label: 'Format',
      items: [
        {
          label: 'Bold',
          shortcut: 'Ctrl+B',
          onClick: () => editor.executeCommand('bold'),
          isActive: () => editor.isActive('strong')
        }
      ]
    }
  ]
});

ColorPicker

Pick colors for text and highlights.

typescript
import { ColorPicker } from '@likhaeditor/ui';

const picker = new ColorPicker({
  container: HTMLElement,
  colors: string[],
  onSelect: (color: string) => void,
  defaultColor?: string
});

Example

typescript
const colorPicker = new ColorPicker({
  container: document.getElementById('color-picker'),
  colors: [
    '#000000', '#FF0000', '#00FF00', '#0000FF',
    '#FFFF00', '#FF00FF', '#00FFFF', '#FFFFFF'
  ],
  onSelect: (color) => {
    editor.executeCommand('setTextColor', color);
  },
  defaultColor: '#000000'
});

Button

Individual button component.

typescript
import { Button } from '@likhaeditor/ui';

const button = new Button({
  label: string,
  icon?: string,
  title?: string,
  onClick: () => void,
  isActive?: () => boolean,
  isDisabled?: () => boolean
});

Example

typescript
const boldButton = new Button({
  label: 'Bold',
  icon: '<svg>...</svg>',
  title: 'Bold (Ctrl+B)',
  onClick: () => editor.executeCommand('bold'),
  isActive: () => editor.isActive('strong'),
  isDisabled: () => false
});

document.getElementById('toolbar').appendChild(boldButton.element);

Dropdown select component.

typescript
import { Dropdown } from '@likhaeditor/ui';

const dropdown = new Dropdown({
  options: DropdownOption[],
  onSelect: (value: string) => void,
  defaultValue?: string,
  placeholder?: string
});

Example

typescript
const headingDropdown = new Dropdown({
  options: [
    { value: '0', label: 'Paragraph' },
    { value: '1', label: 'Heading 1' },
    { value: '2', label: 'Heading 2' },
    { value: '3', label: 'Heading 3' }
  ],
  onSelect: (value) => {
    if (value === '0') {
      editor.executeCommand('setParagraph');
    } else {
      editor.executeCommand('toggleHeading', parseInt(value));
    }
  },
  defaultValue: '0',
  placeholder: 'Select heading...'
});

Theming

All UI components support theming:

typescript
import { setTheme } from '@likhaeditor/ui';

// Set global theme
setTheme('dark');

// Or per component
const toolbar = new Toolbar({
  container: element,
  buttons: [],
  theme: 'dark'
});

Custom Themes

typescript
import { registerTheme } from '@likhaeditor/ui';

registerTheme('custom', {
  background: '#1e1e1e',
  foreground: '#d4d4d4',
  border: '#3e3e3e',
  hover: '#2a2a2a',
  active: '#0e639c',
  disabled: '#6e6e6e'
});

setTheme('custom');

CSS Classes

All components use BEM naming:

css
/* Toolbar */
.likha-toolbar { }
.likha-toolbar__button { }
.likha-toolbar__button--active { }
.likha-toolbar__button--disabled { }
.likha-toolbar__separator { }

/* Dropdown */
.likha-dropdown { }
.likha-dropdown__toggle { }
.likha-dropdown__menu { }
.likha-dropdown__item { }
.likha-dropdown__item--active { }

/* ColorPicker */
.likha-colorpicker { }
.likha-colorpicker__swatch { }
.likha-colorpicker__swatch--selected { }

You can override these classes to customize appearance:

css
.likha-toolbar {
  background: #f0f0f0;
  padding: 12px;
  border-radius: 8px;
}

.likha-toolbar__button {
  border-radius: 4px;
  padding: 6px 10px;
}

.likha-toolbar__button--active {
  background: #0066cc;
  color: white;
}