@motion-proto/live-tokens 0.78.0 → 0.80.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/.claude/skills/live-tokens-check-compliance/SKILL.md +49 -38
- package/.claude/skills/live-tokens-create-component/SKILL.md +23 -28
- package/.claude/skills/live-tokens-create-component/references/contract-tests.md +61 -0
- package/.claude/skills/live-tokens-create-component/references/sketch-mode.md +2 -2
- package/.claude/skills/live-tokens-create-component/references/token-naming.md +6 -15
- package/.claude/skills/live-tokens-create-page/SKILL.md +6 -4
- package/.claude/skills/live-tokens-create-theme/references/design-directions.md +1 -1
- package/.claude/skills/live-tokens-pick-component/SKILL.md +3 -3
- package/.claude/skills/live-tokens-set-colors/references/color-anchors.md +1 -1
- package/.claude/skills/live-tokens-set-geometry/SKILL.md +1 -1
- package/.claude/skills/live-tokens-set-geometry/references/geometry-anchors.md +1 -1
- package/CHANGELOG.md +271 -0
- package/README.md +10 -16
- package/bin/check-component.mjs +154 -551
- package/bin/check-page.mjs +57 -541
- package/bin/cli.mjs +93 -16
- package/bin/contractRunner.mjs +37 -91
- package/bin/lib/buildChecks.mjs +32 -0
- package/bin/lib/catalogue.mjs +161 -34
- package/bin/lib/componentSource.mjs +152 -0
- package/bin/lib/cssValues.mjs +9 -0
- package/bin/lib/dataDir.mjs +126 -0
- package/bin/lib/findings.mjs +103 -12
- package/bin/lib/fixers.mjs +64 -0
- package/bin/lib/geometry.mjs +92 -0
- package/bin/lib/pageSource.mjs +230 -0
- package/bin/lib/report.mjs +57 -59
- package/bin/lib/tokenVocabulary.mjs +104 -34
- package/bin/migrate-build-script.mjs +66 -0
- package/bin/migrate.mjs +5 -0
- package/bin/rules/componentStructure.mjs +344 -0
- package/bin/rules/componentUse.mjs +313 -0
- package/bin/rules/importsAndRoutes.mjs +136 -0
- package/bin/rules/testRuns.mjs +122 -0
- package/bin/rules/tokens.mjs +426 -0
- package/bin/setup-claude.mjs +1 -2
- package/dist-plugin/{chunk-PDNL4NC5.js → chunk-D4WRIKEZ.js} +7 -2
- package/dist-plugin/{chunk-SWXRVZKT.js → chunk-REBHE3ZM.js} +414 -1
- package/dist-plugin/index.cjs +470 -19
- package/dist-plugin/index.d.cts +1 -0
- package/dist-plugin/index.d.ts +1 -0
- package/dist-plugin/index.js +87 -55
- package/dist-plugin/migrateData/index.cjs +422 -4
- package/dist-plugin/migrateData/index.js +2 -2
- package/dist-plugin/setColors/index.cjs +414 -1
- package/dist-plugin/setColors/index.d.cts +1 -1
- package/dist-plugin/setColors/index.d.ts +1 -1
- package/dist-plugin/setColors/index.js +1 -1
- package/dist-plugin/setGeometry/index.cjs +423 -13
- package/dist-plugin/setGeometry/index.d.cts +3 -3
- package/dist-plugin/setGeometry/index.d.ts +3 -3
- package/dist-plugin/setGeometry/index.js +10 -13
- package/dist-plugin/setType/index.d.cts +1 -1
- package/dist-plugin/setType/index.d.ts +1 -1
- package/dist-plugin/{themeTypes-BxRtuN5V.d.cts → themeTypes-B8_Idrp4.d.cts} +2 -2
- package/dist-plugin/{themeTypes-BxRtuN5V.d.ts → themeTypes-B8_Idrp4.d.ts} +2 -2
- package/package.json +2 -2
- package/src/editor/component-editor/CalloutEditor.svelte +2 -2
- package/src/editor/component-editor/CollapsibleSectionEditor.svelte +14 -15
- package/src/editor/component-editor/CornerBadgeEditor.svelte +14 -14
- package/src/editor/component-editor/DialogEditor.svelte +5 -5
- package/src/editor/component-editor/InlineEditActionsEditor.svelte +2 -2
- package/src/editor/component-editor/RadioButtonEditor.svelte +21 -21
- package/src/editor/component-editor/SectionDividerEditor.svelte +7 -7
- package/src/editor/component-editor/SegmentedControlEditor.svelte +5 -5
- package/src/editor/component-editor/SideNavigationEditor.svelte +25 -25
- package/src/editor/component-editor/TabBarEditor.svelte +6 -6
- package/src/editor/component-editor/TableEditor.svelte +6 -6
- package/src/editor/component-editor/ToggleEditor.svelte +2 -2
- package/src/editor/component-editor/index.ts +3 -0
- package/src/editor/component-editor/registry.ts +57 -1
- package/src/editor/component-editor/scaffolding/TokenLayout.svelte +14 -14
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +3 -0
- package/src/editor/component-editor/scaffolding/types.ts +15 -0
- package/src/editor/core/components/adjustAliases.ts +4 -4
- package/src/editor/core/components/aliasKinds.ts +20 -19
- package/src/editor/core/sketch/sketchLayer.ts +3 -3
- package/src/editor/core/themes/migrateComponentConfig.ts +14 -6
- package/src/editor/core/themes/migrations/2026-09-13-badge-brand.ts +42 -0
- package/src/editor/core/themes/migrations/2026-09-13-collapsiblesection-open.ts +33 -0
- package/src/editor/core/themes/migrations/2026-09-13-cornerbadge-prefix.ts +70 -0
- package/src/editor/core/themes/migrations/2026-09-13-hairline.ts +92 -0
- package/src/editor/core/themes/migrations/2026-09-13-indicator.ts +54 -0
- package/src/editor/core/themes/migrations/2026-09-13-sectiondivider-surface.ts +36 -0
- package/src/editor/core/themes/migrations/2026-09-13-selected-state.ts +124 -0
- package/src/editor/core/themes/migrations/2026-09-13-toggle-label.ts +31 -0
- package/src/editor/core/themes/migrations/index.ts +16 -0
- package/src/editor/core/themes/themeService.ts +3 -3
- package/src/editor/core/themes/themeTypes.ts +13 -15
- package/src/editor/docs/Docs.svelte +1 -1
- package/src/editor/docs/content/light-and-dark.md +3 -3
- package/src/editor/docs/content.generated.ts +1 -1
- package/src/editor/index.ts +1 -0
- package/src/editor/overlay/LiveEditorOverlay.svelte +15 -0
- package/src/editor/skill-atlas/SkillAtlas.svelte +4 -4
- package/src/editor/skill-atlas/TreeNodeCard.svelte +4 -4
- package/src/editor/skill-atlas/skillSources.generated.ts +11 -14
- package/src/editor/skill-atlas/skillTrees.ts +1 -3
- package/src/editor/skill-atlas/trees/check-compliance.ts +37 -149
- package/src/editor/skill-atlas/trees/create-component.ts +62 -64
- package/src/editor/skill-atlas/trees/create-page.ts +38 -17
- package/src/editor/skill-atlas/trees/pick-component.ts +3 -3
- package/src/editor/skill-atlas/trees/set-geometry.ts +1 -1
- package/src/editor/ui/UIPaletteSelector.svelte +11 -15
- package/src/editor/ui/variantScales.ts +8 -8
- package/src/live-tokens/data/themes/autumn.json +188 -188
- package/src/live-tokens/data/themes/halloween.json +188 -188
- package/src/live-tokens/data/themes/midnight-study.json +245 -245
- package/src/live-tokens/data/themes/ocean.json +188 -188
- package/src/live-tokens/data/themes/royal-velvet.json +188 -188
- package/src/live-tokens/data/themes/sketchy.json +188 -188
- package/src/live-tokens/data/themes/spring-meadow.json +188 -188
- package/src/live-tokens/data/themes/sunset.json +188 -188
- package/src/system/components/Badge.svelte +27 -23
- package/src/system/components/Button.svelte +13 -7
- package/src/system/components/Callout.svelte +16 -11
- package/src/system/components/Card.svelte +22 -15
- package/src/system/components/CodeSnippet.svelte +10 -6
- package/src/system/components/CollapsibleSection.svelte +81 -76
- package/src/system/components/CornerBadge.svelte +78 -72
- package/src/system/components/Dialog.svelte +21 -18
- package/src/system/components/IconButton.svelte +13 -9
- package/src/system/components/Image.svelte +14 -8
- package/src/system/components/ImageLightbox.svelte +10 -6
- package/src/system/components/InlineEditActions.svelte +17 -14
- package/src/system/components/Input.svelte +13 -7
- package/src/system/components/MenuSelect.svelte +13 -7
- package/src/system/components/Notification.svelte +17 -11
- package/src/system/components/Panel.svelte +13 -6
- package/src/system/components/ProgressBar.svelte +10 -5
- package/src/system/components/RadioButton.svelte +33 -30
- package/src/system/components/SectionDivider.svelte +28 -21
- package/src/system/components/SegmentedControl.svelte +27 -23
- package/src/system/components/SideNavigation.svelte +175 -171
- package/src/system/components/Slider.svelte +11 -7
- package/src/system/components/TabBar.svelte +53 -49
- package/src/system/components/Table.svelte +20 -15
- package/src/system/components/Toggle.svelte +14 -10
- package/src/system/components/Tooltip.svelte +10 -6
- package/src/system/styles/CONVENTIONS.md +3 -4
- package/src/testing-js/chunk-3UKGXCDL.js +48 -0
- package/src/testing-js/chunk-3UKGXCDL.js.map +1 -0
- package/src/testing-js/{chunk-FAFOAWYL.js → chunk-Q3YIAAG3.js} +17 -3
- package/src/testing-js/chunk-Q3YIAAG3.js.map +1 -0
- package/src/testing-js/{chunk-GNIUPIU2.js → chunk-U7OJE5DU.js} +18 -18
- package/src/testing-js/chunk-U7OJE5DU.js.map +1 -0
- package/src/testing-js/{chunk-4JQX6WWL.js → chunk-ZMZQZ33J.js} +474 -166
- package/src/testing-js/chunk-ZMZQZ33J.js.map +1 -0
- package/src/testing-js/component-behavior.contract.js +155 -0
- package/src/testing-js/component-behavior.contract.js.map +1 -0
- package/src/testing-js/component-editor.contract.js +6 -4
- package/src/testing-js/component-editor.contract.js.map +1 -1
- package/src/testing-js/component-render.contract.js +14 -10
- package/src/testing-js/component-render.contract.js.map +1 -1
- package/src/testing-js/index.d.ts +44 -4
- package/src/testing-js/index.js +13 -7
- package/src/testing-js/index.js.map +1 -1
- package/src/testing-js/page-compliance.contract.js +48 -10
- package/src/testing-js/page-compliance.contract.js.map +1 -1
- package/src/testing-js/registry.contract.js +5 -3
- package/src/testing-js/registry.contract.js.map +1 -1
- package/src/testing-js/{vitest-C-wNWcoA.d.ts → vitest-BMLIbDs2.d.ts} +8 -2
- package/src/testing-js/vitest.d.ts +1 -1
- package/src/testing-js/vitest.js +2 -1
- package/template/package.json +1 -2
- package/template/vite.config.ts +3 -2
- package/.claude/skills/live-tokens-create-component/SKILL copy.md +0 -196
- package/.claude/skills/live-tokens-fix-findings/SKILL.md +0 -105
- package/src/editor/skill-atlas/trees/fix-findings.ts +0 -504
- package/src/testing-js/chunk-4JQX6WWL.js.map +0 -1
- package/src/testing-js/chunk-FAFOAWYL.js.map +0 -1
- package/src/testing-js/chunk-GNIUPIU2.js.map +0 -1
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
export const component = 'collapsiblesection';
|
|
6
6
|
|
|
7
|
-
const VARIANTS = ['chromeless', '
|
|
7
|
+
const VARIANTS = ['chromeless', 'hairline', 'container'] as const;
|
|
8
8
|
type Variant = typeof VARIANTS[number];
|
|
9
9
|
const HEADER_STATES = ['default', 'hover'] as const;
|
|
10
10
|
type HeaderState = typeof HEADER_STATES[number];
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
|
|
16
16
|
const VARIANT_LABELS: Record<Variant, string> = {
|
|
17
17
|
chromeless: 'Chromeless',
|
|
18
|
-
|
|
18
|
+
hairline: 'With Hairline',
|
|
19
19
|
container: 'Container',
|
|
20
20
|
};
|
|
21
21
|
|
|
22
|
-
// Header tokens per variant. Chromeless has no chrome;
|
|
23
|
-
//
|
|
22
|
+
// Header tokens per variant. Chromeless has no chrome; hairline exposes the
|
|
23
|
+
// line under the header per state; container's outer chrome lives
|
|
24
24
|
// in the Container part so the header strip just owns surface + padding + text.
|
|
25
25
|
function headerStateTokens(v: Variant, s: HeaderState): Token[] {
|
|
26
26
|
const p = `--collapsiblesection-${v}-${s}`;
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
{ label: 'icon color', groupKey: 'icon', variable: `${p}-icon` },
|
|
31
31
|
{ label: 'icon size', canBeLinked: true, groupKey: 'font-size', variable: `${p}-icon-size` },
|
|
32
32
|
];
|
|
33
|
-
if (v === '
|
|
33
|
+
if (v === 'hairline') {
|
|
34
34
|
base.splice(1, 0,
|
|
35
|
-
{ label: '
|
|
36
|
-
{ label: '
|
|
35
|
+
{ label: 'hairline color', groupKey: 'hairline-color', variable: `${p}-hairline-color` },
|
|
36
|
+
{ label: 'hairline width', canBeLinked: true, groupKey: 'hairline-width', variable: `${p}-hairline-width` },
|
|
37
37
|
);
|
|
38
38
|
}
|
|
39
39
|
return base;
|
|
@@ -46,11 +46,10 @@
|
|
|
46
46
|
{ label: 'corner radius', canBeLinked: true, groupKey: 'radius', variable: '--collapsiblesection-container-frame-radius' },
|
|
47
47
|
];
|
|
48
48
|
|
|
49
|
-
// Body: revealed content area. Chromeless/
|
|
49
|
+
// Body: revealed content area. Chromeless/hairline only own padding; container
|
|
50
50
|
// also paints its own surface so the body can read distinct from the header.
|
|
51
|
-
// (CSS var name keeps the `expanded` slug for backward compatibility.)
|
|
52
51
|
function bodyTokens(v: Variant): Token[] {
|
|
53
|
-
const p = `--collapsiblesection-${v}-
|
|
52
|
+
const p = `--collapsiblesection-${v}-open`;
|
|
54
53
|
const tokens: Token[] = [];
|
|
55
54
|
if (v === 'container') tokens.push({ label: 'surface color', groupKey: 'surface', variable: `${p}-surface` });
|
|
56
55
|
tokens.push({ label: 'padding', canBeLinked: true, groupKey: 'padding', variable: `${p}-padding` });
|
|
@@ -107,13 +106,13 @@
|
|
|
107
106
|
[`--collapsiblesection-${v}-${s}-label-font-weight`, `${v} ${s}`],
|
|
108
107
|
[`--collapsiblesection-${v}-${s}-label-line-height`, `${v} ${s}`],
|
|
109
108
|
];
|
|
110
|
-
if (v === '
|
|
109
|
+
if (v === 'hairline') base.push([`--collapsiblesection-hairline-${s}-hairline-width`, `hairline ${s}`]);
|
|
111
110
|
return base;
|
|
112
111
|
})),
|
|
113
112
|
['--collapsiblesection-container-frame-border-width', 'container frame'],
|
|
114
113
|
['--collapsiblesection-container-frame-radius', 'container frame'],
|
|
115
114
|
...VARIANTS.flatMap((v) => [
|
|
116
|
-
[`--collapsiblesection-${v}-
|
|
115
|
+
[`--collapsiblesection-${v}-open-padding`, `${v} open`] as [string, string],
|
|
117
116
|
]),
|
|
118
117
|
]);
|
|
119
118
|
|
|
@@ -135,7 +134,7 @@
|
|
|
135
134
|
) as Record<string, Token[]>);
|
|
136
135
|
</script>
|
|
137
136
|
|
|
138
|
-
<ComponentEditorBase {component} title="Collapsible Section" description="Expandable section with chevron toggle. Variants: chromeless,
|
|
137
|
+
<ComponentEditorBase {component} title="Collapsible Section" description="Expandable section with chevron toggle. Variants: chromeless, hairline, container." tokens={allTokens} {linked} variants={variantOptions}>
|
|
139
138
|
{#each VARIANTS as v}
|
|
140
139
|
<VariantGroup
|
|
141
140
|
name={v}
|
|
@@ -153,14 +152,14 @@
|
|
|
153
152
|
<CollapsibleSection
|
|
154
153
|
variant={v}
|
|
155
154
|
label="Click to expand"
|
|
156
|
-
|
|
155
|
+
open={isBody}
|
|
157
156
|
class={forceClass}
|
|
158
157
|
>
|
|
159
158
|
<p style="margin: 0; color: var(--text-secondary);">
|
|
160
159
|
{#if isContainerPart}
|
|
161
160
|
(Container) — outer chrome only; switch to Body to see the content area.
|
|
162
161
|
{:else}
|
|
163
|
-
This content is revealed when the section is
|
|
162
|
+
This content is revealed when the section is open. Any content can go here.
|
|
164
163
|
{/if}
|
|
165
164
|
</p>
|
|
166
165
|
</CollapsibleSection>
|
|
@@ -8,25 +8,25 @@
|
|
|
8
8
|
// Shape, spacing, type — uniform across variants, one flat token set.
|
|
9
9
|
// Authored from any variant's panel; edits write the same flat keys.
|
|
10
10
|
const baseTokens: Token[] = [
|
|
11
|
-
{ label: 'offset from corner', canBeLinked: true, groupKey: 'margin', variable: '--
|
|
12
|
-
{ label: 'padding', canBeLinked: true, groupKey: 'padding', variable: '--
|
|
13
|
-
{ label: 'outer corner radius', canBeLinked: true, groupKey: 'outer-radius', variable: '--
|
|
14
|
-
{ label: 'inner corner radius', canBeLinked: true, groupKey: 'inner-radius', variable: '--
|
|
15
|
-
{ label: 'horizontal-axis radius', canBeLinked: true, groupKey: 'h-axis-radius', variable: '--
|
|
16
|
-
{ label: 'vertical-axis radius', canBeLinked: true, groupKey: 'v-axis-radius', variable: '--
|
|
17
|
-
{ label: 'font family', canBeLinked: true, groupKey: 'text-font-family', variable: '--
|
|
18
|
-
{ label: 'font size', canBeLinked: true, groupKey: 'text-font-size', variable: '--
|
|
19
|
-
{ label: 'font weight', canBeLinked: true, groupKey: 'text-font-weight', variable: '--
|
|
20
|
-
{ label: 'line height', canBeLinked: true, groupKey: 'text-line-height', variable: '--
|
|
11
|
+
{ label: 'offset from corner', canBeLinked: true, groupKey: 'margin', variable: '--cornerbadge-margin', element: 'frame' },
|
|
12
|
+
{ label: 'padding', canBeLinked: true, groupKey: 'padding', variable: '--cornerbadge-padding', element: 'frame' },
|
|
13
|
+
{ label: 'outer corner radius', canBeLinked: true, groupKey: 'outer-radius', variable: '--cornerbadge-outer-radius', element: 'frame' },
|
|
14
|
+
{ label: 'inner corner radius', canBeLinked: true, groupKey: 'inner-radius', variable: '--cornerbadge-inner-radius', element: 'frame' },
|
|
15
|
+
{ label: 'horizontal-axis radius', canBeLinked: true, groupKey: 'h-axis-radius', variable: '--cornerbadge-h-axis-radius', element: 'frame' },
|
|
16
|
+
{ label: 'vertical-axis radius', canBeLinked: true, groupKey: 'v-axis-radius', variable: '--cornerbadge-v-axis-radius', element: 'frame' },
|
|
17
|
+
{ label: 'font family', canBeLinked: true, groupKey: 'text-font-family', variable: '--cornerbadge-text-font-family', element: 'text' },
|
|
18
|
+
{ label: 'font size', canBeLinked: true, groupKey: 'text-font-size', variable: '--cornerbadge-text-font-size', element: 'text' },
|
|
19
|
+
{ label: 'font weight', canBeLinked: true, groupKey: 'text-font-weight', variable: '--cornerbadge-text-font-weight', element: 'text' },
|
|
20
|
+
{ label: 'line height', canBeLinked: true, groupKey: 'text-line-height', variable: '--cornerbadge-text-line-height', element: 'text' },
|
|
21
21
|
];
|
|
22
22
|
|
|
23
23
|
// Per-variant color slots — surface, border, text — rebind the inner Badge's
|
|
24
|
-
// colors inside .
|
|
24
|
+
// colors inside .cornerbadge-{v} scope.
|
|
25
25
|
function variantColorTokens(v: Variant): Token[] {
|
|
26
26
|
return [
|
|
27
|
-
{ label: 'surface color', groupKey: 'surface', variable: `--
|
|
28
|
-
{ label: 'border color', groupKey: 'border', variable: `--
|
|
29
|
-
{ label: 'text color', groupKey: 'text', variable: `--
|
|
27
|
+
{ label: 'surface color', groupKey: 'surface', variable: `--cornerbadge-${v}-surface` },
|
|
28
|
+
{ label: 'border color', groupKey: 'border', variable: `--cornerbadge-${v}-border` },
|
|
29
|
+
{ label: 'text color', groupKey: 'text', variable: `--cornerbadge-${v}-text` },
|
|
30
30
|
];
|
|
31
31
|
}
|
|
32
32
|
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
],
|
|
29
29
|
header: [
|
|
30
30
|
{ label: 'surface color', groupKey: 'surface', variable: '--dialog-header-surface' },
|
|
31
|
-
{ label: '
|
|
32
|
-
{ label: '
|
|
31
|
+
{ label: 'hairline color', groupKey: 'border', variable: '--dialog-header-hairline-color' },
|
|
32
|
+
{ label: 'hairline width', groupKey: 'width', variable: '--dialog-header-hairline-width' },
|
|
33
33
|
{ label: 'padding', groupKey: 'padding', variable: '--dialog-header-padding' },
|
|
34
34
|
{ label: 'close icon color', groupKey: 'icon', variable: '--dialog-close-icon' },
|
|
35
35
|
{ label: 'close icon size', groupKey: 'size', variable: '--dialog-close-icon-size' },
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
{ label: 'padding', groupKey: 'padding', variable: '--dialog-body-padding' },
|
|
39
39
|
],
|
|
40
40
|
footer: [
|
|
41
|
-
{ label: '
|
|
42
|
-
{ label: '
|
|
41
|
+
{ label: 'hairline color', groupKey: 'border', variable: '--dialog-footer-hairline-color' },
|
|
42
|
+
{ label: 'hairline width', groupKey: 'width', variable: '--dialog-footer-hairline-width' },
|
|
43
43
|
{ label: 'padding', groupKey: 'padding', variable: '--dialog-footer-padding' },
|
|
44
44
|
],
|
|
45
45
|
};
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
{/if}
|
|
132
132
|
{/snippet}
|
|
133
133
|
<Dialog
|
|
134
|
-
|
|
134
|
+
open
|
|
135
135
|
inline
|
|
136
136
|
title="Sample Dialog"
|
|
137
137
|
confirm={{ label: 'Save', onClick: () => {} }}
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
<div class="inline-edit-demo-row">
|
|
69
69
|
<span style="color: var(--text-secondary);">Editing value...</span>
|
|
70
70
|
<InlineEditActions
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
onsave={() => {}}
|
|
72
|
+
oncancel={() => {}}
|
|
73
73
|
class={forceClass}
|
|
74
74
|
/>
|
|
75
75
|
</div>
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
{ label: 'dot fill', groupKey: 'fill', variable: '--radiobutton-hover-dot-fill' },
|
|
18
18
|
{ label: 'dot size', groupKey: 'size', variable: '--radiobutton-hover-dot-size' },
|
|
19
19
|
],
|
|
20
|
-
|
|
21
|
-
{ label: 'border color', groupKey: 'color', variable: '--radiobutton-
|
|
22
|
-
{ label: 'border thickness', canBeLinked: true, groupKey: 'border-width', variable: '--radiobutton-
|
|
23
|
-
{ label: 'dot fill', groupKey: 'fill', variable: '--radiobutton-
|
|
24
|
-
{ label: 'dot size', groupKey: 'size', variable: '--radiobutton-
|
|
20
|
+
selected: [
|
|
21
|
+
{ label: 'border color', groupKey: 'color', variable: '--radiobutton-selected-dot-border-color' },
|
|
22
|
+
{ label: 'border thickness', canBeLinked: true, groupKey: 'border-width', variable: '--radiobutton-selected-dot-border-width' },
|
|
23
|
+
{ label: 'dot fill', groupKey: 'fill', variable: '--radiobutton-selected-dot-fill' },
|
|
24
|
+
{ label: 'dot size', groupKey: 'size', variable: '--radiobutton-selected-dot-size' },
|
|
25
25
|
],
|
|
26
26
|
};
|
|
27
27
|
|
|
@@ -42,16 +42,16 @@
|
|
|
42
42
|
weightVariable: '--radiobutton-hover-label-font-weight',
|
|
43
43
|
lineHeightVariable: '--radiobutton-hover-label-line-height',
|
|
44
44
|
}],
|
|
45
|
-
|
|
45
|
+
selected: [{
|
|
46
46
|
legend: 'label',
|
|
47
|
-
colorVariable: '--radiobutton-
|
|
48
|
-
familyVariable: '--radiobutton-
|
|
49
|
-
sizeVariable: '--radiobutton-
|
|
50
|
-
weightVariable: '--radiobutton-
|
|
51
|
-
lineHeightVariable: '--radiobutton-
|
|
47
|
+
colorVariable: '--radiobutton-selected-label',
|
|
48
|
+
familyVariable: '--radiobutton-selected-label-font-family',
|
|
49
|
+
sizeVariable: '--radiobutton-selected-label-font-size',
|
|
50
|
+
weightVariable: '--radiobutton-selected-label-font-weight',
|
|
51
|
+
lineHeightVariable: '--radiobutton-selected-label-line-height',
|
|
52
52
|
}],
|
|
53
53
|
};
|
|
54
|
-
const typeGroupTokens: Token[] = (['default', 'hover', '
|
|
54
|
+
const typeGroupTokens: Token[] = (['default', 'hover', 'selected'] as const).flatMap((s) => [
|
|
55
55
|
{ label: 'font family', canBeLinked: true, groupKey: 'font-family', variable: `--radiobutton-${s}-label-font-family` },
|
|
56
56
|
{ label: 'font size', canBeLinked: true, groupKey: 'font-size', variable: `--radiobutton-${s}-label-font-size` },
|
|
57
57
|
{ label: 'font weight', canBeLinked: true, groupKey: 'font-weight', variable: `--radiobutton-${s}-label-font-weight` },
|
|
@@ -60,19 +60,19 @@
|
|
|
60
60
|
const linkableContexts = new Map<string, string>([
|
|
61
61
|
['--radiobutton-default-dot-border-width', 'default'],
|
|
62
62
|
['--radiobutton-hover-dot-border-width', 'hover'],
|
|
63
|
-
['--radiobutton-
|
|
63
|
+
['--radiobutton-selected-dot-border-width', 'selected'],
|
|
64
64
|
['--radiobutton-default-label-font-family', 'default'],
|
|
65
65
|
['--radiobutton-hover-label-font-family', 'hover'],
|
|
66
|
-
['--radiobutton-
|
|
66
|
+
['--radiobutton-selected-label-font-family', 'selected'],
|
|
67
67
|
['--radiobutton-default-label-font-size', 'default'],
|
|
68
68
|
['--radiobutton-hover-label-font-size', 'hover'],
|
|
69
|
-
['--radiobutton-
|
|
69
|
+
['--radiobutton-selected-label-font-size', 'selected'],
|
|
70
70
|
['--radiobutton-default-label-font-weight', 'default'],
|
|
71
71
|
['--radiobutton-hover-label-font-weight', 'hover'],
|
|
72
|
-
['--radiobutton-
|
|
72
|
+
['--radiobutton-selected-label-font-weight', 'selected'],
|
|
73
73
|
['--radiobutton-default-label-line-height', 'default'],
|
|
74
74
|
['--radiobutton-hover-label-line-height', 'hover'],
|
|
75
|
-
['--radiobutton-
|
|
75
|
+
['--radiobutton-selected-label-line-height', 'selected'],
|
|
76
76
|
]);
|
|
77
77
|
export const allTokens: Token[] = [
|
|
78
78
|
...Object.values(states).flat(),
|
|
@@ -108,23 +108,23 @@
|
|
|
108
108
|
>
|
|
109
109
|
{#snippet children({ activeState })}
|
|
110
110
|
{@const forceClass = activeState === 'hover' ? 'force-hover' : ''}
|
|
111
|
-
{@const
|
|
111
|
+
{@const forceSelected = activeState === 'selected'}
|
|
112
112
|
<div class="radio-demo-row">
|
|
113
113
|
<RadioButton
|
|
114
114
|
label="Defense"
|
|
115
|
-
|
|
115
|
+
selected={forceSelected || selectedRadio === 'option-a'}
|
|
116
116
|
class={forceClass}
|
|
117
117
|
on:click={() => (selectedRadio = 'option-a')}
|
|
118
118
|
/>
|
|
119
119
|
<RadioButton
|
|
120
120
|
label="Economy"
|
|
121
|
-
|
|
121
|
+
selected={forceSelected || selectedRadio === 'option-b'}
|
|
122
122
|
class={forceClass}
|
|
123
123
|
on:click={() => (selectedRadio = 'option-b')}
|
|
124
124
|
/>
|
|
125
125
|
<RadioButton
|
|
126
126
|
label="Loyalty"
|
|
127
|
-
|
|
127
|
+
selected={forceSelected || selectedRadio === 'option-c'}
|
|
128
128
|
class={forceClass}
|
|
129
129
|
on:click={() => (selectedRadio = 'option-c')}
|
|
130
130
|
/>
|
|
@@ -33,22 +33,22 @@
|
|
|
33
33
|
function hairlineTokens(v: Variant): Token[] {
|
|
34
34
|
return [
|
|
35
35
|
{ label: 'hairline color', canBeLinked: true, groupKey: 'hairline-color', variable: `--sectiondivider-${v}-hairline-color`, element: 'hairline' },
|
|
36
|
-
{ label: 'hairline
|
|
36
|
+
{ label: 'hairline width', canBeLinked: true, groupKey: 'hairline-width', variable: `--sectiondivider-${v}-hairline-width`, element: 'hairline' },
|
|
37
37
|
];
|
|
38
38
|
}
|
|
39
|
-
function
|
|
39
|
+
function surfaceTokens(v: Variant): Token[] {
|
|
40
40
|
return [
|
|
41
|
-
{ label: '
|
|
41
|
+
{ label: 'surface', groupKey: 'surface', variable: `--sectiondivider-${v}-surface`, kind: 'gradient', family: variants.find((x) => x.key === v)!.family },
|
|
42
42
|
];
|
|
43
43
|
}
|
|
44
44
|
function variantTokens(v: Variant): Token[] {
|
|
45
|
-
return [...containerTokens(v), ...hairlineTokens(v), ...
|
|
45
|
+
return [...containerTokens(v), ...hairlineTokens(v), ...surfaceTokens(v), ...typePaddingTokens(v)];
|
|
46
46
|
}
|
|
47
47
|
function stateTokens(v: Variant): Token[] {
|
|
48
48
|
return [
|
|
49
49
|
...containerTokens(v),
|
|
50
50
|
...hairlineTokens(v),
|
|
51
|
-
...
|
|
51
|
+
...surfaceTokens(v).map((t) => ({ ...t, hidden: true })),
|
|
52
52
|
...typePaddingTokens(v),
|
|
53
53
|
];
|
|
54
54
|
}
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
|
|
118
118
|
const LINKED_GROUP_KEYS = [
|
|
119
119
|
'container-padding', 'radius', 'border', 'border-width', 'shadow',
|
|
120
|
-
'hairline-color', 'hairline-
|
|
120
|
+
'hairline-color', 'hairline-width',
|
|
121
121
|
'title-color', 'description-color', 'eyebrow-color',
|
|
122
122
|
'title-padding', 'description-padding', 'eyebrow-padding',
|
|
123
123
|
'title-font-family', 'title-font-weight', 'title-line-height', 'title-letter-spacing',
|
|
@@ -292,7 +292,7 @@
|
|
|
292
292
|
let visibleVariantTokens = $derived((v: Variant) => withLinkedDisabled(stateTokens(v), linked.varSet));
|
|
293
293
|
|
|
294
294
|
const gradientSources = Object.fromEntries(
|
|
295
|
-
variants.map((v) => [v.key, componentGradientSource(component, `--sectiondivider-${v.key}-
|
|
295
|
+
variants.map((v) => [v.key, componentGradientSource(component, `--sectiondivider-${v.key}-surface`)]),
|
|
296
296
|
) as Record<Variant, ReturnType<typeof componentGradientSource>>;
|
|
297
297
|
|
|
298
298
|
// Family swap on color-family change: for every alias under this variant
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
{ label: 'surface color', element: 'frame', groupKey: 'surface', variable: '--segmentedcontrol-bar-surface' },
|
|
14
14
|
{ label: 'border color', element: 'frame', groupKey: 'border', variable: '--segmentedcontrol-bar-border' },
|
|
15
15
|
{ label: 'border width', element: 'frame', groupKey: 'width', variable: '--segmentedcontrol-bar-border-width' },
|
|
16
|
-
{ label: 'color', element: '
|
|
17
|
-
{ label: 'width', element: '
|
|
18
|
-
{ label: 'inset', element: '
|
|
16
|
+
{ label: 'color', element: 'hairline', groupKey: 'color', variable: '--segmentedcontrol-hairline-color' },
|
|
17
|
+
{ label: 'width', element: 'hairline', groupKey: 'hairline-width', variable: '--segmentedcontrol-hairline-width' },
|
|
18
|
+
{ label: 'inset', element: 'hairline', groupKey: 'hairline-inset', variable: '--segmentedcontrol-hairline-inset' },
|
|
19
19
|
{ label: 'corner radius', element: 'frame', groupKey: 'radius', variable: '--segmentedcontrol-bar-radius' },
|
|
20
20
|
{ label: 'option gap', element: 'frame', groupKey: 'gap', variable: '--segmentedcontrol-bar-gap' },
|
|
21
21
|
{ label: 'padding', element: 'frame', variable: '--segmentedcontrol-bar-padding', groupKey: 'bar-padding' },
|
|
@@ -54,8 +54,8 @@
|
|
|
54
54
|
'control bar': [
|
|
55
55
|
{ label: 'corner radius', element: 'frame', groupKey: 'small-radius', variable: '--segmentedcontrol-bar-small-radius' },
|
|
56
56
|
{ label: 'padding', element: 'frame', variable: '--segmentedcontrol-bar-small-padding', groupKey: 'bar-small-padding' },
|
|
57
|
-
{ label: 'inset', element: '
|
|
58
|
-
{ label: 'width', element: '
|
|
57
|
+
{ label: 'inset', element: 'hairline', groupKey: 'small-hairline-inset', variable: '--segmentedcontrol-small-hairline-inset' },
|
|
58
|
+
{ label: 'width', element: 'hairline', groupKey: 'small-hairline-width', variable: '--segmentedcontrol-small-hairline-width' },
|
|
59
59
|
],
|
|
60
60
|
'option base': [
|
|
61
61
|
{ label: 'icon size', groupKey: 'small-icon-size', variable: '--segmentedcontrol-option-small-icon-size' },
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
export const component = 'sidenavigation';
|
|
6
6
|
|
|
7
7
|
// Single-variant component with five structural parts. Three of them (Title,
|
|
8
|
-
// Item, Footer) carry default/hover/
|
|
8
|
+
// Item, Footer) carry default/hover/selected interaction sub-states; Toggle
|
|
9
9
|
// carries default/hover. Panel is geometry only. Keys use the " / " convention
|
|
10
10
|
// VariantGroup recognises for two-tier parts/state strips.
|
|
11
|
-
const STATEFUL_STATES = ['default', 'hover', '
|
|
11
|
+
const STATEFUL_STATES = ['default', 'hover', 'selected'] as const;
|
|
12
12
|
const TOGGLE_STATES = ['default', 'hover'] as const;
|
|
13
13
|
type StatefulState = typeof STATEFUL_STATES[number];
|
|
14
14
|
type ToggleState = typeof TOGGLE_STATES[number];
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
const STATE_LABELS: Record<string, string> = {
|
|
17
17
|
default: 'Default',
|
|
18
18
|
hover: 'Hover',
|
|
19
|
-
|
|
19
|
+
selected: 'Selected',
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
// --- Panel --------------------------------------------------------------
|
|
@@ -42,14 +42,14 @@
|
|
|
42
42
|
// Title is a flex card containing the label box + toggle box. Per-state
|
|
43
43
|
// tokens drive the card chrome (surface, border, padding); the stateless
|
|
44
44
|
// bar + label-box structure lives in `titleBlockTokens` since it doesn't
|
|
45
|
-
// vary across default/hover/
|
|
45
|
+
// vary across default/hover/selected.
|
|
46
46
|
function titleStateTokens(s: StatefulState): Token[] {
|
|
47
47
|
return [
|
|
48
48
|
{ label: 'surface color', groupKey: 'title-surface', variable: `--sidenavigation-title-${s}-surface` },
|
|
49
49
|
{ label: 'border color', groupKey: 'title-border', variable: `--sidenavigation-title-${s}-border` },
|
|
50
50
|
{ label: 'border width', canBeLinked: true, groupKey: 'title-border-width', variable: `--sidenavigation-title-${s}-border-width` },
|
|
51
|
-
{ label: 'indicator color', groupKey: 'title-
|
|
52
|
-
{ label: 'indicator width', canBeLinked: true, groupKey: 'title-
|
|
51
|
+
{ label: 'indicator color', groupKey: 'title-indicator', variable: `--sidenavigation-title-${s}-indicator` },
|
|
52
|
+
{ label: 'indicator width', canBeLinked: true, groupKey: 'title-indicator-width', variable: `--sidenavigation-title-${s}-indicator-width` },
|
|
53
53
|
{ label: 'padding', canBeLinked: true, groupKey: 'title-padding', variable: `--sidenavigation-title-${s}-padding` },
|
|
54
54
|
];
|
|
55
55
|
}
|
|
@@ -105,8 +105,8 @@
|
|
|
105
105
|
function sectionStateTokens(s: StatefulState): Token[] {
|
|
106
106
|
return [
|
|
107
107
|
{ label: 'surface color', groupKey: 'section-surface', variable: `--sidenavigation-section-${s}-surface` },
|
|
108
|
-
{ label: 'indicator color', groupKey: 'section-
|
|
109
|
-
{ label: 'indicator width', canBeLinked: true, groupKey: 'section-
|
|
108
|
+
{ label: 'indicator color', groupKey: 'section-indicator', variable: `--sidenavigation-section-${s}-indicator` },
|
|
109
|
+
{ label: 'indicator width', canBeLinked: true, groupKey: 'section-indicator-width', variable: `--sidenavigation-section-${s}-indicator-width` },
|
|
110
110
|
];
|
|
111
111
|
}
|
|
112
112
|
function sectionStateTypeGroups(s: StatefulState): TypeGroupConfig[] {
|
|
@@ -131,8 +131,8 @@
|
|
|
131
131
|
return [
|
|
132
132
|
{ label: 'surface color', groupKey: 'item-surface', variable: `--sidenavigation-item-${s}-surface` },
|
|
133
133
|
{ label: 'padding', canBeLinked: true, groupKey: 'item-padding', variable: `--sidenavigation-item-${s}-padding` },
|
|
134
|
-
{ label: 'indicator color', groupKey: 'item-
|
|
135
|
-
{ label: 'indicator width', canBeLinked: true, groupKey: 'item-
|
|
134
|
+
{ label: 'indicator color', groupKey: 'item-indicator', variable: `--sidenavigation-item-${s}-indicator` },
|
|
135
|
+
{ label: 'indicator width', canBeLinked: true, groupKey: 'item-indicator-width', variable: `--sidenavigation-item-${s}-indicator-width` },
|
|
136
136
|
];
|
|
137
137
|
}
|
|
138
138
|
function itemStateTypeGroups(s: StatefulState): TypeGroupConfig[] {
|
|
@@ -158,8 +158,8 @@
|
|
|
158
158
|
{ label: 'surface color', groupKey: 'footer-surface', variable: `--sidenavigation-footer-${s}-surface` },
|
|
159
159
|
{ label: 'padding', canBeLinked: true, groupKey: 'footer-padding', variable: `--sidenavigation-footer-${s}-padding` },
|
|
160
160
|
{ label: 'icon gap', groupKey: 'footer-gap', variable: `--sidenavigation-footer-${s}-gap` },
|
|
161
|
-
{ label: 'indicator color', groupKey: 'footer-
|
|
162
|
-
{ label: 'indicator width', canBeLinked: true, groupKey: 'footer-
|
|
161
|
+
{ label: 'indicator color', groupKey: 'footer-indicator', variable: `--sidenavigation-footer-${s}-indicator` },
|
|
162
|
+
{ label: 'indicator width', canBeLinked: true, groupKey: 'footer-indicator-width', variable: `--sidenavigation-footer-${s}-indicator-width` },
|
|
163
163
|
{ label: 'icon color', groupKey: 'footer-icon', variable: `--sidenavigation-footer-${s}-icon` },
|
|
164
164
|
{ label: 'icon size', canBeLinked: true, groupKey: 'footer-icon-size', variable: `--sidenavigation-footer-${s}-icon-size` },
|
|
165
165
|
];
|
|
@@ -214,11 +214,11 @@
|
|
|
214
214
|
];
|
|
215
215
|
|
|
216
216
|
// Link contexts: within each part, the per-state values share a link tree so
|
|
217
|
-
// a single edit can fan padding/border-width/typography across default/hover/
|
|
217
|
+
// a single edit can fan padding/border-width/typography across default/hover/selected.
|
|
218
218
|
const linkableContexts = new Map<string, string>([
|
|
219
219
|
...STATEFUL_STATES.flatMap((s): Array<[string, string]> => [
|
|
220
220
|
[`--sidenavigation-title-${s}-border-width`, `title ${s}`],
|
|
221
|
-
[`--sidenavigation-title-${s}-
|
|
221
|
+
[`--sidenavigation-title-${s}-indicator-width`, `title ${s}`],
|
|
222
222
|
[`--sidenavigation-title-${s}-padding`, `title ${s}`],
|
|
223
223
|
[`--sidenavigation-title-${s}-label-font-family`, `title ${s}`],
|
|
224
224
|
[`--sidenavigation-title-${s}-label-font-size`, `title ${s}`],
|
|
@@ -232,7 +232,7 @@
|
|
|
232
232
|
[`--sidenavigation-toggle-${s}-icon-size`, `toggle ${s}`],
|
|
233
233
|
]),
|
|
234
234
|
...STATEFUL_STATES.flatMap((s): Array<[string, string]> => [
|
|
235
|
-
[`--sidenavigation-section-${s}-
|
|
235
|
+
[`--sidenavigation-section-${s}-indicator-width`, `section ${s}`],
|
|
236
236
|
[`--sidenavigation-section-${s}-text-font-family`, `section ${s}`],
|
|
237
237
|
[`--sidenavigation-section-${s}-text-font-size`, `section ${s}`],
|
|
238
238
|
[`--sidenavigation-section-${s}-text-font-weight`, `section ${s}`],
|
|
@@ -240,7 +240,7 @@
|
|
|
240
240
|
]),
|
|
241
241
|
...STATEFUL_STATES.flatMap((s): Array<[string, string]> => [
|
|
242
242
|
[`--sidenavigation-item-${s}-padding`, `item ${s}`],
|
|
243
|
-
[`--sidenavigation-item-${s}-
|
|
243
|
+
[`--sidenavigation-item-${s}-indicator-width`, `item ${s}`],
|
|
244
244
|
[`--sidenavigation-item-${s}-text-font-family`, `item ${s}`],
|
|
245
245
|
[`--sidenavigation-item-${s}-text-font-size`, `item ${s}`],
|
|
246
246
|
[`--sidenavigation-item-${s}-text-font-weight`, `item ${s}`],
|
|
@@ -248,7 +248,7 @@
|
|
|
248
248
|
]),
|
|
249
249
|
...STATEFUL_STATES.flatMap((s): Array<[string, string]> => [
|
|
250
250
|
[`--sidenavigation-footer-${s}-padding`, `footer ${s}`],
|
|
251
|
-
[`--sidenavigation-footer-${s}-
|
|
251
|
+
[`--sidenavigation-footer-${s}-indicator-width`, `footer ${s}`],
|
|
252
252
|
[`--sidenavigation-footer-${s}-icon-size`, `footer ${s}`],
|
|
253
253
|
[`--sidenavigation-footer-${s}-text-font-family`, `footer ${s}`],
|
|
254
254
|
[`--sidenavigation-footer-${s}-text-font-size`, `footer ${s}`],
|
|
@@ -349,20 +349,20 @@
|
|
|
349
349
|
]),
|
|
350
350
|
) as Record<string, Token[]>);
|
|
351
351
|
|
|
352
|
-
// Map the
|
|
352
|
+
// Map the shown part/state to the demo's force-hover / force-selected hooks
|
|
353
353
|
// so token edits always have a row painted in that state for the viewer.
|
|
354
354
|
function deriveForce(activeState: string) {
|
|
355
355
|
const [part, sub] = activeState.includes(' / ') ? activeState.split(' / ') : [activeState, ''];
|
|
356
356
|
const partKey = part.toLowerCase();
|
|
357
357
|
const subKey = sub.toLowerCase();
|
|
358
358
|
let forceHoverPart: 'title' | 'toggle' | 'item' | 'footer' | 'section' | null = null;
|
|
359
|
-
let
|
|
359
|
+
let forceSelectedPart: 'title' | 'item' | 'footer' | 'section' | null = null;
|
|
360
360
|
if (subKey === 'hover' && (partKey === 'title' || partKey === 'toggle' || partKey === 'item' || partKey === 'footer' || partKey === 'section')) {
|
|
361
361
|
forceHoverPart = partKey;
|
|
362
|
-
} else if (subKey === '
|
|
363
|
-
|
|
362
|
+
} else if (subKey === 'selected' && (partKey === 'title' || partKey === 'item' || partKey === 'footer' || partKey === 'section')) {
|
|
363
|
+
forceSelectedPart = partKey;
|
|
364
364
|
}
|
|
365
|
-
return { forceHoverPart,
|
|
365
|
+
return { forceHoverPart, forceSelectedPart };
|
|
366
366
|
}
|
|
367
367
|
</script>
|
|
368
368
|
|
|
@@ -396,18 +396,18 @@
|
|
|
396
396
|
{/if}
|
|
397
397
|
{/snippet}
|
|
398
398
|
{#snippet children({ activeState })}
|
|
399
|
-
{@const { forceHoverPart,
|
|
399
|
+
{@const { forceHoverPart, forceSelectedPart } = deriveForce(activeState)}
|
|
400
400
|
<div class="sn-preview-frame">
|
|
401
401
|
<SideNavigation
|
|
402
402
|
sections={demoSections}
|
|
403
403
|
footer={demoFooter}
|
|
404
|
-
|
|
404
|
+
title="Title"
|
|
405
405
|
titleHref="#"
|
|
406
406
|
currentPath="section-1/item-2"
|
|
407
407
|
open={previewOpen}
|
|
408
408
|
ontoggle={() => (previewOpen = !previewOpen)}
|
|
409
409
|
{forceHoverPart}
|
|
410
|
-
{
|
|
410
|
+
{forceSelectedPart}
|
|
411
411
|
/>
|
|
412
412
|
</div>
|
|
413
413
|
{/snippet}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
export const component = 'tabbar';
|
|
6
6
|
|
|
7
|
-
// The tab object — four states (default/hover/
|
|
8
|
-
const tabStateNames = ['default', 'hover', '
|
|
7
|
+
// The tab object — four states (default/hover/selected/disabled) of the same tab button.
|
|
8
|
+
const tabStateNames = ['default', 'hover', 'selected', 'disabled'] as const;
|
|
9
9
|
type TabState = typeof tabStateNames[number];
|
|
10
10
|
// `element` tags split each tab state into frame / icon / indicator / text.
|
|
11
11
|
// No elementOrder: it would force the flat `bar` state into grouped mode.
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
// states (mirrors SegmentedControl's "control bar" + per-option states layout).
|
|
40
40
|
const states: Record<string, Token[]> = {
|
|
41
41
|
bar: [
|
|
42
|
-
{ label: '
|
|
43
|
-
{ label: '
|
|
42
|
+
{ label: 'hairline color', groupKey: 'bar-hairline', variable: '--tabbar-bar-hairline-color' },
|
|
43
|
+
{ label: 'hairline width', groupKey: 'bar-hairline-width', variable: '--tabbar-bar-hairline-width' },
|
|
44
44
|
{ label: 'space above', groupKey: 'bar-top-margin', variable: '--tabbar-bar-top-margin' },
|
|
45
45
|
// Consumed via `padding-bottom: var(--tabbar-bar-bottom-padding)` — a
|
|
46
46
|
// one-axis read. Splitting would produce top/left/right values that have
|
|
47
47
|
// nowhere to render.
|
|
48
48
|
{ label: 'space below tabs', groupKey: 'bar-bottom-padding', variable: '--tabbar-bar-bottom-padding', splittable: false },
|
|
49
|
-
{ label: 'space under
|
|
49
|
+
{ label: 'space under hairline', groupKey: 'bar-bottom-margin', variable: '--tabbar-bar-bottom-margin' },
|
|
50
50
|
{ label: 'tab gap', groupKey: 'tab-gap', variable: '--tabbar-tab-gap' },
|
|
51
51
|
],
|
|
52
52
|
...Object.fromEntries(tabStateNames.map((s) => [`${s} tab`, tabStateTokens(s)])),
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
{/snippet}
|
|
177
177
|
{#snippet children({ activeState })}
|
|
178
178
|
{@const forceClass = activeState === 'hover tab' ? 'force-hover' : ''}
|
|
179
|
-
<TabBar tabs={demoTabs}
|
|
179
|
+
<TabBar tabs={demoTabs} value={selectedDemoTab} class={forceClass} onchange={(id) => (selectedDemoTab = id)} />
|
|
180
180
|
<div class="tab-content-demo">
|
|
181
181
|
<p style="margin: 0;">placeholder tab content</p>
|
|
182
182
|
</div>
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
],
|
|
16
16
|
header: [
|
|
17
17
|
{ label: 'surface color', groupKey: 'header-surface', variable: '--table-default-header-surface' },
|
|
18
|
-
{ label: '
|
|
19
|
-
{ label: '
|
|
18
|
+
{ label: 'hairline color', canBeLinked: true, groupKey: 'border', variable: '--table-default-header-hairline-color' },
|
|
19
|
+
{ label: 'hairline width', canBeLinked: true, groupKey: 'width', variable: '--table-default-header-hairline-width' },
|
|
20
20
|
{ label: 'padding', groupKey: 'header-padding', variable: '--table-default-header-padding' },
|
|
21
21
|
],
|
|
22
22
|
cell: [
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
row: [
|
|
26
26
|
{ label: 'surface color', groupKey: 'row-surface', variable: '--table-default-row-surface' },
|
|
27
27
|
{ label: 'stripe surface', groupKey: 'row-stripe-surface', variable: '--table-default-row-stripe-surface' },
|
|
28
|
-
{ label: '
|
|
29
|
-
{ label: '
|
|
28
|
+
{ label: 'hairline color', canBeLinked: true, groupKey: 'border', variable: '--table-default-row-hairline-color' },
|
|
29
|
+
{ label: 'hairline width', canBeLinked: true, groupKey: 'width', variable: '--table-default-row-hairline-width' },
|
|
30
30
|
],
|
|
31
31
|
column: [
|
|
32
|
-
{ label: '
|
|
33
|
-
{ label: '
|
|
32
|
+
{ label: 'hairline color', canBeLinked: true, groupKey: 'border', variable: '--table-default-column-hairline-color' },
|
|
33
|
+
{ label: 'hairline width', canBeLinked: true, groupKey: 'width', variable: '--table-default-column-hairline-width' },
|
|
34
34
|
],
|
|
35
35
|
};
|
|
36
36
|
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
{ label: 'surface', element: 'thumb', variable: '--toggle-thumb-surface' },
|
|
17
17
|
{ label: 'border', element: 'thumb', variable: '--toggle-thumb-border' },
|
|
18
18
|
{ label: 'size', element: 'thumb', variable: '--toggle-thumb-size' },
|
|
19
|
-
{ label: 'text', element: 'label', variable: '--toggle-label
|
|
19
|
+
{ label: 'text', element: 'label', variable: '--toggle-label' },
|
|
20
20
|
{ label: 'font family', element: 'label', variable: '--toggle-label-font-family' },
|
|
21
21
|
{ label: 'font size', element: 'label', variable: '--toggle-label-font-size' },
|
|
22
22
|
{ label: 'font weight', element: 'label', variable: '--toggle-label-font-weight' },
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
disabled: [
|
|
40
40
|
{ label: 'track surface', variable: '--toggle-disabled-track-surface' },
|
|
41
41
|
{ label: 'thumb surface', variable: '--toggle-disabled-thumb-surface' },
|
|
42
|
-
{ label: 'label text', variable: '--toggle-disabled-label
|
|
42
|
+
{ label: 'label text', variable: '--toggle-disabled-label' },
|
|
43
43
|
],
|
|
44
44
|
};
|
|
45
45
|
|
|
@@ -29,3 +29,6 @@ export type { Token } from './scaffolding/types';
|
|
|
29
29
|
// Intrinsic spec — structural/display props an editor drives outside the token
|
|
30
30
|
// grid (alignment, visibility). Pass an array as `registerComponent({ intrinsics })`.
|
|
31
31
|
export type { IntrinsicSpec } from './scaffolding/types';
|
|
32
|
+
|
|
33
|
+
// Catalogue entry — the shape a runtime file's `catalogue` export satisfies.
|
|
34
|
+
export type { CatalogueEntry } from './scaffolding/types';
|