@newtonedev/editor 0.1.12 → 0.2.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/Editor.d.ts.map +1 -1
- package/dist/components/CodeBlock.d.ts.map +1 -1
- package/dist/components/ConfiguratorPanel.d.ts +6 -3
- package/dist/components/ConfiguratorPanel.d.ts.map +1 -1
- package/dist/components/EditorHeader.d.ts +3 -2
- package/dist/components/EditorHeader.d.ts.map +1 -1
- package/dist/components/EditorShell.d.ts.map +1 -1
- package/dist/components/PresetSelector.d.ts +3 -2
- package/dist/components/PresetSelector.d.ts.map +1 -1
- package/dist/components/PreviewWindow.d.ts.map +1 -1
- package/dist/components/RightSidebar.d.ts.map +1 -1
- package/dist/components/Sidebar.d.ts +8 -1
- package/dist/components/Sidebar.d.ts.map +1 -1
- package/dist/components/TableOfContents.d.ts.map +1 -1
- package/dist/components/sections/ColorsSection.d.ts +6 -3
- package/dist/components/sections/ColorsSection.d.ts.map +1 -1
- package/dist/components/sections/DynamicRangeSection.d.ts +2 -2
- package/dist/components/sections/DynamicRangeSection.d.ts.map +1 -1
- package/dist/components/sections/FontsSection.d.ts +2 -2
- package/dist/components/sections/FontsSection.d.ts.map +1 -1
- package/dist/components/sections/IconsSection.d.ts +2 -2
- package/dist/components/sections/IconsSection.d.ts.map +1 -1
- package/dist/components/sections/OthersSection.d.ts +2 -2
- package/dist/components/sections/OthersSection.d.ts.map +1 -1
- package/dist/components/sections/ScalePlots.d.ts +11 -0
- package/dist/components/sections/ScalePlots.d.ts.map +1 -0
- package/dist/components/sections/index.d.ts +1 -0
- package/dist/components/sections/index.d.ts.map +1 -1
- package/dist/configurator/bridge/toCSS.d.ts +7 -0
- package/dist/configurator/bridge/toCSS.d.ts.map +1 -0
- package/dist/configurator/bridge/toJSON.d.ts +15 -0
- package/dist/configurator/bridge/toJSON.d.ts.map +1 -0
- package/dist/configurator/bridge/toThemeConfig.d.ts +8 -0
- package/dist/configurator/bridge/toThemeConfig.d.ts.map +1 -0
- package/dist/configurator/constants.d.ts +13 -0
- package/dist/configurator/constants.d.ts.map +1 -0
- package/dist/configurator/hex-conversion.d.ts +21 -0
- package/dist/configurator/hex-conversion.d.ts.map +1 -0
- package/dist/configurator/hooks/useConfigurator.d.ts +11 -0
- package/dist/configurator/hooks/useConfigurator.d.ts.map +1 -0
- package/dist/configurator/hooks/usePreviewColors.d.ts +8 -0
- package/dist/configurator/hooks/usePreviewColors.d.ts.map +1 -0
- package/dist/configurator/hooks/useWcagValidation.d.ts +20 -0
- package/dist/configurator/hooks/useWcagValidation.d.ts.map +1 -0
- package/dist/configurator/hue-conversion.d.ts +10 -0
- package/dist/configurator/hue-conversion.d.ts.map +1 -0
- package/dist/configurator/state/actions.d.ts +107 -0
- package/dist/configurator/state/actions.d.ts.map +1 -0
- package/dist/configurator/state/defaults.d.ts +7 -0
- package/dist/configurator/state/defaults.d.ts.map +1 -0
- package/dist/configurator/state/reducer.d.ts +19 -0
- package/dist/configurator/state/reducer.d.ts.map +1 -0
- package/dist/configurator/types.d.ts +60 -0
- package/dist/configurator/types.d.ts.map +1 -0
- package/dist/hooks/useEditorState.d.ts +8 -6
- package/dist/hooks/useEditorState.d.ts.map +1 -1
- package/dist/hooks/usePresets.d.ts +7 -6
- package/dist/hooks/usePresets.d.ts.map +1 -1
- package/dist/index.cjs +30372 -808
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30351 -799
- package/dist/index.js.map +1 -1
- package/dist/preview/CategoryView.d.ts.map +1 -1
- package/dist/preview/ComponentDetailView.d.ts.map +1 -1
- package/dist/preview/ComponentRenderer.d.ts.map +1 -1
- package/dist/preview/IconBrowserView.d.ts.map +1 -1
- package/dist/preview/OverviewView.d.ts.map +1 -1
- package/dist/preview/PaletteScaleView.d.ts +11 -0
- package/dist/preview/PaletteScaleView.d.ts.map +1 -0
- package/dist/types.d.ts +4 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -4
- package/src/Editor.tsx +43 -19
- package/src/components/CodeBlock.tsx +7 -11
- package/src/components/ConfiguratorPanel.tsx +25 -18
- package/src/components/EditorHeader.tsx +29 -39
- package/src/components/EditorShell.tsx +17 -29
- package/src/components/FontPicker.tsx +7 -7
- package/src/components/PresetSelector.tsx +211 -129
- package/src/components/PreviewWindow.tsx +5 -12
- package/src/components/PrimaryNav.tsx +6 -6
- package/src/components/RightSidebar.tsx +24 -25
- package/src/components/Sidebar.tsx +54 -60
- package/src/components/TableOfContents.tsx +4 -5
- package/src/components/sections/ColorsSection.tsx +109 -121
- package/src/components/sections/DynamicRangeSection.tsx +61 -75
- package/src/components/sections/FontsSection.tsx +17 -28
- package/src/components/sections/IconsSection.tsx +2 -2
- package/src/components/sections/OthersSection.tsx +4 -5
- package/src/components/sections/ScalePlots.tsx +221 -0
- package/src/components/sections/index.ts +1 -0
- package/src/configurator/bridge/toCSS.ts +44 -0
- package/src/configurator/bridge/toJSON.ts +24 -0
- package/src/configurator/bridge/toThemeConfig.ts +114 -0
- package/src/configurator/constants.ts +13 -0
- package/src/configurator/hex-conversion.ts +67 -0
- package/src/configurator/hooks/useConfigurator.ts +33 -0
- package/src/configurator/hooks/usePreviewColors.ts +47 -0
- package/src/configurator/hooks/useWcagValidation.ts +133 -0
- package/src/configurator/hue-conversion.ts +25 -0
- package/src/configurator/state/actions.ts +43 -0
- package/src/configurator/state/defaults.ts +107 -0
- package/src/configurator/state/reducer.ts +399 -0
- package/src/configurator/types.ts +65 -0
- package/src/hooks/useEditorState.ts +25 -11
- package/src/hooks/usePresets.ts +54 -33
- package/src/index.ts +33 -0
- package/src/preview/CategoryView.tsx +8 -11
- package/src/preview/ComponentDetailView.tsx +24 -54
- package/src/preview/ComponentRenderer.tsx +2 -4
- package/src/preview/IconBrowserView.tsx +9 -10
- package/src/preview/OverviewView.tsx +9 -12
- package/src/preview/PaletteScaleView.tsx +122 -0
- package/src/types.ts +4 -3
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { generateScale, oklchToSrgb, clampSrgb } from '@newtonedev/colors';
|
|
3
|
+
import type { Grading } from '@newtonedev/colors';
|
|
4
|
+
import type { ColorResult } from 'newtone';
|
|
5
|
+
import type { ConfiguratorState } from '../types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Compute preview swatches for all palettes.
|
|
9
|
+
* Returns an array of arrays: one preview row per palette.
|
|
10
|
+
*/
|
|
11
|
+
export function usePreviewColors(state: ConfiguratorState, useP3 = false): readonly (readonly ColorResult[])[] {
|
|
12
|
+
return useMemo(() => {
|
|
13
|
+
const g = state.globalHueGrading;
|
|
14
|
+
const grading: Grading | undefined =
|
|
15
|
+
g.lightIntensity === 0 && g.darkIntensity === 0
|
|
16
|
+
? undefined
|
|
17
|
+
: {
|
|
18
|
+
light: { hue: g.lightHue, amount: g.lightIntensity },
|
|
19
|
+
dark: { hue: g.darkHue, amount: g.darkIntensity },
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
return state.palettes.map(p => {
|
|
23
|
+
const shift = p.localHueGrade
|
|
24
|
+
? {
|
|
25
|
+
hue: p.localHueGrade.hue,
|
|
26
|
+
amount: p.localHueGrade.intensity,
|
|
27
|
+
light: p.localHueGrade.side === 'light',
|
|
28
|
+
}
|
|
29
|
+
: undefined;
|
|
30
|
+
|
|
31
|
+
const scale = generateScale({
|
|
32
|
+
hue: p.hue,
|
|
33
|
+
contrast: { light: state.dynamicRange.lightest, dark: state.dynamicRange.darkest },
|
|
34
|
+
chroma: { amount: p.chromaRatio, balance: p.chromaPeak },
|
|
35
|
+
grading,
|
|
36
|
+
shift,
|
|
37
|
+
isP3: useP3,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Convert Oklch[] → ColorResult[]
|
|
41
|
+
return scale.map(oklch => {
|
|
42
|
+
const srgb = clampSrgb(oklchToSrgb(oklch));
|
|
43
|
+
return { srgb, oklch } as ColorResult;
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}, [state, useP3]);
|
|
47
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { generateScale, oklchToSrgb, clampSrgb } from '@newtonedev/colors';
|
|
3
|
+
import type { Oklch, Grading, Shift } from '@newtonedev/colors';
|
|
4
|
+
import { getWcagContrastRatio } from 'newtone';
|
|
5
|
+
import type { ConfiguratorState } from '../types';
|
|
6
|
+
|
|
7
|
+
/** Number of positions to sample when searching for the best contrast match. */
|
|
8
|
+
const SEARCH_STEPS = 200;
|
|
9
|
+
const AA_TARGET = 4.5;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Linearly interpolate between steps of a pre-generated scale.
|
|
13
|
+
* Gives continuous resolution from the fixed-step scale returned by generateScale.
|
|
14
|
+
*/
|
|
15
|
+
function interpolateOklch(scale: Oklch[], t: number): Oklch {
|
|
16
|
+
const N = scale.length;
|
|
17
|
+
const fIdx = Math.max(0, Math.min(N - 1, t * (N - 1)));
|
|
18
|
+
const i0 = Math.floor(fIdx);
|
|
19
|
+
const i1 = Math.min(i0 + 1, N - 1);
|
|
20
|
+
const f = fIdx - i0;
|
|
21
|
+
const a = scale[i0];
|
|
22
|
+
const b = scale[i1];
|
|
23
|
+
return {
|
|
24
|
+
L: a.L + (b.L - a.L) * f,
|
|
25
|
+
C: a.C + (b.C - a.C) * f,
|
|
26
|
+
h: a.h + (b.h - a.h) * f,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface WcagValidation {
|
|
31
|
+
/** WCAG contrast ratio at the key color position (null if no keyColor set) */
|
|
32
|
+
readonly keyColorContrast: number | null;
|
|
33
|
+
/** Whether the key color passes WCAG AA for normal text (>= 4.5:1) */
|
|
34
|
+
readonly passesAA: boolean;
|
|
35
|
+
/** Whether the key color passes WCAG AA for large text (>= 3:1) */
|
|
36
|
+
readonly passesAALargeText: boolean;
|
|
37
|
+
/** The step index where auto contrast search would place the key color [0, 25] */
|
|
38
|
+
readonly autoStep: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildShift(lg: { hue: number; intensity: number; side: 'light' | 'dark' }): Shift {
|
|
42
|
+
return { hue: lg.hue, amount: lg.intensity, light: lg.side === 'light' };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Compute WCAG validation info for a non-primary palette's key color.
|
|
47
|
+
*
|
|
48
|
+
* Validates the palette's key color against the primary background
|
|
49
|
+
* in the current preview mode. Also computes where the auto contrast
|
|
50
|
+
* search would place the key color (for showing the default position).
|
|
51
|
+
*/
|
|
52
|
+
export function useWcagValidation(
|
|
53
|
+
state: ConfiguratorState,
|
|
54
|
+
paletteIndex: number,
|
|
55
|
+
): WcagValidation {
|
|
56
|
+
return useMemo(() => {
|
|
57
|
+
const palette = state.palettes[paletteIndex];
|
|
58
|
+
const primary = state.palettes[0];
|
|
59
|
+
if (!palette || !primary) {
|
|
60
|
+
return { keyColorContrast: null, passesAA: true, passesAALargeText: true, autoStep: 13 };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const mode = state.preview.mode;
|
|
64
|
+
const contrast = { light: state.dynamicRange.lightest, dark: state.dynamicRange.darkest };
|
|
65
|
+
|
|
66
|
+
const g = state.globalHueGrading;
|
|
67
|
+
const grading: Grading | undefined =
|
|
68
|
+
g.lightIntensity === 0 && g.darkIntensity === 0
|
|
69
|
+
? undefined
|
|
70
|
+
: {
|
|
71
|
+
light: { hue: g.lightHue, amount: g.lightIntensity },
|
|
72
|
+
dark: { hue: g.darkHue, amount: g.darkIntensity },
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// Generate primary scale to find background
|
|
76
|
+
const primaryScale = generateScale({
|
|
77
|
+
hue: primary.hue,
|
|
78
|
+
contrast,
|
|
79
|
+
chroma: { amount: primary.chromaRatio, balance: primary.chromaPeak },
|
|
80
|
+
grading,
|
|
81
|
+
shift: primary.localHueGrade ? buildShift(primary.localHueGrade) : undefined,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// Background position: light=near-lightest (engineNv≈0.95), dark=near-darkest (engineNv≈0.1)
|
|
85
|
+
const bgEngineNv = mode === 'light' ? 0.95 : 0.1;
|
|
86
|
+
const bgT = 1 - bgEngineNv;
|
|
87
|
+
const bgSrgb = clampSrgb(oklchToSrgb(interpolateOklch(primaryScale, bgT)));
|
|
88
|
+
|
|
89
|
+
// Generate palette scale to find key color and auto position
|
|
90
|
+
const paletteScale = generateScale({
|
|
91
|
+
hue: palette.hue,
|
|
92
|
+
contrast,
|
|
93
|
+
chroma: { amount: palette.chromaRatio, balance: palette.chromaPeak },
|
|
94
|
+
grading,
|
|
95
|
+
shift: palette.localHueGrade ? buildShift(palette.localHueGrade) : undefined,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// Find auto position: search at fine-grained t intervals for best 4.5:1 contrast
|
|
99
|
+
let bestSearchIdx = 0;
|
|
100
|
+
let bestDelta = Infinity;
|
|
101
|
+
for (let i = 0; i < SEARCH_STEPS; i++) {
|
|
102
|
+
const t = i / (SEARCH_STEPS - 1);
|
|
103
|
+
const srgb = clampSrgb(oklchToSrgb(interpolateOklch(paletteScale, t)));
|
|
104
|
+
const cr = getWcagContrastRatio(srgb, bgSrgb);
|
|
105
|
+
const delta = Math.abs(cr - AA_TARGET);
|
|
106
|
+
if (delta < bestDelta) {
|
|
107
|
+
bestDelta = delta;
|
|
108
|
+
bestSearchIdx = i;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Convert search index to step index: t=0→step 0 (lightest), t=1→step 25 (darkest)
|
|
112
|
+
const autoStep = Math.round(bestSearchIdx / (SEARCH_STEPS - 1) * 25);
|
|
113
|
+
|
|
114
|
+
// Resolve per-mode key color step
|
|
115
|
+
const effectiveKeyStep = mode === 'dark' ? palette.keyColorStepDark : palette.keyColorStep;
|
|
116
|
+
|
|
117
|
+
if (effectiveKeyStep === undefined) {
|
|
118
|
+
return { keyColorContrast: null, passesAA: true, passesAALargeText: true, autoStep };
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Look up the key color in the palette scale: step 0=lightest (t=0), step 25=darkest (t=1)
|
|
122
|
+
const keyT = Math.max(0, Math.min(25, effectiveKeyStep)) / 25;
|
|
123
|
+
const keySrgb = clampSrgb(oklchToSrgb(interpolateOklch(paletteScale, keyT)));
|
|
124
|
+
const cr = getWcagContrastRatio(keySrgb, bgSrgb);
|
|
125
|
+
|
|
126
|
+
return {
|
|
127
|
+
keyColorContrast: cr,
|
|
128
|
+
passesAA: cr >= 4.5,
|
|
129
|
+
passesAALargeText: cr >= 3.0,
|
|
130
|
+
autoStep,
|
|
131
|
+
};
|
|
132
|
+
}, [state, paletteIndex]);
|
|
133
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { srgbToOklch } from 'newtone';
|
|
2
|
+
import type { Srgb } from 'newtone';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Convert a traditional HSL color wheel hue (0-359) to its equivalent OKLCH hue.
|
|
6
|
+
*
|
|
7
|
+
* Uses the fully saturated HSL color (S=1, L=0.5) at the given hue,
|
|
8
|
+
* converts to sRGB, then extracts the OKLCH hue component.
|
|
9
|
+
*
|
|
10
|
+
* Traditional hues: 0=red, 60=yellow, 120=green, 180=cyan, 240=blue, 300=magenta.
|
|
11
|
+
*/
|
|
12
|
+
export function traditionalHueToOklch(hue: number): number {
|
|
13
|
+
const h = ((hue % 360) + 360) % 360;
|
|
14
|
+
const x = 1 - Math.abs((h / 60) % 2 - 1);
|
|
15
|
+
|
|
16
|
+
let r: number, g: number, b: number;
|
|
17
|
+
if (h < 60) { r = 1; g = x; b = 0; }
|
|
18
|
+
else if (h < 120) { r = x; g = 1; b = 0; }
|
|
19
|
+
else if (h < 180) { r = 0; g = 1; b = x; }
|
|
20
|
+
else if (h < 240) { r = 0; g = x; b = 1; }
|
|
21
|
+
else if (h < 300) { r = x; g = 0; b = 1; }
|
|
22
|
+
else { r = 1; g = 0; b = x; }
|
|
23
|
+
|
|
24
|
+
return srgbToOklch({ r, g, b } as Srgb).h;
|
|
25
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ColorMode } from '@newtonedev/components';
|
|
2
|
+
import type { TextRole } from '@newtonedev/fonts';
|
|
3
|
+
import type { ConfiguratorState, FontSlotConfig, FontScope, SpacingPreset } from '../types';
|
|
4
|
+
|
|
5
|
+
export type ConfiguratorAction =
|
|
6
|
+
// Palette actions
|
|
7
|
+
| { readonly type: 'SET_PALETTE_HUE'; readonly index: number; readonly hue: number }
|
|
8
|
+
| { readonly type: 'SET_PALETTE_CHROMA_RATIO'; readonly index: number; readonly chromaRatio: number }
|
|
9
|
+
| { readonly type: 'SET_PALETTE_CHROMA_PEAK'; readonly index: number; readonly chromaPeak: number }
|
|
10
|
+
| { readonly type: 'SET_PALETTE_LOCAL_HUE_GRADE_INTENSITY'; readonly index: number; readonly intensity: number }
|
|
11
|
+
| { readonly type: 'SET_PALETTE_LOCAL_HUE_GRADE_HUE'; readonly index: number; readonly hue: number }
|
|
12
|
+
| { readonly type: 'SET_PALETTE_LOCAL_HUE_GRADE_SIDE'; readonly index: number; readonly side: 'light' | 'dark' }
|
|
13
|
+
| { readonly type: 'SET_PALETTE_KEY_COLOR_STEP'; readonly index: number; readonly step: number }
|
|
14
|
+
| { readonly type: 'CLEAR_PALETTE_KEY_COLOR_STEP'; readonly index: number }
|
|
15
|
+
| { readonly type: 'SET_PALETTE_FROM_HEX'; readonly index: number; readonly hue: number; readonly chromaRatio: number; readonly keyColorStep: number }
|
|
16
|
+
| { readonly type: 'SET_PALETTE_KEY_COLOR_STEP_DARK'; readonly index: number; readonly step: number }
|
|
17
|
+
| { readonly type: 'CLEAR_PALETTE_KEY_COLOR_STEP_DARK'; readonly index: number }
|
|
18
|
+
| { readonly type: 'SET_PALETTE_FROM_HEX_DARK'; readonly index: number; readonly hue: number; readonly chromaRatio: number; readonly keyColorStep: number }
|
|
19
|
+
// Dynamic range actions
|
|
20
|
+
| { readonly type: 'SET_LIGHTEST'; readonly value: number }
|
|
21
|
+
| { readonly type: 'SET_DARKEST'; readonly value: number }
|
|
22
|
+
// Global hue grading actions
|
|
23
|
+
| { readonly type: 'SET_GLOBAL_GRADE_LIGHT_INTENSITY'; readonly intensity: number }
|
|
24
|
+
| { readonly type: 'SET_GLOBAL_GRADE_LIGHT_HUE'; readonly hue: number }
|
|
25
|
+
| { readonly type: 'SET_GLOBAL_GRADE_DARK_INTENSITY'; readonly intensity: number }
|
|
26
|
+
| { readonly type: 'SET_GLOBAL_GRADE_DARK_HUE'; readonly hue: number }
|
|
27
|
+
// Spacing actions
|
|
28
|
+
| { readonly type: 'SET_SPACING_PRESET'; readonly preset: SpacingPreset }
|
|
29
|
+
// Roundness actions
|
|
30
|
+
| { readonly type: 'SET_ROUNDNESS_INTENSITY'; readonly intensity: number }
|
|
31
|
+
// Typography actions
|
|
32
|
+
| { readonly type: 'SET_FONT'; readonly scope: FontScope; readonly font: FontSlotConfig }
|
|
33
|
+
| { readonly type: 'SET_TYPE_SCALE_OFFSET'; readonly offset: number }
|
|
34
|
+
| { readonly type: 'SET_ROLE_WEIGHT'; readonly role: TextRole; readonly weight: number }
|
|
35
|
+
// Icons actions
|
|
36
|
+
| { readonly type: 'SET_ICON_VARIANT'; readonly variant: 'outlined' | 'rounded' | 'sharp' }
|
|
37
|
+
| { readonly type: 'SET_ICON_WEIGHT'; readonly weight: 100 | 200 | 300 | 400 | 500 | 600 | 700 }
|
|
38
|
+
| { readonly type: 'SET_ICON_AUTO_GRADE'; readonly autoGrade: boolean }
|
|
39
|
+
// Preview actions
|
|
40
|
+
| { readonly type: 'SET_PREVIEW_MODE'; readonly mode: ColorMode }
|
|
41
|
+
// Control actions
|
|
42
|
+
| { readonly type: 'RESET' }
|
|
43
|
+
| { readonly type: 'LOAD_STATE'; readonly state: ConfiguratorState };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { ConfiguratorState } from '../types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Default configurator state.
|
|
5
|
+
* All hue values are OKLCH hues [0, 360).
|
|
6
|
+
*/
|
|
7
|
+
export const DEFAULT_CONFIGURATOR_STATE: ConfiguratorState = {
|
|
8
|
+
hueSpace: 'oklch',
|
|
9
|
+
palettes: [
|
|
10
|
+
{
|
|
11
|
+
name: 'Primary',
|
|
12
|
+
hue: 262.64,
|
|
13
|
+
chromaRatio: 0.24,
|
|
14
|
+
chromaPeak: 0.5,
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
name: 'Secondary',
|
|
18
|
+
hue: 43.49,
|
|
19
|
+
chromaRatio: 0.8,
|
|
20
|
+
chromaPeak: 0.5,
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Tertiary',
|
|
24
|
+
hue: 195,
|
|
25
|
+
chromaRatio: 0.5,
|
|
26
|
+
chromaPeak: 0.5,
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
name: 'Success',
|
|
30
|
+
hue: 148.13,
|
|
31
|
+
chromaRatio: 0.64,
|
|
32
|
+
chromaPeak: 0.5,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'Warning',
|
|
36
|
+
hue: 73.27,
|
|
37
|
+
chromaRatio: 0.8,
|
|
38
|
+
chromaPeak: 0.5,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Error',
|
|
42
|
+
hue: 29.23,
|
|
43
|
+
chromaRatio: 0.8,
|
|
44
|
+
chromaPeak: 0.5,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
dynamicRange: {
|
|
48
|
+
lightest: 1,
|
|
49
|
+
darkest: 1,
|
|
50
|
+
},
|
|
51
|
+
globalHueGrading: {
|
|
52
|
+
lightHue: 52.78,
|
|
53
|
+
lightIntensity: 0,
|
|
54
|
+
darkHue: 262.64,
|
|
55
|
+
darkIntensity: 0,
|
|
56
|
+
},
|
|
57
|
+
preview: {
|
|
58
|
+
mode: 'light',
|
|
59
|
+
},
|
|
60
|
+
spacing: {
|
|
61
|
+
preset: 'md', // Medium (8px base): default/balanced spacing
|
|
62
|
+
},
|
|
63
|
+
roundness: {
|
|
64
|
+
intensity: 0.5, // 1.0x multiplier = preserves current hardcoded values
|
|
65
|
+
},
|
|
66
|
+
typography: {
|
|
67
|
+
fonts: {
|
|
68
|
+
main: {
|
|
69
|
+
config: {
|
|
70
|
+
type: 'system',
|
|
71
|
+
family: 'system-ui',
|
|
72
|
+
fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
73
|
+
},
|
|
74
|
+
weights: { regular: 400, medium: 500, bold: 700 },
|
|
75
|
+
},
|
|
76
|
+
display: {
|
|
77
|
+
config: {
|
|
78
|
+
type: 'system',
|
|
79
|
+
family: 'system-ui',
|
|
80
|
+
fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
81
|
+
},
|
|
82
|
+
weights: { regular: 400, medium: 500, bold: 700 },
|
|
83
|
+
},
|
|
84
|
+
mono: {
|
|
85
|
+
config: {
|
|
86
|
+
type: 'system',
|
|
87
|
+
family: 'ui-monospace',
|
|
88
|
+
fallback: 'SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
|
89
|
+
},
|
|
90
|
+
weights: { regular: 400, medium: 500, bold: 700 },
|
|
91
|
+
},
|
|
92
|
+
currency: {
|
|
93
|
+
config: {
|
|
94
|
+
type: 'system',
|
|
95
|
+
family: 'system-ui',
|
|
96
|
+
fallback: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
97
|
+
},
|
|
98
|
+
weights: { regular: 400, medium: 500, bold: 700 },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
icons: {
|
|
103
|
+
variant: 'rounded', // Material Design 3 aesthetic
|
|
104
|
+
weight: 400, // Normal weight
|
|
105
|
+
autoGrade: true, // Enable mode-aware grade
|
|
106
|
+
},
|
|
107
|
+
};
|