@hjmds/react 1.30.0 → 1.32.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 (102) hide show
  1. package/dist/auth-screen.d.ts +18 -3
  2. package/dist/auth-screen.d.ts.map +1 -1
  3. package/dist/auth-screen.js +22 -6
  4. package/dist/auth-screen.js.map +1 -1
  5. package/dist/bottom-cta.d.ts +6 -1
  6. package/dist/bottom-cta.d.ts.map +1 -1
  7. package/dist/bottom-cta.js +1 -1
  8. package/dist/bottom-cta.js.map +1 -1
  9. package/dist/bottom-navigation.d.ts +10 -0
  10. package/dist/bottom-navigation.d.ts.map +1 -1
  11. package/dist/bottom-navigation.js +80 -8
  12. package/dist/bottom-navigation.js.map +1 -1
  13. package/dist/carousel.d.ts +29 -1
  14. package/dist/carousel.d.ts.map +1 -1
  15. package/dist/carousel.js +27 -3
  16. package/dist/carousel.js.map +1 -1
  17. package/dist/display.d.ts +8 -2
  18. package/dist/display.d.ts.map +1 -1
  19. package/dist/display.js +12 -7
  20. package/dist/display.js.map +1 -1
  21. package/dist/evidence.d.ts +1 -1
  22. package/dist/evidence.js +1 -1
  23. package/dist/evidence.js.map +1 -1
  24. package/dist/forms.d.ts.map +1 -1
  25. package/dist/forms.js +2 -1
  26. package/dist/forms.js.map +1 -1
  27. package/dist/image-choice.d.ts +20 -2
  28. package/dist/image-choice.d.ts.map +1 -1
  29. package/dist/image-choice.js +60 -7
  30. package/dist/image-choice.js.map +1 -1
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +3 -3
  34. package/dist/index.js.map +1 -1
  35. package/dist/internal/field-error.d.ts +19 -0
  36. package/dist/internal/field-error.d.ts.map +1 -0
  37. package/dist/internal/field-error.js +19 -0
  38. package/dist/internal/field-error.js.map +1 -0
  39. package/dist/internal/initial-focus.d.ts.map +1 -1
  40. package/dist/internal/initial-focus.js +49 -7
  41. package/dist/internal/initial-focus.js.map +1 -1
  42. package/dist/internal/media-album.d.ts +70 -0
  43. package/dist/internal/media-album.d.ts.map +1 -0
  44. package/dist/internal/media-album.js +52 -0
  45. package/dist/internal/media-album.js.map +1 -0
  46. package/dist/internal/message-reactions.d.ts +39 -2
  47. package/dist/internal/message-reactions.d.ts.map +1 -1
  48. package/dist/internal/message-reactions.js +31 -6
  49. package/dist/internal/message-reactions.js.map +1 -1
  50. package/dist/layout.d.ts +19 -3
  51. package/dist/layout.d.ts.map +1 -1
  52. package/dist/layout.js +10 -3
  53. package/dist/layout.js.map +1 -1
  54. package/dist/navigation.d.ts +3 -1
  55. package/dist/navigation.d.ts.map +1 -1
  56. package/dist/navigation.js +4 -2
  57. package/dist/navigation.js.map +1 -1
  58. package/dist/number-field.d.ts.map +1 -1
  59. package/dist/number-field.js +2 -1
  60. package/dist/number-field.js.map +1 -1
  61. package/dist/overlays.d.ts +65 -0
  62. package/dist/overlays.d.ts.map +1 -1
  63. package/dist/overlays.js +36 -3
  64. package/dist/overlays.js.map +1 -1
  65. package/dist/pagination.d.ts +13 -11
  66. package/dist/pagination.d.ts.map +1 -1
  67. package/dist/pagination.js +12 -5
  68. package/dist/pagination.js.map +1 -1
  69. package/dist/public-exports.generated.d.ts +8 -0
  70. package/dist/public-exports.generated.d.ts.map +1 -1
  71. package/dist/public-exports.generated.js +24 -0
  72. package/dist/public-exports.generated.js.map +1 -1
  73. package/dist/screen-flows.d.ts +118 -14
  74. package/dist/screen-flows.d.ts.map +1 -1
  75. package/dist/screen-flows.js +95 -23
  76. package/dist/screen-flows.js.map +1 -1
  77. package/dist/screens.d.ts +69 -10
  78. package/dist/screens.d.ts.map +1 -1
  79. package/dist/screens.js +77 -15
  80. package/dist/screens.js.map +1 -1
  81. package/dist/select.d.ts.map +1 -1
  82. package/dist/select.js +2 -1
  83. package/dist/select.js.map +1 -1
  84. package/dist/selection.d.ts.map +1 -1
  85. package/dist/selection.js +3 -2
  86. package/dist/selection.js.map +1 -1
  87. package/dist/steps.d.ts +11 -1
  88. package/dist/steps.d.ts.map +1 -1
  89. package/dist/steps.js +11 -6
  90. package/dist/steps.js.map +1 -1
  91. package/dist/styles.css +181 -22
  92. package/dist/styles.layered.css +181 -22
  93. package/dist/supplemental-display.d.ts.map +1 -1
  94. package/dist/supplemental-display.js +2 -48
  95. package/dist/supplemental-display.js.map +1 -1
  96. package/dist/theme.d.ts.map +1 -1
  97. package/dist/theme.js +1 -0
  98. package/dist/theme.js.map +1 -1
  99. package/dist/toast.d.ts.map +1 -1
  100. package/dist/toast.js +1 -1
  101. package/dist/toast.js.map +1 -1
  102. package/package.json +3 -3
@@ -1,17 +1,17 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
3
- import { screenPatternRecipe } from "@hjmds/design-contracts/screen-patterns";
4
- import { Text } from "../layout.js";
2
+ import { useEffect, useImperativeHandle, useRef, useState } from "react";
3
+ import { chatMessageRecipe, screenPatternRecipe } from "@hjmds/design-contracts/screen-patterns";
4
+ import { Text, VisuallyHidden } from "../layout.js";
5
5
  import { Popover } from "../popover.js";
6
6
  import { ReactionPicker } from "../reaction-picker.js";
7
7
  /** Chat-specific trigger translation; Popover retains collision, focus, Escape and outside dismissal. */
8
- export function MessageReactions({ children, closeLabel, menuAction, interactiveContent = false, triggerClassName = "hjm-chat-message__bubble", replyAction, menuTitle, menuActions = [], reportAction, ...picker }) {
8
+ export function MessageReactions({ children, closeLabel, menuAction, interactiveContent = false, triggerClassName = "hjm-chat-message__bubble", replyAction, menuTitle, menuActions = [], reportAction, menuRef, ...picker }) {
9
9
  // Reply leads and report trails; legacy single menuAction keeps its place before report.
10
10
  const rows = [
11
11
  ...(replyAction ? [{ id: "reply", ...replyAction }] : []),
12
12
  ...menuActions,
13
13
  ...(menuAction ? [{ id: "menu", ...menuAction }] : []),
14
- ...(reportAction ? [{ id: "report", ...reportAction, danger: true }] : []),
14
+ ...(reportAction ? [{ id: "report", ...reportAction, tone: "danger" }] : []),
15
15
  ];
16
16
  const [open, setOpen] = useState(false);
17
17
  const press = useRef(null);
@@ -24,6 +24,8 @@ export function MessageReactions({ children, closeLabel, menuAction, interactive
24
24
  cancel();
25
25
  setOpen(false);
26
26
  } }, [picker.disabled]);
27
+ useImperativeHandle(menuRef, () => ({ open: () => { if (!picker.disabled)
28
+ setOpen(true); } }), [picker.disabled]);
27
29
  return _jsxs(Popover, { open: open && !picker.disabled, onOpenChange: (next) => { if (!next)
28
30
  setOpen(false); }, title: picker.label, closeLabel: closeLabel, descriptor: { placement: "top", align: "start" }, className: "hjm-message-reactions", trigger: _jsx("div", { className: triggerClassName, tabIndex: picker.disabled ? -1 : 0, role: interactiveContent ? "group" : "button", "aria-label": picker.label, "aria-disabled": picker.disabled, onContextMenu: event => { event.preventDefault(); cancel(); if (!picker.disabled)
29
31
  setOpen(true); },
@@ -44,6 +46,29 @@ export function MessageReactions({ children, closeLabel, menuAction, interactive
44
46
  event.preventDefault();
45
47
  event.stopPropagation();
46
48
  held.current = false;
47
- } }, children: children }), children: [picker.options.length ? _jsx(ReactionPicker, { ...picker, layout: "strip", onValueChange: value => { picker.onValueChange(value); setOpen(false); } }) : null, menuTitle || rows.length ? _jsxs("div", { className: "hjm-message-menu", children: [menuTitle ? _jsx(Text, { variant: "caption", tone: "muted", className: "hjm-message-menu__title", children: menuTitle }) : null, rows.map(row => _jsxs("button", { type: "button", className: "hjm-message-menu__item", "data-tone": row.danger ? "danger" : undefined, disabled: row.disabled, onClick: () => { setOpen(false); row.onPress(); }, children: [row.icon ? _jsx("span", { className: "hjm-message-menu__icon", "aria-hidden": "true", children: row.icon }) : null, _jsx("span", { className: "hjm-message-menu__label", children: row.label }), row.submenu ? _jsx("span", { className: "hjm-message-menu__chevron", "aria-hidden": "true", children: "\u203A" }) : null] }, row.id))] }) : null] });
49
+ } }, children: children }), children: [picker.options.length ? _jsx(ReactionPicker, { ...picker, layout: "strip", onValueChange: value => { picker.onValueChange(value); setOpen(false); } }) : null, menuTitle || rows.length ? _jsxs("div", { className: "hjm-message-menu", children: [menuTitle ? _jsx(Text, { variant: "caption", tone: "muted", className: "hjm-message-menu__title", children: menuTitle }) : null, rows.map(row => _jsxs("button", { type: "button", className: "hjm-message-menu__item", "data-tone": row.tone === "danger" ? "danger" : undefined, disabled: row.disabled, onClick: () => { setOpen(false); row.onPress(); }, children: [row.icon ? _jsx("span", { className: "hjm-message-menu__icon", "aria-hidden": "true", children: row.icon }) : null, _jsx("span", { className: "hjm-message-menu__label", children: row.label }), row.submenu ? _jsx("span", { className: "hjm-message-menu__chevron", "aria-hidden": "true", children: "\u203A" }) : null] }, row.id))] }) : null] });
50
+ }
51
+ /** ChatMessage strips its summary before spreading the rest into the hold menu. */
52
+ export function omitReactionSummary({ summary: _summary, ...rest }) {
53
+ return rest;
54
+ }
55
+ /**
56
+ * Current reactions as one button beside the time; pressing it opens the hold menu (the press target and its name
57
+ * are the whole pill, so per-emoji parts are hidden from assistive tech). The pill shows the brand border when the
58
+ * reader's own reaction is among the items.
59
+ */
60
+ export function ReactionSummaryButton({ label, items, selected, disabled, onPress }) {
61
+ const r = chatMessageRecipe.reactionSummary;
62
+ const mine = items.some(item => item.id === selected);
63
+ return _jsx("button", { type: "button", className: "hjm-chat-message__reaction-summary", "aria-label": label, disabled: disabled, "data-selected": mine || undefined, onClick: onPress, style: { minBlockSize: r.minHeight, paddingInline: r.paddingInline, gap: r.itemGap }, children: items.map(item => _jsxs("span", { "aria-hidden": "true", style: { display: "inline-flex", alignItems: "center", gap: r.emojiGap }, children: [_jsx("span", { children: item.emoji }), item.showCount ? _jsx(Text, { as: "span", variant: "caption", children: item.count }) : null] }, item.id)) });
64
+ }
65
+ /**
66
+ * Read-only counts (`summary.readOnly`, 2026-10-18 Utilverse guests who cannot react): the same place and items as
67
+ * the pill, as plain caption text without the pill surface, so it is neither drawn nor announced as a control. The
68
+ * product label is the text screen readers read; the drawn emoji and numbers are hidden from them.
69
+ */
70
+ export function ReactionSummaryText({ label, items }) {
71
+ const r = chatMessageRecipe.reactionSummary;
72
+ return _jsxs("span", { className: "hjm-chat-message__reaction-counts", style: { minBlockSize: r.minHeight, gap: r.itemGap }, children: [_jsx(VisuallyHidden, { children: label }), items.map(item => _jsxs("span", { "aria-hidden": "true", style: { display: "inline-flex", alignItems: "center", gap: r.emojiGap }, children: [_jsx("span", { children: item.emoji }), item.showCount ? _jsx(Text, { as: "span", variant: "caption", tone: "muted", children: item.count }) : null] }, item.id))] });
48
73
  }
