react-native-terra-ui 0.10.2 → 0.11.1

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 (82) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +8 -4
  3. package/lib/module/components/badge/Badge.js +174 -0
  4. package/lib/module/components/badge/Badge.js.map +1 -0
  5. package/lib/module/components/badge/index.js +4 -0
  6. package/lib/module/components/badge/index.js.map +1 -0
  7. package/lib/module/components/badge/parts/BadgeIndicator.js +191 -0
  8. package/lib/module/components/badge/parts/BadgeIndicator.js.map +1 -0
  9. package/lib/module/components/badge/types.js +4 -0
  10. package/lib/module/components/badge/types.js.map +1 -0
  11. package/lib/module/components/badge/utils.js +25 -0
  12. package/lib/module/components/badge/utils.js.map +1 -0
  13. package/lib/module/components/index.js +1 -0
  14. package/lib/module/components/index.js.map +1 -1
  15. package/lib/module/context/ThemeProvider.js +5 -5
  16. package/lib/module/context/ThemeProvider.js.map +1 -1
  17. package/lib/module/theme/define-config.js +5 -5
  18. package/lib/module/theme/define-config.js.map +1 -1
  19. package/lib/module/theme/errors.js +1 -1
  20. package/lib/module/theme/index.js +2 -2
  21. package/lib/module/theme/index.js.map +1 -1
  22. package/lib/module/theme/registry.js +15 -21
  23. package/lib/module/theme/registry.js.map +1 -1
  24. package/lib/module/theme/resolve-config.js +68 -68
  25. package/lib/module/theme/resolve-config.js.map +1 -1
  26. package/lib/module/theme/runtime.js +11 -11
  27. package/lib/module/theme/runtime.js.map +1 -1
  28. package/lib/module/theme/selection-store.js +7 -7
  29. package/lib/module/theme/selection-store.js.map +1 -1
  30. package/lib/module/theme/unistyles-adapter.js +1 -1
  31. package/lib/module/utils/accent-utils.js +24 -24
  32. package/lib/module/utils/accent-utils.js.map +1 -1
  33. package/lib/typescript/src/components/badge/Badge.d.ts +16 -0
  34. package/lib/typescript/src/components/badge/Badge.d.ts.map +1 -0
  35. package/lib/typescript/src/components/badge/index.d.ts +3 -0
  36. package/lib/typescript/src/components/badge/index.d.ts.map +1 -0
  37. package/lib/typescript/src/components/badge/parts/BadgeIndicator.d.ts +19 -0
  38. package/lib/typescript/src/components/badge/parts/BadgeIndicator.d.ts.map +1 -0
  39. package/lib/typescript/src/components/badge/types.d.ts +48 -0
  40. package/lib/typescript/src/components/badge/types.d.ts.map +1 -0
  41. package/lib/typescript/src/components/badge/utils.d.ts +13 -0
  42. package/lib/typescript/src/components/badge/utils.d.ts.map +1 -0
  43. package/lib/typescript/src/components/index.d.ts +1 -0
  44. package/lib/typescript/src/components/index.d.ts.map +1 -1
  45. package/lib/typescript/src/context/ThemeProvider.d.ts +7 -7
  46. package/lib/typescript/src/context/ThemeProvider.d.ts.map +1 -1
  47. package/lib/typescript/src/theme/define-config.d.ts +11 -8
  48. package/lib/typescript/src/theme/define-config.d.ts.map +1 -1
  49. package/lib/typescript/src/theme/errors.d.ts +1 -1
  50. package/lib/typescript/src/theme/index.d.ts +3 -3
  51. package/lib/typescript/src/theme/index.d.ts.map +1 -1
  52. package/lib/typescript/src/theme/registry.d.ts +5 -5
  53. package/lib/typescript/src/theme/registry.d.ts.map +1 -1
  54. package/lib/typescript/src/theme/resolve-config.d.ts +25 -25
  55. package/lib/typescript/src/theme/resolve-config.d.ts.map +1 -1
  56. package/lib/typescript/src/theme/runtime.d.ts +5 -5
  57. package/lib/typescript/src/theme/runtime.d.ts.map +1 -1
  58. package/lib/typescript/src/theme/selection-store.d.ts +5 -5
  59. package/lib/typescript/src/theme/selection-store.d.ts.map +1 -1
  60. package/lib/typescript/src/theme/types.d.ts +20 -47
  61. package/lib/typescript/src/theme/types.d.ts.map +1 -1
  62. package/lib/typescript/src/theme/unistyles-adapter.d.ts +1 -1
  63. package/lib/typescript/src/utils/accent-utils.d.ts +6 -7
  64. package/lib/typescript/src/utils/accent-utils.d.ts.map +1 -1
  65. package/package.json +1 -1
  66. package/src/components/badge/Badge.tsx +111 -0
  67. package/src/components/badge/index.ts +2 -0
  68. package/src/components/badge/parts/BadgeIndicator.tsx +166 -0
  69. package/src/components/badge/types.ts +58 -0
  70. package/src/components/badge/utils.ts +24 -0
  71. package/src/components/index.ts +1 -0
  72. package/src/context/ThemeProvider.tsx +10 -10
  73. package/src/theme/define-config.ts +12 -7
  74. package/src/theme/errors.ts +1 -1
  75. package/src/theme/index.ts +6 -8
  76. package/src/theme/registry.ts +15 -23
  77. package/src/theme/resolve-config.ts +88 -95
  78. package/src/theme/runtime.ts +11 -11
  79. package/src/theme/selection-store.ts +9 -9
  80. package/src/theme/types.ts +21 -47
  81. package/src/theme/unistyles-adapter.ts +1 -1
  82. package/src/utils/accent-utils.ts +25 -25
