@motion-proto/live-tokens 0.3.7 → 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 (104) hide show
  1. package/README.md +1 -1
  2. package/package.json +11 -9
  3. package/src/component-editor/BadgeEditor.svelte +24 -22
  4. package/src/component-editor/CalloutEditor.svelte +3 -3
  5. package/src/component-editor/CardEditor.svelte +25 -21
  6. package/src/component-editor/CollapsibleSectionEditor.svelte +27 -25
  7. package/src/component-editor/CornerBadgeEditor.svelte +37 -35
  8. package/src/component-editor/DialogEditor.svelte +26 -24
  9. package/src/component-editor/ImageEditor.svelte +11 -9
  10. package/src/component-editor/InlineEditActionsEditor.svelte +17 -15
  11. package/src/component-editor/NotificationEditor.svelte +32 -30
  12. package/src/component-editor/ProgressBarEditor.svelte +3 -3
  13. package/src/component-editor/RadioButtonEditor.svelte +31 -29
  14. package/src/component-editor/SectionDividerEditor.svelte +30 -28
  15. package/src/component-editor/SegmentedControlEditor.svelte +29 -25
  16. package/src/component-editor/StandardButtonsEditor.svelte +42 -38
  17. package/src/component-editor/TabBarEditor.svelte +20 -18
  18. package/src/component-editor/TableEditor.svelte +4 -4
  19. package/src/component-editor/TooltipEditor.svelte +11 -9
  20. package/src/component-editor/registry.ts +2 -2
  21. package/src/component-editor/scaffolding/AngleDial.svelte +20 -19
  22. package/src/component-editor/scaffolding/ComponentEditorBase.svelte +44 -20
  23. package/src/component-editor/scaffolding/ComponentFileManager.svelte +260 -37
  24. package/src/component-editor/scaffolding/ComponentFileMenu.svelte +41 -29
  25. package/src/component-editor/scaffolding/ComponentsTab.svelte +7 -3
  26. package/src/component-editor/scaffolding/CopyFromMenu.svelte +21 -12
  27. package/src/component-editor/scaffolding/DemoHeader.svelte +13 -4
  28. package/src/component-editor/scaffolding/DividerEditor.svelte +27 -14
  29. package/src/component-editor/scaffolding/FieldsetWrapper.svelte +10 -4
  30. package/src/component-editor/scaffolding/GradientCard.svelte +25 -20
  31. package/src/component-editor/scaffolding/LinkageChart.svelte +43 -34
  32. package/src/component-editor/scaffolding/LinkedBlock.svelte +24 -21
  33. package/src/component-editor/scaffolding/NonStylableConfig.svelte +6 -1
  34. package/src/component-editor/scaffolding/SaveAsDialog.svelte +39 -35
  35. package/src/component-editor/scaffolding/ShadowBackdrop.svelte +21 -9
  36. package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +8 -3
  37. package/src/component-editor/scaffolding/StateBlock.svelte +30 -13
  38. package/src/component-editor/scaffolding/TokenLayout.svelte +46 -30
  39. package/src/component-editor/scaffolding/TypeEditor.svelte +52 -26
  40. package/src/component-editor/scaffolding/VariantGroup.svelte +81 -48
  41. package/src/component-editor/scaffolding/componentSectionType.ts +2 -2
  42. package/src/components/Badge.svelte +45 -26
  43. package/src/components/Button.svelte +44 -21
  44. package/src/components/Callout.svelte +17 -12
  45. package/src/components/Card.svelte +23 -11
  46. package/src/components/CollapsibleSection.svelte +56 -27
  47. package/src/components/CornerBadge.svelte +32 -18
  48. package/src/components/Dialog.svelte +55 -31
  49. package/src/components/Image.svelte +14 -5
  50. package/src/components/InlineEditActions.svelte +22 -10
  51. package/src/components/Notification.svelte +39 -19
  52. package/src/components/ProgressBar.svelte +27 -17
  53. package/src/components/RadioButton.svelte +27 -10
  54. package/src/components/SectionDivider.svelte +34 -26
  55. package/src/components/SegmentedControl.svelte +23 -9
  56. package/src/components/TabBar.svelte +23 -10
  57. package/src/components/Table.svelte +8 -3
  58. package/src/components/Tooltip.svelte +15 -5
  59. package/src/lib/ColumnsOverlay.svelte +3 -3
  60. package/src/lib/LiveEditorOverlay.svelte +73 -36
  61. package/src/pages/ComponentEditorPage.svelte +17 -13
  62. package/src/pages/EditorShell.svelte +24 -20
  63. package/src/styles/form-controls.css +2 -2
  64. package/src/styles/tokens.css +59 -81
  65. package/src/ui/BezierCurveEditor.svelte +59 -43
  66. package/src/ui/ColorEditPanel.svelte +71 -44
  67. package/src/ui/EditorViewSwitcher.svelte +9 -5
  68. package/src/ui/FontStackEditor.svelte +16 -15
  69. package/src/ui/GradientEditor.svelte +42 -33
  70. package/src/ui/GradientStopPicker.svelte +18 -29
  71. package/src/ui/PaletteEditor.svelte +238 -212
  72. package/src/ui/PresetFileManager.svelte +20 -18
  73. package/src/ui/ProjectFontsSection.svelte +30 -30
  74. package/src/ui/SurfacesTab.svelte +3 -3
  75. package/src/ui/TextTab.svelte +2 -2
  76. package/src/ui/ThemeFileManager.svelte +38 -35
  77. package/src/ui/Toggle.svelte +11 -9
  78. package/src/ui/UICopyPopover.svelte +19 -15
  79. package/src/ui/UIDialog.svelte +48 -30
  80. package/src/ui/UIFontFamilySelector.svelte +104 -78
  81. package/src/ui/UIFontSizeSelector.svelte +38 -20
  82. package/src/ui/UIFontWeightSelector.svelte +33 -13
  83. package/src/ui/UILineHeightSelector.svelte +33 -13
  84. package/src/ui/UILinkToggle.svelte +7 -6
  85. package/src/ui/UIOptionItem.svelte +21 -7
  86. package/src/ui/UIOptionList.svelte +9 -3
  87. package/src/ui/UIPaddingSelector.svelte +108 -82
  88. package/src/ui/UIPaletteSelector.svelte +186 -161
  89. package/src/ui/UIRadio.svelte +23 -8
  90. package/src/ui/UIRadioGroup.svelte +9 -8
  91. package/src/ui/UIRelinkConfirmPopover.svelte +26 -16
  92. package/src/ui/UITokenSelector.svelte +112 -68
  93. package/src/ui/UIVariantSelector.svelte +79 -57
  94. package/src/ui/VariablesTab.svelte +15 -15
  95. package/src/ui/palette/GradientStopEditor.svelte +45 -26
  96. package/src/ui/palette/OverridesPanel.svelte +85 -49
  97. package/src/ui/palette/PaletteBase.svelte +60 -32
  98. package/src/ui/palette/ScaleCurveEditor.svelte +25 -10
  99. package/src/ui/sections/ColumnsSection.svelte +13 -13
  100. package/src/ui/sections/GradientsSection.svelte +12 -9
  101. package/src/ui/sections/OverlaysSection.svelte +50 -47
  102. package/src/ui/sections/ShadowsSection.svelte +110 -104
  103. package/src/ui/sections/TokenScaleTable.svelte +38 -22
  104. package/src/ui/sections/tokenScales.ts +2 -2
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Live Tokens
2
2
 
