@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.
Files changed (114) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +11 -13
  3. package/dist/components/heading/resolveHeadingRecipe.d.ts +2 -2
  4. package/dist/components/heading/resolveHeadingRecipe.d.ts.map +1 -1
  5. package/dist/components/heading/resolveHeadingRecipe.js.map +1 -1
  6. package/dist/components/text/resolveTextRecipe.d.ts +2 -2
  7. package/dist/components/text/resolveTextRecipe.d.ts.map +1 -1
  8. package/dist/components/text/resolveTextRecipe.js.map +1 -1
  9. package/dist/patterns/theme-composer/ThemeComposer.d.ts.map +1 -1
  10. package/dist/patterns/theme-composer/ThemeComposer.js +10 -86
  11. package/dist/patterns/theme-composer/ThemeComposer.js.map +1 -1
  12. package/dist/patterns/theme-composer/index.d.ts +1 -1
  13. package/dist/patterns/theme-composer/index.d.ts.map +1 -1
  14. package/dist/patterns/theme-composer/index.js.map +1 -1
  15. package/dist/patterns/theme-composer/types.d.ts +1 -13
  16. package/dist/patterns/theme-composer/types.d.ts.map +1 -1
  17. package/dist/patterns/theme-composer/types.js.map +1 -1
  18. package/dist/theme/createZoraThemeConfig.d.ts +1 -1
  19. package/dist/theme/createZoraThemeConfig.d.ts.map +1 -1
  20. package/dist/theme/createZoraThemeConfig.js +5 -6
  21. package/dist/theme/createZoraThemeConfig.js.map +1 -1
  22. package/dist/theme/index.d.ts +1 -1
  23. package/dist/theme/index.d.ts.map +1 -1
  24. package/dist/theme/index.js.map +1 -1
  25. package/dist/theme/types.d.ts +16 -11
  26. package/dist/theme/types.d.ts.map +1 -1
  27. package/dist/theme/types.js +1 -20
  28. package/dist/theme/types.js.map +1 -1
  29. package/dist/theme/useZoraTheme.d.ts +1 -1
  30. package/dist/theme/zoraDefaultTheme.js +1 -1
  31. package/dist/theme/zoraDefaultTheme.js.map +1 -1
  32. package/package.json +5 -4
  33. package/src/components/heading/resolveHeadingRecipe.test.ts +30 -5
  34. package/src/components/heading/resolveHeadingRecipe.ts +6 -6
  35. package/src/components/text/resolveTextRecipe.test.ts +30 -5
  36. package/src/components/text/resolveTextRecipe.ts +6 -6
  37. package/src/patterns/theme-composer/ThemeComposer.test.ts +9 -141
  38. package/src/patterns/theme-composer/ThemeComposer.tsx +10 -131
  39. package/src/patterns/theme-composer/index.ts +1 -6
  40. package/src/patterns/theme-composer/types.ts +1 -15
  41. package/src/showcaseCoverage.test.ts +128 -0
  42. package/src/theme/createZoraThemeConfig.test.ts +51 -26
  43. package/src/theme/createZoraThemeConfig.ts +7 -7
  44. package/src/theme/index.ts +1 -3
  45. package/src/theme/types.ts +22 -34
  46. package/src/theme/zoraDefaultTheme.ts +1 -1
  47. package/dist/internal/color/colorToneRecipes.d.ts +0 -23
  48. package/dist/internal/color/colorToneRecipes.d.ts.map +0 -1
  49. package/dist/internal/color/colorToneRecipes.js +0 -139
  50. package/dist/internal/color/colorToneRecipes.js.map +0 -1
  51. package/dist/internal/color/harmony.d.ts +0 -12
  52. package/dist/internal/color/harmony.d.ts.map +0 -1
  53. package/dist/internal/color/harmony.js +0 -69
  54. package/dist/internal/color/harmony.js.map +0 -1
  55. package/dist/internal/color/hue.d.ts +0 -3
  56. package/dist/internal/color/hue.d.ts.map +0 -1
  57. package/dist/internal/color/hue.js +0 -7
  58. package/dist/internal/color/hue.js.map +0 -1
  59. package/dist/internal/color/index.d.ts +0 -10
  60. package/dist/internal/color/index.d.ts.map +0 -1
  61. package/dist/internal/color/index.js +0 -10
  62. package/dist/internal/color/index.js.map +0 -1
  63. package/dist/internal/color/oklch.d.ts +0 -6
  64. package/dist/internal/color/oklch.d.ts.map +0 -1
  65. package/dist/internal/color/oklch.js +0 -50
  66. package/dist/internal/color/oklch.js.map +0 -1
  67. package/dist/internal/color/primary.d.ts +0 -3
  68. package/dist/internal/color/primary.d.ts.map +0 -1
  69. package/dist/internal/color/primary.js +0 -44
  70. package/dist/internal/color/primary.js.map +0 -1
  71. package/dist/internal/color/roleHues.d.ts +0 -15
  72. package/dist/internal/color/roleHues.d.ts.map +0 -1
  73. package/dist/internal/color/roleHues.js +0 -103
  74. package/dist/internal/color/roleHues.js.map +0 -1
  75. package/dist/internal/color/roleScales.d.ts +0 -20
  76. package/dist/internal/color/roleScales.d.ts.map +0 -1
  77. package/dist/internal/color/roleScales.js +0 -79
  78. package/dist/internal/color/roleScales.js.map +0 -1
  79. package/dist/internal/color/scales.d.ts +0 -19
  80. package/dist/internal/color/scales.d.ts.map +0 -1
  81. package/dist/internal/color/scales.js +0 -135
  82. package/dist/internal/color/scales.js.map +0 -1
  83. package/dist/internal/color/semanticTokens.d.ts +0 -28
  84. package/dist/internal/color/semanticTokens.d.ts.map +0 -1
  85. package/dist/internal/color/semanticTokens.js +0 -84
  86. package/dist/internal/color/semanticTokens.js.map +0 -1
  87. package/dist/internal/color/types.d.ts +0 -10
  88. package/dist/internal/color/types.d.ts.map +0 -1
  89. package/dist/internal/color/types.js +0 -4
  90. package/dist/internal/color/types.js.map +0 -1
  91. package/dist/patterns/theme-composer/recommendations.d.ts +0 -14
  92. package/dist/patterns/theme-composer/recommendations.d.ts.map +0 -1
  93. package/dist/patterns/theme-composer/recommendations.js +0 -58
  94. package/dist/patterns/theme-composer/recommendations.js.map +0 -1
  95. package/src/internal/color/colorToneRecipes.test.ts +0 -89
  96. package/src/internal/color/colorToneRecipes.ts +0 -167
  97. package/src/internal/color/harmony.test.ts +0 -145
  98. package/src/internal/color/harmony.ts +0 -96
  99. package/src/internal/color/hue.test.ts +0 -28
  100. package/src/internal/color/hue.ts +0 -7
  101. package/src/internal/color/index.ts +0 -44
  102. package/src/internal/color/oklch.ts +0 -65
  103. package/src/internal/color/primary.test.ts +0 -105
  104. package/src/internal/color/primary.ts +0 -64
  105. package/src/internal/color/roleHues.test.ts +0 -197
  106. package/src/internal/color/roleHues.ts +0 -142
  107. package/src/internal/color/roleScales.test.ts +0 -220
  108. package/src/internal/color/roleScales.ts +0 -127
  109. package/src/internal/color/scales.test.ts +0 -151
  110. package/src/internal/color/scales.ts +0 -194
  111. package/src/internal/color/semanticTokens.test.ts +0 -170
  112. package/src/internal/color/semanticTokens.ts +0 -114
  113. package/src/internal/color/types.ts +0 -15
  114. 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
- }