49
74
  //# sourceMappingURL=message-reactions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"message-reactions.js","sourceRoot":"","sources":["../../src/internal/message-reactions.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yCAAyC,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,cAAc,EAA4B,MAAM,uBAAuB,CAAC;AAWjF,yGAAyG;AACzG,MAAM,UAAU,gBAAgB,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,kBAAkB,GAAC,KAAK,EAAE,gBAAgB,GAAG,0BAA0B,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,GAAG,EAAE,EAAE,YAAY,EAAE,GAAG,MAAM,EAAS;IACtN,yFAAyF;IACzF,MAAM,IAAI,GAAiD;QACzD,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,GAAG,WAAW;QACd,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3E,CAAC;IACF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,MAAM,CAAwE,IAAI,CAAC,CAAC;IAClG,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,OAAO;QAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrG,SAAS,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,KAAK,CAAC,OAAO;QAAE,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrF,SAAS,CAAC,GAAG,EAAE,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QAAC,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAAC,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3F,OAAO,MAAC,OAAO,IAAC,IAAI,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,EACjJ,UAAU,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,SAAS,EAAC,uBAAuB,EAAC,OAAO,EAAE,cAC3F,SAAS,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,kBAAkB,CAAA,CAAC,CAAA,OAAO,CAAA,CAAC,CAAA,QAAQ,gBAAc,MAAM,CAAC,KAAK,mBAAiB,MAAM,CAAC,QAAQ,EACpK,aAAa,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ;gBAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClG,2FAA2F;YAC3F,kFAAkF;YAClF,SAAS,EAAE,KAAK,CAAC,EAAE,GAAG,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,aAAa,IAAI,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBAAC,KAAK,CAAC,cAAc,EAAE,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAAC,CAAC,CAAC,CAAC,EAChL,aAAa,EAAE,KAAK,CAAC,EAAE;gBACrB,IAAI,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAK,KAAK,CAAC,MAAsB,CAAC,OAAO,CAAC,yBAAyB,CAAC;oBAAE,OAAO;gBACtH,MAAM,EAAE,CAAC;gBAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC/B,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,KAAK,CAAC;gBACzC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,EAAE,CAAC;YACvJ,CAAC,EACD,aAAa,EAAE,KAAK,CAAC,EAAE,GAAG,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,qBAAqB;gBAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EACzL,eAAe,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EACpE,cAAc,EAAE,KAAK,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBAAC,KAAK,CAAC,cAAc,EAAE,CAAC;gBAAC,KAAK,CAAC,eAAe,EAAE,CAAC;gBAAC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;YAAC,CAAC,CAAC,CAAC,YACzH,QAAQ,GAAO,aAEhB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAC,cAAc,OAAK,MAAM,EAAE,MAAM,EAAC,OAAO,EAAC,aAAa,EAAE,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAI,CAAC,CAAC,CAAC,IAAI,EACtJ,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,eAAK,SAAS,EAAC,kBAAkB,aAC1D,SAAS,CAAC,CAAC,CAAC,KAAC,IAAI,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,yBAAyB,YAAE,SAAS,GAAQ,CAAC,CAAC,CAAC,IAAI,EAC9G,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,kBAAqB,IAAI,EAAC,QAAQ,EAAC,SAAS,EAAC,wBAAwB,eAAY,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,aAC3M,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,wBAAwB,iBAAa,MAAM,YAAE,GAAG,CAAC,IAAI,GAAQ,CAAC,CAAC,CAAC,IAAI,EAAC,eAAM,SAAS,EAAC,yBAAyB,YAAE,GAAG,CAAC,KAAK,GAAQ,EAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,2BAA2B,iBAAa,MAAM,uBAAS,CAAC,CAAC,CAAC,IAAI,KAD9N,GAAG,CAAC,EAAE,CACkO,CAAC,IACnQ,CAAC,CAAC,CAAC,IAAI,IACL,CAAC;AACb,CAAC","sourcesContent":["import { useEffect, useRef, useState, type ReactNode } from \"react\";\nimport { screenPatternRecipe } from \"@hjmds/design-contracts/screen-patterns\";\nimport { Text } from \"../layout.js\";\nimport { Popover } from \"../popover.js\";\nimport { ReactionPicker, type ReactionPickerProps } from \"../reaction-picker.js\";\n\n/** One row of the hold menu. Products supply copy and icons; HJM owns order, size and tone. */\nexport type MessageMenuAction = Readonly<{ id: string; label: string; icon?: ReactNode; onPress(): void; disabled?: boolean; /** Shows › for rows that open a further list. */ submenu?: boolean }>;\ntype Props = ReactionPickerProps & Readonly<{ closeLabel: string; menuAction?: Readonly<{label:string;onPress():void;disabled?:boolean}>; children: ReactNode; interactiveContent?:boolean; /** Comments reuse the hold menu without chat bubble styling. */ triggerClassName?: string;\n replyAction?: Readonly<{label:string;onPress():void;disabled?:boolean;icon?:ReactNode}>;\n /** Shown above the actions, e.g. the exact send time that a run only shows once. */\n menuTitle?: string;\n menuActions?: readonly MessageMenuAction[];\n /** Always last and in the danger tone, matching the measured reference menu (2026-10-16). */\n reportAction?: Readonly<{label:string;onPress():void;disabled?:boolean;icon?:ReactNode}> }>;\n/** Chat-specific trigger translation; Popover retains collision, focus, Escape and outside dismissal. */\nexport function MessageReactions({ children, closeLabel, menuAction, interactiveContent=false, triggerClassName = \"hjm-chat-message__bubble\", replyAction, menuTitle, menuActions = [], reportAction, ...picker }: Props) {\n // Reply leads and report trails; legacy single menuAction keeps its place before report.\n const rows: (MessageMenuAction & { danger?: boolean })[] = [\n ...(replyAction ? [{ id: \"reply\", ...replyAction }] : []),\n ...menuActions,\n ...(menuAction ? [{ id: \"menu\", ...menuAction }] : []),\n ...(reportAction ? [{ id: \"report\", ...reportAction, danger: true }] : []),\n ];\n const [open, setOpen] = useState(false);\n const press = useRef<{ timer: ReturnType<typeof setTimeout>; x: number; y: number } | null>(null);\n const held = useRef(false);\n const cancel = () => { if (press.current) clearTimeout(press.current.timer); press.current = null; };\n useEffect(() => () => { if (press.current) clearTimeout(press.current.timer); }, []);\n useEffect(() => { if (picker.disabled) { cancel(); setOpen(false); } }, [picker.disabled]);\n return <Popover open={open && !picker.disabled} onOpenChange={(next) => { if (!next) setOpen(false); }} title={picker.label} closeLabel={closeLabel}\n descriptor={{ placement: \"top\", align: \"start\" }} className=\"hjm-message-reactions\" trigger={<div\n className={triggerClassName} tabIndex={picker.disabled ? -1 : 0} role={interactiveContent?\"group\":\"button\"} aria-label={picker.label} aria-disabled={picker.disabled}\n onContextMenu={event => { event.preventDefault(); cancel(); if (!picker.disabled) setOpen(true); }}\n // Only the bubble itself opens reactions: with interactiveContent, Enter/Space on a nested\n // link or button must keep its native activation instead of being swallowed here.\n onKeyDown={event => { if (event.target === event.currentTarget && (event.key === \"Enter\" || event.key === \" \") && !picker.disabled) { event.preventDefault(); setOpen(true); } }}\n onPointerDown={event => {\n if (picker.disabled || event.button !== 0 || (event.target as HTMLElement).closest(\"button,a,input,textarea\")) return;\n cancel(); held.current = false;\n const { clientX: x, clientY: y } = event;\n press.current = { x, y, timer: setTimeout(() => { held.current = true; press.current = null; setOpen(true); }, screenPatternRecipe.reactionHoldMs) };\n }}\n onPointerMove={event => { const start = press.current; if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > screenPatternRecipe.reactionMoveTolerance) cancel(); }}\n onPointerCancel={cancel} onPointerLeave={cancel} onPointerUp={cancel}\n onClickCapture={event => { if (held.current) { event.preventDefault(); event.stopPropagation(); held.current = false; } }}\n >{children}</div>}>\n {/* Action-only menus (comments, 2026-10-16 reference) pass no options and show no strip. */}\n {picker.options.length ? <ReactionPicker {...picker} layout=\"strip\" onValueChange={value => { picker.onValueChange(value); setOpen(false); }} /> : null}\n {menuTitle || rows.length ? <div className=\"hjm-message-menu\">\n {menuTitle ? <Text variant=\"caption\" tone=\"muted\" className=\"hjm-message-menu__title\">{menuTitle}</Text> : null}\n {rows.map(row => <button key={row.id} type=\"button\" className=\"hjm-message-menu__item\" data-tone={row.danger ? \"danger\" : undefined} disabled={row.disabled} onClick={() => { setOpen(false); row.onPress(); }}>\n {row.icon ? <span className=\"hjm-message-menu__icon\" aria-hidden=\"true\">{row.icon}</span> : null}<span className=\"hjm-message-menu__label\">{row.label}</span>{row.submenu ? <span className=\"hjm-message-menu__chevron\" aria-hidden=\"true\">›</span> : null}</button>)}\n </div> : null}\n </Popover>;\n}\n"]}
