@motion-proto/live-tokens 0.3.9 → 0.5.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/package.json +9 -8
- package/src/component-editor/BadgeEditor.svelte +24 -22
- package/src/component-editor/CalloutEditor.svelte +3 -3
- package/src/component-editor/CardEditor.svelte +25 -21
- package/src/component-editor/CollapsibleSectionEditor.svelte +27 -25
- package/src/component-editor/CornerBadgeEditor.svelte +37 -35
- package/src/component-editor/DialogEditor.svelte +26 -24
- package/src/component-editor/ImageEditor.svelte +11 -9
- package/src/component-editor/InlineEditActionsEditor.svelte +17 -15
- package/src/component-editor/NotificationEditor.svelte +32 -30
- package/src/component-editor/ProgressBarEditor.svelte +3 -3
- package/src/component-editor/RadioButtonEditor.svelte +31 -29
- package/src/component-editor/SectionDividerEditor.svelte +30 -28
- package/src/component-editor/SegmentedControlEditor.svelte +29 -25
- package/src/component-editor/StandardButtonsEditor.svelte +42 -38
- package/src/component-editor/TabBarEditor.svelte +20 -18
- package/src/component-editor/TableEditor.svelte +4 -4
- package/src/component-editor/TooltipEditor.svelte +11 -9
- package/src/component-editor/registry.ts +2 -2
- package/src/component-editor/scaffolding/AngleDial.svelte +20 -19
- package/src/component-editor/scaffolding/ComponentEditorBase.svelte +44 -20
- package/src/component-editor/scaffolding/ComponentFileManager.svelte +260 -37
- package/src/component-editor/scaffolding/ComponentFileMenu.svelte +41 -29
- package/src/component-editor/scaffolding/ComponentsTab.svelte +7 -3
- package/src/component-editor/scaffolding/CopyFromMenu.svelte +21 -12
- package/src/component-editor/scaffolding/DemoHeader.svelte +13 -4
- package/src/component-editor/scaffolding/DividerEditor.svelte +27 -14
- package/src/component-editor/scaffolding/FieldsetWrapper.svelte +10 -4
- package/src/component-editor/scaffolding/GradientCard.svelte +25 -20
- package/src/component-editor/scaffolding/LinkageChart.svelte +43 -34
- package/src/component-editor/scaffolding/LinkedBlock.svelte +24 -21
- package/src/component-editor/scaffolding/NonStylableConfig.svelte +6 -1
- package/src/component-editor/scaffolding/SaveAsDialog.svelte +39 -35
- package/src/component-editor/scaffolding/ShadowBackdrop.svelte +21 -9
- package/src/component-editor/scaffolding/ShadowBackdropControls.svelte +8 -3
- package/src/component-editor/scaffolding/StateBlock.svelte +30 -13
- package/src/component-editor/scaffolding/TokenLayout.svelte +46 -30
- package/src/component-editor/scaffolding/TypeEditor.svelte +52 -26
- package/src/component-editor/scaffolding/VariantGroup.svelte +81 -48
- package/src/component-editor/scaffolding/componentSectionType.ts +2 -2
- package/src/components/Badge.svelte +45 -26
- package/src/components/Button.svelte +44 -21
- package/src/components/Callout.svelte +17 -12
- package/src/components/Card.svelte +23 -11
- package/src/components/CollapsibleSection.svelte +56 -27
- package/src/components/CornerBadge.svelte +32 -18
- package/src/components/Dialog.svelte +55 -31
- package/src/components/Image.svelte +14 -5
- package/src/components/InlineEditActions.svelte +22 -10
- package/src/components/Notification.svelte +39 -19
- package/src/components/ProgressBar.svelte +27 -17
- package/src/components/RadioButton.svelte +27 -10
- package/src/components/SectionDivider.svelte +34 -26
- package/src/components/SegmentedControl.svelte +23 -9
- package/src/components/TabBar.svelte +23 -10
- package/src/components/Table.svelte +8 -3
- package/src/components/Tooltip.svelte +15 -5
- package/src/lib/ColumnsOverlay.svelte +3 -3
- package/src/lib/LiveEditorOverlay.svelte +57 -36
- package/src/pages/ComponentEditorPage.svelte +17 -13
- package/src/pages/EditorShell.svelte +24 -20
- package/src/styles/form-controls.css +2 -2
- package/src/styles/tokens.css +59 -81
- package/src/ui/BezierCurveEditor.svelte +59 -43
- package/src/ui/ColorEditPanel.svelte +71 -44
- package/src/ui/EditorViewSwitcher.svelte +9 -5
- package/src/ui/FontStackEditor.svelte +16 -15
- package/src/ui/GradientEditor.svelte +42 -33
- package/src/ui/GradientStopPicker.svelte +18 -29
- package/src/ui/PaletteEditor.svelte +238 -212
- package/src/ui/PresetFileManager.svelte +20 -18
- package/src/ui/ProjectFontsSection.svelte +30 -30
- package/src/ui/SurfacesTab.svelte +3 -3
- package/src/ui/TextTab.svelte +2 -2
- package/src/ui/ThemeFileManager.svelte +38 -35
- package/src/ui/Toggle.svelte +11 -9
- package/src/ui/UICopyPopover.svelte +19 -15
- package/src/ui/UIDialog.svelte +48 -30
- package/src/ui/UIFontFamilySelector.svelte +104 -78
- package/src/ui/UIFontSizeSelector.svelte +38 -20
- package/src/ui/UIFontWeightSelector.svelte +33 -13
- package/src/ui/UILineHeightSelector.svelte +33 -13
- package/src/ui/UILinkToggle.svelte +7 -6
- package/src/ui/UIOptionItem.svelte +21 -7
- package/src/ui/UIOptionList.svelte +9 -3
- package/src/ui/UIPaddingSelector.svelte +108 -82
- package/src/ui/UIPaletteSelector.svelte +186 -161
- package/src/ui/UIRadio.svelte +23 -8
- package/src/ui/UIRadioGroup.svelte +9 -8
- package/src/ui/UIRelinkConfirmPopover.svelte +26 -16
- package/src/ui/UITokenSelector.svelte +112 -68
- package/src/ui/UIVariantSelector.svelte +79 -57
- package/src/ui/VariablesTab.svelte +15 -15
- package/src/ui/palette/GradientStopEditor.svelte +45 -26
- package/src/ui/palette/OverridesPanel.svelte +85 -49
- package/src/ui/palette/PaletteBase.svelte +60 -32
- package/src/ui/palette/ScaleCurveEditor.svelte +25 -10
- package/src/ui/sections/ColumnsSection.svelte +13 -13
- package/src/ui/sections/GradientsSection.svelte +12 -9
- package/src/ui/sections/OverlaysSection.svelte +50 -47
- package/src/ui/sections/ShadowsSection.svelte +110 -104
- package/src/ui/sections/TokenScaleTable.svelte +38 -22
- package/src/ui/sections/tokenScales.ts +2 -2
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { run } from 'svelte/legacy';
|
|
3
|
+
|
|
2
4
|
/**
|
|
3
5
|
* Visual gradient editor. Stops are draggable diamond handles below a live
|
|
4
6
|
* ribbon; only the selected stop exposes its position + color controls (the
|
|
5
7
|
* old list of every stop is replaced by this single-row pattern, mirroring
|
|
6
8
|
* GradientCard.svelte). Stops can be added/removed with a minimum of two.
|
|
7
9
|
*/
|
|
8
|
-
import { tick, onMount
|
|
10
|
+
import { tick, onMount } from 'svelte';
|
|
9
11
|
import {
|
|
10
12
|
editorState,
|
|
11
13
|
setGradient,
|
|
@@ -19,9 +21,13 @@
|
|
|
19
21
|
import GradientStopPicker from './GradientStopPicker.svelte';
|
|
20
22
|
import AngleDial from '../component-editor/scaffolding/AngleDial.svelte';
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
interface Props {
|
|
25
|
+
variable: string;
|
|
26
|
+
onsave?: () => void;
|
|
27
|
+
oncancel?: () => void;
|
|
28
|
+
}
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
let { variable, onsave, oncancel }: Props = $props();
|
|
25
31
|
|
|
26
32
|
/** Deep snapshot of the gradient at editor open, used to restore on Cancel. */
|
|
27
33
|
let snapshot: { type: GradientType; angle: number; stops: GradientTokenStop[] } | null = null;
|
|
@@ -32,25 +38,27 @@
|
|
|
32
38
|
}
|
|
33
39
|
});
|
|
34
40
|
|
|
35
|
-
function save() {
|
|
41
|
+
function save() { onsave?.(); }
|
|
36
42
|
function cancel() {
|
|
37
43
|
if (snapshot) setGradient(variable, snapshot);
|
|
38
|
-
|
|
44
|
+
oncancel?.();
|
|
39
45
|
}
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
47
|
+
let gradient = $derived($editorState.gradients.tokens.find((t) => t.variable === variable));
|
|
48
|
+
let stopCount = $derived(gradient?.stops.length ?? 0);
|
|
43
49
|
|
|
44
|
-
let selected = 0;
|
|
50
|
+
let selected = $state(0);
|
|
45
51
|
// Keep `selected` in range as stops are added/removed.
|
|
46
|
-
|
|
52
|
+
run(() => {
|
|
53
|
+
if (selected >= stopCount) selected = Math.max(0, stopCount - 1);
|
|
54
|
+
});
|
|
47
55
|
|
|
48
56
|
function setType(type: GradientType) {
|
|
49
57
|
setGradientType(variable, type);
|
|
50
58
|
}
|
|
51
59
|
|
|
52
|
-
function onAngleChange(
|
|
53
|
-
setGradientAngle(variable,
|
|
60
|
+
function onAngleChange(detail: { value: number }) {
|
|
61
|
+
setGradientAngle(variable, detail.value);
|
|
54
62
|
}
|
|
55
63
|
|
|
56
64
|
function setPosition(i: number, pct: number) {
|
|
@@ -63,8 +71,8 @@
|
|
|
63
71
|
if (Number.isFinite(v)) setPosition(selected, v);
|
|
64
72
|
}
|
|
65
73
|
|
|
66
|
-
function handleStopChange(i: number,
|
|
67
|
-
setGradientStop(variable, i, { color:
|
|
74
|
+
function handleStopChange(i: number, payload: { color: string; opacity: number }) {
|
|
75
|
+
setGradientStop(variable, i, { color: payload.color, opacity: payload.opacity });
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
/** Insert a stop at the given percentage, inheriting color/opacity from the
|
|
@@ -103,7 +111,7 @@
|
|
|
103
111
|
* a sensible color rather than a default. */
|
|
104
112
|
function onRibbonClick(e: MouseEvent) {
|
|
105
113
|
if (!gradient || e.button !== 0) return;
|
|
106
|
-
const rect = barEl
|
|
114
|
+
const rect = barEl!.getBoundingClientRect();
|
|
107
115
|
const pct = ((e.clientX - rect.left) / rect.width) * 100;
|
|
108
116
|
const nearest = gradient.stops.reduce(
|
|
109
117
|
(best, s) => (Math.abs(s.position - pct) < Math.abs(best.position - pct) ? s : best),
|
|
@@ -119,11 +127,11 @@
|
|
|
119
127
|
}
|
|
120
128
|
|
|
121
129
|
// ── Ribbon handle drag ─────────────────────────────────────────────────
|
|
122
|
-
let barEl: HTMLDivElement;
|
|
123
|
-
let dragIndex: number | null = null;
|
|
130
|
+
let barEl: HTMLDivElement | undefined = $state();
|
|
131
|
+
let dragIndex: number | null = $state(null);
|
|
124
132
|
|
|
125
133
|
function pctFromEvent(e: PointerEvent): number {
|
|
126
|
-
const rect = barEl
|
|
134
|
+
const rect = barEl!.getBoundingClientRect();
|
|
127
135
|
const x = e.clientX - rect.left;
|
|
128
136
|
return (x / rect.width) * 100;
|
|
129
137
|
}
|
|
@@ -145,21 +153,22 @@
|
|
|
145
153
|
}
|
|
146
154
|
|
|
147
155
|
// Stop colors rendered into the diamonds: token refs become var(...).
|
|
148
|
-
|
|
156
|
+
let stopSwatches = $derived((gradient?.stops ?? []).map((s) => {
|
|
149
157
|
const base = s.color.startsWith('--') ? `var(${s.color})` : s.color;
|
|
150
158
|
const op = s.opacity ?? 100;
|
|
151
159
|
return op >= 100 ? base : `color-mix(in srgb, ${base} ${Math.round(op)}%, transparent)`;
|
|
152
|
-
});
|
|
160
|
+
}));
|
|
153
161
|
</script>
|
|
154
162
|
|
|
155
163
|
{#if gradient}
|
|
156
164
|
<div class="gradient-editor">
|
|
157
165
|
<div class="ribbon-wrap">
|
|
166
|
+
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
158
167
|
<div
|
|
159
168
|
class="ribbon"
|
|
160
169
|
bind:this={barEl}
|
|
161
170
|
style="background: var({variable});"
|
|
162
|
-
|
|
171
|
+
onclick={onRibbonClick}
|
|
163
172
|
role="button"
|
|
164
173
|
tabindex="-1"
|
|
165
174
|
aria-label="Click to add a gradient stop"
|
|
@@ -172,10 +181,10 @@
|
|
|
172
181
|
class:selected={selected === i}
|
|
173
182
|
class:dragging={dragIndex === i}
|
|
174
183
|
style="left: {stop.position}%; --stop-color: {stopSwatches[i]};"
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
184
|
+
onpointerdown={(e) => onHandleDown(e, i)}
|
|
185
|
+
onpointermove={onHandleMove}
|
|
186
|
+
onpointerup={onHandleUp}
|
|
187
|
+
onpointercancel={onHandleUp}
|
|
179
188
|
title={`Stop ${i + 1} (${stop.position}%)`}
|
|
180
189
|
aria-label={`Gradient stop ${i + 1}`}
|
|
181
190
|
>
|
|
@@ -190,24 +199,24 @@
|
|
|
190
199
|
<button
|
|
191
200
|
type="button"
|
|
192
201
|
class:active={gradient.type === 'linear'}
|
|
193
|
-
|
|
202
|
+
onclick={() => setType('linear')}
|
|
194
203
|
>Linear</button>
|
|
195
204
|
<button
|
|
196
205
|
type="button"
|
|
197
206
|
class:active={gradient.type === 'radial'}
|
|
198
|
-
|
|
207
|
+
onclick={() => setType('radial')}
|
|
199
208
|
>Radial</button>
|
|
200
209
|
</div>
|
|
201
210
|
{#if gradient.type === 'linear'}
|
|
202
211
|
<div class="angle-slot">
|
|
203
|
-
<AngleDial value={gradient.angle}
|
|
212
|
+
<AngleDial value={gradient.angle} onchange={onAngleChange} />
|
|
204
213
|
</div>
|
|
205
214
|
{/if}
|
|
206
215
|
<div class="spacer"></div>
|
|
207
216
|
<button
|
|
208
217
|
type="button"
|
|
209
218
|
class="ghost-btn"
|
|
210
|
-
|
|
219
|
+
onclick={addStop}
|
|
211
220
|
title="Add stop"
|
|
212
221
|
>
|
|
213
222
|
<i class="fas fa-plus"></i> Add stop
|
|
@@ -215,7 +224,7 @@
|
|
|
215
224
|
<button
|
|
216
225
|
type="button"
|
|
217
226
|
class="ghost-btn"
|
|
218
|
-
|
|
227
|
+
onclick={removeSelected}
|
|
219
228
|
disabled={gradient.stops.length <= 2}
|
|
220
229
|
title={gradient.stops.length <= 2 ? 'Gradient needs at least two stops' : 'Remove selected stop'}
|
|
221
230
|
>
|
|
@@ -233,7 +242,7 @@
|
|
|
233
242
|
max="100"
|
|
234
243
|
step="0.1"
|
|
235
244
|
value={gradient.stops[selected].position}
|
|
236
|
-
|
|
245
|
+
onchange={onPositionInput}
|
|
237
246
|
/>
|
|
238
247
|
<span class="suffix">%</span>
|
|
239
248
|
</label>
|
|
@@ -242,15 +251,15 @@
|
|
|
242
251
|
stopId={`${variable}-${selected}`}
|
|
243
252
|
color={gradient.stops[selected].color}
|
|
244
253
|
opacity={gradient.stops[selected].opacity ?? 100}
|
|
245
|
-
|
|
254
|
+
onchange={(payload) => handleStopChange(selected, payload)}
|
|
246
255
|
/>
|
|
247
256
|
</div>
|
|
248
257
|
</div>
|
|
249
258
|
{/if}
|
|
250
259
|
|
|
251
260
|
<div class="footer-row">
|
|
252
|
-
<button type="button" class="ghost-btn"
|
|
253
|
-
<button type="button" class="primary-btn"
|
|
261
|
+
<button type="button" class="ghost-btn" onclick={cancel}>Cancel</button>
|
|
262
|
+
<button type="button" class="primary-btn" onclick={save}>Save</button>
|
|
254
263
|
</div>
|
|
255
264
|
</div>
|
|
256
265
|
{/if}
|
|
@@ -5,18 +5,20 @@
|
|
|
5
5
|
* to that scratch var get parsed back out and forwarded as a structured update
|
|
6
6
|
* to gradient state, so we don't have to refactor UIPaletteSelector itself.
|
|
7
7
|
*/
|
|
8
|
-
import { onDestroy, createEventDispatcher } from 'svelte';
|
|
9
8
|
import UIPaletteSelector from './UIPaletteSelector.svelte';
|
|
10
9
|
import { setCssVar, removeCssVar } from '../lib/cssVarSync';
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
interface Props {
|
|
12
|
+
stopId: string; // unique key (e.g. gradient-var + stop index)
|
|
13
|
+
color: string; // token name like '--color-brand-500'
|
|
14
|
+
opacity?: number; // 0–100
|
|
15
|
+
onchange?: (payload: { color: string; opacity: number }) => void;
|
|
16
|
+
}
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
let { stopId, color, opacity = 100, onchange }: Props = $props();
|
|
17
19
|
|
|
18
20
|
/** Scratch var the embedded picker reads/writes; isolated per stop. */
|
|
19
|
-
|
|
21
|
+
let scratchVar = $derived(`--__grad-stop-${stopId}`);
|
|
20
22
|
|
|
21
23
|
function buildScratchValue(c: string, o: number): string {
|
|
22
24
|
const base = c.startsWith('--') ? `var(${c})` : c;
|
|
@@ -39,36 +41,23 @@
|
|
|
39
41
|
return null;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
// Seed
|
|
43
|
-
//
|
|
44
|
-
|
|
44
|
+
// Seed (and re-seed on external updates like undo/redo) the scratch var so
|
|
45
|
+
// UIPaletteSelector reads the current stop value. The effect's cleanup runs
|
|
46
|
+
// on dependency change AND unmount, so it removes the right key even if
|
|
47
|
+
// stopId changes mid-life.
|
|
48
|
+
$effect(() => {
|
|
45
49
|
setCssVar(scratchVar, buildScratchValue(color, opacity));
|
|
46
|
-
|
|
50
|
+
const key = scratchVar;
|
|
51
|
+
return () => removeCssVar(key);
|
|
52
|
+
});
|
|
47
53
|
|
|
48
54
|
function handleChange() {
|
|
49
55
|
const raw = document.documentElement.style.getPropertyValue(scratchVar);
|
|
50
56
|
const parsed = parseScratch(raw);
|
|
51
57
|
if (!parsed) return;
|
|
52
58
|
if (parsed.color === color && parsed.opacity === opacity) return;
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
onDestroy(() => {
|
|
57
|
-
removeCssVar(scratchVar);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
// When external state updates the stop (undo/redo, sibling-stop edits),
|
|
61
|
-
// refresh the scratch so the picker reflects current values.
|
|
62
|
-
let lastSynced = `${color}|${opacity}`;
|
|
63
|
-
$: {
|
|
64
|
-
const sig = `${color}|${opacity}`;
|
|
65
|
-
if (sig !== lastSynced) {
|
|
66
|
-
lastSynced = sig;
|
|
67
|
-
if (typeof document !== 'undefined') {
|
|
68
|
-
setCssVar(scratchVar, buildScratchValue(color, opacity));
|
|
69
|
-
}
|
|
70
|
-
}
|
|
59
|
+
onchange?.(parsed);
|
|
71
60
|
}
|
|
72
61
|
</script>
|
|
73
62
|
|
|
74
|
-
<UIPaletteSelector variable={scratchVar}
|
|
63
|
+
<UIPaletteSelector variable={scratchVar} onchange={handleChange} />
|