@oxyhq/bloom 0.38.0 → 0.40.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 (99) hide show
  1. package/lib/commonjs/design-tokens/theme-css.js +3 -0
  2. package/lib/commonjs/design-tokens/theme-css.js.map +1 -1
  3. package/lib/commonjs/design-tokens/theme.css +3 -0
  4. package/lib/commonjs/prompt-input/Attachments.js +2 -2
  5. package/lib/commonjs/prompt-input/Attachments.js.map +1 -1
  6. package/lib/commonjs/theme/adaptive-colors.js +6 -0
  7. package/lib/commonjs/theme/adaptive-colors.js.map +1 -1
  8. package/lib/commonjs/theme/build-theme-from-seed.js +90 -0
  9. package/lib/commonjs/theme/build-theme-from-seed.js.map +1 -0
  10. package/lib/commonjs/theme/build-theme.js +5 -1
  11. package/lib/commonjs/theme/build-theme.js.map +1 -1
  12. package/lib/commonjs/theme/color-scope/seed-scope.js +99 -0
  13. package/lib/commonjs/theme/color-scope/seed-scope.js.map +1 -0
  14. package/lib/commonjs/theme/index.js +94 -0
  15. package/lib/commonjs/theme/index.js.map +1 -1
  16. package/lib/commonjs/theme/preset-vars.js +4 -0
  17. package/lib/commonjs/theme/preset-vars.js.map +1 -1
  18. package/lib/commonjs/theme/seed-scope/index.js +87 -0
  19. package/lib/commonjs/theme/seed-scope/index.js.map +1 -0
  20. package/lib/commonjs/theme/seed-scope/index.web.js +86 -0
  21. package/lib/commonjs/theme/seed-scope/index.web.js.map +1 -0
  22. package/lib/commonjs/theme/token-registry.js +1 -1
  23. package/lib/commonjs/theme/token-registry.js.map +1 -1
  24. package/lib/module/design-tokens/theme-css.js +3 -0
  25. package/lib/module/design-tokens/theme-css.js.map +1 -1
  26. package/lib/module/design-tokens/theme.css +3 -0
  27. package/lib/module/prompt-input/Attachments.js +2 -2
  28. package/lib/module/prompt-input/Attachments.js.map +1 -1
  29. package/lib/module/theme/adaptive-colors.js +6 -0
  30. package/lib/module/theme/adaptive-colors.js.map +1 -1
  31. package/lib/module/theme/build-theme-from-seed.js +85 -0
  32. package/lib/module/theme/build-theme-from-seed.js.map +1 -0
  33. package/lib/module/theme/build-theme.js +5 -1
  34. package/lib/module/theme/build-theme.js.map +1 -1
  35. package/lib/module/theme/color-scope/seed-scope.js +95 -0
  36. package/lib/module/theme/color-scope/seed-scope.js.map +1 -0
  37. package/lib/module/theme/index.js +7 -0
  38. package/lib/module/theme/index.js.map +1 -1
  39. package/lib/module/theme/preset-vars.js +4 -0
  40. package/lib/module/theme/preset-vars.js.map +1 -1
  41. package/lib/module/theme/seed-scope/index.js +82 -0
  42. package/lib/module/theme/seed-scope/index.js.map +1 -0
  43. package/lib/module/theme/seed-scope/index.web.js +81 -0
  44. package/lib/module/theme/seed-scope/index.web.js.map +1 -0
  45. package/lib/module/theme/token-registry.js +1 -1
  46. package/lib/module/theme/token-registry.js.map +1 -1
  47. package/lib/typescript/commonjs/design-tokens/theme-css.d.ts.map +1 -1
  48. package/lib/typescript/commonjs/theme/adaptive-colors.d.ts.map +1 -1
  49. package/lib/typescript/commonjs/theme/build-theme-from-seed.d.ts +23 -0
  50. package/lib/typescript/commonjs/theme/build-theme-from-seed.d.ts.map +1 -0
  51. package/lib/typescript/commonjs/theme/build-theme.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/theme/color-scope/seed-scope.d.ts +43 -0
  53. package/lib/typescript/commonjs/theme/color-scope/seed-scope.d.ts.map +1 -0
  54. package/lib/typescript/commonjs/theme/index.d.ts +7 -0
  55. package/lib/typescript/commonjs/theme/index.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/theme/preset-vars.d.ts.map +1 -1
  57. package/lib/typescript/commonjs/theme/seed-scope/index.d.ts +37 -0
  58. package/lib/typescript/commonjs/theme/seed-scope/index.d.ts.map +1 -0
  59. package/lib/typescript/commonjs/theme/seed-scope/index.web.d.ts +35 -0
  60. package/lib/typescript/commonjs/theme/seed-scope/index.web.d.ts.map +1 -0
  61. package/lib/typescript/commonjs/theme/token-registry.d.ts +1 -1
  62. package/lib/typescript/commonjs/theme/token-registry.d.ts.map +1 -1
  63. package/lib/typescript/commonjs/theme/types.d.ts +5 -1
  64. package/lib/typescript/commonjs/theme/types.d.ts.map +1 -1
  65. package/lib/typescript/module/design-tokens/theme-css.d.ts.map +1 -1
  66. package/lib/typescript/module/theme/adaptive-colors.d.ts.map +1 -1
  67. package/lib/typescript/module/theme/build-theme-from-seed.d.ts +23 -0
  68. package/lib/typescript/module/theme/build-theme-from-seed.d.ts.map +1 -0
  69. package/lib/typescript/module/theme/build-theme.d.ts.map +1 -1
  70. package/lib/typescript/module/theme/color-scope/seed-scope.d.ts +43 -0
  71. package/lib/typescript/module/theme/color-scope/seed-scope.d.ts.map +1 -0
  72. package/lib/typescript/module/theme/index.d.ts +7 -0
  73. package/lib/typescript/module/theme/index.d.ts.map +1 -1
  74. package/lib/typescript/module/theme/preset-vars.d.ts.map +1 -1
  75. package/lib/typescript/module/theme/seed-scope/index.d.ts +37 -0
  76. package/lib/typescript/module/theme/seed-scope/index.d.ts.map +1 -0
  77. package/lib/typescript/module/theme/seed-scope/index.web.d.ts +35 -0
  78. package/lib/typescript/module/theme/seed-scope/index.web.d.ts.map +1 -0
  79. package/lib/typescript/module/theme/token-registry.d.ts +1 -1
  80. package/lib/typescript/module/theme/token-registry.d.ts.map +1 -1
  81. package/lib/typescript/module/theme/types.d.ts +5 -1
  82. package/lib/typescript/module/theme/types.d.ts.map +1 -1
  83. package/package.json +1 -1
  84. package/src/design-tokens/theme-css.ts +3 -0
  85. package/src/design-tokens/theme.css +3 -0
  86. package/src/prompt-input/Attachments.tsx +2 -2
  87. package/src/theme/__tests__/__snapshots__/visual-gallery.test.tsx.snap +78 -0
  88. package/src/theme/__tests__/build-theme-from-seed-parity.test.ts +33 -0
  89. package/src/theme/__tests__/seed-scope-parity.test.ts +27 -0
  90. package/src/theme/adaptive-colors.ts +6 -0
  91. package/src/theme/build-theme-from-seed.ts +99 -0
  92. package/src/theme/build-theme.ts +5 -1
  93. package/src/theme/color-scope/seed-scope.ts +105 -0
  94. package/src/theme/index.ts +21 -0
  95. package/src/theme/preset-vars.ts +4 -0
  96. package/src/theme/seed-scope/index.tsx +100 -0
  97. package/src/theme/seed-scope/index.web.tsx +110 -0
  98. package/src/theme/token-registry.ts +2 -0
  99. package/src/theme/types.ts +5 -1
