efficient-easel 0.96.0 → 0.98.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 (66) hide show
  1. package/README.md +98 -3
  2. package/dist/autosave/index.d.ts +4 -4
  3. package/dist/blocks/index.d.ts +15 -4
  4. package/dist/{buckets-1vRlQceY.d.ts → buckets-CuLM47h9.d.ts} +1 -1
  5. package/dist/chrome/chrome.css +25 -16
  6. package/dist/chrome/index.d.ts +6 -6
  7. package/dist/chrome/index.js +6 -6
  8. package/dist/chunk-2UX75JDP.js +1 -0
  9. package/dist/{chunk-STFMZJKU.js → chunk-66CKSTXP.js} +6 -6
  10. package/dist/{chunk-6JDII7N3.js → chunk-6PS6STGA.js} +1 -1
  11. package/dist/{chunk-EFTTSIMK.js → chunk-D2BCHTQR.js} +1 -1
  12. package/dist/{chunk-YIMRTIBN.js → chunk-IBOFSS56.js} +1 -1
  13. package/dist/chunk-KRXQM65X.js +1 -0
  14. package/dist/chunk-PI26YXYD.js +462 -0
  15. package/dist/{chunk-FJE4IDBQ.js → chunk-YRLPFZW3.js} +1 -1
  16. package/dist/copy/copy.css +5 -5
  17. package/dist/copy/index.d.ts +5 -5
  18. package/dist/copy/index.js +10 -10
  19. package/dist/data/index.d.ts +171 -4
  20. package/dist/data/index.js +1 -1
  21. package/dist/drag/drag.css +15 -15
  22. package/dist/drag/index.d.ts +1 -1
  23. package/dist/drag/index.js +15 -15
  24. package/dist/edit-lock/index.d.ts +1 -1
  25. package/dist/editor/index.d.ts +9 -9
  26. package/dist/editor/index.js +6 -6
  27. package/dist/fields/fields.css +126 -12
  28. package/dist/fields/index.d.ts +61 -13
  29. package/dist/fields/index.js +41 -34
  30. package/dist/gold/index.d.ts +1 -1
  31. package/dist/icons/index.d.ts +26 -5
  32. package/dist/icons/index.js +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/index.js +1 -1
  35. package/dist/menu/menu.css +4 -4
  36. package/dist/node-ops/index.d.ts +3 -3
  37. package/dist/node-ops/index.js +1 -1
  38. package/dist/panel/index.d.ts +10 -10
  39. package/dist/panel/panel.css +34 -25
  40. package/dist/pick/pick.css +8 -8
  41. package/dist/{plan-DtNw2VuI.d.ts → plan-DChbUXdS.d.ts} +1 -1
  42. package/dist/rail/index.d.ts +2 -2
  43. package/dist/rail/index.js +1 -1
  44. package/dist/rail/rail.css +1 -1
  45. package/dist/render/index.d.ts +2 -2
  46. package/dist/{resolve-DpH8YQOA.d.ts → resolve-D68pb3Bx.d.ts} +1 -1
  47. package/dist/shell/index.d.ts +24 -4
  48. package/dist/shell/index.js +1 -1
  49. package/dist/shell/shell.css +12 -2
  50. package/dist/strings/catalogue.d.ts +4 -4
  51. package/dist/strings/index.d.ts +4 -4
  52. package/dist/style-clipboard/index.js +1 -1
  53. package/dist/tree/index.d.ts +1 -1
  54. package/dist/tree/index.js +1 -1
  55. package/dist/tree/tree.css +11 -11
  56. package/dist/{types-DziKCwsN.d.ts → types-41704JE4.d.ts} +8 -1
  57. package/dist/{types-CEqUFH2j.d.ts → types-C7HFvdtk.d.ts} +26 -4
  58. package/dist/{types-CuNiSnX6.d.ts → types-CnRzp9oc.d.ts} +1 -1
  59. package/dist/{types-_Vayx8ov.d.ts → types-Dy6oR6Z2.d.ts} +2 -2
  60. package/dist/{useNodeOps-6IAej9jy.d.ts → useNodeOps-BF0fQsif.d.ts} +2 -2
  61. package/dist/{words-CsRWXkY4.d.ts → words-Cqmyey0s.d.ts} +2 -2
  62. package/dist/{words-DfxEp_RH.d.ts → words-bOMsUJk9.d.ts} +1 -1
  63. package/package.json +1 -1
  64. package/dist/chunk-FI23ALVJ.js +0 -1
  65. package/dist/chunk-LPRQDDQO.js +0 -1
  66. package/dist/chunk-YNZZYHA4.js +0 -450
package/README.md CHANGED
@@ -5,7 +5,7 @@ the canvas and has no say in what is painted on it: the engine never learns
5
5
  what a section is, and each editor brings its own blocks and its own data.
6
6
 
7
7
  The EFFICIENT editors' shared engine and chrome — the campaign designer
8
- (`efficient-admin-portal`) and the website editor (`efficient-shop`) draw from
8
+ (`efficient-admin-portal`) and the website editor (`efficient-storefront`) draw from
9
9
  one source instead of hand-rolling and drifting — and the engine both run on,
10
10
  which replaced Puck (`@measured/puck`) layer by layer and has carried none of
11
11
  it since 0.93.0.
@@ -18,7 +18,7 @@ it since 0.93.0.
18
18
 
19
19
  ## Why
20
20
 
21
- The storefront editor (`efficient-shop`, Next 16 + Puck) and the campaign
21
+ The storefront editor (`efficient-storefront`, Next 16 + Puck) and the campaign
22
22
  designer (`efficient-admin-portal`, Vite/React) each hand-rolled their own narrow
23
23
  left icon-rail. They had already drifted — button 34px vs 36px, icon 18px vs
24
24
  20px, radius 9 vs 8, a CSS-var accent vs a Tailwind one. `EditorRail` is the one
@@ -399,6 +399,99 @@ Key order is not part of the saved format — the backend stores these in
399
399
  Postgres `jsonb` — but an edited key keeps its place and a new one goes on the
400
400
  end, so a save diffs as the lines that changed.
401
401
 
402
+ ### A page in more than one language — the translation overlay
403
+
404
+ Added in 0.97.0, in the same entry. A page is written once, in a base
405
+ language; each other language is an **overlay** the host stores beside the
406
+ document, never inside it:
407
+
408
+ ```ts
409
+ type TranslationOverlay = Record<string /* node id, or "root" */, Record<string /* prop path */, TranslatedValue>>;
410
+ interface TranslatedValue { v: unknown; src: string } // src: a fingerprint of the BASE value it translates
411
+ ```
412
+
413
+ **The document format is unchanged**, and a page with one language stores no
414
+ overlay: `applyTranslation(data, config)` returns the object it was given.
415
+ `Render` knows nothing of languages. It is handed a document that has already
416
+ been localised.
417
+
418
+ ```ts
419
+ import { applyTranslation, extractTranslation, translationStatus } from 'efficient-easel/data';
420
+
421
+ // Draw the page in German. A value with no entry is the base language's.
422
+ <Render config={config} data={applyTranslation(page, config, german)} />
423
+
424
+ // A translator typed over that page: what to save for German.
425
+ const next = extractTranslation(page, edited, config, german);
426
+
427
+ // How far German has got.
428
+ const { total, missing, stale } = translationStatus(page, config, next);
429
+ ```
430
+
431
+ **A block's fields say what is translated**, with `translatable`:
432
+
433
+ ```ts
434
+ fields: {
435
+ title: { type: 'text' }, // text and textarea: translated
436
+ slug: { type: 'text', translatable: false }, // … unless the field says not
437
+ heading: { type: 'custom', translatable: true, render }, // anything else: only when it says so
438
+ banner: { type: 'custom', translatable: true, render }, // a picture with words in it: one whole value
439
+ height: { type: 'number' }, // never, unless flagged
440
+ items: { type: 'array', arrayFields: { q: { type: 'text' }, href: { type: 'text', translatable: false } } },
441
+ content: { type: 'slot' }, // never: a child block has its own id
442
+ }
443
+ ```
444
+
445
+ An `object` or `array` field is a container: the fields inside it are read by
446
+ the same rule, and a flag on the container is the default for them. A path is
447
+ the prop's keys joined by dots, with an array index as a key: `title`,
448
+ `cta.label`, `items.2.q`. The root's props are translated under the id
449
+ `"root"`.
450
+
451
+ | Export | Notes |
452
+ |---|---|
453
+ | `applyTranslation(data, config, overlay?)` | The document in one language. No overlay (or an empty one): **the same object**. Otherwise only the nodes that took a value are copied. An entry for a node that is not there, or a path that is not words, is passed over. |
454
+ | `extractTranslation(base, edited, config, previous?)` | The overlay a language's edit comes to: an entry for every translatable value that differs from the base. A value equal to the base's makes no entry. Anything else that differs (a block added or moved, a number) is passed over. With `previous`, an entry the edit did not touch is kept as it was, old `src` and all. |
455
+ | `translationStatus(data, config, overlay?)` | `{ total, missing, stale }`, the two lists as `{ id, path }` in document order. A value the base leaves blank wants nothing. |
456
+ | `translatablePaths(node, config)` | `{ path, value }[]` for a node, or for the root (`data.root`). |
457
+ | `rebaseTranslation(previousBase, nextBase, config, overlay)` | Carries an overlay across an edit of the base that moved, added, copied or removed **array items**. |
458
+ | `mapIds(source, copy, config)`, `copyTranslation(overlay, ids)` | For `duplicate` and `copyNode`, which give every copied node a new id: old id → new id, then the copies' entries (only those; lay them over the overlay). |
459
+ | `pruneTranslation(data, config, overlay)` | Drops the entries of nodes that are gone and of paths that no longer exist. Nothing else drops anything. |
460
+ | `translationFingerprint(value)` | What `src` holds. |
461
+
462
+ **Stale.** `src` is the fingerprint of the base value a translation was made
463
+ from (`s<length>.<hash>` of a string; of anything else, its JSON with the keys
464
+ sorted). When the base value changes, the translation is stale:
465
+ `translationStatus` reports it, and it is **still drawn**, because an
466
+ out-of-date translation beats the wrong language. An emptied or removed base
467
+ value is a changed one.
468
+
469
+ **Arrays.** An array item has no id, and the format does not allow one, so its
470
+ entries are stored under its index (`items.2.q`). When the base value at that
471
+ index no longer has the entry's `src`, the entry is looked for among the other
472
+ items of the same array, in the same field, and drawn **there**: the item
473
+ moved. Found nowhere, it is not drawn (the item at that index may be another
474
+ item now) and is reported stale. Two items with the same base words can only be
475
+ told apart by position: an entry that still matches where it stands stays, and
476
+ a displaced one takes the first free match.
477
+
478
+ **What a host does when the base is edited:**
479
+
480
+ | Edit of the base | The host calls |
481
+ |---|---|
482
+ | `move` | nothing: ids do not change |
483
+ | `remove` | nothing. The entries stay, unread, so undoing the delete brings the translations back. `pruneTranslation` when they should go for good. |
484
+ | `duplicate`, `copyNode` | `mapIds(source, copy, config)`, then for each language `{ ...overlay, ...copyTranslation(overlay, ids) }` |
485
+ | `setProps`, `setRoot`, `replaceNode` | nothing: a changed value is stale |
486
+ | an array value changed (an item moved, added, copied, removed) | `rebaseTranslation(before, after, config, overlay)` for each language. It sees both sides, so stale entries travel with their item, a copied item starts with its original's translations, and the saved overlay has the right indices. It drops the entries of an item that was removed: keep the overlay in the same undo step as the base to get them back. |
487
+
488
+ A block type the config does not know keeps its entries for as long as the
489
+ block is in the document.
490
+
491
+ Not here yet: the editor's side (a language switch, the Inspector showing the
492
+ base words under a translation, markers on untranslated rows). Routing and
493
+ `<html lang>` are the host's.
494
+
402
495
  ## Block writing — `efficient-easel/blocks`
