@motion-proto/live-tokens 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -13
- package/dist-plugin/index.cjs +854 -226
- package/dist-plugin/index.d.cts +2 -1
- package/dist-plugin/index.d.ts +2 -1
- package/dist-plugin/index.js +852 -225
- package/package.json +26 -40
- package/src/{styles → app}/site.css +1 -1
- package/src/{component-editor → editor/component-editor}/BadgeEditor.svelte +8 -82
- package/src/{component-editor → editor/component-editor}/CalloutEditor.svelte +4 -4
- package/src/{component-editor → editor/component-editor}/CardEditor.svelte +28 -76
- package/src/{component-editor → editor/component-editor}/CollapsibleSectionEditor.svelte +37 -30
- package/src/{component-editor → editor/component-editor}/CornerBadgeEditor.svelte +31 -93
- package/src/{component-editor → editor/component-editor}/DialogEditor.svelte +60 -57
- package/src/editor/component-editor/ImageEditor.svelte +30 -0
- package/src/{component-editor → editor/component-editor}/InlineEditActionsEditor.svelte +6 -4
- package/src/editor/component-editor/MenuSelectEditor.svelte +160 -0
- package/src/{component-editor → editor/component-editor}/NotificationEditor.svelte +67 -38
- package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
- package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
- package/src/editor/component-editor/SectionDividerEditor.svelte +565 -0
- package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +29 -21
- package/src/{component-editor → editor/component-editor}/TabBarEditor.svelte +9 -14
- package/src/{component-editor → editor/component-editor}/TableEditor.svelte +9 -18
- package/src/{component-editor → editor/component-editor}/TooltipEditor.svelte +11 -47
- package/src/editor/component-editor/editors.d.ts +10 -0
- package/src/{component-editor → editor/component-editor}/registry.ts +28 -18
- package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +54 -15
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +151 -424
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileMenu.svelte +18 -170
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentsTab.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/CopyFromMenu.svelte +44 -4
- package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -12
- package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
- package/src/editor/component-editor/scaffolding/RadialShapePad.svelte +483 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
- package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +85 -0
- package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +345 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +17 -12
- package/src/{component-editor → editor/component-editor}/scaffolding/TypeEditor.svelte +13 -1
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +858 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +1 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/editorContext.ts +19 -9
- package/src/{component-editor → editor/component-editor}/scaffolding/linkedBlock.ts +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/types.ts +25 -0
- package/src/{lib → editor/core/components}/componentConfigKeys.ts +8 -0
- package/src/{lib → editor/core/components}/componentConfigService.ts +3 -3
- package/src/{lib → editor/core/components}/componentPersist.ts +11 -9
- package/src/editor/core/flashStatus.ts +30 -0
- package/src/{lib → editor/core/fonts}/fontLoader.ts +2 -2
- package/src/{lib → editor/core/fonts}/fontMigration.ts +4 -4
- package/src/{lib → editor/core/fonts}/fontParse.ts +1 -1
- package/src/editor/core/manifests/manifestService.ts +171 -0
- package/src/editor/core/palettes/familySwap.ts +99 -0
- package/src/{lib → editor/core/palettes}/paletteDerivation.ts +71 -2
- package/src/{lib → editor/core/palettes}/tokenRegistry.ts +9 -6
- package/src/editor/core/productionPulse.ts +37 -0
- package/src/{lib → editor/core/routing}/router.ts +1 -1
- package/src/{lib/files/versionedFileResource.ts → editor/core/storage/files/versionedFileResourceClient.ts} +8 -1
- package/src/{lib → editor/core/store}/editorCore.ts +24 -8
- package/src/{lib → editor/core/store}/editorPersistence.ts +3 -3
- package/src/{lib → editor/core/store}/editorRenderer.ts +2 -2
- package/src/{lib → editor/core/store}/editorStore.ts +222 -28
- package/src/{lib → editor/core/store}/editorTypes.ts +56 -13
- package/src/editor/core/store/gradientSource.ts +192 -0
- package/src/editor/core/themes/migrations/2026-05-19-collapsiblesection-drop-frame-surface.ts +28 -0
- package/src/editor/core/themes/migrations/2026-05-19-sectiondivider-rich-gradient.ts +35 -0
- package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +82 -0
- package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +24 -0
- package/src/editor/core/themes/migrations/2026-05-22-sectiondivider-intrinsics-to-css.ts +81 -0
- package/src/{lib → editor/core/themes}/migrations/index.ts +10 -0
- package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
- package/src/{lib → editor/core/themes}/slices/components.ts +20 -6
- package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/gradients.ts +89 -14
- package/src/{lib → editor/core/themes}/slices/overlays.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/palettes.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/shadows.ts +3 -3
- package/src/{lib → editor/core/themes}/themeInit.ts +8 -8
- package/src/{lib → editor/core/themes}/themeService.ts +6 -6
- package/src/{lib → editor/core/themes}/themeTypes.ts +67 -8
- package/src/editor/index.ts +69 -0
- package/src/{lib → editor/overlay}/ColumnsOverlay.svelte +0 -1
- package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +80 -129
- package/src/{lib → editor/overlay}/columnsOverlay.ts +2 -2
- package/src/{pages → editor/pages}/ComponentEditorPage.svelte +12 -12
- package/src/{pages → editor/pages}/Editor.svelte +4 -4
- package/src/{pages → editor/pages}/EditorShell.svelte +18 -36
- package/src/{styles → editor/styles}/ui-editor.css +43 -22
- package/src/{styles → editor/styles}/ui-form-controls.css +23 -24
- package/src/{ui → editor/ui}/BezierCurveEditor.svelte +119 -68
- package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
- package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +7 -6
- package/src/editor/ui/FileLoadList.svelte +367 -0
- package/src/editor/ui/FilePill.svelte +80 -0
- package/src/editor/ui/FontStackEditor.svelte +499 -0
- package/src/editor/ui/GradientEditor.svelte +690 -0
- package/src/{ui → editor/ui}/GradientStopPicker.svelte +12 -4
- package/src/editor/ui/ManifestFileManager.svelte +438 -0
- package/src/{ui → editor/ui}/PaletteEditor.svelte +180 -673
- package/src/editor/ui/ProjectFontsSection.svelte +638 -0
- package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
- package/src/{ui → editor/ui}/TextTab.svelte +3 -3
- package/src/editor/ui/ThemeFileManager.svelte +783 -0
- package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
- package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -7
- package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +4 -1
- package/src/editor/ui/UIInfoPopover.svelte +243 -0
- package/src/editor/ui/UILetterSpacingSelector.svelte +65 -0
- package/src/{ui → editor/ui}/UILineHeightSelector.svelte +5 -5
- package/src/{ui → editor/ui}/UILinkToggle.svelte +2 -2
- package/src/{ui → editor/ui}/UIPaddingSelector.svelte +6 -6
- package/src/{ui → editor/ui}/UIPaletteSelector.svelte +57 -30
- package/src/editor/ui/UIPillButton.svelte +168 -0
- package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
- package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
- package/src/editor/ui/UISegmentedControl.svelte +114 -0
- package/src/editor/ui/UISquareButton.svelte +172 -0
- package/src/{ui → editor/ui}/UITokenSelector.svelte +14 -11
- package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
- package/src/{ui → editor/ui}/VariablesTab.svelte +46 -17
- package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
- package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +24 -47
- package/src/{ui → editor/ui}/palette/PaletteBase.svelte +11 -8
- package/src/{ui → editor/ui}/palette/paletteEditorState.ts +1 -1
- package/src/editor/ui/palette/paletteMath.ts +275 -0
- package/src/{ui → editor/ui}/sections/ColumnsSection.svelte +137 -18
- package/src/{ui → editor/ui}/sections/GradientsSection.svelte +8 -8
- package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +18 -18
- package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +23 -23
- package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
- package/src/{components → system/components}/Badge.svelte +0 -36
- package/src/{components → system/components}/Button.svelte +2 -2
- package/src/{components → system/components}/Card.svelte +34 -60
- package/src/{components → system/components}/CollapsibleSection.svelte +25 -2
- package/src/{components → system/components}/CornerBadge.svelte +8 -24
- package/src/{components → system/components}/Dialog.svelte +1 -1
- package/src/system/components/FloatingTokenTags.css +275 -0
- package/src/system/components/FloatingTokenTags.svelte +543 -0
- package/src/{components → system/components}/InlineEditActions.svelte +6 -4
- package/src/system/components/MenuSelect.svelte +229 -0
- package/src/{components → system/components}/Notification.svelte +8 -1
- package/src/{components → system/components}/ProgressBar.svelte +29 -11
- package/src/system/components/SectionDivider.svelte +560 -0
- package/src/{components → system/components}/SegmentedControl.svelte +49 -43
- package/src/{components → system/components}/TabBar.svelte +81 -65
- package/src/{components → system/components}/Table.svelte +17 -3
- package/src/{components → system/components}/Tooltip.svelte +6 -4
- package/src/system/styles/CONVENTIONS.md +178 -0
- package/src/system/styles/fonts.css +20 -0
- package/src/system/styles/tokens.css +601 -0
- package/src/system/styles/tokens.generated.css +544 -0
- package/src/component-editor/ImageEditor.svelte +0 -74
- package/src/component-editor/SectionDividerEditor.svelte +0 -265
- package/src/component-editor/scaffolding/DividerEditor.svelte +0 -94
- package/src/component-editor/scaffolding/GradientCard.svelte +0 -296
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +0 -62
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +0 -37
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +0 -61
- package/src/component-editor/scaffolding/StateBlock.svelte +0 -132
- package/src/component-editor/scaffolding/VariantGroup.svelte +0 -310
- package/src/components/SectionDivider.svelte +0 -483
- package/src/data/google-fonts.json +0 -75
- package/src/lib/index.ts +0 -68
- package/src/lib/presetService.ts +0 -214
- package/src/lib/productionPulse.ts +0 -32
- package/src/styles/fonts.css +0 -30
- package/src/styles/tokens.css +0 -1324
- package/src/ui/FontStackEditor.svelte +0 -361
- package/src/ui/GradientEditor.svelte +0 -470
- package/src/ui/PresetFileManager.svelte +0 -1116
- package/src/ui/ProjectFontsSection.svelte +0 -645
- package/src/ui/ThemeFileManager.svelte +0 -1020
- package/src/ui/UnsavedComponentsDialog.svelte +0 -315
- /package/src/{component-editor → editor/component-editor}/index.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/DemoHeader.svelte +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/componentSectionType.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/componentSources.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/defaultSections.ts +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/siblings.ts +0 -0
- /package/src/{lib → editor/core}/cssVarSync.ts +0 -0
- /package/src/{lib → editor/core/palettes}/oklch.ts +0 -0
- /package/src/{lib → editor/core/routing}/navLinkTypes.ts +0 -0
- /package/src/{lib → editor/core/routing}/parentRouteStore.ts +0 -0
- /package/src/{lib → editor/core/storage}/storage.ts +0 -0
- /package/src/{lib → editor/core/store}/editorConfig.ts +0 -0
- /package/src/{lib → editor/core/store}/editorConfigStore.ts +0 -0
- /package/src/{lib → editor/core/store}/editorKeybindings.ts +0 -0
- /package/src/{lib → editor/core/store}/editorViewStore.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-24-component-prefix-and-suffix-renames.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-24-legacy-keys-and-bg-to-canvas.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-04-27-segmentedcontrol-disabled-flatten.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-frame-and-cleanup.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-08-collapsiblesection-variant-namespace.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-10-sectiondivider-gradient-stops.ts +0 -0
- /package/src/{lib → editor/core/themes}/migrations/2026-05-13-primary-to-brand.ts +0 -0
- /package/src/{lib → editor/core/themes}/parsers/globalRootBlock.ts +0 -0
- /package/src/{lib → editor/core/themes}/slices/domainVars.ts +0 -0
- /package/src/{lib → editor/overlay}/overlayState.ts +0 -0
- /package/src/{pages → editor/pages}/ComponentEditorPage.svelte.d.ts +0 -0
- /package/src/{pages → editor/pages}/Editor.svelte.d.ts +0 -0
- /package/src/{ui → editor/ui}/Toggle.svelte +0 -0
- /package/src/{ui → editor/ui}/UIDialog.svelte +0 -0
- /package/src/{ui → editor/ui}/UIFontWeightSelector.svelte +0 -0
- /package/src/{ui → editor/ui}/UIOptionItem.svelte +0 -0
- /package/src/{ui → editor/ui}/UIOptionList.svelte +0 -0
- /package/src/{ui → editor/ui}/UIRadioGroup.svelte +0 -0
- /package/src/{lib → editor/ui}/copyPopover.ts +0 -0
- /package/src/{ui → editor/ui}/curveEngine.ts +0 -0
- /package/src/{ui → editor/ui}/index.ts +0 -0
- /package/src/{ui → editor/ui}/keepInViewport.ts +0 -0
- /package/src/{ui → editor/ui}/palette/ScaleCurveEditor.svelte +0 -0
- /package/src/{lib → editor/ui}/scrollSection.ts +0 -0
- /package/src/{ui → editor/ui}/sections/tokenScales.ts +0 -0
- /package/src/{ui → editor/ui}/variantScales.ts +0 -0
- /package/src/{assets → system/assets}/newspaper.webp +0 -0
- /package/src/{assets → system/assets}/offering.webp +0 -0
- /package/src/{components → system/components}/Callout.svelte +0 -0
- /package/src/{components → system/components}/Image.svelte +0 -0
- /package/src/{components → system/components}/RadioButton.svelte +0 -0
- /package/src/{components → system/components}/types.ts +0 -0
- /package/src/{styles → system/styles}/_padding.scss +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-italic-latin.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Fraunces/Fraunces-roman-latin.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin-ext.woff2 +0 -0
- /package/src/{styles → system/styles}/fonts/Manrope/Manrope-latin.woff2 +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source adapter for the visual gradient editor.
|
|
3
|
+
*
|
|
4
|
+
* `GradientEditor.svelte` was originally hard-wired to the theme-level
|
|
5
|
+
* gradient library (`state.gradients.tokens`). Components that own their
|
|
6
|
+
* own structured gradients (e.g. SectionDivider's per-variant slot) live
|
|
7
|
+
* in `state.components[...].aliases[...]` as a `kind: 'gradient'` ref.
|
|
8
|
+
*
|
|
9
|
+
* Wrapping both behind one source interface lets the editor read + write
|
|
10
|
+
* either backing store without leaking knowledge of which it's editing.
|
|
11
|
+
* The store-derived `current` field reactively exposes the current value;
|
|
12
|
+
* the mutator methods funnel each change through `mutate`, so undo /
|
|
13
|
+
* persistence still cover the edit identically to direct API calls.
|
|
14
|
+
*/
|
|
15
|
+
import { derived, get, type Readable } from 'svelte/store';
|
|
16
|
+
import { editorState } from './editorStore';
|
|
17
|
+
import type { GradientType, GradientTokenStop, GradientAliasValue, CssVarRef } from './editorTypes';
|
|
18
|
+
import {
|
|
19
|
+
setGradient,
|
|
20
|
+
setGradientType,
|
|
21
|
+
setGradientAngle,
|
|
22
|
+
setGradientCenterX,
|
|
23
|
+
setGradientAspect,
|
|
24
|
+
setGradientStop,
|
|
25
|
+
addGradientStop,
|
|
26
|
+
removeGradientStop,
|
|
27
|
+
} from '../themes/slices/gradients';
|
|
28
|
+
import { setComponentAlias } from '../themes/slices/components';
|
|
29
|
+
import { mutate } from './editorCore';
|
|
30
|
+
|
|
31
|
+
export interface GradientSourceSnapshot {
|
|
32
|
+
type: GradientType;
|
|
33
|
+
angle: number;
|
|
34
|
+
/** Horizontal center for radial gradients, 0–100. */
|
|
35
|
+
centerX?: number;
|
|
36
|
+
/** Per-axis stretch factors for the radial ellipse (1 = unscaled). */
|
|
37
|
+
aspectX?: number;
|
|
38
|
+
aspectY?: number;
|
|
39
|
+
stops: GradientTokenStop[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface GradientSource {
|
|
43
|
+
/** Reactive readable of the current gradient value (or undefined if missing). */
|
|
44
|
+
current: Readable<GradientSourceSnapshot | undefined>;
|
|
45
|
+
setAll(next: GradientSourceSnapshot): void;
|
|
46
|
+
setType(type: GradientType): void;
|
|
47
|
+
setAngle(angle: number): void;
|
|
48
|
+
setCenterX(centerX: number): void;
|
|
49
|
+
setAspect(aspect: { x: number; y: number }): void;
|
|
50
|
+
setStop(index: number, partial: Partial<GradientTokenStop>): void;
|
|
51
|
+
addStop(stop: GradientTokenStop): void;
|
|
52
|
+
removeStop(index: number): void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** Adapter for `--gradient-N` library tokens in `state.gradients.tokens`. */
|
|
56
|
+
export function themeGradientSource(variable: string): GradientSource {
|
|
57
|
+
const current = derived(editorState, ($s) => {
|
|
58
|
+
const t = $s.gradients.tokens.find((g) => g.variable === variable);
|
|
59
|
+
if (!t) return undefined;
|
|
60
|
+
return {
|
|
61
|
+
type: t.type,
|
|
62
|
+
angle: t.angle,
|
|
63
|
+
centerX: t.centerX,
|
|
64
|
+
aspectX: t.aspectX,
|
|
65
|
+
aspectY: t.aspectY,
|
|
66
|
+
stops: t.stops.map((s) => ({ ...s })),
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
current,
|
|
71
|
+
setAll: (next) => setGradient(variable, next),
|
|
72
|
+
setType: (t) => setGradientType(variable, t),
|
|
73
|
+
setAngle: (a) => setGradientAngle(variable, a),
|
|
74
|
+
setCenterX: (x) => setGradientCenterX(variable, x),
|
|
75
|
+
setAspect: (a) => setGradientAspect(variable, a),
|
|
76
|
+
setStop: (i, p) => setGradientStop(variable, i, p),
|
|
77
|
+
addStop: (s) => addGradientStop(variable, s),
|
|
78
|
+
removeStop: (i) => removeGradientStop(variable, i),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function readComponentGradient(component: string, varName: string): GradientAliasValue | undefined {
|
|
83
|
+
const ref = get(editorState).components[component]?.aliases[varName];
|
|
84
|
+
return ref?.kind === 'gradient' ? ref.value : undefined;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function writeComponentGradient(component: string, varName: string, value: GradientAliasValue): void {
|
|
88
|
+
const ref: CssVarRef = { kind: 'gradient', value };
|
|
89
|
+
setComponentAlias(component, varName, ref);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Adapter for component-owned gradients stored inline on a component alias. */
|
|
93
|
+
export function componentGradientSource(component: string, varName: string): GradientSource {
|
|
94
|
+
const current = derived(editorState, ($s) => {
|
|
95
|
+
const ref = $s.components[component]?.aliases[varName];
|
|
96
|
+
if (ref?.kind !== 'gradient') return undefined;
|
|
97
|
+
return {
|
|
98
|
+
type: ref.value.type,
|
|
99
|
+
angle: ref.value.angle,
|
|
100
|
+
centerX: ref.value.centerX,
|
|
101
|
+
aspectX: ref.value.aspectX,
|
|
102
|
+
aspectY: ref.value.aspectY,
|
|
103
|
+
stops: ref.value.stops.map((s) => ({ ...s })),
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
/** Read-modify-write through `mutate` so each edit is one history entry
|
|
107
|
+
* and the renderer + persistence cycle pick it up uniformly with the
|
|
108
|
+
* theme-gradient path. */
|
|
109
|
+
const update = (label: string, mutator: (g: GradientAliasValue) => void): void => {
|
|
110
|
+
mutate(label, (s) => {
|
|
111
|
+
const slice = s.components[component] ?? (s.components[component] = { activeFile: 'default', aliases: {}, config: {} });
|
|
112
|
+
const ref = slice.aliases[varName];
|
|
113
|
+
const base: GradientAliasValue =
|
|
114
|
+
ref?.kind === 'gradient'
|
|
115
|
+
? {
|
|
116
|
+
type: ref.value.type,
|
|
117
|
+
angle: ref.value.angle,
|
|
118
|
+
...(ref.value.centerX !== undefined ? { centerX: ref.value.centerX } : {}),
|
|
119
|
+
...(ref.value.aspectX !== undefined ? { aspectX: ref.value.aspectX } : {}),
|
|
120
|
+
...(ref.value.aspectY !== undefined ? { aspectY: ref.value.aspectY } : {}),
|
|
121
|
+
stops: ref.value.stops.map((st) => ({ ...st })),
|
|
122
|
+
}
|
|
123
|
+
: { type: 'linear', angle: 135, stops: [] };
|
|
124
|
+
mutator(base);
|
|
125
|
+
slice.aliases[varName] = { kind: 'gradient', value: base };
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
return {
|
|
129
|
+
current,
|
|
130
|
+
setAll: (next) => writeComponentGradient(component, varName, {
|
|
131
|
+
type: next.type,
|
|
132
|
+
angle: next.angle,
|
|
133
|
+
...(next.centerX !== undefined ? { centerX: next.centerX } : {}),
|
|
134
|
+
...(next.aspectX !== undefined ? { aspectX: next.aspectX } : {}),
|
|
135
|
+
...(next.aspectY !== undefined ? { aspectY: next.aspectY } : {}),
|
|
136
|
+
stops: next.stops.map((s) => ({ ...s })),
|
|
137
|
+
}),
|
|
138
|
+
setType: (t) => update(`set gradient type ${varName}`, (g) => { g.type = t; }),
|
|
139
|
+
setAngle: (a) => update(`set gradient angle ${varName}`, (g) => { g.angle = a; }),
|
|
140
|
+
setCenterX: (x) => update(`set gradient center ${varName}`, (g) => { g.centerX = x; }),
|
|
141
|
+
setAspect: (a) => update(`set gradient aspect ${varName}`, (g) => {
|
|
142
|
+
// Drop axes that equal 1 so persisted JSON stays minimal and pre-aspect
|
|
143
|
+
// data round-trips unchanged.
|
|
144
|
+
if (a.x === 1) delete g.aspectX;
|
|
145
|
+
else g.aspectX = a.x;
|
|
146
|
+
if (a.y === 1) delete g.aspectY;
|
|
147
|
+
else g.aspectY = a.y;
|
|
148
|
+
}),
|
|
149
|
+
setStop: (i, p) => update(`set gradient stop ${varName}[${i}]`, (g) => {
|
|
150
|
+
const stop = g.stops[i];
|
|
151
|
+
if (!stop) return;
|
|
152
|
+
if (p.position !== undefined) stop.position = p.position;
|
|
153
|
+
if (p.color !== undefined) stop.color = p.color;
|
|
154
|
+
if (p.opacity !== undefined) stop.opacity = p.opacity;
|
|
155
|
+
// `monochrome: true` is the implicit default — drop the field on write
|
|
156
|
+
// so the persisted shape stays minimal. Only the explicit override
|
|
157
|
+
// (`false`) needs to live on the stop.
|
|
158
|
+
if (p.monochrome !== undefined) {
|
|
159
|
+
if (p.monochrome === false) stop.monochrome = false;
|
|
160
|
+
else delete stop.monochrome;
|
|
161
|
+
}
|
|
162
|
+
}),
|
|
163
|
+
addStop: (s) => update(`add gradient stop ${varName}`, (g) => {
|
|
164
|
+
g.stops.push({ ...s });
|
|
165
|
+
g.stops.sort((a, b) => a.position - b.position);
|
|
166
|
+
}),
|
|
167
|
+
removeStop: (i) => update(`remove gradient stop ${varName}[${i}]`, (g) => {
|
|
168
|
+
if (g.stops.length <= 2) return;
|
|
169
|
+
g.stops.splice(i, 1);
|
|
170
|
+
}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Snapshot helper for save/cancel flows. */
|
|
175
|
+
export function snapshotGradient(source: GradientSource): GradientSourceSnapshot | null {
|
|
176
|
+
const cur = get(source.current);
|
|
177
|
+
if (!cur) return null;
|
|
178
|
+
return {
|
|
179
|
+
type: cur.type,
|
|
180
|
+
angle: cur.angle,
|
|
181
|
+
...(cur.centerX !== undefined ? { centerX: cur.centerX } : {}),
|
|
182
|
+
...(cur.aspectX !== undefined ? { aspectX: cur.aspectX } : {}),
|
|
183
|
+
...(cur.aspectY !== undefined ? { aspectY: cur.aspectY } : {}),
|
|
184
|
+
stops: cur.stops.map((s) => ({ ...s })),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/** Read the component-side current gradient value used to seed UI defaults
|
|
189
|
+
* outside the GradientSource flow (e.g. the Monochrome checkbox derivation). */
|
|
190
|
+
export function readComponentGradientSync(component: string, varName: string): GradientAliasValue | undefined {
|
|
191
|
+
return readComponentGradient(component, varName);
|
|
192
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Migration } from './index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* 2026-05-19: drop `--collapsiblesection-container-frame-surface`.
|
|
5
|
+
*
|
|
6
|
+
* The frame-surface token only ever painted the outer `.es-root` background.
|
|
7
|
+
* Since `.section-header` covers that area with its own per-state surface, the
|
|
8
|
+
* frame-surface was only visible where the (typically transparent) frame
|
|
9
|
+
* border zone exposed it — a ring around the header. That made the token
|
|
10
|
+
* read as a "border" while being labeled "surface color" in the editor.
|
|
11
|
+
*
|
|
12
|
+
* Frame is now pure chrome: border color, border width, corner radius. The
|
|
13
|
+
* per-state header surface tokens already cover all the legitimate surface
|
|
14
|
+
* needs of the Container variant.
|
|
15
|
+
*/
|
|
16
|
+
function dropFrameSurface(rawVars: Record<string, string>, meta: { component?: string }): Record<string, string> {
|
|
17
|
+
if (meta.component !== 'collapsiblesection') return rawVars;
|
|
18
|
+
const { '--collapsiblesection-container-frame-surface': _drop, ...rest } = rawVars;
|
|
19
|
+
return rest;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const componentMigration_2026_05_19_collapsiblesectionDropFrameSurface: Migration = {
|
|
23
|
+
id: '2026-05-19-collapsiblesection-drop-frame-surface',
|
|
24
|
+
fromVersion: 6,
|
|
25
|
+
toVersion: 7,
|
|
26
|
+
appliesTo: 'component-config',
|
|
27
|
+
apply: dropFrameSurface,
|
|
28
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Migration } from './index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Component-config migration (2026-05-19, sectiondivider only):
|
|
5
|
+
* the per-variant gradient was 7 flat tokens (angle + 3× (color + position)).
|
|
6
|
+
* It now lives as a single structured alias at `--sectiondivider-{v}-gradient`,
|
|
7
|
+
* carrying `{type, angle, stops[]}` inline on the component slice.
|
|
8
|
+
*
|
|
9
|
+
* The structured value is synthesized *before* this migration runs — see
|
|
10
|
+
* `synthesizeSectionDividerGradients` in `editorStore.ts`. The synthesizer
|
|
11
|
+
* walks the legacy 7-token shape and emits a `kind: 'gradient'` alias into
|
|
12
|
+
* the load path's object subset, where it survives this stripping pass and
|
|
13
|
+
* lands in the in-memory slice.
|
|
14
|
+
*
|
|
15
|
+
* This migration's only job is to delete the now-redundant flat tokens
|
|
16
|
+
* from the disk-shape string subset so a subsequent save round-trips to
|
|
17
|
+
* the new format.
|
|
18
|
+
*/
|
|
19
|
+
const FLAT_RE = /^--sectiondivider-(canvas|neutral|alternate|primary|accent|special)-gradient-(angle|stop-[123]-(color|position))$/;
|
|
20
|
+
|
|
21
|
+
export const componentMigration_2026_05_19_sectiondividerRichGradient: Migration = {
|
|
22
|
+
id: '2026-05-19-sectiondivider-rich-gradient',
|
|
23
|
+
fromVersion: 7,
|
|
24
|
+
toVersion: 8,
|
|
25
|
+
appliesTo: 'component-config',
|
|
26
|
+
apply(rawVars, meta) {
|
|
27
|
+
if (meta.component !== 'sectiondivider') return { ...rawVars };
|
|
28
|
+
const out: Record<string, string> = {};
|
|
29
|
+
for (const [key, value] of Object.entries(rawVars)) {
|
|
30
|
+
if (FLAT_RE.test(key)) continue;
|
|
31
|
+
out[key] = value;
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
},
|
|
35
|
+
};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Migration } from './index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Component-config migration (2026-05-20, sectiondivider only):
|
|
5
|
+
* the variant axis was reshaped from six color families →
|
|
6
|
+
* three size presets (lg/md/sm). Each new variant owns its full token set
|
|
7
|
+
* (typography, geometry, AND colors / background) so the editor can author
|
|
8
|
+
* full visual presets per-variant without a separate color axis.
|
|
9
|
+
*
|
|
10
|
+
* Migration strategy: take **canvas** as the canonical family from the v8
|
|
11
|
+
* file and seed all three new variants from its values. Customisations on
|
|
12
|
+
* other v8 families (neutral, accent, primary, etc.) are dropped — the user
|
|
13
|
+
* customises each new variant from the shared canvas baseline.
|
|
14
|
+
*
|
|
15
|
+
* Two inline suffix renames also land here:
|
|
16
|
+
* `*-title-border-width` → `*-title-outline-width`
|
|
17
|
+
* `*-title-stroke-color` → `*-title-outline-color`
|
|
18
|
+
* `*-padding` → `*-spacing`
|
|
19
|
+
*
|
|
20
|
+
* The structured background payload moves through a companion rename in
|
|
21
|
+
* `migrateComponentAliases` (editorStore.ts), since the runner only sees
|
|
22
|
+
* string keys.
|
|
23
|
+
*/
|
|
24
|
+
const FAMILIES = ['canvas', 'neutral', 'alternate', 'primary', 'accent', 'special'] as const;
|
|
25
|
+
type Family = typeof FAMILIES[number];
|
|
26
|
+
const VARIANTS = ['lg', 'md', 'sm'] as const;
|
|
27
|
+
|
|
28
|
+
const SUFFIX_RENAMES: Array<[RegExp, string]> = [
|
|
29
|
+
[/-title-border-width$/, '-title-outline-width'],
|
|
30
|
+
[/-title-stroke-color$/, '-title-outline-color'],
|
|
31
|
+
[/-padding$/, '-spacing'],
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
function renameKeySuffix(key: string): string {
|
|
35
|
+
for (const [re, repl] of SUFFIX_RENAMES) {
|
|
36
|
+
if (re.test(key)) return key.replace(re, repl);
|
|
37
|
+
}
|
|
38
|
+
return key;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function splitFamilyKey(key: string): { family: Family; suffix: string } | null {
|
|
42
|
+
const m = key.match(/^--sectiondivider-(canvas|neutral|alternate|primary|accent|special)-(.+)$/);
|
|
43
|
+
if (!m) return null;
|
|
44
|
+
return { family: m[1] as Family, suffix: m[2] };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const componentMigration_2026_05_20_sectiondividerSlimVariants: Migration = {
|
|
48
|
+
id: '2026-05-20-sectiondivider-slim-variants',
|
|
49
|
+
fromVersion: 8,
|
|
50
|
+
toVersion: 9,
|
|
51
|
+
appliesTo: 'component-config',
|
|
52
|
+
apply(rawVars, meta) {
|
|
53
|
+
if (meta.component !== 'sectiondivider') return { ...rawVars };
|
|
54
|
+
const out: Record<string, string> = {};
|
|
55
|
+
|
|
56
|
+
// Collect canvas's suffix → value mapping first; everything else gets
|
|
57
|
+
// pruned. (Canvas wins; other families' customisations are discarded
|
|
58
|
+
// because the new variants are size/preset-shaped, not color-shaped.)
|
|
59
|
+
const canvasValues: Record<string, string> = {};
|
|
60
|
+
|
|
61
|
+
for (const [rawKey, value] of Object.entries(rawVars)) {
|
|
62
|
+
const key = renameKeySuffix(rawKey);
|
|
63
|
+
const parts = splitFamilyKey(key);
|
|
64
|
+
if (!parts) {
|
|
65
|
+
// Non-family-prefixed key — pass through verbatim.
|
|
66
|
+
out[key] = value;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (parts.family !== 'canvas') continue; // Drop non-canvas tokens
|
|
70
|
+
canvasValues[parts.suffix] = value;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Seed all three size variants from canvas's values.
|
|
74
|
+
for (const suffix of Object.keys(canvasValues)) {
|
|
75
|
+
for (const v of VARIANTS) {
|
|
76
|
+
out[`--sectiondivider-${v}-${suffix}`] = canvasValues[suffix];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return out;
|
|
81
|
+
},
|
|
82
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Migration } from './index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Component-config migration (2026-05-21, sectiondivider only):
|
|
5
|
+
* the container `*-spacing` token is renamed back to `*-padding` so it can
|
|
6
|
+
* use the editor's splittable padding selector (per-side control). The new
|
|
7
|
+
* editor also adds per-element padding tokens (title / description / eyebrow),
|
|
8
|
+
* but those have no v9 predecessor — they simply start unset.
|
|
9
|
+
*/
|
|
10
|
+
export const componentMigration_2026_05_21_sectiondividerSpacingToPadding: Migration = {
|
|
11
|
+
id: '2026-05-21-sectiondivider-spacing-to-padding',
|
|
12
|
+
fromVersion: 9,
|
|
13
|
+
toVersion: 10,
|
|
14
|
+
appliesTo: 'component-config',
|
|
15
|
+
apply(rawVars, meta) {
|
|
16
|
+
if (meta.component !== 'sectiondivider') return { ...rawVars };
|
|
17
|
+
const out: Record<string, string> = {};
|
|
18
|
+
for (const [key, value] of Object.entries(rawVars)) {
|
|
19
|
+
const renamed = key.replace(/-spacing$/, '-padding');
|
|
20
|
+
out[renamed] = value;
|
|
21
|
+
}
|
|
22
|
+
return out;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { Migration } from './index';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Component-config migration (2026-05-22, sectiondivider only):
|
|
5
|
+
* the per-variant *intrinsics* (align, hairline visibility + position, eyebrow
|
|
6
|
+
* visibility + uppercase, description visibility) move from the `config`
|
|
7
|
+
* bucket — where the editor preview consumed them as runtime props — into
|
|
8
|
+
* the `aliases` bucket as cascading CSS variables. Live consumers can then
|
|
9
|
+
* read them off `:root` via `var(...)`, closing the editor-to-consumer sync
|
|
10
|
+
* gap the old config-bucket encoding had.
|
|
11
|
+
*
|
|
12
|
+
* Mapping per variant `v in (lg, md, sm)`:
|
|
13
|
+
* --sectiondivider-{v}-show-eyebrow ('1' | '') → --sectiondivider-{v}-eyebrow-display ('block' | 'none')
|
|
14
|
+
* --sectiondivider-{v}-show-description ('1' | '') → --sectiondivider-{v}-description-display ('flex' | 'none')
|
|
15
|
+
* --sectiondivider-{v}-show-hairline + -hairline (toggle + pos) → --sectiondivider-{v}-hairline ('none' | <position>)
|
|
16
|
+
* --sectiondivider-{v}-eyebrow-uppercase ('1' | '') → --sectiondivider-{v}-eyebrow-text-transform ('uppercase' | 'none')
|
|
17
|
+
* --sectiondivider-{v}-align → unchanged (value space is already CSS-keyword: 'start' | 'center')
|
|
18
|
+
* --sectiondivider-{v}-color-family → unchanged (still a config-bucket entry; drives editor's family swap)
|
|
19
|
+
*
|
|
20
|
+
* The hairline merge collapses two old keys (a boolean toggle + a position
|
|
21
|
+
* enum) into one. Rules (matching the legacy `getShowHairline` reader):
|
|
22
|
+
* - `show-hairline` explicitly '' → 'none'
|
|
23
|
+
* - `show-hairline` explicitly '1' → existing position, or 'above-label' fallback
|
|
24
|
+
* - both undefined → emit nothing (default 'none' applies via CSS)
|
|
25
|
+
* - `show-hairline` unset but a real position exists → preserve the position
|
|
26
|
+
*
|
|
27
|
+
* The migration touches the unified bag produced by `migrateComponentAliases`
|
|
28
|
+
* (which now pre-merges string-valued config entries). The post-migration
|
|
29
|
+
* `splitAliasesAndConfig` step routes the new keys to `aliases` (since
|
|
30
|
+
* `KNOWN_COMPONENT_CONFIG_KEYS` no longer contains them) while keeping
|
|
31
|
+
* `--sectiondivider-{v}-color-family` in `config`.
|
|
32
|
+
*/
|
|
33
|
+
export const componentMigration_2026_05_22_sectiondividerIntrinsicsToCss: Migration = {
|
|
34
|
+
id: '2026-05-22-sectiondivider-intrinsics-to-css',
|
|
35
|
+
fromVersion: 10,
|
|
36
|
+
toVersion: 11,
|
|
37
|
+
appliesTo: 'component-config',
|
|
38
|
+
apply(rawVars, meta) {
|
|
39
|
+
if (meta.component !== 'sectiondivider') return { ...rawVars };
|
|
40
|
+
const VARIANTS = ['lg', 'md', 'sm'] as const;
|
|
41
|
+
const prefix = '--sectiondivider-';
|
|
42
|
+
const dropped = new Set<string>();
|
|
43
|
+
for (const v of VARIANTS) {
|
|
44
|
+
dropped.add(`${prefix}${v}-show-eyebrow`);
|
|
45
|
+
dropped.add(`${prefix}${v}-show-description`);
|
|
46
|
+
dropped.add(`${prefix}${v}-show-hairline`);
|
|
47
|
+
dropped.add(`${prefix}${v}-hairline`);
|
|
48
|
+
dropped.add(`${prefix}${v}-eyebrow-uppercase`);
|
|
49
|
+
}
|
|
50
|
+
const out: Record<string, string> = {};
|
|
51
|
+
for (const [key, value] of Object.entries(rawVars)) {
|
|
52
|
+
if (dropped.has(key)) continue;
|
|
53
|
+
out[key] = value;
|
|
54
|
+
}
|
|
55
|
+
for (const v of VARIANTS) {
|
|
56
|
+
const showEyebrow = rawVars[`${prefix}${v}-show-eyebrow`];
|
|
57
|
+
if (showEyebrow !== undefined) {
|
|
58
|
+
out[`${prefix}${v}-eyebrow-display`] = showEyebrow === '1' ? 'block' : 'none';
|
|
59
|
+
}
|
|
60
|
+
const showDesc = rawVars[`${prefix}${v}-show-description`];
|
|
61
|
+
if (showDesc !== undefined) {
|
|
62
|
+
out[`${prefix}${v}-description-display`] = showDesc === '1' ? 'flex' : 'none';
|
|
63
|
+
}
|
|
64
|
+
const showHair = rawVars[`${prefix}${v}-show-hairline`];
|
|
65
|
+
const oldHair = rawVars[`${prefix}${v}-hairline`];
|
|
66
|
+
const oldHairIsPos = typeof oldHair === 'string' && oldHair !== '' && oldHair !== 'off';
|
|
67
|
+
let newHair: string | undefined;
|
|
68
|
+
if (showHair === '') newHair = 'none';
|
|
69
|
+
else if (showHair === '1') newHair = oldHairIsPos ? oldHair : 'above-label';
|
|
70
|
+
else if (oldHair !== undefined) newHair = oldHairIsPos ? oldHair : 'none';
|
|
71
|
+
if (newHair !== undefined) {
|
|
72
|
+
out[`${prefix}${v}-hairline`] = newHair;
|
|
73
|
+
}
|
|
74
|
+
const upper = rawVars[`${prefix}${v}-eyebrow-uppercase`];
|
|
75
|
+
if (upper !== undefined) {
|
|
76
|
+
out[`${prefix}${v}-eyebrow-text-transform`] = upper === '1' ? 'uppercase' : 'none';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
@@ -40,6 +40,11 @@ import {
|
|
|
40
40
|
themeMigration_2026_05_13_primaryToBrand,
|
|
41
41
|
componentMigration_2026_05_13_primaryToBrand,
|
|
42
42
|
} from './2026-05-13-primary-to-brand';
|
|
43
|
+
import { componentMigration_2026_05_19_collapsiblesectionDropFrameSurface } from './2026-05-19-collapsiblesection-drop-frame-surface';
|
|
44
|
+
import { componentMigration_2026_05_19_sectiondividerRichGradient } from './2026-05-19-sectiondivider-rich-gradient';
|
|
45
|
+
import { componentMigration_2026_05_20_sectiondividerSlimVariants } from './2026-05-20-sectiondivider-slim-variants';
|
|
46
|
+
import { componentMigration_2026_05_21_sectiondividerSpacingToPadding } from './2026-05-21-sectiondivider-spacing-to-padding';
|
|
47
|
+
import { componentMigration_2026_05_22_sectiondividerIntrinsicsToCss } from './2026-05-22-sectiondivider-intrinsics-to-css';
|
|
43
48
|
|
|
44
49
|
/**
|
|
45
50
|
* Registered migrations. Order in this array does not matter — the runner
|
|
@@ -54,6 +59,11 @@ export const MIGRATIONS: Migration[] = [
|
|
|
54
59
|
componentMigration_2026_05_08_collapsiblesectionFrameAndCleanup,
|
|
55
60
|
componentMigration_2026_05_10_sectiondividerGradientStops,
|
|
56
61
|
componentMigration_2026_05_13_primaryToBrand,
|
|
62
|
+
componentMigration_2026_05_19_collapsiblesectionDropFrameSurface,
|
|
63
|
+
componentMigration_2026_05_19_sectiondividerRichGradient,
|
|
64
|
+
componentMigration_2026_05_20_sectiondividerSlimVariants,
|
|
65
|
+
componentMigration_2026_05_21_sectiondividerSpacingToPadding,
|
|
66
|
+
componentMigration_2026_05_22_sectiondividerIntrinsicsToCss,
|
|
57
67
|
];
|
|
58
68
|
|
|
59
69
|
function countFor(kind: 'theme' | 'component-config'): number {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* the default we leave tokens.css in charge so the `clamp()` in
|
|
5
5
|
* `--columns-gutter` survives until the editor overrides it.
|
|
6
6
|
*/
|
|
7
|
-
import type { ColumnsState } from '
|
|
7
|
+
import type { ColumnsState } from '../../store/editorTypes';
|
|
8
8
|
|
|
9
9
|
export const DEFAULT_COLUMNS: ColumnsState = { count: 12, maxWidth: 1440, gutter: 16, margin: 0 };
|
|
10
10
|
|
|
@@ -50,7 +50,7 @@ export function parseColumnVars(vars: Record<string, string>): Partial<ColumnsSt
|
|
|
50
50
|
* single-source. Mutates `next` and `rawVars` in place.
|
|
51
51
|
*/
|
|
52
52
|
export function loadColumnsFromVars(
|
|
53
|
-
next: import('
|
|
53
|
+
next: import('../../store/editorTypes').EditorState,
|
|
54
54
|
rawVars: Record<string, string>,
|
|
55
55
|
): void {
|
|
56
56
|
const overrides = parseColumnVars(rawVars);
|
|
@@ -30,8 +30,9 @@
|
|
|
30
30
|
* pipeline.
|
|
31
31
|
*/
|
|
32
32
|
import { writable, derived, get, type Readable } from 'svelte/store';
|
|
33
|
-
import type { CssVarRef, EditorState } from '
|
|
34
|
-
import { store, mutate } from '
|
|
33
|
+
import type { CssVarRef, EditorState } from '../../store/editorTypes';
|
|
34
|
+
import { store, mutate } from '../../store/editorCore';
|
|
35
|
+
import { formatGradientValue } from './gradients';
|
|
35
36
|
|
|
36
37
|
const EMPTY_COMPONENT_BASELINE = JSON.stringify({ aliases: {}, config: {} });
|
|
37
38
|
|
|
@@ -43,7 +44,9 @@ export function componentsToVars(components: EditorState['components']): Record<
|
|
|
43
44
|
const out: Record<string, string> = {};
|
|
44
45
|
for (const slice of Object.values(components)) {
|
|
45
46
|
for (const [varName, ref] of Object.entries(slice.aliases)) {
|
|
46
|
-
|
|
47
|
+
if (ref.kind === 'token') out[varName] = `var(${ref.name})`;
|
|
48
|
+
else if (ref.kind === 'literal') out[varName] = ref.value;
|
|
49
|
+
else out[varName] = formatGradientValue(ref.value);
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
return out;
|
|
@@ -239,9 +242,20 @@ export function getComponentPropertySiblings(component: string, varName: string)
|
|
|
239
242
|
function cssVarRefEqual(a: CssVarRef | undefined, b: CssVarRef | undefined): boolean {
|
|
240
243
|
if (!a || !b) return a === b;
|
|
241
244
|
if (a.kind !== b.kind) return false;
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
+
if (a.kind === 'token') return a.name === (b as { kind: 'token'; name: string }).name;
|
|
246
|
+
if (a.kind === 'literal') return a.value === (b as { kind: 'literal'; value: string }).value;
|
|
247
|
+
// gradient: structural compare on type, angle, aspect axes, and stops.
|
|
248
|
+
const av = a.value;
|
|
249
|
+
const bv = (b as { kind: 'gradient'; value: typeof a.value }).value;
|
|
250
|
+
if (av.type !== bv.type || av.angle !== bv.angle || av.stops.length !== bv.stops.length) return false;
|
|
251
|
+
if ((av.aspectX ?? 1) !== (bv.aspectX ?? 1)) return false;
|
|
252
|
+
if ((av.aspectY ?? 1) !== (bv.aspectY ?? 1)) return false;
|
|
253
|
+
for (let i = 0; i < av.stops.length; i++) {
|
|
254
|
+
const sa = av.stops[i];
|
|
255
|
+
const sb = bv.stops[i];
|
|
256
|
+
if (sa.position !== sb.position || sa.color !== sb.color || (sa.opacity ?? 100) !== (sb.opacity ?? 100)) return false;
|
|
257
|
+
}
|
|
258
|
+
return true;
|
|
245
259
|
}
|
|
246
260
|
|
|
247
261
|
/** True iff `varName` is not individually opted out, has ≥2 declared siblings,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* after mutating.
|
|
7
7
|
*/
|
|
8
8
|
import type { FontSource, FontStack } from '../themeTypes';
|
|
9
|
-
import { store, mutate, persist } from '
|
|
9
|
+
import { store, mutate, persist } from '../../store/editorCore';
|
|
10
10
|
|
|
11
11
|
export function setFontSources(sources: FontSource[]): void {
|
|
12
12
|
mutate('update font sources', (s) => { s.fonts.sources = sources; });
|