@motion-proto/live-tokens 0.3.9 → 0.5.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 (103) hide show
  1. package/package.json +9 -8
  2. package/src/component-editor/BadgeEditor.svelte +24 -22
  3. package/src/component-editor/CalloutEditor.svelte +3 -3
  4. package/src/component-editor/CardEditor.svelte +25 -21
  5. package/src/component-editor/CollapsibleSectionEditor.svelte +27 -25
  6. package/src/component-editor/CornerBadgeEditor.svelte +37 -35
  7. package/src/component-editor/DialogEditor.svelte +26 -24
  8. package/src/component-editor/ImageEditor.svelte +11 -9
  9. package/src/component-editor/InlineEditActionsEditor.svelte +17 -15
  10. package/src/component-editor/NotificationEditor.svelte +32 -30
  11. package/src/component-editor/ProgressBarEditor.svelte +3 -3
  12. package/src/component-editor/RadioButtonEditor.svelte +31 -29
  13. package/src/component-editor/SectionDividerEditor.svelte +30 -28
  14. package/src/component-editor/SegmentedControlEditor.svelte +29 -25
  15. package/src/component-editor/StandardButtonsEditor.svelte +42 -38
  16. package/src/component-editor/TabBarEditor.svelte +20 -18
  17. package/src/component-editor/TableEditor.svelte +4 -4
  18. package/src/component-editor/TooltipEditor.svelte +11 -9
  19. package/src/component-editor/registry.ts +2 -2
  20. package/src/component-editor/scaffolding/AngleDial.svelte +20 -19
  21. package/src/component-editor/scaffolding/ComponentEditorBase.svelte +44 -20
  22. package/src/component-editor/scaffolding/ComponentFileManager.svelte +260 -37
  23. package/src/component-editor/scaffolding/ComponentFileMenu.svelte +41 -29
  24. package/src/component-editor/scaffolding/ComponentsTab.svelte +7 -3
  25. package/src/component-editor/scaffolding/CopyFromMenu.svelte +21 -12
  26. package/src/component-editor/scaffolding/DemoHeader.svelte +13 -4
  27. package/src/component-editor/scaffolding/DividerEditor.svelte +27 -14
  28. package/src/component-editor/scaffolding/FieldsetWrapper.svelte +10 -4
  29. package/src/component-editor/scaffolding/GradientCard.svelte +25 -20
  30. package/src/component-editor/scaffolding/LinkageChart.svelte +43 -34
  31. package/src/component-editor/scaffolding/LinkedBlock.svelte +24 -21
  32. package/src/component-editor/scaffolding/NonStylableConfig.svelte +6 -1
  33. package/src/component-editor/scaffolding/SaveAsDialog.svelte +39 -35
  34. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +21 -9
  35. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +8 -3
  36. package/src/component-editor/scaffolding/StateBlock.svelte +30 -13
  37. package/src/component-editor/scaffolding/TokenLayout.svelte +46 -30
  38. package/src/component-editor/scaffolding/TypeEditor.svelte +52 -26
  39. package/src/component-editor/scaffolding/VariantGroup.svelte +81 -48
  40. package/src/component-editor/scaffolding/componentSectionType.ts +2 -2
  41. package/src/components/Badge.svelte +45 -26
  42. package/src/components/Button.svelte +44 -21
  43. package/src/components/Callout.svelte +17 -12
  44. package/src/components/Card.svelte +23 -11
  45. package/src/components/CollapsibleSection.svelte +56 -27
  46. package/src/components/CornerBadge.svelte +32 -18
  47. package/src/components/Dialog.svelte +55 -31
  48. package/src/components/Image.svelte +14 -5
  49. package/src/components/InlineEditActions.svelte +22 -10
  50. package/src/components/Notification.svelte +39 -19
  51. package/src/components/ProgressBar.svelte +27 -17
  52. package/src/components/RadioButton.svelte +27 -10
  53. package/src/components/SectionDivider.svelte +34 -26
  54. package/src/components/SegmentedControl.svelte +23 -9
  55. package/src/components/TabBar.svelte +23 -10
  56. package/src/components/Table.svelte +8 -3
  57. package/src/components/Tooltip.svelte +15 -5
  58. package/src/lib/ColumnsOverlay.svelte +3 -3
  59. package/src/lib/LiveEditorOverlay.svelte +57 -36
  60. package/src/pages/ComponentEditorPage.svelte +17 -13
  61. package/src/pages/EditorShell.svelte +24 -20
  62. package/src/styles/form-controls.css +2 -2
  63. package/src/styles/tokens.css +59 -81
  64. package/src/ui/BezierCurveEditor.svelte +59 -43
  65. package/src/ui/ColorEditPanel.svelte +71 -44
  66. package/src/ui/EditorViewSwitcher.svelte +9 -5
  67. package/src/ui/FontStackEditor.svelte +16 -15
  68. package/src/ui/GradientEditor.svelte +42 -33
  69. package/src/ui/GradientStopPicker.svelte +18 -29
  70. package/src/ui/PaletteEditor.svelte +238 -212
  71. package/src/ui/PresetFileManager.svelte +20 -18
  72. package/src/ui/ProjectFontsSection.svelte +30 -30
  73. package/src/ui/SurfacesTab.svelte +3 -3
  74. package/src/ui/TextTab.svelte +2 -2
  75. package/src/ui/ThemeFileManager.svelte +38 -35
  76. package/src/ui/Toggle.svelte +11 -9
  77. package/src/ui/UICopyPopover.svelte +19 -15
  78. package/src/ui/UIDialog.svelte +48 -30
  79. package/src/ui/UIFontFamilySelector.svelte +104 -78
  80. package/src/ui/UIFontSizeSelector.svelte +38 -20
  81. package/src/ui/UIFontWeightSelector.svelte +33 -13
  82. package/src/ui/UILineHeightSelector.svelte +33 -13
  83. package/src/ui/UILinkToggle.svelte +7 -6
  84. package/src/ui/UIOptionItem.svelte +21 -7
  85. package/src/ui/UIOptionList.svelte +9 -3
  86. package/src/ui/UIPaddingSelector.svelte +108 -82
  87. package/src/ui/UIPaletteSelector.svelte +186 -161
  88. package/src/ui/UIRadio.svelte +23 -8
  89. package/src/ui/UIRadioGroup.svelte +9 -8
  90. package/src/ui/UIRelinkConfirmPopover.svelte +26 -16
  91. package/src/ui/UITokenSelector.svelte +112 -68
  92. package/src/ui/UIVariantSelector.svelte +79 -57
  93. package/src/ui/VariablesTab.svelte +15 -15
  94. package/src/ui/palette/GradientStopEditor.svelte +45 -26
  95. package/src/ui/palette/OverridesPanel.svelte +85 -49
  96. package/src/ui/palette/PaletteBase.svelte +60 -32
  97. package/src/ui/palette/ScaleCurveEditor.svelte +25 -10
  98. package/src/ui/sections/ColumnsSection.svelte +13 -13
  99. package/src/ui/sections/GradientsSection.svelte +12 -9
  100. package/src/ui/sections/OverlaysSection.svelte +50 -47
  101. package/src/ui/sections/ShadowsSection.svelte +110 -104
  102. package/src/ui/sections/TokenScaleTable.svelte +38 -22
  103. package/src/ui/sections/tokenScales.ts +2 -2
