@hjmds/react 1.34.0 → 1.35.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 (137) hide show
  1. package/dist/actions.d.ts +23 -2
  2. package/dist/actions.d.ts.map +1 -1
  3. package/dist/actions.js +61 -6
  4. package/dist/actions.js.map +1 -1
  5. package/dist/advanced-display.d.ts +35 -2
  6. package/dist/advanced-display.d.ts.map +1 -1
  7. package/dist/advanced-display.js +28 -9
  8. package/dist/advanced-display.js.map +1 -1
  9. package/dist/anchor.d.ts +3 -1
  10. package/dist/anchor.d.ts.map +1 -1
  11. package/dist/anchor.js +5 -5
  12. package/dist/anchor.js.map +1 -1
  13. package/dist/auth-screen.d.ts.map +1 -1
  14. package/dist/auth-screen.js +5 -2
  15. package/dist/auth-screen.js.map +1 -1
  16. package/dist/avatar-blobatar-motion.d.ts.map +1 -1
  17. package/dist/avatar-blobatar-motion.js +2 -1
  18. package/dist/avatar-blobatar-motion.js.map +1 -1
  19. package/dist/avatar-blobatar.d.ts.map +1 -1
  20. package/dist/avatar-blobatar.js +2 -1
  21. package/dist/avatar-blobatar.js.map +1 -1
  22. package/dist/bottom-cta.d.ts +8 -1
  23. package/dist/bottom-cta.d.ts.map +1 -1
  24. package/dist/bottom-cta.js +6 -2
  25. package/dist/bottom-cta.js.map +1 -1
  26. package/dist/carousel-motion.d.ts.map +1 -1
  27. package/dist/carousel-motion.js +11 -2
  28. package/dist/carousel-motion.js.map +1 -1
  29. package/dist/carousel.d.ts +10 -0
  30. package/dist/carousel.d.ts.map +1 -1
  31. package/dist/carousel.js +23 -7
  32. package/dist/carousel.js.map +1 -1
  33. package/dist/collapsible.d.ts +6 -0
  34. package/dist/collapsible.d.ts.map +1 -1
  35. package/dist/collapsible.js +22 -20
  36. package/dist/collapsible.js.map +1 -1
  37. package/dist/collection-rail.d.ts +4 -4
  38. package/dist/collection-rail.d.ts.map +1 -1
  39. package/dist/collection-rail.js.map +1 -1
  40. package/dist/conversation-row.d.ts.map +1 -1
  41. package/dist/conversation-row.js +4 -1
  42. package/dist/conversation-row.js.map +1 -1
  43. package/dist/data-table.d.ts +2 -0
  44. package/dist/data-table.d.ts.map +1 -1
  45. package/dist/data-table.js +2 -2
  46. package/dist/data-table.js.map +1 -1
  47. package/dist/display.d.ts +60 -5
  48. package/dist/display.d.ts.map +1 -1
  49. package/dist/display.js +32 -9
  50. package/dist/display.js.map +1 -1
  51. package/dist/evidence.d.ts +1 -1
  52. package/dist/evidence.d.ts.map +1 -1
  53. package/dist/evidence.js +2 -1
  54. package/dist/evidence.js.map +1 -1
  55. package/dist/feedback.d.ts +5 -0
  56. package/dist/feedback.d.ts.map +1 -1
  57. package/dist/feedback.js +7 -5
  58. package/dist/feedback.js.map +1 -1
  59. package/dist/floating-action-button.js +1 -1
  60. package/dist/floating-action-button.js.map +1 -1
  61. package/dist/forms.d.ts.map +1 -1
  62. package/dist/forms.js +4 -4
  63. package/dist/forms.js.map +1 -1
  64. package/dist/image-choice.js +3 -3
  65. package/dist/image-choice.js.map +1 -1
  66. package/dist/index.d.ts +5 -4
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -4
  69. package/dist/index.js.map +1 -1
  70. package/dist/internal/initial-focus.d.ts +6 -0
  71. package/dist/internal/initial-focus.d.ts.map +1 -1
  72. package/dist/internal/initial-focus.js +6 -0
  73. package/dist/internal/initial-focus.js.map +1 -1
  74. package/dist/internal/pending-content.d.ts +19 -0
  75. package/dist/internal/pending-content.d.ts.map +1 -0
  76. package/dist/internal/pending-content.js +34 -0
  77. package/dist/internal/pending-content.js.map +1 -0
  78. package/dist/internal/screen-footer.d.ts +4 -2
  79. package/dist/internal/screen-footer.d.ts.map +1 -1
  80. package/dist/internal/screen-footer.js +2 -2
  81. package/dist/internal/screen-footer.js.map +1 -1
  82. package/dist/internal.d.ts +9 -1
  83. package/dist/internal.d.ts.map +1 -1
  84. package/dist/internal.js +4 -0
  85. package/dist/internal.js.map +1 -1
  86. package/dist/navigation.d.ts.map +1 -1
  87. package/dist/navigation.js +58 -4
  88. package/dist/navigation.js.map +1 -1
  89. package/dist/number-field.d.ts.map +1 -1
  90. package/dist/number-field.js +4 -3
  91. package/dist/number-field.js.map +1 -1
  92. package/dist/overlays.d.ts +4 -0
  93. package/dist/overlays.d.ts.map +1 -1
  94. package/dist/overlays.js +46 -18
  95. package/dist/overlays.js.map +1 -1
  96. package/dist/public-exports.generated.d.ts +6 -0
  97. package/dist/public-exports.generated.d.ts.map +1 -1
  98. package/dist/public-exports.generated.js +18 -0
  99. package/dist/public-exports.generated.js.map +1 -1
  100. package/dist/screen-flows.d.ts +12 -5
  101. package/dist/screen-flows.d.ts.map +1 -1
  102. package/dist/screen-flows.js +25 -14
  103. package/dist/screen-flows.js.map +1 -1
  104. package/dist/screens.d.ts +18 -5
  105. package/dist/screens.d.ts.map +1 -1
  106. package/dist/screens.js +22 -11
  107. package/dist/screens.js.map +1 -1
  108. package/dist/selection.d.ts +22 -0
  109. package/dist/selection.d.ts.map +1 -1
  110. package/dist/selection.js +32 -9
  111. package/dist/selection.js.map +1 -1
  112. package/dist/shortcut-rail.d.ts +27 -0
  113. package/dist/shortcut-rail.d.ts.map +1 -0
  114. package/dist/shortcut-rail.js +37 -0
  115. package/dist/shortcut-rail.js.map +1 -0
  116. package/dist/steps.d.ts +5 -2
  117. package/dist/steps.d.ts.map +1 -1
  118. package/dist/steps.js +3 -3
  119. package/dist/steps.js.map +1 -1
  120. package/dist/styles.css +223 -48
  121. package/dist/styles.layered.css +223 -48
  122. package/dist/task-list.d.ts +3 -1
  123. package/dist/task-list.d.ts.map +1 -1
  124. package/dist/task-list.js +2 -2
  125. package/dist/task-list.js.map +1 -1
  126. package/dist/theme.d.ts.map +1 -1
  127. package/dist/theme.js +1 -0
  128. package/dist/theme.js.map +1 -1
  129. package/dist/time-picker.d.ts +9 -0
  130. package/dist/time-picker.d.ts.map +1 -0
  131. package/dist/time-picker.js +74 -0
  132. package/dist/time-picker.js.map +1 -0
  133. package/dist/top-bar.d.ts +4 -0
  134. package/dist/top-bar.d.ts.map +1 -1
  135. package/dist/top-bar.js +2 -2
  136. package/dist/top-bar.js.map +1 -1
  137. package/package.json +26 -15
@@ -1 +1 @@
1
- {"version":3,"file":"collapsible.js","sourceRoot":"","sources":["../src/collapsible.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n collapsibleRecipe,\n validateCollapsibleOpenState,\n type CollapsibleOpenState,\n} from \"@hjmds/design-contracts/components/collapsible\";\nimport { forwardRef, useId, useLayoutEffect, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { assignRef, classNames } from \"./internal.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type CollapsibleProps = CollapsibleOpenState &\n Readonly<{\n /** The control's label; it also tells the user what will appear. */\n trigger: ReactNode;\n children: ReactNode;\n disabled?: boolean;\n /** Inline tools stay expanded without a disclosure trigger. */\n presentation?: \"disclosure\" | \"inline\";\n /** Preserve local input state while hidden; hidden content stays inaccessible. */\n keepMounted?: boolean;\n /**\n * `none` leaves the open/closed mark to the trigger, which then places `CollapsibleMarker` itself — for triggers\n * whose label is not a single row, where the end-aligned mark floated alone (FolderPreview, 2026-10-17 review).\n */\n marker?: \"end\" | \"none\";\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Collapsible = forwardRef<HTMLDivElement, CollapsibleProps>(function Collapsible(\n { trigger, children, disabled = false, presentation = \"disclosure\", keepMounted = false, marker = \"end\", className, layoutStyle, ...openState },\n forwardedRef,\n) {\n validateCollapsibleOpenState(openState as CollapsibleOpenState);\n const controlled = openState.open !== undefined;\n const [internalOpen, setInternalOpen] = useState(openState.defaultOpen ?? false);\n const open = presentation === \"inline\" || (openState.open ?? internalOpen);\n const host = useRef<HTMLDivElement>(null);\n const button = useRef<HTMLButtonElement>(null);\n const content = useRef<HTMLDivElement>(null);\n const focusedContent = useRef(false);\n const wasOpen = useRef(open);\n useLayoutEffect(() => {\n // A controlled close can remove or hide the currently focused input without\n // activating the trigger. Recover only that focus, never an outside control.\n const active = host.current?.ownerDocument.activeElement;\n if (wasOpen.current && !open && focusedContent.current &&\n (content.current?.contains(active ?? null) || active === host.current?.ownerDocument.body)) {\n (disabled ? host.current : button.current)?.focus();\n }\n if (!open) focusedContent.current = false;\n wasOpen.current = open;\n }, [open, disabled]);\n const id = `${useId().replaceAll(\":\", \"\")}-collapsible`;\n return (\n <div\n ref={node => { host.current = node; assignRef(forwardedRef, node); }}\n tabIndex={-1}\n className={classNames(\"hjm-collapsible\", className)}\n data-state={open ? \"open\" : \"closed\"}\n style={{ ...layoutStyle, \"--hjm-collapsible-gap\": `${collapsibleRecipe.gap}px` } as CSSProperties}\n >\n <button\n ref={button}\n hidden={presentation === \"inline\"}\n type=\"button\"\n className=\"hjm-collapsible__trigger\"\n aria-expanded={open}\n aria-controls={`${id}-content`}\n disabled={disabled}\n onClick={event => {\n if (disabled || presentation === \"inline\") return;\n // Safari does not focus buttons on pointer activation; keep the closing\n // disclosure as the keyboard origin before its focused content disappears.\n if (open) event.currentTarget.focus();\n const next = !open;\n if (!controlled) setInternalOpen(next);\n openState.onOpenChange?.(next);\n }}\n >\n {trigger}\n {marker === \"end\" ? <CollapsibleMarker open={open} /> : null}\n </button>\n {/* Optional persistence keeps theme changes and closing tools from erasing local\n drafts. The HTML hidden boundary removes closed content from focus and speech. */}\n {open || keepMounted ? (\n <div ref={content} onFocusCapture={() => { focusedContent.current = true; }} onBlurCapture={event => { if (event.relatedTarget instanceof Node && !event.currentTarget.contains(event.relatedTarget)) focusedContent.current = false; }} hidden={!open} id={`${id}-content`} role=\"region\" className=\"hjm-collapsible__content\">{children}</div>\n ) : null}\n </div>\n );\n});\n\n/** The decorative open/closed mark; the expanded state itself travels through the trigger's aria-expanded. */\nexport function CollapsibleMarker({ open }: Readonly<{ open: boolean }>) {\n // The shared chevron at glyph.sm: the text \"▸\" rendered about 8px and read as static text (2026-10-17 review).\n // `chevronEnd` is a logical icon, so Icon mirrors it in RTL.\n return <span aria-hidden=\"true\" className=\"hjm-collapsible__marker\" data-state={open ? \"open\" : \"closed\"}><Icon name={open ? \"chevronDown\" : \"chevronEnd\"} size=\"sm\" tone=\"secondary\" decorative /></span>;\n}\n"]}
1
+ {"version":3,"file":"collapsible.js","sourceRoot":"","sources":["../src/collapsible.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n collapsibleRecipe,\n validateCollapsibleOpenState,\n type CollapsibleOpenState,\n} from \"@hjmds/design-contracts/components/collapsible\";\nimport { forwardRef, useId, useLayoutEffect, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { assignRef, classNames } from \"./internal.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { Spinner } from \"./internal/spinner.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type CollapsibleProps = CollapsibleOpenState &\n Readonly<{\n /** The control's label; it also tells the user what will appear. */\n trigger: ReactNode;\n /** Accessible action name when the trigger is artwork or has a shorter visible label. */\n triggerLabel?: string;\n /** Static heading beside the disclosure action, outside the button's accessible name. */\n title?: ReactNode;\n /** While content is being prepared, replace the action with one labeled spinner. */\n pendingLabel?: string;\n children: ReactNode;\n disabled?: boolean;\n /** Inline tools stay expanded without a disclosure trigger. */\n presentation?: \"disclosure\" | \"inline\";\n /** Preserve local input state while hidden; hidden content stays inaccessible. */\n keepMounted?: boolean;\n /**\n * `none` leaves the open/closed mark to the trigger, which then places `CollapsibleMarker` itself — for triggers\n * whose label is not a single row, where the end-aligned mark floated alone (FolderPreview, 2026-10-17 review).\n */\n marker?: \"end\" | \"none\";\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\nexport const Collapsible = forwardRef<HTMLDivElement, CollapsibleProps>(function Collapsible(\n { trigger, triggerLabel, title, pendingLabel, children, disabled = false, presentation = \"disclosure\", keepMounted = false, marker = \"end\", className, layoutStyle, ...openState },\n forwardedRef,\n) {\n validateCollapsibleOpenState(openState as CollapsibleOpenState);\n const controlled = openState.open !== undefined;\n const [internalOpen, setInternalOpen] = useState(openState.defaultOpen ?? false);\n const open = presentation === \"inline\" || (openState.open ?? internalOpen);\n const host = useRef<HTMLDivElement>(null);\n const button = useRef<HTMLButtonElement>(null);\n const content = useRef<HTMLDivElement>(null);\n const focusedContent = useRef(false);\n const contentOpen = open && pendingLabel === undefined;\n const wasOpen = useRef(contentOpen);\n useLayoutEffect(() => {\n // A controlled close can remove or hide the currently focused input without\n // activating the trigger. Recover only that focus, never an outside control.\n const active = host.current?.ownerDocument.activeElement;\n if (wasOpen.current && !contentOpen && focusedContent.current &&\n (content.current?.contains(active ?? null) || active === host.current?.ownerDocument.body)) {\n (disabled || pendingLabel !== undefined ? host.current : button.current)?.focus();\n }\n if (!contentOpen) focusedContent.current = false;\n wasOpen.current = contentOpen;\n }, [contentOpen, disabled, pendingLabel]);\n const id = `${useId().replaceAll(\":\", \"\")}-collapsible`;\n return (\n <div\n ref={node => { host.current = node; assignRef(forwardedRef, node); }}\n tabIndex={-1}\n className={classNames(\"hjm-collapsible\", className)}\n data-state={open ? \"open\" : \"closed\"}\n aria-busy={pendingLabel === undefined ? undefined : true}\n style={{ ...layoutStyle, \"--hjm-collapsible-gap\": `${collapsibleRecipe.gap}px` } as CSSProperties}\n >\n <div className=\"hjm-collapsible__header\" data-titled={title == null ? undefined : true} hidden={presentation === \"inline\"}>\n {title == null ? null : <div className=\"hjm-collapsible__title\">{title}</div>}\n {pendingLabel === undefined ? <button\n ref={button}\n hidden={presentation === \"inline\"}\n type=\"button\"\n className=\"hjm-collapsible__trigger\"\n aria-label={triggerLabel}\n aria-expanded={open}\n aria-controls={`${id}-content`}\n disabled={disabled}\n onClick={event => {\n if (disabled || presentation === \"inline\") return;\n // Safari does not focus buttons on pointer activation; keep the closing\n // disclosure as the keyboard origin before its focused content disappears.\n if (open) event.currentTarget.focus();\n const next = !open;\n if (!controlled) setInternalOpen(next);\n openState.onOpenChange?.(next);\n }}\n >\n {trigger}\n {marker === \"end\" ? <CollapsibleMarker open={open} /> : null}\n </button> : <span className=\"hjm-collapsible__pending\"><Spinner label={pendingLabel} size=\"small\" /></span>}\n </div>\n {/* Optional persistence keeps theme changes and closing tools from erasing local\n drafts. The HTML hidden boundary removes closed content from focus and speech. */}\n {contentOpen || keepMounted ? (\n <div ref={content} onFocusCapture={() => { focusedContent.current = true; }} onBlurCapture={event => { if (event.relatedTarget instanceof Node && !event.currentTarget.contains(event.relatedTarget)) focusedContent.current = false; }} hidden={!contentOpen} id={`${id}-content`} role=\"region\" className=\"hjm-collapsible__content\">{children}</div>\n ) : null}\n </div>\n );\n});\n\n/** The decorative open/closed mark; the expanded state itself travels through the trigger's aria-expanded. */\nexport function CollapsibleMarker({ open }: Readonly<{ open: boolean }>) {\n // The shared chevron at glyph.sm: the text \"▸\" rendered about 8px and read as static text (2026-10-17 review).\n // `chevronEnd` is a logical icon, so Icon mirrors it in RTL.\n return <span aria-hidden=\"true\" className=\"hjm-collapsible__marker\" data-state={open ? \"open\" : \"closed\"}><Icon name={open ? \"chevronDown\" : \"chevronEnd\"} size=\"sm\" tone=\"secondary\" decorative /></span>;\n}\n"]}
@@ -6,10 +6,10 @@ export type CollectionRailLabels = Readonly<{
6
6
  next: string;
7
7
  navigation: string;
8
8
  }>;
