@openleaf-editor/ui 0.1.0-beta.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.
@@ -0,0 +1,509 @@
1
+ /**
2
+ * The toolbar.
3
+ *
4
+ * A plain class rather than a custom element: the editor is already a custom
5
+ * element, buttons are just DOM, and per-button custom elements would cost
6
+ * bundle size and upgrade-timing complexity for no benefit.
7
+ *
8
+ * ## Keyboard model
9
+ *
10
+ * `role="toolbar"` with a roving tabindex, so the whole bar is ONE tab stop.
11
+ * Without that, Tab from the editable region walks a keyboard user through
12
+ * twenty buttons before they reach their content.
13
+ *
14
+ * Two details that are easy to get wrong and both matter:
15
+ *
16
+ * 1. **Arrow-key roving is applied only to `<button>` elements.** The block-type
17
+ * control is a native `<select>`, and when focus is on it, Left/Right have two
18
+ * competing owners -- the roving handler wants to move to the next item, the
19
+ * select natively wants to change its value. Intercepting those keys breaks
20
+ * the select; not intercepting them breaks the toolbar contract. The
21
+ * resolution is that the select owns all of its own key events and is a
22
+ * genuine second tab stop rather than part of the roving scheme.
23
+ *
24
+ * 2. **Escape returns focus and the selection to the content.** Preventing mouse
25
+ * clicks from stealing focus solves the mouse case and leaves the keyboard
26
+ * case undefined: once a screen reader user deliberately enters the toolbar,
27
+ * focus really is on a button, and without a return path their only way out
28
+ * is blind-Tabbing through the rest of the host's form. `Alt+F10` enters,
29
+ * Escape leaves, matching TinyMCE and CKEditor 5 so muscle memory transfers.
30
+ */
31
+ import { activeHeadingLevel, shortcutFor, toggleHeading, setParagraph } from '@openleaf-editor/core';
32
+ import { ensureSprite, iconElement } from './icons.js';
33
+ import { DEFAULT_LAYOUT, getToolbarItem, onRegistryChange, } from './registry.js';
34
+ import { ensureStyles } from './styles.js';
35
+ const BLOCK_TYPE_ID = 'blockType';
36
+ /** Item+callback pairs already reported, so a per-keystroke failure logs once. */
37
+ const reported = new Set();
38
+ /**
39
+ * Call a third-party predicate, falling back rather than propagating.
40
+ *
41
+ * The fallback for BOTH `isActive` and `isEnabled` is `false`. Defaulting
42
+ * `isEnabled` to true would invite a click straight into the code path that just
43
+ * threw; a control whose enablement cannot be computed should read as
44
+ * unavailable, which is the same reasoning the table plugin already applies to
45
+ * commands that are meaningless outside a table.
46
+ *
47
+ * Logged once per item and callback. A predicate that throws on every
48
+ * transaction would otherwise emit thousands of identical lines and bury the
49
+ * first one, which is the only one with a useful stack.
50
+ */
51
+ function guarded(itemId, kind, run) {
52
+ try {
53
+ return run();
54
+ }
55
+ catch (error) {
56
+ const key = `${itemId}:${kind}`;
57
+ if (!reported.has(key)) {
58
+ reported.add(key);
59
+ console.error(`@openleaf-editor/ui: the ${kind} predicate for toolbar item "${itemId}" threw. ` +
60
+ 'The control is shown as unavailable. This is a bug in whatever registered ' +
61
+ 'it, not in the editor.', error);
62
+ }
63
+ return false;
64
+ }
65
+ }
66
+ export class Toolbar {
67
+ el;
68
+ #doc;
69
+ #host;
70
+ #view = null;
71
+ #controls = new Map();
72
+ #select = null;
73
+ #live;
74
+ #liveTimer;
75
+ #layout;
76
+ #unsubscribe;
77
+ /** Focusable buttons in DOM order; the roving tabindex walks this. */
78
+ #focusables = [];
79
+ #rovingIndex = 0;
80
+ constructor(host, doc, options = {}) {
81
+ this.#host = host;
82
+ this.#doc = doc;
83
+ this.#layout = options.layout ?? DEFAULT_LAYOUT;
84
+ ensureStyles(doc);
85
+ ensureSprite(doc);
86
+ this.el = doc.createElement('div');
87
+ this.el.className = 'ol-toolbar';
88
+ this.el.setAttribute('role', 'toolbar');
89
+ this.el.setAttribute('aria-label', options.label ?? 'Formatting');
90
+ this.#live = doc.createElement('div');
91
+ this.#live.className = 'ol-live';
92
+ // Polite and atomic: an assertive region would interrupt the author
93
+ // mid-word, and a non-atomic one can read partial updates.
94
+ this.#live.setAttribute('role', 'status');
95
+ this.#live.setAttribute('aria-live', 'polite');
96
+ this.#live.setAttribute('aria-atomic', 'true');
97
+ this.el.addEventListener('keydown', this.#onKeydown);
98
+ // Re-render when a plugin registers late. Import-time registration races
99
+ // code-split chunks, and a button that silently never appears is worse than
100
+ // a re-render.
101
+ this.#unsubscribe = onRegistryChange(() => {
102
+ this.#rerenderPreservingState();
103
+ });
104
+ }
105
+ /** Attach to a view and build the controls. */
106
+ mount(view) {
107
+ this.#view = view;
108
+ this.#render();
109
+ this.update(view.state);
110
+ }
111
+ destroy() {
112
+ this.#unsubscribe?.();
113
+ clearTimeout(this.#liveTimer);
114
+ this.el.removeEventListener('keydown', this.#onKeydown);
115
+ this.#controls.clear();
116
+ this.#view = null;
117
+ }
118
+ /** The live region element, which the host mounts once. */
119
+ get liveRegion() {
120
+ return this.#live;
121
+ }
122
+ /* -------------------------------------------------------------- *
123
+ * Rendering
124
+ * -------------------------------------------------------------- */
125
+ #render() {
126
+ this.el.replaceChildren();
127
+ this.#controls.clear();
128
+ this.#select = null;
129
+ let group = this.#newGroup();
130
+ for (const token of this.#layout.split(/\s+/).filter(Boolean)) {
131
+ if (token === '|') {
132
+ if (group.childElementCount > 0)
133
+ this.el.appendChild(group);
134
+ this.el.appendChild(this.#newSeparator());
135
+ group = this.#newGroup();
136
+ continue;
137
+ }
138
+ if (token === BLOCK_TYPE_ID) {
139
+ group.appendChild(this.#buildBlockTypeSelect());
140
+ continue;
141
+ }
142
+ const spec = getToolbarItem(token);
143
+ // Silently skipping an unknown id would hide a typo in an integrator's
144
+ // `toolbar` attribute forever.
145
+ if (!spec) {
146
+ console.warn(`@openleaf-editor/ui: no toolbar item registered for "${token}"`);
147
+ continue;
148
+ }
149
+ // Only `button` is implemented. The `type` discriminant exists so that
150
+ // adding variants later is not a breaking change to a published config
151
+ // shape -- but a declared-and-inert variant is worse than an absent one,
152
+ // because the author sees a plausible button and no signal that the
153
+ // control they asked for was not built.
154
+ if (spec.type && spec.type !== 'button') {
155
+ console.warn(`@openleaf-editor/ui: toolbar item "${spec.id}" declares type "${spec.type}", ` +
156
+ 'which is not implemented yet. It is rendering as a button.');
157
+ }
158
+ group.appendChild(this.#buildButton(spec));
159
+ }
160
+ if (group.childElementCount > 0)
161
+ this.el.appendChild(group);
162
+ this.#refreshFocusables();
163
+ }
164
+ /**
165
+ * Rebuild after a registry change without dropping host-pushed state.
166
+ *
167
+ * Source view's pressed state lives on the control via `setItemState`, not in
168
+ * the document. Replacing every button would flash it off, and would yank
169
+ * focus out of a control the author was on.
170
+ */
171
+ #rerenderPreservingState() {
172
+ const forced = new Map();
173
+ for (const [id, control] of this.#controls) {
174
+ const next = {};
175
+ if (control.forcedActive !== undefined)
176
+ next.active = control.forcedActive;
177
+ if (control.forcedEnabled !== undefined)
178
+ next.enabled = control.forcedEnabled;
179
+ if (next.active !== undefined || next.enabled !== undefined)
180
+ forced.set(id, next);
181
+ }
182
+ const active = this.#doc.activeElement;
183
+ const focusedId = active instanceof HTMLElement && this.el.contains(active)
184
+ ? (active.dataset['olId'] ?? null)
185
+ : null;
186
+ this.#render();
187
+ for (const [id, state] of forced)
188
+ this.setItemState(id, state);
189
+ if (this.#view)
190
+ this.update(this.#view.state);
191
+ if (!focusedId)
192
+ return;
193
+ if (focusedId === BLOCK_TYPE_ID) {
194
+ this.#select?.focus();
195
+ return;
196
+ }
197
+ const control = this.#controls.get(focusedId);
198
+ if (!control)
199
+ return;
200
+ const index = this.#focusables.indexOf(control.el);
201
+ if (index >= 0) {
202
+ this.#rovingIndex = index;
203
+ this.#applyRoving();
204
+ }
205
+ control.el.focus();
206
+ }
207
+ #newGroup() {
208
+ const group = this.#doc.createElement('div');
209
+ group.className = 'ol-group';
210
+ return group;
211
+ }
212
+ #newSeparator() {
213
+ const sep = this.#doc.createElement('div');
214
+ sep.className = 'ol-sep';
215
+ // Decorative. A separator announced as "separator" twenty times is noise.
216
+ sep.setAttribute('aria-hidden', 'true');
217
+ return sep;
218
+ }
219
+ #buildButton(spec) {
220
+ const button = this.#doc.createElement('button');
221
+ button.type = 'button';
222
+ button.className = 'ol-btn';
223
+ button.dataset['olId'] = spec.id;
224
+ // The accessible name stays constant across states. Baking "pressed" into
225
+ // it would double up with what the platform already announces.
226
+ button.setAttribute('aria-label', spec.label);
227
+ const shortcut = spec.shortcut ? shortcutFor(spec.shortcut) : null;
228
+ button.title = shortcut ? `${spec.label} (${shortcut})` : spec.label;
229
+ if ((spec.kind ?? 'action') === 'toggle') {
230
+ button.setAttribute('aria-pressed', 'false');
231
+ }
232
+ if (spec.icon)
233
+ button.appendChild(iconElement(spec.icon, this.#doc));
234
+ // Keep focus and the selection in the content. Without this the editor
235
+ // blurs on mousedown, the selection collapses, and the command applies to
236
+ // nothing.
237
+ button.addEventListener('mousedown', (event) => event.preventDefault());
238
+ button.addEventListener('click', () => this.#invoke(spec));
239
+ this.#controls.set(spec.id, { spec, el: button, active: null, enabled: null });
240
+ return button;
241
+ }
242
+ /**
243
+ * The block-type control.
244
+ *
245
+ * A native `<select>`. A custom listbox would be several hundred lines of
246
+ * ARIA that would then owe real screen reader testing to be worth anything,
247
+ * and the native control is already tested by the browser vendors. It carries
248
+ * its own accessible name because the toolbar's own label does not describe it.
249
+ */
250
+ #buildBlockTypeSelect() {
251
+ const select = this.#doc.createElement('select');
252
+ select.className = 'ol-select';
253
+ select.setAttribute('aria-label', 'Paragraph style');
254
+ select.dataset['olId'] = BLOCK_TYPE_ID;
255
+ const options = [
256
+ ['p', 'Paragraph'],
257
+ ['1', 'Heading 1'],
258
+ ['2', 'Heading 2'],
259
+ ['3', 'Heading 3'],
260
+ ['4', 'Heading 4'],
261
+ ['5', 'Heading 5'],
262
+ ['6', 'Heading 6'],
263
+ ];
264
+ for (const [value, label] of options) {
265
+ const option = this.#doc.createElement('option');
266
+ option.value = value;
267
+ option.textContent = label;
268
+ select.appendChild(option);
269
+ }
270
+ select.addEventListener('mousedown', (event) => event.stopPropagation());
271
+ /**
272
+ * Whether the pending change came from a pointer rather than the keyboard.
273
+ *
274
+ * This distinction is load-bearing. In Firefox, and on macOS generally,
275
+ * arrow keys on a closed `<select>` change its value on every press. If the
276
+ * change handler returned focus to the content unconditionally, a keyboard
277
+ * user arrowing through the options would be thrown back into the document
278
+ * on the first press -- making the control unusable by keyboard while
279
+ * working perfectly with a mouse. Caught by a cross-browser test that
280
+ * passed in Chromium and failed in Firefox.
281
+ */
282
+ let pointerDriven = false;
283
+ select.addEventListener('pointerdown', () => {
284
+ pointerDriven = true;
285
+ });
286
+ select.addEventListener('keydown', (event) => {
287
+ pointerDriven = false;
288
+ if (event.key === 'Enter') {
289
+ // A <select> inside a <form> submits it on Enter. The editor almost
290
+ // always sits inside the host's form, so this would post a half-written
291
+ // article.
292
+ event.preventDefault();
293
+ this.returnFocusToContent();
294
+ }
295
+ });
296
+ select.addEventListener('change', () => {
297
+ const view = this.#view;
298
+ if (!view)
299
+ return;
300
+ const value = select.value;
301
+ const command = value === 'p' ? setParagraph : toggleHeading(Number(value));
302
+ command(view.state, view.dispatch, view);
303
+ // Return the caret to the content only when the author committed the
304
+ // choice by pointer. Keyboard users keep focus and leave with Tab or
305
+ // Escape.
306
+ if (pointerDriven) {
307
+ pointerDriven = false;
308
+ view.focus();
309
+ }
310
+ });
311
+ this.#select = select;
312
+ return select;
313
+ }
314
+ /* -------------------------------------------------------------- *
315
+ * Invocation
316
+ * -------------------------------------------------------------- */
317
+ #invoke(spec) {
318
+ const view = this.#view;
319
+ if (!view)
320
+ return;
321
+ if (this.#host.hasAttribute('readonly'))
322
+ return;
323
+ const control = this.#controls.get(spec.id);
324
+ if (control && control.enabled === false)
325
+ return;
326
+ try {
327
+ if (spec.run) {
328
+ spec.run({ view, host: this.#host });
329
+ return;
330
+ }
331
+ if (spec.command) {
332
+ spec.command(view.state, view.dispatch, view);
333
+ view.focus();
334
+ }
335
+ }
336
+ catch (error) {
337
+ console.error(`@openleaf-editor/ui: toolbar item "${spec.id}" threw when activated. ` +
338
+ 'The editor is unaffected.', error);
339
+ }
340
+ }
341
+ /* -------------------------------------------------------------- *
342
+ * State synchronisation
343
+ * -------------------------------------------------------------- */
344
+ /**
345
+ * Reflect the editor state onto the controls.
346
+ *
347
+ * Deliberately synchronous, not batched into an animation frame. Twenty cheap
348
+ * predicates plus a diffed attribute write is sub-millisecond work, and
349
+ * batching would trade a perceptible frame of lag between pressing Bold and
350
+ * the button lighting up for a performance problem that does not exist.
351
+ *
352
+ * `tr` is passed so announcements can be gated on a real formatting change.
353
+ */
354
+ update(state, tr) {
355
+ // Announce only on a discrete formatting transition, never on cursor
356
+ // movement through already-formatted text. That gate is the whole
357
+ // difference between a useful announcement and a chatty one.
358
+ const isFormattingChange = !!tr && (tr.docChanged || tr.storedMarksSet);
359
+ const transitions = [];
360
+ for (const control of this.#controls.values()) {
361
+ const { spec } = control;
362
+ const readonly = this.#host.hasAttribute('readonly');
363
+ const enabled = readonly
364
+ ? false
365
+ : control.forcedEnabled ??
366
+ guarded(spec.id, 'isEnabled', () => spec.isEnabled ? spec.isEnabled(state) : spec.command ? spec.command(state) : true);
367
+ if (enabled !== control.enabled) {
368
+ control.enabled = enabled;
369
+ // aria-disabled, never the disabled attribute: a disabled button is
370
+ // removed from the roving tabindex and cannot be reached or announced,
371
+ // so an author using a screen reader cannot discover it exists.
372
+ control.el.setAttribute('aria-disabled', enabled ? 'false' : 'true');
373
+ }
374
+ if ((spec.kind ?? 'action') === 'toggle') {
375
+ const active = control.forcedActive ??
376
+ guarded(spec.id, 'isActive', () => (spec.isActive ? spec.isActive(state) : false));
377
+ if (active !== control.active) {
378
+ const previous = control.active;
379
+ control.active = active;
380
+ control.el.setAttribute('aria-pressed', active ? 'true' : 'false');
381
+ if (isFormattingChange && previous !== null) {
382
+ transitions.push(`${spec.label} ${active ? 'on' : 'off'}`);
383
+ }
384
+ }
385
+ }
386
+ }
387
+ if (this.#select) {
388
+ const level = activeHeadingLevel(state);
389
+ const value = level === null ? 'p' : String(level);
390
+ if (this.#select.value !== value)
391
+ this.#select.value = value;
392
+ }
393
+ if (transitions.length > 0)
394
+ this.#announce(transitions.join(', '));
395
+ }
396
+ /**
397
+ * Push a state a predicate cannot derive.
398
+ *
399
+ * `isActive`/`isEnabled` assume everything follows from the document and
400
+ * selection. Real plugin state does not: "upload in progress", "collab lock
401
+ * held by another user", "rewrite running" all live outside the document, and
402
+ * a pull-on-transaction model cannot see them.
403
+ */
404
+ setItemState(id, state) {
405
+ const control = this.#controls.get(id);
406
+ if (!control)
407
+ return;
408
+ if (state.active !== undefined) {
409
+ control.forcedActive = state.active;
410
+ control.active = null;
411
+ }
412
+ if (state.enabled !== undefined) {
413
+ control.forcedEnabled = state.enabled;
414
+ control.enabled = null;
415
+ }
416
+ if (this.#view)
417
+ this.update(this.#view.state);
418
+ }
419
+ #announce(message) {
420
+ // Clear then set on a timer: replacing identical text does not re-announce,
421
+ // and the delay coalesces a held shortcut into one utterance.
422
+ this.#live.textContent = '';
423
+ clearTimeout(this.#liveTimer);
424
+ this.#liveTimer = setTimeout(() => {
425
+ this.#live.textContent = message;
426
+ }, 60);
427
+ }
428
+ /* -------------------------------------------------------------- *
429
+ * Roving tabindex
430
+ * -------------------------------------------------------------- */
431
+ #refreshFocusables() {
432
+ this.#focusables = [...this.el.querySelectorAll('button.ol-btn')];
433
+ this.#rovingIndex = 0;
434
+ this.#applyRoving();
435
+ }
436
+ #applyRoving() {
437
+ this.#focusables.forEach((button, index) => {
438
+ button.tabIndex = index === this.#rovingIndex ? 0 : -1;
439
+ });
440
+ }
441
+ #moveRoving(delta) {
442
+ if (this.#focusables.length === 0)
443
+ return;
444
+ const count = this.#focusables.length;
445
+ this.#rovingIndex = (this.#rovingIndex + delta + count) % count;
446
+ this.#applyRoving();
447
+ this.#focusables[this.#rovingIndex]?.focus();
448
+ }
449
+ #setRoving(index) {
450
+ if (this.#focusables.length === 0)
451
+ return;
452
+ this.#rovingIndex = Math.max(0, Math.min(index, this.#focusables.length - 1));
453
+ this.#applyRoving();
454
+ this.#focusables[this.#rovingIndex]?.focus();
455
+ }
456
+ #onKeydown = (event) => {
457
+ // Escape works from anywhere in the toolbar, including from the select.
458
+ if (event.key === 'Escape') {
459
+ event.preventDefault();
460
+ this.returnFocusToContent();
461
+ return;
462
+ }
463
+ const target = event.target;
464
+ // Arrow roving applies ONLY to buttons. The native <select> owns its own
465
+ // key handling; hijacking Left/Right there would break value changing.
466
+ if (!target || target.tagName !== 'BUTTON')
467
+ return;
468
+ const index = this.#focusables.indexOf(target);
469
+ if (index >= 0)
470
+ this.#rovingIndex = index;
471
+ switch (event.key) {
472
+ case 'ArrowRight':
473
+ event.preventDefault();
474
+ this.#moveRoving(1);
475
+ break;
476
+ case 'ArrowLeft':
477
+ event.preventDefault();
478
+ this.#moveRoving(-1);
479
+ break;
480
+ case 'Home':
481
+ event.preventDefault();
482
+ this.#setRoving(0);
483
+ break;
484
+ case 'End':
485
+ event.preventDefault();
486
+ this.#setRoving(this.#focusables.length - 1);
487
+ break;
488
+ default:
489
+ break;
490
+ }
491
+ };
492
+ /** Move focus into the toolbar. Bound to Alt+F10 by the host. */
493
+ focusToolbar() {
494
+ if (this.#focusables.length > 0) {
495
+ this.#applyRoving();
496
+ this.#focusables[this.#rovingIndex]?.focus();
497
+ return;
498
+ }
499
+ // A toolbar that is only the block-type select has no roving buttons.
500
+ // The shortcut is still documented; swallowing it with nowhere to go
501
+ // would make a valid `toolbar` attribute a silent no-op.
502
+ this.#select?.focus();
503
+ }
504
+ /** Return focus and the prior selection to the editable region. */
505
+ returnFocusToContent() {
506
+ this.#view?.focus();
507
+ }
508
+ }
509
+ //# sourceMappingURL=toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../src/toolbar.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@openleaf-editor/ui",
3
+ "version": "0.1.0-beta.0",
4
+ "description": "OpenLeaf toolbar and UI primitives. Plain CSS, no framework, themeable by custom properties.",
5
+ "license": "Apache-2.0",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/PeytonNowlin/openleaf.git",
12
+ "directory": "packages/ui"
13
+ },
14
+ "homepage": "https://peytonnowlin.github.io/openleaf/",
15
+ "bugs": {
16
+ "url": "https://github.com/PeytonNowlin/openleaf/issues"
17
+ },
18
+ "type": "module",
19
+ "main": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "import": "./dist/index.js"
25
+ },
26
+ "./openleaf.css": "./dist/openleaf.css"
27
+ },
28
+ "files": [
29
+ "dist"
30
+ ],
31
+ "dependencies": {
32
+ "prosemirror-state": "^1.4.3",
33
+ "prosemirror-view": "^1.37.0",
34
+ "@openleaf-editor/core": "0.1.0-beta.0"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.json && node scripts/emit-css.mjs"
38
+ }
39
+ }