@@ -0,0 +1,43 @@
1
+ import { type RoleColors, type SchemeVariant } from '../color-engine';
2
+ /**
3
+ * The canonical role → token assignment, sourced from an arbitrary seed's role
4
+ * set instead of a named preset.
5
+ *
6
+ * This MUST stay byte-for-byte identical to the mapping in `getPresetVars`
7
+ * (`preset-vars.ts`): a named preset is just a fixed seed, so scoping a subtree
8
+ * to a preset via `buildScopeVars` and scoping it to that preset's seed hex via
9
+ * `buildSeedScopeVars` are required to produce the same tokens. The parity test
10
+ * (`__tests__/seed-scope-parity.test.ts`) fails CI if the two ever drift.
11
+ *
12
+ * Values are full `rgb(r g b)` strings straight from the engine — no HSL-triple
13
+ * intermediate, so they flow through the scope pipeline unchanged (same as the
14
+ * preset path after `getResolvedTokens`).
15
+ */
16
+ export declare function roleColorsToPresetTokens(r: RoleColors): Record<string, string>;
17
+ /** Options for deriving scope vars directly from a seed colour. */
18
+ export interface SeedScopeOptions {
19
+ /** The seed colour, `#rrggbb`. */
20
+ seed: string;
21
+ mode: 'light' | 'dark';
22
+ /**
23
+ * The tonal scheme variant. Defaults to `'vibrant'` — the same variant every
24
+ * named Bloom preset uses, so a preset's seed reproduces that preset exactly.
25
+ */
26
+ variant?: SchemeVariant;
27
+ /** −1 (low) … 0 (normal) … 1 (high). Defaults to 0. */
28
+ contrastLevel?: number;
29
+ }
30
+ /**
31
+ * Build the CSS custom-property map for an ARBITRARY seed colour — the dynamic
32
+ * (non-preset) counterpart of `buildScopeVars`. Feeds the seed through the
33
+ * colour engine's `generateRoleColors` and assigns the roles to Bloom's
34
+ * canonical token names, then adds the Tailwind v4 `--color-x` aliases (required
35
+ * on web so scoped utilities resolve against the subtree instead of the document
36
+ * root).
37
+ *
38
+ * Scope the returned record onto an element (web: inline `style`; native:
39
+ * NativeWind `VariableContextProvider`) to tint just that subtree — e.g. the
40
+ * ambient region behind album/artist artwork — without re-theming the whole app.
41
+ */
42
+ export declare function buildSeedScopeVars(options: SeedScopeOptions): Record<string, string>;
43
+ //# sourceMappingURL=seed-scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-scope.d.ts","sourceRoot":"","sources":["../../../../../src/theme/color-scope/seed-scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAG1F;;;;;;;;;;;;;GAaG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA0C9E;AAED,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAiBpF"}
@@ -2,7 +2,14 @@ export { BloomThemeProvider } from './BloomThemeProvider';
2
2
  export type { BloomThemeProviderProps, BloomThemeContextValue, } from './BloomThemeProvider';
3
3
  export { BloomColorScope, useColorScopeStyle } from './color-scope';
4
4
  export type { BloomColorScopeProps } from './color-scope';
5
+ export { BloomSeedScope } from './seed-scope';
6
+ export type { BloomSeedScopeProps } from './seed-scope';
7
+ export { buildSeedScopeVars, roleColorsToPresetTokens } from './color-scope/seed-scope';
8
+ export type { SeedScopeOptions } from './color-scope/seed-scope';
9
+ export { generateRoleColors, seedHexFromImagePixels, seedsFromImagePixels, quantizeImage, argbFromHex, hexFromArgb, argbFromRgb, redFromArgb, greenFromArgb, blueFromArgb, } from './color-engine';
10
+ export type { RoleColors, GenerateOptions, RoleName, SchemeVariant } from './color-engine';
5
11
  export { buildTheme, STATUS_COLORS } from './build-theme';