@@ -1,43 +1,26 @@
1
1
  <script lang="ts">
2
- import { createEventDispatcher } from 'svelte';
2
+ import { run } from 'svelte/legacy';
3
+
3
4
  import type { ComponentConfigMeta } from '../../lib/themeTypes';
4
5
  import { sanitizeFileName } from '../../lib/themeService';
5
6
  import UIDialog from '../../ui/UIDialog.svelte';
6
7
 
7
- /** Two-way bound: parent toggles to open/close. */
8
- export let show: boolean = false;
9
- /** Display name to seed the input with when the dialog opens. */
10
- export let currentDisplayName: string = '';
11
- /** Existing files used by the increment helper to find the next available `_NN` suffix. */
12
- export let files: ComponentConfigMeta[] = [];
8
+ interface Props {
9
+ /** Two-way bound: parent toggles to open/close. */
10
+ show?: boolean;
11
+ /** Display name to seed the input with when the dialog opens. */
12
+ currentDisplayName?: string;
13
+ /** Existing files used by the increment helper to find the next available `_NN` suffix. */
14
+ files?: ComponentConfigMeta[];
15
+ onsave?: (payload: { displayName: string; fileName: string }) => void;
16
+ }
13
17
 
14
- const dispatch = createEventDispatcher<{
15
- save: { displayName: string; fileName: string };
16
- }>();
18
+ let { show = $bindable(false), currentDisplayName = '', files = [], onsave }: Props = $props();
17
19
 
