@motion-proto/live-tokens 0.68.1 → 0.70.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 +55 -19
- package/.claude/skills/live-tokens-create-component/references/token-naming.md +30 -1
- package/.claude/skills/live-tokens-fix-findings/SKILL.md +133 -0
- package/.claude/skills/live-tokens-pick-component/SKILL.md +10 -1
- package/CHANGELOG.md +236 -0
- package/README.md +13 -4
- package/bin/check-component.mjs +367 -63
- package/bin/check-page.mjs +409 -0
- package/bin/cli.mjs +107 -9
- package/bin/lib/catalogue.mjs +123 -0
- package/bin/lib/cssValues.mjs +50 -0
- package/bin/lib/findings.mjs +106 -0
- package/bin/lib/tokenVocabulary.mjs +240 -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/index.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
|
@@ -876,6 +876,106 @@ var componentMigration_2026_08_15_lineHeightScaleRename = {
|
|
|
876
876
|
apply: renameValues
|
|
877
877
|
};
|
|
878
878
|
|
|
879
|
+
// src/editor/core/themes/migrations/2026-09-01-scrim-rename.ts
|
|
880
|
+
var RENAMED2 = {
|
|
881
|
+
"--overlay-low": "--scrim-low",
|
|
882
|
+
"--overlay": "--scrim",
|
|
883
|
+
"--overlay-high": "--scrim-high"
|
|
884
|
+
};
|
|
885
|
+
var RENAMED_COMPONENT_KEYS = {
|
|
886
|
+
"--dialog-overlay-surface": "--dialog-scrim-surface"
|
|
887
|
+
};
|
|
888
|
+
var colorsAndTypeMigration_2026_09_01_scrimRename = {
|
|
889
|
+
id: "2026-09-01-scrim-rename-theme",
|
|
890
|
+
fromVersion: 5,
|
|
891
|
+
toVersion: 6,
|
|
892
|
+
appliesTo: "colors-and-type",
|
|
893
|
+
apply(rawVars) {
|
|
894
|
+
const out = {};
|
|
895
|
+
for (const [key, value] of Object.entries(rawVars)) {
|
|
896
|
+
out[RENAMED2[key] ?? key] = value;
|
|
897
|
+
}
|
|
898
|
+
return out;
|
|
899
|
+
}
|
|
900
|
+
};
|
|
901
|
+
var componentMigration_2026_09_01_scrimRename = {
|
|
902
|
+
id: "2026-09-01-scrim-rename-component",
|
|
903
|
+
fromVersion: 21,
|
|
904
|
+
toVersion: 22,
|
|
905
|
+
appliesTo: "component-config",
|
|
906
|
+
apply(rawVars) {
|
|
907
|
+
const out = {};
|
|
908
|
+
for (const [key, value] of Object.entries(rawVars)) {
|
|
909
|
+
out[RENAMED_COMPONENT_KEYS[key] ?? key] = RENAMED2[value] ?? value;
|
|
910
|
+
}
|
|
911
|
+
return out;
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
|
|
915
|
+
// src/editor/core/themes/migrations/2026-09-01-tint-rename.ts
|
|
916
|
+
var RENAMED3 = {
|
|
917
|
+
"--hover-low": "--tint-low",
|
|
918
|
+
"--hover": "--tint",
|
|
919
|
+
"--hover-high": "--tint-high"
|
|
920
|
+
};
|
|
921
|
+
var colorsAndTypeMigration_2026_09_01_tintRename = {
|
|
922
|
+
id: "2026-09-01-tint-rename-theme",
|
|
923
|
+
fromVersion: 6,
|
|
924
|
+
toVersion: 7,
|
|
925
|
+
appliesTo: "colors-and-type",
|
|
926
|
+
apply(rawVars) {
|
|
927
|
+
const out = {};
|
|
928
|
+
for (const [key, value] of Object.entries(rawVars)) out[RENAMED3[key] ?? key] = value;
|
|
929
|
+
return out;
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
var componentMigration_2026_09_01_tintRename = {
|
|
933
|
+
id: "2026-09-01-tint-rename-component",
|
|
934
|
+
fromVersion: 22,
|
|
935
|
+
toVersion: 23,
|
|
936
|
+
appliesTo: "component-config",
|
|
937
|
+
apply(rawVars) {
|
|
938
|
+
const out = {};
|
|
939
|
+
for (const [key, value] of Object.entries(rawVars)) out[key] = RENAMED3[value] ?? value;
|
|
940
|
+
return out;
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
|
|
944
|
+
// src/editor/core/themes/migrations/2026-09-01-tabbar-active-tint.ts
|
|
945
|
+
var componentMigration_2026_09_01_tabbarActiveTint = {
|
|
946
|
+
id: "2026-09-01-tabbar-active-tint",
|
|
947
|
+
fromVersion: 23,
|
|
948
|
+
toVersion: 24,
|
|
949
|
+
appliesTo: "component-config",
|
|
950
|
+
apply(rawVars, meta) {
|
|
951
|
+
if (meta.component !== "tabbar") return { ...rawVars };
|
|
952
|
+
const out = { ...rawVars };
|
|
953
|
+
if (out["--tabbar-active-surface"] === "--scrim-low") {
|
|
954
|
+
out["--tabbar-active-surface"] = "--tint-low";
|
|
955
|
+
}
|
|
956
|
+
return out;
|
|
957
|
+
}
|
|
958
|
+
};
|
|
959
|
+
|
|
960
|
+
// src/editor/core/themes/migrations/2026-09-01-gate-suffix-enabled.ts
|
|
961
|
+
var RENAMED4 = {
|
|
962
|
+
"--card-hover-border-active": "--card-hover-border-enabled",
|
|
963
|
+
"--card-hover-shadow-active": "--card-hover-shadow-enabled",
|
|
964
|
+
"--image-zoom-hover": "--image-zoom-enabled",
|
|
965
|
+
"--image-grow-hover": "--image-grow-enabled"
|
|
966
|
+
};
|
|
967
|
+
var componentMigration_2026_09_01_gateSuffixEnabled = {
|
|
968
|
+
id: "2026-09-01-gate-suffix-enabled",
|
|
969
|
+
fromVersion: 24,
|
|
970
|
+
toVersion: 25,
|
|
971
|
+
appliesTo: "component-config",
|
|
972
|
+
apply(rawVars) {
|
|
973
|
+
const out = {};
|
|
974
|
+
for (const [key, value] of Object.entries(rawVars)) out[RENAMED4[key] ?? key] = value;
|
|
975
|
+
return out;
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
|
|
879
979
|
// src/editor/core/themes/migrations/index.ts
|
|
880
980
|
var MIGRATIONS = [
|
|
881
981
|
colorsAndTypeMigration_2026_04_24_legacyKeysAndBgToCanvas,
|
|
@@ -903,7 +1003,13 @@ var MIGRATIONS = [
|
|
|
903
1003
|
componentMigration_2026_05_29_toggleDeriveTrackFromThumb,
|
|
904
1004
|
colorsAndTypeMigration_2026_08_13_dropLegacyShapeSpaceKeys,
|
|
905
1005
|
colorsAndTypeMigration_2026_08_15_lineHeightScaleRename,
|
|
906
|
-
componentMigration_2026_08_15_lineHeightScaleRename
|
|
1006
|
+
componentMigration_2026_08_15_lineHeightScaleRename,
|
|
1007
|
+
colorsAndTypeMigration_2026_09_01_scrimRename,
|
|
1008
|
+
componentMigration_2026_09_01_scrimRename,
|
|
1009
|
+
colorsAndTypeMigration_2026_09_01_tintRename,
|
|
1010
|
+
componentMigration_2026_09_01_tintRename,
|
|
1011
|
+
componentMigration_2026_09_01_tabbarActiveTint,
|
|
1012
|
+
componentMigration_2026_09_01_gateSuffixEnabled
|
|
907
1013
|
];
|
|
908
1014
|
function countFor(kind) {
|
|
909
1015
|
return MIGRATIONS.filter((m) => m.appliesTo === kind).length;
|
|
@@ -7,10 +7,10 @@ import {
|
|
|
7
7
|
normalizeTheme,
|
|
8
8
|
planLegacyRenames,
|
|
9
9
|
versionedFileResourceServer
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-2YNERPXY.js";
|
|
11
11
|
import {
|
|
12
12
|
CURRENT_COMPONENT_SCHEMA_VERSION
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-GPIBU44G.js";
|
|
14
14
|
import {
|
|
15
15
|
readLiveTokensConfig,
|
|
16
16
|
resolveDataDirs
|
|
@@ -603,6 +603,42 @@ var tokensCssMigration_2026_08_27_editorialLargeSteps = {
|
|
|
603
603
|
}
|
|
604
604
|
};
|
|
605
605
|
|
|
606
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-09-01-scrim-rename.ts
|
|
607
|
+
var RENAMES2 = [
|
|
608
|
+
["--overlay-low", "--scrim-low"],
|
|
609
|
+
["--overlay-high", "--scrim-high"],
|
|
610
|
+
["--overlay", "--scrim"]
|
|
611
|
+
];
|
|
612
|
+
var tokensCssMigration_2026_09_01_scrimRename = {
|
|
613
|
+
id: "2026-09-01-scrim-rename",
|
|
614
|
+
kind: "breaking",
|
|
615
|
+
description: "Rename --overlay-{low,base,high} to --scrim-*; a scrim dims what is behind it",
|
|
616
|
+
apply(css) {
|
|
617
|
+
let out = css;
|
|
618
|
+
for (const [oldName, newName] of RENAMES2) out = renameToken(out, oldName, newName);
|
|
619
|
+
return out;
|
|
620
|
+
}
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
// vite-plugin/tokensCssMigrations/migrations/2026-09-01-tint-scale.ts
|
|
624
|
+
var ENTRIES = [
|
|
625
|
+
{ name: "--tint-low", value: "rgba(255, 255, 255, 0.05)" },
|
|
626
|
+
{ name: "--tint", value: "rgba(255, 255, 255, 0.1)" },
|
|
627
|
+
{ name: "--tint-high", value: "rgba(255, 255, 255, 0.15)" }
|
|
628
|
+
];
|
|
629
|
+
var tokensCssMigration_2026_09_01_tintScale = {
|
|
630
|
+
id: "2026-09-01-tint-scale",
|
|
631
|
+
kind: "additive",
|
|
632
|
+
description: "Add the --tint-* scale; a tint shades the surface it sits on",
|
|
633
|
+
apply(css) {
|
|
634
|
+
return ensureScale(css, {
|
|
635
|
+
entries: ENTRIES,
|
|
636
|
+
sectionComment: "Tints \u2014 translucent washes that shade the surface they sit on",
|
|
637
|
+
anchorPrefixes: ["--scrim", "--overlay"]
|
|
638
|
+
});
|
|
639
|
+
}
|
|
640
|
+
};
|
|
641
|
+
|
|
606
642
|
// vite-plugin/files/dataPaths.ts
|
|
607
643
|
var import_fs = __toESM(require("fs"), 1);
|
|
608
644
|
var import_path = __toESM(require("path"), 1);
|
|
@@ -651,7 +687,9 @@ var TOKENS_CSS_MIGRATIONS = [
|
|
|
651
687
|
tokensCssMigration_2026_08_26_gradientStops,
|
|
652
688
|
tokensCssMigration_2026_08_27_backdropPolarity,
|
|
653
689
|
tokensCssMigration_2026_08_27_editorialSizeSteps,
|
|
654
|
-
tokensCssMigration_2026_08_27_editorialLargeSteps
|
|
690
|
+
tokensCssMigration_2026_08_27_editorialLargeSteps,
|
|
691
|
+
tokensCssMigration_2026_09_01_scrimRename,
|
|
692
|
+
tokensCssMigration_2026_09_01_tintScale
|
|
655
693
|
];
|
|
656
694
|
function runTokensCssMigrations(css) {
|
|
657
695
|
return foldMigrations(css, () => true);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@motion-proto/live-tokens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.70.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Design token editor with live CSS variable editing. Svelte 5 + Vite 8.",
|
|
6
6
|
"keywords": [
|
|
@@ -144,6 +144,7 @@
|
|
|
144
144
|
"check:overlay-portal": "node scripts/check-overlay-portal.mjs",
|
|
145
145
|
"check:editor-font-isolation": "node scripts/check-editor-font-isolation.mjs",
|
|
146
146
|
"check:component-defaults": "node scripts/sync-component-defaults.mjs --check",
|
|
147
|
+
"check:pages": "node bin/cli.mjs check-page --strict",
|
|
147
148
|
"check:production-is-default": "node scripts/check-production-is-default.mjs",
|
|
148
149
|
"check:docs-content": "node scripts/sync-docs.mjs --check",
|
|
149
150
|
"check:token-contract": "node scripts/check-token-contract.mjs",
|
|
@@ -157,7 +158,7 @@
|
|
|
157
158
|
"collapse:theme": "node scripts/collapse-theme-to-default.mjs",
|
|
158
159
|
"check:smoke-install": "bash scripts/smoke-install.sh",
|
|
159
160
|
"check:smoke-create": "bash scripts/smoke-create.sh",
|
|
160
|
-
"prepublishOnly": "npm run check:no-style-imports && npm run check:no-tooling-imports && npm run check:slot-prose && npm run check:overlay-portal && npm run check:editor-font-isolation && npm run check:component-defaults && npm run check:production-is-default && npm run check:docs-content && npm run build:lib && npm run check:token-contract && npm run check:preset-themes && npm run check:skills && npm run check:skill-atlas && npm run check:smoke-install && npm run check:smoke-create"
|
|
161
|
+
"prepublishOnly": "npm run check:no-style-imports && npm run check:no-tooling-imports && npm run check:slot-prose && npm run check:overlay-portal && npm run check:editor-font-isolation && npm run check:component-defaults && npm run check:pages && npm run check:production-is-default && npm run check:docs-content && npm run build:lib && npm run check:token-contract && npm run check:preset-themes && npm run check:skills && npm run check:skill-atlas && npm run check:smoke-install && npm run check:smoke-create"
|
|
161
162
|
},
|
|
162
163
|
"peerDependencies": {
|
|
163
164
|
"@sveltejs/vite-plugin-svelte": "^7.0",
|
package/src/app/site.css
CHANGED
|
@@ -71,7 +71,7 @@ p {
|
|
|
71
71
|
font-size: var(--body-md-font-size);
|
|
72
72
|
color: var(--text-secondary);
|
|
73
73
|
line-height: var(--body-md-line-height);
|
|
74
|
-
margin: 0 0
|
|
74
|
+
margin: 0 0 var(--space-16);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
p:last-child {
|
|
@@ -142,15 +142,15 @@ ol li::marker {
|
|
|
142
142
|
|
|
143
143
|
hr {
|
|
144
144
|
border: none;
|
|
145
|
-
border-top:
|
|
145
|
+
border-top: var(--border-width-1) solid var(--border-neutral-faint);
|
|
146
146
|
margin: var(--space-32) 0;
|
|
147
147
|
}
|
|
148
148
|
|
|
149
149
|
blockquote {
|
|
150
150
|
margin: var(--space-16) 0;
|
|
151
151
|
padding: var(--space-12) var(--space-20);
|
|
152
|
-
border:
|
|
153
|
-
border-left:
|
|
152
|
+
border: var(--border-width-1) solid var(--color-brand-500);
|
|
153
|
+
border-left: var(--border-width-4) solid var(--color-brand-500);
|
|
154
154
|
background: var(--surface-neutral-high);
|
|
155
155
|
border-radius: 0 var(--radius-md) var(--radius-md) 0;
|
|
156
156
|
color: var(--text-secondary);
|
|
@@ -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">
|