12
+ export { buildThemeFromSeed, buildColorsFromSeed } from './build-theme-from-seed';
6
13
  export { THEME_GRADIENTS } from './gradients';
7
14
  export { useTheme, useThemeColor, useBloomTheme } from './use-theme';
8
15
  export { useNavigationTheme } from './use-navigation-theme';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACnF,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5F,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/theme/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,YAAY,EACV,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACpE,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACxF,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAIjE,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,WAAW,EACX,WAAW,EACX,WAAW,EACX,aAAa,EACb,YAAY,GACb,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACnF,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5F,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAClF,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAC5E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"preset-vars.d.ts","sourceRoot":"","sources":["../../../../src/theme/preset-vars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQ1F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,YAAY,CAoDd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,IAAI,CAYN"}
1
+ {"version":3,"file":"preset-vars.d.ts","sourceRoot":"","sources":["../../../../src/theme/preset-vars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAQ1F;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,YAAY,CAwDd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,YAAY,EACvB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,IAAI,CAYN"}
@@ -0,0 +1,37 @@
1
+ import React from 'react';
2
+ import { type StyleProp, type ViewStyle } from 'react-native';
3
+ import type { SchemeVariant } from '../color-engine';
4
+ export interface BloomSeedScopeProps {
5
+ /**
6
+ * The seed colour (`#rrggbb`) to derive this subtree's palette from. When
7
+ * `undefined`, the scope is a no-op and children inherit the parent scope
8
+ * unchanged — pass `undefined` to fall back to the app preset (e.g. on
9
+ * mouse-leave/blur when restoring the default theme).
10
+ */
11
+ seed: string | undefined;
12
+ /** Tonal scheme variant. Defaults to `'vibrant'` (matches Bloom presets). */
13
+ variant?: SchemeVariant;
14
+ /** −1 (low) … 0 (normal) … 1 (high). Defaults to 0. */
15
+ contrastLevel?: number;
16
+ /**
17
+ * When `true`, do not render a wrapping `<View>`. The single child is cloned
18
+ * with the caller's `style` merged into its `style` prop (Radix-style).
19
+ */
20
+ asChild?: boolean;
21
+ /** Additional style applied to the wrapping `<View>` (or merged into the cloned child with `asChild`). */
22
+ style?: StyleProp<ViewStyle>;
23
+ children: React.ReactNode;
24
+ }
25
+ /**
26
+ * Native `<BloomSeedScope>`: scopes a subtree to an ARBITRARY seed colour's
27
+ * palette (the dynamic counterpart of `<BloomColorScope>`, which takes a named
28
+ * preset). Feeds the seed through the colour engine and (1) provides the
29
+ * resulting canonical CSS vars to descendants via react-native-css's
30
+ * `VariableContext` — so `bg-background` / `bg-card` / `var(--primary)` resolve
31
+ * against the seed inside this subtree — and (2) publishes a matching JS `theme`
32
+ * on `BloomThemeContext`, so `useTheme()`/`useBloomTheme()` consumers inside the
33
+ * subtree also re-theme. The `colorPreset` field is left as the parent's (a seed
34
+ * is not a named preset).
35
+ */
36
+ export declare function BloomSeedScope({ seed, variant, contrastLevel, asChild, style, children, }: BloomSeedScopeProps): import("react/jsx-runtime").JSX.Element;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/theme/seed-scope/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAC;AAC3F,OAAO,EAAQ,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAMpE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,0GAA0G;IAC1G,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,aAAa,EACb,OAAe,EACf,KAAK,EACL,QAAQ,GACT,EAAE,mBAAmB,2CA8CrB"}
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import type { SchemeVariant } from '../color-engine';
3
+ export interface BloomSeedScopeProps {
4
+ /**
5
+ * The seed colour (`#rrggbb`) to derive this subtree's palette from. When
6
+ * `undefined`, the scope is a no-op and children inherit the parent scope
7
+ * unchanged — pass `undefined` to fall back to the app preset (e.g. on
8
+ * mouse-leave/blur when restoring the default theme).
9
+ */
10
+ seed: string | undefined;
11
+ /** Tonal scheme variant. Defaults to `'vibrant'` (matches Bloom presets). */
12
+ variant?: SchemeVariant;
13
+ /** −1 (low) … 0 (normal) … 1 (high). Defaults to 0. */
14
+ contrastLevel?: number;
15
+ /**
16
+ * When `true`, do not render a wrapping `<div>`. The single child is cloned
17
+ * with the scope's CSS vars merged into its `style` prop (Radix-style).
18
+ */
19
+ asChild?: boolean;
20
+ /** Additional style applied to the wrapping `<div>` (or merged into the cloned child with `asChild`). */
21
+ style?: React.CSSProperties;
22
+ children: React.ReactNode;
23
+ }
24
+ /**
25
+ * Web `<BloomSeedScope>`: scopes a subtree to an ARBITRARY seed colour's palette
26
+ * (the dynamic counterpart of `<BloomColorScope>`). It (1) writes every canonical
27
+ * `--x` token plus the Tailwind v4 `--color-x` aliases (already resolved to
28
+ * `rgb(...)`) onto the wrapping element's inline `style`, so NativeWind classes
29
+ * inside resolve against the seed palette instead of the document root, and
30
+ * (2) publishes a matching JS `theme` on `BloomThemeContext` so
31
+ * `useTheme()`/`useBloomTheme()` consumers inside the subtree re-theme too. The
32
+ * `colorPreset` field is left as the parent's (a seed is not a named preset).
33
+ */
34
+ export declare function BloomSeedScope({ seed, variant, contrastLevel, asChild, style, children, }: BloomSeedScopeProps): import("react/jsx-runtime").JSX.Element;
35
+ //# sourceMappingURL=index.web.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.web.d.ts","sourceRoot":"","sources":["../../../../../src/theme/seed-scope/index.web.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsE,MAAM,OAAO,CAAC;AAK3F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yGAAyG;IACzG,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B;AAoBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,EAC7B,IAAI,EACJ,OAAO,EACP,aAAa,EACb,OAAe,EACf,KAAK,EACL,QAAQ,GACT,EAAE,mBAAmB,2CA6CrB"}
@@ -12,7 +12,7 @@ import { APP_COLOR_NAMES, type AppColorName } from './color-presets';
12
12
  * Order mirrors `getPresetVars`'s insertion order: base tokens first (in the
13
13
  * order they appear in the preset data), then the synthesized extended tokens.