18
- let saveAsName = '';
19
- let saveAsInput: HTMLInputElement;
20
+ let saveAsName = $state('');
21
+ let saveAsInput: HTMLInputElement | undefined = $state();
20
22
 
21
- // Seed and select the input whenever the dialog opens. setTimeout(..., 0)
22
- // matches the original parent's behaviour: it runs as a macrotask, after
23
- // UIDialog's microtask-queued focus on the confirm button — so the input
24
- // ends up focused-and-selected, not the button.
25
- $: if (show) {
26
- saveAsName =
27
- sanitizeFileName(currentDisplayName) === 'default'
28
- ? nextIncrementName(currentDisplayName).displayName
29
- : currentDisplayName;
30
- setTimeout(() => saveAsInput?.select(), 0);
31
- }
32
23
 
33
- $: saveAsError = (() => {
34
- const trimmed = saveAsName.trim();
35
- if (!trimmed) return '';
36
- if (sanitizeFileName(trimmed) === 'default') {
37
- return 'The name "default" is reserved for the core component definition.';
38
- }
39
- return '';
40
- })();
41
24
 
42
25
  function nextIncrementName(baseDisplay: string): { displayName: string; fileName: string } {
43
26
  const baseName = baseDisplay.replace(/_\d+$/, '');
@@ -67,12 +50,33 @@
67
50
  if (!displayName || saveAsError) return;
68
51
  const fileName = sanitizeFileName(displayName);
69
52
  show = false;
70
- dispatch('save', { displayName, fileName });
53
+ onsave?.({ displayName, fileName });
71
54
  }
72
55
 
73
56
  function handleKeydown(e: KeyboardEvent) {
74
57
  if (e.key === 'Enter') confirmSaveAs();
75
58
  }
59
+ // Seed and select the input whenever the dialog opens. setTimeout(..., 0)
60
+ // matches the original parent's behaviour: it runs as a macrotask, after
61
+ // UIDialog's microtask-queued focus on the confirm button — so the input
62
+ // ends up focused-and-selected, not the button.
63
+ run(() => {
64
+ if (show) {
65
+ saveAsName =
66
+ sanitizeFileName(currentDisplayName) === 'default'
67
+ ? nextIncrementName(currentDisplayName).displayName
68
+ : currentDisplayName;
69
+ setTimeout(() => saveAsInput?.select(), 0);
70
+ }
71
+ });
72
+ let saveAsError = $derived((() => {
73
+ const trimmed = saveAsName.trim();
74
+ if (!trimmed) return '';
75
+ if (sanitizeFileName(trimmed) === 'default') {
76
+ return 'The name "default" is reserved for the core component definition.';
77
+ }
78
+ return '';
79
+ })());
76
80
  </script>
77
81
 
78
82
  <UIDialog
@@ -81,7 +85,7 @@
81
85
  cancelLabel="Cancel"
