efficient-easel 0.0.0 → 0.96.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 (119) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +723 -4
  3. package/dist/autosave/index.d.ts +101 -0
  4. package/dist/autosave/index.js +1 -0
  5. package/dist/blocks/index.d.ts +295 -0
  6. package/dist/blocks/index.js +0 -0
  7. package/dist/buckets-1vRlQceY.d.ts +13 -0
  8. package/dist/canvas/index.d.ts +194 -0
  9. package/dist/canvas/index.js +1 -0
  10. package/dist/chrome/chrome.css +570 -0
  11. package/dist/chrome/index.d.ts +219 -0
  12. package/dist/chrome/index.js +21 -0
  13. package/dist/chunk-2LUSK32B.js +1 -0
  14. package/dist/chunk-2OAZYSWJ.js +1 -0
  15. package/dist/chunk-67VZRQLG.js +13 -0
  16. package/dist/chunk-6JDII7N3.js +1 -0
  17. package/dist/chunk-6OPSJGAI.js +1 -0
  18. package/dist/chunk-6WY6ZXJG.js +1 -0
  19. package/dist/chunk-7A7O2JWQ.js +1 -0
  20. package/dist/chunk-BZ5ASXOL.js +1 -0
  21. package/dist/chunk-CERTFXCV.js +13 -0
  22. package/dist/chunk-EFTTSIMK.js +1 -0
  23. package/dist/chunk-FI23ALVJ.js +1 -0
  24. package/dist/chunk-FJE4IDBQ.js +1 -0
  25. package/dist/chunk-GGTPNGFJ.js +1 -0
  26. package/dist/chunk-H4B72XCJ.js +1 -0
  27. package/dist/chunk-H6DDIBQ4.js +1 -0
  28. package/dist/chunk-KDIVA6WD.js +1 -0
  29. package/dist/chunk-LPRQDDQO.js +1 -0
  30. package/dist/chunk-MCLBHENY.js +1 -0
  31. package/dist/chunk-MFIRYGHW.js +1 -0
  32. package/dist/chunk-NKB3KVAB.js +1 -0
  33. package/dist/chunk-O2NLQBFX.js +1 -0
  34. package/dist/chunk-OGZFDJ6G.js +1 -0
  35. package/dist/chunk-OWBO4WKA.js +0 -0
  36. package/dist/chunk-QB3BZIRA.js +5 -0
  37. package/dist/chunk-RE4LP46F.js +1 -0
  38. package/dist/chunk-STFMZJKU.js +14 -0
  39. package/dist/chunk-SUO5627P.js +1 -0
  40. package/dist/chunk-TDA4HH54.js +1 -0
  41. package/dist/chunk-WK3AFPXY.js +1 -0
  42. package/dist/chunk-YIMRTIBN.js +3 -0
  43. package/dist/chunk-YNZZYHA4.js +450 -0
  44. package/dist/chunk-ZAOM6PFH.js +1 -0
  45. package/dist/chunk-ZNCEOSXO.js +1 -0
  46. package/dist/copy/copy.css +282 -0
  47. package/dist/copy/index.d.ts +336 -0
  48. package/dist/copy/index.js +10 -0
  49. package/dist/data/index.d.ts +208 -0
  50. package/dist/data/index.js +1 -0
  51. package/dist/drag/drag.css +360 -0
  52. package/dist/drag/index.d.ts +379 -0
  53. package/dist/drag/index.js +18 -0
  54. package/dist/edit-lock/index.d.ts +354 -0
  55. package/dist/edit-lock/index.js +1 -0
  56. package/dist/editor/editor.css +58 -0
  57. package/dist/editor/index.d.ts +361 -0
  58. package/dist/editor/index.js +9 -0
  59. package/dist/fields/fields.css +207 -0
  60. package/dist/fields/index.d.ts +273 -0
  61. package/dist/fields/index.js +46 -0
  62. package/dist/gold/gold.css +196 -0
  63. package/dist/gold/index.d.ts +280 -0
  64. package/dist/gold/index.js +1 -0
  65. package/dist/icons/index.d.ts +474 -0
  66. package/dist/icons/index.js +1 -0
  67. package/dist/index.d.ts +6 -0
  68. package/dist/index.js +1 -0
  69. package/dist/markup/index.d.ts +452 -0
  70. package/dist/markup/index.js +1 -0
  71. package/dist/menu/index.d.ts +49 -0
  72. package/dist/menu/index.js +15 -0
  73. package/dist/menu/menu.css +254 -0
  74. package/dist/node-ops/index.d.ts +91 -0
  75. package/dist/node-ops/index.js +1 -0
  76. package/dist/panel/index.d.ts +1088 -0
  77. package/dist/panel/index.js +16 -0
  78. package/dist/panel/panel.css +1460 -0
  79. package/dist/pick/index.d.ts +153 -0
  80. package/dist/pick/index.js +14 -0
  81. package/dist/pick/pick.css +235 -0
  82. package/dist/plan-DtNw2VuI.d.ts +88 -0
  83. package/dist/rail/index.d.ts +145 -0
  84. package/dist/rail/index.js +1 -0
  85. package/dist/rail/rail.css +175 -0
  86. package/dist/render/index.d.ts +117 -0
  87. package/dist/render/index.js +5 -0
  88. package/dist/resolve-DpH8YQOA.d.ts +57 -0
  89. package/dist/shell/index.d.ts +159 -0
  90. package/dist/shell/index.js +1 -0
  91. package/dist/shell/shell.css +122 -0
  92. package/dist/strings/catalogue.d.ts +141 -0
  93. package/dist/strings/catalogue.js +1 -0
  94. package/dist/strings/index.d.ts +56 -0
  95. package/dist/strings/index.js +2 -0
  96. package/dist/style-clipboard/index.d.ts +184 -0
  97. package/dist/style-clipboard/index.js +1 -0
  98. package/dist/tree/index.d.ts +173 -0
  99. package/dist/tree/index.js +1 -0
  100. package/dist/tree/tree.css +618 -0
  101. package/dist/types-CEqUFH2j.d.ts +129 -0
  102. package/dist/types-CuNiSnX6.d.ts +204 -0
  103. package/dist/types-DNrn_w4V.d.ts +88 -0
  104. package/dist/types-DziKCwsN.d.ts +105 -0
  105. package/dist/types-_Vayx8ov.d.ts +153 -0
  106. package/dist/types-pGBXevBU.d.ts +131 -0
  107. package/dist/useNodeOps-6IAej9jy.d.ts +68 -0
  108. package/dist/watch-DmasQA61.d.ts +60 -0
  109. package/dist/wordFit-9B9nqyf3.d.ts +35 -0
  110. package/dist/words-B2YLaKEr.d.ts +30 -0
  111. package/dist/words-B87GIFWH.d.ts +86 -0
  112. package/dist/words-BK-npta-.d.ts +27 -0
  113. package/dist/words-CD3WADyb.d.ts +51 -0
  114. package/dist/words-CsRWXkY4.d.ts +129 -0
  115. package/dist/words-D9ChvbNC.d.ts +52 -0
  116. package/dist/words-DOhF-4D4.d.ts +35 -0
  117. package/dist/words-DagJdwIA.d.ts +78 -0
  118. package/dist/words-DfxEp_RH.d.ts +142 -0
  119. package/package.json +202 -3
