@rtif-sdk/web 1.0.0 → 1.3.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 (70) hide show
  1. package/dist/block-drag-handler.d.ts +5 -0
  2. package/dist/block-drag-handler.d.ts.map +1 -1
  3. package/dist/block-drag-handler.js +32 -3
  4. package/dist/block-drag-handler.js.map +1 -1
  5. package/dist/block-renderer.d.ts +12 -6
  6. package/dist/block-renderer.d.ts.map +1 -1
  7. package/dist/block-renderer.js +98 -9
  8. package/dist/block-renderer.js.map +1 -1
  9. package/dist/block-type-dropdown.d.ts +78 -0
  10. package/dist/block-type-dropdown.d.ts.map +1 -0
  11. package/dist/block-type-dropdown.js +276 -0
  12. package/dist/block-type-dropdown.js.map +1 -0
  13. package/dist/color-picker.d.ts +91 -0
  14. package/dist/color-picker.d.ts.map +1 -0
  15. package/dist/color-picker.js +346 -0
  16. package/dist/color-picker.js.map +1 -0
  17. package/dist/content-handlers.d.ts +7 -8
  18. package/dist/content-handlers.d.ts.map +1 -1
  19. package/dist/content-handlers.js +122 -93
  20. package/dist/content-handlers.js.map +1 -1
  21. package/dist/editor.d.ts.map +1 -1
  22. package/dist/editor.js +224 -15
  23. package/dist/editor.js.map +1 -1
  24. package/dist/embed-utils.d.ts +148 -0
  25. package/dist/embed-utils.d.ts.map +1 -0
  26. package/dist/embed-utils.js +197 -0
  27. package/dist/embed-utils.js.map +1 -0
  28. package/dist/font-family-picker.d.ts +105 -0
  29. package/dist/font-family-picker.d.ts.map +1 -0
  30. package/dist/font-family-picker.js +314 -0
  31. package/dist/font-family-picker.js.map +1 -0
  32. package/dist/font-size-picker.d.ts +82 -0
  33. package/dist/font-size-picker.d.ts.map +1 -0
  34. package/dist/font-size-picker.js +290 -0
  35. package/dist/font-size-picker.js.map +1 -0
  36. package/dist/index.d.ts +18 -4
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +30 -2
  39. package/dist/index.js.map +1 -1
  40. package/dist/plugins/index.d.ts +2 -1
  41. package/dist/plugins/index.d.ts.map +1 -1
  42. package/dist/plugins/index.js +1 -1
  43. package/dist/plugins/index.js.map +1 -1
  44. package/dist/plugins/link-plugin.d.ts +4 -0
  45. package/dist/plugins/link-plugin.d.ts.map +1 -1
  46. package/dist/plugins/link-plugin.js +17 -0
  47. package/dist/plugins/link-plugin.js.map +1 -1
  48. package/dist/plugins/mark-utils.d.ts +31 -0
  49. package/dist/plugins/mark-utils.d.ts.map +1 -1
  50. package/dist/plugins/mark-utils.js +46 -0
  51. package/dist/plugins/mark-utils.js.map +1 -1
  52. package/dist/renderer.d.ts +31 -2
  53. package/dist/renderer.d.ts.map +1 -1
  54. package/dist/renderer.js +131 -55
  55. package/dist/renderer.js.map +1 -1
  56. package/dist/selection-sync.d.ts +2 -26
  57. package/dist/selection-sync.d.ts.map +1 -1
  58. package/dist/selection-sync.js +49 -13
  59. package/dist/selection-sync.js.map +1 -1
  60. package/dist/spatial-index.d.ts +203 -0
  61. package/dist/spatial-index.d.ts.map +1 -0
  62. package/dist/spatial-index.js +211 -0
  63. package/dist/spatial-index.js.map +1 -0
  64. package/dist/types.d.ts +93 -0
  65. package/dist/types.d.ts.map +1 -1
  66. package/dist/virtual-viewport.d.ts +241 -0
  67. package/dist/virtual-viewport.d.ts.map +1 -0
  68. package/dist/virtual-viewport.js +584 -0
  69. package/dist/virtual-viewport.js.map +1 -0
  70. package/package.json +17 -5
