@motion-proto/live-tokens 0.1.1 → 0.3.2
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 +168 -21
- package/dist-plugin/index.cjs +823 -336
- package/dist-plugin/index.d.cts +9 -7
- package/dist-plugin/index.d.ts +9 -7
- package/dist-plugin/index.js +822 -335
- package/package.json +46 -20
- package/src/assets/newspaper.webp +0 -0
- package/src/assets/offering.webp +0 -0
- package/src/component-editor/BadgeEditor.svelte +170 -0
- package/src/component-editor/CalloutEditor.svelte +103 -0
- package/src/component-editor/CardEditor.svelte +184 -0
- package/src/component-editor/CollapsibleSectionEditor.svelte +167 -0
- package/src/component-editor/CornerBadgeEditor.svelte +207 -0
- package/src/component-editor/DialogEditor.svelte +172 -0
- package/src/component-editor/ImageEditor.svelte +72 -0
- package/src/component-editor/InlineEditActionsEditor.svelte +83 -0
- package/src/component-editor/NotificationEditor.svelte +160 -0
- package/src/component-editor/ProgressBarEditor.svelte +124 -0
- package/src/component-editor/RadioButtonEditor.svelte +140 -0
- package/src/component-editor/SectionDividerEditor.svelte +263 -0
- package/src/component-editor/SegmentedControlEditor.svelte +154 -0
- package/src/component-editor/StandardButtonsEditor.svelte +178 -0
- package/src/component-editor/TabBarEditor.svelte +137 -0
- package/src/component-editor/TableEditor.svelte +128 -0
- package/src/component-editor/TooltipEditor.svelte +122 -0
- package/src/component-editor/editorTokens.test.ts +93 -0
- package/src/component-editor/groupKeySlots.test.ts +67 -0
- package/src/component-editor/groupKeySnapshot.test.ts +52 -0
- package/src/component-editor/index.ts +5 -0
- package/src/component-editor/registry.ts +246 -0
- package/src/component-editor/scaffolding/AngleDial.svelte +185 -0
- package/src/component-editor/scaffolding/ComponentEditorBase.svelte +96 -0
- package/src/component-editor/scaffolding/ComponentFileManager.svelte +682 -0
- package/src/component-editor/scaffolding/ComponentFileMenu.svelte +312 -0
- package/src/component-editor/scaffolding/ComponentsTab.svelte +69 -0
- package/src/component-editor/scaffolding/CopyFromMenu.svelte +246 -0
- package/src/component-editor/scaffolding/DemoHeader.svelte +21 -0
- package/src/component-editor/scaffolding/DividerEditor.svelte +81 -0
- package/src/component-editor/scaffolding/FieldsetWrapper.svelte +46 -0
- package/src/component-editor/scaffolding/GradientCard.svelte +291 -0
- package/src/component-editor/scaffolding/LinkageChart.svelte +297 -0
- package/src/component-editor/scaffolding/LinkedBlock.svelte +418 -0
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +57 -0
- package/src/component-editor/scaffolding/SaveAsDialog.svelte +177 -0
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +25 -0
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +56 -0
- package/src/component-editor/scaffolding/StateBlock.svelte +115 -0
- package/src/component-editor/scaffolding/TokenLayout.svelte +511 -0
- package/src/component-editor/scaffolding/TypeEditor.svelte +82 -0
- package/src/component-editor/scaffolding/VariantGroup.svelte +277 -0
- package/src/component-editor/scaffolding/buildTypeGroupTokens.ts +97 -0
- package/src/component-editor/scaffolding/componentSectionType.ts +8 -0
- package/src/component-editor/scaffolding/componentSources.ts +9 -0
- package/src/component-editor/scaffolding/defaultSections.ts +16 -0
- package/src/component-editor/scaffolding/editorContext.ts +44 -0
- package/src/component-editor/scaffolding/linkedBlock.ts +226 -0
- package/src/component-editor/scaffolding/siblings.ts +33 -0
- package/src/component-editor/scaffolding/types.ts +39 -0
- package/src/components/Badge.svelte +231 -42
- package/src/components/Button.svelte +324 -124
- package/src/components/Callout.svelte +145 -0
- package/src/components/Card.svelte +123 -25
- package/src/components/CollapsibleSection.svelte +213 -35
- package/src/components/CornerBadge.svelte +224 -0
- package/src/components/Dialog.svelte +137 -114
- package/src/components/Image.svelte +43 -0
- package/src/components/InlineEditActions.svelte +74 -14
- package/src/components/Notification.svelte +184 -163
- package/src/components/ProgressBar.svelte +216 -22
- package/src/components/RadioButton.svelte +110 -40
- package/src/components/SectionDivider.svelte +428 -74
- package/src/components/SegmentedControl.svelte +203 -0
- package/src/components/TabBar.svelte +146 -21
- package/src/components/Table.svelte +102 -0
- package/src/components/Tooltip.svelte +45 -19
- package/src/components/types.ts +51 -0
- package/src/data/google-fonts.json +75 -0
- package/src/lib/ColumnsOverlay.svelte +20 -7
- package/src/lib/LiveEditorOverlay.svelte +257 -78
- package/src/lib/columnsOverlay.ts +21 -17
- package/src/lib/componentConfig.test.ts +204 -0
- package/src/lib/componentConfigKeys.ts +19 -0
- package/src/lib/componentConfigService.ts +88 -0
- package/src/lib/copyPopover.ts +30 -0
- package/src/lib/cssVarSync.ts +59 -7
- package/src/lib/editorConfigStore.ts +0 -10
- package/src/lib/editorCore.ts +402 -0
- package/src/lib/editorKeybindings.ts +52 -0
- package/src/lib/editorPersistence.ts +106 -0
- package/src/lib/editorRenderer.ts +74 -0
- package/src/lib/editorStore.test.ts +328 -0
- package/src/lib/editorStore.ts +412 -0
- package/src/lib/editorTypes.ts +100 -0
- package/src/lib/editorViewStore.ts +55 -0
- package/src/lib/files/versionedFileResource.ts +140 -0
- package/src/lib/fontLoader.ts +130 -0
- package/src/lib/fontMigration.ts +140 -0
- package/src/lib/fontParse.ts +168 -0
- package/src/lib/index.ts +48 -30
- package/src/lib/lazyConfig.test.ts +54 -0
- package/src/lib/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +64 -0
- package/src/lib/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +71 -0
- package/src/lib/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +43 -0
- package/src/lib/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +68 -0
- package/src/lib/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +35 -0
- package/src/lib/migrations/2026-05-10-sectiondivider-gradient-stops.ts +50 -0
- package/src/lib/migrations/2026-05-13-primary-to-brand.ts +90 -0
- package/src/lib/migrations/index.ts +93 -0
- package/src/lib/migrations/migrations.test.ts +341 -0
- package/src/lib/navLinkTypes.ts +1 -0
- package/src/lib/overlayState.ts +3 -0
- package/src/lib/paletteDerivation.ts +300 -0
- package/src/lib/parentRouteStore.ts +42 -0
- package/src/lib/parsers/globalRootBlock.ts +32 -0
- package/src/lib/presetService.ts +94 -0
- package/src/lib/router.ts +42 -10
- package/src/lib/scrollSection.ts +45 -0
- package/src/lib/slices/columns.ts +59 -0
- package/src/lib/slices/components.ts +362 -0
- package/src/lib/slices/domainVars.ts +15 -0
- package/src/lib/slices/fonts.ts +30 -0
- package/src/lib/slices/gradients.ts +153 -0
- package/src/lib/slices/overlays.ts +132 -0
- package/src/lib/slices/palettes.ts +26 -0
- package/src/lib/slices/shadows.ts +123 -0
- package/src/lib/storage.ts +88 -0
- package/src/lib/themeInit.ts +74 -0
- package/src/lib/themeService.ts +101 -0
- package/src/lib/themeTypes.ts +146 -0
- package/src/lib/tokenRegistry.ts +148 -0
- package/src/pages/ComponentEditorPage.svelte +384 -0
- package/src/pages/ComponentEditorPage.svelte.d.ts +2 -0
- package/src/pages/Editor.svelte +98 -0
- package/src/pages/Editor.svelte.d.ts +2 -0
- package/src/pages/EditorShell.svelte +348 -0
- package/src/styles/_padding.scss +34 -0
- package/src/styles/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
- package/src/styles/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
- package/src/styles/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
- package/src/styles/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
- package/src/styles/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
- package/src/styles/fonts/Manrope/Manrope-latin.woff2 +0 -0
- package/src/styles/fonts.css +22 -10
- package/src/styles/form-controls.css +14 -16
- package/src/styles/tokens.css +1322 -0
- package/src/styles/ui-editor.css +126 -0
- package/src/{showcase → ui}/BezierCurveEditor.svelte +14 -14
- package/src/{showcase → ui}/ColorEditPanel.svelte +42 -36
- package/src/ui/EditorViewSwitcher.svelte +180 -0
- package/src/ui/FontStackEditor.svelte +360 -0
- package/src/ui/GradientEditor.svelte +461 -0
- package/src/ui/GradientStopPicker.svelte +74 -0
- package/src/ui/PaletteEditor.svelte +1590 -0
- package/src/ui/PaletteEditor.test.ts +108 -0
- package/src/ui/PresetFileManager.svelte +567 -0
- package/src/ui/ProjectFontsSection.svelte +645 -0
- package/src/{showcase → ui}/SurfacesTab.svelte +39 -39
- package/src/{showcase → ui}/TextTab.svelte +27 -27
- package/src/{showcase/TokenFileManager.svelte → ui/ThemeFileManager.svelte} +196 -112
- package/src/ui/Toggle.svelte +108 -0
- package/src/ui/UICopyPopover.svelte +78 -0
- package/src/{showcase/EditorDialog.svelte → ui/UIDialog.svelte} +66 -25
- package/src/ui/UIFontFamilySelector.svelte +309 -0
- package/src/ui/UIFontSizeSelector.svelte +165 -0
- package/src/ui/UIFontWeightSelector.svelte +52 -0
- package/src/ui/UILineHeightSelector.svelte +47 -0
- package/src/ui/UILinkToggle.svelte +60 -0
- package/src/ui/UIOptionItem.svelte +74 -0
- package/src/ui/UIOptionList.svelte +27 -0
- package/src/ui/UIPaddingSelector.svelte +661 -0
- package/src/ui/UIPaletteSelector.svelte +1084 -0
- package/src/ui/UIRadio.svelte +72 -0
- package/src/ui/UIRadioGroup.svelte +59 -0
- package/src/ui/UIRelinkConfirmPopover.svelte +235 -0
- package/src/ui/UITokenSelector.svelte +509 -0
- package/src/ui/UIVariantSelector.svelte +145 -0
- package/src/ui/VariablesTab.svelte +252 -0
- package/src/ui/index.ts +31 -0
- package/src/ui/keepInViewport.ts +84 -0
- package/src/ui/palette/GradientStopEditor.svelte +482 -0
- package/src/ui/palette/OverridesPanel.svelte +526 -0
- package/src/ui/palette/PaletteBase.svelte +165 -0
- package/src/ui/palette/ScaleCurveEditor.svelte +38 -0
- package/src/ui/palette/paletteEditorState.ts +89 -0
- package/src/ui/sections/ColumnsSection.svelte +273 -0
- package/src/ui/sections/GradientsSection.svelte +147 -0
- package/src/ui/sections/OverlaysSection.svelte +670 -0
- package/src/ui/sections/ShadowsSection.svelte +1250 -0
- package/src/ui/sections/TokenScaleTable.svelte +332 -0
- package/src/ui/sections/tokenScales.ts +81 -0
- package/src/ui/variantScales.ts +108 -0
- package/src/components/DetailNav.svelte +0 -78
- package/src/components/Toggle.svelte +0 -86
- package/src/lib/tokenInit.ts +0 -29
- package/src/lib/tokenService.ts +0 -144
- package/src/lib/tokenTypes.ts +0 -45
- package/src/pages/Admin.svelte +0 -100
- package/src/pages/ShowcasePage.svelte +0 -144
- package/src/showcase/BackupBrowser.svelte +0 -617
- package/src/showcase/ComponentsTab.svelte +0 -105
- package/src/showcase/PaletteEditor.svelte +0 -2579
- package/src/showcase/PaletteSelector.svelte +0 -627
- package/src/showcase/TokenMap.svelte +0 -54
- package/src/showcase/VariablesTab.svelte +0 -2655
- package/src/showcase/VisualsTab.svelte +0 -231
- package/src/showcase/demos/BadgeDemo.svelte +0 -56
- package/src/showcase/demos/CardDemo.svelte +0 -50
- package/src/showcase/demos/ChoiceButtonsDemo.svelte +0 -192
- package/src/showcase/demos/CollapsibleSectionDemo.svelte +0 -54
- package/src/showcase/demos/DialogDemo.svelte +0 -42
- package/src/showcase/demos/InlineEditActionsDemo.svelte +0 -25
- package/src/showcase/demos/NotificationDemo.svelte +0 -147
- package/src/showcase/demos/ProgressBarDemo.svelte +0 -54
- package/src/showcase/demos/RadioButtonDemo.svelte +0 -56
- package/src/showcase/demos/SectionDividerDemo.svelte +0 -77
- package/src/showcase/demos/StandardButtonsDemo.svelte +0 -455
- package/src/showcase/demos/TabBarDemo.svelte +0 -58
- package/src/showcase/demos/TooltipDemo.svelte +0 -52
- package/src/showcase/editor.css +0 -93
- package/src/showcase/index.ts +0 -17
- package/src/styles/fonts/Domine/Domine-VariableFont_wght.ttf +0 -0
- package/src/styles/fonts/Domine/OFL.txt +0 -97
- package/src/styles/fonts/Domine/README.txt +0 -66
- /package/src/{showcase → ui}/curveEngine.ts +0 -0
package/package.json
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motion-proto/live-tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Design token editor with live CSS variable editing. Svelte 4 + Vite.",
|
|
6
|
-
"keywords": [
|
|
6
|
+
"keywords": [
|
|
7
|
+
"svelte",
|
|
8
|
+
"vite",
|
|
9
|
+
"design-tokens",
|
|
10
|
+
"css-variables",
|
|
11
|
+
"editor"
|
|
12
|
+
],
|
|
7
13
|
"license": "MIT",
|
|
8
14
|
"repository": {
|
|
9
15
|
"type": "git",
|
|
@@ -13,14 +19,22 @@
|
|
|
13
19
|
"bugs": "https://github.com/motionproto/live-tokens/issues",
|
|
14
20
|
"files": [
|
|
15
21
|
"src/lib",
|
|
16
|
-
"src/
|
|
22
|
+
"src/ui",
|
|
23
|
+
"src/component-editor",
|
|
17
24
|
"src/components",
|
|
18
|
-
"src/pages/
|
|
19
|
-
"src/pages/
|
|
20
|
-
"src/
|
|
25
|
+
"src/pages/Editor.svelte",
|
|
26
|
+
"src/pages/Editor.svelte.d.ts",
|
|
27
|
+
"src/pages/EditorShell.svelte",
|
|
28
|
+
"src/pages/ComponentEditorPage.svelte",
|
|
29
|
+
"src/pages/ComponentEditorPage.svelte.d.ts",
|
|
30
|
+
"src/styles/ui-editor.css",
|
|
21
31
|
"src/styles/form-controls.css",
|
|
22
32
|
"src/styles/fonts.css",
|
|
23
33
|
"src/styles/fonts",
|
|
34
|
+
"src/styles/_padding.scss",
|
|
35
|
+
"src/styles/tokens.css",
|
|
36
|
+
"src/data",
|
|
37
|
+
"src/assets",
|
|
24
38
|
"dist-plugin"
|
|
25
39
|
],
|
|
26
40
|
"exports": {
|
|
@@ -29,29 +43,36 @@
|
|
|
29
43
|
"types": "./src/lib/index.ts",
|
|
30
44
|
"default": "./src/lib/index.ts"
|
|
31
45
|
},
|
|
32
|
-
"./
|
|
33
|
-
"svelte": "./src/
|
|
34
|
-
"types": "./src/
|
|
35
|
-
"default": "./src/
|
|
46
|
+
"./component-editor": {
|
|
47
|
+
"svelte": "./src/component-editor/index.ts",
|
|
48
|
+
"types": "./src/component-editor/index.ts",
|
|
49
|
+
"default": "./src/component-editor/index.ts"
|
|
36
50
|
},
|
|
37
|
-
"./
|
|
38
|
-
"svelte": "./src/
|
|
51
|
+
"./ui": {
|
|
52
|
+
"svelte": "./src/ui/index.ts",
|
|
53
|
+
"types": "./src/ui/index.ts",
|
|
54
|
+
"default": "./src/ui/index.ts"
|
|
39
55
|
},
|
|
40
|
-
"./
|
|
41
|
-
"
|
|
56
|
+
"./editor": {
|
|
57
|
+
"types": "./src/pages/Editor.svelte.d.ts",
|
|
58
|
+
"svelte": "./src/pages/Editor.svelte",
|
|
59
|
+
"default": "./src/pages/Editor.svelte"
|
|
42
60
|
},
|
|
43
|
-
"./
|
|
44
|
-
"
|
|
61
|
+
"./component-editor-page": {
|
|
62
|
+
"types": "./src/pages/ComponentEditorPage.svelte.d.ts",
|
|
63
|
+
"svelte": "./src/pages/ComponentEditorPage.svelte",
|
|
64
|
+
"default": "./src/pages/ComponentEditorPage.svelte"
|
|
45
65
|
},
|
|
46
|
-
"./
|
|
47
|
-
"svelte": "./src/
|
|
66
|
+
"./components/*": {
|
|
67
|
+
"svelte": "./src/components/*",
|
|
68
|
+
"default": "./src/components/*"
|
|
48
69
|
},
|
|
49
70
|
"./vite-plugin": {
|
|
50
71
|
"types": "./dist-plugin/index.d.ts",
|
|
51
72
|
"import": "./dist-plugin/index.js",
|
|
52
73
|
"require": "./dist-plugin/index.cjs"
|
|
53
74
|
},
|
|
54
|
-
"./styles/editor.css": "./src/
|
|
75
|
+
"./styles/ui-editor.css": "./src/styles/ui-editor.css",
|
|
55
76
|
"./styles/form-controls.css": "./src/styles/form-controls.css",
|
|
56
77
|
"./styles/fonts.css": "./src/styles/fonts.css"
|
|
57
78
|
},
|
|
@@ -60,8 +81,11 @@
|
|
|
60
81
|
"build": "vite build",
|
|
61
82
|
"preview": "vite preview",
|
|
62
83
|
"check": "svelte-check --tsconfig ./tsconfig.json",
|
|
84
|
+
"test": "vitest run",
|
|
85
|
+
"test:watch": "vitest",
|
|
63
86
|
"build:plugin": "tsup src/vite-plugin/index.ts --out-dir dist-plugin --format esm,cjs --dts --external vite --platform node --clean",
|
|
64
87
|
"build:lib": "npm run build:plugin",
|
|
88
|
+
"deploy:local": "bash scripts/deploy-local.sh",
|
|
65
89
|
"prepublishOnly": "npm run build:lib"
|
|
66
90
|
},
|
|
67
91
|
"peerDependencies": {
|
|
@@ -74,13 +98,15 @@
|
|
|
74
98
|
"@sveltejs/vite-plugin-svelte": "^3.1.2",
|
|
75
99
|
"@tsconfig/svelte": "^5.0.8",
|
|
76
100
|
"@types/node": "^24.12.0",
|
|
101
|
+
"happy-dom": "^20.9.0",
|
|
77
102
|
"sass": "^1.98.0",
|
|
78
103
|
"svelte": "^4.2.20",
|
|
79
104
|
"svelte-check": "^3.8.6",
|
|
80
105
|
"svelte-preprocess": "^6.0.3",
|
|
81
106
|
"tsup": "^8.5.1",
|
|
82
107
|
"typescript": "~5.9.3",
|
|
83
|
-
"vite": "^5.4.21"
|
|
108
|
+
"vite": "^5.4.21",
|
|
109
|
+
"vitest": "^4.1.4"
|
|
84
110
|
},
|
|
85
111
|
"dependencies": {
|
|
86
112
|
"@fortawesome/fontawesome-free": "^7.2.0"
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
+
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
import { badgeVariants } from '../components/Badge.svelte';
|
|
5
|
+
|
|
6
|
+
export const component = 'badge';
|
|
7
|
+
const variants = badgeVariants;
|
|
8
|
+
type Variant = typeof variants[number];
|
|
9
|
+
|
|
10
|
+
// Each variant is its own visual presentation; surface/text/border colors are unique.
|
|
11
|
+
// Shape props (radius/border-width/padding/shadow) and font props can be linked across variants.
|
|
12
|
+
function variantTokens(variant: Variant): Token[] {
|
|
13
|
+
return [
|
|
14
|
+
{ label: 'surface color', groupKey: 'surface', variable: `--badge-${variant}-surface` },
|
|
15
|
+
{ label: 'border color', groupKey: 'border', variable: `--badge-${variant}-border` },
|
|
16
|
+
{ label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: `--badge-${variant}-border-width` },
|
|
17
|
+
{ label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: `--badge-${variant}-radius` },
|
|
18
|
+
{ label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `--badge-${variant}-padding` },
|
|
19
|
+
{ label: 'badge shadow', canBeLinked: true, groupKey: 'shadow', variable: `--badge-${variant}-shadow` },
|
|
20
|
+
{ label: 'backdrop blur', canBeLinked: true, groupKey: 'blur', variable: `--badge-${variant}-blur` },
|
|
21
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: `--badge-${variant}-icon-size` },
|
|
22
|
+
];
|
|
23
|
+
}
|
|
24
|
+
function variantTypeGroups(variant: Variant): TypeGroupConfig[] {
|
|
25
|
+
return [{
|
|
26
|
+
legend: `${variant} text`,
|
|
27
|
+
colorVariable: `--badge-${variant}-text`,
|
|
28
|
+
familyVariable: `--badge-${variant}-text-font-family`,
|
|
29
|
+
sizeVariable: `--badge-${variant}-text-font-size`,
|
|
30
|
+
weightVariable: `--badge-${variant}-text-font-weight`,
|
|
31
|
+
lineHeightVariable: `--badge-${variant}-text-line-height`,
|
|
32
|
+
}];
|
|
33
|
+
}
|
|
34
|
+
function variantTypeGroupTokens(variant: Variant): Token[] {
|
|
35
|
+
return [
|
|
36
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'font-family', variable: `--badge-${variant}-text-font-family` },
|
|
37
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'font-size', variable: `--badge-${variant}-text-font-size` },
|
|
38
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'font-weight', variable: `--badge-${variant}-text-font-weight` },
|
|
39
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'line-height', variable: `--badge-${variant}-text-line-height` },
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
export const allTokens: Token[] = variants.flatMap((v) => [
|
|
43
|
+
...variantTokens(v),
|
|
44
|
+
...buildTypeGroupColorTokens(variantTypeGroups(v)),
|
|
45
|
+
...variantTypeGroupTokens(v),
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
// Cross-variant sharing: any token with canBeLinked+groupKey participates in
|
|
49
|
+
// the linked block when ≥2 variants currently agree on its alias.
|
|
50
|
+
const linkableProps = [
|
|
51
|
+
'border-width', 'radius', 'padding', 'shadow', 'blur', 'icon-size',
|
|
52
|
+
'text-font-family', 'text-font-size', 'text-font-weight', 'text-line-height',
|
|
53
|
+
] as const;
|
|
54
|
+
const linkableContexts = new Map<string, string>(
|
|
55
|
+
variants.flatMap((v) => linkableProps.map((p) => [`--badge-${v}-${p}`, v] as [string, string]))
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
59
|
+
</script>
|
|
60
|
+
|
|
61
|
+
<script lang="ts">
|
|
62
|
+
import Badge from '../components/Badge.svelte';
|
|
63
|
+
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
64
|
+
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
65
|
+
import { editorState } from '../lib/editorStore';
|
|
66
|
+
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
67
|
+
import { buildSiblings } from './scaffolding/siblings';
|
|
68
|
+
import ShadowBackdrop from './scaffolding/ShadowBackdrop.svelte';
|
|
69
|
+
import ShadowBackdropControls from './scaffolding/ShadowBackdropControls.svelte';
|
|
70
|
+
import UIRadioGroup from '../ui/UIRadioGroup.svelte';
|
|
71
|
+
|
|
72
|
+
$: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
|
|
73
|
+
$: visibleVariantTokens = (v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet);
|
|
74
|
+
|
|
75
|
+
let bgMode: 'image' | 'color' = 'image';
|
|
76
|
+
const bgVar = '--backdrop-badge-surface';
|
|
77
|
+
|
|
78
|
+
// Preview-only props for Badge's floating/anchor/flush features (not persisted).
|
|
79
|
+
// For corner-anchored use, prefer the dedicated CornerBadge component; Badge.floating
|
|
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';
|
|
84
|
+
const anchorOptions = [
|
|
85
|
+
{ value: 'top-left' as const, label: 'TL' },
|
|
86
|
+
{ value: 'top-right' as const, label: 'TR' },
|
|
87
|
+
{ value: 'bottom-left' as const, label: 'BL' },
|
|
88
|
+
{ value: 'bottom-right' as const, label: 'BR' },
|
|
89
|
+
];
|
|
90
|
+
</script>
|
|
91
|
+
|
|
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}
|
|
100
|
+
<label class="float-toggle">
|
|
101
|
+
<input type="checkbox" bind:checked={flush} />
|
|
102
|
+
<span>Flush corner</span>
|
|
103
|
+
</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>
|
|
110
|
+
{#each variants as v}
|
|
111
|
+
<VariantGroup
|
|
112
|
+
name={v}
|
|
113
|
+
title={v.charAt(0).toUpperCase() + v.slice(1)}
|
|
114
|
+
states={{ [v]: visibleVariantTokens(v) }}
|
|
115
|
+
typeGroups={{ [v]: variantTypeGroups(v) }}
|
|
116
|
+
{component}
|
|
117
|
+
siblings={buildSiblings(variants, v, (sv) => ({ [sv]: variantTokens(sv) }), (sv) => ({ [sv]: variantTypeGroups(sv) }))}
|
|
118
|
+
>
|
|
119
|
+
<ShadowBackdrop mode={bgMode} colorVariable={bgVar}>
|
|
120
|
+
{#if floating}
|
|
121
|
+
<div class="floating-stage">
|
|
122
|
+
<Badge variant={v} {floating} {anchor} {flush}>{v.charAt(0).toUpperCase() + v.slice(1)}</Badge>
|
|
123
|
+
</div>
|
|
124
|
+
{:else}
|
|
125
|
+
<div class="badge-showcase-grid">
|
|
126
|
+
<Badge variant={v}>{v.charAt(0).toUpperCase() + v.slice(1)}</Badge>
|
|
127
|
+
<Badge variant={v} icon="fa-solid fa-dice-d20">With Icon</Badge>
|
|
128
|
+
</div>
|
|
129
|
+
{/if}
|
|
130
|
+
</ShadowBackdrop>
|
|
131
|
+
</VariantGroup>
|
|
132
|
+
{/each}
|
|
133
|
+
</ComponentEditorBase>
|
|
134
|
+
|
|
135
|
+
<style>
|
|
136
|
+
.badge-showcase-grid {
|
|
137
|
+
display: flex;
|
|
138
|
+
flex-wrap: wrap;
|
|
139
|
+
gap: var(--space-8);
|
|
140
|
+
align-items: center;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/* Anchor parent for floating-preview mode — gives the badge a positioned ancestor
|
|
144
|
+
and a visible surface so blur/offset/flush are observable. */
|
|
145
|
+
.floating-stage {
|
|
146
|
+
position: relative;
|
|
147
|
+
width: 100%;
|
|
148
|
+
min-height: 160px;
|
|
149
|
+
border-radius: var(--ui-radius-md);
|
|
150
|
+
background: rgba(0, 0, 0, 0.15);
|
|
151
|
+
overflow: hidden;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.float-toggle {
|
|
155
|
+
display: inline-flex;
|
|
156
|
+
align-items: center;
|
|
157
|
+
gap: var(--ui-space-4);
|
|
158
|
+
font-size: var(--ui-font-size-sm);
|
|
159
|
+
color: var(--ui-text-secondary);
|
|
160
|
+
cursor: pointer;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.anchor-control {
|
|
164
|
+
display: inline-flex;
|
|
165
|
+
align-items: center;
|
|
166
|
+
gap: var(--ui-space-8);
|
|
167
|
+
font-size: var(--ui-font-size-sm);
|
|
168
|
+
color: var(--ui-text-secondary);
|
|
169
|
+
}
|
|
170
|
+
</style>
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
+
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
import { calloutVariants } from '../components/Callout.svelte';
|
|
5
|
+
|
|
6
|
+
export const component = 'callout';
|
|
7
|
+
const variants = calloutVariants;
|
|
8
|
+
type Variant = typeof variants[number];
|
|
9
|
+
|
|
10
|
+
function variantTokens(v: Variant): Token[] {
|
|
11
|
+
return [
|
|
12
|
+
{ label: 'surface color', groupKey: 'surface', variable: `--callout-${v}-surface` },
|
|
13
|
+
{ label: 'border color', groupKey: 'border', variable: `--callout-${v}-border` },
|
|
14
|
+
{ label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: `--callout-${v}-border-width` },
|
|
15
|
+
{ label: 'accent edge width', canBeLinked: true, groupKey: 'accent-width', variable: `--callout-${v}-accent-width` },
|
|
16
|
+
{ label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: `--callout-${v}-radius` },
|
|
17
|
+
{ label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `--callout-${v}-padding` },
|
|
18
|
+
];
|
|
19
|
+
}
|
|
20
|
+
// Two type groups per variant: label (e.g. "Warning.") and message body.
|
|
21
|
+
function variantTypeGroups(v: Variant): TypeGroupConfig[] {
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
legend: `${v} label`,
|
|
25
|
+
colorVariable: `--callout-${v}-label`,
|
|
26
|
+
familyVariable: `--callout-${v}-label-font-family`,
|
|
27
|
+
sizeVariable: `--callout-${v}-label-font-size`,
|
|
28
|
+
weightVariable: `--callout-${v}-label-font-weight`,
|
|
29
|
+
lineHeightVariable: `--callout-${v}-label-line-height`,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
legend: `${v} message`,
|
|
33
|
+
colorVariable: `--callout-${v}-text`,
|
|
34
|
+
familyVariable: `--callout-${v}-text-font-family`,
|
|
35
|
+
sizeVariable: `--callout-${v}-text-font-size`,
|
|
36
|
+
weightVariable: `--callout-${v}-text-font-weight`,
|
|
37
|
+
lineHeightVariable: `--callout-${v}-text-line-height`,
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
}
|
|
41
|
+
function variantTypeGroupTokens(v: Variant): Token[] {
|
|
42
|
+
return [
|
|
43
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'label-font-family', variable: `--callout-${v}-label-font-family` },
|
|
44
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'label-font-size', variable: `--callout-${v}-label-font-size` },
|
|
45
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'label-font-weight', variable: `--callout-${v}-label-font-weight` },
|
|
46
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'label-line-height', variable: `--callout-${v}-label-line-height` },
|
|
47
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'text-font-family', variable: `--callout-${v}-text-font-family` },
|
|
48
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'text-font-size', variable: `--callout-${v}-text-font-size` },
|
|
49
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'text-font-weight', variable: `--callout-${v}-text-font-weight` },
|
|
50
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'text-line-height', variable: `--callout-${v}-text-line-height` },
|
|
51
|
+
];
|
|
52
|
+
}
|
|
53
|
+
export const allTokens: Token[] = variants.flatMap((v) => [
|
|
54
|
+
...variantTokens(v),
|
|
55
|
+
...buildTypeGroupColorTokens(variantTypeGroups(v)),
|
|
56
|
+
...variantTypeGroupTokens(v),
|
|
57
|
+
]);
|
|
58
|
+
|
|
59
|
+
const linkableProps = [
|
|
60
|
+
'border-width', 'accent-width', 'radius', 'padding',
|
|
61
|
+
'label-font-family', 'label-font-size', 'label-font-weight', 'label-line-height',
|
|
62
|
+
'text-font-family', 'text-font-size', 'text-font-weight', 'text-line-height',
|
|
63
|
+
] as const;
|
|
64
|
+
const linkableContexts = new Map<string, string>(
|
|
65
|
+
variants.flatMap((v) => linkableProps.map((p) => [`--callout-${v}-${p}`, v] as [string, string]))
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<script lang="ts">
|
|
72
|
+
import Callout from '../components/Callout.svelte';
|
|
73
|
+
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
74
|
+
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
75
|
+
import { editorState } from '../lib/editorStore';
|
|
76
|
+
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
77
|
+
import { buildSiblings } from './scaffolding/siblings';
|
|
78
|
+
|
|
79
|
+
$: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
|
|
80
|
+
$: visibleVariantTokens = (v: Variant) => withLinkedDisabled(variantTokens(v), linked.varSet);
|
|
81
|
+
|
|
82
|
+
const sample: Record<Variant, { label: string; message: string }> = {
|
|
83
|
+
info: { label: 'Note.', message: 'This is contextual information you should know about.' },
|
|
84
|
+
success: { label: 'Tip.', message: 'Bookmark this page so you can return when you need it.' },
|
|
85
|
+
warning: { label: 'Warning.', message: 'This is a warning callout for important caveats or potential issues.' },
|
|
86
|
+
danger: { label: 'Danger.', message: 'This action is destructive and cannot be undone.' },
|
|
87
|
+
};
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<ComponentEditorBase {component} title="Callout" description="Bordered callout box with semantic info / success / warning / danger variants, label + message text. Import from <code>components/Callout.svelte</code>" tokens={allTokens} {linked} variants={variantOptions}>
|
|
91
|
+
{#each variants as v}
|
|
92
|
+
<VariantGroup
|
|
93
|
+
name={v}
|
|
94
|
+
title={v.charAt(0).toUpperCase() + v.slice(1)}
|
|
95
|
+
states={{ [v]: visibleVariantTokens(v) }}
|
|
96
|
+
typeGroups={{ [v]: variantTypeGroups(v) }}
|
|
97
|
+
{component}
|
|
98
|
+
siblings={buildSiblings(variants, v, (sv) => ({ [sv]: variantTokens(sv) }), (sv) => ({ [sv]: variantTypeGroups(sv) }))}
|
|
99
|
+
>
|
|
100
|
+
<Callout variant={v} label={sample[v].label}>{sample[v].message}</Callout>
|
|
101
|
+
</VariantGroup>
|
|
102
|
+
{/each}
|
|
103
|
+
</ComponentEditorBase>
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
+
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
4
|
+
|
|
5
|
+
export const component = 'card';
|
|
6
|
+
|
|
7
|
+
// The card is a single object across two states (default, hover).
|
|
8
|
+
// Within each state we keep object shape props (surface/border/border-width/radius/padding/shadow) together.
|
|
9
|
+
// Title and body are nested elements with their own typography.
|
|
10
|
+
const states: Record<string, Token[]> = {
|
|
11
|
+
default: [
|
|
12
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--card-default-surface' },
|
|
13
|
+
{ label: 'header color', groupKey: 'surface', variable: '--card-default-header-surface' },
|
|
14
|
+
{ label: 'border color', groupKey: 'border', variable: '--card-default-border' },
|
|
15
|
+
{ label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: '--card-default-border-width' },
|
|
16
|
+
{ label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: '--card-default-radius' },
|
|
17
|
+
{ label: 'header padding', canBeLinked: true, groupKey: 'header-padding', variable: '--card-default-header-padding' },
|
|
18
|
+
{ label: 'body padding', canBeLinked: true, groupKey: 'body-padding', variable: '--card-default-body-padding' },
|
|
19
|
+
{ label: 'card shadow', canBeLinked: true, groupKey: 'shadow', variable: '--card-default-shadow' },
|
|
20
|
+
{ label: 'background blur', canBeLinked: true, groupKey: 'blur', variable: '--card-default-blur' },
|
|
21
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--card-default-icon-size' },
|
|
22
|
+
],
|
|
23
|
+
hover: [
|
|
24
|
+
{ label: 'surface color', groupKey: 'surface', variable: '--card-hover-surface' },
|
|
25
|
+
{ label: 'header color', groupKey: 'surface', variable: '--card-hover-header-surface' },
|
|
26
|
+
{ label: 'border color', groupKey: 'border', variable: '--card-hover-border' },
|
|
27
|
+
{ label: 'border width', canBeLinked: true, groupKey: 'border-width', variable: '--card-hover-border-width' },
|
|
28
|
+
{ label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: '--card-hover-radius' },
|
|
29
|
+
{ label: 'header padding', canBeLinked: true, groupKey: 'header-padding', variable: '--card-hover-header-padding' },
|
|
30
|
+
{ label: 'body padding', canBeLinked: true, groupKey: 'body-padding', variable: '--card-hover-body-padding' },
|
|
31
|
+
{ label: 'card shadow', canBeLinked: true, groupKey: 'shadow', variable: '--card-hover-shadow' },
|
|
32
|
+
{ label: 'background blur', canBeLinked: true, groupKey: 'blur', variable: '--card-hover-blur' },
|
|
33
|
+
{ label: 'icon size', canBeLinked: true, groupKey: 'icon-size', variable: '--card-hover-icon-size' },
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Two type groups per state: title and body. Linked across states (same nested object).
|
|
38
|
+
const typeGroups: Record<string, TypeGroupConfig[]> = {
|
|
39
|
+
default: [
|
|
40
|
+
{
|
|
41
|
+
legend: 'card title',
|
|
42
|
+
colorVariable: '--card-default-title',
|
|
43
|
+
familyVariable: '--card-default-title-font-family',
|
|
44
|
+
sizeVariable: '--card-default-title-font-size',
|
|
45
|
+
weightVariable: '--card-default-title-font-weight',
|
|
46
|
+
lineHeightVariable: '--card-default-title-line-height',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
legend: 'card body',
|
|
50
|
+
colorVariable: '--card-default-body',
|
|
51
|
+
familyVariable: '--card-default-body-font-family',
|
|
52
|
+
sizeVariable: '--card-default-body-font-size',
|
|
53
|
+
weightVariable: '--card-default-body-font-weight',
|
|
54
|
+
lineHeightVariable: '--card-default-body-line-height',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
hover: [
|
|
58
|
+
{
|
|
59
|
+
legend: 'card title',
|
|
60
|
+
colorVariable: '--card-hover-title',
|
|
61
|
+
familyVariable: '--card-hover-title-font-family',
|
|
62
|
+
sizeVariable: '--card-hover-title-font-size',
|
|
63
|
+
weightVariable: '--card-hover-title-font-weight',
|
|
64
|
+
lineHeightVariable: '--card-hover-title-line-height',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
legend: 'card body',
|
|
68
|
+
colorVariable: '--card-hover-body',
|
|
69
|
+
familyVariable: '--card-hover-body-font-family',
|
|
70
|
+
sizeVariable: '--card-hover-body-font-size',
|
|
71
|
+
weightVariable: '--card-hover-body-font-weight',
|
|
72
|
+
lineHeightVariable: '--card-hover-body-line-height',
|
|
73
|
+
},
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// Title type tokens (linked across states, but title and body are different objects so they don't link to each other).
|
|
78
|
+
const typeGroupTokens: Token[] = [
|
|
79
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'title-font-family', variable: '--card-default-title-font-family' },
|
|
80
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'title-font-family', variable: '--card-hover-title-font-family' },
|
|
81
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'title-font-size', variable: '--card-default-title-font-size' },
|
|
82
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'title-font-size', variable: '--card-hover-title-font-size' },
|
|
83
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'title-font-weight', variable: '--card-default-title-font-weight' },
|
|
84
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'title-font-weight', variable: '--card-hover-title-font-weight' },
|
|
85
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'title-line-height', variable: '--card-default-title-line-height' },
|
|
86
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'title-line-height', variable: '--card-hover-title-line-height' },
|
|
87
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'body-font-family', variable: '--card-default-body-font-family' },
|
|
88
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'body-font-family', variable: '--card-hover-body-font-family' },
|
|
89
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'body-font-size', variable: '--card-default-body-font-size' },
|
|
90
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'body-font-size', variable: '--card-hover-body-font-size' },
|
|
91
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'body-font-weight', variable: '--card-default-body-font-weight' },
|
|
92
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'body-font-weight', variable: '--card-hover-body-font-weight' },
|
|
93
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'body-line-height', variable: '--card-default-body-line-height' },
|
|
94
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'body-line-height', variable: '--card-hover-body-line-height' },
|
|
95
|
+
];
|
|
96
|
+
// Cross-state linked block — present each linkable property from the default state.
|
|
97
|
+
const linkableContexts = new Map<string, string>([
|
|
98
|
+
['--card-default-border-width', 'card'],
|
|
99
|
+
['--card-default-radius', 'card'],
|
|
100
|
+
['--card-default-header-padding', 'card'],
|
|
101
|
+
['--card-default-body-padding', 'card'],
|
|
102
|
+
['--card-default-shadow', 'card'],
|
|
103
|
+
['--card-default-blur', 'card'],
|
|
104
|
+
['--card-default-icon-size', 'card'],
|
|
105
|
+
['--card-default-title-font-family', 'title'],
|
|
106
|
+
['--card-default-title-font-size', 'title'],
|
|
107
|
+
['--card-default-title-font-weight', 'title'],
|
|
108
|
+
['--card-default-title-line-height', 'title'],
|
|
109
|
+
['--card-default-body-font-family', 'body'],
|
|
110
|
+
['--card-default-body-font-size', 'body'],
|
|
111
|
+
['--card-default-body-font-weight', 'body'],
|
|
112
|
+
['--card-default-body-line-height', 'body'],
|
|
113
|
+
]);
|
|
114
|
+
export const allTokens: Token[] = [
|
|
115
|
+
...Object.values(states).flat(),
|
|
116
|
+
...buildTypeGroupColorTokens(typeGroups),
|
|
117
|
+
...typeGroupTokens,
|
|
118
|
+
];
|
|
119
|
+
</script>
|
|
120
|
+
|
|
121
|
+
<script lang="ts">
|
|
122
|
+
import Card from '../components/Card.svelte';
|
|
123
|
+
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
124
|
+
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
125
|
+
import { editorState } from '../lib/editorStore';
|
|
126
|
+
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
127
|
+
import ShadowBackdrop from './scaffolding/ShadowBackdrop.svelte';
|
|
128
|
+
import ShadowBackdropControls from './scaffolding/ShadowBackdropControls.svelte';
|
|
129
|
+
|
|
130
|
+
$: linked = computeLinkedBlock(component, linkableContexts, allTokens, $editorState);
|
|
131
|
+
|
|
132
|
+
$: visibleStates = Object.fromEntries(
|
|
133
|
+
Object.entries(states).map(([name, list]) => [name, withLinkedDisabled(list, linked.varSet)]),
|
|
134
|
+
) as Record<string, Token[]>;
|
|
135
|
+
|
|
136
|
+
let hoverEnabled = true;
|
|
137
|
+
let bgMode: 'image' | 'color' = 'image';
|
|
138
|
+
const bgVar = '--backdrop-card-surface';
|
|
139
|
+
</script>
|
|
140
|
+
|
|
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>
|
|
145
|
+
<VariantGroup
|
|
146
|
+
name="card"
|
|
147
|
+
title="Card"
|
|
148
|
+
states={visibleStates}
|
|
149
|
+
{typeGroups}
|
|
150
|
+
{component}
|
|
151
|
+
let:activeState
|
|
152
|
+
>
|
|
153
|
+
<svelte:fragment slot="state-actions" let:stateName>
|
|
154
|
+
{#if stateName === 'hover'}
|
|
155
|
+
<label class="hover-enable">
|
|
156
|
+
<input type="checkbox" bind:checked={hoverEnabled} />
|
|
157
|
+
<span>Use hover</span>
|
|
158
|
+
</label>
|
|
159
|
+
{/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>
|
|
170
|
+
</ComponentEditorBase>
|
|
171
|
+
|
|
172
|
+
<style>
|
|
173
|
+
.card-demo {
|
|
174
|
+
max-width: 28rem;
|
|
175
|
+
}
|
|
176
|
+
.hover-enable {
|
|
177
|
+
display: inline-flex;
|
|
178
|
+
align-items: center;
|
|
179
|
+
gap: var(--ui-space-4);
|
|
180
|
+
font-size: var(--ui-font-size-sm);
|
|
181
|
+
color: var(--ui-text-secondary);
|
|
182
|
+
cursor: pointer;
|
|
183
|
+
}
|
|
184
|
+
</style>
|