82
86
  confirmLabel="Save"
83
87
  confirmDisabled={!saveAsName.trim() || !!saveAsError}
84
- on:confirm={confirmSaveAs}
88
+ onconfirm={confirmSaveAs}
85
89
  width="360px"
86
90
  >
87
91
  <div class="save-as-dialog">
@@ -92,13 +96,13 @@
92
96
  type="text"
93
97
  bind:value={saveAsName}
94
98
  bind:this={saveAsInput}
95
- on:keydown={handleKeydown}
99
+ onkeydown={handleKeydown}
96
100
  placeholder="Config name…"
97
101
  />
98
102
  <button
99
103
  type="button"
100
104
  class="save-as-increment"
101
- on:click={incrementSaveAsName}
105
+ onclick={incrementSaveAsName}
102
106
  title="Increment filename"
103
107
  >
104
108
  <i class="fas fa-plus"></i>
@@ -1,20 +1,32 @@
1
1
  <script lang="ts">
2
2
  import newspaperBg from '../../assets/newspaper.webp';
3
3
 
4
- export let mode: 'image' | 'color' = 'image';
5
- /** CSS var name (set by ShadowBackdropControls) the backdrop reads when in color mode. */
6
- export let colorVariable: string;
7
- /** Padding around the slotted preview. Set to '0' when the slotted component should cover the full backdrop area (e.g. dialog overlay). */
8
- export let padding: string = '128px';
4
+
5
+
6
+ interface Props {
7
+ mode?: 'image' | 'color';
8
+ /** CSS var name (set by ShadowBackdropControls) the backdrop reads when in color mode. */
9
+ colorVariable: string;
10
+ /** Padding around the slotted preview. Set to '0' when the slotted component should cover the full backdrop area (e.g. dialog overlay). */
11
+ padding?: string;
12
+ children?: import('svelte').Snippet;
13
+ }
14
+
15
+ let {
16
+ mode = 'image',
17
+ colorVariable,
18
+ padding = '128px',
19
+ children
20
+ }: Props = $props();
9
21
 
10
- $: backgroundStyle =
11
- mode === 'image'
22
+ let backgroundStyle =
23
+ $derived(mode === 'image'
12
24
  ? `padding: ${padding}; background-image: url(${newspaperBg}); background-size: cover; background-position: center; background-repeat: no-repeat;`
13
- : `padding: ${padding}; background: var(${colorVariable}, #1a1a1a);`;
25
+ : `padding: ${padding}; background: var(${colorVariable}, #1a1a1a);`);
14
26
  </script>
15
27
 
16
28
  <div class="shadow-backdrop" style={backgroundStyle}>
17
- <slot />
29
+ {@render children?.()}
18
30
  </div>
19
31
 
20
32
  <style>
@@ -5,9 +5,14 @@
5
5
  import { setCssVar } from '../../lib/cssVarSync';
6
6
 
7
7
  type Mode = 'image' | 'color';
8
- export let mode: Mode = 'image';
9
- /** Editor-scoped CSS var the picker writes to (must end with `-surface` to allow gradients). */
10
- export let colorVariable: string;
8
+
9
+ interface Props {
10
+ mode?: Mode;
11
+ /** Editor-scoped CSS var the picker writes to (must end with `-surface` to allow gradients). */
12
+ colorVariable: string;
13
+ }
14
+
15
+ let { mode = $bindable('image'), colorVariable }: Props = $props();
11
16
 
