stilo-editor 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -2
  3. package/dist/characters--8h5uTeF.js +854 -0
  4. package/dist/content.css +398 -0
  5. package/dist/core/drop.d.ts +6 -0
  6. package/dist/core/editor.d.ts +120 -0
  7. package/dist/core/errors.d.ts +6 -0
  8. package/dist/core/events.d.ts +19 -0
  9. package/dist/core/extension-manager.d.ts +57 -0
  10. package/dist/core/extension.d.ts +48 -0
  11. package/dist/core/helpers/active.d.ts +33 -0
  12. package/dist/core/helpers/block-style.d.ts +25 -0
  13. package/dist/core/helpers/input-rules.d.ts +28 -0
  14. package/dist/core/helpers/lists.d.ts +20 -0
  15. package/dist/core/helpers/marks.d.ts +52 -0
  16. package/dist/core/helpers/nodes.d.ts +26 -0
  17. package/dist/core/helpers/parse-rules.d.ts +8 -0
  18. package/dist/core/helpers/word-count.d.ts +14 -0
  19. package/dist/core/html/css.d.ts +106 -0
  20. package/dist/core/html/parse.d.ts +7 -0
  21. package/dist/core/html/paste/base-styles.d.ts +7 -0
  22. package/dist/core/html/paste/google-docs.d.ts +7 -0
  23. package/dist/core/html/paste/index.d.ts +9 -0
  24. package/dist/core/html/paste/table-widths.d.ts +7 -0
  25. package/dist/core/html/paste/word.d.ts +8 -0
  26. package/dist/core/html/sanitize.d.ts +49 -0
  27. package/dist/core/html/serialize.d.ts +31 -0
  28. package/dist/core/types.d.ts +107 -0
  29. package/dist/extensions/blockquote/index.d.ts +15 -0
  30. package/dist/extensions/bold/index.d.ts +17 -0
  31. package/dist/extensions/bullet-list/index.d.ts +9 -0
  32. package/dist/extensions/clear-formatting/index.d.ts +12 -0
  33. package/dist/extensions/code/index.d.ts +15 -0
  34. package/dist/extensions/code-block/index.d.ts +24 -0
  35. package/dist/extensions/default-extensions/index.d.ts +57 -0
  36. package/dist/extensions/document/index.d.ts +17 -0
  37. package/dist/extensions/drop-cursor/index.d.ts +15 -0
  38. package/dist/extensions/gap-cursor/index.d.ts +6 -0
  39. package/dist/extensions/hard-break/index.d.ts +11 -0
  40. package/dist/extensions/heading/index.d.ts +25 -0
  41. package/dist/extensions/highlight/index.d.ts +24 -0
  42. package/dist/extensions/history/index.d.ts +21 -0
  43. package/dist/extensions/horizontal-rule/index.d.ts +11 -0
  44. package/dist/extensions/image/image-view.d.ts +27 -0
  45. package/dist/extensions/image/index.d.ts +29 -0
  46. package/dist/extensions/index.d.ts +36 -0
  47. package/dist/extensions/italic/index.d.ts +16 -0
  48. package/dist/extensions/line-height/index.d.ts +18 -0
  49. package/dist/extensions/link/index.d.ts +23 -0
  50. package/dist/extensions/list-item/index.d.ts +16 -0
  51. package/dist/extensions/move-block/index.d.ts +17 -0
  52. package/dist/extensions/ordered-list/index.d.ts +12 -0
  53. package/dist/extensions/paragraph/index.d.ts +14 -0
  54. package/dist/extensions/placeholder/index.d.ts +13 -0
  55. package/dist/extensions/search/index.d.ts +55 -0
  56. package/dist/extensions/strike/index.d.ts +16 -0
  57. package/dist/extensions/subscript/index.d.ts +16 -0
  58. package/dist/extensions/superscript/index.d.ts +17 -0
  59. package/dist/extensions/table/index.d.ts +70 -0
  60. package/dist/extensions/task-item/index.d.ts +24 -0
  61. package/dist/extensions/task-item/task-item-view.d.ts +24 -0
  62. package/dist/extensions/task-list/index.d.ts +11 -0
  63. package/dist/extensions/text/index.d.ts +12 -0
  64. package/dist/extensions/text-align/index.d.ts +18 -0
  65. package/dist/extensions/text-case/index.d.ts +14 -0
  66. package/dist/extensions/text-style/font-size.d.ts +21 -0
  67. package/dist/extensions/text-style/index.d.ts +30 -0
  68. package/dist/extensions/underline/index.d.ts +15 -0
  69. package/dist/index.d.ts +14 -0
  70. package/dist/index.js +1 -0
  71. package/dist/src-CV6pgfTS.js +2662 -0
  72. package/dist/style.css +1395 -0
  73. package/dist/ui/components/character-picker.d.ts +22 -0
  74. package/dist/ui/components/characters.d.ts +10 -0
  75. package/dist/ui/components/color-button.d.ts +23 -0
  76. package/dist/ui/components/dropdown.d.ts +34 -0
  77. package/dist/ui/components/find-bar.d.ts +24 -0
  78. package/dist/ui/components/font-size-input.d.ts +21 -0
  79. package/dist/ui/components/icon-menu.d.ts +20 -0
  80. package/dist/ui/components/icon.d.ts +3 -0
  81. package/dist/ui/components/link-bubble.d.ts +19 -0
  82. package/dist/ui/components/link-popover.d.ts +20 -0
  83. package/dist/ui/components/popover.d.ts +27 -0
  84. package/dist/ui/components/shortcut.d.ts +11 -0
  85. package/dist/ui/components/status-bar.d.ts +19 -0
  86. package/dist/ui/components/table-actions.d.ts +25 -0
  87. package/dist/ui/components/table-handles.d.ts +16 -0
  88. package/dist/ui/components/table-menu.d.ts +21 -0
  89. package/dist/ui/i18n/en.d.ts +3 -0
  90. package/dist/ui/i18n/it.d.ts +3 -0
  91. package/dist/ui/i18n/types.d.ts +4 -0
  92. package/dist/ui/index.d.ts +23 -0
  93. package/dist/ui/toolbar/fonts.d.ts +8 -0
  94. package/dist/ui/toolbar/items.d.ts +33 -0
  95. package/dist/ui/toolbar/palette.d.ts +6 -0
  96. package/dist/ui/toolbar/toolbar.d.ts +28 -0
  97. package/dist/ui/toolbar/types.d.ts +150 -0
  98. package/dist/ui.css +996 -0
  99. package/dist/ui.js +2350 -0
  100. package/package.json +96 -4
