efficient-easel 11.3.0 → 11.8.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 (106) hide show
  1. package/README.md +20 -41
  2. package/dist/{canvas-typing-DvoqQINU.d.ts → canvas-typing-CC0wA-ys.d.ts} +16 -105
  3. package/dist/chrome/chrome.css +5 -5
  4. package/dist/{chunk-66LWADFP.js → chunk-2XMHLXMA.js} +1 -1
  5. package/dist/chunk-33C6ALT5.js +1 -0
  6. package/dist/{chunk-XJCMEEBH.js → chunk-36LVP5WD.js} +7 -7
  7. package/dist/{chunk-SJPKSE5G.js → chunk-5IUS6PM6.js} +12 -12
  8. package/dist/{chunk-FPAVNX3Y.js → chunk-5XUMLKQF.js} +3 -3
  9. package/dist/{chunk-PPL7GB7D.js → chunk-62VPYC7F.js} +1 -1
  10. package/dist/chunk-643PVCEG.js +1 -0
  11. package/dist/{chunk-TWFM6GNK.js → chunk-6IT5H37Y.js} +1 -1
  12. package/dist/{chunk-AFSSKGTD.js → chunk-6TJ2CIMY.js} +1 -1
  13. package/dist/{chunk-4ACVXF5V.js → chunk-7BRKNQF7.js} +1 -1
  14. package/dist/chunk-A6PY6C3C.js +1 -0
  15. package/dist/{chunk-XWK7WZQS.js → chunk-ATF2T5CI.js} +1 -1
  16. package/dist/chunk-AYWN5NRH.js +1 -0
  17. package/dist/chunk-DE35IQ4T.js +57 -0
  18. package/dist/{chunk-PPHUWGLZ.js → chunk-EC2I7SIY.js} +1 -1
  19. package/dist/{chunk-DGAXQTDW.js → chunk-FHLYUIJJ.js} +1 -1
  20. package/dist/{chunk-65Z5FSAW.js → chunk-G3GWAP5R.js} +5 -5
  21. package/dist/{chunk-2FZJWH24.js → chunk-H4UMY7QF.js} +1 -1
  22. package/dist/chunk-H6IXH4A3.js +1 -0
  23. package/dist/{chunk-EXKKLTXH.js → chunk-HRUMNRYI.js} +1 -1
  24. package/dist/chunk-JHYKRGRA.js +5 -0
  25. package/dist/chunk-JRRYFSCY.js +5 -0
  26. package/dist/chunk-KEWQZYUF.js +7 -0
  27. package/dist/{chunk-IFS5P7CO.js → chunk-LZS7JZK5.js} +1 -1
  28. package/dist/{chunk-FGJSCWUN.js → chunk-NY7HHUGB.js} +2 -2
  29. package/dist/chunk-PS5BWS4I.js +2 -0
  30. package/dist/{chunk-47RGVCPH.js → chunk-QFVRMARS.js} +12 -12
  31. package/dist/chunk-TBF5CVPA.js +1 -0
  32. package/dist/{chunk-26GHWMNN.js → chunk-UBAYMWCX.js} +19 -19
  33. package/dist/chunk-UMDQ6CLQ.js +2 -0
  34. package/dist/{chunk-ZXGQT75B.js → chunk-URC5Y5G2.js} +1 -1
  35. package/dist/chunk-VVPZMWJE.js +1 -0
  36. package/dist/chunk-WRFD4EXD.js +1 -0
  37. package/dist/chunk-YHZSBL2N.js +1 -0
  38. package/dist/copy/copy.css +8 -108
  39. package/dist/copy/index.d.ts +39 -9
  40. package/dist/copy/index.js +18 -19
  41. package/dist/drag/drag.css +8 -8
  42. package/dist/drag/index.js +1 -1
  43. package/dist/easel/index.d.ts +3 -3
  44. package/dist/easel/index.js +1 -1
  45. package/dist/fields/fields.css +8 -8
  46. package/dist/fields/index.js +1 -1
  47. package/dist/gold/index.d.ts +3 -3
  48. package/dist/gold/index.js +1 -1
  49. package/dist/icons/index.d.ts +1 -0
  50. package/dist/markup/index.d.ts +1 -629
  51. package/dist/markup/index.js +1 -1
  52. package/dist/menu/menu.css +1 -1
  53. package/dist/panel/index.js +1 -1
  54. package/dist/panel/panel.css +12 -12
  55. package/dist/pick/index.js +1 -1
  56. package/dist/pick/pick.css +7 -7
  57. package/dist/screen/components/AddBlockRow.js +1 -1
  58. package/dist/screen/components/AddSidePanel.js +1 -1
  59. package/dist/screen/components/MediaSidePanel.js +1 -1
  60. package/dist/screen/components/NodeContextMenu.js +1 -1
  61. package/dist/screen/components/PageEditGuardNotices.js +1 -1
  62. package/dist/screen/components/PanelToggleIcon.d.ts +6 -5
  63. package/dist/screen/components/PanelToggleIcon.js +1 -1
  64. package/dist/screen/components/ScreenChrome.js +1 -1
  65. package/dist/screen/components/ScreenDocumentContext.js +1 -1
  66. package/dist/screen/components/ScreenMount.js +1 -1
  67. package/dist/screen/components/ScreenStoreProvider.js +1 -1
  68. package/dist/screen/components/SectionScreenShell.js +16 -16
  69. package/dist/screen/components/SidePanelHead.js +1 -1
  70. package/dist/screen/components/usePartBridge.js +1 -1
  71. package/dist/screen/index.js +1 -1
  72. package/dist/screen/lib/key-scope.js +1 -1
  73. package/dist/screen/lib/puck/device-fields.js +1 -1
  74. package/dist/screen/lib/puck/slot-child-name.js +1 -1
  75. package/dist/screen/lib/puck/style-clipboard.js +1 -1
  76. package/dist/screen/lib/puck/use-section-ops.js +1 -1
  77. package/dist/screen/lib/screen-parts.js +1 -1
  78. package/dist/screen/screen.css +16 -16
  79. package/dist/screen/words.js +1 -1
  80. package/dist/shell/shell.css +10 -8
  81. package/dist/strings/catalogue.d.ts +2 -2
  82. package/dist/strings/catalogue.js +1 -1
  83. package/dist/strings/index.d.ts +2 -2
  84. package/dist/strings/index.js +1 -1
  85. package/dist/text-styles/index.d.ts +4 -231
  86. package/dist/text-styles/index.js +35 -35
  87. package/dist/text-styles/model.d.ts +259 -0
  88. package/dist/text-styles/model.js +1 -0
  89. package/dist/text-styles/text-styles.css +6 -6
  90. package/dist/{words-dsex49Jh.d.ts → words-CiuKuiy0.d.ts} +12 -6
  91. package/package.json +6 -1
  92. package/dist/chunk-546BBOPE.js +0 -1
  93. package/dist/chunk-AZOCY74V.js +0 -57
  94. package/dist/chunk-BHRC3ASL.js +0 -1
  95. package/dist/chunk-BPFPM3L4.js +0 -7
  96. package/dist/chunk-DD7A6RRL.js +0 -5
  97. package/dist/chunk-EQFBUNEB.js +0 -1
  98. package/dist/chunk-FAAZZXIS.js +0 -1
  99. package/dist/chunk-FFYXVAAL.js +0 -1
  100. package/dist/chunk-GCCBEY2W.js +0 -2
  101. package/dist/chunk-GG4FGBFR.js +0 -1
  102. package/dist/chunk-KQMML6JM.js +0 -4
  103. package/dist/chunk-Q6AM43CA.js +0 -1
  104. package/dist/chunk-U7KFFC7N.js +0 -5
  105. package/dist/chunk-VWXUMVCD.js +0 -1
  106. package/dist/chunk-ZAOM6PFH.js +0 -1
@@ -202,7 +202,7 @@
202
202
  background: var(--sf-app-bg);
203
203
  color: var(--sf-text);
204
204
  font-family: var(--sf-font);
205
- font-size: 14px;
205
+ font-size: var(--text-sm, 14px);
206
206
  -webkit-font-smoothing: antialiased;
207
207
  }
208
208
 
@@ -261,7 +261,7 @@
261
261
  quietly deciding the padding of a dialog AND a different editor's strip is
262
262
  the coupling that made this a question at all. Whether this strip should go
263
263
  flat too is its own decision, on its own card. */
264
- padding: 8px 10px;
264
+ padding: var(--space-8, 8px) var(--space-12, 12px);
265
265
  }
266
266
 
