efficient-easel 0.99.0 → 0.99.2

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 (58) hide show
  1. package/README.md +55 -26
  2. package/dist/autosave/index.d.ts +5 -5
  3. package/dist/blocks/index.d.ts +2 -2
  4. package/dist/canvas/index.d.ts +3 -3
  5. package/dist/chrome/index.d.ts +13 -9
  6. package/dist/chrome/index.js +9 -9
  7. package/dist/chunk-672FAEKU.js +1 -0
  8. package/dist/chunk-7JTL3P6P.js +1 -0
  9. package/dist/chunk-F2PIG3AA.js +10 -0
  10. package/dist/chunk-XUE5O62R.js +3 -0
  11. package/dist/copy/index.d.ts +5 -5
  12. package/dist/data/index.d.ts +4 -4
  13. package/dist/drag/drag.css +26 -6
  14. package/dist/drag/index.d.ts +4 -4
  15. package/dist/drag/index.js +5 -6
  16. package/dist/{editor/editor.css → easel/easel.css} +10 -1
  17. package/dist/easel/index.d.ts +385 -0
  18. package/dist/easel/index.js +1 -0
  19. package/dist/edit-lock/index.d.ts +5 -3
  20. package/dist/edit-lock/index.js +1 -1
  21. package/dist/editor/index.d.ts +9 -360
  22. package/dist/editor/index.js +1 -9
  23. package/dist/fields/index.d.ts +4 -4
  24. package/dist/index.d.ts +3 -3
  25. package/dist/index.js +1 -1
  26. package/dist/menu/index.d.ts +8 -6
  27. package/dist/menu/index.js +4 -4
  28. package/dist/node-ops/index.d.ts +9 -9
  29. package/dist/panel/index.d.ts +1 -1
  30. package/dist/pick/index.d.ts +3 -3
  31. package/dist/rail/index.d.ts +10 -6
  32. package/dist/rail/index.js +1 -1
  33. package/dist/rail/rail.css +1 -1
  34. package/dist/strings/catalogue.d.ts +23 -17
  35. package/dist/strings/catalogue.js +1 -1
  36. package/dist/strings/index.d.ts +28 -20
  37. package/dist/strings/index.js +2 -2
  38. package/dist/style-clipboard/index.d.ts +5 -5
  39. package/dist/tree/index.d.ts +2 -2
  40. package/dist/{types-Dy6oR6Z2.d.ts → types-BOSGNvil.d.ts} +26 -14
  41. package/dist/{types-DNrn_w4V.d.ts → types-Bs_gVkVI.d.ts} +18 -10
  42. package/dist/{types-pGBXevBU.d.ts → types-DO-b0LNj.d.ts} +13 -7
  43. package/dist/{types-CnRzp9oc.d.ts → types-p9j2Fac7.d.ts} +11 -9
  44. package/dist/{watch-DmasQA61.d.ts → watch-B5RTR-WX.d.ts} +1 -1
  45. package/dist/{wordFit-9B9nqyf3.d.ts → wordFit-D4S36PvB.d.ts} +1 -1
  46. package/dist/{words-D9ChvbNC.d.ts → words-BDignMl_.d.ts} +1 -1
  47. package/dist/{words-bOMsUJk9.d.ts → words-C74EUpFr.d.ts} +2 -2
  48. package/dist/{words-B2YLaKEr.d.ts → words-CnnHb9jo.d.ts} +1 -1
  49. package/dist/{words-DOhF-4D4.d.ts → words-DMG4dYq2.d.ts} +1 -1
  50. package/dist/{words-BK-npta-.d.ts → words-N4ebT88_.d.ts} +1 -1
  51. package/dist/{words-Cqmyey0s.d.ts → words-c-3h9xQQ.d.ts} +2 -2
  52. package/dist/{words-B87GIFWH.d.ts → words-is_Vy6hn.d.ts} +1 -1
  53. package/package.json +9 -3
  54. package/dist/chunk-IBOFSS56.js +0 -3
  55. package/dist/chunk-JE63JHKO.js +0 -1
  56. package/dist/chunk-TDA4HH54.js +0 -1
  57. /package/dist/{chunk-OWBO4WKA.js → chunk-2PHD4L6A.js} +0 -0
  58. /package/dist/{chunk-GGTPNGFJ.js → chunk-AELNNAFM.js} +0 -0
package/README.md CHANGED
@@ -21,7 +21,7 @@ it since 0.93.0.
21
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
- 20px, radius 9 vs 8, a CSS-var accent vs a Tailwind one. `EditorRail` is the one
24
+ 20px, radius 9 vs 8, a CSS-var accent vs a Tailwind one. `EaselRail` is the one
25
25
  rail they converge on.
26
26
 
27
27
  ## The leaf
@@ -36,14 +36,14 @@ it.
36
36
  // A client component in any editor:
37
37
  'use client';
38
38
  import {
39
- EditorRail,
39
+ EaselRail,
40
40
  PagesIcon, LayersIcon, StylesIcon, MediaIcon, SitemapIcon, AddIcon,
41
41
  } from 'efficient-easel/rail';
42
42
  import 'efficient-easel/rail.css'; // once, from a client/global entry
43
43
 
