efficient-easel 0.99.1 → 0.100.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 (110) hide show
  1. package/README.md +281 -36
  2. package/dist/autosave/index.d.ts +12 -6
  3. package/dist/blocks/index.d.ts +2 -2
  4. package/dist/canvas/index.d.ts +3 -3
  5. package/dist/canvas/index.js +1 -1
  6. package/dist/chrome/chrome.css +96 -29
  7. package/dist/chrome/index.d.ts +72 -19
  8. package/dist/chrome/index.js +17 -21
  9. package/dist/chunk-3EDSDPIP.js +1 -0
  10. package/dist/chunk-67GNT6PF.js +1 -0
  11. package/dist/{chunk-PI26YXYD.js → chunk-6EIVTKZZ.js} +21 -14
  12. package/dist/chunk-A5UK76FC.js +6 -0
  13. package/dist/chunk-AZT7V4UM.js +10 -0
  14. package/dist/chunk-DICUMYMG.js +12 -0
  15. package/dist/chunk-HDVD27VB.js +1 -0
  16. package/dist/chunk-JQM3V7XQ.js +1 -0
  17. package/dist/{chunk-TDA4HH54.js → chunk-JUQ6YJCG.js} +1 -1
  18. package/dist/chunk-LA54QLP5.js +1 -0
  19. package/dist/chunk-LGKQXSKO.js +16 -0
  20. package/dist/chunk-M6F6LS3H.js +1 -0
  21. package/dist/chunk-MH5GUZFQ.js +9 -0
  22. package/dist/chunk-P6O363EE.js +6 -0
  23. package/dist/chunk-PAELDYYS.js +1 -0
  24. package/dist/{chunk-JYPOOHII.js → chunk-QKVR3K73.js} +3 -3
  25. package/dist/chunk-SAJUCHOX.js +1 -0
  26. package/dist/chunk-TRVZ7C23.js +1 -0
  27. package/dist/chunk-V7GIIXFB.js +16 -0
  28. package/dist/{chunk-IBOFSS56.js → chunk-WZ7TGAAT.js} +1 -1
  29. package/dist/chunk-ZJEBF4NB.js +1 -0
  30. package/dist/copy/copy.css +388 -5
  31. package/dist/copy/index.d.ts +271 -8
  32. package/dist/copy/index.js +31 -10
  33. package/dist/data/index.d.ts +4 -4
  34. package/dist/drag/drag.css +10 -1
  35. package/dist/drag/index.d.ts +102 -11
  36. package/dist/drag/index.js +18 -17
  37. package/dist/{editor/editor.css → easel/easel.css} +16 -1
  38. package/dist/{editor → easel}/index.d.ts +146 -51
  39. package/dist/easel/index.js +9 -0
  40. package/dist/edit-lock/index.d.ts +3 -3
  41. package/dist/edit-lock/index.js +1 -1
  42. package/dist/fields/fields.css +103 -26
  43. package/dist/fields/index.d.ts +51 -13
  44. package/dist/fields/index.js +30 -46
  45. package/dist/gold/index.js +1 -1
  46. package/dist/icons/index.d.ts +10 -1
  47. package/dist/icons/index.js +1 -1
  48. package/dist/index.d.ts +3 -3
  49. package/dist/index.js +1 -1
  50. package/dist/markup/index.d.ts +94 -10
  51. package/dist/markup/index.js +1 -1
  52. package/dist/menu/index.d.ts +61 -6
  53. package/dist/menu/index.js +15 -15
  54. package/dist/menu/menu.css +17 -6
  55. package/dist/node-ops/index.d.ts +9 -9
  56. package/dist/node-ops/index.js +1 -1
  57. package/dist/panel/index.d.ts +73 -5
  58. package/dist/panel/index.js +18 -16
  59. package/dist/panel/panel.css +56 -1
  60. package/dist/pick/index.d.ts +42 -4
  61. package/dist/pick/index.js +7 -14
  62. package/dist/pick/pick.css +14 -0
  63. package/dist/rail/index.d.ts +6 -6
  64. package/dist/rail/index.js +1 -1
  65. package/dist/rail/rail.css +1 -1
  66. package/dist/strings/catalogue.d.ts +24 -40
  67. package/dist/strings/catalogue.js +1 -1
  68. package/dist/strings/index.d.ts +25 -23
  69. package/dist/strings/index.js +2 -2
  70. package/dist/style-clipboard/index.d.ts +5 -5
  71. package/dist/style-clipboard/index.js +1 -1
  72. package/dist/text-styles/index.d.ts +328 -0
  73. package/dist/text-styles/index.js +38 -0
  74. package/dist/text-styles/text-styles.css +309 -0
  75. package/dist/tree/index.d.ts +44 -3
  76. package/dist/tree/index.js +1 -1
  77. package/dist/tree/tree.css +71 -0
  78. package/dist/{types-CnRzp9oc.d.ts → types-DGcCsxs8.d.ts} +79 -12
  79. package/dist/{types-DNrn_w4V.d.ts → types-DWS-s9z-.d.ts} +10 -10
  80. package/dist/{types-pGBXevBU.d.ts → types-Djdq6Xkd.d.ts} +15 -8
  81. package/dist/{types-Dy6oR6Z2.d.ts → types-E3HrTPg2.d.ts} +20 -14
  82. package/dist/{types-C7HFvdtk.d.ts → types-VqL6t5HH.d.ts} +82 -5
  83. package/dist/{watch-DmasQA61.d.ts → watch-BTYOJpQU.d.ts} +19 -2
  84. package/dist/{wordFit-9B9nqyf3.d.ts → wordFit-D4S36PvB.d.ts} +1 -1
  85. package/dist/{words-DagJdwIA.d.ts → words-AHHfiaRY.d.ts} +31 -2
  86. package/dist/{words-D9ChvbNC.d.ts → words-BDignMl_.d.ts} +1 -1
  87. package/dist/{words-Cqmyey0s.d.ts → words-BMzV04b1.d.ts} +2 -2
  88. package/dist/words-CJjUKcV5.d.ts +37 -0
  89. package/dist/words-CRYvAiHX.d.ts +105 -0
  90. package/dist/{words-B2YLaKEr.d.ts → words-CnnHb9jo.d.ts} +1 -1
  91. package/dist/{words-CD3WADyb.d.ts → words-CzoyDNHm.d.ts} +4 -0
  92. package/dist/{words-bOMsUJk9.d.ts → words-DBq7vfHy.d.ts} +59 -6
  93. package/dist/{words-DOhF-4D4.d.ts → words-DMG4dYq2.d.ts} +1 -1
  94. package/dist/{words-BK-npta-.d.ts → words-DgHcY5qB.d.ts} +10 -4
  95. package/dist/{words-B87GIFWH.d.ts → words-is_Vy6hn.d.ts} +1 -1
  96. package/package.json +14 -8
  97. package/dist/chunk-66CKSTXP.js +0 -14
  98. package/dist/chunk-67VZRQLG.js +0 -13
  99. package/dist/chunk-6PS6STGA.js +0 -1
  100. package/dist/chunk-7A7O2JWQ.js +0 -1
  101. package/dist/chunk-H4B72XCJ.js +0 -1
  102. package/dist/chunk-JE63JHKO.js +0 -1
  103. package/dist/chunk-KDIVA6WD.js +0 -1
  104. package/dist/chunk-MCLBHENY.js +0 -1
  105. package/dist/chunk-QB3BZIRA.js +0 -5
  106. package/dist/chunk-SJQG5ENJ.js +0 -1
  107. package/dist/chunk-SUO5627P.js +0 -1
  108. package/dist/chunk-ZT7M24XD.js +0 -1
  109. package/dist/editor/index.js +0 -9
  110. /package/dist/{chunk-GGTPNGFJ.js → chunk-AELNNAFM.js} +0 -0