267
267
  /* The save pill (dot, ring, words, the autosave switch around it) is
@@ -292,7 +292,7 @@
292
292
  display: flex;
293
293
  align-items: center;
294
294
  justify-content: space-between;
295
- padding: 13px 14px 11px;
295
+ padding: var(--space-16, 16px) var(--space-16, 16px) var(--space-12, 12px);
296
296
  flex: none;
297
297
  }
298
298
 
@@ -303,7 +303,7 @@
303
303
  `0.83em 0` on an h2 and would push the whole head open. The `--btn` variant
304
304
  below re-states its own margin and wins by source order. */
305
305
  .sf-panel-title {
306
- font-size: 14px;
306
+ font-size: var(--text-sm, 14px);
307
307
  font-weight: 600;
308
308
  color: var(--sf-text);
309
309
  margin: 0;
@@ -321,8 +321,8 @@
321
321
  font-family: inherit;
322
322
  cursor: pointer;
323
323
  text-align: left;
324
- padding: 5px 8px;
325
- margin: -5px -8px;
324
+ padding: var(--space-8, 8px);
325
+ margin: calc(-1 * var(--space-8, 8px));
326
326
  border-radius: var(--sf-row-radius);
327
327
  transition: background 0.12s;
328
328
  }
@@ -358,7 +358,7 @@
358
358
  display: flex;
359
359
  align-items: center;
360
360
  justify-content: center;
361
- font-size: 12px;
361
+ font-size: var(--text-xs, 12px);
362
362
  flex: none;
363
363
  /* NO GROUND AND NO RULE. Every row carries a glyph now, so a filled tile on
364
364
  each one is 40 tiles down a page — the chip was a way of picking the icon
@@ -375,7 +375,7 @@
375
375
  way of saying the indent already says. 12px/500 is `.es-group-head`'s size
376
376
  at a row's weight, so the tree and the inspector's headings agree on how big
377
377
  a name in this editor is. */
378
- font-size: 12px;
378
+ font-size: var(--text-xs, 12px);
379
379
  font-weight: 500;
380
380
  color: var(--sf-text);
381
381
  white-space: nowrap;
@@ -404,13 +404,13 @@
404
404
  align-items: center;
405
405
  gap: 8px;
406
406
  width: 100%;
407
- padding: 6px 9px;
407
+ padding: var(--space-8, 8px) var(--space-12, 12px);
408
408
  border: none;
409
409
  background: transparent;
410
410
  border-radius: var(--radius-lg);
411
411
  cursor: pointer;
412
412
  color: var(--sf-accent);
413
- font-size: 12px;
413
+ font-size: var(--text-xs, 12px);
414
414
  font-weight: 500;
415
415
  }
416
416
 
@@ -432,7 +432,7 @@
432
432
  display: flex;
433
433
  align-items: center;
434
434
  justify-content: center;
435
- font-size: 14px;
435
+ font-size: var(--text-sm, 14px);
436
436
  flex: none;
437
437
  background: var(--sf-accent-tint);
438
438
  }
@@ -442,7 +442,7 @@
442
442
  that opens it is the add card (`.sf-add-card`, the trigger's own look). What
443
443
  stays is a heading's count, quieter than its word. */
444
444
  .sf-menugroup-count {
445
- font-size: 11px;
445
+ font-size: var(--text-2xs, 11px);
446
446
  color: var(--sf-field-placeholder);
447
447
  }
448
448
 
@@ -457,7 +457,7 @@
457
457
  flex: 1;
458
458
  min-height: 0;
459
459
  overflow-y: auto;
460
- padding: 0 14px 16px;
460
+ padding: 0 var(--space-16, 16px) var(--space-16, 16px);
461
461
  }
462
462
 
463
463
  /* ── Footer "Add block" menu — heterogeneous block-type picker ──────────── */
@@ -665,7 +665,7 @@
665
665
 
666
666
  .sf-msg {
667
667
  padding: 24px;
668
- font-size: 14px;
668
+ font-size: var(--text-sm, 14px);
669
669
  color: var(--sf-icon);
670
670
  }
671
671
 
@@ -737,10 +737,10 @@
737
737
  a full-width strip, so it keeps its own rule. */
738
738
  .sf-device-scope {
739
739
  margin: 8px 0 2px;
740
- padding: 7px 10px;
740
+ padding: var(--space-8, 8px) var(--space-12, 12px);
741
741
  border-radius: var(--radius-md);
742
742
  background: var(--sf-chip-bg);
743
- font-size: 11.5px;
743
+ font-size: var(--text-xs, 12px);
744
744
  line-height: 1.35;
745
745
  color: var(--sf-muted);
746
746
  }
@@ -1 +1 @@
1
- export{DEFAULT_SCREEN_ADD_WORDS,DEFAULT_SCREEN_SAVE_STATUS_WORDS,DEFAULT_SCREEN_WORDS}from"../chunk-VWXUMVCD.js";
1
+ export{DEFAULT_SCREEN_ADD_WORDS,DEFAULT_SCREEN_SAVE_STATUS_WORDS,DEFAULT_SCREEN_WORDS}from"../chunk-VVPZMWJE.js";
@@ -137,14 +137,16 @@
137
137
  --es-panel-gap: 12px;
138
138
 
139
139
  /* — spacing: ONE scale for every panel (owner ruling, 2026-10-02) —
140
- Six steps and no seventh. Every margin, padding and gap in this package
141
- is one of them; `tests/spacing-scale.test.ts` holds every sheet to it. */
142
- --es-space-2: 2px;
143
- --es-space-4: 4px;
144
- --es-space-8: 8px;
145
- --es-space-12: 12px;
146
- --es-space-16: 16px;
147
- --es-space-32: 32px;
140
+ The scale itself is the shell's (efficient-shell `--space-*`, 2/4/8/12/16/
141
+ 20/24/32/40/48, owner ruling 2026-10-12); these six names read it. Every
142
+ margin, padding and gap in this package is a step of it;
143
+ `tests/spacing-scale.test.ts` holds every sheet to it. */
144
+ --es-space-2: var(--space-2, 2px);
145
+ --es-space-4: var(--space-4, 4px);
146
+ --es-space-8: var(--space-8, 8px);
147
+ --es-space-12: var(--space-12, 12px);
148
+ --es-space-16: var(--space-16, 16px);
149
+ --es-space-32: var(--space-32, 32px);
148
150
 
149
151
  /* — shadows: black at an alpha (no shell elevation token yet) — */
150
152
  --es-panel-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 10px 30px rgba(0, 0, 0, 0.06);
@@ -1,6 +1,6 @@
1
1
  import { S as SaveWords } from '../words-pgIK0I6g.js';
2
2
  import { N as NoticeWords, C as ChromeWords } from '../words-BpiVrsW5.js';
3
- import { C as CopyWords } from '../words-dsex49Jh.js';
3
+ import { C as CopyWords } from '../words-CiuKuiy0.js';
4
4
  import { D as DragWords } from '../words-BDignMl_.js';
5
5
  import { LockWords } from '../edit-lock/index.js';
6
6
  import { F as FieldsWords } from '../words-vhnV8sM7.js';
@@ -18,7 +18,7 @@ import '../wordFit-7XpmhcaW.js';
18
18
  import 'react';
19
19
  import '../panelWidths-D9hTLR25.js';
20
20
  import '../engine-CvXpFE86.js';
21
- import '../markup/index.js';
21
+ import 'efficient-shell/markup';
22
22
  import '../buckets-Tj-nkBpg.js';
23
23
 