14
14
  */
15
- export declare const CANONICAL_TOKENS: readonly ["background", "foreground", "surface", "surface-foreground", "popover", "popover-foreground", "primary", "primary-foreground", "secondary", "secondary-foreground", "muted", "muted-foreground", "accent", "accent-foreground", "destructive", "border", "input", "ring", "sidebar", "card", "card-foreground", "chart-1", "chart-2", "chart-3", "chart-4", "chart-5", "content-area", "sidebar-foreground", "sidebar-primary", "sidebar-primary-foreground", "sidebar-accent", "sidebar-accent-foreground", "sidebar-border", "sidebar-ring"];
15
+ export declare const CANONICAL_TOKENS: readonly ["background", "foreground", "surface", "surface-foreground", "popover", "popover-foreground", "primary", "primary-foreground", "secondary", "secondary-foreground", "tertiary", "tertiary-foreground", "muted", "muted-foreground", "accent", "accent-foreground", "destructive", "border", "input", "ring", "sidebar", "card", "card-foreground", "chart-1", "chart-2", "chart-3", "chart-4", "chart-5", "content-area", "sidebar-foreground", "sidebar-primary", "sidebar-primary-foreground", "sidebar-accent", "sidebar-accent-foreground", "sidebar-border", "sidebar-ring"];
16
16
  /** A canonical token name (no leading `--`). */
17
17
  export type CanonicalToken = (typeof CANONICAL_TOKENS)[number];