@@ -9,7 +9,16 @@
9
9
  * colours are the same colours, not copies of them.
10
10
  *
11
11
  * Needs `efficient-easel/shell.css` for the `--es-*` tokens. Widths come in as
12
- * `--es-left-w` / `--es-right-w` from `panelWidthVars()`, set on the editor ROOT.
12
+ * `--es-left-w` / `--es-right-w` from `panelWidthVars()` or `setPanelWidthVars()`,
13
+ * set on the editor ROOT.
14
+ *
15
+ * EVERY READ OF A WIDTH CARRIES ITS DEFAULT (`DEFAULT_PANEL_W`: 288 / 320;
16
+ * `tests/csp-server-render` holds the two together). A server-rendered editor
17
+ * has no width in scope until its script runs — and under a
18
+ * Content-Security-Policy that refuses `style` attributes, none from the HTML
19
+ * at all — and without a fallback the rail's column was 1px wide. A fallback
20
+ * at the read, not a declaration on a root: a host may set the variables on an
21
+ * ancestor of its own, and a default declared lower down would shadow them.
13
22
  *
14
23
  * Light only (owner, 2026-08-06: no dark mode in the editor or the designer).
15
24
  */
@@ -47,7 +56,7 @@
47
56
  want more room than the window has — the column collapses to its buttons
48
57
  with a correct `width` sitting right here (found twice on :5173, 2026-09-04). */
49
58
  flex: none;
50
- width: var(--es-left-w);
59
+ width: var(--es-left-w, 288px);
51
60
  box-sizing: border-box;
52
61
  height: 100%;
53
62
  gap: 0;
@@ -320,11 +329,11 @@
320
329
  container-type: inline-size;
321
330
  }
322
331
  .es-sidepanel--left {
323
- width: var(--es-left-w);
332
+ width: var(--es-left-w, 288px);
324
333
  border-right: 1px solid var(--es-line);
325
334
  }
326
335
  .es-sidepanel--right {
327
- width: var(--es-right-w);
336
+ width: var(--es-right-w, 320px);
328
337
  border-left: 1px solid var(--es-line);
329
338
  }
330
339
  .es-panel-head {
@@ -363,11 +372,11 @@
363
372
  touch-action: none;
364
373
  }
365
374
  .es-resizer--left {
366
- left: var(--es-left-w);
375
+ left: var(--es-left-w, 288px);
367
376
  justify-content: flex-start;
368
377
  }
369
378
  .es-resizer--right {
370
- right: var(--es-right-w);
379
+ right: var(--es-right-w, 320px);
371
380
  justify-content: flex-end;
372
381
  }
