@ankhorage/zora 0.16.1 → 1.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/CHANGELOG.md +69 -0
- package/README.md +11 -13
- package/dist/components/heading/resolveHeadingRecipe.d.ts +2 -2
- package/dist/components/heading/resolveHeadingRecipe.d.ts.map +1 -1
- package/dist/components/heading/resolveHeadingRecipe.js.map +1 -1
- package/dist/components/text/resolveTextRecipe.d.ts +2 -2
- package/dist/components/text/resolveTextRecipe.d.ts.map +1 -1
- package/dist/components/text/resolveTextRecipe.js.map +1 -1
- package/dist/patterns/theme-composer/ThemeComposer.d.ts.map +1 -1
- package/dist/patterns/theme-composer/ThemeComposer.js +10 -86
- package/dist/patterns/theme-composer/ThemeComposer.js.map +1 -1
- package/dist/patterns/theme-composer/index.d.ts +1 -1
- package/dist/patterns/theme-composer/index.d.ts.map +1 -1
- package/dist/patterns/theme-composer/index.js.map +1 -1
- package/dist/patterns/theme-composer/types.d.ts +1 -13
- package/dist/patterns/theme-composer/types.d.ts.map +1 -1
- package/dist/patterns/theme-composer/types.js.map +1 -1
- package/dist/theme/createZoraThemeConfig.d.ts +1 -1
- package/dist/theme/createZoraThemeConfig.d.ts.map +1 -1
- package/dist/theme/createZoraThemeConfig.js +5 -6
- package/dist/theme/createZoraThemeConfig.js.map +1 -1
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/types.d.ts +16 -11
- package/dist/theme/types.d.ts.map +1 -1
- package/dist/theme/types.js +1 -20
- package/dist/theme/types.js.map +1 -1
- package/dist/theme/useZoraTheme.d.ts +1 -1
- package/dist/theme/zoraDefaultTheme.js +1 -1
- package/dist/theme/zoraDefaultTheme.js.map +1 -1
- package/package.json +5 -4
- package/src/components/heading/resolveHeadingRecipe.test.ts +30 -5
- package/src/components/heading/resolveHeadingRecipe.ts +6 -6
- package/src/components/text/resolveTextRecipe.test.ts +30 -5
- package/src/components/text/resolveTextRecipe.ts +6 -6
- package/src/patterns/theme-composer/ThemeComposer.test.ts +9 -141
- package/src/patterns/theme-composer/ThemeComposer.tsx +10 -131
- package/src/patterns/theme-composer/index.ts +1 -6
- package/src/patterns/theme-composer/types.ts +1 -15
- package/src/showcaseCoverage.test.ts +128 -0
- package/src/theme/createZoraThemeConfig.test.ts +51 -26
- package/src/theme/createZoraThemeConfig.ts +7 -7
- package/src/theme/index.ts +1 -3
- package/src/theme/types.ts +22 -34
- package/src/theme/zoraDefaultTheme.ts +1 -1
- package/dist/internal/color/colorToneRecipes.d.ts +0 -23
- package/dist/internal/color/colorToneRecipes.d.ts.map +0 -1
- package/dist/internal/color/colorToneRecipes.js +0 -139
- package/dist/internal/color/colorToneRecipes.js.map +0 -1
- package/dist/internal/color/harmony.d.ts +0 -12
- package/dist/internal/color/harmony.d.ts.map +0 -1
- package/dist/internal/color/harmony.js +0 -69
- package/dist/internal/color/harmony.js.map +0 -1
- package/dist/internal/color/hue.d.ts +0 -3
- package/dist/internal/color/hue.d.ts.map +0 -1
- package/dist/internal/color/hue.js +0 -7
- package/dist/internal/color/hue.js.map +0 -1
- package/dist/internal/color/index.d.ts +0 -10
- package/dist/internal/color/index.d.ts.map +0 -1
- package/dist/internal/color/index.js +0 -10
- package/dist/internal/color/index.js.map +0 -1
- package/dist/internal/color/oklch.d.ts +0 -6
- package/dist/internal/color/oklch.d.ts.map +0 -1
- package/dist/internal/color/oklch.js +0 -50
- package/dist/internal/color/oklch.js.map +0 -1
- package/dist/internal/color/primary.d.ts +0 -3
- package/dist/internal/color/primary.d.ts.map +0 -1
- package/dist/internal/color/primary.js +0 -44
- package/dist/internal/color/primary.js.map +0 -1
- package/dist/internal/color/roleHues.d.ts +0 -15
- package/dist/internal/color/roleHues.d.ts.map +0 -1
- package/dist/internal/color/roleHues.js +0 -103
- package/dist/internal/color/roleHues.js.map +0 -1
- package/dist/internal/color/roleScales.d.ts +0 -20
- package/dist/internal/color/roleScales.d.ts.map +0 -1
- package/dist/internal/color/roleScales.js +0 -79
- package/dist/internal/color/roleScales.js.map +0 -1
- package/dist/internal/color/scales.d.ts +0 -19
- package/dist/internal/color/scales.d.ts.map +0 -1
- package/dist/internal/color/scales.js +0 -135
- package/dist/internal/color/scales.js.map +0 -1
- package/dist/internal/color/semanticTokens.d.ts +0 -28
- package/dist/internal/color/semanticTokens.d.ts.map +0 -1
- package/dist/internal/color/semanticTokens.js +0 -84
- package/dist/internal/color/semanticTokens.js.map +0 -1
- package/dist/internal/color/types.d.ts +0 -10
- package/dist/internal/color/types.d.ts.map +0 -1
- package/dist/internal/color/types.js +0 -4
- package/dist/internal/color/types.js.map +0 -1
- package/dist/patterns/theme-composer/recommendations.d.ts +0 -14
- package/dist/patterns/theme-composer/recommendations.d.ts.map +0 -1
- package/dist/patterns/theme-composer/recommendations.js +0 -58
- package/dist/patterns/theme-composer/recommendations.js.map +0 -1
- package/src/internal/color/colorToneRecipes.test.ts +0 -89
- package/src/internal/color/colorToneRecipes.ts +0 -167
- package/src/internal/color/harmony.test.ts +0 -145
- package/src/internal/color/harmony.ts +0 -96
- package/src/internal/color/hue.test.ts +0 -28
- package/src/internal/color/hue.ts +0 -7
- package/src/internal/color/index.ts +0 -44
- package/src/internal/color/oklch.ts +0 -65
- package/src/internal/color/primary.test.ts +0 -105
- package/src/internal/color/primary.ts +0 -64
- package/src/internal/color/roleHues.test.ts +0 -197
- package/src/internal/color/roleHues.ts +0 -142
- package/src/internal/color/roleScales.test.ts +0 -220
- package/src/internal/color/roleScales.ts +0 -127
- package/src/internal/color/scales.test.ts +0 -151
- package/src/internal/color/scales.ts +0 -194
- package/src/internal/color/semanticTokens.test.ts +0 -170
- package/src/internal/color/semanticTokens.ts +0 -114
- package/src/internal/color/types.ts +0 -15
- package/src/patterns/theme-composer/recommendations.ts +0 -85
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import type { ZoraColorTone, ZoraHexColor, ZoraThemeMode } from '../../theme/types';
|
|
2
|
-
import { parseHexToOklch } from './oklch';
|
|
3
|
-
import { getZoraRoleColorScale, type ZoraComputedRoleColorScales } from './roleScales';
|
|
4
|
-
|
|
5
|
-
export interface ZoraSemanticColorTokens {
|
|
6
|
-
background: ZoraHexColor;
|
|
7
|
-
surface: ZoraHexColor;
|
|
8
|
-
surfaceRaised: ZoraHexColor;
|
|
9
|
-
surfaceTint: ZoraHexColor;
|
|
10
|
-
border: ZoraHexColor;
|
|
11
|
-
text: ZoraHexColor;
|
|
12
|
-
textMuted: ZoraHexColor;
|
|
13
|
-
primary: ZoraHexColor;
|
|
14
|
-
secondary: ZoraHexColor;
|
|
15
|
-
accent: ZoraHexColor;
|
|
16
|
-
highlight: ZoraHexColor;
|
|
17
|
-
onPrimary: ZoraHexColor;
|
|
18
|
-
onAccent: ZoraHexColor;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Selects the more readable of two candidate hex colors against a given background,
|
|
23
|
-
* using OKLCH lightness as a simple contrast proxy.
|
|
24
|
-
*/
|
|
25
|
-
export function getReadableTextColor(
|
|
26
|
-
background: ZoraHexColor,
|
|
27
|
-
candidates: readonly [ZoraHexColor, ZoraHexColor],
|
|
28
|
-
): ZoraHexColor {
|
|
29
|
-
const bgL = parseHexToOklch(background).l;
|
|
30
|
-
const [a, b] = candidates;
|
|
31
|
-
const diffA = Math.abs(parseHexToOklch(a).l - bgL);
|
|
32
|
-
const diffB = Math.abs(parseHexToOklch(b).l - bgL);
|
|
33
|
-
return diffA >= diffB ? a : b;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function createZoraSemanticColorTokens(options: {
|
|
37
|
-
roleScales: ZoraComputedRoleColorScales;
|
|
38
|
-
mode: ZoraThemeMode;
|
|
39
|
-
colorTone: ZoraColorTone;
|
|
40
|
-
}): ZoraSemanticColorTokens {
|
|
41
|
-
// colorTone is accepted now and reserved for future per-tone step overrides
|
|
42
|
-
// (e.g. obsidian/pastel may shift surface selections differently).
|
|
43
|
-
const { roleScales, mode } = options;
|
|
44
|
-
|
|
45
|
-
const neutral = getZoraRoleColorScale(roleScales, 'neutral').scale;
|
|
46
|
-
const surfaceTintScale = getZoraRoleColorScale(roleScales, 'surfaceTint').scale;
|
|
47
|
-
const primaryScale = getZoraRoleColorScale(roleScales, 'primary').scale;
|
|
48
|
-
const secondaryScale = getZoraRoleColorScale(roleScales, 'secondary').scale;
|
|
49
|
-
const accentScale = getZoraRoleColorScale(roleScales, 'accent').scale;
|
|
50
|
-
const highlightScale = getZoraRoleColorScale(roleScales, 'highlight').scale;
|
|
51
|
-
|
|
52
|
-
if (mode === 'light') {
|
|
53
|
-
const background = neutral[50];
|
|
54
|
-
const surface = neutral[100];
|
|
55
|
-
const surfaceRaised = neutral[50];
|
|
56
|
-
const surfaceTint = surfaceTintScale[100];
|
|
57
|
-
const border = neutral[200];
|
|
58
|
-
const text = neutral[900];
|
|
59
|
-
const textMuted = neutral[700];
|
|
60
|
-
const primary = primaryScale[600];
|
|
61
|
-
const secondary = secondaryScale[600];
|
|
62
|
-
const accent = accentScale[600];
|
|
63
|
-
const highlight = highlightScale[600];
|
|
64
|
-
const onPrimary = getReadableTextColor(primary, [neutral[50], neutral[950]]);
|
|
65
|
-
const onAccent = getReadableTextColor(accent, [neutral[50], neutral[950]]);
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
background,
|
|
69
|
-
surface,
|
|
70
|
-
surfaceRaised,
|
|
71
|
-
surfaceTint,
|
|
72
|
-
border,
|
|
73
|
-
text,
|
|
74
|
-
textMuted,
|
|
75
|
-
primary,
|
|
76
|
-
secondary,
|
|
77
|
-
accent,
|
|
78
|
-
highlight,
|
|
79
|
-
onPrimary,
|
|
80
|
-
onAccent,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// dark mode
|
|
85
|
-
const background = neutral[950];
|
|
86
|
-
const surface = neutral[900];
|
|
87
|
-
const surfaceRaised = neutral[800];
|
|
88
|
-
const surfaceTint = surfaceTintScale[900];
|
|
89
|
-
const border = neutral[700];
|
|
90
|
-
const text = neutral[50];
|
|
91
|
-
const textMuted = neutral[300];
|
|
92
|
-
const primary = primaryScale[400];
|
|
93
|
-
const secondary = secondaryScale[400];
|
|
94
|
-
const accent = accentScale[400];
|
|
95
|
-
const highlight = highlightScale[400];
|
|
96
|
-
const onPrimary = getReadableTextColor(primary, [neutral[50], neutral[950]]);
|
|
97
|
-
const onAccent = getReadableTextColor(accent, [neutral[50], neutral[950]]);
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
background,
|
|
101
|
-
surface,
|
|
102
|
-
surfaceRaised,
|
|
103
|
-
surfaceTint,
|
|
104
|
-
border,
|
|
105
|
-
text,
|
|
106
|
-
textMuted,
|
|
107
|
-
primary,
|
|
108
|
-
secondary,
|
|
109
|
-
accent,
|
|
110
|
-
highlight,
|
|
111
|
-
onPrimary,
|
|
112
|
-
onAccent,
|
|
113
|
-
};
|
|
114
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { ZoraHexColor } from '../../theme/types';
|
|
2
|
-
|
|
3
|
-
export interface ZoraOklchColor {
|
|
4
|
-
l: number;
|
|
5
|
-
c: number;
|
|
6
|
-
h: number;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export const ZORA_COLOR_SCALE_STEPS = [
|
|
10
|
-
50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950,
|
|
11
|
-
] as const;
|
|
12
|
-
|
|
13
|
-
export type ZoraColorScaleStep = (typeof ZORA_COLOR_SCALE_STEPS)[number];
|
|
14
|
-
|
|
15
|
-
export type ZoraColorScale = Record<ZoraColorScaleStep, ZoraHexColor>;
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import type { ZoraHexColor, ZoraTheme } from '../../theme/types';
|
|
2
|
-
import type {
|
|
3
|
-
ThemeComposerAppCategory,
|
|
4
|
-
ThemeComposerAppMood,
|
|
5
|
-
ThemeComposerRecommendation,
|
|
6
|
-
} from './types';
|
|
7
|
-
|
|
8
|
-
export function findThemeComposerRecommendation(options: {
|
|
9
|
-
appCategory?: ThemeComposerAppCategory;
|
|
10
|
-
appMood?: ThemeComposerAppMood;
|
|
11
|
-
recommendations?: readonly ThemeComposerRecommendation[];
|
|
12
|
-
}): ThemeComposerRecommendation | undefined {
|
|
13
|
-
if (options.appCategory === undefined || options.recommendations === undefined) {
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return options.recommendations.find(
|
|
18
|
-
(recommendation) =>
|
|
19
|
-
recommendation.appCategory === options.appCategory &&
|
|
20
|
-
(options.appMood === undefined || recommendation.appMood === options.appMood),
|
|
21
|
-
);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function formatThemeComposerLabel(value: string): string {
|
|
25
|
-
const spaced = value
|
|
26
|
-
.replace(/_/g, ' ')
|
|
27
|
-
.replace(/([a-z0-9])([A-Z])/g, '$1 $2')
|
|
28
|
-
.trim();
|
|
29
|
-
|
|
30
|
-
if (spaced.length === 0) {
|
|
31
|
-
return value;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return `${spaced.slice(0, 1).toUpperCase()}${spaced.slice(1)}`;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function hueDegreesToZoraHexColor(hueDegrees: number): ZoraHexColor {
|
|
38
|
-
const normalizedHue = ((hueDegrees % 360) + 360) % 360;
|
|
39
|
-
const chroma = 0.56;
|
|
40
|
-
const lightness = 0.46;
|
|
41
|
-
const second = chroma * (1 - Math.abs(((normalizedHue / 60) % 2) - 1));
|
|
42
|
-
const match = lightness - chroma / 2;
|
|
43
|
-
|
|
44
|
-
const hueSector = Math.floor(normalizedHue / 60);
|
|
45
|
-
const [redPrime, greenPrime, bluePrime] = (() => {
|
|
46
|
-
switch (hueSector) {
|
|
47
|
-
case 0:
|
|
48
|
-
return [chroma, second, 0] as const;
|
|
49
|
-
case 1:
|
|
50
|
-
return [second, chroma, 0] as const;
|
|
51
|
-
case 2:
|
|
52
|
-
return [0, chroma, second] as const;
|
|
53
|
-
case 3:
|
|
54
|
-
return [0, second, chroma] as const;
|
|
55
|
-
case 4:
|
|
56
|
-
return [second, 0, chroma] as const;
|
|
57
|
-
default:
|
|
58
|
-
return [chroma, 0, second] as const;
|
|
59
|
-
}
|
|
60
|
-
})();
|
|
61
|
-
|
|
62
|
-
const toHexChannel = (channel: number): string => {
|
|
63
|
-
const value = Math.round(Math.min(1, Math.max(0, channel + match)) * 255);
|
|
64
|
-
return value.toString(16).padStart(2, '0');
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
return `#${toHexChannel(redPrime)}${toHexChannel(greenPrime)}${toHexChannel(bluePrime)}`;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
export function createThemeFromThemeComposerRecommendation(options: {
|
|
71
|
-
value: ZoraTheme;
|
|
72
|
-
recommendation: ThemeComposerRecommendation;
|
|
73
|
-
}): ZoraTheme {
|
|
74
|
-
const suggestedPrimaryColor =
|
|
75
|
-
options.recommendation.suggestedPrimaryHueDegrees === undefined
|
|
76
|
-
? options.value.primaryColor
|
|
77
|
-
: hueDegreesToZoraHexColor(options.recommendation.suggestedPrimaryHueDegrees);
|
|
78
|
-
|
|
79
|
-
return {
|
|
80
|
-
...options.value,
|
|
81
|
-
primaryColor: suggestedPrimaryColor,
|
|
82
|
-
harmony: options.recommendation.suggestedHarmony,
|
|
83
|
-
colorTone: options.recommendation.suggestedColorTone,
|
|
84
|
-
};
|
|
85
|
-
}
|