efficient-easel 0.99.2 → 0.100.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +233 -17
  2. package/dist/autosave/index.d.ts +11 -5
  3. package/dist/blocks/index.d.ts +1 -1
  4. package/dist/canvas/index.d.ts +2 -2
  5. package/dist/canvas/index.js +1 -1
  6. package/dist/chrome/chrome.css +96 -29
  7. package/dist/chrome/index.d.ts +67 -18
  8. package/dist/chrome/index.js +17 -21
  9. package/dist/chunk-3EDSDPIP.js +1 -0
  10. package/dist/chunk-67GNT6PF.js +1 -0
  11. package/dist/{chunk-PI26YXYD.js → chunk-6EIVTKZZ.js} +21 -14
  12. package/dist/chunk-A5UK76FC.js +6 -0
  13. package/dist/chunk-AZT7V4UM.js +10 -0
  14. package/dist/chunk-DICUMYMG.js +12 -0
  15. package/dist/chunk-HDVD27VB.js +1 -0
  16. package/dist/chunk-JQM3V7XQ.js +1 -0
  17. package/dist/chunk-JUQ6YJCG.js +1 -0
  18. package/dist/chunk-LA54QLP5.js +1 -0
  19. package/dist/chunk-LGKQXSKO.js +16 -0
  20. package/dist/chunk-M6F6LS3H.js +1 -0
  21. package/dist/chunk-MH5GUZFQ.js +9 -0
  22. package/dist/chunk-P6O363EE.js +6 -0
  23. package/dist/chunk-PAELDYYS.js +1 -0
  24. package/dist/{chunk-JYPOOHII.js → chunk-QKVR3K73.js} +3 -3
  25. package/dist/chunk-SAJUCHOX.js +1 -0
  26. package/dist/chunk-TRVZ7C23.js +1 -0
  27. package/dist/chunk-V7GIIXFB.js +16 -0
  28. package/dist/chunk-WZ7TGAAT.js +3 -0
  29. package/dist/chunk-ZJEBF4NB.js +1 -0
  30. package/dist/copy/copy.css +388 -5
  31. package/dist/copy/index.d.ts +268 -5
  32. package/dist/copy/index.js +31 -10
  33. package/dist/drag/drag.css +10 -1
  34. package/dist/drag/index.d.ts +99 -8
  35. package/dist/drag/index.js +18 -17
  36. package/dist/easel/easel.css +15 -0
  37. package/dist/easel/index.d.ts +104 -33
  38. package/dist/easel/index.js +9 -1
  39. package/dist/edit-lock/index.d.ts +1 -3
  40. package/dist/edit-lock/index.js +1 -1
  41. package/dist/fields/fields.css +103 -26
  42. package/dist/fields/index.d.ts +47 -9
  43. package/dist/fields/index.js +30 -46
  44. package/dist/gold/index.js +1 -1
  45. package/dist/icons/index.d.ts +10 -1
  46. package/dist/icons/index.js +1 -1
  47. package/dist/index.d.ts +2 -2
  48. package/dist/index.js +1 -1
  49. package/dist/markup/index.d.ts +94 -10
  50. package/dist/markup/index.js +1 -1
  51. package/dist/menu/index.d.ts +58 -5
  52. package/dist/menu/index.js +15 -15
  53. package/dist/menu/menu.css +17 -6
  54. package/dist/node-ops/index.d.ts +1 -1
  55. package/dist/node-ops/index.js +1 -1
  56. package/dist/panel/index.d.ts +72 -4
  57. package/dist/panel/index.js +18 -16
  58. package/dist/panel/panel.css +56 -1
  59. package/dist/pick/index.d.ts +39 -1
  60. package/dist/pick/index.js +7 -14
  61. package/dist/pick/pick.css +14 -0
  62. package/dist/rail/index.d.ts +3 -7
  63. package/dist/rail/index.js +1 -1
  64. package/dist/strings/catalogue.d.ts +13 -35
  65. package/dist/strings/catalogue.js +1 -1
  66. package/dist/strings/index.d.ts +12 -18
  67. package/dist/strings/index.js +2 -2
  68. package/dist/style-clipboard/index.d.ts +1 -1
  69. package/dist/style-clipboard/index.js +1 -1
  70. package/dist/text-styles/index.d.ts +328 -0
  71. package/dist/text-styles/index.js +38 -0
  72. package/dist/text-styles/text-styles.css +309 -0
  73. package/dist/tree/index.d.ts +43 -2
  74. package/dist/tree/index.js +1 -1
  75. package/dist/tree/tree.css +71 -0
  76. package/dist/{types-p9j2Fac7.d.ts → types-DGcCsxs8.d.ts} +72 -7
  77. package/dist/{types-Bs_gVkVI.d.ts → types-DWS-s9z-.d.ts} +1 -9
  78. package/dist/{types-DO-b0LNj.d.ts → types-Djdq6Xkd.d.ts} +9 -8
  79. package/dist/{types-BOSGNvil.d.ts → types-E3HrTPg2.d.ts} +7 -13
  80. package/dist/{types-C7HFvdtk.d.ts → types-VqL6t5HH.d.ts} +82 -5
  81. package/dist/{watch-B5RTR-WX.d.ts → watch-BTYOJpQU.d.ts} +18 -1
  82. package/dist/{words-DagJdwIA.d.ts → words-AHHfiaRY.d.ts} +31 -2
  83. package/dist/{words-c-3h9xQQ.d.ts → words-BMzV04b1.d.ts} +1 -1
  84. package/dist/words-CJjUKcV5.d.ts +37 -0
  85. package/dist/words-CRYvAiHX.d.ts +105 -0
  86. package/dist/{words-CD3WADyb.d.ts → words-CzoyDNHm.d.ts} +4 -0
  87. package/dist/{words-C74EUpFr.d.ts → words-DBq7vfHy.d.ts} +57 -4
  88. package/dist/{words-N4ebT88_.d.ts → words-DgHcY5qB.d.ts} +9 -3
  89. package/package.json +8 -8
  90. package/dist/chunk-66CKSTXP.js +0 -14
  91. package/dist/chunk-672FAEKU.js +0 -1
  92. package/dist/chunk-67VZRQLG.js +0 -13
  93. package/dist/chunk-6PS6STGA.js +0 -1
  94. package/dist/chunk-7A7O2JWQ.js +0 -1
  95. package/dist/chunk-7JTL3P6P.js +0 -1
  96. package/dist/chunk-F2PIG3AA.js +0 -10
  97. package/dist/chunk-H4B72XCJ.js +0 -1
  98. package/dist/chunk-KDIVA6WD.js +0 -1
  99. package/dist/chunk-MCLBHENY.js +0 -1
  100. package/dist/chunk-QB3BZIRA.js +0 -5
  101. package/dist/chunk-SJQG5ENJ.js +0 -1
  102. package/dist/chunk-SUO5627P.js +0 -1
  103. package/dist/chunk-XUE5O62R.js +0 -3
  104. package/dist/chunk-ZT7M24XD.js +0 -1
  105. package/dist/editor/index.d.ts +0 -10
  106. package/dist/editor/index.js +0 -1
  107. /package/dist/{chunk-2PHD4L6A.js → chunk-OWBO4WKA.js} +0 -0
