@ankhorage/zora 0.12.3 → 0.13.2
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/CHANGELOG.md +18 -0
- package/README.md +10 -4
- package/dist/internal/color/colorToneRecipes.d.ts +23 -0
- package/dist/internal/color/colorToneRecipes.d.ts.map +1 -0
- package/dist/internal/color/colorToneRecipes.js +139 -0
- package/dist/internal/color/colorToneRecipes.js.map +1 -0
- package/dist/internal/color/index.d.ts +2 -1
- package/dist/internal/color/index.d.ts.map +1 -1
- package/dist/internal/color/index.js +1 -0
- package/dist/internal/color/index.js.map +1 -1
- package/dist/internal/color/roleScales.d.ts +2 -1
- package/dist/internal/color/roleScales.d.ts.map +1 -1
- package/dist/internal/color/roleScales.js +33 -5
- package/dist/internal/color/roleScales.js.map +1 -1
- package/dist/internal/color/scales.d.ts +2 -0
- package/dist/internal/color/scales.d.ts.map +1 -1
- package/dist/internal/color/scales.js +16 -9
- package/dist/internal/color/scales.js.map +1 -1
- package/dist/theme/createZoraThemeConfig.js +2 -2
- package/dist/theme/createZoraThemeConfig.js.map +1 -1
- package/dist/theme/types.d.ts +6 -4
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js +20 -1
- package/dist/theme/types.js.map +1 -1
- package/dist/theme/zoraDefaultTheme.js +1 -1
- package/dist/theme/zoraDefaultTheme.js.map +1 -1
- package/package.json +2 -2
- package/src/components/heading/resolveHeadingRecipe.test.ts +2 -2
- package/src/components/text/resolveTextRecipe.test.ts +2 -2
- package/src/internal/color/colorToneRecipes.test.ts +89 -0
- package/src/internal/color/colorToneRecipes.ts +167 -0
- package/src/internal/color/index.ts +9 -0
- package/src/internal/color/roleScales.test.ts +72 -99
- package/src/internal/color/roleScales.ts +36 -6
- package/src/internal/color/scales.ts +27 -10
- package/src/theme/createZoraThemeConfig.test.ts +5 -5
- package/src/theme/createZoraThemeConfig.ts +2 -2
- package/src/theme/types.ts +26 -10
- package/src/theme/zoraDefaultTheme.ts +1 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ZoraHexColor } from '../../theme/types';
|
|
2
|
+
import type { ZoraColorToneRecipe } from './colorToneRecipes';
|
|
3
|
+
import { getZoraColorToneRoleChromaFactor } from './colorToneRecipes';
|
|
2
4
|
import { clampOklchToGamut, formatOklchAsHex, parseHexToOklch } from './oklch';
|
|
3
5
|
import { type ZoraColorScale, type ZoraColorScaleStep } from './types';
|
|
4
6
|
|
|
@@ -13,6 +15,7 @@ export interface CreateZoraHueScaleOptions {
|
|
|
13
15
|
hue: number;
|
|
14
16
|
seedChroma: number;
|
|
15
17
|
role: ZoraHueScaleRoleId;
|
|
18
|
+
colorToneRecipe: ZoraColorToneRecipe;
|
|
16
19
|
}
|
|
17
20
|
|
|
18
21
|
const PRIMARY_LIGHTNESS_BY_STEP: Record<ZoraColorScaleStep, number> = {
|
|
@@ -62,14 +65,6 @@ const MIN_PRIMARY_SCALE_CHROMA = 0.04;
|
|
|
62
65
|
const NEUTRAL_CHROMA = 0.012;
|
|
63
66
|
const DEFAULT_NEUTRAL_HUE_DEGREES = 260;
|
|
64
67
|
|
|
65
|
-
const ROLE_CHROMA_FACTOR = {
|
|
66
|
-
primary: 1,
|
|
67
|
-
secondary: 0.72,
|
|
68
|
-
accent: 0.85,
|
|
69
|
-
highlight: 1,
|
|
70
|
-
surfaceTint: 0.18,
|
|
71
|
-
} satisfies Record<ZoraHueScaleRoleId, number>;
|
|
72
|
-
|
|
73
68
|
function clampNumber(value: number, min: number, max: number): number {
|
|
74
69
|
return Math.max(min, Math.min(value, max));
|
|
75
70
|
}
|
|
@@ -85,12 +80,34 @@ function resolvePrimaryScaleChroma(seedChroma: number, step: ZoraColorScaleStep)
|
|
|
85
80
|
return shouldEnforceMin ? Math.max(bounded, MIN_PRIMARY_SCALE_CHROMA) : bounded;
|
|
86
81
|
}
|
|
87
82
|
|
|
83
|
+
function resolveRoleScaleChroma(options: {
|
|
84
|
+
seedChroma: number;
|
|
85
|
+
step: ZoraColorScaleStep;
|
|
86
|
+
maxChroma: number;
|
|
87
|
+
minMidChroma: number;
|
|
88
|
+
}): number {
|
|
89
|
+
const cappedSeedChroma = clampNumber(options.seedChroma, 0, options.maxChroma);
|
|
90
|
+
const multiplier = PRIMARY_CHROMA_MULTIPLIER_BY_STEP[options.step];
|
|
91
|
+
const scaled = cappedSeedChroma * multiplier;
|
|
92
|
+
const bounded = clampNumber(scaled, 0, options.maxChroma);
|
|
93
|
+
const shouldEnforceMin =
|
|
94
|
+
options.step >= 300 && options.step <= 700 && options.seedChroma >= options.minMidChroma;
|
|
95
|
+
|
|
96
|
+
return shouldEnforceMin ? Math.max(bounded, options.minMidChroma) : bounded;
|
|
97
|
+
}
|
|
98
|
+
|
|
88
99
|
function resolveHueScaleChroma(
|
|
89
100
|
options: CreateZoraHueScaleOptions,
|
|
90
101
|
step: ZoraColorScaleStep,
|
|
91
102
|
): number {
|
|
92
|
-
const factor =
|
|
93
|
-
|
|
103
|
+
const factor = getZoraColorToneRoleChromaFactor(options.colorToneRecipe, options.role);
|
|
104
|
+
|
|
105
|
+
return resolveRoleScaleChroma({
|
|
106
|
+
seedChroma: options.seedChroma * factor,
|
|
107
|
+
step,
|
|
108
|
+
maxChroma: options.colorToneRecipe.maxChroma,
|
|
109
|
+
minMidChroma: options.colorToneRecipe.minMidChroma,
|
|
110
|
+
});
|
|
94
111
|
}
|
|
95
112
|
|
|
96
113
|
function createScaleEntries(options: CreateZoraColorScaleOptions): ZoraColorScale {
|
|
@@ -16,10 +16,10 @@ describe('createZoraThemeConfig', () => {
|
|
|
16
16
|
expect(themeConfig.name).toBe('ZORA');
|
|
17
17
|
expect(isSixDigitHexColor(themeConfig.light.primaryColor)).toBe(true);
|
|
18
18
|
expect(themeConfig.light.harmony).toBe('analogous');
|
|
19
|
-
expect(themeConfig.light.
|
|
19
|
+
expect(themeConfig.light.colorTone).toBe('jewel');
|
|
20
20
|
expect(isSixDigitHexColor(themeConfig.dark.primaryColor)).toBe(true);
|
|
21
21
|
expect(themeConfig.dark.harmony).toBe('analogous');
|
|
22
|
-
expect(themeConfig.dark.
|
|
22
|
+
expect(themeConfig.dark.colorTone).toBe('jewel');
|
|
23
23
|
|
|
24
24
|
expect(themeConfig.light.primaryColor).not.toBe(themeConfig.dark.primaryColor);
|
|
25
25
|
|
|
@@ -33,17 +33,17 @@ describe('createZoraThemeConfig', () => {
|
|
|
33
33
|
id: 'studio',
|
|
34
34
|
primaryColor: '#0f766e',
|
|
35
35
|
harmony: 'analogous',
|
|
36
|
-
|
|
36
|
+
colorTone: 'jewel',
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
expect(themeConfig.id).toBe('studio');
|
|
40
40
|
expect(themeConfig.name).toBe('studio');
|
|
41
41
|
expect(isSixDigitHexColor(themeConfig.light.primaryColor)).toBe(true);
|
|
42
42
|
expect(themeConfig.light.harmony).toBe('analogous');
|
|
43
|
-
expect(themeConfig.light.
|
|
43
|
+
expect(themeConfig.light.colorTone).toBe('jewel');
|
|
44
44
|
expect(isSixDigitHexColor(themeConfig.dark.primaryColor)).toBe(true);
|
|
45
45
|
expect(themeConfig.dark.harmony).toBe('analogous');
|
|
46
|
-
expect(themeConfig.dark.
|
|
46
|
+
expect(themeConfig.dark.colorTone).toBe('jewel');
|
|
47
47
|
|
|
48
48
|
expect(themeConfig.light.primaryColor).not.toBe(themeConfig.dark.primaryColor);
|
|
49
49
|
});
|
|
@@ -11,12 +11,12 @@ export function createZoraThemeConfig(theme: ZoraTheme = zoraDefaultTheme): Them
|
|
|
11
11
|
light: {
|
|
12
12
|
primaryColor: resolveModePrimaryColor(theme.primaryColor, 'light'),
|
|
13
13
|
harmony: theme.harmony,
|
|
14
|
-
|
|
14
|
+
colorTone: theme.colorTone,
|
|
15
15
|
},
|
|
16
16
|
dark: {
|
|
17
17
|
primaryColor: resolveModePrimaryColor(theme.primaryColor, 'dark'),
|
|
18
18
|
harmony: theme.harmony,
|
|
19
|
-
|
|
19
|
+
colorTone: theme.colorTone,
|
|
20
20
|
},
|
|
21
21
|
};
|
|
22
22
|
}
|
package/src/theme/types.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ThemeConfig } from '@ankhorage/surface';
|
|
1
|
+
import type { ColorHarmony, ColorTone, ThemeConfig } from '@ankhorage/surface';
|
|
2
2
|
|
|
3
3
|
export type ZoraThemeId = string;
|
|
4
4
|
|
|
@@ -6,22 +6,38 @@ export type ZoraThemeMode = 'light' | 'dark';
|
|
|
6
6
|
|
|
7
7
|
export type ZoraHexColor = `#${string}`;
|
|
8
8
|
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
export const ZORA_COLOR_HARMONIES = [
|
|
10
|
+
'monochromatic',
|
|
11
|
+
'analogous',
|
|
12
|
+
'complementary',
|
|
13
|
+
'splitComplementary',
|
|
14
|
+
'triadic',
|
|
15
|
+
'tetradic',
|
|
16
|
+
] as const satisfies readonly ColorHarmony[];
|
|
16
17
|
|
|
17
|
-
export type
|
|
18
|
+
export type ZoraColorHarmony = ColorHarmony;
|
|
19
|
+
|
|
20
|
+
export const ZORA_COLOR_TONES = [
|
|
21
|
+
'neutral',
|
|
22
|
+
'pastel',
|
|
23
|
+
'earth',
|
|
24
|
+
'mineral',
|
|
25
|
+
'muted',
|
|
26
|
+
'jewel',
|
|
27
|
+
'fluorescent',
|
|
28
|
+
'obsidian',
|
|
29
|
+
'vaporwave',
|
|
30
|
+
'monochromeAccent',
|
|
31
|
+
] as const satisfies readonly ColorTone[];
|
|
32
|
+
|
|
33
|
+
export type ZoraColorTone = ColorTone;
|
|
18
34
|
|
|
19
35
|
export interface ZoraTheme {
|
|
20
36
|
id: ZoraThemeId;
|
|
21
37
|
name?: string;
|
|
22
38
|
primaryColor: ZoraHexColor;
|
|
23
39
|
harmony: ZoraColorHarmony;
|
|
24
|
-
|
|
40
|
+
colorTone: ZoraColorTone;
|
|
25
41
|
}
|
|
26
42
|
|
|
27
43
|
export interface ZoraComputedTheme {
|