@motion-proto/live-tokens 0.68.1 → 0.69.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-build-page/SKILL.md +16 -5
- package/.claude/skills/live-tokens-create-component/SKILL.md +43 -8
- package/.claude/skills/live-tokens-create-component/references/token-naming.md +30 -1
- package/.claude/skills/live-tokens-fix-findings/SKILL.md +131 -0
- package/.claude/skills/live-tokens-pick-component/SKILL.md +2 -1
- package/CHANGELOG.md +207 -0
- package/README.md +11 -4
- package/bin/check-component.mjs +367 -63
- package/bin/check-page.mjs +409 -0
- package/bin/cli.mjs +57 -8
- package/bin/lib/cssValues.mjs +50 -0
- package/bin/lib/findings.mjs +106 -0
- package/bin/lib/tokenVocabulary.mjs +213 -0
- package/dist-plugin/adjust/index.cjs +174 -23
- package/dist-plugin/adjust/index.js +68 -23
- package/dist-plugin/{chunk-2UX6EVVA.js → chunk-2YNERPXY.js} +1 -1
- package/dist-plugin/{chunk-NE6N66EE.js → chunk-GPIBU44G.js} +107 -1
- package/dist-plugin/{chunk-ZHPX7ZYQ.js → chunk-RFVYPNRO.js} +39 -1
- package/dist-plugin/generateColorsAndType/index.cjs +107 -1
- package/dist-plugin/generateColorsAndType/index.js +1 -1
- package/dist-plugin/index.cjs +146 -2
- package/dist-plugin/index.js +3 -3
- package/dist-plugin/migrateData/index.cjs +107 -1
- package/dist-plugin/migrateData/index.js +2 -2
- package/dist-plugin/tokensCssMigrations/index.cjs +39 -1
- package/dist-plugin/tokensCssMigrations/index.js +1 -1
- package/package.json +3 -2
- package/src/app/site.css +4 -4
- package/src/editor/component-editor/ButtonEditor.svelte +71 -4
- package/src/editor/component-editor/CardEditor.svelte +6 -6
- package/src/editor/component-editor/DialogEditor.svelte +3 -3
- package/src/editor/component-editor/IconButtonEditor.svelte +68 -3
- package/src/editor/component-editor/ImageEditor.svelte +8 -8
- package/src/editor/component-editor/ImageLightboxEditor.svelte +12 -1
- package/src/editor/component-editor/MenuSelectEditor.svelte +63 -3
- package/src/editor/component-editor/SegmentedControlEditor.svelte +63 -3
- package/src/editor/component-editor/SideNavigationEditor.svelte +67 -3
- package/src/editor/component-editor/SliderEditor.svelte +186 -0
- package/src/editor/component-editor/TabBarEditor.svelte +63 -3
- package/src/editor/component-editor/registry.ts +10 -0
- package/src/editor/core/components/aliasKinds.ts +51 -28
- package/src/editor/core/sketch/sketchLayer.ts +16 -0
- package/src/editor/core/store/editorPersistence.ts +44 -1
- package/src/editor/core/store/editorRenderer.ts +2 -2
- package/src/editor/core/store/editorStore.ts +18 -18
- package/src/editor/core/store/editorTypes.ts +7 -6
- package/src/editor/core/themes/migrations/2026-09-01-gate-suffix-enabled.ts +31 -0
- package/src/editor/core/themes/migrations/2026-09-01-scrim-rename.ts +52 -0
- package/src/editor/core/themes/migrations/2026-09-01-tabbar-active-tint.ts +27 -0
- package/src/editor/core/themes/migrations/2026-09-01-tint-rename.ts +42 -0
- package/src/editor/core/themes/migrations/index.ts +16 -0
- package/src/editor/core/themes/slices/domainVars.ts +2 -2
- package/src/editor/core/themes/slices/washes.ts +107 -0
- package/src/editor/docs/content/editing-tokens.md +5 -3
- package/src/editor/docs/content.generated.ts +1 -1
- package/src/editor/pages/EditorShell.svelte +1 -1
- package/src/editor/ui/SurfacesTab.svelte +3 -3
- package/src/editor/ui/UITokenSelector.svelte +1 -0
- package/src/editor/ui/VariablesTab.svelte +2 -2
- package/src/editor/ui/sections/{OverlaysSection.svelte → WashesSection.svelte} +44 -43
- package/src/live-tokens/data/colors-and-type/autumn.json +6 -6
- package/src/live-tokens/data/colors-and-type/default.json +6 -6
- package/src/live-tokens/data/colors-and-type/halloween.json +6 -6
- package/src/live-tokens/data/colors-and-type/midnight-study.json +6 -6
- package/src/live-tokens/data/colors-and-type/ocean.json +6 -6
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +6 -6
- package/src/live-tokens/data/colors-and-type/sketchy.json +6 -6
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +6 -6
- package/src/live-tokens/data/colors-and-type/sunset.json +6 -6
- package/src/live-tokens/data/themes/autumn.json +81 -13
- package/src/live-tokens/data/themes/halloween.json +81 -13
- package/src/live-tokens/data/themes/midnight-study.json +81 -13
- package/src/live-tokens/data/themes/ocean.json +81 -13
- package/src/live-tokens/data/themes/royal-velvet.json +81 -13
- package/src/live-tokens/data/themes/sketchy.json +81 -13
- package/src/live-tokens/data/themes/spring-meadow.json +81 -13
- package/src/live-tokens/data/themes/sunset.json +81 -13
- package/src/live-tokens/data/tokens.generated.css +6 -6
- package/src/system/components/Button.svelte +28 -10
- package/src/system/components/Card.svelte +6 -6
- package/src/system/components/Dialog.svelte +3 -3
- package/src/system/components/IconButton.svelte +23 -7
- package/src/system/components/Image.svelte +6 -6
- package/src/system/components/MenuSelect.svelte +17 -1
- package/src/system/components/SegmentedControl.svelte +20 -2
- package/src/system/components/SideNavigation.svelte +22 -2
- package/src/system/components/Slider.svelte +348 -0
- package/src/system/components/TabBar.svelte +20 -2
- package/src/system/styles/CONVENTIONS.md +2 -2
- package/src/system/styles/tokens.css +12 -4
- package/template/package.json +3 -2
- package/template/src/pages/Home.svelte +1 -1
- package/src/editor/core/themes/slices/overlays.ts +0 -101
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildSiblings } from './scaffolding/siblings';
|
|
3
|
-
import type { Token } from './scaffolding/types';
|
|
3
|
+
import type { Token, IntrinsicSpec } from './scaffolding/types';
|
|
4
4
|
|
|
5
5
|
export const component = 'button';
|
|
6
6
|
|
|
@@ -101,14 +101,34 @@
|
|
|
101
101
|
);
|
|
102
102
|
|
|
103
103
|
const variantOptions = variants.map((v) => ({ value: v, label: v.charAt(0).toUpperCase() + v.slice(1) }));
|
|
104
|
+
|
|
105
|
+
// The hover tint is off unless a project turns it on: the gate holds a
|
|
106
|
+
// transparent layer, a no-op, until it holds the tint itself.
|
|
107
|
+
export const intrinsics: IntrinsicSpec[] = [
|
|
108
|
+
{
|
|
109
|
+
key: 'shimmer',
|
|
110
|
+
variants: ['default'],
|
|
111
|
+
variable: () => '--button-shimmer',
|
|
112
|
+
values: ['var(--shimmer-on)', 'var(--shimmer-off)'],
|
|
113
|
+
default: { default: 'var(--shimmer-on)' },
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
key: 'hover-tint',
|
|
117
|
+
variants: ['default'],
|
|
118
|
+
variable: () => '--button-hover-tint-enabled',
|
|
119
|
+
values: ['var(--color-transparent)', 'var(--button-hover-tint)'],
|
|
120
|
+
default: { default: 'var(--color-transparent)' },
|
|
121
|
+
},
|
|
122
|
+
];
|
|
104
123
|
</script>
|
|
105
124
|
|
|
106
125
|
<script lang="ts">
|
|
107
126
|
import Button from '../../system/components/Button.svelte';
|
|
108
127
|
import Toggle from '../ui/Toggle.svelte';
|
|
128
|
+
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
109
129
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
110
130
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
111
|
-
import { editorState, setComponentAlias } from '../core/store/editorStore';
|
|
131
|
+
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
112
132
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
113
133
|
|
|
114
134
|
let shimmerRef = $derived($editorState.components.button?.aliases['--button-shimmer']);
|
|
@@ -118,12 +138,49 @@
|
|
|
118
138
|
setComponentAlias('button', '--button-shimmer', { kind: 'token', name: checked ? '--shimmer-on' : '--shimmer-off' });
|
|
119
139
|
}
|
|
120
140
|
|
|
141
|
+
// One switch. Turning the tint on also stands each hover surface down to its
|
|
142
|
+
// own base, so hover is the tint alone rather than a swap wearing a wash.
|
|
143
|
+
// Written as aliases rather than gated in CSS: a component token's value is
|
|
144
|
+
// substituted at :root, so it can never name a per-variant private var.
|
|
145
|
+
// Off clears the overrides, returning each surface to its shipped default.
|
|
146
|
+
const HOVER_SWAPS: readonly (readonly [hover: string, base: string])[] = [
|
|
147
|
+
['--button-primary-hover-surface', '--button-primary-surface'],
|
|
148
|
+
['--button-secondary-hover-surface', '--button-secondary-surface'],
|
|
149
|
+
['--button-outline-hover-surface', '--button-outline-surface'],
|
|
150
|
+
['--button-success-hover-surface', '--button-success-surface'],
|
|
151
|
+
['--button-danger-hover-surface', '--button-danger-surface'],
|
|
152
|
+
['--button-warning-hover-surface', '--button-warning-surface'],
|
|
153
|
+
];
|
|
154
|
+
const TINT_ON = 'var(--button-hover-tint)';
|
|
155
|
+
const TINT_OFF = 'var(--color-transparent)';
|
|
156
|
+
|
|
157
|
+
let tintOn = $derived.by(() => {
|
|
158
|
+
const ref = $editorState.components.button?.aliases['--button-hover-tint-enabled'];
|
|
159
|
+
return (ref?.kind === 'literal' ? ref.value : TINT_OFF) === TINT_ON;
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
function setTintOn(checked: boolean) {
|
|
163
|
+
setComponentAlias('button', '--button-hover-tint-enabled', {
|
|
164
|
+
kind: 'literal',
|
|
165
|
+
value: checked ? TINT_ON : TINT_OFF,
|
|
166
|
+
});
|
|
167
|
+
for (const [hover, base] of HOVER_SWAPS) {
|
|
168
|
+
if (checked) setComponentAlias('button', hover, { kind: 'token', name: base });
|
|
169
|
+
else clearComponentAlias('button', hover);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
121
173
|
let previewSize = $state<'default' | 'small'>('default');
|
|
122
174
|
|
|
123
175
|
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
124
176
|
|
|
125
177
|
let visibleVariantStates = $derived((v: Variant) => Object.fromEntries(
|
|
126
|
-
Object.entries(variantStates(v)).map(([name, list]) => [
|
|
178
|
+
Object.entries(variantStates(v)).map(([name, list]) => [
|
|
179
|
+
name,
|
|
180
|
+
withLinkedDisabled(list, linked.varSet).map((t) =>
|
|
181
|
+
tintOn && t.variable.endsWith('-hover-surface') ? { ...t, disabled: true } : t,
|
|
182
|
+
),
|
|
183
|
+
]),
|
|
127
184
|
) as Record<string, Token[]>);
|
|
128
185
|
|
|
129
186
|
let visibleSmallStates = $derived(Object.fromEntries(
|
|
@@ -158,7 +215,17 @@
|
|
|
158
215
|
>
|
|
159
216
|
{#snippet extraPropertyRows(stateName)}
|
|
160
217
|
{#if stateName === 'hover'}
|
|
161
|
-
<div class="property-row">
|
|
218
|
+
<div class="property-row" data-token-variables="--button-hover-tint-enabled">
|
|
219
|
+
<span class="property-label">tint layer</span>
|
|
220
|
+
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
221
|
+
</div>
|
|
222
|
+
{#if tintOn}
|
|
223
|
+
<div class="property-row">
|
|
224
|
+
<span class="property-label">tint color</span>
|
|
225
|
+
<UIPaletteSelector variable="--button-hover-tint" {component} showNone={false} />
|
|
226
|
+
</div>
|
|
227
|
+
{/if}
|
|
228
|
+
<div class="property-row" data-token-variables="--button-shimmer">
|
|
162
229
|
<span class="property-label">hover shimmer</span>
|
|
163
230
|
<Toggle checked={shimmerEnabled} onchange={handleShimmerChange} />
|
|
164
231
|
</div>
|
|
@@ -92,14 +92,14 @@
|
|
|
92
92
|
{
|
|
93
93
|
key: 'hover-border',
|
|
94
94
|
variants: ['default'],
|
|
95
|
-
variable: () => '--card-hover-border-
|
|
95
|
+
variable: () => '--card-hover-border-enabled',
|
|
96
96
|
values: [HOVER_OFF.border, HOVER_ON.border],
|
|
97
97
|
default: { default: HOVER_OFF.border },
|
|
98
98
|
},
|
|
99
99
|
{
|
|
100
100
|
key: 'hover-shadow',
|
|
101
101
|
variants: ['default'],
|
|
102
|
-
variable: () => '--card-hover-shadow-
|
|
102
|
+
variable: () => '--card-hover-shadow-enabled',
|
|
103
103
|
values: [HOVER_OFF.shadow, HOVER_ON.shadow],
|
|
104
104
|
default: { default: HOVER_OFF.shadow },
|
|
105
105
|
},
|
|
@@ -122,15 +122,15 @@
|
|
|
122
122
|
($editorState.components[component]?.aliases ?? {}) as Record<string, import('../core/store/editorTypes').CssVarRef>,
|
|
123
123
|
);
|
|
124
124
|
let hoverEnabled = $derived.by(() => {
|
|
125
|
-
const ref = aliases['--card-hover-border-
|
|
125
|
+
const ref = aliases['--card-hover-border-enabled'];
|
|
126
126
|
const raw = ref?.kind === 'literal' ? ref.value : HOVER_OFF.border;
|
|
127
127
|
return raw === HOVER_ON.border;
|
|
128
128
|
});
|
|
129
129
|
|
|
130
130
|
function setHoverEnabled(checked: boolean) {
|
|
131
131
|
const v = checked ? HOVER_ON : HOVER_OFF;
|
|
132
|
-
setComponentAlias(component, '--card-hover-border-
|
|
133
|
-
setComponentAlias(component, '--card-hover-shadow-
|
|
132
|
+
setComponentAlias(component, '--card-hover-border-enabled', { kind: 'literal', value: v.border });
|
|
133
|
+
setComponentAlias(component, '--card-hover-shadow-enabled', { kind: 'literal', value: v.shadow });
|
|
134
134
|
}
|
|
135
135
|
</script>
|
|
136
136
|
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
{#if stateName === 'hover'}
|
|
147
147
|
<div
|
|
148
148
|
class="hover-control"
|
|
149
|
-
data-token-variables="--card-hover-border-
|
|
149
|
+
data-token-variables="--card-hover-border-enabled --card-hover-shadow-enabled"
|
|
150
150
|
>
|
|
151
151
|
<label class="hover-enable">
|
|
152
152
|
<input type="checkbox" checked={hoverEnabled} onchange={(e) => setHoverEnabled(e.currentTarget.checked)} />
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
const DEFAULT_CONFIRM: ButtonVariant = 'primary';
|
|
13
13
|
const DEFAULT_CANCEL: ButtonVariant = 'outline';
|
|
14
14
|
|
|
15
|
-
// Frame-level tokens (the dialog box itself +
|
|
15
|
+
// Frame-level tokens (the dialog box itself + scrim + header + body + footer + close icon).
|
|
16
16
|
// Button styling lives in Button.svelte — the dialog only owns its own chrome.
|
|
17
17
|
const frameStates: Record<string, Token[]> = {
|
|
18
|
-
|
|
19
|
-
{ label: '
|
|
18
|
+
scrim: [
|
|
19
|
+
{ label: 'scrim color', groupKey: 'surface', variable: '--dialog-scrim-surface' },
|
|
20
20
|
],
|
|
21
21
|
dialog: [
|
|
22
22
|
{ label: 'surface color', variable: '--dialog-surface' },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildSiblings } from './scaffolding/siblings';
|
|
3
|
-
import type { Token } from './scaffolding/types';
|
|
3
|
+
import type { Token, IntrinsicSpec } from './scaffolding/types';
|
|
4
4
|
|
|
5
5
|
export const component = 'iconbutton';
|
|
6
6
|
|
|
@@ -92,21 +92,72 @@
|
|
|
92
92
|
danger: 'fas fa-trash',
|
|
93
93
|
warning: 'fas fa-triangle-exclamation',
|
|
94
94
|
};
|
|
95
|
+
|
|
96
|
+
// The hover tint is off unless a project turns it on: the gate holds a
|
|
97
|
+
// transparent layer, a no-op, until it holds the tint itself.
|
|
98
|
+
export const intrinsics: IntrinsicSpec[] = [
|
|
99
|
+
{
|
|
100
|
+
key: 'hover-tint',
|
|
101
|
+
variants: ['default'],
|
|
102
|
+
variable: () => '--iconbutton-hover-tint-enabled',
|
|
103
|
+
values: ['var(--color-transparent)', 'var(--iconbutton-hover-tint)'],
|
|
104
|
+
default: { default: 'var(--color-transparent)' },
|
|
105
|
+
},
|
|
106
|
+
];
|
|
95
107
|
</script>
|
|
96
108
|
|
|
97
109
|
<script lang="ts">
|
|
98
110
|
import IconButton from '../../system/components/IconButton.svelte';
|
|
99
111
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
100
112
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
101
|
-
import { editorState } from '../core/store/editorStore';
|
|
113
|
+
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
102
114
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
115
|
+
import Toggle from '../ui/Toggle.svelte';
|
|
116
|
+
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
117
|
+
|
|
118
|
+
// One switch. Turning the tint on also stands each hover surface down to its
|
|
119
|
+
// own base, so hover is the tint alone rather than a swap wearing a wash.
|
|
120
|
+
// Written as aliases rather than gated in CSS: a component token's value is
|
|
121
|
+
// substituted at :root, so it can never name a per-variant private var.
|
|
122
|
+
// Off clears the overrides, returning each surface to its shipped default.
|
|
123
|
+
const HOVER_SWAPS: readonly (readonly [hover: string, base: string])[] = [
|
|
124
|
+
['--iconbutton-primary-hover-surface', '--iconbutton-primary-surface'],
|
|
125
|
+
['--iconbutton-secondary-hover-surface', '--iconbutton-secondary-surface'],
|
|
126
|
+
['--iconbutton-outline-hover-surface', '--iconbutton-outline-surface'],
|
|
127
|
+
['--iconbutton-success-hover-surface', '--iconbutton-success-surface'],
|
|
128
|
+
['--iconbutton-danger-hover-surface', '--iconbutton-danger-surface'],
|
|
129
|
+
['--iconbutton-warning-hover-surface', '--iconbutton-warning-surface'],
|
|
130
|
+
];
|
|
131
|
+
const TINT_ON = 'var(--iconbutton-hover-tint)';
|
|
132
|
+
const TINT_OFF = 'var(--color-transparent)';
|
|
133
|
+
|
|
134
|
+
let tintOn = $derived.by(() => {
|
|
135
|
+
const ref = $editorState.components.iconbutton?.aliases['--iconbutton-hover-tint-enabled'];
|
|
136
|
+
return (ref?.kind === 'literal' ? ref.value : TINT_OFF) === TINT_ON;
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
function setTintOn(checked: boolean) {
|
|
140
|
+
setComponentAlias('iconbutton', '--iconbutton-hover-tint-enabled', {
|
|
141
|
+
kind: 'literal',
|
|
142
|
+
value: checked ? TINT_ON : TINT_OFF,
|
|
143
|
+
});
|
|
144
|
+
for (const [hover, base] of HOVER_SWAPS) {
|
|
145
|
+
if (checked) setComponentAlias('iconbutton', hover, { kind: 'token', name: base });
|
|
146
|
+
else clearComponentAlias('iconbutton', hover);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
103
149
|
|
|
104
150
|
let previewSize = $state<'default' | 'small'>('default');
|
|
105
151
|
|
|
106
152
|
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
107
153
|
|
|
108
154
|
let visibleVariantStates = $derived((v: Variant) => Object.fromEntries(
|
|
109
|
-
Object.entries(variantStates(v)).map(([name, list]) => [
|
|
155
|
+
Object.entries(variantStates(v)).map(([name, list]) => [
|
|
156
|
+
name,
|
|
157
|
+
withLinkedDisabled(list, linked.varSet).map((t) =>
|
|
158
|
+
tintOn && t.variable.endsWith('-hover-surface') ? { ...t, disabled: true } : t,
|
|
159
|
+
),
|
|
160
|
+
]),
|
|
110
161
|
) as Record<string, Token[]>);
|
|
111
162
|
|
|
112
163
|
let visibleSmallStates = $derived(Object.fromEntries(
|
|
@@ -139,6 +190,20 @@
|
|
|
139
190
|
siblings={buildSiblings(variants, v, variantStates)}
|
|
140
191
|
previewActions={sizeAction}
|
|
141
192
|
>
|
|
193
|
+
{#snippet extraPropertyRows(stateName)}
|
|
194
|
+
{#if stateName === 'hover'}
|
|
195
|
+
<div class="property-row" data-token-variables="--iconbutton-hover-tint-enabled">
|
|
196
|
+
<span class="property-label">tint layer</span>
|
|
197
|
+
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
198
|
+
</div>
|
|
199
|
+
{#if tintOn}
|
|
200
|
+
<div class="property-row">
|
|
201
|
+
<span class="property-label">tint color</span>
|
|
202
|
+
<UIPaletteSelector variable="--iconbutton-hover-tint" {component} showNone={false} />
|
|
203
|
+
</div>
|
|
204
|
+
{/if}
|
|
205
|
+
{/if}
|
|
206
|
+
{/snippet}
|
|
142
207
|
{#snippet children({ activeState })}
|
|
143
208
|
{@const forceClass = activeState === 'hover' ? 'force-hover' : activeState === 'active' ? 'force-active' : ''}
|
|
144
209
|
{@const isDisabled = activeState === 'disabled'}
|
|
@@ -16,22 +16,22 @@
|
|
|
16
16
|
|
|
17
17
|
export const allTokens: Token[] = Object.values(states).flat();
|
|
18
18
|
|
|
19
|
-
// Global zoom defaults. `none` = off; `scale(...)` = on. `--image-zoom-
|
|
20
|
-
// content within the masked frame (overflow scaling); `--image-grow-
|
|
19
|
+
// Global zoom defaults. `none` = off; `scale(...)` = on. `--image-zoom-enabled` scales the
|
|
20
|
+
// content within the masked frame (overflow scaling); `--image-grow-enabled` scales the whole
|
|
21
21
|
// frame so it grows. At most one is ever `scale(...)`.
|
|
22
22
|
const ZOOM_ON = 'scale(var(--image-zoom-scale))';
|
|
23
23
|
export const intrinsics: IntrinsicSpec[] = [
|
|
24
24
|
{
|
|
25
25
|
key: 'zoom',
|
|
26
26
|
variants: ['default'],
|
|
27
|
-
variable: () => '--image-zoom-
|
|
27
|
+
variable: () => '--image-zoom-enabled',
|
|
28
28
|
values: ['none', ZOOM_ON],
|
|
29
29
|
default: { default: 'none' },
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
key: 'grow',
|
|
33
33
|
variants: ['default'],
|
|
34
|
-
variable: () => '--image-grow-
|
|
34
|
+
variable: () => '--image-grow-enabled',
|
|
35
35
|
values: ['none', ZOOM_ON],
|
|
36
36
|
default: { default: 'none' },
|
|
37
37
|
},
|
|
@@ -52,15 +52,15 @@
|
|
|
52
52
|
const ref = aliases[variable];
|
|
53
53
|
return ref?.kind === 'literal' ? ref.value : fallback;
|
|
54
54
|
}
|
|
55
|
-
let contentOn = $derived(aliasValue('--image-zoom-
|
|
56
|
-
let frameOn = $derived(aliasValue('--image-grow-
|
|
55
|
+
let contentOn = $derived(aliasValue('--image-zoom-enabled', intrinsics[0].default.default) === ZOOM_ON);
|
|
56
|
+
let frameOn = $derived(aliasValue('--image-grow-enabled', intrinsics[1].default.default) === ZOOM_ON);
|
|
57
57
|
let useZoom = $derived(contentOn || frameOn);
|
|
58
58
|
// Overflow scaling = mask the zoom to the frame (the content path). Off = grow the frame.
|
|
59
59
|
let overflowScaling = $derived(!frameOn);
|
|
60
60
|
|
|
61
61
|
function applyZoom(zoomOn: boolean, masked: boolean) {
|
|
62
|
-
setComponentAlias(component, '--image-zoom-
|
|
63
|
-
setComponentAlias(component, '--image-grow-
|
|
62
|
+
setComponentAlias(component, '--image-zoom-enabled', { kind: 'literal', value: zoomOn && masked ? ZOOM_ON : 'none' });
|
|
63
|
+
setComponentAlias(component, '--image-grow-enabled', { kind: 'literal', value: zoomOn && !masked ? ZOOM_ON : 'none' });
|
|
64
64
|
}
|
|
65
65
|
const setUseZoom = (checked: boolean) => applyZoom(checked, overflowScaling);
|
|
66
66
|
const setOverflowScaling = (checked: boolean) => applyZoom(useZoom, checked);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
|
-
import type { Token } from './scaffolding/types';
|
|
2
|
+
import type { Token, IntrinsicSpec } from './scaffolding/types';
|
|
3
3
|
|
|
4
4
|
export const component = 'imagelightbox';
|
|
5
5
|
|
|
@@ -28,6 +28,17 @@
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
export const allTokens: Token[] = Object.values(states).flat();
|
|
31
|
+
|
|
32
|
+
// How a tile crops inside its frame: a structural choice, not a themeable value.
|
|
33
|
+
export const intrinsics: IntrinsicSpec[] = [
|
|
34
|
+
{
|
|
35
|
+
key: 'tile-fit',
|
|
36
|
+
variants: ['default'],
|
|
37
|
+
variable: () => '--imagelightbox-tile-object-fit',
|
|
38
|
+
values: ['contain', 'cover'],
|
|
39
|
+
default: { default: 'contain' },
|
|
40
|
+
},
|
|
41
|
+
];
|
|
31
42
|
</script>
|
|
32
43
|
|
|
33
44
|
<script lang="ts">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupTokens, buildTypeGroupShareableContexts } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
-
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
3
|
+
import type { Token, TypeGroupConfig, IntrinsicSpec } from './scaffolding/types';
|
|
4
4
|
|
|
5
5
|
export const component = 'menuselect';
|
|
6
6
|
|
|
@@ -91,14 +91,55 @@
|
|
|
91
91
|
['--menuselect-selected-icon-size', 'selected item'],
|
|
92
92
|
['--menuselect-disabled-icon-size', 'disabled item'],
|
|
93
93
|
]);
|
|
94
|
+
|
|
95
|
+
// The hover tint is off unless a project turns it on: the gate holds a
|
|
96
|
+
// transparent layer, a no-op, until it holds the tint itself.
|
|
97
|
+
export const intrinsics: IntrinsicSpec[] = [
|
|
98
|
+
{
|
|
99
|
+
key: 'hover-tint',
|
|
100
|
+
variants: ['default'],
|
|
101
|
+
variable: () => '--menuselect-hover-tint-enabled',
|
|
102
|
+
values: ['var(--color-transparent)', 'var(--menuselect-hover-tint)'],
|
|
103
|
+
default: { default: 'var(--color-transparent)' },
|
|
104
|
+
},
|
|
105
|
+
];
|
|
94
106
|
</script>
|
|
95
107
|
|
|
96
108
|
<script lang="ts">
|
|
97
109
|
import MenuSelect from '../../system/components/MenuSelect.svelte';
|
|
98
110
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
99
111
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
100
|
-
import { editorState } from '../core/store/editorStore';
|
|
112
|
+
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
101
113
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
114
|
+
import Toggle from '../ui/Toggle.svelte';
|
|
115
|
+
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
116
|
+
|
|
117
|
+
// One switch. Turning the tint on also stands each hover surface down to its
|
|
118
|
+
// own base, so hover is the tint alone rather than a swap wearing a wash.
|
|
119
|
+
// Written as aliases rather than gated in CSS: a component token's value is
|
|
120
|
+
// substituted at :root, so it can never name a per-variant private var.
|
|
121
|
+
// Off clears the overrides, returning each surface to its shipped default.
|
|
122
|
+
const HOVER_SWAPS: readonly (readonly [hover: string, base: string])[] = [
|
|
123
|
+
['--menuselect-hover-surface', '--menuselect-default-surface'],
|
|
124
|
+
];
|
|
125
|
+
const TINT_ON = 'var(--menuselect-hover-tint)';
|
|
126
|
+
const TINT_OFF = 'var(--color-transparent)';
|
|
127
|
+
|
|
128
|
+
let tintOn = $derived.by(() => {
|
|
129
|
+
const ref = $editorState.components.menuselect?.aliases['--menuselect-hover-tint-enabled'];
|
|
130
|
+
return (ref?.kind === 'literal' ? ref.value : TINT_OFF) === TINT_ON;
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
function setTintOn(checked: boolean) {
|
|
134
|
+
setComponentAlias('menuselect', '--menuselect-hover-tint-enabled', {
|
|
135
|
+
kind: 'literal',
|
|
136
|
+
value: checked ? TINT_ON : TINT_OFF,
|
|
137
|
+
});
|
|
138
|
+
for (const [hover, base] of HOVER_SWAPS) {
|
|
139
|
+
if (checked) setComponentAlias('menuselect', hover, { kind: 'token', name: base });
|
|
140
|
+
else clearComponentAlias('menuselect', hover);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
102
143
|
|
|
103
144
|
type Item = { value: string; label: string; icon?: string; disabled?: boolean };
|
|
104
145
|
const items: Item[] = [
|
|
@@ -114,7 +155,12 @@
|
|
|
114
155
|
let linked = $derived(computeLinkedBlock(component, linkableContexts, allTokens, $editorState));
|
|
115
156
|
|
|
116
157
|
let visibleStates = $derived(Object.fromEntries(
|
|
117
|
-
Object.entries(states).map(([name, list]) => [
|
|
158
|
+
Object.entries(states).map(([name, list]) => [
|
|
159
|
+
name,
|
|
160
|
+
withLinkedDisabled(list, linked.varSet).map((t) =>
|
|
161
|
+
tintOn && t.variable.endsWith('-hover-surface') ? { ...t, disabled: true } : t,
|
|
162
|
+
),
|
|
163
|
+
]),
|
|
118
164
|
) as Record<string, Token[]>);
|
|
119
165
|
</script>
|
|
120
166
|
|
|
@@ -126,6 +172,20 @@
|
|
|
126
172
|
{typeGroups}
|
|
127
173
|
{component}
|
|
128
174
|
>
|
|
175
|
+
{#snippet extraPropertyRows(stateName)}
|
|
176
|
+
{#if stateName === 'hover item'}
|
|
177
|
+
<div class="property-row" data-token-variables="--menuselect-hover-tint-enabled">
|
|
178
|
+
<span class="property-label">tint layer</span>
|
|
179
|
+
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
180
|
+
</div>
|
|
181
|
+
{#if tintOn}
|
|
182
|
+
<div class="property-row">
|
|
183
|
+
<span class="property-label">tint color</span>
|
|
184
|
+
<UIPaletteSelector variable="--menuselect-hover-tint" {component} showNone={false} />
|
|
185
|
+
</div>
|
|
186
|
+
{/if}
|
|
187
|
+
{/if}
|
|
188
|
+
{/snippet}
|
|
129
189
|
{#snippet canvasToolbarExtras()}
|
|
130
190
|
<hr class="canvas-toolbar-divider" />
|
|
131
191
|
<label class="show-icons-row">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupTokens, buildTypeGroupShareableContexts } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
-
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
3
|
+
import type { Token, TypeGroupConfig, IntrinsicSpec } from './scaffolding/types';
|
|
4
4
|
|
|
5
5
|
export const component = 'segmentedcontrol';
|
|
6
6
|
|
|
@@ -123,14 +123,55 @@
|
|
|
123
123
|
const linkableContexts = new Map<string, string>(
|
|
124
124
|
buildTypeGroupShareableContexts(typeGroups),
|
|
125
125
|
);
|
|
126
|
+
|
|
127
|
+
// The hover tint is off unless a project turns it on: the gate holds a
|
|
128
|
+
// transparent layer, a no-op, until it holds the tint itself.
|
|
129
|
+
export const intrinsics: IntrinsicSpec[] = [
|
|
130
|
+
{
|
|
131
|
+
key: 'hover-tint',
|
|
132
|
+
variants: ['default'],
|
|
133
|
+
variable: () => '--segmentedcontrol-hover-tint-enabled',
|
|
134
|
+
values: ['var(--color-transparent)', 'var(--segmentedcontrol-hover-tint)'],
|
|
135
|
+
default: { default: 'var(--color-transparent)' },
|
|
136
|
+
},
|
|
137
|
+
];
|
|
126
138
|
</script>
|
|
127
139
|
|
|
128
140
|
<script lang="ts">
|
|
129
141
|
import SegmentedControl from '../../system/components/SegmentedControl.svelte';
|
|
130
142
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
131
143
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
132
|
-
import { editorState } from '../core/store/editorStore';
|
|
144
|
+
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
133
145
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
146
|
+
import Toggle from '../ui/Toggle.svelte';
|
|
147
|
+
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
148
|
+
|
|
149
|
+
// One switch. Turning the tint on also stands each hover surface down to its
|
|
150
|
+
// own base, so hover is the tint alone rather than a swap wearing a wash.
|
|
151
|
+
// Written as aliases rather than gated in CSS: a component token's value is
|
|
152
|
+
// substituted at :root, so it can never name a per-variant private var.
|
|
153
|
+
// Off clears the overrides, returning each surface to its shipped default.
|
|
154
|
+
const HOVER_SWAPS: readonly (readonly [hover: string, base: string])[] = [
|
|
155
|
+
['--segmentedcontrol-option-hover-surface', '--color-transparent'],
|
|
156
|
+
];
|
|
157
|
+
const TINT_ON = 'var(--segmentedcontrol-hover-tint)';
|
|
158
|
+
const TINT_OFF = 'var(--color-transparent)';
|
|
159
|
+
|
|
160
|
+
let tintOn = $derived.by(() => {
|
|
161
|
+
const ref = $editorState.components.segmentedcontrol?.aliases['--segmentedcontrol-hover-tint-enabled'];
|
|
162
|
+
return (ref?.kind === 'literal' ? ref.value : TINT_OFF) === TINT_ON;
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
function setTintOn(checked: boolean) {
|
|
166
|
+
setComponentAlias('segmentedcontrol', '--segmentedcontrol-hover-tint-enabled', {
|
|
167
|
+
kind: 'literal',
|
|
168
|
+
value: checked ? TINT_ON : TINT_OFF,
|
|
169
|
+
});
|
|
170
|
+
for (const [hover, base] of HOVER_SWAPS) {
|
|
171
|
+
if (checked) setComponentAlias('segmentedcontrol', hover, { kind: 'token', name: base });
|
|
172
|
+
else clearComponentAlias('segmentedcontrol', hover);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
134
175
|
|
|
135
176
|
type Segment = { value: string; label: string; icon?: string; disabled?: boolean };
|
|
136
177
|
const segments: Segment[] = [
|
|
@@ -148,7 +189,12 @@
|
|
|
148
189
|
let activeTypeGroups = $derived(previewSize === 'small' ? emptyTypeGroups : typeGroups);
|
|
149
190
|
|
|
150
191
|
let visibleStates = $derived(Object.fromEntries(
|
|
151
|
-
Object.entries(activeStates).map(([name, list]) => [
|
|
192
|
+
Object.entries(activeStates).map(([name, list]) => [
|
|
193
|
+
name,
|
|
194
|
+
withLinkedDisabled(list, linked.varSet).map((t) =>
|
|
195
|
+
tintOn && t.variable.endsWith('-hover-surface') ? { ...t, disabled: true } : t,
|
|
196
|
+
),
|
|
197
|
+
]),
|
|
152
198
|
) as Record<string, Token[]>);
|
|
153
199
|
</script>
|
|
154
200
|
|
|
@@ -160,6 +206,20 @@
|
|
|
160
206
|
typeGroups={activeTypeGroups}
|
|
161
207
|
{component}
|
|
162
208
|
>
|
|
209
|
+
{#snippet extraPropertyRows(stateName)}
|
|
210
|
+
{#if stateName === 'hover option'}
|
|
211
|
+
<div class="property-row" data-token-variables="--segmentedcontrol-hover-tint-enabled">
|
|
212
|
+
<span class="property-label">tint layer</span>
|
|
213
|
+
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
214
|
+
</div>
|
|
215
|
+
{#if tintOn}
|
|
216
|
+
<div class="property-row">
|
|
217
|
+
<span class="property-label">tint color</span>
|
|
218
|
+
<UIPaletteSelector variable="--segmentedcontrol-hover-tint" {component} showNone={false} />
|
|
219
|
+
</div>
|
|
220
|
+
{/if}
|
|
221
|
+
{/if}
|
|
222
|
+
{/snippet}
|
|
163
223
|
{#snippet previewActions()}
|
|
164
224
|
<label>
|
|
165
225
|
<span>Size</span>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script module lang="ts">
|
|
2
2
|
import { buildTypeGroupColorTokens } from './scaffolding/buildTypeGroupTokens';
|
|
3
|
-
import type { Token, TypeGroupConfig } from './scaffolding/types';
|
|
3
|
+
import type { Token, TypeGroupConfig, IntrinsicSpec } from './scaffolding/types';
|
|
4
4
|
|
|
5
5
|
export const component = 'sidenavigation';
|
|
6
6
|
|
|
@@ -259,14 +259,59 @@
|
|
|
259
259
|
['--sidenavigation-panel-padding', 'panel'],
|
|
260
260
|
['--sidenavigation-title-label-border-width', 'title block'],
|
|
261
261
|
]);
|
|
262
|
+
|
|
263
|
+
// The hover tint is off unless a project turns it on: the gate holds a
|
|
264
|
+
// transparent layer, a no-op, until it holds the tint itself.
|
|
265
|
+
export const intrinsics: IntrinsicSpec[] = [
|
|
266
|
+
{
|
|
267
|
+
key: 'hover-tint',
|
|
268
|
+
variants: ['default'],
|
|
269
|
+
variable: () => '--sidenavigation-hover-tint-enabled',
|
|
270
|
+
values: ['var(--color-transparent)', 'var(--sidenavigation-hover-tint)'],
|
|
271
|
+
default: { default: 'var(--color-transparent)' },
|
|
272
|
+
},
|
|
273
|
+
];
|
|
262
274
|
</script>
|
|
263
275
|
|
|
264
276
|
<script lang="ts">
|
|
265
277
|
import SideNavigation, { type SideNavSection, type SideNavFooter } from '../../system/components/SideNavigation.svelte';
|
|
266
278
|
import VariantGroup from './scaffolding/VariantGroup.svelte';
|
|
267
279
|
import ComponentEditorBase from './scaffolding/ComponentEditorBase.svelte';
|
|
268
|
-
import { editorState } from '../core/store/editorStore';
|
|
280
|
+
import { editorState, setComponentAlias, clearComponentAlias } from '../core/store/editorStore';
|
|
269
281
|
import { computeLinkedBlock, withLinkedDisabled } from './scaffolding/linkedBlock';
|
|
282
|
+
import Toggle from '../ui/Toggle.svelte';
|
|
283
|
+
import UIPaletteSelector from '../ui/UIPaletteSelector.svelte';
|
|
284
|
+
|
|
285
|
+
// One switch. Turning the tint on also stands each hover surface down to its
|
|
286
|
+
// own base, so hover is the tint alone rather than a swap wearing a wash.
|
|
287
|
+
// Written as aliases rather than gated in CSS: a component token's value is
|
|
288
|
+
// substituted at :root, so it can never name a per-variant private var.
|
|
289
|
+
// Off clears the overrides, returning each surface to its shipped default.
|
|
290
|
+
const HOVER_SWAPS: readonly (readonly [hover: string, base: string])[] = [
|
|
291
|
+
['--sidenavigation-title-hover-surface', '--sidenavigation-title-default-surface'],
|
|
292
|
+
['--sidenavigation-toggle-hover-surface', '--sidenavigation-toggle-default-surface'],
|
|
293
|
+
['--sidenavigation-section-hover-surface', '--sidenavigation-section-default-surface'],
|
|
294
|
+
['--sidenavigation-item-hover-surface', '--sidenavigation-item-default-surface'],
|
|
295
|
+
['--sidenavigation-footer-hover-surface', '--sidenavigation-footer-default-surface'],
|
|
296
|
+
];
|
|
297
|
+
const TINT_ON = 'var(--sidenavigation-hover-tint)';
|
|
298
|
+
const TINT_OFF = 'var(--color-transparent)';
|
|
299
|
+
|
|
300
|
+
let tintOn = $derived.by(() => {
|
|
301
|
+
const ref = $editorState.components.sidenavigation?.aliases['--sidenavigation-hover-tint-enabled'];
|
|
302
|
+
return (ref?.kind === 'literal' ? ref.value : TINT_OFF) === TINT_ON;
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
function setTintOn(checked: boolean) {
|
|
306
|
+
setComponentAlias('sidenavigation', '--sidenavigation-hover-tint-enabled', {
|
|
307
|
+
kind: 'literal',
|
|
308
|
+
value: checked ? TINT_ON : TINT_OFF,
|
|
309
|
+
});
|
|
310
|
+
for (const [hover, base] of HOVER_SWAPS) {
|
|
311
|
+
if (checked) setComponentAlias('sidenavigation', hover, { kind: 'token', name: base });
|
|
312
|
+
else clearComponentAlias('sidenavigation', hover);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
270
315
|
|
|
271
316
|
const demoSections: SideNavSection[] = [
|
|
272
317
|
{
|
|
@@ -296,7 +341,12 @@
|
|
|
296
341
|
let previewOpen = $state(true);
|
|
297
342
|
|
|
298
343
|
let visibleStates = $derived(Object.fromEntries(
|
|
299
|
-
Object.entries(states).map(([name, list]) => [
|
|
344
|
+
Object.entries(states).map(([name, list]) => [
|
|
345
|
+
name,
|
|
346
|
+
withLinkedDisabled(list, linked.varSet).map((t) =>
|
|
347
|
+
tintOn && t.variable.endsWith('-hover-surface') ? { ...t, disabled: true } : t,
|
|
348
|
+
),
|
|
349
|
+
]),
|
|
300
350
|
) as Record<string, Token[]>);
|
|
301
351
|
|
|
302
352
|
// Map the active part/state to the demo's force-hover / force-active hooks
|
|
@@ -331,6 +381,20 @@
|
|
|
331
381
|
{component}
|
|
332
382
|
selectorLabel="Part"
|
|
333
383
|
>
|
|
384
|
+
{#snippet extraPropertyRows(stateName)}
|
|
385
|
+
{#if stateName.endsWith(' / Hover')}
|
|
386
|
+
<div class="property-row" data-token-variables="--sidenavigation-hover-tint-enabled">
|
|
387
|
+
<span class="property-label">tint layer</span>
|
|
388
|
+
<Toggle checked={tintOn} onchange={setTintOn} />
|
|
389
|
+
</div>
|
|
390
|
+
{#if tintOn}
|
|
391
|
+
<div class="property-row">
|
|
392
|
+
<span class="property-label">tint color</span>
|
|
393
|
+
<UIPaletteSelector variable="--sidenavigation-hover-tint" {component} showNone={false} />
|
|
394
|
+
</div>
|
|
395
|
+
{/if}
|
|
396
|
+
{/if}
|
|
397
|
+
{/snippet}
|
|
334
398
|
{#snippet children({ activeState })}
|
|
335
399
|
{@const { forceHoverPart, forceActivePart } = deriveForce(activeState)}
|
|
336
400
|
<div class="sn-preview-frame">
|