@@ -38,6 +38,9 @@ interface FieldNumberProps extends ControlBase {
38
38
  /** Two small stacked arrows at the cell's end. */
39
39
  steppers?: boolean;
40
40
  placeholder?: string;
41
+ /** The cell's tooltip — the text box's cells say their name and step here
42
+ * (E5b), since the cell draws no name. */
43
+ title?: string;
41
44
  }
42
45
  /**
43
46
  * A slider row (Site styles, Email styles): the name left and the typed value
@@ -50,20 +53,94 @@ interface FieldSliderProps extends Omit<FieldNumberProps, 'icon' | 'steppers' |
50
53
  label: string;
51
54
  sliderMin: number;
52
55
  sliderMax: number;
56
+ /**
57
+ * The word for "no number of its own: each section draws its own" (plan
58
+ * step E6). Given, the slider gains one spot left of `sliderMin` that means
59
+ * it, and the value reads the word while there is no number.
60
+ */
61
+ auto?: string;
53
62
  }
54
63
  interface FieldOption<V = unknown> {
55
64
  label: string;
56
65
  value: V;
57
66
  disabled?: boolean;
58
67
  icon?: ReactNode;
68
+ /**
69
+ * The heading this option sits under in the open list — what `<optgroup>`
70
+ * did. Each RUN of options with the same group gets one heading, in the
71
+ * order the options come; an option with none sits under no heading. A
72
+ * heading is not an option: it cannot be chosen and the keys never land on it.
73
+ */
74
+ group?: string;
75
+ /**
76
+ * A small picture at the head of the row (a product's cover). One option
77
+ * with a `thumb` key gives EVERY row the picture column, so a mixed list
78
+ * keeps its columns; `null` draws the empty well. No option with the key, no
79
+ * column.
80
+ */
81
+ thumb?: string | null;
82
+ /**
83
+ * One quiet fact at the end of the row (a price, a count). It is not part
84
+ * of the option's name: a screen reader does not hear it, and the closed
85
+ * control never shows it.
86
+ */
87
+ meta?: string;
59
88
  }
