@hjmds/react 1.14.0 → 1.16.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 (91) hide show
  1. package/README.md +5 -0
  2. package/dist/asset.d.ts.map +1 -1
  3. package/dist/asset.js +4 -1
  4. package/dist/asset.js.map +1 -1
  5. package/dist/clipboard.d.ts.map +1 -1
  6. package/dist/clipboard.js +39 -5
  7. package/dist/clipboard.js.map +1 -1
  8. package/dist/code-block.d.ts.map +1 -1
  9. package/dist/code-block.js +3 -1
  10. package/dist/code-block.js.map +1 -1
  11. package/dist/collapsible.d.ts +4 -0
  12. package/dist/collapsible.d.ts.map +1 -1
  13. package/dist/collapsible.js +4 -4
  14. package/dist/collapsible.js.map +1 -1
  15. package/dist/collection-rail.d.ts +24 -0
  16. package/dist/collection-rail.d.ts.map +1 -0
  17. package/dist/collection-rail.js +109 -0
  18. package/dist/collection-rail.js.map +1 -0
  19. package/dist/command-palette.d.ts.map +1 -1
  20. package/dist/command-palette.js +3 -1
  21. package/dist/command-palette.js.map +1 -1
  22. package/dist/content-transition.d.ts +1 -1
  23. package/dist/content-transition.d.ts.map +1 -1
  24. package/dist/content-transition.js +3 -2
  25. package/dist/content-transition.js.map +1 -1
  26. package/dist/context-menu.d.ts.map +1 -1
  27. package/dist/context-menu.js +3 -1
  28. package/dist/context-menu.js.map +1 -1
  29. package/dist/design-profile.d.ts +18 -0
  30. package/dist/design-profile.d.ts.map +1 -0
  31. package/dist/design-profile.js +27 -0
  32. package/dist/design-profile.js.map +1 -0
  33. package/dist/effect-surface.d.ts.map +1 -1
  34. package/dist/effect-surface.js +4 -3
  35. package/dist/effect-surface.js.map +1 -1
  36. package/dist/evidence.d.ts +1 -1
  37. package/dist/evidence.js +1 -1
  38. package/dist/evidence.js.map +1 -1
  39. package/dist/floating-action-button.d.ts +1 -1
  40. package/dist/floating-action-button.d.ts.map +1 -1
  41. package/dist/floating-action-button.js +4 -1
  42. package/dist/floating-action-button.js.map +1 -1
  43. package/dist/heading.d.ts.map +1 -1
  44. package/dist/heading.js +3 -1
  45. package/dist/heading.js.map +1 -1
  46. package/dist/internal.d.ts +51 -0
  47. package/dist/internal.d.ts.map +1 -1
  48. package/dist/internal.js +7 -1
  49. package/dist/internal.js.map +1 -1
  50. package/dist/layout.d.ts +5 -1
  51. package/dist/layout.d.ts.map +1 -1
  52. package/dist/layout.js +11 -3
  53. package/dist/layout.js.map +1 -1
  54. package/dist/menubar.d.ts.map +1 -1
  55. package/dist/menubar.js +5 -2
  56. package/dist/menubar.js.map +1 -1
  57. package/dist/navigation.d.ts.map +1 -1
  58. package/dist/navigation.js +30 -9
  59. package/dist/navigation.js.map +1 -1
  60. package/dist/popover.d.ts.map +1 -1
  61. package/dist/popover.js +3 -1
  62. package/dist/popover.js.map +1 -1
  63. package/dist/provider.d.ts +4 -0
  64. package/dist/provider.d.ts.map +1 -1
  65. package/dist/provider.js +8 -2
  66. package/dist/provider.js.map +1 -1
  67. package/dist/screens.d.ts +7 -2
  68. package/dist/screens.d.ts.map +1 -1
  69. package/dist/screens.js +20 -7
  70. package/dist/screens.js.map +1 -1
  71. package/dist/selection.d.ts.map +1 -1
  72. package/dist/selection.js +4 -1
  73. package/dist/selection.js.map +1 -1
  74. package/dist/sidebar.d.ts.map +1 -1
  75. package/dist/sidebar.js +2 -1
  76. package/dist/sidebar.js.map +1 -1
  77. package/dist/skip-nav.d.ts.map +1 -1
  78. package/dist/skip-nav.js +2 -1
  79. package/dist/skip-nav.js.map +1 -1
  80. package/dist/styles.css +42 -8
  81. package/dist/styles.layered.css +42 -8
  82. package/dist/theme.d.ts.map +1 -1
  83. package/dist/theme.js +37 -8
  84. package/dist/theme.js.map +1 -1
  85. package/dist/toggle-group.d.ts.map +1 -1
  86. package/dist/toggle-group.js +3 -1
  87. package/dist/toggle-group.js.map +1 -1
  88. package/dist/top.d.ts.map +1 -1
  89. package/dist/top.js +9 -4
  90. package/dist/top.js.map +1 -1
  91. package/package.json +13 -3
@@ -45,6 +45,13 @@
45
45
  overflow-wrap: anywhere;
46
46
  }
47
47
 
48
+ /* Family role changes the type voice, never the document level or control state. */
49
+ .hjm-root :where(h1, h2, h3, h4, h5, h6) { font-family: var(--hjm-font-family-display, var(--hjm-font-family-ui, inherit)); }
50
+ .hjm-text[data-font-role="ui"] { font-family: var(--hjm-font-family-ui, inherit); }
51
+ .hjm-text[data-font-role="display"] { font-family: var(--hjm-font-family-display, var(--hjm-font-family-ui, inherit)); }
52
+ .hjm-text[data-font-role="reading"] { font-family: var(--hjm-font-family-reading, var(--hjm-font-family-ui, inherit)); }
53
+ .hjm-text[data-font-role="code"] { font-family: var(--hjm-font-family-code, monospace); }
54
+
48
55
  .hjm-text[data-variant="caption"] { font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); }
49
56
  .hjm-text[data-variant="label"] { font-size: var(--hjm-type-label-size); line-height: var(--hjm-type-label-line-height); }
50
57
  .hjm-text[data-variant="body"] { font-size: var(--hjm-type-body-size); line-height: var(--hjm-type-body-line-height); }
@@ -73,17 +80,31 @@
73
80
  border: 1px solid transparent;
74
81
  border-radius: var(--hjm-radius-lg);
75
82
  background: var(--hjm-color-bg);
83
+ box-shadow: var(--hjm-surface-inset-shadow, none);
76
84
  }
77
85
  /* A child image would otherwise spill past the rounded corner. An elevated tone
78
86
  opts out because clipping cuts off its own shadow. */
79
87
  .hjm-surface[data-clips="true"] { overflow: hidden; }
80
- .hjm-surface[data-tone="raised"] { background: var(--hjm-color-bg); box-shadow: var(--hjm-shadow-floating); }
88
+ .hjm-surface[data-tone="raised"] { background: var(--hjm-color-bg); box-shadow: var(--hjm-surface-raised-shadow, var(--hjm-shadow-floating)); }
81
89
  .hjm-surface[data-tone="accent"] { background: var(--hjm-color-bg); }
82
90
  .hjm-surface[data-tone="sunken"] { background: var(--hjm-color-bg); }
83
91
  .hjm-surface[data-tone="subtle"] { background: var(--hjm-color-bg); }
84
92
  .hjm-surface[data-bordered="true"] { border-color: var(--hjm-color-border); }
85
93
  .hjm-surface[data-tone="accent"][data-bordered="true"] { border-color: color-mix(in srgb, var(--hjm-color-primary) 30%, transparent); }
86
94
 
95
+ /* Whole-surface material belongs to Surface/Card; ProgressiveBlur remains an
96
+ edge/scroll mask. Feature detection and the OS preference retain opaque fill. */
97
+ @supports (background: color-mix(in srgb, white 90%, transparent)) and ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
98
+ .hjm-surface[data-tone] {
99
+ background: color-mix(in srgb, var(--hjm-color-bg) calc(var(--hjm-surface-fill-opacity, 1) * 100%), transparent);
100
+ backdrop-filter: var(--hjm-surface-blur, none);
101
+ -webkit-backdrop-filter: var(--hjm-surface-blur, none);
102
+ }
103
+ }
104
+ @media (prefers-reduced-transparency: reduce) {
105
+ .hjm-surface[data-tone] { background: var(--hjm-color-bg); backdrop-filter: none; -webkit-backdrop-filter: none; }
106
+ }
107
+
87
108
  .hjm-stack,
88
109
  .hjm-grid { min-inline-size: 0; }
89
110
  .hjm-grid > * { min-inline-size: 0; }
@@ -195,6 +216,8 @@
195
216
  }
196
217
  .hjm-button,
