@motion-proto/live-tokens 0.49.1 → 0.52.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/CHANGELOG.md +72 -0
- package/dist-plugin/adjust/index.d.cts +1 -1
- package/dist-plugin/adjust/index.d.ts +1 -1
- package/dist-plugin/{chunk-76TFDTJO.js → chunk-JIGIIE5P.js} +60 -132
- package/dist-plugin/{chunk-44RSTAII.js → chunk-TKZBVIW5.js} +33 -5
- package/dist-plugin/chunk-YR6GPXW2.js +129 -0
- package/dist-plugin/generateColorsAndType/index.cjs +100 -33
- package/dist-plugin/generateColorsAndType/index.d.cts +1 -1
- package/dist-plugin/generateColorsAndType/index.d.ts +1 -1
- package/dist-plugin/generateColorsAndType/index.js +35 -14
- package/dist-plugin/index.cjs +95 -55
- package/dist-plugin/index.js +5 -3
- package/dist-plugin/{themeTypes-DSwKq-bj.d.cts → themeTypes-Dky03HL9.d.cts} +18 -5
- package/dist-plugin/{themeTypes-DSwKq-bj.d.ts → themeTypes-Dky03HL9.d.ts} +18 -5
- package/dist-plugin/tokensCssMigrations/index.cjs +71 -5
- package/dist-plugin/tokensCssMigrations/index.d.cts +20 -9
- package/dist-plugin/tokensCssMigrations/index.d.ts +20 -9
- package/dist-plugin/tokensCssMigrations/index.js +4 -1
- package/package.json +8 -1
- package/src/editor/bootstrap.ts +2 -0
- package/src/editor/component-editor/ButtonEditor.svelte +1 -1
- package/src/editor/component-editor/CardEditor.svelte +5 -2
- package/src/editor/component-editor/IconButtonEditor.svelte +1 -1
- package/src/editor/component-editor/ImageEditor.svelte +1 -1
- package/src/editor/component-editor/NotificationEditor.svelte +6 -0
- package/src/editor/component-editor/SectionDividerEditor.svelte +4 -1
- package/src/editor/component-editor/SideNavigationEditor.svelte +6 -0
- package/src/editor/component-editor/TabBarEditor.svelte +1 -5
- package/src/editor/component-editor/scaffolding/ComponentEditorBase.svelte +8 -1
- package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +10 -32
- package/src/editor/component-editor/scaffolding/StateBlock.svelte +2 -0
- package/src/editor/component-editor/scaffolding/TypeEditor.svelte +3 -1
- package/src/editor/component-editor/scaffolding/types.ts +3 -0
- package/src/editor/core/components/componentConfigService.ts +25 -0
- package/src/editor/core/cssVarSync.ts +65 -7
- package/src/editor/core/fonts/fontLoader.ts +12 -3
- package/src/editor/core/fonts/fontWeightAvailability.ts +97 -0
- package/src/editor/core/palettes/oklch.ts +3 -137
- package/src/editor/core/palettes/paletteDerivation.ts +79 -37
- package/src/editor/core/preview/lookPreview.ts +23 -18
- package/src/editor/core/store/editorRenderer.ts +22 -7
- package/src/editor/core/store/editorStore.ts +31 -0
- package/src/editor/core/store/gradientSource.ts +5 -0
- package/src/editor/core/themes/colorsAndTypeService.ts +2 -12
- package/src/editor/core/themes/generateColorsAndType.ts +18 -8
- package/src/editor/core/themes/migrations/2026-05-20-sectiondivider-slim-variants.ts +4 -1
- package/src/editor/core/themes/migrations/2026-05-21-sectiondivider-spacing-to-padding.ts +4 -1
- package/src/editor/core/themes/migrations/2026-05-25-cornerbadge-flatten-variants.ts +8 -0
- package/src/editor/core/themes/slices/fonts.ts +4 -5
- package/src/editor/core/themes/themeDocumentSync.ts +66 -0
- package/src/editor/core/themes/themeInit.ts +7 -10
- package/src/editor/core/themes/themeService.ts +10 -3
- package/src/editor/core/themes/themeTypes.ts +18 -6
- package/src/editor/docs/content/editing-tokens.md +6 -2
- package/src/editor/docs/content/themes-workflow.md +14 -11
- package/src/editor/docs/content/where-themes-live.md +2 -2
- package/src/editor/docs/content.generated.ts +3 -3
- package/src/editor/ui/BezierCurveEditor.svelte +90 -67
- package/src/editor/ui/FileLoadList.svelte +1 -0
- package/src/editor/ui/FontStackEditor.svelte +1 -2
- package/src/editor/ui/GradientEditor.svelte +5 -1
- package/src/editor/ui/PaletteEditor.svelte +150 -44
- package/src/editor/ui/ProjectFontsSection.svelte +0 -5
- package/src/editor/ui/ThemePanel.svelte +206 -42
- package/src/editor/ui/Toggle.svelte +14 -2
- package/src/editor/ui/UIDialog.svelte +7 -1
- package/src/editor/ui/UIFontFamilySelector.svelte +13 -13
- package/src/editor/ui/UIFontSizeSelector.svelte +5 -5
- package/src/editor/ui/UIFontWeightSelector.svelte +52 -2
- package/src/editor/ui/UIOptionItem.svelte +14 -1
- package/src/editor/ui/UIPaddingSelector.svelte +4 -3
- package/src/editor/ui/UIPaletteSelector.svelte +20 -13
- package/src/editor/ui/UIRelinkConfirmDialog.svelte +18 -3
- package/src/editor/ui/UITextTransformSelector.svelte +5 -5
- package/src/editor/ui/UITokenSelector.svelte +29 -7
- package/src/editor/ui/colors/ColorStory.svelte +12 -8
- package/src/editor/ui/curveEngine.ts +101 -21
- package/src/editor/ui/palette/OverridesPanel.svelte +19 -5
- package/src/editor/ui/palette/PaletteBase.svelte +17 -78
- package/src/editor/ui/palette/ScaleCurveEditor.svelte +109 -20
- package/src/editor/ui/palette/curveSummary.ts +20 -0
- package/src/editor/ui/palette/dockMagnify.ts +5 -13
- package/src/editor/ui/palette/paletteMath.ts +7 -4
- package/src/live-tokens/data/colors-and-type/autumn.json +528 -528
- package/src/live-tokens/data/colors-and-type/default.json +247 -247
- package/src/live-tokens/data/colors-and-type/halloween.json +532 -532
- package/src/live-tokens/data/colors-and-type/midnight-study.json +538 -538
- package/src/live-tokens/data/colors-and-type/ocean.json +521 -521
- package/src/live-tokens/data/colors-and-type/royal-velvet.json +532 -532
- package/src/live-tokens/data/colors-and-type/spring-meadow.json +504 -504
- package/src/live-tokens/data/colors-and-type/sunset.json +531 -531
- package/src/live-tokens/data/themes/autumn.json +527 -527
- package/src/live-tokens/data/themes/halloween.json +531 -531
- package/src/live-tokens/data/themes/midnight-study.json +537 -537
- package/src/live-tokens/data/themes/ocean.json +520 -520
- package/src/live-tokens/data/themes/royal-velvet.json +531 -531
- package/src/live-tokens/data/themes/spring-meadow.json +516 -514
- package/src/live-tokens/data/themes/sunset.json +531 -531
- package/src/live-tokens/data/tokens.generated.css +282 -282
- package/src/system/components/Button.svelte +2 -1
- package/src/system/components/FloatingTokenTags.css +2 -2
- package/src/system/components/FloatingTokenTags.svelte +11 -0
- package/src/system/components/IconButton.svelte +2 -1
- package/src/system/components/Image.svelte +9 -3
- package/src/system/components/ImageLightbox.svelte +2 -0
- package/src/system/components/SectionDivider.svelte +20 -2
- package/src/system/components/SideNavigation.svelte +15 -1
- package/src/system/internal/backgroundContrast.ts +7 -0
- package/src/system/internal/oklch.ts +189 -0
- package/src/system/styles/fonts.css +6 -6
- package/src/system/styles/tokens.css +283 -283
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { onMount, onDestroy, tick } from 'svelte';
|
|
3
3
|
import { oklchToHexClamped, type Oklch } from '../core/palettes/oklch';
|
|
4
|
-
import { type CurveAnchor, lightnessCurveConfig, saturationCurveConfig } from './curveEngine';
|
|
4
|
+
import { type CurveAnchor, lightnessCurveConfig, saturationCurveConfig, hueCurveConfig } from './curveEngine';
|
|
5
5
|
import ColorEditPanel from './ColorEditPanel.svelte';
|
|
6
6
|
import OverridesPanel from './palette/OverridesPanel.svelte';
|
|
7
7
|
import UIPillButton from './UIPillButton.svelte';
|
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
import ScaleCurveEditor from './palette/ScaleCurveEditor.svelte';
|
|
10
10
|
import PaletteBase from './palette/PaletteBase.svelte';
|
|
11
11
|
import PaletteJumpButton from './palette/PaletteJumpButton.svelte';
|
|
12
|
+
import Toggle from './Toggle.svelte';
|
|
12
13
|
import { type EditingState, idleState, BASE_KEY, isEditingBase as isBaseEdit } from './palette/paletteEditorState';
|
|
13
|
-
import { dockTrackTemplate } from './palette/dockMagnify';
|
|
14
14
|
import {
|
|
15
15
|
type Step, type Scale,
|
|
16
16
|
GRAY_FALLBACK,
|
|
17
|
-
DEFAULT_PALETTE_LIGHTNESS, DEFAULT_PALETTE_SATURATION,
|
|
17
|
+
DEFAULT_PALETTE_LIGHTNESS, DEFAULT_PALETTE_SATURATION, DEFAULT_PALETTE_HUE,
|
|
18
18
|
defaultScaleCurves, defaultScaleCurvesObject, defaultPaletteConfig,
|
|
19
19
|
paletteStepLightness, scales,
|
|
20
20
|
paletteStepKey, stepKey, scaleCurveKey as getScaleCurveKey,
|
|
@@ -32,6 +32,12 @@
|
|
|
32
32
|
import { pendingPaletteFocus } from '../core/store/paletteFocus';
|
|
33
33
|
import { showCopyPopover } from './copyPopover';
|
|
34
34
|
|
|
35
|
+
// Full sRGB chroma range (gamutClamp trims per hue/lightness). Neutrals default
|
|
36
|
+
// low but are not capped; their calm character comes from defaults, not a ceiling.
|
|
37
|
+
const BASE_CHROMA_MAX = 0.4;
|
|
38
|
+
// Where a typical neutral's chroma sits, marked on the slider as a soft nudge.
|
|
39
|
+
const NEUTRAL_CALM_CHROMA = 0.05;
|
|
40
|
+
|
|
35
41
|
interface Props {
|
|
36
42
|
label: string;
|
|
37
43
|
displayLabel?: string | null;
|
|
@@ -80,6 +86,14 @@
|
|
|
80
86
|
const idx = saturationCurve.findIndex(a => Math.abs(a.x - x) < 0.5);
|
|
81
87
|
return idx >= 0 ? idx : null;
|
|
82
88
|
});
|
|
89
|
+
// Unlike lightness/saturation, hue has no always-present curve to search: it stays
|
|
90
|
+
// undefined until the first edit (RJC 5), and there is nothing to lock before then.
|
|
91
|
+
let lockedHueIdx: number | null = $derived.by(() => {
|
|
92
|
+
if (!anchorToBase || anchorPlacement === undefined || hueCurve === undefined) return null;
|
|
93
|
+
const x = stepIndexToX(anchorPlacement.step);
|
|
94
|
+
const idx = hueCurve.findIndex(a => Math.abs(a.x - x) < 0.5);
|
|
95
|
+
return idx >= 0 ? idx : null;
|
|
96
|
+
});
|
|
83
97
|
|
|
84
98
|
// Held at component scope so inline header-swatch handlers and the function
|
|
85
99
|
// handlers share one handle for commit/cancel.
|
|
@@ -114,14 +128,36 @@
|
|
|
114
128
|
function setLightnessCurve(a: CurveAnchor[]) { edit('lightnessCurve', a); }
|
|
115
129
|
function setSaturationCurve(a: CurveAnchor[]) { edit('saturationCurve', a); }
|
|
116
130
|
|
|
131
|
+
// First edit materializes the field (RJC 5) with `a` — the curve the UI
|
|
132
|
+
// actually rendered and edited — written in BEFORE syncBaseAnchor runs, not
|
|
133
|
+
// after: syncBaseAnchor pins the anchor by inserting a y=0 point into
|
|
134
|
+
// whatever `cfg.hueCurve` currently holds, so calling it against the
|
|
135
|
+
// about-to-be-discarded flat default and then overwriting with `a` would
|
|
136
|
+
// throw the pin away. Wave 3's idempotency guarantee is what makes
|
|
137
|
+
// re-running syncBaseAnchor here safe without disturbing the
|
|
138
|
+
// lightness/saturation anchors it already placed.
|
|
139
|
+
function setHueCurve(a: CurveAnchor[]) {
|
|
140
|
+
mutate(`${label}: hueCurve`, (s) => {
|
|
141
|
+
if (!s.palettes[label]) s.palettes[label] = seedConfig();
|
|
142
|
+
const cfg = s.palettes[label];
|
|
143
|
+
const materializing = cfg.hueCurve === undefined;
|
|
144
|
+
cfg.hueCurve = a;
|
|
145
|
+
if (materializing) syncBaseAnchor(cfg);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
117
149
|
function handleOffset(key: string, value: number) {
|
|
118
150
|
edit('curveOffset', { ...curveOffset, [key]: value });
|
|
119
151
|
}
|
|
120
152
|
|
|
153
|
+
function handleAutoSmooth(key: string, value: boolean) {
|
|
154
|
+
edit('curveAutoSmooth', { ...curveAutoSmooth, [key]: value });
|
|
155
|
+
}
|
|
156
|
+
|
|
121
157
|
let editing: EditingState = $state(idleState);
|
|
122
158
|
|
|
123
159
|
function computePaletteOklch(index: number, base: Oklch): Oklch {
|
|
124
|
-
return computePaletteOklchPure(index, base, lightnessCurve, saturationCurve, curveOffset);
|
|
160
|
+
return computePaletteOklchPure(index, base, lightnessCurve, saturationCurve, curveOffset, hueCurve);
|
|
125
161
|
}
|
|
126
162
|
|
|
127
163
|
function computeDerivedOklch(step: Step, base: Oklch, scaleTitle: string): Oklch {
|
|
@@ -176,7 +212,17 @@
|
|
|
176
212
|
scaleEditorOpen = scaleEditorOpen;
|
|
177
213
|
}
|
|
178
214
|
|
|
179
|
-
|
|
215
|
+
// Session-scoped (RJC 9): viewport state, never written to theme JSON.
|
|
216
|
+
// Keyed by the same curveKey strings that already key curveOffset, so a
|
|
217
|
+
// hue key ("hue" or "<scale>-hue") defaults closed and the rest open.
|
|
218
|
+
let curveSectionOpen: Record<string, boolean> = $state({});
|
|
219
|
+
const sectionOpen = (key: string) => curveSectionOpen[key] ?? !key.endsWith('hue');
|
|
220
|
+
function toggleCurveSection(key: string) {
|
|
221
|
+
curveSectionOpen[key] = !sectionOpen(key);
|
|
222
|
+
curveSectionOpen = curveSectionOpen;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function setScaleCurve(title: string, channel: 'lightness' | 'saturation' | 'hue', a: CurveAnchor[]) {
|
|
180
226
|
const cur = scaleCurves[title] ?? { lightness: defaultScaleCurves[title].lightness(), saturation: defaultScaleCurves[title].saturation() };
|
|
181
227
|
edit('scaleCurves', { ...scaleCurves, [title]: { ...cur, [channel]: a } });
|
|
182
228
|
}
|
|
@@ -389,22 +435,16 @@
|
|
|
389
435
|
let baseColor = $derived($editorState.palettes[label]?.baseColor ?? initialColor);
|
|
390
436
|
let lightnessCurve = $derived($editorState.palettes[label]?.lightnessCurve ?? DEFAULT_PALETTE_LIGHTNESS());
|
|
391
437
|
let saturationCurve = $derived($editorState.palettes[label]?.saturationCurve ?? DEFAULT_PALETTE_SATURATION());
|
|
438
|
+
// Left undefined when absent (RJC 5): materializing here would seed every
|
|
439
|
+
// fresh palette with a redundant flat curve it never asked for.
|
|
440
|
+
let hueCurve = $derived($editorState.palettes[label]?.hueCurve);
|
|
392
441
|
let scaleCurves = $derived($editorState.palettes[label]?.scaleCurves ?? defaultScaleCurvesObject());
|
|
393
442
|
let curveOffset = $derived($editorState.palettes[label]?.curveOffset ?? { lightness: 0, saturation: 0 });
|
|
443
|
+
let curveAutoSmooth = $derived($editorState.palettes[label]?.curveAutoSmooth ?? {});
|
|
394
444
|
let overrides = $derived($editorState.palettes[label]?.overrides ?? {});
|
|
395
445
|
let snappedScales = $derived(new Set($editorState.palettes[label]?.snappedScales ?? []));
|
|
396
446
|
let anchorToBase = $derived($editorState.palettes[label]?.anchorToBase ?? true);
|
|
397
447
|
let anchorPlacement = $derived($editorState.palettes[label]?.anchorPlacement);
|
|
398
|
-
let anchorStepLabel = $derived(anchorToBase && anchorPlacement !== undefined
|
|
399
|
-
? paletteStepLightness[anchorPlacement.step]?.label ?? null
|
|
400
|
-
: null);
|
|
401
|
-
// Dock magnification: the grid transitions between track lists, so dialing
|
|
402
|
-
// lightness reads as swatches opening/closing while the anchor walks the
|
|
403
|
-
// ramp. Column 0 is the white bookend, so step i is column i+1.
|
|
404
|
-
let swatchTemplate = $derived(dockTrackTemplate(
|
|
405
|
-
paletteStepLightness.length + 2,
|
|
406
|
-
anchorToBase && anchorPlacement !== undefined ? anchorPlacement.step + 1 : null,
|
|
407
|
-
));
|
|
408
448
|
let emptyMode = $derived($editorState.palettes[label]?.emptyMode ?? 'solid');
|
|
409
449
|
let gradientStyle = $derived($editorState.palettes[label]?.gradientStyle ?? 'linear');
|
|
410
450
|
let gradientAngle = $derived($editorState.palettes[label]?.gradientAngle ?? 180);
|
|
@@ -417,7 +457,7 @@
|
|
|
417
457
|
let editingKey = $derived(editing.kind === 'idle' ? null : editing.kind === 'editingBase' ? BASE_KEY : editing.stepKey);
|
|
418
458
|
let editingDraft = $derived(editing.kind === 'editingStep' ? editing.draft : null);
|
|
419
459
|
let paletteComputed = $derived((() => {
|
|
420
|
-
const _bc = baseColor, _lc = lightnessCurve, _sc = saturationCurve, _co = curveOffset, _ed = editingDraft, _ek = editingKey, _ov = overrides, _ab = anchorToBase, _ap = anchorPlacement;
|
|
460
|
+
const _bc = baseColor, _lc = lightnessCurve, _sc = saturationCurve, _hc = hueCurve, _co = curveOffset, _ed = editingDraft, _ek = editingKey, _ov = overrides, _ab = anchorToBase, _ap = anchorPlacement;
|
|
421
461
|
return paletteStepLightness.map((ps, index) => {
|
|
422
462
|
const k = paletteStepKey(ps.label);
|
|
423
463
|
const oklch = computePaletteOklch(index, baseColor);
|
|
@@ -488,23 +528,55 @@
|
|
|
488
528
|
<PaletteBase
|
|
489
529
|
{label}
|
|
490
530
|
{displayLabel}
|
|
491
|
-
{neutral}
|
|
492
531
|
{baseColor}
|
|
493
|
-
{anchorToBase}
|
|
494
|
-
{anchorStepLabel}
|
|
495
532
|
{isEditingBase}
|
|
496
|
-
{panelOpen}
|
|
497
533
|
pinnedOpen={paletteEditorOpen}
|
|
498
|
-
{editingColor}
|
|
499
|
-
{editPanelTitle}
|
|
500
534
|
{copiedKey}
|
|
501
535
|
onStartEdit={startBaseEdit}
|
|
502
|
-
onConfirm={confirmEdit}
|
|
503
|
-
onCancel={cancelEdit}
|
|
504
|
-
onBaseChange={(h, c, l) => setBaseColor(label, { l: l / 100, c, h })}
|
|
505
|
-
onAnchorToBaseChange={setAnchorToBase}
|
|
506
536
|
onCopyBaseHex={copyHex}
|
|
507
|
-
|
|
537
|
+
>
|
|
538
|
+
{#snippet actions()}
|
|
539
|
+
<PaletteJumpButton family={label} {displayLabel} target="wheel" />
|
|
540
|
+
<UIPillButton size="compact" variant="outline" onclick={clearPaletteOverrides}>Clear Overrides</UIPillButton>
|
|
541
|
+
<UIPillButton size="compact" variant="outline" onclick={() => paletteEditorOpen = !paletteEditorOpen}>
|
|
542
|
+
{paletteEditorOpen ? 'Close' : 'Edit'}
|
|
543
|
+
</UIPillButton>
|
|
544
|
+
{/snippet}
|
|
545
|
+
</PaletteBase>
|
|
546
|
+
|
|
547
|
+
{#if paletteEditorOpen || (isEditingBase && panelOpen && editingColor)}
|
|
548
|
+
<div class="swatch-grid" style="--swatch-cols: {paletteStepLightness.length + 2}">
|
|
549
|
+
<div class="base-panel" style="grid-column: 2 / {paletteStepLightness.length + 2}">
|
|
550
|
+
<ColorEditPanel
|
|
551
|
+
title={isEditingBase ? editPanelTitle : 'Base Color'}
|
|
552
|
+
showRemoveOverride={false}
|
|
553
|
+
hideActions={!isEditingBase}
|
|
554
|
+
hidePreview
|
|
555
|
+
hue={baseColor.h}
|
|
556
|
+
chroma={baseColor.c}
|
|
557
|
+
lightness={baseColor.l * 100}
|
|
558
|
+
chromaMax={BASE_CHROMA_MAX}
|
|
559
|
+
chromaHint={neutral ? NEUTRAL_CALM_CHROMA : undefined}
|
|
560
|
+
onHueChromaChange={(h, c, l) => setBaseColor(label, { l: l / 100, c, h })}
|
|
561
|
+
onConfirm={confirmEdit}
|
|
562
|
+
onCancel={cancelEdit}
|
|
563
|
+
onRemoveOverride={() => {}}
|
|
564
|
+
onSliderStart={() => beginSliderGesture(`edit ${label} base`)}
|
|
565
|
+
>
|
|
566
|
+
{#snippet actions()}
|
|
567
|
+
<div class="base-anchor-toggle">
|
|
568
|
+
<Toggle
|
|
569
|
+
checked={anchorToBase}
|
|
570
|
+
onchange={(v) => setAnchorToBase(v ?? !anchorToBase)}
|
|
571
|
+
label="Base color must appear in palette"
|
|
572
|
+
labelFirst
|
|
573
|
+
/>
|
|
574
|
+
</div>
|
|
575
|
+
{/snippet}
|
|
576
|
+
</ColorEditPanel>
|
|
577
|
+
</div>
|
|
578
|
+
</div>
|
|
579
|
+
{/if}
|
|
508
580
|
|
|
509
581
|
<!-- Palette + Text row -->
|
|
510
582
|
<div class="scales-row">
|
|
@@ -521,13 +593,8 @@
|
|
|
521
593
|
<span>Gradient</span>
|
|
522
594
|
</label>
|
|
523
595
|
{/if}
|
|
524
|
-
<PaletteJumpButton family={label} {displayLabel} target="wheel" />
|
|
525
|
-
<UIPillButton size="compact" variant="outline" onclick={clearPaletteOverrides}>Clear Overrides</UIPillButton>
|
|
526
|
-
<UIPillButton size="compact" variant="outline" onclick={() => paletteEditorOpen = !paletteEditorOpen}>
|
|
527
|
-
{paletteEditorOpen ? 'Close' : 'Edit'}
|
|
528
|
-
</UIPillButton>
|
|
529
596
|
</div>
|
|
530
|
-
<div class="swatch-grid" style="--swatch-cols: {paletteStepLightness.length + 2}
|
|
597
|
+
<div class="swatch-grid" style="--swatch-cols: {paletteStepLightness.length + 2}">
|
|
531
598
|
<div class="step-column">
|
|
532
599
|
<button class="step-label copyable-label" class:copied={copiedLabelKey === 'palette-white'} type="button" onclick={(e) => copyVarName('palette-white', `--color-${cssNamespace}-white`, e)}>
|
|
533
600
|
{copiedLabelKey === 'palette-white' ? 'copied!' : 'white'}
|
|
@@ -585,16 +652,20 @@
|
|
|
585
652
|
</div>
|
|
586
653
|
{/if}
|
|
587
654
|
<ScaleCurveEditor
|
|
588
|
-
curveKey="
|
|
589
|
-
anchors={
|
|
590
|
-
cfg={
|
|
655
|
+
curveKey="hue"
|
|
656
|
+
anchors={hueCurve ?? DEFAULT_PALETTE_HUE()}
|
|
657
|
+
cfg={hueCurveConfig}
|
|
591
658
|
stepCount={paletteStepLightness.length}
|
|
592
|
-
defaults={
|
|
593
|
-
offset={curveOffset['
|
|
594
|
-
|
|
659
|
+
defaults={DEFAULT_PALETTE_HUE()}
|
|
660
|
+
offset={curveOffset['hue'] ?? 0}
|
|
661
|
+
autoSmooth={curveAutoSmooth['hue']}
|
|
662
|
+
lockedAnchorIndex={lockedHueIdx}
|
|
663
|
+
open={sectionOpen('hue')}
|
|
664
|
+
onToggleOpen={() => toggleCurveSection('hue')}
|
|
595
665
|
onLockedAnchorUnlock={() => anchorUnlockPrompt = true}
|
|
596
|
-
onAnchorsChange={
|
|
666
|
+
onAnchorsChange={setHueCurve}
|
|
597
667
|
onOffsetChange={handleOffset}
|
|
668
|
+
onAutoSmoothChange={handleAutoSmooth}
|
|
598
669
|
/>
|
|
599
670
|
<ScaleCurveEditor
|
|
600
671
|
curveKey="saturation"
|
|
@@ -603,10 +674,30 @@
|
|
|
603
674
|
stepCount={paletteStepLightness.length}
|
|
604
675
|
defaults={DEFAULT_PALETTE_SATURATION()}
|
|
605
676
|
offset={curveOffset['saturation'] ?? 0}
|
|
677
|
+
autoSmooth={curveAutoSmooth['saturation']}
|
|
606
678
|
lockedAnchorIndex={lockedSaturationIdx}
|
|
679
|
+
open={sectionOpen('saturation')}
|
|
680
|
+
onToggleOpen={() => toggleCurveSection('saturation')}
|
|
607
681
|
onLockedAnchorUnlock={() => anchorUnlockPrompt = true}
|
|
608
682
|
onAnchorsChange={setSaturationCurve}
|
|
609
683
|
onOffsetChange={handleOffset}
|
|
684
|
+
onAutoSmoothChange={handleAutoSmooth}
|
|
685
|
+
/>
|
|
686
|
+
<ScaleCurveEditor
|
|
687
|
+
curveKey="lightness"
|
|
688
|
+
anchors={lightnessCurve}
|
|
689
|
+
cfg={lightnessCurveConfig}
|
|
690
|
+
stepCount={paletteStepLightness.length}
|
|
691
|
+
defaults={DEFAULT_PALETTE_LIGHTNESS()}
|
|
692
|
+
offset={curveOffset['lightness'] ?? 0}
|
|
693
|
+
autoSmooth={curveAutoSmooth['lightness']}
|
|
694
|
+
lockedAnchorIndex={lockedLightnessIdx}
|
|
695
|
+
open={sectionOpen('lightness')}
|
|
696
|
+
onToggleOpen={() => toggleCurveSection('lightness')}
|
|
697
|
+
onLockedAnchorUnlock={() => anchorUnlockPrompt = true}
|
|
698
|
+
onAnchorsChange={setLightnessCurve}
|
|
699
|
+
onOffsetChange={handleOffset}
|
|
700
|
+
onAutoSmoothChange={handleAutoSmooth}
|
|
610
701
|
/>
|
|
611
702
|
</div>
|
|
612
703
|
{/if}
|
|
@@ -641,6 +732,7 @@
|
|
|
641
732
|
{cssNamespace}
|
|
642
733
|
{scaleCurves}
|
|
643
734
|
{curveOffset}
|
|
735
|
+
{curveAutoSmooth}
|
|
644
736
|
{defaultScaleCurves}
|
|
645
737
|
overrides={overridesHex}
|
|
646
738
|
{editingKey}
|
|
@@ -663,6 +755,9 @@
|
|
|
663
755
|
onCopyVarName={copyVarName}
|
|
664
756
|
onSetScaleCurve={setScaleCurve}
|
|
665
757
|
onOffsetChange={handleOffset}
|
|
758
|
+
onAutoSmoothChange={handleAutoSmooth}
|
|
759
|
+
{sectionOpen}
|
|
760
|
+
onToggleCurveSection={toggleCurveSection}
|
|
666
761
|
/>
|
|
667
762
|
{/snippet}
|
|
668
763
|
|
|
@@ -862,8 +957,9 @@
|
|
|
862
957
|
|
|
863
958
|
.swatch-grid {
|
|
864
959
|
display: grid;
|
|
960
|
+
/* Even tracks: the curve editors below plot one step per column, so a wider
|
|
961
|
+
anchored column would slide every swatch out from under its own point. */
|
|
865
962
|
grid-template-columns: repeat(var(--swatch-cols), minmax(0, 1fr));
|
|
866
|
-
transition: grid-template-columns var(--ui-transition-fast);
|
|
867
963
|
gap: var(--ui-space-4) var(--swatch-gap, var(--ui-space-4));
|
|
868
964
|
align-items: start;
|
|
869
965
|
justify-content: start;
|
|
@@ -871,6 +967,16 @@
|
|
|
871
967
|
max-width: calc(var(--swatch-cols) * 4.5rem + (var(--swatch-cols) - 1) * var(--swatch-gap, var(--ui-space-4)));
|
|
872
968
|
}
|
|
873
969
|
|
|
970
|
+
/* The picker rides the same track geometry as the curve editors below, so
|
|
971
|
+
the two graphs share one left and right edge. */
|
|
972
|
+
.base-panel {
|
|
973
|
+
min-width: 0;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
.base-anchor-toggle {
|
|
977
|
+
margin-left: auto;
|
|
978
|
+
}
|
|
979
|
+
|
|
874
980
|
.curve-grid-span {
|
|
875
981
|
display: flex;
|
|
876
982
|
flex-direction: column;
|
|
@@ -927,9 +1033,9 @@
|
|
|
927
1033
|
outline-offset: 1px;
|
|
928
1034
|
}
|
|
929
1035
|
|
|
930
|
-
/* The step the base color is placed at:
|
|
931
|
-
|
|
932
|
-
|
|
1036
|
+
/* The step the base color is placed at: taller, with an emphasized border. It
|
|
1037
|
+
keeps its column width so the curve editors stay aligned. No fill change:
|
|
1038
|
+
the swatch itself already IS the picked color. */
|
|
933
1039
|
.swatch.gray-swatch.anchored {
|
|
934
1040
|
border-color: var(--ui-border-higher);
|
|
935
1041
|
height: calc(5.75rem + var(--ui-space-2));
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import type { FontFamily, FontSource } from '../core/themes/themeTypes';
|
|
3
3
|
import { editorState, setFontSources, transaction } from '../core/store/editorStore';
|
|
4
|
-
import { applyFontSources, applyFontStacks } from '../core/fonts/fontLoader';
|
|
5
4
|
import {
|
|
6
5
|
buildSourceFromFontFaceText,
|
|
7
6
|
buildSourceFromUrl,
|
|
@@ -69,8 +68,6 @@
|
|
|
69
68
|
|
|
70
69
|
function commitSources(next: FontSource[]) {
|
|
71
70
|
setFontSources(next);
|
|
72
|
-
applyFontSources(next);
|
|
73
|
-
applyFontStacks(fontStacksList, next);
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
/** One paste field → sniff whether it's @font-face or a URL/embed and
|
|
@@ -220,8 +217,6 @@
|
|
|
220
217
|
s.fonts.sources = next;
|
|
221
218
|
s.fonts.stacks = updatedStacks;
|
|
222
219
|
});
|
|
223
|
-
applyFontSources(next);
|
|
224
|
-
applyFontStacks(updatedStacks, next);
|
|
225
220
|
}
|
|
226
221
|
|
|
227
222
|
/** Resolve a clickable target for the row. We prefer the human-readable
|