1
+ {"version":3,"file":"message-reactions.js","sourceRoot":"","sources":["../../src/internal/message-reactions.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useEffect, useImperativeHandle, useRef, useState, type ReactNode, type Ref } from \"react\";\nimport { chatMessageRecipe, screenPatternRecipe, type ChatReactionSummaryItem } from \"@hjmds/design-contracts/screen-patterns\";\nimport type { MenuItemTone } from \"@hjmds/design-contracts/recipes\";\nimport { Text, VisuallyHidden } from \"../layout.js\";\nimport { Popover } from \"../popover.js\";\nimport { ReactionPicker, type ReactionPickerProps } from \"../reaction-picker.js\";\n\n/** One row of the hold menu. Products supply copy and icons; HJM owns order, size and tone. */\nexport type MessageMenuAction = Readonly<{ id: string; label: string; icon?: ReactNode; onPress(): void; disabled?: boolean; /** Shows › for rows that open a further list. */ submenu?: boolean;\n /** Same vocabulary as Menu items: `danger` for destructive rows such as delete (default `neutral`). */ tone?: MenuItemTone }>;\n/** Lets the owning message open the same hold menu from its reaction summary. */\nexport type MessageReactionsHandle = Readonly<{ open(): void }>;\ntype Props = ReactionPickerProps & Readonly<{ closeLabel: string; menuAction?: Readonly<{label:string;onPress():void;disabled?:boolean}>; children: ReactNode; interactiveContent?:boolean; /** Comments reuse the hold menu without chat bubble styling. */ triggerClassName?: string;\n replyAction?: Readonly<{label:string;onPress():void;disabled?:boolean;icon?:ReactNode}>;\n /** Shown above the actions, e.g. the exact send time that a run only shows once. */\n menuTitle?: string;\n menuActions?: readonly MessageMenuAction[];\n /** Always last and in the danger tone, matching the measured reference menu (2026-10-16). */\n reportAction?: Readonly<{label:string;onPress():void;disabled?:boolean;icon?:ReactNode}>;\n menuRef?: Ref<MessageReactionsHandle> }>;\n/** Chat-specific trigger translation; Popover retains collision, focus, Escape and outside dismissal. */\nexport function MessageReactions({ children, closeLabel, menuAction, interactiveContent=false, triggerClassName = \"hjm-chat-message__bubble\", replyAction, menuTitle, menuActions = [], reportAction, menuRef, ...picker }: Props) {\n // Reply leads and report trails; legacy single menuAction keeps its place before report.\n const rows: MessageMenuAction[] = [\n ...(replyAction ? [{ id: \"reply\", ...replyAction }] : []),\n ...menuActions,\n ...(menuAction ? [{ id: \"menu\", ...menuAction }] : []),\n ...(reportAction ? [{ id: \"report\", ...reportAction, tone: \"danger\" as const }] : []),\n ];\n const [open, setOpen] = useState(false);\n const press = useRef<{ timer: ReturnType<typeof setTimeout>; x: number; y: number } | null>(null);\n const held = useRef(false);\n const cancel = () => { if (press.current) clearTimeout(press.current.timer); press.current = null; };\n useEffect(() => () => { if (press.current) clearTimeout(press.current.timer); }, []);\n useEffect(() => { if (picker.disabled) { cancel(); setOpen(false); } }, [picker.disabled]);\n useImperativeHandle(menuRef, () => ({ open: () => { if (!picker.disabled) setOpen(true); } }), [picker.disabled]);\n return <Popover open={open && !picker.disabled} onOpenChange={(next) => { if (!next) setOpen(false); }} title={picker.label} closeLabel={closeLabel}\n descriptor={{ placement: \"top\", align: \"start\" }} className=\"hjm-message-reactions\" trigger={<div\n className={triggerClassName} tabIndex={picker.disabled ? -1 : 0} role={interactiveContent?\"group\":\"button\"} aria-label={picker.label} aria-disabled={picker.disabled}\n onContextMenu={event => { event.preventDefault(); cancel(); if (!picker.disabled) setOpen(true); }}\n // Only the bubble itself opens reactions: with interactiveContent, Enter/Space on a nested\n // link or button must keep its native activation instead of being swallowed here.\n onKeyDown={event => { if (event.target === event.currentTarget && (event.key === \"Enter\" || event.key === \" \") && !picker.disabled) { event.preventDefault(); setOpen(true); } }}\n onPointerDown={event => {\n if (picker.disabled || event.button !== 0 || (event.target as HTMLElement).closest(\"button,a,input,textarea\")) return;\n cancel(); held.current = false;\n const { clientX: x, clientY: y } = event;\n press.current = { x, y, timer: setTimeout(() => { held.current = true; press.current = null; setOpen(true); }, screenPatternRecipe.reactionHoldMs) };\n }}\n onPointerMove={event => { const start = press.current; if (start && Math.hypot(event.clientX - start.x, event.clientY - start.y) > screenPatternRecipe.reactionMoveTolerance) cancel(); }}\n onPointerCancel={cancel} onPointerLeave={cancel} onPointerUp={cancel}\n onClickCapture={event => { if (held.current) { event.preventDefault(); event.stopPropagation(); held.current = false; } }}\n >{children}</div>}>\n {/* Action-only menus (comments, 2026-10-16 reference) pass no options and show no strip. */}\n {picker.options.length ? <ReactionPicker {...picker} layout=\"strip\" onValueChange={value => { picker.onValueChange(value); setOpen(false); }} /> : null}\n {menuTitle || rows.length ? <div className=\"hjm-message-menu\">\n {menuTitle ? <Text variant=\"caption\" tone=\"muted\" className=\"hjm-message-menu__title\">{menuTitle}</Text> : null}\n {rows.map(row => <button key={row.id} type=\"button\" className=\"hjm-message-menu__item\" data-tone={row.tone === \"danger\" ? \"danger\" : undefined} disabled={row.disabled} onClick={() => { setOpen(false); row.onPress(); }}>\n {row.icon ? <span className=\"hjm-message-menu__icon\" aria-hidden=\"true\">{row.icon}</span> : null}<span className=\"hjm-message-menu__label\">{row.label}</span>{row.submenu ? <span className=\"hjm-message-menu__chevron\" aria-hidden=\"true\">›</span> : null}</button>)}\n </div> : null}\n </Popover>;\n}\n\n/** ChatMessage strips its summary before spreading the rest into the hold menu. */\nexport function omitReactionSummary<T extends Readonly<{ summary?: unknown }>>({ summary: _summary, ...rest }: T): Omit<T, \"summary\"> {\n return rest;\n}\n\n/**\n * Current reactions as one button beside the time; pressing it opens the hold menu (the press target and its name\n * are the whole pill, so per-emoji parts are hidden from assistive tech). The pill shows the brand border when the\n * reader's own reaction is among the items.\n */\nexport function ReactionSummaryButton({ label, items, selected, disabled, onPress }: Readonly<{ label: string; items: readonly (ChatReactionSummaryItem & Readonly<{ showCount: boolean }>)[]; selected: string | null; disabled: boolean; onPress(): void }>) {\n const r = chatMessageRecipe.reactionSummary;\n const mine = items.some(item => item.id === selected);\n return <button type=\"button\" className=\"hjm-chat-message__reaction-summary\" aria-label={label} disabled={disabled} data-selected={mine || undefined} onClick={onPress}\n style={{ minBlockSize: r.minHeight, paddingInline: r.paddingInline, gap: r.itemGap }}>\n {items.map(item => <span key={item.id} aria-hidden=\"true\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: r.emojiGap }}><span>{item.emoji}</span>{item.showCount ? <Text as=\"span\" variant=\"caption\">{item.count}</Text> : null}</span>)}\n </button>;\n}\n\n/**\n * Read-only counts (`summary.readOnly`, 2026-10-18 Utilverse guests who cannot react): the same place and items as\n * the pill, as plain caption text without the pill surface, so it is neither drawn nor announced as a control. The\n * product label is the text screen readers read; the drawn emoji and numbers are hidden from them.\n */\nexport function ReactionSummaryText({ label, items }: Readonly<{ label: string; items: readonly (ChatReactionSummaryItem & Readonly<{ showCount: boolean }>)[] }>) {\n const r = chatMessageRecipe.reactionSummary;\n return <span className=\"hjm-chat-message__reaction-counts\" style={{ minBlockSize: r.minHeight, gap: r.itemGap }}>\n <VisuallyHidden>{label}</VisuallyHidden>\n {items.map(item => <span key={item.id} aria-hidden=\"true\" style={{ display: \"inline-flex\", alignItems: \"center\", gap: r.emojiGap }}><span>{item.emoji}</span>{item.showCount ? <Text as=\"span\" variant=\"caption\" tone=\"muted\">{item.count}</Text> : null}</span>)}\n </span>;\n}\n"]}
package/dist/layout.d.ts CHANGED
@@ -4,7 +4,7 @@ import { type ContainerGutter, type ContainerSize } from "@hjmds/design-contract
4
4
  import { type LayoutSidebarRole } from "@hjmds/design-contracts/components/layout";