12
17
  const options: ReadonlyArray<{ value: Mode; label: string }> = [
13
18
  { value: 'image', label: 'Image' },
@@ -12,21 +12,38 @@
12
12
  import TypeEditor from './TypeEditor.svelte';
13
13
  import type { Token, TypeGroupConfig } from './types';
14
14
 
15
- /** Tokens for this state, fed to `<TokenLayout>`. */
16
- export let tokens: Token[];
17
- /** Type groups for this state; rendered as a row of `<TypeEditor>` blocks. */
18
- export let typeGroups: TypeGroupConfig[] = [];
19
- /** Forwarded to TypeEditor and TokenLayout so writes persist through the editor store. */
20
- export let component: string | undefined = undefined;
21
- /** Per-variable rank passed through to TokenLayout for linked-block alignment. */
22
- export let linkedOrder: Map<string, number> | undefined = undefined;
23
- /** Render the token grid with N visual columns. >1 spreads a long property
15
+
16
+
17
+
18
+
19
+
20
+ interface Props {
21
+ /** Tokens for this state, fed to `<TokenLayout>`. */
22
+ tokens: Token[];
23
+ /** Type groups for this state; rendered as a row of `<TypeEditor>` blocks. */
24
+ typeGroups?: TypeGroupConfig[];
25
+ /** Forwarded to TypeEditor and TokenLayout so writes persist through the editor store. */
26
+ component?: string | undefined;
27
+ /** Per-variable rank passed through to TokenLayout for linked-block alignment. */
28
+ linkedOrder?: Map<string, number> | undefined;
29
+ /** Render the token grid with N visual columns. >1 spreads a long property
24
30
  list horizontally; only meaningful for state-blocks without typeGroups
25
31
  (the two-col flex layout already partitions screen real estate when
26
32
  typeGroups are present). */
27
- export let columns: number = 1;
33
+ columns?: number;
34
+ onchange?: () => void;
35
+ }
36
+
37
+ let {
38
+ tokens,
39
+ typeGroups = [],
40
+ component = undefined,
41
+ linkedOrder = undefined,
42
+ columns = 1,
43
+ onchange,
44
+ }: Props = $props();
28
45
 
29
- $: hasTypeGroups = typeGroups.length > 0;
46
+ let hasTypeGroups = $derived(typeGroups.length > 0);
30
47
  </script>
31
48
 
32
49
  <div class="state-controls" class:two-col={hasTypeGroups}>
@@ -50,7 +67,7 @@
50
67
  outlineColorVariable={tg.outlineColorVariable}
51
68
  outlineColorLabel={tg.outlineColorLabel ?? 'outline color'}
52
69
  {component}
53
- on:change
70
+ {onchange}
54
71
  />
55
72
  {/each}
56
73
  </div>
@@ -61,7 +78,7 @@
61
78
  {component}
62
79
  {linkedOrder}
63
80
  {columns}
64
- on:change
81
+ {onchange}
65
82
  />
66
83
  </div>
67
84
 
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { createEventDispatcher, type ComponentType } from 'svelte';
2
+ import type { Component } from 'svelte';
3
3
  import UIPaletteSelector from '../../ui/UIPaletteSelector.svelte';
4
4
  import UIVariantSelector from '../../ui/UIVariantSelector.svelte';
5
5
  import UIFontFamilySelector from '../../ui/UIFontFamilySelector.svelte';
@@ -40,21 +40,40 @@
40
40
 
41
41
  type Entry = { kind: Kind; token: Token };
42
42
 
43
- export let title: string = '';
44
- export let tokens: Token[];
45
- /** Forwarded to each selector; when set, writes persist through the editor store. */
46
- export let component: string | undefined = undefined;
47
- /** Optional context labels per variable (shown below the selector). */
48
- export let contexts: Record<string, string[]> = {};
49
- /** Per-variable rank that overrides kind rank when sorting; lets linked tokens align with the top linked row. */
50
- export let linkedOrder: Map<string, number> | undefined = undefined;
51
- /** Set true on the linked-block instance so dimmed variant rows can scroll/flash to the matching anchor. */
52
- export let isLinkedBlock: boolean = false;
53
- /** Number of visual columns. >1 switches to a column-major grid (grid-auto-flow: column)
43
+
44
+
45
+
46
+
47
+
48
+ interface Props {
49
+ title?: string;
50
+ tokens: Token[];
51
+ /** Forwarded to each selector; when set, writes persist through the editor store. */
52
+ component?: string | undefined;
53
+ /** Optional context labels per variable (shown below the selector). */
54
+ contexts?: Record<string, string[]>;
55
+ /** Per-variable rank that overrides kind rank when sorting; lets linked tokens align with the top linked row. */
56
+ linkedOrder?: Map<string, number> | undefined;
57
+ /** Set true on the linked-block instance so dimmed variant rows can scroll/flash to the matching anchor. */
58
+ isLinkedBlock?: boolean;
59
+ /** Number of visual columns. >1 switches to a column-major grid (grid-auto-flow: column)
54
60
  so the consumer can spread a long property list across the available width. In
55
61
  multi-col mode, the linked-first sort + zone divider are dropped — kind-grouped flow
56
62
  reads more naturally when columns themselves carry the visual grouping. */
