@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
package/dist/openleaf.css CHANGED
@@ -14,8 +14,11 @@
14
14
  --ol-surface-hover: var(--openleaf-color-surface-hover, #f0f1f3);
15
15
  --ol-surface-active: var(--openleaf-color-surface-active, #dbe9ff);
16
16
  --ol-border: var(--openleaf-color-border, #d1d9e0);
17
+ /* Control boundaries, not decoration. See "Two border tokens" above. */
18
+ --ol-border-strong: var(--openleaf-color-border-strong, #6e7781);
17
19
  --ol-accent: var(--openleaf-color-accent, #0550ae);
18
20
  --ol-focus: var(--openleaf-color-focus, #0969da);
21
+ --ol-danger: var(--openleaf-color-danger, #cf222e);
19
22
  --ol-button-size: var(--openleaf-button-size, 32px);
20
23
  --ol-icon-size: var(--openleaf-icon-size, 16px);
21
24
  --ol-gap: var(--openleaf-gap, 2px);
@@ -31,6 +34,7 @@
31
34
  --ol-focus-offset: var(--openleaf-focus-offset, 1px);
32
35
 
33
36
  display: block;
37
+ position: relative;
34
38
  color: var(--ol-text);
35
39
  }
36
40
 
@@ -49,8 +53,10 @@
49
53
  --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);
50
54
  --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);
51
55
  --ol-border: var(--openleaf-color-border, #3d444d);
56
+ --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);
52
57
  --ol-accent: var(--openleaf-color-accent, #79c0ff);
53
58
  --ol-focus: var(--openleaf-color-focus, #79c0ff);
59
+ --ol-danger: var(--openleaf-color-danger, #ff8182);
54
60
  }
55
61
  }
56
62
 
@@ -61,8 +67,10 @@
61
67
  --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);
62
68
  --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);
63
69
  --ol-border: var(--openleaf-color-border, #3d444d);
70
+ --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);
64
71
  --ol-accent: var(--openleaf-color-accent, #79c0ff);
65
72
  --ol-focus: var(--openleaf-color-focus, #79c0ff);
73
+ --ol-danger: var(--openleaf-color-danger, #ff8182);
66
74
  }
67
75
 
68
76
  .ol-editor[data-ol-scheme="dark"] {
@@ -72,8 +80,10 @@
72
80
  --ol-surface-hover: var(--openleaf-color-surface-hover, #21262d);
73
81
  --ol-surface-active: var(--openleaf-color-surface-active, #1f3a5f);
74
82
  --ol-border: var(--openleaf-color-border, #3d444d);
83
+ --ol-border-strong: var(--openleaf-color-border-strong, #8b949e);
75
84
  --ol-accent: var(--openleaf-color-accent, #79c0ff);
76
85
  --ol-focus: var(--openleaf-color-focus, #79c0ff);
86
+ --ol-danger: var(--openleaf-color-danger, #ff8182);
77
87
  }
78
88
 
79
89
  /* Native widget chrome -- the popup a `select` opens, scrollbars, the caret,
@@ -99,7 +109,7 @@
99
109
  box-sizing: border-box;
100
110
  margin: 0;
101
111
  padding: 4px;
102
- border: 1px solid var(--ol-border);
112
+ border: 1px solid var(--ol-border-strong);
103
113
  border-bottom: 0;
104
114
  border-radius: var(--ol-radius) var(--ol-radius) 0 0;
105
115
  background: var(--ol-surface);
@@ -120,7 +130,12 @@
120
130
  after it -- a stranded line floating at the end of a row. Wrapping begins
121
131
  around 690-740px, well inside ordinary desktop widths (a CMS sidebar, a
122
132
  half-width split pane), so this was not a 360px-only edge case.
123
- border-inline-start rather than border-left, so it flips under RTL. */
133
+ border-inline-start rather than border-left, so it flips under RTL.
134
+
135
+ This selector is why the renderer emits NO element between groups. It used to
136
+ emit an .ol-sep div, which made the two groups non-adjacent and stopped this
137
+ rule from ever matching -- so no divider rendered in any theme, and every bar
138
+ carried inert empty divs. Adding a separator element back here breaks this. */
124
139
  .ol-editor .ol-group + .ol-group {
125
140
  border-inline-start: 1px solid var(--ol-border);
126
141
  padding-inline-start: 5px;
@@ -199,7 +214,7 @@
199
214
  removed from the roving tabindex and cannot be reached or announced, so an
200
215
  author using a screen reader cannot discover that the control exists. */
201
216
  .ol-editor .ol-btn[aria-disabled="true"] {
202
- opacity: 0.4;
217
+ opacity: 0.55;
203
218
  cursor: default;
204
219
  }
205
220
 
@@ -225,7 +240,7 @@
225
240
  max-width: 11em;
226
241
  padding: 0 22px 0 6px;
227
242
  margin: 0;
228
- border: 1px solid var(--ol-border);
243
+ border: 1px solid var(--ol-border-strong);
229
244
  border-radius: var(--ol-radius);
230
245
  background-color: transparent;
231
246
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
@@ -246,6 +261,10 @@
246
261
  -webkit-appearance: none;
247
262
  }
248
263
 
264
+ .ol-editor .ol-select--wide {
265
+ max-width: 14em;
266
+ }
267
+
249
268
  .ol-editor .ol-select:hover {
250
269
  background-color: var(--ol-surface-hover);
251
270
  }
@@ -264,7 +283,7 @@
264
283
 
265
284
  .ol-editor .ol-content {
266
285
  box-sizing: border-box;
267
- border: 1px solid var(--ol-border);
286
+ border: 1px solid var(--ol-border-strong);
268
287
  border-radius: 0 0 var(--ol-radius) var(--ol-radius);
269
288
  background: var(--ol-surface);
270
289
  }
@@ -306,6 +325,15 @@
306
325
  position: relative;
307
326
  }
308
327
 
328
+ /* Presentational valign is otherwise beaten by the rule above, which would
329
+ make the cell-properties dialog a no-op on screen. */
330
+ .ol-editor .ol-content .ProseMirror td[valign="middle"],
331
+ .ol-editor .ol-content .ProseMirror th[valign="middle"] { vertical-align: middle; }
332
+ .ol-editor .ol-content .ProseMirror td[valign="bottom"],
333
+ .ol-editor .ol-content .ProseMirror th[valign="bottom"] { vertical-align: bottom; }
334
+ .ol-editor .ol-content .ProseMirror td[valign="baseline"],
335
+ .ol-editor .ol-content .ProseMirror th[valign="baseline"] { vertical-align: baseline; }
336
+
309
337
  .ol-editor .ol-content .ProseMirror th {
310
338
  background: var(--ol-surface-hover);
311
339
  font-weight: 600;
@@ -314,7 +342,13 @@
314
342
 
315
343
  /* prosemirror-tables marks cells in a rectangular selection with this class.
316
344
  An ::after overlay rather than a background so it composes with a cell that
317
- already has one, and so a header cell still reads as a header. */
345
+ already has one, and so a header cell still reads as a header.
346
+
347
+ The ring, not the tint, is the indicator -- see "Cell selection" above. */
348
+ .ol-editor .ol-content .ProseMirror .selectedCell {
349
+ outline: 2px solid var(--ol-accent);
350
+ outline-offset: -2px;
351
+ }
318
352
  .ol-editor .ol-content .ProseMirror .selectedCell::after {
319
353
  content: "";
320
354
  position: absolute;
@@ -340,6 +374,47 @@
340
374
  cursor: col-resize;
341
375
  }
342
376
 
377
+ .ol-editor .ol-content .ProseMirror img.ol-float-left {
378
+ float: left;
379
+ margin: 0 1em 0.5em 0;
380
+ }
381
+ .ol-editor .ol-content .ProseMirror img.ol-float-right {
382
+ float: right;
383
+ margin: 0 0 0.5em 1em;
384
+ }
385
+ .ol-editor .ol-content .ProseMirror img.ol-align-center {
386
+ display: block;
387
+ margin: 0 auto 0.5em;
388
+ }
389
+ .ol-editor .ol-content .ProseMirror figure {
390
+ margin: 0 0 1em;
391
+ }
392
+ .ol-editor .ol-content .ProseMirror figcaption {
393
+ font-size: .9em;
394
+ opacity: .8;
395
+ margin-top: .35em;
396
+ }
397
+ .ol-editor .ol-content .ProseMirror details {
398
+ border: 1px solid var(--ol-border);
399
+ border-radius: var(--ol-radius);
400
+ padding: .5em .75em;
401
+ margin: 0 0 1em;
402
+ }
403
+ .ol-editor .ol-content .ProseMirror summary {
404
+ cursor: pointer;
405
+ font-weight: 600;
406
+ }
407
+ .ol-editor .ol-content .ProseMirror hr.ol-pagebreak {
408
+ border: 0;
409
+ border-top: 2px dashed var(--ol-border);
410
+ margin: 1.5em 0;
411
+ }
412
+ .ol-editor .ol-content .ProseMirror iframe,
413
+ .ol-editor .ol-content .ProseMirror video,
414
+ .ol-editor .ol-content .ProseMirror audio {
415
+ max-width: 100%;
416
+ }
417
+
343
418
  /* Preserved-but-unrecognised markup, surfaced rather than hidden. */
344
419
  .ol-editor .ol-content .ProseMirror-selectednode {
345
420
  outline: 2px solid var(--ol-focus);
@@ -353,7 +428,7 @@
353
428
  width: 100%;
354
429
  min-height: 12rem;
355
430
  padding: 12px;
356
- border: 1px solid var(--ol-border);
431
+ border: 1px solid var(--ol-border-strong);
357
432
  border-radius: 0 0 var(--ol-radius) var(--ol-radius);
358
433
  background: var(--ol-surface);
359
434
  color: var(--ol-text);
@@ -388,6 +463,215 @@
388
463
  border: 0;
389
464
  }
390
465
 
466
+ /* Menubar, menus, floating chrome, visual aids, fullscreen, inline. */
467
+ .ol-editor .ol-menubar {
468
+ display: flex;
469
+ flex-wrap: wrap;
470
+ gap: var(--ol-gap);
471
+ box-sizing: border-box;
472
+ margin: 0;
473
+ padding: 2px 4px;
474
+ border: 1px solid var(--ol-border-strong);
475
+ border-bottom: 0;
476
+ border-radius: var(--ol-radius) var(--ol-radius) 0 0;
477
+ background: var(--ol-surface);
478
+ position: relative;
479
+ z-index: var(--ol-z);
480
+ }
481
+ .ol-editor .ol-menubar + .ol-toolbar {
482
+ border-radius: 0;
483
+ }
484
+ .ol-editor .ol-menu-trigger {
485
+ box-sizing: border-box;
486
+ margin: 0;
487
+ padding: 4px 8px;
488
+ border: 1px solid transparent;
489
+ border-radius: var(--ol-radius);
490
+ background: transparent;
491
+ color: var(--ol-text);
492
+ font: inherit;
493
+ font-family: var(--ol-font);
494
+ font-size: var(--ol-font-size);
495
+ cursor: pointer;
496
+ appearance: none;
497
+ }
498
+ .ol-editor .ol-menu-trigger:hover,
499
+ .ol-editor .ol-menu-trigger[aria-expanded="true"] {
500
+ background: var(--ol-surface-hover);
501
+ }
502
+ .ol-editor .ol-menu-trigger:focus-visible {
503
+ outline: var(--ol-focus-width) solid var(--ol-focus);
504
+ outline-offset: var(--ol-focus-offset);
505
+ }
506
+ .ol-editor .ol-menu {
507
+ position: absolute;
508
+ z-index: calc(var(--ol-z) + 20);
509
+ min-width: 12rem;
510
+ /* Capped, so a deep menu opened low on a short window can be flipped above
511
+ its trigger instead of running off the bottom of the page. */
512
+ max-height: 60vh;
513
+ overflow-y: auto;
514
+ margin: 0;
515
+ padding: 4px;
516
+ border: 1px solid var(--ol-border-strong);
517
+ border-radius: var(--ol-radius);
518
+ background: var(--ol-surface);
519
+ box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
520
+ }
521
+ .ol-editor .ol-menu-item {
522
+ display: block;
523
+ box-sizing: border-box;
524
+ width: 100%;
525
+ margin: 0;
526
+ padding: 6px 10px;
527
+ border: 0;
528
+ border-radius: var(--ol-radius);
529
+ background: transparent;
530
+ color: var(--ol-text);
531
+ font: inherit;
532
+ font-family: var(--ol-font);
533
+ font-size: var(--ol-font-size);
534
+ text-align: start;
535
+ cursor: pointer;
536
+ appearance: none;
537
+ }
538
+ .ol-editor .ol-menu-item:hover {
539
+ background: var(--ol-surface-hover);
540
+ }
541
+ /* Was outline:none plus a 1.13:1 background swap. See "Menu focus" above. */
542
+ .ol-editor .ol-menu-item:focus-visible {
543
+ background: var(--ol-surface-hover);
544
+ outline: var(--ol-focus-width) solid var(--ol-focus);
545
+ outline-offset: -2px;
546
+ }
547
+ /* 0.55, not 0.4: see "Disabled is not invisible" above. */
548
+ .ol-editor .ol-menu-item[aria-disabled="true"] {
549
+ opacity: 0.55;
550
+ cursor: default;
551
+ }
552
+ .ol-editor .ol-menu-sep {
553
+ height: 1px;
554
+ margin: 4px 0;
555
+ background: var(--ol-border);
556
+ }
557
+ /* `display: flex` on .ol-toolbar above outranks the UA's `[hidden]` rule --
558
+ a class selector beats an attribute selector on specificity -- so setting
559
+ `el.hidden = true` in floating.ts styled a hidden bar and showed it anyway.
560
+ Both floating bars sat over the prose at rest, with no selection to format.
561
+ The overflow panel needed the same rule for the same reason; see below. */
562
+ .ol-editor .ol-toolbar.ol-floating[hidden] {
563
+ display: none;
564
+ }
565
+ .ol-editor .ol-toolbar.ol-floating {
566
+ position: absolute;
567
+ flex-wrap: nowrap;
568
+ border: 1px solid var(--ol-border);
569
+ border-radius: var(--ol-radius);
570
+ box-shadow: 0 8px 24px rgb(0 0 0 / 12%);
571
+ z-index: calc(var(--ol-z) + 10);
572
+ }
573
+ .ol-editor .ol-toolbar.ol-toolbar--overflow {
574
+ flex-wrap: nowrap;
575
+ overflow: hidden;
576
+ }
577
+ /* The More panel. Positioned in viewport coordinates from script, because the
578
+ bar it belongs to may live inside a host with `overflow: hidden` -- which is
579
+ the situation the whole feature exists for. */
580
+ .ol-editor .ol-overflow-menu {
581
+ display: flex;
582
+ flex-direction: column;
583
+ align-items: stretch;
584
+ gap: var(--ol-gap);
585
+ max-height: 70vh;
586
+ overflow-y: auto;
587
+ }
588
+ .ol-editor .ol-overflow-menu[hidden] {
589
+ display: none;
590
+ }
591
+ /* Vertical: the panel exists because there is no horizontal room left. */
592
+ .ol-editor .ol-overflow-menu .ol-group {
593
+ flex-direction: column;
594
+ align-items: stretch;
595
+ }
596
+ .ol-editor .ol-overflow-menu .ol-group + .ol-group {
597
+ border-inline-start: 0;
598
+ border-block-start: 1px solid var(--ol-border);
599
+ padding-inline-start: 0;
600
+ margin-inline-start: 0;
601
+ padding-block-start: 4px;
602
+ margin-block-start: 3px;
603
+ }
604
+ .ol-editor.ol-visual-aids .ol-empty-block {
605
+ outline: 1px dashed var(--ol-border);
606
+ outline-offset: 2px;
607
+ min-height: 1.2em;
608
+ }
609
+ .ol-editor.ol-visual-aids .ol-nbsp {
610
+ background: color-mix(in srgb, var(--ol-accent) 25%, transparent);
611
+ box-shadow: inset 0 -1px 0 var(--ol-accent);
612
+ }
613
+ .ol-editor.ol-visual-aids .ol-hidden-structure {
614
+ outline: 1px dotted var(--ol-accent);
615
+ outline-offset: 2px;
616
+ }
617
+ .ol-editor .ol-noneditable {
618
+ cursor: default;
619
+ background: repeating-linear-gradient(
620
+ -45deg,
621
+ transparent,
622
+ transparent 6px,
623
+ color-mix(in srgb, var(--ol-border) 35%, transparent) 6px,
624
+ color-mix(in srgb, var(--ol-border) 35%, transparent) 7px
625
+ );
626
+ }
627
+ .ol-editor.ol-fullscreen {
628
+ position: fixed;
629
+ inset: 0;
630
+ z-index: 2147483000;
631
+ margin: 0;
632
+ border-radius: 0;
633
+ background: var(--ol-surface);
634
+ display: flex;
635
+ flex-direction: column;
636
+ }
637
+ .ol-editor.ol-fullscreen .ol-content,
638
+ .ol-editor.ol-fullscreen .ol-source {
639
+ flex: 1 1 auto;
640
+ min-height: 0;
641
+ overflow: auto;
642
+ }
643
+ .ol-editor.ol-autoresize .ol-content .ProseMirror {
644
+ overflow: hidden;
645
+ }
646
+ .ol-editor.ol-inline:not(.ol-inline-active) .ol-toolbar,
647
+ .ol-editor.ol-inline:not(.ol-inline-active) .ol-menubar {
648
+ position: absolute;
649
+ width: 1px;
650
+ height: 1px;
651
+ overflow: hidden;
652
+ clip: rect(0 0 0 0);
653
+ clip-path: inset(50%);
654
+ }
655
+ .ol-editor.ol-inline .ol-content {
656
+ border-radius: var(--ol-radius);
657
+ }
658
+ .ol-help-table {
659
+ width: 100%;
660
+ border-collapse: collapse;
661
+ font: inherit;
662
+ }
663
+ .ol-help-table th,
664
+ .ol-help-table td {
665
+ padding: 4px 8px;
666
+ text-align: start;
667
+ vertical-align: top;
668
+ border-bottom: 1px solid var(--openleaf-color-border, #d1d9e0);
669
+ }
670
+ .ol-help-table th {
671
+ font-weight: 600;
672
+ white-space: nowrap;
673
+ }
674
+
391
675
  /* Coarse pointers get a larger target. WCAG 2.2 SC 2.5.8 asks for 24x24 CSS px
392
676
  minimum; 32 clears that on a mouse and 40 is comfortable on a thumb. */
393
677
  @media (pointer: coarse) {
@@ -423,4 +707,38 @@
423
707
  color: GrayText;
424
708
  opacity: 1;
425
709
  }
710
+ .ol-editor .ol-menu-item:focus-visible {
711
+ outline-color: Highlight;
712
+ }
713
+ .ol-editor .ol-menu-item[aria-disabled="true"] {
714
+ color: GrayText;
715
+ opacity: 1;
716
+ }
717
+ .ol-editor .ol-menu-trigger[aria-expanded="true"] {
718
+ border-color: Highlight;
719
+ color: Highlight;
720
+ }
721
+ .ol-editor .ol-content .ProseMirror .selectedCell {
722
+ outline-color: Highlight;
723
+ }
724
+ .ol-editor .ol-content .ProseMirror .selectedCell::after {
725
+ background: transparent;
726
+ }
727
+ .ol-editor .ol-content .ProseMirror .column-resize-handle {
728
+ background: Highlight;
729
+ }
730
+ .ol-editor.ol-visual-aids .ol-nbsp {
731
+ background: transparent;
732
+ box-shadow: inset 0 -2px 0 Highlight;
733
+ }
734
+ .ol-editor.ol-visual-aids .ol-hidden-structure {
735
+ outline-color: Highlight;
736
+ }
737
+ .ol-editor.ol-visual-aids .ol-empty-block {
738
+ outline-color: GrayText;
739
+ }
740
+ .ol-editor .ol-noneditable {
741
+ background: transparent;
742
+ outline: 1px dashed GrayText;
743
+ }
426
744
  }
@@ -0,0 +1,44 @@
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
+ export declare class ToolbarOverflow {
37
+ #private;
38
+ constructor(toolbar: HTMLElement, host: HTMLElement, doc: Document, onLayout?: () => void);
39
+ /** Re-home the trigger after the toolbar rebuilt its children. */
40
+ reattach(): void;
41
+ destroy(): void;
42
+ layout(): void;
43
+ }
44
+ //# sourceMappingURL=overflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overflow.d.ts","sourceRoot":"","sources":["../src/overflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAUH,qBAAa,eAAe;;gBAiBd,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI;IA+CzF,kEAAkE;IAClE,QAAQ,IAAI,IAAI;IA6BhB,OAAO,IAAI,IAAI;IAcf,MAAM,IAAI,IAAI;CAyLf"}