@dryui/theme-wizard 3.0.0 → 4.0.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/dist/engine/index.d.ts +2 -2
- package/dist/engine/index.js +1 -1
- package/dist/engine/presets.d.ts +7 -0
- package/dist/engine/presets.js +90 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/steps/BrandColor.svelte +33 -35
- package/package.json +5 -5
package/dist/engine/index.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ export { encodeTheme, decodeTheme, encodeRecipe, decodeRecipe } from './url-code
|
|
|
6
6
|
export type { DecodedTheme, WizardRecipe } from './url-codec.js';
|
|
7
7
|
export { generatePalette, textToBrand } from './palette.js';
|
|
8
8
|
export type { PaletteResult } from './palette.js';
|
|
9
|
-
export { PRESETS } from './presets.js';
|
|
10
|
-
export type { Preset } from './presets.js';
|
|
9
|
+
export { PRESETS, RECIPE_PRESETS } from './presets.js';
|
|
10
|
+
export type { Preset, RecipePreset } from './presets.js';
|
package/dist/engine/index.js
CHANGED
|
@@ -3,4 +3,4 @@ export { hsbToHsl, hslToHsb, hslToRgb, hslToHex, hexToHsl, cssColorToRgb, relati
|
|
|
3
3
|
export { generateCss, downloadCss, copyCss, exportJson } from './export-css.js';
|
|
4
4
|
export { encodeTheme, decodeTheme, encodeRecipe, decodeRecipe } from './url-codec.js';
|
|
5
5
|
export { generatePalette, textToBrand } from './palette.js';
|
|
6
|
-
export { PRESETS } from './presets.js';
|
|
6
|
+
export { PRESETS, RECIPE_PRESETS } from './presets.js';
|
package/dist/engine/presets.d.ts
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import type { BrandInput } from './derivation.js';
|
|
2
|
+
import type { WizardRecipe } from './url-codec.js';
|
|
2
3
|
export interface Preset {
|
|
3
4
|
name: string;
|
|
4
5
|
brandInput: BrandInput;
|
|
5
6
|
}
|
|
6
7
|
export declare const PRESETS: Preset[];
|
|
8
|
+
export interface RecipePreset {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
recipe: WizardRecipe;
|
|
12
|
+
}
|
|
13
|
+
export declare const RECIPE_PRESETS: RecipePreset[];
|
package/dist/engine/presets.js
CHANGED
|
@@ -32,3 +32,93 @@ export const PRESETS = [
|
|
|
32
32
|
brandInput: { h: 10, s: 85, b: 75 }
|
|
33
33
|
}
|
|
34
34
|
];
|
|
35
|
+
export const RECIPE_PRESETS = [
|
|
36
|
+
{
|
|
37
|
+
name: 'Default',
|
|
38
|
+
description: 'Balanced starting point',
|
|
39
|
+
recipe: {
|
|
40
|
+
brand: { h: 230, s: 65, b: 85 },
|
|
41
|
+
personality: 'structured',
|
|
42
|
+
typography: { fontPreset: 'System', scale: 'default' },
|
|
43
|
+
shape: { radiusPreset: 'soft', radiusScale: 1, density: 'default' },
|
|
44
|
+
shadows: { preset: 'elevated', intensity: 1, tintBrand: true }
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'Dashboard',
|
|
49
|
+
description: 'Dense, data-first interface',
|
|
50
|
+
recipe: {
|
|
51
|
+
brand: { h: 200, s: 80, b: 70 },
|
|
52
|
+
personality: 'structured',
|
|
53
|
+
typography: { fontPreset: 'Geometric', scale: 'compact' },
|
|
54
|
+
shape: { radiusPreset: 'sharp', radiusScale: 1, density: 'compact' },
|
|
55
|
+
shadows: { preset: 'subtle', intensity: 1, tintBrand: false }
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'Editorial',
|
|
60
|
+
description: 'Warm, readable, content-forward',
|
|
61
|
+
recipe: {
|
|
62
|
+
brand: { h: 340, s: 65, b: 85 },
|
|
63
|
+
personality: 'clean',
|
|
64
|
+
typography: { fontPreset: 'Serif', scale: 'spacious' },
|
|
65
|
+
shape: { radiusPreset: 'soft', radiusScale: 1, density: 'spacious' },
|
|
66
|
+
shadows: { preset: 'flat', intensity: 1, tintBrand: true }
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'Terminal',
|
|
71
|
+
description: 'Precise, monospace, technical',
|
|
72
|
+
recipe: {
|
|
73
|
+
brand: { h: 145, s: 60, b: 55 },
|
|
74
|
+
personality: 'minimal',
|
|
75
|
+
typography: { fontPreset: 'Mono', scale: 'compact' },
|
|
76
|
+
shape: { radiusPreset: 'sharp', radiusScale: 1, density: 'compact' },
|
|
77
|
+
shadows: { preset: 'flat', intensity: 1, tintBrand: false }
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
name: 'Playful',
|
|
82
|
+
description: 'Warm, rounded, approachable',
|
|
83
|
+
recipe: {
|
|
84
|
+
brand: { h: 25, s: 80, b: 90 },
|
|
85
|
+
personality: 'rich',
|
|
86
|
+
typography: { fontPreset: 'Humanist', scale: 'default' },
|
|
87
|
+
shape: { radiusPreset: 'pill', radiusScale: 1, density: 'default' },
|
|
88
|
+
shadows: { preset: 'deep', intensity: 1, tintBrand: true }
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'Corporate',
|
|
93
|
+
description: 'Professional and measured',
|
|
94
|
+
recipe: {
|
|
95
|
+
brand: { h: 230, s: 65, b: 85 },
|
|
96
|
+
personality: 'structured',
|
|
97
|
+
typography: { fontPreset: 'Classical', scale: 'default' },
|
|
98
|
+
shape: { radiusPreset: 'soft', radiusScale: 1, density: 'default' },
|
|
99
|
+
shadows: { preset: 'elevated', intensity: 1, tintBrand: false }
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'Midnight',
|
|
104
|
+
description: 'Dark, atmospheric, layered',
|
|
105
|
+
recipe: {
|
|
106
|
+
brand: { h: 270, s: 45, b: 80 },
|
|
107
|
+
personality: 'rich',
|
|
108
|
+
typography: { fontPreset: 'System', scale: 'default' },
|
|
109
|
+
shape: { radiusPreset: 'rounded', radiusScale: 1, density: 'default' },
|
|
110
|
+
shadows: { preset: 'deep', intensity: 1, tintBrand: true }
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
name: 'Ember',
|
|
115
|
+
description: 'Bold, warm, high contrast',
|
|
116
|
+
recipe: {
|
|
117
|
+
brand: { h: 10, s: 85, b: 75 },
|
|
118
|
+
personality: 'structured',
|
|
119
|
+
typography: { fontPreset: 'Geometric', scale: 'default' },
|
|
120
|
+
shape: { radiusPreset: 'rounded', radiusScale: 1, density: 'default' },
|
|
121
|
+
shadows: { preset: 'elevated', intensity: 1, tintBrand: true }
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from './engine/index.js';
|
|
2
|
+
export { bg } from './actions.js';
|
|
2
3
|
export { wizardState, getDerivedTheme, setBrandHsb, setStep, goNextStep, goPrevStep, activateFastTrack, applyPreset, getStyleString, setFontPreset, setTypeScale, resetToDefaults, applyRecipe, setRadiusPreset, setRadiusScale, setDensity, getShadowTokens, getShapeTokens, setPersonality, getPersonalityTokens, getAllTokens, getOverrideTokens, RADIUS_PRESETS, FONT_STACKS } from './state.svelte.js';
|
|
3
4
|
export type { PreviewMode, NeutralMode, RadiusPreset, Density, ShadowPreset, Personality, TypeScale, FontPreset } from './state.svelte.js';
|
|
4
5
|
export { default as PersonalityStep } from './steps/Personality.svelte';
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Re-export all engine functions and types
|
|
2
2
|
export * from './engine/index.js';
|
|
3
|
+
// Re-export actions
|
|
4
|
+
export { bg } from './actions.js';
|
|
3
5
|
// Re-export state (Svelte 5 runes)
|
|
4
6
|
export { wizardState, getDerivedTheme, setBrandHsb, setStep, goNextStep, goPrevStep, activateFastTrack, applyPreset, getStyleString, setFontPreset, setTypeScale, resetToDefaults, applyRecipe, setRadiusPreset, setRadiusScale, setDensity, getShadowTokens, getShapeTokens, setPersonality, getPersonalityTokens, getAllTokens, getOverrideTokens, RADIUS_PRESETS, FONT_STACKS } from './state.svelte.js';
|
|
5
7
|
// Step components
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import { Button } from '@dryui/ui';
|
|
2
3
|
import { ColorPicker } from '@dryui/ui/color-picker';
|
|
3
4
|
import { Text } from '@dryui/ui/text';
|
|
4
5
|
import { setBrandHsb, getDerivedTheme, wizardState } from '../state.svelte.js';
|
|
@@ -10,17 +11,11 @@
|
|
|
10
11
|
hsbToHsl,
|
|
11
12
|
hslToHex
|
|
12
13
|
} from '../engine/index.js';
|
|
13
|
-
import type { BrandInput } from '../engine/index.js';
|
|
14
14
|
import { bg } from '../actions';
|
|
15
15
|
|
|
16
16
|
let { mode = 'light' }: { mode?: 'light' | 'dark' } = $props();
|
|
17
17
|
|
|
18
18
|
let isDark = $derived(mode === 'dark');
|
|
19
|
-
let brand = $state<BrandInput>({ ...wizardState.brandHsb });
|
|
20
|
-
|
|
21
|
-
$effect(() => {
|
|
22
|
-
setBrandHsb(brand.h, brand.s, brand.b);
|
|
23
|
-
});
|
|
24
19
|
|
|
25
20
|
const SWATCH_TOKENS = [
|
|
26
21
|
{ key: '--dry-color-fill', label: 'Fill' },
|
|
@@ -44,32 +39,34 @@
|
|
|
44
39
|
);
|
|
45
40
|
|
|
46
41
|
let pickerColor = $derived.by(() => {
|
|
47
|
-
const hsl = hsbToHsl(
|
|
42
|
+
const hsl = hsbToHsl(
|
|
43
|
+
wizardState.brandHsb.h,
|
|
44
|
+
wizardState.brandHsb.s / 100,
|
|
45
|
+
wizardState.brandHsb.b / 100
|
|
46
|
+
);
|
|
48
47
|
return hslToHex(hsl.h, hsl.s, hsl.l);
|
|
49
48
|
});
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
if (pickerHex && pickerHex !== pickerColor) {
|
|
59
|
-
const hsl = hexToHsl(pickerHex);
|
|
50
|
+
const pickerModel = {
|
|
51
|
+
get hex() {
|
|
52
|
+
return pickerColor;
|
|
53
|
+
},
|
|
54
|
+
set hex(value: string) {
|
|
55
|
+
if (!value || value === pickerColor) return;
|
|
56
|
+
const hsl = hexToHsl(value);
|
|
60
57
|
const hsb = hslToHsb(hsl.h, hsl.s, hsl.l);
|
|
61
|
-
|
|
58
|
+
setBrandHsb(hsb.h, Math.round(hsb.s * 100), Math.round(hsb.b * 100));
|
|
62
59
|
}
|
|
63
|
-
}
|
|
60
|
+
};
|
|
64
61
|
|
|
65
62
|
function selectPreset(preset: (typeof PRESETS)[number]) {
|
|
66
|
-
|
|
63
|
+
setBrandHsb(preset.brandInput.h, preset.brandInput.s, preset.brandInput.b);
|
|
67
64
|
}
|
|
68
65
|
</script>
|
|
69
66
|
|
|
70
67
|
<section class="brand-section">
|
|
71
68
|
<div class="picker-wrap">
|
|
72
|
-
<ColorPicker.Root bind:value={
|
|
69
|
+
<ColorPicker.Root bind:value={pickerModel.hex} areaHeight={160}>
|
|
73
70
|
<ColorPicker.Area />
|
|
74
71
|
<ColorPicker.HueSlider />
|
|
75
72
|
<ColorPicker.Input format="hex" />
|
|
@@ -90,22 +87,23 @@
|
|
|
90
87
|
{#each PRESETS as preset, i (preset.name)}
|
|
91
88
|
{@const presetTheme = PRESET_THEMES[i] ?? PRESET_THEMES[0]!}
|
|
92
89
|
{@const presetTokens = isDark ? presetTheme.dark : presetTheme.light}
|
|
93
|
-
<button
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
90
|
+
<Button type="button" variant="bare" onclick={() => selectPreset(preset)}>
|
|
91
|
+
<div
|
|
92
|
+
class="preset-btn"
|
|
93
|
+
data-selected={wizardState.brandHsb.h === preset.brandInput.h &&
|
|
94
|
+
wizardState.brandHsb.s === preset.brandInput.s &&
|
|
95
|
+
wizardState.brandHsb.b === preset.brandInput.b
|
|
96
|
+
? ''
|
|
97
|
+
: undefined}
|
|
98
|
+
>
|
|
99
|
+
<div class="preset-thumb">
|
|
100
|
+
{#each SWATCH_TOKENS as { key } (key)}
|
|
101
|
+
<div class="preset-swatch" use:bg={presetTokens[key] ?? ''}></div>
|
|
102
|
+
{/each}
|
|
103
|
+
</div>
|
|
104
|
+
<Text as="span" size="xs" color="muted">{preset.name.toLowerCase()}</Text>
|
|
106
105
|
</div>
|
|
107
|
-
|
|
108
|
-
</button>
|
|
106
|
+
</Button>
|
|
109
107
|
{/each}
|
|
110
108
|
</div>
|
|
111
109
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dryui/theme-wizard",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
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.4.0",
|
|
41
|
+
"@dryui/ui": "^0.4.0",
|
|
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.4.0",
|
|
48
|
+
"@dryui/ui": "^0.4.0",
|
|
49
49
|
"lucide-svelte": "^1.0.1",
|
|
50
50
|
"svelte": "^5.55.3",
|
|
51
51
|
"@sveltejs/package": "^2.5.7",
|