@motion-proto/live-tokens 0.3.9 → 0.6.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.
- package/README.md +47 -4
- package/package.json +18 -12
- package/src/component-editor/BadgeEditor.svelte +24 -22
- package/src/component-editor/CalloutEditor.svelte +3 -3
- package/src/component-editor/CardEditor.svelte +25 -21
- package/src/component-editor/CollapsibleSectionEditor.svelte +27 -25
- package/src/component-editor/CornerBadgeEditor.svelte +37 -35
- package/src/component-editor/DialogEditor.svelte +26 -24
- package/src/component-editor/ImageEditor.svelte +11 -9
- package/src/component-editor/InlineEditActionsEditor.svelte +17 -15
- package/src/component-editor/NotificationEditor.svelte +32 -30
- package/src/component-editor/ProgressBarEditor.svelte +3 -3
- package/src/component-editor/RadioButtonEditor.svelte +31 -29
- package/src/component-editor/SectionDividerEditor.svelte +30 -28
- package/src/component-editor/SegmentedControlEditor.svelte +29 -25
- package/src/component-editor/StandardButtonsEditor.svelte +42 -38
- package/src/component-editor/TabBarEditor.svelte +20 -18
- package/src/component-editor/TableEditor.svelte +4 -4
- package/src/component-editor/TooltipEditor.svelte +11 -9
- package/src/component-editor/registry.ts +2 -2
- package/src/component-editor/scaffolding/AngleDial.svelte +20 -19
- package/src/component-editor/scaffolding/ComponentEditorBase.svelte +44 -20
- package/src/component-editor/scaffolding/ComponentFileManager.svelte +262 -38
- package/src/component-editor/scaffolding/ComponentFileMenu.svelte +41 -29
- package/src/component-editor/scaffolding/ComponentsTab.svelte +7 -3
- package/src/component-editor/scaffolding/CopyFromMenu.svelte +21 -12
- package/src/component-editor/scaffolding/DemoHeader.svelte +13 -4
- package/src/component-editor/scaffolding/DividerEditor.svelte +27 -14
- package/src/component-editor/scaffolding/FieldsetWrapper.svelte +10 -4
- package/src/component-editor/scaffolding/GradientCard.svelte +25 -20
- package/src/component-editor/scaffolding/LinkageChart.svelte +43 -34
- package/src/component-editor/scaffolding/LinkedBlock.svelte +24 -21
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +6 -1
- package/src/component-editor/scaffolding/SaveAsDialog.svelte +39 -35
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +21 -9
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +8 -3
- package/src/component-editor/scaffolding/StateBlock.svelte +30 -13
- package/src/component-editor/scaffolding/TokenLayout.svelte +46 -30
- package/src/component-editor/scaffolding/TypeEditor.svelte +52 -26
- package/src/component-editor/scaffolding/VariantGroup.svelte +81 -48
- package/src/component-editor/scaffolding/componentSectionType.ts +2 -2
- package/src/components/Badge.svelte +45 -26
- package/src/components/Button.svelte +44 -21
- package/src/components/Callout.svelte +17 -12
- package/src/components/Card.svelte +23 -11
- package/src/components/CollapsibleSection.svelte +56 -27
- package/src/components/CornerBadge.svelte +32 -18
- package/src/components/Dialog.svelte +55 -31
- package/src/components/Image.svelte +14 -5
- package/src/components/InlineEditActions.svelte +22 -10
- package/src/components/Notification.svelte +39 -19
- package/src/components/ProgressBar.svelte +27 -17
- package/src/components/RadioButton.svelte +27 -10
- package/src/components/SectionDivider.svelte +34 -26
- package/src/components/SegmentedControl.svelte +23 -9
- package/src/components/TabBar.svelte +23 -10
- package/src/components/Table.svelte +8 -3
- package/src/components/Tooltip.svelte +15 -5
- package/src/lib/ColumnsOverlay.svelte +3 -3
- package/src/lib/LiveEditorOverlay.svelte +57 -36
- package/src/pages/ComponentEditorPage.svelte +25 -14
- package/src/pages/Editor.svelte +8 -2
- package/src/pages/EditorShell.svelte +24 -20
- package/src/styles/site.css +138 -0
- package/src/styles/tokens.css +78 -76
- package/src/styles/ui-form-controls.css +186 -0
- package/src/ui/BezierCurveEditor.svelte +59 -43
- package/src/ui/ColorEditPanel.svelte +71 -44
- package/src/ui/EditorViewSwitcher.svelte +9 -5
- package/src/ui/FontStackEditor.svelte +17 -16
- package/src/ui/GradientEditor.svelte +42 -33
- package/src/ui/GradientStopPicker.svelte +18 -29
- package/src/ui/PaletteEditor.svelte +238 -212
- package/src/ui/PresetFileManager.svelte +20 -18
- package/src/ui/ProjectFontsSection.svelte +34 -34
- package/src/ui/SurfacesTab.svelte +3 -3
- package/src/ui/TextTab.svelte +2 -2
- package/src/ui/ThemeFileManager.svelte +38 -35
- package/src/ui/Toggle.svelte +11 -9
- package/src/ui/UICopyPopover.svelte +19 -15
- package/src/ui/UIDialog.svelte +48 -30
- package/src/ui/UIFontFamilySelector.svelte +104 -78
- package/src/ui/UIFontSizeSelector.svelte +38 -20
- package/src/ui/UIFontWeightSelector.svelte +33 -13
- package/src/ui/UILineHeightSelector.svelte +33 -13
- package/src/ui/UILinkToggle.svelte +7 -6
- package/src/ui/UIOptionItem.svelte +21 -7
- package/src/ui/UIOptionList.svelte +9 -3
- package/src/ui/UIPaddingSelector.svelte +108 -82
- package/src/ui/UIPaletteSelector.svelte +186 -161
- package/src/ui/UIRadio.svelte +23 -8
- package/src/ui/UIRadioGroup.svelte +9 -8
- package/src/ui/UIRelinkConfirmPopover.svelte +26 -16
- package/src/ui/UITokenSelector.svelte +112 -68
- package/src/ui/UIVariantSelector.svelte +79 -57
- package/src/ui/VariablesTab.svelte +15 -15
- package/src/ui/palette/GradientStopEditor.svelte +45 -26
- package/src/ui/palette/OverridesPanel.svelte +85 -49
- package/src/ui/palette/PaletteBase.svelte +60 -32
- package/src/ui/palette/ScaleCurveEditor.svelte +25 -10
- package/src/ui/sections/ColumnsSection.svelte +13 -13
- package/src/ui/sections/GradientsSection.svelte +12 -9
- package/src/ui/sections/OverlaysSection.svelte +50 -47
- package/src/ui/sections/ShadowsSection.svelte +110 -104
- package/src/ui/sections/TokenScaleTable.svelte +38 -22
- package/src/ui/sections/tokenScales.ts +2 -2
- package/src/styles/form-controls.css +0 -188
package/README.md
CHANGED
|
@@ -127,13 +127,56 @@ The components carry their own design-token aliases (declared inside each `.svel
|
|
|
127
127
|
|
|
128
128
|
### Styles
|
|
129
129
|
|
|
130
|
+
Editor chrome (`ui-editor.css`, `ui-form-controls.css`) and the icon font are
|
|
131
|
+
**auto-loaded by the editor pages themselves**; you don't import them. The
|
|
132
|
+
only stylesheet a consumer needs is a `tokens.css` declaring the design-token
|
|
133
|
+
CSS variables on `:root`.
|
|
134
|
+
|
|
135
|
+
You can use the package's default as a starting point:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import '@motion-proto/live-tokens/starter/tokens.css';
|
|
139
|
+
import '@motion-proto/live-tokens/starter/site.css'; // optional: themed h1/p/a styles
|
|
140
|
+
import '@motion-proto/live-tokens/starter/fonts.css'; // optional: Fraunces + Manrope @font-face
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
…or copy `node_modules/@motion-proto/live-tokens/src/styles/tokens.css` into
|
|
144
|
+
your project and edit. The editor will seed `themes/default.json` on first
|
|
145
|
+
run and you can promote your edits back into the file.
|
|
146
|
+
|
|
147
|
+
## Consuming live-tokens from scratch
|
|
148
|
+
|
|
149
|
+
The minimum a consumer needs after `npm install @motion-proto/live-tokens`:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
// src/main.ts
|
|
153
|
+
import '@motion-proto/live-tokens/starter/tokens.css';
|
|
154
|
+
import { mount } from 'svelte';
|
|
155
|
+
import App from './App.svelte';
|
|
156
|
+
|
|
157
|
+
mount(App, { target: document.getElementById('app')! });
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```svelte
|
|
161
|
+
<!-- src/App.svelte -->
|
|
162
|
+
<script lang="ts">
|
|
163
|
+
import Editor from '@motion-proto/live-tokens/editor';
|
|
164
|
+
</script>
|
|
165
|
+
|
|
166
|
+
<Editor />
|
|
167
|
+
```
|
|
168
|
+
|
|
130
169
|
```ts
|
|
131
|
-
|
|
132
|
-
import '
|
|
133
|
-
import '@
|
|
170
|
+
// vite.config.ts
|
|
171
|
+
import { defineConfig } from 'vite';
|
|
172
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
173
|
+
|
|
174
|
+
export default defineConfig({
|
|
175
|
+
plugins: [svelte()],
|
|
176
|
+
});
|
|
134
177
|
```
|
|
135
178
|
|
|
136
|
-
|
|
179
|
+
No `css: 'injected'` workaround, no `optimizeDeps` excludes — `vite build` works as-is. (You'll want the full `themeFileApi` plugin from the Quick install section above when you're ready to persist edits to disk.)
|
|
137
180
|
|
|
138
181
|
## Greenfield? Use the starter
|
|
139
182
|
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motion-proto/live-tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Design token editor with live CSS variable editing. Svelte
|
|
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"
|
|
@@ -28,11 +29,12 @@
|
|
|
28
29
|
"src/pages/ComponentEditorPage.svelte",
|
|
29
30
|
"src/pages/ComponentEditorPage.svelte.d.ts",
|
|
30
31
|
"src/styles/ui-editor.css",
|
|
31
|
-
"src/styles/form-controls.css",
|
|
32
|
+
"src/styles/ui-form-controls.css",
|
|
32
33
|
"src/styles/fonts.css",
|
|
33
34
|
"src/styles/fonts",
|
|
34
35
|
"src/styles/_padding.scss",
|
|
35
36
|
"src/styles/tokens.css",
|
|
37
|
+
"src/styles/site.css",
|
|
36
38
|
"src/data",
|
|
37
39
|
"src/assets",
|
|
38
40
|
"dist-plugin",
|
|
@@ -76,8 +78,9 @@
|
|
|
76
78
|
"require": "./dist-plugin/index.cjs"
|
|
77
79
|
},
|
|
78
80
|
"./styles/ui-editor.css": "./src/styles/ui-editor.css",
|
|
79
|
-
"./
|
|
80
|
-
"./
|
|
81
|
+
"./starter/tokens.css": "./src/styles/tokens.css",
|
|
82
|
+
"./starter/site.css": "./src/styles/site.css",
|
|
83
|
+
"./starter/fonts.css": "./src/styles/fonts.css"
|
|
81
84
|
},
|
|
82
85
|
"scripts": {
|
|
83
86
|
"dev": "vite",
|
|
@@ -89,26 +92,29 @@
|
|
|
89
92
|
"build:plugin": "tsup src/vite-plugin/index.ts --out-dir dist-plugin --format esm,cjs --dts --external vite --platform node --clean",
|
|
90
93
|
"build:lib": "npm run build:plugin",
|
|
91
94
|
"deploy:local": "bash scripts/deploy-local.sh",
|
|
92
|
-
"
|
|
95
|
+
"check:no-style-imports": "node scripts/check-no-style-imports.mjs",
|
|
96
|
+
"check:editor-font-isolation": "node scripts/check-editor-font-isolation.mjs",
|
|
97
|
+
"check:smoke-install": "bash scripts/smoke-install.sh",
|
|
98
|
+
"prepublishOnly": "npm run check:no-style-imports && npm run check:editor-font-isolation && npm run build:lib && npm run check:smoke-install"
|
|
93
99
|
},
|
|
94
100
|
"peerDependencies": {
|
|
95
101
|
"sass": "^1.0",
|
|
96
|
-
"svelte": "^
|
|
102
|
+
"svelte": "^5",
|
|
97
103
|
"svelte-preprocess": "^6.0",
|
|
98
|
-
"vite": "^
|
|
104
|
+
"vite": "^6 || ^7"
|
|
99
105
|
},
|
|
100
106
|
"devDependencies": {
|
|
101
|
-
"@sveltejs/vite-plugin-svelte": "^
|
|
107
|
+
"@sveltejs/vite-plugin-svelte": "^6.2.4",
|
|
102
108
|
"@tsconfig/svelte": "^5.0.8",
|
|
103
109
|
"@types/node": "^24.12.0",
|
|
104
110
|
"happy-dom": "^20.9.0",
|
|
105
111
|
"sass": "^1.98.0",
|
|
106
|
-
"svelte": "^
|
|
107
|
-
"svelte-check": "^
|
|
112
|
+
"svelte": "^5.55.5",
|
|
113
|
+
"svelte-check": "^4.4.8",
|
|
108
114
|
"svelte-preprocess": "^6.0.3",
|
|
109
115
|
"tsup": "^8.5.1",
|
|
110
116
|
"typescript": "~5.9.3",
|
|
111
|
-
"vite": "^
|
|
117
|
+
"vite": "^7.3.3",
|
|
112
118
|
"vitest": "^4.1.4"
|
|
113
119
|
},
|
|
114
120
|
"dependencies": {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<script
|
|
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
|
-
|
|
73
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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={
|
|
102
|
-
<span>
|
|
97
|
+
<input type="checkbox" bind:checked={floating} />
|
|
98
|
+
<span>Floating preview</span>
|
|
103
99
|
</label>
|
|
104
|
-
|
|
105
|
-
<
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
|
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
|
-
|
|
80
|
-
|
|
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
|
|
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
|
-
|
|
130
|
+
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
131
131
|
|
|
132
|
-
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
-
|
|
153
|
+
|
|
152
154
|
>
|
|
153
|
-
|
|
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
|
-
|
|
161
|
-
{
|
|
162
|
-
|
|
163
|
-
<
|
|
164
|
-
<
|
|
165
|
-
<
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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
|
|
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
|
-
|
|
128
|
+
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
129
129
|
|
|
130
|
-
|
|
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
|
-
|
|
144
|
+
|
|
145
145
|
>
|
|
146
|
-
{
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
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
|
|
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
|
-
|
|
69
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
<
|
|
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
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
|
|
120
|
-
|
|
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
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
<
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
116
|
+
{#snippet config()}
|
|
117
|
+
|
|
118
|
+
<label>
|
|
119
|
+
<span>Cancel button (left)</span>
|
|
120
|
+
<select class="ui-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="ui-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
|
|
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
|
-
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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">
|