24
24
  /**
@@ -1 +1 @@
1
- export{DEFAULT_EASEL_STRINGS,mergeEaselStrings}from"../chunk-FAAZZXIS.js";import"../chunk-OGH6CC3E.js";import"../chunk-ZAOM6PFH.js";import"../chunk-6WY6ZXJG.js";import"../chunk-VWXUMVCD.js";import"../chunk-TBY3DFKS.js";import"../chunk-K56YDHYQ.js";import"../chunk-KFV7N2DJ.js";import"../chunk-WK3AFPXY.js";import"../chunk-H6DDIBQ4.js";import"../chunk-Z6PVRXVY.js";import"../chunk-RE4LP46F.js";import"../chunk-2OAZYSWJ.js";import"../chunk-Q6AM43CA.js";import"../chunk-FFYXVAAL.js";import"../chunk-546BBOPE.js";import"../chunk-GG4FGBFR.js";
1
+ export{DEFAULT_EASEL_STRINGS,mergeEaselStrings}from"../chunk-A6PY6C3C.js";import"../chunk-OGH6CC3E.js";import"../chunk-643PVCEG.js";import"../chunk-6WY6ZXJG.js";import"../chunk-VVPZMWJE.js";import"../chunk-TBY3DFKS.js";import"../chunk-K56YDHYQ.js";import"../chunk-KFV7N2DJ.js";import"../chunk-WK3AFPXY.js";import"../chunk-H6DDIBQ4.js";import"../chunk-33C6ALT5.js";import"../chunk-WRFD4EXD.js";import"../chunk-Z6PVRXVY.js";import"../chunk-RE4LP46F.js";import"../chunk-2OAZYSWJ.js";import"../chunk-AYWN5NRH.js";
@@ -3,7 +3,7 @@ export { CanvasWords, DEFAULT_EASEL_STRINGS, RailWords, mergeEaselStrings } from
3
3
  import * as react from 'react';
4
4
  import { ReactNode } from 'react';
5
5
  export { C as ChromeWords, N as NoticeWords } from '../words-BpiVrsW5.js';
6
- export { C as CopyWords } from '../words-dsex49Jh.js';
6
+ export { C as CopyWords } from '../words-CiuKuiy0.js';
7
7
  export { D as DragWords } from '../words-BDignMl_.js';
8
8
  export { F as FieldsWords } from '../words-vhnV8sM7.js';
9
9
  export { LockWords } from '../edit-lock/index.js';
@@ -15,7 +15,7 @@ export { ScreenAddWords, ScreenWords } from '../screen/words.js';
15
15
  export { S as StyleClipboardWords } from '../words-CnnHb9jo.js';
16
16
  export { T as TextStylesWords } from '../words-gIDCeRv3.js';
17
17
  export { T as TreeWords } from '../words-Cl9xMUYY.js';
18
- import '../markup/index.js';
18
+ import 'efficient-shell/markup';
19
19
  import '../buckets-Tj-nkBpg.js';
20
20
  import '../types-DGyDHiJV.js';
21
21
  import '../types-CsgMwHHa.js';
@@ -1,2 +1,2 @@
1
- import{DEFAULT_EASEL_STRINGS as r,mergeEaselStrings as n}from"../chunk-FAAZZXIS.js";export{DEFAULT_EASEL_STRINGS,mergeEaselStrings}from"../chunk-FAAZZXIS.js";import"../chunk-OGH6CC3E.js";import"../chunk-ZAOM6PFH.js";import"../chunk-6WY6ZXJG.js";import"../chunk-VWXUMVCD.js";import"../chunk-TBY3DFKS.js";import"../chunk-K56YDHYQ.js";import"../chunk-KFV7N2DJ.js";import"../chunk-WK3AFPXY.js";import"../chunk-H6DDIBQ4.js";import"../chunk-Z6PVRXVY.js";import"../chunk-RE4LP46F.js";import"../chunk-2OAZYSWJ.js";import"../chunk-Q6AM43CA.js";import"../chunk-FFYXVAAL.js";import"../chunk-546BBOPE.js";import{stringsContext as o}from"../chunk-MFIRYGHW.js";import"../chunk-GG4FGBFR.js";import{useContext as t,useMemo as c}from"react";import{jsx as i}from"react/jsx-runtime";function s({value:s,locale:u,children:m}){const e=o(),p=t(e),h=p?.strings??r,j=u??p?.locale??"en",k=c(()=>({strings:n(h,s),locale:j}),[h,s,j]);/* @__PURE__ */
1
+ import{DEFAULT_EASEL_STRINGS as r,mergeEaselStrings as n}from"../chunk-A6PY6C3C.js";export{DEFAULT_EASEL_STRINGS,mergeEaselStrings}from"../chunk-A6PY6C3C.js";import"../chunk-OGH6CC3E.js";import"../chunk-643PVCEG.js";import"../chunk-6WY6ZXJG.js";import"../chunk-VVPZMWJE.js";import"../chunk-TBY3DFKS.js";import"../chunk-K56YDHYQ.js";import"../chunk-KFV7N2DJ.js";import"../chunk-WK3AFPXY.js";import"../chunk-H6DDIBQ4.js";import"../chunk-33C6ALT5.js";import"../chunk-WRFD4EXD.js";import"../chunk-Z6PVRXVY.js";import"../chunk-RE4LP46F.js";import"../chunk-2OAZYSWJ.js";import{stringsContext as o}from"../chunk-MFIRYGHW.js";import"../chunk-AYWN5NRH.js";import{useContext as t,useMemo as c}from"react";import{jsx as i}from"react/jsx-runtime";function s({value:s,locale:u,children:m}){const e=o(),p=t(e),h=p?.strings??r,j=u??p?.locale??"en",k=c(()=>({strings:n(h,s),locale:j}),[h,s,j]);/* @__PURE__ */
2
2
  return i(e.Provider,{value:k,children:m})}function u(){return t(o())?.strings??r}function m(){return t(o())?.locale??"en"}export{s as EaselStringsProvider,m as useEaselLocale,u as useEaselStrings};
