efficient-easel 16.1.0 → 17.0.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 (128) hide show
  1. package/README.md +23 -64
  2. package/dist/autosave/index.d.ts +4 -4
  3. package/dist/blocks/index.d.ts +2 -2
  4. package/dist/chrome/index.d.ts +3 -3
  5. package/dist/chrome/index.js +1 -1
  6. package/dist/{chunk-UVQR7W6I.js → chunk-3ERZNZ5S.js} +1 -1
  7. package/dist/{chunk-2H3W5OLQ.js → chunk-4UBYPRAS.js} +1 -1
  8. package/dist/{chunk-ATOXCKEE.js → chunk-7TOQCTHV.js} +3 -3
  9. package/dist/chunk-BU2YSTLJ.js +14 -0
  10. package/dist/{chunk-VVPZMWJE.js → chunk-EL4F3IN7.js} +1 -1
  11. package/dist/chunk-EXCIHRAE.js +4 -0
  12. package/dist/{chunk-HV56SLR2.js → chunk-FJL3MYPA.js} +1 -1
  13. package/dist/{chunk-IE55HNMA.js → chunk-GWIVPLOX.js} +11 -11
  14. package/dist/chunk-INIPQLPR.js +1 -0
  15. package/dist/{chunk-RFSLDGDA.js → chunk-JSH3XKEF.js} +1 -1
  16. package/dist/chunk-M2Z775ZC.js +1 -0
  17. package/dist/chunk-MI54XTWD.js +5 -0
  18. package/dist/chunk-MTNBJPXX.js +2 -0
  19. package/dist/{chunk-K6EM4F5N.js → chunk-N3LYD2LK.js} +11 -11
  20. package/dist/{chunk-V6VKM2QX.js → chunk-NFLO4I2N.js} +1 -1
  21. package/dist/chunk-OLRLHE5K.js +7 -0
  22. package/dist/chunk-SHS6WCLL.js +1 -0
  23. package/dist/chunk-SPQOPWCL.js +5 -0
  24. package/dist/{chunk-TZIIRGVY.js → chunk-U277UX5I.js} +1 -1
  25. package/dist/{chunk-GPLMNRHR.js → chunk-V63ERBLW.js} +1 -1
  26. package/dist/chunk-WR3EVON3.js +57 -0
  27. package/dist/{chunk-62VPYC7F.js → chunk-XDZHKYQX.js} +1 -1
  28. package/dist/chunk-XLUVTPKK.js +1 -0
  29. package/dist/{chunk-2L2L7G5L.js → chunk-Z72CYM3L.js} +1 -1
  30. package/dist/copy/index.js +23 -11
  31. package/dist/draw/client.js +1 -1
  32. package/dist/draw/index.js +1 -1
  33. package/dist/easel/index.d.ts +35 -6
  34. package/dist/easel/index.js +1 -1
  35. package/dist/fields/index.js +1 -1
  36. package/dist/gold/gold.css +1 -1
  37. package/dist/{host-DGmdCaNL.d.ts → host-Cxbhp0zg.d.ts} +0 -4
  38. package/dist/icons/index.d.ts +0 -2
  39. package/dist/node-ops/index.d.ts +2 -2
  40. package/dist/node-ops/index.js +1 -1
  41. package/dist/panel/index.js +1 -1
  42. package/dist/{plan-CGREINRO.d.ts → plan-2BLk7pWs.d.ts} +19 -1
  43. package/dist/rail/index.d.ts +2 -2
  44. package/dist/screen/components/AddBlockRow.js +1 -1
  45. package/dist/screen/components/AddSidePanel.js +1 -1
  46. package/dist/screen/components/MediaSidePanel.d.ts +3 -3
  47. package/dist/screen/components/MediaSidePanel.js +1 -1
  48. package/dist/screen/components/NodeContextMenu.d.ts +6 -6
  49. package/dist/screen/components/NodeContextMenu.js +1 -1
  50. package/dist/screen/components/PageEditGuardNotices.js +1 -1
  51. package/dist/screen/components/SaveControls.d.ts +5 -5
  52. package/dist/screen/components/SaveControls.js +1 -1
  53. package/dist/screen/components/ScreenChrome.js +1 -1
  54. package/dist/screen/components/ScreenDocumentContext.d.ts +3 -3
  55. package/dist/screen/components/ScreenDocumentContext.js +1 -1
  56. package/dist/screen/components/ScreenMount.d.ts +5 -5
  57. package/dist/screen/components/ScreenMount.js +1 -1
  58. package/dist/screen/components/ScreenStoreProvider.d.ts +5 -5
  59. package/dist/screen/components/ScreenStoreProvider.js +1 -1
  60. package/dist/screen/components/SectionScreenShell.js +16 -16
  61. package/dist/screen/components/SidePanelHead.js +1 -1
  62. package/dist/screen/components/panel-widths.js +1 -1
  63. package/dist/screen/components/usePartBridge.d.ts +5 -5
  64. package/dist/screen/components/usePartBridge.js +1 -1
  65. package/dist/screen/index.d.ts +5 -5
  66. package/dist/screen/index.js +1 -1
  67. package/dist/screen/lib/admin-bridge.d.ts +2 -2
  68. package/dist/screen/lib/document-addressing.d.ts +3 -3
  69. package/dist/screen/lib/document-hooks.d.ts +2 -2
  70. package/dist/screen/lib/host-chrome.d.ts +0 -10
  71. package/dist/screen/lib/host.d.ts +3 -3
  72. package/dist/screen/lib/key-scope.js +1 -1
  73. package/dist/screen/lib/media-panel.d.ts +3 -3
  74. package/dist/screen/lib/media-picker.d.ts +3 -3
  75. package/dist/screen/lib/page-lock.d.ts +2 -2
  76. package/dist/screen/lib/puck/block-choice.d.ts +13 -1
  77. package/dist/screen/lib/puck/block-choice.js +1 -1
  78. package/dist/screen/lib/puck/device-fields.js +1 -1
  79. package/dist/screen/lib/puck/palette-sections.d.ts +2 -2
  80. package/dist/screen/lib/puck/section-doc.d.ts +2 -2
  81. package/dist/screen/lib/puck/style-clipboard.d.ts +5 -5
  82. package/dist/screen/lib/puck/style-clipboard.js +1 -1
  83. package/dist/screen/lib/puck/use-section-ops.d.ts +2 -2
  84. package/dist/screen/lib/puck/use-section-ops.js +1 -1
  85. package/dist/screen/lib/save-status.d.ts +2 -2
  86. package/dist/screen/lib/screen-parts.d.ts +5 -27
  87. package/dist/screen/lib/screen-parts.js +1 -1
  88. package/dist/screen/lib/section-templates.d.ts +2 -2
  89. package/dist/screen/lib/session-context.d.ts +2 -2
  90. package/dist/screen/lib/session.d.ts +2 -2
  91. package/dist/screen/words.d.ts +0 -2
  92. package/dist/screen/words.js +1 -1
  93. package/dist/shell/shell.css +6 -1
  94. package/dist/strings/index.d.ts +134 -20
  95. package/dist/strings/index.js +2 -2
  96. package/dist/text-styles/index.js +26 -26
  97. package/dist/{types-CsgMwHHa.d.ts → types-Cy7rdmXt.d.ts} +1 -1
  98. package/dist/{types-DGyDHiJV.d.ts → types-DT8ywrFQ.d.ts} +1 -1
  99. package/dist/{types-NQozKWEz.d.ts → types-kR_4wYBw.d.ts} +1 -1
  100. package/dist/{useNodeOps-BHRkUFfG.d.ts → useNodeOps-B0XZ8Bl8.d.ts} +1 -1
  101. package/dist/{words-pgIK0I6g.d.ts → words-DkWcK1rh.d.ts} +2 -2
  102. package/package.json +2 -41
  103. package/dist/chunk-44COUKXO.js +0 -5
  104. package/dist/chunk-4BGYVIDQ.js +0 -57
  105. package/dist/chunk-ECM5F6JJ.js +0 -1
  106. package/dist/chunk-H4UMY7QF.js +0 -13
  107. package/dist/chunk-HMXIAMCU.js +0 -1
  108. package/dist/chunk-HQ4VVRIC.js +0 -1
  109. package/dist/chunk-IN22IYOM.js +0 -1
  110. package/dist/chunk-JQOYUH4A.js +0 -7
  111. package/dist/chunk-L2VGRQ4R.js +0 -4
  112. package/dist/chunk-L3GSW4XI.js +0 -1
  113. package/dist/chunk-QX7GVECM.js +0 -13
  114. package/dist/chunk-U25CP5VX.js +0 -5
  115. package/dist/chunk-XQGV2XAK.js +0 -1
  116. package/dist/chunk-ZZ64CEC2.js +0 -2
  117. package/dist/gold/index.d.ts +0 -283
  118. package/dist/gold/index.js +0 -1
  119. package/dist/icons/meanings.d.ts +0 -1
  120. package/dist/icons/meanings.js +0 -1
  121. package/dist/index.d.ts +0 -6
  122. package/dist/index.js +0 -1
  123. package/dist/markup/index.d.ts +0 -1
  124. package/dist/markup/index.js +0 -1
  125. package/dist/shell/index.d.ts +0 -195
  126. package/dist/shell/index.js +0 -1
  127. package/dist/strings/catalogue.d.ts +0 -139
  128. package/dist/strings/catalogue.js +0 -1