57
- export let columns: number = 1;
63
+ columns?: number;
64
+ onchange?: () => void;
65
+ }
66
+
67
+ let {
68
+ title = '',
69
+ tokens,
70
+ component = undefined,
71
+ contexts = {},
72
+ linkedOrder = undefined,
73
+ isLinkedBlock = false,
74
+ columns = 1,
75
+ onchange,
76
+ }: Props = $props();
58
77
 
59
78
  /** Suffix/prefix patterns mapped to kinds — single source of truth used by `categorize`.
60
79
  Order matters: `text` must run before `border`/`surface` because `--text-*` would
@@ -134,7 +153,7 @@
134
153
  /** Selector registry: one entry per kind. `extra` props (e.g. UIPaddingSelector's
135
154
  `mode`/`splittable`/`rowLabel`) are forwarded alongside the linked props. */
136
155
  type SelectorEntry = {
137
- component: ComponentType;
156
+ component: Component<any, any, any>;
138
157
  extra?: (token: Token) => Record<string, unknown>;
139
158
  /** When true, the row is rendered as a self-contained block (spans all grid columns,
140
159
  no .token-row wrapper, no contexts strip). Currently only `padding-split`. */
@@ -235,8 +254,6 @@
235
254
  return set;
236
255
  }
237
256
 
238
- const dispatch = createEventDispatcher();
239
-
240
257
  /** When a row collapses several groupKey leads into one display, mirror the lead's
241
258
  new alias onto each peer (and its siblings) so the merged display stays in sync. */
242
259
  function handleRowChange(token: Token) {
@@ -248,7 +265,7 @@
248
265
  else clearComponentAliasLinked(component, peer);
249
266
  }
250
267
  }
251
- dispatch('change');
268
+ onchange?.();
252
269
  }
253
270
 
254
271
  /** Bidirectional hover cue with the Linked-properties block. The upper grid
@@ -263,20 +280,20 @@
263
280
  hoveredLinkedVariable?.set(variable);
264
281
  }
265
282
 
266
- $: hoveredVar = !isLinkedBlock && hoveredLinkedVariable ? $hoveredLinkedVariable : null;
267
- $: isMultiCol = columns > 1;
268
- $: linkedKinds = computeLinkedKinds(component, $editorState);
269
- $: entries = buildEntries(tokens.filter((t) => !t.hidden), linkedOrder, linkedKinds, component, $editorState, isMultiCol);
283
+ let hoveredVar = $derived(!isLinkedBlock && hoveredLinkedVariable ? $hoveredLinkedVariable : null);
284
+ let isMultiCol = $derived(columns > 1);
285
+ let linkedKinds = $derived(computeLinkedKinds(component, $editorState));
286
+ let entries = $derived(buildEntries(tokens.filter((t) => !t.hidden), linkedOrder, linkedKinds, component, $editorState, isMultiCol));
270
287
  /** Index of the first independent (non-linked) entry; -1 when there are no linked entries or no boundary.
271
288
  Suppressed in multi-col mode (no divider — column structure is the grouping). */