@@ -1,235 +1,8 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { T as TextStylesWords } from '../words-gIDCeRv3.js';
4
- export { D as DEFAULT_TEXT_STYLES_WORDS } from '../words-gIDCeRv3.js';
5
-
6
- /**
7
- * The text styles as data (plan step E6): what a style is, the list both
8
- * editors start from, the design's ranges, and the pure changes the list
9
- * makes. No React and no browser global, so P3 and S2 can use it where they
10
- * read and write their own storage.
11
- *
12
- * What this does NOT know is where a host keeps its styles, or what its old
13
- * values were called. Turning an email's "Label" into Body 5, or the website's
14
- * "Tight" into 95 % / −0.01 em, is the host's (P3, S2). The units here are the
15
- * panel's: px, and % for line spacing.
16
- */
17
-
18
- type TextStyleKind = 'heading' | 'body';
19
- /** As typed · Uppercase · Lowercase. No value = Auto where the host offers it, As typed where not. */
20
- type TextStyleCase = 'none' | 'upper' | 'capitalize' | 'lower';
21
- /**
22
- * One style's own settings. A missing key has nothing of its own: it is Auto
23
- * where the host offers Auto for that setting, and otherwise shows the host's
24
- * `fallback`, grey.
25
- */
26
- interface TextStyleValues {
27
- /** A font's `value`, from the host's list. */
28
- font?: string;
29
- /** A theme colour's `key`, or a `#rrggbb`. */
30
- color?: string;
31
- /** px. */
32
- size?: number;
33
- /** 100–900. */
34
- weight?: number;
35
- italic?: boolean;
36
- /** % of the font size; below 100 is tighter than the type. */
37
- lineSpacing?: number;
38
- /** px; may be negative. */
39
- letterSpacing?: number;
40
- /** px. */
41
- paragraphSpacing?: number;
42
- letterCase?: TextStyleCase;
43
- /** px; headings only — the largest a heading is drawn anywhere on the site. */
44
- largestSize?: number;
45
- }
46
- interface TextStyle {
47
- /** The host's, stable: the list never renames an id. */
48
- id: string;
49
- kind: TextStyleKind;
50
- /** Stored, so the host's words: "Heading 1", "Body 5". */
51
- name: string;
52
- values: TextStyleValues;
53
- }
54
- /** A font the host offers. */
55
- interface TextStyleFont {
56
- value: string;
57
- label: string;
58
- /** The CSS `font-family` the list draws the name and the preview in. */
59
- family: string;
60
- /** `false` when this font has no italic loaded: the Italic button is off. */
61
- italic?: boolean;
62
- }
63
- /** A theme colour the host offers, stored by its key. */
64
- interface TextStyleColour {
65
- key: string;
66
- name: string;
67
- /** `#rrggbb`. */
68
- value: string;
69
- }
70
- /** Every setting an open style can show, in the order it shows them. */
71
- declare const TEXT_STYLE_SETTINGS: readonly ["font", "color", "size", "weight", "emphasis", "lineSpacing", "letterSpacing", "paragraphSpacing", "letterCase", "largestSize"];
72
- type TextStyleSetting = (typeof TEXT_STYLE_SETTINGS)[number];
73
- /** The settings an Email styles list shows — the campaign design page. */
74
- declare const CAMPAIGN_TEXT_STYLE_SETTINGS: readonly TextStyleSetting[];
75
- /** The settings that may be Auto, when the host says so (Site styles). */
76
- type TextStyleAuto = 'size' | 'lineSpacing' | 'letterSpacing' | 'letterCase';
77
- /** The kinds, in the order the list draws them. */
78
- declare const TEXT_STYLE_KINDS: readonly TextStyleKind[];
79
- /** At most this many of EACH kind (Lewis, 2026-10-02). */
80
- declare const TEXT_STYLE_MAX = 7;
81
- /** How many of each the list starts with: Heading 1–3, Body 1–5. */
82
- declare const TEXT_STYLE_DEFAULT_COUNT: Readonly<Record<TextStyleKind, number>>;
83
- /** A number setting's slider: its travel, the typed limits, the steps and the unit. */
84
- interface TextStyleRange {
85
- /** The lowest a typed value may be; `undefined` = no limit. */
86
- min: number | undefined;
87
- /** The highest a typed value may be; `undefined` = no limit. */
88
- max: number | undefined;
89
- sliderMin: number;
90
- sliderMax: number;
91
- step: number;
92
- shiftStep: number;
93
- unit: string;
94
- }
95
- /**
96
- * The design's numbers (campaign page, "the three boxes' rules" and the slider
97
- * ranges; website page §5). A typed value may go past the slider; only `min`
98
- * and `max` hold it. Line spacing down to 50 % and letter spacing down to
99
- * −10 px are Lewis's (2026-10-06).
100
- */
101
- declare const TEXT_STYLE_RANGES: {
102
- readonly size: TextStyleRange;
103
- readonly weight: {
104
- readonly min: 100;
105
- readonly max: 900;
106
- readonly sliderMin: 300;
107
- readonly sliderMax: 900;
108
- readonly step: 100;
109
- readonly shiftStep: 100;
110
- readonly unit: "";
111
- };
112
- readonly lineSpacing: {
113
- readonly min: 50;
114
- readonly max: 250;
115
- readonly sliderMin: 50;
116
- readonly sliderMax: 250;
117
- readonly step: 1;
118
- readonly shiftStep: 10;
119
- readonly unit: "%";
120
- };
121
- readonly letterSpacing: {
122
- readonly min: -10;
123
- readonly max: undefined;
124
- readonly sliderMin: -5;
125
- readonly sliderMax: 10;
126
- readonly step: 0.1;
127
- readonly shiftStep: 1;
128
- readonly unit: "px";
129
- };
130
- readonly paragraphSpacing: {
131
- readonly min: 0;
132
- readonly max: undefined;
133
- readonly sliderMin: 0;
134
- readonly sliderMax: 48;
135
- readonly step: 1;
136
- readonly shiftStep: 10;
137
- readonly unit: "px";
138
- };
139
- readonly largestSize: TextStyleRange;
140
- };
141
- type TextStyleNumber = keyof typeof TEXT_STYLE_RANGES;
142
- /** Heading 1–3 then Body 1–5, ids `heading-1` … `body-5`, no values: the host fills them. */
143
- declare function defaultTextStyles(name?: (v: {
144
- kind: TextStyleKind;
145
- n: number;
146
- }) => string): TextStyle[];
147
- /** Whether another style of this kind fits under the cap. */
148
- declare function canAddTextStyle(styles: readonly TextStyle[], kind: TextStyleKind, max?: number): boolean;
149
- /**
150
- * Whether a style is one the list starts with (Heading 1–3, Body 1–5), which
151
- * can never be deleted. Decided by the fixed id (`heading-1` … `body-5`),
152
- * never by the name: a host's words name the styles.
153
- */
154
- declare function isDefaultTextStyle(style: TextStyle): boolean;
155
- /**
156
- * A new style of `kind`, after the last one of that kind: a copy of that
157
- * one's values, named the next free number ("Heading 4"). `null` at the cap.
158
- * The list given is not changed.
159
- *
160
- * The name and the id are chosen apart. The name is the next number after
161
- * the styles of its kind, skipping a name already taken, so after a delete
162
- * the names have no gap. The id is above every id of its kind
163
- * (`heading-7` when `heading-6` is there), and the name's number when that
164
- * is higher. So an id freed by a delete is used again only when it was the
165
- * highest of its kind, and then the new style is a copy of the one that
166
- * id's text was already drawn as (`resolveTextStyle`): nothing on the page
167
- * jumps.
168
- *
169
- * `make` lets a host build the new style itself (its own ids); it gets the
170
- * kind and the number the new style is called.
171
- */
172
- declare function addTextStyle(styles: readonly TextStyle[], kind: TextStyleKind, options?: {
173
- max?: number;
174
- name?: (v: {
175
- kind: TextStyleKind;
176
- n: number;
177
- }) => string;
178
- make?: (kind: TextStyleKind, n: number) => TextStyle;
179
- }): {
180
- styles: TextStyle[];
181
- added: TextStyle;
182
- } | null;
183
- /**
184
- * The list without one ADDED style. `null` for a default (they are never
185
- * deleted) or an id not in the list. The list given is not changed.
186
- *
187
- * The styles of its kind after it close the gap by NAME — "Heading 5" becomes
188
- * "Heading 4" — when their name is still the number of their place. Their
189
- * ids never change, so text on them stays on them. Text on the deleted one
190
- * is not rewritten: `resolveTextStyle` draws it as the nearest earlier style
191
- * of its kind.
192
- *
193
- * `name` is the host's words for a style's name, as `addTextStyle` takes it.
194
- */
195
- declare function removeTextStyle(styles: readonly TextStyle[], id: string, options?: {
196
- name?: (v: {
197
- kind: TextStyleKind;
198
- n: number;
199
- }) => string;
200
- }): {
201
- styles: TextStyle[];
202
- removed: TextStyle;
203
- } | null;
204
- /**
205
- * The style text on `id` draws as: that style, or — when it was deleted —
206
- * the nearest EARLIER style of its kind still in the list (`heading-5` gone:
207
- * Heading 4's id, else `heading-3`). The defaults are never deleted, so an
208
- * id the model made always finds one. `undefined` for an id the model did
209
- * not make (a host's own, through `make`): that host resolves its own.
210
- *
211
- * Read every stored style id through this, so a deleted style's text keeps
212
- * drawing — in a saved page and in a sent email alike — and nothing stored
213
- * is rewritten.
214
- */
215
- declare function resolveTextStyle(styles: readonly TextStyle[], id: string): TextStyle | undefined;
216
- /**
217
- * The list with one style's values changed. A key given as `undefined` is
218
- * removed: the setting has nothing of its own again. Nothing is changed in
219
- * place, and the other styles are the same objects.
220
- */
221
- declare function updateTextStyle(styles: readonly TextStyle[], id: string, patch: Partial<TextStyleValues>): TextStyle[];
222
- /** The size a style's NAME is drawn at in the list: half its size plus 6, kept within 12–20 px. */
223
- declare function textStyleRowSize(px: number): number;
224
- /** A weight's name, by the hundred it is nearest. */
225
- declare function weightWord(weight: number, words: TextStylesWords): string;
226
- /**
227
- * A row's grey line, "Playfair Display · 28 px · Semibold". `autoSize`: a
228
- * size with no number reads the Auto word. A weight with none is Regular.
229
- */
230
- declare function describeTextStyle(values: TextStyleValues, fonts: readonly TextStyleFont[], words: TextStylesWords, options?: {
231
- autoSize?: boolean;
232
- }): string;
3
+ import { TextStyle, TextStyleFont, TextStyleColour, TextStyleSetting, TextStyleAuto, TextStyleValues, TextStyleKind } from './model.js';
4
+ export { CAMPAIGN_TEXT_STYLE_SETTINGS, TEXT_STYLE_CASES, TEXT_STYLE_CASE_CSS, TEXT_STYLE_DEFAULT_COUNT, TEXT_STYLE_KINDS, TEXT_STYLE_MAX, TEXT_STYLE_RANGES, TEXT_STYLE_SETTINGS, TextStyleCase, TextStyleCaseCss, TextStyleNumber, TextStyleRange, addTextStyle, canAddTextStyle, defaultTextStyles, describeTextStyle, isDefaultTextStyle, isTextStyleCase, removeTextStyle, resolveTextStyle, textStyleCaseCss, textStyleCaseOfCss, textStyleRowSize, updateTextStyle, weightWord } from './model.js';
5
+ export { D as DEFAULT_TEXT_STYLES_WORDS, T as TextStylesWords } from '../words-gIDCeRv3.js';
233
6
 
