@openleaf-editor/ui 0.1.0-beta.1 → 0.1.0-beta.3

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 (82) hide show
  1. package/README.md +85 -0
  2. package/dist/block-type.d.ts +5 -0
  3. package/dist/block-type.d.ts.map +1 -0
  4. package/dist/block-type.js +133 -0
  5. package/dist/block-type.js.map +1 -0
  6. package/dist/content-css.d.ts +31 -0
  7. package/dist/content-css.d.ts.map +1 -0
  8. package/dist/content-css.js +272 -0
  9. package/dist/content-css.js.map +1 -0
  10. package/dist/css.d.ts +23 -0
  11. package/dist/css.d.ts.map +1 -0
  12. package/dist/css.js +813 -0
  13. package/dist/css.js.map +1 -0
  14. package/dist/dialog.d.ts +158 -18
  15. package/dist/dialog.d.ts.map +1 -1
  16. package/dist/dialog.js +605 -130
  17. package/dist/dialog.js.map +1 -1
  18. package/dist/floating.d.ts +29 -0
  19. package/dist/floating.d.ts.map +1 -0
  20. package/dist/floating.js +130 -0
  21. package/dist/floating.js.map +1 -0
  22. package/dist/help.d.ts +9 -0
  23. package/dist/help.d.ts.map +1 -0
  24. package/dist/help.js +97 -0
  25. package/dist/help.js.map +1 -0
  26. package/dist/i18n.d.ts +39 -0
  27. package/dist/i18n.d.ts.map +1 -0
  28. package/dist/i18n.js +114 -0
  29. package/dist/i18n.js.map +1 -0
  30. package/dist/icons.d.ts +7 -1
  31. package/dist/icons.d.ts.map +1 -1
  32. package/dist/icons.js +10 -2
  33. package/dist/icons.js.map +1 -1
  34. package/dist/index.d.ts +15 -7
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +14 -6
  37. package/dist/index.js.map +1 -1
  38. package/dist/items.d.ts +2 -1
  39. package/dist/items.d.ts.map +1 -1
  40. package/dist/items.js +263 -17
  41. package/dist/items.js.map +1 -1
  42. package/dist/live.d.ts +42 -0
  43. package/dist/live.d.ts.map +1 -0
  44. package/dist/live.js +83 -0
  45. package/dist/live.js.map +1 -0
  46. package/dist/menu.d.ts +85 -0
  47. package/dist/menu.d.ts.map +1 -0
  48. package/dist/menu.js +500 -0
  49. package/dist/menu.js.map +1 -0
  50. package/dist/openleaf.css +325 -7
  51. package/dist/overflow.d.ts +44 -0
  52. package/dist/overflow.d.ts.map +1 -0
  53. package/dist/overflow.js +323 -0
  54. package/dist/overflow.js.map +1 -0
  55. package/dist/pickers.d.ts +43 -0
  56. package/dist/pickers.d.ts.map +1 -0
  57. package/dist/pickers.js +52 -0
  58. package/dist/pickers.js.map +1 -0
  59. package/dist/registry.d.ts +72 -18
  60. package/dist/registry.d.ts.map +1 -1
  61. package/dist/registry.js +7 -6
  62. package/dist/registry.js.map +1 -1
  63. package/dist/skins.d.ts.map +1 -1
  64. package/dist/skins.js +48 -14
  65. package/dist/skins.js.map +1 -1
  66. package/dist/styles.d.ts +61 -1
  67. package/dist/styles.d.ts.map +1 -1
  68. package/dist/styles.js +77 -421
  69. package/dist/styles.js.map +1 -1
  70. package/dist/testing.d.ts +3 -0
  71. package/dist/testing.d.ts.map +1 -0
  72. package/dist/testing.js +3 -0
  73. package/dist/testing.js.map +1 -0
  74. package/dist/toolbar.d.ts +91 -12
  75. package/dist/toolbar.d.ts.map +1 -1
  76. package/dist/toolbar.js +459 -127
  77. package/dist/toolbar.js.map +1 -1
  78. package/dist/upload.d.ts +11 -0
  79. package/dist/upload.d.ts.map +1 -1
  80. package/dist/upload.js +15 -1
  81. package/dist/upload.js.map +1 -1
  82. package/package.json +17 -3