373
382
  .es-resizer-bar {
@@ -393,45 +402,42 @@ body.es-col-resizing iframe {
393
402
  }
394
403
 
395
404
  /* ── Inspector head ──────────────────────────────────────────────────────── */
396
- /* ↰ Go up one level: a quiet full-width row above the inspector head
397
- (campaign designer UpLevelControl, card 66042). The whole row is the button. */
405
+ /* ← Go up one level: the blue text link (owner ruling 2026-10-06, the website
406
+ Locations panel's look, one look in both editors). The arrow and the parent's
407
+ name in the accent colour, 12px; no box, no fill, no divider, and NO hover
408
+ change, as on the link it was taken from. Only the focus ring shows. At the
409
+ panel top it sits in the panel's own inset, 16 and 12 under 260px (one
410
+ spacing scale, owner ruling 2026-10-02); `inline` drops the wrapper. */
398
411
  .es-insp-up {
399
412
  display: flex;
400
- align-items: center;
401
413
  flex: none;
402
- padding: 8px;
403
- border-bottom: 1px solid var(--es-divider);
414
+ min-width: 0;
415
+ padding: 12px 16px 0;
404
416
  }
405
417
  .es-insp-up-btn {
406
- display: flex;
407
- align-items: center;
408
- gap: 8px;
409
- flex: 1;
418
+ display: inline-flex;
419
+ align-items: baseline;
420
+ gap: 4px;
421
+ max-width: 100%;
410
422
  min-width: 0;
411
- padding: 4px 8px;
423
+ padding: 0;
412
424
  border: 0;
413
- border-radius: 6px;
414
- background: transparent;
415
- cursor: pointer;
425
+ background: none;
416
426
  font: inherit;
417
427
  font-size: 12px;
418
- color: var(--es-muted);
428
+ color: var(--es-accent);
419
429
  text-align: left;
420
- transition: background 0.12s, color 0.12s;
421
- }
422
- .es-insp-up-btn:hover {
423
- background: var(--es-hover);
424
- color: var(--es-text);
430
+ cursor: pointer;
425
431
  }
426
432
  .es-insp-up-btn:focus-visible {
427
433
  outline: 2px solid var(--es-accent);
428
- outline-offset: 1px;
434
+ outline-offset: 2px;
429
435
  }
430
- .es-insp-up-icon {
431
- display: inline-flex;
436
+ .es-insp-up-arrow {
432
437
  flex: none;
433
438
  }
434
439
  .es-insp-up-name {
440
+ min-width: 0;
435
441
  overflow: hidden;
436
442
  text-overflow: ellipsis;
437
443
  white-space: nowrap;
@@ -450,7 +456,46 @@ body.es-col-resizing iframe {
450
456
  is the host's. */
451
457
  @container (width < 260px) {
452
458
  .es-panel-head,
453
- .es-insp-head { padding-inline: 12px; }
459
+ .es-insp-head,
460
+ .es-insp-up { padding-inline: 12px; }
461
+ }
462
+ /* A HEAD WITH A WAY-OUT WORD, UNDER 260px (card [MERGE] One Media Panel Head
463
+ For Both Editors, GG 2026-10-06). At a 220px panel the chip, Cancel, the
464
+ hairline and Hide left the titles about 38px: "Choose image" drew "Ch…" in
465
+ both editors. Nothing is cut (owner: change the layout, never the feature):
466
+ the word takes its own row, under the titles, and the hairline goes because
467
+ nothing stands beside Hide to part it from.
468
+ row 1 [chip] Choose image [hide]
469
+ For Background image
470
+ row 2 [Cancel]
471
+ The actions box steps aside (`display: contents`) so its buttons can sit in
472
+ different rows; every glyph button is locked to row 1 and takes the next
473
+ free column, so a head with several tools keeps them side by side. */
474
+ @container (width < 260px) {
475
+ .es-insp-head:has(.es-insp-textbtn) {
476
+ display: grid;
477
+ grid-template-columns: auto minmax(0, 1fr);
478
+ grid-auto-columns: auto;
479
+ align-items: center;
480
+ column-gap: 12px;
481
+ row-gap: 8px;
482
+ }
483
+ .es-insp-head:has(.es-insp-textbtn) > .es-insp-chip,
484
+ .es-insp-head:has(.es-insp-textbtn) > .es-insp-titles,
485
+ .es-insp-head:has(.es-insp-textbtn) .es-insp-iconbtn {
486
+ grid-row: 1;
487
+ }
488
+ .es-insp-head:has(.es-insp-textbtn) > .es-insp-actions {
489
+ display: contents;
490
+ }
491
+ .es-insp-head:has(.es-insp-textbtn) .es-insp-textbtn {
492
+ grid-row: 2;
493
+ grid-column: 2;
494
+ justify-self: start;
495
+ }
496
+ .es-insp-head:has(.es-insp-textbtn) .es-insp-divider {
497
+ display: none;
498
+ }
454
499
  }
455
500
  .es-insp-chip {
456
501
  width: 26px;
@@ -519,6 +564,28 @@ body.es-col-resizing iframe {
519
564
  color: var(--es-accent);
520
565
  }
521
566
 
567
+ /* A side panel's head has two pieces besides its glyph buttons (MediaPanelHead,
568
+ card [MERGE] One Media Panel Head, 2026-10-06; until then each editor's own
569
+ sheet drew them, as `.sf-head-*` and `.cd-head-*`). A MODE's way out is a
570
+ word ("Cancel", "Done") on the ghost button, drawn to the 28px of the head's
571
+ icon buttons so the row keeps one height (its sides are the scale's 12; both
572
+ editors drew 10, off the 2/4/8/12/16/32 scale); the hairline parts the
573
+ panel's own tools from the Hide panel button that ends every head. */
574
+ .es-btn-ghost.es-insp-textbtn {
575
+ height: 28px;
576
+ padding: 0 12px;
577
+ font-size: 12.5px;
578
+ border-radius: 7px;
579
+ white-space: nowrap;
580
+ }
581
+ .es-insp-divider {
582
+ width: 1px;
583
+ height: 16px;
584
+ margin: 0 4px;
585
+ background: var(--es-line);
586
+ flex: none;
587
+ }
588
+
522
589
  /* ── Edit notice — somebody else is in here, or a save was refused ───────── */
523
590
  /* A bar under the top bar, never a dialog (blueprint 2.5): the operator has to
524
591
  be able to read and copy from the screen it warns them about. No token of its
@@ -1,11 +1,11 @@
1
1
  import * as react from 'react';
2
- import { T as TopBarProps, a as TopBarClusterProps, b as TopBarRailProps, E as EditorIconButtonProps, D as DeviceSwitchProps, c as SaveStateProps, d as SaveStateToggleProps, P as PanelResizeHandleProps, I as InspectorHeadProps, e as InspectorIconButtonProps, f as InspectorUpLevelProps, g as EditNoticeProps } from '../types-CnRzp9oc.js';
3
- export { h as DEFAULT_PANEL_W, i as DeviceOption, M as MAX_PANEL_W, j as MIN_PANEL_W, k as PanelSide, l as PanelWidths, S as SaveTone, m as clampPanelWidth, p as panelWidthVars } from '../types-CnRzp9oc.js';
2
+ import { T as TopBarProps, a as TopBarClusterProps, b as TopBarRailProps, E as EaselIconButtonProps, D as DeviceSwitchProps, c as SaveStateProps, d as SaveStateToggleProps, P as PanelResizeHandleProps, I as InspectorHeadProps, e as InspectorIconButtonProps, f as InspectorUpLevelProps, M as MediaPanelHeadProps, g as MediaPickKind, h as EditNoticeProps } from '../types-DGcCsxs8.js';
3
+ export { i as DEFAULT_PANEL_W, j as DeviceOption, k as MAX_PANEL_W, l as MIN_PANEL_W, m as PanelSide, n as PanelWidths, R as RailWordsShown, S as SaveTone, o as clampPanelWidth, p as panelWidthVars, s as setPanelWidthVars } from '../types-DGcCsxs8.js';
4
4
  import { LockWords, EditAccess, SaveConflict } from '../edit-lock/index.js';
5
- import { N as NoticeWords } from '../words-DagJdwIA.js';
6
- export { C as ChromeWords } from '../words-DagJdwIA.js';
7
- import '../types-DNrn_w4V.js';
8
- import '../wordFit-9B9nqyf3.js';
5
+ import { N as NoticeWords } from '../words-AHHfiaRY.js';
6
+ export { C as ChromeWords } from '../words-AHHfiaRY.js';
7
+ import '../types-DWS-s9z-.js';
8
+ import '../wordFit-D4S36PvB.js';
9
9
 
10
10
  /**
11
11
  * The editor's top bar — 52px, white, a soft shadow, three clusters.
@@ -21,7 +21,7 @@ import '../wordFit-9B9nqyf3.js';
21
21
  *
22
22
  * Hook-free, directive-free: a server component may import it.
23
23
  */
24
- declare function EditorTopBar({ children }: TopBarProps): react.JSX.Element;
24
+ declare function EaselTopBar({ children }: TopBarProps): react.JSX.Element;
25
25
  declare function TopBarCluster({ kind, style, children }: TopBarClusterProps): react.JSX.Element;
26
26
  /**
27
27
  * The bar's ONE divider: between what you did (undo / redo) and what you are
@@ -31,7 +31,7 @@ declare function TopBarDivider(): react.JSX.Element;
31
31
 
32
32
  /**
33
33
  * The rail in the top bar: the left column of the bar (exactly the left panel's
34
- * width, carrying its hairline — `.es-cluster--rail`) holding an `EditorRail` in
34
+ * width, carrying its hairline — `.es-cluster--rail`) holding an `EaselRail` in
35
35
  * `orientation="row"`, wearing its words by THE SETTINGS TABS' RULE (owner,
36
36
  * 2026-09-18: "the rule must be the same as the top tabs of the right settings
37
37
  * panel"):
@@ -52,8 +52,16 @@ declare function TopBarDivider(): react.JSX.Element;
52
52
  * rail in the page) once, again when the labels change, and once the web fonts
53
53
  * have loaded. On a server, and anywhere a canvas cannot measure, there is no
54
54
  * measurement and the rail is icon-only, which always fits.
55
+ *
56
+ * AND A HOST MAY ASK WHICH STATE IT IS IN (`onWords`; second host, 2026-10-07).
57
+ * A longer language drops its words sooner — German "Zurück" and "Ebenen"
58
+ * where English has "Back" and "Layers" — and because the choosing is CSS's, a
59
+ * host had no way to see that it had happened. The answer is READ BACK from
60
+ * what the stylesheet drew (a clipped word is 0 wide), never worked out a
61
+ * second time here, so there is still one rule. Only a host that asks pays for
62
+ * it: one ResizeObserver on the column.
55
63
  */
56
- declare function TopBarRail({ items, ariaLabel }: TopBarRailProps): react.JSX.Element;
64
+ declare function TopBarRail({ items, ariaLabel, onWords }: TopBarRailProps): react.JSX.Element;
57
65
 
58
66
  /**
59
67
  * A 30px glyph button in the top bar — undo, redo, the panel toggles.
@@ -62,7 +70,7 @@ declare function TopBarRail({ items, ariaLabel }: TopBarRailProps): react.JSX.El
62
70
  * icon-only button has no other name, and "button" is all a screen reader would
63
71
  * say. `state` is for a toggle; a plain action leaves it off.
64
72
  */
65
- declare function EditorIconButton({ label, onClick, disabled, state, buttonRef, children }: EditorIconButtonProps): react.JSX.Element;
73
+ declare function EaselIconButton({ label, onClick, disabled, state, buttonRef, children }: EaselIconButtonProps): react.JSX.Element;
66
74
 
67
75
  /**
68
76
  * Which device the canvas previews — icon-only, one button held down.
@@ -133,17 +141,62 @@ declare function InspectorHead({ icon, name, kind, actions }: InspectorHeadProps
133
141
  /** A 28px glyph button in the inspector head. Named, like every icon-only button. */
134
142
  declare function InspectorIconButton({ label, title, hasPopup, onClick, disabled, danger, expanded, buttonRef, children, }: InspectorIconButtonProps): react.JSX.Element;
135
143
  /**
136
- * ↰ GO UP ONE LEVEL — one row at the top of the settings panel, naming the
137
- * level above what is selected and selecting it when pressed. Lifted from the
138
- * campaign designer's UpLevelControl (card 66042), where it moved off the
139
- * canvas so a merchant could climb TWICE (Block → Column → Section).
144
+ * ← GO UP ONE LEVEL — a blue text link naming the level above what is open,
145
+ * selecting it when pressed. Lifted from the campaign designer's UpLevelControl
146
+ * (card 66042), where it moved off the canvas so a merchant could climb TWICE
147
+ * (Block → Column → Section).
148
+ *
149
+ * ONE LOOK IN BOTH EDITORS (Lewis, 2026-10-06, card [MERGE] One Up-One-Level
150
+ * Link In Both Editors). There were three: this row ("↰ Columns", a filled
151
+ * hover row), the website part panel's "‹ Back" and the Locations panel's
152
+ * "← Locations". He picked the Locations panel's: the arrow and the parent's
153
+ * name in the accent colour, no box, no fill, no hover change. The arrow is
154
+ * drawn here, so a host passes no glyph, and the words are always WHERE IT
155
+ * GOES — the parent's name, never "Back".
140
156
  *
141
- * The WHOLE row is the button, glyph and name: the name of where you are going
142
- * is the part that reads as the thing to press. The host renders nothing when
157
+ * The whole link is the button, arrow and name. The host renders nothing when
143
158
  * there is no level above (efficient-easel/node-ops `parentStep` says so) — a
144
159
  * dead control would be permanent furniture on the level selected most.
160
+ *
161
+ * `inline` drops the panel-top inset, for a level inside the panel body (an
162
+ * open list item, a sub-panel): the link is the same, only where it sits
163
+ * differs.
164
+ */
165
+ declare function InspectorUpLevel({ name, onSelect, label, inline }: InspectorUpLevelProps): react.JSX.Element;
166
+
167
+ /**
168
+ * THE MEDIA PANEL'S HEAD — one part for both editors (card [MERGE] One Media
169
+ * Panel Head For Both Editors, owner ruling 2026-10-06: a part exists once, in
170
+ * efficient-easel).
171
+ *
172
+ * The Media Library under it was already one component, the admin portal's,
173
+ * drawn narrow in a left panel. Its head was drawn twice: by the campaign
174
+ * designer (`EmailMediaPanel`) and by the website editor (`MediaSidePanel` on
175
+ * its `SidePanelHead`). Both were this shape on `InspectorHead`; where they
176
+ * differed, the website editor's won (GG, 2026-10-06):
177
+ *
178
+ * browsing [media] Media library │ [hide]
179
+ * <the site or campaign>
180
+ * picking [image] Choose image [Cancel] │ [hide]
181
+ * For Background image
182
+ *
183
+ * • choosing is a MODE over the panel, so the head says so and names its way
184
+ * out in a WORD. Cancel leaves the field as it was; what the panel shows
185
+ * next is the host's to decide (both go back to the view before);
186
+ * • the kind word is what the field can hold: image, video or SVG logo
187
+ * ({@link mediaPickKind} reads it from the field's `accept`);
188
+ * • a pick with no field name keeps the browsing context line;
189
+ * • Hide panel is always last, after a hairline when Cancel is there, and is
190
+ * not drawn at all where the panel cannot be hidden (no `onHide`). There
191
+ * is no ✕ in a panel head: ✕ closes windows.
192
+ */
193
+ declare function MediaPanelHead({ context, pick, onCancel, onHide, side }: MediaPanelHeadProps): react.JSX.Element;
194
+ /**
195
+ * What a field can hold, from the `accept` it asks with: `image/svg+xml` is an
196
+ * SVG logo, `video/*` a video, anything else an image. The website editor's
197
+ * rule (`pickNoun`), lifted with its head.
145
198
  */
146
- declare function InspectorUpLevel({ name, onSelect, icon, label }: InspectorUpLevelProps): react.JSX.Element;
199
+ declare function mediaPickKind(accept: string): MediaPickKind;
147
200
 
148
201
  /**
149
202
  * The bar that says why edits are not being saved — somebody else holds the
@@ -201,7 +254,7 @@ type EditNoticeContent = {
201
254
  /**
202
255
  * The two groups of words a notice is written in: its own sentences, and the
203
256
  * edit lock's "2 minutes ago" / "Someone else". The whole catalogue fits —
204
- * `editNotice(access, conflict, noun, useEditorStrings())`.
257
+ * `editNotice(access, conflict, noun, useEaselStrings())`.
205
258
  */
206
259
  type EditNoticeWords = {
207
260
  notice: NoticeWords;
@@ -216,4 +269,4 @@ type EditNoticeWords = {
216
269
  */
217
270
  declare function editNotice(access: EditAccess, conflict: SaveConflict | null, noun: string, words?: EditNoticeWords): EditNoticeContent | null;
218
271
 
219
- export { DeviceSwitch, DeviceSwitchProps, EditNotice, type EditNoticeAction, type EditNoticeContent, EditNoticeProps, type EditNoticeWords, EditorIconButton, EditorIconButtonProps, EditorTopBar, InspectorHead, InspectorHeadProps, InspectorIconButton, InspectorIconButtonProps, InspectorUpLevel, InspectorUpLevelProps, NoticeWords, PanelResizeHandle, PanelResizeHandleProps, SaveState, SaveStateProps, SaveStateToggle, SaveStateToggleProps, TopBarCluster, TopBarClusterProps, TopBarDivider, TopBarProps, TopBarRail, editNotice };
272
+ export { DeviceSwitch, DeviceSwitchProps, EaselIconButton, EaselIconButtonProps, EaselTopBar, EditNotice, type EditNoticeAction, type EditNoticeContent, EditNoticeProps, type EditNoticeWords, InspectorHead, InspectorHeadProps, InspectorIconButton, InspectorIconButtonProps, InspectorUpLevel, InspectorUpLevelProps, MediaPanelHead, MediaPanelHeadProps, MediaPickKind, NoticeWords, PanelResizeHandle, PanelResizeHandleProps, SaveState, SaveStateProps, SaveStateToggle, SaveStateToggleProps, TopBarCluster, TopBarClusterProps, TopBarDivider, TopBarProps, TopBarRail, TopBarRailProps, editNotice, mediaPickKind };
@@ -1,21 +1,17 @@
1
- import{DEFAULT_NOTICE_WORDS as e,DEFAULT_CHROME_WORDS as n}from"../chunk-KDIVA6WD.js";import{holderOf as t,describeAge as i,nameOrSomeone as a}from"../chunk-TDA4HH54.js";import{DEFAULT_LOCK_WORDS as r}from"../chunk-RE4LP46F.js";import{railTokens as o,EditorRail as s}from"../chunk-IBOFSS56.js";import{DEFAULT_RAIL_WORDS as l}from"../chunk-2OAZYSWJ.js";import{useWords as c}from"../chunk-MFIRYGHW.js";import"../chunk-BZ5ASXOL.js";import{jsx as d,jsxs as u}from"react/jsx-runtime";import{useRef as m,useState as p,useCallback as v,useEffect as h,useLayoutEffect as b}from"react";function f({children:e}){/* @__PURE__ */
2
- return d("div",{className:"es-topbar",children:e})}function k({kind:e,style:n,children:t}){/* @__PURE__ */
3
- return d("div",{className:e?`es-cluster es-cluster--${e}`:"es-cluster",style:n,children:t})}function g(){/* @__PURE__ */
4
- return d("div",{className:"es-divider-v","aria-hidden":"true"})}var y="undefined"==typeof window?h:b;function w({items:e,ariaLabel:n}){const t=c("rail",l),i=m(null),[a,r]=p(void 0),u=JSON.stringify(e.map(e=>e.label));return y(()=>{const n=i.current?.querySelector(".es-rail");if(!n)return;const t=document.createElement("canvas").getContext?.("2d")??null,a=()=>{if(!t)return r(void 0);const i=function(e,n,t){const i=parseFloat(getComputedStyle(e).getPropertyValue(n));return Number.isFinite(i)?i:t}(n,"--es-rail-word-size",o.wordFontSize),a=getComputedStyle(n).getPropertyValue("--es-rail-word-weight").trim()||String(o.wordFontWeight),s=getComputedStyle(n.querySelector(".es-rail-btn")??n).fontFamily;t.font=`${a} ${i}px ${s}`;const l=e.map(e=>t.measureText(e.label).width),c=e=>Math.ceil(4*e)/4;r({labelsPx:c(l.reduce((e,n)=>e+n,0)),widestLabelPx:c(Math.max(0,...l))})};a();let s=!0;return document.fonts?.ready.then(()=>s&&a()),()=>{s=!1}},[u]),/* @__PURE__ */d("div",{ref:i,className:"es-cluster es-cluster--rail es-rail-fit",children:/* @__PURE__ */d(s,{items:e,ariaLabel:n??t.label,orientation:"row",wordFit:a})})}function N({label:e,onClick:n,disabled:t,state:i,buttonRef:a,children:r}){/* @__PURE__ */
5
- return d("button",{ref:a,type:"button",className:i?`es-iconbtn es-iconbtn--${i}`:"es-iconbtn",title:e,"aria-label":e,disabled:t,onClick:n,children:r})}function x({devices:e,value:t,onChange:i,ariaLabel:a}){const r=c("chrome",n);/* @__PURE__ */
6
- return d("div",{className:"es-devseg",role:"group","aria-label":a??r.device,children:e.map(e=>{const n=e.id===t;/* @__PURE__ */
7
- return d("button",{type:"button",title:e.label,"aria-label":e.label,"aria-pressed":n,className:n?"is-active":void 0,onClick:()=>{n||i(e.id)},children:e.icon},e.id)})})}var C={idle:"is-quiet",saved:"is-quiet is-saved",saving:"is-saving",error:"is-error",off:"is-off","off-unsaved":"is-off is-unsaved"};function O({tone:e,label:n,counting:t,waitMs:i,ringRef:a,role:r}){/* @__PURE__ */
8
- return u("span",{className:`es-savestate ${C[e]}`,role:r,"aria-live":"polite",children:[/* @__PURE__ */d("span",t?{ref:a,className:"es-savestate-ring is-counting",style:void 0!==i?{"--es-savewait":`${i}ms`}:void 0,"aria-hidden":"true"}:{className:"es-savestate-dot","aria-hidden":"true"}),n]})}function S({pressed:e,title:n,onToggle:t,children:i}){/* @__PURE__ */
9
- return d("button",{type:"button",className:"es-savestate-toggle","aria-pressed":e,title:n,onClick:t,children:i})}var P="es-col-resizing";function L({side:e,width:t,min:i,max:a,defaultWidth:r,label:o,onResize:s}){const l=c("chrome",n),u=m(null),p=v((n,t)=>{const r="left"===e?n+t:n-t;return Math.round(Math.min(a,Math.max(i,r)))},[e,i,a]),b=v(e=>{u.current&&(u.current=null,document.body.classList.remove(P),e.currentTarget.hasPointerCapture(e.pointerId)&&e.currentTarget.releasePointerCapture(e.pointerId))},[]),f=v(e=>{0===e.button&&(u.current={x:e.clientX,w:t,moved:!1},e.currentTarget.setPointerCapture(e.pointerId),document.body.classList.add(P))},[t]),k=v(e=>{const n=u.current;if(!n)return;if(0===e.buttons)return void b(e);const t=e.clientX-n.x;if(!n.moved){if(Math.abs(t)<3)return;n.moved=!0}s(p(n.w,t))},[s,p,b]),g=v(e=>{"ArrowLeft"===e.key?(e.preventDefault(),s(e=>p(e,-16))):"ArrowRight"===e.key?(e.preventDefault(),s(e=>p(e,16))):"Home"===e.key&&(e.preventDefault(),s(r))},[s,p,r]);return h(()=>()=>document.body.classList.remove(P),[]),/* @__PURE__ */d("div",{className:`es-resizer es-resizer--${e}`,role:"separator",tabIndex:0,"aria-orientation":"vertical","aria-label":o,"aria-valuenow":t,"aria-valuemin":i,"aria-valuemax":a,title:l.resize,onPointerDown:f,onPointerMove:k,onPointerUp:b,onPointerCancel:b,onLostPointerCapture:b,onDoubleClick:()=>s(r),onKeyDown:g,children:/* @__PURE__ */d("span",{className:"es-resizer-bar","aria-hidden":"true"})})}function M({icon:e,name:n,kind:t,actions:i}){/* @__PURE__ */
10
- return u("div",{className:"es-insp-head",children:[
11
- /* @__PURE__ */d("span",{className:"es-insp-chip","aria-hidden":"true",children:e}),
12
- /* @__PURE__ */u("div",{className:"es-insp-titles",children:[
13
- /* @__PURE__ */d("h2",{className:"es-insp-name",children:n}),
14
- /* @__PURE__ */d("div",{className:"es-insp-kind",children:t})]}),i?/* @__PURE__ */d("div",{className:"es-insp-actions",children:i}):null]})}function B({label:e,title:n,hasPopup:t,onClick:i,disabled:a,danger:r,expanded:o,buttonRef:s,children:l}){/* @__PURE__ */
15
- return d("button",{ref:s,type:"button",className:r?"es-insp-iconbtn es-insp-iconbtn--danger":"es-insp-iconbtn",title:n??e,"aria-label":e,"aria-haspopup":t,"aria-expanded":o,disabled:a,onClick:i,children:l})}function $({name:e,onSelect:t,icon:i,label:a}){const r=c("chrome",n),o=a??r.upLevel;/* @__PURE__ */
16
- return d("div",{className:"es-insp-up",children:/* @__PURE__ */u("button",{type:"button",className:"es-insp-up-btn",title:o,"aria-label":r.upLevelTo({label:o,name:e}),onClick:t,children:[i?/* @__PURE__ */d("span",{className:"es-insp-up-icon","aria-hidden":"true",children:i}):null,
17
- /* @__PURE__ */d("span",{className:"es-insp-up-name",children:e})]})})}var D={notice:e,lock:r};function R(e,n,r,o=D){const s=o.notice,l=t(e),c={kind:"reload",label:s.reload};if(n){const e=i(n.secondsAgo,o.lock);return{tone:"warning",urgent:!0,lead:n.savedByYou?s.savedByYou({noun:r,when:e}):s.savedByOther({name:a(n.savedBy,o.lock),noun:r,when:e}),body:s.conflictBody,actions:l?[c,{kind:"take-over",label:s.takeOver,title:s.takeOverWhileDeciding}]:[c]}}if(!l)return null;const d=a(l.name,o.lock),u=i(l.secondsSinceSeen,o.lock);switch(e.kind){case"takenover":return{tone:"warning",urgent:!0,lead:s.tookOver({name:d,noun:r,when:i(l.secondsSinceHeld,o.lock)}),body:s.tookOverBody,actions:[{kind:"take-back",label:s.takeBack},c]};case"readonly":return{tone:"neutral",urgent:!1,lead:s.viewingOnly,body:s.viewingOnlyBody({name:d,noun:r,seen:u}),actions:[{kind:"take-over",label:s.takeOver}]};default:return{tone:"warning",urgent:!1,lead:s.editing({name:d,noun:r}),body:s.editingBody({seen:u}),actions:[{kind:"view-read-only",label:s.viewReadOnly},{kind:"take-over",label:s.takeOver,title:s.takeOverTold}]}}}function F({access:n,conflict:t,noun:i,onTakeOver:a,onViewReadOnly:o,onReload:s}){const l=R(n,t,i,{notice:c("notice",e),lock:c("lock",r)});if(!l)return null;const m={reload:s,"take-over":a,"take-back":a,"view-read-only":o};/* @__PURE__ */
18
- return u("div",{className:`es-notice is-${l.tone}`,role:l.urgent?"alert":"status",children:[
19
- /* @__PURE__ */u("span",{className:"es-notice-text",children:[
20
- /* @__PURE__ */d("strong",{children:l.lead})," ",l.body]}),
21
- /* @__PURE__ */d("span",{className:"es-notice-actions",children:l.actions.map(e=>/* @__PURE__ */d("button",{type:"button",className:"es-notice-btn",title:e.title,onClick:m[e.kind],children:e.label},e.kind))})]})}var T={left:288,right:320},j=220,z=560;function A(e){return Math.min(560,Math.max(220,Math.round(e)))}function I(e){return{"--es-left-w":`${e.left}px`,"--es-right-w":`${e.right}px`}}export{T as DEFAULT_PANEL_W,x as DeviceSwitch,F as EditNotice,N as EditorIconButton,f as EditorTopBar,M as InspectorHead,B as InspectorIconButton,$ as InspectorUpLevel,z as MAX_PANEL_W,j as MIN_PANEL_W,L as PanelResizeHandle,O as SaveState,S as SaveStateToggle,k as TopBarCluster,g as TopBarDivider,w as TopBarRail,A as clampPanelWidth,R as editNotice,I as panelWidthVars};
1
+ import{holderOf as e,describeAge as t,nameOrSomeone as n}from"../chunk-JUQ6YJCG.js";import{DEFAULT_LOCK_WORDS as r}from"../chunk-RE4LP46F.js";import{InspectorIconButton as i,InspectorHead as o}from"../chunk-MH5GUZFQ.js";export{InspectorHead,InspectorIconButton,InspectorUpLevel}from"../chunk-MH5GUZFQ.js";import{DEFAULT_NOTICE_WORDS as a,DEFAULT_CHROME_WORDS as s}from"../chunk-ZJEBF4NB.js";import{railTokens as l,EaselRail as c}from"../chunk-WZ7TGAAT.js";import{DEFAULT_RAIL_WORDS as d}from"../chunk-2OAZYSWJ.js";import{useWords as u}from"../chunk-MFIRYGHW.js";import"../chunk-BZ5ASXOL.js";import{PanelLeftIcon as m,PanelRightIcon as v,MediaIcon as f,ImageIcon as h}from"../chunk-6EIVTKZZ.js";import{jsx as p,jsxs as b,Fragment as k}from"react/jsx-runtime";import{useRef as g,useState as y,useCallback as w,useEffect as x,useLayoutEffect as C}from"react";function N({children:e}){/* @__PURE__ */
2
+ return p("div",{className:"es-topbar",children:e})}function O({kind:e,style:t,children:n}){/* @__PURE__ */
3
+ return p("div",{className:e?`es-cluster es-cluster--${e}`:"es-cluster",style:t,children:n})}function P(){/* @__PURE__ */
4
+ return p("div",{className:"es-divider-v","aria-hidden":"true"})}var B="undefined"==typeof window?x:C;function L({items:e,ariaLabel:t,onWords:n}){const r=u("rail",d),i=g(null),[o,a]=y(void 0),[s,m]=y(null),v=JSON.stringify(e.map(e=>e.label));B(()=>{const t=i.current?.querySelector(".es-rail");if(!t)return;const n=document.createElement("canvas").getContext?.("2d")??null,r=()=>{if(m(v),!n)return a(void 0);const r=function(e,t,n){const r=parseFloat(getComputedStyle(e).getPropertyValue(t));return Number.isFinite(r)?r:n}(t,"--es-rail-word-size",l.wordFontSize),i=getComputedStyle(t).getPropertyValue("--es-rail-word-weight").trim()||String(l.wordFontWeight),o=getComputedStyle(t.querySelector(".es-rail-btn")??t).fontFamily;n.font=`${i} ${r}px ${o}`;const s=e.map(e=>n.measureText(e.label).width),c=e=>Math.ceil(4*e)/4;a({labelsPx:c(s.reduce((e,t)=>e+t,0)),widestLabelPx:c(Math.max(0,...s))})};r();let o=!0;return document.fonts?.ready.then(()=>o&&r()),()=>{o=!1}},[v]);const f=g(n);f.current=n;const h=g(null),b=Boolean(n),k=e.map(e=>e.active?"1":"0").join("");return B(()=>{const e=i.current;if(!b||!e||s!==v)return;const t=()=>{const t=Array.from(e.querySelectorAll(".es-rail-word")),n=t.filter(e=>e.getBoundingClientRect().width>0).length,r=t.length>0&&n===t.length?"all":n>0?"chosen":"none";r!==h.current&&(h.current=r,f.current?.(r))};t();const n=e.ownerDocument.defaultView?.ResizeObserver,r=n?new n(t):null;return r?.observe(e),()=>r?.disconnect()},[b,s,v,o,k]),/* @__PURE__ */p("div",{ref:i,className:"es-cluster es-cluster--rail es-rail-fit",children:/* @__PURE__ */p(c,{items:e,ariaLabel:t??r.label,orientation:"row",wordFit:o})})}function M({label:e,onClick:t,disabled:n,state:r,buttonRef:i,children:o}){/* @__PURE__ */
5
+ return p("button",{ref:i,type:"button",className:r?`es-iconbtn es-iconbtn--${r}`:"es-iconbtn",title:e,"aria-label":e,disabled:n,onClick:t,children:o})}function S({devices:e,value:t,onChange:n,ariaLabel:r}){const i=u("chrome",s);/* @__PURE__ */
6
+ return p("div",{className:"es-devseg",role:"group","aria-label":r??i.device,children:e.map(e=>{const r=e.id===t;/* @__PURE__ */
7
+ return p("button",{type:"button",title:e.label,"aria-label":e.label,"aria-pressed":r,className:r?"is-active":void 0,onClick:()=>{r||n(e.id)},children:e.icon},e.id)})})}var $={idle:"is-quiet",saved:"is-quiet is-saved",saving:"is-saving",error:"is-error",off:"is-off","off-unsaved":"is-off is-unsaved"};function j({tone:e,label:t,counting:n,waitMs:r,ringRef:i,role:o}){/* @__PURE__ */
8
+ return b("span",{className:`es-savestate ${$[e]}`,role:o,"aria-live":"polite",children:[/* @__PURE__ */p("span",n?{ref:i,className:"es-savestate-ring is-counting",style:void 0!==r?{"--es-savewait":`${r}ms`}:void 0,"aria-hidden":"true"}:{className:"es-savestate-dot","aria-hidden":"true"}),t]})}function F({pressed:e,title:t,onToggle:n,children:r}){/* @__PURE__ */
9
+ return p("button",{type:"button",className:"es-savestate-toggle","aria-pressed":e,title:t,onClick:n,children:r})}var z="es-col-resizing";function R({side:e,width:t,min:n,max:r,defaultWidth:i,label:o,onResize:a}){const l=u("chrome",s),c=g(null),d=w((t,i)=>{const o="left"===e?t+i:t-i;return Math.round(Math.min(r,Math.max(n,o)))},[e,n,r]),m=w(e=>{c.current&&(c.current=null,document.body.classList.remove(z),e.currentTarget.hasPointerCapture(e.pointerId)&&e.currentTarget.releasePointerCapture(e.pointerId))},[]),v=w(e=>{0===e.button&&(c.current={x:e.clientX,w:t,moved:!1},e.currentTarget.setPointerCapture(e.pointerId),document.body.classList.add(z))},[t]),f=w(e=>{const t=c.current;if(!t)return;if(0===e.buttons)return void m(e);const n=e.clientX-t.x;if(!t.moved){if(Math.abs(n)<3)return;t.moved=!0}a(d(t.w,n))},[a,d,m]),h=w(e=>{"ArrowLeft"===e.key?(e.preventDefault(),a(e=>d(e,-16))):"ArrowRight"===e.key?(e.preventDefault(),a(e=>d(e,16))):"Home"===e.key&&(e.preventDefault(),a(i))},[a,d,i]);return x(()=>()=>document.body.classList.remove(z),[]),/* @__PURE__ */p("div",{className:`es-resizer es-resizer--${e}`,role:"separator",tabIndex:0,"aria-orientation":"vertical","aria-label":o,"aria-valuenow":t,"aria-valuemin":n,"aria-valuemax":r,title:l.resize,onPointerDown:v,onPointerMove:f,onPointerUp:m,onPointerCancel:m,onLostPointerCapture:m,onDoubleClick:()=>a(i),onKeyDown:h,children:/* @__PURE__ */p("span",{className:"es-resizer-bar","aria-hidden":"true"})})}function I({context:e,pick:t,onCancel:n,onHide:r,side:a="left"}){const l=u("chrome",s),c=r?/* @__PURE__ */p(i,{label:l.hidePanelLabel({side:a}),title:l.hidePanel,onClick:r,children:/* @__PURE__ */p("left"===a?m:v,{size:16})}):null;if(!t)/* @__PURE__ */
10
+ return p(o,{icon:/* @__PURE__ */p(f,{}),name:l.mediaLibrary,kind:e,actions:c??void 0});const d=l.mediaKinds[t.kind];/* @__PURE__ */
11
+ return p(o,{icon:/* @__PURE__ */p(h,{size:15}),name:l.mediaChoose({kind:d}),kind:t.field?l.mediaFor({field:t.field}):e,actions:/* @__PURE__ */b(k,{children:[
12
+ /* @__PURE__ */p("button",{type:"button",className:"es-btn-ghost es-insp-textbtn",title:l.mediaKeep({kind:d}),onClick:n,children:l.mediaCancel}),c?/* @__PURE__ */b(k,{children:[
13
+ /* @__PURE__ */p("span",{className:"es-insp-divider","aria-hidden":"true"}),c]}):null]})})}function T(e){return/svg/i.test(e)?"svg":e.startsWith("video")?"video":"image"}var A={notice:a,lock:r};function D(r,i,o,a=A){const s=a.notice,l=e(r),c={kind:"reload",label:s.reload};if(i){const e=t(i.secondsAgo,a.lock);return{tone:"warning",urgent:!0,lead:i.savedByYou?s.savedByYou({noun:o,when:e}):s.savedByOther({name:n(i.savedBy,a.lock),noun:o,when:e}),body:s.conflictBody,actions:l?[c,{kind:"take-over",label:s.takeOver,title:s.takeOverWhileDeciding}]:[c]}}if(!l)return null;const d=n(l.name,a.lock),u=t(l.secondsSinceSeen,a.lock);switch(r.kind){case"takenover":return{tone:"warning",urgent:!0,lead:s.tookOver({name:d,noun:o,when:t(l.secondsSinceHeld,a.lock)}),body:s.tookOverBody,actions:[{kind:"take-back",label:s.takeBack},c]};case"readonly":return{tone:"neutral",urgent:!1,lead:s.viewingOnly,body:s.viewingOnlyBody({name:d,noun:o,seen:u}),actions:[{kind:"take-over",label:s.takeOver}]};default:return{tone:"warning",urgent:!1,lead:s.editing({name:d,noun:o}),body:s.editingBody({seen:u}),actions:[{kind:"view-read-only",label:s.viewReadOnly},{kind:"take-over",label:s.takeOver,title:s.takeOverTold}]}}}function W({access:e,conflict:t,noun:n,onTakeOver:i,onViewReadOnly:o,onReload:s}){const l=D(e,t,n,{notice:u("notice",a),lock:u("lock",r)});if(!l)return null;const c={reload:s,"take-over":i,"take-back":i,"view-read-only":o};/* @__PURE__ */
14
+ return b("div",{className:`es-notice is-${l.tone}`,role:l.urgent?"alert":"status",children:[
15
+ /* @__PURE__ */b("span",{className:"es-notice-text",children:[
16
+ /* @__PURE__ */p("strong",{children:l.lead})," ",l.body]}),
17
+ /* @__PURE__ */p("span",{className:"es-notice-actions",children:l.actions.map(e=>/* @__PURE__ */p("button",{type:"button",className:"es-notice-btn",title:e.title,onClick:c[e.kind],children:e.label},e.kind))})]})}var Z={left:288,right:320},H=220,q=560;function G(e){return Math.min(560,Math.max(220,Math.round(e)))}function J(e){return{"--es-left-w":`${e.left}px`,"--es-right-w":`${e.right}px`}}function U(e,t){e.style.setProperty("--es-left-w",`${t.left}px`),e.style.setProperty("--es-right-w",`${t.right}px`)}export{Z as DEFAULT_PANEL_W,S as DeviceSwitch,M as EaselIconButton,N as EaselTopBar,W as EditNotice,q as MAX_PANEL_W,H as MIN_PANEL_W,I as MediaPanelHead,R as PanelResizeHandle,j as SaveState,F as SaveStateToggle,O as TopBarCluster,P as TopBarDivider,L as TopBarRail,G as clampPanelWidth,D as editNotice,T as mediaPickKind,J as panelWidthVars,U as setPanelWidthVars};
@@ -0,0 +1 @@
1
+ var e={dragHint:"Drag to move · ⌥↑ ⌥↓",collapse:"Collapse",expand:"Expand",collapseNamed:({label:e})=>`Collapse ${e}`,expandNamed:({label:e})=>`Expand ${e}`,emptySlot:"No blocks yet",addBlock:"Add a block",dropHere:"Drop here"};export{e as DEFAULT_TREE_WORDS};
@@ -0,0 +1 @@
1
+ import{zoneKey as e}from"./chunk-KRXQM65X.js";import{useRef as t,useEffect as n,useState as r,useSyncExternalStore as o,useCallback as i}from"react";var l=56,c=16;function a(e){const t=Math.max(e,0);return t>=l?0:Math.ceil(16*(1-t/l))}function u(e,t,n){if(e<t-l||e>n+l)return 0;const r=e-t,o=n-e;return r<l&&r<=o?-a(r):o<l?a(o):0}function s(e){const t=e?.ownerDocument?.defaultView;for(let n=e?.parentElement??null;n;n=n.parentElement){const e=t?.getComputedStyle(n).overflowY;if(("auto"===e||"scroll"===e)&&n.scrollHeight>n.clientHeight)return n}return null}function f(e){const t=e?.ownerDocument?.defaultView?.getComputedStyle(e).overflowY;return e&&("auto"===t||"scroll"===t)&&e.scrollHeight>e.clientHeight?e:s(e)}function d(e){const t=e.scrollingElement??e.documentElement;return t&&t.scrollHeight>t.clientHeight?t:null}function g(e,t=e){const n=t.ownerDocument,r=n.defaultView;if(!r)return()=>{};let o=null,i=0;const l=e=>{o=e.clientY},c=()=>{if(null!==o){const n=t.getBoundingClientRect(),r=u(o,n.top,n.bottom);r&&(e.scrollTop+=r)}i=r.requestAnimationFrame(c)};return n.addEventListener("dragover",l,!0),i=r.requestAnimationFrame(c),()=>{n.removeEventListener("dragover",l,!0),r.cancelAnimationFrame(i)}}function p(e){return/move|all|uninitialized/i.test(e)?"move":"copy"}function m(){let e=null,t=null;const n=/* @__PURE__ */new Set,r=()=>{if(t!==e){t=e;for(const e of[...n])e()}};return{get:()=>e,shown:()=>t,start(t){e=t,globalThis.setTimeout(r,0)},end(){null===e&&null===t||(e=null,r())},subscribe:e=>(n.add(e),()=>{n.delete(e)})}}function v(e,t,n,r){if(e.into)return{side:"into",to:e.into};return"first"===e.pinned||"last"!==e.pinned&&t>n+r/2?{side:"after",to:{...e.place,index:e.place.index+1}}:{side:"before",to:{...e.place,index:e.place.index}}}var D=(t,n)=>e(t)===e(n);function w(e,t){return D(e,t)&&(t.index===e.index||t.index===e.index+1)}function y(e,t){return D(e,t)&&e.index<t.index?t.index-1:t.index}function x(e,t){return{...e,index:t<0?e.index-1:e.index+2}}function h(e,t){if(!t)return e;const n={...t,...e};for(const[r,o]of Object.entries(e)){const e=t[r];"function"==typeof o&&"function"==typeof e&&(n[r]=t=>{o(t),e(t)})}return n}function T(l){const c=t(l);n(()=>{c.current=l});const[a]=r(()=>m()),u=l.session??a,d=o(u.subscribe,u.shown,u.shown),[D,y]=r(null),x=t(null),T=i(()=>{x.current?.(),x.current=null},[]),b=i(()=>{T(),u.end(),y(null)},[u,T]);n(()=>u.subscribe(()=>{u.get()||(T(),y(null))}),[u,T]),n(()=>T,[T]);const k=i((e,t)=>{y(n=>n&&n.key===e&&n.side===t?n:{key:e,side:t})},[]),E=i(e=>{y(t=>t&&t.key===e?null:t)},[]),A=(e,t,n,r)=>!("into"===n?r===e.key:void 0!==e.from&&w(e.from,t))&&c.current.canDrop(e.item,t);return{dragging:d?.item??null,row:(e,t)=>{const{keyOf:n,readOnly:r}=c.current,o=n(e.item),i=!r&&!e.pinned&&!1!==e.canDrag,l=t=>{const n=t.currentTarget.getBoundingClientRect();return v(e,t.clientY,n.top,n.height)},a={draggable:i||void 0,onDragStart:i?t=>{const n=t.currentTarget;u.start({key:o,item:e.item,from:e.place}),t.dataTransfer.effectAllowed="move";try{t.dataTransfer.setData("text/plain",o)}catch{}n.classList.add("is-lifting");const r=n.getBoundingClientRect();t.dataTransfer.setDragImage?.(n,t.clientX-r.left,t.clientY-r.top),n.ownerDocument.defaultView?.setTimeout(()=>n.classList.remove("is-lifting"),0);const i=s(n);T(),x.current=i?g(i):null}:void 0,onDragEnd:i?()=>b():void 0,onDragOver:e=>{const t=u.get();if(!t)return;const n=l(e);A(t,n.to,n.side,o)?(e.preventDefault(),e.dataTransfer.dropEffect=p(e.dataTransfer.effectAllowed),k(o,n.side)):E(o)},onDrop:e=>{const t=u.get();if(!t)return;const n=l(e);A(t,n.to,n.side,o)&&(e.preventDefault(),b(),c.current.onDrop(t.item,n.to))},onKeyDown:t=>{if("ArrowUp"!==t.key&&"ArrowDown"!==t.key)return;if(!t.altKey||t.ctrlKey||t.metaKey||t.shiftKey)return;if(t.preventDefault(),t.repeat||!i)return;const{onStep:n,canStep:r}=c.current,o="ArrowUp"===t.key?-1:1;n&&!1!==r?.(e.item,o)&&n(e.item,o)}};return{draggable:i,dragging:d?.key===o,drop:D?.key===o?D.side:void 0,rowProps:h(a,t)}},seam:(t,n)=>{const r=(o=t.place,`seam:${e(o)}:${o.index}`);var o;const i={onDragOver:e=>{const n=u.get();n&&(A(n,t.place,"before",r)?(e.preventDefault(),e.dataTransfer.dropEffect=p(e.dataTransfer.effectAllowed),k(r,"before")):E(r))},onDrop:e=>{const n=u.get();n&&A(n,t.place,"before",r)&&(e.preventDefault(),b(),c.current.onDrop(n.item,t.place))}};return{drop:D?.key===r,seamProps:h(i,n)}},rootProps:e=>h({onDragEnter:e=>{if(!u.get()||x.current)return;const t=f(e.currentTarget);x.current=t?g(t):null},onDragLeave:e=>{const t=e.relatedTarget;t&&e.currentTarget.contains(t)||y(null)}},e)}}export{l as AUTO_SCROLL_EDGE,c as AUTO_SCROLL_MAX_SPEED,u as autoScrollDelta,a as autoScrollSpeed,m as createDragSession,p as dropEffectFor,v as dropOnRow,d as frameScrollBox,y as gapToMoveIndex,w as isNoOpDrop,f as scrollBoxOf,s as scrollParent,g as startAutoScroll,x as stepGap,T as useTreeDrag};