44
44
  export function LeftRail({ view, onView, onAdd }) {
45
45
  return (
46
- <EditorRail
46
+ <EaselRail
47
47
  ariaLabel="Left panel views"
48
48
  items={[
49
49
  { id: 'pages', label: 'Pages', icon: <PagesIcon />, active: view === 'pages', onSelect: () => onView('pages') },
@@ -59,14 +59,14 @@ export function LeftRail({ view, onView, onAdd }) {
59
59
 
60
60
  ## API
61
61
 
62
- ### `<EditorRail items ariaLabel? className? orientation? />`
62
+ ### `<EaselRail items ariaLabel? className? orientation? />`
63
63
 
64
64
  A **pure presentational** toolbar. It owns the look, never the app state — you
65
65
  decide which item is `active` and what each `onSelect` does.
66
66
 
67
67
  | prop | type | default | notes |
68
68
  |---|---|---|---|
69
- | `items` | `EditorRailItem[]` | — | buttons, in render order |
69
+ | `items` | `EaselRailItem[]` | — | buttons, in render order |
70
70
  | `ariaLabel` | `string` | `"Editor"` | names the toolbar for assistive tech |
71
71
  | `className` | `string` | — | merged onto `.es-rail` |
72
72
  | `orientation` | `'column' \| 'row'` | `'column'` | which way the buttons run |
@@ -85,17 +85,17 @@ changes. A row is 34px tall, so a 52px bar centres it with 9px to spare.
85
85
 
86
86
  ```tsx
87
87
  // The same rail, in the top bar's empty middle.
88
- <EditorRail orientation="row" ariaLabel="Editor views" items={items} />
88
+ <EaselRail orientation="row" ariaLabel="Editor views" items={items} />
89
89
  ```
90
90
 
91
91
  `aria-orientation` follows the layout (`vertical` / `horizontal`); the `toolbar`
92
92
  role does not change, because a rail that mixes view toggles with plain actions
93
93
  is a toolbar whichever way it runs.
94
94
 
95
- ### `EditorRailItem`
95
+ ### `EaselRailItem`
96
96
 
97
97
  ```ts
98
- interface EditorRailItem {
98
+ interface EaselRailItem {
99
99
  id: string; // React key + selection correlation
100
100
  label: string; // aria-label + hover title
101
101
  icon: React.ReactNode; // an 18px currentColor glyph — use the shipped icons
@@ -109,7 +109,7 @@ A **view item** passes `active: true | false` and renders as a toggle
109
109
  (`aria-pressed`, `.is-active` highlight). An **action item** (the quick-add "+")
110
110
  omits `active` and renders as a plain button.
111
111
 
112
- `EditorRailButton` — the single-button building block `EditorRail` maps to — is
112
+ `EaselRailButton` — the single-button building block `EaselRail` maps to — is
113
113
  exported too, for bespoke layouts.
114
114
 
115
115
  ## Tokens
@@ -263,7 +263,7 @@ export const pageEditLock = createEditLock({
263
263
 
264
264
  The plain half needs no binding: `canWriteDocument`, `holderOf`,
265
265
  `readLockHolder`, `accessForNewDocument`, `documentPermissions`, `describeAge`,
266
- `nameOrSomeone`, `newEditorClientId`, `shouldReleaseHeldWrite`,
266
+ `nameOrSomeone`, `newEaselClientId`, `shouldReleaseHeldWrite`,
267
267
  `shouldReloadAfterTakeover`, `documentVersionMoved`, `reloadIfVersionMoved`.
268
268
  The bound half —
269
269
  `accessAfterClaimFailure`, `accessAfterTakeoverFailure`,
@@ -296,16 +296,16 @@ the editor owns the device, the save status, the widths and which panels are ope
296
296
 
297
297
  ```tsx
298
298
  import {
299
- EditorTopBar, TopBarCluster, TopBarDivider, EditorIconButton, DeviceSwitch,
299
+ EaselTopBar, TopBarCluster, TopBarDivider, EaselIconButton, DeviceSwitch,
300
300
  SaveState, PanelResizeHandle, InspectorHead, DEFAULT_PANEL_W, panelWidthVars,
301
301
  } from 'efficient-easel/chrome';
302
302
  import 'efficient-easel/chrome.css'; // once, after shell.css
303
303
 
304
304
  <div className="es-editor" style={panelWidthVars(widths)}> {/* the vars go on the ROOT */}
305
- <EditorTopBar>
306
- <TopBarCluster kind="rail"><EditorRail orientation="row" items={items} /></TopBarCluster>
305
+ <EaselTopBar>
306
+ <TopBarCluster kind="rail"><EaselRail orientation="row" items={items} /></TopBarCluster>
307
307
  <TopBarCluster>
308
- <EditorIconButton label="Undo" onClick={undo}><UndoIcon /></EditorIconButton>
308
+ <EaselIconButton label="Undo" onClick={undo}><UndoIcon /></EaselIconButton>
309
309
  <TopBarDivider />
310
310
  <DeviceSwitch devices={devices} value={device} onChange={setDevice} />
311
311
  </TopBarCluster>
@@ -313,7 +313,7 @@ import 'efficient-easel/chrome.css'; // once, after shell.css
313
313
  <SaveState tone="saved" label="" />
314
314
  <button className="es-btn-primary">Done</button>
315
315
  </TopBarCluster>
316
- </EditorTopBar>
316
+ </EaselTopBar>
317
317
  …
318
318
  </div>
319
319
  ```
@@ -754,24 +754,24 @@ typed catalogue, so a host in another language can translate it. A host that
754
754
  does nothing sees the English it always saw.
755
755
 
756
756
  ```tsx
757
- import { EditorStringsProvider, useEditorStrings, type DeepPartial, type EditorStrings } from 'efficient-easel/strings';
757
+ import { EaselStringsProvider, useEaselStrings, type DeepPartial, type EaselStrings } from 'efficient-easel/strings';
758
758
 
759
- const german: DeepPartial<EditorStrings> = {
759
+ const german: DeepPartial<EaselStrings> = {
760
760
  save: { failed: 'Speichern fehlgeschlagen' },
761
761
  lock: { minutesAgo: ({ count }) => `vor ${count} Min.` }, // a value or a plural: a function
762
762
  };
763
763
 
764
- <EditorStringsProvider value={german} locale="de">
764
+ <EaselStringsProvider value={german} locale="de">
765
765
  <Editor />
766
- </EditorStringsProvider>;
766
+ </EaselStringsProvider>;
767
767
  ```
768
768
 
769
- - **`EditorStrings`** is grouped by the module that says the word (`notice`,
769
+ - **`EaselStrings`** is grouped by the module that says the word (`notice`,
770
770
  `lock`, `save`, `chrome`, `rail`, `tree`, `panel`, `fields`, `pick`, `drag`,
771
771
  `menu`, `styleClipboard`, `copy`, `canvas`). A plain word is a `string`;
772
772
  anything with a value in it is a function, so the host places the value and
773
- does its own plural. `DEFAULT_EDITOR_STRINGS` is the English.
774
- - **What is left out falls back** (`mergeEditorStrings`), and a provider inside
773
+ does its own plural. `DEFAULT_EASEL_STRINGS` is the English.
774
+ - **What is left out falls back** (`mergeEaselStrings`), and a provider inside
775
775
  another lays its words over the outer one's.
776
776
  - **The provider reaches the parts that have hooks:** the edit notice, the device
777
777
  switch, "up one level", the panel grip and the top-bar rail; the copy box, its
@@ -784,9 +784,9 @@ const german: DeepPartial<EditorStrings> = {
784
784
  argument:
785
785
 
786
786
  ```tsx
787
- const strings = useEditorStrings();
787
+ const strings = useEaselStrings();
788
788
 
789
- <EditorRail items={items} ariaLabel={strings.rail.label} />
789
+ <EaselRail items={items} ariaLabel={strings.rail.label} />
790
790
  <TreeRow … words={strings.tree} />
791
791
  <ColourPicker … words={strings.pick.colour} />
792
792
  <ImageBox … words={strings.pick.image} />
@@ -799,17 +799,46 @@ const german: DeepPartial<EditorStrings> = {
799
799
  styleMenuItems({ …, words: strings.styleClipboard });
800
800
  pasteMessage(plan, source, target, strings.styleClipboard);
801
801
  ```
802
- - **`useEditorLocale()`** is the provider's `locale` (`'en'` with none), for a
802
+ - **`useEaselLocale()`** is the provider's `locale` (`'en'` with none), for a
803
803
  host's own blocks and fields. The engine does not read it.
804
804
  - **A server file may import it.** Importing the entry runs nothing — the React
805
805
  context is made on first use. `efficient-easel/strings/catalogue` is the
806
- catalogue, its types and `mergeEditorStrings` with no React in its graph at
806
+ catalogue, its types and `mergeEaselStrings` with no React in its graph at
807
807
  all: what a host's own test imports to check its languages against the
808
808
  engine's keys.
809
809
 
810
810
  What a host supplies was never the engine's and is not in the catalogue: a
811
811
  block's name, a field's label, a tile's caption, the document's `noun`.
812
812
 
813
+ ## The names before the Easel rename
814
+
815
+ The package took the name `efficient-easel` at 0.96.0. Its exports followed:
816
+ every `Editor…` name is an `Easel…` one, and the store's subpath is
817
+ `efficient-easel/easel`. **Every old name still works**, deprecated, and is the
818
+ same value as its new name, so an app moves file by file.
819
+
820
+ | Subpath | Was | Is |
821
+ | --- | --- | --- |
822
+ | `efficient-easel/editor` | the subpath itself, and `editor.css` | `efficient-easel/easel`, `easel.css` |
823
+ | `/easel` | `createEditor`, `Editor`, `EditorOptions` | `createEasel`, `Easel`, `EaselOptions` |
824
+ | `/easel` | `EditorProvider` (prop `editor`) | `EaselProvider` (prop `easel`) |
825
+ | `/easel` | `useEditor`, `useEditorApi`, `createUseEditor`, `useEditorNodeOps` | `useEasel`, `useEaselApi`, `createUseEasel`, `useEaselNodeOps` |
826
+ | `/easel` | `EditorCanvas`, `EditorCanvasProps` | `EaselCanvas`, `EaselCanvasProps` |
827
+ | `/easel` | `EditorConfig`, `EditorView`, `EditorUi`, `EditorAction`, `EditorCore`, `EditorHistory` | `EaselConfig`, `EaselView`, `EaselUi`, `EaselAction`, `EaselCore`, `EaselHistory` |
828
+ | `/rail` | `EditorRail`, `EditorRailButton`, `EditorRailItem`, `EditorRailProps`, `EditorRailButtonProps`, `EditorRailOrientation` | `EaselRail`, `EaselRailButton`, `EaselRailItem`, `EaselRailProps`, `EaselRailButtonProps`, `EaselRailOrientation` |
829
+ | `/menu` | `EditorContextMenu`, `EditorContextMenuItem`, `EditorContextMenuProps`, `EditorContextMenuSkin` | `EaselContextMenu`, `EaselContextMenuItem`, `EaselContextMenuProps`, `EaselContextMenuSkin` |
830
+ | `/chrome` | `EditorTopBar`, `EditorIconButton`, `EditorIconButtonProps` | `EaselTopBar`, `EaselIconButton`, `EaselIconButtonProps` |
831
+ | `/strings` | `EditorStrings`, `DEFAULT_EDITOR_STRINGS`, `mergeEditorStrings`, `EditorStringsProvider`, `EditorStringsProviderProps`, `useEditorStrings`, `useEditorLocale` | `EaselStrings`, `DEFAULT_EASEL_STRINGS`, `mergeEaselStrings`, `EaselStringsProvider`, `EaselStringsProviderProps`, `useEaselStrings`, `useEaselLocale` |
832
+ | `/edit-lock` | `newEditorClientId` | `newEaselClientId` |
833
+
834
+ `efficient-easel/editor` and `efficient-easel/easel` are built on one chunk, so
835
+ a provider imported from one is read by a hook imported from the other.
836
+
837
+ Not renamed, because other code holds them: the `.es-editor` class and every
838
+ other `es-` class, the `--es-*` variables, the `editor-shell:style-clipboard`
839
+ storage key, and the rail's default label, the word "Editor", which a screen
840
+ reader says to the person using a host's editor.
841
+
813
842
  ## Develop
814
843
 
815
844
  Node is native on the dev Mac (v26.8.1) — run these in your own worktree; a
@@ -1,8 +1,8 @@
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
- import '../types-DNrn_w4V.js';
5
- import '../wordFit-9B9nqyf3.js';
1
+ import { A as Autosave, a as AutosaveSnapshot, b as SaveIndicator, c as AutosaveOptions } from '../words-c-3h9xQQ.js';
2
+ export { d as AutosaveClock, S as SaveWords, e as createAutosave, s as saveIndicator } from '../words-c-3h9xQQ.js';
3
+ import '../types-p9j2Fac7.js';
4
+ import '../types-Bs_gVkVI.js';
5
+ import '../wordFit-D4S36PvB.js';
6
6
  import 'react';
7
7
  import '../edit-lock/index.js';
8
8
 
@@ -1,5 +1,5 @@
1
1
  import { ReactElement, FC, CSSProperties, ReactNode, JSX } from 'react';
2
- import { P as Permissions, A as AppState } from '../types-Dy6oR6Z2.js';
2
+ import { P as Permissions, A as AppState } from '../types-BOSGNvil.js';
3
3
  import '../data/index.js';
4
4
  import '../types-41704JE4.js';
5
5
  import '../resolve-D68pb3Bx.js';
@@ -21,7 +21,7 @@ import '../plan-DChbUXdS.js';
21
21
  * - the `ConfigParams` form of `Config<{ components, root, fields }>` and the
22
22
  * user field-type extension it carries (neither app uses it);
23
23
  * - everything about Puck's own editor — its store, overrides, plugins and
24
- * history. Those are the engine's now (`efficient-easel/editor`).
24
+ * history. Those are the engine's now (`efficient-easel/easel`).
25
25
  *
26
26
  * The `puck` prop keeps its name: it is what every block's `render` destructures
27
27
  * (`puck.isEditing`, `puck.renderDropZone`), and renaming it is the block rewrite
@@ -1,6 +1,6 @@
1
1
  import { RefObject } from 'react';
2
- import { C as CanvasTarget, W as WatchOptions } from '../watch-DmasQA61.js';
3
- export { B as BLOCK_SELECTOR, a as CANVAS_SELECTOR, i as isFrameReady, w as watchCanvasFrame } from '../watch-DmasQA61.js';
2
+ import { C as CanvasTarget, W as WatchOptions } from '../watch-B5RTR-WX.js';
3
+ export { B as BLOCK_SELECTOR, a as CANVAS_SELECTOR, i as isFrameReady, w as watchCanvasFrame } from '../watch-B5RTR-WX.js';
4
4
 
5
5
  /**
6
6
  * The small facts every canvas surface needs, written once — pure DOM, no
@@ -103,7 +103,7 @@ declare function fitCanvas({ available, width, maxScale, }: {
103
103
  * 'nonce-…'`), where a `<style>` without it is refused. Every sheet
104
104
  * `upsertCanvasStyle` / `useCanvasStyle` creates in `doc` afterwards wears it.
105
105
  *
106
- * `CanvasFrame` (`efficient-easel/editor`) calls this with its `nonce` prop as
106
+ * `CanvasFrame` (`efficient-easel/easel`) calls this with its `nonce` prop as
107
107
  * it builds the frame, so a host says it once; a host that builds its own
108
108
  * frame calls it itself. `undefined` (or `''`) forgets it.
109
109
  */
@@ -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, g as EditNoticeProps } from '../types-p9j2Fac7.js';
3
+ export { h as DEFAULT_PANEL_W, i as DeviceOption, j as EditorIconButtonProps, M as MAX_PANEL_W, k as MIN_PANEL_W, l as PanelSide, m as PanelWidths, S as SaveTone, n as clampPanelWidth, p as panelWidthVars } from '../types-p9j2Fac7.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';
7
- import '../types-DNrn_w4V.js';
8
- import '../wordFit-9B9nqyf3.js';
7
+ import '../types-Bs_gVkVI.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,17 +21,19 @@ 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
28
28
  * looking at (device, panels). A second one splits the very run this order makes.
29
29
  */
30
30
  declare function TopBarDivider(): react.JSX.Element;
31
+ /** @deprecated The name before the Easel rename: `EaselTopBar`. */
32
+ declare const EditorTopBar: typeof EaselTopBar;
31
33
 
32
34
  /**
33
35
  * 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
36
+ * width, carrying its hairline — `.es-cluster--rail`) holding an `EaselRail` in
35
37
  * `orientation="row"`, wearing its words by THE SETTINGS TABS' RULE (owner,
36
38
  * 2026-09-18: "the rule must be the same as the top tabs of the right settings
37
39
  * panel"):
@@ -62,7 +64,9 @@ declare function TopBarRail({ items, ariaLabel }: TopBarRailProps): react.JSX.El
62
64
  * icon-only button has no other name, and "button" is all a screen reader would
63
65
  * say. `state` is for a toggle; a plain action leaves it off.
64
66
  */
65
- declare function EditorIconButton({ label, onClick, disabled, state, buttonRef, children }: EditorIconButtonProps): react.JSX.Element;
67
+ declare function EaselIconButton({ label, onClick, disabled, state, buttonRef, children }: EaselIconButtonProps): react.JSX.Element;
68
+ /** @deprecated The name before the Easel rename: `EaselIconButton`. */
69
+ declare const EditorIconButton: typeof EaselIconButton;
66
70
 
67
71
  /**
68
72
  * Which device the canvas previews — icon-only, one button held down.
@@ -201,7 +205,7 @@ type EditNoticeContent = {
201
205
  /**
202
206
  * The two groups of words a notice is written in: its own sentences, and the
203
207
  * edit lock's "2 minutes ago" / "Someone else". The whole catalogue fits —
204
- * `editNotice(access, conflict, noun, useEditorStrings())`.
208
+ * `editNotice(access, conflict, noun, useEaselStrings())`.
205
209
  */
206
210
  type EditNoticeWords = {
207
211
  notice: NoticeWords;
@@ -216,4 +220,4 @@ type EditNoticeWords = {
216
220
  */
217
221
  declare function editNotice(access: EditAccess, conflict: SaveConflict | null, noun: string, words?: EditNoticeWords): EditNoticeContent | null;
218
222
 
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 };
223
+ export { DeviceSwitch, DeviceSwitchProps, EaselIconButton, EaselIconButtonProps, EaselTopBar, EditNotice, type EditNoticeAction, type EditNoticeContent, EditNoticeProps, type EditNoticeWords, EditorIconButton, EditorTopBar, InspectorHead, InspectorHeadProps, InspectorIconButton, InspectorIconButtonProps, InspectorUpLevel, InspectorUpLevelProps, NoticeWords, PanelResizeHandle, PanelResizeHandleProps, SaveState, SaveStateProps, SaveStateToggle, SaveStateToggleProps, TopBarCluster, TopBarClusterProps, TopBarDivider, TopBarProps, TopBarRail, editNotice };
@@ -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-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__ */
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-672FAEKU.js";import{DEFAULT_LOCK_WORDS as r}from"../chunk-RE4LP46F.js";import{railTokens as o,EaselRail as s}from"../chunk-XUE5O62R.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
- 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__ */
4
+ return d("div",{className:"es-divider-v","aria-hidden":"true"})}var y=f,w="undefined"==typeof window?h:b;function N({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 w(()=>{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 x({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})}var C=x;function O({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
- 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__ */
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 P={idle:"is-quiet",saved:"is-quiet is-saved",saving:"is-saving",error:"is-error",off:"is-off","off-unsaved":"is-off is-unsaved"};function S({tone:e,label:n,counting:t,waitMs:i,ringRef:a,role:r}){/* @__PURE__ */
8
+ return u("span",{className:`es-savestate ${P[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 L({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 M="es-col-resizing";function R({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(M),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(M))},[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(M),[]),/* @__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 $({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 $({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 D({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 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__ */
17
+ /* @__PURE__ */d("span",{className:"es-insp-up-name",children:e})]})})}var F={notice:e,lock:r};function j(e,n,r,o=F){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 z({access:n,conflict:t,noun:i,onTakeOver:a,onViewReadOnly:o,onReload:s}){const l=j(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 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};
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},A=220,I=560;function W(e){return Math.min(560,Math.max(220,Math.round(e)))}function q(e){return{"--es-left-w":`${e.left}px`,"--es-right-w":`${e.right}px`}}export{T as DEFAULT_PANEL_W,O as DeviceSwitch,x as EaselIconButton,f as EaselTopBar,z as EditNotice,C as EditorIconButton,y as EditorTopBar,$ as InspectorHead,B as InspectorIconButton,D as InspectorUpLevel,I as MAX_PANEL_W,A as MIN_PANEL_W,R as PanelResizeHandle,S as SaveState,L as SaveStateToggle,k as TopBarCluster,g as TopBarDivider,N as TopBarRail,W as clampPanelWidth,j as editNotice,q as panelWidthVars};
@@ -0,0 +1 @@
1
+ import{DEFAULT_LOCK_WORDS as e}from"./chunk-RE4LP46F.js";var n=e=>"editing"===e.kind;function t(e){return e?{kind:"checking"}:{kind:"editing"}}var r=e=>"blocked"===e.kind||"readonly"===e.kind||"takenover"===e.kind?e.holder:null;function o(e){if(!e||"object"!=typeof e)return null;const n=e;return"string"!=typeof n.holder_name?null:{name:n.holder_name,secondsSinceSeen:"number"==typeof n.seconds_since_seen?n.seconds_since_seen:0,secondsSinceHeld:"number"==typeof n.seconds_since_held?n.seconds_since_held:0}}var a=e=>e?{edit:!0,insert:!0,delete:!0,duplicate:!0,drag:!1}:{edit:!1,insert:!1,delete:!1,duplicate:!1,drag:!1};function s(n,t=e){if(!Number.isFinite(n)||n<45)return t.justNow;const r=Math.round(n/60);if(r<60)return t.minutesAgo({count:r});const o=Math.round(r/60);return t.hoursAgo({count:o})}var c=(n,t=e)=>n.trim()||t.someone;function d(){return`tab-${"undefined"!=typeof crypto&&"randomUUID"in crypto?crypto.randomUUID():Math.random().toString(36).slice(2)}`.slice(0,64)}var i=d,u="edit_lock_taken";function l(e,t,r){return!(n(e)||!n(t))&&(r.pending&&r.autoSaveEnabled&&!r.saveConflict)}function f(e,t,o){return!(null===r(e)||!n(t))&&(!o.pending&&!o.saveConflict)}function k(e,n){return e!==n&&Date.parse(e)>=Date.parse(n)}async function h(e){if(!e.ours)return!1;const n=await e.stored().catch(()=>null);return!(!n||!k(n,e.ours)||e.hasPending())&&(e.reload(),!0)}function y(e){const{readFailure:n,conflictCode:t}=e,r=e=>{const t=n(e);return t&&409===t.status?o(t.data):null},a=e=>{const n=r(e);return n?{kind:"blocked",holder:n}:{kind:"editing"}},s=(e,n)=>{const t=r(e);return t?{kind:"blocked",holder:t}:n},c=(e,n)=>{const t=r(e);return t?{kind:"takenover",holder:t}:n},d=e=>{const t=n(e);return null!==t&&(401===t.status||403===t.status)};return{accessAfterClaimFailure:a,accessAfterTakeoverFailure:s,accessAfterHeartbeatFailure:c,isAuthRejection:d,readSaveConflict:e=>{const r=n(e);if(!r||409!==r.status)return null;if(!r.data||"object"!=typeof r.data)return null;const o=r.data;return o.code!==t?null:{savedBy:"string"==typeof o.saved_by?o.saved_by:"",savedByYou:!0===o.saved_by_you,secondsAgo:"number"==typeof o.seconds_ago?o.seconds_ago:0}},readLockTaken:e=>{const t=n(e);return t&&409===t.status&&t.data&&"object"==typeof t.data?t.data.code!==u?null:o(t.data)??{name:"",secondsSinceSeen:0,secondsSinceHeld:0}:null},makeClaimBeat:e=>{let n=!1;return async t=>{let r,o;try{const a=await e.claim(t);if(e.cancelled())return;r=e.currentAccess(),o={kind:"editing"},!n&&a.heartbeat_seconds>0&&(n=!0,e.startHeartbeat(1e3*a.heartbeat_seconds))}catch(n){if(e.cancelled())return;r=e.currentAccess(),o=t?s(n,r):"checking"===r.kind?a(n):c(n,r),d(n)&&e.stopHeartbeat()}e.setAccess(o);const i=e.heldWrite();l(r,o,i)?e.releaseHeldWrite():t&&f(r,o,i)&&e.reloadIfMoved?.()}}}}export{u as EDIT_LOCK_TAKEN,t as accessForNewDocument,n as canWriteDocument,y as createEditLock,s as describeAge,a as documentPermissions,k as documentVersionMoved,r as holderOf,c as nameOrSomeone,d as newEaselClientId,i as newEditorClientId,o as readLockHolder,h as reloadIfVersionMoved,l as shouldReleaseHeldWrite,f as shouldReloadAfterTakeover};
@@ -0,0 +1 @@
1
+ import{DEFAULT_STYLE_CLIPBOARD_WORDS as o}from"./chunk-6WY6ZXJG.js";import{DEFAULT_NODE_MENU_WORDS as r}from"./chunk-WK3AFPXY.js";import{DEFAULT_PICK_WORDS as t}from"./chunk-ZAOM6PFH.js";import{DEFAULT_CANVAS_WORDS as m}from"./chunk-AELNNAFM.js";import{DEFAULT_FIELDS_WORDS as n}from"./chunk-SUO5627P.js";import{DEFAULT_TREE_WORDS as c}from"./chunk-H4B72XCJ.js";import{DEFAULT_PANEL_WORDS as f}from"./chunk-7A7O2JWQ.js";import{DEFAULT_SAVE_WORDS as p}from"./chunk-H6DDIBQ4.js";import{DEFAULT_CHROME_WORDS as s,DEFAULT_NOTICE_WORDS as i}from"./chunk-KDIVA6WD.js";import{DEFAULT_LOCK_WORDS as u}from"./chunk-RE4LP46F.js";import{DEFAULT_RAIL_WORDS as e}from"./chunk-2OAZYSWJ.js";import{DEFAULT_COPY_WORDS as k}from"./chunk-ZT7M24XD.js";import{DEFAULT_DRAG_WORDS as j}from"./chunk-O2NLQBFX.js";var h={notice:i,lock:u,save:p,chrome:s,rail:e,tree:c,panel:f,fields:n,pick:t,drag:j,menu:r,styleClipboard:o,copy:k,canvas:m},l=o=>"object"==typeof o&&null!==o;function a(o,r){const t={};for(const m of Object.keys(o)){const n=o[m],c=r[m];null==c?t[m]=n:l(n)?t[m]=l(c)?a(n,c):n:t[m]=typeof c==typeof n?c:n}return t}function A(o,r){return r?a(o,r):o}var y=h,O=A;export{h as DEFAULT_EASEL_STRINGS,y as DEFAULT_EDITOR_STRINGS,A as mergeEaselStrings,O as mergeEditorStrings};
@@ -0,0 +1,10 @@
1
+ import{toItemSelector as e,fromItemSelector as t,useNodeOps as n}from"./chunk-D2BCHTQR.js";import{DEFAULT_CANVAS_WORDS as o}from"./chunk-AELNNAFM.js";import{useResolvedFields as r}from"./chunk-YRLPFZW3.js";import{useWords as a}from"./chunk-MFIRYGHW.js";import{setCanvasNonce as i}from"./chunk-ZNCEOSXO.js";import{find as s,ROOT_ID as l,getList as d,remove as c,parseZoneKey as u,move as p,duplicate as h,replaceNode as f,createNode as m,insert as v,normalizeData as y,createResolveCache as g,resolveNodeData as k,ROOT_SLOT as b}from"./chunk-KRXQM65X.js";import{topLevelSlotKeys as w,fieldsFrom as S,defaultsFrom as I}from"./chunk-NKB3KVAB.js";import{createContext as C,useEffect as x,useContext as E,useRef as O,useSyncExternalStore as A,useState as D,useLayoutEffect as z,useMemo as M,useCallback as Z}from"react";import{jsx as $,jsxs as N}from"react/jsx-runtime";import{createPortal as R}from"react-dom";function B(e){return!["setData","setUi","set"].includes(e.type)}var j=(e,t,n,o)=>{const r=d(e,t,u(n));return r?.[o]??null},L=(e,t,n,o,r)=>{const a=j(e,t,n,o);if(!a)throw new Error(`${r}: nothing at ${n}[${o}]`);return a};function P(t,n){const{selection:o}=t;return{...t.ui,itemSelector:e(t.data,n,o),selectedSlot:o&&"slot"===o.kind?{parentId:o.parentId,slot:o.slot}:null}}function K(e,t,n){return n?"node"===n.kind?s(e,t,n.id)?n:null:n.parentId===l?d(e,t,n)?n:null:s(e,t,n.parentId)&&d(e,t,n)?n:null:null}function F(e,n,o,r=!1){const{itemSelector:a,selectedSlot:i,...s}=o;let l=e.selection;var d;return"itemSelector"in o&&(l=t(e.data,n,a??null)),"selectedSlot"in o&&(i?l=(d=i)?{kind:"slot",parentId:d.parentId,slot:d.slot}:null:"slot"===l?.kind&&(l=null)),{...e,selection:l,ui:r?s:{...e.ui,...s}}}function H(e,t,n){const o=V(e,t,n);if(o===e)return e;const r=K(o.data,n,o.selection);return r===o.selection?o:{...o,selection:r}}function V(e,t,n){const{data:o}=e;switch(t.type){case"setData":{const n="function"==typeof t.data?t.data(o):t.data;return{...e,data:{...o,...n}}}case"setUi":return F(e,n,"function"==typeof t.ui?t.ui(P(e,n)):t.ui);case"set":{const r={data:o,ui:P(e,n)},a="function"==typeof t.state?t.state(r):t.state;let i=a.data?{...e,data:a.data}:e;return a.ui&&(i=F(i,n,a.ui,!0)),i}case"insert":{const r={...u(t.destinationZone),index:t.destinationIndex},a=m(n,t.componentType,{},t.id?{id:t.id}:{});return{...e,data:v(o,n,r,a)}}case"replace":{const r=L(o,n,t.destinationZone,t.destinationIndex,"replace");if(r.props.id!==t.data.props.id)throw new Error("Can't change the id during a replace action. Use remove and insert for a new node.");return{...e,data:f(o,n,r.props.id,t.data)}}case"replaceRoot":{const n={...o.root,props:{...o.root.props,...t.root.props},readOnly:t.root.readOnly};return{...e,data:{...o,root:n}}}case"duplicate":{const r=L(o,n,t.sourceZone,t.sourceIndex,"duplicate"),a=h(o,n,r.props.id),i=j(a,n,t.sourceZone,t.sourceIndex+1);return{...e,data:a,selection:i?{kind:"node",id:i.props.id}:e.selection}}case"reorder":return V(e,{...t,type:"move",sourceZone:t.destinationZone},n);case"move":{if(t.sourceZone===t.destinationZone&&t.sourceIndex===t.destinationIndex)return e;const r=j(o,n,t.sourceZone,t.sourceIndex);if(!r)return e;const a={...u(t.destinationZone),index:t.destinationIndex};return{...e,data:p(o,n,r.props.id,a)}}case"remove":{const r=L(o,n,t.zone,t.index,"remove");return{...e,data:c(o,n,r.props.id)}}default:return e}}var T={drag:!0,duplicate:!0,delete:!0,edit:!0,insert:!0},q={leftSideBarVisible:!0,rightSideBarVisible:!0,arrayState:{},componentList:{},isDragging:!1,previewMode:"edit",viewports:{current:{width:360,height:"auto"},options:[],controlsVisible:!0},field:{focus:null}},Y=0,U=()=>`history-${Y+=1}`;function W(n){let o=n.config;const r=n.now??(()=>Date.now()),a=n.historyCoalesceMs??250;let i=n.permissions??{};const l=y(n.data,o);let c={data:l,selection:null,ui:{...q}};if(n.ui){const{itemSelector:e,selectedSlot:r,...a}=n.ui;c={data:l,selection:r?{kind:"slot",...r}:t(l,o,e??null),ui:{...q,...a}}}let u=[{core:c,at:-1/0,sealed:!0,id:U()}],p=0;const h=e=>{const t=u[p],n=r();!e&&p===u.length-1&&p>0&&!t.sealed&&n-t.at<a?u=[...u.slice(0,p),{...t,core:c,at:n}]:(u=[...u.slice(0,p+1),{core:c,at:n,sealed:e,id:U()}],p=u.length-1)},m=/* @__PURE__ */new Set;let v=null,b=null,w=0,S=null,I=!1;const C=()=>{for(const e of[...m])e()},x=()=>{u=[...u.slice(0,p),{...u[p],core:c},...u.slice(p+1)]},E=(e,t)=>{w>0?I=I||t:(t?h(!1):c!==e&&x(),c.data!==e.data&&n.onChange?.(c.data),c!==e&&C())},O=e=>{const t=c;if(c=H(c,e,o),c===t)return;const n=e.recordHistory??B(e);E(t,n&&c.data!==t.data)},A=e=>{0===w&&(S=c,I=!1),w+=1;try{e()}catch(e){throw w-=1,0===w&&S&&(c=S,S=null),e}if(w-=1,w>0||!S)return;const t=S;S=null,I&&c.data!==t.data?h(!0):c!==t&&x(),c.data!==t.data&&n.onChange?.(c.data),c!==t&&C()},D=e=>{const t=c,n=K(c.data,o,e);var r,a;(r=n,a=c.selection,r===a||r&&a&&r.kind===a.kind&&("node"===r.kind&&"node"===a.kind?r.id===a.id:"slot"===r.kind&&"slot"===a.kind&&r.parentId===a.parentId&&r.slot===a.slot))||(c={...c,selection:n},E(t,!1))},z=e=>{const t=c;p=e,c=u[p].core,c.data!==t.data&&n.onChange?.(c.data),c!==t&&C()},M=(e={})=>{const t=e.root?o.root?.permissions:o.components[e.item?.type??e.type??""]?.permissions;return{...T,...i,...t}},Z=g(),$={resolveCache:Z,async resolveAll({trigger:e="load",metadata:t}={}){const n=c.data,r={type:"root",props:{...n.root.props??{}}},a=[...n.content,...Object.values(n.zones??{}).flat()],[i,...l]=await Promise.all([k(r,o,{cache:Z,trigger:e,metadata:t}),...a.map(n=>k(n,o,{cache:Z,trigger:e,metadata:t}))]);A(()=>{const e=c;let t=c.data;l.forEach((e,r)=>{if(!e.didChange)return;const i=a[r].props.id,l=s(t,o,i)?.node;l&&l===s(n,o,i)?.node&&(t=f(t,o,i,e.node))}),i.didChange&&t.root===n.root&&(t={...t,root:{...t.root,props:i.node.props,readOnly:i.node.readOnly??t.root.readOnly}}),t!==c.data&&(c={...c,data:t,selection:K(t,o,c.selection)},E(e,!1))})},get config(){return o},getState(){if(v&&b===c)return v;const t=c,n={data:t.data,ui:P(t,o)},r="node"===t.selection?.kind?s(t.data,o,t.selection.id)?.node??null:null;return v={appState:n,selection:t.selection,selectedItem:r,config:o,dispatch:O,history:{back:()=>$.undo(),forward:()=>$.redo(),hasPast:p>0,hasFuture:p<u.length-1,histories:u.map(e=>({id:e.id,state:{data:e.core.data,ui:P(e.core,o)}})),index:p,setHistoryIndex:e=>{e>=0&&e<u.length&&e!==p&&z(e)}},getPermissions:M,getItemById:e=>s(t.data,o,e)?.node,getItemBySelector:e=>function(e,t,n){const[o,r]=(n.zone??"root:default-zone").split(/:(.*)/s);return d(e,t,{parentId:o,slot:r})?.[n.index]}(t.data,o,e),getSelectorForId:n=>{const r=e(t.data,o,{kind:"node",id:n});return r?{index:r.index,zone:r.zone??"root:default-zone"}:void 0}},b=t,v},subscribe:e=>(m.add(e),()=>{m.delete(e)}),dispatch:O,batch:A,select:e=>D(e?{kind:"node",id:e}:null),selectSlot:e=>D(e?{kind:"slot",parentId:e.parentId,slot:e.slot}:null),run(e){A(()=>{const t=c,n=void 0===e.select?c.selection:e.select;c={...c,data:e.data,selection:K(e.data,o,n)},E(t,e.data!==t.data)})},load(e,t={}){const n=c,r=y(e,o);c={...c,data:r,selection:K(r,o,t.selection??c.selection)},t.keepHistory||(u=[{core:c,at:-1/0,sealed:!0,id:U()}],p=0),c!==n&&C()},undo(){p>0&&z(p-1)},redo(){p<u.length-1&&z(p+1)},setPermissions(e){i=e,v=null,C()},setConfig(e){e!==o&&(o=e,v=null,C())}};return $}var X=W;function Q(e,t){const n=e=>{if(e.altKey)return;e.metaKey!==e.ctrlKey&&("KeyZ"===e.code?(e.preventDefault(),e.shiftKey?t.redo():t.undo()):"KeyY"!==e.code||e.shiftKey||(e.preventDefault(),t.redo()))};return e.addEventListener("keydown",n),()=>e.removeEventListener("keydown",n)}var G=C(null);function J({easel:e,hotkeys:t=!0,resolveOnMount:n=!0,children:o}){return x(()=>{n&&e.resolveAll()},[e,n]),x(()=>{if(t&&"undefined"!=typeof document)return Q(document,e)},[e,t]),/* @__PURE__ */$(G.Provider,{value:e,children:o})}function _(){const e=E(G);if(!e)throw new Error("useEasel: no <EaselProvider> above this component");return e}function ee(e){const t=_(),n=O({view:null,selector:null,value:void 0,has:!1}),o=()=>{const o=t.getState(),r=n.current;if(r.has&&r.view===o&&r.selector===e)return r.value;const a=e(o);return r.has&&Object.is(r.value,a)?(n.current={view:o,selector:e,value:r.value,has:!0},r.value):(n.current={view:o,selector:e,value:a,has:!0},a)};return A(t.subscribe,o,o)}function te(){return function(e){return ee(e)}}function ne({editor:e,...t}){/* @__PURE__ */
2
+ return $(J,{easel:e,...t})}var oe=_,re=ee,ae=te,ie="data-puck-component",se="data-puck-dropzone",le={},de="data-es-mirror";function ce(e,t,n){for(const e of Array.from(t.head.querySelectorAll(`[${de}]`)))e.remove();for(const o of Array.from(e.head.querySelectorAll('style, link[rel="stylesheet"]'))){const e=o.cloneNode(!0);e.setAttribute(de,""),n&&e.setAttribute("nonce",n),t.head.appendChild(e)}}function ue({children:e,id:t="preview-frame",title:n,className:r,style:s,mirrorStyles:l=!0,onDocument:d,height:c="auto",nonce:u}){const p=a("canvas",o),h=O(null),[f,m]=D(null);return z(()=>{const e=h.current,t=f?.ownerDocument.defaultView;if("auto"!==c||!e||!f||!t)return;const n=()=>{e.style.height=`${Math.ceil(f.getBoundingClientRect().height)}px`};n();const o=t.ResizeObserver,r=o?new o(n):null;return r?.observe(f),()=>r?.disconnect()},[f,c]),z(()=>{let e=h.current?.contentDocument;if(!e)return;"CSS1Compat"!==e.compatMode&&(e.open(),e.write("<!DOCTYPE html><html><head></head><body></body></html>"),e.close(),e=h.current?.contentDocument??e),e.body||e.documentElement.appendChild(e.createElement("body")),e.body.style.margin="0";const t=e.createElement("div");t.setAttribute("data-puck-entry",""),t.id="frame-root","fill"===c&&t.classList.add("es-frame-fill"),e.body.appendChild(t),i(e,u),m(t),d?.(e);let n=null;const o=h.current?.ownerDocument;if(l&&o){ce(o,e,u);const t=o.defaultView;t&&"MutationObserver"in t&&(n=new t.MutationObserver(()=>ce(o,e,u)),n.observe(o.head,{childList:!0,subtree:!0,characterData:!0}))}return()=>{n?.disconnect(),t.remove(),m(null),d?.(null)}},[]),/* @__PURE__ */$("iframe",{ref:h,id:t,title:n??p.frame,className:r,style:{border:0,width:"100%",display:"block",..."fill"===c?{height:"100%"}:null,...s},children:f?R(e,f):null})}var pe=C(null),he=C(le),fe=[];function me({parentId:e,slot:t,className:n,style:o,minEmptyHeight:r=128}){const a=_(),i=ee(n=>d(n.appState.data,a.config,{parentId:e,slot:t})??fe),s=ee(t=>"node"===t.selection?.kind&&t.selection.id===e&&e!==l),c=ee(n=>"slot"===n.selection?.kind&&n.selection.parentId===e&&n.selection.slot===t),u=E(pe),p=["es-zone"];return i.length&&p.push("has-children"),e===l&&p.push("is-root"),(s||c)&&p.push("is-area-selected"),null!==u&&u===e&&e!==l&&p.push("is-hovering-area"),n&&p.push(n),/* @__PURE__ */$("div",{className:p.join(" "),[se]:`${e}:${t}`,style:{...o,"--min-empty-height":`${r}px`},children:i.map(e=>/* @__PURE__ */$(ge,{node:e},e.props.id))})}function ve(e,t,n,o){const r="root"===t?e.root:e.components[t],a={...o};for(const e of w(S(r)))a[e]=function(t={}){/* @__PURE__ */
3
+ return $(me,{parentId:n,slot:e,...t})};return a}function ye(e){return function({zone:t,...n}){/* @__PURE__ */
4
+ return $(me,{parentId:e,slot:t,...n})}}function ge({node:e}){const t=_().config,n=t.components[e.type],o=e.props.id,r=function(e){const t=O(null);return M(()=>n=>{const o=t.current;o&&o!==n&&(o.removeAttribute(ie),o.removeAttribute("data-puck-dnd")),t.current=n,n&&(n.setAttribute(ie,e),n.setAttribute("data-puck-dnd",e),n.style.position="relative")},[e])}(o),a=E(he);if(!n?.render)return null;const i=n.render,s=ve(t,e.type,o,{...I(n),...e.props}),l={renderDropZone:ye(o),isEditing:!0,dragRef:n.inline?r:null,metadata:{...a,...n.metadata}};return n.inline?/* @__PURE__ */$(i,{...s,puck:l,editMode:!0}):/* @__PURE__ */$("div",{[ie]:o,"data-puck-dnd":o,style:{position:"relative"},children:/* @__PURE__ */$(i,{...s,puck:l,editMode:!0})})}function ke({metadata:e}){const t=ee(e=>e.config),n=ee(e=>e.appState.data.root).props??{},o=t.root?.render,r=/* @__PURE__ */$(me,{parentId:l,slot:b}),a=o?/* @__PURE__ */$(o,{id:"puck-root",...ve(t,"root",l,n),puck:{renderDropZone:ye(l),isEditing:!0,dragRef:null,metadata:e??{}},editMode:!0,children:r}):r;/* @__PURE__ */
5
+ return $(he.Provider,{value:e??le,children:a})}function be({id:e,kind:t,overlay:n}){const o=O(null),[r,a]=D(null);z(()=>{const t=o.current?.ownerDocument,n=t?.defaultView;if(!t||!n||!e)return void a(null);let r=0;const i=()=>{r=0;const i=function(e,t){if(!e||!t)return null;const n=e.getBoundingClientRect(),o=t.getBoundingClientRect();return{top:n.top-o.top,left:n.left-o.left,width:n.width,height:n.height}}(t.querySelector(`[${ie}="${n.CSS?.escape?n.CSS.escape(e):e}"]`),o.current?.parentElement??null);a(e=>{return(t=e)===(n=i)||t&&n&&t.top===n.top&&t.left===n.left&&t.width===n.width&&t.height===n.height?e:i;var t,n})},s=()=>{r||(r=(n.requestAnimationFrame??(e=>n.setTimeout(e,16)))(i))};i();const l="MutationObserver"in n?new n.MutationObserver(s):null;l?.observe(t.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0});const d="ResizeObserver"in n?new n.ResizeObserver(s):null;return d?.observe(t.documentElement),n.addEventListener("resize",s),()=>{l?.disconnect(),d?.disconnect(),n.removeEventListener("resize",s),r&&(n.cancelAnimationFrame??n.clearTimeout)(r)}},[e]);const i=/* @__PURE__ */$("div",{ref:o,"aria-hidden":"true",className:`es-canvas-outline is-${t}`,style:r?{position:"absolute",top:r.top,left:r.left,width:r.width,height:r.height}:{display:"none"}});return n&&e?/* @__PURE__ */$(n,{componentId:e,kind:t,children:i}):i}function we({frame:e=!0,className:t,style:n,metadata:o,mirrorStyles:r,onDocument:a,height:i,title:s,nonce:l,frameWrapper:d,overlay:c,children:u}){const p=_(),[h,f]=D(void 0),m=ee(e=>"node"===e.selection?.kind?e.selection.id:null),[v,y]=D(null),g=/* @__PURE__ */N("div",{className:"es-canvas-content",style:{position:"relative"},onClick:e=>{const t=e.target;t.closest?.("a[href]")&&e.preventDefault();const n=t.closest?.(`[${ie}]`);n?p.select(n.getAttribute(ie)):t.hasAttribute?.(se)||p.select(null)},onMouseOver:e=>{const t=e.target.closest?.(`[${ie}]`),n=t?.getAttribute(ie)??null;n!==v&&y(n)},onMouseLeave:()=>y(null),children:[
6
+ /* @__PURE__ */$(pe.Provider,{value:v,children:/* @__PURE__ */$(ke,{metadata:o})}),
7
+ /* @__PURE__ */N("div",{className:"es-canvas-outlines",style:{position:"absolute",top:0,left:0,pointerEvents:"none"},children:[
8
+ /* @__PURE__ */$(be,{id:v&&v!==m?v:null,kind:"hover",overlay:c}),
9
+ /* @__PURE__ */$(be,{id:m,kind:"selected",overlay:c})]}),u]}),k=d?/* @__PURE__ */$(d,{document:h,children:g}):g,b=O(null);/* @__PURE__ */
10
+ return $("div",{className:"es-canvas"+(t?` ${t}`:""),style:n,"data-puck-preview":"",children:e?/* @__PURE__ */$(ue,{mirrorStyles:r,onDocument:e=>{b.current?.(),b.current=e?Q(e,p):null,f(e??void 0),a?.(e)},height:i,title:s,nonce:l,children:k}):/* @__PURE__ */$("div",{id:"preview-frame","data-puck-entry":"",children:k})})}var Se=we;function Ie(e={}){const t=_(),o=ee(e=>e.appState.data);return n({...e,data:o,config:t.config,commit:(e,{select:n})=>t.run({data:e,select:n})})}function Ce(){const e=_(),t=ee(e=>e.config),n=e.resolveCache,o=ee(e=>e.selectedItem),a=ee(e=>e.appState.data.root),i=o?o.props.id:"root",l=a.props??{},d=M(()=>o||{type:"root",props:l},[o,l]),c=o?t.components[o.type]:t.root,u=e.getState(),p=o?s(u.appState.data,t,i):null,h=p&&"root"!==p.place.parentId?p.place.parentId:null,f=h?u.getItemById(h)??null:null,{fields:m}=r({id:i,node:d,block:c,parent:f,appState:u.appState}),v=u.getPermissions(o?{item:o}:{root:!0}),y=Z((o,r)=>{(async()=>{const a=e.getState();if("root"!==i){const s=a.getItemById(i),l=a.getSelectorForId(i);if(!s||!l)return;const d={...s,props:{...s.props,[o]:r}},{node:c}=await k(d,t,{cache:n,trigger:"replace"}),u=e.getState().getSelectorForId(i);if(!u)return;return void e.dispatch({type:"replace",destinationZone:u.zone??"root:default-zone",destinationIndex:u.index,data:c})}const s=a.appState.data.root.props??{},{node:l}=await k({type:"root",props:{...s,[o]:r}},t,{cache:n,trigger:"replace"});e.dispatch({type:"replaceRoot",root:{props:l.props,readOnly:l.readOnly},recordHistory:!0})})()},[e,t,n,i]);return{id:i,node:d,fields:m,values:d.props,readOnly:!1===v.edit,onChange:y}}var xe=Ie;export{ue as CanvasFrame,q as DEFAULT_UI,we as EaselCanvas,J as EaselProvider,ke as EditDocument,Se as EditorCanvas,ne as EditorProvider,Q as bindUndoKeys,W as createEasel,X as createEditor,te as createUseEasel,ae as createUseEditor,B as recordsByDefault,H as reduce,P as uiView,ee as useEasel,_ as useEaselApi,Ie as useEaselNodeOps,re as useEditor,oe as useEditorApi,xe as useEditorNodeOps,Ce as useSelectedFields,K as validSelection};
@@ -0,0 +1,3 @@
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
+ 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]})}var l=o;function t({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 n=t,d={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"}},s={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{t as EaselRail,o as EaselRailButton,n as EditorRail,l as EditorRailButton,s as railCssVars,d as railTokens};
@@ -1,8 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { MarkStyle, MarkupTool, WrapResult, InlineRule } from '../markup/index.js';
4
- import { a as CopyAlign } from '../words-bOMsUJk9.js';
5
- export { b as COPY_ALIGNS, c as COPY_ALIGN_FIT, d as COPY_ALIGN_GLYPHS, e as COPY_ALIGN_LABELS, C as CopyWords, f as copyAlignOptions } from '../words-bOMsUJk9.js';
4
+ import { a as CopyAlign } from '../words-C74EUpFr.js';
5
+ export { b as COPY_ALIGNS, c as COPY_ALIGN_FIT, d as COPY_ALIGN_GLYPHS, e as COPY_ALIGN_LABELS, C as CopyWords, f as copyAlignOptions } from '../words-C74EUpFr.js';
6
6
 
7
7
  /** `'b'` → `Meta+B`, `'shift+x'` → `Meta+Shift+X` — the ARIA spelling of a
8
8
  * shortcut. Meta is what the tooltips promise (⌘); Ctrl works too. */
@@ -65,7 +65,7 @@ interface MarkBarProps {
65
65
  */
66
66
  glyphs?: Partial<Record<MarkStyle, ReactNode>>;
67
67
  /**
68
- * What the group is CALLED. Defaults to "Formatting" (`EditorStrings.copy.formatting`).
68
+ * What the group is CALLED. Defaults to "Formatting" (`EaselStrings.copy.formatting`).
69
69
  *
70
70
  * A bar bound to one box needs nothing more. A bar SHARED by several rows has
71
71
  * to say which row it is aimed at, because the visible cue — the marked row —
@@ -286,10 +286,10 @@ declare function pasteToMarkup(data: PasteData, opts: PasteOptions): string;
286
286
  *
287
287
  * A browser's own text undo cannot do it: it forgets everything the moment a
288
288
  * value is set from script, and every mark, link, clear and paste is set from
289
- * script. And the editor's undo (`efficient-easel/editor` `bindUndoKeys`)
289
+ * script. And the easel's undo (`efficient-easel/easel` `bindUndoKeys`)
290
290
  * steps the whole document, a keystroke at a time. So the box keeps the steps
291
291
  * IT made, with the selection each one started from, and answers ⌘Z itself —
292
- * the key never reaches the editor while the caret is in the box, so one key
292
+ * the key never reaches the easel while the caret is in the box, so one key
293
293
  * is never answered twice.
294
294
  *
295
295
  * Typing is one step per burst: keystrokes less than a second apart are one
@@ -199,12 +199,12 @@ declare function copyTranslation(overlay: TranslationOverlay | null | undefined,
199
199
  * The Ground Up For Efficient Editor", 2026-09-29, step 1.1). Every function
200
200
  * takes a document and returns a new one; nothing here holds state, knows
201
201
  * about React, or touches a browser global, so a server component, a Node
202
- * script, a test and the editor's store all call the same code.
202
+ * script, a test and the easel's store all call the same code.
203
203
  *
204
204
  * find · walk · slotsOf read
205
205
  * insert · move · remove · duplicate change the tree
206
206
  * setProps · setRoot change one node's props, or the root's
207
- * normalizeData what the editor does to a document it opens
207
+ * normalizeData what the easel does to a document it opens
208
208
  * createNode · newId make a block the way the Add panel does
209
209
  * applyTranslation · … a page's other languages, kept beside it (./translate)
210
210
  *
@@ -232,7 +232,7 @@ declare function copyTranslation(overlay: TranslationOverlay | null | undefined,
232
232
  * ERRORS. An edit that names a node or slot that is not there, an index off the
233
233
  * end of a list, a move into the node's own subtree, or an insert that would
234
234
  * put a second copy of an id into the document throws a `DataError`. The
235
- * editor's store decides what an operator sees; this layer never guesses.
235
+ * easel's store decides what an operator sees; this layer never guesses.
236
236
  *
237
237
  * LEAF DISCIPLINE: no imports outside this folder, no dependency at all.
238
238
  * `crypto` is read inside `newId`, never at module evaluation.
@@ -294,7 +294,7 @@ declare function find(data: Data, config: DataConfig, id: string): Found | null;
294
294
  /** The list at an address, or `null` when no such slot exists. */
295
295
  declare function getList(data: Data, config: DataConfig, address: SlotAddress): Node[] | null;
296
296
  /**
297
- * What the editor does to a document when it opens it — the same result Puck
297
+ * What the easel does to a document when it opens it — the same result Puck
298
298
  * reaches on load, with the older formats converted (rule 4):
299
299
  *
300
300
  * - `root` holding its props directly becomes `{ props: { …those keys } }`;
@@ -113,28 +113,48 @@
113
113
  transform: scale(1);
114
114
  }
115
115
 
116
- /* An empty slot: a faint dashed cell that adds a block there, and takes a drop. */
116
+ /* An empty slot: a cell that adds a block there, and takes a drop. At rest it
117
+ draws NOTHING — no fill, no border, no label — so what is under it shows as
118
+ on the live page (owner, option B, 2026-10-06: a HeroSlide's empty "groups"
119
+ slot covers the whole slide, and the old pale fill hid the picture). On hover
120
+ and on keyboard focus: the dashed outline and "+ Add block", and still no
121
+ fill on the cell — the label carries the tint, so it reads over a picture.
122
+ A drag over it lights the whole cell, as before. Touch has no hover: there
123
+ the slot is added to from Layers' "Add" rows. */
117
124
  .es-canvas-empty {
118
125
  position: absolute;
119
126
  box-sizing: border-box;
120
127
  display: flex;
121
128
  align-items: center;
122
129
  justify-content: center;
123
- border: 1.5px dashed var(--es-input-border);
130
+ border: 1.5px dashed transparent;
124
131
  border-radius: 6px;
125
- background: color-mix(in srgb, var(--es-app-bg) 60%, transparent);
126
- color: var(--es-muted);
132
+ background: transparent;
133
+ color: var(--es-accent-text);
127
134
  font: 500 12px/1.3 var(--es-font);
128
135
  cursor: pointer;
129
136
  pointer-events: auto;
130
- transition: border-color 0.12s, background 0.12s, color 0.12s;
137
+ transition: border-color 0.12s, background 0.12s;
138
+ }
139
+ .es-canvas-empty-add {
140
+ padding: 2px 12px;
141
+ border-radius: 999px;
142
+ background: var(--es-accent-tint);
143
+ opacity: 0;
144
+ transition: opacity 0.12s;
131
145
  }
132
146
  .es-canvas-empty:hover,
133
147
  .es-canvas-empty:focus-visible,
134
148
  .es-canvas-empty.is-over {
135
149
  border-color: var(--es-accent);
150
+ }
151
+ .es-canvas-empty.is-over {
136
152
  background: var(--es-accent-tint);
137
- color: var(--es-accent-text);
153
+ }
154
+ .es-canvas-empty:hover .es-canvas-empty-add,
155
+ .es-canvas-empty:focus-visible .es-canvas-empty-add,
156
+ .es-canvas-empty.is-over .es-canvas-empty-add {
157
+ opacity: 1;
138
158
  }
139
159
 
140
160
  /* ── The Add panel's shell ───────────────────────────────────────────────────
@@ -1,8 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { HTMLAttributes, ReactNode } from 'react';
3
3
  import { P as Place, S as SlotAddress } from '../types-41704JE4.js';
4
- import { C as CanvasTarget$1 } from '../watch-DmasQA61.js';
5
- import { D as DragWords } from '../words-D9ChvbNC.js';
4
+ import { C as CanvasTarget$1 } from '../watch-B5RTR-WX.js';
5
+ import { D as DragWords } from '../words-BDignMl_.js';
6
6
 
7
7
  /**
8
8
  * The one drag in flight, shared by every surface of an editor — the Layers
@@ -286,7 +286,7 @@ type CanvasDragLayerProps<I> = {
286
286
  measure?: (canvas: CanvasTarget$1, layer: Element) => MeasuredCanvas;
287
287
  /**
288
288
  * The layer's own words in the host's language:
289
- * `useEditorStrings().drag.canvas` (0.95.0). Left out, English. `seamLabel`
289
+ * `useEaselStrings().drag.canvas` (0.95.0). Left out, English. `seamLabel`
290
290
  * and `zoneAddLabel` above still win for their one word. A prop, not the
291
291
  * strings provider: drag imports only its own lane.
292
292
  */
@@ -334,7 +334,7 @@ type AddPanelProps<I> = {
334
334
  readOnly?: boolean;
335
335
  /**
336
336
  * The shell's own words in the host's language:
337
- * `useEditorStrings().drag.add` (0.95.0). Left out, English. `hint` and
337
+ * `useEaselStrings().drag.add` (0.95.0). Left out, English. `hint` and
338
338
  * `searchLabel` above still win for their one line. A prop, not the strings
339
339
  * provider: drag imports only its own lane.
340
340
  */