@ankhorage/zora 0.16.2 → 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 +62 -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 +4 -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 +14 -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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,67 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- 4d50ada: **Breaking: ZORA core theme model and color stack cleanup**
|
|
8
|
+
|
|
9
|
+
## Removed APIs
|
|
10
|
+
- `ZoraTheme.colorTone` — removed; `colorTone` is no longer part of the theme seed
|
|
11
|
+
- `ZoraColorTone` type — removed
|
|
12
|
+
- `ZORA_COLOR_TONES` constant — removed
|
|
13
|
+
- `ZoraHexColor` type — removed; ZORA themes now accept normal string hex values
|
|
14
|
+
- `ZoraComputedTheme.mode` — replaced by `light` and `dark` mode objects
|
|
15
|
+
- `ThemeComposerRecommendation` — removed
|
|
16
|
+
- `ThemeComposerAppMood` — removed
|
|
17
|
+
- `ThemeComposerAppCategory` — removed (was an opaque `string` alias)
|
|
18
|
+
- `ThemeComposerProps.appMood` — removed
|
|
19
|
+
- `ThemeComposerProps.recommendations` — removed
|
|
20
|
+
- Internal color stack (`src/internal/color/`) — removed; ZORA no longer owns color math
|
|
21
|
+
|
|
22
|
+
## Added / Changed APIs
|
|
23
|
+
- `ZoraTheme.name` — now **required** (was optional); ZORA themes must provide a real display name
|
|
24
|
+
- `ZoraTheme.appCategory` — new required field; use `AppCategory` from `@ankhorage/contracts`
|
|
25
|
+
- `ZoraTheme.primaryColor` — remains a public `string`; ZORA validates it internally with `@ankhorage/color-theory`
|
|
26
|
+
- `ZoraComputedTheme` — now has `light: ZoraComputedThemeMode` and `dark: ZoraComputedThemeMode` instead of a single `mode`
|
|
27
|
+
- `ZoraComputedThemeMode` — new type: `{ mode, surfaceTheme, generated, swatches, semanticColors? }`
|
|
28
|
+
- Primary color is now preserved identically for both light and dark `ThemeConfig` modes (no dark-mode mutation)
|
|
29
|
+
- `SurfaceTheme` (from `@ankhorage/surface`) replaces `AnkhTheme` as the resolved runtime theme type
|
|
30
|
+
|
|
31
|
+
## New dependencies
|
|
32
|
+
- `@ankhorage/color-theory@^0.0.2` — canonical color types and generation utilities
|
|
33
|
+
- `@ankhorage/contracts@^1.1.0` — theme config and app category types
|
|
34
|
+
|
|
35
|
+
## Removed dependencies
|
|
36
|
+
- `culori` — no longer a direct ZORA dependency; color math is delegated to `@ankhorage/color-theory`
|
|
37
|
+
- `@types/culori` — removed
|
|
38
|
+
|
|
39
|
+
## Migration
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
// Before
|
|
43
|
+
const theme: ZoraTheme = {
|
|
44
|
+
id: 'my-theme',
|
|
45
|
+
name: 'My Theme',
|
|
46
|
+
primaryColor: '#0f766e',
|
|
47
|
+
harmony: 'analogous',
|
|
48
|
+
colorTone: 'jewel',
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// After
|
|
52
|
+
const theme: ZoraTheme = {
|
|
53
|
+
id: 'my-theme',
|
|
54
|
+
name: 'My Theme',
|
|
55
|
+
appCategory: 'developer_tools',
|
|
56
|
+
primaryColor: '#0f766e',
|
|
57
|
+
harmony: 'analogous',
|
|
58
|
+
};
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The `name` field is now required. `primaryColor` stays app-facing and ergonomic as
|
|
62
|
+
a string, while ZORA validates it when converting the source theme to a runtime
|
|
63
|
+
`ThemeConfig`.
|
|
64
|
+
|
|
3
65
|
## 0.16.2
|
|
4
66
|
|
|
5
67
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -90,28 +90,24 @@ export function App({ appTheme }: { appTheme: ZoraTheme }) {
|
|
|
90
90
|
}
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
ZORA themes use a single seed `primaryColor`.
|
|
94
|
-
|
|
93
|
+
ZORA themes use a single seed `primaryColor`. The selected primary color is preserved
|
|
94
|
+
identically for both light and dark mode. Color generation is handled by
|
|
95
|
+
`@ankhorage/color-theory` via Surface.
|
|
95
96
|
|
|
96
97
|
```tsx
|
|
97
98
|
<ZoraProvider
|
|
98
99
|
theme={{
|
|
99
100
|
id: 'studio',
|
|
101
|
+
name: 'Studio',
|
|
102
|
+
appCategory: 'developer_tools',
|
|
100
103
|
primaryColor: '#0f766e',
|
|
101
104
|
harmony: 'analogous',
|
|
102
|
-
colorTone: 'jewel',
|
|
103
105
|
}}
|
|
104
106
|
>
|
|
105
107
|
<App />
|
|
106
108
|
</ZoraProvider>
|
|
107
109
|
```
|
|
108
110
|
|
|
109
|
-
> **`colorTone` vs component `tone`** — `colorTone` is a theme-seed field that
|
|
110
|
-
> selects the color-world / palette tone for the whole theme (e.g. `'jewel'`,
|
|
111
|
-
> `'pastel'`). Component `tone` props (e.g. `<Text tone="muted" />`,
|
|
112
|
-
> `<Button tone="primary" />`) express semantic color intent inside that theme
|
|
113
|
-
> and are independent of `colorTone`.
|
|
114
|
-
|
|
115
111
|
`mode` and `themeId` are available on public ZORA components through `ZoraBaseProps`.
|
|
116
112
|
Use component props for local component/subtree overrides.
|
|
117
113
|
|
|
@@ -1425,9 +1421,9 @@ Pass a theme seed to define your app theme:
|
|
|
1425
1421
|
theme={{
|
|
1426
1422
|
id: 'studio',
|
|
1427
1423
|
name: 'Studio',
|
|
1424
|
+
appCategory: 'developer_tools',
|
|
1428
1425
|
primaryColor: '#0f766e',
|
|
1429
1426
|
harmony: 'analogous',
|
|
1430
|
-
colorTone: 'jewel',
|
|
1431
1427
|
}}
|
|
1432
1428
|
>
|
|
1433
1429
|
<App />
|
|
@@ -1453,15 +1449,17 @@ No inherited props. `ZoraProviderProps` is declared directly by ZORA.
|
|
|
1453
1449
|
|
|
1454
1450
|
### `createZoraThemeConfig`
|
|
1455
1451
|
|
|
1456
|
-
Creates a
|
|
1452
|
+
Creates a `ThemeConfig` (from `@ankhorage/contracts`) from a ZORA theme seed.
|
|
1453
|
+
The primary color is preserved identically for both light and dark mode configs.
|
|
1454
|
+
Color generation is handled downstream by `@ankhorage/color-theory` via Surface.
|
|
1457
1455
|
|
|
1458
1456
|
```tsx
|
|
1459
1457
|
const themeConfig = createZoraThemeConfig({
|
|
1460
1458
|
id: 'studio',
|
|
1461
1459
|
name: 'Studio',
|
|
1460
|
+
appCategory: 'developer_tools',
|
|
1462
1461
|
primaryColor: '#0f766e',
|
|
1463
1462
|
harmony: 'analogous',
|
|
1464
|
-
colorTone: 'jewel',
|
|
1465
1463
|
});
|
|
1466
1464
|
```
|
|
1467
1465
|
|
|
@@ -1485,9 +1483,9 @@ Default ZORA theme seed.
|
|
|
1485
1483
|
const zoraDefaultTheme: ZoraTheme = {
|
|
1486
1484
|
id: 'zora',
|
|
1487
1485
|
name: 'ZORA',
|
|
1486
|
+
appCategory: 'developer_tools',
|
|
1488
1487
|
primaryColor: '#0f766e',
|
|
1489
1488
|
harmony: 'analogous',
|
|
1490
|
-
colorTone: 'jewel',
|
|
1491
1489
|
};
|
|
1492
1490
|
```
|
|
1493
1491
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SurfaceTheme } from '@ankhorage/surface';
|
|
2
2
|
import type { TextStyle } from 'react-native';
|
|
3
3
|
import type { HeadingAlign, HeadingLevel, HeadingSize, HeadingTone, HeadingWeight } from './types';
|
|
4
4
|
interface ResolveHeadingRecipeOptions {
|
|
@@ -10,6 +10,6 @@ interface ResolveHeadingRecipeOptions {
|
|
|
10
10
|
italic?: boolean;
|
|
11
11
|
}
|
|
12
12
|
export declare function resolveHeadingSizeFromLevel(level: HeadingLevel): HeadingSize;
|
|
13
|
-
export declare function resolveHeadingRecipe(theme:
|
|
13
|
+
export declare function resolveHeadingRecipe(theme: SurfaceTheme, { align, italic, level, size, tone, weight }: ResolveHeadingRecipeOptions): TextStyle;
|
|
14
14
|
export {};
|
|
15
15
|
//# sourceMappingURL=resolveHeadingRecipe.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveHeadingRecipe.d.ts","sourceRoot":"","sources":["../../../src/components/heading/resolveHeadingRecipe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"resolveHeadingRecipe.d.ts","sourceRoot":"","sources":["../../../src/components/heading/resolveHeadingRecipe.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAEnG,UAAU,2BAA2B;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAQD,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAe5E;AA6ED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,EAAE,KAAK,EAAE,MAAc,EAAE,KAAK,EAAE,IAAI,EAAE,IAAgB,EAAE,MAAM,EAAE,EAAE,2BAA2B,GAC5F,SAAS,CAcX"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveHeadingRecipe.js","sourceRoot":"","sources":["../../../src/components/heading/resolveHeadingRecipe.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,2BAA2B,CAAC,KAAmB;IAC7D,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,CAAC;YACJ,OAAO,IAAI,CAAC;QACd,KAAK,CAAC;YACJ,OAAO,IAAI,CAAC;QACd,KAAK,CAAC;YACJ,OAAO,IAAI,CAAC;QACd,KAAK,CAAC;YACJ,OAAO,IAAI,CAAC;QACd,KAAK,CAAC;YACJ,OAAO,IAAI,CAAC;QACd,KAAK,CAAC;YACJ,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,2BAA2B,CAAC,IAAqC;IACxE,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,IAAI;YACP,OAAO,CAAC,CAAC;QACX,KAAK,IAAI;YACP,OAAO,CAAC,CAAC;QACX,KAAK,IAAI;YACP,OAAO,CAAC,CAAC;QACX,KAAK,IAAI;YACP,OAAO,CAAC,CAAC;QACX,KAAK,IAAI;YACP,OAAO,CAAC,CAAC;QACX,KAAK,IAAI;YACP,OAAO,CAAC,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB,CAAC,
|
|
1
|
+
{"version":3,"file":"resolveHeadingRecipe.js","sourceRoot":"","sources":["../../../src/components/heading/resolveHeadingRecipe.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FontWeight, SurfaceTheme } from '@ankhorage/surface';\nimport type { TextStyle } from 'react-native';\n\nimport type { HeadingAlign, HeadingLevel, HeadingSize, HeadingTone, HeadingWeight } from './types';\n\ninterface ResolveHeadingRecipeOptions {\n level: HeadingLevel;\n size?: HeadingSize;\n tone?: HeadingTone;\n align?: HeadingAlign;\n weight?: HeadingWeight;\n italic?: boolean;\n}\n\ninterface HeadingRecipe {\n fontSize: number;\n lineHeight: number;\n weight: HeadingWeight;\n}\n\nexport function resolveHeadingSizeFromLevel(level: HeadingLevel): HeadingSize {\n switch (level) {\n case 1:\n return 'h1';\n case 2:\n return 'h2';\n case 3:\n return 'h3';\n case 4:\n return 'h4';\n case 5:\n return 'h5';\n case 6:\n return 'h6';\n }\n}\n\nfunction resolveHeadingLevelFromSize(size: Exclude<HeadingSize, 'display'>): HeadingLevel {\n switch (size) {\n case 'h1':\n return 1;\n case 'h2':\n return 2;\n case 'h3':\n return 3;\n case 'h4':\n return 4;\n case 'h5':\n return 5;\n case 'h6':\n return 6;\n }\n}\n\nfunction resolveSizeRecipe(theme: SurfaceTheme, size: HeadingSize): HeadingRecipe {\n if (size === 'display') {\n const fontSize = theme.typography.sizes['3xl'];\n\n return {\n fontSize,\n lineHeight: fontSize + 8,\n weight: 'bold',\n };\n }\n\n const heading = theme.typography.headings[resolveHeadingLevelFromSize(size)];\n\n return {\n fontSize: heading.size,\n lineHeight: heading.lineHeight,\n weight: heading.weight,\n };\n}\n\nfunction resolveToneColor(theme: SurfaceTheme, tone: HeadingTone): string {\n switch (tone) {\n case 'muted':\n return theme.semantics.content.muted;\n case 'subtle':\n return theme.semantics.content.subtle;\n case 'inverse':\n return theme.semantics.content.inverse;\n case 'primary':\n return theme.semantics.brand.base;\n case 'danger':\n return theme.semantics.danger.base;\n case 'success':\n return theme.semantics.success.base;\n case 'warning':\n return theme.semantics.warning.base;\n case 'default':\n default:\n return theme.semantics.content.default;\n }\n}\n\nfunction resolveWeight(theme: SurfaceTheme, weight: HeadingWeight): FontWeight {\n return theme.typography.weights[weight];\n}\n\nfunction resolveFontFamily({\n theme,\n weight,\n italic,\n}: {\n theme: SurfaceTheme;\n weight: FontWeight;\n italic: boolean;\n}): string | undefined {\n return theme.typography.fonts[italic ? 'italic' : 'normal'][weight];\n}\n\nexport function resolveHeadingRecipe(\n theme: SurfaceTheme,\n { align, italic = false, level, size, tone = 'default', weight }: ResolveHeadingRecipeOptions,\n): TextStyle {\n const recipe = resolveSizeRecipe(theme, size ?? resolveHeadingSizeFromLevel(level));\n const resolvedWeight = resolveWeight(theme, weight ?? recipe.weight);\n\n return {\n color: resolveToneColor(theme, tone),\n elevation: 0,\n fontFamily: resolveFontFamily({ theme, weight: resolvedWeight, italic }),\n fontSize: recipe.fontSize,\n fontStyle: italic ? 'italic' : 'normal',\n fontWeight: resolvedWeight,\n lineHeight: recipe.lineHeight,\n textAlign: align,\n };\n}\n"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type Breakpoint, type Responsive, type SurfaceTheme } from '@ankhorage/surface';
|
|
2
2
|
import type { TextStyle } from 'react-native';
|
|
3
3
|
import type { TextAlign, TextTone, TextVariant, TextWeight } from './types';
|
|
4
4
|
interface ResolveTextStyleOptions {
|
|
5
|
-
theme:
|
|
5
|
+
theme: SurfaceTheme;
|
|
6
6
|
breakpoint: Breakpoint;
|
|
7
7
|
variant?: Responsive<TextVariant>;
|
|
8
8
|
tone?: Responsive<TextTone>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveTextRecipe.d.ts","sourceRoot":"","sources":["../../../src/components/text/resolveTextRecipe.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,
|
|
1
|
+
{"version":3,"file":"resolveTextRecipe.d.ts","sourceRoot":"","sources":["../../../src/components/text/resolveTextRecipe.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,UAAU,EAGf,KAAK,UAAU,EACf,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAU5E,UAAU,uBAAuB;IAC/B,KAAK,EAAE,YAAY,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,OAAO,CAAC,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC;IAClC,IAAI,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC5B,MAAM,CAAC,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC;IAChC,KAAK,CAAC,EAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA0GD,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,UAAU,EACV,OAAO,EACP,IAAI,EACJ,MAAM,EACN,KAAK,EACL,MAAc,GACf,EAAE,uBAAuB,GAAG,SAAS,CA2BrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolveTextRecipe.js","sourceRoot":"","sources":["../../../src/components/text/resolveTextRecipe.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"resolveTextRecipe.js","sourceRoot":"","sources":["../../../src/components/text/resolveTextRecipe.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type Breakpoint,\n type FontWeight,\n resolveResponsive,\n type Responsive,\n type SurfaceTheme,\n} from '@ankhorage/surface';\nimport type { TextStyle } from 'react-native';\n\nimport type { TextAlign, TextTone, TextVariant, TextWeight } from './types';\n\ninterface VariantRecipe {\n fontSize: number;\n lineHeight: number;\n weight: TextWeight;\n textTransform?: TextStyle['textTransform'];\n letterSpacing?: number;\n}\n\ninterface ResolveTextStyleOptions {\n theme: SurfaceTheme;\n breakpoint: Breakpoint;\n variant?: Responsive<TextVariant>;\n tone?: Responsive<TextTone>;\n weight?: Responsive<TextWeight>;\n align?: Responsive<TextAlign>;\n italic?: boolean;\n}\n\nfunction isMediumBreakpointOrLarger(breakpoint: Breakpoint): boolean {\n return breakpoint === 'md' || breakpoint === 'lg' || breakpoint === 'xl';\n}\n\nfunction resolveWeight(theme: SurfaceTheme, weight: TextWeight): FontWeight {\n return theme.typography.weights[weight];\n}\n\nfunction resolveFontFamily({\n theme,\n variant,\n weight,\n italic,\n}: {\n theme: SurfaceTheme;\n variant: TextVariant;\n weight: FontWeight;\n italic: boolean;\n}): string | undefined {\n if (variant === 'code') {\n return 'monospace';\n }\n\n return theme.typography.fonts[italic ? 'italic' : 'normal'][weight];\n}\n\nfunction resolveVariantRecipe(\n theme: SurfaceTheme,\n variant: TextVariant,\n breakpoint: Breakpoint,\n): VariantRecipe {\n switch (variant) {\n case 'lead':\n return {\n fontSize: isMediumBreakpointOrLarger(breakpoint)\n ? theme.typography.sizes.l\n : theme.typography.sizes.m,\n lineHeight: isMediumBreakpointOrLarger(breakpoint) ? 28 : 24,\n weight: 'regular',\n };\n case 'bodySmall':\n return {\n fontSize: theme.typography.sizes.s,\n lineHeight: 20,\n weight: 'regular',\n };\n case 'caption':\n return {\n fontSize: theme.typography.sizes.xs,\n lineHeight: 16,\n weight: 'regular',\n };\n case 'label':\n return {\n fontSize: theme.typography.sizes.s,\n lineHeight: 18,\n weight: 'medium',\n };\n case 'eyebrow':\n return {\n fontSize: theme.typography.sizes.xs,\n lineHeight: 16,\n weight: 'semiBold',\n textTransform: 'uppercase',\n letterSpacing: 0.8,\n };\n case 'code':\n return {\n fontSize: theme.typography.sizes.s,\n lineHeight: 20,\n weight: 'regular',\n };\n case 'body':\n default:\n return {\n fontSize: theme.typography.sizes.m,\n lineHeight: 24,\n weight: 'regular',\n };\n }\n}\n\nfunction resolveToneColor(theme: SurfaceTheme, tone: TextTone): string {\n switch (tone) {\n case 'muted':\n return theme.semantics.content.muted;\n case 'subtle':\n return theme.semantics.content.subtle;\n case 'inverse':\n return theme.semantics.content.inverse;\n case 'primary':\n return theme.semantics.brand.base;\n case 'danger':\n return theme.semantics.danger.base;\n case 'success':\n return theme.semantics.success.base;\n case 'warning':\n return theme.semantics.warning.base;\n case 'default':\n default:\n return theme.semantics.content.default;\n }\n}\n\nexport function resolveTextStyle({\n theme,\n breakpoint,\n variant,\n tone,\n weight,\n align,\n italic = false,\n}: ResolveTextStyleOptions): TextStyle {\n const resolvedVariant = resolveResponsive(variant, breakpoint) ?? 'body';\n const resolvedTone = resolveResponsive(tone, breakpoint) ?? 'default';\n const resolvedAlign = resolveResponsive(align, breakpoint);\n const recipe = resolveVariantRecipe(theme, resolvedVariant, breakpoint);\n const resolvedWeight = resolveWeight(\n theme,\n resolveResponsive(weight, breakpoint) ?? recipe.weight,\n );\n\n return {\n color: resolveToneColor(theme, resolvedTone),\n elevation: 0,\n fontFamily: resolveFontFamily({\n theme,\n variant: resolvedVariant,\n weight: resolvedWeight,\n italic,\n }),\n fontSize: recipe.fontSize,\n fontStyle: italic ? 'italic' : 'normal',\n fontWeight: resolvedWeight,\n letterSpacing: recipe.letterSpacing,\n lineHeight: recipe.lineHeight,\n textAlign: resolvedAlign,\n textTransform: recipe.textTransform,\n };\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeComposer.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ThemeComposer.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAa1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AA0KlD,eAAO,MAAM,aAAa,0DAAyC,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { COLOR_HARMONIES, parseHexColorOrThrow } from '@ankhorage/color-theory';
|
|
1
2
|
import { Box, Stack } from '@ankhorage/surface';
|
|
2
3
|
import React from 'react';
|
|
3
4
|
import { Badge } from '../../components/badge';
|
|
@@ -8,45 +9,23 @@ import { Input } from '../../components/input';
|
|
|
8
9
|
import { Select } from '../../components/select';
|
|
9
10
|
import { Tabs } from '../../components/tabs';
|
|
10
11
|
import { Text } from '../../components/text';
|
|
11
|
-
import { ZORA_COLOR_HARMONIES, ZORA_COLOR_TONES, } from '../../theme/types';
|
|
12
12
|
import { useZoraTheme } from '../../theme/useZoraTheme';
|
|
13
13
|
import { withZoraThemeScope } from '../../theme/withZoraThemeScope';
|
|
14
|
-
import { createThemeFromThemeComposerRecommendation, findThemeComposerRecommendation, formatThemeComposerLabel, } from './recommendations';
|
|
15
|
-
const HEX_RE = /^#[0-9A-Fa-f]{6}$/;
|
|
16
14
|
function isValidHex(value) {
|
|
17
|
-
|
|
15
|
+
try {
|
|
16
|
+
parseHexColorOrThrow(value);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
18
22
|
}
|
|
19
|
-
const HARMONY_OPTIONS =
|
|
20
|
-
const TONE_OPTIONS = ZORA_COLOR_TONES.map((t) => ({ value: t, label: t }));
|
|
23
|
+
const HARMONY_OPTIONS = COLOR_HARMONIES.map((h) => ({ value: h, label: h }));
|
|
21
24
|
const MODE_TABS = [
|
|
22
25
|
{ value: 'light', label: 'Light' },
|
|
23
26
|
{ value: 'dark', label: 'Dark' },
|
|
24
27
|
];
|
|
25
|
-
|
|
26
|
-
neutral: 'Neutral',
|
|
27
|
-
pastel: 'Pastel',
|
|
28
|
-
earth: 'Earth',
|
|
29
|
-
mineral: 'Mineral',
|
|
30
|
-
muted: 'Muted',
|
|
31
|
-
jewel: 'Neutral',
|
|
32
|
-
fluorescent: 'Obsidian',
|
|
33
|
-
obsidian: 'Obsidian',
|
|
34
|
-
vaporwave: 'Pastel',
|
|
35
|
-
monochromeAccent: 'Neutral',
|
|
36
|
-
};
|
|
37
|
-
const COLOR_TONE_FOREGROUND_TONE = {
|
|
38
|
-
neutral: 'Jewel',
|
|
39
|
-
pastel: 'Jewel',
|
|
40
|
-
earth: 'Mineral',
|
|
41
|
-
mineral: 'Jewel',
|
|
42
|
-
muted: 'Jewel',
|
|
43
|
-
jewel: 'Jewel',
|
|
44
|
-
fluorescent: 'Fluorescent',
|
|
45
|
-
obsidian: 'Fluorescent',
|
|
46
|
-
vaporwave: 'Fluorescent',
|
|
47
|
-
monochromeAccent: 'Jewel',
|
|
48
|
-
};
|
|
49
|
-
function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeChange, onSubmit, appCategory, appMood, recommendations, testID, }) {
|
|
28
|
+
function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeChange, onSubmit, testID, }) {
|
|
50
29
|
const { theme } = useZoraTheme();
|
|
51
30
|
const [hexInput, setHexInput] = React.useState(value.primaryColor);
|
|
52
31
|
const [hexError, setHexError] = React.useState(undefined);
|
|
@@ -68,41 +47,7 @@ function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeCh
|
|
|
68
47
|
}
|
|
69
48
|
}
|
|
70
49
|
const activeMode = mode ?? 'light';
|
|
71
|
-
const recommendation = findThemeComposerRecommendation({
|
|
72
|
-
appCategory,
|
|
73
|
-
appMood,
|
|
74
|
-
recommendations,
|
|
75
|
-
});
|
|
76
50
|
return (<Stack gap="l" testID={testID}>
|
|
77
|
-
{recommendation ? (<Card title="Recommended starting point" description="Use this as an optional starting point. It is only applied when you choose it." actions={<Button size="s" emphasis="soft" tone="primary" onPress={() => onChange(createThemeFromThemeComposerRecommendation({
|
|
78
|
-
value,
|
|
79
|
-
recommendation,
|
|
80
|
-
}))} testID={testID ? `${testID}-apply-recommendation` : undefined}>
|
|
81
|
-
Apply recommendation
|
|
82
|
-
</Button>}>
|
|
83
|
-
<Stack gap="s">
|
|
84
|
-
<Stack direction="row" gap="s" wrap="wrap">
|
|
85
|
-
<Badge tone="primary" emphasis="soft">
|
|
86
|
-
{formatThemeComposerLabel(recommendation.appMood)} mood
|
|
87
|
-
</Badge>
|
|
88
|
-
<Badge tone="neutral" emphasis="soft">
|
|
89
|
-
{formatThemeComposerLabel(recommendation.suggestedColorTone)} color tone
|
|
90
|
-
</Badge>
|
|
91
|
-
<Badge tone="neutral" emphasis="soft">
|
|
92
|
-
{formatThemeComposerLabel(recommendation.suggestedHarmony)} harmony
|
|
93
|
-
</Badge>
|
|
94
|
-
{recommendation.suggestedPrimaryHueDegrees === undefined ? null : (<Badge tone="neutral" emphasis="soft">
|
|
95
|
-
{recommendation.suggestedPrimaryHueDegrees}° hue
|
|
96
|
-
</Badge>)}
|
|
97
|
-
</Stack>
|
|
98
|
-
<Text tone="muted" variant="bodySmall">
|
|
99
|
-
Suggested for {formatThemeComposerLabel(recommendation.appCategory)}. The color tone
|
|
100
|
-
controls palette character, harmony controls accent relationships, and hue sets the
|
|
101
|
-
starting primary color when available.
|
|
102
|
-
</Text>
|
|
103
|
-
</Stack>
|
|
104
|
-
</Card>) : null}
|
|
105
|
-
|
|
106
51
|
{/* Section: Primary Color */}
|
|
107
52
|
<Card title="Primary color" description="Set the seed color for your theme palette.">
|
|
108
53
|
<Stack gap="m">
|
|
@@ -128,27 +73,6 @@ function ThemeComposerInner({ themeId: _themeId, value, onChange, mode, onModeCh
|
|
|
128
73
|
<Select value={value.harmony} options={HARMONY_OPTIONS} onValueChange={(h) => onChange({ ...value, harmony: h })} testID={testID ? `${testID}-harmony-select` : undefined}/>
|
|
129
74
|
</Card>
|
|
130
75
|
|
|
131
|
-
{/* Section: Color tone */}
|
|
132
|
-
<Card title="Color tone" description="Controls the vibrancy and saturation style of the palette.">
|
|
133
|
-
<Stack gap="s">
|
|
134
|
-
<Select value={value.colorTone} options={TONE_OPTIONS} onValueChange={(t) => onChange({ ...value, colorTone: t })} testID={testID ? `${testID}-tone-select` : undefined}/>
|
|
135
|
-
<Stack direction="row" gap="s" align="center">
|
|
136
|
-
<Text tone="muted" variant="caption">
|
|
137
|
-
Background:
|
|
138
|
-
</Text>
|
|
139
|
-
<Badge tone="neutral" emphasis="soft">
|
|
140
|
-
{COLOR_TONE_BACKGROUND_TONE[value.colorTone]}
|
|
141
|
-
</Badge>
|
|
142
|
-
<Text tone="muted" variant="caption">
|
|
143
|
-
Foreground:
|
|
144
|
-
</Text>
|
|
145
|
-
<Badge tone="neutral" emphasis="soft">
|
|
146
|
-
{COLOR_TONE_FOREGROUND_TONE[value.colorTone]}
|
|
147
|
-
</Badge>
|
|
148
|
-
</Stack>
|
|
149
|
-
</Stack>
|
|
150
|
-
</Card>
|
|
151
|
-
|
|
152
76
|
{/* Section: Mode */}
|
|
153
77
|
<Card title="Mode" description="Switch between light and dark presentation.">
|
|
154
78
|
<Tabs value={activeMode} items={MODE_TABS} onValueChange={(m) => onModeChange?.(m)} variant="segmented" testID={testID ? `${testID}-mode-tabs` : undefined}/>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeComposer.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Box, Stack } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Badge } from '../../components/badge';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Heading } from '../../components/heading';\nimport { Input } from '../../components/input';\nimport { Select } from '../../components/select';\nimport { Tabs } from '../../components/tabs';\nimport { Text } from '../../components/text';\nimport {\n ZORA_COLOR_HARMONIES,\n ZORA_COLOR_TONES,\n type ZoraColorTone,\n type ZoraTheme,\n type ZoraThemeMode,\n} from '../../theme/types';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport {\n createThemeFromThemeComposerRecommendation,\n findThemeComposerRecommendation,\n formatThemeComposerLabel,\n} from './recommendations';\nimport type { ThemeComposerProps } from './types';\n\nconst HEX_RE = /^#[0-9A-Fa-f]{6}$/;\n\nfunction isValidHex(value: string): boolean {\n return HEX_RE.test(value);\n}\n\nconst HARMONY_OPTIONS = ZORA_COLOR_HARMONIES.map((h) => ({ value: h, label: h }));\n\nconst TONE_OPTIONS = ZORA_COLOR_TONES.map((t) => ({ value: t, label: t }));\n\nconst MODE_TABS = [\n { value: 'light' as ZoraThemeMode, label: 'Light' },\n { value: 'dark' as ZoraThemeMode, label: 'Dark' },\n];\n\nconst COLOR_TONE_BACKGROUND_TONE: Record<ZoraColorTone, string> = {\n neutral: 'Neutral',\n pastel: 'Pastel',\n earth: 'Earth',\n mineral: 'Mineral',\n muted: 'Muted',\n jewel: 'Neutral',\n fluorescent: 'Obsidian',\n obsidian: 'Obsidian',\n vaporwave: 'Pastel',\n monochromeAccent: 'Neutral',\n};\n\nconst COLOR_TONE_FOREGROUND_TONE: Record<ZoraColorTone, string> = {\n neutral: 'Jewel',\n pastel: 'Jewel',\n earth: 'Mineral',\n mineral: 'Jewel',\n muted: 'Jewel',\n jewel: 'Jewel',\n fluorescent: 'Fluorescent',\n obsidian: 'Fluorescent',\n vaporwave: 'Fluorescent',\n monochromeAccent: 'Jewel',\n};\n\nfunction ThemeComposerInner({\n themeId: _themeId,\n value,\n onChange,\n mode,\n onModeChange,\n onSubmit,\n appCategory,\n appMood,\n recommendations,\n testID,\n}: ThemeComposerProps) {\n const { theme } = useZoraTheme();\n\n const [hexInput, setHexInput] = React.useState<string>(value.primaryColor);\n const [hexError, setHexError] = React.useState<string | undefined>(undefined);\n\n // Keep local hex input in sync when value.primaryColor changes externally\n React.useEffect(() => {\n setHexInput(value.primaryColor);\n setHexError(undefined);\n }, [value.primaryColor]);\n\n function handleHexChange(text: string) {\n // Ensure leading hash\n const normalized = text.startsWith('#') ? text : `#${text}`;\n setHexInput(normalized);\n\n if (isValidHex(normalized)) {\n setHexError(undefined);\n onChange({ ...value, primaryColor: normalized as ZoraTheme['primaryColor'] });\n } else {\n setHexError('Enter a valid 6-digit hex color (e.g. #0f766e).');\n }\n }\n\n const activeMode = mode ?? 'light';\n const recommendation = findThemeComposerRecommendation({\n appCategory,\n appMood,\n recommendations,\n });\n\n return (\n <Stack gap=\"l\" testID={testID}>\n {recommendation ? (\n <Card\n title=\"Recommended starting point\"\n description=\"Use this as an optional starting point. It is only applied when you choose it.\"\n actions={\n <Button\n size=\"s\"\n emphasis=\"soft\"\n tone=\"primary\"\n onPress={() =>\n onChange(\n createThemeFromThemeComposerRecommendation({\n value,\n recommendation,\n }),\n )\n }\n testID={testID ? `${testID}-apply-recommendation` : undefined}\n >\n Apply recommendation\n </Button>\n }\n >\n <Stack gap=\"s\">\n <Stack direction=\"row\" gap=\"s\" wrap=\"wrap\">\n <Badge tone=\"primary\" emphasis=\"soft\">\n {formatThemeComposerLabel(recommendation.appMood)} mood\n </Badge>\n <Badge tone=\"neutral\" emphasis=\"soft\">\n {formatThemeComposerLabel(recommendation.suggestedColorTone)} color tone\n </Badge>\n <Badge tone=\"neutral\" emphasis=\"soft\">\n {formatThemeComposerLabel(recommendation.suggestedHarmony)} harmony\n </Badge>\n {recommendation.suggestedPrimaryHueDegrees === undefined ? null : (\n <Badge tone=\"neutral\" emphasis=\"soft\">\n {recommendation.suggestedPrimaryHueDegrees}° hue\n </Badge>\n )}\n </Stack>\n <Text tone=\"muted\" variant=\"bodySmall\">\n Suggested for {formatThemeComposerLabel(recommendation.appCategory)}. The color tone\n controls palette character, harmony controls accent relationships, and hue sets the\n starting primary color when available.\n </Text>\n </Stack>\n </Card>\n ) : null}\n\n {/* Section: Primary Color */}\n <Card title=\"Primary color\" description=\"Set the seed color for your theme palette.\">\n <Stack gap=\"m\">\n <Stack direction=\"row\" gap=\"m\" align=\"center\">\n <Box flex={1}>\n <Input\n value={hexInput}\n onChangeText={handleHexChange}\n placeholder=\"#0f766e\"\n autoCapitalize=\"none\"\n autoCorrect={false}\n maxLength={7}\n invalid={hexError !== undefined}\n testID={testID ? `${testID}-hex-input` : undefined}\n />\n </Box>\n {/* Color preview chip */}\n <Box\n width={36}\n height={36}\n radius=\"m\"\n style={{\n backgroundColor: isValidHex(hexInput) ? hexInput : theme.colors.border,\n borderWidth: 1,\n borderColor: theme.colors.border,\n }}\n />\n </Stack>\n {hexError ? (\n <Text tone=\"danger\" variant=\"bodySmall\">\n {hexError}\n </Text>\n ) : null}\n </Stack>\n </Card>\n\n {/* Section: Harmony */}\n <Card\n title=\"Harmony\"\n description=\"Choose how accent hues are generated from your primary color.\"\n >\n <Select\n value={value.harmony}\n options={HARMONY_OPTIONS}\n onValueChange={(h) => onChange({ ...value, harmony: h })}\n testID={testID ? `${testID}-harmony-select` : undefined}\n />\n </Card>\n\n {/* Section: Color tone */}\n <Card\n title=\"Color tone\"\n description=\"Controls the vibrancy and saturation style of the palette.\"\n >\n <Stack gap=\"s\">\n <Select\n value={value.colorTone}\n options={TONE_OPTIONS}\n onValueChange={(t) => onChange({ ...value, colorTone: t })}\n testID={testID ? `${testID}-tone-select` : undefined}\n />\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Text tone=\"muted\" variant=\"caption\">\n Background:\n </Text>\n <Badge tone=\"neutral\" emphasis=\"soft\">\n {COLOR_TONE_BACKGROUND_TONE[value.colorTone]}\n </Badge>\n <Text tone=\"muted\" variant=\"caption\">\n Foreground:\n </Text>\n <Badge tone=\"neutral\" emphasis=\"soft\">\n {COLOR_TONE_FOREGROUND_TONE[value.colorTone]}\n </Badge>\n </Stack>\n </Stack>\n </Card>\n\n {/* Section: Mode */}\n <Card title=\"Mode\" description=\"Switch between light and dark presentation.\">\n <Tabs\n value={activeMode}\n items={MODE_TABS}\n onValueChange={(m) => onModeChange?.(m)}\n variant=\"segmented\"\n testID={testID ? `${testID}-mode-tabs` : undefined}\n />\n </Card>\n\n {/* Section: Preview */}\n <Card title=\"Preview\" description=\"A quick look at how your theme renders common controls.\">\n <Stack gap=\"m\">\n <Heading level={4}>Heading</Heading>\n <Text>Body text — this shows default text color and weight.</Text>\n <Text tone=\"muted\" variant=\"bodySmall\">\n Muted caption text.\n </Text>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Button tone=\"primary\" emphasis=\"solid\" size=\"m\">\n Primary\n </Button>\n <Button tone=\"neutral\" emphasis=\"soft\" size=\"m\">\n Neutral\n </Button>\n <Button tone=\"danger\" emphasis=\"ghost\" size=\"m\">\n Danger\n </Button>\n </Stack>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Badge tone=\"primary\">Primary</Badge>\n <Badge tone=\"success\" emphasis=\"soft\">\n Success\n </Badge>\n <Badge tone=\"warning\" emphasis=\"soft\">\n Warning\n </Badge>\n <Badge tone=\"danger\" emphasis=\"soft\">\n Danger\n </Badge>\n </Stack>\n <Card\n tone=\"subtle\"\n title=\"Nested card\"\n description=\"Subtle tone inside the preview.\"\n compact\n />\n </Stack>\n </Card>\n\n {/* Submit */}\n {onSubmit ? (\n <Button\n tone=\"primary\"\n emphasis=\"solid\"\n onPress={() => onSubmit(value)}\n testID={testID ? `${testID}-submit` : undefined}\n >\n Apply theme\n </Button>\n ) : null}\n </Stack>\n );\n}\n\nexport const ThemeComposer = withZoraThemeScope(ThemeComposerInner);\n"]}
|
|
1
|
+
{"version":3,"file":"ThemeComposer.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/ThemeComposer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { COLOR_HARMONIES, parseHexColorOrThrow } from '@ankhorage/color-theory';\nimport { Box, Stack } from '@ankhorage/surface';\nimport React from 'react';\n\nimport { Badge } from '../../components/badge';\nimport { Button } from '../../components/button';\nimport { Card } from '../../components/card';\nimport { Heading } from '../../components/heading';\nimport { Input } from '../../components/input';\nimport { Select } from '../../components/select';\nimport { Tabs } from '../../components/tabs';\nimport { Text } from '../../components/text';\nimport type { ZoraThemeMode } from '../../theme/types';\nimport { useZoraTheme } from '../../theme/useZoraTheme';\nimport { withZoraThemeScope } from '../../theme/withZoraThemeScope';\nimport type { ThemeComposerProps } from './types';\n\nfunction isValidHex(value: string): boolean {\n try {\n parseHexColorOrThrow(value);\n return true;\n } catch {\n return false;\n }\n}\n\nconst HARMONY_OPTIONS = COLOR_HARMONIES.map((h) => ({ value: h, label: h }));\n\nconst MODE_TABS = [\n { value: 'light' as ZoraThemeMode, label: 'Light' },\n { value: 'dark' as ZoraThemeMode, label: 'Dark' },\n];\n\nfunction ThemeComposerInner({\n themeId: _themeId,\n value,\n onChange,\n mode,\n onModeChange,\n onSubmit,\n testID,\n}: ThemeComposerProps) {\n const { theme } = useZoraTheme();\n\n const [hexInput, setHexInput] = React.useState<string>(value.primaryColor);\n const [hexError, setHexError] = React.useState<string | undefined>(undefined);\n\n // Keep local hex input in sync when value.primaryColor changes externally\n React.useEffect(() => {\n setHexInput(value.primaryColor);\n setHexError(undefined);\n }, [value.primaryColor]);\n\n function handleHexChange(text: string) {\n // Ensure leading hash\n const normalized = text.startsWith('#') ? text : `#${text}`;\n setHexInput(normalized);\n\n if (isValidHex(normalized)) {\n setHexError(undefined);\n onChange({ ...value, primaryColor: normalized });\n } else {\n setHexError('Enter a valid 6-digit hex color (e.g. #0f766e).');\n }\n }\n\n const activeMode = mode ?? 'light';\n\n return (\n <Stack gap=\"l\" testID={testID}>\n {/* Section: Primary Color */}\n <Card title=\"Primary color\" description=\"Set the seed color for your theme palette.\">\n <Stack gap=\"m\">\n <Stack direction=\"row\" gap=\"m\" align=\"center\">\n <Box flex={1}>\n <Input\n value={hexInput}\n onChangeText={handleHexChange}\n placeholder=\"#0f766e\"\n autoCapitalize=\"none\"\n autoCorrect={false}\n maxLength={7}\n invalid={hexError !== undefined}\n testID={testID ? `${testID}-hex-input` : undefined}\n />\n </Box>\n {/* Color preview chip */}\n <Box\n width={36}\n height={36}\n radius=\"m\"\n style={{\n backgroundColor: isValidHex(hexInput) ? hexInput : theme.colors.border,\n borderWidth: 1,\n borderColor: theme.colors.border,\n }}\n />\n </Stack>\n {hexError ? (\n <Text tone=\"danger\" variant=\"bodySmall\">\n {hexError}\n </Text>\n ) : null}\n </Stack>\n </Card>\n\n {/* Section: Harmony */}\n <Card\n title=\"Harmony\"\n description=\"Choose how accent hues are generated from your primary color.\"\n >\n <Select\n value={value.harmony}\n options={HARMONY_OPTIONS}\n onValueChange={(h) => onChange({ ...value, harmony: h })}\n testID={testID ? `${testID}-harmony-select` : undefined}\n />\n </Card>\n\n {/* Section: Mode */}\n <Card title=\"Mode\" description=\"Switch between light and dark presentation.\">\n <Tabs\n value={activeMode}\n items={MODE_TABS}\n onValueChange={(m) => onModeChange?.(m)}\n variant=\"segmented\"\n testID={testID ? `${testID}-mode-tabs` : undefined}\n />\n </Card>\n\n {/* Section: Preview */}\n <Card title=\"Preview\" description=\"A quick look at how your theme renders common controls.\">\n <Stack gap=\"m\">\n <Heading level={4}>Heading</Heading>\n <Text>Body text — this shows default text color and weight.</Text>\n <Text tone=\"muted\" variant=\"bodySmall\">\n Muted caption text.\n </Text>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Button tone=\"primary\" emphasis=\"solid\" size=\"m\">\n Primary\n </Button>\n <Button tone=\"neutral\" emphasis=\"soft\" size=\"m\">\n Neutral\n </Button>\n <Button tone=\"danger\" emphasis=\"ghost\" size=\"m\">\n Danger\n </Button>\n </Stack>\n <Stack direction=\"row\" gap=\"s\" align=\"center\">\n <Badge tone=\"primary\">Primary</Badge>\n <Badge tone=\"success\" emphasis=\"soft\">\n Success\n </Badge>\n <Badge tone=\"warning\" emphasis=\"soft\">\n Warning\n </Badge>\n <Badge tone=\"danger\" emphasis=\"soft\">\n Danger\n </Badge>\n </Stack>\n <Card\n tone=\"subtle\"\n title=\"Nested card\"\n description=\"Subtle tone inside the preview.\"\n compact\n />\n </Stack>\n </Card>\n\n {/* Submit */}\n {onSubmit ? (\n <Button\n tone=\"primary\"\n emphasis=\"solid\"\n onPress={() => onSubmit(value)}\n testID={testID ? `${testID}-submit` : undefined}\n >\n Apply theme\n </Button>\n ) : null}\n </Stack>\n );\n}\n\nexport const ThemeComposer = withZoraThemeScope(ThemeComposerInner);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { ThemeComposer } from './ThemeComposer';\nexport type {
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC","sourcesContent":["export { ThemeComposer } from './ThemeComposer';\nexport type { ThemeComposerProps } from './types';\n"]}
|
|
@@ -1,22 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ZoraTheme, ZoraThemeMode } from '../../theme/types';
|
|
2
2
|
import type { ZoraBaseProps } from '../../theme/ZoraBaseProps';
|
|
3
|
-
export type ThemeComposerAppCategory = string;
|
|
4
|
-
export type ThemeComposerAppMood = string;
|
|
5
|
-
export interface ThemeComposerRecommendation {
|
|
6
|
-
appCategory: ThemeComposerAppCategory;
|
|
7
|
-
appMood: ThemeComposerAppMood;
|
|
8
|
-
suggestedColorTone: ZoraColorTone;
|
|
9
|
-
suggestedHarmony: ZoraColorHarmony;
|
|
10
|
-
suggestedPrimaryHueDegrees?: number;
|
|
11
|
-
}
|
|
12
3
|
export interface ThemeComposerProps extends ZoraBaseProps {
|
|
13
4
|
value: ZoraTheme;
|
|
14
5
|
onChange: (theme: ZoraTheme) => void;
|
|
15
6
|
mode?: ZoraThemeMode;
|
|
16
7
|
onModeChange?: (mode: ZoraThemeMode) => void;
|
|
17
8
|
onSubmit?: (theme: ZoraTheme) => void;
|
|
18
|
-
appCategory?: ThemeComposerAppCategory;
|
|
19
|
-
appMood?: ThemeComposerAppMood;
|
|
20
|
-
recommendations?: readonly ThemeComposerRecommendation[];
|
|
21
9
|
}
|
|
22
10
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/patterns/theme-composer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,kBAAmB,SAAQ,aAAa;IACvD,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IAC7C,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACvC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/types.ts"],"names":[],"mappings":"","sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/patterns/theme-composer/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { ZoraTheme, ZoraThemeMode } from '../../theme/types';\nimport type { ZoraBaseProps } from '../../theme/ZoraBaseProps';\n\nexport interface ThemeComposerProps extends ZoraBaseProps {\n value: ZoraTheme;\n onChange: (theme: ZoraTheme) => void;\n mode?: ZoraThemeMode;\n onModeChange?: (mode: ZoraThemeMode) => void;\n onSubmit?: (theme: ZoraTheme) => void;\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ThemeConfig } from '@ankhorage/
|
|
1
|
+
import type { ThemeConfig } from '@ankhorage/contracts';
|
|
2
2
|
import type { ZoraTheme } from './types';
|
|
3
3
|
export declare function createZoraThemeConfig(theme?: ZoraTheme): ThemeConfig;
|
|
4
4
|
//# sourceMappingURL=createZoraThemeConfig.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZoraThemeConfig.d.ts","sourceRoot":"","sources":["../../src/theme/createZoraThemeConfig.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createZoraThemeConfig.d.ts","sourceRoot":"","sources":["../../src/theme/createZoraThemeConfig.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGzC,wBAAgB,qBAAqB,CAAC,KAAK,GAAE,SAA4B,GAAG,WAAW,CAetF"}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parseHexColorOrThrow } from '@ankhorage/color-theory';
|
|
2
2
|
import { zoraDefaultTheme } from './zoraDefaultTheme';
|
|
3
3
|
export function createZoraThemeConfig(theme = zoraDefaultTheme) {
|
|
4
|
+
const primaryColor = parseHexColorOrThrow(theme.primaryColor);
|
|
4
5
|
return {
|
|
5
6
|
id: theme.id,
|
|
6
|
-
name: theme.name
|
|
7
|
+
name: theme.name,
|
|
7
8
|
light: {
|
|
8
|
-
primaryColor
|
|
9
|
+
primaryColor,
|
|
9
10
|
harmony: theme.harmony,
|
|
10
|
-
colorTone: theme.colorTone,
|
|
11
11
|
},
|
|
12
12
|
dark: {
|
|
13
|
-
primaryColor
|
|
13
|
+
primaryColor,
|
|
14
14
|
harmony: theme.harmony,
|
|
15
|
-
colorTone: theme.colorTone,
|
|
16
15
|
},
|
|
17
16
|
};
|
|
18
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createZoraThemeConfig.js","sourceRoot":"","sources":["../../src/theme/createZoraThemeConfig.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createZoraThemeConfig.js","sourceRoot":"","sources":["../../src/theme/createZoraThemeConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAI/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,MAAM,UAAU,qBAAqB,CAAC,QAAmB,gBAAgB;IACvE,MAAM,YAAY,GAAG,oBAAoB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAE9D,OAAO;QACL,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE;YACL,YAAY;YACZ,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB;QACD,IAAI,EAAE;YACJ,YAAY;YACZ,OAAO,EAAE,KAAK,CAAC,OAAO;SACvB;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { parseHexColorOrThrow } from '@ankhorage/color-theory';\nimport type { ThemeConfig } from '@ankhorage/contracts';\n\nimport type { ZoraTheme } from './types';\nimport { zoraDefaultTheme } from './zoraDefaultTheme';\n\nexport function createZoraThemeConfig(theme: ZoraTheme = zoraDefaultTheme): ThemeConfig {\n const primaryColor = parseHexColorOrThrow(theme.primaryColor);\n\n return {\n id: theme.id,\n name: theme.name,\n light: {\n primaryColor,\n harmony: theme.harmony,\n },\n dark: {\n primaryColor,\n harmony: theme.harmony,\n },\n };\n}\n"]}
|
package/dist/theme/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createZoraThemeConfig } from './createZoraThemeConfig';
|
|
2
|
-
export type {
|
|
2
|
+
export type { ZoraComputedTheme, ZoraComputedThemeMode, ZoraTheme, ZoraThemeId, ZoraThemeMode, } from './types';
|
|
3
3
|
export { useZoraTheme } from './useZoraTheme';
|
|
4
4
|
export { withZoraThemeScope } from './withZoraThemeScope';
|
|
5
5
|
export type { ZoraBaseProps } from './ZoraBaseProps';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EACV,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EACV,iBAAiB,EACjB,qBAAqB,EACrB,SAAS,EACT,WAAW,EACX,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/theme/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAQhE,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["export { createZoraThemeConfig } from './createZoraThemeConfig';\nexport type {\n ZoraComputedTheme,\n ZoraComputedThemeMode,\n ZoraTheme,\n ZoraThemeId,\n ZoraThemeMode,\n} from './types';\nexport { useZoraTheme } from './useZoraTheme';\nexport { withZoraThemeScope } from './withZoraThemeScope';\nexport type { ZoraBaseProps } from './ZoraBaseProps';\nexport { zoraDefaultTheme } from './zoraDefaultTheme';\nexport type { ZoraProviderProps } from './ZoraProvider';\nexport { ZoraProvider } from './ZoraProvider';\nexport type { ZoraThemeScopeProps } from './ZoraThemeScope';\nexport { ZoraThemeScope } from './ZoraThemeScope';\n"]}
|