272
- $: firstIndependentIdx = (() => {
289
+ let firstIndependentIdx = $derived((() => {
273
290
  if (isMultiCol) return -1;
274
291
  const idx = entries.findIndex((e) => !linkedKinds.has(e.kind));
275
292
  if (idx <= 0) return -1;
276
293
  return idx;
277
- })();
294
+ })());
278
295
  /** Rows per column for column-major flow; ceil so the last column may be short. */
279
- $: rowsPerCol = isMultiCol ? Math.max(1, Math.ceil(entries.length / columns)) : entries.length;
296
+ let rowsPerCol = $derived(isMultiCol ? Math.max(1, Math.ceil(entries.length / columns)) : entries.length);
280
297
 
281
298
  </script>
282
299
 
@@ -320,24 +337,23 @@
320
337
  -->
321
338
  {@const isLinkedRow = linkedKinds.has(entry.kind)}
322
339
  {@const isHovered = !isLinkedBlock && isLinkedRow && hoveredVar === token.variable}
323
- <!-- svelte-ignore a11y-no-static-element-interactions -->
340
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
324
341
  <div
325
342
  class="token-entry"
326
343
  class:token-row={!sel.standalone}
327
344
  class:has-contexts={!sel.standalone && !!ctxs?.length}
328
345
  class:linked-hovered={isHovered}
329
346
  class:non-first-set={isNonFirstSet}
330
- on:mouseenter={isLinkedBlock || !isLinkedRow ? undefined : () => setHover(token.variable)}
331
- on:mouseleave={isLinkedBlock || !isLinkedRow ? undefined : () => setHover(null)}
347
+ onmouseenter={isLinkedBlock || !isLinkedRow ? undefined : () => setHover(token.variable)}
348
+ onmouseleave={isLinkedBlock || !isLinkedRow ? undefined : () => setHover(null)}
332
349
  >