197
218
  .hjm-icon-button {
219
+ /* Controls keep ui even when placed inside a reading-font text container. */
220
+ font-family: var(--hjm-font-family-ui, inherit);
198
221
  display: inline-flex;
199
222
  align-items: center;
200
223
  justify-content: center;
@@ -296,7 +319,8 @@
296
319
 
297
320
  /* Input interiors use the theme canvas (white in light mode), not tinted
298
321
  surfaces. Focus and selection still use blue borders and compact indicators. */
299
- .hjm-field { display: grid; gap: var(--hjm-space-xs); min-inline-size: 0; }
322
+ .hjm-field {
323
+ font-family: var(--hjm-font-family-ui, inherit); display: grid; gap: var(--hjm-space-xs); min-inline-size: 0; }
300
324
  .hjm-field__label { color: var(--hjm-color-text-body); font-weight: var(--hjm-font-weight-semibold); }
301
325
  .hjm-field__control {
302
326
  display: flex;
@@ -1681,6 +1705,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1681
1705
  */
1682
1706
  .hjm-heading {
1683
1707
  margin: 0;
1708
+ font-family: var(--hjm-font-family-display, var(--hjm-font-family-ui, inherit));
1684
1709
  color: var(--hjm-color-text);
1685
1710
  font-size: calc(var(--hjm-heading-size) * var(--hjm-text-scale, 1));
1686
1711
  line-height: calc(var(--hjm-heading-line-height) * var(--hjm-text-scale, 1));
@@ -2503,8 +2528,8 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2503
2528
  .hjm-toast[data-tone="warning"] .hjm-toast__icon { color: var(--hjm-toast-accent-warning); background: var(--hjm-toast-badge-warning); }
2504
2529
  .hjm-toast[data-tone="danger"] .hjm-toast__icon { color: var(--hjm-toast-accent-danger); background: var(--hjm-toast-badge-danger); }
2505
2530
  .hjm-toast__content { grid-column: 2; grid-row: 1; align-self: center; min-inline-size: 0; display: grid; gap: var(--hjm-space-xxs); padding-block: var(--hjm-space-xxs); overflow-wrap: anywhere; word-break: keep-all; }
2506
- .hjm-toast__title { font-weight: var(--hjm-font-weight-bold); line-height: 1.35; }
2507
- .hjm-toast__description { color: var(--hjm-toast-description-color); line-height: 1.45; }
2531
+ .hjm-toast__title { font-weight: var(--hjm-font-weight-bold); line-height: var(--hjm-toast-title-line-height, 1.35); }
2532
+ .hjm-toast__description { color: var(--hjm-toast-description-color); line-height: var(--hjm-toast-description-line-height, 1.45); }
2508
2533
  .hjm-toast__close { grid-column: 3; grid-row: 1; align-self: start; display: grid; place-items: center; inline-size: var(--hjm-control-min-touch-target); min-block-size: var(--hjm-control-min-touch-target); margin-block-start: calc(-1 * var(--hjm-space-xxs)); border: 0; border-radius: 50%; color: var(--hjm-color-text-muted); background: transparent; cursor: pointer; }
2509
2534
  .hjm-toast__close:hover { color: var(--hjm-color-text); }
2510
2535
  .hjm-toast__action { grid-column: 2 / -1; grid-row: 2; justify-self: end; margin-inline-end: var(--hjm-space-xs); min-block-size: var(--hjm-control-min-touch-target); max-inline-size: 100%; padding-inline: var(--hjm-space-md); border: 0; border-radius: 999px; color: var(--hjm-toast-action-color); background: var(--hjm-toast-action-background); font: inherit; font-weight: var(--hjm-font-weight-bold); overflow-wrap: anywhere; text-align: center; cursor: pointer; }
@@ -2584,7 +2609,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2584
2609
  .hjm-top-bar[data-large-text="true"] { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
2585
2610
  .hjm-top-bar[data-large-text="true"] .hjm-top-bar__title { grid-column: 1 / -1; grid-row: 2; padding-block: var(--hjm-space-xs); text-align: start; }
2586
2611
  .hjm-top-bar[data-large-text="true"] .hjm-top-bar__trailing { grid-column: 2; grid-row: 1; }
2587
- .hjm-bottom-cta { display: grid; gap: var(--hjm-bottom-cta-gap); min-block-size: var(--hjm-bottom-cta-min-height); padding: var(--hjm-bottom-cta-padding-top) var(--hjm-bottom-cta-padding-inline) max(var(--hjm-bottom-cta-padding-bottom), env(safe-area-inset-bottom, 0px), var(--hjm-bottom-cta-safe-area)); border-block-start: 1px solid var(--hjm-color-border); background: var(--hjm-color-bg); }
2612
+ .hjm-bottom-cta { display: grid; gap: var(--hjm-bottom-cta-gap); min-block-size: var(--hjm-bottom-cta-min-height); padding: var(--hjm-bottom-cta-padding-top) var(--hjm-bottom-cta-padding-inline) max(var(--hjm-bottom-cta-padding-bottom), env(safe-area-inset-bottom, 0px), var(--hjm-bottom-cta-safe-area)); border-block-start: 1px solid var(--hjm-color-border); background: var(--hjm-color-bg); box-shadow: var(--hjm-bottom-cta-shadow, none); }
2588
2613
  .hjm-bottom-cta[data-position="sticky"] { position: sticky; inset-block-end: 0; z-index: var(--hjm-layer-sticky); }
2589
2614
  .hjm-bottom-cta__description { margin: 0; font-size: var(--hjm-type-caption-size); line-height: var(--hjm-type-caption-line-height); color: var(--hjm-color-text-muted); overflow-wrap: anywhere; }
2590
2615
  .hjm-bottom-cta__actions { display: flex; flex-wrap: wrap; gap: var(--hjm-bottom-cta-gap); }
@@ -2771,9 +2796,10 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2771
2796
  }
2772
2797
 
2773
2798
  /* Measured elastic indicator stays beneath labels; no filter touches text or hit targets. */
2774
- .hjm-tabs[data-appearance="gooey"] .hjm-tabs__list { position: relative; }
2775
- .hjm-tabs[data-appearance="gooey"] .hjm-tabs__tab[data-state="selected"]::after { display: none; }
2776
- .hjm-tabs__gooey { position: absolute; bottom: 0; height: 6px; border-radius: var(--hjm-radius-full); background: var(--hjm-color-content-brand); pointer-events: none; }
2799
+ .hjm-tabs:is([data-appearance="gooey"], [data-appearance="slide"]) .hjm-tabs__list { position: relative; }
2800
+ .hjm-tabs:is([data-appearance="gooey"], [data-appearance="slide"]) .hjm-tabs__tab[data-state="selected"]::after { display: none; }
2801
+ .hjm-tabs__indicator { position: absolute; bottom: 0; height: 2px; border-radius: var(--hjm-radius-full); background: var(--hjm-color-content-brand); pointer-events: none; }
2802
+ .hjm-tabs__gooey { height: 6px; }
2777
2803
 
2778
2804
  /* Capsule destinations retain route/link semantics. At larger text sizes we show
2779
2805
  every label vertically instead of shrinking type to mimic the reference. */
@@ -2947,4 +2973,12 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2947
2973
  [data-motion="reduced"] .hjm-segmented__highlight { transition: none; }
2948
2974
  @media (prefers-reduced-motion: reduce) { .hjm-segmented__highlight { transition: none; } }
2949
2975
 
2976
+ /* Explicit hidden rules beat the trigger's flex display; retained tools must leave focus and speech. */
2977
+ .hjm-collapsible__trigger[hidden], .hjm-collapsible__content[hidden] { display: none; }
2978
+ /* The enclosing Surface owns its color/elevation; this layer contributes decoration only. */
2979
+ .hjm-profile-card-effect { background: transparent !important; }
2980
+ /* Profile header columns cannot keep the row's minimum flex-basis as a tall empty spacer. */
2981
+ .hjm-screen[data-presentation="editorial"] .hjm-screen__heading,
2982
+ .hjm-screen[data-presentation="landscape"] .hjm-screen__heading { flex: 0 1 auto; inline-size: 100%; }
2983
+
2950
2984
  }
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAgBnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAmB7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CAuJf"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAgBnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAmB7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CAmLf"}
package/dist/theme.js CHANGED
@@ -1,4 +1,5 @@
1
- import { backdrop, control, easing, fontFamily, fontWeight, motion, layer, radius, shadow, spacing, stroke, typography, } from "@hjmds/design-contracts/foundations";
1
+ import { resolveSurfaceFillOpacity } from "@hjmds/design-contracts/palette-contrast";
2
+ import { backdrop, control, easing, fontFamily, resolveFontFamilyStack, fontWeight, motion, layer, radius, shadow, spacing, stroke, typography, } from "@hjmds/design-contracts/foundations";
2
3
  import { resolveColorReference } from "@hjmds/design-contracts/color-references";
3
4
  import { focusIndicatorContract } from "@hjmds/design-contracts/contracts";
4
5
  import { visibleControlHeight, } from "@hjmds/design-contracts/components/design-system-provider";
@@ -8,16 +9,17 @@ function kebab(value) {
8
9
  return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
9
10
  }
10
11
  // RN shadow token -> CSS; blur = radius, as react-native-web maps it.
11
- function shadowCss(token) {
12
+ function shadowCss(token, offsetX = 0) {
12
13
  const hex = token.color.replace("#", "");
13
14
  const [r, g, b] = [0, 2, 4].map((start) => Number.parseInt(hex.slice(start, start + 2), 16));
14
- return `0 ${token.offsetY}px ${token.radius}px rgb(${r} ${g} ${b} / ${Math.round(token.opacity * 100)}%)`;
15
+ return `${offsetX}px ${token.offsetY}px ${token.radius}px rgb(${r} ${g} ${b} / ${Math.round(token.opacity * 100)}%)`;
15
16
  }
16
17
  function rem(value) {
17
18
  return `${Number((value / 16).toFixed(5))}rem`;
18
19
  }
19
20
  export function createHjmThemeStyle(value) {
20
21
  const { environment, palette } = value;
22
+ const profileTokens = value.designProfile?.tokens;
21
23
  const style = {
22
24
  "--hjm-backdrop-modal": `color-mix(in srgb, ${backdrop.modal.color} ${backdrop.modal.opacity * 100}%, transparent)`,
23
25
  "--hjm-text-scale": environment.textScale,
@@ -38,10 +40,10 @@ export function createHjmThemeStyle(value) {
38
40
  for (const [name, value] of Object.entries(spacing)) {
39
41
  style[`--hjm-space-${kebab(name)}`] = `${value}px`;
40
42
  }
41
- for (const [name, value] of Object.entries(radius)) {
43
+ for (const [name, value] of Object.entries(profileTokens?.radius ?? radius)) {
42
44
  style[`--hjm-radius-${kebab(name)}`] = `${value}px`;
43
45
  }
44
- for (const [name, value] of Object.entries(typography)) {
46
+ for (const [name, value] of Object.entries(profileTokens?.typography ?? typography)) {
45
47
  style[`--hjm-type-${kebab(name)}-size`] =
46
48
  `calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;
47
49
  style[`--hjm-type-${kebab(name)}-line-height`] =
@@ -56,7 +58,12 @@ export function createHjmThemeStyle(value) {
56
58
  ? "0ms"
57
59
  : `${value}ms`;
58
60
  }
59
- style["--hjm-font-family-ui"] = fontFamily.ui.join(", ");
61
+ style["--hjm-font-family-ui"] = (profileTokens?.fontFamily.ui ?? fontFamily.ui).join(", ");
62
+ style["--hjm-font-family-code"] = (profileTokens?.fontFamily.code ?? fontFamily.code).join(", ");
63
+ // Roles resolve from the nearest Provider, including portal/nested reset contexts.
64
+ for (const role of ["display", "reading"]) {
65
+ style[`--hjm-font-family-${role}`] = resolveFontFamilyStack(profileTokens?.fontFamily ?? fontFamily, role).join(", ");
66
+ }
60
67
  for (const [name, value] of Object.entries(stroke)) {
61
68
  style[`--hjm-stroke-${kebab(name)}`] = `${value}px`;
62
69
  }
@@ -96,16 +103,38 @@ export function createHjmThemeStyle(value) {
96
103
  for (const [name, value] of Object.entries(layer)) {
97
104
  style[`--hjm-layer-${kebab(name)}`] = value;
98
105
  }
99
- for (const [name, token] of Object.entries(shadow)) {
106
+ for (const [name, token] of Object.entries(profileTokens?.shadow ?? shadow)) {
100
107
  style[`--hjm-shadow-${kebab(name)}`] = shadowCss(token);
101
108
  }
109
+ const surfaceMaterial = value.designProfile?.material.surface;
110
+ // Defaults are emitted on every Provider, so a nested neutral profile clears
111
+ // inherited glass/clay. Unsupported transparency remains an opaque CSS fill.
112
+ style["--hjm-surface-blur"] = surfaceMaterial?.blurStrength ? `blur(${surfaceMaterial.blurStrength * 32}px)` : "none";
113
+ style["--hjm-surface-fill-opacity"] = surfaceMaterial?.blurStrength ? resolveSurfaceFillOpacity(surfaceMaterial.fillOpacity, palette.theme) : 1;
114
+ const insetShadow = surfaceMaterial?.insetShadows.length
115
+ ? surfaceMaterial.insetShadows.map(token => `inset ${shadowCss(token, token.offsetX)}`).join(", ")
116
+ : "";
117
+ style["--hjm-surface-inset-shadow"] = insetShadow || "none";
118
+ style["--hjm-surface-raised-shadow"] = shadowCss(profileTokens?.shadow.floating ?? shadow.floating) + (insetShadow ? `, ${insetShadow}` : "");
119
+ // BottomCTA overlaps content above it (bottomCtaRecipe rationale). Profile
120
+ // strength is shared, but its shadow must cast upward rather than behind the
121
+ // footer; preserve the stylesheet-only legacy path when no profile is supplied.
122
+ style["--hjm-bottom-cta-shadow"] = profileTokens
123
+ ? shadowCss({ ...profileTokens.shadow.floating, offsetY: -Math.abs(profileTokens.shadow.floating.offsetY) })
124
+ : "none";
125
+ // Toast body metrics follow a selected profile; emit legacy values when no profile is selected
126
+ // instead of inheriting a parent profile or changing standalone presentation.
127
+ style["--hjm-toast-title-line-height"] = profileTokens ? "var(--hjm-type-body-line-height)" : "1.35";
128
+ style["--hjm-toast-description-line-height"] = profileTokens ? "var(--hjm-type-body-line-height)" : "1.45";
102
129
  // Overlay chrome and sizes come from the recipes Native reads (1.5.0).
103
130
  for (const [name, chrome] of [["dialog", dialogRecipe.content], ["sheet", sheetRecipe.content], ["toast", toastRecipe.surface]]) {
104
131
  style[`--hjm-${name}-background`] = resolveColorReference(chrome.background, palette);
105
132
  style[`--hjm-${name}-border`] = resolveColorReference(chrome.border, palette);
106
133
  style[`--hjm-${name}-border-width`] = `${chrome.borderWidth}px`;
107
134
  style[`--hjm-${name}-radius`] = `var(--hjm-radius-${chrome.radius})`;
108
- style[`--hjm-${name}-shadow`] = shadowCss(chrome.shadow);
135
+ // Recipes select the floating role. Resolve its value from the profile so
136
+ // dialogs, sheets and toasts cannot retain neutral shadows after a theme switch.
137
+ style[`--hjm-${name}-shadow`] = shadowCss(profileTokens?.shadow.floating ?? chrome.shadow);
109
138
  }
110
139
  style["--hjm-sheet-max-height"] = `${sheetRecipe.content.maxHeightRatio * 100}dvh`;
111
140
  style["--hjm-sheet-max-width"] = `${sheetRecipe.web.maxWidth}px`;
package/dist/theme.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,MAAM,EACN,UAAU,EACV,UAAU,EACV,MAAM,EACN,KAAK,EACL,MAAM,EACN,MAAM,EACN,OAAO,EACP,MAAM,EACN,UAAU,GACX,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAC3E,OAAO,EACL,oBAAoB,GAErB,MAAM,2DAA2D,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACjF,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,YAAY,EACZ,aAAa,EACb,UAAU,EACV,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,cAAc,EACd,aAAa,EACb,YAAY,EACZ,WAAW,GACZ,MAAM,iCAAiC,CAAC;AAMzC,SAAS,KAAK,CAAC,KAAa;IAC1B,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACzE,CAAC;AAID,sEAAsE;AACtE,SAAS,SAAS,CAAC,KAAkB;IACnC,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IAC7F,OAAO,KAAK,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC;AAC5G,CAAC;AAED,SAAS,GAAG,CAAC,KAAa;IACxB,OAAO,GAAG,MAAM,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAgC;IAEhC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IACvC,MAAM,KAAK,GAAkB;QAC3B,sBAAsB,EAAE,sBAAsB,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,iBAAiB;QACnH,kBAAkB,EAAE,WAAW,CAAC,SAAS;QACzC,oBAAoB,EAAE,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,WAAW,EAAE,WAAW,CAAC,KAAK;QAC9B,eAAe,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE;QACjC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI;KAC1B,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,KAAK,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;QAClE,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IAC/C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACtE,KAAK,CAAC,qBAAqB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IACpD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,KAAK,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC;IACrD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC;IACtD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,KAAK,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC;YACrC,QAAQ,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QACzD,KAAK,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC;YAC5C,QAAQ,GAAG,CAAC,KAAK,CAAC,UAAU,CAAC,2BAA2B,CAAC;QAC3D,KAAK,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC;IAC/D,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,KAAK,CAAC,qBAAqB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IACpD,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,WAAW,CAAC,aAAa;YAC9D,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACzD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,KAAK,IAAI,CAAC;IACtD,CAAC;IACD,oEAAoE;IACpE,KAAK,CAAC,mBAAmB,CAAC,GAAG,qBAAqB,CAAC,sBAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC1F,KAAK,CAAC,mBAAmB,CAAC,GAAG,GAAG,sBAAsB,CAAC,KAAK,IAAI,CAAC;IACjE,KAAK,CAAC,oBAAoB,CAAC,GAAG,GAAG,sBAAsB,CAAC,MAAM,IAAI,CAAC;IACnE,KAAK,CAAC,4CAA4C,CAAC,GAAG,qBAAqB,CACzE,sBAAsB,CAAC,MAAM,CAAC,iBAAiB,EAC/C,OAAO,CACR,CAAC;IACF,0EAA0E;IAC1E,oDAAoD;IACpD,KAAK,CAAC,oBAAoB,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACrD,KAAK,CAAC,6BAA6B,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;QAC/D,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9D,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAChE,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9D,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC9D,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,GAAG,CAC/C,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAC5C,CAAC;IACJ,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAClE,KAAK,CAAC,kBAAkB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC9E,KAAK,CAAC,kBAAkB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC9E,KAAK,CAAC,kBAAkB,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QACrF,KAAK,CAAC,kBAAkB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IACpF,CAAC;IACD,yEAAyE;IACzE,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,aAAa,GAAG,MAAM,CAAC,cAAc,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9D,KAAK,CAAC,4BAA4B,CAAC;QACjC,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC;IACpD,KAAK,CAAC,yBAAyB,CAAC,GAAG,GAAG,cAAc,CAAC,SAAS,CAAC,QAAQ,IAAI,CAAC;IAC5E,KAAK,CAAC,uBAAuB,CAAC,GAAG,gBAAgB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC7E,KAAK,CAAC,6BAA6B,CAAC,GAAG,cAAc,CAAC,SAAS,CAAC,WAAW,CAAC;IAC5E,KAAK,CAAC,2BAA2B,CAAC,GAAG,cAAc,CAAC,SAAS,CAAC,SAAS,CAAC;IACxE,4EAA4E;IAC5E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,KAAK,CAAC,eAAe,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;IAC9C,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACnD,KAAK,CAAC,gBAAgB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;IACD,uEAAuE;IACvE,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,CAAU,EAAE,CAAC;QACzI,KAAK,CAAC,SAAS,IAAI,aAAa,CAAC,GAAG,qBAAqB,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACtF,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,GAAG,qBAAqB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9E,KAAK,CAAC,SAAS,IAAI,eAAe,CAAC,GAAG,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC;QAChE,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,GAAG,oBAAoB,MAAM,CAAC,MAAM,GAAG,CAAC;QACrE,KAAK,CAAC,SAAS,IAAI,SAAS,CAAC,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3D,CAAC;IACD,KAAK,CAAC,wBAAwB,CAAC,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,cAAc,GAAG,GAAG,KAAK,CAAC;IACnF,KAAK,CAAC,uBAAuB,CAAC,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC;IACjE,KAAK,CAAC,0BAA0B,CAAC,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC;IACpE,KAAK,CAAC,2BAA2B,CAAC,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC;IACtE,KAAK,CAAC,0BAA0B,CAAC,GAAG,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7F,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9D,IAAI,KAAK,KAAK,IAAI;YAAE,KAAK,CAAC,oBAAoB,IAAI,EAAE,CAAC,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,CAAC;IAC9E,CAAC;IACD,sGAAsG;IACtG,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;QACjE,KAAK,CAAC,sBAAsB,IAAI,EAAE,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtF,KAAK,CAAC,qBAAqB,IAAI,EAAE,CAAC,GAAG,qBAAqB,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACtF,CAAC;IACD,KAAK,CAAC,wBAAwB,CAAC,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC;IACxE,KAAK,CAAC,+BAA+B,CAAC,GAAG,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvG,KAAK,CAAC,0BAA0B,CAAC,GAAG,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC7F,KAAK,CAAC,+BAA+B,CAAC,GAAG,qBAAqB,CAAC,WAAW,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACvG,MAAM,SAAS,GAAG,WAAW,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;IAClD,KAAK,CAAC,2BAA2B,CAAC,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,QAAQ,IAAI,CAAC;IACnG,KAAK,CAAC,yBAAyB,CAAC,GAAG,gBAAgB,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;IAC1F,sGAAsG;IACtG,oGAAoG;IACpG,iEAAiE;IACjE,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;QACnE,KAAK,CAAC,8BAA8B,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,iBAAiB,IAAI,CAAC;QAC5E,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;QAC1D,KAAK,CAAC,4BAA4B,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,aAAa,IAAI,CAAC;QACtE,KAAK,CAAC,iCAAiC,IAAI,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,YAAY,IAAI,CAAC;IAC5E,CAAC;IACD,KAAK,CAAC,yBAAyB,CAAC,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC;IACzE,KAAK,CAAC,uBAAuB,CAAC,GAAG,GAAG,aAAa,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC;IACtE,uHAAuH;IACvH,KAAK,CAAC,oBAAoB,CAAC,GAAG,GAAG,UAAU,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC;IAChE,KAAK,CAAC,8BAA8B,CAAC,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC;IAC5E,KAAK,CAAC,gCAAgC,CAAC,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC;IAChF,KAAK,CAAC,iCAAiC,CAAC,GAAG,GAAG,aAAa,CAAC,WAAW,CAAC,gBAAgB,IAAI,CAAC;IAC7F,KAAK,CAAC,8BAA8B,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC;IACrE,KAAK,CAAC,+BAA+B,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,QAAQ,CAAC;IACvE,KAAK,CAAC,0BAA0B,CAAC,GAAG,GAAG,WAAW,CAAC,WAAW,IAAI,CAAC;IACnE,KAAK,CAAC,8BAA8B,CAAC,GAAG,GAAG,WAAW,CAAC,cAAc,IAAI,CAAC;IAC1E,KAAK,CAAC,8BAA8B,CAAC,GAAG,WAAW,CAAC,eAAe,CAAC;IACpE,KAAK,CAAC,gCAAgC,CAAC,GAAG,GAAG,OAAO,CAAC,cAAc,IAAI,CAAC;IACxE,KAAK,CAAC,4BAA4B,CAAC,GAAG,GAAG,OAAO,CAAC,WAAW,IAAI,CAAC;IACjE,KAAK,CAAC,kCAAkC,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;IAChF,KAAK,CAAC,2BAA2B,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;IACtE,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACjE,2EAA2E;QAC3E,yEAAyE;QACzE,KAAK,CAAC,wBAAwB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,GAAG,oBAAoB,CAAC,KAAK,EAAE,WAAW,CAAC,mBAAmB,CAAC,IAAI,CAAC;IACxE,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import {\n backdrop,\n control,\n easing,\n fontFamily,\n fontWeight,\n motion,\n layer,\n radius,\n shadow,\n spacing,\n stroke,\n typography,\n} from \"@hjmds/design-contracts/foundations\";\nimport { resolveColorReference } from \"@hjmds/design-contracts/color-references\";\nimport { focusIndicatorContract } from \"@hjmds/design-contracts/contracts\";\nimport {\n visibleControlHeight,\n type DesignSystemProviderValue,\n} from \"@hjmds/design-contracts/components/design-system-provider\";\nimport { buttonRecipe, fieldRecipe } from \"@hjmds/design-contracts/recipes/base\";\nimport {\n bottomNavigationRecipe,\n comboboxRecipe,\n dialogRecipe,\n listRowRecipe,\n menuRecipe,\n searchFieldRecipe,\n selectRecipe,\n sheetRecipe,\n skeletonRecipe,\n tooltipRecipe,\n switchRecipe,\n toastRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport type { CSSProperties } from \"react\";\n\nexport type HjmThemeStyle = CSSProperties &\n Record<`--hjm-${string}`, string | number>;\n\nfunction kebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\ntype ShadowToken = Readonly<{ color: string; opacity: number; radius: number; offsetY: number }>;\n\n// RN shadow token -> CSS; blur = radius, as react-native-web maps it.\nfunction shadowCss(token: ShadowToken): string {\n const hex = token.color.replace(\"#\", \"\");\n const [r, g, b] = [0, 2, 4].map((start) => Number.parseInt(hex.slice(start, start + 2), 16));\n return `0 ${token.offsetY}px ${token.radius}px rgb(${r} ${g} ${b} / ${Math.round(token.opacity * 100)}%)`;\n}\n\nfunction rem(value: number): string {\n return `${Number((value / 16).toFixed(5))}rem`;\n}\n\nexport function createHjmThemeStyle(\n value: DesignSystemProviderValue,\n): HjmThemeStyle {\n const { environment, palette } = value;\n const style: HjmThemeStyle = {\n \"--hjm-backdrop-modal\": `color-mix(in srgb, ${backdrop.modal.color} ${backdrop.modal.opacity * 100}%, transparent)`,\n \"--hjm-text-scale\": environment.textScale,\n \"--hjm-motion-scale\": environment.reducedMotion ? 0 : 1,\n colorScheme: environment.theme,\n backgroundColor: palette.theme.bg,\n color: palette.theme.text,\n };\n\n for (const [name, color] of Object.entries(palette.theme)) {\n style[`--hjm-color-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccents)) {\n style[`--hjm-accent-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccentFills)) {\n style[`--hjm-accent-fill-${kebab(name)}`] = color;\n }\n for (const [name, value] of Object.entries(spacing)) {\n style[`--hjm-space-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(radius)) {\n style[`--hjm-radius-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(typography)) {\n style[`--hjm-type-${kebab(name)}-size`] =\n `calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-line-height`] =\n `calc(${rem(value.lineHeight)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-weight`] = value.fontWeight;\n }\n for (const [name, value] of Object.entries(fontWeight)) {\n style[`--hjm-font-weight-${kebab(name)}`] = value;\n }\n for (const [name, value] of Object.entries(motion)) {\n style[`--hjm-motion-${kebab(name)}`] = environment.reducedMotion\n ? \"0ms\"\n : `${value}ms`;\n }\n\n style[\"--hjm-font-family-ui\"] = fontFamily.ui.join(\", \");\n for (const [name, value] of Object.entries(stroke)) {\n style[`--hjm-stroke-${kebab(name)}`] = `${value}px`;\n }\n // Unset before 1.4.1, so focus rules were invalid and drew no ring.\n style[\"--hjm-color-focus\"] = resolveColorReference(focusIndicatorContract.color, palette);\n style[\"--hjm-focus-width\"] = `${focusIndicatorContract.width}px`;\n style[\"--hjm-focus-offset\"] = `${focusIndicatorContract.offset}px`;\n style[\"--hjm-bottom-navigation-pressed-background\"] = resolveColorReference(\n bottomNavigationRecipe.states.pressedBackground,\n palette,\n );\n // Row rhythm and the leading frame come from the recipe so the stylesheet\n // does not carry a second copy of the same numbers.\n style[\"--hjm-list-row-gap\"] = rem(listRowRecipe.gap);\n style[\"--hjm-list-row-leading-size\"] = rem(listRowRecipe.leadingSize);\n for (const [name, value] of Object.entries(switchRecipe.sizes)) {\n style[`--hjm-switch-${kebab(name)}-width`] = rem(value.width);\n style[`--hjm-switch-${kebab(name)}-height`] = rem(value.height);\n style[`--hjm-switch-${kebab(name)}-thumb`] = rem(value.thumb);\n style[`--hjm-switch-${kebab(name)}-inset`] = rem(value.inset);\n style[`--hjm-switch-${kebab(name)}-offset`] = rem(\n value.width - value.thumb - value.inset * 2,\n );\n }\n for (const [name, value] of Object.entries(listRowRecipe.density)) {\n style[`--hjm-list-row-${kebab(name)}-one-line`] = rem(value.oneLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-two-line`] = rem(value.twoLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-padding-inline`] = rem(value.paddingHorizontal);\n style[`--hjm-list-row-${kebab(name)}-padding-block`] = rem(value.paddingVertical);\n }\n // The recipe owns these; a second copy in the stylesheet drifts silently\n // because the gates read that file as text only. Block and text heights\n // already resolve through --hjm-space-*, so they are not re-emitted.\n const skeletonCurve = easing[skeletonRecipe.animation.easing];\n style[\"--hjm-skeleton-circle-size\"] =\n `${skeletonRecipe.shapes.circle.defaultHeight}px`;\n style[\"--hjm-skeleton-duration\"] = `${skeletonRecipe.animation.duration}ms`;\n style[\"--hjm-skeleton-easing\"] = `cubic-bezier(${skeletonCurve.join(\", \")})`;\n style[\"--hjm-skeleton-from-opacity\"] = skeletonRecipe.animation.fromOpacity;\n style[\"--hjm-skeleton-to-opacity\"] = skeletonRecipe.animation.toOpacity;\n // Export the shared order instead of keeping a second numeric scale in CSS.\n for (const [name, value] of Object.entries(layer)) {\n style[`--hjm-layer-${kebab(name)}`] = value;\n }\n for (const [name, token] of Object.entries(shadow)) {\n style[`--hjm-shadow-${kebab(name)}`] = shadowCss(token);\n }\n // Overlay chrome and sizes come from the recipes Native reads (1.5.0).\n for (const [name, chrome] of [[\"dialog\", dialogRecipe.content], [\"sheet\", sheetRecipe.content], [\"toast\", toastRecipe.surface]] as const) {\n style[`--hjm-${name}-background`] = resolveColorReference(chrome.background, palette);\n style[`--hjm-${name}-border`] = resolveColorReference(chrome.border, palette);\n style[`--hjm-${name}-border-width`] = `${chrome.borderWidth}px`;\n style[`--hjm-${name}-radius`] = `var(--hjm-radius-${chrome.radius})`;\n style[`--hjm-${name}-shadow`] = shadowCss(chrome.shadow);\n }\n style[\"--hjm-sheet-max-height\"] = `${sheetRecipe.content.maxHeightRatio * 100}dvh`;\n style[\"--hjm-sheet-max-width\"] = `${sheetRecipe.web.maxWidth}px`;\n style[\"--hjm-sheet-handle-width\"] = `${sheetRecipe.handle.width}px`;\n style[\"--hjm-sheet-handle-height\"] = `${sheetRecipe.handle.height}px`;\n style[\"--hjm-sheet-handle-color\"] = resolveColorReference(sheetRecipe.handle.color, palette);\n for (const [name, ratio] of Object.entries(sheetRecipe.sizes)) {\n if (ratio !== null) style[`--hjm-sheet-size-${name}`] = `${ratio * 100}dvh`;\n }\n // Toast badge/action colours resolve from the recipe so Web and Native share one tone table (1.10.0).\n for (const [tone, contract] of Object.entries(toastRecipe.tones)) {\n style[`--hjm-toast-accent-${tone}`] = resolveColorReference(contract.accent, palette);\n style[`--hjm-toast-badge-${tone}`] = resolveColorReference(contract.badge, palette);\n }\n style[\"--hjm-toast-badge-size\"] = `${toastRecipe.icon.badgeDiameter}px`;\n style[\"--hjm-toast-action-background\"] = resolveColorReference(toastRecipe.action.background, palette);\n style[\"--hjm-toast-action-color\"] = resolveColorReference(toastRecipe.action.color, palette);\n style[\"--hjm-toast-description-color\"] = resolveColorReference(toastRecipe.description.color, palette);\n const toastExit = toastRecipe.transition.web.exit;\n style[\"--hjm-toast-exit-duration\"] = environment.reducedMotion ? \"0ms\" : `${toastExit.duration}ms`;\n style[\"--hjm-toast-exit-easing\"] = `cubic-bezier(${easing[toastExit.easing].join(\", \")})`;\n // SearchField geometry comes from searchFieldRecipe (2026-10-06 follow-up). Web had drawn TextField's\n // 16px padding for both sizes and a 44px clear button even at `medium`, where the recipe and Native\n // use a 36 circle with a 4px hit slop (44 target, 36 footprint).\n for (const [name, size] of Object.entries(searchFieldRecipe.sizes)) {\n style[`--hjm-search-field-padding-${name}`] = `${size.paddingHorizontal}px`;\n style[`--hjm-search-field-gap-${name}`] = `${size.gap}px`;\n style[`--hjm-search-field-clear-${name}`] = `${size.clearDiameter}px`;\n style[`--hjm-search-field-clear-slop-${name}`] = `${size.clearHitSlop}px`;\n }\n style[\"--hjm-tooltip-max-width\"] = `${tooltipRecipe.content.maxWidth}px`;\n style[\"--hjm-tooltip-padding\"] = `${tooltipRecipe.surface.padding}px`;\n // Floating collection surfaces read their padding from the recipe (2026-10-06): the stylesheet's 4 had drifted from 8.\n style[\"--hjm-menu-padding\"] = `${menuRecipe.surface.padding}px`;\n style[\"--hjm-select-popover-padding\"] = `${selectRecipe.popover.padding}px`;\n style[\"--hjm-combobox-popover-padding\"] = `${comboboxRecipe.popover.padding}px`;\n style[\"--hjm-tooltip-collision-padding\"] = `${tooltipRecipe.positioning.collisionPadding}px`;\n style[\"--hjm-button-pressed-opacity\"] = buttonRecipe.opacity.pressed;\n style[\"--hjm-button-disabled-opacity\"] = buttonRecipe.opacity.disabled;\n style[\"--hjm-field-border-width\"] = `${fieldRecipe.borderWidth}px`;\n style[\"--hjm-field-focus-ring-width\"] = `${fieldRecipe.focusRingWidth}px`;\n style[\"--hjm-field-disabled-opacity\"] = fieldRecipe.disabledOpacity;\n style[\"--hjm-control-min-touch-target\"] = `${control.minTouchTarget}px`;\n style[\"--hjm-control-field-height\"] = `${control.fieldHeight}px`;\n style[\"--hjm-field-multiline-min-height\"] = rem(fieldRecipe.multilineMinHeight);\n style[\"--hjm-field-padding-block\"] = rem(fieldRecipe.paddingVertical);\n for (const [name, value] of Object.entries(control.buttonHeight)) {\n // The axis is applied to the emitted variables rather than to each rule so\n // that every stylesheet consumer of a control height honours it at once.\n style[`--hjm-control-button-${kebab(name)}`] =\n `${visibleControlHeight(value, environment.minimumVisualTarget)}px`;\n }\n\n return style;\n}\n"]}
1
+ {"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveSurfaceFillOpacity } from \"@hjmds/design-contracts/palette-contrast\";\nimport {\n backdrop,\n control,\n easing,\n fontFamily,\n resolveFontFamilyStack,\n fontWeight,\n motion,\n layer,\n radius,\n shadow,\n spacing,\n stroke,\n typography,\n} from \"@hjmds/design-contracts/foundations\";\nimport { resolveColorReference } from \"@hjmds/design-contracts/color-references\";\nimport { focusIndicatorContract } from \"@hjmds/design-contracts/contracts\";\nimport {\n visibleControlHeight,\n type DesignSystemProviderValue,\n} from \"@hjmds/design-contracts/components/design-system-provider\";\nimport { buttonRecipe, fieldRecipe } from \"@hjmds/design-contracts/recipes/base\";\nimport {\n bottomNavigationRecipe,\n comboboxRecipe,\n dialogRecipe,\n listRowRecipe,\n menuRecipe,\n searchFieldRecipe,\n selectRecipe,\n sheetRecipe,\n skeletonRecipe,\n tooltipRecipe,\n switchRecipe,\n toastRecipe,\n} from \"@hjmds/design-contracts/recipes\";\nimport type { CSSProperties } from \"react\";\n\nexport type HjmThemeStyle = CSSProperties &\n Record<`--hjm-${string}`, string | number>;\n\nfunction kebab(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\ntype ShadowToken = Readonly<{ color: string; opacity: number; radius: number; offsetY: number }>;\n\n// RN shadow token -> CSS; blur = radius, as react-native-web maps it.\nfunction shadowCss(token: ShadowToken, offsetX = 0): string {\n const hex = token.color.replace(\"#\", \"\");\n const [r, g, b] = [0, 2, 4].map((start) => Number.parseInt(hex.slice(start, start + 2), 16));\n return `${offsetX}px ${token.offsetY}px ${token.radius}px rgb(${r} ${g} ${b} / ${Math.round(token.opacity * 100)}%)`;\n}\n\nfunction rem(value: number): string {\n return `${Number((value / 16).toFixed(5))}rem`;\n}\n\nexport function createHjmThemeStyle(\n value: DesignSystemProviderValue,\n): HjmThemeStyle {\n const { environment, palette } = value;\n const profileTokens = value.designProfile?.tokens;\n const style: HjmThemeStyle = {\n \"--hjm-backdrop-modal\": `color-mix(in srgb, ${backdrop.modal.color} ${backdrop.modal.opacity * 100}%, transparent)`,\n \"--hjm-text-scale\": environment.textScale,\n \"--hjm-motion-scale\": environment.reducedMotion ? 0 : 1,\n colorScheme: environment.theme,\n backgroundColor: palette.theme.bg,\n color: palette.theme.text,\n };\n\n for (const [name, color] of Object.entries(palette.theme)) {\n style[`--hjm-color-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccents)) {\n style[`--hjm-accent-${kebab(name)}`] = color;\n }\n for (const [name, color] of Object.entries(palette.statusAccentFills)) {\n style[`--hjm-accent-fill-${kebab(name)}`] = color;\n }\n for (const [name, value] of Object.entries(spacing)) {\n style[`--hjm-space-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(profileTokens?.radius ?? radius)) {\n style[`--hjm-radius-${kebab(name)}`] = `${value}px`;\n }\n for (const [name, value] of Object.entries(profileTokens?.typography ?? typography)) {\n style[`--hjm-type-${kebab(name)}-size`] =\n `calc(${rem(value.fontSize)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-line-height`] =\n `calc(${rem(value.lineHeight)} * var(--hjm-text-scale))`;\n style[`--hjm-type-${kebab(name)}-weight`] = value.fontWeight;\n }\n for (const [name, value] of Object.entries(fontWeight)) {\n style[`--hjm-font-weight-${kebab(name)}`] = value;\n }\n for (const [name, value] of Object.entries(motion)) {\n style[`--hjm-motion-${kebab(name)}`] = environment.reducedMotion\n ? \"0ms\"\n : `${value}ms`;\n }\n\n style[\"--hjm-font-family-ui\"] = (profileTokens?.fontFamily.ui ?? fontFamily.ui).join(\", \");\n style[\"--hjm-font-family-code\"] = (profileTokens?.fontFamily.code ?? fontFamily.code).join(\", \");\n // Roles resolve from the nearest Provider, including portal/nested reset contexts.\n for (const role of [\"display\", \"reading\"] as const) {\n style[`--hjm-font-family-${role}`] = resolveFontFamilyStack(profileTokens?.fontFamily ?? fontFamily, role).join(\", \");\n }\n for (const [name, value] of Object.entries(stroke)) {\n style[`--hjm-stroke-${kebab(name)}`] = `${value}px`;\n }\n // Unset before 1.4.1, so focus rules were invalid and drew no ring.\n style[\"--hjm-color-focus\"] = resolveColorReference(focusIndicatorContract.color, palette);\n style[\"--hjm-focus-width\"] = `${focusIndicatorContract.width}px`;\n style[\"--hjm-focus-offset\"] = `${focusIndicatorContract.offset}px`;\n style[\"--hjm-bottom-navigation-pressed-background\"] = resolveColorReference(\n bottomNavigationRecipe.states.pressedBackground,\n palette,\n );\n // Row rhythm and the leading frame come from the recipe so the stylesheet\n // does not carry a second copy of the same numbers.\n style[\"--hjm-list-row-gap\"] = rem(listRowRecipe.gap);\n style[\"--hjm-list-row-leading-size\"] = rem(listRowRecipe.leadingSize);\n for (const [name, value] of Object.entries(switchRecipe.sizes)) {\n style[`--hjm-switch-${kebab(name)}-width`] = rem(value.width);\n style[`--hjm-switch-${kebab(name)}-height`] = rem(value.height);\n style[`--hjm-switch-${kebab(name)}-thumb`] = rem(value.thumb);\n style[`--hjm-switch-${kebab(name)}-inset`] = rem(value.inset);\n style[`--hjm-switch-${kebab(name)}-offset`] = rem(\n value.width - value.thumb - value.inset * 2,\n );\n }\n for (const [name, value] of Object.entries(listRowRecipe.density)) {\n style[`--hjm-list-row-${kebab(name)}-one-line`] = rem(value.oneLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-two-line`] = rem(value.twoLineMinHeight);\n style[`--hjm-list-row-${kebab(name)}-padding-inline`] = rem(value.paddingHorizontal);\n style[`--hjm-list-row-${kebab(name)}-padding-block`] = rem(value.paddingVertical);\n }\n // The recipe owns these; a second copy in the stylesheet drifts silently\n // because the gates read that file as text only. Block and text heights\n // already resolve through --hjm-space-*, so they are not re-emitted.\n const skeletonCurve = easing[skeletonRecipe.animation.easing];\n style[\"--hjm-skeleton-circle-size\"] =\n `${skeletonRecipe.shapes.circle.defaultHeight}px`;\n style[\"--hjm-skeleton-duration\"] = `${skeletonRecipe.animation.duration}ms`;\n style[\"--hjm-skeleton-easing\"] = `cubic-bezier(${skeletonCurve.join(\", \")})`;\n style[\"--hjm-skeleton-from-opacity\"] = skeletonRecipe.animation.fromOpacity;\n style[\"--hjm-skeleton-to-opacity\"] = skeletonRecipe.animation.toOpacity;\n // Export the shared order instead of keeping a second numeric scale in CSS.\n for (const [name, value] of Object.entries(layer)) {\n style[`--hjm-layer-${kebab(name)}`] = value;\n }\n for (const [name, token] of Object.entries(profileTokens?.shadow ?? shadow)) {\n style[`--hjm-shadow-${kebab(name)}`] = shadowCss(token);\n }\n const surfaceMaterial = value.designProfile?.material.surface;\n // Defaults are emitted on every Provider, so a nested neutral profile clears\n // inherited glass/clay. Unsupported transparency remains an opaque CSS fill.\n style[\"--hjm-surface-blur\"] = surfaceMaterial?.blurStrength ? `blur(${surfaceMaterial.blurStrength * 32}px)` : \"none\";\n style[\"--hjm-surface-fill-opacity\"] = surfaceMaterial?.blurStrength ? resolveSurfaceFillOpacity(surfaceMaterial.fillOpacity, palette.theme) : 1;\n const insetShadow = surfaceMaterial?.insetShadows.length\n ? surfaceMaterial.insetShadows.map(token => `inset ${shadowCss(token, token.offsetX)}`).join(\", \")\n : \"\";\n style[\"--hjm-surface-inset-shadow\"] = insetShadow || \"none\";\n style[\"--hjm-surface-raised-shadow\"] = shadowCss(profileTokens?.shadow.floating ?? shadow.floating) + (insetShadow ? `, ${insetShadow}` : \"\");\n // BottomCTA overlaps content above it (bottomCtaRecipe rationale). Profile\n // strength is shared, but its shadow must cast upward rather than behind the\n // footer; preserve the stylesheet-only legacy path when no profile is supplied.\n style[\"--hjm-bottom-cta-shadow\"] = profileTokens\n ? shadowCss({ ...profileTokens.shadow.floating, offsetY: -Math.abs(profileTokens.shadow.floating.offsetY) })\n : \"none\";\n // Toast body metrics follow a selected profile; emit legacy values when no profile is selected\n // instead of inheriting a parent profile or changing standalone presentation.\n style[\"--hjm-toast-title-line-height\"] = profileTokens ? \"var(--hjm-type-body-line-height)\" : \"1.35\";\n style[\"--hjm-toast-description-line-height\"] = profileTokens ? \"var(--hjm-type-body-line-height)\" : \"1.45\";\n // Overlay chrome and sizes come from the recipes Native reads (1.5.0).\n for (const [name, chrome] of [[\"dialog\", dialogRecipe.content], [\"sheet\", sheetRecipe.content], [\"toast\", toastRecipe.surface]] as const) {\n style[`--hjm-${name}-background`] = resolveColorReference(chrome.background, palette);\n style[`--hjm-${name}-border`] = resolveColorReference(chrome.border, palette);\n style[`--hjm-${name}-border-width`] = `${chrome.borderWidth}px`;\n style[`--hjm-${name}-radius`] = `var(--hjm-radius-${chrome.radius})`;\n // Recipes select the floating role. Resolve its value from the profile so\n // dialogs, sheets and toasts cannot retain neutral shadows after a theme switch.\n style[`--hjm-${name}-shadow`] = shadowCss(profileTokens?.shadow.floating ?? chrome.shadow);\n }\n style[\"--hjm-sheet-max-height\"] = `${sheetRecipe.content.maxHeightRatio * 100}dvh`;\n style[\"--hjm-sheet-max-width\"] = `${sheetRecipe.web.maxWidth}px`;\n style[\"--hjm-sheet-handle-width\"] = `${sheetRecipe.handle.width}px`;\n style[\"--hjm-sheet-handle-height\"] = `${sheetRecipe.handle.height}px`;\n style[\"--hjm-sheet-handle-color\"] = resolveColorReference(sheetRecipe.handle.color, palette);\n for (const [name, ratio] of Object.entries(sheetRecipe.sizes)) {\n if (ratio !== null) style[`--hjm-sheet-size-${name}`] = `${ratio * 100}dvh`;\n }\n // Toast badge/action colours resolve from the recipe so Web and Native share one tone table (1.10.0).\n for (const [tone, contract] of Object.entries(toastRecipe.tones)) {\n style[`--hjm-toast-accent-${tone}`] = resolveColorReference(contract.accent, palette);\n style[`--hjm-toast-badge-${tone}`] = resolveColorReference(contract.badge, palette);\n }\n style[\"--hjm-toast-badge-size\"] = `${toastRecipe.icon.badgeDiameter}px`;\n style[\"--hjm-toast-action-background\"] = resolveColorReference(toastRecipe.action.background, palette);\n style[\"--hjm-toast-action-color\"] = resolveColorReference(toastRecipe.action.color, palette);\n style[\"--hjm-toast-description-color\"] = resolveColorReference(toastRecipe.description.color, palette);\n const toastExit = toastRecipe.transition.web.exit;\n style[\"--hjm-toast-exit-duration\"] = environment.reducedMotion ? \"0ms\" : `${toastExit.duration}ms`;\n style[\"--hjm-toast-exit-easing\"] = `cubic-bezier(${easing[toastExit.easing].join(\", \")})`;\n // SearchField geometry comes from searchFieldRecipe (2026-10-06 follow-up). Web had drawn TextField's\n // 16px padding for both sizes and a 44px clear button even at `medium`, where the recipe and Native\n // use a 36 circle with a 4px hit slop (44 target, 36 footprint).\n for (const [name, size] of Object.entries(searchFieldRecipe.sizes)) {\n style[`--hjm-search-field-padding-${name}`] = `${size.paddingHorizontal}px`;\n style[`--hjm-search-field-gap-${name}`] = `${size.gap}px`;\n style[`--hjm-search-field-clear-${name}`] = `${size.clearDiameter}px`;\n style[`--hjm-search-field-clear-slop-${name}`] = `${size.clearHitSlop}px`;\n }\n style[\"--hjm-tooltip-max-width\"] = `${tooltipRecipe.content.maxWidth}px`;\n style[\"--hjm-tooltip-padding\"] = `${tooltipRecipe.surface.padding}px`;\n // Floating collection surfaces read their padding from the recipe (2026-10-06): the stylesheet's 4 had drifted from 8.\n style[\"--hjm-menu-padding\"] = `${menuRecipe.surface.padding}px`;\n style[\"--hjm-select-popover-padding\"] = `${selectRecipe.popover.padding}px`;\n style[\"--hjm-combobox-popover-padding\"] = `${comboboxRecipe.popover.padding}px`;\n style[\"--hjm-tooltip-collision-padding\"] = `${tooltipRecipe.positioning.collisionPadding}px`;\n style[\"--hjm-button-pressed-opacity\"] = buttonRecipe.opacity.pressed;\n style[\"--hjm-button-disabled-opacity\"] = buttonRecipe.opacity.disabled;\n style[\"--hjm-field-border-width\"] = `${fieldRecipe.borderWidth}px`;\n style[\"--hjm-field-focus-ring-width\"] = `${fieldRecipe.focusRingWidth}px`;\n style[\"--hjm-field-disabled-opacity\"] = fieldRecipe.disabledOpacity;\n style[\"--hjm-control-min-touch-target\"] = `${control.minTouchTarget}px`;\n style[\"--hjm-control-field-height\"] = `${control.fieldHeight}px`;\n style[\"--hjm-field-multiline-min-height\"] = rem(fieldRecipe.multilineMinHeight);\n style[\"--hjm-field-padding-block\"] = rem(fieldRecipe.paddingVertical);\n for (const [name, value] of Object.entries(control.buttonHeight)) {\n // The axis is applied to the emitted variables rather than to each rule so\n // that every stylesheet consumer of a control height honours it at once.\n style[`--hjm-control-button-${kebab(name)}`] =\n `${visibleControlHeight(value, environment.minimumVisualTarget)}px`;\n }\n\n return style;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../src/toggle-group.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACrB,MAAM,iDAAiD,CAAC;AAGzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,gBAAgB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAClE,UAAU,EAAE,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,eAAO,MAAM,WAAW,EAsDlB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;CAAE,KAC9D,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"toggle-group.d.ts","sourceRoot":"","sources":["../src/toggle-group.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACrB,MAAM,iDAAiD,CAAC;AAGzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,gBAAgB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,IAAI,QAAQ,CAAC;IAClE,UAAU,EAAE,qBAAqB,CAAC,EAAE,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IAC7B,iBAAiB,CAAC,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;IACpC,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC;IACpD,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,eAAO,MAAM,WAAW,EAwDlB,CAAC,EAAE,SAAS,MAAM,GAAG,MAAM,EAC/B,KAAK,EAAE,gBAAgB,CAAC,EAAE,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;CAAE,KAC9D,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC"}
@@ -16,7 +16,9 @@ export const ToggleGroup = forwardRef(function ToggleGroup({ descriptor, pressed
16
16
  "--hjm-toggle-min-height": `${metrics.minHeight}px`,
17
17
  "--hjm-toggle-padding": `${metrics.paddingHorizontal}px`,
18
18
  "--hjm-toggle-gap": `${toggleGroupRecipe.gap}px`,
19
- "--hjm-toggle-radius": `${toggleGroupRecipe.radius}px`,
19
+ // Use the closest Provider's CSS role without adding its runtime graph to
20
+ // this small entry. Standalone groups retain the numeric recipe fallback.
21
+ "--hjm-toggle-radius": `var(--hjm-radius-md, ${toggleGroupRecipe.radius}px)`,
20
22
  }, children: descriptor.items.map((item) => (_jsx("button", { type: "button", "aria-pressed": pressed.has(item.id), "aria-disabled": item.disabled || undefined, disabled: item.disabled, className: "hjm-toggle-group__item", onClick: () => setPressed(toggleGroupSelection(descriptor, pressed, item.id)), children: item.label }, item.id))) }));
21
23
  });
22
24
  //# sourceMappingURL=toggle-group.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toggle-group.js","sourceRoot":"","sources":["../src/toggle-group.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,oBAAoB,EACpB,6BAA6B,GAG9B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAsB,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAcjE,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,WAAW,CACxD,EACE,UAAU,EACV,UAAU,EAAE,iBAAiB,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,EACtC,SAAS,EACT,WAAW,GACU,EACvB,YAAuC;IAEvC,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,oBAAoB,CAAkB;QACrE,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QACxE,YAAY,EAAE,iBAAiB,IAAI,IAAI,GAAG,EAAM;QAChD,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;KAC9E,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,6BAA6B,CAAC,UAAU,EAAE,UAAU,CAAC,EAC3D,CAAC,UAAU,EAAE,UAAU,CAAC,CACzB,CAAC;IACF,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,CACL,cACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,OAAO,gBACA,UAAU,CAAC,kBAAkB,EACzC,SAAS,EAAE,UAAU,CAAC,kBAAkB,EAAE,SAAS,CAAC,eACzC,IAAI,EACf,KAAK,EAAE;YACL,GAAG,WAAW;YACd,yBAAyB,EAAE,GAAG,OAAO,CAAC,SAAS,IAAI;YACnD,sBAAsB,EAAE,GAAG,OAAO,CAAC,iBAAiB,IAAI;YACxD,kBAAkB,EAAE,GAAG,iBAAiB,CAAC,GAAG,IAAI;YAChD,qBAAqB,EAAE,GAAG,iBAAiB,CAAC,MAAM,IAAI;SACtC,YAEjB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC9B,iBAEE,IAAI,EAAC,QAAQ,kBAEC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mBACnB,IAAI,CAAC,QAAQ,IAAI,SAAS,EACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,SAAS,EAAC,wBAAwB,EAClC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,YAE5E,IAAI,CAAC,KAAK,IATN,IAAI,CAAC,EAAE,CAUL,CACV,CAAC,GACE,CACP,CAAC;AACJ,CAAC,CAE6B,CAAC","sourcesContent":["import {\n reconcileToggleGroupSelection,\n toggleGroupRecipe,\n toggleGroupSelection,\n validateToggleGroupDescriptor,\n type ToggleGroupDescriptor,\n type ToggleGroupSize,\n} from \"@hjmds/design-contracts/components/toggle-group\";\nimport { forwardRef, useMemo, type CSSProperties } from \"react\";\nimport { classNames, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ToggleGroupProps<Id extends string = string> = Readonly<{\n descriptor: ToggleGroupDescriptor<Id>;\n pressedIds?: ReadonlySet<Id>;\n defaultPressedIds?: ReadonlySet<Id>;\n onPressedIdsChange?: (ids: ReadonlySet<Id>) => void;\n size?: ToggleGroupSize;\n className?: string;\n /** Canonical layout-only placement on the root group. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ToggleGroup = forwardRef(function ToggleGroup<Id extends string = string>(\n {\n descriptor,\n pressedIds: controlledPressed,\n defaultPressedIds,\n onPressedIdsChange,\n size = toggleGroupRecipe.defaults.size,\n className,\n layoutStyle,\n }: ToggleGroupProps<Id>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n validateToggleGroupDescriptor(descriptor);\n const [rawPressed, setPressed] = useControllableState<ReadonlySet<Id>>({\n ...(controlledPressed === undefined ? {} : { value: controlledPressed }),\n defaultValue: defaultPressedIds ?? new Set<Id>(),\n ...(onPressedIdsChange === undefined ? {} : { onChange: onPressedIdsChange }),\n });\n const pressed = useMemo(\n () => reconcileToggleGroupSelection(descriptor, rawPressed),\n [descriptor, rawPressed],\n );\n const metrics = toggleGroupRecipe.sizes[size];\n return (\n <div\n ref={forwardedRef}\n role=\"group\"\n aria-label={descriptor.accessibilityLabel}\n className={classNames(\"hjm-toggle-group\", className)}\n data-size={size}\n style={{\n ...layoutStyle,\n \"--hjm-toggle-min-height\": `${metrics.minHeight}px`,\n \"--hjm-toggle-padding\": `${metrics.paddingHorizontal}px`,\n \"--hjm-toggle-gap\": `${toggleGroupRecipe.gap}px`,\n \"--hjm-toggle-radius\": `${toggleGroupRecipe.radius}px`,\n } as CSSProperties}\n >\n {descriptor.items.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n // The pressed state rides on aria-pressed, never on color alone.\n aria-pressed={pressed.has(item.id)}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n className=\"hjm-toggle-group__item\"\n onClick={() => setPressed(toggleGroupSelection(descriptor, pressed, item.id))}\n >\n {item.label}\n </button>\n ))}\n </div>\n );\n}) as <Id extends string = string>(\n props: ToggleGroupProps<Id> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"]}
1
+ {"version":3,"file":"toggle-group.js","sourceRoot":"","sources":["../src/toggle-group.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,6BAA6B,EAC7B,iBAAiB,EACjB,oBAAoB,EACpB,6BAA6B,GAG9B,MAAM,iDAAiD,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,OAAO,EAAsB,MAAM,OAAO,CAAC;AAChE,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAcjE,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,WAAW,CACxD,EACE,UAAU,EACV,UAAU,EAAE,iBAAiB,EAC7B,iBAAiB,EACjB,kBAAkB,EAClB,IAAI,GAAG,iBAAiB,CAAC,QAAQ,CAAC,IAAI,EACtC,SAAS,EACT,WAAW,GACU,EACvB,YAAuC;IAEvC,6BAA6B,CAAC,UAAU,CAAC,CAAC;IAC1C,MAAM,CAAC,UAAU,EAAE,UAAU,CAAC,GAAG,oBAAoB,CAAkB;QACrE,GAAG,CAAC,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QACxE,YAAY,EAAE,iBAAiB,IAAI,IAAI,GAAG,EAAM;QAChD,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;KAC9E,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,OAAO,CACrB,GAAG,EAAE,CAAC,6BAA6B,CAAC,UAAU,EAAE,UAAU,CAAC,EAC3D,CAAC,UAAU,EAAE,UAAU,CAAC,CACzB,CAAC;IACF,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9C,OAAO,CACL,cACE,GAAG,EAAE,YAAY,EACjB,IAAI,EAAC,OAAO,gBACA,UAAU,CAAC,kBAAkB,EACzC,SAAS,EAAE,UAAU,CAAC,kBAAkB,EAAE,SAAS,CAAC,eACzC,IAAI,EACf,KAAK,EAAE;YACL,GAAG,WAAW;YACd,yBAAyB,EAAE,GAAG,OAAO,CAAC,SAAS,IAAI;YACnD,sBAAsB,EAAE,GAAG,OAAO,CAAC,iBAAiB,IAAI;YACxD,kBAAkB,EAAE,GAAG,iBAAiB,CAAC,GAAG,IAAI;YAChD,0EAA0E;YAC1E,0EAA0E;YAC1E,qBAAqB,EAAE,wBAAwB,iBAAiB,CAAC,MAAM,KAAK;SAC5D,YAEjB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAC9B,iBAEE,IAAI,EAAC,QAAQ,kBAEC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,mBACnB,IAAI,CAAC,QAAQ,IAAI,SAAS,EACzC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,SAAS,EAAC,wBAAwB,EAClC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,oBAAoB,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,YAE5E,IAAI,CAAC,KAAK,IATN,IAAI,CAAC,EAAE,CAUL,CACV,CAAC,GACE,CACP,CAAC;AACJ,CAAC,CAE6B,CAAC","sourcesContent":["import {\n reconcileToggleGroupSelection,\n toggleGroupRecipe,\n toggleGroupSelection,\n validateToggleGroupDescriptor,\n type ToggleGroupDescriptor,\n type ToggleGroupSize,\n} from \"@hjmds/design-contracts/components/toggle-group\";\nimport { forwardRef, useMemo, type CSSProperties } from \"react\";\nimport { classNames, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type ToggleGroupProps<Id extends string = string> = Readonly<{\n descriptor: ToggleGroupDescriptor<Id>;\n pressedIds?: ReadonlySet<Id>;\n defaultPressedIds?: ReadonlySet<Id>;\n onPressedIdsChange?: (ids: ReadonlySet<Id>) => void;\n size?: ToggleGroupSize;\n className?: string;\n /** Canonical layout-only placement on the root group. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const ToggleGroup = forwardRef(function ToggleGroup<Id extends string = string>(\n {\n descriptor,\n pressedIds: controlledPressed,\n defaultPressedIds,\n onPressedIdsChange,\n size = toggleGroupRecipe.defaults.size,\n className,\n layoutStyle,\n }: ToggleGroupProps<Id>,\n forwardedRef: React.Ref<HTMLDivElement>,\n) {\n validateToggleGroupDescriptor(descriptor);\n const [rawPressed, setPressed] = useControllableState<ReadonlySet<Id>>({\n ...(controlledPressed === undefined ? {} : { value: controlledPressed }),\n defaultValue: defaultPressedIds ?? new Set<Id>(),\n ...(onPressedIdsChange === undefined ? {} : { onChange: onPressedIdsChange }),\n });\n const pressed = useMemo(\n () => reconcileToggleGroupSelection(descriptor, rawPressed),\n [descriptor, rawPressed],\n );\n const metrics = toggleGroupRecipe.sizes[size];\n return (\n <div\n ref={forwardedRef}\n role=\"group\"\n aria-label={descriptor.accessibilityLabel}\n className={classNames(\"hjm-toggle-group\", className)}\n data-size={size}\n style={{\n ...layoutStyle,\n \"--hjm-toggle-min-height\": `${metrics.minHeight}px`,\n \"--hjm-toggle-padding\": `${metrics.paddingHorizontal}px`,\n \"--hjm-toggle-gap\": `${toggleGroupRecipe.gap}px`,\n // Use the closest Provider's CSS role without adding its runtime graph to\n // this small entry. Standalone groups retain the numeric recipe fallback.\n \"--hjm-toggle-radius\": `var(--hjm-radius-md, ${toggleGroupRecipe.radius}px)`,\n } as CSSProperties}\n >\n {descriptor.items.map((item) => (\n <button\n key={item.id}\n type=\"button\"\n // The pressed state rides on aria-pressed, never on color alone.\n aria-pressed={pressed.has(item.id)}\n aria-disabled={item.disabled || undefined}\n disabled={item.disabled}\n className=\"hjm-toggle-group__item\"\n onClick={() => setPressed(toggleGroupSelection(descriptor, pressed, item.id))}\n >\n {item.label}\n </button>\n ))}\n </div>\n );\n}) as <Id extends string = string>(\n props: ToggleGroupProps<Id> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement | null;\n"]}
package/dist/top.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"top.d.ts","sourceRoot":"","sources":["../src/top.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAiD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC9B,UAAU,EAAE,aAAa,CAAC;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,eAAO,MAAM,GAAG;gBARF,aAAa;IACzB,kFAAkF;eACvE,SAAS;gBACR,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;gDAoCrC,CAAC"}
1
+ {"version":3,"file":"top.d.ts","sourceRoot":"","sources":["../src/top.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAiD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEtF,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAC9B,UAAU,EAAE,aAAa,CAAC;IAC1B,kFAAkF;IAClF,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,eAAO,MAAM,GAAG;gBARF,aAAa;IACzB,kFAAkF;eACvE,SAAS;gBACR,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;gDAyCrC,CAAC"}
package/dist/top.js CHANGED
@@ -1,16 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { topDefaults, topRecipe, validateTopDescriptor, } from "@hjmds/design-contracts/components/top";
3
3
  import { forwardRef, createElement } from "react";
4
- import { classNames } from "./internal.js";
4
+ import { classNames, useDesignProfileDefaults } from "./internal.js";
5
5
  export const Top = forwardRef(function Top({ descriptor, trailing, className, layoutStyle }, forwardedRef) {
6
6
  validateTopDescriptor(descriptor);
7
7
  const size = descriptor.size ?? topDefaults.size;
8
8
  const level = descriptor.headingLevel ?? topDefaults.headingLevel;
9
9
  const metrics = topRecipe.sizes[size];
10
+ const profile = useDesignProfileDefaults();
11
+ // Keep the visual role independent of the semantic heading level and preserve recipe defaults.
12
+ const title = profile
13
+ ? size === "large" ? profile.tokens.heading.level2 : profile.tokens.typography.titleLarge
14
+ : metrics.title;
10
15
  return (_jsxs("header", { ref: forwardedRef, className: classNames("hjm-top", className), "data-size": size, style: { ...layoutStyle,
11
- "--hjm-top-title-size": `${metrics.title.fontSize}px`,
12
- "--hjm-top-title-line-height": `${metrics.title.lineHeight}px`,
13
- "--hjm-top-title-weight": metrics.title.fontWeight,
16
+ "--hjm-top-title-size": `${title.fontSize}px`,
17
+ "--hjm-top-title-line-height": `${title.lineHeight}px`,
18
+ "--hjm-top-title-weight": title.fontWeight,
14
19
  "--hjm-top-padding-top": `${metrics.paddingTop}px`,
15
20
  "--hjm-top-padding-bottom": `${metrics.paddingBottom}px`,
16
21
  }, children: [descriptor.eyebrow ? _jsx("p", { className: "hjm-top__eyebrow", children: descriptor.eyebrow }) : null, _jsxs("div", { className: "hjm-top__row", children: [createElement(`h${level}`, { className: "hjm-top__title" }, descriptor.title), trailing ? _jsx("div", { className: "hjm-top__trailing", children: trailing }) : null] }), descriptor.description ? _jsx("p", { className: "hjm-top__description", children: descriptor.description }) : null] }));
package/dist/top.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"top.js","sourceRoot":"","sources":["../src/top.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,qBAAqB,GAEtB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAsC,MAAM,OAAO,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAY3C,MAAM,CAAC,MAAM,GAAG,GAAG,UAAU,CAAwB,SAAS,GAAG,CAC/D,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,EAChD,YAAY;IAEZ,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC;IAClE,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,CACL,kBACE,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,eAChC,IAAI,EACf,KAAK,EAAE,EAAE,GAAG,WAAW;YACrB,sBAAsB,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,IAAI;YACrD,6BAA6B,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI;YAC9D,wBAAwB,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU;YAClD,uBAAuB,EAAE,GAAG,OAAO,CAAC,UAAU,IAAI;YAClD,0BAA0B,EAAE,GAAG,OAAO,CAAC,aAAa,IAAI;SACxC,aAEjB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,YAAG,SAAS,EAAC,kBAAkB,YAAE,UAAU,CAAC,OAAO,GAAK,CAAC,CAAC,CAAC,IAAI,EACrF,eAAK,SAAS,EAAC,cAAc,aAK1B,aAAa,CAAC,IAAI,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,UAAU,CAAC,KAAK,CAAC,EAC7E,QAAQ,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,mBAAmB,YAAE,QAAQ,GAAO,CAAC,CAAC,CAAC,IAAI,IAClE,EACL,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,YAAG,SAAS,EAAC,sBAAsB,YAAE,UAAU,CAAC,WAAW,GAAK,CAAC,CAAC,CAAC,IAAI,IAC1F,CACV,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import {\n topDefaults,\n topRecipe,\n validateTopDescriptor,\n type TopDescriptor,\n} from \"@hjmds/design-contracts/components/top\";\nimport { forwardRef, createElement, type CSSProperties, type ReactNode } from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type TopProps = Readonly<{\n descriptor: TopDescriptor;\n /** Secondary action sharing the title row; drops below it when space runs out. */\n trailing?: ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Top = forwardRef<HTMLElement, TopProps>(function Top(\n { descriptor, trailing, className, layoutStyle },\n forwardedRef,\n) {\n validateTopDescriptor(descriptor);\n const size = descriptor.size ?? topDefaults.size;\n const level = descriptor.headingLevel ?? topDefaults.headingLevel;\n const metrics = topRecipe.sizes[size];\n return (\n <header\n ref={forwardedRef}\n className={classNames(\"hjm-top\", className)}\n data-size={size}\n style={{ ...layoutStyle,\n \"--hjm-top-title-size\": `${metrics.title.fontSize}px`,\n \"--hjm-top-title-line-height\": `${metrics.title.lineHeight}px`,\n \"--hjm-top-title-weight\": metrics.title.fontWeight,\n \"--hjm-top-padding-top\": `${metrics.paddingTop}px`,\n \"--hjm-top-padding-bottom\": `${metrics.paddingBottom}px`,\n } as CSSProperties}\n >\n {descriptor.eyebrow ? <p className=\"hjm-top__eyebrow\">{descriptor.eyebrow}</p> : null}\n <div className=\"hjm-top__row\">\n {/*\n A real heading element at the declared level, not styled text: this\n block is what a screen reader lands on when it skips to the content.\n */}\n {createElement(`h${level}`, { className: \"hjm-top__title\" }, descriptor.title)}\n {trailing ? <div className=\"hjm-top__trailing\">{trailing}</div> : null}\n </div>\n {descriptor.description ? <p className=\"hjm-top__description\">{descriptor.description}</p> : null}\n </header>\n );\n});\n"]}
1
+ {"version":3,"file":"top.js","sourceRoot":"","sources":["../src/top.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,WAAW,EACX,SAAS,EACT,qBAAqB,GAEtB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAsC,MAAM,OAAO,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAYrE,MAAM,CAAC,MAAM,GAAG,GAAG,UAAU,CAAwB,SAAS,GAAG,CAC/D,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,EAChD,YAAY;IAEZ,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,YAAY,IAAI,WAAW,CAAC,YAAY,CAAC;IAClE,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,wBAAwB,EAAE,CAAC;IAC3C,+FAA+F;IAC/F,MAAM,KAAK,GAAG,OAAO;QACnB,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU;QACzF,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IAClB,OAAO,CACL,kBACE,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,eAChC,IAAI,EACf,KAAK,EAAE,EAAE,GAAG,WAAW;YACrB,sBAAsB,EAAE,GAAG,KAAK,CAAC,QAAQ,IAAI;YAC7C,6BAA6B,EAAE,GAAG,KAAK,CAAC,UAAU,IAAI;YACtD,wBAAwB,EAAE,KAAK,CAAC,UAAU;YAC1C,uBAAuB,EAAE,GAAG,OAAO,CAAC,UAAU,IAAI;YAClD,0BAA0B,EAAE,GAAG,OAAO,CAAC,aAAa,IAAI;SACxC,aAEjB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,YAAG,SAAS,EAAC,kBAAkB,YAAE,UAAU,CAAC,OAAO,GAAK,CAAC,CAAC,CAAC,IAAI,EACrF,eAAK,SAAS,EAAC,cAAc,aAK1B,aAAa,CAAC,IAAI,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,gBAAgB,EAAE,EAAE,UAAU,CAAC,KAAK,CAAC,EAC7E,QAAQ,CAAC,CAAC,CAAC,cAAK,SAAS,EAAC,mBAAmB,YAAE,QAAQ,GAAO,CAAC,CAAC,CAAC,IAAI,IAClE,EACL,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,YAAG,SAAS,EAAC,sBAAsB,YAAE,UAAU,CAAC,WAAW,GAAK,CAAC,CAAC,CAAC,IAAI,IAC1F,CACV,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import {\n topDefaults,\n topRecipe,\n validateTopDescriptor,\n type TopDescriptor,\n} from \"@hjmds/design-contracts/components/top\";\nimport { forwardRef, createElement, type CSSProperties, type ReactNode } from \"react\";\nimport { classNames, useDesignProfileDefaults } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type TopProps = Readonly<{\n descriptor: TopDescriptor;\n /** Secondary action sharing the title row; drops below it when space runs out. */\n trailing?: ReactNode;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Top = forwardRef<HTMLElement, TopProps>(function Top(\n { descriptor, trailing, className, layoutStyle },\n forwardedRef,\n) {\n validateTopDescriptor(descriptor);\n const size = descriptor.size ?? topDefaults.size;\n const level = descriptor.headingLevel ?? topDefaults.headingLevel;\n const metrics = topRecipe.sizes[size];\n const profile = useDesignProfileDefaults();\n // Keep the visual role independent of the semantic heading level and preserve recipe defaults.\n const title = profile\n ? size === \"large\" ? profile.tokens.heading.level2 : profile.tokens.typography.titleLarge\n : metrics.title;\n return (\n <header\n ref={forwardedRef}\n className={classNames(\"hjm-top\", className)}\n data-size={size}\n style={{ ...layoutStyle,\n \"--hjm-top-title-size\": `${title.fontSize}px`,\n \"--hjm-top-title-line-height\": `${title.lineHeight}px`,\n \"--hjm-top-title-weight\": title.fontWeight,\n \"--hjm-top-padding-top\": `${metrics.paddingTop}px`,\n \"--hjm-top-padding-bottom\": `${metrics.paddingBottom}px`,\n } as CSSProperties}\n >\n {descriptor.eyebrow ? <p className=\"hjm-top__eyebrow\">{descriptor.eyebrow}</p> : null}\n <div className=\"hjm-top__row\">\n {/*\n A real heading element at the declared level, not styled text: this\n block is what a screen reader lands on when it skips to the content.\n */}\n {createElement(`h${level}`, { className: \"hjm-top__title\" }, descriptor.title)}\n {trailing ? <div className=\"hjm-top__trailing\">{trailing}</div> : null}\n </div>\n {descriptor.description ? <p className=\"hjm-top__description\">{descriptor.description}</p> : null}\n </header>\n );\n});\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hjmds/react",
3
- "version": "1.14.0",
3
+ "version": "1.16.0",
4
4
  "description": "Accessible React 19 renderers for HJM design contracts.",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -502,6 +502,16 @@
502
502
  "types": "./dist/document-resource.d.ts",
503
503
  "import": "./dist/document-resource.js",
504
504
  "default": "./dist/document-resource.js"
505
+ },
506
+ "./design-profile": {
507
+ "types": "./dist/design-profile.d.ts",
508
+ "import": "./dist/design-profile.js",
509
+ "default": "./dist/design-profile.js"
510
+ },
511
+ "./collection-rail": {
512
+ "types": "./dist/collection-rail.d.ts",
513
+ "import": "./dist/collection-rail.js",
514
+ "default": "./dist/collection-rail.js"
505
515
  }
506
516
  },
507
517
  "files": [
@@ -511,7 +521,7 @@
511
521
  "THIRD_PARTY_NOTICES.md"
512
522
  ],
513
523
  "peerDependencies": {
514
- "@hjmds/design-contracts": ">=1.14.0 <1.15.0",
524
+ "@hjmds/design-contracts": ">=1.16.0 <1.17.0",
515
525
  "react": ">=19.0.0",
516
526
  "react-dom": ">=19.0.0",
517
527
  "@number-flow/react": "0.6.2",
@@ -548,7 +558,7 @@
548
558
  "blobatar": "2.7.0",
549
559
  "@blobatar/react": "2.7.0",
550
560
  "lucide-react": "1.49.0",
551
- "@hjmds/design-contracts": "1.14.0"
561
+ "@hjmds/design-contracts": "1.16.0"
552
562
  },
553
563
  "peerDependenciesMeta": {
554
564
  "@number-flow/react": {