@@ -0,0 +1,323 @@
1
+ /**
2
+ * Collapse overflowing toolbar groups into a "More" panel.
3
+ *
4
+ * Wrapping is the default for a reason: a control that moved behind a click is
5
+ * a control the author does not have. Overflow is therefore opt-in. When it is
6
+ * on, groups that do not fit the current width are moved out of the bar and
7
+ * offered in a panel at the end, so a narrow CMS sidebar still has every item
8
+ * without a two-row bar.
9
+ *
10
+ * ## Why the real controls move rather than being cloned
11
+ *
12
+ * The first implementation cloned each control into a `role="menu"`. Cloning a
13
+ * live control produces a listener-free copy that has to forward every
14
+ * interaction back to an original it can only find by id, duplicates that id
15
+ * and the accessible name, and goes stale the moment the caret moves -- three
16
+ * bugs that only exist because there were two of everything. Moving the group
17
+ * node itself has none of them: the control in the panel IS the control, so it
18
+ * carries its own listeners, its own state and its own accessible name, and
19
+ * nothing can drift.
20
+ *
21
+ * ## The keyboard pattern
22
+ *
23
+ * The panel is a vertical `role="toolbar"`, not a `role="menu"`: a menu owns a
24
+ * content model of `menuitem` children, and a `<select>` is not one -- the
25
+ * default bar has four. So the panel is the same widget as the bar it came
26
+ * from, turned ninety degrees, and it keeps the same contract: one tab stop,
27
+ * arrow keys to move, Home/End to the ends, Escape back to the trigger. Tab
28
+ * closes, because a panel a keyboard user can walk out of and leave open is the
29
+ * failure mode of every hand-rolled popup.
30
+ *
31
+ * Up/Down are taken from a `<select>` inside the panel the same way Left/Right
32
+ * are taken from one in the bar; Alt+Down still opens its list, and typeahead
33
+ * still selects. Home/End are left to the select, which uses them for its own
34
+ * first and last option.
35
+ */
36
+ import { t } from './i18n.js';
37
+ import { iconElement } from './icons.js';
38
+ /** Focusable controls, matching what the toolbar's own roving walks. */
39
+ const FOCUSABLE = 'button.ol-btn, select.ol-select';
40
+ let panelCounter = 0;
41
+ export class ToolbarOverflow {
42
+ #toolbar;
43
+ #host;
44
+ #doc;
45
+ #more;
46
+ #panel;
47
+ #observer = null;
48
+ #onLayout;
49
+ /**
50
+ * A pending coalesced layout.
51
+ *
52
+ * A ResizeObserver fires once per observed element, so a ten-group bar paid
53
+ * for ten layouts in one frame. One rAF collapses them, and the frame is
54
+ * cancelled on destroy so a queued layout cannot run against a torn-down bar.
55
+ */
56
+ #frame = null;
57
+ constructor(toolbar, host, doc, onLayout) {
58
+ this.#toolbar = toolbar;
59
+ this.#host = host;
60
+ this.#doc = doc;
61
+ this.#onLayout = onLayout;
62
+ toolbar.classList.add('ol-toolbar--overflow');
63
+ this.#panel = doc.createElement('div');
64
+ this.#panel.className = 'ol-menu ol-overflow-menu';
65
+ this.#panel.id = `ol-overflow-${(panelCounter += 1)}`;
66
+ this.#panel.setAttribute('role', 'toolbar');
67
+ this.#panel.setAttribute('aria-orientation', 'vertical');
68
+ this.#panel.setAttribute('aria-label', t('More formatting'));
69
+ this.#panel.hidden = true;
70
+ this.#panel.addEventListener('keydown', this.#onKeydown);
71
+ this.#more = doc.createElement('button');
72
+ this.#more.type = 'button';
73
+ this.#more.className = 'ol-btn ol-overflow-more';
74
+ this.#more.setAttribute('aria-label', t('More'));
75
+ // Not `aria-haspopup`: none of its values describes a toolbar, and "true"
76
+ // means menu, which is what this deliberately is not. Expanded plus a
77
+ // pointer at the panel is the honest relationship.
78
+ this.#more.setAttribute('aria-expanded', 'false');
79
+ this.#more.setAttribute('aria-controls', this.#panel.id);
80
+ this.#more.hidden = true;
81
+ this.#more.appendChild(iconElement('more', doc));
82
+ this.#more.addEventListener('mousedown', (event) => event.preventDefault());
83
+ this.#more.addEventListener('click', () => {
84
+ if (this.#panel.hidden)
85
+ this.#open();
86
+ else
87
+ this.#close(true);
88
+ });
89
+ // Immediately after the bar, never at the end of the editor: appended to the
90
+ // host it landed after the editable region, so Tab from More walked into the
91
+ // content and the panel could only be reached by going backwards.
92
+ if (toolbar.parentNode)
93
+ toolbar.after(this.#panel);
94
+ else
95
+ host.appendChild(this.#panel);
96
+ toolbar.appendChild(this.#more);
97
+ if (typeof ResizeObserver !== 'undefined') {
98
+ this.#observer = new ResizeObserver(() => this.#schedule());
99
+ this.#observer.observe(toolbar);
100
+ }
101
+ this.layout();
102
+ }
103
+ /** Re-home the trigger after the toolbar rebuilt its children. */
104
+ reattach() {
105
+ // The groups in the panel belong to the render that was just thrown away.
106
+ // Restoring them would put two of every control in the bar.
107
+ this.#panel.replaceChildren();
108
+ if (!this.#more.isConnected)
109
+ this.#toolbar.appendChild(this.#more);
110
+ this.layout();
111
+ }
112
+ /**
113
+ * Coalesce resize notifications into one layout per frame.
114
+ *
115
+ * The observer watches the very element `layout` resizes, so an unthrottled
116
+ * callback fed itself: hiding a group changes the bar's size, which notifies
117
+ * the observer, which lays out again. A frame is the right budget for work
118
+ * whose only purpose is deciding what the next paint shows.
119
+ */
120
+ #schedule() {
121
+ if (this.#frame !== null)
122
+ return;
123
+ const win = this.#toolbar.ownerDocument.defaultView;
124
+ if (!win?.requestAnimationFrame) {
125
+ this.layout();
126
+ return;
127
+ }
128
+ this.#frame = win.requestAnimationFrame(() => {
129
+ this.#frame = null;
130
+ this.layout();
131
+ });
132
+ }
133
+ destroy() {
134
+ // A queued frame outlives destroy() and would lay out a torn-down bar.
135
+ if (this.#frame !== null) {
136
+ this.#toolbar.ownerDocument.defaultView?.cancelAnimationFrame(this.#frame);
137
+ this.#frame = null;
138
+ }
139
+ this.#observer?.disconnect();
140
+ this.#close();
141
+ this.#restore();
142
+ this.#more.remove();
143
+ this.#panel.remove();
144
+ this.#toolbar.classList.remove('ol-toolbar--overflow');
145
+ }
146
+ layout() {
147
+ this.#restore();
148
+ // Revealed BEFORE the reads, not after the compute. The trigger takes a
149
+ // width and a gap in the row the moment it is shown, and it cannot be
150
+ // measured while hidden -- `display: none` reports 0. Showing it here means
151
+ // its footprint is inside the same `scrollWidth` as everything else, so the
152
+ // arithmetic needs no second measurement and no second layout pass.
153
+ //
154
+ // Measured every time rather than cached: the width follows
155
+ // `--openleaf-button-size`, which a skin or an integrator token changes at
156
+ // runtime (compact is 28px, the default 32px, coarse-pointer 40px), so a
157
+ // value pinned at first layout goes quietly wrong on the next density
158
+ // change.
159
+ this.#more.hidden = false;
160
+ this.#close();
161
+ // READ. Every measurement is taken here, while the bar is fully expanded,
162
+ // because a width read after a style write forces the browser to lay the
163
+ // whole bar out again. The old loop alternated the two once per group, so a
164
+ // ten-group bar paid for ten layouts -- from a ResizeObserver watching the
165
+ // element it was resizing.
166
+ const budget = this.#toolbar.clientWidth;
167
+ const groups = this.#groups();
168
+ const total = this.#toolbar.scrollWidth;
169
+ const widths = groups.map((group) => group.offsetWidth);
170
+ const moreWidth = this.#more.offsetWidth;
171
+ const gap = Number.parseFloat(this.#toolbar.ownerDocument.defaultView?.getComputedStyle(this.#toolbar).columnGap ?? '') || 0;
172
+ if (budget === 0) {
173
+ this.#more.hidden = true;
174
+ return;
175
+ }
176
+ // COMPUTE. In overflow mode the bar is a nowrap flex row with one uniform
177
+ // gap, so moving the last k groups out takes exactly their widths and k
178
+ // gaps off the scroll width. Nothing has to be re-measured between them.
179
+ //
180
+ // The trigger's footprint has to come back OUT to answer "does this bar
181
+ // overflow at all", because a bar that fits never shows one -- and charging
182
+ // it for a button it will not show would collapse a group for nothing.
183
+ const trigger = moreWidth > 0 ? moreWidth + gap : 0;
184
+ if (total - trigger <= budget + 1) {
185
+ this.#more.hidden = true;
186
+ return;
187
+ }
188
+ // Past here the trigger stays, so `total` -- which already includes it -- is
189
+ // the right starting point. Leaving it out is what let a bar stay
190
+ // overflowing by roughly the width of the More button: the groups fit, then
191
+ // revealing the trigger pushed the row back over its budget, and it
192
+ // converged only on the next ResizeObserver pass, with a visible flash in
193
+ // between.
194
+ let used = total;
195
+ let count = 0;
196
+ while (used > budget + 1 && count < groups.length) {
197
+ used -= (widths[groups.length - 1 - count] ?? 0) + gap;
198
+ count += 1;
199
+ }
200
+ if (count === 0) {
201
+ this.#more.hidden = true;
202
+ return;
203
+ }
204
+ // WRITE. Backwards, inserted at the front, so the panel keeps the bar's
205
+ // order. The controls themselves move -- they are not cloned -- which is
206
+ // what makes the panel operable rather than a picture of the bar.
207
+ for (let i = groups.length - 1; i >= groups.length - count; i -= 1) {
208
+ const group = groups[i];
209
+ if (group)
210
+ this.#panel.insertBefore(group, this.#panel.firstChild);
211
+ }
212
+ // The trigger is already visible -- revealed before the reads, above. And
213
+ // there are no separator elements to hide: the divider is a border on the
214
+ // group, so a group that moved into the panel takes its own rule with it
215
+ // and cannot leave one stranded at the end of the bar.
216
+ this.#onLayout?.();
217
+ void this.#host;
218
+ }
219
+ /* -------------------------------------------------------------- *
220
+ * Open, close, and the keyboard
221
+ * -------------------------------------------------------------- */
222
+ #open() {
223
+ this.#panel.hidden = false;
224
+ this.#more.setAttribute('aria-expanded', 'true');
225
+ this.#position();
226
+ this.#doc.addEventListener('pointerdown', this.#onPointerDown, true);
227
+ this.#doc.defaultView?.addEventListener('scroll', this.#onViewportChange, true);
228
+ this.#doc.defaultView?.addEventListener('resize', this.#onViewportChange);
229
+ this.#focus(0);
230
+ }
231
+ #close(returnFocus = false) {
232
+ if (this.#panel.hidden)
233
+ return;
234
+ this.#panel.hidden = true;
235
+ this.#more.setAttribute('aria-expanded', 'false');
236
+ this.#doc.removeEventListener('pointerdown', this.#onPointerDown, true);
237
+ this.#doc.defaultView?.removeEventListener('scroll', this.#onViewportChange, true);
238
+ this.#doc.defaultView?.removeEventListener('resize', this.#onViewportChange);
239
+ if (returnFocus)
240
+ this.#more.focus();
241
+ }
242
+ /**
243
+ * Under the trigger, in viewport coordinates and clamped to it.
244
+ *
245
+ * Fixed rather than absolute because the bar may sit inside a host with
246
+ * `overflow: hidden`, which is the case the whole feature exists for.
247
+ */
248
+ #position() {
249
+ const rect = this.#more.getBoundingClientRect();
250
+ const box = this.#panel.getBoundingClientRect();
251
+ const view = this.#doc.defaultView;
252
+ const width = view?.innerWidth ?? 0;
253
+ const height = view?.innerHeight ?? 0;
254
+ const below = rect.bottom + 4;
255
+ const top = below + box.height > height ? Math.max(4, rect.top - box.height - 4) : below;
256
+ this.#panel.style.position = 'fixed';
257
+ this.#panel.style.left = `${Math.round(Math.max(4, Math.min(rect.left, width - box.width - 4)))}px`;
258
+ this.#panel.style.top = `${Math.round(top)}px`;
259
+ }
260
+ #focusables() {
261
+ return [...this.#panel.querySelectorAll(FOCUSABLE)];
262
+ }
263
+ #focus(index) {
264
+ const items = this.#focusables();
265
+ if (items.length === 0)
266
+ return;
267
+ const next = items[(index + items.length) % items.length];
268
+ for (const item of items)
269
+ item.tabIndex = item === next ? 0 : -1;
270
+ next?.focus();
271
+ }
272
+ #onKeydown = (event) => {
273
+ const target = event.target;
274
+ if (event.key === 'Escape' || event.key === 'Tab') {
275
+ event.preventDefault();
276
+ this.#close(true);
277
+ return;
278
+ }
279
+ const items = this.#focusables();
280
+ const index = items.indexOf(target);
281
+ if (index < 0)
282
+ return;
283
+ if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {
284
+ // Alt+Down is how a keyboard user opens a native select's list.
285
+ if (event.altKey)
286
+ return;
287
+ event.preventDefault();
288
+ this.#focus(index + (event.key === 'ArrowDown' ? 1 : -1));
289
+ return;
290
+ }
291
+ if (event.key === 'Home' || event.key === 'End') {
292
+ // Left to the select, which uses them for its own first and last option.
293
+ if (target?.tagName === 'SELECT')
294
+ return;
295
+ event.preventDefault();
296
+ this.#focus(event.key === 'Home' ? 0 : items.length - 1);
297
+ }
298
+ };
299
+ #onPointerDown = (event) => {
300
+ const target = event.target;
301
+ if (!(target instanceof Node))
302
+ return;
303
+ if (this.#panel.contains(target) || this.#more.contains(target))
304
+ return;
305
+ this.#close();
306
+ };
307
+ #onViewportChange = () => this.#close();
308
+ /* -------------------------------------------------------------- *
309
+ * Moving groups back and forth
310
+ * -------------------------------------------------------------- */
311
+ #restore() {
312
+ for (const group of [...this.#panel.children])
313
+ this.#toolbar.appendChild(group);
314
+ // Overflow always takes a suffix of the groups, so appending in panel order
315
+ // puts them back where they were. The trigger stays last.
316
+ if (this.#more.isConnected)
317
+ this.#toolbar.appendChild(this.#more);
318
+ }
319
+ #groups() {
320
+ return [...this.#toolbar.querySelectorAll(':scope > .ol-group')];
321
+ }
322
+ }
323
+ //# sourceMappingURL=overflow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overflow.js","sourceRoot":"","sources":["../src/overflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Shared pickers: file, image and media, plus optional link and image lists.
3
+ *
4
+ * OpenLeaf has no media library. What it can own is the seam a CMS already has
5
+ * -- "open our file browser and give me a URL" -- so the link dialog, the
6
+ * image dialog and the media dialog all call the same function. Registering
7
+ * three uploaders that each talk to the same endpoint is how this used to go
8
+ * wrong in every other editor.
9
+ *
10
+ * Lists are separate: they are the short, known set of destinations a site
11
+ * wants to offer (the privacy policy, a hero image), not a replacement for
12
+ * the library.
13
+ */
14
+ export type FilePickerKind = 'file' | 'image' | 'media';
15
+ export interface PickedResource {
16
+ url: string;
17
+ title?: string;
18
+ text?: string;
19
+ alt?: string;
20
+ }
21
+ export type FilePicker = (meta: {
22
+ kind: FilePickerKind;
23
+ host: HTMLElement;
24
+ }) => Promise<PickedResource | null>;
25
+ export interface ListedResource {
26
+ /** Shown in the list. */
27
+ title: string;
28
+ /** The URL inserted. */
29
+ value: string;
30
+ }
31
+ type ListSource = readonly ListedResource[] | (() => readonly ListedResource[]);
32
+ /** Register the shared file picker for every editor on the page. `null` removes it. */
33
+ export declare function registerFilePicker(picker: FilePicker | null): void;
34
+ export declare function filePickerFor(host: HTMLElement | null | undefined): FilePicker | null;
35
+ export declare function registerLinkList(list: ListSource | null): void;
36
+ export declare function registerImageList(list: ListSource | null): void;
37
+ /** Class names offered in the image dialog. Authors can still type others. */
38
+ export declare function registerImageClasses(list: readonly string[] | (() => readonly string[]) | null): void;
39
+ export declare function listedLinks(): ListedResource[];
40
+ export declare function listedImages(): ListedResource[];
41
+ export declare function listedImageClasses(): string[];
42
+ export {};
43
+ //# sourceMappingURL=pickers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pickers.d.ts","sourceRoot":"","sources":["../src/pickers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAEvD,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE;IAC9B,IAAI,EAAE,cAAc,CAAA;IACpB,IAAI,EAAE,WAAW,CAAA;CAClB,KAAK,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAA;AAEpC,MAAM,WAAW,cAAc;IAC7B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAA;CACd;AAED,KAAK,UAAU,GAAG,SAAS,cAAc,EAAE,GAAG,CAAC,MAAM,SAAS,cAAc,EAAE,CAAC,CAAA;AAW/E,uFAAuF;AACvF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAElE;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,CAGrF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE9D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAE/D;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,CAAC,MAAM,SAAS,MAAM,EAAE,CAAC,GAAG,IAAI,GACzD,IAAI,CAEN;AAOD,wBAAgB,WAAW,IAAI,cAAc,EAAE,CAE9C;AAED,wBAAgB,YAAY,IAAI,cAAc,EAAE,CAE/C;AAED,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAG7C"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Shared pickers: file, image and media, plus optional link and image lists.
3
+ *
4
+ * OpenLeaf has no media library. What it can own is the seam a CMS already has
5
+ * -- "open our file browser and give me a URL" -- so the link dialog, the
6
+ * image dialog and the media dialog all call the same function. Registering
7
+ * three uploaders that each talk to the same endpoint is how this used to go
8
+ * wrong in every other editor.
9
+ *
10
+ * Lists are separate: they are the short, known set of destinations a site
11
+ * wants to offer (the privacy policy, a hero image), not a replacement for
12
+ * the library.
13
+ */
14
+ let globalPicker = null;
15
+ let linkList = null;
16
+ let imageList = null;
17
+ let imageClasses = null;
18
+ /** Register the shared file picker for every editor on the page. `null` removes it. */
19
+ export function registerFilePicker(picker) {
20
+ globalPicker = picker;
21
+ }
22
+ export function filePickerFor(host) {
23
+ const own = host?.filePicker;
24
+ return own ?? globalPicker;
25
+ }
26
+ export function registerLinkList(list) {
27
+ linkList = list;
28
+ }
29
+ export function registerImageList(list) {
30
+ imageList = list;
31
+ }
32
+ /** Class names offered in the image dialog. Authors can still type others. */
33
+ export function registerImageClasses(list) {
34
+ imageClasses = list;
35
+ }
36
+ function resolveList(source) {
37
+ if (!source)
38
+ return [];
39
+ return [...(typeof source === 'function' ? source() : source)];
40
+ }
41
+ export function listedLinks() {
42
+ return resolveList(linkList);
43
+ }
44
+ export function listedImages() {
45
+ return resolveList(imageList);
46
+ }
47
+ export function listedImageClasses() {
48
+ if (!imageClasses)
49
+ return [];
50
+ return [...(typeof imageClasses === 'function' ? imageClasses() : imageClasses)];
51
+ }
52
+ //# sourceMappingURL=pickers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pickers.js","sourceRoot":"","sources":["../src/pickers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAyBH,IAAI,YAAY,GAAsB,IAAI,CAAA;AAC1C,IAAI,QAAQ,GAAsB,IAAI,CAAA;AACtC,IAAI,SAAS,GAAsB,IAAI,CAAA;AACvC,IAAI,YAAY,GAAyD,IAAI,CAAA;AAM7E,uFAAuF;AACvF,MAAM,UAAU,kBAAkB,CAAC,MAAyB;IAC1D,YAAY,GAAG,MAAM,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAoC;IAChE,MAAM,GAAG,GAAI,IAA0C,EAAE,UAAU,CAAA;IACnE,OAAO,GAAG,IAAI,YAAY,CAAA;AAC5B,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAuB;IACtD,QAAQ,GAAG,IAAI,CAAA;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAuB;IACvD,SAAS,GAAG,IAAI,CAAA;AAClB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,oBAAoB,CAClC,IAA0D;IAE1D,YAAY,GAAG,IAAI,CAAA;AACrB,CAAC;AAED,SAAS,WAAW,CAAC,MAAyB;IAC5C,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAA;IACtB,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAA;AAChE,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAA;AAC9B,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,WAAW,CAAC,SAAS,CAAC,CAAA;AAC/B,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC,YAAY;QAAE,OAAO,EAAE,CAAA;IAC5B,OAAO,CAAC,GAAG,CAAC,OAAO,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAA;AAClF,CAAC"}
@@ -19,27 +19,42 @@
19
19
  import type { Command, EditorState } from 'prosemirror-state';
20
20
  import type { EditorView } from 'prosemirror-view';
21
21
  import type { IconName } from './icons.js';
22
+ import type { FormatSpec } from '@openleaf-editor/core';
22
23
  /** What a custom `run` handler receives. */
23
24
  export interface ToolbarContext {
24
25
  view: EditorView;
26
+ /**
27
+ * The id this item was registered under.
28
+ *
29
+ * A custom control must put it in `data-ol-id`, which is what the toolbar
30
+ * reads back to restore focus across a re-render. Every custom control in the
31
+ * tree wrote its human LABEL there instead, so focus restoration silently
32
+ * failed for all of them -- passing the id here is what makes getting it right
33
+ * the default rather than something each plugin has to remember.
34
+ */
35
+ id?: string;
25
36
  /** The `<openleaf-editor>` element, for dispatching events or hosting dialogs. */
26
37
  host: HTMLElement;
38
+ /** Extra host-defined block formats available to select controls. */
39
+ formats?: readonly FormatSpec[];
27
40
  }
28
41
  /**
29
42
  * A control a `custom` item builds for itself.
30
43
  *
31
44
  * The contract is narrow on purpose. A custom item owns its own markup, so it
32
45
  * can be a colour grid or a table-size picker, but it does not get to own the
33
- * toolbar's keyboard model: the element it returns must contain exactly one
34
- * focusable `button.ol-btn`, because that is what the roving tabindex walks. A
35
- * control with two focusable buttons in the bar would make the toolbar two tab
36
- * stops where the author expects one; a control with none would be unreachable
37
- * by keyboard. Anything else the control needs -- a popover, a grid of swatches
38
- * -- belongs outside the toolbar element, in the top layer or on the host.
46
+ * toolbar's keyboard model. Button-like custom controls participate in the
47
+ * roving tabindex through one `button.ol-btn`; select controls identify their
48
+ * native focus target with `focusable`. A control with two focusable elements
49
+ * in the bar would make the toolbar two tab stops where the author expects one.
50
+ * Anything else the control needs -- a popover, a grid of swatches -- belongs
51
+ * outside the toolbar element, in the top layer or on the host.
39
52
  */
40
53
  export interface ToolbarControl {
41
54
  /** The element placed in the toolbar. */
42
55
  el: HTMLElement;
56
+ /** Focus target when the control is not a standard toolbar button. */
57
+ focusable?: HTMLElement;
43
58
  /**
44
59
  * Reflect the editor state. Called on every transaction, so it must be cheap
45
60
  * and must not throw; a throw is caught and logged once, like a predicate.
@@ -48,6 +63,11 @@ export interface ToolbarControl {
48
63
  /** Release listeners, and remove anything the control put in the document. */
49
64
  destroy?: () => void;
50
65
  }
66
+ /** One choice in a `type: 'select'` toolbar item. */
67
+ export interface ToolbarSelectOption {
68
+ value: string;
69
+ label: string;
70
+ }
51
71
  export interface ToolbarItemSpec {
52
72
  /** Stable id used in the `toolbar` layout attribute. */
53
73
  id: string;
@@ -55,17 +75,22 @@ export interface ToolbarItemSpec {
55
75
  * What kind of control this is.
56
76
  *
57
77
  * `button` is the common case. `custom` hands the item a chance to build its
78
+ * own DOM through `render`, which is how the colour picker and block-type
79
+ * select exist without id-specific branches in the toolbar.
80
+ *
81
+ * `select` and `custom` both build through `render`; the distinct name keeps
82
+ * the public declaration honest about the control users will receive.
58
83
  * own DOM through `render`, which is how the colour picker exists at all: a
59
84
  * swatch grid is not a button, and modelling it as one would have meant
60
- * special-casing it in the toolbar by id, the way the block-type `select`
61
- * still is.
85
+ * special-casing it in the toolbar by id.
62
86
  *
63
- * `select` remains unimplemented, and the block-type control is special-cased
64
- * by id rather than being one. Declaring it logs a warning rather than
65
- * rendering a plausible-looking button that is not the control asked for.
87
+ * `select` builds a native `<select>` from `options` / `getValue` /
88
+ * `applyValue`. The block-type control stays special-cased by id because it
89
+ * owns formats the host injects at mount time; everything else that is a
90
+ * preset list (font family, size, line height) uses this type.
66
91
  */
67
92
  type?: 'button' | 'select' | 'custom';
68
- /** Accessible name. Kept constant across states -- the platform announces pressed. */
93
+ /** Accessible name. Use `labelFor` when the same control does insert versus edit. */
69
94
  label: string;
70
95
  icon?: IconName;
71
96
  /**
@@ -78,10 +103,38 @@ export interface ToolbarItemSpec {
78
103
  /** For items needing more than the editor state -- dialogs, mode switches. */
79
104
  run?: (ctx: ToolbarContext) => void;
80
105
  /**
81
- * For `type: 'custom'`: build the control. Required for that type, ignored
82
- * otherwise.
106
+ * For `type: 'custom'` or `type: 'select'`: build the control.
83
107
  */
84
108
  render?: (ctx: ToolbarContext) => ToolbarControl;
109
+ /**
110
+ * For `type: 'select'`: the choices shown. Required for that type. An empty
111
+ * `value` is the "Default" / clear option.
112
+ */
113
+ options?: readonly ToolbarSelectOption[];
114
+ /**
115
+ * For `type: 'select'`: the value that matches the selection. Empty string
116
+ * means no explicit formatting (the Default option).
117
+ */
118
+ getValue?: (state: EditorState) => string;
119
+ /**
120
+ * For `type: 'select'`: turn a chosen value into a command. Empty string
121
+ * clears.
122
+ */
123
+ applyValue?: (value: string) => Command;
124
+ /**
125
+ * Optional CSS modifier for a select (e.g. `wide` for long font names).
126
+ * Becomes `ol-select--{mod}` on the element.
127
+ */
128
+ selectMod?: string;
129
+ /**
130
+ * Accessible name that depends on the selection.
131
+ *
132
+ * `label` stays the default. Use this when the same control does two
133
+ * different things -- insert versus edit -- so the name can say which.
134
+ * Do not use it to bake "pressed" into a toggle; the platform already
135
+ * announces that.
136
+ */
137
+ labelFor?: (state: EditorState) => string;
85
138
  isActive?: (state: EditorState) => boolean;
86
139
  /** Defaults to asking `command` whether it would apply. */
87
140
  isEnabled?: (state: EditorState) => boolean;
@@ -104,10 +157,11 @@ export declare function clearToolbarItems(): void;
104
157
  * Order reasoning: history sits leftmost because it is the control an author
105
158
  * reaches for under stress and muscle memory puts it at the start of the bar in
106
159
  * every office application. Block type comes next because choosing what a
107
- * paragraph *is* precedes decorating it. Then character marks, then block
108
- * structure, then insertions, and finally source view -- the one control that
109
- * changes the editor's mode rather than the document, kept away from the rest
110
- * so it is not hit by accident.
160
+ * paragraph *is* precedes decorating it. Font family, size and line height sit
161
+ * beside it as the next layer of look. Then character marks, alignment, indent,
162
+ * lists, insertions, and finally source view -- the one control that changes
163
+ * the editor's mode rather than the document, kept away from the rest so it is
164
+ * not hit by accident.
111
165
  */
112
166
  export declare const DEFAULT_LAYOUT: string;
113
167
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAE1C,4CAA4C;AAC5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,kFAAkF;IAClF,IAAI,EAAE,WAAW,CAAA;CAClB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,yCAAyC;IACzC,EAAE,EAAE,WAAW,CAAA;IACf;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IACrC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,EAAE,EAAE,MAAM,CAAA;IACV;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;IACrC,sFAAsF;IACtF,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IAC1B,mFAAmF;IACnF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,8EAA8E;IAC9E,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAA;IACnC;;;OAGG;IACH,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,cAAc,CAAA;IAChD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAA;IAC1C,2DAA2D;IAC3D,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAA;IAC3C,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAcD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAGjE;AAcD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAG/D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CAEtE;AAED,wBAAgB,eAAe,IAAI,eAAe,EAAE,CAEnD;AAED,gDAAgD;AAChD,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,QAGgE,CAAA;AAE3F;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,kBAAkB,QAG9B,CAAA"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
package/dist/registry.js CHANGED
@@ -67,14 +67,15 @@ export function clearToolbarItems() {
67
67
  * Order reasoning: history sits leftmost because it is the control an author
68
68
  * reaches for under stress and muscle memory puts it at the start of the bar in
69
69
  * every office application. Block type comes next because choosing what a
70
- * paragraph *is* precedes decorating it. Then character marks, then block
71
- * structure, then insertions, and finally source view -- the one control that
72
- * changes the editor's mode rather than the document, kept away from the rest
73
- * so it is not hit by accident.
70
+ * paragraph *is* precedes decorating it. Font family, size and line height sit
71
+ * beside it as the next layer of look. Then character marks, alignment, indent,
72
+ * lists, insertions, and finally source view -- the one control that changes
73
+ * the editor's mode rather than the document, kept away from the rest so it is
74
+ * not hit by accident.
74
75
  */
75
- export const DEFAULT_LAYOUT = 'undo redo | blockType | bold italic underline strikethrough code | ' +
76
+ export const DEFAULT_LAYOUT = 'undo redo | blockType | fontFamily fontSize lineHeight | bold italic underline strikethrough code | ' +
76
77
  'alignLeft alignCenter alignRight alignJustify | ' +
77
- 'bulletList orderedList blockquote codeBlock | link unlink image horizontalRule | source';
78
+ 'indent outdent | bulletList orderedList blockquote codeBlock | link unlink image horizontalRule | source';
78
79
  /**
79
80
  * The default layout with the colour controls in it.
80
81
  *
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AA8EH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAA;AAEnD;;;;;;;GAOG;AACH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAA;AAEvC,MAAM,UAAU,gBAAgB,CAAC,QAAoB;IACnD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACzC,CAAC;AAED,SAAS,MAAM;IACb,4EAA4E;IAC5E,2EAA2E;IAC3E,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,QAAQ,EAAE,CAAA;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,oDAAoD,EAAE,KAAK,CAAC,CAAA;QAC5E,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAqB;IACvD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,CAAA;AACV,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,iBAAiB;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAA;IAChB,MAAM,EAAE,CAAA;AACV,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,cAAc,GACzB,qEAAqE;IACrE,kDAAkD;IAClD,yFAAyF,CAAA;AAE3F;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,CACtD,WAAW,EACX,wCAAwC,CACzC,CAAA"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAoIH,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA2B,CAAA;AAEnD;;;;;;;GAOG;AACH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAA;AAEvC,MAAM,UAAU,gBAAgB,CAAC,QAAoB;IACnD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;AACzC,CAAC;AAED,SAAS,MAAM;IACb,4EAA4E;IAC5E,2EAA2E;IAC3E,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,QAAQ,EAAE,CAAA;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,oDAAoD,EAAE,KAAK,CAAC,CAAA;QAC5E,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAqB;IACvD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAA;IAC3B,MAAM,EAAE,CAAA;AACV,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU;IACvC,OAAO,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;AACzB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;AAC/B,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,iBAAiB;IAC/B,QAAQ,CAAC,KAAK,EAAE,CAAA;IAChB,MAAM,EAAE,CAAA;AACV,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,cAAc,GACzB,sGAAsG;IACtG,kDAAkD;IAClD,0GAA0G,CAAA;AAE5G;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,cAAc,CAAC,OAAO,CACtD,WAAW,EACX,wCAAwC,CACzC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"skins.d.ts","sourceRoot":"","sources":["../src/skins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,MAAM,WAAW,IAAI;IACnB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAC1B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,IAAI,EAyEzC,CAAA;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAI7D;AAuBD,wBAAgB,cAAc,IAAI,SAAS,IAAI,EAAE,CAEhD;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAuBtE;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAQ/E"}
1
+ {"version":3,"file":"skins.d.ts","sourceRoot":"","sources":["../src/skins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAIH,MAAM,WAAW,IAAI;IACnB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,6EAA6E;IAC7E,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAC1B;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,IAAI,EAiFzC,CAAA;AA6CD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAI7D;AAwBD,wBAAgB,cAAc,IAAI,SAAS,IAAI,EAAE,CAEhD;AAED,2DAA2D;AAC3D,wBAAgB,WAAW,CAAC,GAAG,CAAC,EAAE,QAAQ,GAAG,IAAI,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAuBtE;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;AAEpD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,CAQ/E"}