@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
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@motion-proto/live-tokens",
3
- "version": "0.3.9",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
- "description": "Design token editor with live CSS variable editing. Svelte 4/5 + Vite 5/6/7.",
5
+ "description": "Design token editor with live CSS variable editing. Svelte 5 + Vite 6/7.",
6
6
  "keywords": [
7
7
  "svelte",
8
8
  "vite",
@@ -11,6 +11,7 @@
11
11
  "editor"
12
12
  ],
13
13
  "license": "MIT",
14
+ "author": "Mark Pearce <mark@motionproto.com>",
14
15
  "repository": {
15
16
  "type": "git",
16
17
  "url": "git+https://github.com/motionproto/live-tokens.git"
@@ -93,22 +94,22 @@
93
94
  },
94
95
  "peerDependencies": {
95
96
  "sass": "^1.0",
96
- "svelte": "^4.2 || ^5",
97
+ "svelte": "^5",
97
98
  "svelte-preprocess": "^6.0",
98
- "vite": "^5 || ^6 || ^7"
99
+ "vite": "^6 || ^7"
99
100
  },
100
101
  "devDependencies": {
101
- "@sveltejs/vite-plugin-svelte": "^3.1.2",
102
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
102
103
  "@tsconfig/svelte": "^5.0.8",
103
104
  "@types/node": "^24.12.0",
104
105
  "happy-dom": "^20.9.0",
105
106
  "sass": "^1.98.0",
106
- "svelte": "^4.2.20",
107
- "svelte-check": "^3.8.6",
107
+ "svelte": "^5.55.5",
108
+ "svelte-check": "^4.4.8",
108
109
  "svelte-preprocess": "^6.0.3",
109
110
  "tsup": "^8.5.1",
110
111
  "typescript": "~5.9.3",
111
- "vite": "^5.4.21",
112
+ "vite": "^7.3.3",
112
113
  "vitest": "^4.1.4"
113
114
  },