3
- A foundational design system for quickly styling and building Svelte 4 + Vite microsites. **Edit your tokens and components in real time** — colors, typography, spacing, per-component aliases — and see the site update as you drag the slider. Save the result as a portable configuration you can carry from project to project.
3
+ A foundational design system for quickly styling and building Svelte + Vite microsites. **Edit your tokens and components in real time** — colors, typography, spacing, per-component aliases — and see the site update as you drag the slider. Save the result as a portable configuration you can carry from project to project.
4
4
 
5
5
  `npm install @motion-proto/live-tokens` into your app — install once, style fast. The editor is dev-only; production builds get plain CSS variables and your chosen components, nothing else.
6
6
 
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@motion-proto/live-tokens",
3
- "version": "0.3.7",
3
+ "version": "0.5.0",
4
4
  "type": "module",
5
- "description": "Design token editor with live CSS variable editing. Svelte 4 + Vite.",
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"
@@ -37,7 +38,8 @@
37
38
  "src/assets",
38
39
  "dist-plugin",
39
40
  "!**/*.test.ts",
40
- "!**/*.spec.ts"
41
+ "!**/*.spec.ts",
42
+ "!**/__tests__/**"
41
43
  ],
42
44
  "exports": {
43
45
  ".": {
@@ -92,22 +94,22 @@
92
94
  },
93
95
  "peerDependencies": {
94
96
  "sass": "^1.0",
95
- "svelte": "^4.2",
97
+ "svelte": "^5",
96
98
  "svelte-preprocess": "^6.0",
97
- "vite": "^5.0"
99
+ "vite": "^6 || ^7"
98
100
  },
99
101
  "devDependencies": {
100
- "@sveltejs/vite-plugin-svelte": "^3.1.2",
102
+ "@sveltejs/vite-plugin-svelte": "^6.2.4",
101
103
  "@tsconfig/svelte": "^5.0.8",
102
104
  "@types/node": "^24.12.0",
103
105
  "happy-dom": "^20.9.0",
104
106
  "sass": "^1.98.0",
105
- "svelte": "^4.2.20",
106
- "svelte-check": "^3.8.6",
107
+ "svelte": "^5.55.5",
108
+ "svelte-check": "^4.4.8",
107
109
  "svelte-preprocess": "^6.0.3",
108
110
  "tsup": "^8.5.1",
109
111
  "typescript": "~5.9.3",
110
- "vite": "^5.4.21",
112
+ "vite": "^7.3.3",
111
113
  "vitest": "^4.1.4"
112
114
  },
113
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