5
5
  import { type SurfacePadding, type SurfaceRadius, type SurfaceTone } from "@hjmds/design-contracts/recipes/base";
6
6
  import { type StackAlign, type StackAxis, type StackGap, type StackJustify, type TextEmphasis, type TextTone } from "@hjmds/design-contracts/recipes";
7
- import { type FontRole, type TextVariant } from "@hjmds/design-contracts/foundations";
7
+ import { type FontRole, type NumericVariant, type TextVariant } from "@hjmds/design-contracts/foundations";
8
8
  import { type AnchorHTMLAttributes, type HTMLAttributes, type ReactElement, type ReactNode, type Ref } from "react";
9
9
  import type { HjmCompositionStyleProp } from "./composition-style.js";
10
10
  export type { SurfacePadding, SurfaceRadius, SurfaceTone, } from "@hjmds/design-contracts/recipes/base";
@@ -62,24 +62,40 @@ export declare const Layout: import("react").ForwardRefExoticComponent<Omit<HTML
62
62
  /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
63
63
  layoutStyle?: HjmCompositionStyleProp;
64
64
  }> & import("react").RefAttributes<HTMLDivElement>>;
65
- export type TextProps = Omit<HTMLAttributes<HTMLElement>, "children"> & Readonly<{
65
+ export type TextProps = Omit<HTMLAttributes<HTMLElement>, "children" | "color"> & Readonly<{
66
66
  children: ReactNode;
67
67
  as?: "span" | "p" | "div" | "strong" | "small";
68
68
  variant?: TextVariant;
69
69
  /** Overrides the variant family role; never changes its semantic element or metrics. */
70
70
  fontRole?: FontRole;
71
71
  tone?: TextTone;
72
+ /**
73
+ * Product-owned color role (team, sentiment, chart series) replacing the `tone` color while the HJM variant
74
+ * metrics and font face stay. Mirrors Native, where dropping to a raw text host lost the face (2026-10-18).
75
+ * Replaces the legacy HTML `color` attribute type, which no browser applies to text. Contrast is the product's.
76
+ */
77
+ color?: string;
78
+ /** Digit spacing; `tabular` keeps changing numbers (scores, timers, counts) from shifting the layout. */
79
+ numeric?: NumericVariant;
72
80
  emphasis?: TextEmphasis;
73
81
  /** Canonical layout-only placement. Controlled visual keys are excluded. */
74
82
  layoutStyle?: HjmCompositionStyleProp;
75
83
  }>;
76
- export declare const Text: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLElement>, "children"> & Readonly<{
84
+ export declare const Text: import("react").ForwardRefExoticComponent<Omit<HTMLAttributes<HTMLElement>, "color" | "children"> & Readonly<{
77
85
  children: ReactNode;
78
86
  as?: "span" | "p" | "div" | "strong" | "small";
79
87
  variant?: TextVariant;
80
88
  /** Overrides the variant family role; never changes its semantic element or metrics. */
81
89
  fontRole?: FontRole;
82
90
  tone?: TextTone;
91
+ /**
92
+ * Product-owned color role (team, sentiment, chart series) replacing the `tone` color while the HJM variant
93
+ * metrics and font face stay. Mirrors Native, where dropping to a raw text host lost the face (2026-10-18).
94
+ * Replaces the legacy HTML `color` attribute type, which no browser applies to text. Contrast is the product's.
95
+ */
96
+ color?: string;
97
+ /** Digit spacing; `tabular` keeps changing numbers (scores, timers, counts) from shifting the layout. */
98
+ numeric?: NumericVariant;
83
99
  emphasis?: TextEmphasis;
84
100
  /** Canonical layout-only placement. Controlled visual keys are excluded. */
85
101
  layoutStyle?: HjmCompositionStyleProp;
@@ -1 +1 @@
1
- {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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"}
package/dist/layout.js CHANGED
@@ -9,7 +9,7 @@ import { resolveContainerDescriptor, } from "@hjmds/design-contracts/components/
9
9
  import { layoutRecipe, validateLayoutWebDescriptor, } from "@hjmds/design-contracts/components/layout";
10
10
  import { surfaceDefaults, surfaceGeometry, surfaceRecipe, } from "@hjmds/design-contracts/recipes/base";
11
11
  import { resolveTextDefaultWeight, stackRecipe, textRecipe, } from "@hjmds/design-contracts/recipes";
12
- import { resolveTextFontRole, typography } from "@hjmds/design-contracts/foundations";
12
+ import { numeric as numericVariants, resolveTextFontRole, typography } from "@hjmds/design-contracts/foundations";
13
13
  import { createElement, forwardRef, useId, useRef, } from "react";
14
14
  import { classNames, composeRefs, useElementWidth, useWindowWidth, } from "./internal.js";
15
15
  function hasRegionContent(content) {
@@ -94,7 +94,7 @@ export const Layout = forwardRef(function Layout({ children, header, footer, sid
94
94
  ...mainStyle,
95
95
  }, children: children }), hasFooter ? (_jsx("footer", { ...restFooterProps, className: classNames("hjm-layout__footer", footerClassName), children: footer })) : null] }));
96
96
  });