9
- export type CollectionRailProps = Omit<HTMLAttributes<HTMLDivElement>, "children"> & Readonly<{
9
+ export type CollectionRailProps<Item extends CollectionRailItem = CollectionRailItem> = Omit<HTMLAttributes<HTMLDivElement>, "children"> & Readonly<{
10
10
  label: string;
11
- items: readonly CollectionRailItem[];
12
- renderItem: (item: CollectionRailItem) => ReactNode;
11
+ items: readonly Item[];
12
+ renderItem: (item: Item) => ReactNode;
13
13
  labels: CollectionRailLabels;
14
14
  density?: CollectionRailDensity;
15
15
  emptyContent?: ReactNode;
@@ -26,5 +26,5 @@ export type CollectionRailProps = Omit<HTMLAttributes<HTMLDivElement>, "children
26
26
  layoutStyle?: HjmCompositionStyleProp;
27
27
  }>;
28
28
  /** Finite all-mounted list placement; Card, inputs and Dialog keep their own state. */
29
- export declare function CollectionRail({ label, items, renderItem, labels, density, emptyContent, defaultStartKey, onStartKeyChange, bleed, layoutStyle, ...props }: CollectionRailProps): import("react").JSX.Element;
29
+ export declare function CollectionRail<Item extends CollectionRailItem = CollectionRailItem>({ label, items, renderItem, labels, density, emptyContent, defaultStartKey, onStartKeyChange, bleed, layoutStyle, ...props }: CollectionRailProps<Item>): import("react").JSX.Element;
30
30
  //# sourceMappingURL=collection-rail.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"collection-rail.d.ts","sourceRoot":"","sources":["../src/collection-rail.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/F,OAAO,EAG4B,KAAK,kBAAkB,EAAE,KAAK,qBAAqB,EACrF,MAAM,yCAAyC,CAAC;AAIjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACpG,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC;IAC5F,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAAC,UAAU,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,SAAS,CAAC;IACzG,MAAM,EAAE,oBAAoB,CAAC;IAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IACxF,6FAA6F;IAC7F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qGAAqG;IACrG,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAA+C,EAChH,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAa,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,+BA8H7G"}
1
+ {"version":3,"file":"collection-rail.d.ts","sourceRoot":"","sources":["../src/collection-rail.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqC,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC/F,OAAO,EAG4B,KAAK,kBAAkB,EAAE,KAAK,qBAAqB,EACrF,MAAM,yCAAyC,CAAC;AAIjD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACpG,MAAM,MAAM,mBAAmB,CAAC,IAAI,SAAS,kBAAkB,GAAG,kBAAkB,IAAI,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC;IAClJ,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IAAC,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,SAAS,CAAC;IAC7E,MAAM,EAAE,oBAAoB,CAAC;IAAC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAAC,YAAY,CAAC,EAAE,SAAS,CAAC;IACxF,6FAA6F;IAC7F,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qGAAqG;IACrG,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,uFAAuF;AACvF,wBAAgB,cAAc,CAAC,IAAI,SAAS,kBAAkB,GAAG,kBAAkB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,OAA+C,EACtK,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,KAAa,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,CAAC,IAAI,CAAC,+BA8HnH"}
@@ -1 +1 @@
1
- {"version":3,"file":"collection-rail.js","sourceRoot":"","sources":["../src/collection-rail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useLayoutEffect, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport {\n collectionRailRecipe, validateCollectionRail, resolveCollectionRailLayout, resolveCollectionRailViewport,\n getCollectionRailTargetOffset, getCollectionRailItemOffset, getCollectionRailRevealOffset,\n getCollectionRailKeyboardIntent, type CollectionRailItem, type CollectionRailDensity, type CollectionRailLayout,\n} from \"@hjmds/design-contracts/collection-rail\";\nimport { IconButton } from \"./actions.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type CollectionRailLabels = Readonly<{ previous: string; next: string; navigation: string }>;\nexport type CollectionRailProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> & Readonly<{\n label: string; items: readonly CollectionRailItem[]; renderItem: (item: CollectionRailItem) => ReactNode;\n labels: CollectionRailLabels; density?: CollectionRailDensity; emptyContent?: ReactNode;\n /** Initial scroll anchor, not selection. Later collection changes reconcile by stable ID. */\n defaultStartKey?: string;\n /** Observed leading item, independent of product selection/detail state. Empty lists report null. */\n onStartKeyChange?: (key: string | null) => void;\n /**\n * Scroll to the screen edges from inside the default inset ScreenLayout body: the viewport reaches past the body\n * gutter (`--hjm-screen-body-inline`) and pads it back, so the first and last items rest on the gutter (no\n * `body-edge` + per-section gutter, spint home 2026-10-17). Place the rail directly in the body.\n */\n bleed?: boolean;\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Finite all-mounted list placement; Card, inputs and Dialog keep their own state. */\nexport function CollectionRail({ label, items, renderItem, labels, density = collectionRailRecipe.defaults.density,\n emptyContent, defaultStartKey, onStartKeyChange, bleed = false, layoutStyle, ...props }: CollectionRailProps) {\n validateCollectionRail(items);\n if (!label.trim() || Object.values(labels).some(value => !value.trim())) throw new TypeError(\"CollectionRail labels must not be empty\");\n const theme = useOptionalHjmTheme(), direction = theme?.environment.direction ?? \"ltr\";\n const gap = collectionRailRecipe.gap;\n const viewportRef = useRef<HTMLDivElement>(null);\n const detachedFocus = useRef<HTMLElement | null>(null);\n useLayoutEffect(() => {\n const old = detachedFocus.current;\n detachedFocus.current = null;\n // A removed card must leave a keyboard origin in this collection, without\n // moving focus away from a surviving input or an external control.\n if (old && !old.isConnected && old.ownerDocument.activeElement === old.ownerDocument.body) {\n viewportRef.current?.focus({ preventScroll: true });\n }\n });\n const anchor = useRef<string | null>(defaultStartKey ?? items[0]?.id ?? null);\n const initialized = useRef(false);\n if (!initialized.current) { validateCollectionRail(items, defaultStartKey); initialized.current = true; }\n const callback = useRef(onStartKeyChange); callback.current = onStartKeyChange;\n const current = useRef({ layout: resolveCollectionRailLayout(items.length, 0, density, gap), offset: 0 });\n const pendingOffset = useRef<number | null>(null);\n const [position, setPosition] = useState(current.current);\n const identity = JSON.stringify(items.map(item => item.id));\n const itemsRef = useRef(items); itemsRef.current = items;\n\n function publish(layout: CollectionRailLayout, offset: number) {\n const resolved = resolveCollectionRailViewport(layout, offset);\n const key = itemsRef.current[resolved.startIndex]?.id ?? null;\n if (key !== anchor.current) { anchor.current = key; callback.current?.(key); }\n current.current = { layout, offset: resolved.offset };\n setPosition(current.current);\n }\n function scrollToOffset(offset: number, animated: boolean) {\n const viewport = viewportRef.current;\n if (!viewport) return;\n const resolved = resolveCollectionRailViewport(current.current.layout, offset);\n // CSS RTL scrollLeft is negative; clamp Safari rubber-banding through the\n // shared logical resolver rather than reversing data or selection keys.\n viewport.scrollTo({ left: direction === \"rtl\" ? -resolved.offset : resolved.offset,\n behavior: animated && !theme?.environment.reducedMotion ? \"smooth\" : \"instant\" });\n pendingOffset.current = animated && !theme?.environment.reducedMotion ? resolved.offset : null;\n // Smooth scroll is a request, not an observed viewport. Publishing its\n // destination now would disable the end action and report an unseen anchor.\n publish(current.current.layout, direction === \"rtl\" ? -viewport.scrollLeft : viewport.scrollLeft);\n }\n useLayoutEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n let initialMeasurement = true;\n function measure() {\n // clientWidth includes the bleed padding; item geometry uses the gutter-aligned box inside it.\n const style = getComputedStyle(viewport!);\n const room = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);\n const next = resolveCollectionRailLayout(itemsRef.current.length, Math.max(0, viewport!.clientWidth - room), density, gap);\n // ResizeObserver also delivers an initial unchanged box. Re-aligning then\n // would undo a focus reveal that happened after the layout effect.\n if (!initialMeasurement && next.viewport === current.current.layout.viewport) return;\n initialMeasurement = false;\n pendingOffset.current = null;\n const index = Math.max(0, itemsRef.current.findIndex(item => item.id === anchor.current));\n let offset = next.count ? getCollectionRailItemOffset(next, index) : 0;\n const focused = document.activeElement?.closest(\"[data-collection-rail-item]\");\n const focusedIndex = focused && viewport!.contains(focused)\n ? itemsRef.current.findIndex(item => item.id === focused.getAttribute(\"data-collection-rail-item\")) : -1;\n // A narrower viewport cannot keep a distant focused action and the old\n // leading item visible together; focus exposure takes priority over anchor alignment.\n if (focusedIndex >= 0) offset = getCollectionRailRevealOffset(next, offset, focusedIndex);\n current.current = { layout: next, offset };\n // Width/direction changes keep the leading item's identity, and never\n // key/remount its input or detail owner (docs/collection-rail.md).\n viewport!.scrollTo({ left: direction === \"rtl\" ? -offset : offset, behavior: \"instant\" });\n publish(next, offset);\n }\n measure();\n const observer = new ResizeObserver(measure); observer.observe(viewport);\n return () => observer.disconnect();\n }, [identity, density, gap, direction, bleed]);\n\n function navigate(intent: \"previous\" | \"next\" | \"first\" | \"last\") {\n scrollToOffset(getCollectionRailTargetOffset(current.current.layout, pendingOffset.current ?? current.current.offset, intent), true);\n }\n const resolved = resolveCollectionRailViewport(position.layout, position.offset);\n return <div {...props} style={{ ...props.style, ...layoutStyle, minWidth: 0 }}\n data-collection-rail data-start-key={items[resolved.startIndex]?.id} dir={direction}\n onKeyDown={event => {\n props.onKeyDown?.(event);\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n // Item widgets own arrows/Home/End. Rail navigation belongs only to its\n // viewport and explicit controls, not an input nested in a visible card.\n if (event.target !== viewportRef.current && !(event.target instanceof Element && event.target.closest(\"[data-collection-rail-controls]\"))) return;\n const intent = getCollectionRailKeyboardIntent(event.key, direction);\n if (intent) { event.preventDefault(); navigate(intent); }\n }}>\n <div ref={viewportRef} role=\"list\" aria-label={label} tabIndex={0} data-collection-rail-viewport data-bleed={bleed || undefined}\n className=\"hjm-collection-rail__viewport\"\n style={{ overflowX: \"auto\", overscrollBehaviorX: \"contain\", minWidth: 0 }}\n onPointerDown={() => { pendingOffset.current = null; }} onWheel={() => { pendingOffset.current = null; }}\n onScroll={event => {\n const offset = direction === \"rtl\" ? -event.currentTarget.scrollLeft : event.currentTarget.scrollLeft;\n if (pendingOffset.current !== null && Math.abs(offset - pendingOffset.current) <= 0.5) pendingOffset.current = null;\n publish(current.current.layout, offset);\n }}>\n <div style={{ display: \"flex\", gap, width: \"max-content\", minWidth: \"100%\", paddingBlock: \"var(--hjm-space-xs)\" }}>\n {items.map((item, index) => <div key={item.id} role=\"listitem\" data-collection-rail-item={item.id}\n ref={node => {\n if (!node) return;\n return () => {\n const active = node.ownerDocument.activeElement;\n if (active instanceof HTMLElement && node.contains(active)) detachedFocus.current = active;\n };\n }}\n style={{ flex: \"0 0 auto\", width: position.layout.itemWidth || \"auto\", minWidth: 0 }}\n onFocusCapture={() => scrollToOffset(getCollectionRailRevealOffset(current.current.layout, current.current.offset, index), false)}>\n {renderItem(item)}\n </div>)}\n </div>\n {items.length === 0 ? emptyContent : null}\n </div>\n <div data-collection-rail-controls role=\"group\" aria-label={labels.navigation}\n style={{ display: \"flex\", flexWrap: \"wrap\", justifyContent: \"flex-end\", gap: \"var(--hjm-space-sm)\", marginBlockStart: \"var(--hjm-space-sm)\" }}>\n {/* Tool actions: icon buttons named by the localized label, as Carousel (2026-10-17 review E9). */}\n <IconButton label={labels.previous} tone=\"ghost\" aria-disabled={resolved.atStart} onClick={() => navigate(\"previous\")}><Icon name=\"chevronStart\" /></IconButton>\n <IconButton label={labels.next} tone=\"ghost\" aria-disabled={resolved.atEnd} onClick={() => navigate(\"next\")}><Icon name=\"chevronEnd\" /></IconButton>\n </div>\n </div>;\n}\n"]}
1
+ {"version":3,"file":"collection-rail.js","sourceRoot":"","sources":["../src/collection-rail.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useLayoutEffect, useRef, useState, type HTMLAttributes, type ReactNode } from \"react\";\nimport {\n collectionRailRecipe, validateCollectionRail, resolveCollectionRailLayout, resolveCollectionRailViewport,\n getCollectionRailTargetOffset, getCollectionRailItemOffset, getCollectionRailRevealOffset,\n getCollectionRailKeyboardIntent, type CollectionRailItem, type CollectionRailDensity, type CollectionRailLayout,\n} from \"@hjmds/design-contracts/collection-rail\";\nimport { IconButton } from \"./actions.js\";\nimport { Icon } from \"./supplemental-display.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type CollectionRailLabels = Readonly<{ previous: string; next: string; navigation: string }>;\nexport type CollectionRailProps<Item extends CollectionRailItem = CollectionRailItem> = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> & Readonly<{\n label: string; items: readonly Item[]; renderItem: (item: Item) => ReactNode;\n labels: CollectionRailLabels; density?: CollectionRailDensity; emptyContent?: ReactNode;\n /** Initial scroll anchor, not selection. Later collection changes reconcile by stable ID. */\n defaultStartKey?: string;\n /** Observed leading item, independent of product selection/detail state. Empty lists report null. */\n onStartKeyChange?: (key: string | null) => void;\n /**\n * Scroll to the screen edges from inside the default inset ScreenLayout body: the viewport reaches past the body\n * gutter (`--hjm-screen-body-inline`) and pads it back, so the first and last items rest on the gutter (no\n * `body-edge` + per-section gutter, spint home 2026-10-17). Place the rail directly in the body.\n */\n bleed?: boolean;\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\n/** Finite all-mounted list placement; Card, inputs and Dialog keep their own state. */\nexport function CollectionRail<Item extends CollectionRailItem = CollectionRailItem>({ label, items, renderItem, labels, density = collectionRailRecipe.defaults.density,\n emptyContent, defaultStartKey, onStartKeyChange, bleed = false, layoutStyle, ...props }: CollectionRailProps<Item>) {\n validateCollectionRail(items);\n if (!label.trim() || Object.values(labels).some(value => !value.trim())) throw new TypeError(\"CollectionRail labels must not be empty\");\n const theme = useOptionalHjmTheme(), direction = theme?.environment.direction ?? \"ltr\";\n const gap = collectionRailRecipe.gap;\n const viewportRef = useRef<HTMLDivElement>(null);\n const detachedFocus = useRef<HTMLElement | null>(null);\n useLayoutEffect(() => {\n const old = detachedFocus.current;\n detachedFocus.current = null;\n // A removed card must leave a keyboard origin in this collection, without\n // moving focus away from a surviving input or an external control.\n if (old && !old.isConnected && old.ownerDocument.activeElement === old.ownerDocument.body) {\n viewportRef.current?.focus({ preventScroll: true });\n }\n });\n const anchor = useRef<string | null>(defaultStartKey ?? items[0]?.id ?? null);\n const initialized = useRef(false);\n if (!initialized.current) { validateCollectionRail(items, defaultStartKey); initialized.current = true; }\n const callback = useRef(onStartKeyChange); callback.current = onStartKeyChange;\n const current = useRef({ layout: resolveCollectionRailLayout(items.length, 0, density, gap), offset: 0 });\n const pendingOffset = useRef<number | null>(null);\n const [position, setPosition] = useState(current.current);\n const identity = JSON.stringify(items.map(item => item.id));\n const itemsRef = useRef(items); itemsRef.current = items;\n\n function publish(layout: CollectionRailLayout, offset: number) {\n const resolved = resolveCollectionRailViewport(layout, offset);\n const key = itemsRef.current[resolved.startIndex]?.id ?? null;\n if (key !== anchor.current) { anchor.current = key; callback.current?.(key); }\n current.current = { layout, offset: resolved.offset };\n setPosition(current.current);\n }\n function scrollToOffset(offset: number, animated: boolean) {\n const viewport = viewportRef.current;\n if (!viewport) return;\n const resolved = resolveCollectionRailViewport(current.current.layout, offset);\n // CSS RTL scrollLeft is negative; clamp Safari rubber-banding through the\n // shared logical resolver rather than reversing data or selection keys.\n viewport.scrollTo({ left: direction === \"rtl\" ? -resolved.offset : resolved.offset,\n behavior: animated && !theme?.environment.reducedMotion ? \"smooth\" : \"instant\" });\n pendingOffset.current = animated && !theme?.environment.reducedMotion ? resolved.offset : null;\n // Smooth scroll is a request, not an observed viewport. Publishing its\n // destination now would disable the end action and report an unseen anchor.\n publish(current.current.layout, direction === \"rtl\" ? -viewport.scrollLeft : viewport.scrollLeft);\n }\n useLayoutEffect(() => {\n const viewport = viewportRef.current;\n if (!viewport) return;\n let initialMeasurement = true;\n function measure() {\n // clientWidth includes the bleed padding; item geometry uses the gutter-aligned box inside it.\n const style = getComputedStyle(viewport!);\n const room = (parseFloat(style.paddingLeft) || 0) + (parseFloat(style.paddingRight) || 0);\n const next = resolveCollectionRailLayout(itemsRef.current.length, Math.max(0, viewport!.clientWidth - room), density, gap);\n // ResizeObserver also delivers an initial unchanged box. Re-aligning then\n // would undo a focus reveal that happened after the layout effect.\n if (!initialMeasurement && next.viewport === current.current.layout.viewport) return;\n initialMeasurement = false;\n pendingOffset.current = null;\n const index = Math.max(0, itemsRef.current.findIndex(item => item.id === anchor.current));\n let offset = next.count ? getCollectionRailItemOffset(next, index) : 0;\n const focused = document.activeElement?.closest(\"[data-collection-rail-item]\");\n const focusedIndex = focused && viewport!.contains(focused)\n ? itemsRef.current.findIndex(item => item.id === focused.getAttribute(\"data-collection-rail-item\")) : -1;\n // A narrower viewport cannot keep a distant focused action and the old\n // leading item visible together; focus exposure takes priority over anchor alignment.\n if (focusedIndex >= 0) offset = getCollectionRailRevealOffset(next, offset, focusedIndex);\n current.current = { layout: next, offset };\n // Width/direction changes keep the leading item's identity, and never\n // key/remount its input or detail owner (docs/collection-rail.md).\n viewport!.scrollTo({ left: direction === \"rtl\" ? -offset : offset, behavior: \"instant\" });\n publish(next, offset);\n }\n measure();\n const observer = new ResizeObserver(measure); observer.observe(viewport);\n return () => observer.disconnect();\n }, [identity, density, gap, direction, bleed]);\n\n function navigate(intent: \"previous\" | \"next\" | \"first\" | \"last\") {\n scrollToOffset(getCollectionRailTargetOffset(current.current.layout, pendingOffset.current ?? current.current.offset, intent), true);\n }\n const resolved = resolveCollectionRailViewport(position.layout, position.offset);\n return <div {...props} style={{ ...props.style, ...layoutStyle, minWidth: 0 }}\n data-collection-rail data-start-key={items[resolved.startIndex]?.id} dir={direction}\n onKeyDown={event => {\n props.onKeyDown?.(event);\n if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) return;\n // Item widgets own arrows/Home/End. Rail navigation belongs only to its\n // viewport and explicit controls, not an input nested in a visible card.\n if (event.target !== viewportRef.current && !(event.target instanceof Element && event.target.closest(\"[data-collection-rail-controls]\"))) return;\n const intent = getCollectionRailKeyboardIntent(event.key, direction);\n if (intent) { event.preventDefault(); navigate(intent); }\n }}>\n <div ref={viewportRef} role=\"list\" aria-label={label} tabIndex={0} data-collection-rail-viewport data-bleed={bleed || undefined}\n className=\"hjm-collection-rail__viewport\"\n style={{ overflowX: \"auto\", overscrollBehaviorX: \"contain\", minWidth: 0 }}\n onPointerDown={() => { pendingOffset.current = null; }} onWheel={() => { pendingOffset.current = null; }}\n onScroll={event => {\n const offset = direction === \"rtl\" ? -event.currentTarget.scrollLeft : event.currentTarget.scrollLeft;\n if (pendingOffset.current !== null && Math.abs(offset - pendingOffset.current) <= 0.5) pendingOffset.current = null;\n publish(current.current.layout, offset);\n }}>\n <div style={{ display: \"flex\", gap, width: \"max-content\", minWidth: \"100%\", paddingBlock: \"var(--hjm-space-xs)\" }}>\n {items.map((item, index) => <div key={item.id} role=\"listitem\" data-collection-rail-item={item.id}\n ref={node => {\n if (!node) return;\n return () => {\n const active = node.ownerDocument.activeElement;\n if (active instanceof HTMLElement && node.contains(active)) detachedFocus.current = active;\n };\n }}\n style={{ flex: \"0 0 auto\", width: position.layout.itemWidth || \"auto\", minWidth: 0 }}\n onFocusCapture={() => scrollToOffset(getCollectionRailRevealOffset(current.current.layout, current.current.offset, index), false)}>\n {renderItem(item)}\n </div>)}\n </div>\n {items.length === 0 ? emptyContent : null}\n </div>\n <div data-collection-rail-controls role=\"group\" aria-label={labels.navigation}\n style={{ display: \"flex\", flexWrap: \"wrap\", justifyContent: \"flex-end\", gap: \"var(--hjm-space-sm)\", marginBlockStart: \"var(--hjm-space-sm)\" }}>\n {/* Tool actions: icon buttons named by the localized label, as Carousel (2026-10-17 review E9). */}\n <IconButton label={labels.previous} tone=\"ghost\" aria-disabled={resolved.atStart} onClick={() => navigate(\"previous\")}><Icon name=\"chevronStart\" /></IconButton>\n <IconButton label={labels.next} tone=\"ghost\" aria-disabled={resolved.atEnd} onClick={() => navigate(\"next\")}><Icon name=\"chevronEnd\" /></IconButton>\n </div>\n </div>;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-row.d.ts","sourceRoot":"","sources":["../src/conversation-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CACvF,CAAC,CAAC;AAEH,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAc,EAAE,EAAE,oBAAoB,+BAazG"}
1
+ {"version":3,"file":"conversation-row.d.ts","sourceRoot":"","sources":["../src/conversation-row.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CACvF,CAAC,CAAC;AAEH,2FAA2F;AAC3F,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAc,EAAE,EAAE,oBAAoB,+BAgBzG"}
@@ -3,6 +3,9 @@ import { conversationRowRecipe as recipe } from "@hjmds/design-contracts/convers
3
3
  import { Text } from "./layout.js";
4
4
  /** Presentation inside a router-owned link: the host supplies its full accessible name. */
5
5
  export function ConversationRow({ title, preview, metadata, avatar, unread = false }) {
6
- return _jsxs("span", { "aria-hidden": "true", "data-hjm-conversation-row": "true", "data-unread": unread || undefined, style: { display: "flex", alignItems: "center", gap: recipe.gap, paddingInline: recipe.paddingInline, paddingBlock: recipe.paddingBlock, minWidth: 0, width: "100%", boxSizing: "border-box" }, children: [_jsx("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: recipe.avatarSize, height: recipe.avatarSize, flexShrink: 0, borderRadius: "50%", overflow: "hidden" }, children: avatar }), _jsxs("span", { style: { display: "flex", flexDirection: "column", gap: recipe.contentGap, flex: 1, minWidth: 0 }, children: [_jsx(Text, { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: unread ? recipe.unreadTitleWeight : recipe.titleWeight }, children: title }), _jsxs("span", { style: { display: "flex", minWidth: 0 }, children: [_jsx(Text, { variant: "label", tone: unread ? "primary" : "subtle", style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: unread ? recipe.unreadPreviewWeight : recipe.titleWeight }, children: preview }), _jsx(Text, { variant: "label", tone: unread ? "primary" : "subtle", style: { flexShrink: 0, /* "pre": flex items drop the leading space of " · " (2026-10-17 comparison); still no wrap. */ whiteSpace: "pre", fontWeight: unread ? recipe.unreadPreviewWeight : recipe.titleWeight }, children: ` · ${metadata}` })] })] }), unread ? _jsx("span", { "data-hjm-unread-dot": "true", style: { width: recipe.unreadSize, height: recipe.unreadSize, flexShrink: 0, borderRadius: "50%", background: "var(--hjm-color-content-brand)" } }) : null] });
6
+ // Separators join visible fields; a missing preview must not leave a leading dot.
7
+ const hasPreview = preview.trim().length > 0;
8
+ const hasMetadata = metadata.trim().length > 0;
9
+ return _jsxs("span", { "aria-hidden": "true", "data-hjm-conversation-row": "true", "data-unread": unread || undefined, style: { display: "flex", alignItems: "center", gap: recipe.gap, paddingInline: recipe.paddingInline, paddingBlock: recipe.paddingBlock, minWidth: 0, width: "100%", boxSizing: "border-box" }, children: [_jsx("span", { style: { display: "flex", alignItems: "center", justifyContent: "center", width: recipe.avatarSize, height: recipe.avatarSize, flexShrink: 0, borderRadius: "50%", overflow: "hidden" }, children: avatar }), _jsxs("span", { style: { display: "flex", flexDirection: "column", gap: recipe.contentGap, flex: 1, minWidth: 0 }, children: [_jsx(Text, { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: unread ? recipe.unreadTitleWeight : recipe.titleWeight }, children: title }), _jsxs("span", { style: { display: "flex", minWidth: 0 }, children: [hasPreview ? _jsx(Text, { variant: "label", tone: unread ? "primary" : "subtle", style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: unread ? recipe.unreadPreviewWeight : recipe.titleWeight }, children: preview }) : null, hasMetadata ? _jsx(Text, { variant: "label", tone: unread ? "primary" : "subtle", style: { flexShrink: 0, /* "pre": flex items drop the leading space of " · " (2026-10-17 comparison); still no wrap. */ whiteSpace: "pre", fontWeight: unread ? recipe.unreadPreviewWeight : recipe.titleWeight }, children: hasPreview ? ` · ${metadata}` : metadata }) : null] })] }), unread ? _jsx("span", { "data-hjm-unread-dot": "true", style: { width: recipe.unreadSize, height: recipe.unreadSize, flexShrink: 0, borderRadius: "50%", background: "var(--hjm-color-content-brand)" } }) : null] });
7
10
  }
8
11
  //# sourceMappingURL=conversation-row.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conversation-row.js","sourceRoot":"","sources":["../src/conversation-row.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,qBAAqB,IAAI,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAC3F,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAMnC,2FAA2F;AAC3F,MAAM,UAAU,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,KAAK,EAAwB;IACxG,OAAO,+BAAkB,MAAM,+BAA2B,MAAM,iBAAc,MAAM,IAAI,SAAS,EAC/F,KAAK,EAAE,EAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,QAAQ,EAAC,GAAG,EAAC,MAAM,CAAC,GAAG,EAAC,aAAa,EAAC,MAAM,CAAC,aAAa,EAAC,YAAY,EAAC,MAAM,CAAC,YAAY,EAAC,QAAQ,EAAC,CAAC,EAAC,KAAK,EAAC,MAAM,EAAC,SAAS,EAAC,YAAY,EAAC,aAC7K,eAAM,KAAK,EAAE,EAAC,OAAO,EAAC,MAAM,EAAC,UAAU,EAAC,QAAQ,EAAC,cAAc,EAAC,QAAQ,EAAC,KAAK,EAAC,MAAM,CAAC,UAAU,EAAC,MAAM,EAAC,MAAM,CAAC,UAAU,EAAC,UAAU,EAAC,CAAC,EAAC,YAAY,EAAC,KAAK,EAAC,QAAQ,EAAC,QAAQ,EAAC,YAAG,MAAM,GAAQ,EAC7L,gBAAM,KAAK,EAAE,EAAC,OAAO,EAAC,MAAM,EAAC,aAAa,EAAC,QAAQ,EAAC,GAAG,EAAC,MAAM,CAAC,UAAU,EAAC,IAAI,EAAC,CAAC,EAAC,QAAQ,EAAC,CAAC,EAAC,aAC1F,KAAC,IAAI,IAAC,KAAK,EAAE,EAAC,QAAQ,EAAC,QAAQ,EAAC,YAAY,EAAC,UAAU,EAAC,UAAU,EAAC,QAAQ,EAAC,UAAU,EAAC,MAAM,CAAA,CAAC,CAAA,MAAM,CAAC,iBAAiB,CAAA,CAAC,CAAA,MAAM,CAAC,WAAW,EAAC,YAAG,KAAK,GAAQ,EAC1J,gBAAM,KAAK,EAAE,EAAC,OAAO,EAAC,MAAM,EAAC,QAAQ,EAAC,CAAC,EAAC,aACtC,KAAC,IAAI,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAE,MAAM,CAAA,CAAC,CAAA,SAAS,CAAA,CAAC,CAAA,QAAQ,EAAE,KAAK,EAAE,EAAC,QAAQ,EAAC,QAAQ,EAAC,YAAY,EAAC,UAAU,EAAC,UAAU,EAAC,QAAQ,EAAC,UAAU,EAAC,MAAM,CAAA,CAAC,CAAA,MAAM,CAAC,mBAAmB,CAAA,CAAC,CAAA,MAAM,CAAC,WAAW,EAAC,YAAG,OAAO,GAAQ,EAC/M,KAAC,IAAI,IAAC,OAAO,EAAC,OAAO,EAAC,IAAI,EAAE,MAAM,CAAA,CAAC,CAAA,SAAS,CAAA,CAAC,CAAA,QAAQ,EAAE,KAAK,EAAE,EAAC,UAAU,EAAC,CAAC,EAAC,+FAA+F,CAAA,UAAU,EAAC,KAAK,EAAC,UAAU,EAAC,MAAM,CAAA,CAAC,CAAA,MAAM,CAAC,mBAAmB,CAAA,CAAC,CAAA,MAAM,CAAC,WAAW,EAAC,YAAG,MAAM,QAAQ,EAAE,GAAQ,IAClR,IACF,EACN,MAAM,CAAA,CAAC,CAAA,sCAA0B,MAAM,EAAC,KAAK,EAAE,EAAC,KAAK,EAAC,MAAM,CAAC,UAAU,EAAC,MAAM,EAAC,MAAM,CAAC,UAAU,EAAC,UAAU,EAAC,CAAC,EAAC,YAAY,EAAC,KAAK,EAAC,UAAU,EAAC,gCAAgC,EAAC,GAAG,CAAA,CAAC,CAAA,IAAI,IACjL,CAAC;AACV,CAAC","sourcesContent":["import type { ReactNode } from \"react\";\nimport { conversationRowRecipe as recipe } from \"@hjmds/design-contracts/conversation-row\";\nimport { Text } from \"./layout.js\";\n\nexport type ConversationRowProps = Readonly<{\n title: string; preview: string; metadata: string; avatar: ReactNode; unread?: boolean;\n}>;\n\n/** Presentation inside a router-owned link: the host supplies its full accessible name. */\nexport function ConversationRow({ title, preview, metadata, avatar, unread = false }: ConversationRowProps) {\n return <span aria-hidden=\"true\" data-hjm-conversation-row=\"true\" data-unread={unread || undefined}\n style={{display:\"flex\",alignItems:\"center\",gap:recipe.gap,paddingInline:recipe.paddingInline,paddingBlock:recipe.paddingBlock,minWidth:0,width:\"100%\",boxSizing:\"border-box\"}}>\n <span style={{display:\"flex\",alignItems:\"center\",justifyContent:\"center\",width:recipe.avatarSize,height:recipe.avatarSize,flexShrink:0,borderRadius:\"50%\",overflow:\"hidden\"}}>{avatar}</span>\n <span style={{display:\"flex\",flexDirection:\"column\",gap:recipe.contentGap,flex:1,minWidth:0}}>\n <Text style={{overflow:\"hidden\",textOverflow:\"ellipsis\",whiteSpace:\"nowrap\",fontWeight:unread?recipe.unreadTitleWeight:recipe.titleWeight}}>{title}</Text>\n <span style={{display:\"flex\",minWidth:0}}>\n <Text variant=\"label\" tone={unread?\"primary\":\"subtle\"} style={{overflow:\"hidden\",textOverflow:\"ellipsis\",whiteSpace:\"nowrap\",fontWeight:unread?recipe.unreadPreviewWeight:recipe.titleWeight}}>{preview}</Text>\n <Text variant=\"label\" tone={unread?\"primary\":\"subtle\"} style={{flexShrink:0,/* \"pre\": flex items drop the leading space of \" · \" (2026-10-17 comparison); still no wrap. */whiteSpace:\"pre\",fontWeight:unread?recipe.unreadPreviewWeight:recipe.titleWeight}}>{` · ${metadata}`}</Text>\n </span>\n </span>\n {unread?<span data-hjm-unread-dot=\"true\" style={{width:recipe.unreadSize,height:recipe.unreadSize,flexShrink:0,borderRadius:\"50%\",background:\"var(--hjm-color-content-brand)\"}}/>:null}\n </span>;\n}\n"]}
1
+ {"version":3,"file":"conversation-row.js","sourceRoot":"","sources":["../src/conversation-row.tsx"],"names":[],"mappings":"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","sourcesContent":["import type { ReactNode } from \"react\";\nimport { conversationRowRecipe as recipe } from \"@hjmds/design-contracts/conversation-row\";\nimport { Text } from \"./layout.js\";\n\nexport type ConversationRowProps = Readonly<{\n title: string; preview: string; metadata: string; avatar: ReactNode; unread?: boolean;\n}>;\n\n/** Presentation inside a router-owned link: the host supplies its full accessible name. */\nexport function ConversationRow({ title, preview, metadata, avatar, unread = false }: ConversationRowProps) {\n // Separators join visible fields; a missing preview must not leave a leading dot.\n const hasPreview = preview.trim().length > 0;\n const hasMetadata = metadata.trim().length > 0;\n return <span aria-hidden=\"true\" data-hjm-conversation-row=\"true\" data-unread={unread || undefined}\n style={{display:\"flex\",alignItems:\"center\",gap:recipe.gap,paddingInline:recipe.paddingInline,paddingBlock:recipe.paddingBlock,minWidth:0,width:\"100%\",boxSizing:\"border-box\"}}>\n <span style={{display:\"flex\",alignItems:\"center\",justifyContent:\"center\",width:recipe.avatarSize,height:recipe.avatarSize,flexShrink:0,borderRadius:\"50%\",overflow:\"hidden\"}}>{avatar}</span>\n <span style={{display:\"flex\",flexDirection:\"column\",gap:recipe.contentGap,flex:1,minWidth:0}}>\n <Text style={{overflow:\"hidden\",textOverflow:\"ellipsis\",whiteSpace:\"nowrap\",fontWeight:unread?recipe.unreadTitleWeight:recipe.titleWeight}}>{title}</Text>\n <span style={{display:\"flex\",minWidth:0}}>\n {hasPreview ? <Text variant=\"label\" tone={unread?\"primary\":\"subtle\"} style={{overflow:\"hidden\",textOverflow:\"ellipsis\",whiteSpace:\"nowrap\",fontWeight:unread?recipe.unreadPreviewWeight:recipe.titleWeight}}>{preview}</Text> : null}\n {hasMetadata ? <Text variant=\"label\" tone={unread?\"primary\":\"subtle\"} style={{flexShrink:0,/* \"pre\": flex items drop the leading space of \" · \" (2026-10-17 comparison); still no wrap. */whiteSpace:\"pre\",fontWeight:unread?recipe.unreadPreviewWeight:recipe.titleWeight}}>{hasPreview ? ` · ${metadata}` : metadata}</Text> : null}\n </span>\n </span>\n {unread?<span data-hjm-unread-dot=\"true\" style={{width:recipe.unreadSize,height:recipe.unreadSize,flexShrink:0,borderRadius:\"50%\",background:\"var(--hjm-color-content-brand)\"}}/>:null}\n </span>;\n}\n"]}
@@ -16,6 +16,8 @@ export type DataTableProps<ColumnKey extends string = string, RowKey extends str
16
16
  rows: readonly DataTableRowDescriptor<RowKey>[];
17
17
  labels: DataTableLabels;
18
18
  renderCell: (rowId: RowKey, columnId: ColumnKey) => ReactNode;
19
+ /** Text for rich cells. Native composes the row name; Web labels each cell. Omit to use visible primitive text. */
20
+ getCellText?: (rowId: RowKey, columnId: ColumnKey) => string | undefined;
19
21
  selection?: DataTableSelection<RowKey>;
20
22
  sortState?: DataTableSortState<ColumnKey>;
21
23
  sortCycle?: DataTableSortCycle;
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../src/data-table.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"data-table.d.ts","sourceRoot":"","sources":["../src/data-table.tsx"],"names":[],"mappings":"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"}
@@ -38,7 +38,7 @@ function bodySections(items) {
38
38
  // An empty table still renders one (empty) tbody, as before row groups existed.
39
39
  return sections.length > 0 ? sections : [{ group: null, rows: [] }];
40
40
  }
41
- export const DataTable = forwardRef(function DataTable({ columns, rows, labels, renderCell, selection, sortState = null, sortCycle = dataTableDefaults.sortCycle, onSortChange, asyncState = { status: "idle" }, density: densityProp, footer, summaryRow, columnGroups, rowGroups, cellStyle, heatColors, maxBodyHeight, className, layoutStyle, }, forwardedRef) {
41
+ export const DataTable = forwardRef(function DataTable({ columns, rows, labels, renderCell, getCellText, selection, sortState = null, sortCycle = dataTableDefaults.sortCycle, onSortChange, asyncState = { status: "idle" }, density: densityProp, footer, summaryRow, columnGroups, rowGroups, cellStyle, heatColors, maxBodyHeight, className, layoutStyle, }, forwardedRef) {
42
42
  // Unconditional: `??` on the hook call would break the rules of hooks.
43
43
  const densityDefault = useHjmDensityDefault({ comfortable: "regular", compact: "compact" });
44
44
  const density = densityProp ?? densityDefault;
@@ -158,7 +158,7 @@ export const DataTable = forwardRef(function DataTable({ columns, rows, labels,
158
158
  const emphasis = tableCellEmphasis(cellStyle?.(row.id, column.id), heatColors);
159
159
  // Sub-rows (TanStack `depth`) indent only the first column, which is the pinned one when pinning.
160
160
  const depth = columnIndex === 0 ? row.depth ?? 0 : 0;
161
- return (_jsx("td", { className: classNames(sticky.className, emphasis.heat && "hjm-table-family__heat"), "data-tone": emphasis.tone, "data-heat": emphasis.heat, "data-depth": depth > 0 ? depth : undefined, style: {
161
+ return (_jsx("td", { "aria-label": getCellText?.(row.id, column.id), className: classNames(sticky.className, emphasis.heat && "hjm-table-family__heat"), "data-tone": emphasis.tone, "data-heat": emphasis.heat, "data-depth": depth > 0 ? depth : undefined, style: {
162
162
  textAlign: column.align ?? dataTableColumnDefaults.align,
163
163
  ...emphasis.style,
164
164
  ...(depth > 0 ? { "--hjm-data-table-indent": `${depth * dataTableFamilyRecipe.depthIndent}px` } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"data-table.js","sourceRoot":"","sources":["../src/data-table.tsx"],"names":[],"mappings":"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","sourcesContent":["import { TableSortButton } from \"./table-sort-button.js\";\nimport {\n dataTableColumnDefaults,\n dataTableDefaults,\n dataTableFamilyRecipe,\n dataTableFirstSortDirection,\n getNextDataTableSortState,\n resolveDataTableBody,\n resolveDataTableHeaderBands,\n splitPinnedDataTableColumns,\n resolveDataTableSelectAllState,\n validateDataTableColumns,\n validateDataTableRows,\n validateDataTableSortState,\n type DataTableAsyncState,\n type DataTableBodyItem,\n type DataTableCellHeat,\n type DataTableCellTone,\n type DataTableColumnDescriptor,\n type DataTableColumnGroup,\n type DataTableDensity,\n type DataTableRowDescriptor,\n type DataTableRowGroup,\n type DataTableSelection,\n type DataTableSortCycle,\n type DataTableSortState,\n} from \"@hjmds/design-contracts/components/data-table\";\nimport { forwardRef, useLayoutEffect, useMemo, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { useHjmDensityDefault } from \"./provider.js\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { tableCellEmphasis, type TableHeatColors } from \"./table-family.js\";\n\nexport type DataTableLabels = Readonly<{\n /** Accessible name for the table itself. */\n table: string;\n selectAll: string;\n /** Composes one row's selection control name from its id. */\n selectRow: (rowId: string) => string;\n /** Composes a sortable header's action name, including its current direction. */\n sortColumn: (header: string, direction: DataTableSortState<string>) => string;\n}>;\n\nexport type DataTableProps<ColumnKey extends string = string, RowKey extends string = string> = Readonly<{\n columns: readonly DataTableColumnDescriptor<ColumnKey>[];\n rows: readonly DataTableRowDescriptor<RowKey>[];\n labels: DataTableLabels;\n renderCell: (rowId: RowKey, columnId: ColumnKey) => ReactNode;\n selection?: DataTableSelection<RowKey>;\n sortState?: DataTableSortState<ColumnKey>;\n sortCycle?: DataTableSortCycle;\n onSortChange?: (next: DataTableSortState<ColumnKey>) => void;\n asyncState?: DataTableAsyncState;\n density?: DataTableDensity;\n /** Composed beneath the table by the product — pagination, load more, totals. */\n footer?: ReactNode;\n /**\n * Optional summary row rendered as the table's `tfoot` (totals, averages). Returns the cell for\n * each column; HJM never computes the aggregate (2026-10-14, stat tables).\n */\n summaryRow?: (columnId: ColumnKey) => ReactNode;\n /** Header bands above leaf columns (Batting | Running). */\n columnGroups?: readonly DataTableColumnGroup<ColumnKey>[];\n /** Labeled row sections (Starters / Substitutes); each renders as its own `tbody`. */\n rowGroups?: readonly DataTableRowGroup<RowKey>[];\n /** Per-cell emphasis decided by the product (AG Grid cellClassRules / Savant percentile heat). */\n cellStyle?: (rowId: RowKey, columnId: ColumnKey) => Readonly<{ tone?: DataTableCellTone | null; heat?: DataTableCellHeat | null }> | null;\n /** Heat base colors (any CSS color); default high = danger red, low = info blue (Savant). */\n heatColors?: TableHeatColors;\n /** Bounds the scroll box height in px; the header stays fixed while rows scroll. */\n maxBodyHeight?: number;\n className?: string;\n /** Canonical layout-only placement on the root wrapper. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nfunction selectedRowKeysFrom<RowKey extends string>(\n selection: DataTableSelection<RowKey> | undefined,\n): ReadonlySet<RowKey> {\n if (!selection || selection.mode === \"none\") return new Set<RowKey>();\n if (selection.mode === \"single\") {\n const key = selection.selectedKey ?? selection.defaultSelectedKey ?? null;\n return key === null ? new Set<RowKey>() : new Set<RowKey>([key]);\n }\n return selection.selectedKeys ?? selection.defaultSelectedKeys ?? new Set<RowKey>();\n}\n\n/**\n * Pinned columns and bounded heights need their own scroll box (sticky cells stick to it);\n * other tables keep the original DOM.\n */\nfunction TableScroll({ scroll, maxBodyHeight, children }: Readonly<{ scroll: boolean; maxBodyHeight?: number | undefined; children: ReactNode }>) {\n if (!scroll && maxBodyHeight === undefined) return <>{children}</>;\n return (\n <div className=\"hjm-data-table__scroll\" data-bounded={maxBodyHeight !== undefined || undefined} style={maxBodyHeight !== undefined ? { maxBlockSize: maxBodyHeight } : undefined}>\n {children}\n </div>\n );\n}\n\ntype BodySection<RowKey> = { group: Readonly<{ id: string; label: string }> | null; rows: RowKey[] };\n\n/** Splits the resolved body into `tbody` sections: loose rows first, then one per row group. */\nfunction bodySections<RowKey>(items: readonly DataTableBodyItem<RowKey & string>[]): BodySection<RowKey>[] {\n const sections: BodySection<RowKey>[] = [];\n for (const item of items) {\n if (item.kind === \"group\") { sections.push({ group: { id: item.id, label: item.label }, rows: [] }); continue; }\n if (sections.length === 0) sections.push({ group: null, rows: [] });\n sections.at(-1)!.rows.push(item.id as RowKey);\n }\n // An empty table still renders one (empty) tbody, as before row groups existed.\n return sections.length > 0 ? sections : [{ group: null, rows: [] }];\n}\n\nexport const DataTable = forwardRef(function DataTable<\n ColumnKey extends string = string,\n RowKey extends string = string,\n>(\n {\n columns,\n rows,\n labels,\n renderCell,\n selection,\n sortState = null,\n sortCycle = dataTableDefaults.sortCycle,\n onSortChange,\n asyncState = { status: \"idle\" },\n density: densityProp,\n footer,\n summaryRow,\n columnGroups,\n rowGroups,\n cellStyle,\n heatColors,\n maxBodyHeight,\n className,\n layoutStyle,\n }: DataTableProps<ColumnKey, RowKey>,\n forwardedRef: React.Ref<HTMLTableElement>,\n) {\n // Unconditional: `??` on the hook call would break the rules of hooks.\n const densityDefault = useHjmDensityDefault({ comfortable: \"regular\", compact: \"compact\" });\n const density = densityProp ?? densityDefault;\n validateDataTableColumns(columns);\n validateDataTableRows(rows);\n validateDataTableSortState(sortState, columns);\n const multiple = selection?.mode === \"multiple\";\n const single = selection?.mode === \"single\";\n // `defaultSelectedKey(s)` used to be re-read on every render, so an\n // uncontrolled table reported the click to `onSelectionChange` but kept showing\n // the default (same defect and fix as Tree, 2026-10-06). The uncontrolled value\n // lives in state; a controlled `selectedKey(s)` (including `null`) still wins.\n const selectionControlled = single\n ? selection.selectedKey !== undefined\n : multiple ? selection.selectedKeys !== undefined : true;\n const [uncontrolledKeys, setUncontrolledKeys] = useState<ReadonlySet<RowKey>>(() => selectedRowKeysFrom(selection));\n const selectedKeys: ReadonlySet<RowKey> = selectionControlled\n ? selectedRowKeysFrom(selection)\n : uncontrolledKeys;\n const commitSelection = (next: ReadonlySet<RowKey>) => {\n if (!selectionControlled) setUncontrolledKeys(next);\n };\n const hasSelector = selection !== undefined && selection.mode !== \"none\";\n // Only an unbroken leading run is pinned (contract). Sticky offsets need the rendered widths of\n // the cells before each pinned column, so they are measured rather than guessed from `width`.\n const pinnedCount = splitPinnedDataTableColumns(columns).pinned.length;\n const headerRowRef = useRef<HTMLTableRowElement>(null);\n const [pinnedOffsets, setPinnedOffsets] = useState<readonly number[]>([]);\n useLayoutEffect(() => {\n const row = headerRowRef.current;\n if (!row || pinnedCount === 0) return;\n const stickyCells = pinnedCount + (hasSelector ? 1 : 0);\n const measure = () => {\n const cells = [...row.cells].slice(0, stickyCells);\n const offsets: number[] = [];\n let sum = 0;\n for (const cell of cells) { offsets.push(sum); sum += cell.getBoundingClientRect().width; }\n setPinnedOffsets((previous) => previous.length === offsets.length && previous.every((value, i) => value === offsets[i]) ? previous : offsets);\n };\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(measure);\n for (const cell of [...row.cells].slice(0, stickyCells)) observer.observe(cell);\n return () => observer.disconnect();\n }, [pinnedCount, hasSelector, columns]);\n // Sticky props for the selector cell (when pinning) and each pinned column, by visual position.\n const stickyAt = (position: number, isLast: boolean): Readonly<{ className?: string; style?: CSSProperties }> => {\n if (pinnedCount === 0) return {};\n return {\n className: isLast ? \"hjm-data-table__pinned hjm-data-table__pinned-edge\" : \"hjm-data-table__pinned\",\n style: { insetInlineStart: pinnedOffsets[position] ?? 0 },\n };\n };\n const selectorSticky = hasSelector && pinnedCount > 0 ? stickyAt(0, false) : {};\n const columnSticky = (index: number) => index < pinnedCount ? stickyAt(index + (hasSelector ? 1 : 0), index === pinnedCount - 1) : {};\n const selectAllState = multiple ? resolveDataTableSelectAllState(rows, selectedKeys) : false;\n const bands = useMemo(() => columnGroups && columnGroups.length > 0 ? resolveDataTableHeaderBands(columns, columnGroups) : null, [columns, columnGroups]);\n const sections = useMemo(() => bodySections<RowKey>(resolveDataTableBody(rows, rowGroups ?? [])), [rows, rowGroups]);\n const rowById = useMemo(() => new Map(rows.map((row) => [row.id, row])), [rows]);\n const columnSpan = columns.length + (hasSelector ? 1 : 0);\n\n const toggleRow = (row: DataTableRowDescriptor<RowKey>) => {\n if (row.disabled || !selection || selection.mode === \"none\") return;\n if (selection.mode === \"single\") {\n const current = selectedKeys.has(row.id) ? row.id : null;\n const next = current === row.id && selection.disallowEmptySelection !== true ? null : row.id;\n commitSelection(next === null ? new Set<RowKey>() : new Set<RowKey>([next]));\n selection.onSelectionChange?.(next);\n return;\n }\n const next = new Set(selectedKeys);\n if (next.has(row.id)) next.delete(row.id); else next.add(row.id);\n commitSelection(next);\n selection.onSelectionChange?.(next);\n };\n const toggleAll = () => {\n if (!multiple) return;\n // Disabled rows stay out of both the denominator and the result, matching\n // the shared select-all accounting.\n const selectable = rows.filter((row) => !row.disabled);\n const next = selectAllState === true\n ? new Set([...selectedKeys].filter((id) => !selectable.some((row) => row.id === id)))\n : new Set([...selectedKeys, ...selectable.map((row) => row.id)]);\n commitSelection(next);\n selection.onSelectionChange?.(next);\n };\n\n return (\n <div className={classNames(\"hjm-data-table\", className)} style={layoutStyle} data-density={density}>\n {asyncState.status === \"idle\" ? null : (\n <p className=\"hjm-data-table__state\" role={asyncState.status === \"error\" ? \"alert\" : \"status\"}>{asyncState.message}</p>\n )}\n <TableScroll scroll={pinnedCount > 0} maxBodyHeight={maxBodyHeight}>\n <table ref={forwardedRef} className=\"hjm-data-table__table\" aria-label={labels.table} aria-busy={asyncState.status === \"loading\" || undefined}>\n <thead>\n {bands ? (\n <tr className=\"hjm-data-table__bands\">\n {hasSelector ? <td aria-hidden=\"true\" className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style} /> : null}\n {bands.map((band) => {\n const first = columns.findIndex((column) => column.id === band.columnIds[0]);\n // A band sticks only when every column under it is pinned; otherwise it scrolls with them.\n const sticky = first + band.span <= pinnedCount ? columnSticky(first + band.span - 1) : {};\n const stickyStyle = sticky.style ? { insetInlineStart: pinnedOffsets[first + (hasSelector ? 1 : 0)] ?? 0 } : undefined;\n return band.header === null\n ? <td key={band.id} aria-hidden=\"true\" colSpan={band.span} className={sticky.className} style={stickyStyle} />\n : <th key={band.id} scope=\"colgroup\" colSpan={band.span} className={classNames(\"hjm-data-table__band\", sticky.className)} style={stickyStyle}><span>{band.header}</span></th>;\n })}\n </tr>\n ) : null}\n <tr ref={headerRowRef}>\n {selection && selection.mode !== \"none\" ? (\n <th scope=\"col\" className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style}>\n {multiple ? (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={selectAllState === \"mixed\" ? \"mixed\" : String(selectAllState === true) as \"true\" | \"false\"}\n aria-label={labels.selectAll}\n className=\"hjm-data-table__check\"\n onClick={toggleAll}\n >\n {selectAllState === true ? \"✓\" : selectAllState === \"mixed\" ? \"–\" : \"\"}\n </button>\n ) : null}\n </th>\n ) : null}\n {columns.map((column, columnIndex) => {\n const sorted = sortState?.columnId === column.id ? sortState.direction : null;\n const sticky = columnSticky(columnIndex);\n return (\n <th\n key={column.id}\n scope=\"col\"\n // The direction passes straight through to aria-sort; the\n // contract already speaks that vocabulary.\n aria-sort={sorted ?? undefined}\n className={sticky.className}\n style={{ inlineSize: column.width, textAlign: column.align ?? dataTableColumnDefaults.align, ...sticky.style } as CSSProperties}\n >\n {column.sortable ? (\n // A button inside the header, never the header itself.\n <TableSortButton\n header={column.header}\n direction={sorted}\n glyphs={{ ascending: \"▲\", descending: \"▼\", none: \"↕\" }}\n className=\"hjm-data-table__sort\"\n accessibleName={labels.sortColumn(column.header, sortState as DataTableSortState<string>)}\n // `sortDescFirst` columns (stat tables: highest first) start descending.\n onSort={() => onSortChange?.(getNextDataTableSortState(sortState, column.id, sortCycle, dataTableFirstSortDirection(column)))}\n />\n ) : column.header}\n </th>\n );\n })}\n </tr>\n </thead>\n {sections.map((section) => (\n <tbody key={section.group?.id ?? \"rows\"}>\n {section.group ? (\n <tr className=\"hjm-data-table__group\">\n <th scope=\"rowgroup\" colSpan={columnSpan}><span>{section.group.label}</span></th>\n </tr>\n ) : null}\n {section.rows.map((rowId) => rowById.get(rowId)!).map((row) => (\n <tr key={row.id} aria-selected={selection && selection.mode !== \"none\" ? selectedKeys.has(row.id) : undefined} data-disabled={row.disabled || undefined}>\n {selection && selection.mode !== \"none\" ? (\n <td className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style}>\n <button\n type=\"button\"\n role={multiple ? \"checkbox\" : \"radio\"}\n aria-checked={selectedKeys.has(row.id)}\n aria-label={labels.selectRow(row.id)}\n aria-disabled={row.disabled || undefined}\n className=\"hjm-data-table__check\"\n onClick={() => toggleRow(row)}\n >\n {selectedKeys.has(row.id) ? \"✓\" : \"\"}\n </button>\n </td>\n ) : null}\n {columns.map((column, columnIndex) => {\n const sticky = columnSticky(columnIndex);\n const emphasis = tableCellEmphasis(cellStyle?.(row.id, column.id), heatColors);\n // Sub-rows (TanStack `depth`) indent only the first column, which is the pinned one when pinning.\n const depth = columnIndex === 0 ? row.depth ?? 0 : 0;\n return (\n <td\n key={column.id}\n className={classNames(sticky.className, emphasis.heat && \"hjm-table-family__heat\")}\n data-tone={emphasis.tone}\n data-heat={emphasis.heat}\n data-depth={depth > 0 ? depth : undefined}\n style={{\n textAlign: column.align ?? dataTableColumnDefaults.align,\n ...emphasis.style,\n ...(depth > 0 ? { \"--hjm-data-table-indent\": `${depth * dataTableFamilyRecipe.depthIndent}px` } : {}),\n ...sticky.style,\n } as CSSProperties}\n >\n {renderCell(row.id, column.id)}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n ))}\n {summaryRow ? (\n <tfoot>\n <tr className=\"hjm-data-table__summary\">\n {hasSelector ? <td className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style} /> : null}\n {columns.map((column, columnIndex) => {\n const sticky = columnSticky(columnIndex);\n return (\n <td key={column.id} className={sticky.className} style={{ textAlign: column.align ?? dataTableColumnDefaults.align, ...sticky.style } as CSSProperties}>\n {summaryRow(column.id)}\n </td>\n );\n })}\n </tr>\n </tfoot>\n ) : null}\n </table>\n </TableScroll>\n {/* Pagination or load-more is composed beneath the table, never owned by it. */}\n {footer ? <div className=\"hjm-data-table__footer\">{footer}</div> : null}\n </div>\n );\n}) as <ColumnKey extends string = string, RowKey extends string = string>(\n props: DataTableProps<ColumnKey, RowKey> & { ref?: React.Ref<HTMLTableElement> },\n) => React.ReactElement | null;\n\nexport {\n LineScore,\n MatrixTable,\n ComparisonTable,\n type LineScoreProps,\n type MatrixTableProps,\n type ComparisonTableProps,\n type TableHeatColors,\n} from \"./table-family.js\";\n"]}
1
+ {"version":3,"file":"data-table.js","sourceRoot":"","sources":["../src/data-table.tsx"],"names":[],"mappings":"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","sourcesContent":["import { TableSortButton } from \"./table-sort-button.js\";\nimport {\n dataTableColumnDefaults,\n dataTableDefaults,\n dataTableFamilyRecipe,\n dataTableFirstSortDirection,\n getNextDataTableSortState,\n resolveDataTableBody,\n resolveDataTableHeaderBands,\n splitPinnedDataTableColumns,\n resolveDataTableSelectAllState,\n validateDataTableColumns,\n validateDataTableRows,\n validateDataTableSortState,\n type DataTableAsyncState,\n type DataTableBodyItem,\n type DataTableCellHeat,\n type DataTableCellTone,\n type DataTableColumnDescriptor,\n type DataTableColumnGroup,\n type DataTableDensity,\n type DataTableRowDescriptor,\n type DataTableRowGroup,\n type DataTableSelection,\n type DataTableSortCycle,\n type DataTableSortState,\n} from \"@hjmds/design-contracts/components/data-table\";\nimport { forwardRef, useLayoutEffect, useMemo, useRef, useState, type CSSProperties, type ReactNode } from \"react\";\nimport { useHjmDensityDefault } from \"./provider.js\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\nimport { tableCellEmphasis, type TableHeatColors } from \"./table-family.js\";\n\nexport type DataTableLabels = Readonly<{\n /** Accessible name for the table itself. */\n table: string;\n selectAll: string;\n /** Composes one row's selection control name from its id. */\n selectRow: (rowId: string) => string;\n /** Composes a sortable header's action name, including its current direction. */\n sortColumn: (header: string, direction: DataTableSortState<string>) => string;\n}>;\n\nexport type DataTableProps<ColumnKey extends string = string, RowKey extends string = string> = Readonly<{\n columns: readonly DataTableColumnDescriptor<ColumnKey>[];\n rows: readonly DataTableRowDescriptor<RowKey>[];\n labels: DataTableLabels;\n renderCell: (rowId: RowKey, columnId: ColumnKey) => ReactNode;\n /** Text for rich cells. Native composes the row name; Web labels each cell. Omit to use visible primitive text. */\n getCellText?: (rowId: RowKey, columnId: ColumnKey) => string | undefined;\n selection?: DataTableSelection<RowKey>;\n sortState?: DataTableSortState<ColumnKey>;\n sortCycle?: DataTableSortCycle;\n onSortChange?: (next: DataTableSortState<ColumnKey>) => void;\n asyncState?: DataTableAsyncState;\n density?: DataTableDensity;\n /** Composed beneath the table by the product — pagination, load more, totals. */\n footer?: ReactNode;\n /**\n * Optional summary row rendered as the table's `tfoot` (totals, averages). Returns the cell for\n * each column; HJM never computes the aggregate (2026-10-14, stat tables).\n */\n summaryRow?: (columnId: ColumnKey) => ReactNode;\n /** Header bands above leaf columns (Batting | Running). */\n columnGroups?: readonly DataTableColumnGroup<ColumnKey>[];\n /** Labeled row sections (Starters / Substitutes); each renders as its own `tbody`. */\n rowGroups?: readonly DataTableRowGroup<RowKey>[];\n /** Per-cell emphasis decided by the product (AG Grid cellClassRules / Savant percentile heat). */\n cellStyle?: (rowId: RowKey, columnId: ColumnKey) => Readonly<{ tone?: DataTableCellTone | null; heat?: DataTableCellHeat | null }> | null;\n /** Heat base colors (any CSS color); default high = danger red, low = info blue (Savant). */\n heatColors?: TableHeatColors;\n /** Bounds the scroll box height in px; the header stays fixed while rows scroll. */\n maxBodyHeight?: number;\n className?: string;\n /** Canonical layout-only placement on the root wrapper. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nfunction selectedRowKeysFrom<RowKey extends string>(\n selection: DataTableSelection<RowKey> | undefined,\n): ReadonlySet<RowKey> {\n if (!selection || selection.mode === \"none\") return new Set<RowKey>();\n if (selection.mode === \"single\") {\n const key = selection.selectedKey ?? selection.defaultSelectedKey ?? null;\n return key === null ? new Set<RowKey>() : new Set<RowKey>([key]);\n }\n return selection.selectedKeys ?? selection.defaultSelectedKeys ?? new Set<RowKey>();\n}\n\n/**\n * Pinned columns and bounded heights need their own scroll box (sticky cells stick to it);\n * other tables keep the original DOM.\n */\nfunction TableScroll({ scroll, maxBodyHeight, children }: Readonly<{ scroll: boolean; maxBodyHeight?: number | undefined; children: ReactNode }>) {\n if (!scroll && maxBodyHeight === undefined) return <>{children}</>;\n return (\n <div className=\"hjm-data-table__scroll\" data-bounded={maxBodyHeight !== undefined || undefined} style={maxBodyHeight !== undefined ? { maxBlockSize: maxBodyHeight } : undefined}>\n {children}\n </div>\n );\n}\n\ntype BodySection<RowKey> = { group: Readonly<{ id: string; label: string }> | null; rows: RowKey[] };\n\n/** Splits the resolved body into `tbody` sections: loose rows first, then one per row group. */\nfunction bodySections<RowKey>(items: readonly DataTableBodyItem<RowKey & string>[]): BodySection<RowKey>[] {\n const sections: BodySection<RowKey>[] = [];\n for (const item of items) {\n if (item.kind === \"group\") { sections.push({ group: { id: item.id, label: item.label }, rows: [] }); continue; }\n if (sections.length === 0) sections.push({ group: null, rows: [] });\n sections.at(-1)!.rows.push(item.id as RowKey);\n }\n // An empty table still renders one (empty) tbody, as before row groups existed.\n return sections.length > 0 ? sections : [{ group: null, rows: [] }];\n}\n\nexport const DataTable = forwardRef(function DataTable<\n ColumnKey extends string = string,\n RowKey extends string = string,\n>(\n {\n columns,\n rows,\n labels,\n renderCell,\n getCellText,\n selection,\n sortState = null,\n sortCycle = dataTableDefaults.sortCycle,\n onSortChange,\n asyncState = { status: \"idle\" },\n density: densityProp,\n footer,\n summaryRow,\n columnGroups,\n rowGroups,\n cellStyle,\n heatColors,\n maxBodyHeight,\n className,\n layoutStyle,\n }: DataTableProps<ColumnKey, RowKey>,\n forwardedRef: React.Ref<HTMLTableElement>,\n) {\n // Unconditional: `??` on the hook call would break the rules of hooks.\n const densityDefault = useHjmDensityDefault({ comfortable: \"regular\", compact: \"compact\" });\n const density = densityProp ?? densityDefault;\n validateDataTableColumns(columns);\n validateDataTableRows(rows);\n validateDataTableSortState(sortState, columns);\n const multiple = selection?.mode === \"multiple\";\n const single = selection?.mode === \"single\";\n // `defaultSelectedKey(s)` used to be re-read on every render, so an\n // uncontrolled table reported the click to `onSelectionChange` but kept showing\n // the default (same defect and fix as Tree, 2026-10-06). The uncontrolled value\n // lives in state; a controlled `selectedKey(s)` (including `null`) still wins.\n const selectionControlled = single\n ? selection.selectedKey !== undefined\n : multiple ? selection.selectedKeys !== undefined : true;\n const [uncontrolledKeys, setUncontrolledKeys] = useState<ReadonlySet<RowKey>>(() => selectedRowKeysFrom(selection));\n const selectedKeys: ReadonlySet<RowKey> = selectionControlled\n ? selectedRowKeysFrom(selection)\n : uncontrolledKeys;\n const commitSelection = (next: ReadonlySet<RowKey>) => {\n if (!selectionControlled) setUncontrolledKeys(next);\n };\n const hasSelector = selection !== undefined && selection.mode !== \"none\";\n // Only an unbroken leading run is pinned (contract). Sticky offsets need the rendered widths of\n // the cells before each pinned column, so they are measured rather than guessed from `width`.\n const pinnedCount = splitPinnedDataTableColumns(columns).pinned.length;\n const headerRowRef = useRef<HTMLTableRowElement>(null);\n const [pinnedOffsets, setPinnedOffsets] = useState<readonly number[]>([]);\n useLayoutEffect(() => {\n const row = headerRowRef.current;\n if (!row || pinnedCount === 0) return;\n const stickyCells = pinnedCount + (hasSelector ? 1 : 0);\n const measure = () => {\n const cells = [...row.cells].slice(0, stickyCells);\n const offsets: number[] = [];\n let sum = 0;\n for (const cell of cells) { offsets.push(sum); sum += cell.getBoundingClientRect().width; }\n setPinnedOffsets((previous) => previous.length === offsets.length && previous.every((value, i) => value === offsets[i]) ? previous : offsets);\n };\n measure();\n if (typeof ResizeObserver === \"undefined\") return;\n const observer = new ResizeObserver(measure);\n for (const cell of [...row.cells].slice(0, stickyCells)) observer.observe(cell);\n return () => observer.disconnect();\n }, [pinnedCount, hasSelector, columns]);\n // Sticky props for the selector cell (when pinning) and each pinned column, by visual position.\n const stickyAt = (position: number, isLast: boolean): Readonly<{ className?: string; style?: CSSProperties }> => {\n if (pinnedCount === 0) return {};\n return {\n className: isLast ? \"hjm-data-table__pinned hjm-data-table__pinned-edge\" : \"hjm-data-table__pinned\",\n style: { insetInlineStart: pinnedOffsets[position] ?? 0 },\n };\n };\n const selectorSticky = hasSelector && pinnedCount > 0 ? stickyAt(0, false) : {};\n const columnSticky = (index: number) => index < pinnedCount ? stickyAt(index + (hasSelector ? 1 : 0), index === pinnedCount - 1) : {};\n const selectAllState = multiple ? resolveDataTableSelectAllState(rows, selectedKeys) : false;\n const bands = useMemo(() => columnGroups && columnGroups.length > 0 ? resolveDataTableHeaderBands(columns, columnGroups) : null, [columns, columnGroups]);\n const sections = useMemo(() => bodySections<RowKey>(resolveDataTableBody(rows, rowGroups ?? [])), [rows, rowGroups]);\n const rowById = useMemo(() => new Map(rows.map((row) => [row.id, row])), [rows]);\n const columnSpan = columns.length + (hasSelector ? 1 : 0);\n\n const toggleRow = (row: DataTableRowDescriptor<RowKey>) => {\n if (row.disabled || !selection || selection.mode === \"none\") return;\n if (selection.mode === \"single\") {\n const current = selectedKeys.has(row.id) ? row.id : null;\n const next = current === row.id && selection.disallowEmptySelection !== true ? null : row.id;\n commitSelection(next === null ? new Set<RowKey>() : new Set<RowKey>([next]));\n selection.onSelectionChange?.(next);\n return;\n }\n const next = new Set(selectedKeys);\n if (next.has(row.id)) next.delete(row.id); else next.add(row.id);\n commitSelection(next);\n selection.onSelectionChange?.(next);\n };\n const toggleAll = () => {\n if (!multiple) return;\n // Disabled rows stay out of both the denominator and the result, matching\n // the shared select-all accounting.\n const selectable = rows.filter((row) => !row.disabled);\n const next = selectAllState === true\n ? new Set([...selectedKeys].filter((id) => !selectable.some((row) => row.id === id)))\n : new Set([...selectedKeys, ...selectable.map((row) => row.id)]);\n commitSelection(next);\n selection.onSelectionChange?.(next);\n };\n\n return (\n <div className={classNames(\"hjm-data-table\", className)} style={layoutStyle} data-density={density}>\n {asyncState.status === \"idle\" ? null : (\n <p className=\"hjm-data-table__state\" role={asyncState.status === \"error\" ? \"alert\" : \"status\"}>{asyncState.message}</p>\n )}\n <TableScroll scroll={pinnedCount > 0} maxBodyHeight={maxBodyHeight}>\n <table ref={forwardedRef} className=\"hjm-data-table__table\" aria-label={labels.table} aria-busy={asyncState.status === \"loading\" || undefined}>\n <thead>\n {bands ? (\n <tr className=\"hjm-data-table__bands\">\n {hasSelector ? <td aria-hidden=\"true\" className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style} /> : null}\n {bands.map((band) => {\n const first = columns.findIndex((column) => column.id === band.columnIds[0]);\n // A band sticks only when every column under it is pinned; otherwise it scrolls with them.\n const sticky = first + band.span <= pinnedCount ? columnSticky(first + band.span - 1) : {};\n const stickyStyle = sticky.style ? { insetInlineStart: pinnedOffsets[first + (hasSelector ? 1 : 0)] ?? 0 } : undefined;\n return band.header === null\n ? <td key={band.id} aria-hidden=\"true\" colSpan={band.span} className={sticky.className} style={stickyStyle} />\n : <th key={band.id} scope=\"colgroup\" colSpan={band.span} className={classNames(\"hjm-data-table__band\", sticky.className)} style={stickyStyle}><span>{band.header}</span></th>;\n })}\n </tr>\n ) : null}\n <tr ref={headerRowRef}>\n {selection && selection.mode !== \"none\" ? (\n <th scope=\"col\" className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style}>\n {multiple ? (\n <button\n type=\"button\"\n role=\"checkbox\"\n aria-checked={selectAllState === \"mixed\" ? \"mixed\" : String(selectAllState === true) as \"true\" | \"false\"}\n aria-label={labels.selectAll}\n className=\"hjm-data-table__check\"\n onClick={toggleAll}\n >\n {selectAllState === true ? \"✓\" : selectAllState === \"mixed\" ? \"–\" : \"\"}\n </button>\n ) : null}\n </th>\n ) : null}\n {columns.map((column, columnIndex) => {\n const sorted = sortState?.columnId === column.id ? sortState.direction : null;\n const sticky = columnSticky(columnIndex);\n return (\n <th\n key={column.id}\n scope=\"col\"\n // The direction passes straight through to aria-sort; the\n // contract already speaks that vocabulary.\n aria-sort={sorted ?? undefined}\n className={sticky.className}\n style={{ inlineSize: column.width, textAlign: column.align ?? dataTableColumnDefaults.align, ...sticky.style } as CSSProperties}\n >\n {column.sortable ? (\n // A button inside the header, never the header itself.\n <TableSortButton\n header={column.header}\n direction={sorted}\n glyphs={{ ascending: \"▲\", descending: \"▼\", none: \"↕\" }}\n className=\"hjm-data-table__sort\"\n accessibleName={labels.sortColumn(column.header, sortState as DataTableSortState<string>)}\n // `sortDescFirst` columns (stat tables: highest first) start descending.\n onSort={() => onSortChange?.(getNextDataTableSortState(sortState, column.id, sortCycle, dataTableFirstSortDirection(column)))}\n />\n ) : column.header}\n </th>\n );\n })}\n </tr>\n </thead>\n {sections.map((section) => (\n <tbody key={section.group?.id ?? \"rows\"}>\n {section.group ? (\n <tr className=\"hjm-data-table__group\">\n <th scope=\"rowgroup\" colSpan={columnSpan}><span>{section.group.label}</span></th>\n </tr>\n ) : null}\n {section.rows.map((rowId) => rowById.get(rowId)!).map((row) => (\n <tr key={row.id} aria-selected={selection && selection.mode !== \"none\" ? selectedKeys.has(row.id) : undefined} data-disabled={row.disabled || undefined}>\n {selection && selection.mode !== \"none\" ? (\n <td className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style}>\n <button\n type=\"button\"\n role={multiple ? \"checkbox\" : \"radio\"}\n aria-checked={selectedKeys.has(row.id)}\n aria-label={labels.selectRow(row.id)}\n aria-disabled={row.disabled || undefined}\n className=\"hjm-data-table__check\"\n onClick={() => toggleRow(row)}\n >\n {selectedKeys.has(row.id) ? \"✓\" : \"\"}\n </button>\n </td>\n ) : null}\n {columns.map((column, columnIndex) => {\n const sticky = columnSticky(columnIndex);\n const emphasis = tableCellEmphasis(cellStyle?.(row.id, column.id), heatColors);\n // Sub-rows (TanStack `depth`) indent only the first column, which is the pinned one when pinning.\n const depth = columnIndex === 0 ? row.depth ?? 0 : 0;\n return (\n <td\n key={column.id}\n aria-label={getCellText?.(row.id, column.id)}\n className={classNames(sticky.className, emphasis.heat && \"hjm-table-family__heat\")}\n data-tone={emphasis.tone}\n data-heat={emphasis.heat}\n data-depth={depth > 0 ? depth : undefined}\n style={{\n textAlign: column.align ?? dataTableColumnDefaults.align,\n ...emphasis.style,\n ...(depth > 0 ? { \"--hjm-data-table-indent\": `${depth * dataTableFamilyRecipe.depthIndent}px` } : {}),\n ...sticky.style,\n } as CSSProperties}\n >\n {renderCell(row.id, column.id)}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n ))}\n {summaryRow ? (\n <tfoot>\n <tr className=\"hjm-data-table__summary\">\n {hasSelector ? <td className={classNames(\"hjm-data-table__selector\", selectorSticky.className)} style={selectorSticky.style} /> : null}\n {columns.map((column, columnIndex) => {\n const sticky = columnSticky(columnIndex);\n return (\n <td key={column.id} className={sticky.className} style={{ textAlign: column.align ?? dataTableColumnDefaults.align, ...sticky.style } as CSSProperties}>\n {summaryRow(column.id)}\n </td>\n );\n })}\n </tr>\n </tfoot>\n ) : null}\n </table>\n </TableScroll>\n {/* Pagination or load-more is composed beneath the table, never owned by it. */}\n {footer ? <div className=\"hjm-data-table__footer\">{footer}</div> : null}\n </div>\n );\n}) as <ColumnKey extends string = string, RowKey extends string = string>(\n props: DataTableProps<ColumnKey, RowKey> & { ref?: React.Ref<HTMLTableElement> },\n) => React.ReactElement | null;\n\nexport {\n LineScore,\n MatrixTable,\n ComparisonTable,\n type LineScoreProps,\n type MatrixTableProps,\n type ComparisonTableProps,\n type TableHeatColors,\n} from \"./table-family.js\";\n"]}
package/dist/display.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { listRowRecipe, type BadgeSize, type BadgeTone, type BadgeVariant as ContractBadgeVariant, type ListRowDensity, type ListRowLeadingShape } from "@hjmds/design-contracts/recipes";
1
+ import { listRowRecipe, type BadgeAdornmentContext, type BadgeSize, type BadgeTone, type BadgeVariant as ContractBadgeVariant, type ListRowDensity, type ListRowLeadingShape } from "@hjmds/design-contracts/recipes";
2
2
  import { type TagTone } from "@hjmds/design-contracts/components/tag";
3
3
  import { type CardHeadingLevel } from "@hjmds/design-contracts/components/card";
4
4
  import { type SurfacePadding, type SurfaceRadius, type SurfaceTone } from "@hjmds/design-contracts/recipes/base";
@@ -11,8 +11,8 @@ export type BadgeProps = HTMLAttributes<HTMLSpanElement> & Readonly<{
11
11
  tone?: BadgeTone;
12
12
  size?: BadgeSize;
13
13
  variant?: BadgeVariant;
14
- leading?: ReactNode;
15
- trailing?: ReactNode;
14
+ leading?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);
15
+ trailing?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);
16
16
  /** Canonical layout-only placement. Controlled visual keys are excluded. */
17
17
  layoutStyle?: HjmCompositionStyleProp;
18
18
  }>;
@@ -20,8 +20,8 @@ export declare const Badge: import("react").ForwardRefExoticComponent<HTMLAttrib
20
20
  tone?: BadgeTone;
21
21
  size?: BadgeSize;
22
22
  variant?: BadgeVariant;
23
- leading?: ReactNode;
24
- trailing?: ReactNode;
23
+ leading?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);
24
+ trailing?: ReactNode | ((context: BadgeAdornmentContext) => ReactNode);
25
25
  /** Canonical layout-only placement. Controlled visual keys are excluded. */
26
26
  layoutStyle?: HjmCompositionStyleProp;
27
27
  }> & import("react").RefAttributes<HTMLSpanElement>>;
@@ -42,7 +42,25 @@ export type CardProps = Omit<HTMLAttributes<HTMLElement>, "title"> & Readonly<{
42
42
  description?: ReactNode;
43
43
  leading?: ReactNode;
44
44
  media?: ReactNode;
45
+ /** Decorative artwork behind the shared body/actions; its host determines the available height. */
46
+ backgroundMedia?: ReactNode;
47
+ /** Platform gesture/accessibility host behind content. Requires backgroundMedia; never put metadata/actions here. */
48
+ backgroundInteraction?: ReactNode;
49
+ /** Non-interactive cover classification at the shared top/end inset. Requires backgroundMedia. */
50
+ mediaBadges?: ReactNode;
51
+ badges?: ReactNode;
52
+ /** Activate only the passive cover; other card content/actions keep independent targets. */
53
+ mediaAction?: Readonly<{
54
+ label: string;
55
+ onActivate(): void;
56
+ icon?: (context: Readonly<{
57
+ color: string;
58
+ size: number;
59
+ }>) => ReactNode;
60
+ }>;
45
61
  actions?: ReactNode;
62
+ /** Independent commands at the header end; never nested in whole-card activation. */
63
+ headerActions?: ReactNode;
46
64
  headingLevel?: CardHeadingLevel;
47
65
  selected?: boolean;
48
66
  /**
@@ -50,6 +68,10 @@ export type CardProps = Omit<HTMLAttributes<HTMLElement>, "title"> & Readonly<{
50
68
  * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.
51
69
  */
52
70
  onActivate?: () => void;
71
+ /** A native anchor preserves new-tab, copy-link and browser previews; it is exclusive with onActivate. */
72
+ href?: string;
73
+ /** Framework routing and product effects can wrap the shared anchor without replacing its placement. */
74
+ renderLink?: (props: React.ComponentPropsWithRef<"a">) => ReactNode;
53
75
  disabled?: boolean;
54
76
  tone?: SurfaceTone;
55
77
  bordered?: boolean;
@@ -63,7 +85,25 @@ export declare const Card: import("react").ForwardRefExoticComponent<Omit<HTMLAt
63
85
  description?: ReactNode;
64
86
  leading?: ReactNode;
65
87
  media?: ReactNode;
88
+ /** Decorative artwork behind the shared body/actions; its host determines the available height. */
89
+ backgroundMedia?: ReactNode;
90
+ /** Platform gesture/accessibility host behind content. Requires backgroundMedia; never put metadata/actions here. */
91
+ backgroundInteraction?: ReactNode;
92
+ /** Non-interactive cover classification at the shared top/end inset. Requires backgroundMedia. */
93
+ mediaBadges?: ReactNode;
94
+ badges?: ReactNode;
95
+ /** Activate only the passive cover; other card content/actions keep independent targets. */
96
+ mediaAction?: Readonly<{
97
+ label: string;
98
+ onActivate(): void;
99
+ icon?: (context: Readonly<{
100
+ color: string;
101
+ size: number;
102
+ }>) => ReactNode;
103
+ }>;
66
104
  actions?: ReactNode;
105
+ /** Independent commands at the header end; never nested in whole-card activation. */
106
+ headerActions?: ReactNode;
67
107
  headingLevel?: CardHeadingLevel;
68
108
  selected?: boolean;
69
109
  /**
@@ -71,6 +111,10 @@ export declare const Card: import("react").ForwardRefExoticComponent<Omit<HTMLAt
71
111
  * action region, so actions remain independent buttons (never a button inside a button). Keep other children passive.
72
112
  */
73
113
  onActivate?: () => void;
114
+ /** A native anchor preserves new-tab, copy-link and browser previews; it is exclusive with onActivate. */
115
+ href?: string;
116
+ /** Framework routing and product effects can wrap the shared anchor without replacing its placement. */
117
+ renderLink?: (props: React.ComponentPropsWithRef<"a">) => ReactNode;
74
118
  disabled?: boolean;
75
119
  tone?: SurfaceTone;
76
120
  bordered?: boolean;
@@ -79,6 +123,17 @@ export declare const Card: import("react").ForwardRefExoticComponent<Omit<HTMLAt
79
123
  /** Canonical layout-only placement; forwarded to the root Surface, which applies it. */
80
124
  layoutStyle?: HjmCompositionStyleProp;
81
125
  }> & import("react").RefAttributes<HTMLElement>>;
126
+ /** An attributed quotation reuses Card material while keeping quotation semantics and its caption together. */
127
+ export type QuoteCardProps = Omit<HTMLAttributes<HTMLElement>, "children" | "title"> & Readonly<{
128
+ children: ReactNode;
129
+ attribution?: string;
130
+ renderMark?: (context: {
131
+ color: string;
132
+ size: number;
133
+ }) => ReactNode;
134
+ layoutStyle?: HjmCompositionStyleProp;
135
+ }>;
136
+ export declare function QuoteCard({ children, attribution, renderMark, ...props }: QuoteCardProps): import("react").JSX.Element;
82
137
  export type ListRowProps = Omit<HTMLAttributes<HTMLElement>, "title" | "onClick"> & Readonly<{
83
138
  title: ReactNode;
84
139
  description?: ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,IAAI,oBAAoB,EACzC,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEL,KAAK,OAAO,EACb,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC,eAAe,CAAC,GACtD,QAAQ,CAAC;IACP,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACnB,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,KAAK;WATP,SAAS;WACT,SAAS;cACN,YAAY;cACZ,SAAS;eACR,SAAS;IAClB,4EAA4E;kBAChE,uBAAuB;oDAuCvC,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,GACtE,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACb,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,GAAG;cANF,MAAM;WACT,OAAO;IACZ,4EAA4E;kBAChE,uBAAuB;oDAsBvC,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAChE,QAAQ,CAAC;IACP,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,wFAAwF;IACxF,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL,eAAO,MAAM,IAAI;YArBL,SAAS;kBACH,SAAS;cACb,SAAS;YACX,SAAS;cACP,SAAS;mBACJ,gBAAgB;eACpB,OAAO;IAClB;;;OAGG;iBACU,MAAM,IAAI;eACZ,OAAO;WACX,WAAW;eACP,OAAO;cACR,cAAc;aACf,aAAa;IACtB,wFAAwF;kBAC1E,uBAAuB;gDAyGvC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,GAC/E,QAAQ,CAAC;IACP,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACpE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,OAAO,aAAa,CAAC,KAAK,CAAC;IACxC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACvC,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,OAAO;WA7BT,SAAS;kBACF,SAAS;cACb,SAAS;eACR,SAAS;IACpB,+DAA+D;qBAC9C,SAAS;IAC1B,uEAAuE;iBAC1D,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS;cACzD,cAAc;IACxB,mFAAmF;WAC5E,MAAM,OAAO,aAAa,CAAC,KAAK;IACvC,2EAA2E;mBAC5D,mBAAmB;eACvB,OAAO;eACP,OAAO;IAClB;;;;OAIG;cACO,OAAO;IACjB,uDAAuD;mBACxC,MAAM;WACd,MAAM;cACH,iBAAiB,CAAC,WAAW,CAAC;IACtC,4EAA4E;kBAChE,uBAAuB;gDAsHvC,CAAC"}
1
+ {"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,aAAa,EACb,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,YAAY,IAAI,oBAAoB,EACzC,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACzB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAEL,KAAK,OAAO,EACb,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAEL,KAAK,gBAAgB,EACtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EACjB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EAAE,OAAO,EAAE,MAAM,wCAAwC,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,oBAAoB,CAAC;AAEhD,MAAM,MAAM,UAAU,GAAG,cAAc,CAAC,eAAe,CAAC,GACtD,QAAQ,CAAC;IACP,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,OAAO,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,OAAO,EAAE,qBAAqB,KAAK,SAAS,CAAC,CAAC;IACtE,QAAQ,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC,OAAO,EAAE,qBAAqB,KAAK,SAAS,CAAC,CAAC;IACrE,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,KAAK;WATP,SAAS;WACT,SAAS;cACN,YAAY;cACZ,SAAS,GAAG,CAAC,CAAC,OAAO,EAAE,qBAAqB,KAAK,SAAS,CAAC;eAC1D,SAAS,GAAG,CAAC,CAAC,OAAO,EAAE,qBAAqB,KAAK,SAAS,CAAC;IACpE,4EAA4E;kBAChE,uBAAuB;oDAwCvC,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,EAAE,UAAU,CAAC,GACtE,QAAQ,CAAC;IACP,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACb,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,GAAG;cANF,MAAM;WACT,OAAO;IACZ,4EAA4E;kBAChE,uBAAuB;oDAsBvC,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC,GAChE,QAAQ,CAAC;IACP,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,mGAAmG;IACnG,eAAe,CAAC,EAAE,SAAS,CAAC;IAC5B,qHAAqH;IACrH,qBAAqB,CAAC,EAAE,SAAS,CAAC;IAClC,kGAAkG;IAClG,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,4FAA4F;IAC5F,WAAW,CAAC,EAAE,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,IAAI,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,KAAK,SAAS,CAAA;KAAE,CAAC,CAAC;IACxI,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,qFAAqF;IACrF,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,0GAA0G;IAC1G,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wGAAwG;IACxG,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,wFAAwF;IACxF,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL,eAAO,MAAM,IAAI;YApCL,SAAS;kBACH,SAAS;cACb,SAAS;YACX,SAAS;IACjB,mGAAmG;sBACjF,SAAS;IAC3B,qHAAqH;4BAC7F,SAAS;IACjC,kGAAkG;kBACpF,SAAS;aACd,SAAS;IAClB,4FAA4F;kBAC9E,QAAQ,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,IAAI,IAAI,CAAC;QAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,CAAC,KAAK,SAAS,CAAA;KAAE,CAAC;cAC7H,SAAS;IACnB,qFAAqF;oBACrE,SAAS;mBACV,gBAAgB;eACpB,OAAO;IAClB;;;OAGG;iBACU,MAAM,IAAI;IACvB,0GAA0G;WACnG,MAAM;IACb,wGAAwG;iBAC3F,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS;eACxD,OAAO;WACX,WAAW;eACP,OAAO;cACR,cAAc;aACf,aAAa;IACtB,wFAAwF;kBAC1E,uBAAuB;gDAqIvC,CAAC;AAEH,+GAA+G;AAC/G,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC;IAC9F,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,SAAS,CAAC;IACrE,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAOxF;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC,GAC/E,QAAQ,CAAC;IACP,KAAK,EAAE,SAAS,CAAC;IACjB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,+DAA+D;IAC/D,cAAc,CAAC,EAAE,SAAS,CAAC;IAC3B,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;IACpE,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,mFAAmF;IACnF,IAAI,CAAC,EAAE,MAAM,OAAO,aAAa,CAAC,KAAK,CAAC;IACxC,2EAA2E;IAC3E,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uDAAuD;IACvD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACvC,4EAA4E;IAC9E,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACzC,CAAC,CAAC;AAEH,eAAO,MAAM,OAAO;WA7BT,SAAS;kBACF,SAAS;cACb,SAAS;eACR,SAAS;IACpB,+DAA+D;qBAC9C,SAAS;IAC1B,uEAAuE;iBAC1D,CAAC,KAAK,EAAE,KAAK,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,SAAS;cACzD,cAAc;IACxB,mFAAmF;WAC5E,MAAM,OAAO,aAAa,CAAC,KAAK;IACvC,2EAA2E;mBAC5D,mBAAmB;eACvB,OAAO;eACP,OAAO;IAClB;;;;OAIG;cACO,OAAO;IACjB,uDAAuD;mBACxC,MAAM;WACd,MAAM;cACH,iBAAiB,CAAC,WAAW,CAAC;IACtC,4EAA4E;kBAChE,uBAAuB;gDAsHvC,CAAC"}