@motion-proto/live-tokens 0.6.1 → 0.7.1
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 +149 -136
- package/dist-plugin/index.d.cts +1 -1
- package/dist-plugin/index.d.ts +1 -1
- package/dist-plugin/index.js +147 -135
- package/package.json +26 -41
- 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 +3 -3
- 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 +64 -37
- package/src/{component-editor → editor/component-editor}/ProgressBarEditor.svelte +5 -4
- package/src/{component-editor → editor/component-editor}/RadioButtonEditor.svelte +3 -3
- package/src/{component-editor → editor/component-editor}/SectionDividerEditor.svelte +57 -84
- package/src/{component-editor → editor/component-editor}/SegmentedControlEditor.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/StandardButtonsEditor.svelte +16 -20
- 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/{component-editor → editor/component-editor}/registry.ts +28 -18
- package/src/{component-editor → editor/component-editor}/scaffolding/AngleDial.svelte +2 -2
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentEditorBase.svelte +3 -51
- package/src/{component-editor → editor/component-editor}/scaffolding/ComponentFileManager.svelte +144 -416
- 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/DividerEditor.svelte +1 -1
- package/src/{component-editor → editor/component-editor}/scaffolding/FieldsetWrapper.svelte +1 -1
- package/src/{component-editor → editor/component-editor}/scaffolding/GradientCard.svelte +6 -6
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkageChart.svelte +6 -6
- package/src/{component-editor → editor/component-editor}/scaffolding/LinkedBlock.svelte +6 -11
- package/src/editor/component-editor/scaffolding/NonStylableConfig.svelte +38 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/SaveAsDialog.svelte +66 -12
- package/src/editor/component-editor/scaffolding/ShadowBackdrop.svelte +72 -0
- package/src/editor/component-editor/scaffolding/ShadowBackdropControls.svelte +132 -0
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +257 -0
- package/src/{component-editor → editor/component-editor}/scaffolding/TokenLayout.svelte +9 -7
- package/src/editor/component-editor/scaffolding/VariantGroup.svelte +644 -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 +14 -0
- package/src/{lib → editor/core/components}/componentConfigService.ts +2 -2
- package/src/{lib → editor/core/components}/componentPersist.ts +5 -5
- 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 +116 -0
- package/src/{lib → editor/core/palettes}/paletteDerivation.ts +2 -2
- package/src/{lib → editor/core/palettes}/tokenRegistry.ts +5 -5
- 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 +17 -17
- package/src/{lib → editor/core/store}/editorTypes.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/columns.ts +2 -2
- package/src/{lib → editor/core/themes}/slices/components.ts +2 -2
- package/src/{lib → editor/core/themes}/slices/fonts.ts +1 -1
- package/src/{lib → editor/core/themes}/slices/gradients.ts +2 -2
- 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 +6 -6
- package/src/{lib → editor/core/themes}/themeService.ts +6 -6
- package/src/{lib → editor/core/themes}/themeTypes.ts +11 -7
- package/src/editor/index.ts +69 -0
- package/src/{lib → editor/overlay}/LiveEditorOverlay.svelte +79 -125
- 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 +41 -21
- package/src/{styles → editor/styles}/ui-form-controls.css +8 -8
- package/src/{ui → editor/ui}/BezierCurveEditor.svelte +8 -8
- package/src/{ui → editor/ui}/ColorEditPanel.svelte +13 -13
- package/src/{ui → editor/ui}/EditorViewSwitcher.svelte +8 -6
- package/src/editor/ui/FileLoadList.svelte +350 -0
- package/src/editor/ui/FilePill.svelte +80 -0
- package/src/{ui → editor/ui}/FontStackEditor.svelte +7 -7
- package/src/{ui → editor/ui}/GradientEditor.svelte +11 -11
- package/src/{ui → editor/ui}/GradientStopPicker.svelte +1 -1
- package/src/editor/ui/ManifestFileManager.svelte +371 -0
- package/src/{ui → editor/ui}/PaletteEditor.svelte +132 -598
- package/src/{ui → editor/ui}/ProjectFontsSection.svelte +102 -144
- package/src/{ui → editor/ui}/SurfacesTab.svelte +3 -3
- package/src/{ui → editor/ui}/TextTab.svelte +3 -3
- package/src/{ui → editor/ui}/ThemeFileManager.svelte +286 -519
- package/src/{ui → editor/ui}/UICopyPopover.svelte +4 -4
- package/src/{ui → editor/ui}/UIFontFamilySelector.svelte +6 -6
- package/src/{ui → editor/ui}/UIFontSizeSelector.svelte +1 -1
- package/src/editor/ui/UIInfoPopover.svelte +244 -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 +26 -26
- package/src/editor/ui/UIPillButton.svelte +138 -0
- package/src/{ui → editor/ui}/UIRadio.svelte +2 -2
- package/src/{ui → editor/ui}/UIRelinkConfirmPopover.svelte +4 -4
- package/src/editor/ui/UISquareButton.svelte +172 -0
- package/src/{ui → editor/ui}/UITokenSelector.svelte +10 -10
- package/src/{ui → editor/ui}/UIVariantSelector.svelte +1 -1
- package/src/{ui → editor/ui}/VariablesTab.svelte +31 -8
- package/src/{ui → editor/ui}/palette/GradientStopEditor.svelte +13 -13
- package/src/{ui → editor/ui}/palette/OverridesPanel.svelte +13 -13
- package/src/{ui → editor/ui}/palette/PaletteBase.svelte +8 -5
- 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 -17
- package/src/{ui → editor/ui}/sections/GradientsSection.svelte +7 -7
- package/src/{ui → editor/ui}/sections/OverlaysSection.svelte +17 -17
- package/src/{ui → editor/ui}/sections/ShadowsSection.svelte +22 -22
- package/src/{ui → editor/ui}/sections/TokenScaleTable.svelte +3 -3
- package/src/{components → system/components}/Badge.svelte +0 -36
- package/src/{components → system/components}/Card.svelte +8 -62
- package/src/{components → system/components}/CornerBadge.svelte +8 -24
- package/src/{components → system/components}/Dialog.svelte +1 -1
- package/src/system/components/FloatingTokenTags.css +256 -0
- package/src/system/components/FloatingTokenTags.svelte +592 -0
- package/src/{components → system/components}/InlineEditActions.svelte +6 -4
- package/src/system/components/MenuSelect.svelte +229 -0
- package/src/{components → system/components}/ProgressBar.svelte +29 -11
- 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/{styles → system/styles}/fonts.css +6 -3
- package/src/{styles → system/styles}/tokens.css +149 -29
- package/src/component-editor/ImageEditor.svelte +0 -74
- 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/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/ui/PresetFileManager.svelte +0 -1116
- package/src/ui/UnsavedComponentsDialog.svelte +0 -315
- /package/src/{styles → app}/site.css +0 -0
- /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/TypeEditor.svelte +0 -0
- /package/src/{component-editor → editor/component-editor}/scaffolding/buildTypeGroupTokens.ts +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/components}/componentConfigKeys.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}/migrations/index.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}/ColumnsOverlay.svelte +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}/Button.svelte +0 -0
- /package/src/{components → system/components}/Callout.svelte +0 -0
- /package/src/{components → system/components}/CollapsibleSection.svelte +0 -0
- /package/src/{components → system/components}/Image.svelte +0 -0
- /package/src/{components → system/components}/Notification.svelte +0 -0
- /package/src/{components → system/components}/RadioButton.svelte +0 -0
- /package/src/{components → system/components}/SectionDivider.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
package/src/lib/index.ts
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
export { default as LiveEditorOverlay } from './LiveEditorOverlay.svelte';
|
|
2
|
-
export type { NavLink } from './navLinkTypes';
|
|
3
|
-
export { default as ColumnsOverlay } from './ColumnsOverlay.svelte';
|
|
4
|
-
|
|
5
|
-
export { columnsVisible, toggleColumns, init as initColumnsOverlay } from './columnsOverlay';
|
|
6
|
-
export { configureEditor, storageKey } from './editorConfig';
|
|
7
|
-
export { activeFileName } from './editorConfigStore';
|
|
8
|
-
export { init as initRouter, route, navigate } from './router';
|
|
9
|
-
export { init as initCssVarSync } from './cssVarSync';
|
|
10
|
-
export { init as initEditorStore } from './editorStore';
|
|
11
|
-
|
|
12
|
-
export { setCssVar, removeCssVar } from './cssVarSync';
|
|
13
|
-
|
|
14
|
-
export {
|
|
15
|
-
listThemes,
|
|
16
|
-
loadTheme,
|
|
17
|
-
saveTheme,
|
|
18
|
-
deleteTheme,
|
|
19
|
-
getActiveTheme,
|
|
20
|
-
setActiveFile,
|
|
21
|
-
getProductionInfo,
|
|
22
|
-
setProductionFile,
|
|
23
|
-
sanitizeFileName,
|
|
24
|
-
} from './themeService';
|
|
25
|
-
export type { ProductionInfo } from './themeService';
|
|
26
|
-
|
|
27
|
-
export type {
|
|
28
|
-
PaletteConfig,
|
|
29
|
-
Theme,
|
|
30
|
-
ThemeMeta,
|
|
31
|
-
GradientStyle,
|
|
32
|
-
GradientStop,
|
|
33
|
-
FontSource,
|
|
34
|
-
FontSourceKind,
|
|
35
|
-
FontFamily,
|
|
36
|
-
FontStack,
|
|
37
|
-
FontStackSlot,
|
|
38
|
-
FontStackVariable,
|
|
39
|
-
SystemCascadePreset,
|
|
40
|
-
GenericFamily,
|
|
41
|
-
Preset,
|
|
42
|
-
PresetMeta,
|
|
43
|
-
} from './themeTypes';
|
|
44
|
-
|
|
45
|
-
export {
|
|
46
|
-
listPresets,
|
|
47
|
-
loadPreset,
|
|
48
|
-
savePreset,
|
|
49
|
-
deletePreset,
|
|
50
|
-
getActivePreset,
|
|
51
|
-
setActivePreset,
|
|
52
|
-
applyPreset,
|
|
53
|
-
captureCurrentAsPreset,
|
|
54
|
-
} from './presetService';
|
|
55
|
-
export type { ApplyPresetResult } from './presetService';
|
|
56
|
-
|
|
57
|
-
export {
|
|
58
|
-
applyFontSources,
|
|
59
|
-
applyFontStacks,
|
|
60
|
-
resolveFontStackValues,
|
|
61
|
-
SYSTEM_CASCADES,
|
|
62
|
-
} from './fontLoader';
|
|
63
|
-
export { migrateThemeFonts, defaultFontSources, defaultFontStacks } from './fontMigration';
|
|
64
|
-
|
|
65
|
-
export { hexToOklch, oklchToHex, gamutClamp } from './oklch';
|
|
66
|
-
export type { Oklch } from './oklch';
|
|
67
|
-
|
|
68
|
-
export { initializeTheme } from './themeInit';
|
package/src/lib/presetService.ts
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
import type { Preset, PresetMeta, Theme, ComponentConfig } from './themeTypes';
|
|
2
|
-
import { versionedFileResource } from './files/versionedFileResource';
|
|
3
|
-
import { listComponents } from './componentConfigService';
|
|
4
|
-
import { getActiveTheme, getProductionInfo } from './themeService';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* REST client for preset (bundle) manifest files. Each preset file references
|
|
8
|
-
* a theme file basename + a per-component config file basename. Loading a
|
|
9
|
-
* preset flips the corresponding `_active.json` pointers via `applyPreset`,
|
|
10
|
-
* leaving the underlying theme + component-config files as the source of
|
|
11
|
-
* truth.
|
|
12
|
-
*
|
|
13
|
-
* Mirrors the lifecycle of `themeService.ts` and `componentConfigService.ts`
|
|
14
|
-
* but adds one custom route — `PUT /api/presets/:name/apply` — that the
|
|
15
|
-
* server uses to atomically validate every reference and flip every pointer
|
|
16
|
-
* in one shot.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const presetsResource = versionedFileResource<Preset, PresetMeta, never>({
|
|
20
|
-
baseUrl: '/api/presets',
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
export const listPresets = async (): Promise<PresetMeta[]> => {
|
|
24
|
-
const data = await presetsResource.list();
|
|
25
|
-
return data.files;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export const loadPreset = (fileName: string): Promise<Preset> =>
|
|
29
|
-
presetsResource.load(fileName);
|
|
30
|
-
export const savePreset = (fileName: string, data: Preset): Promise<void> =>
|
|
31
|
-
presetsResource.save(fileName, data);
|
|
32
|
-
export const deletePreset = (fileName: string): Promise<void> =>
|
|
33
|
-
presetsResource.remove(fileName);
|
|
34
|
-
export const getActivePreset = (): Promise<Preset | null> => presetsResource.getActive();
|
|
35
|
-
export const setActivePreset = (fileName: string): Promise<void> =>
|
|
36
|
-
presetsResource.setActive(fileName);
|
|
37
|
-
|
|
38
|
-
export interface ApplyPresetResult {
|
|
39
|
-
ok: boolean;
|
|
40
|
-
preset: Preset;
|
|
41
|
-
theme: Theme;
|
|
42
|
-
componentConfigs: Record<string, ComponentConfig>;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Server-side atomic apply: validate every referenced file exists, flip the
|
|
47
|
-
* theme + each component's `_active.json` pointer, and return the resolved
|
|
48
|
-
* theme + component configs in one payload.
|
|
49
|
-
*
|
|
50
|
-
* The client typically follows this with a full page reload — loading a
|
|
51
|
-
* preset is a "blow up the world" action and preserving editor session
|
|
52
|
-
* state across that boundary is low value.
|
|
53
|
-
*/
|
|
54
|
-
export async function applyPreset(fileName: string): Promise<ApplyPresetResult> {
|
|
55
|
-
const res = await fetch(`/api/presets/${encodeURIComponent(fileName)}/apply`, {
|
|
56
|
-
method: 'PUT',
|
|
57
|
-
});
|
|
58
|
-
if (!res.ok) {
|
|
59
|
-
const err = await res.json().catch(() => ({ error: 'Apply failed' }));
|
|
60
|
-
throw new Error(err.error || 'Apply failed');
|
|
61
|
-
}
|
|
62
|
-
return res.json();
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Build a manifest from the *currently active files on disk* (not in-memory
|
|
67
|
-
* editor state) and persist it. Dirty editor state isn't a file yet, so it's
|
|
68
|
-
* not part of any preset until the user saves it. Callers should warn the
|
|
69
|
-
* user via the UI if `$dirty` is true before invoking this.
|
|
70
|
-
*/
|
|
71
|
-
export async function captureCurrentAsPreset(
|
|
72
|
-
fileName: string,
|
|
73
|
-
displayName: string,
|
|
74
|
-
): Promise<void> {
|
|
75
|
-
const activeTheme = await getActiveTheme();
|
|
76
|
-
if (!activeTheme || !activeTheme._fileName) {
|
|
77
|
-
throw new Error('No active theme on disk to capture');
|
|
78
|
-
}
|
|
79
|
-
const components = await listComponents();
|
|
80
|
-
const componentConfigs: Record<string, string> = {};
|
|
81
|
-
for (const c of components) {
|
|
82
|
-
componentConfigs[c.name] = c.activeFile || 'default';
|
|
83
|
-
}
|
|
84
|
-
const now = new Date().toISOString();
|
|
85
|
-
const manifest: Preset = {
|
|
86
|
-
name: displayName,
|
|
87
|
-
createdAt: now,
|
|
88
|
-
updatedAt: now,
|
|
89
|
-
theme: activeTheme._fileName,
|
|
90
|
-
componentConfigs,
|
|
91
|
-
};
|
|
92
|
-
await savePreset(fileName, manifest);
|
|
93
|
-
await setActivePreset(fileName);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
// ── Production preset ──────────────────────────────────────────────────────
|
|
97
|
-
//
|
|
98
|
-
// The production preset is the manifest whose references describe what
|
|
99
|
-
// tokens.css + the component overrides block currently encode. A separate
|
|
100
|
-
// pointer (`presets/_production.json`) from the active preset lets the editor
|
|
101
|
-
// run experiments without disturbing what end users see. Applying a preset to
|
|
102
|
-
// production flips every per-artifact `_production.json` pointer to match the
|
|
103
|
-
// manifest and re-bakes css.
|
|
104
|
-
|
|
105
|
-
export interface PresetProductionInfo {
|
|
106
|
-
fileName: string;
|
|
107
|
-
name: string;
|
|
108
|
-
theme: string;
|
|
109
|
-
componentConfigs: Record<string, string>;
|
|
110
|
-
updatedAt: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export async function getProductionPreset(): Promise<PresetProductionInfo | null> {
|
|
114
|
-
try {
|
|
115
|
-
const res = await fetch('/api/presets/production');
|
|
116
|
-
if (!res.ok) return null;
|
|
117
|
-
return res.json();
|
|
118
|
-
} catch {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export async function applyPresetToProduction(fileName: string): Promise<PresetProductionInfo> {
|
|
124
|
-
const res = await fetch('/api/presets/production', {
|
|
125
|
-
method: 'PUT',
|
|
126
|
-
headers: { 'Content-Type': 'application/json' },
|
|
127
|
-
body: JSON.stringify({ name: fileName }),
|
|
128
|
-
});
|
|
129
|
-
if (!res.ok) {
|
|
130
|
-
const err = await res.json().catch(() => ({ error: 'Apply to production failed' }));
|
|
131
|
-
throw new Error(err.error || 'Apply to production failed');
|
|
132
|
-
}
|
|
133
|
-
return res.json();
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Snapshot whatever each artifact's `_production.json` currently points at
|
|
138
|
-
* into a new preset manifest. Recovery path when individual component Adopts
|
|
139
|
-
* have drifted production away from the production preset and the user wants
|
|
140
|
-
* to preserve that state under a name rather than re-converge to a preset.
|
|
141
|
-
*
|
|
142
|
-
* Does NOT flip `presets/_production.json` — the new preset's references
|
|
143
|
-
* already match production by construction, but tagging it as the production
|
|
144
|
-
* preset is a separate UX decision left to the caller.
|
|
145
|
-
*/
|
|
146
|
-
export async function captureProductionAsPreset(
|
|
147
|
-
fileName: string,
|
|
148
|
-
displayName: string,
|
|
149
|
-
): Promise<void> {
|
|
150
|
-
const themeInfo = await getProductionInfo();
|
|
151
|
-
const components = await listComponents();
|
|
152
|
-
const componentConfigs: Record<string, string> = {};
|
|
153
|
-
for (const c of components) {
|
|
154
|
-
componentConfigs[c.name] = c.productionFile || 'default';
|
|
155
|
-
}
|
|
156
|
-
const now = new Date().toISOString();
|
|
157
|
-
const manifest: Preset = {
|
|
158
|
-
name: displayName,
|
|
159
|
-
createdAt: now,
|
|
160
|
-
updatedAt: now,
|
|
161
|
-
theme: themeInfo.fileName,
|
|
162
|
-
componentConfigs,
|
|
163
|
-
};
|
|
164
|
-
await savePreset(fileName, manifest);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Three states comparing the active preset against current production:
|
|
169
|
-
* - 'in-production' — active preset IS the production preset AND every
|
|
170
|
-
* manifest reference matches the per-artifact production pointer.
|
|
171
|
-
* - 'editor-only' — the production preset is a different preset; applying
|
|
172
|
-
* this one would flip pointers.
|
|
173
|
-
* - 'diverged' — this IS the production preset, but per-artifact
|
|
174
|
-
* production has drifted (individual component Adopt clicks since the
|
|
175
|
-
* last apply). Two recovery paths: re-apply to converge, or capture
|
|
176
|
-
* production as a new preset to name the divergence.
|
|
177
|
-
*/
|
|
178
|
-
export type ProductionPresetStatus = 'in-production' | 'editor-only' | 'diverged';
|
|
179
|
-
|
|
180
|
-
export interface ProductionComparison {
|
|
181
|
-
status: ProductionPresetStatus;
|
|
182
|
-
productionPreset: PresetProductionInfo | null;
|
|
183
|
-
themeDrift: boolean;
|
|
184
|
-
driftedComponents: string[];
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export async function compareActiveToProduction(
|
|
188
|
-
activePreset: Preset,
|
|
189
|
-
): Promise<ProductionComparison> {
|
|
190
|
-
const [productionPreset, themeInfo, components] = await Promise.all([
|
|
191
|
-
getProductionPreset(),
|
|
192
|
-
getProductionInfo(),
|
|
193
|
-
listComponents(),
|
|
194
|
-
]);
|
|
195
|
-
const componentProdMap = new Map(components.map((c) => [c.name, c.productionFile]));
|
|
196
|
-
const themeDrift = themeInfo.fileName !== activePreset.theme;
|
|
197
|
-
const driftedComponents: string[] = [];
|
|
198
|
-
for (const [comp, file] of Object.entries(activePreset.componentConfigs)) {
|
|
199
|
-
const prod = componentProdMap.get(comp);
|
|
200
|
-
if (prod !== file) driftedComponents.push(comp);
|
|
201
|
-
}
|
|
202
|
-
const manifestMatches = !themeDrift && driftedComponents.length === 0;
|
|
203
|
-
const activeFile = activePreset._fileName;
|
|
204
|
-
const isActiveProductionPreset =
|
|
205
|
-
!!activeFile && !!productionPreset && productionPreset.fileName === activeFile;
|
|
206
|
-
|
|
207
|
-
let status: ProductionPresetStatus;
|
|
208
|
-
if (!isActiveProductionPreset) {
|
|
209
|
-
status = 'editor-only';
|
|
210
|
-
} else {
|
|
211
|
-
status = manifestMatches ? 'in-production' : 'diverged';
|
|
212
|
-
}
|
|
213
|
-
return { status, productionPreset, themeDrift, driftedComponents };
|
|
214
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { writable } from 'svelte/store';
|
|
2
|
-
import type { ProductionInfo } from './themeService';
|
|
3
|
-
import type { ProductionComparison } from './presetService';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Monotonic counter that ticks every time a production pointer flips —
|
|
7
|
-
* theme production, a component's production, or a preset applied to
|
|
8
|
-
* production. UI surfaces that compare against current production state
|
|
9
|
-
* (notably `PresetFileManager`) subscribe to this so an Adopt click in a
|
|
10
|
-
* sibling manager refreshes their derived status without per-pair wiring.
|
|
11
|
-
*
|
|
12
|
-
* Bumpers: `ThemeFileManager.handleApplyToProduction`,
|
|
13
|
-
* `ComponentFileManager.handleUpdateProduction`,
|
|
14
|
-
* `presetService.applyPresetToProduction` (called from `PresetFileManager`).
|
|
15
|
-
* Anyone setting `_production.json` should bump.
|
|
16
|
-
*/
|
|
17
|
-
export const productionRevision = writable(0);
|
|
18
|
-
|
|
19
|
-
export function bumpProductionRevision(): void {
|
|
20
|
-
productionRevision.update((n) => n + 1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Cached production-state stores. The Theme and Preset file managers live in
|
|
25
|
-
* the sidebar footer, swapping in/out of the DOM as the user toggles between
|
|
26
|
-
* the tokens and components views. Keeping the last-known production state in
|
|
27
|
-
* module-level Svelte stores means a remount renders the correct Adopt-button
|
|
28
|
-
* state on the first frame instead of flashing through "not in sync" while a
|
|
29
|
-
* fresh fetch resolves.
|
|
30
|
-
*/
|
|
31
|
-
export const themeProductionInfo = writable<ProductionInfo | null>(null);
|
|
32
|
-
export const presetProductionComparison = writable<ProductionComparison | null>(null);
|