@@ -1,283 +0,0 @@
1
- import * as react from 'react';
2
- import { Ref } from 'react';
3
- import { InlineRule, InlineKind } from 'efficient-shell/markup';
4
-
5
- /**
6
- * The type-in-place box: a controlled leaf, and NOTHING else.
7
- *
8
- * It holds no string of its own, knows no document, and performs no write. The
9
- * host owns the value and decides what a commit means — which is what lets the
10
- * same component serve the storefront editor and the campaign designer without
11
- * either one leaking into it.
12
- */
13
- interface GoldTextInputProps {
14
- /** The authored string, delimiters and all. The single source of truth. */
15
- value: string;
16
- /**
17
- * Every keystroke. The layer repaints from what the host sends back, so a host
18
- * that drops this on the floor gets a box that does not type — deliberately:
19
- * one value, one owner.
20
- */
21
- onInput: (value: string) => void;
22
- /**
23
- * The edit is finished and may be written: on blur, and on Enter when
24
- * {@link multiline} is false. Fires ONCE per editing session, and never at all
25
- * if nothing was typed — clicking into a part and back out must not dirty the
26
- * page (owner ruling 6), and one session is one undo step (ruling 2).
27
- */
28
- onCommit?: (value: string) => void;
29
- /**
30
- * Escape. The argument is the value the component was given when it gained
31
- * focus; the HOST puts it back, because the host owns the string. After a
32
- * cancel the pending edit is forgotten, so the blur that follows writes
33
- * nothing.
34
- */
35
- onCancel?: (restored: string) => void;
36
- /**
37
- * What Enter means — NOT how the text wraps. Both modes soft-wrap exactly as
38
- * the box does, because the layer under it has to wrap identically.
39
- *
40
- * - `false` (default): Enter commits and never inserts a newline;
41
- * - `true`: Enter inserts a newline and commits nothing.
42
- */
43
- multiline?: boolean;
44
- /** Shown while the value is empty — through the first focus, and away on the
45
- * first keystroke. */
46
- placeholder?: string;
47
- /** Extra class(es) merged onto the wrapper. */
48
- className?: string;
49
- /**
50
- * The grammar's rule set — `STOREFRONT_MARKUP` in the shop,
51
- * `CAMPAIGN_MARKUP` in the campaign designer, both from
52
- * `efficient-shell/markup`. Defaults to `STANDARD_MARKUP`, which is the subset
53
- * every product shares; a product with legacy runs (the storefront's
54
- * `*phrase*` accent) MUST pass its own set or those runs draw as plain text
55
- * here while the page paints them gold.
56
- */
57
- rules?: readonly InlineRule[];
58
- /** Accessible name for the box. In-place editing has no visible label. */
59
- ariaLabel?: string;
60
- /**
61
- * Nothing may be typed. The box goes out of the tab order and announces the
62
- * state itself, rather than a parent dimming a control that is still
63
- * focusable — the regression the 2026-08-06 audit closed.
64
- *
65
- * The LAYER still paints, deliberately: a sent campaign opens read-only, and
66
- * a merchant reading it should see their own formatting, not raw delimiters.
67
- */
68
- disabled?: boolean;
69
- /**
70
- * A handle on the textarea.
71
- *
72
- * A plain prop rather than `ref`, for the same reason {@link GoldLayerProps}
73
- * gives for `layerRef`: React 18 would need `forwardRef` and React 19 takes
74
- * `ref` as an ordinary prop, and this package supports both.
75
- *
76
- * It exists because a caret operation — a mark button, an inserted merge tag —
77
- * has to read the live selection off this element and put it back after the
78
- * repaint. `efficient-easel/copy` is the caller that does that.
79
- */
80
- inputRef?: Ref<HTMLTextAreaElement>;
81
- }
82
- interface GoldLayerProps {
83
- value: string;
84
- rules?: readonly InlineRule[];
85
- className?: string;
86
- /**
87
- * A handle on the layer element.
88
- *
89
- * A plain prop rather than `ref` on purpose: React 18 would need
90
- * `forwardRef` and React 19 takes `ref` as an ordinary prop, and this package
91
- * supports both (`peerDependencies: react >=18`). One named prop behaves
92
- * identically on either and needs no version branch.
93
- */
94
- layerRef?: Ref<HTMLDivElement>;
95
- }
96
-
97
- /**
98
- * Type where the text sits, and watch the gold appear as you type.
99
- *
100
- * The arrangement, in one paragraph: a textarea whose own text is TRANSPARENT
101
- * sits on top of a layer holding the same characters, painted. What you read is
102
- * the layer; what the caret walks is the box. Both take their type styles from
103
- * whatever the host renders them inside (`font: inherit` all the way down), so
104
- * the glyphs land on top of each other instead of near each other, and the box
105
- * inherits the page's own type rather than a size this package invented.
106
- *
107
- * The layer is the element IN FLOW and the box is absolutely positioned over it,
108
- * which is deliberate: the layer holds the same characters, so it wraps to the
109
- * same height, so the box grows as the merchant types without anyone measuring
110
- * anything.
111
- *
112
- * WHAT IT DOES NOT DO: write. It has no document, no section, no Puck, no shop.
113
- * `onCommit` says "this edit is finished"; what that means is the host's
114
- * business. That is what makes it shareable by both editors (constitution E2)
115
- * and testable without any of them.
116
- *
117
- * No `'use client'` — same reason as the rail: the directive is the HOST's to
118
- * place, and both editors' chrome are already client components. Unlike the
119
- * rail, though, this leaf has hooks, so it must be rendered inside that client
120
- * boundary; a server component can import the module but cannot render it.
121
- *
122
- * Requires `efficient-easel/gold.css`, imported once from a client entry.
123
- */
124
- declare function GoldTextInput({ value, onInput, onCommit, onCancel, multiline, placeholder, className, rules, ariaLabel, disabled, inputRef, }: GoldTextInputProps): react.JSX.Element;
125
-
126
- /**
127
- * The formatted text, drawn UNDER the box.
128
- *
129
- * It is a MARKER layer, not a preview of the page. That distinction is the whole
130
- * design, and it is why a bold run here is not drawn at weight 600:
131
- *
132
- * the caret, the selection and the line breaks all come from the transparent
133
- * textarea on top, which has ONE font. A heavier or slanted face down here is
134
- * wider, so a marked line would wrap a word earlier than the box does and
135
- * every line after it would sit on top of the wrong text.
136
- *
137
- * So the layer may only paint what cannot move a glyph — colour, opacity,
138
- * text-decoration, a shadow. A merchant sees WHERE the formatting starts and
139
- * ends and in which colour it will land; the real weight and slant appear on the
140
- * page the moment they click away. Full WYSIWYG (asterisks gone, real faces) is
141
- * a second text engine and is deliberately out of scope — see
142
- * docs/agents/text-and-grammar.md, gold rule 2.
143
- *
144
- * The elements mirror the storefront's own renderer (`goldPhrases.tsx`):
145
- * `<strong>` for bold, `<em>` for italic and for the gold accent, `<s>` for
146
- * struck-out. The classes carry the paint; the tokens carry the values.
147
- */
148
- declare function GoldLayer({ value, rules, className, layerRef }: GoldLayerProps): react.JSX.Element;
149
-
150
- /**
151
- * Cutting an authored string into the pieces the layer paints — WITHOUT losing a
152
- * character.
153
- *
154
- * The grammar is not re-implemented here and never will be (constitution E8):
155
- * {@link tokenizeInline} from `efficient-shell/markup` decides what is a run and
156
- * what is not, exactly as it does for the published page. What it does not
157
- * return is the delimiters — it hands back a run's INNER text, because every
158
- * other consumer wants the words without the asterisks.
159
- *
160
- * This layer wants the asterisks. It draws underneath a transparent box whose
161
- * caret walks the stored string, so the two surfaces must hold the same
162
- * characters in the same order: drop the `**` and every glyph after it sits two
163
- * columns left of the caret that is supposed to be inside it.
164
- *
165
- * So each parsed run is located back in the source and cut into three pieces —
166
- * opening delimiter, inner text, closing delimiter — and EVERY piece is sliced
167
- * out of the original string rather than rebuilt from the token. Nothing is
168
- * retyped, so nothing can be retyped wrong.
169
- */
170
- /** A piece of the source: a parsed run's kind, or the delimiters around one. */
171
- type GoldSegmentKind = InlineKind | 'delimiter';
172
- interface GoldSegment {
173
- kind: GoldSegmentKind;
174
- /** Verbatim source text. Concatenating every segment reproduces the input. */
175
- text: string;
176
- }
177
- /**
178
- * Split `value` into paint-able segments under `rules`.
179
- *
180
- * GUARANTEE: `segments.map(s => s.text).join('') === value`, always. If the walk
181
- * below cannot line a run up with the rule that produced it — which would mean
182
- * the grammar and this function disagree — the whole string comes back as one
183
- * plain `text` segment. Losing the gold is a disappointment; losing a character
184
- * puts the caret in the wrong place, so the fallback is never in doubt.
185
- */
186
- declare function goldSegments(value: string, rules: readonly InlineRule[]): GoldSegment[];
187
-
188
- /**
189
- * Gold-layer paint tokens.
190
- *
191
- * SHORT LIST BY DESIGN. The layer draws inside whatever the host renders it in
192
- * and inherits that context's type entirely — family, size, weight, line-height,
193
- * letter-spacing — because it has to sit on top of a box that inherits the same
194
- * (see `GoldTextInput`). So there is no type here to tokenise; what is left is
195
- * the paint, and only the paint that cannot move a glyph.
196
- *
197
- * NOTHING HERE IS INVENTED (docs/agents/leaves-and-tokens.md, "the tokens are
198
- * not ours to invent"):
199
- * - the gold defers to the page's own `--gold`, falling back to the
200
- * storefront's light-theme value (`efficient-storefront/app/globals.css` → `--gold:
201
- * #c9a461`), so the mark in the box matches the mark on the page;
202
- * - the caret and the placeholder defer to the shell layer's `--es-text` /
203
- * `--es-field-placeholder` (see `shell/tokens.ts`), falling back to the
204
- * efficient-shell tokens those resolve to (UI-24), for a box drawn outside
205
- * an `.es-editor` root;
206
- * - the FOCUSED dim is the rail's existing disabled opacity (0.35), not a new
207
- * number. Its RESTING sibling (0.25) is the one value in this file picked by
208
- * eye rather than borrowed: nothing else in the product paints a mark that
209
- * has to hold its width while it stops being read, so there was nothing to
210
- * copy. The owner chose it against a picker rendering the candidates at
211
- * heading and body size; 0.18 was tried there first and still read too
212
- * faint (card 8807). That history is here on purpose: a later reader who
213
- * finds 0.25 with nothing behind it will "fix" it to match some other
214
- * number, and this is the paragraph that stops them.
215
- *
216
- * Every value is a STRING, unlike the rail's and shell's pixel magnitudes:
217
- * none of these is a length, so nothing here gains a unit on the way into CSS.
218
- *
219
- * Exposed BOTH ways, per the same value: `goldTokens` (this object) and
220
- * `gold.css` (the stylesheet, which declares them on `.es-gold` — names in
221
- * {@link goldCssVars}). The parity gate in `tests/gold-leaf-safety.test.ts`
222
- * proves the two never drift.
223
- */
224
- declare const goldTokens: {
225
- /** The mark colour — `==phrase==` and the legacy `*phrase*`. */
226
- readonly accent: "var(--gold, #c9a461)";
227
- /** Quiet — `^^phrase^^`. Colour only: the page draws it smaller, but a
228
- * smaller glyph down here would pull the layer off the caret. */
229
- readonly quiet: "var(--es-muted, var(--ink-faint))";
230
- /** The caret. Set explicitly because the box's own text is transparent, and
231
- * `caret-color: auto` would make the caret transparent with it. */
232
- readonly caret: "var(--es-text, var(--ink-strongest))";
233
- /** The hint shown while the value is empty. */
234
- readonly placeholder: "var(--es-field-placeholder, var(--ink-faintest))";
235
- /** How far the asterisks are dimmed WHILE THE BOX HAS FOCUS — the moment they
236
- * are what the merchant is aiming at, so this is the louder of the pair.
237
- * Out of focus they drop to {@link goldTokens.delimiterRestingOpacity}. */
238
- readonly delimiterOpacity: "0.35";
239
- /** How far they are dimmed AT REST, when nobody is typing (card 8807). A
240
- * whisper, and deliberately not 0.
241
- *
242
- * FADED, never removed: the characters stay in the layer at their full width
243
- * in BOTH states, which is the deal — anything that took them out would move
244
- * a glyph. So the width is spent either way, and 0 spends it with nothing to
245
- * show for it: a short, heavily marked string loses about a quarter of its
246
- * line to blanks that read as a rendering bug. Faint, the same space reads as
247
- * punctuation. */
248
- readonly delimiterRestingOpacity: "0.25";
249
- /**
250
- * Faux-bold. A real `font-weight: 600` is wider, and a wider run down here
251
- * wraps a line earlier than the transparent box on top of it — after which
252
- * every following line is drawn over the wrong text. The shadow reads heavier
253
- * and moves nothing.
254
- */
255
- readonly boldShadow: "0 0 0.4px currentColor";
256
- /** Italic, marked rather than slanted — an italic FACE has its own widths, and
257
- * the layer may not change a glyph's advance. Same reason as the bold. */
258
- readonly italicDecoration: "underline dotted";
259
- /** Strike-through is metric-safe, so it is drawn exactly as it will print. */
260
- readonly strikeDecoration: "line-through";
261
- /**
262
- * The field's inner inset, applied to the LAYER, the BOX and the
263
- * PLACEHOLDER together — never to the wrapper.
264
- *
265
- * ⚠️ ZERO IS THE ONLY SAFE DEFAULT AND A HOST MUST NOT PAD `.es-gold`.
266
- * The box is `position: absolute; inset: 0`, which resolves to the
267
- * wrapper's PADDING box, while the layer is in flow and starts at its
268
- * CONTENT box — so padding the wrapper moves the glyphs and leaves the
269
- * caret behind. That shipped: `.es-copy-box` padded the wrapper and every
270
- * character sat 6px right of its caret and 4px down (reported 2026-09-26).
271
- * A host that wants an inset sets this token.
272
- */
273
- readonly pad: "0";
274
- };
275
- type GoldTokens = typeof goldTokens;
276
- /**
277
- * The CSS custom-property name behind each token. `gold.css` sets these on
278
- * `.es-gold`, so overriding one on (or above) the box re-themes it without
279
- * shipping new CSS — e.g. `style={{ ['--es-gold-accent']: brand }}`.
280
- */
281
- declare const goldCssVars: Record<keyof GoldTokens, string>;
282
-
283
- export { GoldLayer, type GoldLayerProps, type GoldSegment, type GoldSegmentKind, GoldTextInput, type GoldTextInputProps, type GoldTokens, goldCssVars, goldSegments, goldTokens };
@@ -1 +0,0 @@
1
- export{GoldLayer,GoldTextInput,goldSegments}from"../chunk-H4UMY7QF.js";var e={accent:"var(--gold, #c9a461)",quiet:"var(--es-muted, var(--ink-faint))",caret:"var(--es-text, var(--ink-strongest))",placeholder:"var(--es-field-placeholder, var(--ink-faintest))",delimiterOpacity:"0.35",delimiterRestingOpacity:"0.25",boldShadow:"0 0 0.4px currentColor",italicDecoration:"underline dotted",strikeDecoration:"line-through",pad:"0"},t={accent:"--es-gold-accent",quiet:"--es-gold-quiet",caret:"--es-gold-caret",placeholder:"--es-gold-placeholder",delimiterOpacity:"--es-gold-delim-opacity",delimiterRestingOpacity:"--es-gold-delim-resting-opacity",boldShadow:"--es-gold-bold-shadow",italicDecoration:"--es-gold-italic-decoration",strikeDecoration:"--es-gold-strike-decoration",pad:"--es-gold-pad"};export{t as goldCssVars,e as goldTokens};
@@ -1 +0,0 @@
1
- export { efficientIconMeanings as iconMeanings } from 'efficient-shell/icons/efficient-meanings';
@@ -1 +0,0 @@
1
- export{efficientIconMeanings as iconMeanings}from"efficient-shell/icons/efficient-meanings";
package/dist/index.d.ts DELETED
@@ -1,6 +0,0 @@
1
- export { EaselRail, EaselRailButton, RailTokens, railCssVars, railTokens } from './rail/index.js';
2
- export { AddIcon, LayersIcon, MediaIcon, PageIcon as PagesIcon, EfficientIconProps as RailIconProps, SitemapIcon, StylesIcon } from 'efficient-shell/icons/efficient';
3
- export { W as WordFit } from './wordFit-7XpmhcaW.js';
4
- export { E as EaselRailButtonProps, a as EaselRailItem, b as EaselRailOrientation, c as EaselRailProps } from './types-CsgMwHHa.js';
5
- export { SPACING_SCALE, ShellTokens, shellCssVars, shellDarkTokens, shellTokens } from './shell/index.js';
6
- import 'react';
package/dist/index.js DELETED
@@ -1 +0,0 @@
1
- export{SPACING_SCALE,shellCssVars,shellDarkTokens,shellTokens}from"./chunk-HMXIAMCU.js";export{AddIcon,LayersIcon,MediaIcon,PageIcon as PagesIcon,SitemapIcon,StylesIcon,railCssVars,railTokens}from"./chunk-4VJATVVR.js";export{EaselRail,EaselRailButton}from"./chunk-MJM6SFD3.js";import"./chunk-2OAZYSWJ.js";
@@ -1 +0,0 @@
1
- export * from 'efficient-shell/markup';
@@ -1 +0,0 @@
1
- export*from"efficient-shell/markup";
@@ -1,195 +0,0 @@
1
- /**
2
- * Editor SHELL design tokens — the chrome's names for efficient-shell's tokens.
3
- *
4
- * Where `rail/tokens.ts` owns the slim icon-rail, this owns the rest of the
5
- * editor chrome theme: accent, surfaces, fields, text, lines, chips, named
6
- * chrome literals, danger/warning/success, radii, gap, shadows and font.
7
- *
8
- * NOTHING HERE IS A VALUE OF OUR OWN (harness UI-24, efficient-harness#117):
9
- * every colour, radius and the typeface is a `var()` of an efficient-shell
10
- * token (`efficient-shell/ui.css`), or — where the shell has no token for the
11
- * role yet, marked SHELL GAP below — a `color-mix()` of shell tokens. Up to
12
- * 0.106.0 these were hex values mirrored from the storefront editor's `--sf-*`
13
- * block, light only; now the editor follows the shell's theme, dark included,
14
- * and its accent themes. The one literal colour is `frameBg`, which is canvas
15
- * (the page's paper), not chrome.
16
- *
17
- * Exposed BOTH ways, per the same value (mirrors the rail):
18
- * - `shellTokens` — this JS object, for code that needs the values in an
19
- * inline style (they are CSS expressions, so they resolve only where the
20
- * host has loaded the shell's CSS — which it must, see README);
21
- * - `shell.css` — the stylesheet, which declares the identical values as CSS
22
- * custom properties on `.es-editor` (names listed in `shellCssVars`).
23
- *
24
- * Numeric fields are pixel magnitudes (unitless) so they compose in code; the
25
- * CSS applies the `px`. Only spacing is numeric now.
26
- */
27
- declare const shellTokens: {
28
- /** `--es-accent` — the custom accent (`--accent-600`, stamped by the shell's
29
- * `useTheme()`), else the shell's themed primary fill (`--submit-bg`, which
30
- * the pink / green / grey themes remap). */
31
- readonly accent: "var(--accent-600, var(--submit-bg))";
32
- /** `--es-accent-tint` — a wash of the accent on the surface. SHELL GAP: the
33
- * shell has no accent-soft token; mixed from shell tokens until it does. */
34
- readonly accentTint: "color-mix(in srgb, var(--es-accent) 10%, var(--surface))";
35
- /** `--es-accent-tint-strong` — a stronger wash. SHELL GAP, as above. */
36
- readonly accentTintStrong: "color-mix(in srgb, var(--es-accent) 18%, var(--surface))";
37
- /** `--es-accent-line` — a quiet accent hairline (an empty slot's outline). SHELL GAP. */
38
- readonly accentLine: "color-mix(in srgb, var(--es-accent) 32%, var(--surface))";
39
- /** `--es-accent-text` — accent as words: darker than the fill on light,
40
- * lighter on dark, because it leans on the ramp's strongest ink. SHELL GAP. */
41
- readonly accentText: "color-mix(in srgb, var(--es-accent) 65%, var(--ink-strongest))";
42
- /** `--es-accent-ring` — the shell's focus ring wash. */
43
- readonly accentRing: "var(--rosh-focus-ring)";
44
- /** `--es-accent-shadow` — accent button shadow. SHELL GAP. */
45
- readonly accentShadow: "color-mix(in srgb, var(--es-accent) 35%, transparent)";
46
- /** `--es-on-accent` — ink on a solid fill. SHELL GAP: the shell's nearest is
47
- * the status tier's `--status-on-solid` (white in both themes). */
48
- readonly onAccent: "var(--status-on-solid)";
49
- /** `--es-app-bg` — the sunken ground behind the panels. */
50
- readonly appBg: "var(--surface-sunken)";
51
- /** `--es-preview-bg` — the well round the canvas. */
52
- readonly previewBg: "var(--surface-raised)";
53
- /** `--es-panel` — panels. */
54
- readonly panel: "var(--surface)";
55
- /** `--es-raised` — a lifted surface. NOT the active chip since card 66302. */
56
- readonly raised: "var(--surface)";
57
- /** `--es-topbar-bg`. */
58
- readonly topbarBg: "var(--surface)";
59
- /** `--es-frame-bg` — the paper behind the preview iframe. CANVAS, not chrome:
60
- * it is the page's own white in every theme (UI-24 leaves output alone). */
61
- readonly frameBg: "#ffffff";
62
- /** `--es-hover` — row / icon hover. */
63
- readonly hover: "var(--surface-raised)";
64
- /** `--es-hatch` — 45° upload-slot texture. */
65
- readonly hatch: "color-mix(in srgb, var(--ink-strongest) 2%, transparent)";
66
- /** `--es-addcard-veil` — add-section card hover wash. */
67
- readonly addcardVeil: "color-mix(in srgb, var(--surface-sunken) 66%, transparent)";
68
- /** `--es-field-bg`. */
69
- readonly fieldBg: "var(--surface)";
70
- /** `--es-track-bg` — segmented / search track. */
71
- readonly trackBg: "var(--surface-raised)";
72
- /** `--es-input-border`. */
73
- readonly inputBorder: "var(--line-strong)";
74
- /** `--es-field-text`. */
75
- readonly fieldText: "var(--ink-strong)";
76
- /** `--es-field-placeholder`. */
77
- readonly fieldPlaceholder: "var(--ink-faintest)";
78
- /** `--es-knob` — toggle knob (the shell's Switch draws it `bg-white`, which
79
- * its dark theme turns into `--surface`). */
80
- readonly knob: "var(--surface)";
81
- /** `--es-text`. */
82
- readonly text: "var(--ink-strongest)";
83
- /** `--es-text-strong` — active labels (the ramp has nothing past strongest). */
84
- readonly textStrong: "var(--ink-strongest)";
85
- /** `--es-text-secondary`. */
86
- readonly textSecondary: "var(--ink)";
87
- /** `--es-muted`. */
88
- readonly muted: "var(--ink-faint)";
89
- /** `--es-icon` — icon buttons. */
90
- readonly icon: "var(--ink-faint)";
91
- /** `--es-disabled` — disabled / faint glyphs. */
92
- readonly disabled: "var(--ink-faintest)";
93
- /** `--es-divider`. */
94
- readonly divider: "var(--line)";
95
- /** `--es-line` — hairlines. */
96
- readonly line: "var(--line)";
97
- /** `--es-btn-border`. */
98
- readonly btnBorder: "var(--line-strong)";
99
- /** `--es-btn-text`. */
100
- readonly btnText: "var(--ink)";
101
- /** `--es-chip-bg`. */
102
- readonly chipBg: "var(--surface-raised)";
103
- /** `--es-chip-fg`. */
104
- readonly chipFg: "var(--ink-faint)";
105
- /** `--es-brand-square` — wordmark square. */
106
- readonly brandSquare: "var(--ink-strongest)";
107
- /** `--es-device-border` — tablet/mobile frame. */
108
- readonly deviceBorder: "var(--line)";
109
- /** `--es-toast-bg` — dark chip / seam pill, white ink on it in both themes:
110
- * the shell's solid status tier (`--status-draft-solid`, 10.3:1 with white). */
111
- readonly toastBg: "var(--status-draft-solid)";
112
- /** `--es-toggle-off` — toggle track (the shell's Switch: `bg-gray-300`). */
113
- readonly toggleOff: "var(--line-strong)";
114
- /** `--es-scrollbar`. */
115
- readonly scrollbar: "var(--line-strong)";
116
- /** `--es-scrollbar-hover`. */
117
- readonly scrollbarHover: "var(--ink-faintest)";
118
- /** `--es-danger` — danger words and edges: the status tier's ink, which
119
- * clears AA on the surface and on its own wash, light and dark. */
120
- readonly danger: "var(--status-danger-soft-ink)";
121
- /** `--es-danger-strong` — danger words on `--es-danger-tint`. */
122
- readonly dangerStrong: "var(--status-danger-soft-ink)";
123
- /** `--es-danger-tint` — the danger wash. */
124
- readonly dangerTint: "var(--status-danger-soft)";
125
- /** `--es-warning` — the "Preview" pill's words and edge (amber: pending). */
126
- readonly warning: "var(--status-pending-soft-ink)";
127
- /** `--es-preview-tint` — the "Preview" pill's wash. */
128
- readonly previewTint: "var(--status-pending-soft)";
129
- /** `--es-success` — a green tick and its label. */
130
- readonly success: "var(--status-success-soft-ink)";
131
- /** `--es-panel-radius` — 12px, `--radius-xl`. */
132
- readonly panelRadius: "var(--radius-xl)";
133
- /** `--es-row-radius` — the shell's card radius (`--radius-card`, 8px by default). */
134
- readonly rowRadius: "var(--radius-card, var(--radius-lg))";
135
- /** `--es-field-radius` — the shell's control radius (`--radius-control`, 6px by default). */
136
- readonly fieldRadius: "var(--radius-control, var(--radius-md))";
137
- /** `--es-panel-gap` — inter-pane gutter + outer frame padding, ONE token.
138
- * 12 since the one spacing scale (was 10, which is not a step). */
139
- readonly panelGap: 12;
140
- /** `--es-space-2` — between the buttons of one group (B · I · U · S). */
141
- readonly space2: 2;
142
- /** `--es-space-4` — a sub-name to its control; between the cells of one group. */
143
- readonly space4: 4;
144
- /** `--es-space-8` — between the layers of ONE setting (bar → box → Show marks). */
145
- readonly space8: 8;
146
- /** `--es-space-12` — between rows under one heading; inside one setting;
147
- * the panel's padding when it is narrower than 260px. */
148
- readonly space12: 12;
149
- /** `--es-space-16` — the panel's own padding. */
150
- readonly space16: 16;
151
- /** `--es-space-32` — between two settings. */
152
- readonly space32: 32;
153
- /** `--es-panel-shadow`. */
154
- readonly panelShadow: "0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06)";
155
- /** `--es-topbar-shadow`. */
156
- readonly topbarShadow: "0 1px 3px rgba(0, 0, 0, 0.06)";
157
- /**
158
- * `--es-raised-shadow` — what a small surface sitting ON another one casts:
159
- * the chip in the settings tab strip's track (card 66138). Tighter and darker
160
- * than `panelShadow`, which is a whole panel floating over the app; this one
161
- * has to read across 3px of track without looking like a second panel.
162
- */
163
- readonly raisedShadow: "0 1px 2px rgba(16, 24, 40, 0.1)";
164
- /** `--es-font` — the shell's face. */
165
- readonly font: "var(--font-sans)";
166
- };
167
- type ShellTokens = typeof shellTokens;
168
- /**
169
- * The tokens `shell.css` re-points under the shell's dark theme
170
- * (`:is([data-theme="dark"], .dark) .es-editor`). Shell tokens only: the shell
171
- * draws a track and a chip's ground with `bg-gray-100`, and its dark theme
172
- * remaps that utility to `--surface` rather than `--surface-raised`, so these
173
- * three follow it. Code that reads `shellTokens` for an inline style under a
174
- * dark shell reads these over it.
175
- */
176
- declare const shellDarkTokens: {
177
- readonly previewBg: "var(--surface)";
178
- readonly trackBg: "var(--surface)";
179
- readonly chipBg: "var(--surface)";
180
- };
181
- /**
182
- * The one spacing scale, smallest first (owner ruling, 2026-10-02): the six
183
- * `space*` tokens above as a list, for code that must snap a number to it.
184
- * A seventh step is a new ruling, not a new entry.
185
- */
186
- declare const SPACING_SCALE: readonly [2, 4, 8, 12, 16, 32];
187
- /**
188
- * The CSS custom-property name behind each `shellTokens` key. `shell.css` sets
189
- * these on `.es-editor`; override any of them on (or above) the editor root to
190
- * re-theme without shipping new CSS. The `shell-tokens.test.ts` parity gate
191
- * proves this map, `shellTokens` and `shell.css` never drift apart.
192
- */
193
- declare const shellCssVars: Record<keyof ShellTokens, string>;
194
-
195
- export { SPACING_SCALE, type ShellTokens, shellCssVars, shellDarkTokens, shellTokens };
@@ -1 +0,0 @@
1
- export{SPACING_SCALE,shellCssVars,shellDarkTokens,shellTokens}from"../chunk-HMXIAMCU.js";
@@ -1,139 +0,0 @@
1
- import { S as SaveWords } from '../words-pgIK0I6g.js';
2
- import { N as NoticeWords, C as ChromeWords } from '../words-BpiVrsW5.js';
3
- import { C as CopyWords } from '../words-D-yhjdOg.js';
4
- import { D as DragWords } from '../words-CvwYvkJm.js';
5
- import { LockWords } from '../edit-lock/index.js';
6
- import { F as FieldsWords } from '../words-vhnV8sM7.js';
7
- import { N as NodeMenuWords } from '../words-DMG4dYq2.js';
8
- import { P as PanelWords } from '../words-zH1H0WFw.js';
9
- import { P as PickWords } from '../words-DWvCJXwR.js';
10
- import { ScreenWords } from '../screen/words.js';
11
- export { ScreenAddWords } from '../screen/words.js';
12
- import { S as StyleClipboardWords } from '../words-CnnHb9jo.js';
13
- import { T as TextStylesWords } from '../words-gIDCeRv3.js';
14
- import { T as TreeWords } from '../words-Cl9xMUYY.js';
15
- import '../types-DGyDHiJV.js';
16
- import '../types-CsgMwHHa.js';
17
- import '../wordFit-7XpmhcaW.js';
18
- import 'react';
19
- import '../panelWidths-D9hTLR25.js';
20
- import '../engine-CvXpFE86.js';
21
- import 'efficient-shell/markup';
22
- import '../buckets-Tj-nkBpg.js';
23
-
24
- /**
25
- * The easel canvas's own words (`efficient-easel/strings`, 0.95.0): what the
26
- * frame is called when the host does not name it (`title`), and the name of
27
- * the bar of text tools that floats above words typed on the canvas.
28
- *
29
- * A plain module with no import.
30
- */
31
- type CanvasWords = {
32
- /** The canvas frame's accessible name. */
33
- frame: string;
34
- /** The floating bar of text tools over the words being typed (its group's name). */
35
- textTools: string;
36
- };
37
-
38
- /**
39
- * The rail's own words. There is one: what the toolbar is called when the host
40
- * does not name it (`ariaLabel`). Every other word on the rail is an item's
41
- * `label`, and those are the host's.
42
- *
43
- * A plain module with no import, so the rail stays the leaf it is
44
- * (`tests/rail-leaf-safety.test.tsx`). It is NOT exported from `./index`: the
45
- * rail's runtime exports are pinned (`tests/rail-public-shape.test.tsx`), and a
46
- * host reads these through `efficient-easel/strings`.
47
- */
48
- type RailWords = {
49
- /** The toolbar's accessible name. */
50
- label: string;
51
- };
52
-
53
- /**
54
- * THE ENGINE'S OWN WORDS, as one catalogue a host can translate (0.95.0).
55
- *
56
- * Every word and sentence this package itself draws or returns — visible text,
57
- * `aria-label`s, tooltips, placeholders — is an entry here, grouped by the
58
- * module that says it. What a HOST supplies (a block's name, a field's label, a
59
- * tile's caption, the document's noun) was never the engine's and is not here —
60
- * with one exception: the assembled screen (`efficient-easel/screen`) draws the
61
- * edit notice itself, so the noun it says it with is a word of its own group,
62
- * the website's "page" until a host says another.
63
- *
64
- * - A plain word is a `string`.
65
- * - Anything with a value in it, or a count that can be one or many, is a
66
- * function: the host puts the value where its language wants it and does
67
- * its own plural.
68
- *
69
- * ── Where the English lives ───────────────────────────────────────────────
70
- * In each module's own `words.ts`, NOT here. A leaf may only import its own
71
- * lane (`tests/*-leaf-safety`), and several are held to a bundle that never
72
- * spells a browser global — while one sentence below does ("another tab or
73
- * window"). So a module owns its group and its defaults, and this file only
74
- * puts the groups side by side. `DEFAULT_EASEL_STRINGS.pick` IS the pickers'
75
- * own default object, not a copy of it.
76
- *
77
- * ── Framework-free ────────────────────────────────────────────────────────
78
- * No React, no browser global, nothing run at import but object literals
79
- * (`tests/strings-leaf-safety.test.ts`). A server-side test in a host imports
80
- * this to check its own catalogues against the engine's keys; it is published
81
- * on its own as `efficient-easel/strings/catalogue`. The provider and the
82
- * hooks are in ./provider.
83
- */
84
-
85
- /** Every word the engine says, by the module that says it. */
86
- interface EaselStrings {
87
- /** `efficient-easel/chrome` — `EditNotice`: who holds the document, a refused save. */
88
- notice: NoticeWords;
89
- /** `efficient-easel/edit-lock` — "2 minutes ago", "Someone else". */
90
- lock: LockWords;
91
- /** `efficient-easel/autosave` — the save pill. */
92
- save: SaveWords;
93
- /** `efficient-easel/chrome` — the device switch, "up one level", the panel grip. */
94
- chrome: ChromeWords;
95
- /** `efficient-easel/rail` — the toolbar's name. */
96
- rail: RailWords;
97
- /** `efficient-easel/tree` — the drag hint and the caret. */
98
- tree: TreeWords;
99
- /** `efficient-easel/panel` — the tab strip's name and each tab's word. */
100
- panel: PanelWords;
101
- /** `efficient-easel/fields` — the number box, the dropdown, the list field. */
102
- fields: FieldsWords;
103
- /** `efficient-easel/pick` — the colour row and the image box. */
104
- pick: PickWords;
105
- /** `efficient-easel/drag` — the Add panel and the canvas layer. */
106
- drag: DragWords;
107
- /** `efficient-easel/node-ops` — the right-click rows. */
108
- menu: NodeMenuWords;
109
- /** `efficient-easel/style-clipboard` — Copy style, Paste style and what a paste says. */
110
- styleClipboard: StyleClipboardWords;
111
- /** `efficient-easel/copy` — the formatting bar, alignment, the link window, each mark. */
112
- copy: CopyWords;
113
- /** `efficient-easel/easel` — the canvas frame's name. */
114
- canvas: CanvasWords;
115
- /** `efficient-easel/text-styles` — the Email styles / Site styles list (E6). */
116
- textStyles: TextStylesWords;
117
- /** `efficient-easel/screen` — a document opening, one that will not, the
118
- * notice's word for the document, the Layers tree's frame, the Add panel,
119
- * the main button and the block keys. */
120
- screen: ScreenWords;
121
- }
122
- /** Today's English, word for word. */
123
- declare const DEFAULT_EASEL_STRINGS: EaselStrings;
124
- /**
125
- * A catalogue with any part left out. A function entry is taken whole or not
126
- * at all: it has no "part" to leave out.
127
- */
128
- type DeepPartial<T> = T extends (...args: never[]) => unknown ? T : T extends object ? {
129
- [K in keyof T]?: DeepPartial<T[K]>;
130
- } : T;
131
- /**
132
- * `defaults` with every entry `partial` gives laid over it. Whatever `partial`
133
- * leaves out (or gives as `undefined` / `null`) keeps the default, so a host
134
- * that has translated half the catalogue shows the other half in English
135
- * rather than as nothing. Neither argument is changed.
136
- */
137
- declare function mergeEaselStrings(defaults: EaselStrings, partial?: DeepPartial<EaselStrings> | null): EaselStrings;
138
-
139
- export { type CanvasWords, ChromeWords, CopyWords, DEFAULT_EASEL_STRINGS, type DeepPartial, DragWords, type EaselStrings, FieldsWords, LockWords, NodeMenuWords, NoticeWords, PanelWords, PickWords, type RailWords, SaveWords, ScreenWords, StyleClipboardWords, TextStylesWords, TreeWords, mergeEaselStrings };
@@ -1 +0,0 @@
1
- export{DEFAULT_EASEL_STRINGS,mergeEaselStrings}from"../chunk-IN22IYOM.js";import"../chunk-OGH6CC3E.js";import"../chunk-OFBZOI6W.js";import"../chunk-VVPZMWJE.js";import"../chunk-6WY6ZXJG.js";import"../chunk-WK3AFPXY.js";import"../chunk-KAML3KQH.js";import"../chunk-TBY3DFKS.js";import"../chunk-K56YDHYQ.js";import"../chunk-KFV7N2DJ.js";import"../chunk-H6DDIBQ4.js";import"../chunk-Z6PVRXVY.js";import"../chunk-RE4LP46F.js";import"../chunk-2OAZYSWJ.js";import"../chunk-B4JN227A.js";import"../chunk-WRFD4EXD.js";