@@ -0,0 +1,22 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createCharacterPicker}. */
4
+ export interface CharacterPickerOptions {
5
+ /** The toolbar button that opens the picker. */
6
+ anchor: HTMLElement;
7
+ /** The element the picker scrolls with: the toolbar. */
8
+ container: HTMLElement;
9
+ messages: Messages;
10
+ }
11
+ /** The special characters and emoji picker; it stays open after each insertion. */
12
+ export interface CharacterPicker {
13
+ readonly isOpen: boolean;
14
+ /** Opens the picker, loading its data the first time; the focus goes to the search field. */
15
+ open(): Promise<void>;
16
+ /** Closes the picker and gives the focus back to the editor. */
17
+ close(): void;
18
+ toggle(): void;
19
+ destroy(): void;
20
+ }
21
+ /** Creates the character picker (closed), anchored to the toolbar button. */
22
+ export declare function createCharacterPicker(editor: Editor, options: CharacterPickerOptions): CharacterPicker;
@@ -0,0 +1,10 @@
1
+ import type { MessageKey } from '../i18n/types';
2
+ /** A category of the character picker: its label and its characters with their names. */
3
+ export interface CharacterCategory {
4
+ labelKey: MessageKey;
5
+ characters: ReadonlyArray<readonly [character: string, name: string]>;
6
+ }
7
+ /** Special characters, by category. */
8
+ export declare const SYMBOLS: readonly CharacterCategory[];
9
+ /** Emoji, by category. */
10
+ export declare const EMOJI: readonly CharacterCategory[];
@@ -0,0 +1,23 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ import type { ToolbarColorButton } from '../toolbar/types';
4
+ /** Options of {@link createColorButton}. */
5
+ export interface ColorButtonOptions {
6
+ /** The element the popover scrolls with: the toolbar. */
7
+ container: HTMLElement;
8
+ messages: Messages;
9
+ }
10
+ /** A color split button and its popover (T-026). */
11
+ export interface ColorButton {
12
+ /** The wrapper of the two parts. */
13
+ readonly element: HTMLElement;
14
+ /** Applies the last used color. */
15
+ readonly main: HTMLButtonElement;
16
+ /** Opens the popover. */
17
+ readonly arrow: HTMLButtonElement;
18
+ /** Refreshes the enabled and pressed states. */
19
+ update(): void;
20
+ destroy(): void;
21
+ }
22
+ /** Creates the split button of `item` and its popover (closed), mounted in `container`. */
23
+ export declare function createColorButton(editor: Editor, item: ToolbarColorButton, options: ColorButtonOptions): ColorButton;
@@ -0,0 +1,34 @@
1
+ import { type IconNode } from 'lucide';
2
+ /** One option as displayed: label and shortcut already resolved and formatted. */
3
+ export interface DropdownOptionView {
4
+ id: string;
5
+ label: string;
6
+ shortcut?: string;
7
+ /** The label is drawn in this font family. */
8
+ fontFamily?: string;
9
+ /** An action (`menuitem`), never checked; otherwise a `menuitemradio`. */
10
+ action?: boolean;
11
+ }
12
+ export interface DropdownOptions {
13
+ /** Accessible name of the trigger and of the menu; shown when no option is active. */
14
+ label: string;
15
+ options: DropdownOptionView[];
16
+ /** Shown by the trigger instead of the value; the value stays in its accessible name. */
17
+ icon?: IconNode;
18
+ /** The popover container (the toolbar element). */
19
+ container: HTMLElement;
20
+ onSelect(id: string): void;
21
+ }
22
+ export interface DropdownState {
23
+ activeId: string | null;
24
+ disabledIds: ReadonlySet<string>;
25
+ /** Shown by the trigger when no option is active; default: the dropdown label. */
26
+ valueLabel?: string | null;
27
+ }
28
+ export interface Dropdown {
29
+ /** The trigger button; the toolbar inserts it in its group. */
30
+ readonly trigger: HTMLButtonElement;
31
+ update(state: DropdownState): void;
32
+ destroy(): void;
33
+ }
34
+ export declare function createDropdown(options: DropdownOptions): Dropdown;
@@ -0,0 +1,24 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createFindBar}. */
4
+ export interface FindBarOptions {
5
+ /** The find bar is appended inside it, after the toolbar. */
6
+ container: HTMLElement;
7
+ messages: Messages;
8
+ /** The toolbar button that toggles the bar: it gets `aria-expanded`. */
9
+ button?: HTMLElement | null;
10
+ }
11
+ /** The find and replace bar (T-043). */
12
+ export interface FindBar {
13
+ readonly element: HTMLElement;
14
+ readonly isOpen: boolean;
15
+ /** Shows the bar and focuses the find field, prefilled with the selected text. */
16
+ open(): void;
17
+ /** Hides the bar, clears the search and gives the focus back to the editor. */
18
+ close(): void;
19
+ /** Closes the bar when it is open, otherwise opens it. */
20
+ toggle(): void;
21
+ destroy(): void;
22
+ }
23
+ /** Creates the find bar (hidden). */
24
+ export declare function createFindBar(editor: Editor, options: FindBarOptions): FindBar;
@@ -0,0 +1,21 @@
1
+ import { type Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ import type { ToolbarFontSizeInput } from '../toolbar/types';
4
+ /** Options of {@link createFontSizeInput}. */
5
+ export interface CreateFontSizeInputOptions {
6
+ /** The element the list scrolls with: the toolbar. */
7
+ container: HTMLElement;
8
+ messages: Messages;
9
+ }
10
+ /** The font size control and its list (T-038). */
11
+ export interface FontSizeInput {
12
+ /** The wrapper of the three parts. */
13
+ readonly element: HTMLElement;
14
+ /** The toolbar items, in order: decrease, field, increase. */
15
+ readonly parts: readonly HTMLElement[];
16
+ /** Shows the size at the selection and refreshes the enabled state. */
17
+ update(): void;
18
+ destroy(): void;
19
+ }
20
+ /** Creates the font size control of `item` (list closed); the list is mounted in `container`. */
21
+ export declare function createFontSizeInput(editor: Editor, item: ToolbarFontSizeInput, options: CreateFontSizeInputOptions): FontSizeInput;
@@ -0,0 +1,20 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ import type { ToolbarIconMenu } from '../toolbar/types';
4
+ /** Options of {@link createIconMenu}. */
5
+ export interface IconMenuOptions {
6
+ /** The element the menu scrolls with: the toolbar. */
7
+ container: HTMLElement;
8
+ messages: Messages;
9
+ /** Whether shortcuts are shown with Mac symbols. */
10
+ mac: boolean;
11
+ }
12
+ /** A button that shows the icon of the active option and opens the options in a row (T-039). */
13
+ export interface IconMenu {
14
+ readonly trigger: HTMLButtonElement;
15
+ /** Shows the active option and refreshes the enabled states. */
16
+ update(): void;
17
+ destroy(): void;
18
+ }
19
+ /** Creates the trigger of `item` and its menu (closed), mounted in `container`. */
20
+ export declare function createIconMenu(editor: Editor, item: ToolbarIconMenu, options: IconMenuOptions): IconMenu;
@@ -0,0 +1,3 @@
1
+ import type { IconNode } from 'lucide';
2
+ /** An SVG element for a lucide icon, with class `stilo-icon` and `aria-hidden="true"`. */
3
+ export declare function createIcon(icon: IconNode): SVGElement;
@@ -0,0 +1,19 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createLinkBubble}. */
4
+ export interface LinkBubbleOptions {
5
+ /** The element the bubble scrolls with: the parent of the editable element. */
6
+ container: HTMLElement;
7
+ messages: Messages;
8
+ /** Called by the edit button (the toolbar opens the link popover). */
9
+ onEdit(): void;
10
+ }
11
+ /** The link bubble: shown under the link at the cursor while the editor has the focus. */
12
+ export interface LinkBubble {
13
+ readonly isOpen: boolean;
14
+ /** Shows, moves or hides the bubble after the selection or the focus changed. */
15
+ update(): void;
16
+ destroy(): void;
17
+ }
18
+ /** Creates the link bubble, which follows the editor on its own. */
19
+ export declare function createLinkBubble(editor: Editor, options: LinkBubbleOptions): LinkBubble;
@@ -0,0 +1,20 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createLinkPopover}. */
4
+ export interface LinkPopoverOptions {
5
+ /** The element the popover scrolls with: the parent of the editable element. */
6
+ container: HTMLElement;
7
+ messages: Messages;
8
+ }
9
+ /** The link popover: adds, edits or removes the link of the selection. */
10
+ export interface LinkPopover {
11
+ readonly isOpen: boolean;
12
+ /** Opens the popover under the selection; does nothing when {@link canEditLink} is false. */
13
+ open(): void;
14
+ close(): void;
15
+ destroy(): void;
16
+ }
17
+ /** Whether the selection is in a link or can be linked (a cursor outside a link cannot). */
18
+ export declare function canEditLink(editor: Editor): boolean;
19
+ /** Creates the link popover (closed), anchored to the selection of `editor`. */
20
+ export declare function createLinkPopover(editor: Editor, options: LinkPopoverOptions): LinkPopover;
@@ -0,0 +1,27 @@
1
+ import type { Placement, VirtualElement } from '@floating-ui/dom';
2
+ /** Why a popover closed. `api` = `close()` or `destroy()` was called. */
3
+ export type PopoverCloseReason = 'escape' | 'outside' | 'api';
4
+ export interface PopoverOptions {
5
+ /** What the popover is anchored to: an element, or a rectangle (e.g. the selection). */
6
+ anchor: Element | VirtualElement;
7
+ /** The floating element; the popover appends it to `container`. */
8
+ content: HTMLElement;
9
+ /**
10
+ * The element the popover scrolls with: it gets the class `stilo-popover-host`
11
+ * (`position: relative`), so the browser moves the popover with it on scroll.
12
+ */
13
+ container: HTMLElement;
14
+ /** Default: 'bottom-start'. */
15
+ placement?: Placement;
16
+ /** Distance from the anchor in px. Default: 4. */
17
+ offset?: number;
18
+ /** Called on every open → closed transition. */
19
+ onClose?(reason: PopoverCloseReason): void;
20
+ }
21
+ export interface Popover {
22
+ readonly isOpen: boolean;
23
+ open(): void;
24
+ close(): void;
25
+ destroy(): void;
26
+ }
27
+ export declare function createPopover(options: PopoverOptions): Popover;
@@ -0,0 +1,11 @@
1
+ /** Whether the platform shows Mac shortcuts. */
2
+ export declare function isMacPlatform(): boolean;
3
+ /**
4
+ * Formats a keymap shortcut for display.
5
+ *
6
+ * Off Mac: `Mod` means `Ctrl`; modifiers in the order `Ctrl`, `Alt`, `Shift`, then the key,
7
+ * joined with `+`. On Mac: `Ctrl` → `⌃`, `Alt` → `⌥`, `Shift` → `⇧`, `Mod` → `⌘`, in the
8
+ * order `⌃⌥⇧⌘`, then the key, no separator. A single-character key is uppercased; longer
9
+ * keys stay as written.
10
+ */
11
+ export declare function formatShortcut(shortcut: string, mac: boolean): string;
@@ -0,0 +1,19 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createStatusBar}. */
4
+ export interface StatusBarOptions {
5
+ /** The status bar element is appended inside it. */
6
+ container: HTMLElement;
7
+ /** UI strings. Default: `en`. */
8
+ messages?: Messages;
9
+ }
10
+ /** A status bar created by {@link createStatusBar}. */
11
+ export interface StatusBar {
12
+ readonly element: HTMLElement;
13
+ /** Counts again now (it also counts 500 ms after the last change). */
14
+ update(): void;
15
+ /** Removes the status bar and every listener. Calling it twice is a no-op. */
16
+ destroy(): void;
17
+ }
18
+ /** Creates a status bar with the word and character count of the document (F-901). */
19
+ export declare function createStatusBar(editor: Editor, options: StatusBarOptions): StatusBar;
@@ -0,0 +1,25 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** A table operation: the command of the same name, `toggleHeader*` for the header toggles. */
4
+ export type TableAction = 'addRowBefore' | 'addRowAfter' | 'deleteRow' | 'addColumnBefore' | 'addColumnAfter' | 'deleteColumn' | 'mergeCells' | 'splitCell' | 'toggleHeaderRow' | 'toggleHeaderColumn' | 'deleteTable';
5
+ /** Options of {@link createTableActions}. */
6
+ export interface TableActionsOptions {
7
+ /** The operations, in groups divided by a separator. */
8
+ groups: ReadonlyArray<ReadonlyArray<TableAction>>;
9
+ /** The accessible name of the menu. */
10
+ label: string;
11
+ messages: Messages;
12
+ /** Closes the popover holding the menu (`Tab`, and before an operation runs). */
13
+ close(): void;
14
+ }
15
+ /** A `role="menu"` of table operations, for a popover. */
16
+ export interface TableActions {
17
+ readonly element: HTMLElement;
18
+ /** Enables the items whose command can run and checks the header toggles. */
19
+ refresh(): void;
20
+ /** Focuses the first enabled item. */
21
+ focusFirst(): void;
22
+ destroy(): void;
23
+ }
24
+ /** Creates a menu of table operations; an item runs its command on the selection. */
25
+ export declare function createTableActions(editor: Editor, options: TableActionsOptions): TableActions;
@@ -0,0 +1,16 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createTableHandles}. */
4
+ export interface TableHandlesOptions {
5
+ /** The element the handles scroll with: the parent of the editable element. */
6
+ container: HTMLElement;
7
+ messages: Messages;
8
+ }
9
+ /** The handles of the row, the column and the table of the cell under the mouse or the cursor. */
10
+ export interface TableHandles {
11
+ /** Shows, moves or hides the handles after the selection, the focus or the mouse changed. */
12
+ update(): void;
13
+ destroy(): void;
14
+ }
15
+ /** Creates the table handles, which follow the editor on their own. */
16
+ export declare function createTableHandles(editor: Editor, options: TableHandlesOptions): TableHandles;
@@ -0,0 +1,21 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ /** Options of {@link createTableMenu}. */
4
+ export interface TableMenuOptions {
5
+ /** The toolbar button that opens the menu. */
6
+ anchor: HTMLElement;
7
+ /** The element the menu scrolls with: the toolbar. */
8
+ container: HTMLElement;
9
+ messages: Messages;
10
+ }
11
+ /** The table menu: the insert grid outside a table, the table operations inside one. */
12
+ export interface TableMenu {
13
+ readonly isOpen: boolean;
14
+ open(): void;
15
+ /** Closes the menu and gives the focus back to the editor. */
16
+ close(): void;
17
+ toggle(): void;
18
+ destroy(): void;
19
+ }
20
+ /** Creates the table menu (closed), anchored to the toolbar button. */
21
+ export declare function createTableMenu(editor: Editor, options: TableMenuOptions): TableMenu;
@@ -0,0 +1,3 @@
1
+ import type { Messages } from './types';
2
+ /** English UI strings. */
3
+ export declare const en: Messages;
@@ -0,0 +1,3 @@
1
+ import type { Messages } from './types';
2
+ /** Italian UI strings. */
3
+ export declare const it: Messages;
@@ -0,0 +1,4 @@
1
+ /** Keys of the built-in UI strings (dot.case). */
2
+ export type MessageKey = 'toolbar.label' | 'toolbar.undo' | 'toolbar.redo' | 'toolbar.bold' | 'toolbar.italic' | 'toolbar.underline' | 'toolbar.strike' | 'toolbar.subscript' | 'toolbar.superscript' | 'toolbar.code' | 'toolbar.clearFormatting' | 'toolbar.textCase' | 'toolbar.bulletList' | 'toolbar.orderedList' | 'toolbar.taskList' | 'toolbar.blockquote' | 'toolbar.codeBlock' | 'toolbar.horizontalRule' | 'toolbar.link' | 'toolbar.heading' | 'toolbar.fontFamily' | 'toolbar.fontSize' | 'fontSize.decrease' | 'fontSize.increase' | 'toolbar.textAlign' | 'align.left' | 'align.center' | 'align.right' | 'align.justify' | 'toolbar.lineHeight' | 'lineHeight.default' | 'textCase.upper' | 'textCase.lower' | 'textCase.title' | 'textCase.sentence' | 'textCase.toggle' | 'font.default' | 'font.sansSerif' | 'font.serif' | 'font.monospace' | 'heading.paragraph' | 'heading.h1' | 'heading.h2' | 'heading.h3' | 'heading.h4' | 'heading.h5' | 'heading.h6' | 'link.url' | 'link.newTab' | 'link.apply' | 'link.remove' | 'link.edit' | 'link.open' | 'toolbar.characters' | 'characters.search' | 'characters.noResults' | 'characters.symbols' | 'characters.emoji' | 'characters.punctuation' | 'characters.currency' | 'characters.math' | 'characters.arrows' | 'characters.greek' | 'characters.latin' | 'characters.signs' | 'characters.smileys' | 'characters.people' | 'characters.nature' | 'characters.food' | 'characters.travel' | 'characters.activities' | 'characters.objects' | 'characters.emojiSymbols' | 'toolbar.textColor' | 'toolbar.highlight' | 'color.more' | 'color.default' | 'color.none' | 'color.pick' | 'color.custom' | 'color.apply' | 'color.black' | 'color.darkGray2' | 'color.darkGray1' | 'color.gray' | 'color.lightGray1' | 'color.lightGray2' | 'color.lightGray3' | 'color.white' | 'color.red' | 'color.orange' | 'color.yellow' | 'color.green' | 'color.cyan' | 'color.blue' | 'color.purple' | 'color.pink' | 'color.lightRed' | 'color.lightOrange' | 'color.lightYellow' | 'color.lightGreen' | 'color.lightCyan' | 'color.lightBlue' | 'color.lightPurple' | 'color.lightPink' | 'color.darkRed' | 'color.darkOrange' | 'color.darkYellow' | 'color.darkGreen' | 'color.darkCyan' | 'color.darkBlue' | 'color.darkPurple' | 'color.darkPink' | 'toolbar.table' | 'table.insert' | 'table.size' | 'table.row' | 'table.column' | 'table.headerRow' | 'table.headerColumn' | 'table.addRowBefore' | 'table.addRowAfter' | 'table.deleteRow' | 'table.addColumnBefore' | 'table.addColumnAfter' | 'table.deleteColumn' | 'table.mergeCells' | 'table.splitCell' | 'table.deleteTable' | 'toolbar.find' | 'find.find' | 'find.replace' | 'find.previous' | 'find.next' | 'find.matchCase' | 'find.wholeWord' | 'find.replaceOne' | 'find.replaceAll' | 'find.close' | 'find.position' | 'find.results' | 'find.noResults' | 'status.words' | 'status.characters';
3
+ /** UI strings: every {@link MessageKey}, plus the label keys of custom toolbar items. */
4
+ export type Messages = Readonly<Record<MessageKey, string>> & Readonly<Record<string, string>>;
@@ -0,0 +1,23 @@
1
+ /** Public API of the Stilo default UI. */
2
+ /** Dropdown component. */
3
+ export type { Dropdown, DropdownOptions, DropdownOptionView, DropdownState, } from './components/dropdown';
4
+ /** Shortcut formatting utilities. */
5
+ export { formatShortcut } from './components/shortcut';
6
+ /** Status bar with the word and character count. */
7
+ export { createStatusBar, type StatusBar, type StatusBarOptions, } from './components/status-bar';
8
+ /** English UI strings. */
9
+ export { en } from './i18n/en';
10
+ /** Italian UI strings. */
11
+ export { it } from './i18n/it';
12
+ /** i18n types. */
13
+ export type { MessageKey, Messages } from './i18n/types';
14
+ /** Default lists of the font dropdowns. */
15
+ export { DEFAULT_FONT_SIZES, DEFAULT_FONTS } from './toolbar/fonts';
16
+ /** Default toolbar items and layout. */
17
+ export { DEFAULT_ITEMS, DEFAULT_TOOLBAR, type FontSizeInputOptions, fontFamilyDropdown, fontSizeInput, headingDropdown, highlightButton, lineHeightDropdown, textAlignMenu, textColorButton, } from './toolbar/items';
18
+ /** Default palette of the color buttons. */
19
+ export { DEFAULT_PALETTE } from './toolbar/palette';
20
+ /** Toolbar element and creation function. */
21
+ export { createToolbar, type Toolbar, type ToolbarOptions } from './toolbar/toolbar';
22
+ /** Toolbar item types. */
23
+ export type { ToolbarButton, ToolbarColor, ToolbarColorButton, ToolbarContext, ToolbarDropdown, ToolbarDropdownOption, ToolbarFont, ToolbarFontSizeInput, ToolbarIconMenu, ToolbarIconMenuOption, ToolbarItem, } from './toolbar/types';
@@ -0,0 +1,8 @@
1
+ import type { ToolbarFont } from './types';
2
+ /**
3
+ * The default fonts of the font family dropdown: the three generic families, which every system
4
+ * resolves, then common fonts with fallbacks for the systems that lack them.
5
+ */
6
+ export declare const DEFAULT_FONTS: readonly ToolbarFont[];
7
+ /** The default sizes of the font size list, by unit (`rem` uses the px list). */
8
+ export declare const DEFAULT_FONT_SIZES: Readonly<Record<'pt' | 'px', readonly number[]>>;
@@ -0,0 +1,33 @@
1
+ import type { FontSizeUnit, HeadingLevel } from '../../index';
2
+ import type { ToolbarColor, ToolbarColorButton, ToolbarDropdown, ToolbarFont, ToolbarFontSizeInput, ToolbarIconMenu, ToolbarItem } from './types';
3
+ /** Default toolbar item IDs for the `items` configuration. */
4
+ export declare const DEFAULT_TOOLBAR: ReadonlyArray<ReadonlyArray<string>>;
5
+ /** The default toolbar items, by ID. */
6
+ export declare const DEFAULT_ITEMS: Readonly<Record<string, ToolbarItem>>;
7
+ /** The text color split button (`TextStyle` extension), default color black. */
8
+ export declare function textColorButton(palette?: readonly ToolbarColor[]): ToolbarColorButton;
9
+ /** The highlight split button (`Highlight` extension), default a plain `<mark>`. */
10
+ export declare function highlightButton(palette?: readonly ToolbarColor[]): ToolbarColorButton;
11
+ /**
12
+ * The font family dropdown (`TextStyle` extension): "Default" removes the font family, then one
13
+ * option per font, drawn in that font. A font that is not in the list is shown by its first name.
14
+ */
15
+ export declare function fontFamilyDropdown(fonts?: readonly ToolbarFont[]): ToolbarDropdown;
16
+ /** Options of {@link fontSizeInput}. */
17
+ export interface FontSizeInputOptions {
18
+ /** The unit the field shows and writes. Default: `pt`. */
19
+ unit?: FontSizeUnit;
20
+ /** The sizes of the list, in `unit` (px for `rem`). Default: `DEFAULT_FONT_SIZES` of the unit. */
21
+ sizes?: readonly number[];
22
+ }
23
+ /** The font size control (`TextStyle` extension): −, a field with a list of sizes, +. */
24
+ export declare function fontSizeInput(options?: FontSizeInputOptions): ToolbarFontSizeInput;
25
+ /** The text alignment menu (`TextAlign` extension): left, center, right, justify. */
26
+ export declare function textAlignMenu(): ToolbarIconMenu;
27
+ /**
28
+ * The line spacing dropdown (`LineHeight` extension): "Default" (no line height of its own) and
29
+ * the `values`, shown as numbers.
30
+ */
31
+ export declare function lineHeightDropdown(values?: readonly number[]): ToolbarDropdown;
32
+ /** A heading dropdown toolbar item. */
33
+ export declare function headingDropdown(levels?: HeadingLevel[]): ToolbarDropdown;
@@ -0,0 +1,6 @@
1
+ import type { ToolbarColor } from './types';
2
+ /**
3
+ * The default palette of the color buttons, 8 columns: grays, then 8 hues in their vivid, light
4
+ * and dark shades.
5
+ */
6
+ export declare const DEFAULT_PALETTE: readonly ToolbarColor[];
@@ -0,0 +1,28 @@
1
+ import type { Editor } from '../../index';
2
+ import type { Messages } from '../i18n/types';
3
+ import type { ToolbarItem } from './types';
4
+ /** Options of {@link createToolbar}. */
5
+ export interface ToolbarOptions {
6
+ /** The toolbar element is appended inside it. */
7
+ container: HTMLElement;
8
+ /** Groups of items: an ID of DEFAULT_ITEMS or a custom item. Default: DEFAULT_TOOLBAR. */
9
+ items?: ReadonlyArray<ReadonlyArray<string | ToolbarItem>>;
10
+ /** UI strings. Default: `en`. */
11
+ messages?: Messages;
12
+ /**
13
+ * Keeps the toolbar visible at the top of the scrolling area: `container` gets the class
14
+ * `stilo-toolbar-host` (`position: sticky`). Default: `true`.
15
+ */
16
+ sticky?: boolean;
17
+ }
18
+ /** A toolbar created by {@link createToolbar}. */
19
+ export interface Toolbar {
20
+ /** The `role="toolbar"` element. */
21
+ readonly element: HTMLElement;
22
+ /** Refreshes active/enabled states now (they also refresh on every transaction). */
23
+ update(): void;
24
+ /** Removes the toolbar and every listener. Calling it twice is a no-op. */
25
+ destroy(): void;
26
+ }
27
+ /** Creates the toolbar element and buttons, and registers event handlers. */
28
+ export declare function createToolbar(editor: Editor, options: ToolbarOptions): Toolbar;
@@ -0,0 +1,150 @@
1
+ import type { IconNode } from 'lucide';
2
+ import type { Editor, FontSizeUnit } from '../../index';
3
+ /** A toolbar button. */
4
+ export interface ToolbarButton {
5
+ /** Unique within the toolbar; written as `data-item`. */
6
+ id: string;
7
+ kind: 'button';
8
+ icon: IconNode;
9
+ /** Key of the label in `messages`; a missing key is shown as is. */
10
+ labelKey: string;
11
+ /** Keymap notation shown in the tooltip, e.g. 'Mod-b'. */
12
+ shortcut?: string;
13
+ /** Runs on click, after the editor got the focus back. */
14
+ run(editor: Editor, context: ToolbarContext): void;
15
+ /** Present = toggle button (`aria-pressed`). */
16
+ isActive?(editor: Editor): boolean;
17
+ /** Default: always enabled. */
18
+ isEnabled?(editor: Editor): boolean;
19
+ /** False = not rendered (e.g. its extension is disabled). Default: available. */
20
+ isAvailable?(editor: Editor): boolean;
21
+ }
22
+ /** UI services the toolbar offers to {@link ToolbarButton.run}. */
23
+ export interface ToolbarContext {
24
+ /** Opens the link popover under the selection (no-op without the `Link` extension). */
25
+ openLinkPopover(): void;
26
+ /** Opens or closes the character picker (no-op without the `characters` item). */
27
+ toggleCharacterPicker(): void;
28
+ /** Opens or closes the find bar (no-op without the `Search` extension). */
29
+ toggleFindBar(): void;
30
+ /** Opens or closes the table menu (no-op without the `table` item). T-045. */
31
+ toggleTableMenu(): void;
32
+ }
33
+ /** A dropdown of mutually exclusive options, or of actions (T-048) (T-014). */
34
+ export interface ToolbarDropdown {
35
+ id: string;
36
+ kind: 'dropdown';
37
+ /** Key of the accessible name of the trigger and of the menu. */
38
+ labelKey: string;
39
+ /** Shown by the trigger instead of the active option (T-040); default: the option label. */
40
+ icon?: IconNode;
41
+ options: ToolbarDropdownOption[];
42
+ /**
43
+ * The text of the trigger when no option is active, e.g. a font size that is not in the list;
44
+ * `null` (or no function) shows the dropdown label.
45
+ */
46
+ getValueLabel?(editor: Editor): string | null;
47
+ isAvailable?(editor: Editor): boolean;
48
+ }
49
+ /** An option of a {@link ToolbarDropdown}. */
50
+ export interface ToolbarDropdownOption {
51
+ /** Unique within the dropdown; used in the class `stilo-dropdown__option--<id>`. */
52
+ id: string;
53
+ labelKey: string;
54
+ shortcut?: string;
55
+ /** Shows the option label in this font family (a CSS `font-family` list). */
56
+ fontFamily?: string;
57
+ run(editor: Editor): void;
58
+ /** Without it the option is an action (`role="menuitem"`), never checked. T-048. */
59
+ isActive?(editor: Editor): boolean;
60
+ /** Default: always enabled. */
61
+ isEnabled?(editor: Editor): boolean;
62
+ }
63
+ /** A color of a {@link ToolbarColorButton} palette. */
64
+ export interface ToolbarColor {
65
+ /** A CSS color, written as the editor stores it (e.g. lowercase `#rrggbb`). */
66
+ color: string;
67
+ /** Key of the color name in `messages`; a missing key is shown as is. */
68
+ labelKey: string;
69
+ }
70
+ /**
71
+ * A split button that applies a color (T-026): the main part applies the last used color (or
72
+ * removes it when the whole selection has it), the arrow opens a popover with the palette.
73
+ */
74
+ export interface ToolbarColorButton {
75
+ /** Unique within the toolbar; written as `data-item` on both parts. */
76
+ id: string;
77
+ kind: 'color';
78
+ icon: IconNode;
79
+ labelKey: string;
80
+ palette: readonly ToolbarColor[];
81
+ /** The color the main part applies until one is picked (`null`: the mark without a color). */
82
+ defaultColor: string | null;
83
+ /**
84
+ * Shows a "Default" choice next to "No color" that applies the color `null`; its label is
85
+ * drawn inside a `<mark>`, the browser's look of a highlight without a color.
86
+ */
87
+ defaultChoice?: boolean;
88
+ /** Applies `color` to the selection; `false` when the color is refused. */
89
+ setColor(editor: Editor, color: string | null): boolean;
90
+ /** Removes the color from the selection. */
91
+ unsetColor(editor: Editor): void;
92
+ /** Whether the whole selection has `color`. */
93
+ hasColor(editor: Editor, color: string | null): boolean;
94
+ /** The color at the selection, `null` when there is none. */
95
+ getColor(editor: Editor): string | null;
96
+ /** Default: always enabled. */
97
+ isEnabled?(editor: Editor): boolean;
98
+ isAvailable?(editor: Editor): boolean;
99
+ }
100
+ /** A font of the `fontFamilyDropdown` list. */
101
+ export interface ToolbarFont {
102
+ /** A CSS `font-family` list, written as the editor stores it (`'Times New Roman', serif`). */
103
+ fontFamily: string;
104
+ /** Key of the font name in `messages`; a missing key is shown as is. */
105
+ labelKey: string;
106
+ }
107
+ /**
108
+ * The font size control (T-038): a decrease button, a field that shows the size at the selection,
109
+ * takes a typed size and opens a list of sizes, and an increase button.
110
+ */
111
+ export interface ToolbarFontSizeInput {
112
+ /** Unique within the toolbar; written as `data-item` on the three parts. */
113
+ id: string;
114
+ kind: 'fontSize';
115
+ /** Key of the accessible name of the field and of the list. */
116
+ labelKey: string;
117
+ /** The unit the field shows and writes; `rem` shows px and writes rem. */
118
+ unit: FontSizeUnit;
119
+ /** The sizes of the list, in `unit` (px for `rem`). */
120
+ sizes: readonly number[];
121
+ isAvailable?(editor: Editor): boolean;
122
+ }
123
+ /**
124
+ * A button that shows the icon of the active option (of the first one when none is active) and
125
+ * opens the options as icons in a row (T-039).
126
+ */
127
+ export interface ToolbarIconMenu {
128
+ /** Unique within the toolbar; written as `data-item`. */
129
+ id: string;
130
+ kind: 'iconMenu';
131
+ /** Key of the accessible name of the trigger and of the menu. */
132
+ labelKey: string;
133
+ options: ToolbarIconMenuOption[];
134
+ isAvailable?(editor: Editor): boolean;
135
+ }
136
+ /** An option of a {@link ToolbarIconMenu}. */
137
+ export interface ToolbarIconMenuOption {
138
+ /** Unique within the menu; used in the class `stilo-icon-menu__option--<id>`. */
139
+ id: string;
140
+ icon: IconNode;
141
+ labelKey: string;
142
+ /** Keymap notation shown in the tooltip. */
143
+ shortcut?: string;
144
+ run(editor: Editor): void;
145
+ isActive(editor: Editor): boolean;
146
+ /** Default: always enabled. */
147
+ isEnabled?(editor: Editor): boolean;
148
+ }
149
+ /** A single item in the toolbar. */
150
+ export type ToolbarItem = ToolbarButton | ToolbarDropdown | ToolbarColorButton | ToolbarFontSizeInput | ToolbarIconMenu;