60
- interface FieldSelectProps<V = unknown> extends ControlBase {
61
- value: V | undefined;
89
+ /**
90
+ * `ariaLabelledBy` / `ariaLabel` name the button AND its open list. Left out,
91
+ * the button is named by its `<label for>` (or by what it shows) and the list
92
+ * by the button, so the list is never without a name.
93
+ */
94
+ interface FieldSelectBase<V> extends ControlBase {
62
95
  options: readonly FieldOption<V>[];
63
- onChange: (value: V) => void;
64
- /** Shown when the value names no option. */
96
+ /** Shown when the value names no option (when nothing is on, for `multiple`). */
65
97
  placeholder?: string;
98
+ /**
99
+ * A search box at the top of the open list. Typing narrows the options by
100
+ * label and the keys walk what is left; a letter goes into the box, so
101
+ * there is no letter jump. A long list (every product in a catalogue).
102
+ */
103
+ searchable?: boolean;
104
+ /**
105
+ * The search box's hint and name, in the host's own words ("Search your
106
+ * catalog…"). Left out, the catalogue's `fields.search`.
107
+ */
108
+ searchPlaceholder?: string;
109
+ /** Each group heading says how many of its options are showing. Derived, never passed. */
110
+ groupCount?: boolean;
111
+ /**
112
+ * The list opens IN FLOW, pushing the rows below it down, instead of
113
+ * floating. For a list inside a panel that scrolls, where a floating list is
114
+ * clipped by the panel's edge.
115
+ */
116
+ inline?: boolean;
117
+ /** Draws an option's row in place of its label (each style in its own face). It is still an option. */
118
+ renderOption?: (option: FieldOption<V>, state: {
119
+ active: boolean;
120
+ chosen: boolean;
121
+ }) => ReactNode;
122
+ }
123
+ /** One of a set. */
124
+ interface FieldSelectOneProps<V = unknown> extends FieldSelectBase<V> {
125
+ multiple?: false;
126
+ value: V | undefined;
127
+ onChange: (value: V) => void;
128
+ /** Draws the closed control's value in place of the chosen label. */
129
+ renderValue?: (chosen: FieldOption<V> | undefined) => ReactNode;
66
130
  }
131
+ /**
132
+ * Several of a set (`multiple`). The value is a list, saved in the order the
133
+ * OPTIONS come, never in the order they were ticked: two lists that look the
134
+ * same hold the same data. An empty list is an answer, not a missing one.
135
+ */
136
+ interface FieldSelectManyProps<V = unknown> extends FieldSelectBase<V> {
137
+ multiple: true;
138
+ value: readonly V[] | undefined;
139
+ onChange: (value: V[]) => void;
140
+ /** Draws the closed control's value in place of the labels of what is on. */
141
+ renderValue?: (on: FieldOption<V>[]) => ReactNode;
142
+ }
143
+ type FieldSelectProps<V = unknown> = FieldSelectOneProps<V> | FieldSelectManyProps<V>;
67
144
  interface FieldMeta {
68
145
  label?: string;
69
146
  /** The tab this field opens; inherited by the fields after it (see above). */
@@ -148,4 +225,4 @@ type FieldRenderer = (props: {
148
225
  readOnly?: boolean;
149
226
  }) => ReactNode;
150
227
 
151
- export type { ArrayFieldDef as A, CustomFieldDef as C, FieldRenderer as F, InspectorFields as I, NumberFieldDef as N, ObjectFieldDef as O, RadioFieldDef as R, SelectFieldDef as S, TextFieldDef as T, InspectorFieldDef as a, FieldTextProps as b, FieldNumberProps as c, FieldSliderProps as d, FieldSelectProps as e, FieldOption as f, CustomFieldRenderProps as g, SlotFieldDef as h, TextareaFieldDef as i };
228
+ export type { ArrayFieldDef as A, CustomFieldDef as C, FieldRenderer as F, InspectorFields as I, NumberFieldDef as N, ObjectFieldDef as O, RadioFieldDef as R, SelectFieldDef as S, TextFieldDef as T, InspectorFieldDef as a, FieldTextProps as b, FieldNumberProps as c, FieldSliderProps as d, FieldSelectManyProps as e, FieldSelectOneProps as f, FieldOption as g, CustomFieldRenderProps as h, FieldSelectProps as i, SlotFieldDef as j, TextareaFieldDef as k };
@@ -32,6 +32,14 @@ interface WatchOptions {
32
32
  * `load` — and a measurement taken then measures nothing. For the editor's
33
33
  * canvas pass `BLOCK_SELECTOR`. Watched with a MutationObserver on the frame's
34
34
  * document, never polled.
35
+ *
36
+ * ⚠️ "Ready" then means "holds a block", so a page with NO blocks is never
37
+ * ready: the frame is not published, and nothing that needs the canvas (the
38
+ * drag layer, a canvas stylesheet, a context menu) works on an empty page —
39
+ * the one page a first block has to be dropped on. An editor whose page can
40
+ * be empty names something the canvas ALWAYS draws instead — a list,
41
+ * `LIST_SELECTOR`: the page's own is there with nothing in it — or leaves
42
+ * this out.
35
43
  */
36
44
  readySelector?: string;
37
45
  }
@@ -41,6 +49,15 @@ interface WatchOptions {
41
49
  * because both apps' canvas CSS and checks read it.
42
50
  */
43
51
  declare const BLOCK_SELECTOR = "[data-puck-component]";
52
+ /**
53
+ * Every LIST the canvas draws carries this attribute — the page's own
54
+ * (`root:default-zone`) and each slot's — whether or not there is a block in
55
+ * it. So it is the `readySelector` for an editor whose page may be EMPTY: the
56
+ * canvas of a page with no blocks holds no `BLOCK_SELECTOR` and would never be
57
+ * published, on the one page a first block has to be dropped on (second host,
58
+ * 2026-10-07: it had typed the attribute out by hand to get this).
59
+ */
60
+ declare const LIST_SELECTOR = "[data-puck-dropzone]";
44
61
  /** The canvas frame: Puck 0.20's, and the engine's own `CanvasFrame` since 0.89.0. */
45
62
  declare const CANVAS_SELECTOR = "iframe#preview-frame";
46
63
  /**
@@ -57,4 +74,4 @@ declare function isFrameReady(frame: HTMLIFrameElement): boolean;
57
74
  */
58
75
  declare function watchCanvasFrame(root: Node, onChange: (target: CanvasTarget | null) => void, { selector, readySelector }?: WatchOptions): () => void;
59
76
 
60
- export { BLOCK_SELECTOR as B, type CanvasTarget as C, type WatchOptions as W, CANVAS_SELECTOR as a, isFrameReady as i, watchCanvasFrame as w };
77
+ export { BLOCK_SELECTOR as B, type CanvasTarget as C, LIST_SELECTOR as L, type WatchOptions as W, CANVAS_SELECTOR as a, isFrameReady as i, watchCanvasFrame as w };
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * The editor frame's own words (`efficient-easel/strings`, 0.95.0), in two
3
- * groups: what `EditNotice` says (`NoticeWords`) and the few words the rest of
4
- * the chrome carries when the host gives none (`ChromeWords`).
3
+ * groups: what `EditNotice` says (`NoticeWords`) and the words the rest of the
4
+ * chrome carries when the host gives none (`ChromeWords`), the media panel's
5
+ * head among them.
5
6
  *
6
7
  * A plain module with no import. Anything with a value in it is a function, so
7
8
  * a host puts the name, the noun and the time where its language wants them.
@@ -73,6 +74,34 @@ type ChromeWords = {
73
74
  }) => string;
74
75
  /** `PanelResizeHandle`: the tooltip. */
75
76
  resize: string;
77
+ /** `MediaPanelHead`, browsing: the panel's name. */
78
+ mediaLibrary: string;
79
+ /** `MediaPanelHead`, choosing: the panel's name. `kind` is a `mediaKinds` word. */
80
+ mediaChoose: (v: {
81
+ kind: string;
82
+ }) => string;
83
+ /** `MediaPanelHead`, choosing: the line under the name. `field` is the host's label for the field. */
84
+ mediaFor: (v: {
85
+ field: string;
86
+ }) => string;
87
+ /** What a field can hold, as the head says it, by `MediaPickKind`. */
88
+ mediaKinds: {
89
+ image: string;
90
+ video: string;
91
+ svg: string;
92
+ };
93
+ /** `MediaPanelHead`: the word that leaves choosing. */
94
+ mediaCancel: string;
95
+ /** `MediaPanelHead`: Cancel's tooltip. `kind` is a `mediaKinds` word. */
96
+ mediaKeep: (v: {
97
+ kind: string;
98
+ }) => string;
99
+ /** The Hide panel button at the end of a side panel's head: the tooltip. */
100
+ hidePanel: string;
101
+ /** The same button: its accessible name. */
102
+ hidePanelLabel: (v: {
103
+ side: 'left' | 'right';
104
+ }) => string;
76
105
  };
77
106
 
78
107
  export type { ChromeWords as C, NoticeWords as N };
@@ -1,4 +1,4 @@
1
- import { S as SaveTone } from './types-p9j2Fac7.js';
1
+ import { S as SaveTone } from './types-DGcCsxs8.js';
2
2
 
3
3
  /** Time and timers, passed in so a test can run minutes in a millisecond. */
4
4
  type AutosaveClock = {
@@ -0,0 +1,37 @@
1
+ import { S as SettingsBucket } from './buckets-CuLM47h9.js';
2
+
3
+ /**
4
+ * The settings panel's own words (`efficient-easel/strings`, 0.95.0): what
5
+ * the tab strip is called, what each tab SAYS, and the Default / Reset part.
6
+ *
7
+ * A bucket's key (`'Content'`, `'Style'`, …) is an identifier — fields name
8
+ * their tab with it and `SETTINGS_BUCKETS` orders them — so it never changes
9
+ * with the language. `buckets` is the word drawn for each key.
10
+ *
11
+ * The panel is hook-free, so nothing here is read from the strings provider:
12
+ * `SettingsTabs` takes its name as `ariaLabel` and each tab's word as the
13
+ * item's `label`, and `Inspector` (which has hooks) passes both.
14
+ * `SettingsDefaultReset` takes `words`, and a host passes the four from
15
+ * `useWords('panel', …)`.
16
+ */
17
+
18
+ type PanelWords = {
19
+ /** The tab strip's accessible name. */
20
+ settings: string;
21
+ /** The word each tab shows, by its key. */
22
+ buckets: Record<SettingsBucket, string>;
23
+ /** `SettingsDefaultReset`, resting: the value follows its default. */
24
+ followsDefault: string;
25
+ /** `SettingsDefaultReset`, changed: the button that clears the value. */
26
+ reset: string;
27
+ /** The Reset button's accessible name — which setting it resets. */
28
+ resetName: (p: {
29
+ label: string;
30
+ }) => string;
31
+ /** The Reset button's tooltip, when the host says what the default is. */
32
+ backToDefault: (p: {
33
+ detail: string;
34
+ }) => string;
35
+ };
36
+
37
+ export type { PanelWords as P };
@@ -0,0 +1,105 @@
1
+ /**
2
+ * The text-styles list's own words (`efficient-easel/strings`, plan step E6).
3
+ * A style's NAME is the host's data ("Heading 1" is stored); `styleName` is
4
+ * only how a NEW one is named. The fonts' and theme colours' names are the
5
+ * host's too.
6
+ *
7
+ * A plain module with no import. The English is the design's own (both pages,
8
+ * final 2026-10-06): "Body", never "Paragraph" (N10.1); US spelling, "Color".
9
+ */
10
+ type TextStylesWords = {
11
+ /** The two group headings, in the order they are drawn. */
12
+ groups: {
13
+ heading: string;
14
+ body: string;
15
+ };
16
+ /** The button under each group. */
17
+ add: {
18
+ heading: string;
19
+ body: string;
20
+ };
21
+ /** Beside the button: how many there are of the most allowed. */
22
+ count: (v: {
23
+ n: number;
24
+ max: number;
25
+ }) => string;
26
+ /** The button's tooltip once the group is full. */
27
+ full: (v: {
28
+ kind: 'heading' | 'body';
29
+ max: number;
30
+ }) => string;
31
+ /** A new style's name. `n` counts from 1 within its kind. */
32
+ styleName: (v: {
33
+ kind: 'heading' | 'body';
34
+ n: number;
35
+ }) => string;
36
+ /** Delete's tooltip: the same word as the Layers delete and the node menu. */
37
+ remove: string;
38
+ /** Delete's accessible name. `name` is the style's: "Heading 4". */
39
+ removeNamed: (v: {
40
+ name: string;
41
+ }) => string;
42
+ /** The line an open style's preview is drawn in, unless the host gives its own. */
43
+ sample: string;
44
+ /** The preview's accessible name. */
45
+ preview: string;
46
+ /** A row's grey line. Each part is already words: "16 px", "Auto", "Regular". */
47
+ summary: (v: {
48
+ font: string;
49
+ size: string;
50
+ weight: string;
51
+ }) => string;
52
+ /** A size in the grey line. */
53
+ px: (v: {
54
+ n: number;
55
+ }) => string;
56
+ /** No number of its own: each section draws its own. */
57
+ auto: string;
58
+ /** A weight's name, by the hundred it is nearest. */
59
+ weights: {
60
+ thin: string;
61
+ extraLight: string;
62
+ light: string;
63
+ regular: string;
64
+ medium: string;
65
+ semibold: string;
66
+ bold: string;
67
+ extraBold: string;
68
+ black: string;
69
+ };
70
+ /** Each setting's name in an open style. */
71
+ settings: {
72
+ font: string;
73
+ color: string;
74
+ size: string;
75
+ weight: string;
76
+ /** The B · I row (Site styles). */
77
+ emphasis: string;
78
+ lineSpacing: string;
79
+ letterSpacing: string;
80
+ paragraphSpacing: string;
81
+ letterCase: string;
82
+ largestSize: string;
83
+ };
84
+ bold: string;
85
+ italic: string;
86
+ /** The Italic button's tooltip when the font has no italic. */
87
+ italicMissing: string;
88
+ /** Letter case's buttons. */
89
+ case: {
90
+ auto: string;
91
+ autoTitle: string;
92
+ none: string;
93
+ upper: string;
94
+ lower: string;
95
+ };
96
+ colour: {
97
+ /** The rainbow swatch at the end of the theme's colours. */
98
+ any: string;
99
+ /** What the Color row reads while the style has no colour of its own. */
100
+ follows: string;
101
+ };
102
+ };
103
+ declare const DEFAULT_TEXT_STYLES_WORDS: TextStylesWords;
104
+
105
+ export { DEFAULT_TEXT_STYLES_WORDS as D, type TextStylesWords as T };
@@ -13,6 +13,10 @@ type FieldsWords = {
13
13
  more: string;
14
14
  /** `FieldSelect`: what the box says while nothing is chosen. */
15
15
  choose: string;
16
+ /** `FieldSelect` with `searchable`: the search box's hint and name. Optional: a host's older catalogue falls back to the English. */
17
+ search?: string;
18
+ /** `FieldSelect` with `searchable`: what the list says when nothing matches. */
19
+ noMatches?: string;
16
20
  /** `ListField` — an array field drawn as rows. */
17
21
  list: {
18
22
  /** One item's word when the field names none. */
@@ -48,10 +48,9 @@ type CopyAlign = (typeof COPY_ALIGNS)[number];
48
48
  * rule (British is for client-facing design work, not the product). The words
49
49
  * themselves are ./words' (`EaselStrings.copy.align`); this is their English. */
50
50
  declare const COPY_ALIGN_LABELS: Record<CopyAlign, string>;
51
- /** The mark each direction draws. `justify` is `align-separate` — the icon
52
- * set's own "rows pushed apart to both edges", which is what justified text
53
- * is. The campaign designer already made this choice; it moves here rather
54
- * than being made a second time. */
51
+ /** The mark each direction draws. `justify` is `align-justify` (E5b, design
52
+ * final 2026-10-06): rows run edge to edge. Until then it borrowed
53
+ * `align-separate`, whose own entry says it is NOT justify. */
55
54
  declare const COPY_ALIGN_GLYPHS: Record<CopyAlign, ReactNode>;
56
55
  /**
57
56
  * How wide this strip's WORDS are, for the drop-to-glyphs threshold.
@@ -123,6 +122,9 @@ type CopyWords = {
123
122
  /** Why an address was refused. */
124
123
  refused: string;
125
124
  remove: string;
125
+ /** E5b: the window's Cancel. Optional, so a host's words from before still
126
+ * type; English when left out. */
127
+ cancel?: string;
126
128
  apply: string;
127
129
  };
128
130
  /**
@@ -137,6 +139,57 @@ type CopyWords = {
137
139
  }>;
138
140
  /** What a mark writes when nothing is selected — typed over at once. */
139
141
  placeholders: MarkPlaceholders;
142
+ /** The switch under a many-line box that shows the raw text with its marks
143
+ * (E5a). Optional, so a host's words from before still type; English when
144
+ * left out. */
145
+ showMarks?: string;
146
+ /**
147
+ * The final toolbar's buttons (E5b, design final 2026-10-06): what each is
148
+ * called — its accessible name and tooltip. Undo's tooltip also says how to
149
+ * redo, since there is no Redo button. Optional, like every E5b word, so a
150
+ * host's words from before still type.
151
+ */
152
+ toolbar?: {
153
+ bold: string;
154
+ italic: string;
155
+ underline: string;
156
+ strike: string;
157
+ color: string;
158
+ link: string;
159
+ sup: string;
160
+ sub: string;
161
+ undo: string;
162
+ undoTitle: string;
163
+ bullet: string;
164
+ number: string;
165
+ letterCase: string;
166
+ caseNone: string;
167
+ caseUpper: string;
168
+ caseLower: string;
169
+ };
170
+ /** The colour window: its name, the theme row's label, and Remove. */
171
+ colors?: {
172
+ title: string;
173
+ theme: string;
174
+ remove: string;
175
+ /** "Any color": the square, the hue bar and the hex box under the theme. */
176
+ any: string;
177
+ square: string;
178
+ hue: string;
179
+ hex: string;
180
+ };
181
+ /** The number cells' names, and the tooltip each one carries. */
182
+ cells?: {
183
+ fontSize: string;
184
+ lineHeight: string;
185
+ letterSpacing: string;
186
+ paragraphSpacing: string;
187
+ tip: (v: {
188
+ name: string;
189
+ step: number;
190
+ unit: string;
191
+ }) => string;
192
+ };
140
193
  };
141
194
 
142
195
  export { type CopyWords as C, type CopyAlign as a, COPY_ALIGNS as b, COPY_ALIGN_FIT as c, COPY_ALIGN_GLYPHS as d, COPY_ALIGN_LABELS as e, copyAlignOptions as f };
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * The Layers tree's own words (`efficient-easel/strings`, 0.95.0): the drag
3
- * hint and the caret's. A row's name, its marks and its actions are the
4
- * host's.
3
+ * hint, the caret's and an empty slot's. A row's name, its marks and its
4
+ * actions are the host's.
5
5
  *
6
6
  * The tree is hook-free, so it does not read the strings provider: `TreeRow`
7
- * takes these as its `words` prop and a host passes
7
+ * and `TreeEmptySlot` take these as their `words` prop and a host passes
8
8
  * `useEaselStrings().tree`.
9
9
  */
10
10
  type TreeWords = {
@@ -22,6 +22,12 @@ type TreeWords = {
22
22
  expandNamed: (v: {
23
23
  label: string;
24
24
  }) => string;
25
+ /** What an empty slot says when it offers nothing: a read-only tree. */
26
+ emptySlot?: string;
27
+ /** What an empty slot's button says. */
28
+ addBlock?: string;
29
+ /** What an empty slot says while a drag may land in it. */
30
+ dropHere?: string;
25
31
  };
26
32
 
27
33
  export type { TreeWords as T };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "efficient-easel",
3
- "version": "0.99.2",
3
+ "version": "0.100.0",
4
4
  "description": "Efficient Easel: the EFFICIENT editors' shared engine and chrome: the saved document as pure functions, the published renderer, and the editor frame, panels, Layers tree, text grammar and type-in-place box. Published as editor-shell up to 0.66.0 and as efficient-editor up to 0.95.0.",
5
5
  "license": "UNLICENSED",
6
6
  "author": "Efficient Pty Ltd",
@@ -97,18 +97,18 @@
97
97
  "default": "./dist/fields/index.js"
98
98
  },
99
99
  "./fields.css": "./dist/fields/fields.css",
100
+ "./text-styles": {
101
+ "types": "./dist/text-styles/index.d.ts",
102
+ "import": "./dist/text-styles/index.js",
103
+ "default": "./dist/text-styles/index.js"
104
+ },
105
+ "./text-styles.css": "./dist/text-styles/text-styles.css",
100
106
  "./easel": {
101
107
  "types": "./dist/easel/index.d.ts",
102
108
  "import": "./dist/easel/index.js",
103
109
  "default": "./dist/easel/index.js"
104
110
  },
105
111
  "./easel.css": "./dist/easel/easel.css",
106
- "./editor": {
107
- "types": "./dist/editor/index.d.ts",
108
- "import": "./dist/editor/index.js",
109
- "default": "./dist/editor/index.js"
110
- },
111
- "./editor.css": "./dist/easel/easel.css",
112
112
  "./autosave": {
113
113
  "types": "./dist/autosave/index.d.ts",
114
114
  "import": "./dist/autosave/index.js",
@@ -188,7 +188,7 @@
188
188
  "typescript": "^5.3.0"
189
189
  },
190
190
  "scripts": {
191
- "build": "tsup && cp src/rail/rail.css dist/rail/rail.css && cp src/shell/shell.css dist/shell/shell.css && cp src/gold/gold.css dist/gold/gold.css && cp src/copy/copy.css dist/copy/copy.css && cp src/panel/panel.css dist/panel/panel.css && cp src/menu/menu.css dist/menu/menu.css && cp src/chrome/chrome.css dist/chrome/chrome.css && cp src/tree/tree.css dist/tree/tree.css && cp src/drag/drag.css dist/drag/drag.css && cp src/pick/pick.css dist/pick/pick.css && cp src/fields/fields.css dist/fields/fields.css && cp src/easel/easel.css dist/easel/easel.css",
191
+ "build": "tsup && cp src/rail/rail.css dist/rail/rail.css && cp src/shell/shell.css dist/shell/shell.css && cp src/gold/gold.css dist/gold/gold.css && cp src/copy/copy.css dist/copy/copy.css && cp src/panel/panel.css dist/panel/panel.css && cp src/menu/menu.css dist/menu/menu.css && cp src/chrome/chrome.css dist/chrome/chrome.css && cp src/tree/tree.css dist/tree/tree.css && cp src/drag/drag.css dist/drag/drag.css && cp src/pick/pick.css dist/pick/pick.css && cp src/fields/fields.css dist/fields/fields.css && cp src/text-styles/text-styles.css dist/text-styles/text-styles.css && cp src/easel/easel.css dist/easel/easel.css",
192
192
  "dev": "tsup --watch",
193
193
  "typecheck": "tsc --noEmit && tsc -p tsconfig.test.json",
194
194
  "test": "node scripts/test.mjs",
@@ -1,14 +0,0 @@
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
- return r("div",{...l,className:e?`es-tree ${e}`:"es-tree",children:a})}function t({children:e}){/* @__PURE__ */
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: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
- /* @__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:P,children:[o?
7
- /* @__PURE__ */l(n,{children:[
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??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
- /* @__PURE__ */r("span",{className:"es-tree-chip","aria-hidden":"true",children:s}),
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
- 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
- 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 +0,0 @@
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};
@@ -1,13 +0,0 @@
1
- import{DEFAULT_PANEL_WORDS as e}from"./chunk-7A7O2JWQ.js";import{jsx as a,jsxs as l,Fragment as i}from"react/jsx-runtime";import{isValidElement as n,cloneElement as s}from"react";function r({items:i,activeId:n,onSelect:s,ariaLabel:r=e.settings,className:t}){
2
- /* @__PURE__ */
3
- return a("div",{className:"es-tabs-fit",children:/* @__PURE__ */a("div",{role:"tablist","aria-label":r,"aria-orientation":"horizontal",className:t?`es-tabs ${t}`:"es-tabs",children:i.map(e=>{const i=e.id===n,r=`es-tab${e.icon?" has-icon":""}${i?" is-active":""}`;/* @__PURE__ */
4
- return l("button",{type:"button",role:"tab",id:e.htmlId,title:e.label,"aria-label":e.label,"aria-selected":i,"aria-controls":e.panelId,className:r,onClick:()=>s(e.id),children:[e.icon?/* @__PURE__ */a("span",{className:"es-tab-icon","aria-hidden":"true",children:e.icon}):null,
5
- /* @__PURE__ */a("span",{className:"es-tab-word",children:e.label}),"number"==typeof e.badge&&e.badge>0?/* @__PURE__ */a("span",{className:"es-tab-badge",children:e.badge}):null]},e.id)})})})}function t({checked:e,onChange:l,disabled:i,id:n,ariaLabel:s,ariaLabelledBy:r,className:t}){/* @__PURE__ */
6
- return a("button",{type:"button",role:"switch",id:n,"aria-checked":e,"aria-label":s,"aria-labelledby":r,disabled:i,className:t?`es-switch ${t}`:"es-switch",onClick:()=>l(!e)})}function c(e){return Array.isArray(e)?e.some(c):n(e)}function d(e,a,l){if(!n(e)||e.type!==t)return e;const i=e.props;return i.ariaLabel||i.ariaLabelledBy?e:s(e,l?{ariaLabelledBy:l}:{ariaLabel:a})}function o({label:e,labelId:n,icon:s,value:r,hint:t,changed:o,htmlFor:u,action:h,children:b,className:m}){const p=c(b),N=c(h);if(!p&&!N)return null;const f=["es-field"];p||f.push("is-inline"),o&&f.push("is-changed"),m&&f.push(m);const g=/* @__PURE__ */l(i,{children:[s?/* @__PURE__ */a("span",{className:"es-field-icon","aria-hidden":"true",children:s}):null,
7
- /* @__PURE__ */a("span",{className:"es-field-label",id:n,children:e})]});/* @__PURE__ */
8
- return l("div",{className:f.join(" "),children:[
9
- /* @__PURE__ */l("div",{className:"es-field-head",children:[u?/* @__PURE__ */a("label",{className:"es-field-name",htmlFor:u,children:g}):/* @__PURE__ */a("span",{className:"es-field-name",children:g}),null!=r?/* @__PURE__ */a("span",{className:"es-field-value",children:r}):null,N?d(h,e,n):null]}),p?/* @__PURE__ */a("div",{className:"es-field-ctl",children:b}):null,t?/* @__PURE__ */a("p",{className:"es-field-hint",children:t}):null]})}function u({title:e,open:i,onToggle:n,count:s,id:r,children:t,className:c}){const d=r?`${r}-body`:void 0;/* @__PURE__ */
10
- return l("div",{className:c?`es-group ${c}`:"es-group",children:[
11
- /* @__PURE__ */l("button",{type:"button",id:r,"aria-expanded":i,"aria-controls":d,className:"es-group-head",onClick:()=>n(!i),children:[e,"number"==typeof s&&s>0?/* @__PURE__ */a("span",{className:"es-group-count",children:s}):null,
12
- /* @__PURE__ */a("span",{className:"es-group-sign","aria-hidden":"true"})]}),
13
- /* @__PURE__ */a("div",{id:d,className:"es-group-body",hidden:!i,children:t})]})}var h=Object.freeze(["Content","Style","Layout","Animation"]);export{h as SETTINGS_BUCKETS,o as SettingsField,u as SettingsGroup,t as SettingsSwitch,r as SettingsTabs};
@@ -1 +0,0 @@
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 +0,0 @@
1
- var t={settings:"Settings",buckets:{Content:"Content",Style:"Style",Layout:"Layout",Animation:"Animation"}};export{t as DEFAULT_PANEL_WORDS};
@@ -1 +0,0 @@
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};
@@ -1,10 +0,0 @@
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};