97
- export const Text = forwardRef(function Text({ as = "span", variant = textRecipe.defaults.variant, fontRole, tone = textRecipe.defaults.tone, emphasis: suppliedEmphasis, className, layoutStyle, style, ...props }, ref) {
97
+ export const Text = forwardRef(function Text({ as = "span", variant = textRecipe.defaults.variant, fontRole, tone = textRecipe.defaults.tone, color, numeric, emphasis: suppliedEmphasis, className, layoutStyle, style, ...props }, ref) {
98
98
  const profile = useDesignProfileDefaults();
99
99
  const emphasis = suppliedEmphasis ?? textRecipe.defaults.emphasis;
100
100
  const defaultWeight = suppliedEmphasis === undefined
@@ -110,7 +110,14 @@ export const Text = forwardRef(function Text({ as = "span", variant = textRecipe
110
110
  "data-emphasis": emphasis,
111
111
  // The variant default weight goes first so caller `style`/placement win, matching Native's style order
112
112
  // (it used to be spread last and overrode an explicit style weight under a profile).
113
- style: { ...(defaultWeight === undefined ? {} : { fontWeight: defaultWeight }), ...style, ...layoutStyle },
113
+ "data-numeric": numeric,
114
+ style: {
115
+ ...(defaultWeight === undefined ? {} : { fontWeight: defaultWeight }),
116
+ ...(color === undefined ? {} : { color }),
117
+ ...(numeric === undefined ? {} : { fontVariantNumeric: numericVariants[numeric] }),
118
+ ...style,
119
+ ...layoutStyle,
120
+ },
114
121
  });
115
122
  });
116
123
  export const Surface = forwardRef(function Surface({ as = "div", tone = surfaceDefaults.tone, bordered, padding = surfaceDefaults.padding, radius = surfaceDefaults.radius, className, layoutStyle, style, ...props }, ref) {
@@ -1 +1 @@
1
- {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n// Layout renderers read profile context; declaring this granular entry keeps server-owned guide text outside the client graph.\n// Root-barrel marking would also move unrelated exports; see docs/qa/2026-10-07-rsc-profile-boundary.md.\nimport { useDesignProfileDefaults } from \"./internal.js\";\nimport {\n resolveGridLayout,\n type GridDescriptor,\n type GridGap,\n} from \"@hjmds/design-contracts/grid\";\nimport {\n resolveAspectRatioDescriptor,\n type AspectRatioValue,\n} from \"@hjmds/design-contracts/components/aspect-ratio\";\nimport {\n resolveContainerDescriptor,\n type ContainerGutter,\n type ContainerSize,\n} from \"@hjmds/design-contracts/components/container\";\nimport {\n layoutRecipe,\n validateLayoutWebDescriptor,\n type LayoutSidebarDescriptor,\n type LayoutSidebarRole,\n} from \"@hjmds/design-contracts/components/layout\";\nimport {\n surfaceDefaults,\n surfaceGeometry,\n surfaceRecipe,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n resolveTextDefaultWeight,\n stackRecipe,\n textRecipe,\n type StackAlign,\n type StackAxis,\n type StackGap,\n type StackJustify,\n type TextEmphasis,\n type TextTone,\n} from \"@hjmds/design-contracts/recipes\";\nimport { resolveTextFontRole, typography, type FontRole, type TextVariant } from \"@hjmds/design-contracts/foundations\";\nimport {\n createElement,\n forwardRef,\n useId,\n useRef,\n type AnchorHTMLAttributes,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n classNames,\n composeRefs,\n useElementWidth,\n useWindowWidth,\n} from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type {\n SurfacePadding,\n SurfaceRadius,\n SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nexport type {\n StackAlign,\n StackAxis,\n StackGap,\n StackJustify,\n TextEmphasis,\n TextTone,\n} from \"@hjmds/design-contracts/recipes\";\n\ntype LayoutRegionProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"children\" | \"role\"\n>;\n\ntype LayoutSidebarBase = Readonly<{\n children: ReactNode;\n role: LayoutSidebarRole;\n label: string;\n landmarkProps?: Omit<LayoutRegionProps, \"aria-label\">;\n landmarkRef?: Ref<HTMLElement>;\n}>;\n\n/**\n * A persistent sidebar is rendered in the shell grid. An overlay sidebar is\n * deliberately handed to the product's SidePanel (or equivalent) through\n * `renderOverlay`; Layout never owns a second open/dismiss lifecycle.\n */\nexport type LayoutSidebar =\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"persistent\";\n renderOverlay?: never;\n }>)\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"overlay\";\n renderOverlay(sidebarLandmark: ReactElement): ReactNode;\n }>);\n\nexport type LayoutProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children: ReactNode;\n header?: ReactNode;\n footer?: ReactNode;\n sidebar?: LayoutSidebar;\n skipLinkLabel?: string;\n /** Stable product id for deep links; a hydration-safe id is generated when omitted. */\n mainId?: string;\n mainRef?: Ref<HTMLElement>;\n headerProps?: LayoutRegionProps;\n mainProps?: Omit<LayoutRegionProps, \"id\" | \"tabIndex\">;\n footerProps?: LayoutRegionProps;\n skipLinkProps?: Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"children\" | \"href\"\n >;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction hasRegionContent(content: ReactNode | undefined): boolean {\n return content !== undefined && content !== null && content !== false;\n}\n\nfunction assertMainId(id: string): void {\n if (id.trim().length === 0) {\n throw new TypeError(\"Layout mainId must not be empty\");\n }\n if (/\\s/u.test(id)) {\n throw new TypeError(\"Layout mainId must not contain whitespace\");\n }\n}\n\n/** Accessible Web app shell with real landmarks and bypass navigation. */\nexport const Layout = forwardRef<HTMLDivElement, LayoutProps>(function Layout(\n {\n children,\n header,\n footer,\n sidebar,\n skipLinkLabel,\n mainId: mainIdProp,\n mainRef: forwardedMainRef,\n headerProps,\n mainProps,\n footerProps,\n skipLinkProps,\n className,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const generatedId = `hjm-main-${useId().replaceAll(\":\", \"\")}`;\n const internalMainRef = useRef<HTMLElement>(null);\n const mainId = mainIdProp ?? generatedId;\n assertMainId(mainId);\n\n const hasHeader = hasRegionContent(header);\n const hasFooter = hasRegionContent(footer);\n const descriptor = {\n ...(hasHeader ? { hasHeader: true } : {}),\n ...(hasFooter ? { hasFooter: true } : {}),\n ...(sidebar === undefined\n ? {}\n : {\n sidebar: {\n role: sidebar.role,\n mode: sidebar.mode,\n label: sidebar.label,\n } satisfies LayoutSidebarDescriptor,\n }),\n ...(skipLinkLabel === undefined ? {} : { skipLinkLabel }),\n };\n validateLayoutWebDescriptor(descriptor);\n\n if (\n sidebar?.mode === \"overlay\" &&\n typeof sidebar.renderOverlay !== \"function\"\n ) {\n throw new TypeError(\n \"Layout overlay sidebar requires renderOverlay so SidePanel owns its lifecycle\",\n );\n }\n\n const {\n className: headerClassName,\n ...restHeaderProps\n } = headerProps ?? {};\n const {\n className: mainClassName,\n style: mainStyle,\n ...restMainProps\n } = mainProps ?? {};\n const {\n className: footerClassName,\n ...restFooterProps\n } = footerProps ?? {};\n const {\n className: skipLinkClassName,\n onClick: onSkipLinkClick,\n ...restSkipLinkProps\n } = skipLinkProps ?? {};\n\n let sidebarNode: ReactNode;\n if (sidebar !== undefined) {\n const {\n className: sidebarClassName,\n style: sidebarStyle,\n ...restSidebarProps\n } = sidebar.landmarkProps ?? {};\n const sidebarLandmark = createElement(\n sidebar.role === \"navigation\" ? \"nav\" : \"aside\",\n {\n ...restSidebarProps,\n ref: sidebar.landmarkRef,\n className: classNames(\"hjm-layout__sidebar\", sidebarClassName),\n \"aria-label\": sidebar.label,\n \"data-mode\": sidebar.mode,\n style: {\n ...(sidebar.mode === \"persistent\"\n ? { inlineSize: layoutRecipe.sidebar.width }\n : {}),\n ...sidebarStyle,\n },\n },\n sidebar.children,\n );\n sidebarNode = sidebar.mode === \"overlay\"\n ? sidebar.renderOverlay(sidebarLandmark)\n : sidebarLandmark;\n }\n\n const moveFocusToMain = (event: MouseEvent<HTMLAnchorElement>) => {\n onSkipLinkClick?.(event);\n if (event.defaultPrevented) return;\n const main = internalMainRef.current;\n if (main === null) return;\n event.preventDefault();\n const url = new URL(window.location.href);\n url.hash = mainId;\n window.history.replaceState(window.history.state, \"\", url);\n main.focus({ preventScroll: true });\n main.scrollIntoView?.({ block: \"start\" });\n };\n\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-layout\", className)}\n data-hjm-component=\"Layout\"\n data-sidebar-mode={sidebar?.mode ?? \"none\"}\n >\n {skipLinkLabel === undefined ? null : (\n <a\n {...restSkipLinkProps}\n href={`#${mainId}`}\n className={classNames(\n \"hjm-layout__skip-link\",\n skipLinkClassName,\n )}\n onClick={moveFocusToMain}\n >\n {skipLinkLabel}\n </a>\n )}\n {hasHeader ? (\n <header\n {...restHeaderProps}\n className={classNames(\"hjm-layout__header\", headerClassName)}\n >\n {header}\n </header>\n ) : null}\n {sidebarNode}\n <main\n {...restMainProps}\n ref={composeRefs(internalMainRef, forwardedMainRef)}\n id={mainId}\n className={classNames(\"hjm-layout__main\", mainClassName)}\n tabIndex={-1}\n style={{\n maxInlineSize: layoutRecipe.main.maxWidth,\n paddingInline: layoutRecipe.main.paddingHorizontal,\n ...mainStyle,\n }}\n >\n {children}\n </main>\n {hasFooter ? (\n <footer\n {...restFooterProps}\n className={classNames(\"hjm-layout__footer\", footerClassName)}\n >\n {footer}\n </footer>\n ) : null}\n </div>\n );\n});\n\nexport type TextProps = Omit<HTMLAttributes<HTMLElement>, \"children\"> &\n Readonly<{\n children: ReactNode;\n as?: \"span\" | \"p\" | \"div\" | \"strong\" | \"small\";\n variant?: TextVariant;\n /** Overrides the variant family role; never changes its semantic element or metrics. */\n fontRole?: FontRole;\n tone?: TextTone;\n emphasis?: TextEmphasis;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Text = forwardRef<HTMLElement, TextProps>(function Text(\n {\n as = \"span\",\n variant = textRecipe.defaults.variant,\n fontRole,\n tone = textRecipe.defaults.tone,\n emphasis: suppliedEmphasis,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const profile = useDesignProfileDefaults();\n const emphasis = suppliedEmphasis ?? textRecipe.defaults.emphasis;\n const defaultWeight = suppliedEmphasis === undefined\n ? resolveTextDefaultWeight(variant, profile?.tokens.typography ?? typography, profile !== undefined)\n : undefined;\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-text\", className),\n \"data-variant\": variant,\n \"data-font-role\": resolveTextFontRole(variant, fontRole ?? (props.role === \"heading\" ? \"display\" : undefined)),\n \"data-tone\": tone,\n \"data-emphasis\": emphasis,\n // The variant default weight goes first so caller `style`/placement win, matching Native's style order\n // (it used to be spread last and overrode an explicit style weight under a profile).\n style: { ...(defaultWeight === undefined ? {} : { fontWeight: defaultWeight }), ...style, ...layoutStyle },\n });\n});\n\nexport type SurfaceProps = HTMLAttributes<HTMLElement> &\n Readonly<{\n as?: \"div\" | \"section\" | \"article\" | \"button\";\n /** Native button host used by interactive Card; passive surfaces remain divs. */\n type?: \"button\";\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Surface = forwardRef<HTMLElement, SurfaceProps>(function Surface(\n {\n as = \"div\",\n tone = surfaceDefaults.tone,\n bordered,\n padding = surfaceDefaults.padding,\n radius = surfaceDefaults.radius,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const contract = surfaceRecipe[tone];\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-surface\", className),\n \"data-tone\": tone,\n // Canvas framing is the default; preserve the caller's explicit border opt-out.\n \"data-bordered\": bordered ?? (surfaceDefaults.bordered || contract.borderAlways),\n \"data-elevated\": contract.elevated,\n \"data-clips\": contract.clipsContent,\n \"data-padding\": padding,\n \"data-radius\": radius,\n style: {\n padding: surfaceGeometry.paddings[padding],\n borderRadius: `var(--hjm-radius-${radius})`,\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type StackProps = HTMLAttributes<HTMLDivElement> &\n Readonly<{\n axis?: StackAxis;\n gap?: StackGap;\n align?: StackAlign;\n justify?: StackJustify;\n wrap?: boolean;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst justifyValues = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n between: \"space-between\",\n} as const;\n\nexport const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(\n {\n axis = stackRecipe.defaults.axis,\n gap = stackRecipe.defaults.gap,\n align = stackRecipe.defaults.align,\n justify = stackRecipe.defaults.justify,\n wrap = stackRecipe.defaults.wrap,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-stack\", className)}\n data-axis={axis}\n data-gap={gap}\n style={{\n display: \"flex\",\n flexDirection: stackRecipe.axes[axis],\n gap: stackRecipe.gaps[gap],\n alignItems: align === \"start\" || align === \"end\" ? `flex-${align}` : align,\n justifyContent: justifyValues[justify],\n flexWrap: wrap ? \"wrap\" : \"nowrap\",\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type ContainerProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n size?: ContainerSize;\n gutter?: ContainerGutter;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** A centered, token-guttered content boundary shared with Native large screens. */\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container(\n { size, gutter, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveContainerDescriptor({\n ...(size === undefined ? {} : { size }),\n ...(gutter === undefined ? {} : { gutter }),\n });\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-container\", className)}\n data-size={resolved.size}\n data-gutter={resolved.gutter}\n style={{\n maxInlineSize: resolved.maxWidth ?? undefined,\n paddingInline: resolved.paddingInline,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type AspectRatioProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n ratio?: AspectRatioValue;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Responsive media frame. Products retain object-fit, crop, and content semantics. */\nexport const AspectRatio = forwardRef<HTMLDivElement, AspectRatioProps>(function AspectRatio(\n { ratio, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveAspectRatioDescriptor(\n ratio === undefined ? {} : { ratio },\n );\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-aspect-ratio\", className)}\n data-ratio={resolved.source}\n style={{ ...layoutStyle, aspectRatio: resolved.ratio, ...style }}\n />\n );\n});\n\n// No `layoutStyle`: the element is clipped to 1px by design, so placement has no visible effect.\nexport type VisuallyHiddenProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{ children: ReactNode }>;\n\n/** Keeps meaningful copy available to assistive technology without visible layout. */\nexport const VisuallyHidden = forwardRef<HTMLSpanElement, VisuallyHiddenProps>(\n function VisuallyHidden({ className, ...props }, ref) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-visually-hidden\", className)}\n />\n );\n },\n);\n\nexport type GridProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Pick<GridDescriptor, \"columns\" | \"gap\" | \"minColumnWidth\"> &\n Readonly<{\n children?: ReactNode;\n /** Test/SSR override. Browser renderers otherwise observe window.innerWidth. */\n windowWidth?: number;\n /** Container measurement override; ResizeObserver is used when omitted. */\n availableWidth?: number;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Grid = forwardRef<HTMLDivElement, GridProps>(function Grid(\n {\n columns,\n gap,\n minColumnWidth,\n windowWidth,\n availableWidth,\n className,\n layoutStyle,\n style,\n ...props\n },\n forwardedRef,\n) {\n const browserWindowWidth = useWindowWidth();\n const [measuredWidth, gridRef] = useElementWidth(forwardedRef);\n const compactSsrWidth = 320;\n const effectiveWindowWidth =\n windowWidth ??\n (browserWindowWidth > 0 ? browserWindowWidth : compactSsrWidth);\n const effectiveAvailableWidth =\n availableWidth ??\n (measuredWidth !== undefined && measuredWidth > 0\n ? measuredWidth\n : effectiveWindowWidth);\n const descriptor: GridDescriptor = {\n columns,\n ...(gap === undefined ? {} : { gap }),\n ...(minColumnWidth === undefined ? {} : { minColumnWidth }),\n };\n const layout = resolveGridLayout(descriptor, {\n windowWidth: effectiveWindowWidth,\n availableWidth: effectiveAvailableWidth,\n });\n\n return (\n <div\n {...props}\n ref={gridRef}\n className={classNames(\"hjm-grid\", className)}\n data-window-class={layout.windowClass}\n data-columns={layout.columns}\n data-requested-columns={layout.requestedColumns}\n data-state={layout.columns < layout.requestedColumns ? \"collapsed\" : \"resolved\"}\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${layout.columns}, minmax(0, 1fr))`,\n rowGap: layout.rowGap,\n columnGap: layout.columnGap,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type SectionProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n children: ReactNode;\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Large-text-safe semantic content section with an optional header action. */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n title,\n description,\n action,\n children,\n headingLevel = 2,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const hasHeader = title !== undefined || description !== undefined || action !== undefined;\n return (\n <section {...props} style={{ ...style, ...layoutStyle }} ref={ref} className={classNames(\"hjm-section\", className)}>\n {hasHeader ? (\n <header className=\"hjm-section__header\">\n <div className=\"hjm-section__copy\">\n {title === undefined ? null : createElement(\n `h${headingLevel}`,\n { className: \"hjm-section__title\" },\n title,\n )}\n {description === undefined ? null : (\n <div className=\"hjm-section__description\">{description}</div>\n )}\n </div>\n {action === undefined ? null : <div className=\"hjm-section__action\">{action}</div>}\n </header>\n ) : null}\n <div className=\"hjm-section__content\">{children}</div>\n </section>\n );\n});\n\nexport type { GridGap };\nexport type { AspectRatioValue, ContainerGutter, ContainerSize };\n"]}
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../src/layout.tsx"],"names":[],"mappings":"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","sourcesContent":["\"use client\";\n\n// Layout renderers read profile context; declaring this granular entry keeps server-owned guide text outside the client graph.\n// Root-barrel marking would also move unrelated exports; see docs/qa/2026-10-07-rsc-profile-boundary.md.\nimport { useDesignProfileDefaults } from \"./internal.js\";\nimport {\n resolveGridLayout,\n type GridDescriptor,\n type GridGap,\n} from \"@hjmds/design-contracts/grid\";\nimport {\n resolveAspectRatioDescriptor,\n type AspectRatioValue,\n} from \"@hjmds/design-contracts/components/aspect-ratio\";\nimport {\n resolveContainerDescriptor,\n type ContainerGutter,\n type ContainerSize,\n} from \"@hjmds/design-contracts/components/container\";\nimport {\n layoutRecipe,\n validateLayoutWebDescriptor,\n type LayoutSidebarDescriptor,\n type LayoutSidebarRole,\n} from \"@hjmds/design-contracts/components/layout\";\nimport {\n surfaceDefaults,\n surfaceGeometry,\n surfaceRecipe,\n type SurfacePadding,\n type SurfaceRadius,\n type SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nimport {\n resolveTextDefaultWeight,\n stackRecipe,\n textRecipe,\n type StackAlign,\n type StackAxis,\n type StackGap,\n type StackJustify,\n type TextEmphasis,\n type TextTone,\n} from \"@hjmds/design-contracts/recipes\";\nimport { numeric as numericVariants, resolveTextFontRole, typography, type FontRole, type NumericVariant, type TextVariant } from \"@hjmds/design-contracts/foundations\";\nimport {\n createElement,\n forwardRef,\n useId,\n useRef,\n type AnchorHTMLAttributes,\n type HTMLAttributes,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n type Ref,\n} from \"react\";\nimport {\n classNames,\n composeRefs,\n useElementWidth,\n useWindowWidth,\n} from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type {\n SurfacePadding,\n SurfaceRadius,\n SurfaceTone,\n} from \"@hjmds/design-contracts/recipes/base\";\nexport type {\n StackAlign,\n StackAxis,\n StackGap,\n StackJustify,\n TextEmphasis,\n TextTone,\n} from \"@hjmds/design-contracts/recipes\";\n\ntype LayoutRegionProps = Omit<\n HTMLAttributes<HTMLElement>,\n \"children\" | \"role\"\n>;\n\ntype LayoutSidebarBase = Readonly<{\n children: ReactNode;\n role: LayoutSidebarRole;\n label: string;\n landmarkProps?: Omit<LayoutRegionProps, \"aria-label\">;\n landmarkRef?: Ref<HTMLElement>;\n}>;\n\n/**\n * A persistent sidebar is rendered in the shell grid. An overlay sidebar is\n * deliberately handed to the product's SidePanel (or equivalent) through\n * `renderOverlay`; Layout never owns a second open/dismiss lifecycle.\n */\nexport type LayoutSidebar =\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"persistent\";\n renderOverlay?: never;\n }>)\n | (LayoutSidebarBase &\n Readonly<{\n mode: \"overlay\";\n renderOverlay(sidebarLandmark: ReactElement): ReactNode;\n }>);\n\nexport type LayoutProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children: ReactNode;\n header?: ReactNode;\n footer?: ReactNode;\n sidebar?: LayoutSidebar;\n skipLinkLabel?: string;\n /** Stable product id for deep links; a hydration-safe id is generated when omitted. */\n mainId?: string;\n mainRef?: Ref<HTMLElement>;\n headerProps?: LayoutRegionProps;\n mainProps?: Omit<LayoutRegionProps, \"id\" | \"tabIndex\">;\n footerProps?: LayoutRegionProps;\n skipLinkProps?: Omit<\n AnchorHTMLAttributes<HTMLAnchorElement>,\n \"children\" | \"href\"\n >;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nfunction hasRegionContent(content: ReactNode | undefined): boolean {\n return content !== undefined && content !== null && content !== false;\n}\n\nfunction assertMainId(id: string): void {\n if (id.trim().length === 0) {\n throw new TypeError(\"Layout mainId must not be empty\");\n }\n if (/\\s/u.test(id)) {\n throw new TypeError(\"Layout mainId must not contain whitespace\");\n }\n}\n\n/** Accessible Web app shell with real landmarks and bypass navigation. */\nexport const Layout = forwardRef<HTMLDivElement, LayoutProps>(function Layout(\n {\n children,\n header,\n footer,\n sidebar,\n skipLinkLabel,\n mainId: mainIdProp,\n mainRef: forwardedMainRef,\n headerProps,\n mainProps,\n footerProps,\n skipLinkProps,\n className,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const generatedId = `hjm-main-${useId().replaceAll(\":\", \"\")}`;\n const internalMainRef = useRef<HTMLElement>(null);\n const mainId = mainIdProp ?? generatedId;\n assertMainId(mainId);\n\n const hasHeader = hasRegionContent(header);\n const hasFooter = hasRegionContent(footer);\n const descriptor = {\n ...(hasHeader ? { hasHeader: true } : {}),\n ...(hasFooter ? { hasFooter: true } : {}),\n ...(sidebar === undefined\n ? {}\n : {\n sidebar: {\n role: sidebar.role,\n mode: sidebar.mode,\n label: sidebar.label,\n } satisfies LayoutSidebarDescriptor,\n }),\n ...(skipLinkLabel === undefined ? {} : { skipLinkLabel }),\n };\n validateLayoutWebDescriptor(descriptor);\n\n if (\n sidebar?.mode === \"overlay\" &&\n typeof sidebar.renderOverlay !== \"function\"\n ) {\n throw new TypeError(\n \"Layout overlay sidebar requires renderOverlay so SidePanel owns its lifecycle\",\n );\n }\n\n const {\n className: headerClassName,\n ...restHeaderProps\n } = headerProps ?? {};\n const {\n className: mainClassName,\n style: mainStyle,\n ...restMainProps\n } = mainProps ?? {};\n const {\n className: footerClassName,\n ...restFooterProps\n } = footerProps ?? {};\n const {\n className: skipLinkClassName,\n onClick: onSkipLinkClick,\n ...restSkipLinkProps\n } = skipLinkProps ?? {};\n\n let sidebarNode: ReactNode;\n if (sidebar !== undefined) {\n const {\n className: sidebarClassName,\n style: sidebarStyle,\n ...restSidebarProps\n } = sidebar.landmarkProps ?? {};\n const sidebarLandmark = createElement(\n sidebar.role === \"navigation\" ? \"nav\" : \"aside\",\n {\n ...restSidebarProps,\n ref: sidebar.landmarkRef,\n className: classNames(\"hjm-layout__sidebar\", sidebarClassName),\n \"aria-label\": sidebar.label,\n \"data-mode\": sidebar.mode,\n style: {\n ...(sidebar.mode === \"persistent\"\n ? { inlineSize: layoutRecipe.sidebar.width }\n : {}),\n ...sidebarStyle,\n },\n },\n sidebar.children,\n );\n sidebarNode = sidebar.mode === \"overlay\"\n ? sidebar.renderOverlay(sidebarLandmark)\n : sidebarLandmark;\n }\n\n const moveFocusToMain = (event: MouseEvent<HTMLAnchorElement>) => {\n onSkipLinkClick?.(event);\n if (event.defaultPrevented) return;\n const main = internalMainRef.current;\n if (main === null) return;\n event.preventDefault();\n const url = new URL(window.location.href);\n url.hash = mainId;\n window.history.replaceState(window.history.state, \"\", url);\n main.focus({ preventScroll: true });\n main.scrollIntoView?.({ block: \"start\" });\n };\n\n return (\n <div\n {...props}\n style={{ ...props.style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-layout\", className)}\n data-hjm-component=\"Layout\"\n data-sidebar-mode={sidebar?.mode ?? \"none\"}\n >\n {skipLinkLabel === undefined ? null : (\n <a\n {...restSkipLinkProps}\n href={`#${mainId}`}\n className={classNames(\n \"hjm-layout__skip-link\",\n skipLinkClassName,\n )}\n onClick={moveFocusToMain}\n >\n {skipLinkLabel}\n </a>\n )}\n {hasHeader ? (\n <header\n {...restHeaderProps}\n className={classNames(\"hjm-layout__header\", headerClassName)}\n >\n {header}\n </header>\n ) : null}\n {sidebarNode}\n <main\n {...restMainProps}\n ref={composeRefs(internalMainRef, forwardedMainRef)}\n id={mainId}\n className={classNames(\"hjm-layout__main\", mainClassName)}\n tabIndex={-1}\n style={{\n maxInlineSize: layoutRecipe.main.maxWidth,\n paddingInline: layoutRecipe.main.paddingHorizontal,\n ...mainStyle,\n }}\n >\n {children}\n </main>\n {hasFooter ? (\n <footer\n {...restFooterProps}\n className={classNames(\"hjm-layout__footer\", footerClassName)}\n >\n {footer}\n </footer>\n ) : null}\n </div>\n );\n});\n\nexport type TextProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"color\"> &\n Readonly<{\n children: ReactNode;\n as?: \"span\" | \"p\" | \"div\" | \"strong\" | \"small\";\n variant?: TextVariant;\n /** Overrides the variant family role; never changes its semantic element or metrics. */\n fontRole?: FontRole;\n tone?: TextTone;\n /**\n * Product-owned color role (team, sentiment, chart series) replacing the `tone` color while the HJM variant\n * metrics and font face stay. Mirrors Native, where dropping to a raw text host lost the face (2026-10-18).\n * Replaces the legacy HTML `color` attribute type, which no browser applies to text. Contrast is the product's.\n */\n color?: string;\n /** Digit spacing; `tabular` keeps changing numbers (scores, timers, counts) from shifting the layout. */\n numeric?: NumericVariant;\n emphasis?: TextEmphasis;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Text = forwardRef<HTMLElement, TextProps>(function Text(\n {\n as = \"span\",\n variant = textRecipe.defaults.variant,\n fontRole,\n tone = textRecipe.defaults.tone,\n color,\n numeric,\n emphasis: suppliedEmphasis,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const profile = useDesignProfileDefaults();\n const emphasis = suppliedEmphasis ?? textRecipe.defaults.emphasis;\n const defaultWeight = suppliedEmphasis === undefined\n ? resolveTextDefaultWeight(variant, profile?.tokens.typography ?? typography, profile !== undefined)\n : undefined;\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-text\", className),\n \"data-variant\": variant,\n \"data-font-role\": resolveTextFontRole(variant, fontRole ?? (props.role === \"heading\" ? \"display\" : undefined)),\n \"data-tone\": tone,\n \"data-emphasis\": emphasis,\n // The variant default weight goes first so caller `style`/placement win, matching Native's style order\n // (it used to be spread last and overrode an explicit style weight under a profile).\n \"data-numeric\": numeric,\n style: {\n ...(defaultWeight === undefined ? {} : { fontWeight: defaultWeight }),\n ...(color === undefined ? {} : { color }),\n ...(numeric === undefined ? {} : { fontVariantNumeric: numericVariants[numeric] }),\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type SurfaceProps = HTMLAttributes<HTMLElement> &\n Readonly<{\n as?: \"div\" | \"section\" | \"article\" | \"button\";\n /** Native button host used by interactive Card; passive surfaces remain divs. */\n type?: \"button\";\n disabled?: boolean;\n tone?: SurfaceTone;\n bordered?: boolean;\n padding?: SurfacePadding;\n radius?: SurfaceRadius;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Surface = forwardRef<HTMLElement, SurfaceProps>(function Surface(\n {\n as = \"div\",\n tone = surfaceDefaults.tone,\n bordered,\n padding = surfaceDefaults.padding,\n radius = surfaceDefaults.radius,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const contract = surfaceRecipe[tone];\n return createElement(as, {\n ...props,\n ref,\n className: classNames(\"hjm-surface\", className),\n \"data-tone\": tone,\n // Canvas framing is the default; preserve the caller's explicit border opt-out.\n \"data-bordered\": bordered ?? (surfaceDefaults.bordered || contract.borderAlways),\n \"data-elevated\": contract.elevated,\n \"data-clips\": contract.clipsContent,\n \"data-padding\": padding,\n \"data-radius\": radius,\n style: {\n padding: surfaceGeometry.paddings[padding],\n borderRadius: `var(--hjm-radius-${radius})`,\n ...style,\n ...layoutStyle,\n },\n });\n});\n\nexport type StackProps = HTMLAttributes<HTMLDivElement> &\n Readonly<{\n axis?: StackAxis;\n gap?: StackGap;\n align?: StackAlign;\n justify?: StackJustify;\n wrap?: boolean;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nconst justifyValues = {\n start: \"flex-start\",\n center: \"center\",\n end: \"flex-end\",\n between: \"space-between\",\n} as const;\n\nexport const Stack = forwardRef<HTMLDivElement, StackProps>(function Stack(\n {\n axis = stackRecipe.defaults.axis,\n gap = stackRecipe.defaults.gap,\n align = stackRecipe.defaults.align,\n justify = stackRecipe.defaults.justify,\n wrap = stackRecipe.defaults.wrap,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-stack\", className)}\n data-axis={axis}\n data-gap={gap}\n style={{\n display: \"flex\",\n flexDirection: stackRecipe.axes[axis],\n gap: stackRecipe.gaps[gap],\n alignItems: align === \"start\" || align === \"end\" ? `flex-${align}` : align,\n justifyContent: justifyValues[justify],\n flexWrap: wrap ? \"wrap\" : \"nowrap\",\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type ContainerProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n size?: ContainerSize;\n gutter?: ContainerGutter;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** A centered, token-guttered content boundary shared with Native large screens. */\nexport const Container = forwardRef<HTMLDivElement, ContainerProps>(function Container(\n { size, gutter, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveContainerDescriptor({\n ...(size === undefined ? {} : { size }),\n ...(gutter === undefined ? {} : { gutter }),\n });\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-container\", className)}\n data-size={resolved.size}\n data-gutter={resolved.gutter}\n style={{\n maxInlineSize: resolved.maxWidth ?? undefined,\n paddingInline: resolved.paddingInline,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type AspectRatioProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n children?: ReactNode;\n ratio?: AspectRatioValue;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Responsive media frame. Products retain object-fit, crop, and content semantics. */\nexport const AspectRatio = forwardRef<HTMLDivElement, AspectRatioProps>(function AspectRatio(\n { ratio, className, layoutStyle, style, ...props },\n ref,\n) {\n const resolved = resolveAspectRatioDescriptor(\n ratio === undefined ? {} : { ratio },\n );\n return (\n <div\n {...props}\n ref={ref}\n className={classNames(\"hjm-aspect-ratio\", className)}\n data-ratio={resolved.source}\n style={{ ...layoutStyle, aspectRatio: resolved.ratio, ...style }}\n />\n );\n});\n\n// No `layoutStyle`: the element is clipped to 1px by design, so placement has no visible effect.\nexport type VisuallyHiddenProps = HTMLAttributes<HTMLSpanElement> &\n Readonly<{ children: ReactNode }>;\n\n/** Keeps meaningful copy available to assistive technology without visible layout. */\nexport const VisuallyHidden = forwardRef<HTMLSpanElement, VisuallyHiddenProps>(\n function VisuallyHidden({ className, ...props }, ref) {\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-visually-hidden\", className)}\n />\n );\n },\n);\n\nexport type GridProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Pick<GridDescriptor, \"columns\" | \"gap\" | \"minColumnWidth\"> &\n Readonly<{\n children?: ReactNode;\n /** Test/SSR override. Browser renderers otherwise observe window.innerWidth. */\n windowWidth?: number;\n /** Container measurement override; ResizeObserver is used when omitted. */\n availableWidth?: number;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Grid = forwardRef<HTMLDivElement, GridProps>(function Grid(\n {\n columns,\n gap,\n minColumnWidth,\n windowWidth,\n availableWidth,\n className,\n layoutStyle,\n style,\n ...props\n },\n forwardedRef,\n) {\n const browserWindowWidth = useWindowWidth();\n const [measuredWidth, gridRef] = useElementWidth(forwardedRef);\n const compactSsrWidth = 320;\n const effectiveWindowWidth =\n windowWidth ??\n (browserWindowWidth > 0 ? browserWindowWidth : compactSsrWidth);\n const effectiveAvailableWidth =\n availableWidth ??\n (measuredWidth !== undefined && measuredWidth > 0\n ? measuredWidth\n : effectiveWindowWidth);\n const descriptor: GridDescriptor = {\n columns,\n ...(gap === undefined ? {} : { gap }),\n ...(minColumnWidth === undefined ? {} : { minColumnWidth }),\n };\n const layout = resolveGridLayout(descriptor, {\n windowWidth: effectiveWindowWidth,\n availableWidth: effectiveAvailableWidth,\n });\n\n return (\n <div\n {...props}\n ref={gridRef}\n className={classNames(\"hjm-grid\", className)}\n data-window-class={layout.windowClass}\n data-columns={layout.columns}\n data-requested-columns={layout.requestedColumns}\n data-state={layout.columns < layout.requestedColumns ? \"collapsed\" : \"resolved\"}\n style={{\n display: \"grid\",\n gridTemplateColumns: `repeat(${layout.columns}, minmax(0, 1fr))`,\n rowGap: layout.rowGap,\n columnGap: layout.columnGap,\n ...style,\n ...layoutStyle,\n }}\n />\n );\n});\n\nexport type SectionProps = Omit<HTMLAttributes<HTMLElement>, \"children\" | \"title\"> &\n Readonly<{\n title?: ReactNode;\n description?: ReactNode;\n action?: ReactNode;\n children: ReactNode;\n headingLevel?: 2 | 3 | 4 | 5 | 6;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/** Large-text-safe semantic content section with an optional header action. */\nexport const Section = forwardRef<HTMLElement, SectionProps>(function Section(\n {\n title,\n description,\n action,\n children,\n headingLevel = 2,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n) {\n const hasHeader = title !== undefined || description !== undefined || action !== undefined;\n return (\n <section {...props} style={{ ...style, ...layoutStyle }} ref={ref} className={classNames(\"hjm-section\", className)}>\n {hasHeader ? (\n <header className=\"hjm-section__header\">\n <div className=\"hjm-section__copy\">\n {title === undefined ? null : createElement(\n `h${headingLevel}`,\n { className: \"hjm-section__title\" },\n title,\n )}\n {description === undefined ? null : (\n <div className=\"hjm-section__description\">{description}</div>\n )}\n </div>\n {action === undefined ? null : <div className=\"hjm-section__action\">{action}</div>}\n </header>\n ) : null}\n <div className=\"hjm-section__content\">{children}</div>\n </section>\n );\n});\n\nexport type { GridGap };\nexport type { AspectRatioValue, ContainerGutter, ContainerSize };\n"]}
@@ -1,7 +1,7 @@
1
1
  import { type TabSwipePosition, type TabsAppearance } from "@hjmds/design-contracts/gooey-navigation";
2
2
  export type { TabsAppearance };
3
3
  import { type TabsActivationMode, type TabsDirection, type TabsMountPolicy, type TabsOrientation, type TabsPanelMode } from "@hjmds/design-contracts/behaviors";
4
- import { type TabSize, type TabsLayout, type TabsOverflow } from "@hjmds/design-contracts/recipes";
4
+ import { type TabSize, type TabsIndicator, type TabsLayout, type TabsOverflow } from "@hjmds/design-contracts/recipes";
5
5
  import { type HTMLAttributes, type ReactNode } from "react";
6
6
  import type { HjmCompositionStyleProp } from "./composition-style.js";
7
7
  export type TabLeadingRenderProps = Readonly<{
@@ -42,6 +42,8 @@ export type TabsProps = Omit<HTMLAttributes<HTMLDivElement>, "dir" | "onChange">
42
42
  size?: TabSize;
43
43
  layout?: TabsLayout;
44
44
  overflow?: TabsOverflow;
45
+ /** Selection mark: the 2pt underline (default) or a brand-tinted pill behind the selected tab. */
46
+ indicator?: TabsIndicator;
45
47
  /** Set false when panels are rendered separately with `TabPanel`. */
46
48
  renderPanels?: boolean;
47
49
  /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../src/navigation.tsx"],"names":[],"mappings":"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"}
@@ -81,10 +81,12 @@ export function TabPanel(props) {
81
81
  return (_jsx(TabPanelHost, { ...hostProps, id: getTabPanelId(tabsId, value, dynamic ? "dynamic" : "keyed"), labelledBy: getTabId(tabsId, dynamic ? activeValue : value), selected: selected, dynamic: dynamic, children: children }));
82
82
  }
83
83
  export const Tabs = forwardRef(function Tabs(props, ref) {
84
- const { label, items, activationMode = tabsBehaviorDefaults.activationMode, mountPolicy = tabsBehaviorDefaults.mountPolicy, panelMode = tabsBehaviorDefaults.panelMode, appearance: suppliedAppearance, swipePosition, orientation = tabsBehaviorDefaults.orientation, direction: directionProp, loop = tabsBehaviorDefaults.loop, size = tabsRecipe.defaults.size, layout = tabsRecipe.defaults.layout, overflow = tabsRecipe.defaults.overflow, renderPanels = true, className, id, value: valueProp, defaultValue, onValueChange, layoutStyle, ...rest } = props;
84
+ const { label, items, activationMode = tabsBehaviorDefaults.activationMode, mountPolicy = tabsBehaviorDefaults.mountPolicy, panelMode = tabsBehaviorDefaults.panelMode, appearance: suppliedAppearance, swipePosition, orientation = tabsBehaviorDefaults.orientation, direction: directionProp, loop = tabsBehaviorDefaults.loop, size = tabsRecipe.defaults.size, layout = tabsRecipe.defaults.layout, overflow = tabsRecipe.defaults.overflow, indicator = tabsRecipe.defaults.indicator, renderPanels = true, className, id, value: valueProp, defaultValue, onValueChange, layoutStyle, ...rest } = props;
85
85
  validateItems(items);
86
86
  if (label.trim().length === 0)
87
87
  throw new TypeError("Tabs label must not be empty");
88
+ if (!(indicator in tabsRecipe.indicators))
89
+ throw new TypeError(`Unsupported Tabs indicator: ${String(indicator)}`);
88
90
  if (panelMode === "dynamic" && mountPolicy !== "active") {
89
91
  throw new TypeError("Tabs dynamic panelMode requires active mountPolicy");
90
92
  }
@@ -271,7 +273,7 @@ export const Tabs = forwardRef(function Tabs(props, ref) {
271
273
  }
272
274
  };
273
275
  const panelId = (value) => getTabPanelId(baseId, value, panelMode);
274
- return (_jsxs("div", { ...rest, style: { ...rest.style, ...layoutStyle }, ref: ref, id: baseId, className: classNames("hjm-tabs", className), "data-size": size, "data-layout": layout, "data-overflow": overflow, "data-appearance": appearance, "data-orientation": orientation, "data-mount-policy": mountPolicy, "data-panel-mode": panelMode, "data-state": "ready", dir: direction, children: [_jsxs("div", { className: "hjm-tabs__list", role: "tablist", "aria-label": label, "aria-orientation": orientation, children: [movingIndicator ? _jsx("span", { ref: indicatorRef, "aria-hidden": "true", className: classNames("hjm-tabs__indicator", appearance === "gooey" && "hjm-tabs__gooey") }) : null, items.map((item) => {
276
+ return (_jsxs("div", { ...rest, style: { ...rest.style, ...layoutStyle }, ref: ref, id: baseId, className: classNames("hjm-tabs", className), "data-size": size, "data-layout": layout, "data-overflow": overflow, "data-appearance": appearance, "data-indicator": indicator, "data-indicator-motion": movingIndicator ? "moving" : "static", "data-orientation": orientation, "data-mount-policy": mountPolicy, "data-panel-mode": panelMode, "data-state": "ready", dir: direction, children: [_jsxs("div", { className: "hjm-tabs__list", role: "tablist", "aria-label": label, "aria-orientation": orientation, children: [movingIndicator ? _jsx("span", { ref: indicatorRef, "aria-hidden": "true", className: classNames("hjm-tabs__indicator", appearance === "gooey" && "hjm-tabs__gooey") }) : null, items.map((item) => {
275
277
  const selected = item.id === value;
276
278
  const tabId = getTabId(baseId, item.id);
277
279
  const leadingSize = iconRecipe.sizes[tabsRecipe.icon.glyph];