@@ -0,0 +1,254 @@
1
+ /*
2
+ * efficient-easel/menu.css — the right-click menu box (card 66400.d).
3
+ *
4
+ * THE VALUES ARE NOT OURS. They are the storefront editor's shipped
5
+ * `.sf-blockmenu` / `.sf-blockmenu-item` — `efficient-shop/components/storefront-editor.css`,
6
+ * read at line 1165 — which is the look card 66400.d names for the menu Lewis
7
+ * approved on 2026-08-31. Each `--sf-*` there is already an alias of the
8
+ * matching `--es-*` here (card 66024), so the look is expressed with no new
9
+ * value except the three noted below. Change one only to track a deliberate
10
+ * change THERE. Pinned by `tests/menu-box-css.test.ts`.
11
+ *
12
+ * ⚠️ THREE VALUES ARE UNDER A LIVE QUESTION, and each is behind ONE var so
13
+ * settling it is a three-line change. The drawing Lewis approved that same day
14
+ * (`mockups/editor-add-and-context-v1.html`, its `.ctx` rule) is a FLOATING
15
+ * menu, where `.sf-blockmenu` is an in-flow picker, and it holds different
16
+ * numbers for exactly the three things that difference would move:
17
+ *
18
+ * .sf-blockmenu (shipped) .ctx (the drawing)
19
+ * radius 8px 9px
20
+ * shadow 0 6px 18px rgba(0,0,0,.08) 0 10px 28px rgba(0,0,0,.16)
21
+ * min-width 220px (the admin box's own) 186px
22
+ *
23
+ * This sheet ships `.sf-blockmenu`'s, per the card's own constraint. The
24
+ * question is with the fork that owns the design.
25
+ *
26
+ * LIGHT only — neither editing surface has a dark mode (owner, 2026-08-06), so
27
+ * there is no dark counterpart block here. Do not add one.
28
+ *
29
+ * Import once from a client entry / global stylesheet:
30
+ * import 'efficient-easel/menu.css';
31
+ */
32
+
33
+ /* ── this sheet's own vars ──────────────────────────────────────────────────
34
+ ON `.es-editor`, the chrome root, following `rail.css` (which owns
35
+ `--es-rail-*`) and `panel.css` (`--es-row-gap`): the sheet that owns the
36
+ rules owns its tokens, and `shell.css` stays a verbatim mirror of the
37
+ storefront editor's `--sf-*` block. None of these is a shell token.
38
+
39
+ ⚠️ The box itself names `es-editor` (see `skin.ts`) — it is portalled to
40
+ `document.body`, outside the editor tree, so this is also where it picks these
41
+ up. Read that note before moving them.
42
+
43
+ ⛔ CUSTOM PROPERTIES ONLY IN THIS BLOCK. Never a paint property.
44
+
45
+ `.es-editor` is not this package's own element — it is the class each editor
46
+ puts on ITS OWN chrome root, and the campaign designer puts it on a root that
47
+ lives INSIDE the admin portal's DOM (card 66024 made that the mechanism by
48
+ which the designer is themed; `CampaignDesigner.tsx` adds the class and
49
+ `campaignBlocks.css` aliases its `--cd-*` onto these values). A custom
50
+ property declared here is inert until something reads it. A `background`, a
51
+ `padding`, a `font` — anything that PAINTS — is not: it applies to that root
52
+ the moment this sheet is imported, in every editor that imports it, and in
53
+ the admin portal's own document.
54
+
55
+ Audited on 2026-09-02 across every sheet in this package that opens an
56
+ `.es-editor` block, and the honest number is zero:
57
+
58
+ shell.css 67 declarations, 67 custom, 0 paint
59
+ panel.css 11 declarations, 11 custom, 0 paint
60
+ menu.css 7 declarations, 7 custom, 0 paint
61
+
62
+ ⚠️ Nothing enforces this — it is a rule with no test behind it. If you are
63
+ adding a declaration here, you are the check. */
64
+ .es-editor {
65
+ /* HOW FAR THE BOX FLOATS OFF THE PAGE BEHIND IT.
66
+ The drawing's value. `.sf-blockmenu` — the shop's shipped Add-block picker
67
+ — carries `0 6px 18px rgba(0,0,0,.08)`, and this is deliberately heavier:
68
+ that picker sits IN FLOW inside a panel, while this box FLOATS over
69
+ content, and a floating box has to separate itself from whatever is under
70
+ it. The drawing's own header cites `.sf-blockmenu`, so its author had that
71
+ value open and moved off it on purpose.
72
+ This is the CONTEXT half of the split described on `--es-menu-hover-bg`:
73
+ it follows the situation, not the neighbour. */
74
+ --es-menu-shadow: 0 10px 28px rgba(0, 0, 0, 0.16);
75
+
76
+ /* HOW SOFT ITS CORNERS ARE. The drawing's 9px, one more than the in-flow
77
+ picker's 8 — the same floating-vs-in-flow distinction. */
78
+ --es-menu-radius: 9px;
79
+
80
+ /* THE NARROWEST THE BOX MAY GET — a floor, not a width.
81
+ A menu that shrank to its longest label would change width with its
82
+ contents, so a merchant's pointer would land on a different row depending
83
+ on which label happened to be longest. The drawing's 186px. It is also the
84
+ width the flyout measures against when it decides to flip left. */
85
+ --es-menu-min-w: 186px;
86
+
87
+ /* WHAT A ROW DOES UNDER THE POINTER — the one thing a merchant watches move.
88
+ ⚠️ THIS ONE DOES NOT FOLLOW THE DRAWING, AND THAT IS DELIBERATE. The
89
+ drawing's `.ctx` washes the row GREY and leaves the text alone. This washes
90
+ the accent tint and turns the text blue, which is `.sf-blockmenu` — the Add
91
+ menu, one keystroke away in the same editor.
92
+
93
+ Owner ruling, 2026-09-02, recorded as a dated amendment in the
94
+ `owner-design-rulings` skill ("the right-click menu hovers BLUE, not the
95
+ drawing's grey"): it was put to him rather than decided, because two menus
96
+ in one editor highlighting differently is a rule-zero failure. His word was
97
+ blue.
98
+
99
+ ⛔ DO NOT "RESTORE" THE DRAWING'S GREY. The split from the three values
100
+ above is not an inconsistency, it is the rule:
101
+
102
+ hover interaction grammar -> follows the NEIGHBOUR
103
+ shadow / radius / context -> follows the SITUATION
104
+ min-width (this box floats; the Add
105
+ menu sits in flow)
106
+
107
+ Still behind a var, because that is what made asking him cost nothing. */
108
+ --es-menu-hover-bg: var(--es-accent-tint);
109
+ --es-menu-hover-fg: var(--es-accent);
110
+
111
+ /* A ROW THAT DESTROYS SOMETHING.
112
+ ⚠️ The drawing is the ONLY reference for this one — `.sf-blockmenu` has no
113
+ danger row at all, so nothing is being overridden here. Its `#b91c1c` is
114
+ exactly `--es-danger-strong`, so it is read from the token layer rather
115
+ than copied as a literal. */
116
+ --es-menu-danger-fg: var(--es-danger-strong);
117
+
118
+ /* THE SHORTCUT COLUMN'S INK — quieter than a label, quieter than `--es-muted`,
119
+ because a shortcut is a reminder and never the thing being read.
120
+ ⚠️ The one value here with no shell token behind it: the drawing's own
121
+ `#b6bcc4`, which is lighter than `--es-disabled` (#9ca3af). Named here
122
+ rather than reaching for a token that is not this colour. */
123
+ --es-menu-shortcut-fg: #b6bcc4;
124
+ }
125
+
126
+
127
+ /* ── the box ────────────────────────────────────────────────────────────────
128
+ FIXED and lifted on purpose: it hangs OVER the panel it was opened from
129
+ rather than inside it, so a left panel dragged to its 220px minimum — which
130
+ clips its own overflow — cannot cut it off. Measured in Chromium at both
131
+ panel widths; see `tests/fixtures/menu-clipping.html`. */
132
+ .es-menu {
133
+ position: fixed;
134
+ z-index: 9999;
135
+ box-sizing: border-box;
136
+ display: flex;
137
+ flex-direction: column;
138
+ gap: 1px;
139
+ min-width: var(--es-menu-min-w);
140
+ /* A box that could grow past the viewport would be unreachable on its far
141
+ side whatever the edge-flip did. */
142
+ max-width: calc(100vw - 16px);
143
+ padding: 4px;
144
+ border: 1px solid var(--es-line);
145
+ border-radius: var(--es-menu-radius);
146
+ background: var(--es-panel);
147
+ box-shadow: var(--es-menu-shadow);
148
+ font-family: var(--es-font);
149
+ /* For `maxHeight`. The flyout is portalled separately BECAUSE of this: a CSS
150
+ overflow that is not `visible` on one axis clips the other too, so an
151
+ in-flow flyout would be cut off at this box's edge. */
152
+ overflow-y: auto;
153
+ overscroll-behavior: contain;
154
+ }
155
+
156
+ /* ── a row ──────────────────────────────────────────────────────────────── */
157
+ .es-menu-item {
158
+ display: flex;
159
+ align-items: center;
160
+ gap: 8px;
161
+ width: 100%;
162
+ padding: 7px 9px;
163
+ border: none;
164
+ border-radius: 6px;
165
+ background: transparent;
166
+ color: var(--es-text);
167
+ font: inherit;
168
+ font-size: 12.5px;
169
+ text-align: left;
170
+ cursor: pointer;
171
+ }
172
+
173
+ /* The one thing a merchant watches move — see `--es-menu-hover-*` above for
174
+ which reference this follows and why it is behind a var. */
175
+ .es-menu-item:hover {
176
+ background: var(--es-menu-hover-bg);
177
+ color: var(--es-menu-hover-fg);
178
+ }
179
+
180
+ .es-menu-item:focus-visible {
181
+ outline: 2px solid var(--es-accent-ring);
182
+ outline-offset: -2px;
183
+ }
184
+
185
+ .es-menu-item.is-danger {
186
+ color: var(--es-menu-danger-fg);
187
+ }
188
+ /* The drawing gives a danger row no hover of its own: it takes the same grey as
189
+ every other row and KEEPS its red, rather than washing red as well. Stated as
190
+ its own rule because `.es-menu-item:hover` would otherwise repaint the text. */
191
+ .es-menu-item.is-danger:hover {
192
+ background: var(--es-menu-hover-bg);
193
+ color: var(--es-menu-danger-fg);
194
+ }
195
+
196
+ /* ── the parts of a row ─────────────────────────────────────────────────── */
197
+ .es-menu-label {
198
+ flex: 1;
199
+ }
200
+ /* A state name in a flyout can be long; a row in the box never is. */
201
+ .es-menu-label-sub {
202
+ overflow: hidden;
203
+ text-overflow: ellipsis;
204
+ white-space: nowrap;
205
+ }
206
+
207
+ .es-menu-chevron {
208
+ color: var(--es-icon);
209
+ }
210
+
211
+ /* The drawing's `.ci` — a fixed 16px column so labels line up whether or not a
212
+ row has a glyph, exactly as the tick column does in a flyout. */
213
+ .es-menu-icon {
214
+ flex: none;
215
+ width: 16px;
216
+ text-align: center;
217
+ color: var(--es-muted);
218
+ font-size: 11px;
219
+ }
220
+
221
+ /* The drawing's `.k`. `margin-left: auto` is what right-aligns it, so it works
222
+ whether or not the row also carries a chevron. */
223
+ .es-menu-shortcut {
224
+ margin-left: auto;
225
+ color: var(--es-menu-shortcut-fg);
226
+ font-size: 11px;
227
+ }
228
+
229
+ /* Present on every row of a flyout that uses one, so the labels line up whether
230
+ or not the row is the state you are already on. */
231
+ .es-menu-tick {
232
+ flex: none;
233
+ width: 12px;
234
+ color: var(--es-accent);
235
+ }
236
+
237
+ /* ── a caption, and a separator ─────────────────────────────────────────── */
238
+ .es-menu-header {
239
+ padding: 6px 9px 4px;
240
+ color: var(--es-muted);
241
+ font-size: 10px;
242
+ font-weight: 500;
243
+ letter-spacing: 0.06em;
244
+ text-transform: uppercase;
245
+ }
246
+
247
+ /* AIR, NOT A LINE (card 66350). The owner has asked for divider hairlines to
248
+ go, more than once, and `tests/panel-no-divider-lines.test.ts` sweeps every
249
+ stylesheet this package ships for a one-sided border — this one included. A
250
+ `'—'` item still separates; it does it with a gap. With the box's own 1px
251
+ `gap` either side, that is 7px between groups against 1px between rows. */
252
+ .es-menu-divider {
253
+ height: 5px;
254
+ }
@@ -0,0 +1,91 @@
1
+ export { A as AfterRemove, I as ItemSelector, N as NodeSelection, P as Planned, S as StepBounds, c as canStep, f as fromItemSelector, p as parentStep, a as planDuplicate, b as planMove, d as planPaste, e as planRemove, g as planSetProps, h as planStep, t as toItemSelector } from '../plan-DtNw2VuI.js';
2
+ export { C as ClipboardEntry, N as NodeClipboard, a as NodeOps, b as NodeOpsHost, c as createNodeClipboard, u as useNodeOps } from '../useNodeOps-6IAej9jy.js';
3
+ import { ReactNode } from 'react';
4
+ import { E as EditorContextMenuItem } from '../types-pGBXevBU.js';
5
+ import { N as NodeMenuWords } from '../words-DOhF-4D4.js';
6
+ import '../types-DziKCwsN.js';
7
+
8
+ /**
9
+ * nodeMenuItems — the right-click rows for a block, ONE list for both editors.
10
+ *
11
+ * The campaign designer (`blockMenuItems`) and the storefront editor
12
+ * (`nodeMenuItems`) each built their own, in the same row type and drawn by the
13
+ * same `EditorContextMenu`, and they had drifted: different group order, the
14
+ * layer flyout in a different group, Copy / Cut / Paste / Rename on one side
15
+ * only, and no pinned-block rule on the storefront. The ORDER and the GROUPS
16
+ * are decided here once:
17
+ *
18
+ * title | pick | make | style | change | remove
19
+ * pick : Select layer (when the host puts the layer flyout here)
20
+ * make : Add inside · Duplicate · Move up · Move down · Copy · Cut · Paste
21
+ * style : the host's Copy style / Paste style rows (efficient-easel/style-clipboard)
22
+ * change : Rename · Hide/Show · the layer flyout (when it goes here) · Up one level
23
+ * remove : Delete
24
+ *
25
+ * WHAT IS OFFERED IS THE HOST'S CALL, BY PRESENCE. A row appears when the host
26
+ * passes its action and is omitted when it does not — never drawn disabled,
27
+ * the rule both editors already follow. So the pinned Header and Footer, a
28
+ * locked block, a read-only campaign are all answered upstream, where the host
29
+ * knows why; a pinned block with nothing to offer gets `pinnedLine`.
30
+ *
31
+ * Every row's label, icon and shortcut can be overridden (`rows`), so each
32
+ * editor keeps its own words ("Hide from email", "Delete section") until the
33
+ * two are asked to agree. Extra host rows go into a named group (`extras`).
34
+ */
35
+
36
+ type NodeMenuRowId = 'layer' | 'addInside' | 'duplicate' | 'moveUp' | 'moveDown' | 'copy' | 'cut' | 'paste' | 'rename' | 'hide' | 'show' | 'upLevel' | 'delete';
37
+ type RowLook = Partial<Pick<EditorContextMenuItem, 'label' | 'icon' | 'shortcut' | 'danger'>> & {
38
+ /** `null` draws the row with no glyph. */
39
+ icon?: ReactNode | null;
40
+ };
41
+ interface NodeMenuOptions {
42
+ /** The menu's caption — the block's name. */
43
+ title: string;
44
+ /** The layer flyout: its entries (built by the host from the ancestor chain) and which group it sits in. */
45
+ layer?: {
46
+ items: EditorContextMenuItem[];
47
+ group?: 'pick' | 'change';
48
+ };
49
+ /** Each present action is offered; an absent one is not. */
50
+ actions: {
51
+ addInside?: () => void;
52
+ duplicate?: () => void;
53
+ moveUp?: () => void;
54
+ moveDown?: () => void;
55
+ copy?: () => void;
56
+ cut?: () => void;
57
+ /** `label` names what is held: "Paste ‹label›". */
58
+ paste?: {
59
+ label: string;
60
+ run: () => void;
61
+ };
62
+ rename?: () => void;
63
+ /** `hidden` says which of Hide / Show to offer. */
64
+ hide?: {
65
+ hidden: boolean;
66
+ run: () => void;
67
+ };
68
+ upLevel?: () => void;
69
+ delete?: () => void;
70
+ };
71
+ /** The host's style rows (styleMenuItems). Offered on pinned blocks too. */
72
+ style?: EditorContextMenuItem[];
73
+ /**
74
+ * The block cannot move or be removed: show this line when nothing else is on
75
+ * offer. It is a CAPTION, like the title — it says why the menu is short, and
76
+ * a row that looked clickable and did nothing would say the opposite.
77
+ */
78
+ pinnedLine?: string;
79
+ /** Per-row look overrides: label, icon (`null` = none), shortcut, danger. */
80
+ rows?: Partial<Record<NodeMenuRowId, RowLook>>;
81
+ /** Host rows added to the end of a group. */
82
+ extras?: Partial<Record<'pick' | 'make' | 'change' | 'remove', EditorContextMenuItem[]>>;
83
+ /**
84
+ * The rows' own words in the host's language: `useEditorStrings().menu`
85
+ * (0.95.0). Left out, English. A row's `rows` override still wins.
86
+ */
87
+ words?: NodeMenuWords;
88
+ }
89
+ declare function nodeMenuItems(options: NodeMenuOptions): EditorContextMenuItem[];
90
+
91
+ export { type NodeMenuOptions, type NodeMenuRowId, NodeMenuWords, nodeMenuItems };
@@ -0,0 +1 @@
1
+ import{DEFAULT_NODE_MENU_WORDS as e}from"../chunk-WK3AFPXY.js";export{canStep,fromItemSelector,parentStep,planDuplicate,planMove,planPaste,planRemove,planSetProps,planStep,toItemSelector,useNodeOps}from"../chunk-EFTTSIMK.js";import{TrashIcon as n,EyeIcon as t,EyeOffIcon as o,RenameIcon as p,PasteIcon as l,CopyIcon as c,MoveDownIcon as s,MoveUpIcon as a,DuplicateIcon as i,AddIcon as r,LayersIcon as u}from"../chunk-YNZZYHA4.js";import"../chunk-LPRQDDQO.js";import"../chunk-NKB3KVAB.js";import{jsx as h}from"react/jsx-runtime";function d(){let e=null;const n=/* @__PURE__ */new Set;return{get:()=>e,set(t){e=t;for(const e of[...n])e()},subscribe:e=>(n.add(e),()=>n.delete(e))}}var m={layer:{icon:/* @__PURE__ */h(u,{})},addInside:{icon:/* @__PURE__ */h(r,{})},duplicate:{icon:/* @__PURE__ */h(i,{})},moveUp:{icon:/* @__PURE__ */h(a,{})},moveDown:{icon:/* @__PURE__ */h(s,{})},copy:{icon:/* @__PURE__ */h(c,{}),shortcut:"⌘C"},cut:{icon:/* @__PURE__ */h(c,{}),shortcut:"⌘X"},paste:{icon:/* @__PURE__ */h(l,{}),shortcut:"⌘V"},rename:{icon:/* @__PURE__ */h(p,{})},hide:{icon:/* @__PURE__ */h(o,{})},show:{icon:/* @__PURE__ */h(t,{})},upLevel:{},delete:{icon:/* @__PURE__ */h(n,{}),danger:!0}};function v(n){const{actions:t,rows:o={},extras:p={},words:l=e}=n,c=e=>({...m[e],label:l[e],...o[e]}),s=(e,n,t)=>{const o=c(e),p={label:t??o.label??e,onClick:n};return o.icon&&(p.icon=o.icon),o.shortcut&&(p.shortcut=o.shortcut),o.danger&&(p.danger=!0),p},a=()=>{const e=c("layer"),t={label:e.label??l.layer,onClick:()=>{},children:n.layer.items};return e.icon&&(t.icon=e.icon),t},i=[],r=[],u=[],h=[],d=!!n.layer&&n.layer.items.length>1;if(d&&"pick"===(n.layer.group??"pick")&&i.push(a()),t.addInside&&r.push(s("addInside",t.addInside)),t.duplicate&&r.push(s("duplicate",t.duplicate)),t.moveUp&&r.push(s("moveUp",t.moveUp)),t.moveDown&&r.push(s("moveDown",t.moveDown)),t.copy&&r.push(s("copy",t.copy)),t.cut&&r.push(s("cut",t.cut)),t.paste){const e=c("paste").label??l.paste;r.push(s("paste",t.paste.run,l.pasteNamed({paste:e,label:t.paste.label})))}t.rename&&u.push(s("rename",t.rename)),t.hide&&u.push(t.hide.hidden?s("show",t.hide.run):s("hide",t.hide.run)),d&&"change"===n.layer.group&&u.push(a()),t.upLevel&&u.push(s("upLevel",t.upLevel)),t.delete&&h.push(s("delete",t.delete)),i.push(...p.pick??[]),r.push(...p.make??[]),u.push(...p.change??[]),h.push(...p.remove??[]);const v=[i,r,n.style??[],u,h].filter(e=>e.length>0),g=i.length+r.length+u.length+h.length===0,k=[{label:n.title,header:!0,onClick:()=>{}}];return g&&n.pinnedLine&&k.push({label:n.pinnedLine,header:!0,onClick:()=>{}}),v.forEach((e,t)=>{(t>0||g&&n.pinnedLine)&&k.push({label:"—",onClick:()=>{}}),k.push(...e)}),k}export{d as createNodeClipboard,v as nodeMenuItems};