@dryui/theme-wizard 4.0.0 → 5.0.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/package.json +5 -5
- package/dist/actions.d.ts +0 -4
- package/dist/actions.js +0 -9
- package/dist/components/AlphaSlider.svelte +0 -13
- package/dist/components/AlphaSlider.svelte.d.ts +0 -9
- package/dist/components/ContrastBadge.svelte +0 -22
- package/dist/components/ContrastBadge.svelte.d.ts +0 -8
- package/dist/components/HsbPicker.svelte +0 -304
- package/dist/components/HsbPicker.svelte.d.ts +0 -9
- package/dist/components/StepIndicator.svelte +0 -87
- package/dist/components/StepIndicator.svelte.d.ts +0 -7
- package/dist/components/TokenPreview.svelte +0 -55
- package/dist/components/TokenPreview.svelte.d.ts +0 -8
- package/dist/components/WizardShell.svelte +0 -140
- package/dist/components/WizardShell.svelte.d.ts +0 -15
- package/dist/engine/derivation.d.ts +0 -282
- package/dist/engine/derivation.js +0 -1445
- package/dist/engine/derivation.test.d.ts +0 -1
- package/dist/engine/derivation.test.js +0 -956
- package/dist/engine/export-css.d.ts +0 -32
- package/dist/engine/export-css.js +0 -90
- package/dist/engine/export-css.test.d.ts +0 -1
- package/dist/engine/export-css.test.js +0 -78
- package/dist/engine/index.d.ts +0 -10
- package/dist/engine/index.js +0 -6
- package/dist/engine/palette.d.ts +0 -16
- package/dist/engine/palette.js +0 -44
- package/dist/engine/presets.d.ts +0 -13
- package/dist/engine/presets.js +0 -124
- package/dist/engine/url-codec.d.ts +0 -53
- package/dist/engine/url-codec.js +0 -243
- package/dist/engine/url-codec.test.d.ts +0 -1
- package/dist/engine/url-codec.test.js +0 -137
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -19
- package/dist/state.svelte.d.ts +0 -104
- package/dist/state.svelte.js +0 -574
- package/dist/steps/BrandColor.svelte +0 -216
- package/dist/steps/BrandColor.svelte.d.ts +0 -6
- package/dist/steps/Personality.svelte +0 -319
- package/dist/steps/Personality.svelte.d.ts +0 -3
- package/dist/steps/PreviewExport.svelte +0 -115
- package/dist/steps/PreviewExport.svelte.d.ts +0 -9
- package/dist/steps/Shape.svelte +0 -121
- package/dist/steps/Shape.svelte.d.ts +0 -18
- package/dist/steps/Typography.svelte +0 -115
- package/dist/steps/Typography.svelte.d.ts +0 -18
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dryui/theme-wizard",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.1",
|
|
4
4
|
"author": "Rob Balfre",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
"check": "svelte-check --tsconfig ./tsconfig.json"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"@dryui/primitives": "^0.
|
|
41
|
-
"@dryui/ui": "^0.
|
|
40
|
+
"@dryui/primitives": "^0.5.1",
|
|
41
|
+
"@dryui/ui": "^0.5.1",
|
|
42
42
|
"lucide-svelte": ">=1.0.1",
|
|
43
43
|
"svelte": "^5.55.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@dryui/lint": "^0.2.0",
|
|
47
|
-
"@dryui/primitives": "^0.
|
|
48
|
-
"@dryui/ui": "^0.
|
|
47
|
+
"@dryui/primitives": "^0.5.1",
|
|
48
|
+
"@dryui/ui": "^0.5.1",
|
|
49
49
|
"lucide-svelte": "^1.0.1",
|
|
50
50
|
"svelte": "^5.55.3",
|
|
51
51
|
"@sveltejs/package": "^2.5.7",
|
package/dist/actions.d.ts
DELETED
package/dist/actions.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { AlphaSlider } from '@dryui/ui/alpha-slider';
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
value?: number;
|
|
6
|
-
color?: string;
|
|
7
|
-
onchange?: (value: number) => void;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
let { value = $bindable(50), color = 'hsl(230, 65%, 55%)', onchange }: Props = $props();
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<AlphaSlider bind:value {color} {...onchange ? { onchange } : {}} />
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { AlphaSlider } from '@dryui/ui/alpha-slider';
|
|
2
|
-
interface Props {
|
|
3
|
-
value?: number;
|
|
4
|
-
color?: string;
|
|
5
|
-
onchange?: (value: number) => void;
|
|
6
|
-
}
|
|
7
|
-
declare const AlphaSlider: import("svelte").Component<Props, {}, "value">;
|
|
8
|
-
type AlphaSlider = ReturnType<typeof AlphaSlider>;
|
|
9
|
-
export default AlphaSlider;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { Badge } from '@dryui/ui/badge';
|
|
3
|
-
import { contrastBetweenCssColors } from '../engine/derivation.js';
|
|
4
|
-
|
|
5
|
-
interface Props {
|
|
6
|
-
foreground: string;
|
|
7
|
-
background: string;
|
|
8
|
-
threshold?: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
let { foreground, background, threshold = 4.5 }: Props = $props();
|
|
12
|
-
|
|
13
|
-
let ratio = $derived(contrastBetweenCssColors(foreground, background));
|
|
14
|
-
|
|
15
|
-
let passes = $derived(ratio !== null && ratio >= threshold);
|
|
16
|
-
let ratioLabel = $derived(ratio !== null ? `${ratio.toFixed(1)}:1` : '---');
|
|
17
|
-
let badgeColor = $derived<'success' | 'danger' | 'gray'>(
|
|
18
|
-
ratio === null ? 'gray' : passes ? 'success' : 'danger'
|
|
19
|
-
);
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<Badge variant="soft" color={badgeColor} size="sm">{ratioLabel}</Badge>
|
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { Slider } from '@dryui/ui/slider';
|
|
3
|
-
import { NumberInput } from '@dryui/ui/number-input';
|
|
4
|
-
import { Input } from '@dryui/ui/input';
|
|
5
|
-
import { Field } from '@dryui/ui/field';
|
|
6
|
-
import { Label } from '@dryui/ui/label';
|
|
7
|
-
import { hsbToHsl, hslToHex, hexToHsl, hslToHsb } from '../engine/derivation.js';
|
|
8
|
-
|
|
9
|
-
interface Props {
|
|
10
|
-
h?: number;
|
|
11
|
-
s?: number;
|
|
12
|
-
b?: number;
|
|
13
|
-
onchange?: (h: number, s: number, b: number) => void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
let { h = $bindable(230), s = $bindable(65), b = $bindable(85), onchange }: Props = $props();
|
|
17
|
-
|
|
18
|
-
let canvas: HTMLCanvasElement | undefined = $state();
|
|
19
|
-
let isDragging = $state(false);
|
|
20
|
-
|
|
21
|
-
// Derived hex value from current HSB
|
|
22
|
-
let hexValue = $derived.by(() => {
|
|
23
|
-
const hsl = hsbToHsl(h, s / 100, b / 100);
|
|
24
|
-
return hslToHex(hsl.h, hsl.s, hsl.l);
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// Derived preview color as CSS hsl string
|
|
28
|
-
let previewColor = $derived.by(() => {
|
|
29
|
-
const hsl = hsbToHsl(h, s / 100, b / 100);
|
|
30
|
-
return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s * 100)}%, ${Math.round(hsl.l * 100)}%)`;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Pure hue color for canvas gradient (full saturation, full brightness)
|
|
34
|
-
let hueColor = $derived.by(() => {
|
|
35
|
-
const hsl = hsbToHsl(h, 1, 1);
|
|
36
|
-
return `hsl(${Math.round(hsl.h)}, ${Math.round(hsl.s * 100)}%, ${Math.round(hsl.l * 100)}%)`;
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
function drawCanvas() {
|
|
40
|
-
if (!canvas) return;
|
|
41
|
-
const ctx = canvas.getContext('2d');
|
|
42
|
-
if (!ctx) return;
|
|
43
|
-
|
|
44
|
-
const width = canvas.width;
|
|
45
|
-
const height = canvas.height;
|
|
46
|
-
|
|
47
|
-
// Horizontal gradient: white -> full hue color
|
|
48
|
-
const hGrad = ctx.createLinearGradient(0, 0, width, 0);
|
|
49
|
-
hGrad.addColorStop(0, '#ffffff');
|
|
50
|
-
hGrad.addColorStop(1, hueColor);
|
|
51
|
-
ctx.fillStyle = hGrad;
|
|
52
|
-
ctx.fillRect(0, 0, width, height);
|
|
53
|
-
|
|
54
|
-
// Vertical gradient: transparent -> black (overlay)
|
|
55
|
-
const vGrad = ctx.createLinearGradient(0, 0, 0, height);
|
|
56
|
-
vGrad.addColorStop(0, 'rgba(0,0,0,0)');
|
|
57
|
-
vGrad.addColorStop(1, 'rgba(0,0,0,1)');
|
|
58
|
-
ctx.fillStyle = vGrad;
|
|
59
|
-
ctx.fillRect(0, 0, width, height);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
$effect(() => {
|
|
63
|
-
// Redraw canvas when hue changes (hueColor is derived from h)
|
|
64
|
-
void hueColor;
|
|
65
|
-
drawCanvas();
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
$effect(() => {
|
|
69
|
-
// Initial draw once canvas is mounted
|
|
70
|
-
if (canvas) {
|
|
71
|
-
drawCanvas();
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
function getPositionFromEvent(e: PointerEvent): { x: number; y: number } {
|
|
76
|
-
if (!canvas) return { x: 0, y: 0 };
|
|
77
|
-
const rect = canvas.getBoundingClientRect();
|
|
78
|
-
const x = Math.max(0, Math.min(e.clientX - rect.left, rect.width));
|
|
79
|
-
const y = Math.max(0, Math.min(e.clientY - rect.top, rect.height));
|
|
80
|
-
return { x, y };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function updateFromCanvasPosition(x: number, y: number) {
|
|
84
|
-
if (!canvas) return;
|
|
85
|
-
const newS = Math.round((x / canvas.width) * 100);
|
|
86
|
-
const newB = Math.round((1 - y / canvas.height) * 100);
|
|
87
|
-
s = Math.max(0, Math.min(100, newS));
|
|
88
|
-
b = Math.max(0, Math.min(100, newB));
|
|
89
|
-
onchange?.(h, s, b);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function handlePointerDown(e: PointerEvent) {
|
|
93
|
-
if (!canvas) return;
|
|
94
|
-
isDragging = true;
|
|
95
|
-
canvas.setPointerCapture(e.pointerId);
|
|
96
|
-
const { x, y } = getPositionFromEvent(e);
|
|
97
|
-
updateFromCanvasPosition(x, y);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function handlePointerMove(e: PointerEvent) {
|
|
101
|
-
if (!isDragging) return;
|
|
102
|
-
const { x, y } = getPositionFromEvent(e);
|
|
103
|
-
updateFromCanvasPosition(x, y);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
function handlePointerUp(e: PointerEvent) {
|
|
107
|
-
isDragging = false;
|
|
108
|
-
if (canvas) canvas.releasePointerCapture(e.pointerId);
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function handleHexInput(val: string) {
|
|
112
|
-
const hex = val.trim();
|
|
113
|
-
if (/^#[0-9a-fA-F]{6}$/.test(hex)) {
|
|
114
|
-
try {
|
|
115
|
-
const hsl = hexToHsl(hex);
|
|
116
|
-
const hsb = hslToHsb(hsl.h, hsl.s, hsl.l);
|
|
117
|
-
h = Math.round(hsb.h);
|
|
118
|
-
s = Math.round(hsb.s * 100);
|
|
119
|
-
b = Math.round(hsb.b * 100);
|
|
120
|
-
onchange?.(h, s, b);
|
|
121
|
-
} catch {
|
|
122
|
-
// invalid hex, ignore
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Crosshair position on canvas
|
|
128
|
-
let crosshairX = $derived((s / 100) * 256);
|
|
129
|
-
let crosshairY = $derived((1 - b / 100) * 256);
|
|
130
|
-
|
|
131
|
-
function crosshairPosition(node: HTMLElement) {
|
|
132
|
-
$effect(() => {
|
|
133
|
-
node.style.setProperty('left', `${crosshairX}px`);
|
|
134
|
-
node.style.setProperty('top', `${crosshairY}px`);
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function swatchBackground(node: HTMLElement) {
|
|
139
|
-
$effect(() => {
|
|
140
|
-
node.style.setProperty('background', previewColor);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// Local bindable values for number inputs
|
|
145
|
-
let hValue = $state(h);
|
|
146
|
-
let sValue = $state(s);
|
|
147
|
-
let bValue = $state(b);
|
|
148
|
-
let hexInputValue = $state('');
|
|
149
|
-
|
|
150
|
-
// Sync external changes to local state
|
|
151
|
-
$effect(() => {
|
|
152
|
-
hValue = h;
|
|
153
|
-
});
|
|
154
|
-
$effect(() => {
|
|
155
|
-
sValue = s;
|
|
156
|
-
});
|
|
157
|
-
$effect(() => {
|
|
158
|
-
bValue = b;
|
|
159
|
-
});
|
|
160
|
-
$effect(() => {
|
|
161
|
-
hexInputValue = hexValue;
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
// React to local number input changes
|
|
165
|
-
$effect(() => {
|
|
166
|
-
const clamped = Math.max(0, Math.min(360, hValue));
|
|
167
|
-
if (clamped !== h) {
|
|
168
|
-
h = clamped;
|
|
169
|
-
onchange?.(h, s, b);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
$effect(() => {
|
|
173
|
-
const clamped = Math.max(0, Math.min(100, sValue));
|
|
174
|
-
if (clamped !== s) {
|
|
175
|
-
s = clamped;
|
|
176
|
-
onchange?.(h, s, b);
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
$effect(() => {
|
|
180
|
-
const clamped = Math.max(0, Math.min(100, bValue));
|
|
181
|
-
if (clamped !== b) {
|
|
182
|
-
b = clamped;
|
|
183
|
-
onchange?.(h, s, b);
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
</script>
|
|
187
|
-
|
|
188
|
-
<div class="hsb-picker-root">
|
|
189
|
-
<div class="canvas-wrapper">
|
|
190
|
-
<canvas
|
|
191
|
-
bind:this={canvas}
|
|
192
|
-
width={256}
|
|
193
|
-
height={256}
|
|
194
|
-
class="saturation-canvas"
|
|
195
|
-
onpointerdown={handlePointerDown}
|
|
196
|
-
onpointermove={handlePointerMove}
|
|
197
|
-
onpointerup={handlePointerUp}
|
|
198
|
-
></canvas>
|
|
199
|
-
<div class="crosshair" use:crosshairPosition></div>
|
|
200
|
-
</div>
|
|
201
|
-
|
|
202
|
-
<div class="row-slider">
|
|
203
|
-
<Slider
|
|
204
|
-
bind:value={h}
|
|
205
|
-
min={0}
|
|
206
|
-
max={360}
|
|
207
|
-
step={1}
|
|
208
|
-
size="sm"
|
|
209
|
-
oninput={() => onchange?.(h, s, b)}
|
|
210
|
-
/>
|
|
211
|
-
</div>
|
|
212
|
-
|
|
213
|
-
<div class="row-fields-end">
|
|
214
|
-
<div class="hsb-field">
|
|
215
|
-
<Field.Root>
|
|
216
|
-
<Label size="sm">H</Label>
|
|
217
|
-
<NumberInput bind:value={hValue} min={0} max={360} step={1} size="sm" />
|
|
218
|
-
</Field.Root>
|
|
219
|
-
</div>
|
|
220
|
-
<div class="hsb-field">
|
|
221
|
-
<Field.Root>
|
|
222
|
-
<Label size="sm">S</Label>
|
|
223
|
-
<NumberInput bind:value={sValue} min={0} max={100} step={1} size="sm" />
|
|
224
|
-
</Field.Root>
|
|
225
|
-
</div>
|
|
226
|
-
<div class="hsb-field">
|
|
227
|
-
<Field.Root>
|
|
228
|
-
<Label size="sm">B</Label>
|
|
229
|
-
<NumberInput bind:value={bValue} min={0} max={100} step={1} size="sm" />
|
|
230
|
-
</Field.Root>
|
|
231
|
-
</div>
|
|
232
|
-
</div>
|
|
233
|
-
|
|
234
|
-
<div class="row-swatch">
|
|
235
|
-
<div class="preview-swatch" use:swatchBackground></div>
|
|
236
|
-
<Input
|
|
237
|
-
bind:value={hexInputValue}
|
|
238
|
-
size="sm"
|
|
239
|
-
placeholder="#000000"
|
|
240
|
-
oninput={() => handleHexInput(hexInputValue)}
|
|
241
|
-
/>
|
|
242
|
-
</div>
|
|
243
|
-
</div>
|
|
244
|
-
|
|
245
|
-
<style>
|
|
246
|
-
.hsb-picker-root {
|
|
247
|
-
display: grid;
|
|
248
|
-
grid-template-columns: 256px;
|
|
249
|
-
gap: var(--dry-space-2);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
.row-slider {
|
|
253
|
-
display: grid;
|
|
254
|
-
grid-auto-flow: column;
|
|
255
|
-
grid-auto-columns: 1fr;
|
|
256
|
-
align-items: center;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.row-fields-end {
|
|
260
|
-
display: grid;
|
|
261
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
262
|
-
align-items: end;
|
|
263
|
-
gap: var(--dry-space-2);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
.row-swatch {
|
|
267
|
-
display: grid;
|
|
268
|
-
grid-template-columns: var(--dry-space-8) minmax(0, 1fr);
|
|
269
|
-
align-items: center;
|
|
270
|
-
gap: var(--dry-space-2);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
.canvas-wrapper {
|
|
274
|
-
position: relative;
|
|
275
|
-
height: 256px;
|
|
276
|
-
border-radius: var(--dry-radius-md);
|
|
277
|
-
overflow: hidden;
|
|
278
|
-
cursor: crosshair;
|
|
279
|
-
border: 1px solid var(--dry-color-stroke-weak);
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
.saturation-canvas {
|
|
283
|
-
display: block;
|
|
284
|
-
height: 256px;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
.crosshair {
|
|
288
|
-
position: absolute;
|
|
289
|
-
aspect-ratio: 1;
|
|
290
|
-
height: 12px;
|
|
291
|
-
border-radius: 50%;
|
|
292
|
-
border: 2px solid var(--dry-color-bg-overlay);
|
|
293
|
-
box-shadow: 0 0 0 1px color-mix(in srgb, var(--dry-color-text-strong) 40%, transparent);
|
|
294
|
-
transform: translate(-50%, -50%);
|
|
295
|
-
pointer-events: none;
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
.preview-swatch {
|
|
299
|
-
aspect-ratio: 1;
|
|
300
|
-
height: var(--dry-space-8);
|
|
301
|
-
border-radius: var(--dry-radius-md);
|
|
302
|
-
border: 1px solid var(--dry-color-stroke-weak);
|
|
303
|
-
}
|
|
304
|
-
</style>
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
interface Props {
|
|
2
|
-
h?: number;
|
|
3
|
-
s?: number;
|
|
4
|
-
b?: number;
|
|
5
|
-
onchange?: (h: number, s: number, b: number) => void;
|
|
6
|
-
}
|
|
7
|
-
declare const HsbPicker: import("svelte").Component<Props, {}, "b" | "h" | "s">;
|
|
8
|
-
type HsbPicker = ReturnType<typeof HsbPicker>;
|
|
9
|
-
export default HsbPicker;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { Stepper } from '@dryui/ui/stepper';
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
currentStep?: number;
|
|
6
|
-
onstep?: (step: number) => void;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
let { currentStep = 1, onstep }: Props = $props();
|
|
10
|
-
|
|
11
|
-
let navEl = $state<HTMLElement | null>(null);
|
|
12
|
-
|
|
13
|
-
const STEPS = [
|
|
14
|
-
{ n: 1, label: 'Personality' },
|
|
15
|
-
{ n: 2, label: 'Brand' },
|
|
16
|
-
{ n: 3, label: 'Typography' },
|
|
17
|
-
{ n: 4, label: 'Shape' },
|
|
18
|
-
{ n: 5, label: 'Preview' }
|
|
19
|
-
];
|
|
20
|
-
|
|
21
|
-
// Stepper uses 0-based indexing; wizard uses 1-based
|
|
22
|
-
let activeStepIndex = $derived(currentStep - 1);
|
|
23
|
-
|
|
24
|
-
function handleStepClick(index: number) {
|
|
25
|
-
onstep?.(index + 1);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
$effect(() => {
|
|
29
|
-
currentStep;
|
|
30
|
-
|
|
31
|
-
if (!navEl) return;
|
|
32
|
-
|
|
33
|
-
requestAnimationFrame(() => {
|
|
34
|
-
const activeStep = navEl?.querySelector(
|
|
35
|
-
"[aria-current='step'] [data-part='indicator-button']"
|
|
36
|
-
);
|
|
37
|
-
if (activeStep instanceof HTMLElement) {
|
|
38
|
-
activeStep.scrollIntoView({
|
|
39
|
-
block: 'nearest',
|
|
40
|
-
inline: 'center'
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
</script>
|
|
46
|
-
|
|
47
|
-
<nav bind:this={navEl} class="wizard-stepper" aria-label="Wizard steps">
|
|
48
|
-
<Stepper.Root activeStep={activeStepIndex}>
|
|
49
|
-
<Stepper.List>
|
|
50
|
-
{#each STEPS as step, i (step.n)}
|
|
51
|
-
{#if i > 0}
|
|
52
|
-
<Stepper.Separator step={i} />
|
|
53
|
-
{/if}
|
|
54
|
-
<Stepper.Step step={i} clickable onclick={handleStepClick}>
|
|
55
|
-
{step.label}
|
|
56
|
-
</Stepper.Step>
|
|
57
|
-
{/each}
|
|
58
|
-
</Stepper.List>
|
|
59
|
-
</Stepper.Root>
|
|
60
|
-
</nav>
|
|
61
|
-
|
|
62
|
-
<style>
|
|
63
|
-
.wizard-stepper {
|
|
64
|
-
container-type: inline-size;
|
|
65
|
-
overflow-x: auto;
|
|
66
|
-
padding-bottom: var(--dry-space-1);
|
|
67
|
-
scrollbar-width: none;
|
|
68
|
-
display: grid;
|
|
69
|
-
grid-template-columns: max-content;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.wizard-stepper::-webkit-scrollbar {
|
|
73
|
-
display: none;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
@container (max-width: 30rem) {
|
|
77
|
-
.wizard-stepper {
|
|
78
|
-
--dry-stepper-gap: var(--dry-space-1);
|
|
79
|
-
--dry-stepper-indicator-size: 0.875rem;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/* Narrow-screen override for step label font size via CSS custom property. */
|
|
83
|
-
.wizard-stepper {
|
|
84
|
-
--dry-type-small-size: 0.75rem;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
</style>
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
interface Props {
|
|
3
|
-
name: string;
|
|
4
|
-
value: string;
|
|
5
|
-
showValue?: boolean;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
let { name, value, showValue = true }: Props = $props();
|
|
9
|
-
|
|
10
|
-
import { bg } from '../actions';
|
|
11
|
-
|
|
12
|
-
let label = $derived(name.replace(/^--dry-/, ''));
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<div class="token-preview">
|
|
16
|
-
<div class="swatch" use:bg={value}></div>
|
|
17
|
-
<div class="token-info">
|
|
18
|
-
<span class="token-name">{label}</span>
|
|
19
|
-
{#if showValue}
|
|
20
|
-
<span class="token-value">{value}</span>
|
|
21
|
-
{/if}
|
|
22
|
-
</div>
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<style>
|
|
26
|
-
.token-preview {
|
|
27
|
-
display: grid;
|
|
28
|
-
grid-template-columns: 2rem 1fr;
|
|
29
|
-
align-items: center;
|
|
30
|
-
gap: var(--dry-space-2);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.swatch {
|
|
34
|
-
aspect-ratio: 1;
|
|
35
|
-
border-radius: var(--dry-radius-sm, 4px);
|
|
36
|
-
border: 1px solid var(--dry-color-stroke-weak);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.token-info {
|
|
40
|
-
display: grid;
|
|
41
|
-
gap: var(--dry-space-1);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
.token-name {
|
|
45
|
-
font-family: var(--dry-font-mono);
|
|
46
|
-
font-size: var(--dry-type-small-size);
|
|
47
|
-
color: var(--dry-color-text-strong);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.token-value {
|
|
51
|
-
font-family: var(--dry-font-mono);
|
|
52
|
-
font-size: var(--dry-type-xs-size, 0.7rem);
|
|
53
|
-
color: var(--dry-color-text-weak);
|
|
54
|
-
}
|
|
55
|
-
</style>
|