18
18
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"token-registry.d.ts","sourceRoot":"","sources":["../../../../src/theme/token-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGrE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,0hBAmCnB,CAAC;AAEX,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAW/D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA+ChD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"token-registry.d.ts","sourceRoot":"","sources":["../../../../src/theme/token-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAGrE;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,gBAAgB,6jBAqCnB,CAAC;AAEX,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAW/D;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA+ChD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,OAAO,GAAG,MAAM,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxB;AAED,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -14,8 +14,12 @@ export interface ThemeColors {
14
14
  primaryLight: string;
15
15
  /** Legacy alias: the page background (`--background`), NOT the focus ring. */
16
16
  primaryDark: string;
17
- /** Legacy alias: mirrors `primary` (`--primary`) for backwards compatibility. */
17
+ /** The M3 secondary accent — a real contrast colour (no longer a mirror of primary). */
18
18
  secondary: string;
19
+ secondaryForeground: string;
20
+ /** The M3 tertiary accent, completing the primary/secondary/tertiary trio. */
21
+ tertiary: string;
22
+ tertiaryForeground: string;
19
23
  tint: string;
20
24
  icon: string;
21
25
  iconActive: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/theme/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAE3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IAErB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IAEpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IAEpB,iFAAiF;IACjF,SAAS,EAAE,MAAM,CAAC;IAElB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjC;AAED,uEAAuE;AACvE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE3D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,yFAAyF;IACzF,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/theme/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAE3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IAErB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IAEpB,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,WAAW,EAAE,MAAM,CAAC;IAEpB,wFAAwF;IACxF,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAE3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IAEb,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB,EAAE,MAAM,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACjC;AAED,uEAAuE;AACvE,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAE3D,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,WAAW,CAAC;IACpB,yFAAyF;IACzF,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CAClB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/bloom",
3
- "version": "0.38.0",
3
+ "version": "0.40.0",
4
4
  "description": "Bloom UI — Oxy ecosystem component library for React Native + Expo + Web",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -73,6 +73,9 @@ export function bloomThemeCss(): string {
73
73
  // `destructive` carries no themed foreground token; its text is always the
74
74
  // fixed light-on-error colour.
75
75
  lines.push(' --color-destructive-foreground: #ffffff;');
76
+ // `divider` is a semantic alias of the border token (M3 outlineVariant) so
77
+ // `bg-divider` / `border-divider` read intentionally in list/section UIs.
78
+ lines.push(' --color-divider: var(--border);');
76
79
 
77
80
  // Spacing.
78
81
  for (const [key, value] of Object.entries(SPACING)) {
@@ -36,6 +36,8 @@
36
36
  --color-primary-foreground: var(--primary-foreground);
37
37
  --color-secondary: var(--secondary);
38
38
  --color-secondary-foreground: var(--secondary-foreground);
39
+ --color-tertiary: var(--tertiary);
40
+ --color-tertiary-foreground: var(--tertiary-foreground);
39
41
  --color-muted: var(--muted);
40
42
  --color-muted-foreground: var(--muted-foreground);
41
43
  --color-accent: var(--accent);
@@ -61,6 +63,7 @@
61
63
  --color-sidebar-border: var(--sidebar-border);
62
64
  --color-sidebar-ring: var(--sidebar-ring);
63
65
  --color-destructive-foreground: #ffffff;
66
+ --color-divider: var(--border);
64
67
  --spacing-space-2: 2px;
65
68
  --spacing-space-4: 4px;
66
69
  --spacing-space-8: 8px;
@@ -101,7 +101,7 @@ function ImageAttachmentItem({
101
101
  height: 120,
102
102
  borderRadius: 16,
103
103
  overflow: 'hidden',
104
- backgroundColor: theme.colors.backgroundSecondary,
104
+ backgroundColor: theme.colors.card,
105
105
  borderWidth: 1,
106
106
  borderColor: theme.colors.border,
107
107
  }}
@@ -168,7 +168,7 @@ function DocumentAttachmentItem({
168
168
  borderWidth: 1,
169
169
  borderColor: theme.colors.border,
170
170
  overflow: 'hidden',
171
- backgroundColor: theme.colors.backgroundSecondary,
171
+ backgroundColor: theme.colors.card,
172
172
  }}
173
173
  >
174
174
  <View
@@ -26,8 +26,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
26
26
  "primarySubtle": "rgb(101 62 0)",
27
27
  "primarySubtleForeground": "rgb(255 221 184)",
28
28
  "secondary": "rgb(227 194 140)",
29
+ "secondaryForeground": "rgb(65 45 5)",
29
30
  "shadow": "rgba(0, 0, 0, 0.3)",
30
31
  "success": "#10B981",
32
+ "tertiary": "rgb(225 196 119)",
33
+ "tertiaryForeground": "rgb(61 46 0)",
31
34
  "text": "rgb(244 223 203)",
32
35
  "textSecondary": "rgb(217 195 171)",
33
36
  "textTertiary": "rgb(161 141 120)",
@@ -58,8 +61,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
58
61
  "primarySubtle": "rgb(255 221 184)",
59
62
  "primarySubtleForeground": "rgb(101 62 0)",
60
63
  "secondary": "rgb(115 90 46)",
64
+ "secondaryForeground": "rgb(255 255 255)",
61
65
  "shadow": "rgba(0, 0, 0, 0.1)",
62
66
  "success": "#10B981",
67
+ "tertiary": "rgb(114 92 26)",
68
+ "tertiaryForeground": "rgb(255 255 255)",
63
69
  "text": "rgb(36 26 14)",
64
70
  "textSecondary": "rgb(84 68 50)",
65
71
  "textTertiary": "rgb(135 116 96)",
@@ -90,8 +96,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
90
96
  "primarySubtle": "rgb(0 74 120)",
91
97
  "primarySubtleForeground": "rgb(207 229 255)",
92
98
  "secondary": "rgb(185 198 234)",
99
+ "secondaryForeground": "rgb(35 48 77)",
93
100
  "shadow": "rgba(0, 0, 0, 0.3)",
94
101
  "success": "#10B981",
102
+ "tertiary": "rgb(193 194 249)",
103
+ "tertiaryForeground": "rgb(42 43 89)",
95
104
  "text": "rgb(220 227 238)",
96
105
  "textSecondary": "rgb(190 199 212)",
97
106
  "textTertiary": "rgb(136 146 158)",
@@ -122,8 +131,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
122
131
  "primarySubtle": "rgb(207 229 255)",
123
132
  "primarySubtleForeground": "rgb(0 74 120)",
124
133
  "secondary": "rgb(81 94 125)",
134
+ "secondaryForeground": "rgb(255 255 255)",
125
135
  "shadow": "rgba(0, 0, 0, 0.1)",
126
136
  "success": "#10B981",
137
+ "tertiary": "rgb(89 90 139)",
138
+ "tertiaryForeground": "rgb(255 255 255)",
127
139
  "text": "rgb(21 28 36)",
128
140
  "textSecondary": "rgb(62 72 82)",
129
141
  "textTertiary": "rgb(111 120 132)",
@@ -154,8 +166,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
154
166
  "primarySubtle": "rgb(40 80 0)",
155
167
  "primarySubtleForeground": "rgb(138 254 0)",
156
168
  "secondary": "rgb(174 207 172)",
169
+ "secondaryForeground": "rgb(26 54 30)",
157
170
  "shadow": "rgba(0, 0, 0, 0.3)",
158
171
  "success": "#10B981",
172
+ "tertiary": "rgb(151 212 179)",
173
+ "tertiaryForeground": "rgb(0 56 36)",
159
174
  "text": "rgb(223 229 211)",
160
175
  "textSecondary": "rgb(193 202 180)",
161
176
  "textTertiary": "rgb(139 148 128)",
@@ -186,8 +201,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
186
201
  "primarySubtle": "rgb(138 254 0)",
187
202
  "primarySubtleForeground": "rgb(40 80 0)",
188
203
  "secondary": "rgb(72 101 73)",
204
+ "secondaryForeground": "rgb(255 255 255)",
189
205
  "shadow": "rgba(0, 0, 0, 0.1)",
190
206
  "success": "#10B981",
207
+ "tertiary": "rgb(47 105 78)",
208
+ "tertiaryForeground": "rgb(255 255 255)",
191
209
  "text": "rgb(24 29 18)",
192
210
  "textSecondary": "rgb(65 73 57)",
193
211
  "textTertiary": "rgb(114 122 103)",
@@ -218,8 +236,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
218
236
  "primarySubtle": "rgb(0 82 54)",
219
237
  "primarySubtleForeground": "rgb(71 255 184)",
220
238
  "secondary": "rgb(162 208 195)",
239
+ "secondaryForeground": "rgb(5 55 46)",
221
240
  "shadow": "rgba(0, 0, 0, 0.3)",
222
241
  "success": "#10B981",
242
+ "tertiary": "rgb(140 211 208)",
243
+ "tertiaryForeground": "rgb(0 55 54)",
223
244
  "text": "rgb(217 230 220)",
224
245
  "textSecondary": "rgb(186 203 191)",
225
246
  "textTertiary": "rgb(132 149 138)",
@@ -250,8 +271,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
250
271
  "primarySubtle": "rgb(71 255 184)",
251
272
  "primarySubtleForeground": "rgb(0 82 54)",
252
273
  "secondary": "rgb(59 102 92)",
274
+ "secondaryForeground": "rgb(255 255 255)",
253
275
  "shadow": "rgba(0, 0, 0, 0.1)",
254
276
  "success": "#10B981",
277
+ "tertiary": "rgb(26 105 103)",
278
+ "tertiaryForeground": "rgb(255 255 255)",
255
279
  "text": "rgb(19 30 24)",
256
280
  "textSecondary": "rgb(59 74 65)",
257
281
  "textTertiary": "rgb(107 123 113)",
@@ -282,8 +306,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
282
306
  "primarySubtle": "rgb(0 80 72)",
283
307
  "primarySubtleForeground": "rgb(0 254 229)",
284
308
  "secondary": "rgb(160 207 210)",
309
+ "secondaryForeground": "rgb(0 55 58)",
285
310
  "shadow": "rgba(0, 0, 0, 0.3)",
286
311
  "success": "#10B981",
312
+ "tertiary": "rgb(145 208 228)",
313
+ "tertiaryForeground": "rgb(0 54 65)",
287
314
  "text": "rgb(215 230 225)",
288
315
  "textSecondary": "rgb(184 202 198)",
289
316
  "textTertiary": "rgb(130 148 144)",
@@ -314,8 +341,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
314
341
  "primarySubtle": "rgb(0 254 229)",
315
342
  "primarySubtleForeground": "rgb(0 80 72)",
316
343
  "secondary": "rgb(56 101 105)",
344
+ "secondaryForeground": "rgb(255 255 255)",
317
345
  "shadow": "rgba(0, 0, 0, 0.1)",
318
346
  "success": "#10B981",
347
+ "tertiary": "rgb(33 102 120)",
348
+ "tertiaryForeground": "rgb(255 255 255)",
319
349
  "text": "rgb(17 30 28)",
320
350
  "textSecondary": "rgb(57 74 71)",
321
351
  "textTertiary": "rgb(105 123 119)",
@@ -346,8 +376,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
346
376
  "primarySubtle": "rgb(120 50 0)",
347
377
  "primarySubtleForeground": "rgb(255 219 202)",
348
378
  "secondary": "rgb(238 189 147)",
379
+ "secondaryForeground": "rgb(71 41 11)",
349
380
  "shadow": "rgba(0, 0, 0, 0.3)",
350
381
  "success": "#10B981",
382
+ "tertiary": "rgb(238 191 121)",
383
+ "tertiaryForeground": "rgb(68 43 0)",
351
384
  "text": "rgb(248 221 209)",
352
385
  "textSecondary": "rgb(223 192 178)",
353
386
  "textTertiary": "rgb(166 139 126)",
@@ -378,8 +411,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
378
411
  "primarySubtle": "rgb(255 219 202)",
379
412
  "primarySubtleForeground": "rgb(120 50 0)",
380
413
  "secondary": "rgb(124 86 52)",
414
+ "secondaryForeground": "rgb(255 255 255)",
381
415
  "shadow": "rgba(0, 0, 0, 0.1)",
382
416
  "success": "#10B981",
417
+ "tertiary": "rgb(123 88 28)",
418
+ "tertiaryForeground": "rgb(255 255 255)",
383
419
  "text": "rgb(38 24 17)",
384
420
  "textSecondary": "rgb(87 66 56)",
385
421
  "textTertiary": "rgb(139 114 102)",
@@ -410,8 +446,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
410
446
  "primarySubtle": "rgb(119 0 154)",
411
447
  "primarySubtleForeground": "rgb(251 215 255)",
412
448
  "secondary": "rgb(227 186 218)",
449
+ "secondaryForeground": "rgb(67 39 63)",
413
450
  "shadow": "rgba(0, 0, 0, 0.3)",
414
451
  "success": "#10B981",
452
+ "tertiary": "rgb(246 179 213)",
453
+ "tertiaryForeground": "rgb(78 32 60)",
415
454
  "text": "rgb(237 222 235)",
416
455
  "textSecondary": "rgb(210 193 210)",
417
456
  "textTertiary": "rgb(155 140 155)",
@@ -442,8 +481,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
442
481
  "primarySubtle": "rgb(251 215 255)",
443
482
  "primarySubtleForeground": "rgb(119 0 154)",
444
483
  "secondary": "rgb(117 84 111)",
484
+ "secondaryForeground": "rgb(255 255 255)",
445
485
  "shadow": "rgba(0, 0, 0, 0.1)",
446
486
  "success": "#10B981",
487
+ "tertiary": "rgb(131 78 107)",
488
+ "tertiaryForeground": "rgb(255 255 255)",
447
489
  "text": "rgb(33 25 34)",
448
490
  "textSecondary": "rgb(79 67 80)",
449
491
  "textTertiary": "rgb(129 115 129)",
@@ -474,8 +516,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
474
516
  "primarySubtle": "rgb(140 0 83)",
475
517
  "primarySubtleForeground": "rgb(255 217 228)",
476
518
  "secondary": "rgb(242 183 192)",
519
+ "secondaryForeground": "rgb(75 37 44)",
477
520
  "shadow": "rgba(0, 0, 0, 0.3)",
478
521
  "success": "#10B981",
522
+ "tertiary": "rgb(255 179 175)",
523
+ "tertiaryForeground": "rgb(83 32 31)",
479
524
  "text": "rgb(245 220 227)",
480
525
  "textSecondary": "rgb(219 191 200)",
481
526
  "textTertiary": "rgb(163 138 146)",
@@ -506,8 +551,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
506
551
  "primarySubtle": "rgb(255 217 228)",
507
552
  "primarySubtleForeground": "rgb(140 0 83)",
508
553
  "secondary": "rgb(128 81 89)",
554
+ "secondaryForeground": "rgb(255 255 255)",
509
555
  "shadow": "rgba(0, 0, 0, 0.1)",
510
556
  "success": "#10B981",
557
+ "tertiary": "rgb(139 77 74)",
558
+ "tertiaryForeground": "rgb(255 255 255)",
511
559
  "text": "rgb(37 24 29)",
512
560
  "textSecondary": "rgb(85 65 72)",
513
561
  "textTertiary": "rgb(136 113 120)",
@@ -538,8 +586,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
538
586
  "primarySubtle": "rgb(86 0 202)",
539
587
  "primarySubtleForeground": "rgb(233 221 255)",
540
588
  "secondary": "rgb(215 189 228)",
589
+ "secondaryForeground": "rgb(59 41 71)",
541
590
  "shadow": "rgba(0, 0, 0, 0.3)",
542
591
  "success": "#10B981",
592
+ "tertiary": "rgb(233 183 230)",
593
+ "tertiaryForeground": "rgb(71 35 73)",
543
594
  "text": "rgb(231 224 238)",
544
595
  "textSecondary": "rgb(203 195 213)",
545
596
  "textTertiary": "rgb(148 142 159)",
@@ -570,8 +621,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
570
621
  "primarySubtle": "rgb(233 221 255)",
571
622
  "primarySubtleForeground": "rgb(86 0 202)",
572
623
  "secondary": "rgb(107 87 120)",
624
+ "secondaryForeground": "rgb(255 255 255)",
573
625
  "shadow": "rgba(0, 0, 0, 0.1)",
574
626
  "success": "#10B981",
627
+ "tertiary": "rgb(121 80 121)",
628
+ "tertiaryForeground": "rgb(255 255 255)",
575
629
  "text": "rgb(29 26 36)",
576
630
  "textSecondary": "rgb(73 68 83)",
577
631
  "textTertiary": "rgb(122 116 132)",
@@ -602,8 +656,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
602
656
  "primarySubtle": "rgb(147 0 19)",
603
657
  "primarySubtleForeground": "rgb(255 218 215)",
604
658
  "secondary": "rgb(245 185 162)",
659
+ "secondaryForeground": "rgb(75 39 23)",
605
660
  "shadow": "rgba(0, 0, 0, 0.3)",
606
661
  "success": "#10B981",
662
+ "tertiary": "rgb(251 184 132)",
663
+ "tertiaryForeground": "rgb(77 38 0)",
607
664
  "text": "rgb(249 220 217)",
608
665
  "textSecondary": "rgb(223 191 188)",
609
666
  "textTertiary": "rgb(167 138 136)",
@@ -634,8 +691,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
634
691
  "primarySubtle": "rgb(255 218 215)",
635
692
  "primarySubtleForeground": "rgb(147 0 19)",
636
693
  "secondary": "rgb(129 83 65)",
694
+ "secondaryForeground": "rgb(255 255 255)",
637
695
  "shadow": "rgba(0, 0, 0, 0.1)",
638
696
  "success": "#10B981",
697
+ "tertiary": "rgb(133 83 39)",
698
+ "tertiaryForeground": "rgb(255 255 255)",
639
699
  "text": "rgb(39 24 23)",
640
700
  "textSecondary": "rgb(88 65 63)",
641
701
  "textTertiary": "rgb(140 113 110)",
@@ -666,8 +726,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
666
726
  "primarySubtle": "rgb(0 76 110)",
667
727
  "primarySubtleForeground": "rgb(201 230 255)",
668
728
  "secondary": "rgb(180 200 233)",
729
+ "secondaryForeground": "rgb(29 49 76)",
669
730
  "shadow": "rgba(0, 0, 0, 0.3)",
670
731
  "success": "#10B981",
732
+ "tertiary": "rgb(185 196 250)",
733
+ "tertiaryForeground": "rgb(34 46 90)",
671
734
  "text": "rgb(219 227 237)",
672
735
  "textSecondary": "rgb(188 200 211)",
673
736
  "textTertiary": "rgb(134 146 157)",
@@ -698,8 +761,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
698
761
  "primarySubtle": "rgb(201 230 255)",
699
762
  "primarySubtleForeground": "rgb(0 76 110)",
700
763
  "secondary": "rgb(76 95 124)",
764
+ "secondaryForeground": "rgb(255 255 255)",
701
765
  "shadow": "rgba(0, 0, 0, 0.1)",
702
766
  "success": "#10B981",
767
+ "tertiary": "rgb(81 92 139)",
768
+ "tertiaryForeground": "rgb(255 255 255)",
703
769
  "text": "rgb(20 29 35)",
704
770
  "textSecondary": "rgb(61 72 81)",
705
771
  "textTertiary": "rgb(109 120 131)",
@@ -730,8 +796,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
730
796
  "primarySubtle": "rgb(0 79 88)",
731
797
  "primarySubtleForeground": "rgb(154 240 255)",
732
798
  "secondary": "rgb(166 204 224)",
799
+ "secondaryForeground": "rgb(9 53 68)",
733
800
  "shadow": "rgba(0, 0, 0, 0.3)",
734
801
  "success": "#10B981",
802
+ "tertiary": "rgb(160 203 243)",
803
+ "tertiaryForeground": "rgb(0 51 81)",
735
804
  "text": "rgb(215 229 232)",
736
805
  "textSecondary": "rgb(184 202 205)",
737
806
  "textTertiary": "rgb(131 148 151)",
@@ -762,8 +831,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
762
831
  "primarySubtle": "rgb(154 240 255)",
763
832
  "primarySubtleForeground": "rgb(0 79 88)",
764
833
  "secondary": "rgb(62 99 116)",
834
+ "secondaryForeground": "rgb(255 255 255)",
765
835
  "shadow": "rgba(0, 0, 0, 0.1)",
766
836
  "success": "#10B981",
837
+ "tertiary": "rgb(54 98 133)",
838
+ "tertiaryForeground": "rgb(255 255 255)",
767
839
  "text": "rgb(17 29 32)",
768
840
  "textSecondary": "rgb(57 73 77)",
769
841
  "textTertiary": "rgb(105 122 125)",
@@ -794,8 +866,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
794
866
  "primarySubtle": "rgb(90 67 0)",
795
867
  "primarySubtleForeground": "rgb(255 223 154)",
796
868
  "secondary": "rgb(214 198 141)",
869
+ "secondaryForeground": "rgb(57 48 5)",
797
870
  "shadow": "rgba(0, 0, 0, 0.3)",
798
871
  "success": "#10B981",
872
+ "tertiary": "rgb(207 201 125)",
873
+ "tertiaryForeground": "rgb(53 50 0)",
799
874
  "text": "rgb(238 225 202)",
800
875
  "textSecondary": "rgb(211 197 170)",
801
876
  "textTertiary": "rgb(156 143 119)",
@@ -826,8 +901,11 @@ exports[`theme.colors snapshot for all presets (catches unintended palette shift
826
901
  "primarySubtle": "rgb(255 223 154)",
827
902
  "primarySubtleForeground": "rgb(90 67 0)",
828
903
  "secondary": "rgb(106 94 47)",
904
+ "secondaryForeground": "rgb(255 255 255)",
829
905
  "shadow": "rgba(0, 0, 0, 0.1)",
830
906
  "success": "#10B981",
907
+ "tertiary": "rgb(100 96 32)",
908
+ "tertiaryForeground": "rgb(255 255 255)",
831
909
  "text": "rgb(33 27 13)",
832
910
  "textSecondary": "rgb(79 70 49)",
833
911
  "textTertiary": "rgb(130 118 95)",
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Parity guard for the dynamic JS-theme seed path.
3
+ *
4
+ * A named preset is just a fixed seed, so `buildThemeFromSeed(preset.hex, mode)`
5
+ * MUST produce the identical `theme.colors` as the preset path
6
+ * `buildTheme(name, mode)`. If `buildColorsFromSeed` ever drifts from
7
+ * `buildColorsFromPreset`, this fails.
8
+ *
9
+ * NOTE: `buildTheme` can apply an adaptive (Material You) override on native, but
10
+ * this test runs under jsdom/node where `Platform.OS !== 'web'` is false and
11
+ * `isAdaptive` defaults to false, so the comparison is against the preset-derived
12
+ * palette (not adaptive), which is exactly what the seed path reproduces.
13
+ */
14
+ import { APP_COLOR_NAMES, APP_COLOR_PRESETS, type AppColorName } from '../color-presets';
15
+ import { buildTheme } from '../build-theme';
16
+ import { buildThemeFromSeed } from '../build-theme-from-seed';
17
+
18
+ describe('buildThemeFromSeed parity with buildTheme (preset)', () => {
19
+ const modes: Array<'light' | 'dark'> = ['light', 'dark'];
20
+
21
+ for (const name of APP_COLOR_NAMES as readonly AppColorName[]) {
22
+ for (const mode of modes) {
23
+ it(`matches preset "${name}" colours in ${mode} mode`, () => {
24
+ const preset = APP_COLOR_PRESETS[name];
25
+ const fromPreset = buildTheme(name, mode);
26
+ const fromSeed = buildThemeFromSeed(preset.hex, mode, preset.variant);
27
+ expect(fromSeed.colors).toEqual(fromPreset.colors);
28
+ expect(fromSeed.mode).toBe(fromPreset.mode);
29
+ expect(fromSeed.isDark).toBe(fromPreset.isDark);
30
+ });
31
+ }
32
+ }
33
+ });
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Parity guard for the dynamic seed-scope path.
3
+ *
4
+ * A named preset is just a fixed seed fed through the same colour engine, so
5
+ * `buildSeedScopeVars({ seed: preset.hex, ... })` MUST produce the identical
6
+ * token record as the preset path (`buildScopeVars(name, mode)`), including the
7
+ * Tailwind v4 `--color-*` aliases. If the role → token mapping in
8
+ * `seed-scope.ts` ever drifts from `getPresetVars`, this fails.
9
+ */
10
+ import { APP_COLOR_NAMES, APP_COLOR_PRESETS, type AppColorName } from '../color-presets';
11
+ import { buildScopeVars } from '../color-scope/style-builder';
12
+ import { buildSeedScopeVars } from '../color-scope/seed-scope';
13
+
14
+ describe('buildSeedScopeVars parity with preset scope', () => {
15
+ const modes: Array<'light' | 'dark'> = ['light', 'dark'];
16
+
17
+ for (const name of APP_COLOR_NAMES as readonly AppColorName[]) {
18
+ for (const mode of modes) {
19
+ it(`matches preset "${name}" in ${mode} mode`, () => {
20
+ const preset = APP_COLOR_PRESETS[name];
21
+ const fromPreset = buildScopeVars(name, mode);
22
+ const fromSeed = buildSeedScopeVars({ seed: preset.hex, mode });
23
+ expect(fromSeed).toEqual(fromPreset);
24
+ });
25
+ }
26
+ }
27
+ });