234
7
  interface TextStylesListProps {
235
8
  /** Headings and bodies, in the host's order; the list draws headings first. */
@@ -368,4 +141,4 @@ interface ColourSwatchRowProps {
368
141
  */
369
142
  declare function ColourSwatchRow({ value, hex, colours, label, followsWord, anyWord, onChange, readOnly }: ColourSwatchRowProps): react.JSX.Element;
370
143
 
371
- export { CAMPAIGN_TEXT_STYLE_SETTINGS, ColourSwatchRow, type ColourSwatchRowProps, TEXT_STYLE_DEFAULT_COUNT, TEXT_STYLE_KINDS, TEXT_STYLE_MAX, TEXT_STYLE_RANGES, TEXT_STYLE_SETTINGS, type TextStyle, type TextStyleAuto, type TextStyleCase, type TextStyleColour, type TextStyleFont, TextStyleItem, type TextStyleItemProps, type TextStyleKind, type TextStyleNumber, type TextStyleRange, type TextStyleSetting, type TextStyleValues, TextStylesGroup, type TextStylesGroupProps, TextStylesList, type TextStylesListProps, TextStylesWords, addTextStyle, canAddTextStyle, defaultTextStyles, describeTextStyle, isDefaultTextStyle, removeTextStyle, resolveTextStyle, textStyleRowSize, updateTextStyle, weightWord };
144
+ export { ColourSwatchRow, type ColourSwatchRowProps, TextStyle, TextStyleAuto, TextStyleColour, TextStyleFont, TextStyleItem, type TextStyleItemProps, TextStyleKind, TextStyleSetting, TextStyleValues, TextStylesGroup, type TextStylesGroupProps, TextStylesList, type TextStylesListProps };
@@ -1,35 +1,35 @@
1
- import{hexReadout as e,ColourWindow as n,typedHex as t}from"../chunk-FPAVNX3Y.js";import{DEFAULT_TEXT_STYLES_WORDS as s}from"../chunk-OGH6CC3E.js";export{DEFAULT_TEXT_STYLES_WORDS}from"../chunk-OGH6CC3E.js";import"../chunk-ZAOM6PFH.js";import{FieldSlider as a}from"../chunk-XWFH2NHZ.js";import{FieldSelect as i}from"../chunk-65Z5FSAW.js";import"../chunk-FFYXVAAL.js";import{useWords as l}from"../chunk-MFIRYGHW.js";import{withTip as r}from"../chunk-P2VEMZH5.js";import{hsvToHex as o,Tooltip as d,ColorSwatch as c,IconButton as u}from"efficient-shell/ui";import{useState as m,useRef as f,useId as h,useEffect as p,Fragment as v}from"react";import{TrashIcon as g,ChevronIcon as y,BoldIcon as k,ItalicIcon as b,CaseLowerIcon as x,CaseCapitalizedIcon as w,CaseUpperIcon as S,CaseNormalIcon as N}from"efficient-shell/icons/efficient";import{jsxs as C,jsx as z,Fragment as O}from"react/jsx-runtime";var M=["font","color","size","weight","emphasis","lineSpacing","letterSpacing","paragraphSpacing","letterCase","largestSize"],$=["font","color","size","weight","lineSpacing","letterSpacing","paragraphSpacing","letterCase"],A=["heading","body"],j=7,F={heading:3,body:5},E={min:5,max:void 0,sliderMin:12,sliderMax:72,step:1,shiftStep:10,unit:"px"},W={size:E,weight:{min:100,max:900,sliderMin:300,sliderMax:900,step:100,shiftStep:100,unit:""},lineSpacing:{min:50,max:250,sliderMin:50,sliderMax:250,step:1,shiftStep:10,unit:"%"},letterSpacing:{min:-10,max:void 0,sliderMin:-5,sliderMax:10,step:.1,shiftStep:1,unit:"px"},paragraphSpacing:{min:0,max:void 0,sliderMin:0,sliderMax:48,step:1,shiftStep:10,unit:"px"},largestSize:E},H=(e,n)=>`${"heading"===e?"Heading":"Body"} ${n}`;function L(e=({kind:e,n:n})=>H(e,n)){return A.flatMap(n=>Array.from({length:F[n]},(t,s)=>({id:`${n}-${s+1}`,kind:n,name:e({kind:n,n:s+1}),values:{}})))}function B(e,n,t=j){return e.filter(e=>e.kind===n).length<t}function D(e,n){const t=new RegExp(`^${n}-([1-9]\\d*)$`).exec(e);return t?Number(t[1]):void 0}function I(e){const n=D(e.id,e.kind);return void 0!==n&&n<=F[e.kind]}function R(e,n,t={}){const{max:s=j,name:a=({kind:e,n:n})=>H(e,n),make:i}=t;if(!B(e,n,s))return null;const l=e.filter(e=>e.kind===n);let r=l.length+1;const o=new Set(e.map(e=>e.name));for(;o.has(a({kind:n,n:r}));)r+=1;const d=new Set(e.map(e=>e.id));let c=Math.max(r,...l.map(e=>(D(e.id,n)??0)+1));for(;d.has(`${n}-${c}`);)c+=1;const u=l.at(-1),m=i?i(n,r):{id:`${n}-${c}`,kind:n,name:a({kind:n,n:r}),values:{...u?.values??{}}},f=u?e.indexOf(u)+1:"heading"===n?0:e.length;return{styles:[...e.slice(0,f),m,...e.slice(f)],added:m}}function T(e,n,t={}){const{name:s=({kind:e,n:n})=>H(e,n)}=t,a=e.find(e=>e.id===n);if(!a||I(a))return null;const i=e.filter(e=>e.kind===a.kind),l=i.indexOf(a),r=/* @__PURE__ */new Map;return i.forEach((e,n)=>{n>l&&e.name===s({kind:e.kind,n:n+1})&&r.set(e,s({kind:e.kind,n:n}))}),{styles:e.filter(e=>e!==a).map(e=>r.has(e)?{...e,name:r.get(e)}:e),removed:a}}function V(e,n){const t=e.find(e=>e.id===n);if(t)return t;for(const t of A){const s=D(n,t);if(void 0===s)continue;let a;for(const n of e){const e=n.kind===t?D(n.id,t):void 0;void 0!==e&&e<s&&(!a||e>a.n)&&(a={n:e,style:n})}return a?.style}}function X(e,n,t){return e.map(e=>{if(e.id!==n)return e;const s={...e.values};for(const[e,n]of Object.entries(t))void 0===n?delete s[e]:s[e]=n;return{...e,values:s}})}function Y(e){return Math.min(20,Math.max(12,Math.round(.5*e+6)))}function Z(e,n){const t=n.weights;return[t.thin,t.extraLight,t.light,t.regular,t.medium,t.semibold,t.bold,t.extraBold,t.black][Math.min(8,Math.max(0,Math.round(e/100)-1))]}function q(e,n,t,s={}){const a=n.find(n=>n.value===e.font)?.label??e.font??"",i=void 0===e.size?s.autoSize?t.auto:"":t.px({n:e.size});return t.summary({font:a,size:i,weight:Z(e.weight??400,t)})}var G=`conic-gradient(${[0,60,120,180,240,300,0].map(e=>o({h:e,s:1,v:1})).join(", ")})`;function P({value:t,hex:s,colours:a,label:i,followsWord:l,anyWord:r,onChange:o,readOnly:u=!1}){const[v,g]=m(!1),y=f(null),k=f(null),b=h(),x=void 0!==t&&a.some(e=>e.key===t),w=void 0!==t&&!x;return p(()=>{if(!v)return;const e=y.current?.ownerDocument;if(!e)return;const n=e=>{y.current&&!y.current.contains(e.target)&&g(!1)};return e.addEventListener("click",n,!0),()=>e.removeEventListener("click",n,!0)},[v]),/* @__PURE__ */C("div",{ref:y,className:"es-ts-set","data-ts-setting":"color",children:[
2
- /* @__PURE__ */C("div",{className:"es-ts-top",children:[
3
- /* @__PURE__ */z("span",{className:"es-ts-sub",children:i}),
4
- /* @__PURE__ */z("span",{className:"es-ts-colour-read",children:s?e(s):l})]}),
5
- /* @__PURE__ */C("div",{className:"es-ts-swatches",role:"group","aria-label":i,children:[a.map(n=>/* @__PURE__ */z(d,{content:`${n.name} · ${e(n.value)}`,children:/* @__PURE__ */z(c,{color:n.value,size:"sm",className:"es-ts-swatch","aria-label":n.name,selected:t===n.key,disabled:u,onClick:()=>o(n.key)})},n.key)),
6
- /* @__PURE__ */z(d,{content:r,children:/* @__PURE__ */z(c,{ref:k,color:G,size:"sm",className:"es-ts-swatch es-ts-swatch--any","aria-label":r,selected:w,"aria-expanded":v,"aria-controls":v?b:void 0,disabled:u,onClick:()=>g(e=>!e)})})]}),v?/* @__PURE__ */z(n,{id:b,value:s??"",onChange:e=>o(e),label:i,readOnly:u,onClose:()=>{g(!1),k.current?.focus()}}):null]})}function _({styles:e,onChange:n,fonts:t,colours:a=[],settings:i=$,auto:o=[],fallback:d,sample:c,openId:u,defaultOpenId:v=null,onOpenChange:y,onAdd:k,rowActions:b,onRemove:x,max:w=j,readOnly:S=!1}){const N=l("textStyles",s),M=h(),[F,E]=m(v),W=void 0!==u?u:F,H=e=>{void 0===u&&E(e),y?.(e)},L=f(null),[D,V]=m(null);p(()=>{if(!D||!L.current)return;const e=[...L.current.querySelectorAll(".es-ts-item")].find(e=>e.dataset.tsId===D.id),n=e?e.querySelector(".es-ts-row"):L.current.querySelector(`.es-ts-add[data-ts-kind="${D.kind}"]`);n?.focus(),V(null)},[D]);/* @__PURE__ */
7
- return z("div",{className:"es-ts",ref:L,children:A.map(s=>{const l=e.filter(e=>e.kind===s),u=!B(e,s,w),m=!S&&!u;/* @__PURE__ */
8
- return C(U,{label:N.groups[s],children:[l.map(s=>{const l=b?.(s),u=null!=l&&!1!==l,m=Boolean(x)&&!S&&!I(s);/* @__PURE__ */
9
- return z(K,{style:s,fonts:t,colours:a,settings:i,auto:o,fallback:d,sample:c,readOnly:S,open:W===s.id,onOpenChange:e=>H(e?s.id:null),onChange:t=>n(e.map(e=>e.id===t.id?t:e)),actions:m||u?/* @__PURE__ */C(O,{children:[m?r(N.remove,/* @__PURE__ */z("button",{type:"button",className:"es-ts-del","aria-label":N.removeNamed({name:s.name}),onClick:()=>(t=>{if(S||!x)return;const s=T(e,t.id,{name:N.styleName});if(!s)return;const a=e.filter(e=>e.kind===t.kind),i=a[a.indexOf(t)+1];W===t.id&&H(null),n(s.styles),x(s.removed),V({id:i?.id??null,kind:t.kind})})(s),children:/* @__PURE__ */z(g,{size:14,"aria-hidden":"true"})})):null,u?l:null]}):null},s.id)}),r(!S&&u?N.full({kind:s,max:w}):void 0,/* @__PURE__ */C("button",{type:"button",className:"es-ts-add","data-ts-kind":s,disabled:S,"aria-disabled":!(S||!u)||void 0,"aria-describedby":!S&&u?`${M}-full-${s}`:void 0,onClick:()=>{m&&(t=>{if(S)return;const s=R(e,t,{max:w,name:N.styleName,make:k});s&&n(s.styles)})(s)},children:[
10
- /* @__PURE__ */z("span",{className:"es-ts-add-word",children:N.add[s]}),
11
- /* @__PURE__ */z("span",{className:"es-ts-count",children:N.count({n:l.length,max:w})})]})),S||!u?null:/* @__PURE__ */z("span",{id:`${M}-full-${s}`,className:"es-vh",children:N.full({kind:s,max:w})})]},s)})})}function U({label:e,children:n}){const t=h();/* @__PURE__ */
12
- return C("section",{className:"es-ts-section","aria-labelledby":t,children:[
13
- /* @__PURE__ */z("div",{className:"es-ts-group",id:t,children:e}),n]})}function K({style:e,fonts:n,colours:t=[],settings:a=$,auto:i=[],fallback:r,sample:o,open:d,onOpenChange:c,onChange:u,actions:m,readOnly:f=!1}){const p=l("textStyles",s),g=`${h()}-open-${e.id}`,k=new Set(i),b=M.filter(e=>a.includes(e)),x={...r?.(e)??{},...e.values},w=n.find(e=>e.value===x.font),S={fontFamily:w?.family,fontSize:`${Y(x.size??16)}px`,fontWeight:x.weight,fontStyle:x.italic?"italic":void 0};/* @__PURE__ */
14
- return C(v,{children:[
15
- /* @__PURE__ */C("div",{className:"es-ts-item","data-ts-id":e.id,children:[
16
- /* @__PURE__ */C("button",{type:"button",className:"es-ts-row","aria-expanded":d,"aria-controls":d?g:void 0,onClick:()=>c(!d),children:[
17
- /* @__PURE__ */z("span",{className:"es-ts-chev","aria-hidden":"true",children:/* @__PURE__ */z(y,{size:12})}),
18
- /* @__PURE__ */z("span",{className:"es-ts-name",style:S,children:e.name}),
19
- /* @__PURE__ */z("span",{className:"es-ts-meta",children:q(x,n,p,{autoSize:k.has("size")&&void 0===e.values.size})})]}),m?/* @__PURE__ */z("div",{className:"es-ts-actions",children:m}):null]}),d?/* @__PURE__ */z("div",{className:"es-ts-open",id:g,children:/* @__PURE__ */z(ee,{style:e,values:x,fonts:n,colours:t,settings:b,autoSet:k,sample:o??p.sample,words:p,readOnly:f,set:n=>u(X([e],e.id,n)[0])})}):null]})}var J={none:N,upper:S,capitalize:w,lower:x},Q={none:"none",upper:"uppercase",capitalize:"capitalize",lower:"lowercase"};function ee({style:e,values:n,fonts:s,colours:i,settings:l,autoSet:o,sample:d,words:c,readOnly:m,set:f}){const h=e.values,p=s.find(e=>e.value===n.font),v=function(e,n){return e?n.find(n=>n.key===e)?.value??t(e)??void 0:void 0}(n.color,i),g=e=>"largestSize"===e||o.has(e),y=e=>g(e)?h[e]:n[e],x=y("size"),w=y("lineSpacing"),S=y("letterSpacing"),N=g("letterCase")?h.letterCase:n.letterCase,M={fontFamily:p?.family,fontSize:void 0===x?void 0:`${x}px`,fontWeight:n.weight,fontStyle:n.italic?"italic":void 0,lineHeight:void 0===w?void 0:String(w/100),letterSpacing:void 0===S?void 0:`${S}px`,color:v,textTransform:N?Q[N]:void 0},$=e=>{const t=W[e],s=g(e);/* @__PURE__ */
20
- return z("div",{className:"es-ts-slider","data-ts-setting":e,children:/* @__PURE__ */z(a,{label:c.settings[e],value:h[e],onChange:n=>f({[e]:n}),min:t.min,max:t.max,step:t.step,shiftStep:t.shiftStep,sliderMin:t.sliderMin,sliderMax:t.sliderMax,unit:t.unit||void 0,styleValue:s?void 0:n[e],auto:s?c.auto:void 0,readOnly:m})},e)};/* @__PURE__ */
21
- return C(O,{children:[
22
- /* @__PURE__ */z("div",{className:"es-ts-preview",style:M,"aria-label":c.preview,children:d}),l.map(t=>{switch(t){case"font":/* @__PURE__ */
23
- return z(ne,{value:h.font,fonts:s,words:c,readOnly:m,set:f},t);case"color":/* @__PURE__ */
24
- return z(te,{value:h.color,hex:v,colours:i,words:c,readOnly:m,set:f},t);case"emphasis":{const e=(n.weight??400)>=600,s=!1!==p?.italic;/* @__PURE__ */
25
- return C("div",{className:"es-ts-set","data-ts-setting":t,children:[
26
- /* @__PURE__ */z("span",{className:"es-ts-sub",children:c.settings.emphasis}),
27
- /* @__PURE__ */C("div",{className:"es-ts-icons",children:[r(c.bold,/* @__PURE__ */z(u,{className:"es-ts-icon","aria-label":c.bold,"aria-pressed":e,disabled:m,onClick:()=>f({weight:e?400:700}),children:/* @__PURE__ */z(k,{size:16})})),m||s?r(c.italic,/* @__PURE__ */z(u,{className:"es-ts-icon","aria-label":c.italic,"aria-pressed":Boolean(n.italic),disabled:m,onClick:()=>f({italic:!n.italic||void 0}),children:/* @__PURE__ */z(b,{size:16})})):/* @__PURE__ */z(u,{className:"es-ts-icon","aria-label":c.italic,"aria-pressed":Boolean(n.italic),"aria-disabled":!0,disabledReason:c.italicMissing,children:/* @__PURE__ */z(b,{size:16})})]})]},t)}case"letterCase":/* @__PURE__ */
28
- return z(se,{value:h.letterCase??n.letterCase,auto:g("letterCase"),words:c,readOnly:m,set:f},t);case"largestSize":return"heading"===e.kind?$(t):null;default:return $(t)}})]})}function ne({value:e,fonts:n,words:t,readOnly:s,set:a}){const l=h();/* @__PURE__ */
29
- return C("div",{className:"es-ts-set","data-ts-setting":"font",children:[
30
- /* @__PURE__ */z("span",{className:"es-ts-sub",id:l,children:t.settings.font}),
31
- /* @__PURE__ */z(i,{value:e,options:n.map(e=>({label:e.label,value:e.value})),onChange:e=>a({font:e}),ariaLabelledBy:l,readOnly:s})]})}function te({value:e,hex:n,colours:t,words:s,readOnly:a,set:i}){/* @__PURE__ */
32
- return z(P,{value:e,hex:n,colours:t,label:s.settings.color,followsWord:s.colour.follows,anyWord:s.colour.any,readOnly:a,onChange:e=>i({color:e})})}function se({value:e,auto:n,words:t,readOnly:s,set:a}){const i=n?["auto","none","upper","capitalize","lower"]:["none","upper","capitalize","lower"],l=e??(n?"auto":"none"),o=f([]),d=e=>a({letterCase:"auto"===e?void 0:e});/* @__PURE__ */
33
- return C("div",{className:"es-ts-set","data-ts-setting":"letterCase",children:[
34
- /* @__PURE__ */z("span",{className:"es-ts-sub",children:t.settings.letterCase}),
35
- /* @__PURE__ */z("div",{className:"es-ts-icons",role:"radiogroup","aria-label":t.settings.letterCase,onKeyDown:e=>{const n="ArrowRight"===e.key||"ArrowDown"===e.key?1:"ArrowLeft"===e.key||"ArrowUp"===e.key?-1:0;if(!n||s)return;e.preventDefault();const t=(i.indexOf(l)+n+i.length)%i.length;d(i[t]),o.current[t]?.focus()},children:i.map((e,n)=>{const a=e===l;if("auto"===e)return r(t.case.autoTitle,/* @__PURE__ */z(u,{ref:e=>{o.current[n]=e},role:"radio",pressed:a,className:"es-ts-icon es-ts-icon--word","aria-checked":a,"aria-label":t.case.auto,tabIndex:a?0:-1,disabled:s,onClick:()=>d(e),children:t.case.auto},e));const i=J[e];return r(t.case[e],/* @__PURE__ */z(u,{ref:e=>{o.current[n]=e},role:"radio",pressed:a,className:"es-ts-icon","aria-checked":a,"aria-label":t.case[e],tabIndex:a?0:-1,disabled:s,onClick:()=>d(e),children:/* @__PURE__ */z(i,{size:16})},e))})})]})}export{$ as CAMPAIGN_TEXT_STYLE_SETTINGS,P as ColourSwatchRow,F as TEXT_STYLE_DEFAULT_COUNT,A as TEXT_STYLE_KINDS,j as TEXT_STYLE_MAX,W as TEXT_STYLE_RANGES,M as TEXT_STYLE_SETTINGS,K as TextStyleItem,U as TextStylesGroup,_ as TextStylesList,R as addTextStyle,B as canAddTextStyle,L as defaultTextStyles,q as describeTextStyle,I as isDefaultTextStyle,T as removeTextStyle,V as resolveTextStyle,Y as textStyleRowSize,X as updateTextStyle,Z as weightWord};
1
+ import{hexReadout as e,ColourWindow as s,typedHex as t}from"../chunk-5XUMLKQF.js";import{DEFAULT_TEXT_STYLES_WORDS as a}from"../chunk-OGH6CC3E.js";export{DEFAULT_TEXT_STYLES_WORDS}from"../chunk-OGH6CC3E.js";import"../chunk-643PVCEG.js";import{FieldSlider as l}from"../chunk-XWFH2NHZ.js";import{TEXT_STYLE_KINDS as n,canAddTextStyle as i,TEXT_STYLE_MAX as r,isDefaultTextStyle as o,CAMPAIGN_TEXT_STYLE_SETTINGS as c,TEXT_STYLE_SETTINGS as d,textStyleRowSize as u,describeTextStyle as m,updateTextStyle as h,textStyleCaseCss as f,TEXT_STYLE_CASES as p,addTextStyle as v,removeTextStyle as y,TEXT_STYLE_RANGES as S}from"../chunk-YHZSBL2N.js";export{CAMPAIGN_TEXT_STYLE_SETTINGS,TEXT_STYLE_CASES,TEXT_STYLE_CASE_CSS,TEXT_STYLE_DEFAULT_COUNT,TEXT_STYLE_KINDS,TEXT_STYLE_MAX,TEXT_STYLE_RANGES,TEXT_STYLE_SETTINGS,addTextStyle,canAddTextStyle,defaultTextStyles,describeTextStyle,isDefaultTextStyle,isTextStyleCase,removeTextStyle,resolveTextStyle,textStyleCaseCss,textStyleCaseOfCss,textStyleRowSize,updateTextStyle,weightWord}from"../chunk-YHZSBL2N.js";import{FieldSelect as g}from"../chunk-G3GWAP5R.js";import"../chunk-WRFD4EXD.js";import{useWords as b}from"../chunk-MFIRYGHW.js";import{withTip as N}from"../chunk-P2VEMZH5.js";import{hsvToHex as k,Tooltip as C,ColorSwatch as T,IconButton as x}from"efficient-shell/ui";import{useState as w,useRef as E,useId as O,useEffect as _,Fragment as z}from"react";import{TrashIcon as L,ChevronIcon as A,BoldIcon as j,ItalicIcon as X,CaseLowerIcon as $,CaseCapitalizedIcon as W,CaseUpperIcon as Y,CaseNormalIcon as D}from"efficient-shell/icons/efficient";import{jsxs as G,jsx as I,Fragment as M}from"react/jsx-runtime";var F=`conic-gradient(${[0,60,120,180,240,300,0].map(e=>k({h:e,s:1,v:1})).join(", ")})`;function H({value:t,hex:a,colours:l,label:n,followsWord:i,anyWord:r,onChange:o,readOnly:c=!1}){const[d,u]=w(!1),m=E(null),h=E(null),f=O(),p=void 0!==t&&l.some(e=>e.key===t),v=void 0!==t&&!p;return _(()=>{if(!d)return;const e=m.current?.ownerDocument;if(!e)return;const s=e=>{m.current&&!m.current.contains(e.target)&&u(!1)};return e.addEventListener("click",s,!0),()=>e.removeEventListener("click",s,!0)},[d]),/* @__PURE__ */G("div",{ref:m,className:"es-ts-set","data-ts-setting":"color",children:[
2
+ /* @__PURE__ */G("div",{className:"es-ts-top",children:[
3
+ /* @__PURE__ */I("span",{className:"es-ts-sub",children:n}),
4
+ /* @__PURE__ */I("span",{className:"es-ts-colour-read",children:a?e(a):i})]}),
5
+ /* @__PURE__ */G("div",{className:"es-ts-swatches",role:"group","aria-label":n,children:[l.map(s=>/* @__PURE__ */I(C,{content:`${s.name} · ${e(s.value)}`,children:/* @__PURE__ */I(T,{color:s.value,size:"sm",className:"es-ts-swatch","aria-label":s.name,selected:t===s.key,disabled:c,onClick:()=>o(s.key)})},s.key)),
6
+ /* @__PURE__ */I(C,{content:r,children:/* @__PURE__ */I(T,{ref:h,color:F,size:"sm",className:"es-ts-swatch es-ts-swatch--any","aria-label":r,selected:v,"aria-expanded":d,"aria-controls":d?f:void 0,disabled:c,onClick:()=>u(e=>!e)})})]}),d?/* @__PURE__ */I(s,{id:f,value:a??"",onChange:e=>o(e),label:n,readOnly:c,onClose:()=>{u(!1),h.current?.focus()}}):null]})}function R({styles:e,onChange:s,fonts:t,colours:l=[],settings:d=c,auto:u=[],fallback:m,sample:h,openId:f,defaultOpenId:p=null,onOpenChange:S,onAdd:g,rowActions:k,onRemove:C,max:T=r,readOnly:x=!1}){const z=b("textStyles",a),A=O(),[j,X]=w(p),$=void 0!==f?f:j,W=e=>{void 0===f&&X(e),S?.(e)},Y=E(null),[D,F]=w(null);_(()=>{if(!D||!Y.current)return;const e=[...Y.current.querySelectorAll(".es-ts-item")].find(e=>e.dataset.tsId===D.id),s=e?e.querySelector(".es-ts-row"):Y.current.querySelector(`.es-ts-add[data-ts-kind="${D.kind}"]`);s?.focus(),F(null)},[D]);/* @__PURE__ */
7
+ return I("div",{className:"es-ts",ref:Y,children:n.map(a=>{const n=e.filter(e=>e.kind===a),r=!i(e,a,T),c=!x&&!r;/* @__PURE__ */
8
+ return G(B,{label:z.groups[a],children:[n.map(a=>{const n=k?.(a),i=null!=n&&!1!==n,r=Boolean(C)&&!x&&!o(a);/* @__PURE__ */
9
+ return I(U,{style:a,fonts:t,colours:l,settings:d,auto:u,fallback:m,sample:h,readOnly:x,open:$===a.id,onOpenChange:e=>W(e?a.id:null),onChange:t=>s(e.map(e=>e.id===t.id?t:e)),actions:r||i?/* @__PURE__ */G(M,{children:[r?N(z.remove,/* @__PURE__ */I("button",{type:"button",className:"es-ts-del","aria-label":z.removeNamed({name:a.name}),onClick:()=>(t=>{if(x||!C)return;const a=y(e,t.id,{name:z.styleName});if(!a)return;const l=e.filter(e=>e.kind===t.kind),n=l[l.indexOf(t)+1];$===t.id&&W(null),s(a.styles),C(a.removed),F({id:n?.id??null,kind:t.kind})})(a),children:/* @__PURE__ */I(L,{size:14,"aria-hidden":"true"})})):null,i?n:null]}):null},a.id)}),N(!x&&r?z.full({kind:a,max:T}):void 0,/* @__PURE__ */G("button",{type:"button",className:"es-ts-add","data-ts-kind":a,disabled:x,"aria-disabled":!(x||!r)||void 0,"aria-describedby":!x&&r?`${A}-full-${a}`:void 0,onClick:()=>{c&&(t=>{if(x)return;const a=v(e,t,{max:T,name:z.styleName,make:g});a&&s(a.styles)})(a)},children:[
10
+ /* @__PURE__ */I("span",{className:"es-ts-add-word",children:z.add[a]}),
11
+ /* @__PURE__ */I("span",{className:"es-ts-count",children:z.count({n:n.length,max:T})})]})),x||!r?null:/* @__PURE__ */I("span",{id:`${A}-full-${a}`,className:"es-vh",children:z.full({kind:a,max:T})})]},a)})})}function B({label:e,children:s}){const t=O();/* @__PURE__ */
12
+ return G("section",{className:"es-ts-section","aria-labelledby":t,children:[
13
+ /* @__PURE__ */I("div",{className:"es-ts-group",id:t,children:e}),s]})}function U({style:e,fonts:s,colours:t=[],settings:l=c,auto:n=[],fallback:i,sample:r,open:o,onOpenChange:f,onChange:p,actions:v,readOnly:y=!1}){const S=b("textStyles",a),g=`${O()}-open-${e.id}`,N=new Set(n),k=d.filter(e=>l.includes(e)),C={...i?.(e)??{},...e.values},T=s.find(e=>e.value===C.font),x={fontFamily:T?.family,fontSize:`${u(C.size??16)}px`,fontWeight:C.weight,fontStyle:C.italic?"italic":void 0};/* @__PURE__ */
14
+ return G(z,{children:[
15
+ /* @__PURE__ */G("div",{className:"es-ts-item","data-ts-id":e.id,children:[
16
+ /* @__PURE__ */G("button",{type:"button",className:"es-ts-row","aria-expanded":o,"aria-controls":o?g:void 0,onClick:()=>f(!o),children:[
17
+ /* @__PURE__ */I("span",{className:"es-ts-chev","aria-hidden":"true",children:/* @__PURE__ */I(A,{size:12})}),
18
+ /* @__PURE__ */I("span",{className:"es-ts-name",style:x,children:e.name}),
19
+ /* @__PURE__ */I("span",{className:"es-ts-meta",children:m(C,s,S,{autoSize:N.has("size")&&void 0===e.values.size})})]}),v?/* @__PURE__ */I("div",{className:"es-ts-actions",children:v}):null]}),o?/* @__PURE__ */I("div",{className:"es-ts-open",id:g,children:/* @__PURE__ */I(Z,{style:e,values:C,fonts:s,colours:t,settings:k,autoSet:N,sample:r??S.sample,words:S,readOnly:y,set:s=>p(h([e],e.id,s)[0])})}):null]})}var P={none:D,upper:Y,capitalize:W,lower:$};function Z({style:e,values:s,fonts:a,colours:n,settings:i,autoSet:r,sample:o,words:c,readOnly:d,set:u}){const m=e.values,h=a.find(e=>e.value===s.font),p=function(e,s){return e?s.find(s=>s.key===e)?.value??t(e)??void 0:void 0}(s.color,n),v=e=>"largestSize"===e||r.has(e),y=e=>v(e)?m[e]:s[e],g=y("size"),b=y("lineSpacing"),k=y("letterSpacing"),C=v("letterCase")?m.letterCase:s.letterCase,T={fontFamily:h?.family,fontSize:void 0===g?void 0:`${g}px`,fontWeight:s.weight,fontStyle:s.italic?"italic":void 0,lineHeight:void 0===b?void 0:String(b/100),letterSpacing:void 0===k?void 0:`${k}px`,color:p,textTransform:f(C)},w=e=>{const t=S[e],a=v(e);/* @__PURE__ */
20
+ return I("div",{className:"es-ts-slider","data-ts-setting":e,children:/* @__PURE__ */I(l,{label:c.settings[e],value:m[e],onChange:s=>u({[e]:s}),min:t.min,max:t.max,step:t.step,shiftStep:t.shiftStep,sliderMin:t.sliderMin,sliderMax:t.sliderMax,unit:t.unit||void 0,styleValue:a?void 0:s[e],auto:a?c.auto:void 0,readOnly:d})},e)};/* @__PURE__ */
21
+ return G(M,{children:[
22
+ /* @__PURE__ */I("div",{className:"es-ts-preview",style:T,"aria-label":c.preview,children:o}),i.map(t=>{switch(t){case"font":/* @__PURE__ */
23
+ return I(q,{value:m.font,fonts:a,words:c,readOnly:d,set:u},t);case"color":/* @__PURE__ */
24
+ return I(K,{value:m.color,hex:p,colours:n,words:c,readOnly:d,set:u},t);case"emphasis":{const e=(s.weight??400)>=600,a=!1!==h?.italic;/* @__PURE__ */
25
+ return G("div",{className:"es-ts-set","data-ts-setting":t,children:[
26
+ /* @__PURE__ */I("span",{className:"es-ts-sub",children:c.settings.emphasis}),
27
+ /* @__PURE__ */G("div",{className:"es-ts-icons",children:[N(c.bold,/* @__PURE__ */I(x,{className:"es-ts-icon","aria-label":c.bold,"aria-pressed":e,disabled:d,onClick:()=>u({weight:e?400:700}),children:/* @__PURE__ */I(j,{size:16})})),d||a?N(c.italic,/* @__PURE__ */I(x,{className:"es-ts-icon","aria-label":c.italic,"aria-pressed":Boolean(s.italic),disabled:d,onClick:()=>u({italic:!s.italic||void 0}),children:/* @__PURE__ */I(X,{size:16})})):/* @__PURE__ */I(x,{className:"es-ts-icon","aria-label":c.italic,"aria-pressed":Boolean(s.italic),"aria-disabled":!0,disabledReason:c.italicMissing,children:/* @__PURE__ */I(X,{size:16})})]})]},t)}case"letterCase":/* @__PURE__ */
28
+ return I(V,{value:m.letterCase??s.letterCase,auto:v("letterCase"),words:c,readOnly:d,set:u},t);case"largestSize":return"heading"===e.kind?w(t):null;default:return w(t)}})]})}function q({value:e,fonts:s,words:t,readOnly:a,set:l}){const n=O();/* @__PURE__ */
29
+ return G("div",{className:"es-ts-set","data-ts-setting":"font",children:[
30
+ /* @__PURE__ */I("span",{className:"es-ts-sub",id:n,children:t.settings.font}),
31
+ /* @__PURE__ */I(g,{value:e,options:s.map(e=>({label:e.label,value:e.value})),onChange:e=>l({font:e}),ariaLabelledBy:n,readOnly:a})]})}function K({value:e,hex:s,colours:t,words:a,readOnly:l,set:n}){/* @__PURE__ */
32
+ return I(H,{value:e,hex:s,colours:t,label:a.settings.color,followsWord:a.colour.follows,anyWord:a.colour.any,readOnly:l,onChange:e=>n({color:e})})}function V({value:e,auto:s,words:t,readOnly:a,set:l}){const n=s?["auto",...p]:p,i=e??(s?"auto":"none"),r=E([]),o=e=>l({letterCase:"auto"===e?void 0:e});/* @__PURE__ */
33
+ return G("div",{className:"es-ts-set","data-ts-setting":"letterCase",children:[
34
+ /* @__PURE__ */I("span",{className:"es-ts-sub",children:t.settings.letterCase}),
35
+ /* @__PURE__ */I("div",{className:"es-ts-icons",role:"radiogroup","aria-label":t.settings.letterCase,onKeyDown:e=>{const s="ArrowRight"===e.key||"ArrowDown"===e.key?1:"ArrowLeft"===e.key||"ArrowUp"===e.key?-1:0;if(!s||a)return;e.preventDefault();const t=(n.indexOf(i)+s+n.length)%n.length;o(n[t]),r.current[t]?.focus()},children:n.map((e,s)=>{const l=e===i;if("auto"===e)return N(t.case.autoTitle,/* @__PURE__ */I(x,{ref:e=>{r.current[s]=e},role:"radio",pressed:l,className:"es-ts-icon es-ts-icon--word","aria-checked":l,"aria-label":t.case.auto,tabIndex:l?0:-1,disabled:a,onClick:()=>o(e),children:t.case.auto},e));const n=P[e];return N(t.case[e],/* @__PURE__ */I(x,{ref:e=>{r.current[s]=e},role:"radio",pressed:l,className:"es-ts-icon","aria-checked":l,"aria-label":t.case[e],tabIndex:l?0:-1,disabled:a,onClick:()=>o(e),children:/* @__PURE__ */I(n,{size:16})},e))})})]})}export{H as ColourSwatchRow,U as TextStyleItem,B as TextStylesGroup,R as TextStylesList};