403
496
 
404
497
  `efficient-easel/blocks` (added in 0.92.0) holds the types a block is written
@@ -406,7 +499,9 @@ with: Puck 0.20's `Config`, `ComponentConfig`, `Fields`, `Field`,
406
499
  `CustomField`, `ComponentData`, `Data`, `Slot` and `SlotComponent`, with the
407
500
  same generics. An app that typed its blocks with Puck's imports them from here
408
501
  instead, and no block changes. It is types only: nothing in it exists at
409
- runtime.
502
+ runtime. One key is the engine's own: `translatable` on a field (0.97.0),
503
+ which says whether the prop is written again per language (the translation
504
+ overlay, above). It is optional, so a field written for Puck is still a field.
410
505
 
411
506
  ```ts
412
507
  import type { Config, CustomField, Slot } from 'efficient-easel/blocks';
@@ -1,6 +1,6 @@
1
- import { A as Autosave, a as AutosaveSnapshot, b as SaveIndicator, c as AutosaveOptions } from '../words-CsRWXkY4.js';
2
- export { d as AutosaveClock, S as SaveWords, e as createAutosave, s as saveIndicator } from '../words-CsRWXkY4.js';
3
- import '../types-CuNiSnX6.js';
1
+ import { A as Autosave, a as AutosaveSnapshot, b as SaveIndicator, c as AutosaveOptions } from '../words-Cqmyey0s.js';
2
+ export { d as AutosaveClock, S as SaveWords, e as createAutosave, s as saveIndicator } from '../words-Cqmyey0s.js';
3
+ import '../types-CnRzp9oc.js';
4
4
  import '../types-DNrn_w4V.js';
5
5
  import '../wordFit-9B9nqyf3.js';
6
6
  import 'react';
@@ -29,7 +29,7 @@ declare function useAutosave<T>(options: UseAutosaveOptions<T>): UseAutosave<T>;
29
29
  * async save cannot be finished during unload, which is why the close-tab
30
30
  * handler only warns. Both editors had these same two listeners of their own
31
31
  * (efficient-admin-portal `src/components/email/autosaveTabAway.ts`,
32
- * efficient-shop `components/StorefrontDocumentContext.tsx`).
32
+ * efficient-storefront `components/StorefrontDocumentContext.tsx`).
33
33
  *
34
34
  * - `visibilitychange` to `hidden` is the one that matters, and an ordinary
35
35
  * save: the page is alive, so it completes. Guarded on `hidden` because the
@@ -1,9 +1,9 @@
1
1
  import { ReactElement, FC, CSSProperties, ReactNode, JSX } from 'react';
2
- import { P as Permissions, A as AppState } from '../types-_Vayx8ov.js';
2
+ import { P as Permissions, A as AppState } from '../types-Dy6oR6Z2.js';
3
3
  import '../data/index.js';
4
- import '../types-DziKCwsN.js';
5
- import '../resolve-DpH8YQOA.js';
6
- import '../plan-DtNw2VuI.js';
4
+ import '../types-41704JE4.js';
5
+ import '../resolve-D68pb3Bx.js';
6
+ import '../plan-DChbUXdS.js';
7
7
 
8
8
  /**
9
9
  * efficient-easel/blocks — how a block is WRITTEN: its config, its fields, the
@@ -48,6 +48,17 @@ type BaseField = {
48
48
  labelIcon?: ReactElement;
49
49
  metadata?: Metadata;
50
50
  visible?: boolean;
51
+ /**
52
+ * NOT PUCK'S — the engine's (0.97.0). Whether this prop is written again in
53
+ * each language of a multilingual page (`efficient-easel/data`, the
54
+ * translation overlay). Left out, a `text` or `textarea` field is and every
55
+ * other type is not, so a `custom` field that edits words, or a picture with
56
+ * words in it, says `translatable: true`, and a `text` field that holds an
57
+ * address or a code says `false`. On an `object` or `array` field it is the
58
+ * default for the fields inside it. A `slot` is never translated: its
59
+ * children are blocks with ids of their own.
60
+ */
61
+ translatable?: boolean;
51
62
  };
52
63
  type TextField = BaseField & {
53
64
  type: 'text';
@@ -3,7 +3,7 @@
3
3
  * Layout, Animation. A panel shows only the tabs that hold a setting — an empty
4
4
  * tab is hidden, never drawn (same day).
5
5
  *
6
- * The website editor wrote this list in `efficient-shop/lib/puck/field-groups.ts`
6
+ * The website editor wrote this list in `efficient-storefront/lib/puck/field-groups.ts`
7
7
  * (`BUCKETS`). From 0.43.0 it lives here, so the campaign editor spells its panel
8
8
  * the same four words in the same order instead of keeping a second list.
9
9
  */
@@ -2,7 +2,7 @@
2
2
  * efficient-easel/chrome.css — the editor frame: top bar, device switch, save pill,
3
3
  * flat side panels, resize grips, inspector head.
4
4
  *
5
- * EVERY VALUE HERE WAS READ OFF `efficient-shop/components/storefront-editor.css`
5
+ * EVERY VALUE HERE WAS READ OFF `efficient-storefront/components/storefront-editor.css`
6
6
  * on origin/main (release 14.24.0, 2026-09-17), where the website editor drew
7
7
  * these parts as `.sf-*`. Each `--sf-*` token it spent is an alias of the
8
8
  * `--es-*` token spent here (`--sf-muted: var(--es-muted)` and so on), so the
@@ -35,7 +35,7 @@
35
35
  .es-cluster {
36
36
  display: flex;
37
37
  align-items: center;
38
- gap: 6px;
38
+ gap: 8px;
39
39
  }
40
40
  .es-cluster--right {
41
41
  gap: 8px;
@@ -125,7 +125,7 @@
125
125
  gap: 2px;
126
126
  background: var(--es-track-bg);
127
127
  border-radius: 9px;
128
- padding: 3px;
128
+ padding: 2px;
129
129
  }
130
130
  .es-devseg button {
131
131
  width: 30px;
@@ -155,8 +155,8 @@
155
155
  .es-btn-ghost {
156
156
  display: flex;
157
157
  align-items: center;
158
- gap: 6px;
159
- padding: 7px 12px;
158
+ gap: 8px;
159
+ padding: 8px 12px;
160
160
  border: 1px solid var(--es-btn-border);
161
161
  background: var(--es-panel);
162
162
  border-radius: 8px;
@@ -184,7 +184,7 @@
184
184
  }
185
185
  /* The ONE primary button in the bar (Publish on the website). */
186
186
  .es-btn-primary {
187
- padding: 7px 16px;
187
+ padding: 8px 16px;
188
188
  border: none;
189
189
  background: var(--es-accent);
190
190
  border-radius: 8px;
@@ -205,8 +205,8 @@
205
205
  .es-savestate {
206
206
  display: inline-flex;
207
207
  align-items: center;
208
- gap: 6px;
209
- padding: 5px 10px;
208
+ gap: 8px;
209
+ padding: 4px 12px;
210
210
  border-radius: 8px;
211
211
  font-size: 12px;
212
212
  font-weight: 500;
@@ -331,7 +331,7 @@
331
331
  display: flex;
332
332
  align-items: center;
333
333
  justify-content: space-between;
334
- padding: 13px 14px 11px;
334
+ padding: 12px 16px;
335
335
  flex: none;
336
336
  }
337
337
  /* A panel's own name. States the margin an h2 would otherwise bring. */
@@ -399,16 +399,16 @@ body.es-col-resizing iframe {
399
399
  display: flex;
400
400
  align-items: center;
401
401
  flex: none;
402
- padding: 6px 8px;
402
+ padding: 8px;
403
403
  border-bottom: 1px solid var(--es-divider);
404
404
  }
405
405
  .es-insp-up-btn {
406
406
  display: flex;
407
407
  align-items: center;
408
- gap: 6px;
408
+ gap: 8px;
409
409
  flex: 1;
410
410
  min-width: 0;
411
- padding: 4px 6px;
411
+ padding: 4px 8px;
412
412
  border: 0;
413
413
  border-radius: 6px;
414
414
  background: transparent;
@@ -439,10 +439,19 @@ body.es-col-resizing iframe {
439
439
  .es-insp-head {
440
440
  display: flex;
441
441
  align-items: center;
442
- gap: 10px;
443
- padding: 12px 14px;
442
+ gap: 12px;
443
+ padding: 12px 16px;
444
444
  flex: none;
445
445
  }
446
+ /* THE PANEL'S OWN PADDING IS 16, AND 12 UNDER 260px (one spacing scale, owner
447
+ ruling 2026-10-02). The side panel is the size container (above), so this
448
+ asks the panel's width — a panel is dragged between 220 and 560 — and never
449
+ the screen's. Only the heads are padded here: the settings body's padding
450
+ is the host's. */
451
+ @container (width < 260px) {
452
+ .es-panel-head,
453
+ .es-insp-head { padding-inline: 12px; }
454
+ }
446
455
  .es-insp-chip {
447
456
  width: 26px;
448
457
  height: 26px;
@@ -545,7 +554,7 @@ body.es-col-resizing iframe {
545
554
  .es-notice-actions {
546
555
  display: flex;
547
556
  flex-wrap: wrap;
548
- gap: 6px;
557
+ gap: 8px;
549
558
  }
550
559
  .es-notice-btn {
551
560
  appearance: none;
@@ -553,7 +562,7 @@ body.es-col-resizing iframe {
553
562
  font: inherit;
554
563
  font-size: 12px;
555
564
  font-weight: 500;
556
- padding: 4px 10px;
565
+ padding: 4px 12px;
557
566
  border: 1px solid var(--es-btn-border);
558
567
  border-radius: var(--es-field-radius);
559
568
  background: var(--es-raised);
@@ -1,6 +1,6 @@
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-CuNiSnX6.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-CuNiSnX6.js';
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';
4
4
  import { LockWords, EditAccess, SaveConflict } from '../edit-lock/index.js';
5
5
  import { N as NoticeWords } from '../words-DagJdwIA.js';
6
6
  export { C as ChromeWords } from '../words-DagJdwIA.js';
@@ -10,7 +10,7 @@ import '../wordFit-9B9nqyf3.js';
10
10
  /**
11
11
  * The editor's top bar — 52px, white, a soft shadow, three clusters.
12
12
  *
13
- * Lifted from the website editor's `.sf-topbar` (efficient-shop). Its order is a
13
+ * Lifted from the website editor's `.sf-topbar` (efficient-storefront). Its order is a
14
14
  * decision, not a layout accident, so it is written here once:
15
15
  *
16
16
  * rail what the LEFT panel contains (Add, Layers, styles…). Exactly the left
@@ -67,7 +67,7 @@ declare function EditorIconButton({ label, onClick, disabled, state, buttonRef,
67
67
  /**
68
68
  * Which device the canvas previews — icon-only, one button held down.
69
69
  *
70
- * Lifted from `efficient-shop/components/DeviceSwitch.tsx`. It takes its devices
70
+ * Lifted from `efficient-storefront/components/DeviceSwitch.tsx`. It takes its devices
71
71
  * as a list because the two editors do not preview the same set: the website
72
72
  * has Desktop / Tablet / Mobile, an email has Desktop / Phone. The drawing, the
73
73
  * size and the pressed state are what must match, and those live here.
@@ -105,7 +105,7 @@ declare function SaveStateToggle({ pressed, title, onToggle, children }: SaveSta
105
105
  /**
106
106
  * A drag grip on a side panel's inner edge.
107
107
  *
108
- * Lifted from `efficient-shop/components/PanelResizeHandle.tsx`; the campaign
108
+ * Lifted from `efficient-storefront/components/PanelResizeHandle.tsx`; the campaign
109
109
  * designer carried its own copy of the same idea. It owns NO width: the editor
110
110
  * holds and persists it, and the grip only reports a new clamped width through
111
111
  * `onResize`. The host renders it as an absolute child of the panel row, pinned
@@ -168,7 +168,7 @@ declare function EditNotice({ access, conflict, noun, onTakeOver, onViewReadOnly
168
168
  * The two editors said this differently: the campaign designer in a strip under
169
169
  * its top bar (`EditLockBanner`, efficient-admin-portal
170
170
  * `src/components/email/CampaignDesigner.tsx`), the website editor in modal
171
- * dialogs over the canvas (`PageEditGuardNotices`, efficient-shop
171
+ * dialogs over the canvas (`PageEditGuardNotices`, efficient-storefront
172
172
  * `components/PageEditGuardNotices.tsx`), which said "choosing one for both is a
173
173
  * design ruling nobody has made". The blueprint made it: a bar, never a dialog,
174
174
  * the save conflict included. A dialog stops the operator reading the very
@@ -1,21 +1,21 @@
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-YIMRTIBN.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__ */
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
2
  return d("div",{className:"es-topbar",children:e})}function k({kind:e,style:n,children:t}){/* @__PURE__ */
3
3
  return d("div",{className:e?`es-cluster es-cluster--${e}`:"es-cluster",style:n,children:t})}function g(){/* @__PURE__ */
4
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
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
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
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 P({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 S="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(S),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(S))},[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(S),[]),/* @__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__ */
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
10
  return u("div",{className:"es-insp-head",children:[
11
11
  /* @__PURE__ */d("span",{className:"es-insp-chip","aria-hidden":"true",children:e}),
12
12
  /* @__PURE__ */u("div",{className:"es-insp-titles",children:[
13
13
  /* @__PURE__ */d("h2",{className:"es-insp-name",children:n}),
14
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 R({name:e,onSelect:t,icon:i,label:a}){const r=c("chrome",n),o=a??r.upLevel;/* @__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
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 $={notice:e,lock:r};function D(e,n,r,o=$){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 T({access:n,conflict:t,noun:i,onTakeOver:a,onViewReadOnly:o,onReload:s}){const l=D(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__ */
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
18
  return u("div",{className:`es-notice is-${l.tone}`,role:l.urgent?"alert":"status",children:[
19
19
  /* @__PURE__ */u("span",{className:"es-notice-text",children:[
20
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 j={left:288,right:320},z=220,F=560;function I(e){return Math.min(560,Math.max(220,Math.round(e)))}function A(e){return{"--es-left-w":`${e.left}px`,"--es-right-w":`${e.right}px`}}export{j as DEFAULT_PANEL_W,x as DeviceSwitch,T as EditNotice,N as EditorIconButton,f as EditorTopBar,M as InspectorHead,B as InspectorIconButton,R as InspectorUpLevel,F as MAX_PANEL_W,z as MIN_PANEL_W,L as PanelResizeHandle,O as SaveState,P as SaveStateToggle,k as TopBarCluster,g as TopBarDivider,w as TopBarRail,I as clampPanelWidth,D as editNotice,A as panelWidthVars};
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};
@@ -0,0 +1 @@
1
+ var e={accent:"#2563eb",accentTint:"#eff6ff",accentTintStrong:"#dbeafe",accentLine:"#bfdbfe",accentText:"#1d4ed8",accentRing:"rgba(37, 99, 235, 0.25)",accentShadow:"rgba(37, 99, 235, 0.35)",onAccent:"#ffffff",appBg:"#f9fafb",previewBg:"#f3f4f6",panel:"#ffffff",raised:"#ffffff",topbarBg:"#ffffff",frameBg:"#ffffff",hover:"#f3f4f6",hatch:"rgba(0, 0, 0, 0.018)",addcardVeil:"rgba(248, 249, 250, 0.66)",fieldBg:"#ffffff",trackBg:"#f3f4f6",inputBorder:"#d1d5db",fieldText:"#1f2937",fieldPlaceholder:"#9ca3af",knob:"#ffffff",text:"#111827",textStrong:"#030712",textSecondary:"#374151",muted:"#6b7280",icon:"#6b7280",disabled:"#9ca3af",divider:"#e5e7eb",line:"#e5e7eb",btnBorder:"#d1d5db",btnText:"#374151",chipBg:"#f3f4f6",chipFg:"#6b7280",brandSquare:"#111827",deviceBorder:"#e5e7eb",toastBg:"#111827",toggleOff:"#d1d5db",scrollbar:"#d1d5db",scrollbarHover:"#9ca3af",danger:"#dc2626",dangerStrong:"#b91c1c",dangerTint:"#fef2f2",warning:"#b45309",previewTint:"#fef3c7",success:"#15803d",panelRadius:12,rowRadius:8,fieldRadius:6,panelGap:12,space2:2,space4:4,space8:8,space12:12,space16:16,space32:32,panelShadow:"0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)",topbarShadow:"0 1px 3px rgba(0, 0, 0, 0.06)",raisedShadow:"0 1px 2px rgba(16, 24, 40, 0.1)",font:'-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif'},a=[e.space2,e.space4,e.space8,e.space12,e.space16,e.space32],s={accent:"--es-accent",accentTint:"--es-accent-tint",accentTintStrong:"--es-accent-tint-strong",accentLine:"--es-accent-line",accentText:"--es-accent-text",accentRing:"--es-accent-ring",accentShadow:"--es-accent-shadow",onAccent:"--es-on-accent",appBg:"--es-app-bg",previewBg:"--es-preview-bg",panel:"--es-panel",raised:"--es-raised",topbarBg:"--es-topbar-bg",frameBg:"--es-frame-bg",hover:"--es-hover",hatch:"--es-hatch",addcardVeil:"--es-addcard-veil",fieldBg:"--es-field-bg",trackBg:"--es-track-bg",inputBorder:"--es-input-border",fieldText:"--es-field-text",fieldPlaceholder:"--es-field-placeholder",knob:"--es-knob",text:"--es-text",textStrong:"--es-text-strong",textSecondary:"--es-text-secondary",muted:"--es-muted",icon:"--es-icon",disabled:"--es-disabled",divider:"--es-divider",line:"--es-line",btnBorder:"--es-btn-border",btnText:"--es-btn-text",chipBg:"--es-chip-bg",chipFg:"--es-chip-fg",brandSquare:"--es-brand-square",deviceBorder:"--es-device-border",toastBg:"--es-toast-bg",toggleOff:"--es-toggle-off",scrollbar:"--es-scrollbar",scrollbarHover:"--es-scrollbar-hover",danger:"--es-danger",dangerStrong:"--es-danger-strong",dangerTint:"--es-danger-tint",warning:"--es-warning",previewTint:"--es-preview-tint",success:"--es-success",panelRadius:"--es-panel-radius",rowRadius:"--es-row-radius",fieldRadius:"--es-field-radius",panelGap:"--es-panel-gap",space2:"--es-space-2",space4:"--es-space-4",space8:"--es-space-8",space12:"--es-space-12",space16:"--es-space-16",space32:"--es-space-32",panelShadow:"--es-panel-shadow",topbarShadow:"--es-topbar-shadow",raisedShadow:"--es-raised-shadow",font:"--es-font"};export{a as SPACING_SCALE,s as shellCssVars,e as shellTokens};
@@ -1,14 +1,14 @@
1
- import{DEFAULT_TREE_WORDS as e}from"./chunk-H4B72XCJ.js";import{ChevronIcon as a}from"./chunk-YNZZYHA4.js";import{jsx as r,jsxs as l,Fragment as n}from"react/jsx-runtime";function s({className:e,children:a,rootProps:l}){/* @__PURE__ */
1
+ import{DEFAULT_TREE_WORDS as e}from"./chunk-H4B72XCJ.js";import{ChevronIcon as a}from"./chunk-PI26YXYD.js";import{jsx as r,jsxs as l,Fragment as n}from"react/jsx-runtime";function s({className:e,children:a,rootProps:l}){/* @__PURE__ */
2
2
  return r("div",{...l,className:e?`es-tree ${e}`:"es-tree",children:a})}function t({children:e}){/* @__PURE__ */
3
3
  return r("div",{className:"es-tree-group",children:e})}function i({children:e}){/* @__PURE__ */
4
- return r("div",{className:"es-subtree",children:e})}var d=e.dragHint;function c({icon:s,name:t,preview:i,selected:d,hidden:c,draggable:o,dragHint:p,dragging:h,drop:m,fold:u,handle:b,actions:N,nameSlot:g,onSelect:k,marks:f,badge:v,trailing:y,children:w,rowProps:x,words:A=e}){const C=["es-tree-row",d?"is-selected":"",c?"is-hidden":"",o?"is-draggable":"",h?"is-dragging":"",m?`is-drop-${m}`:""].filter(Boolean).join(" "),j=/* @__PURE__ */l(n,{children:[
4
+ return r("div",{className:"es-subtree",children:e})}var d=e.dragHint;function c({icon:s,name:t,preview:i,selected:d,hidden:c,draggable:o,dragHint:p,dragging:h,drop:m,fold:u,handle:b,actions:g,nameSlot:N,onSelect:k,marks:f,badge:v,trailing:y,children:w,rowProps:x,words:C=e}){const P=["es-tree-row",d?"is-selected":"",c?"is-hidden":"",o?"is-draggable":"",h?"is-dragging":"",m?`is-drop-${m}`:""].filter(Boolean).join(" "),j=/* @__PURE__ */l(n,{children:[
5
5
  /* @__PURE__ */l("span",{className:"es-tree-name",children:[t,i?/* @__PURE__ */r("span",{className:"es-tree-preview",children:i}):null]}),f?.map(e=>/* @__PURE__ */r("span",{className:"es-tree-mark",title:e.label,"aria-label":e.label,role:"img",children:e.icon},e.key)),null!=v&&!1!==v?/* @__PURE__ */r("span",{className:"es-tree-badge",children:v}):null]});/* @__PURE__ */
6
- return l("div",{...x,className:C,children:[o?
6
+ return l("div",{...x,className:P,children:[o?
7
7
  /* @__PURE__ */l(n,{children:[
8
8
  /* @__PURE__ */r("span",{className:"es-tree-grip","aria-hidden":"true",children:"⋮"}),
9
- /* @__PURE__ */r("span",{className:"es-tree-hint","aria-hidden":"true",children:p??A.dragHint})]}):b?/* @__PURE__ */r("button",{type:"button",className:"es-tree-handle",...b,children:"⋮⋮"}):null,u?/* @__PURE__ */r("button",{type:"button",className:"es-tree-caret","aria-label":u.open?A.collapseNamed({label:u.label}):A.expandNamed({label:u.label}),"aria-expanded":u.open,title:u.open?A.collapse:A.expand,onClick:e=>{e.stopPropagation(),u.onToggle()},children:/* @__PURE__ */r(a,{size:11,strokeWidth:2.6,className:u.open?"es-tree-chev is-open":"es-tree-chev"})}):/* @__PURE__ */r("span",{className:"es-tree-caret-spacer","aria-hidden":"true"}),
9
+ /* @__PURE__ */r("span",{className:"es-tree-hint","aria-hidden":"true",children:p??C.dragHint})]}):b?/* @__PURE__ */r("button",{type:"button",className:"es-tree-handle",...b,children:"⋮⋮"}):null,u?/* @__PURE__ */r("button",{type:"button",className:"es-tree-caret","aria-label":u.open?C.collapseNamed({label:u.label}):C.expandNamed({label:u.label}),"aria-expanded":u.open,title:u.open?C.collapse:C.expand,onClick:e=>{e.stopPropagation(),u.onToggle()},children:/* @__PURE__ */r(a,{size:11,strokeWidth:2.6,className:u.open?"es-tree-chev is-open":"es-tree-chev"})}):/* @__PURE__ */r("span",{className:"es-tree-caret-spacer","aria-hidden":"true"}),
10
10
  /* @__PURE__ */r("span",{className:"es-tree-chip","aria-hidden":"true",children:s}),
11
- /* @__PURE__ */l("span",{className:"es-tree-name-box",children:[g??(k?
12
- /* @__PURE__ */r("button",{type:"button",className:"es-tree-select","aria-current":d?"true":void 0,"aria-keyshortcuts":o?"Alt+ArrowUp Alt+ArrowDown":void 0,onClick:k,children:j}):j),N?/* @__PURE__ */r("span",{className:"es-tree-actions",children:N}):null]}),y?/* @__PURE__ */r("span",{className:"es-tree-trailing",title:y.label,"aria-label":y.label,role:"img",children:y.icon}):null,w]})}function o({kind:e,label:a,onClick:l,pressed:n,disabled:s,children:t}){/* @__PURE__ */
11
+ /* @__PURE__ */l("span",{className:"es-tree-name-box",children:[N??(k?
12
+ /* @__PURE__ */r("button",{type:"button",className:"es-tree-select","aria-current":d?"true":void 0,"aria-keyshortcuts":o?"Alt+ArrowUp Alt+ArrowDown":void 0,onClick:k,children:j}):j),g?/* @__PURE__ */r("span",{className:"es-tree-actions",children:g}):null]}),y?/* @__PURE__ */r("span",{className:"es-tree-trailing",title:y.label,"aria-label":y.label,role:"img",children:y.icon}):null,w]})}function o({kind:e,label:a,onClick:l,pressed:n,disabled:s,children:t}){/* @__PURE__ */
13
13
  return r("button",{type:"button",className:"delete"===e?"es-tree-del":"eye"===e?"es-tree-eye":"es-tree-act",title:a,"aria-label":a,"aria-pressed":n,disabled:s,onClick:e=>{e.stopPropagation(),l()},children:t})}function p({drop:e,onAdd:a,label:l,seamProps:n}){const s=["es-tree-seam",e?"is-drop":"",a?"has-add":""].filter(Boolean).join(" ");/* @__PURE__ */
14
14
  return r("div",{...n,className:s,children:a?/* @__PURE__ */r("button",{type:"button",className:"es-tree-seam-add","aria-label":l,title:l,onClick:a,children:"+"}):null})}export{s as LayersTree,i as Subtree,d as TREE_DRAG_HINT,t as TreeGroupLabel,c as TreeRow,o as TreeRowAction,p as TreeSeam};
@@ -1 +1 @@
1
- import{zoneKey as e}from"./chunk-LPRQDDQO.js";import{useRef as t,useEffect as n,useState as r,useSyncExternalStore as o,useCallback as i}from"react";var c=56,l=16;function u(e){const t=Math.max(e,0);return t>=c?0:Math.ceil(16*(1-t/c))}function a(e,t,n){if(e<t-c||e>n+c)return 0;const r=e-t,o=n-e;return r<c&&r<=o?-u(r):o<c?u(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.ownerDocument,n=t.defaultView;if(!n)return()=>{};let r=null,o=0;const i=e=>{r=e.clientY},c=()=>{if(null!==r){const t=e.getBoundingClientRect(),n=a(r,t.top,t.bottom);n&&(e.scrollTop+=n)}o=n.requestAnimationFrame(c)};return t.addEventListener("dragover",i,!0),o=n.requestAnimationFrame(c),()=>{t.removeEventListener("dragover",i,!0),n.cancelAnimationFrame(o)}}function g(){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 p(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 m=(t,n)=>e(t)===e(n);function v(e,t){return m(e,t)&&(t.index===e.index||t.index===e.index+1)}function D(e,t){return m(e,t)&&e.index<t.index?t.index-1:t.index}function y(e,t){return{...e,index:t<0?e.index-1:e.index+2}}function w(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 x(c){const l=t(c);n(()=>{l.current=c});const[u]=r(()=>g()),a=c.session??u,m=o(a.subscribe,a.shown,a.shown),[D,y]=r(null),x=t(null),b=i(()=>{x.current?.(),x.current=null},[]),h=i(()=>{b(),a.end(),y(null)},[a,b]);n(()=>a.subscribe(()=>{a.get()||(b(),y(null))}),[a,b]),n(()=>b,[b]);const T=i((e,t)=>{y(n=>n&&n.key===e&&n.side===t?n:{key:e,side:t})},[]),k=i(e=>{y(t=>t&&t.key===e?null:t)},[]),E=(e,t,n,r)=>!("into"===n?r===e.key:void 0!==e.from&&v(e.from,t))&&l.current.canDrop(e.item,t);return{dragging:m?.item??null,row:(e,t)=>{const{keyOf:n,readOnly:r}=l.current,o=n(e.item),i=!r&&!e.pinned&&!1!==e.canDrag,c=t=>{const n=t.currentTarget.getBoundingClientRect();return p(e,t.clientY,n.top,n.height)},u={draggable:i||void 0,onDragStart:i?t=>{const n=t.currentTarget;a.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);b(),x.current=i?d(i):null}:void 0,onDragEnd:i?()=>h():void 0,onDragOver:e=>{const t=a.get();if(!t)return;const n=c(e);E(t,n.to,n.side,o)?(e.preventDefault(),e.dataTransfer.dropEffect="move",T(o,n.side)):k(o)},onDrop:e=>{const t=a.get();if(!t)return;const n=c(e);E(t,n.to,n.side,o)&&(e.preventDefault(),h(),l.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}=l.current,o="ArrowUp"===t.key?-1:1;n&&!1!==r?.(e.item,o)&&n(e.item,o)}};return{draggable:i,dragging:m?.key===o,drop:D?.key===o?D.side:void 0,rowProps:w(u,t)}},seam:(t,n)=>{const r=(o=t.place,`seam:${e(o)}:${o.index}`);var o;const i={onDragOver:e=>{const n=a.get();n&&(E(n,t.place,"before",r)?(e.preventDefault(),e.dataTransfer.dropEffect="move",T(r,"before")):k(r))},onDrop:e=>{const n=a.get();n&&E(n,t.place,"before",r)&&(e.preventDefault(),h(),l.current.onDrop(n.item,t.place))}};return{drop:D?.key===r,seamProps:w(i,n)}},rootProps:e=>w({onDragEnter:e=>{if(!a.get()||x.current)return;const t=f(e.currentTarget);x.current=t?d(t):null},onDragLeave:e=>{const t=e.relatedTarget;t&&e.currentTarget.contains(t)||y(null)}},e)}}export{c as AUTO_SCROLL_EDGE,l as AUTO_SCROLL_MAX_SPEED,a as autoScrollDelta,u as autoScrollSpeed,g as createDragSession,p as dropOnRow,D as gapToMoveIndex,v as isNoOpDrop,f as scrollBoxOf,s as scrollParent,d as startAutoScroll,y as stepGap,x as useTreeDrag};
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 c=56,l=16;function u(e){const t=Math.max(e,0);return t>=c?0:Math.ceil(16*(1-t/c))}function a(e,t,n){if(e<t-c||e>n+c)return 0;const r=e-t,o=n-e;return r<c&&r<=o?-u(r):o<c?u(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.ownerDocument,n=t.defaultView;if(!n)return()=>{};let r=null,o=0;const i=e=>{r=e.clientY},c=()=>{if(null!==r){const t=e.getBoundingClientRect(),n=a(r,t.top,t.bottom);n&&(e.scrollTop+=n)}o=n.requestAnimationFrame(c)};return t.addEventListener("dragover",i,!0),o=n.requestAnimationFrame(c),()=>{t.removeEventListener("dragover",i,!0),n.cancelAnimationFrame(o)}}function g(){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 p(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 m=(t,n)=>e(t)===e(n);function v(e,t){return m(e,t)&&(t.index===e.index||t.index===e.index+1)}function D(e,t){return m(e,t)&&e.index<t.index?t.index-1:t.index}function y(e,t){return{...e,index:t<0?e.index-1:e.index+2}}function w(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 x(c){const l=t(c);n(()=>{l.current=c});const[u]=r(()=>g()),a=c.session??u,m=o(a.subscribe,a.shown,a.shown),[D,y]=r(null),x=t(null),b=i(()=>{x.current?.(),x.current=null},[]),h=i(()=>{b(),a.end(),y(null)},[a,b]);n(()=>a.subscribe(()=>{a.get()||(b(),y(null))}),[a,b]),n(()=>b,[b]);const T=i((e,t)=>{y(n=>n&&n.key===e&&n.side===t?n:{key:e,side:t})},[]),k=i(e=>{y(t=>t&&t.key===e?null:t)},[]),E=(e,t,n,r)=>!("into"===n?r===e.key:void 0!==e.from&&v(e.from,t))&&l.current.canDrop(e.item,t);return{dragging:m?.item??null,row:(e,t)=>{const{keyOf:n,readOnly:r}=l.current,o=n(e.item),i=!r&&!e.pinned&&!1!==e.canDrag,c=t=>{const n=t.currentTarget.getBoundingClientRect();return p(e,t.clientY,n.top,n.height)},u={draggable:i||void 0,onDragStart:i?t=>{const n=t.currentTarget;a.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);b(),x.current=i?d(i):null}:void 0,onDragEnd:i?()=>h():void 0,onDragOver:e=>{const t=a.get();if(!t)return;const n=c(e);E(t,n.to,n.side,o)?(e.preventDefault(),e.dataTransfer.dropEffect="move",T(o,n.side)):k(o)},onDrop:e=>{const t=a.get();if(!t)return;const n=c(e);E(t,n.to,n.side,o)&&(e.preventDefault(),h(),l.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}=l.current,o="ArrowUp"===t.key?-1:1;n&&!1!==r?.(e.item,o)&&n(e.item,o)}};return{draggable:i,dragging:m?.key===o,drop:D?.key===o?D.side:void 0,rowProps:w(u,t)}},seam:(t,n)=>{const r=(o=t.place,`seam:${e(o)}:${o.index}`);var o;const i={onDragOver:e=>{const n=a.get();n&&(E(n,t.place,"before",r)?(e.preventDefault(),e.dataTransfer.dropEffect="move",T(r,"before")):k(r))},onDrop:e=>{const n=a.get();n&&E(n,t.place,"before",r)&&(e.preventDefault(),h(),l.current.onDrop(n.item,t.place))}};return{drop:D?.key===r,seamProps:w(i,n)}},rootProps:e=>w({onDragEnter:e=>{if(!a.get()||x.current)return;const t=f(e.currentTarget);x.current=t?d(t):null},onDragLeave:e=>{const t=e.relatedTarget;t&&e.currentTarget.contains(t)||y(null)}},e)}}export{c as AUTO_SCROLL_EDGE,l as AUTO_SCROLL_MAX_SPEED,a as autoScrollDelta,u as autoScrollSpeed,g as createDragSession,p as dropOnRow,D as gapToMoveIndex,v as isNoOpDrop,f as scrollBoxOf,s as scrollParent,d as startAutoScroll,y as stepGap,x as useTreeDrag};
@@ -1 +1 @@
1
- import{find as t,remove as e,getList as n,newId as r,duplicate as o,move as a,copyNode as c,insert as l,setProps as d}from"./chunk-LPRQDDQO.js";import{useRef as s,useSyncExternalStore as i,useCallback as p,useMemo as u}from"react";var f=t=>({kind:"node",id:t});function m(r,o,a,c="none"){const l=t(r,o,a),d=e(r,o,a);if("none"===c||!l)return{data:d,select:null};const s=n(r,o,l.place)??[],i=s[l.place.index+1]??s[l.place.index-1];return i?.props?.id?{data:d,select:f(i.props.id)}:"root"!==l.place.parentId?{data:d,select:f(l.place.parentId)}:{data:d,select:null}}function x(e,n,a,c={}){const l=t(e,n,a)?.node,d=c.id??r(l?.type??"Node");return{data:o(e,n,a,{strip:c.strip,id:d}),select:f(d)}}function I(t,e,n,r){return{data:a(t,e,n,r),select:f(n)}}var v=(t,e)=>({min:0,max:e-1});function b(e,r,o,a,c=v){const l=t(e,r,o);if(!l)return!1;const d=n(e,r,l.place)?.length??0,{min:s,max:i}=c(l.place,d),p=l.place.index+a;return l.place.index>=s&&l.place.index<=i&&p>=s&&p<=i}function g(e,n,r,o,a=v){if(!b(e,n,r,o,a))return null;const c=t(e,n,r);return I(e,n,r,{...c.place,index:c.place.index+o})}function k(t,e,n,r,o={}){const a=c(n,e,{strip:o.strip});return{data:l(t,e,r,a),select:f(a.props.id)}}function y(t,e,n,r){return{data:d(t,e,n,r),select:void 0}}function O(e,n,r,o=()=>!1){if(!r)return null;if("slot"===r.kind)return t(e,n,r.parentId)?f(r.parentId):null;const a=t(e,n,r.id);if(!a||"root"===a.place.parentId)return null;const c=t(e,n,a.place.parentId);return c?o(c.node,a.place.slot)?{kind:"slot",parentId:c.node.props.id,slot:a.place.slot}:f(c.node.props.id):null}function h(e,n,r){if(!r||"node"!==r.kind)return null;const o=t(e,n,r.id);return o?{zone:`${o.place.parentId}:${o.place.slot}`,index:o.place.index}:null}function z(t,e,r){if(!r)return null;const[o,a]=(r.zone??"root:default-zone").split(/:(.*)/s),c={parentId:o,slot:a},l=n(t,e,c)?.[r.index];return l?.props?.id?f(l.props.id):null}var R={get:()=>null,set:()=>{},subscribe:()=>()=>{}};function B(e){const n=s(e);n.current=e;const r=e.clipboard??R,o=i(r.subscribe,r.get,r.get),a=p(t=>{const e=n.current;if(e.readOnly)return!1;const r=t(e.data,e.config);return!!r&&((r.data!==e.data||void 0!==r.select)&&(e.commit(r.data,{select:r.select}),n.current={...e,data:r.data},!0))},[]);return u(()=>{const e=()=>n.current,r=(n,r)=>{const o=t(e().data,e().config,n);return o?{node:o.node,label:r,from:{parentId:o.place.parentId,slot:o.place.slot}}:null};return{held:o,remove:t=>a((n,r)=>m(n,r,t,e().afterRemove)),duplicate:t=>a((n,r)=>x(n,r,t,{strip:e().strip})),move:(t,e)=>a((n,r)=>I(n,r,t,e)),step:(t,n)=>a((r,o)=>g(r,o,t,n,e().stepBounds)),canStep:(t,n)=>b(e().data,e().config,t,n,e().stepBounds),setProps:(t,e)=>a((n,r)=>y(n,r,t,e)),copy:(t,n)=>{const o=r(t,n);return o&&(e().clipboard??R).set(o),!!o},cut:(t,n)=>{if(e().readOnly)return!1;const o=r(t,n);return!!o&&((e().clipboard??R).set(o),a((n,r)=>m(n,r,t,e().afterRemove)))},paste:t=>{const n=(e().clipboard??R).get();return!!n&&a((r,o)=>k(r,o,n.node,t,{strip:e().strip}))},parentOf:t=>O(e().data,e().config,t,e().slotIsLevel)}},[o,a])}export{b as canStep,z as fromItemSelector,O as parentStep,x as planDuplicate,I as planMove,k as planPaste,m as planRemove,y as planSetProps,g as planStep,h as toItemSelector,B as useNodeOps};
1
+ import{find as t,remove as e,getList as n,newId as r,duplicate as o,move as a,copyNode as c,insert as l,setProps as d}from"./chunk-KRXQM65X.js";import{useRef as s,useSyncExternalStore as i,useCallback as p,useMemo as u}from"react";var f=t=>({kind:"node",id:t});function m(r,o,a,c="none"){const l=t(r,o,a),d=e(r,o,a);if("none"===c||!l)return{data:d,select:null};const s=n(r,o,l.place)??[],i=s[l.place.index+1]??s[l.place.index-1];return i?.props?.id?{data:d,select:f(i.props.id)}:"root"!==l.place.parentId?{data:d,select:f(l.place.parentId)}:{data:d,select:null}}function x(e,n,a,c={}){const l=t(e,n,a)?.node,d=c.id??r(l?.type??"Node");return{data:o(e,n,a,{strip:c.strip,id:d}),select:f(d)}}function I(t,e,n,r){return{data:a(t,e,n,r),select:f(n)}}var v=(t,e)=>({min:0,max:e-1});function b(e,r,o,a,c=v){const l=t(e,r,o);if(!l)return!1;const d=n(e,r,l.place)?.length??0,{min:s,max:i}=c(l.place,d),p=l.place.index+a;return l.place.index>=s&&l.place.index<=i&&p>=s&&p<=i}function g(e,n,r,o,a=v){if(!b(e,n,r,o,a))return null;const c=t(e,n,r);return I(e,n,r,{...c.place,index:c.place.index+o})}function k(t,e,n,r,o={}){const a=c(n,e,{strip:o.strip});return{data:l(t,e,r,a),select:f(a.props.id)}}function y(t,e,n,r){return{data:d(t,e,n,r),select:void 0}}function h(e,n,r,o=()=>!1){if(!r)return null;if("slot"===r.kind)return t(e,n,r.parentId)?f(r.parentId):null;const a=t(e,n,r.id);if(!a||"root"===a.place.parentId)return null;const c=t(e,n,a.place.parentId);return c?o(c.node,a.place.slot)?{kind:"slot",parentId:c.node.props.id,slot:a.place.slot}:f(c.node.props.id):null}function z(e,n,r){if(!r||"node"!==r.kind)return null;const o=t(e,n,r.id);return o?{zone:`${o.place.parentId}:${o.place.slot}`,index:o.place.index}:null}function O(t,e,r){if(!r)return null;const[o,a]=(r.zone??"root:default-zone").split(/:(.*)/s),c={parentId:o,slot:a},l=n(t,e,c)?.[r.index];return l?.props?.id?f(l.props.id):null}var R={get:()=>null,set:()=>{},subscribe:()=>()=>{}};function B(e){const n=s(e);n.current=e;const r=e.clipboard??R,o=i(r.subscribe,r.get,r.get),a=p(t=>{const e=n.current;if(e.readOnly)return!1;const r=t(e.data,e.config);return!!r&&((r.data!==e.data||void 0!==r.select)&&(e.commit(r.data,{select:r.select}),n.current={...e,data:r.data},!0))},[]);return u(()=>{const e=()=>n.current,r=(n,r)=>{const o=t(e().data,e().config,n);return o?{node:o.node,label:r,from:{parentId:o.place.parentId,slot:o.place.slot}}:null};return{held:o,remove:t=>a((n,r)=>m(n,r,t,e().afterRemove)),duplicate:t=>a((n,r)=>x(n,r,t,{strip:e().strip})),move:(t,e)=>a((n,r)=>I(n,r,t,e)),step:(t,n)=>a((r,o)=>g(r,o,t,n,e().stepBounds)),canStep:(t,n)=>b(e().data,e().config,t,n,e().stepBounds),setProps:(t,e)=>a((n,r)=>y(n,r,t,e)),copy:(t,n)=>{const o=r(t,n);return o&&(e().clipboard??R).set(o),!!o},cut:(t,n)=>{if(e().readOnly)return!1;const o=r(t,n);return!!o&&((e().clipboard??R).set(o),a((n,r)=>m(n,r,t,e().afterRemove)))},paste:t=>{const n=(e().clipboard??R).get();return!!n&&a((r,o)=>k(r,o,n.node,t,{strip:e().strip}))},parentOf:t=>h(e().data,e().config,t,e().slotIsLevel)}},[o,a])}export{b as canStep,O as fromItemSelector,h as parentStep,x as planDuplicate,I as planMove,k as planPaste,m as planRemove,y as planSetProps,g as planStep,z as toItemSelector,B as useNodeOps};
@@ -1,3 +1,3 @@
1
1
  import{DEFAULT_RAIL_WORDS as a}from"./chunk-2OAZYSWJ.js";import{wordFitVars as i}from"./chunk-BZ5ASXOL.js";import{jsxs as e,jsx as r}from"react/jsx-runtime";function o({label:a,worded:i,icon:o,active:l,disabled:t,onSelect:n,className:d}){const s=["es-rail-btn",l?"is-active":"",d??""].filter(Boolean).join(" ");/* @__PURE__ */
2
2
  return e("button",{type:"button",className:s,title:a,"aria-label":a,"aria-pressed":"boolean"==typeof l?l:void 0,disabled:t,onClick:t?void 0:n,children:[o,i?/* @__PURE__ */r("span",{className:"es-rail-word","aria-hidden":"true",children:a}):null]})}function l({items:e,ariaLabel:l=a.label,className:t,orientation:n="column",wordFit:d}){const s="row"===n,c=s&&d?d:void 0;/* @__PURE__ */
3
- return r("div",{className:["es-rail",s?"es-rail-row":"",c?"is-measured":"",t??""].filter(Boolean).join(" "),role:"toolbar","aria-orientation":s?"horizontal":"vertical","aria-label":l,style:c&&i(e.length,c),children:e.map(a=>/* @__PURE__ */r(o,{label:a.label,worded:Boolean(c),icon:a.icon,active:a.active,disabled:a.disabled,onSelect:a.onSelect},a.id))})}var t={railWidth:46,railPaddingY:8,railGap:4,railRadius:12,buttonSize:34,buttonRadius:9,iconSize:18,wordPaddingX:8,wordGap:6,wordFontSize:12,wordFontWeight:500,transition:"background 0.12s, color 0.12s",disabledOpacity:.35,color:{background:"#ffffff",shadow:"0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)",idle:"#6b7280",hoverBg:"#f3f4f6",hoverFg:"#111827",accent:"#2563eb",accentTint:"#eff6ff"}},n={railWidth:"--es-rail-w",railPaddingY:"--es-rail-pad-y",railGap:"--es-rail-gap",railRadius:"--es-rail-radius",buttonSize:"--es-rail-btn-size",buttonRadius:"--es-rail-btn-radius",iconSize:"--es-rail-icon-size",wordPaddingX:"--es-rail-word-pad-x",wordGap:"--es-rail-word-gap",wordFontSize:"--es-rail-word-size",wordFontWeight:"--es-rail-word-weight",background:"--es-rail-bg",shadow:"--es-rail-shadow",idle:"--es-rail-fg",hoverBg:"--es-rail-hover-bg",hoverFg:"--es-rail-hover-fg",accent:"--es-rail-accent",accentTint:"--es-rail-accent-tint"};export{l as EditorRail,o as EditorRailButton,n as railCssVars,t as railTokens};
3
+ return r("div",{className:["es-rail",s?"es-rail-row":"",c?"is-measured":"",t??""].filter(Boolean).join(" "),role:"toolbar","aria-orientation":s?"horizontal":"vertical","aria-label":l,style:c&&i(e.length,c),children:e.map(a=>/* @__PURE__ */r(o,{label:a.label,worded:Boolean(c),icon:a.icon,active:a.active,disabled:a.disabled,onSelect:a.onSelect},a.id))})}var t={railWidth:46,railPaddingY:8,railGap:4,railRadius:12,buttonSize:34,buttonRadius:9,iconSize:18,wordPaddingX:8,wordGap:8,wordFontSize:12,wordFontWeight:500,transition:"background 0.12s, color 0.12s",disabledOpacity:.35,color:{background:"#ffffff",shadow:"0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)",idle:"#6b7280",hoverBg:"#f3f4f6",hoverFg:"#111827",accent:"#2563eb",accentTint:"#eff6ff"}},n={railWidth:"--es-rail-w",railPaddingY:"--es-rail-pad-y",railGap:"--es-rail-gap",railRadius:"--es-rail-radius",buttonSize:"--es-rail-btn-size",buttonRadius:"--es-rail-btn-radius",iconSize:"--es-rail-icon-size",wordPaddingX:"--es-rail-word-pad-x",wordGap:"--es-rail-word-gap",wordFontSize:"--es-rail-word-size",wordFontWeight:"--es-rail-word-weight",background:"--es-rail-bg",shadow:"--es-rail-shadow",idle:"--es-rail-fg",hoverBg:"--es-rail-hover-bg",hoverFg:"--es-rail-hover-fg",accent:"--es-rail-accent",accentTint:"--es-rail-accent-tint"};export{l as EditorRail,o as EditorRailButton,n as railCssVars,t as railTokens};
@@ -0,0 +1 @@
1
+ import{isRecord as t,fieldsFrom as n,blockOf as o,topLevelSlotKeys as e,slotLocations as r,setIn as s,fieldsOf as i,isNode as c,defaultsFrom as p}from"./chunk-NKB3KVAB.js";var f=()=>({lastChange:{}});function a(t,n){if(t===n)return!0;if(!t||!n||"object"!=typeof t||"object"!=typeof n)return t!=t&&n!=n;if(Array.isArray(t)!==Array.isArray(n))return!1;if(Array.isArray(t)){const o=n;if(t.length!==o.length)return!1;for(let n=0;n<t.length;n++)if(!a(t[n],o[n]))return!1;return!0}const o=Object.keys(t),e=Object.keys(n);if(o.length!==e.length)return!1;for(const e of o){if(!Object.prototype.hasOwnProperty.call(n,e))return!1;if(!a(t[e],n[e]))return!1}return!0}function l(t,n){if(!t)return{};const o=t.props??{},e=n?.props??{},r={};for(const t of Object.keys(o))r[t]=!a(e[t],o[t]);return r}async function u(i,c,p={}){const{metadata:d={},trigger:h="replace",cache:y=f(),onResolveStart:g,onResolveEnd:m}=p,w=function(t,n){return t.type&&"root"!==t.type?n.components[t.type]:n.root}(i,c);let b={...i};const v=Boolean(w?.resolveData&&i.props),j=t(i.props)&&"id"in i.props?String(i.props.id):"root";if(v){const t=y.lastChange[j];if("force"!==h&&t&&a(i,t.item))return{node:t.resolved,didChange:!1};const n=l(i,t?.item??null);g?.(i);const o=await w.resolveData(i,{changed:n,lastData:t?.item??null,metadata:{...d,...w.metadata??{}},trigger:h})??{};b.props={...i.props,...o.props??{}},o.readOnly&&Object.keys(o.readOnly).length&&(b.readOnly=o.readOnly)}const $=n(i.type&&"root"!==i.type?o(c,i.type):c.root);if(w)for(const t of e($))void 0===b.props[t]&&(b={...b,props:{...b.props,[t]:[]}});for(const t of r(b.props,$)){if(!t.present)continue;const n=await Promise.all(t.content.map(async t=>(await u(t,c,{metadata:d,trigger:h,cache:y,onResolveStart:g,onResolveEnd:m})).node));b={...b,props:s(b.props,t.segments,n)}}return v&&m?.(b),y.lastChange[j]={item:i,resolved:b},{node:b,didChange:!a(i,b)}}var d="root";function h(t){if(void 0===t)return"u";if("string"==typeof t)return`s${t.length.toString(36)}.${y(t)}`;const n=g(t);return`j${n.length.toString(36)}.${y(n)}`}function y(t){let n=2166136261;for(let o=0;o<t.length;o++)n^=t.charCodeAt(o),n=Math.imul(n,16777619);return(n>>>0).toString(36)}function g(t){if(null===t||"object"!=typeof t)return JSON.stringify(t)??"null";if(Array.isArray(t))return`[${t.map(g).join(",")}]`;const n=t;return`{${Object.keys(n).filter(t=>void 0!==n[t]).sort().map(t=>`${JSON.stringify(t)}:${g(n[t])}`).join(",")}}`}var m=(t,n)=>Object.prototype.hasOwnProperty.call(t,n);function w(t,n){return t&&m(t,n)?t[n]:void 0}var b=t=>Object.keys(t).length>0,v=n=>t(n)&&"string"==typeof n.src&&void 0!==n.v,j=t=>null==t||"string"==typeof t&&""===t.trim(),$=t=>"text"===t||"textarea"===t,O=(t,n)=>"boolean"==typeof t.translatable?t.translatable:n;function k(n,o){const e=w(n,o);return t(e)?e:void 0}function A(t,n){const o=[];return x(t,n,[],[],[],void 0,o),o}function x(n,o,e,r,s,i,c){for(const p of Object.keys(o)){const f=o[p];if(!f||"slot"===f.type)continue;if(0===e.length&&"id"===p)continue;const a=[...e,p],l=[...r,p],u=w(n,p),d=O(f,i);if("object"===f.type&&f.objectFields)null==u?x({},f.objectFields,a,l,s,d,c):t(u)&&x(u,f.objectFields,a,l,s,d,c);else if("array"===f.type&&f.arrayFields){if(!Array.isArray(u))continue;const n=f.arrayFields;u.forEach((o,e)=>{t(o)&&x(o,n,[...a,e],[...l,"*"],[...s,e],d,c)})}else(d??$(f.type))&&c.push({path:a.join("."),segments:a,pattern:l.join("."),indices:s,value:u})}}function z(t,n){const o=t.split("."),e=[],r=[];let s,i=n,c=0;for(;c<o.length;){const t=w(i,o[c]);if(!t||"slot"===t.type)return null;if(0===c&&"id"===o[c])return null;e.push(o[c]),c+=1;const n=O(t,s);if("object"===t.type&&t.objectFields)i=t.objectFields,s=n;else{if("array"!==t.type||!t.arrayFields)return c!==o.length?null:n??$(t.type)?{pattern:e.join("."),indices:r}:null;{const p=o[c];if(void 0===p||!/^(0|[1-9]\d*)$/.test(p))return null;r.push(Number(p)),e.push("*"),c+=1,i=t.arrayFields,s=n}}}return null}function I(n,o){return A(t(n?.props)?n.props:{},i(o,n?.type??d)).map(({path:t,value:n})=>({path:t,value:n}))}function S(t,n,o){const e=A(t,n),r=/* @__PURE__ */new Map,s=[],i=[];if(!o)return{positions:e,hits:r,orphans:s,beaten:i};const c=/* @__PURE__ */new Map;for(const t of e)c.set(t.path,t);const p=/* @__PURE__ */new Map,f=t=>{let n=p.get(t);return void 0===n&&(n=h(t.value),p.set(t,n)),n},a=[];for(const t of Object.keys(o)){const e=o[t],p=c.get(t);if(!v(e)){(p?i:s).push(t);continue}if(p&&f(p)===e.src){r.set(t,{position:p,entry:e,from:t,stale:!1,applied:!0});continue}const l=p??z(t,n);l?l.indices.length>0?a.push({path:t,entry:e,own:p,pattern:l.pattern,indices:l.indices}):p?r.set(t,{position:p,entry:e,from:t,stale:!0,applied:!0}):s.push(t):s.push(t)}a.sort((t,n)=>function(t,n){const o=Math.min(t.length,n.length);for(let e=0;e<o;e++)if(t[e]!==n[e])return t[e]-n[e];return t.length-n.length}(t.indices,n.indices)||(t.path<n.path?-1:t.path>n.path?1:0));const l=[];for(const t of a){let n,o=-1;for(const s of e){if(s.pattern!==t.pattern||r.has(s.path))continue;if(f(s)!==t.entry.src)continue;const e=F(s.indices,t.indices);e>o&&(n=s,o=e)}n?r.set(n.path,{position:n,entry:t.entry,from:t.path,stale:!1,applied:!0}):l.push(t)}for(const t of l)t.own?r.has(t.path)?i.push(t.path):r.set(t.path,{position:t.own,entry:t.entry,from:t.path,stale:!0,applied:!1}):s.push(t.path);return{positions:e,hits:r,orphans:s,beaten:i}}function F(t,n){let o=0;for(;o<t.length&&o<n.length&&t[o]===n[o];)o+=1;return o}function M(n,o,e){const p=t=>{if(!Array.isArray(t))return t;let n=null;return t.forEach((o,r)=>{if(!c(o))return;const s=f(e(o.props.id,o.type,o.props),o.type);s!==o.props&&(n??=[...t],n[r]={...o,props:s})}),n??t},f=(t,n)=>{let e=t;for(const c of r(t,i(o,n))){if(!c.present)continue;const t=p(c.content);t!==c.content&&(e=s(e,c.segments,t))}return e};let a=n;const l=t(n.root?.props)?n.root.props:{},u=e(d,d,l),h=p(n.content);h!==n.content&&(a={...a,content:h});const y=f(u,d);y!==l&&(a={...a,root:{...a.root,props:y}});const g=n.zones;if(t(g)){let t=g;for(const n of Object.keys(g)){if(-1===n.indexOf(":"))continue;const o=p(g[n]);o!==g[n]&&(t={...t,[n]:o})}t!==g&&(a={...a,zones:t})}return a}function N(t,n){const o=/* @__PURE__ */new Map;return M(t,n,(t,n,e)=>(o.has(t)||o.set(t,{type:n,props:e}),e)),o}function E(t,n,o){return o&&b(o)?M(t,n,(t,e,r)=>{const c=k(o,t);if(!c)return r;const p=S(r,i(n,e),c);let f=r;for(const t of p.positions){const n=p.hits.get(t.path);n&&n.applied&&!a(t.value,n.entry.v)&&(f=s(f,t.segments,n.entry.v))}return f}):t}function D(t,n,o){const e={total:0,missing:[],stale:[]};return M(t,n,(t,r,s)=>{const c=S(s,i(n,r),k(o,t));for(const n of c.positions){const o=c.hits.get(n.path);!o&&j(n.value)||(e.total+=1,o?o.stale&&e.stale.push({id:t,path:n.path}):e.missing.push({id:t,path:n.path}))}return s}),e}function C(n,o){let e=n;for(let n=0;n<o.length-1;n++){const r=o[n];if("number"==typeof r){if(!Array.isArray(e)||r>=e.length)return{held:!1,value:void 0};e=e[r]}else{if(!t(e))return{held:!1,value:void 0};e=w(e,r)}}return t(e)?{held:!0,value:w(e,String(o[o.length-1]))}:{held:!1,value:void 0}}function J(n,e,r,s){const c=N(e,r),p={},f=/* @__PURE__ */new Set;if(M(n,r,(t,n,e)=>{if(f.has(t))return e;f.add(t);const l=k(s,t),u=c.get(t);if(!u||u.type!==n||!o(r,n))return l&&(p[t]=l),e;const d=S(e,i(r,n),l),y={};for(const t of d.positions){const n=d.hits.get(t.path),{held:o,value:e}=C(u.props,t.segments),r=n&&n.applied?n.entry.v:t.value;!o||void 0!==e&&a(e,r)?n&&(y[t.path]=n.entry):void 0===e||a(e,t.value)||(y[t.path]={v:e,src:h(t.value)})}if(l)for(const t of d.orphans)m(y,t)||(y[t]=l[t]);return b(y)&&(p[t]=l&&P(y,l)?l:y),e}),!s)return p;for(const n of Object.keys(s))f.has(n)||m(p,n)||!t(s[n])||(p[n]=s[n]);return P(p,s)?s:p}function P(t,n){const o=Object.keys(t);return o.length===Object.keys(n).length&&o.every(o=>m(n,o)&&t[o]===n[o])}function R(t,n,e){const r={},s=/* @__PURE__ */new Set;let c=!1;M(t,n,(t,p,f)=>{if(m(r,t))return f;const a=k(e,t);if(!o(n,p))return U(f,s),a&&(r[t]=a),f;if(!a)return f;const l=function(t,n){let o=0===t.orphans.length&&0===t.beaten.length;const e={};for(const n of t.positions){const r=t.hits.get(n.path);r&&(e[n.path]=r.entry,r.from!==n.path&&(o=!1))}return o?n:e}(S(f,i(n,p),a),a);return l!==a&&(c=!0),b(l)&&(r[t]=l),f});for(const t of s){const n=k(e,t);n&&!m(r,t)&&(r[t]=n)}return c||Object.keys(r).length!==Object.keys(e).length?r:e}function U(n,o){if(Array.isArray(n))for(const t of n)U(t,o);else if(t(n)){c(n)&&"string"==typeof n.props.id&&o.add(n.props.id);for(const t of Object.keys(n))U(n[t],o)}}function B(n,e,r,s){if(!t(s)||!b(s))return s;const c=N(e,r),p=/* @__PURE__ */new Map;if(M(n,r,(t,n,e)=>{if(p.has(t))return e;const f=k(s,t),a=c.get(t);if(!f||!a||a.type!==n||!o(r,n))return e;const l=function(t,n,o,e){const r=S(t,o,e),s=/* @__PURE__ */new Map,i=/* @__PURE__ */new Map;K(t,n,o,"","",void 0,s,i);const c={};let p=0===r.beaten.length;for(const t of r.positions){const n=r.hits.get(t.path);if(!n)continue;const o=s.get(t.path)?.[0];void 0!==o?(c[o]=n.entry,o!==n.from&&(p=!1)):p=!1}for(const t of r.positions){const n=r.hits.get(t.path);if(n)for(const o of i.get(t.path)??[])m(c,o)||(c[o]=n.entry,p=!1)}for(const t of[...r.orphans].sort())m(c,t)?p=!1:c[t]=e[t];return p?e:c}(e,a.props,i(r,n),f);return l!==f&&p.set(t,l),e}),0===p.size)return s;const f={};for(const t of Object.keys(s)){const n=p.get(t);n?b(n)&&(f[t]=n):f[t]=s[t]}return f}function K(n,o,e,r,s,i,c,p){for(const f of Object.keys(e)){const a=e[f];if(!a||"slot"===a.type)continue;if(""===r&&"id"===f)continue;const l=""===r?f:`${r}.${f}`,u=""===s?f:`${s}.${f}`,d=w(n,f),h=w(o,f),y=O(a,i);if("object"===a.type&&a.objectFields){if(null!=d&&!t(d))continue;K(t(d)?d:{},t(h)?h:{},a.objectFields,l,u,y,c,p)}else if("array"===a.type&&a.arrayFields){if(!Array.isArray(d))continue;const n=Array.isArray(h)?h:[];for(const o of T(d,n)){const e=d[o.from];if(!t(e))continue;const r="edited"===o.kind?n[o.to]:e;K(e,t(r)?r:{},a.arrayFields,`${l}.${o.from}`,`${u}.${o.to}`,y,"copy"===o.kind?p:c,p)}}else if(y??$(a.type)){const t=c.get(l);t?t.push(u):c.set(l,[u])}}}function T(t,n){const o=t.map(g),e=n.map(g),r=o.map(()=>!1),s=e.map(()=>!1),i=[],c=Math.min(o.length,e.length);for(let t=0;t<c;t++)o[t]===e[t]&&(i.push({from:t,to:t,kind:"same"}),r[t]=s[t]=!0);for(let t=0;t<e.length;t++){if(s[t])continue;const n=o.findIndex((n,o)=>!r[o]&&n===e[t]);-1!==n&&(i.push({from:n,to:t,kind:"same"}),r[n]=s[t]=!0)}for(let t=0;t<c;t++)r[t]||s[t]||(i.push({from:t,to:t,kind:"edited"}),r[t]=s[t]=!0);for(let t=0;t<e.length;t++){if(s[t])continue;const n=o.indexOf(e[t]);-1!==n&&i.push({from:n,to:t,kind:"copy"})}return i}function V(t,n,o){const e={},s=(t,n)=>{if(t.type!==n.type)return;e[t.props.id]=n.props.id;const p=r(n.props,i(o,n.type));for(const n of r(t.props,i(o,t.type))){const t=p.find(t=>t.slot===n.slot);t&&n.content.forEach((n,o)=>{const e=t.content[o];c(n)&&c(e)&&s(n,e)})}};return c(t)&&c(n)&&s(t,n),e}function q(t,n){const o={};if(!t)return o;for(const e of Object.keys(n)){const r=k(t,e),s=n[e];r&&b(r)&&"string"==typeof s&&(o[s]={...r})}return o}var G="root",H="default-zone",L={parentId:G,slot:H},Q=({parentId:t,slot:n})=>`${t}:${n}`;function W(t){const n=t.indexOf(":");if(-1===n)throw new Y("no-slot",`"${t}" is not a zone key`);return{parentId:t.slice(0,n),slot:t.slice(n+1)}}var X=t=>t.parentId===G&&t.slot===H,Y=class extends Error{code;constructor(t,n){super(n),this.name="DataError",this.code=t}};function Z(t){try{const n=globalThis.crypto;if(n&&"function"==typeof n.randomUUID)return`${t}-${n.randomUUID()}`}catch{}return`${t}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,10)}`}function _(t,n){return r(t.props,i(n,t.type)).map(({slot:t,content:n})=>({slot:t,content:n}))}function tt(t,o){return r(nt(t),n(o.root))}function nt(n){return t(n.root?.props)?n.root.props:{}}function ot(t,n,o){const e=(t,n,e,r,s)=>{if(!Array.isArray(t))return t;const i=[...e,n];let f=null;return t.forEach((e,a)=>{if(!c(e))return;const l={place:{...n,index:a},path:i,parent:r,depth:s};let u=o(e,l)??e;if(u!==e&&u.props.id!==e.props.id)throw new Y("id-change",`walk: ${e.props.id} came back as ${u.props.id}`);u=p(u,i,s+1),u!==e&&(f??=[...t],f[a]=u)}),f??t},p=(t,o,c)=>{let p=t.props;for(const f of r(t.props,i(n,t.type))){if(!f.present)continue;const n=e(f.content,{parentId:t.props.id,slot:f.slot},o,t,c);n!==f.content&&(p=s(p,f.segments,n))}return p===t.props?t:{...t,props:p}};let f=t;const a=e(t.content,L,[],null,0);a!==t.content&&(f={...f,content:a});let l=nt(f);for(const t of tt(f,n)){if(!t.present)continue;const n=e(t.content,{parentId:G,slot:t.slot},[],null,0);n!==t.content&&(l=s(l,t.segments,n))}l!==nt(f)&&(f={...f,root:{...f.root,props:l}});const u=f.zones;if(u){let t=u;for(const n of Object.keys(u)){const o=et(n);if(!o)continue;const r=e(u[n],o,[],null,0);r!==u[n]&&(t={...t,[n]:r})}t!==u&&(f={...f,zones:t})}return f}function et(t){const n=t.indexOf(":");return-1===n?null:{parentId:t.slice(0,n),slot:t.slice(n+1)}}function rt(t,n,o){let e=null;const r={};try{ot(t,n,(t,n)=>{if(t.props.id===o)throw e={node:t,place:n.place,path:n.path},r})}catch(t){if(t!==r)throw t}return e}function st(t,n,o){if(X(o))return Array.isArray(t.content)?t.content:[];const e=t.zones?.[Q(o)];if(o.parentId===G){const r=tt(t,n).find(t=>t.slot===o.slot);return r?r.content:e??null}const s=rt(t,n,o.parentId);if(s){const t=r(s.node.props,i(n,s.node.type)).find(t=>t.slot===o.slot);if(t)return t.content}return e??null}function it(t,n){const o=/* @__PURE__ */new Set;return ot(t,n,t=>{o.add(t.props.id)}),o}function ct(t,n){const o=/* @__PURE__ */new Set([t.props.id]),e=t=>{for(const{content:r}of _(t,n))for(const t of r)c(t)&&(o.add(t.props.id),e(t))};return e(t),o}function pt(t,n,o,e){if(X(o)){const n=Array.isArray(t.content)?t.content:[];return{...t,content:e(n)}}const c=Q(o),p=!!t.zones&&Array.isArray(t.zones[c]);if(o.parentId===G){const r=tt(t,n).find(t=>t.slot===o.slot);if(r){const n=s(nt(t),r.segments,e(r.content));return{...t,root:{...t.root,props:n}}}}else{const c=rt(t,n,o.parentId);if(c){const p=r(c.node.props,i(n,c.node.type)).find(t=>t.slot===o.slot);if(p)return ft(t,n,c,t=>({...t,props:s(t.props,p.segments,e(p.content))}))}else if(!p)throw new Y("not-found",`no node ${o.parentId}`)}if(p)return{...t,zones:{...t.zones,[c]:e(t.zones[c])}};throw new Y("no-slot",`no slot "${o.slot}" on ${o.parentId}`)}function ft(t,n,o,e){return pt(t,n,o.place,t=>{const n=[...t];return n[o.place.index]=e(t[o.place.index]),n})}function at(t,n,o){const e=rt(t,n,o);if(!e)throw new Y("not-found",`no node ${o}`);return e}function lt(t,n,o){const e=st(t,n,o);if(e)return e;if(o.parentId!==G&&!rt(t,n,o.parentId))throw new Y("not-found",`no node ${o.parentId}`);throw new Y("no-slot",`no slot "${o.slot}" on ${o.parentId}`)}function ut(t,n,o){if(!Number.isInteger(t)||t<0||t>n)throw new Y("bad-index",`${o}: index ${t} is outside 0…${n}`)}function dt(t,i){const c=o(i,t.type);if(!c)return t;const p=n(c);let f=t.props;for(const t of e(p))null==f[t]&&(f={...f,[t]:[]});for(const t of r(f,p)){if(!t.present)continue;const n=ht(t.content,i);n!==t.content&&(f=s(f,t.segments,n))}return f===t.props?t:{...t,props:f}}function ht(n,o){let e=null;return n.forEach((r,s)=>{if(!t(r)||"string"!=typeof r.type)return;let i=r;if(t(i.props)){if("string"!=typeof i.props.id||""===i.props.id){const{id:t,...n}=i.props;i={...i,props:{id:Z(i.type),...n}}}}else i={...i,props:{id:Z(i.type)}};const c=dt(i,o);c!==r&&(e??=[...n],e[s]=c)}),e??n}function yt(t,o){const i=n(o.root);let c=t.props;for(const t of e(i))null==c[t]&&(c={...c,[t]:[]});for(const t of r(c,i)){if(!t.present)continue;const n=ht(t.content,o);n!==t.content&&(c=s(c,t.segments,n))}return c===t.props?t:{...t,props:c}}function gt(n,o){let e=t(n)?n:{};const r=e.root;if(t(r)){if(!t(r.props)){const t=Object.keys(r).filter(t=>"props"!==t);e={...e,root:t.length?{props:{...wt(r,t)}}:{props:{}}}}}else e={...e,root:{props:{}}};const s=p(o.root);if(s){const t=Object.keys(s).filter(t=>!(t in e.root.props));if(t.length){const n=bt(wt(s,t));e={...e,root:{...e.root,props:{...e.root.props,...n}}}}}const i=yt(e.root,o);i!==e.root&&(e={...e,root:i}),Array.isArray(e.content)||(e={...e,content:[]});const c=ht(e.content,o);return c!==e.content&&(e={...e,content:c}),e=t(e.zones)?function(t,n){let o=t;for(const e of Object.keys(t.zones??{})){const t=o.zones[e];if(!Array.isArray(t)||0===t.length)continue;const r=et(e);if(!r||X(r))continue;const s=mt(o,n,r);if(!s||s.content.length>0)continue;const{[e]:i,...c}=o.zones;o=pt({...o,zones:c},n,r,()=>ht(t,n))}const e=o.zones;let r=e;for(const t of Object.keys(e)){if(!Array.isArray(e[t]))continue;const o=ht(e[t],n);o!==e[t]&&(r={...r,[t]:o})}return r===e?o:{...o,zones:r}}(e,o):{...e,zones:{}},e}function mt(t,n,o){if(o.parentId===G)return tt(t,n).find(t=>t.slot===o.slot);const e=rt(t,n,o.parentId);return e?r(e.node.props,i(n,e.node.type)).find(t=>t.slot===o.slot):void 0}function wt(t,n){const o={};for(const e of n)o[e]=t[e];return o}function bt(t){return void 0===t?t:JSON.parse(JSON.stringify(t))}function vt(t,n,o={},e={}){const r=t.components[n];if(!r)throw new Y("unknown-type",`no block type "${n}" in the config`);return dt({type:n,props:{...bt(p(r)??{}),...bt(o),id:e.id??Z(n)}},t)}function jt(n,o,e,r){if(!c(r))throw new Y("unknown-type","insert: not a node");const s=lt(n,o,e);ut(e.index,s.length,"insert");const i=dt(t(r.props)&&"string"==typeof r.props.id&&r.props.id?r:{...r,props:{...r.props,id:Z(r.type)}},o),p=it(n,o);for(const t of ct(i,o))if(p.has(t))throw new Y("duplicate-id",`insert: ${t} is already in the document`);return pt(n,o,e,t=>[...t.slice(0,e.index),i,...t.slice(e.index)])}function $t(t,n,o){const e=at(t,n,o);let r=pt(t,n,e.place,t=>[...t.slice(0,e.place.index),...t.slice(e.place.index+1)]);if(r.zones&&Object.keys(r.zones).length){const t=ct(e.node,n),o=Object.keys(r.zones).filter(n=>!t.has(n.split(":")[0]));o.length!==Object.keys(r.zones).length&&(r={...r,zones:wt(r.zones,o)})}return r}function Ot(t,n,o,e){const r=at(t,n,o);if(ct(r.node,n).has(e.parentId))throw new Y("cycle",`move: ${o} cannot go inside itself`);if(r.place.parentId===e.parentId&&r.place.slot===e.slot){const o=lt(t,n,e);return ut(e.index,o.length-1,"move"),e.index===r.place.index?t:pt(t,n,e,t=>{const n=[...t],[o]=n.splice(r.place.index,1);return n.splice(e.index,0,o),n})}ut(e.index,lt(t,n,e).length,"move");const s=pt(t,n,r.place,t=>[...t.slice(0,r.place.index),...t.slice(r.place.index+1)]);return pt(s,n,e,t=>[...t.slice(0,e.index),r.node,...t.slice(e.index)])}function kt(t,n,o,e={}){const r=at(t,n,o),s=xt(bt(r.node),n,e.strip,e.id);return pt(t,n,r.place,t=>[...t.slice(0,r.place.index+1),s,...t.slice(r.place.index+1)])}function At(t,n,o={}){return xt(bt(t),n,o.strip,o.id)}function xt(t,n,o,e){let p={...t,props:{...t.props,id:e??Z(t.type)}};if(o){const t=o(p);if(t.props.id!==p.props.id)throw new Y("id-change","duplicate: strip must not change the id");p=t}let f=p.props;for(const t of r(f,i(n,p.type))){if(!t.present)continue;const e=t.content.map(t=>c(t)?xt(t,n,o):t);f=s(f,t.segments,e)}return dt({...p,props:f},n)}function zt(t,n,o,e){if("id"in e&&e.id!==o)throw new Y("id-change",`setProps: ${o} cannot become ${String(e.id)}`);const r=at(t,n,o);return Ft(r.node.props,e)?ft(t,n,r,t=>dt({...t,props:{...t.props,...e,id:o}},n)):t}function It(t,n,o,e){if(!c(e))throw new Y("unknown-type","replaceNode: not a node");if(e.props.id!==o)throw new Y("id-change",`replaceNode: ${o} cannot become ${String(e.props.id)}`);const r=at(t,n,o),s=dt(e,n),i=it(t,n);for(const t of ct(r.node,n))i.delete(t);for(const t of ct(s,n))if(i.has(t))throw new Y("duplicate-id",`replaceNode: ${t} is already in the document`);return ft(t,n,r,()=>s)}function St(t,n,o){const e=nt(t);if(!Ft(e,o))return t;const r=yt({...t.root,props:{...e,...o}},n);return{...t,root:r}}function Ft(t,n){return Object.keys(n).some(o=>!(o in t)||!Object.is(t[o],n[o]))}export{Y as DataError,G as ROOT_ID,L as ROOT_LIST,H as ROOT_SLOT,E as applyTranslation,l as changedProps,At as copyNode,q as copyTranslation,vt as createNode,f as createResolveCache,a as deepEqual,kt as duplicate,J as extractTranslation,rt as find,st as getList,jt as insert,V as mapIds,Ot as move,Z as newId,gt as normalizeData,W as parseZoneKey,R as pruneTranslation,B as rebaseTranslation,$t as remove,It as replaceNode,u as resolveNodeData,zt as setProps,St as setRoot,_ as slotsOf,I as translatablePaths,h as translationFingerprint,D as translationStatus,ot as walk,Q as zoneKey};