@newtonedev/components 0.1.4 → 0.1.6
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/composites/actions/Button/Button.d.ts +37 -0
- package/dist/composites/actions/Button/Button.d.ts.map +1 -0
- package/dist/composites/actions/Button/Button.styles.d.ts +65 -0
- package/dist/composites/actions/Button/Button.styles.d.ts.map +1 -0
- package/dist/{Button → composites/actions/Button}/Button.types.d.ts +12 -3
- package/dist/composites/actions/Button/Button.types.d.ts.map +1 -0
- package/dist/composites/actions/Button/index.d.ts.map +1 -0
- package/dist/composites/form-controls/Select/Select.d.ts.map +1 -0
- package/dist/{Select → composites/form-controls/Select}/Select.styles.d.ts +1 -1
- package/dist/composites/form-controls/Select/Select.styles.d.ts.map +1 -0
- package/dist/composites/form-controls/Select/Select.types.d.ts.map +1 -0
- package/dist/composites/form-controls/Select/SelectOption.d.ts.map +1 -0
- package/dist/composites/form-controls/Select/index.d.ts.map +1 -0
- package/dist/composites/form-controls/Select/useSelect.d.ts.map +1 -0
- package/dist/composites/form-controls/TextInput/TextInput.d.ts.map +1 -0
- package/dist/{TextInput → composites/form-controls/TextInput}/TextInput.styles.d.ts +1 -1
- package/dist/composites/form-controls/TextInput/TextInput.styles.d.ts.map +1 -0
- package/dist/composites/form-controls/TextInput/TextInput.types.d.ts.map +1 -0
- package/dist/composites/form-controls/TextInput/index.d.ts.map +1 -0
- package/dist/composites/form-controls/Toggle/Toggle.d.ts.map +1 -0
- package/dist/{Toggle → composites/form-controls/Toggle}/Toggle.styles.d.ts +1 -1
- package/dist/composites/form-controls/Toggle/Toggle.styles.d.ts.map +1 -0
- package/dist/composites/form-controls/Toggle/Toggle.types.d.ts.map +1 -0
- package/dist/composites/form-controls/Toggle/index.d.ts.map +1 -0
- package/dist/composites/layout/AppShell/AppShell.d.ts.map +1 -0
- package/dist/{AppShell → composites/layout/AppShell}/AppShell.styles.d.ts +1 -1
- package/dist/composites/layout/AppShell/AppShell.styles.d.ts.map +1 -0
- package/dist/composites/layout/AppShell/AppShell.types.d.ts.map +1 -0
- package/dist/composites/layout/AppShell/index.d.ts.map +1 -0
- package/dist/composites/layout/Card/Card.d.ts.map +1 -0
- package/dist/{Card → composites/layout/Card}/Card.styles.d.ts +1 -1
- package/dist/composites/layout/Card/Card.styles.d.ts.map +1 -0
- package/dist/{Card → composites/layout/Card}/Card.types.d.ts +1 -1
- package/dist/composites/layout/Card/Card.types.d.ts.map +1 -0
- package/dist/composites/layout/Card/index.d.ts.map +1 -0
- package/dist/composites/layout/Navbar/Navbar.d.ts.map +1 -0
- package/dist/{Navbar → composites/layout/Navbar}/Navbar.styles.d.ts +1 -1
- package/dist/composites/layout/Navbar/Navbar.styles.d.ts.map +1 -0
- package/dist/composites/layout/Navbar/Navbar.types.d.ts.map +1 -0
- package/dist/composites/layout/Navbar/index.d.ts.map +1 -0
- package/dist/composites/layout/Sidebar/Sidebar.d.ts.map +1 -0
- package/dist/{Sidebar → composites/layout/Sidebar}/Sidebar.styles.d.ts +1 -1
- package/dist/composites/layout/Sidebar/Sidebar.styles.d.ts.map +1 -0
- package/dist/composites/layout/Sidebar/Sidebar.types.d.ts.map +1 -0
- package/dist/composites/layout/Sidebar/index.d.ts.map +1 -0
- package/dist/composites/overlays/Popover/Popover.d.ts.map +1 -0
- package/dist/{Popover → composites/overlays/Popover}/Popover.styles.d.ts +1 -1
- package/dist/composites/overlays/Popover/Popover.styles.d.ts.map +1 -0
- package/dist/composites/overlays/Popover/Popover.types.d.ts.map +1 -0
- package/dist/composites/overlays/Popover/index.d.ts.map +1 -0
- package/dist/composites/overlays/Popover/usePopover.d.ts.map +1 -0
- package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.d.ts.map +1 -0
- package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.styles.d.ts +1 -1
- package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +1 -0
- package/dist/composites/range-inputs/ColorScaleSlider/ColorScaleSlider.types.d.ts.map +1 -0
- package/dist/composites/range-inputs/ColorScaleSlider/index.d.ts.map +1 -0
- package/dist/composites/range-inputs/HueSlider/HueSlider.d.ts.map +1 -0
- package/dist/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.styles.d.ts +1 -1
- package/dist/composites/range-inputs/HueSlider/HueSlider.styles.d.ts.map +1 -0
- package/dist/composites/range-inputs/HueSlider/HueSlider.types.d.ts.map +1 -0
- package/dist/composites/range-inputs/HueSlider/index.d.ts.map +1 -0
- package/dist/composites/range-inputs/Slider/Slider.d.ts.map +1 -0
- package/dist/{Slider → composites/range-inputs/Slider}/Slider.styles.d.ts +1 -1
- package/dist/composites/range-inputs/Slider/Slider.styles.d.ts.map +1 -0
- package/dist/composites/range-inputs/Slider/Slider.types.d.ts.map +1 -0
- package/dist/composites/range-inputs/Slider/index.d.ts.map +1 -0
- package/dist/index.cjs +1277 -764
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +30 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1234 -726
- package/dist/index.js.map +1 -1
- package/dist/primitives/Frame/Frame.d.ts +2 -3
- package/dist/primitives/Frame/Frame.d.ts.map +1 -1
- package/dist/primitives/Frame/Frame.types.d.ts +4 -15
- package/dist/primitives/Frame/Frame.types.d.ts.map +1 -1
- package/dist/primitives/Icon/Icon.d.ts.map +1 -1
- package/dist/primitives/Text/Text.d.ts.map +1 -1
- package/dist/primitives/Text/Text.types.d.ts +9 -4
- package/dist/primitives/Text/Text.types.d.ts.map +1 -1
- package/dist/primitives/Wrapper/Wrapper.d.ts +1 -1
- package/dist/primitives/Wrapper/Wrapper.types.d.ts +1 -1
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/theme/FrameContext.d.ts +7 -5
- package/dist/theme/FrameContext.d.ts.map +1 -1
- package/dist/theme/NewtoneProvider.d.ts +5 -6
- package/dist/theme/NewtoneProvider.d.ts.map +1 -1
- package/dist/theme/defaults.d.ts.map +1 -1
- package/dist/theme/types.d.ts +38 -24
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/tokens/computeTokens.d.ts +82 -7
- package/dist/tokens/computeTokens.d.ts.map +1 -1
- package/dist/tokens/types.d.ts +66 -14
- package/dist/tokens/types.d.ts.map +1 -1
- package/dist/tokens/useTokens.d.ts +11 -14
- package/dist/tokens/useTokens.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/composites/actions/Button/Button.styles.ts +338 -0
- package/src/composites/actions/Button/Button.tsx +119 -0
- package/src/{Button → composites/actions/Button}/Button.types.ts +14 -3
- package/src/{Select → composites/form-controls/Select}/Select.styles.ts +1 -1
- package/src/{Select → composites/form-controls/Select}/Select.tsx +4 -4
- package/src/{Select → composites/form-controls/Select}/SelectOption.tsx +4 -4
- package/src/{TextInput → composites/form-controls/TextInput}/TextInput.styles.ts +1 -1
- package/src/{TextInput → composites/form-controls/TextInput}/TextInput.tsx +1 -1
- package/src/{Toggle → composites/form-controls/Toggle}/Toggle.styles.ts +2 -2
- package/src/{Toggle → composites/form-controls/Toggle}/Toggle.tsx +1 -1
- package/src/{AppShell → composites/layout/AppShell}/AppShell.styles.ts +1 -1
- package/src/{AppShell → composites/layout/AppShell}/AppShell.tsx +1 -1
- package/src/{Card → composites/layout/Card}/Card.styles.ts +1 -1
- package/src/{Card → composites/layout/Card}/Card.tsx +1 -1
- package/src/{Card → composites/layout/Card}/Card.types.ts +1 -1
- package/src/{Navbar → composites/layout/Navbar}/Navbar.styles.ts +1 -1
- package/src/{Navbar → composites/layout/Navbar}/Navbar.tsx +1 -1
- package/src/{Sidebar → composites/layout/Sidebar}/Sidebar.styles.ts +1 -1
- package/src/{Sidebar → composites/layout/Sidebar}/Sidebar.tsx +1 -1
- package/src/{Popover → composites/overlays/Popover}/Popover.styles.ts +1 -1
- package/src/{Popover → composites/overlays/Popover}/Popover.tsx +1 -1
- package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.styles.ts +2 -2
- package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.tsx +1 -1
- package/src/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.styles.ts +1 -1
- package/src/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.tsx +1 -1
- package/src/{Slider → composites/range-inputs/Slider}/Slider.styles.ts +3 -3
- package/src/{Slider → composites/range-inputs/Slider}/Slider.tsx +1 -1
- package/src/index.ts +40 -33
- package/src/primitives/Frame/Frame.tsx +10 -18
- package/src/primitives/Frame/Frame.types.ts +5 -17
- package/src/primitives/Icon/Icon.tsx +16 -1
- package/src/primitives/Text/Text.tsx +18 -8
- package/src/primitives/Text/Text.types.ts +9 -4
- package/src/primitives/Wrapper/Wrapper.tsx +1 -1
- package/src/primitives/Wrapper/Wrapper.types.ts +1 -1
- package/src/registry/registry.ts +239 -6
- package/src/theme/FrameContext.tsx +7 -5
- package/src/theme/NewtoneProvider.tsx +5 -10
- package/src/theme/defaults.ts +0 -9
- package/src/theme/types.ts +53 -26
- package/src/tokens/computeTokens.ts +351 -113
- package/src/tokens/types.ts +82 -14
- package/src/tokens/useTokens.ts +29 -24
- package/dist/AppShell/AppShell.d.ts.map +0 -1
- package/dist/AppShell/AppShell.styles.d.ts.map +0 -1
- package/dist/AppShell/AppShell.types.d.ts.map +0 -1
- package/dist/AppShell/index.d.ts.map +0 -1
- package/dist/Button/Button.d.ts +0 -28
- package/dist/Button/Button.d.ts.map +0 -1
- package/dist/Button/Button.styles.d.ts +0 -46
- package/dist/Button/Button.styles.d.ts.map +0 -1
- package/dist/Button/Button.types.d.ts.map +0 -1
- package/dist/Button/index.d.ts.map +0 -1
- package/dist/Card/Card.d.ts.map +0 -1
- package/dist/Card/Card.styles.d.ts.map +0 -1
- package/dist/Card/Card.types.d.ts.map +0 -1
- package/dist/Card/index.d.ts.map +0 -1
- package/dist/ColorScaleSlider/ColorScaleSlider.d.ts.map +0 -1
- package/dist/ColorScaleSlider/ColorScaleSlider.styles.d.ts.map +0 -1
- package/dist/ColorScaleSlider/ColorScaleSlider.types.d.ts.map +0 -1
- package/dist/ColorScaleSlider/index.d.ts.map +0 -1
- package/dist/HueSlider/HueSlider.d.ts.map +0 -1
- package/dist/HueSlider/HueSlider.styles.d.ts.map +0 -1
- package/dist/HueSlider/HueSlider.types.d.ts.map +0 -1
- package/dist/HueSlider/index.d.ts.map +0 -1
- package/dist/Navbar/Navbar.d.ts.map +0 -1
- package/dist/Navbar/Navbar.styles.d.ts.map +0 -1
- package/dist/Navbar/Navbar.types.d.ts.map +0 -1
- package/dist/Navbar/index.d.ts.map +0 -1
- package/dist/Popover/Popover.d.ts.map +0 -1
- package/dist/Popover/Popover.styles.d.ts.map +0 -1
- package/dist/Popover/Popover.types.d.ts.map +0 -1
- package/dist/Popover/index.d.ts.map +0 -1
- package/dist/Popover/usePopover.d.ts.map +0 -1
- package/dist/Select/Select.d.ts.map +0 -1
- package/dist/Select/Select.styles.d.ts.map +0 -1
- package/dist/Select/Select.types.d.ts.map +0 -1
- package/dist/Select/SelectOption.d.ts.map +0 -1
- package/dist/Select/index.d.ts.map +0 -1
- package/dist/Select/useSelect.d.ts.map +0 -1
- package/dist/Sidebar/Sidebar.d.ts.map +0 -1
- package/dist/Sidebar/Sidebar.styles.d.ts.map +0 -1
- package/dist/Sidebar/Sidebar.types.d.ts.map +0 -1
- package/dist/Sidebar/index.d.ts.map +0 -1
- package/dist/Slider/Slider.d.ts.map +0 -1
- package/dist/Slider/Slider.styles.d.ts.map +0 -1
- package/dist/Slider/Slider.types.d.ts.map +0 -1
- package/dist/Slider/index.d.ts.map +0 -1
- package/dist/TextInput/TextInput.d.ts.map +0 -1
- package/dist/TextInput/TextInput.styles.d.ts.map +0 -1
- package/dist/TextInput/TextInput.types.d.ts.map +0 -1
- package/dist/TextInput/index.d.ts.map +0 -1
- package/dist/Toggle/Toggle.d.ts.map +0 -1
- package/dist/Toggle/Toggle.styles.d.ts.map +0 -1
- package/dist/Toggle/Toggle.types.d.ts.map +0 -1
- package/dist/Toggle/index.d.ts.map +0 -1
- package/src/Button/Button.styles.ts +0 -133
- package/src/Button/Button.tsx +0 -86
- /package/dist/{Button → composites/actions/Button}/index.d.ts +0 -0
- /package/dist/{Select → composites/form-controls/Select}/Select.d.ts +0 -0
- /package/dist/{Select → composites/form-controls/Select}/Select.types.d.ts +0 -0
- /package/dist/{Select → composites/form-controls/Select}/SelectOption.d.ts +0 -0
- /package/dist/{Select → composites/form-controls/Select}/index.d.ts +0 -0
- /package/dist/{Select → composites/form-controls/Select}/useSelect.d.ts +0 -0
- /package/dist/{TextInput → composites/form-controls/TextInput}/TextInput.d.ts +0 -0
- /package/dist/{TextInput → composites/form-controls/TextInput}/TextInput.types.d.ts +0 -0
- /package/dist/{TextInput → composites/form-controls/TextInput}/index.d.ts +0 -0
- /package/dist/{Toggle → composites/form-controls/Toggle}/Toggle.d.ts +0 -0
- /package/dist/{Toggle → composites/form-controls/Toggle}/Toggle.types.d.ts +0 -0
- /package/dist/{Toggle → composites/form-controls/Toggle}/index.d.ts +0 -0
- /package/dist/{AppShell → composites/layout/AppShell}/AppShell.d.ts +0 -0
- /package/dist/{AppShell → composites/layout/AppShell}/AppShell.types.d.ts +0 -0
- /package/dist/{AppShell → composites/layout/AppShell}/index.d.ts +0 -0
- /package/dist/{Card → composites/layout/Card}/Card.d.ts +0 -0
- /package/dist/{Card → composites/layout/Card}/index.d.ts +0 -0
- /package/dist/{Navbar → composites/layout/Navbar}/Navbar.d.ts +0 -0
- /package/dist/{Navbar → composites/layout/Navbar}/Navbar.types.d.ts +0 -0
- /package/dist/{Navbar → composites/layout/Navbar}/index.d.ts +0 -0
- /package/dist/{Sidebar → composites/layout/Sidebar}/Sidebar.d.ts +0 -0
- /package/dist/{Sidebar → composites/layout/Sidebar}/Sidebar.types.d.ts +0 -0
- /package/dist/{Sidebar → composites/layout/Sidebar}/index.d.ts +0 -0
- /package/dist/{Popover → composites/overlays/Popover}/Popover.d.ts +0 -0
- /package/dist/{Popover → composites/overlays/Popover}/Popover.types.d.ts +0 -0
- /package/dist/{Popover → composites/overlays/Popover}/index.d.ts +0 -0
- /package/dist/{Popover → composites/overlays/Popover}/usePopover.d.ts +0 -0
- /package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.d.ts +0 -0
- /package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.types.d.ts +0 -0
- /package/dist/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/index.d.ts +0 -0
- /package/dist/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.d.ts +0 -0
- /package/dist/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.types.d.ts +0 -0
- /package/dist/{HueSlider → composites/range-inputs/HueSlider}/index.d.ts +0 -0
- /package/dist/{Slider → composites/range-inputs/Slider}/Slider.d.ts +0 -0
- /package/dist/{Slider → composites/range-inputs/Slider}/Slider.types.d.ts +0 -0
- /package/dist/{Slider → composites/range-inputs/Slider}/index.d.ts +0 -0
- /package/src/{Button → composites/actions/Button}/index.ts +0 -0
- /package/src/{Select → composites/form-controls/Select}/Select.types.ts +0 -0
- /package/src/{Select → composites/form-controls/Select}/index.ts +0 -0
- /package/src/{Select → composites/form-controls/Select}/useSelect.ts +0 -0
- /package/src/{TextInput → composites/form-controls/TextInput}/TextInput.types.ts +0 -0
- /package/src/{TextInput → composites/form-controls/TextInput}/index.ts +0 -0
- /package/src/{Toggle → composites/form-controls/Toggle}/Toggle.types.ts +0 -0
- /package/src/{Toggle → composites/form-controls/Toggle}/index.ts +0 -0
- /package/src/{AppShell → composites/layout/AppShell}/AppShell.types.ts +0 -0
- /package/src/{AppShell → composites/layout/AppShell}/index.ts +0 -0
- /package/src/{Card → composites/layout/Card}/index.ts +0 -0
- /package/src/{Navbar → composites/layout/Navbar}/Navbar.types.ts +0 -0
- /package/src/{Navbar → composites/layout/Navbar}/index.ts +0 -0
- /package/src/{Sidebar → composites/layout/Sidebar}/Sidebar.types.ts +0 -0
- /package/src/{Sidebar → composites/layout/Sidebar}/index.ts +0 -0
- /package/src/{Popover → composites/overlays/Popover}/Popover.types.ts +0 -0
- /package/src/{Popover → composites/overlays/Popover}/index.ts +0 -0
- /package/src/{Popover → composites/overlays/Popover}/usePopover.ts +0 -0
- /package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/ColorScaleSlider.types.ts +0 -0
- /package/src/{ColorScaleSlider → composites/range-inputs/ColorScaleSlider}/index.ts +0 -0
- /package/src/{HueSlider → composites/range-inputs/HueSlider}/HueSlider.types.ts +0 -0
- /package/src/{HueSlider → composites/range-inputs/HueSlider}/index.ts +0 -0
- /package/src/{Slider → composites/range-inputs/Slider}/Slider.types.ts +0 -0
- /package/src/{Slider → composites/range-inputs/Slider}/index.ts +0 -0
|
@@ -1,7 +1,119 @@
|
|
|
1
|
-
import { getColor
|
|
1
|
+
import { getColor } from 'newtone';
|
|
2
2
|
import type { PaletteConfig } from 'newtone';
|
|
3
|
-
import type { ColorSystemConfig, ColorMode,
|
|
4
|
-
import type { ResolvedTokens } from './types';
|
|
3
|
+
import type { ColorSystemConfig, ColorMode, ElevationLevel, FontConfig, TokenOverrides } from '../theme/types';
|
|
4
|
+
import type { ResolvedTokens, PaletteTokens } from './types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Per-mode fallback defaults shape shared by all palette defaults.
|
|
8
|
+
*/
|
|
9
|
+
export type PaletteDefaults = {
|
|
10
|
+
readonly light: {
|
|
11
|
+
readonly background: { readonly elevated: number; readonly ground: number; readonly sunken: number };
|
|
12
|
+
readonly text: { readonly primary: number; readonly secondary: number; readonly tertiary: number; readonly disabled: number };
|
|
13
|
+
readonly action: { readonly enabled: number; readonly hovered: number; readonly pressed: number };
|
|
14
|
+
readonly border: { readonly enabled: number; readonly focused: number; readonly filled: number };
|
|
15
|
+
};
|
|
16
|
+
readonly dark: {
|
|
17
|
+
readonly background: { readonly elevated: number; readonly ground: number; readonly sunken: number };
|
|
18
|
+
readonly text: { readonly primary: number; readonly secondary: number; readonly tertiary: number; readonly disabled: number };
|
|
19
|
+
readonly action: { readonly enabled: number; readonly hovered: number; readonly pressed: number };
|
|
20
|
+
readonly border: { readonly enabled: number; readonly focused: number; readonly filled: number };
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Per-mode fallback defaults for the neutral palette (normalized scale).
|
|
26
|
+
* Single source of truth — consumed by computeTokens and the admin Token Tuner.
|
|
27
|
+
*
|
|
28
|
+
* Light: 0 = lightest, 1 = darkest. Dark: 0 = darkest, 1 = lightest.
|
|
29
|
+
* Structured by token group so all per-palette defaults follow the same shape.
|
|
30
|
+
*/
|
|
31
|
+
export const NEUTRAL_DEFAULTS: PaletteDefaults = {
|
|
32
|
+
light: {
|
|
33
|
+
background: { elevated: 0, ground: 0.03, sunken: 0.06 },
|
|
34
|
+
text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
|
|
35
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
36
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
37
|
+
},
|
|
38
|
+
dark: {
|
|
39
|
+
background: { elevated: 0.24, ground: 0.20, sunken: 0.16 },
|
|
40
|
+
text: { primary: 1.0, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
|
|
41
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
42
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Accent palette defaults. Initial values match neutral — will be tuned per-palette later.
|
|
48
|
+
*/
|
|
49
|
+
export const ACCENT_DEFAULTS: PaletteDefaults = {
|
|
50
|
+
light: {
|
|
51
|
+
background: { elevated: 0, ground: 0.03, sunken: 0.06 },
|
|
52
|
+
text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
|
|
53
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
54
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
55
|
+
},
|
|
56
|
+
dark: {
|
|
57
|
+
background: { elevated: 0.24, ground: 0.20, sunken: 0.16 },
|
|
58
|
+
text: { primary: 1.0, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
|
|
59
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
60
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Success palette defaults. Initial values match neutral — will be tuned per-palette later.
|
|
66
|
+
*/
|
|
67
|
+
export const SUCCESS_DEFAULTS: PaletteDefaults = {
|
|
68
|
+
light: {
|
|
69
|
+
background: { elevated: 0, ground: 0.03, sunken: 0.06 },
|
|
70
|
+
text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
|
|
71
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
72
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
73
|
+
},
|
|
74
|
+
dark: {
|
|
75
|
+
background: { elevated: 0.24, ground: 0.20, sunken: 0.16 },
|
|
76
|
+
text: { primary: 1.0, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
|
|
77
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
78
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Warning palette defaults. Initial values match neutral — will be tuned per-palette later.
|
|
84
|
+
*/
|
|
85
|
+
export const WARNING_DEFAULTS: PaletteDefaults = {
|
|
86
|
+
light: {
|
|
87
|
+
background: { elevated: 0, ground: 0.03, sunken: 0.06 },
|
|
88
|
+
text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
|
|
89
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
90
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
91
|
+
},
|
|
92
|
+
dark: {
|
|
93
|
+
background: { elevated: 0.24, ground: 0.20, sunken: 0.16 },
|
|
94
|
+
text: { primary: 1.0, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
|
|
95
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
96
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Error palette defaults. Initial values match neutral — will be tuned per-palette later.
|
|
102
|
+
*/
|
|
103
|
+
export const ERROR_DEFAULTS: PaletteDefaults = {
|
|
104
|
+
light: {
|
|
105
|
+
background: { elevated: 0, ground: 0.03, sunken: 0.06 },
|
|
106
|
+
text: { primary: 0.9, secondary: 0.7, tertiary: 0.5, disabled: 0.3 },
|
|
107
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
108
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
109
|
+
},
|
|
110
|
+
dark: {
|
|
111
|
+
background: { elevated: 0.24, ground: 0.20, sunken: 0.16 },
|
|
112
|
+
text: { primary: 1.0, secondary: 0.85, tertiary: 0.7, disabled: 0.55 },
|
|
113
|
+
action: { enabled: 0.04, hovered: 0.06, pressed: 0.08 },
|
|
114
|
+
border: { enabled: 0.08, focused: 0.16, filled: 0.24 },
|
|
115
|
+
},
|
|
116
|
+
};
|
|
5
117
|
|
|
6
118
|
/**
|
|
7
119
|
* Convert FontConfig to CSS font-family string
|
|
@@ -11,6 +123,104 @@ function fontConfigToFamily(font: FontConfig): string {
|
|
|
11
123
|
return `${family}, ${font.fallback}`;
|
|
12
124
|
}
|
|
13
125
|
|
|
126
|
+
const clamp = (n: number) => Math.max(0, Math.min(1, n));
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Compute the complete PaletteTokens for a non-neutral palette.
|
|
130
|
+
*
|
|
131
|
+
* Uses the palette's hue/saturation with positions from the palette's defaults,
|
|
132
|
+
* plus fill tokens at the palette's key NV position.
|
|
133
|
+
*
|
|
134
|
+
* @param palette - The palette config (hue, saturation, key NV, etc.)
|
|
135
|
+
* @param defaults - Per-mode defaults for this palette (positions + offsets)
|
|
136
|
+
* @param mode - Current color mode
|
|
137
|
+
* @param elevation - Current elevation level
|
|
138
|
+
* @param dynamicRange - Global dynamic range
|
|
139
|
+
* @param elevationDelta - Compensation delta (current surface vs elevated reference)
|
|
140
|
+
* @param effectiveTextMode - Derived from actual background lightness
|
|
141
|
+
* @param autoAccentNv - Auto-derived key NV fallback
|
|
142
|
+
* @param neutralTextPrimary - Neutral textPrimary for onFill (dark text on light fills)
|
|
143
|
+
* @param neutralBgElevated - Neutral backgroundElevated for onFill (light text on dark fills)
|
|
144
|
+
*/
|
|
145
|
+
function computePaletteTokens(
|
|
146
|
+
palette: PaletteConfig,
|
|
147
|
+
defaults: PaletteDefaults,
|
|
148
|
+
mode: ColorMode,
|
|
149
|
+
elevation: ElevationLevel,
|
|
150
|
+
dynamicRange: { readonly lightest: number; readonly darkest: number },
|
|
151
|
+
elevationDelta: number,
|
|
152
|
+
effectiveTextMode: ColorMode,
|
|
153
|
+
autoAccentNv: number,
|
|
154
|
+
neutralTextPrimary: ReturnType<typeof getColor>,
|
|
155
|
+
neutralBgElevated: ReturnType<typeof getColor>,
|
|
156
|
+
): PaletteTokens {
|
|
157
|
+
const modeDefaults = defaults[mode];
|
|
158
|
+
const toEngineNv = (nv: number) => mode === 'light' ? 1 - nv : nv;
|
|
159
|
+
const textToEngineNv = (nv: number) => effectiveTextMode === 'light' ? 1 - nv : nv;
|
|
160
|
+
|
|
161
|
+
const colorAt = (engineNv: number) => getColor(
|
|
162
|
+
palette.hue, palette.saturation, dynamicRange,
|
|
163
|
+
clamp(engineNv), palette.desaturation, palette.paletteHueGrading
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// --- Fill: key color (user-chosen or auto-derived), elevation-compensated ---
|
|
167
|
+
const resolveKeyNv = (p: PaletteConfig): number | undefined =>
|
|
168
|
+
mode === 'dark' ? p.keyNormalizedValueDark : p.keyNormalizedValue;
|
|
169
|
+
|
|
170
|
+
const keyNv = resolveKeyNv(palette);
|
|
171
|
+
const fillBaseNv = keyNv ?? autoAccentNv;
|
|
172
|
+
const fillNv = clamp(fillBaseNv + elevationDelta);
|
|
173
|
+
const fill = colorAt(fillNv);
|
|
174
|
+
|
|
175
|
+
const hoverDir = effectiveTextMode === 'light' ? -modeDefaults.action.hovered : modeDefaults.action.hovered;
|
|
176
|
+
const activeDir = effectiveTextMode === 'light' ? -modeDefaults.action.pressed : modeDefaults.action.pressed;
|
|
177
|
+
const fillHover = colorAt(clamp(fillNv + hoverDir));
|
|
178
|
+
const fillActive = colorAt(clamp(fillNv + activeDir));
|
|
179
|
+
|
|
180
|
+
// onFill: high-contrast text on the fill color
|
|
181
|
+
const onFill = fill.oklch.L > 0.6 ? neutralTextPrimary : neutralBgElevated;
|
|
182
|
+
|
|
183
|
+
// --- Surface: palette-tinted backgrounds at standard positions ---
|
|
184
|
+
const bgNormalized = elevation === 2
|
|
185
|
+
? modeDefaults.background.elevated
|
|
186
|
+
: elevation === 1
|
|
187
|
+
? modeDefaults.background.ground
|
|
188
|
+
: modeDefaults.background.sunken;
|
|
189
|
+
const bgNv = clamp(toEngineNv(bgNormalized));
|
|
190
|
+
const background = colorAt(bgNv);
|
|
191
|
+
const backgroundElevated = colorAt(clamp(toEngineNv(modeDefaults.background.elevated)));
|
|
192
|
+
const backgroundSunken = colorAt(clamp(toEngineNv(modeDefaults.background.sunken)));
|
|
193
|
+
|
|
194
|
+
// --- Interactive surface: offset from palette background ---
|
|
195
|
+
const interactiveOffset = modeDefaults.action.enabled;
|
|
196
|
+
const interactiveNv = clamp(bgNv + (effectiveTextMode === 'light' ? -interactiveOffset : interactiveOffset));
|
|
197
|
+
const backgroundInteractive = colorAt(interactiveNv);
|
|
198
|
+
|
|
199
|
+
const hoverShift = modeDefaults.action.hovered;
|
|
200
|
+
const activeShift = modeDefaults.action.pressed;
|
|
201
|
+
const backgroundInteractiveHover = colorAt(clamp(interactiveNv + (effectiveTextMode === 'light' ? -hoverShift : hoverShift)));
|
|
202
|
+
const backgroundInteractiveActive = colorAt(clamp(interactiveNv + (effectiveTextMode === 'light' ? -activeShift : activeShift)));
|
|
203
|
+
|
|
204
|
+
// --- Text: palette-hued text at standard positions, elevation-compensated ---
|
|
205
|
+
const textPrimary = colorAt(clamp(textToEngineNv(modeDefaults.text.primary) + elevationDelta));
|
|
206
|
+
const textSecondary = colorAt(clamp(textToEngineNv(modeDefaults.text.secondary) + elevationDelta));
|
|
207
|
+
const textTertiary = colorAt(clamp(textToEngineNv(modeDefaults.text.tertiary) + elevationDelta));
|
|
208
|
+
const textDisabled = colorAt(clamp(textToEngineNv(modeDefaults.text.disabled) + elevationDelta));
|
|
209
|
+
|
|
210
|
+
// --- Border: offset from palette background ---
|
|
211
|
+
const borderOffset = modeDefaults.border.enabled;
|
|
212
|
+
const borderNv = effectiveTextMode === 'light' ? bgNv - borderOffset : bgNv + borderOffset;
|
|
213
|
+
const border = colorAt(clamp(borderNv));
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
fill, fillHover, fillActive, onFill,
|
|
217
|
+
background, backgroundElevated, backgroundSunken,
|
|
218
|
+
backgroundInteractive, backgroundInteractiveHover, backgroundInteractiveActive,
|
|
219
|
+
textPrimary, textSecondary, textTertiary, textDisabled,
|
|
220
|
+
border,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
|
|
14
224
|
/**
|
|
15
225
|
* Compute design tokens for a specific mode/theme/elevation combination.
|
|
16
226
|
*
|
|
@@ -18,11 +228,13 @@ function fontConfigToFamily(font: FontConfig): string {
|
|
|
18
228
|
* based on the current theme context. All colors are computed on-demand using
|
|
19
229
|
* the pure functions from the engine.
|
|
20
230
|
*
|
|
231
|
+
* Background surfaces use absolute positions from NEUTRAL_DEFAULTS (or tokenOverrides
|
|
232
|
+
* when present). Elevation compensation is derived from the difference between
|
|
233
|
+
* the current surface and the elevated reference surface.
|
|
234
|
+
*
|
|
21
235
|
* @param config - Complete color system configuration (dynamic range + palettes)
|
|
22
236
|
* @param mode - Current color mode ('light' or 'dark')
|
|
23
|
-
* @param themeMapping - Theme configuration (which palette and NV to use)
|
|
24
237
|
* @param elevation - Elevation level (0=sunken, 1=default, 2=elevated)
|
|
25
|
-
* @param elevationOffsets - NV offsets for each elevation level
|
|
26
238
|
* @param spacing - Spacing scale for paddings, gaps, and margins
|
|
27
239
|
* @param radius - Border radius scale for component roundness
|
|
28
240
|
* @param typography - Typography configuration with fonts and scales
|
|
@@ -34,9 +246,7 @@ function fontConfigToFamily(font: FontConfig): string {
|
|
|
34
246
|
* const tokens = computeTokens(
|
|
35
247
|
* config.colorSystem,
|
|
36
248
|
* 'light',
|
|
37
|
-
* config.themes.neutral,
|
|
38
249
|
* 1,
|
|
39
|
-
* config.elevation.offsets,
|
|
40
250
|
* config.spacing,
|
|
41
251
|
* config.radius,
|
|
42
252
|
* config.typography,
|
|
@@ -48,9 +258,7 @@ function fontConfigToFamily(font: FontConfig): string {
|
|
|
48
258
|
export function computeTokens(
|
|
49
259
|
config: ColorSystemConfig,
|
|
50
260
|
mode: ColorMode,
|
|
51
|
-
themeMapping: ThemeMapping,
|
|
52
261
|
elevation: ElevationLevel,
|
|
53
|
-
elevationOffsets: readonly [number, number, number],
|
|
54
262
|
spacing: { readonly '00': number; readonly '02': number; readonly '04': number; readonly '06': number; readonly '08': number; readonly '10': number; readonly '12': number; readonly '16': number; readonly '20': number; readonly '24': number; readonly '32': number; readonly '40': number; readonly '48': number },
|
|
55
263
|
radius: { readonly none: number; readonly sm: number; readonly md: number; readonly lg: number; readonly xl: number; readonly pill: 999 },
|
|
56
264
|
typography: {
|
|
@@ -63,19 +271,44 @@ export function computeTokens(
|
|
|
63
271
|
readonly variant: 'outlined' | 'rounded' | 'sharp';
|
|
64
272
|
readonly weight: 100 | 200 | 300 | 400 | 500 | 600 | 700;
|
|
65
273
|
readonly autoGrade: boolean;
|
|
66
|
-
}
|
|
274
|
+
},
|
|
275
|
+
tokenOverrides?: TokenOverrides
|
|
67
276
|
): ResolvedTokens {
|
|
68
277
|
const { dynamicRange, palettes } = config;
|
|
69
|
-
const palette = palettes[
|
|
278
|
+
const palette = palettes[0]; // Always neutral palette for backgrounds
|
|
70
279
|
|
|
71
280
|
if (!palette) {
|
|
72
|
-
throw new Error(
|
|
281
|
+
throw new Error('Neutral palette (index 0) not found');
|
|
73
282
|
}
|
|
74
283
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
const
|
|
284
|
+
const neutralDefaults = NEUTRAL_DEFAULTS[mode];
|
|
285
|
+
|
|
286
|
+
// --- Mode-specific normalized field resolution ---
|
|
287
|
+
const toEngineNv = (nv: number) => mode === 'light' ? 1 - nv : nv;
|
|
288
|
+
const bgElevatedNorm = mode === 'light' ? tokenOverrides?.backgroundElevated : tokenOverrides?.backgroundElevatedDark;
|
|
289
|
+
const bgDefaultNorm = mode === 'light' ? tokenOverrides?.backgroundDefault : tokenOverrides?.backgroundDefaultDark;
|
|
290
|
+
const bgSunkenNorm = mode === 'light' ? tokenOverrides?.backgroundSunken : tokenOverrides?.backgroundSunkenDark;
|
|
291
|
+
const textPrimaryNorm = mode === 'light' ? tokenOverrides?.textPrimaryNormalized : tokenOverrides?.textPrimaryNormalizedDark;
|
|
292
|
+
const textSecondaryNorm = mode === 'light' ? tokenOverrides?.textSecondaryNormalized : tokenOverrides?.textSecondaryNormalizedDark;
|
|
293
|
+
const textTertiaryNorm = mode === 'light' ? tokenOverrides?.textTertiaryNormalized : tokenOverrides?.textTertiaryNormalizedDark;
|
|
294
|
+
const textDisabledNorm = mode === 'light' ? tokenOverrides?.textDisabledNormalized : tokenOverrides?.textDisabledNormalizedDark;
|
|
295
|
+
|
|
296
|
+
// --- Background NV resolution ---
|
|
297
|
+
// Absolute positions from tokenOverrides or NEUTRAL_DEFAULTS.
|
|
298
|
+
// Ground = Background/01 (elevated). Everything diverges from there.
|
|
299
|
+
const bgNormalized = elevation === 2
|
|
300
|
+
? (bgElevatedNorm ?? neutralDefaults.background.elevated)
|
|
301
|
+
: elevation === 1
|
|
302
|
+
? (bgDefaultNorm ?? neutralDefaults.background.ground)
|
|
303
|
+
: (bgSunkenNorm ?? neutralDefaults.background.sunken);
|
|
304
|
+
const backgroundNv = clamp(toEngineNv(bgNormalized));
|
|
305
|
+
const elevatedNv = clamp(toEngineNv(bgElevatedNorm ?? neutralDefaults.background.elevated));
|
|
306
|
+
const sunkenNv = clamp(toEngineNv(bgSunkenNorm ?? neutralDefaults.background.sunken));
|
|
307
|
+
|
|
308
|
+
// Elevation compensation: how far the current surface is from the reference (bg01/elevated).
|
|
309
|
+
// Tokens designed at bg01 shift by this delta on deeper surfaces to preserve perceptual contrast.
|
|
310
|
+
// Always 0 on bg01. Negative on bg02/bg03 in both modes (surface is darker → tokens darken too).
|
|
311
|
+
const elevationDelta = backgroundNv - elevatedNv;
|
|
79
312
|
|
|
80
313
|
// Derive effective text mode from actual background lightness.
|
|
81
314
|
// This handles inverted themes (e.g., strong: dark bg in light mode)
|
|
@@ -92,8 +325,7 @@ export function computeTokens(
|
|
|
92
325
|
palette.paletteHueGrading
|
|
93
326
|
);
|
|
94
327
|
|
|
95
|
-
// Compute elevated surface
|
|
96
|
-
const elevatedNv = Math.max(0, Math.min(1, baseNv + elevationOffsets[2]));
|
|
328
|
+
// Compute elevated surface
|
|
97
329
|
const backgroundElevated = getColor(
|
|
98
330
|
palette.hue,
|
|
99
331
|
palette.saturation,
|
|
@@ -103,8 +335,7 @@ export function computeTokens(
|
|
|
103
335
|
palette.paletteHueGrading
|
|
104
336
|
);
|
|
105
337
|
|
|
106
|
-
// Compute sunken surface
|
|
107
|
-
const sunkenNv = Math.max(0, Math.min(1, baseNv + elevationOffsets[0]));
|
|
338
|
+
// Compute sunken surface
|
|
108
339
|
const backgroundSunken = getColor(
|
|
109
340
|
palette.hue,
|
|
110
341
|
palette.saturation,
|
|
@@ -114,140 +345,147 @@ export function computeTokens(
|
|
|
114
345
|
palette.paletteHueGrading
|
|
115
346
|
);
|
|
116
347
|
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
|
|
348
|
+
// --- Tunable constants (overridable via tokenOverrides, per-mode) ---
|
|
349
|
+
// All values are magnitudes — direction auto-inverts per effectiveTextMode
|
|
350
|
+
// (darker in light mode, lighter in dark mode)
|
|
351
|
+
const INTERACTIVE_COMPONENT_OFFSET = mode === 'light'
|
|
352
|
+
? (tokenOverrides?.interactiveComponentOffset ?? neutralDefaults.action.enabled)
|
|
353
|
+
: (tokenOverrides?.interactiveComponentOffsetDark ?? neutralDefaults.action.enabled);
|
|
354
|
+
const HOVER_SHIFT = mode === 'light'
|
|
355
|
+
? (tokenOverrides?.hoverShift ?? neutralDefaults.action.hovered)
|
|
356
|
+
: (tokenOverrides?.hoverShiftDark ?? neutralDefaults.action.hovered);
|
|
357
|
+
const ACTIVE_SHIFT = mode === 'light'
|
|
358
|
+
? (tokenOverrides?.activeShift ?? neutralDefaults.action.pressed)
|
|
359
|
+
: (tokenOverrides?.activeShiftDark ?? neutralDefaults.action.pressed);
|
|
360
|
+
const BORDER_OFFSET = mode === 'light'
|
|
361
|
+
? (tokenOverrides?.borderOffset ?? neutralDefaults.border.enabled)
|
|
362
|
+
: (tokenOverrides?.borderOffsetDark ?? neutralDefaults.border.enabled);
|
|
363
|
+
// Compute interactive component background (FIXED NV offset from current elevation)
|
|
364
|
+
// Unlike backgroundElevated/backgroundSunken which use discrete levels, this uses a fixed
|
|
365
|
+
// luminosity offset to ensure CONSISTENT visual contrast across all elevations (-2 to 2).
|
|
366
|
+
// Used by: Button (neutral primary variant) and future components with neutral filled backgrounds.
|
|
367
|
+
const interactiveComponentNv = clamp(backgroundNv + (effectiveTextMode === 'light' ? -INTERACTIVE_COMPONENT_OFFSET : INTERACTIVE_COMPONENT_OFFSET));
|
|
368
|
+
const backgroundInteractive = getColor(
|
|
120
369
|
palette.hue,
|
|
121
370
|
palette.saturation,
|
|
122
371
|
dynamicRange,
|
|
123
|
-
|
|
124
|
-
effectiveTextMode,
|
|
372
|
+
interactiveComponentNv,
|
|
125
373
|
palette.desaturation,
|
|
126
|
-
palette.paletteHueGrading
|
|
127
|
-
background,
|
|
374
|
+
palette.paletteHueGrading
|
|
128
375
|
);
|
|
129
376
|
|
|
130
|
-
//
|
|
131
|
-
const
|
|
377
|
+
// Neutral hover/active: shift from interactive component base (same direction as accent hover/active)
|
|
378
|
+
const neutralHoverNv = clamp(interactiveComponentNv + (effectiveTextMode === 'light' ? -HOVER_SHIFT : HOVER_SHIFT));
|
|
379
|
+
const backgroundInteractiveHover = getColor(
|
|
132
380
|
palette.hue,
|
|
133
381
|
palette.saturation,
|
|
134
382
|
dynamicRange,
|
|
135
|
-
|
|
136
|
-
effectiveTextMode,
|
|
383
|
+
neutralHoverNv,
|
|
137
384
|
palette.desaturation,
|
|
138
|
-
palette.paletteHueGrading
|
|
139
|
-
background,
|
|
385
|
+
palette.paletteHueGrading
|
|
140
386
|
);
|
|
141
387
|
|
|
142
|
-
|
|
143
|
-
const
|
|
388
|
+
const neutralActiveNv = clamp(interactiveComponentNv + (effectiveTextMode === 'light' ? -ACTIVE_SHIFT : ACTIVE_SHIFT));
|
|
389
|
+
const backgroundInteractiveActive = getColor(
|
|
390
|
+
palette.hue,
|
|
391
|
+
palette.saturation,
|
|
392
|
+
dynamicRange,
|
|
393
|
+
neutralActiveNv,
|
|
394
|
+
palette.desaturation,
|
|
395
|
+
palette.paletteHueGrading
|
|
396
|
+
);
|
|
144
397
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
398
|
+
// --- Text color resolution (elevation-compensated) ---
|
|
399
|
+
// Normalized positions define text contrast at bg01 (elevated). On deeper surfaces,
|
|
400
|
+
// elevationDelta shifts text toward the background to preserve the same contrast distance.
|
|
401
|
+
// Uses effectiveTextMode for NV conversion so inverted themes (e.g., strong: dark bg in
|
|
402
|
+
// light mode) auto-correct text direction — light text on dark bg, dark text on light bg.
|
|
403
|
+
const textToEngineNv = (nv: number) => effectiveTextMode === 'light' ? 1 - nv : nv;
|
|
148
404
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
405
|
+
const textPrimary = getColor(palette.hue, palette.saturation, dynamicRange,
|
|
406
|
+
clamp(textToEngineNv(textPrimaryNorm ?? neutralDefaults.text.primary) + elevationDelta),
|
|
407
|
+
palette.desaturation, palette.paletteHueGrading);
|
|
152
408
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
? getColor(
|
|
157
|
-
accentPalette.hue,
|
|
158
|
-
accentPalette.saturation,
|
|
159
|
-
dynamicRange,
|
|
160
|
-
accentKeyNv,
|
|
161
|
-
accentPalette.desaturation,
|
|
162
|
-
accentPalette.paletteHueGrading
|
|
163
|
-
)
|
|
164
|
-
: getColorByContrast(
|
|
165
|
-
accentPalette.hue,
|
|
166
|
-
accentPalette.saturation,
|
|
167
|
-
dynamicRange,
|
|
168
|
-
4.5,
|
|
169
|
-
effectiveTextMode,
|
|
170
|
-
accentPalette.desaturation,
|
|
171
|
-
accentPalette.paletteHueGrading,
|
|
172
|
-
background,
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
// Hover/active states: Shift NV slightly from interactive base
|
|
176
|
-
// In light mode (light bg), go darker; in dark mode (dark bg), go lighter
|
|
177
|
-
const interactiveNv = accentKeyNv ?? (effectiveTextMode === 'light' ? 0.3 : 0.7);
|
|
178
|
-
|
|
179
|
-
const interactiveHover = getColor(
|
|
180
|
-
accentPalette.hue,
|
|
181
|
-
accentPalette.saturation,
|
|
182
|
-
dynamicRange,
|
|
183
|
-
interactiveNv + (effectiveTextMode === 'light' ? -0.05 : 0.05),
|
|
184
|
-
accentPalette.desaturation,
|
|
185
|
-
accentPalette.paletteHueGrading
|
|
186
|
-
);
|
|
409
|
+
const textSecondary = getColor(palette.hue, palette.saturation, dynamicRange,
|
|
410
|
+
clamp(textToEngineNv(textSecondaryNorm ?? neutralDefaults.text.secondary) + elevationDelta),
|
|
411
|
+
palette.desaturation, palette.paletteHueGrading);
|
|
187
412
|
|
|
188
|
-
const
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
);
|
|
413
|
+
const textTertiary = getColor(palette.hue, palette.saturation, dynamicRange,
|
|
414
|
+
clamp(textToEngineNv(textTertiaryNorm ?? neutralDefaults.text.tertiary) + elevationDelta),
|
|
415
|
+
palette.desaturation, palette.paletteHueGrading);
|
|
416
|
+
|
|
417
|
+
const textDisabled = getColor(palette.hue, palette.saturation, dynamicRange,
|
|
418
|
+
clamp(textToEngineNv(textDisabledNorm ?? neutralDefaults.text.disabled) + elevationDelta),
|
|
419
|
+
palette.desaturation, palette.paletteHueGrading);
|
|
196
420
|
|
|
197
421
|
// Border: Subtle contrast from background
|
|
198
|
-
const borderNv = effectiveTextMode === 'light' ? backgroundNv -
|
|
422
|
+
const borderNv = effectiveTextMode === 'light' ? backgroundNv - BORDER_OFFSET : backgroundNv + BORDER_OFFSET;
|
|
199
423
|
const border = getColor(
|
|
200
424
|
palette.hue,
|
|
201
425
|
palette.saturation,
|
|
202
426
|
dynamicRange,
|
|
203
|
-
|
|
427
|
+
clamp(borderNv),
|
|
204
428
|
palette.desaturation,
|
|
205
429
|
palette.paletteHueGrading
|
|
206
430
|
);
|
|
207
431
|
|
|
208
|
-
//
|
|
209
|
-
//
|
|
432
|
+
// --- Per-palette token computation ---
|
|
433
|
+
// Auto accent NV: derived from text primary position (used when no explicit key color is set)
|
|
434
|
+
const autoAccentNv = clamp(textToEngineNv(textPrimaryNorm ?? neutralDefaults.text.primary));
|
|
435
|
+
|
|
436
|
+
const accentPalette = palettes[1];
|
|
437
|
+
if (!accentPalette) {
|
|
438
|
+
throw new Error('Accent palette (index 1) not found');
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
const accent = computePaletteTokens(
|
|
442
|
+
accentPalette, ACCENT_DEFAULTS, mode, elevation, dynamicRange,
|
|
443
|
+
elevationDelta, effectiveTextMode, autoAccentNv,
|
|
444
|
+
textPrimary, backgroundElevated,
|
|
445
|
+
);
|
|
446
|
+
|
|
210
447
|
const successPalette = palettes[2];
|
|
211
448
|
const warningPalette = palettes[3];
|
|
212
449
|
const errorPalette = palettes[4];
|
|
213
450
|
|
|
214
|
-
|
|
451
|
+
// Semantic palettes: fall back to accent palette if not present
|
|
215
452
|
const success = successPalette
|
|
216
|
-
? (
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
:
|
|
222
|
-
|
|
223
|
-
const warningKeyNv = warningPalette ? resolveKeyNv(warningPalette) : undefined;
|
|
453
|
+
? computePaletteTokens(
|
|
454
|
+
successPalette, SUCCESS_DEFAULTS, mode, elevation, dynamicRange,
|
|
455
|
+
elevationDelta, effectiveTextMode, autoAccentNv,
|
|
456
|
+
textPrimary, backgroundElevated,
|
|
457
|
+
)
|
|
458
|
+
: accent;
|
|
459
|
+
|
|
224
460
|
const warning = warningPalette
|
|
225
|
-
? (
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
:
|
|
231
|
-
|
|
232
|
-
const errorKeyNv = errorPalette ? resolveKeyNv(errorPalette) : undefined;
|
|
461
|
+
? computePaletteTokens(
|
|
462
|
+
warningPalette, WARNING_DEFAULTS, mode, elevation, dynamicRange,
|
|
463
|
+
elevationDelta, effectiveTextMode, autoAccentNv,
|
|
464
|
+
textPrimary, backgroundElevated,
|
|
465
|
+
)
|
|
466
|
+
: accent;
|
|
467
|
+
|
|
233
468
|
const error = errorPalette
|
|
234
|
-
? (
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
:
|
|
469
|
+
? computePaletteTokens(
|
|
470
|
+
errorPalette, ERROR_DEFAULTS, mode, elevation, dynamicRange,
|
|
471
|
+
elevationDelta, effectiveTextMode, autoAccentNv,
|
|
472
|
+
textPrimary, backgroundElevated,
|
|
473
|
+
)
|
|
474
|
+
: accent;
|
|
240
475
|
|
|
241
476
|
return {
|
|
242
477
|
background,
|
|
243
478
|
backgroundElevated,
|
|
244
479
|
backgroundSunken,
|
|
480
|
+
backgroundInteractive,
|
|
481
|
+
backgroundInteractiveHover,
|
|
482
|
+
backgroundInteractiveActive,
|
|
245
483
|
textPrimary,
|
|
246
484
|
textSecondary,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
interactiveActive,
|
|
485
|
+
textTertiary,
|
|
486
|
+
textDisabled,
|
|
250
487
|
border,
|
|
488
|
+
accent,
|
|
251
489
|
success,
|
|
252
490
|
warning,
|
|
253
491
|
error,
|