333
350
  {#if !sel.standalone}
334
351
  <span class="token-label">{token.label}</span>
335
352
  {/if}
336
- <svelte:component
337
- this={sel.component}
353
+ <sel.component
338
354
  {...sharedProps}
339
355
  {...extra}
340
- on:change={() => handleRowChange(token)}
356
+ onchange={() => handleRowChange(token)}
341
357
  />
342
358
  {#if !sel.standalone && ctxs?.length}
343
359
  <div class="token-contexts">
@@ -8,57 +8,83 @@
8
8
  import FieldsetWrapper from './FieldsetWrapper.svelte';
9
9
  import { BORDER_WIDTH } from '../../ui/variantScales';
10
10
 
11
- export let colorVariable: string;
12
- export let colorLabel: string = 'color';
13
- export let familyVariable: string | undefined = undefined;
14
- export let familyLabel: string = 'family';
15
- export let sizeVariable: string | undefined = undefined;
16
- export let sizeLabel: string = 'size';
17
- export let weightVariable: string | undefined = undefined;
18
- export let weightLabel: string = 'weight';
19
- export let lineHeightVariable: string | undefined = undefined;
20
- export let lineHeightLabel: string = 'line-h';
21
- /** Optional outline rows rendered under the typography rows so a text-with-
11
+
12
+
13
+
14
+ interface Props {
15
+ colorVariable: string;
16
+ colorLabel?: string;
17
+ familyVariable?: string | undefined;
18
+ familyLabel?: string;
19
+ sizeVariable?: string | undefined;
20
+ sizeLabel?: string;
21
+ weightVariable?: string | undefined;
22
+ weightLabel?: string;
23
+ lineHeightVariable?: string | undefined;
24
+ lineHeightLabel?: string;
25
+ /** Optional outline rows rendered under the typography rows so a text-with-
22
26
  stroke group keeps stroke controls visually nested with the type they
23
27
  drive (e.g. SectionDivider title outline). */
24
- export let outlineWidthVariable: string | undefined = undefined;
25
- export let outlineWidthLabel: string = 'outline thickness';
26
- export let outlineColorVariable: string | undefined = undefined;
27
- export let outlineColorLabel: string = 'outline color';
28
- /** When set, writes persist through the editor store under this component. */
29
- export let component: string | undefined = undefined;
30
- /** Legend text for the fieldset. */
31
- export let legend: string = 'type';
28
+ outlineWidthVariable?: string | undefined;
29
+ outlineWidthLabel?: string;
30
+ outlineColorVariable?: string | undefined;
31
+ outlineColorLabel?: string;
32
+ /** When set, writes persist through the editor store under this component. */
33
+ component?: string | undefined;
34
+ /** Legend text for the fieldset. */
35
+ legend?: string;
36
+ onchange?: () => void;
37
+ }
38
+
39
+ let {
40
+ colorVariable,
41
+ colorLabel = 'color',
42
+ familyVariable = undefined,
43
+ familyLabel = 'family',
44
+ sizeVariable = undefined,
45
+ sizeLabel = 'size',
46
+ weightVariable = undefined,
47
+ weightLabel = 'weight',
48
+ lineHeightVariable = undefined,
49
+ lineHeightLabel = 'line-h',
50
+ outlineWidthVariable = undefined,
51
+ outlineWidthLabel = 'outline thickness',
52
+ outlineColorVariable = undefined,
53
+ outlineColorLabel = 'outline color',
54
+ component = undefined,
55
+ legend = 'type',
56
+ onchange,
57
+ }: Props = $props();
32
58
  </script>
33
59
 
34
60
  <FieldsetWrapper {legend}>
35
61
  <div class="type-grid">
36
62
  <span class="row-label">{colorLabel}</span>
37
- <UIPaletteSelector variable={colorVariable} {component} on:change />
63
+ <UIPaletteSelector variable={colorVariable} {component} {onchange} />
38
64
 
39
65
  {#if familyVariable}
40
66
  <span class="row-label">{familyLabel}</span>
41
- <UIFontFamilySelector variable={familyVariable} {component} canBeLinked on:change />
67
+ <UIFontFamilySelector variable={familyVariable} {component} canBeLinked {onchange} />
42
68
  {/if}
43
69
  {#if weightVariable}
44
70
  <span class="row-label">{weightLabel}</span>
45
- <UIFontWeightSelector variable={weightVariable} {component} canBeLinked on:change />
71
+ <UIFontWeightSelector variable={weightVariable} {component} canBeLinked {onchange} />
46
72
  {/if}
47
73
  {#if sizeVariable}
48
74
  <span class="row-label">{sizeLabel}</span>
49
- <UIFontSizeSelector variable={sizeVariable} {component} canBeLinked on:change />
75
+ <UIFontSizeSelector variable={sizeVariable} {component} canBeLinked {onchange} />
50
76
  {/if}
51
77
  {#if lineHeightVariable}
52
78
  <span class="row-label">{lineHeightLabel}</span>
53
- <UILineHeightSelector variable={lineHeightVariable} {component} canBeLinked on:change />
79
+ <UILineHeightSelector variable={lineHeightVariable} {component} canBeLinked {onchange} />
54
80
  {/if}
55
81
  {#if outlineWidthVariable}
56
82
  <span class="row-label">{outlineWidthLabel}</span>
57
- <UIVariantSelector variable={outlineWidthVariable} {component} canBeLinked {...BORDER_WIDTH} on:change />
83
+ <UIVariantSelector variable={outlineWidthVariable} {component} canBeLinked {...BORDER_WIDTH} {onchange} />
58
84
  {/if}
59
85
  {#if outlineColorVariable}
60
86
  <span class="row-label">{outlineColorLabel}</span>
61
- <UIPaletteSelector variable={outlineColorVariable} {component} canBeLinked on:change />
87
+ <UIPaletteSelector variable={outlineColorVariable} {component} canBeLinked {onchange} />
62
88
  {/if}
63
89
  </div>
64
90
  </FieldsetWrapper>