@@ -203,10 +203,10 @@ declare global {
203
203
  namespace TerraUI {
204
204
  /**
205
205
  * Augment to declare app-specific semantic color keys. Declared keys become
206
- * valid in `shared` / `schemes` / accent overrides, `theme.color`, and
206
+ * valid in `shared` / named theme tokens, `theme.color`, and
207
207
  * component color props. Keys must not collide with built-in canonical or
208
208
  * deprecated names. Type augmentation alone cannot prove a value exists at
209
- * runtime — provide every declared color through `shared` or both `schemes`.
209
+ * runtime — provide every declared color through `shared` or each theme's light/dark entries.
210
210
  *
211
211
  * @example
212
212
  * declare global {
@@ -309,7 +309,7 @@ export type ContentColorToken = TextColorToken;
309
309
  */
310
310
  export type ColorToken = keyof ThemeColor | (string & {});
311
311
 
312
- // ─── Configuration / accents ─────────────────────────────────────────────────
312
+ // ─── Configuration / themes ─────────────────────────────────────────────────
313
313
 
314
314
  export type Scheme = "light" | "dark";
315
315
 
@@ -319,46 +319,22 @@ export type Scheme = "light" | "dark";
319
319
  */
320
320
  export type ThemeMode = "system" | "light" | "dark";
321
321
 
322
- /**
323
- * A seed-generated accent with local exceptions. The seed is a starting color
324
- * for the accent family, not a promise that `accent.solid.bg` equals it — pin
325
- * `accent.solid.bg` in `overrides` when an exact fill is required.
326
- */
327
- export interface AccentSeed {
328
- /** Opaque six-digit sRGB hex (`#rrggbb`). Other formats are rejected at configure time. */
322
+ /** Explicit theme tokens plus a seed-generated accent palette. */
323
+ export type ThemeSeed = TerraThemeOverride & {
324
+ /** Opaque six-digit hex color. Explicit `color` values win over generation. */
329
325
  seed: string;
330
- /**
331
- * Flat semantic color patch applied after generation. Within the patch a
332
- * canonical name beats its deprecated alias; across layers an explicit
333
- * override beats every generated value.
334
- */
335
- overrides?: Partial<ThemeColor>;
336
- }
326
+ };
337
327
 
338
- /**
339
- * One scheme's accent input:
340
- * - a color string — equivalent to `{ seed: value }`;
341
- * - `{ seed, overrides }` — generation with explicit exceptions;
342
- * - a full {@link TerraThemeOverride} — skips generation (expert path).
343
- */
344
- export type AccentSchemeInput = string | AccentSeed | TerraThemeOverride;
328
+ /** A seed shorthand, explicit theme tokens, or both via `{ seed, color, ... }`. */
329
+ export type ThemeSchemeInput = string | ThemeSeed | TerraThemeOverride;
345
330
 
346
331
  /**
347
- * A named, runtime-switchable overlay on each scheme. A missing scheme leaves
348
- * that scheme unmodified; the other scheme's seed is never copied implicitly.
332
+ * A complete named light/dark theme. Missing schemes inherit defaults + shared;
333
+ * seeds are never copied from the other scheme.
349
334
  */
350
- export type Accent = Partial<Record<Scheme, AccentSchemeInput>>;
351
-
352
- /** @deprecated Use {@link Accent} — a color string per scheme. */
353
- export type AccentShorthand = Record<Scheme, string>;
335
+ export type NamedTheme = Partial<Record<Scheme, ThemeSchemeInput>>;
354
336
 
355
- /** @deprecated Use {@link Accent} a {@link TerraThemeOverride} per scheme. */
356
- export type AccentOverride = Partial<Record<Scheme, TerraThemeOverride>>;
357
-
358
- /**
359
- * The compatibility output of `normalizeAccent`: per-scheme partial-theme
360
- * overrides generated against the default themes.
361
- */
337
+ /** Output of the legacy normalizeAccent helper. */
362
338
  export interface NormalizedAccent {
363
339
  light: DeepPartial<TerraTheme>;
364
340
  dark: DeepPartial<TerraTheme>;
@@ -474,10 +450,8 @@ export interface ComponentDefaults {
474
450
  export interface TerraConfig {
475
451
  /** Scheme-agnostic token overrides, applied to both light and dark themes. */
476
452
  shared?: TerraThemeOverride;
477
- /** Per-scheme token overrides, applied after `shared`. */
478
- schemes?: { light?: TerraThemeOverride; dark?: TerraThemeOverride };
479
- /** Runtime-switchable named overrides (hue shorthand or full partial). */
480
- accents?: Record<string, Accent>;
453
+ /** Named light/dark themes applied over defaults + shared. */
454
+ themes?: Record<string, NamedTheme>;
481
455
  /**
482
456
  * App-provided icon overrides. Semantic icons (`navigation.*`, `status.*`)
483
457
  * fall back to the built-in defaults when omitted; app icons (`add`, etc.)
@@ -490,8 +464,8 @@ export interface TerraConfig {
490
464
  * `resizeMode`. Wrap third-party components to match `TerraImageProps`.
491
465
  */
492
466
  image?: TerraImageComponent;
493
- /** Name of the accent (from `accents`) to apply by default. */
494
- defaultAccent?: string;
467
+ /** Name of the theme (from `themes`) to apply by default. */
468
+ defaultTheme?: string;
495
469
  /** Per-component default props (e.g. `{ button: { radius: 'full' } }`). */
496
470
  components?: ComponentDefaults;
497
471
  /**
@@ -507,13 +481,13 @@ export interface TerraConfig {
507
481
  }
508
482
 
509
483
  /** The subset of {@link TerraConfig} that affects resolved theme tokens. */
510
- export type TerraThemeInput = Pick<TerraConfig, "shared" | "schemes" | "accents" | "defaultAccent">;
484
+ export type TerraThemeInput = Pick<TerraConfig, "shared" | "themes" | "defaultTheme">;
511
485
 
512
486
  /** Options for pure theme creation. */
513
487
  export interface CreateTerraThemesOptions {
514
488
  /**
515
- * Accent to overlay. Omitted → `defaultAccent`; `null` → the base themes
516
- * with no accent. An unknown name throws.
489
+ * Named theme to select. Omitted → `defaultTheme`; `null` → the base themes
490
+ * with no named theme. An unknown name throws.
517
491
  */
518
- accent?: string | null;
492
+ theme?: string | null;
519
493
  }
@@ -52,7 +52,7 @@ export function configureUnistyles({
52
52
  * runtime holds the new `light` theme and the previous `dark` theme. Callers
53
53
  * publish registry/selection state only after this returns, so on a throw Terra
54
54
  * still reports the previous selection; calling the same command again with the
55
- * previous selection (e.g. `applyAccent(getCurrentAccent() ?? null)`) rewrites
55
+ * previous selection (e.g. `setTheme(getCurrentTheme() ?? null)`) rewrites
56
56
  * both themes and restores consistency. No automatic rollback is attempted.
57
57
  */
58
58
  export function updateThemes(themes: Record<Scheme, TerraTheme>): void {
@@ -1,13 +1,13 @@
1
1
  import { normalizeTokenOverride } from "#theme/legacy-tokens";
2
- import { normalizeAccentScheme } from "#theme/resolve-config";
2
+ import { normalizeThemeScheme } from "#theme/resolve-config";
3
3
  import { defaultDarkTheme, defaultLightTheme } from "#theme/theme";
4
4
  import type {
5
- Accent,
6
- AccentSchemeInput,
5
+ NamedTheme,
7
6
  NormalizedAccent,
8
7
  Scheme,
9
8
  TerraTheme,
10
- ThemeColor,
9
+ TerraThemeOverride,
10
+ ThemeSchemeInput,
11
11
  } from "#theme/types";
12
12
  import {
13
13
  ACCENT_SURFACE_ROLES,
@@ -30,31 +30,32 @@ export function defaultAccentContext(scheme: Scheme): AccentGenerationContext {
30
30
  }
31
31
 
32
32
  /**
33
- * Generated accent colours for `seed` with `overrides` applied last. Within
34
- * the override patch canonical names beat their legacy aliases, while an
35
- * alias-only key still beats the generated canonical value.
33
+ * Generate a palette using the named theme's ordinary surface overrides. The
34
+ * rest of the patch passes through as authored, matching the unseeded branch —
35
+ * so `spacing.base` / `radius.base` stay pseudo-tokens here; only
36
+ * `applyThemeLayer` expands them into a scale.
36
37
  */
37
38
  function seedToColorPatch(
38
39
  seed: string,
39
- overrides: Partial<ThemeColor> | undefined,
40
+ patch: TerraThemeOverride | undefined,
40
41
  scheme: Scheme
41
42
  ): DeepPartial<TerraTheme> {
42
- const generated = generateAccentColors(seed, defaultAccentContext(scheme)).colors;
43
- const color: Record<string, string> = { ...generated };
44
- const normalized = normalizeTokenOverride({ color: overrides })?.color;
45
- if (normalized) {
46
- for (const [key, value] of Object.entries(normalized)) {
47
- if (value !== undefined) color[key] = value as string;
48
- }
43
+ const normalized = normalizeTokenOverride(patch);
44
+ const context = defaultAccentContext(scheme);
45
+ for (const role of ACCENT_SURFACE_ROLES) {
46
+ const value = normalized?.color?.[role];
47
+ if (value !== undefined) context.surfaces[role] = value;
49
48
  }
50
- return { color } as unknown as DeepPartial<TerraTheme>;
49
+ context.pressedOpacity = normalized?.opacity?.pressed ?? context.pressedOpacity;
50
+ const generated = generateAccentColors(seed, context).colors;
51
+ return { ...normalized, color: { ...generated, ...normalized?.color } } as DeepPartial<TerraTheme>;
51
52
  }
52
53
 
53
- function normalizeSchemeInput(input: AccentSchemeInput | undefined, scheme: Scheme): DeepPartial<TerraTheme> {
54
- const normalized = normalizeAccentScheme(input, `accents.<accent>.${scheme}`);
54
+ function normalizeSchemeInput(input: ThemeSchemeInput | undefined, scheme: Scheme): DeepPartial<TerraTheme> {
55
+ const normalized = normalizeThemeScheme(input, `themes.<name>.${scheme}`);
55
56
  if (normalized.kind === "none") return {};
56
57
  if (normalized.kind === "seed") {
57
- return seedToColorPatch(normalized.seed, normalized.overrides, scheme);
58
+ return seedToColorPatch(normalized.seed, normalized.patch, scheme);
58
59
  }
59
60
  // Preserve the compatibility helper's identity contract for full patches;
60
61
  // the resolver itself uses the sanitized copy in `normalized.patch`.
@@ -62,13 +63,12 @@ function normalizeSchemeInput(input: AccentSchemeInput | undefined, scheme: Sche
62
63
  }
63
64
 
64
65
  /**
65
- * Compatibility wrapper: normalizes any accent input into per-scheme
66
- * partial-theme overrides. Strings and `{ seed, overrides }` are generated
67
- * against the DEFAULT themes' surfaces and pressed opacity (the resolver
68
- * pipeline uses the actual resolved surfaces instead); full theme patches
69
- * pass through unchanged. Pure and independent of the registry.
66
+ * @deprecated Prefer createTerraThemes for complete theme resolution.
67
+ * Generates per-scheme patches without shared config. Explicit unseeded patches
68
+ * pass through unchanged; seeded entries generate against their own surface and
69
+ * color tokens and carry the remainder of the patch through unresolved.
70
70
  */
71
- export function normalizeAccent(accent: Accent): NormalizedAccent {
71
+ export function normalizeAccent(accent: NamedTheme): NormalizedAccent {
72
72
  return {
73
73
  light: normalizeSchemeInput(accent.light, "light"),
74
74
  dark: normalizeSchemeInput(accent.dark, "dark"),