@@ -0,0 +1,276 @@
1
+ /**
2
+ * Block type dropdown — a combobox-style dropdown for switching block types.
3
+ *
4
+ * Shows the currently active block type (e.g., "Heading 1", "Bullet List")
5
+ * and lets the user switch to a different type. Uses the same
6
+ * `mousedown + preventDefault()` pattern as the toolbar to avoid stealing
7
+ * editor focus.
8
+ *
9
+ * @module
10
+ */
11
+ // ---------------------------------------------------------------------------
12
+ // Module-scoped counter for unique IDs
13
+ // ---------------------------------------------------------------------------
14
+ let instanceCounter = 0;
15
+ // ---------------------------------------------------------------------------
16
+ // Factory
17
+ // ---------------------------------------------------------------------------
18
+ /**
19
+ * Create a block type dropdown backed by a {@link CommandBus}.
20
+ *
21
+ * The dropdown reflects the currently active block type by querying
22
+ * `bus.isActive()` for each item. It subscribes to the bus for live updates.
23
+ *
24
+ * @param container - The DOM element to render the dropdown into
25
+ * @param bus - The CommandBus to execute commands and query state
26
+ * @param items - Array of dropdown item configurations
27
+ * @returns A handle for lifecycle management
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const dropdown = createBlockTypeDropdown(
32
+ * document.getElementById('toolbar')!,
33
+ * bus,
34
+ * [
35
+ * { command: null, label: 'Paragraph' },
36
+ * { command: 'toggleHeading', payload: { level: 1 }, label: 'Heading 1', icon: 'H1' },
37
+ * ],
38
+ * );
39
+ * ```
40
+ */
41
+ export function createBlockTypeDropdown(container, bus, items) {
42
+ const doc = container.ownerDocument;
43
+ const id = ++instanceCounter;
44
+ const menuId = `rtif-btd-menu-${id}`;
45
+ let isOpen = false;
46
+ let highlightIndex = -1;
47
+ let destroyed = false;
48
+ // -----------------------------------------------------------------------
49
+ // DOM creation
50
+ // -----------------------------------------------------------------------
51
+ const wrapper = doc.createElement('div');
52
+ wrapper.className = 'rtif-block-type-dropdown';
53
+ // Trigger button
54
+ const trigger = doc.createElement('button');
55
+ trigger.type = 'button';
56
+ trigger.className = 'rtif-block-type-dropdown-trigger';
57
+ trigger.setAttribute('role', 'combobox');
58
+ trigger.setAttribute('aria-haspopup', 'listbox');
59
+ trigger.setAttribute('aria-expanded', 'false');
60
+ trigger.setAttribute('aria-controls', menuId);
61
+ trigger.setAttribute('aria-label', 'Block type');
62
+ const iconSpan = doc.createElement('span');
63
+ iconSpan.className = 'rtif-block-type-dropdown-icon';
64
+ const labelSpan = doc.createElement('span');
65
+ labelSpan.className = 'rtif-block-type-dropdown-label';
66
+ const chevronSpan = doc.createElement('span');
67
+ chevronSpan.className = 'rtif-block-type-dropdown-chevron';
68
+ chevronSpan.textContent = '\u25BE'; // ▾
69
+ trigger.appendChild(iconSpan);
70
+ trigger.appendChild(labelSpan);
71
+ trigger.appendChild(chevronSpan);
72
+ // Menu
73
+ const menu = doc.createElement('div');
74
+ menu.id = menuId;
75
+ menu.className = 'rtif-block-type-dropdown-menu';
76
+ menu.setAttribute('role', 'listbox');
77
+ menu.setAttribute('aria-label', 'Block types');
78
+ menu.hidden = true;
79
+ // Options
80
+ const optionEls = [];
81
+ for (let i = 0; i < items.length; i++) {
82
+ const item = items[i];
83
+ const option = doc.createElement('div');
84
+ option.className = 'rtif-block-type-dropdown-option';
85
+ option.id = `rtif-btd-option-${id}-${i}`;
86
+ option.setAttribute('role', 'option');
87
+ option.setAttribute('aria-selected', 'false');
88
+ if (item.icon) {
89
+ const optIcon = doc.createElement('span');
90
+ optIcon.className = 'rtif-block-type-dropdown-option-icon';
91
+ optIcon.textContent = item.icon;
92
+ option.appendChild(optIcon);
93
+ }
94
+ const optLabel = doc.createElement('span');
95
+ optLabel.className = 'rtif-block-type-dropdown-option-label';
96
+ optLabel.textContent = item.label;
97
+ option.appendChild(optLabel);
98
+ option.addEventListener('mousedown', (e) => {
99
+ e.preventDefault();
100
+ selectItem(i);
101
+ });
102
+ menu.appendChild(option);
103
+ optionEls.push(option);
104
+ }
105
+ wrapper.appendChild(trigger);
106
+ wrapper.appendChild(menu);
107
+ container.appendChild(wrapper);
108
+ // -----------------------------------------------------------------------
109
+ // Active state detection
110
+ // -----------------------------------------------------------------------
111
+ function findActiveIndex() {
112
+ for (let i = 0; i < items.length; i++) {
113
+ const item = items[i];
114
+ if (item.command !== null && bus.isActive(item.command, item.payload)) {
115
+ return i;
116
+ }
117
+ }
118
+ // Default: find the null-command item (Paragraph), else fall back to 0
119
+ const nullIdx = items.findIndex((it) => it.command === null);
120
+ return nullIdx !== -1 ? nullIdx : 0;
121
+ }
122
+ function updateDisplay() {
123
+ const activeIdx = findActiveIndex();
124
+ const active = items[activeIdx];
125
+ iconSpan.textContent = active.icon ?? '';
126
+ labelSpan.textContent = active.label;
127
+ // Update aria-selected on options
128
+ for (let i = 0; i < optionEls.length; i++) {
129
+ optionEls[i].setAttribute('aria-selected', i === activeIdx ? 'true' : 'false');
130
+ }
131
+ }
132
+ // -----------------------------------------------------------------------
133
+ // Open / close
134
+ // -----------------------------------------------------------------------
135
+ function openMenu() {
136
+ if (isOpen)
137
+ return;
138
+ isOpen = true;
139
+ highlightIndex = -1;
140
+ menu.hidden = false;
141
+ trigger.setAttribute('aria-expanded', 'true');
142
+ trigger.removeAttribute('aria-activedescendant');
143
+ doc.addEventListener('mousedown', onDocumentMouseDown);
144
+ }
145
+ function closeMenu() {
146
+ if (!isOpen)
147
+ return;
148
+ isOpen = false;
149
+ highlightIndex = -1;
150
+ menu.hidden = true;
151
+ trigger.setAttribute('aria-expanded', 'false');
152
+ trigger.removeAttribute('aria-activedescendant');
153
+ // Clear highlight
154
+ for (const el of optionEls) {
155
+ el.classList.remove('rtif-block-type-dropdown-option-highlighted');
156
+ }
157
+ doc.removeEventListener('mousedown', onDocumentMouseDown);
158
+ }
159
+ // -----------------------------------------------------------------------
160
+ // Selection
161
+ // -----------------------------------------------------------------------
162
+ function selectItem(index) {
163
+ const item = items[index];
164
+ if (item.command === null) {
165
+ // "Paragraph" — toggle off the currently active type
166
+ const activeIdx = findActiveIndex();
167
+ const activeItem = items[activeIdx];
168
+ if (activeItem && activeItem.command !== null) {
169
+ bus.execute(activeItem.command, activeItem.payload);
170
+ }
171
+ // If already on paragraph, this is a no-op
172
+ }
173
+ else {
174
+ bus.execute(item.command, item.payload);
175
+ }
176
+ closeMenu();
177
+ }
178
+ // -----------------------------------------------------------------------
179
+ // Keyboard navigation
180
+ // -----------------------------------------------------------------------
181
+ function onKeyDown(e) {
182
+ if (!isOpen)
183
+ return;
184
+ switch (e.key) {
185
+ case 'ArrowDown': {
186
+ e.preventDefault();
187
+ highlightIndex = (highlightIndex + 1) % items.length;
188
+ updateHighlight();
189
+ break;
190
+ }
191
+ case 'ArrowUp': {
192
+ e.preventDefault();
193
+ highlightIndex = highlightIndex <= 0
194
+ ? items.length - 1
195
+ : highlightIndex - 1;
196
+ updateHighlight();
197
+ break;
198
+ }
199
+ case 'Enter': {
200
+ e.preventDefault();
201
+ if (highlightIndex >= 0 && highlightIndex < items.length) {
202
+ selectItem(highlightIndex);
203
+ }
204
+ break;
205
+ }
206
+ case 'Escape': {
207
+ e.preventDefault();
208
+ closeMenu();
209
+ break;
210
+ }
211
+ }
212
+ }
213
+ function updateHighlight() {
214
+ for (let i = 0; i < optionEls.length; i++) {
215
+ const el = optionEls[i];
216
+ if (i === highlightIndex) {
217
+ el.classList.add('rtif-block-type-dropdown-option-highlighted');
218
+ }
219
+ else {
220
+ el.classList.remove('rtif-block-type-dropdown-option-highlighted');
221
+ }
222
+ }
223
+ if (highlightIndex >= 0 && highlightIndex < optionEls.length) {
224
+ trigger.setAttribute('aria-activedescendant', optionEls[highlightIndex].id);
225
+ }
226
+ else {
227
+ trigger.removeAttribute('aria-activedescendant');
228
+ }
229
+ }
230
+ // -----------------------------------------------------------------------
231
+ // Event handlers
232
+ // -----------------------------------------------------------------------
233
+ function onTriggerMouseDown(e) {
234
+ e.preventDefault();
235
+ }
236
+ function onTriggerClick() {
237
+ if (isOpen) {
238
+ closeMenu();
239
+ }
240
+ else {
241
+ openMenu();
242
+ }
243
+ }
244
+ function onDocumentMouseDown(e) {
245
+ // Close on outside click, but not if clicking inside wrapper
246
+ if (!wrapper.contains(e.target)) {
247
+ closeMenu();
248
+ }
249
+ }
250
+ trigger.addEventListener('mousedown', onTriggerMouseDown);
251
+ trigger.addEventListener('click', onTriggerClick);
252
+ trigger.addEventListener('keydown', onKeyDown);
253
+ // -----------------------------------------------------------------------
254
+ // Bus subscription
255
+ // -----------------------------------------------------------------------
256
+ updateDisplay();
257
+ const unsubscribe = bus.subscribe(() => updateDisplay());
258
+ // -----------------------------------------------------------------------
259
+ // Handle
260
+ // -----------------------------------------------------------------------
261
+ return {
262
+ element: wrapper,
263
+ destroy() {
264
+ if (destroyed)
265
+ return;
266
+ destroyed = true;
267
+ unsubscribe();
268
+ closeMenu();
269
+ trigger.removeEventListener('mousedown', onTriggerMouseDown);
270
+ trigger.removeEventListener('click', onTriggerClick);
271
+ trigger.removeEventListener('keydown', onKeyDown);
272
+ wrapper.remove();
273
+ },
274
+ };
275
+ }
276
+ //# sourceMappingURL=block-type-dropdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"block-type-dropdown.js","sourceRoot":"","sources":["../src/block-type-dropdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Color picker — a swatch grid dropdown for applying text colors.
3
+ *
4
+ * Shows the current text color in the trigger button and lets the user
5
+ * pick from preset swatches or enter a custom hex color. Uses the same
6
+ * `mousedown + preventDefault()` pattern as the toolbar to avoid stealing
7
+ * editor focus.
8
+ *
9
+ * @module
10
+ */
11
+ import type { IEditorEngine } from '@rtif-sdk/engine';
12
+ import type { CommandBus } from './command-bus.js';
13
+ /**
14
+ * Default color swatches displayed in the color picker grid.
15
+ *
16
+ * Row 1: dark/saturated colors.
17
+ * Row 2: light/pastel colors.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * const picker = createColorPicker({
22
+ * container, bus, engine,
23
+ * swatches: DEFAULT_COLOR_SWATCHES.slice(0, 10), // first row only
24
+ * });
25
+ * ```
26
+ */
27
+ export declare const DEFAULT_COLOR_SWATCHES: readonly string[];
28
+ /**
29
+ * Configuration for the color picker.
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * const picker = createColorPicker({
34
+ * container: document.getElementById('toolbar')!,
35
+ * bus: editor.commandBus,
36
+ * engine,
37
+ * swatches: DEFAULT_COLOR_SWATCHES,
38
+ * showCustom: true,
39
+ * });
40
+ * ```
41
+ */
42
+ export interface ColorPickerConfig {
43
+ /** The DOM element to render the picker into. */
44
+ readonly container: HTMLElement;
45
+ /** The command bus for executing color commands. */
46
+ readonly bus: CommandBus;
47
+ /** The engine for querying the current mark value. */
48
+ readonly engine: IEditorEngine;
49
+ /** Color swatches to display (default: {@link DEFAULT_COLOR_SWATCHES}). */
50
+ readonly swatches?: readonly string[];
51
+ /** Number of columns in the swatch grid (default: 10). */
52
+ readonly columns?: number;
53
+ /** Whether to show the custom hex color input (default: true). */
54
+ readonly showCustom?: boolean;
55
+ }
56
+ /**
57
+ * Handle returned by {@link createColorPicker} for lifecycle management.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * const picker = createColorPicker({ container, bus, engine });
62
+ * // ... later:
63
+ * picker.destroy();
64
+ * ```
65
+ */
66
+ export interface ColorPickerHandle {
67
+ /** The picker's root wrapper element. */
68
+ readonly element: HTMLElement;
69
+ /** Remove all event listeners and DOM nodes. Idempotent. */
70
+ destroy(): void;
71
+ }
72
+ /**
73
+ * Create a color picker dropdown backed by a {@link CommandBus}.
74
+ *
75
+ * The picker reflects the current text color by querying the engine's
76
+ * mark state. It subscribes to the bus for live updates.
77
+ *
78
+ * @param config - Picker configuration
79
+ * @returns A handle for lifecycle management
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * const picker = createColorPicker({
84
+ * container: toolbar,
85
+ * bus: editor.commandBus,
86
+ * engine,
87
+ * });
88
+ * ```
89
+ */
90
+ export declare function createColorPicker(config: ColorPickerConfig): ColorPickerHandle;
91
+ //# sourceMappingURL=color-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-picker.d.ts","sourceRoot":"","sources":["../src/color-picker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAanD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,MAAM,EAOnD,CAAC;AAMF;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,oDAAoD;IACpD,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,2EAA2E;IAC3E,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,0DAA0D;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,4DAA4D;IAC5D,OAAO,IAAI,IAAI,CAAC;CACjB;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CA2V9E"}