114
115
  "dependencies": {
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
3
3
  import type { Token, TypeGroupConfig } from './scaffolding/types';
4
4
  import { badgeVariants } from '../components/Badge.svelte';
@@ -69,18 +69,18 @@
69
69
  import ShadowBackdropControls from './scaffolding/ShadowBackdropControls.svelte';
70
70
  import UIRadioGroup from '../ui/UIRadioGroup.svelte';
71
71
 
72
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
73
- $: visibleVariantTokens = (v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet);
72
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
73
+ let visibleVariantTokens = $derived((v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet));
74
74
 
75
- let bgMode: 'image' | 'color' = 'image';
75
+ let bgMode: 'image' | 'color' = $state('image');
76
76
  const bgVar = '--backdrop-badge-surface';
77
77
 
78
78
  // Preview-only props for Badge's floating/anchor/flush features (not persisted).
79
79
  // For corner-anchored use, prefer the dedicated CornerBadge component; Badge.floating
80
80
  // is the low-level escape hatch for off-corner floating placements.
81
- let floating: boolean = false;
82
- let flush: boolean = false;
83
- let anchor: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' = 'bottom-right';
81
+ let floating: boolean = $state(false);
82
+ let flush: boolean = $state(false);
83
+ let anchor: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' = $state('bottom-right');
84
84
  const anchorOptions = [
85
85
  { value: 'top-left' as const, label: 'TL' },
86
86
  { value: 'top-right' as const, label: 'TR' },
@@ -90,23 +90,25 @@
90
90
  </script>
91
91
 
92
92
  <ComponentEditorBase {component} title="Badge" description="Pill-shaped badges with color variants. Import from <code>components/Badge.svelte</code>" tokens={allTokens} {linked} variants={variantOptions}>
93
- <svelte:fragment slot="config">
94
- <ShadowBackdropControls bind:mode={bgMode} colorVariable={bgVar} />
95
- <label class="float-toggle">
96
- <input type="checkbox" bind:checked={floating} />
97
- <span>Floating preview</span>
98
- </label>
99
- {#if floating}
93
+ {#snippet config()}
94
+
95
+ <ShadowBackdropControls bind:mode={bgMode} colorVariable={bgVar} />
100
96
  <label class="float-toggle">
101
- <input type="checkbox" bind:checked={flush} />
102
- <span>Flush corner</span>
97
+ <input type="checkbox" bind:checked={floating} />
98
+ <span>Floating preview</span>
103
99
  </label>
104
- <div class="anchor-control">
105
- <span>Anchor</span>
106
- <UIRadioGroup bind:value={anchor} name="badge-anchor" options={anchorOptions} />
107
- </div>
108
- {/if}
109
- </svelte:fragment>
100
+ {#if floating}
101
+ <label class="float-toggle">
102
+ <input type="checkbox" bind:checked={flush} />
103
+ <span>Flush corner</span>
104
+ </label>
105
+ <div class="anchor-control">
106
+ <span>Anchor</span>
107
+ <UIRadioGroup bind:value={anchor} name="badge-anchor" options={anchorOptions} />
108
+ </div>
109
+ {/if}
110
+
111
+ {/snippet}
110
112
  {#each variants as v}
111
113
  <VariantGroup
112
114
  name={v}
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
3
3
  import type { Token, TypeGroupConfig } from './scaffolding/types';
4
4
  import { calloutVariants } from '../components/Callout.svelte';
@@ -76,8 +76,8 @@
76
76
  import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
77
77
  import { buildSiblings } from './scaffolding/siblings';
78
78
 
79
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
80
- $: visibleVariantTokens = (v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet);
79
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
80
+ let visibleVariantTokens = $derived((v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet));
81
81
 
82
82
  const sample: Record<Variant, { label: string; message: string }> = {
83
83
  info: { label: 'Note.', message: 'This is contextual information you should know about.' },
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
3
3
  import type { Token, TypeGroupConfig } from './scaffolding/types';
4
4
 
@@ -127,46 +127,50 @@
127
127
  import ShadowBackdrop from './scaffolding/ShadowBackdrop.svelte';
128
128
  import ShadowBackdropControls from './scaffolding/ShadowBackdropControls.svelte';
129
129
 
130
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
130
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
131
131
 
132
- $: visibleStates = Object.fromEntries(
132
+ let visibleStates = $derived(Object.fromEntries(
133
133
  Object.entries(states).map(([name, list]) => [name, withLinkedDisabled(list, linked.varSet)]),
134
- ) as Record<string, Token[]>;
134
+ ) as Record<string, Token[]>);
135
135
 
136
- let hoverEnabled = true;
137
- let bgMode: 'image' | 'color' = 'image';
136
+ let hoverEnabled = $state(true);
137
+ let bgMode: 'image' | 'color' = $state('image');
138
138
  const bgVar = '--backdrop-card-surface';
139
139
  </script>
140
140
 
141
141
  <ComponentEditorBase {component} title="Card" description="Generic card with icon, title, and slotted body. Import from <code>components/Card.svelte</code>" tokens={allTokens} {linked}>
142
- <svelte:fragment slot="config">
143
- <ShadowBackdropControls bind:mode={bgMode} colorVariable={bgVar} />
144
- </svelte:fragment>
142
+ {#snippet config()}
143
+
144
+ <ShadowBackdropControls bind:mode={bgMode} colorVariable={bgVar} />
145
+
146
+ {/snippet}
145
147
  <VariantGroup
146
148
  name="card"
147
149
  title="Card"
148
150
  states={visibleStates}
149
151
  {typeGroups}
150
152
  {component}
151
- let:activeState
153
+
152
154
  >
153
- <svelte:fragment slot="state-actions" let:stateName>
155
+ {#snippet stateActions(stateName)}
154
156
  {#if stateName === 'hover'}
155
157
  <label class="hover-enable">
156
158
  <input type="checkbox" bind:checked={hoverEnabled} />
157
159
  <span>Use hover</span>
158
160
  </label>
159
161
  {/if}
160
- </svelte:fragment>
161
- {@const previewClass = activeState === 'hover' ? 'force-hover' : (hoverEnabled ? '' : 'no-hover')}
162
- <ShadowBackdrop mode={bgMode} colorVariable={bgVar}>
163
- <div class="card-demo">
164
- <Card title="Card title" class={previewClass}>
165
- <p style="margin: 0;">Slotted body content. Hover the card (or switch the editor to the Hover state) to preview hover styling.</p>
166
- </Card>
167
- </div>
168
- </ShadowBackdrop>
169
- </VariantGroup>
162
+ {/snippet}
163
+ {#snippet children({ activeState })}
164
+ {@const previewClass = activeState === 'hover' ? 'force-hover' : (hoverEnabled ? '' : 'no-hover')}
165
+ <ShadowBackdrop mode={bgMode} colorVariable={bgVar}>
166
+ <div class="card-demo">
167
+ <Card title="Card title" class={previewClass}>
168
+ <p style="margin: 0;">Slotted body content. Hover the card (or switch the editor to the Hover state) to preview hover styling.</p>
169
+ </Card>
170
+ </div>
171
+ </ShadowBackdrop>
172
+ {/snippet}
173
+ </VariantGroup>
170
174
  </ComponentEditorBase>
171
175
 
172
176
  <style>
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
3
3
  import type { Token, TypeGroupConfig } from './scaffolding/types';
4
4
 
@@ -125,11 +125,11 @@
125
125
  import { editorState } from '../lib/editorStore';
126
126
  import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
127
127
 
128
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
128
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
129
129
 
130
- $: visibleVariantStates = (v: Variant) => Object.fromEntries(
130
+ let visibleVariantStates = $derived((v: Variant) => Object.fromEntries(
131
131
  Object.entries(variantStates(v)).map(([name, list]) => [name, withLinkedDisabled(list, linked.varSet)]),
132
- ) as Record<string, Token[]>;
132
+ ) as Record<string, Token[]>);
133
133
  </script>
134
134
 
135
135
  <ComponentEditorBase {component} title="Collapsible Section" description="Expandable section with chevron toggle. Variants: chromeless, divider, container. Import from <code>components/CollapsibleSection.svelte</code>" tokens={allTokens} {linked} variants={variantOptions}>
@@ -141,27 +141,29 @@
141
141
  typeGroups={variantTypeGroups(v)}
142
142
  {component}
143
143
  siblings={buildSiblings(VARIANTS, v, variantStates, variantTypeGroups)}
144
- let:activeState
144
+
145
145
  >
146
- {@const isExpanded = activeState === 'expanded'}
147
- {@const isFrame = activeState === 'frame'}
148
- {@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
149
- {@const forceActive = activeState === 'active'}
150
- <CollapsibleSection
151
- variant={v}
152
- label="Click to expand"
153
- expanded={isExpanded}
154
- active={forceActive}
155
- class={forceClass}
156
- >
157
- <p style="margin: 0; color: var(--text-secondary);">
158
- {#if isFrame}
159
- (Frame) — outer chrome only; expand the section to see content area styling.
160
- {:else}
161
- This content is revealed when the section is expanded. Any content can go here.
162
- {/if}
163
- </p>
164
- </CollapsibleSection>
165
- </VariantGroup>
146
+ {#snippet children({ activeState })}
147
+ {@const isExpanded = activeState === 'expanded'}
148
+ {@const isFrame = activeState === 'frame'}
149
+ {@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
150
+ {@const forceActive = activeState === 'active'}
151
+ <CollapsibleSection
152
+ variant={v}
153
+ label="Click to expand"
154
+ expanded={isExpanded}
155
+ active={forceActive}
156
+ class={forceClass}
157
+ >
158
+ <p style="margin: 0; color: var(--text-secondary);">
159
+ {#if isFrame}
160
+ (Frame) — outer chrome only; expand the section to see content area styling.
161
+ {:else}
162
+ This content is revealed when the section is expanded. Any content can go here.
163
+ {/if}
164
+ </p>
165
+ </CollapsibleSection>
166
+ {/snippet}
167
+ </VariantGroup>
166
168
  {/each}
167
169
  </ComponentEditorBase>
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import type { Token } from './scaffolding/types';
3
3
  import { badgeVariants } from '../components/Badge.svelte';
4
4
 
@@ -65,10 +65,10 @@
65
65
  import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
66
66
  import demoImageUrl from '../assets/newspaper.webp';
67
67
 
68
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
69
- $: visibleStates = Object.fromEntries(
68
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
69
+ let visibleStates = $derived(Object.fromEntries(
70
70
  badgeVariants.map((v) => [v, withLinkedDisabled(variantTokens(v), linked.varSet)]),
71
- ) as Record<string, Token[]>;
71
+ ) as Record<string, Token[]>);
72
72
 
73
73
  const bgVar = '--backdrop-cornerbadge-surface';
74
74
 
@@ -78,7 +78,7 @@
78
78
  }
79
79
  });
80
80
 
81
- let anchor: CornerAnchor = 'bottom-right';
81
+ let anchor: CornerAnchor = $state('bottom-right');
82
82
  const anchorGrid: ReadonlyArray<{ value: CornerAnchor; icon: string; label: string }> = [
83
83
  { value: 'top-left', icon: 'fas fa-arrow-up-left', label: 'Top left' },
84
84
  { value: 'top-right', icon: 'fas fa-arrow-up-right', label: 'Top right' },
@@ -86,42 +86,44 @@
86
86
  { value: 'bottom-right', icon: 'fas fa-arrow-down-right', label: 'Bottom right' },
87
87
  ];
88
88
 
89
- let variant: BadgeVariant = 'accent';
89
+ let variant: BadgeVariant = $state('accent');
90
90
  const variantOptions = badgeVariants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
91
91
  </script>
92
92
 
93
93
  <ComponentEditorBase {component} title="Corner Badge" description="Badge pinned flush to a corner of a positioned ancestor. Composes <code>Badge</code>; adds offset + inner-radius tokens. Import from <code>components/CornerBadge.svelte</code>" tokens={allTokens} {linked}>
94
- <svelte:fragment slot="config">
95
- <label class="backdrop-config">
96
- <span>Sample background</span>
97
- <div class="picker-slot">
98
- <UIPaletteSelector variable={bgVar} />
94
+ {#snippet config()}
95
+
96
+ <label class="backdrop-config">
97
+ <span>Sample background</span>
98
+ <div class="picker-slot">
99
+ <UIPaletteSelector variable={bgVar} />
100
+ </div>
101
+ </label>
102
+ <div class="control-row">
103
+ <span>Anchor</span>
104
+ <div class="anchor-grid" role="radiogroup" aria-label="Corner badge anchor">
105
+ {#each anchorGrid as opt (opt.value)}
106
+ <button
107
+ type="button"
108
+ class="anchor-btn"
109
+ class:checked={anchor === opt.value}
110
+ role="radio"
111
+ aria-checked={anchor === opt.value}
112
+ aria-label={opt.label}
113
+ title={opt.label}
114
+ onclick={() => (anchor = opt.value)}
115
+ >
116
+ <i class={opt.icon} aria-hidden="true"></i>
117
+ </button>
118
+ {/each}
119
+ </div>
99
120
  </div>
100
- </label>
101
- <div class="control-row">
102
- <span>Anchor</span>
103
- <div class="anchor-grid" role="radiogroup" aria-label="Corner badge anchor">
104
- {#each anchorGrid as opt (opt.value)}
105
- <button
106
- type="button"
107
- class="anchor-btn"
108
- class:checked={anchor === opt.value}
109
- role="radio"
110
- aria-checked={anchor === opt.value}
111
- aria-label={opt.label}
112
- title={opt.label}
113
- on:click={() => (anchor = opt.value)}
114
- >
115
- <i class={opt.icon} aria-hidden="true"></i>
116
- </button>
117
- {/each}
121
+ <div class="control-row">
122
+ <span>Variant</span>
123
+ <UIRadioGroup bind:value={variant} name="corner-badge-variant" options={variantOptions} />
118
124
  </div>
119
- </div>
120
- <div class="control-row">
121
- <span>Variant</span>
122
- <UIRadioGroup bind:value={variant} name="corner-badge-variant" options={variantOptions} />
123
- </div>
124
- </svelte:fragment>
125
+
126
+ {/snippet}
125
127
  <VariantGroup name="cornerbadge" title="Corner Badge" states={visibleStates} {component}>
126
128
  <ShadowBackdrop mode="color" colorVariable={bgVar}>
127
129
  <div class="corner-stage-wrap">
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
3
3
  import type { Token, TypeGroupConfig } from './scaffolding/types';
4
4
 
@@ -95,9 +95,9 @@
95
95
  import ShadowBackdrop from './scaffolding/ShadowBackdrop.svelte';
96
96
  import ShadowBackdropControls from './scaffolding/ShadowBackdropControls.svelte';
97
97
 
98
- $: config = $editorState.components.dialog?.config ?? {};
99
- $: confirmVariant = (BUTTON_VARIANTS.includes(config[CONFIRM_VAR] as ButtonVariant) ? config[CONFIRM_VAR] : DEFAULT_CONFIRM) as ButtonVariant;
100
- $: cancelVariant = (BUTTON_VARIANTS.includes(config[CANCEL_VAR] as ButtonVariant) ? config[CANCEL_VAR] : DEFAULT_CANCEL) as ButtonVariant;
98
+ let config = $derived($editorState.components.dialog?.config ?? {});
99
+ let confirmVariant = $derived((BUTTON_VARIANTS.includes(config[CONFIRM_VAR] as ButtonVariant) ? config[CONFIRM_VAR] : DEFAULT_CONFIRM) as ButtonVariant);
100
+ let cancelVariant = $derived((BUTTON_VARIANTS.includes(config[CANCEL_VAR] as ButtonVariant) ? config[CANCEL_VAR] : DEFAULT_CANCEL) as ButtonVariant);
101
101
 
102
102
  function setConfirmVariant(e: Event) {
103
103
  const v = (e.target as HTMLSelectElement).value;
@@ -108,30 +108,32 @@
108
108
  setComponentConfig(component, CANCEL_VAR, v);
109
109
  }
110
110
 
111
- let bgMode: 'image' | 'color' = 'image';
111
+ let bgMode: 'image' | 'color' = $state('image');
112
112
  const bgVar = '--backdrop-dialog-surface';
113
113
  </script>
114
114
 
115
115
  <ComponentEditorBase {component} title="Dialog" description="Modal dialog with focus management and slide-in animation. Import from <code>components/Dialog.svelte</code>" tokens={allTokens}>
116
- <svelte:fragment slot="config">
117
- <label>
118
- <span>Cancel button (left)</span>
119
- <select class="form-select" value={cancelVariant} on:change={setCancelVariant}>
120
- {#each BUTTON_VARIANTS as v}
121
- <option value={v}>{variantLabel(v)}</option>
122
- {/each}
123
- </select>
124
- </label>
125
- <label>
126
- <span>Confirm button (right)</span>
127
- <select class="form-select" value={confirmVariant} on:change={setConfirmVariant}>
128
- {#each BUTTON_VARIANTS as v}
129
- <option value={v}>{variantLabel(v)}</option>
130
- {/each}
131
- </select>
132
- </label>
133
- <ShadowBackdropControls bind:mode={bgMode} colorVariable={bgVar} />
134
- </svelte:fragment>
116
+ {#snippet config()}
117
+
118
+ <label>
119
+ <span>Cancel button (left)</span>
120
+ <select class="form-select" value={cancelVariant} onchange={setCancelVariant}>
121
+ {#each BUTTON_VARIANTS as v}
122
+ <option value={v}>{variantLabel(v)}</option>
123
+ {/each}
124
+ </select>
125
+ </label>
126
+ <label>
127
+ <span>Confirm button (right)</span>
128
+ <select class="form-select" value={confirmVariant} onchange={setConfirmVariant}>
129
+ {#each BUTTON_VARIANTS as v}
130
+ <option value={v}>{variantLabel(v)}</option>
131
+ {/each}
132
+ </select>
133
+ </label>
134
+ <ShadowBackdropControls bind:mode={bgMode} colorVariable={bgVar} />
135
+
136
+ {/snippet}
135
137
  <div class="dialog-preview">
136
138
  <ShadowBackdrop mode={bgMode} colorVariable={bgVar} padding="0">
137
139
  <Dialog
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import type { Token } from './scaffolding/types';
3
3
 
4
4
  export const component = 'image';
@@ -36,14 +36,16 @@
36
36
  </script>
37
37
 
38
38
  <ComponentEditorBase {component} title="Image" description="Framed image with rounded corners, border, and shadow. Import from <code>components/Image.svelte</code>" tokens={allTokens}>
39
- <svelte:fragment slot="config">
40
- <label class="backdrop-config">
41
- <span>Sample background</span>
42
- <div class="picker-slot">
43
- <UIPaletteSelector variable={bgVar} />
44
- </div>
45
- </label>
46
- </svelte:fragment>
39
+ {#snippet config()}
40
+
41
+ <label class="backdrop-config">
42
+ <span>Sample background</span>
43
+ <div class="picker-slot">
44
+ <UIPaletteSelector variable={bgVar} />
45
+ </div>
46
+ </label>
47
+
48
+ {/snippet}
47
49
  <VariantGroup name="image" title="Image" {states} {component}>
48
50
  <ShadowBackdrop mode="color" colorVariable={bgVar}>
49
51
  <div class="image-demo-grid">
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import type { Token } from './scaffolding/types';
3
3
 
4
4
  export const component = 'inlineeditactions';
@@ -45,11 +45,11 @@
45
45
  import { editorState } from '../lib/editorStore';
46
46
  import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
47
47
 
48
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
48
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
49
49
 
50
- $: visibleStatesByButton = (btn: Button) => Object.fromEntries(
50
+ let visibleStatesByButton = $derived((btn: Button) => Object.fromEntries(
51
51
  Object.entries(buttonStates(btn)).map(([name, list]) => [name, withLinkedDisabled(list, linked.varSet)]),
52
- ) as Record<string, Token[]>;
52
+ ) as Record<string, Token[]>);
53
53
  </script>
54
54
 
55
55
  <ComponentEditorBase {component} title="Inline Edit Actions" description="Confirm/cancel button pair for inline editing. Import from <code>components/InlineEditActions.svelte</code>" tokens={allTokens} {linked}>
@@ -59,18 +59,20 @@
59
59
  title={btn === 'save' ? 'Save button' : 'Cancel button'}
60
60
  states={visibleStatesByButton(btn)}
61
61
  {component}
62
- let:activeState
62
+
63
63
  >
64
- {@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
65
- <div class="inline-edit-demo-row">
66
- <span style="color: var(--text-secondary);">Editing value...</span>
67
- <InlineEditActions
68
- onSave={() => {}}
69
- onCancel={() => {}}
70
- class={forceClass}
71
- />
72
- </div>
73
- </VariantGroup>
64
+ {#snippet children({ activeState })}
65
+ {@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
66
+ <div class="inline-edit-demo-row">
67
+ <span style="color: var(--text-secondary);">Editing value...</span>
68
+ <InlineEditActions
69
+ onSave={() => {}}
70
+ onCancel={() => {}}
71
+ class={forceClass}
72
+ />
73
+ </div>
74
+ {/snippet}
75
+ </VariantGroup>
74
76
  {/each}
75
77
  </ComponentEditorBase>
76
78
 
@@ -1,4 +1,4 @@
1
- <script context="module" lang="ts">
1
+ <script module lang="ts">
2
2
  import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
3
3
  import type { Token, TypeGroupConfig } from './scaffolding/types';
4
4
 
@@ -95,47 +95,49 @@
95
95
  import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
96
96
  import { buildSiblings } from './scaffolding/siblings';
97
97
 
98
- $: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
99
- $: visibleVariantTokens = (v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet);
98
+ let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
99
+ let visibleVariantTokens = $derived((v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet));
100
100
 
101
101
  import type { NotificationActions } from '../components/types';
102
102
 
103
- let dismissible = false;
104
- let rightOption: ButtonVariantOption = 'none';
105
- let leftOption: ButtonVariantOption = 'none';
106
- $: actions = ((): NotificationActions => {
103
+ let dismissible = $state(false);
104
+ let rightOption: ButtonVariantOption = $state('none');
105
+ let leftOption: ButtonVariantOption = $state('none');
106
+ let actions = $derived(((): NotificationActions => {
107
107
  const a: NotificationActions = {};
108
108
  const right = toVariant(rightOption);
109
109
  const left = toVariant(leftOption);
110
110
  if (right) a.right = { label: 'Confirm', variant: right, onClick: () => {} };
111
111
  if (left) a.left = { label: 'Cancel', variant: left, onClick: () => {} };
112
112
  return a;
113
- })();
113
+ })());
114
114
  </script>
115
115
 
116
116
  <ComponentEditorBase {component} title="Notification" description="Contextual feedback notifications with multiple variants. Import from <code>components/Notification.svelte</code>" tokens={allTokens} {linked} variants={variantOptions}>
117
- <svelte:fragment slot="config">
118
- <label>
119
- <input type="checkbox" bind:checked={dismissible} />
120
- <span>Dismissible</span>
121
- </label>
122
- <label>
123
- <span>Right button</span>
124
- <select class="form-select" bind:value={rightOption}>
125
- {#each BUTTON_VARIANT_OPTIONS as v}
126
- <option value={v}>{variantLabel(v)}</option>
127
- {/each}
128
- </select>
129
- </label>
130
- <label>
131
- <span>Left button</span>
132
- <select class="form-select" bind:value={leftOption}>
133
- {#each BUTTON_VARIANT_OPTIONS as v}
134
- <option value={v}>{variantLabel(v)}</option>
135
- {/each}
136
- </select>
137
- </label>
138
- </svelte:fragment>
117
+ {#snippet config()}
118
+
119
+ <label>
120
+ <input type="checkbox" bind:checked={dismissible} />
121
+ <span>Dismissible</span>
122
+ </label>
123
+ <label>
124
+ <span>Right button</span>
125
+ <select class="form-select" bind:value={rightOption}>
126
+ {#each BUTTON_VARIANT_OPTIONS as v}
127
+ <option value={v}>{variantLabel(v)}</option>
128
+ {/each}
129
+ </select>
130
+ </label>
131
+ <label>
132
+ <span>Left button</span>
133
+ <select class="form-select" bind:value={leftOption}>
134
+ {#each BUTTON_VARIANT_OPTIONS as v}
135
+ <option value={v}>{variantLabel(v)}</option>
136
+ {/each}
137
+ </select>
138
+ </label>
139
+
140
+ {/snippet}
139
141
  {#each variants as v}
140
142
  <VariantGroup
141
143
  name={v}