@hjmds/react 1.18.0 → 1.19.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 (188) hide show
  1. package/dist/advanced-display.d.ts.map +1 -1
  2. package/dist/advanced-display.js +41 -9
  3. package/dist/advanced-display.js.map +1 -1
  4. package/dist/advanced-forms.d.ts.map +1 -1
  5. package/dist/advanced-forms.js +22 -9
  6. package/dist/advanced-forms.js.map +1 -1
  7. package/dist/agreement.d.ts.map +1 -1
  8. package/dist/agreement.js +17 -11
  9. package/dist/agreement.js.map +1 -1
  10. package/dist/auth-screen.d.ts.map +1 -1
  11. package/dist/auth-screen.js +15 -2
  12. package/dist/auth-screen.js.map +1 -1
  13. package/dist/avatar-blobatar-motion.d.ts.map +1 -1
  14. package/dist/avatar-blobatar-motion.js +10 -2
  15. package/dist/avatar-blobatar-motion.js.map +1 -1
  16. package/dist/bottom-navigation.d.ts.map +1 -1
  17. package/dist/bottom-navigation.js +1 -1
  18. package/dist/bottom-navigation.js.map +1 -1
  19. package/dist/calendar.d.ts.map +1 -1
  20. package/dist/calendar.js +10 -2
  21. package/dist/calendar.js.map +1 -1
  22. package/dist/carousel-motion.d.ts +1 -0
  23. package/dist/carousel-motion.d.ts.map +1 -1
  24. package/dist/carousel-motion.js +4 -3
  25. package/dist/carousel-motion.js.map +1 -1
  26. package/dist/carousel.d.ts.map +1 -1
  27. package/dist/carousel.js +22 -4
  28. package/dist/carousel.js.map +1 -1
  29. package/dist/collapsible.d.ts.map +1 -1
  30. package/dist/collapsible.js +28 -4
  31. package/dist/collapsible.js.map +1 -1
  32. package/dist/collection-rail.d.ts.map +1 -1
  33. package/dist/collection-rail.js +19 -1
  34. package/dist/collection-rail.js.map +1 -1
  35. package/dist/color-picker.d.ts.map +1 -1
  36. package/dist/color-picker.js +12 -4
  37. package/dist/color-picker.js.map +1 -1
  38. package/dist/command-palette.d.ts.map +1 -1
  39. package/dist/command-palette.js +14 -2
  40. package/dist/command-palette.js.map +1 -1
  41. package/dist/context-menu.d.ts.map +1 -1
  42. package/dist/context-menu.js +31 -10
  43. package/dist/context-menu.js.map +1 -1
  44. package/dist/date-entry.d.ts +1 -1
  45. package/dist/date-entry.d.ts.map +1 -1
  46. package/dist/date-entry.js +20 -7
  47. package/dist/date-entry.js.map +1 -1
  48. package/dist/date-picker.d.ts.map +1 -1
  49. package/dist/date-picker.js +22 -6
  50. package/dist/date-picker.js.map +1 -1
  51. package/dist/display.d.ts +5 -1
  52. package/dist/display.d.ts.map +1 -1
  53. package/dist/display.js +3 -2
  54. package/dist/display.js.map +1 -1
  55. package/dist/duration-field.d.ts +2 -2
  56. package/dist/duration-field.d.ts.map +1 -1
  57. package/dist/duration-field.js +11 -3
  58. package/dist/duration-field.js.map +1 -1
  59. package/dist/evidence.d.ts +1 -1
  60. package/dist/evidence.js +1 -1
  61. package/dist/evidence.js.map +1 -1
  62. package/dist/feedback.d.ts.map +1 -1
  63. package/dist/feedback.js +3 -2
  64. package/dist/feedback.js.map +1 -1
  65. package/dist/field-group.d.ts +4 -2
  66. package/dist/field-group.d.ts.map +1 -1
  67. package/dist/field-group.js +4 -3
  68. package/dist/field-group.js.map +1 -1
  69. package/dist/file-picker.d.ts.map +1 -1
  70. package/dist/file-picker.js +15 -5
  71. package/dist/file-picker.js.map +1 -1
  72. package/dist/forms.d.ts +2 -2
  73. package/dist/forms.js +1 -1
  74. package/dist/forms.js.map +1 -1
  75. package/dist/gravity-letters.d.ts.map +1 -1
  76. package/dist/gravity-letters.js +9 -1
  77. package/dist/gravity-letters.js.map +1 -1
  78. package/dist/grid-reveal.d.ts.map +1 -1
  79. package/dist/grid-reveal.js +9 -1
  80. package/dist/grid-reveal.js.map +1 -1
  81. package/dist/index.d.ts +1 -0
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +1 -0
  84. package/dist/index.js.map +1 -1
  85. package/dist/inline-confirm.d.ts.map +1 -1
  86. package/dist/inline-confirm.js +25 -4
  87. package/dist/inline-confirm.js.map +1 -1
  88. package/dist/internal/document-resource.d.ts.map +1 -1
  89. package/dist/internal/document-resource.js +2 -2
  90. package/dist/internal/document-resource.js.map +1 -1
  91. package/dist/masonry.d.ts.map +1 -1
  92. package/dist/masonry.js +2 -1
  93. package/dist/masonry.js.map +1 -1
  94. package/dist/mentions.d.ts.map +1 -1
  95. package/dist/mentions.js +12 -4
  96. package/dist/mentions.js.map +1 -1
  97. package/dist/menu-morph.js +1 -1
  98. package/dist/menu-morph.js.map +1 -1
  99. package/dist/menubar.d.ts.map +1 -1
  100. package/dist/menubar.js +43 -19
  101. package/dist/menubar.js.map +1 -1
  102. package/dist/modal.d.ts.map +1 -1
  103. package/dist/modal.js +15 -4
  104. package/dist/modal.js.map +1 -1
  105. package/dist/navigation.d.ts.map +1 -1
  106. package/dist/navigation.js +8 -2
  107. package/dist/navigation.js.map +1 -1
  108. package/dist/number-field.d.ts.map +1 -1
  109. package/dist/number-field.js +3 -1
  110. package/dist/number-field.js.map +1 -1
  111. package/dist/overlay-stack.d.ts.map +1 -1
  112. package/dist/overlay-stack.js +23 -6
  113. package/dist/overlay-stack.js.map +1 -1
  114. package/dist/overlays.d.ts.map +1 -1
  115. package/dist/overlays.js +8 -0
  116. package/dist/overlays.js.map +1 -1
  117. package/dist/pagination.d.ts.map +1 -1
  118. package/dist/pagination.js +16 -4
  119. package/dist/pagination.js.map +1 -1
  120. package/dist/saved-items.d.ts.map +1 -1
  121. package/dist/saved-items.js +6 -1
  122. package/dist/saved-items.js.map +1 -1
  123. package/dist/screen-flows.d.ts +1 -2
  124. package/dist/screen-flows.d.ts.map +1 -1
  125. package/dist/screen-flows.js +120 -16
  126. package/dist/screen-flows.js.map +1 -1
  127. package/dist/screens.d.ts.map +1 -1
  128. package/dist/screens.js +32 -7
  129. package/dist/screens.js.map +1 -1
  130. package/dist/select.d.ts.map +1 -1
  131. package/dist/select.js +6 -1
  132. package/dist/select.js.map +1 -1
  133. package/dist/side-panel.d.ts.map +1 -1
  134. package/dist/side-panel.js +11 -2
  135. package/dist/side-panel.js.map +1 -1
  136. package/dist/sidebar.d.ts.map +1 -1
  137. package/dist/sidebar.js +8 -1
  138. package/dist/sidebar.js.map +1 -1
  139. package/dist/skip-nav.d.ts.map +1 -1
  140. package/dist/skip-nav.js +16 -3
  141. package/dist/skip-nav.js.map +1 -1
  142. package/dist/sortable.d.ts.map +1 -1
  143. package/dist/sortable.js +2 -1
  144. package/dist/sortable.js.map +1 -1
  145. package/dist/splitter.d.ts.map +1 -1
  146. package/dist/splitter.js +23 -11
  147. package/dist/splitter.js.map +1 -1
  148. package/dist/statistic-motion.d.ts.map +1 -1
  149. package/dist/statistic-motion.js +30 -2
  150. package/dist/statistic-motion.js.map +1 -1
  151. package/dist/status-text.d.ts +11 -0
  152. package/dist/status-text.d.ts.map +1 -0
  153. package/dist/status-text.js +7 -0
  154. package/dist/status-text.js.map +1 -0
  155. package/dist/styles.css +14 -4
  156. package/dist/styles.layered.css +14 -4
  157. package/dist/supplemental-display.d.ts.map +1 -1
  158. package/dist/supplemental-display.js +19 -8
  159. package/dist/supplemental-display.js.map +1 -1
  160. package/dist/supplemental-navigation.d.ts.map +1 -1
  161. package/dist/supplemental-navigation.js +10 -1
  162. package/dist/supplemental-navigation.js.map +1 -1
  163. package/dist/tags-input.d.ts.map +1 -1
  164. package/dist/tags-input.js +18 -8
  165. package/dist/tags-input.js.map +1 -1
  166. package/dist/theme.d.ts.map +1 -1
  167. package/dist/theme.js +1 -0
  168. package/dist/theme.js.map +1 -1
  169. package/dist/toast.d.ts.map +1 -1
  170. package/dist/toast.js +31 -16
  171. package/dist/toast.js.map +1 -1
  172. package/dist/toggle-group.d.ts.map +1 -1
  173. package/dist/toggle-group.js +6 -1
  174. package/dist/toggle-group.js.map +1 -1
  175. package/dist/tour.d.ts.map +1 -1
  176. package/dist/tour.js +15 -2
  177. package/dist/tour.js.map +1 -1
  178. package/dist/transfer-list.d.ts +1 -1
  179. package/dist/transfer-list.d.ts.map +1 -1
  180. package/dist/transfer-list.js +52 -7
  181. package/dist/transfer-list.js.map +1 -1
  182. package/dist/tree.d.ts.map +1 -1
  183. package/dist/tree.js +41 -8
  184. package/dist/tree.js.map +1 -1
  185. package/dist/virtual-list.d.ts.map +1 -1
  186. package/dist/virtual-list.js +44 -7
  187. package/dist/virtual-list.js.map +1 -1
  188. package/package.json +8 -3
@@ -946,6 +946,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
946
946
  .hjm-list-row__leading[data-shape="circle"] { border-radius: var(--hjm-radius-full); }
947
947
  .hjm-list-row__content { flex: 1 1 auto; min-inline-size: 0; display: grid; gap: var(--hjm-space-xxs); }
948
948
  .hjm-list-row__title { color: var(--hjm-color-text-body); font-weight: var(--hjm-font-weight-bold); overflow-wrap: anywhere; }
949
+ .hjm-list-row[data-tone="danger"] .hjm-list-row__title { color: var(--hjm-color-danger); }
949
950
  .hjm-list-row__description, .hjm-list-row__trailing { color: var(--hjm-color-text-muted); overflow-wrap: anywhere; }
950
951
 
951
952
  .hjm-section { display: grid; gap: var(--hjm-space-xs); min-inline-size: 0; overflow-wrap: anywhere; }
@@ -1103,15 +1104,13 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1103
1104
  background: var(--hjm-color-surface-alt);
1104
1105
  }
1105
1106
  .hjm-list-row--loading .hjm-list-row__title[data-placeholder] {
1106
- inline-size: 60%;
1107
1107
  block-size: var(--hjm-type-body-large-line-height);
1108
1108
  }
1109
1109
  .hjm-list-row--loading .hjm-list-row__description[data-placeholder] {
1110
- inline-size: 40%;
1111
1110
  block-size: var(--hjm-type-body-line-height);
1112
1111
  }
1113
1112
  .hjm-list-row--loading .hjm-list-row__leading[data-placeholder] { background: var(--hjm-color-surface-alt); }
1114
- .hjm-list-row--loading .hjm-list-row__trailing[data-placeholder] { inline-size: var(--hjm-space-xxl); }
1113
+ .hjm-list-row--loading .hjm-list-row__trailing[data-placeholder] { block-size: var(--hjm-type-caption-line-height); }
1115
1114
  .hjm-spinner { display: inline-flex; align-items: center; justify-content: center; color: var(--hjm-color-content-brand); }
1116
1115
  .hjm-spinner[data-tone="neutral"] { color: var(--hjm-color-text-muted); }
1117
1116
  .hjm-spinner[data-tone="inverse"] { color: var(--hjm-color-on-primary); }
@@ -1318,7 +1317,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1318
1317
  .hjm-transfer-list__option:focus-visible,
1319
1318
  .hjm-transfer-list__empty:focus-visible,
1320
1319
  .hjm-transfer-list__select-all:focus-visible { outline: 2px solid var(--hjm-color-focus); outline-offset: -2px; }
1321
- .hjm-transfer-list__empty { margin: 0; padding: var(--hjm-space-md) var(--hjm-space-sm); color: var(--hjm-color-text-muted); }
1320
+ .hjm-transfer-list__empty { margin: 0; padding: var(--hjm-space-md) var(--hjm-space-sm); color: var(--hjm-color-text-muted); text-align: center; }
1322
1321
  .hjm-transfer-list__actions { display: flex; flex-direction: column; gap: var(--hjm-space-sm); /* transferListRecipe.moveControls.gap sm 12, as Native */ padding-block-start: var(--hjm-space-xl); }
1323
1322
 
1324
1323
  /* AuthProviderButton ------------------------------------------------------ */
@@ -2537,6 +2536,11 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2537
2536
  1.10.0 layout: [tone badge][title + description][close] / action pill on its own row, end-aligned.
2538
2537
  The 2px tone strip is retired — the tinted badge carries tone (toastRecipe.toneMark width 0). */
2539
2538
  .hjm-toast { position: relative; min-inline-size: 0; min-block-size: 3.5rem; display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: start; column-gap: var(--hjm-space-sm); row-gap: var(--hjm-space-xs); padding: var(--hjm-space-sm) var(--hjm-space-xs) var(--hjm-space-sm) var(--hjm-space-md); overflow: hidden; border: var(--hjm-toast-border-width) solid var(--hjm-toast-border); border-radius: var(--hjm-toast-radius); color: var(--hjm-color-text); background: var(--hjm-toast-background); box-shadow: var(--hjm-toast-shadow); pointer-events: auto; }
2539
+ /* Whole-card activation is a sibling surface; explicit controls stay above it. */
2540
+ .hjm-toast__press { position: absolute; inset: 0; z-index: 1; border: 0; border-radius: inherit; padding: 0; background: transparent; cursor: pointer; }
2541
+ .hjm-toast__press:focus-visible { outline: 2px solid var(--hjm-color-content-brand); outline-offset: -2px; }
2542
+ .hjm-toast:has(> .hjm-toast__press:active) { opacity: var(--hjm-toast-pressed-opacity); }
2543
+ .hjm-toast:has(> .hjm-toast__press) > :is(.hjm-toast__action, .hjm-toast__close) { position: relative; z-index: 2; }
2540
2544
  .hjm-toast__tone-mark { display: none; }
2541
2545
  .hjm-toast__icon { grid-column: 1; grid-row: 1; align-self: start; display: grid; place-items: center; inline-size: var(--hjm-toast-badge-size); block-size: var(--hjm-toast-badge-size); border-radius: 50%; color: var(--hjm-toast-accent-neutral); background: var(--hjm-toast-badge-neutral); }
2542
2546
  .hjm-toast[data-tone="info"] .hjm-toast__icon { color: var(--hjm-toast-accent-info); background: var(--hjm-toast-badge-info); }
@@ -3019,4 +3023,10 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3019
3023
  .hjm-card[data-interactive="true"]:active:not(:disabled) { opacity: var(--hjm-card-pressed-opacity); }
3020
3024
  .hjm-card[data-interactive="true"]:disabled { opacity: var(--hjm-card-disabled-opacity); cursor: default; }
3021
3025
 
3026
+ /* Full destination cards keep all names and widths stable; colors remain product semantic roles. */
3027
+ .hjm-bottom-navigation[data-selection="tile"] .hjm-bottom-navigation__surface { background: var(--hjm-color-surface-accent); }
3028
+ .hjm-bottom-navigation[data-selection="tile"] .hjm-bottom-navigation__list { padding: var(--hjm-space-xxs); gap: var(--hjm-space-xxs); }
3029
+ .hjm-bottom-navigation[data-selection="tile"] .hjm-bottom-navigation__item[data-state="selected"] { background: var(--hjm-color-primary); color: var(--hjm-color-on-primary); }
3030
+ .hjm-bottom-navigation[data-selection="tile"] .hjm-bottom-navigation__item:not([data-state="selected"]):active { background: var(--hjm-bottom-navigation-pressed-background); }
3031
+
3022
3032
  }
@@ -1 +1 @@
1
- {"version":3,"file":"supplemental-display.d.ts","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"supplemental-display.d.ts","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { getIconTransform, resolveIconDescriptor, } from "@hjmds/design-contracts/components/icon";
3
3
  import { imageRecipe, resolveImageAspectRatio, resolveImageDescriptor, resolveImageFallbackAccessibilityLabel, } from "@hjmds/design-contracts/components/image";
4
4
  import { counterBadgeRecipe, formatCounterBadgeCount, iconRecipe, } from "@hjmds/design-contracts/recipes";
5
- import { forwardRef, useState, } from "react";
5
+ import { forwardRef, useState, useMemo, useRef, useLayoutEffect, } from "react";
6
6
  import { classNames } from "./internal.js";
7
7
  import { useOptionalHjmTheme } from "./provider.js";
8
8
  /** Internal, dependency-free semantic glyph registry. All marks share one 24px stroke grid. */
@@ -76,19 +76,30 @@ export const Image = forwardRef(function Image({ src, width, height, fit, decora
76
76
  ...(decorative === undefined ? {} : { decorative }),
77
77
  ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),
78
78
  });
79
- const [state, setState] = useState({
80
- src: descriptor.src,
81
- status: "loading",
82
- });
83
- const status = state.src === descriptor.src ? state.status : "loading";
79
+ // A→B→A is a new request even when the URL repeats. Retire adapter callbacks
80
+ // at commit/unmount so old network events cannot update state or product observers.
81
+ // Responsive source candidates and request policy are part of image identity;
82
+ // a new srcSet must recover even when its fallback src is unchanged.
83
+ const generation = useMemo(() => ({}), [descriptor.src, imageProps?.srcSet, imageProps?.sizes, imageProps?.crossOrigin, imageProps?.referrerPolicy]);
84
+ const activeGeneration = useRef(generation);
85
+ useLayoutEffect(() => {
86
+ activeGeneration.current = generation;
87
+ return () => { activeGeneration.current = null; };
88
+ }, [generation]);
89
+ const [state, setState] = useState({ generation, status: "loading" });
90
+ const status = state.generation === generation ? state.status : "loading";
84
91
  const { className: imageClassName, style: imageStyle, ...restImageProps } = imageProps ?? {};
85
92
  const handleLoad = (event) => {
86
- setState({ src: descriptor.src, status: "loaded" });
93
+ if (activeGeneration.current !== generation)
94
+ return;
95
+ setState({ generation, status: "loaded" });
87
96
  onLoadStatusChange?.("loaded");
88
97
  onLoad?.(event);
89
98
  };
90
99
  const handleError = (event) => {
91
- setState({ src: descriptor.src, status: "error" });
100
+ if (activeGeneration.current !== generation)
101
+ return;
102
+ setState({ generation, status: "error" });
92
103
  onLoadStatusChange?.("error");
93
104
  onError?.(event);
94
105
  };
@@ -1 +1 @@
1
- {"version":3,"file":"supplemental-display.js","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getIconTransform,\n resolveIconDescriptor,\n type IconDescriptor,\n type SemanticIconName,\n} from \"@hjmds/design-contracts/components/icon\";\nimport {\n imageRecipe,\n resolveImageAspectRatio,\n resolveImageDescriptor,\n resolveImageFallbackAccessibilityLabel,\n type ImageDescriptor,\n type ImageLoadStatus,\n} from \"@hjmds/design-contracts/components/image\";\nimport {\n counterBadgeRecipe,\n formatCounterBadgeCount,\n iconRecipe,\n type CounterBadgeSize,\n type CounterBadgeTone,\n type CounterBadgeVariant,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ImgHTMLAttributes,\n type ReactElement,\n type ReactEventHandler,\n type ReactNode,\n type Ref,\n type SVGAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\n/** Internal, dependency-free semantic glyph registry. All marks share one 24px stroke grid. */\nconst iconPaths = {\n add: \"M12 5v14M5 12h14\",\n ai: \"M12 2l1.2 4.1L17 8l-3.8 1.9L12 14l-1.2-4.1L7 8l3.8-1.9L12 2ZM19 14l.7 2.3L22 17.5l-2.3 1.2L19 21l-.7-2.3-2.3-1.2 2.3-1.2L19 14Z\",\n alert: \"M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01\",\n back: \"M15 18 9 12l6-6M9 12h10\",\n calendar: \"M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm2-2v4m10-4v4M3 9h18\",\n check: \"m5 12 4 4L19 6\",\n chevronDown: \"m6 9 6 6 6-6\",\n chevronEnd: \"m9 6 6 6-6 6\",\n chevronStart: \"m15 6-6 6 6 6\",\n chevronUp: \"m6 15 6-6 6 6\",\n close: \"M6 6l12 12M18 6 6 18\",\n compare: \"M8 7h11m0 0-3-3m3 3-3 3M16 17H5m0 0 3-3m-3 3 3 3\",\n copy: \"M8 8h11a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2V8Zm8 0V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3\",\n delete: \"M4 7h16M9 7V4h6v3m3 0-1 14H7L6 7m4 4v6m4-6v6\",\n download: \"M12 3v12m0 0 5-5m-5 5-5-5M4 19v2h16v-2\",\n edit: \"m4 16-1 5 5-1L19 9l-4-4L4 16Zm9-9 4 4\",\n error: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-14v5m0 3h.01\",\n favorite: \"M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1.1-1.1a5.5 5.5 0 0 0-7.8 7.8L12 21l8.8-8.6a5.5 5.5 0 0 0 0-7.8Z\",\n filter: \"M3 5h18l-7 8v6l-4 2v-8L3 5Z\",\n forward: \"m9 6 6 6-6 6m6-6H5\",\n help: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-3-13a3 3 0 1 1 4.7 2.5c-1 .7-1.7 1.2-1.7 2.5m0 3h.01\",\n home: \"m3 11 9-8 9 8v10h-6v-6H9v6H3V11Z\",\n info: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-11v6m0-10h.01\",\n lock: \"M6 10h12v11H6V10Zm3 0V7a3 3 0 0 1 6 0v3\",\n menu: \"M4 6h16M4 12h16M4 18h16\",\n more: \"M5 12h.01M12 12h.01M19 12h.01\",\n notifications: \"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9Zm-8 12h4\",\n pause: \"M8 5v14m8-14v14\",\n play: \"m8 5 11 7-11 7V5Z\",\n refresh: \"M20 7v5h-5M4 17v-5h5m10.5-3A8 8 0 0 0 6 6l-2 2m.5 7A8 8 0 0 0 18 18l2-2\",\n search: \"m21 21-4.4-4.4M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z\",\n settings: \"M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm7.4-3.5 2-1.5-2-3.5-2.4 1a8 8 0 0 0-2-1.2L14.7 4h-4l-.4 2.8A8 8 0 0 0 8 8L5.6 7l-2 3.5 2 1.5a8 8 0 0 0 0 2l-2 1.5 2 3.5L8 18a8 8 0 0 0 2.3 1.2l.4 2.8h4l.3-2.8A8 8 0 0 0 17 18l2.4 1 2-3.5-2-1.5a8 8 0 0 0 0-2Z\",\n share: \"M18 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM6 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm12 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM8.6 16.5l6.8 4M15.4 6.5l-6.8 4\",\n success: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-5-10 3 3 7-7\",\n trendDown: \"M3 7l7 7 4-4 7 7m0 0v-6m0 6h-6\",\n trendFlat: \"M4 12h16m0 0-4-4m4 4-4 4\",\n trendUp: \"M3 17l7-7 4 4 7-7m0 0v6m0-6h-6\",\n upload: \"M12 21V9m0 0-5 5m5-5 5 5M4 5V3h16v2\",\n user: \"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-8 9a8 8 0 0 1 16 0\",\n users: \"M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-7 10a7 7 0 0 1 14 0m1-16a4 4 0 0 1 0 7m0 3a6 6 0 0 1 5 6\",\n visibility: \"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z\",\n visibilityOff: \"m3 3 18 18M10.6 5.2A9 9 0 0 1 12 5c6 0 10 7 10 7a17 17 0 0 1-2.1 3M6.6 6.6C3.8 8.5 2 12 2 12s4 7 10 7a9 9 0 0 0 3.4-.7M9.9 9.9a3 3 0 0 0 4.2 4.2\",\n warning: \"M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01\",\n} as const satisfies Record<SemanticIconName, string>;\n\nexport type IconProps = Omit<\n SVGAttributes<SVGSVGElement>,\n \"children\" | \"color\"\n> & IconDescriptor & Readonly<{\n /** Optional glyph inside the existing 24-unit SVG frame; HJM owns semantics. */\n renderGlyph?: (props: Readonly<{ name: SemanticIconName; size: number; color: string; strokeWidth: number }>) => ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Icon = forwardRef<SVGSVGElement, IconProps>(function Icon(\n {\n name,\n size,\n tone,\n weight,\n directionality,\n decorative,\n accessibilityLabel,\n renderGlyph,\n className,\n style,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const descriptor = resolveIconDescriptor({\n name,\n ...(size === undefined ? {} : { size }),\n ...(tone === undefined ? {} : { tone }),\n ...(weight === undefined ? {} : { weight }),\n ...(directionality === undefined ? {} : { directionality }),\n ...(decorative === undefined ? {} : { decorative }),\n ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),\n } as IconDescriptor);\n const theme = useOptionalHjmTheme();\n const transform = getIconTransform(\n descriptor.directionality,\n theme?.environment.direction ?? \"ltr\",\n );\n const dimension = iconRecipe.sizes[descriptor.size];\n return (\n <svg\n {...props}\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={classNames(\"hjm-icon\", className)}\n data-name={descriptor.name}\n data-size={descriptor.size}\n data-tone={descriptor.tone}\n data-weight={descriptor.weight}\n data-transform={transform}\n width={dimension}\n height={dimension}\n stroke=\"currentColor\"\n strokeWidth={iconRecipe.weights[descriptor.weight]}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role={descriptor.decorative ? undefined : \"img\"}\n aria-hidden={descriptor.decorative || undefined}\n aria-label={descriptor.decorative ? undefined : descriptor.accessibilityLabel}\n focusable=\"false\"\n style={{ ...style, ...layoutStyle }}\n >\n {renderGlyph?.({ name: descriptor.name, size: 24, color: \"currentColor\", strokeWidth: iconRecipe.weights[descriptor.weight] }) ?? <path d={iconPaths[descriptor.name]} />}\n </svg>\n );\n});\n\ntype ImageElementProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n | \"alt\"\n | \"aria-hidden\"\n | \"aria-label\"\n | \"children\"\n | \"className\"\n | \"height\"\n | \"onError\"\n | \"onLoad\"\n | \"role\"\n | \"src\"\n | \"style\"\n | \"width\"\n>;\n\n/** Canonical props handed to a framework adapter such as `next/image`. */\nexport type ImageAdapterProps = ImageElementProps &\n Readonly<{\n src: string;\n alt: string;\n width: number;\n height: number;\n className?: string;\n style: CSSProperties;\n \"aria-hidden\"?: true;\n onLoad: ReactEventHandler<HTMLImageElement>;\n onError: ReactEventHandler<HTMLImageElement>;\n ref?: Ref<HTMLImageElement>;\n }>;\n\ntype ImageRootProps = Omit<\n HTMLAttributes<HTMLSpanElement>,\n | \"aria-hidden\"\n | \"aria-label\"\n | \"aria-labelledby\"\n | \"children\"\n | \"onError\"\n | \"onLoad\"\n | \"role\"\n>;\n\nexport type ImageProps = ImageRootProps &\n ImageDescriptor &\n Readonly<{\n /** Additional native `<img>` props shared with the framework adapter. */\n imageProps?: ImageElementProps &\n Readonly<{ className?: string; style?: CSSProperties }>;\n /**\n * Receives the complete accessible image contract. The adapter must pass\n * these props to its underlying image element so HJM can observe failure.\n */\n renderImage?: (props: ImageAdapterProps) => ReactElement;\n /** Visual content only; HJM keeps the fallback's accessible name. */\n fallback?: ReactNode;\n imageRef?: Ref<HTMLImageElement>;\n onLoad?: ReactEventHandler<HTMLImageElement>;\n onError?: ReactEventHandler<HTMLImageElement>;\n onLoadStatusChange?: (status: Extract<ImageLoadStatus, \"loaded\" | \"error\">) => void;\n /** Canonical layout-only placement on the root frame; the aspect ratio stays descriptor-owned. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\ntype ImageState = Readonly<{\n src: string;\n status: Extract<ImageLoadStatus, \"loading\" | \"loaded\" | \"error\">;\n}>;\n\n/** Intrinsic-size image with canonical alt semantics and an accessible fallback. */\nexport const Image = forwardRef<HTMLSpanElement, ImageProps>(function Image(\n {\n src,\n width,\n height,\n fit,\n decorative,\n accessibilityLabel,\n imageProps,\n renderImage,\n fallback,\n imageRef,\n onLoad,\n onError,\n onLoadStatusChange,\n className,\n style,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const descriptor = resolveImageDescriptor({\n src,\n width,\n height,\n ...(fit === undefined ? {} : { fit }),\n ...(decorative === undefined ? {} : { decorative }),\n ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),\n } as ImageDescriptor);\n const [state, setState] = useState<ImageState>({\n src: descriptor.src,\n status: \"loading\",\n });\n const status = state.src === descriptor.src ? state.status : \"loading\";\n const {\n className: imageClassName,\n style: imageStyle,\n ...restImageProps\n } = imageProps ?? {};\n\n const handleLoad: ReactEventHandler<HTMLImageElement> = (event) => {\n setState({ src: descriptor.src, status: \"loaded\" });\n onLoadStatusChange?.(\"loaded\");\n onLoad?.(event);\n };\n const handleError: ReactEventHandler<HTMLImageElement> = (event) => {\n setState({ src: descriptor.src, status: \"error\" });\n onLoadStatusChange?.(\"error\");\n onError?.(event);\n };\n const adapterProps: ImageAdapterProps = {\n ...restImageProps,\n src: descriptor.src,\n alt: descriptor.decorative ? \"\" : descriptor.accessibilityLabel,\n width: descriptor.width,\n height: descriptor.height,\n className: classNames(\"hjm-image__asset\", imageClassName) ??\n \"hjm-image__asset\",\n style: { ...imageStyle, objectFit: descriptor.fit },\n ...(descriptor.decorative ? { \"aria-hidden\": true } : {}),\n onLoad: handleLoad,\n onError: handleError,\n ...(imageRef === undefined ? {} : { ref: imageRef }),\n };\n\n let visual: ReactNode;\n if (status === \"error\") {\n const fallbackLabel = resolveImageFallbackAccessibilityLabel(descriptor);\n visual = (\n <span\n className=\"hjm-image__fallback\"\n role={descriptor.decorative ? undefined : \"img\"}\n aria-label={fallbackLabel}\n aria-hidden={descriptor.decorative || undefined}\n >\n <span className=\"hjm-image__fallback-icon\" aria-hidden=\"true\">\n {fallback ?? (\n <Icon\n name={imageRecipe.fallback.icon.name}\n tone={imageRecipe.fallback.icon.tone}\n decorative\n />\n )}\n </span>\n </span>\n );\n } else if (renderImage === undefined) {\n const { ref: assetRef, ...nativeImageProps } = adapterProps;\n visual = <img {...nativeImageProps} ref={assetRef} />;\n } else {\n visual = renderImage(adapterProps);\n }\n\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-image\", className)}\n data-fit={descriptor.fit}\n data-status={status}\n style={{\n inlineSize: descriptor.width,\n ...style,\n ...layoutStyle,\n aspectRatio: resolveImageAspectRatio(\n descriptor.width,\n descriptor.height,\n ),\n }}\n >\n {visual}\n </span>\n );\n});\n\nexport type CounterBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n count: number;\n max?: number;\n tone?: CounterBadgeTone;\n size?: CounterBadgeSize;\n variant?: CounterBadgeVariant;\n /**\n * Says \"there is something new\" without a number. Use it where the count is\n * unknown or not worth reading; inventing a number would be worse than\n * saying none. The accessible name then carries the whole meaning.\n */\n dot?: boolean;\n accessibilityLabel?: string;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const CounterBadge = forwardRef<HTMLSpanElement, CounterBadgeProps>(\n function CounterBadge(\n {\n count,\n max = counterBadgeRecipe.defaults.max,\n tone = counterBadgeRecipe.defaults.tone,\n size = counterBadgeRecipe.defaults.size,\n variant = counterBadgeRecipe.defaults.variant,\n dot = false,\n accessibilityLabel,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n ) {\n const label = formatCounterBadgeCount(count, max);\n if (accessibilityLabel !== undefined && accessibilityLabel.trim().length === 0) {\n throw new TypeError(\"CounterBadge accessibilityLabel must not be empty\");\n }\n if (dot && accessibilityLabel === undefined) {\n // A dot with no name is a decoration that nobody can read.\n throw new TypeError(\"CounterBadge dot requires an accessibilityLabel\");\n }\n if (label === null) return null;\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-counter-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n data-dot={dot || undefined}\n style={dot ? { ...style, ...layoutStyle, \"--hjm-counter-dot-size\": `${counterBadgeRecipe.dotSize}px` } as typeof style : { ...style, ...layoutStyle }}\n aria-hidden={accessibilityLabel === undefined || undefined}\n // A named count needs a semantic role; generic spans cannot carry aria-label.\n role={accessibilityLabel === undefined ? undefined : \"img\"}\n aria-label={accessibilityLabel}\n >\n {dot ? null : label}\n </span>\n );\n },\n);\n"]}
1
+ {"version":3,"file":"supplemental-display.js","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n getIconTransform,\n resolveIconDescriptor,\n type IconDescriptor,\n type SemanticIconName,\n} from \"@hjmds/design-contracts/components/icon\";\nimport {\n imageRecipe,\n resolveImageAspectRatio,\n resolveImageDescriptor,\n resolveImageFallbackAccessibilityLabel,\n type ImageDescriptor,\n type ImageLoadStatus,\n} from \"@hjmds/design-contracts/components/image\";\nimport {\n counterBadgeRecipe,\n formatCounterBadgeCount,\n iconRecipe,\n type CounterBadgeSize,\n type CounterBadgeTone,\n type CounterBadgeVariant,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useState,\n useMemo,\n useRef,\n useLayoutEffect,\n type CSSProperties,\n type HTMLAttributes,\n type ImgHTMLAttributes,\n type ReactElement,\n type ReactEventHandler,\n type ReactNode,\n type Ref,\n type SVGAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport { useOptionalHjmTheme } from \"./provider.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\n/** Internal, dependency-free semantic glyph registry. All marks share one 24px stroke grid. */\nconst iconPaths = {\n add: \"M12 5v14M5 12h14\",\n ai: \"M12 2l1.2 4.1L17 8l-3.8 1.9L12 14l-1.2-4.1L7 8l3.8-1.9L12 2ZM19 14l.7 2.3L22 17.5l-2.3 1.2L19 21l-.7-2.3-2.3-1.2 2.3-1.2L19 14Z\",\n alert: \"M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01\",\n back: \"M15 18 9 12l6-6M9 12h10\",\n calendar: \"M5 4h14a2 2 0 0 1 2 2v13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2Zm2-2v4m10-4v4M3 9h18\",\n check: \"m5 12 4 4L19 6\",\n chevronDown: \"m6 9 6 6 6-6\",\n chevronEnd: \"m9 6 6 6-6 6\",\n chevronStart: \"m15 6-6 6 6 6\",\n chevronUp: \"m6 15 6-6 6 6\",\n close: \"M6 6l12 12M18 6 6 18\",\n compare: \"M8 7h11m0 0-3-3m3 3-3 3M16 17H5m0 0 3-3m-3 3 3 3\",\n copy: \"M8 8h11a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H10a2 2 0 0 1-2-2V8Zm8 0V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h3\",\n delete: \"M4 7h16M9 7V4h6v3m3 0-1 14H7L6 7m4 4v6m4-6v6\",\n download: \"M12 3v12m0 0 5-5m-5 5-5-5M4 19v2h16v-2\",\n edit: \"m4 16-1 5 5-1L19 9l-4-4L4 16Zm9-9 4 4\",\n error: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-14v5m0 3h.01\",\n favorite: \"M20.8 4.6a5.5 5.5 0 0 0-7.8 0L12 5.7l-1.1-1.1a5.5 5.5 0 0 0-7.8 7.8L12 21l8.8-8.6a5.5 5.5 0 0 0 0-7.8Z\",\n filter: \"M3 5h18l-7 8v6l-4 2v-8L3 5Z\",\n forward: \"m9 6 6 6-6 6m6-6H5\",\n help: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-3-13a3 3 0 1 1 4.7 2.5c-1 .7-1.7 1.2-1.7 2.5m0 3h.01\",\n home: \"m3 11 9-8 9 8v10h-6v-6H9v6H3V11Z\",\n info: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-11v6m0-10h.01\",\n lock: \"M6 10h12v11H6V10Zm3 0V7a3 3 0 0 1 6 0v3\",\n menu: \"M4 6h16M4 12h16M4 18h16\",\n more: \"M5 12h.01M12 12h.01M19 12h.01\",\n notifications: \"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9Zm-8 12h4\",\n pause: \"M8 5v14m8-14v14\",\n play: \"m8 5 11 7-11 7V5Z\",\n refresh: \"M20 7v5h-5M4 17v-5h5m10.5-3A8 8 0 0 0 6 6l-2 2m.5 7A8 8 0 0 0 18 18l2-2\",\n search: \"m21 21-4.4-4.4M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z\",\n settings: \"M12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7Zm7.4-3.5 2-1.5-2-3.5-2.4 1a8 8 0 0 0-2-1.2L14.7 4h-4l-.4 2.8A8 8 0 0 0 8 8L5.6 7l-2 3.5 2 1.5a8 8 0 0 0 0 2l-2 1.5 2 3.5L8 18a8 8 0 0 0 2.3 1.2l.4 2.8h4l.3-2.8A8 8 0 0 0 17 18l2.4 1 2-3.5-2-1.5a8 8 0 0 0 0-2Z\",\n share: \"M18 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM6 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Zm12 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6ZM8.6 16.5l6.8 4M15.4 6.5l-6.8 4\",\n success: \"M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-5-10 3 3 7-7\",\n trendDown: \"M3 7l7 7 4-4 7 7m0 0v-6m0 6h-6\",\n trendFlat: \"M4 12h16m0 0-4-4m4 4-4 4\",\n trendUp: \"M3 17l7-7 4 4 7-7m0 0v6m0-6h-6\",\n upload: \"M12 21V9m0 0-5 5m5-5 5 5M4 5V3h16v2\",\n user: \"M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-8 9a8 8 0 0 1 16 0\",\n users: \"M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-7 10a7 7 0 0 1 14 0m1-16a4 4 0 0 1 0 7m0 3a6 6 0 0 1 5 6\",\n visibility: \"M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Zm10 3a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z\",\n visibilityOff: \"m3 3 18 18M10.6 5.2A9 9 0 0 1 12 5c6 0 10 7 10 7a17 17 0 0 1-2.1 3M6.6 6.6C3.8 8.5 2 12 2 12s4 7 10 7a9 9 0 0 0 3.4-.7M9.9 9.9a3 3 0 0 0 4.2 4.2\",\n warning: \"M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01\",\n} as const satisfies Record<SemanticIconName, string>;\n\nexport type IconProps = Omit<\n SVGAttributes<SVGSVGElement>,\n \"children\" | \"color\"\n> & IconDescriptor & Readonly<{\n /** Optional glyph inside the existing 24-unit SVG frame; HJM owns semantics. */\n renderGlyph?: (props: Readonly<{ name: SemanticIconName; size: number; color: string; strokeWidth: number }>) => ReactNode;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const Icon = forwardRef<SVGSVGElement, IconProps>(function Icon(\n {\n name,\n size,\n tone,\n weight,\n directionality,\n decorative,\n accessibilityLabel,\n renderGlyph,\n className,\n style,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const descriptor = resolveIconDescriptor({\n name,\n ...(size === undefined ? {} : { size }),\n ...(tone === undefined ? {} : { tone }),\n ...(weight === undefined ? {} : { weight }),\n ...(directionality === undefined ? {} : { directionality }),\n ...(decorative === undefined ? {} : { decorative }),\n ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),\n } as IconDescriptor);\n const theme = useOptionalHjmTheme();\n const transform = getIconTransform(\n descriptor.directionality,\n theme?.environment.direction ?? \"ltr\",\n );\n const dimension = iconRecipe.sizes[descriptor.size];\n return (\n <svg\n {...props}\n ref={ref}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n className={classNames(\"hjm-icon\", className)}\n data-name={descriptor.name}\n data-size={descriptor.size}\n data-tone={descriptor.tone}\n data-weight={descriptor.weight}\n data-transform={transform}\n width={dimension}\n height={dimension}\n stroke=\"currentColor\"\n strokeWidth={iconRecipe.weights[descriptor.weight]}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n role={descriptor.decorative ? undefined : \"img\"}\n aria-hidden={descriptor.decorative || undefined}\n aria-label={descriptor.decorative ? undefined : descriptor.accessibilityLabel}\n focusable=\"false\"\n style={{ ...style, ...layoutStyle }}\n >\n {renderGlyph?.({ name: descriptor.name, size: 24, color: \"currentColor\", strokeWidth: iconRecipe.weights[descriptor.weight] }) ?? <path d={iconPaths[descriptor.name]} />}\n </svg>\n );\n});\n\ntype ImageElementProps = Omit<\n ImgHTMLAttributes<HTMLImageElement>,\n | \"alt\"\n | \"aria-hidden\"\n | \"aria-label\"\n | \"children\"\n | \"className\"\n | \"height\"\n | \"onError\"\n | \"onLoad\"\n | \"role\"\n | \"src\"\n | \"style\"\n | \"width\"\n>;\n\n/** Canonical props handed to a framework adapter such as `next/image`. */\nexport type ImageAdapterProps = ImageElementProps &\n Readonly<{\n src: string;\n alt: string;\n width: number;\n height: number;\n className?: string;\n style: CSSProperties;\n \"aria-hidden\"?: true;\n onLoad: ReactEventHandler<HTMLImageElement>;\n onError: ReactEventHandler<HTMLImageElement>;\n ref?: Ref<HTMLImageElement>;\n }>;\n\ntype ImageRootProps = Omit<\n HTMLAttributes<HTMLSpanElement>,\n | \"aria-hidden\"\n | \"aria-label\"\n | \"aria-labelledby\"\n | \"children\"\n | \"onError\"\n | \"onLoad\"\n | \"role\"\n>;\n\nexport type ImageProps = ImageRootProps &\n ImageDescriptor &\n Readonly<{\n /** Additional native `<img>` props shared with the framework adapter. */\n imageProps?: ImageElementProps &\n Readonly<{ className?: string; style?: CSSProperties }>;\n /**\n * Receives the complete accessible image contract. The adapter must pass\n * these props to its underlying image element so HJM can observe failure.\n */\n renderImage?: (props: ImageAdapterProps) => ReactElement;\n /** Visual content only; HJM keeps the fallback's accessible name. */\n fallback?: ReactNode;\n imageRef?: Ref<HTMLImageElement>;\n onLoad?: ReactEventHandler<HTMLImageElement>;\n onError?: ReactEventHandler<HTMLImageElement>;\n onLoadStatusChange?: (status: Extract<ImageLoadStatus, \"loaded\" | \"error\">) => void;\n /** Canonical layout-only placement on the root frame; the aspect ratio stays descriptor-owned. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\ntype ImageState = Readonly<{\n generation: object;\n status: Extract<ImageLoadStatus, \"loading\" | \"loaded\" | \"error\">;\n}>;\n\n/** Intrinsic-size image with canonical alt semantics and an accessible fallback. */\nexport const Image = forwardRef<HTMLSpanElement, ImageProps>(function Image(\n {\n src,\n width,\n height,\n fit,\n decorative,\n accessibilityLabel,\n imageProps,\n renderImage,\n fallback,\n imageRef,\n onLoad,\n onError,\n onLoadStatusChange,\n className,\n style,\n layoutStyle,\n ...props\n },\n ref,\n) {\n const descriptor = resolveImageDescriptor({\n src,\n width,\n height,\n ...(fit === undefined ? {} : { fit }),\n ...(decorative === undefined ? {} : { decorative }),\n ...(accessibilityLabel === undefined ? {} : { accessibilityLabel }),\n } as ImageDescriptor);\n // A→B→A is a new request even when the URL repeats. Retire adapter callbacks\n // at commit/unmount so old network events cannot update state or product observers.\n // Responsive source candidates and request policy are part of image identity;\n // a new srcSet must recover even when its fallback src is unchanged.\n const generation = useMemo(() => ({}), [descriptor.src, imageProps?.srcSet, imageProps?.sizes, imageProps?.crossOrigin, imageProps?.referrerPolicy]);\n const activeGeneration = useRef<object | null>(generation);\n useLayoutEffect(() => {\n activeGeneration.current = generation;\n return () => { activeGeneration.current = null; };\n }, [generation]);\n const [state, setState] = useState<ImageState>({ generation, status: \"loading\" });\n const status = state.generation === generation ? state.status : \"loading\";\n const {\n className: imageClassName,\n style: imageStyle,\n ...restImageProps\n } = imageProps ?? {};\n\n const handleLoad: ReactEventHandler<HTMLImageElement> = (event) => {\n if (activeGeneration.current !== generation) return;\n setState({ generation, status: \"loaded\" });\n onLoadStatusChange?.(\"loaded\");\n onLoad?.(event);\n };\n const handleError: ReactEventHandler<HTMLImageElement> = (event) => {\n if (activeGeneration.current !== generation) return;\n setState({ generation, status: \"error\" });\n onLoadStatusChange?.(\"error\");\n onError?.(event);\n };\n const adapterProps: ImageAdapterProps = {\n ...restImageProps,\n src: descriptor.src,\n alt: descriptor.decorative ? \"\" : descriptor.accessibilityLabel,\n width: descriptor.width,\n height: descriptor.height,\n className: classNames(\"hjm-image__asset\", imageClassName) ??\n \"hjm-image__asset\",\n style: { ...imageStyle, objectFit: descriptor.fit },\n ...(descriptor.decorative ? { \"aria-hidden\": true } : {}),\n onLoad: handleLoad,\n onError: handleError,\n ...(imageRef === undefined ? {} : { ref: imageRef }),\n };\n\n let visual: ReactNode;\n if (status === \"error\") {\n const fallbackLabel = resolveImageFallbackAccessibilityLabel(descriptor);\n visual = (\n <span\n className=\"hjm-image__fallback\"\n role={descriptor.decorative ? undefined : \"img\"}\n aria-label={fallbackLabel}\n aria-hidden={descriptor.decorative || undefined}\n >\n <span className=\"hjm-image__fallback-icon\" aria-hidden=\"true\">\n {fallback ?? (\n <Icon\n name={imageRecipe.fallback.icon.name}\n tone={imageRecipe.fallback.icon.tone}\n decorative\n />\n )}\n </span>\n </span>\n );\n } else if (renderImage === undefined) {\n const { ref: assetRef, ...nativeImageProps } = adapterProps;\n visual = <img {...nativeImageProps} ref={assetRef} />;\n } else {\n visual = renderImage(adapterProps);\n }\n\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-image\", className)}\n data-fit={descriptor.fit}\n data-status={status}\n style={{\n inlineSize: descriptor.width,\n ...style,\n ...layoutStyle,\n aspectRatio: resolveImageAspectRatio(\n descriptor.width,\n descriptor.height,\n ),\n }}\n >\n {visual}\n </span>\n );\n});\n\nexport type CounterBadgeProps = Omit<HTMLAttributes<HTMLSpanElement>, \"children\"> &\n Readonly<{\n count: number;\n max?: number;\n tone?: CounterBadgeTone;\n size?: CounterBadgeSize;\n variant?: CounterBadgeVariant;\n /**\n * Says \"there is something new\" without a number. Use it where the count is\n * unknown or not worth reading; inventing a number would be worse than\n * saying none. The accessible name then carries the whole meaning.\n */\n dot?: boolean;\n accessibilityLabel?: string;\n /** Canonical layout-only placement. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const CounterBadge = forwardRef<HTMLSpanElement, CounterBadgeProps>(\n function CounterBadge(\n {\n count,\n max = counterBadgeRecipe.defaults.max,\n tone = counterBadgeRecipe.defaults.tone,\n size = counterBadgeRecipe.defaults.size,\n variant = counterBadgeRecipe.defaults.variant,\n dot = false,\n accessibilityLabel,\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n ) {\n const label = formatCounterBadgeCount(count, max);\n if (accessibilityLabel !== undefined && accessibilityLabel.trim().length === 0) {\n throw new TypeError(\"CounterBadge accessibilityLabel must not be empty\");\n }\n if (dot && accessibilityLabel === undefined) {\n // A dot with no name is a decoration that nobody can read.\n throw new TypeError(\"CounterBadge dot requires an accessibilityLabel\");\n }\n if (label === null) return null;\n return (\n <span\n {...props}\n ref={ref}\n className={classNames(\"hjm-counter-badge\", className)}\n data-tone={tone}\n data-size={size}\n data-variant={variant}\n data-dot={dot || undefined}\n style={dot ? { ...style, ...layoutStyle, \"--hjm-counter-dot-size\": `${counterBadgeRecipe.dotSize}px` } as typeof style : { ...style, ...layoutStyle }}\n aria-hidden={accessibilityLabel === undefined || undefined}\n // A named count needs a semantic role; generic spans cannot carry aria-label.\n role={accessibilityLabel === undefined ? undefined : \"img\"}\n aria-label={accessibilityLabel}\n >\n {dot ? null : label}\n </span>\n );\n },\n);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"supplemental-navigation.d.ts","sourceRoot":"","sources":["../src/supplemental-navigation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AA8BtE,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAC1E,QAAQ,CAAC;IACP,UAAU,EAAE,kBAAkB,CAAC;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,sBAAsB,CAAC;IACnC,gBAAgB,CAAC,EAAE,CACjB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,qBAAqB,KAC1B,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACzE,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,QAAQ;gBAnBL,kBAAkB;WACvB,YAAY;cACT,eAAe;gBACb,sBAAsB;uBACf,CACjB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,qBAAqB,KAC1B,IAAI;qBACQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI;uBACrD,OAAO,GAAG,QAAQ,GAAG,IAAI;iBAC/B,MAAM;IACnB,gGAAgG;kBAClF,uBAAuB;mDAkJxC,CAAC"}
1
+ {"version":3,"file":"supplemental-navigation.d.ts","sourceRoot":"","sources":["../src/supplemental-navigation.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC3B,MAAM,8CAA8C,CAAC;AACtD,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAOL,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AA8BtE,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,UAAU,CAAC,GAC1E,QAAQ,CAAC;IACP,UAAU,EAAE,kBAAkB,CAAC;IAC/B,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,UAAU,EAAE,sBAAsB,CAAC;IACnC,gBAAgB,CAAC,EAAE,CACjB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,qBAAqB,KAC1B,IAAI,CAAC;IACV,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACzE,gBAAgB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEL;;;GAGG;AACH,eAAO,MAAM,QAAQ;gBAnBL,kBAAkB;WACvB,YAAY;cACT,eAAe;gBACb,sBAAsB;uBACf,CACjB,OAAO,EAAE,sBAAsB,EAC/B,MAAM,EAAE,qBAAqB,KAC1B,IAAI;qBACQ,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,qBAAqB,KAAK,IAAI;uBACrD,OAAO,GAAG,QAAQ,GAAG,IAAI;iBAC/B,MAAM;IACnB,gGAAgG;kBAClF,uBAAuB;mDAyJxC,CAAC"}
@@ -39,6 +39,7 @@ export const LoadMore = forwardRef(function LoadMore({ descriptor, mode = loadMo
39
39
  onLoadMoreRef.current = onLoadMore;
40
40
  const [controllerFacade] = useState(createLoadMoreControllerFacade);
41
41
  const controller = controllerFacade.facade;
42
+ const requestGeneration = useRef(0);
42
43
  const sentinelRef = useRef(null);
43
44
  const currentRequestIdentityRef = useRef(null);
44
45
  const completedRequestIdentityRef = useRef(null);
@@ -47,6 +48,7 @@ export const LoadMore = forwardRef(function LoadMore({ descriptor, mode = loadMo
47
48
  : null;
48
49
  useLayoutEffect(() => {
49
50
  currentRequestIdentityRef.current = currentRequestIdentity;
51
+ return () => { currentRequestIdentityRef.current = null; };
50
52
  }, [currentRequestIdentity]);
51
53
  const request = useCallback(async (state, reason) => {
52
54
  if (state.status === "loading" || state.status === "complete")
@@ -61,15 +63,19 @@ export const LoadMore = forwardRef(function LoadMore({ descriptor, mode = loadMo
61
63
  // until the product commits a new cursor or a retryable error state.
62
64
  if (completedRequestIdentityRef.current === requestIdentity)
63
65
  return;
66
+ const generation = requestGeneration.current;
64
67
  try {
65
68
  const outcome = await controller.request(state, reason);
69
+ if (generation !== requestGeneration.current)
70
+ return;
66
71
  if (outcome === "started") {
67
72
  completedRequestIdentityRef.current = requestIdentity;
68
73
  }
69
74
  onRequestOutcome?.(outcome, reason);
70
75
  }
71
76
  catch (error) {
72
- onRequestError?.(error, reason);
77
+ if (generation === requestGeneration.current)
78
+ onRequestError?.(error, reason);
73
79
  }
74
80
  }, [controller, onRequestError, onRequestOutcome]);
75
81
  useEffect(() => {
@@ -78,7 +84,10 @@ export const LoadMore = forwardRef(function LoadMore({ descriptor, mode = loadMo
78
84
  onLoadMore: (nextRequest) => onLoadMoreRef.current(nextRequest),
79
85
  });
80
86
  const detach = controllerFacade.attach(attached);
87
+ requestGeneration.current += 1;
81
88
  return () => {
89
+ // The query remains product-owned; only this retired footer's callbacks stop.
90
+ requestGeneration.current += 1;
82
91
  detach();
83
92
  attached.dispose();
84
93
  };
@@ -1 +1 @@
1
- {"version":3,"file":"supplemental-navigation.js","sourceRoot":"","sources":["../src/supplemental-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createLoadMoreController,\n validateLoadMoreDescriptor,\n type LoadMoreController,\n type LoadMoreControllerSnapshot,\n type LoadMoreDescriptor,\n type LoadMoreMode,\n type LoadMoreRequestHandler,\n type LoadMoreRequestOutcome,\n type LoadMoreRequestReason,\n} from \"@hjmds/design-contracts/components/load-more\";\nimport {\n loadMoreRecipe,\n type LoadMoreDensity,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type HTMLAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nfunction createLoadMoreControllerFacade(): Readonly<{\n facade: LoadMoreController;\n attach(controller: LoadMoreController): () => void;\n}> {\n const detachedSnapshot: LoadMoreControllerSnapshot = {\n mode: \"automatic\",\n inFlightRequestKey: null,\n disposed: true,\n };\n let active: LoadMoreController | null = null;\n return {\n facade: {\n getSnapshot: () => active?.getSnapshot() ?? detachedSnapshot,\n request: (state, reason) => {\n if (!active) throw new Error(\"Cannot use a detached LoadMore controller\");\n return active.request(state, reason);\n },\n dispose: () => active?.dispose() ?? false,\n },\n attach(controller) {\n active = controller;\n return () => {\n if (active === controller) active = null;\n };\n },\n };\n}\n\nexport type LoadMoreProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n descriptor: LoadMoreDescriptor;\n mode?: LoadMoreMode;\n density?: LoadMoreDensity;\n onLoadMore: LoadMoreRequestHandler;\n onRequestOutcome?: (\n outcome: LoadMoreRequestOutcome,\n reason: LoadMoreRequestReason,\n ) => void;\n onRequestError?: (error: unknown, reason: LoadMoreRequestReason) => void;\n intersectionRoot?: Element | Document | null;\n rootMargin?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/**\n * A collection footer that keeps product data controlled while the shared\n * controller prevents overlapping cursor requests.\n */\nexport const LoadMore = forwardRef<HTMLDivElement, LoadMoreProps>(\n function LoadMore(\n {\n descriptor,\n mode = loadMoreRecipe.defaults.mode,\n density = loadMoreRecipe.defaults.density,\n onLoadMore,\n onRequestOutcome,\n onRequestError,\n intersectionRoot = null,\n rootMargin = \"200px 0px\",\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n ) {\n validateLoadMoreDescriptor(descriptor);\n const onLoadMoreRef = useRef(onLoadMore);\n onLoadMoreRef.current = onLoadMore;\n const [controllerFacade] = useState(createLoadMoreControllerFacade);\n const controller = controllerFacade.facade;\n const sentinelRef = useRef<HTMLSpanElement>(null);\n const currentRequestIdentityRef = useRef<string | null>(null);\n const completedRequestIdentityRef = useRef<string | null>(null);\n const currentRequestIdentity =\n descriptor.state.status === \"ready\" || descriptor.state.status === \"error\"\n ? `${descriptor.state.status}:${descriptor.state.requestKey}`\n : null;\n\n useLayoutEffect(() => {\n currentRequestIdentityRef.current = currentRequestIdentity;\n }, [currentRequestIdentity]);\n\n const request = useCallback(\n async (\n state: LoadMoreDescriptor[\"state\"],\n reason: LoadMoreRequestReason,\n ) => {\n if (state.status === \"loading\" || state.status === \"complete\") return;\n const requestIdentity = `${state.status}:${state.requestKey}`;\n // IntersectionObserver may deliver an already queued callback after\n // disconnect. Only events for the currently committed descriptor may\n // enter the shared request controller.\n if (currentRequestIdentityRef.current !== requestIdentity) return;\n // Once a request settles successfully, retire that exact state/key\n // until the product commits a new cursor or a retryable error state.\n if (completedRequestIdentityRef.current === requestIdentity) return;\n try {\n const outcome = await controller.request(state, reason);\n if (outcome === \"started\") {\n completedRequestIdentityRef.current = requestIdentity;\n }\n onRequestOutcome?.(outcome, reason);\n } catch (error) {\n onRequestError?.(error, reason);\n }\n },\n [controller, onRequestError, onRequestOutcome],\n );\n\n useEffect(() => {\n const attached = createLoadMoreController({\n mode,\n onLoadMore: (nextRequest) => onLoadMoreRef.current(nextRequest),\n });\n const detach = controllerFacade.attach(attached);\n return () => {\n detach();\n attached.dispose();\n };\n }, [controllerFacade, mode]);\n\n useEffect(() => {\n if (\n mode !== \"automatic\" ||\n descriptor.state.status !== \"ready\" ||\n typeof IntersectionObserver === \"undefined\"\n ) {\n return;\n }\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n void request(descriptor.state, \"viewport\");\n }\n },\n { root: intersectionRoot, rootMargin },\n );\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [descriptor.state, intersectionRoot, mode, request, rootMargin]);\n\n const { state, labels } = descriptor;\n return (\n <div\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-load-more\", className)}\n data-mode={mode}\n data-density={density}\n data-state={state.status}\n aria-busy={state.status === \"loading\" || undefined}\n >\n <span ref={sentinelRef} className=\"hjm-load-more__sentinel\" aria-hidden=\"true\" />\n {state.status === \"ready\" ? (\n <button\n type=\"button\"\n className=\"hjm-load-more__trigger\"\n onClick={() => void request(state, \"manual\")}\n >\n {labels.loadMore}\n </button>\n ) : state.status === \"loading\" ? (\n <div className=\"hjm-load-more__status\" role=\"status\">\n <span className=\"hjm-load-more__spinner\" aria-hidden=\"true\" />\n <span className=\"hjm-visually-hidden\">{labels.loading}</span>\n </div>\n ) : state.status === \"error\" ? (\n <div className=\"hjm-load-more__error\">\n <span role=\"alert\">{state.message}</span>\n <button\n type=\"button\"\n className=\"hjm-load-more__trigger\"\n onClick={() => void request(state, \"retry\")}\n >\n {labels.retry}\n </button>\n </div>\n ) : (\n <div className=\"hjm-load-more__end\">{labels.complete}</div>\n )}\n </div>\n );\n },\n);\n"]}
1
+ {"version":3,"file":"supplemental-navigation.js","sourceRoot":"","sources":["../src/supplemental-navigation.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n createLoadMoreController,\n validateLoadMoreDescriptor,\n type LoadMoreController,\n type LoadMoreControllerSnapshot,\n type LoadMoreDescriptor,\n type LoadMoreMode,\n type LoadMoreRequestHandler,\n type LoadMoreRequestOutcome,\n type LoadMoreRequestReason,\n} from \"@hjmds/design-contracts/components/load-more\";\nimport {\n loadMoreRecipe,\n type LoadMoreDensity,\n} from \"@hjmds/design-contracts/recipes\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type HTMLAttributes,\n} from \"react\";\nimport { classNames } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nfunction createLoadMoreControllerFacade(): Readonly<{\n facade: LoadMoreController;\n attach(controller: LoadMoreController): () => void;\n}> {\n const detachedSnapshot: LoadMoreControllerSnapshot = {\n mode: \"automatic\",\n inFlightRequestKey: null,\n disposed: true,\n };\n let active: LoadMoreController | null = null;\n return {\n facade: {\n getSnapshot: () => active?.getSnapshot() ?? detachedSnapshot,\n request: (state, reason) => {\n if (!active) throw new Error(\"Cannot use a detached LoadMore controller\");\n return active.request(state, reason);\n },\n dispose: () => active?.dispose() ?? false,\n },\n attach(controller) {\n active = controller;\n return () => {\n if (active === controller) active = null;\n };\n },\n };\n}\n\nexport type LoadMoreProps = Omit<HTMLAttributes<HTMLDivElement>, \"children\"> &\n Readonly<{\n descriptor: LoadMoreDescriptor;\n mode?: LoadMoreMode;\n density?: LoadMoreDensity;\n onLoadMore: LoadMoreRequestHandler;\n onRequestOutcome?: (\n outcome: LoadMoreRequestOutcome,\n reason: LoadMoreRequestReason,\n ) => void;\n onRequestError?: (error: unknown, reason: LoadMoreRequestReason) => void;\n intersectionRoot?: Element | Document | null;\n rootMargin?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n }>;\n\n/**\n * A collection footer that keeps product data controlled while the shared\n * controller prevents overlapping cursor requests.\n */\nexport const LoadMore = forwardRef<HTMLDivElement, LoadMoreProps>(\n function LoadMore(\n {\n descriptor,\n mode = loadMoreRecipe.defaults.mode,\n density = loadMoreRecipe.defaults.density,\n onLoadMore,\n onRequestOutcome,\n onRequestError,\n intersectionRoot = null,\n rootMargin = \"200px 0px\",\n className,\n layoutStyle,\n style,\n ...props\n },\n ref,\n ) {\n validateLoadMoreDescriptor(descriptor);\n const onLoadMoreRef = useRef(onLoadMore);\n onLoadMoreRef.current = onLoadMore;\n const [controllerFacade] = useState(createLoadMoreControllerFacade);\n const controller = controllerFacade.facade;\n const requestGeneration = useRef(0);\n const sentinelRef = useRef<HTMLSpanElement>(null);\n const currentRequestIdentityRef = useRef<string | null>(null);\n const completedRequestIdentityRef = useRef<string | null>(null);\n const currentRequestIdentity =\n descriptor.state.status === \"ready\" || descriptor.state.status === \"error\"\n ? `${descriptor.state.status}:${descriptor.state.requestKey}`\n : null;\n\n useLayoutEffect(() => {\n currentRequestIdentityRef.current = currentRequestIdentity;\n return () => { currentRequestIdentityRef.current = null; };\n }, [currentRequestIdentity]);\n\n const request = useCallback(\n async (\n state: LoadMoreDescriptor[\"state\"],\n reason: LoadMoreRequestReason,\n ) => {\n if (state.status === \"loading\" || state.status === \"complete\") return;\n const requestIdentity = `${state.status}:${state.requestKey}`;\n // IntersectionObserver may deliver an already queued callback after\n // disconnect. Only events for the currently committed descriptor may\n // enter the shared request controller.\n if (currentRequestIdentityRef.current !== requestIdentity) return;\n // Once a request settles successfully, retire that exact state/key\n // until the product commits a new cursor or a retryable error state.\n if (completedRequestIdentityRef.current === requestIdentity) return;\n const generation = requestGeneration.current;\n try {\n const outcome = await controller.request(state, reason);\n if (generation !== requestGeneration.current) return;\n if (outcome === \"started\") {\n completedRequestIdentityRef.current = requestIdentity;\n }\n onRequestOutcome?.(outcome, reason);\n } catch (error) {\n if (generation === requestGeneration.current) onRequestError?.(error, reason);\n }\n },\n [controller, onRequestError, onRequestOutcome],\n );\n\n useEffect(() => {\n const attached = createLoadMoreController({\n mode,\n onLoadMore: (nextRequest) => onLoadMoreRef.current(nextRequest),\n });\n const detach = controllerFacade.attach(attached);\n requestGeneration.current += 1;\n return () => {\n // The query remains product-owned; only this retired footer's callbacks stop.\n requestGeneration.current += 1;\n detach();\n attached.dispose();\n };\n }, [controllerFacade, mode]);\n\n useEffect(() => {\n if (\n mode !== \"automatic\" ||\n descriptor.state.status !== \"ready\" ||\n typeof IntersectionObserver === \"undefined\"\n ) {\n return;\n }\n const sentinel = sentinelRef.current;\n if (!sentinel) return;\n const observer = new IntersectionObserver(\n (entries) => {\n if (entries.some((entry) => entry.isIntersecting)) {\n void request(descriptor.state, \"viewport\");\n }\n },\n { root: intersectionRoot, rootMargin },\n );\n observer.observe(sentinel);\n return () => observer.disconnect();\n }, [descriptor.state, intersectionRoot, mode, request, rootMargin]);\n\n const { state, labels } = descriptor;\n return (\n <div\n {...props}\n style={{ ...style, ...layoutStyle }}\n ref={ref}\n className={classNames(\"hjm-load-more\", className)}\n data-mode={mode}\n data-density={density}\n data-state={state.status}\n aria-busy={state.status === \"loading\" || undefined}\n >\n <span ref={sentinelRef} className=\"hjm-load-more__sentinel\" aria-hidden=\"true\" />\n {state.status === \"ready\" ? (\n <button\n type=\"button\"\n className=\"hjm-load-more__trigger\"\n onClick={() => void request(state, \"manual\")}\n >\n {labels.loadMore}\n </button>\n ) : state.status === \"loading\" ? (\n <div className=\"hjm-load-more__status\" role=\"status\">\n <span className=\"hjm-load-more__spinner\" aria-hidden=\"true\" />\n <span className=\"hjm-visually-hidden\">{labels.loading}</span>\n </div>\n ) : state.status === \"error\" ? (\n <div className=\"hjm-load-more__error\">\n <span role=\"alert\">{state.message}</span>\n <button\n type=\"button\"\n className=\"hjm-load-more__trigger\"\n onClick={() => void request(state, \"retry\")}\n >\n {labels.retry}\n </button>\n </div>\n ) : (\n <div className=\"hjm-load-more__end\">{labels.complete}</div>\n )}\n </div>\n );\n },\n);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tags-input.d.ts","sourceRoot":"","sources":["../src/tags-input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,+CAA+C,CAAC;AASvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACnD;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC3C,gEAAgE;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC7C,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,eAAO,MAAM,SAAS;WA/Bb,MAAM;WACN,SAAS,MAAM,EAAE;kBACV,SAAS,MAAM,EAAE;mBAChB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI;IAChD,6EAA6E;eAClE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI;IAClD;;;OAGG;oBACa,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;aAC9B,eAAe;iBACX,SAAS,kBAAkB,EAAE;IAC1C,gEAAgE;wBAC5C,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM;IAC3C;;;;OAIG;kBACW,SAAS,mBAAmB,EAAE;IAC5C,wDAAwD;uBACrC,MAAM;kBACX,MAAM;kBACN,MAAM;eACT,OAAO;gBACN,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;qDAyKrC,CAAC"}
1
+ {"version":3,"file":"tags-input.d.ts","sourceRoot":"","sources":["../src/tags-input.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACzB,MAAM,+CAA+C,CAAC;AAUvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEtE,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI,CAAC;IACnD;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,UAAU,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC3C,gEAAgE;IAChE,kBAAkB,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IAC5C;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC7C,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gGAAgG;IAChG,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,eAAO,MAAM,SAAS;WA/Bb,MAAM;WACN,SAAS,MAAM,EAAE;kBACV,SAAS,MAAM,EAAE;mBAChB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI;IAChD,6EAA6E;eAClE,CAAC,MAAM,EAAE,qBAAqB,KAAK,IAAI;IAClD;;;OAGG;oBACa,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI;aAC9B,eAAe;iBACX,SAAS,kBAAkB,EAAE;IAC1C,gEAAgE;wBAC5C,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM;IAC3C;;;;OAIG;kBACW,SAAS,mBAAmB,EAAE;IAC5C,wDAAwD;uBACrC,MAAM;kBACX,MAAM;kBACN,MAAM;eACT,OAAO;gBACN,MAAM;IAClB,gGAAgG;kBAClF,uBAAuB;qDAiLrC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { removeTagAt, resolveTagsInputActiveSuggestion, resolveTagsInputCommit, tagsInputBehaviorDefaults, tagsInputRecipe, } from "@hjmds/design-contracts/components/tags-input";
3
- import { forwardRef, useRef, useState, } from "react";
3
+ import { forwardRef, useId, useRef, useState, } from "react";
4
4
  import { classNames, composeRefs, useControllableState } from "./internal.js";
5
5
  export const TagsInput = forwardRef(function TagsInput({ label, tags: controlledTags, defaultTags, onTagsChange, onReject, onDraftChange, policy, commitKeys = tagsInputRecipe.defaults.commitKeys, suggestions, suggestionsLabel, composeRemoveLabel, placeholder, description, disabled = false, className, layoutStyle, }, forwardedRef) {
6
6
  const [tags, setTags] = useControllableState({
@@ -13,15 +13,20 @@ export const TagsInput = forwardRef(function TagsInput({ label, tags: controlled
13
13
  // removes it. Removing on the first press loses work with no warning.
14
14
  const [armedIndex, setArmedIndex] = useState(null);
15
15
  const [activeSuggestionId, setActiveSuggestionId] = useState(null);
16
- const openSuggestions = (suggestions?.length ?? 0) > 0 && draft.trim().length > 0;
17
- const activeSuggestion = suggestions?.find((item) => item.id === activeSuggestionId) ?? null;
16
+ const [suggestionsDismissed, setSuggestionsDismissed] = useState(false);
17
+ const hasSuggestions = (suggestions?.length ?? 0) > 0 && draft.trim().length > 0;
18
+ const openSuggestions = hasSuggestions && !suggestionsDismissed;
19
+ const activeSuggestion = suggestions?.find((item) => item.id === activeSuggestionId && !item.disabled) ?? null;
18
20
  const inputRef = useRef(null);
19
- const id = `hjm-tags-${label.replace(/\s+/gu, "-")}`;
21
+ const id = `hjm-tags-${useId().replaceAll(":", "")}`;
20
22
  const changeDraft = (next) => {
21
23
  setDraft(next);
24
+ setSuggestionsDismissed(false);
22
25
  onDraftChange?.(next);
23
26
  };
24
27
  const commit = (value) => {
28
+ if (disabled)
29
+ return;
25
30
  const result = resolveTagsInputCommit(tags, value, policy ?? {});
26
31
  if (!result.accepted) {
27
32
  onReject?.(result);
@@ -39,15 +44,20 @@ export const TagsInput = forwardRef(function TagsInput({ label, tags: controlled
39
44
  inputRef.current?.focus();
40
45
  };
41
46
  const onKeyDown = (event) => {
47
+ // IME confirmation keys belong to the composition, not tag submission.
48
+ if (disabled || event.nativeEvent.isComposing || event.keyCode === 229)
49
+ return;
42
50
  const key = event.key;
43
- if (openSuggestions && (key === "ArrowDown" || key === "ArrowUp")) {
51
+ if (hasSuggestions && (key === "ArrowDown" || key === "ArrowUp")) {
44
52
  event.preventDefault();
53
+ setSuggestionsDismissed(false);
45
54
  setActiveSuggestionId(resolveTagsInputActiveSuggestion(suggestions ?? [], activeSuggestionId, key === "ArrowDown" ? "next" : "previous"));
46
55
  return;
47
56
  }
48
- if (key === "Escape" && activeSuggestionId !== null) {
57
+ if (key === "Escape" && openSuggestions) {
49
58
  // Dismissing the candidate list must not clear what the user typed.
50
59
  event.preventDefault();
60
+ setSuggestionsDismissed(true);
51
61
  setActiveSuggestionId(null);
52
62
  return;
53
63
  }
@@ -78,11 +88,11 @@ export const TagsInput = forwardRef(function TagsInput({ label, tags: controlled
78
88
  "--hjm-tags-gap": `${tagsInputRecipe.frame.gap}px`,
79
89
  "--hjm-tags-tag-min-height": `${tagsInputRecipe.tag.minHeight}px`,
80
90
  "--hjm-tags-remove-target": `${tagsInputRecipe.remove.minTouchTarget}px`,
81
- }, onClick: () => inputRef.current?.focus(), children: [_jsx("ul", { className: "hjm-tags-input__list", children: tags.map((tag, index) => (_jsxs("li", { className: "hjm-tags-input__tag", "data-armed": armedIndex === index || undefined, children: [_jsx("span", { children: tag }), _jsx("button", { type: "button", "aria-label": composeRemoveLabel(tag), className: "hjm-tags-input__remove", disabled: disabled, onClick: () => remove(index), children: "\u00D7" })] }, `${tag}-${index}`))) }), _jsx("input", { ref: composeRefs(inputRef, forwardedRef), id: id, type: "text", className: "hjm-tags-input__input", value: draft, placeholder: placeholder, disabled: disabled, "aria-describedby": description ? `${id}-description` : undefined, role: suggestions ? "combobox" : undefined, "aria-expanded": suggestions ? openSuggestions : undefined, "aria-controls": suggestions && openSuggestions ? `${id}-suggestions` : undefined, "aria-activedescendant": activeSuggestion ? `${id}-suggestion-${activeSuggestion.id}` : undefined, "aria-autocomplete": suggestions ? "list" : undefined, onChange: (event) => { changeDraft(event.target.value); setArmedIndex(null); setActiveSuggestionId(null); }, onKeyDown: onKeyDown, onBlur: () => { if (commitKeys.includes("Blur"))
91
+ }, onClick: () => inputRef.current?.focus(), children: [_jsx("ul", { className: "hjm-tags-input__list", children: tags.map((tag, index) => (_jsxs("li", { className: "hjm-tags-input__tag", "data-armed": armedIndex === index || undefined, children: [_jsx("span", { children: tag }), _jsx("button", { type: "button", "aria-label": composeRemoveLabel(tag), className: "hjm-tags-input__remove", disabled: disabled, onClick: () => remove(index), children: "\u00D7" })] }, `${tag}-${index}`))) }), _jsx("input", { ref: composeRefs(inputRef, forwardedRef), id: id, type: "text", className: "hjm-tags-input__input", value: draft, placeholder: placeholder, disabled: disabled, "aria-describedby": description ? `${id}-description` : undefined, role: suggestions ? "combobox" : undefined, "aria-expanded": suggestions ? openSuggestions : undefined, "aria-controls": suggestions && openSuggestions ? `${id}-suggestions` : undefined, "aria-activedescendant": openSuggestions && activeSuggestion ? `${id}-suggestion-${activeSuggestion.id}` : undefined, "aria-autocomplete": suggestions ? "list" : undefined, onChange: (event) => { changeDraft(event.target.value); setArmedIndex(null); setActiveSuggestionId(null); }, onKeyDown: onKeyDown, onBlur: () => { if (commitKeys.includes("Blur"))
82
92
  commit(draft); setArmedIndex(null); } })] }), openSuggestions ? (_jsx("ul", { id: `${id}-suggestions`, role: "listbox", "aria-label": suggestionsLabel, className: "hjm-tags-input__suggestions", children: (suggestions ?? []).map((item) => (_jsx("li", { id: `${id}-suggestion-${item.id}`, role: "option", "aria-selected": item.id === activeSuggestionId, "aria-disabled": item.disabled || undefined, className: "hjm-tags-input__suggestion", onMouseDown: (event) => {
83
93
  // Commit before blur so the draft is still there to replace.
84
94
  event.preventDefault();
85
- if (!item.disabled)
95
+ if (!disabled && !item.disabled)
86
96
  commit(item.value ?? item.label);
87
97
  }, onMouseEnter: () => { if (!item.disabled)
88
98
  setActiveSuggestionId(item.id); }, children: item.label }, item.id))) })) : null, description ? _jsx("p", { id: `${id}-description`, className: "hjm-tags-input__description", children: description }) : null] }));
@@ -1 +1 @@
1
- {"version":3,"file":"tags-input.js","sourceRoot":"","sources":["../src/tags-input.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n removeTagAt,\n resolveTagsInputActiveSuggestion,\n resolveTagsInputCommit,\n tagsInputBehaviorDefaults,\n tagsInputRecipe,\n type TagsInputCommitKey,\n type TagsInputCommitResult,\n type TagsInputPolicy,\n type TagsInputSuggestion,\n} from \"@hjmds/design-contracts/components/tags-input\";\nimport {\n forwardRef,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n} from \"react\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type TagsInputProps = Readonly<{\n label: string;\n tags?: readonly string[];\n defaultTags?: readonly string[];\n onTagsChange?: (tags: readonly string[]) => void;\n /** Fires when a value could not be committed, with the contract's reason. */\n onReject?: (result: TagsInputCommitResult) => void;\n /**\n * The text being typed. A product filtering `suggestions` cannot do it\n * without this — the draft lives here, not in the product's state.\n */\n onDraftChange?: (draft: string) => void;\n policy?: TagsInputPolicy;\n commitKeys?: readonly TagsInputCommitKey[];\n /** Composes one tag's remove-control name from the tag text. */\n composeRemoveLabel: (tag: string) => string;\n /**\n * Candidates for the current draft, already filtered by the product. Present\n * them and the field becomes the multi-select combobox case without a second\n * value shape.\n */\n suggestions?: readonly TagsInputSuggestion[];\n /** Localized accessible name for the candidate list. */\n suggestionsLabel?: string;\n placeholder?: string;\n description?: string;\n disabled?: boolean;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const TagsInput = forwardRef<HTMLInputElement, TagsInputProps>(function TagsInput(\n {\n label,\n tags: controlledTags,\n defaultTags,\n onTagsChange,\n onReject,\n onDraftChange,\n policy,\n commitKeys = tagsInputRecipe.defaults.commitKeys,\n suggestions,\n suggestionsLabel,\n composeRemoveLabel,\n placeholder,\n description,\n disabled = false,\n className,\n layoutStyle,\n },\n forwardedRef,\n) {\n const [tags, setTags] = useControllableState<readonly string[]>({\n ...(controlledTags === undefined ? {} : { value: controlledTags }),\n defaultValue: defaultTags ?? [],\n ...(onTagsChange === undefined ? {} : { onChange: onTagsChange }),\n });\n const [draft, setDraft] = useState(\"\");\n // Backspace on an empty field selects the last tag first; a second press\n // removes it. Removing on the first press loses work with no warning.\n const [armedIndex, setArmedIndex] = useState<number | null>(null);\n const [activeSuggestionId, setActiveSuggestionId] = useState<string | null>(null);\n const openSuggestions = (suggestions?.length ?? 0) > 0 && draft.trim().length > 0;\n const activeSuggestion = suggestions?.find((item) => item.id === activeSuggestionId) ?? null;\n const inputRef = useRef<HTMLInputElement>(null);\n const id = `hjm-tags-${label.replace(/\\s+/gu, \"-\")}`;\n\n const changeDraft = (next: string) => {\n setDraft(next);\n onDraftChange?.(next);\n };\n const commit = (value: string) => {\n const result = resolveTagsInputCommit(tags, value, policy ?? {});\n if (!result.accepted) { onReject?.(result); return; }\n setTags([...tags, result.value]);\n setDraft(\"\");\n onDraftChange?.(\"\");\n setArmedIndex(null);\n setActiveSuggestionId(null);\n };\n const remove = (index: number) => {\n setTags(removeTagAt(tags, index));\n setArmedIndex(null);\n inputRef.current?.focus();\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n const key = event.key;\n if (openSuggestions && (key === \"ArrowDown\" || key === \"ArrowUp\")) {\n event.preventDefault();\n setActiveSuggestionId(resolveTagsInputActiveSuggestion(\n suggestions ?? [],\n activeSuggestionId,\n key === \"ArrowDown\" ? \"next\" : \"previous\",\n ));\n return;\n }\n if (key === \"Escape\" && activeSuggestionId !== null) {\n // Dismissing the candidate list must not clear what the user typed.\n event.preventDefault();\n setActiveSuggestionId(null);\n return;\n }\n const isCommitKey =\n (key === \"Enter\" && commitKeys.includes(\"Enter\")) ||\n (key === \",\" && commitKeys.includes(\"Comma\")) ||\n (key === \" \" && commitKeys.includes(\"Space\"));\n if (isCommitKey) {\n event.preventDefault();\n // A highlighted candidate wins over the raw text; otherwise the typed\n // value commits, which is what makes this different from a Select.\n commit(activeSuggestion ? activeSuggestion.value ?? activeSuggestion.label : draft);\n return;\n }\n if (key !== \"Backspace\" || draft.length > 0 || tags.length === 0) {\n if (key !== \"Backspace\") setArmedIndex(null);\n return;\n }\n event.preventDefault();\n const last = tags.length - 1;\n if (armedIndex === last || tagsInputBehaviorDefaults.backspaceRemovesLastTag) remove(last);\n else setArmedIndex(last);\n };\n\n return (\n <div style={layoutStyle} className={classNames(\"hjm-tags-input\", className)} data-disabled={disabled || undefined}>\n <label className=\"hjm-tags-input__label\" htmlFor={id}>{label}</label>\n <div\n className=\"hjm-tags-input__frame\"\n style={{\n \"--hjm-tags-min-height\": `${tagsInputRecipe.frame.minHeight}px`,\n \"--hjm-tags-gap\": `${tagsInputRecipe.frame.gap}px`,\n \"--hjm-tags-tag-min-height\": `${tagsInputRecipe.tag.minHeight}px`,\n \"--hjm-tags-remove-target\": `${tagsInputRecipe.remove.minTouchTarget}px`,\n } as CSSProperties}\n onClick={() => inputRef.current?.focus()}\n >\n <ul className=\"hjm-tags-input__list\">\n {tags.map((tag, index) => (\n <li key={`${tag}-${index}`} className=\"hjm-tags-input__tag\" data-armed={armedIndex === index || undefined}>\n <span>{tag}</span>\n <button\n type=\"button\"\n aria-label={composeRemoveLabel(tag)}\n className=\"hjm-tags-input__remove\"\n disabled={disabled}\n onClick={() => remove(index)}\n >\n ×\n </button>\n </li>\n ))}\n </ul>\n <input\n ref={composeRefs(inputRef, forwardedRef)}\n id={id}\n type=\"text\"\n className=\"hjm-tags-input__input\"\n value={draft}\n placeholder={placeholder}\n disabled={disabled}\n aria-describedby={description ? `${id}-description` : undefined}\n role={suggestions ? \"combobox\" : undefined}\n aria-expanded={suggestions ? openSuggestions : undefined}\n aria-controls={suggestions && openSuggestions ? `${id}-suggestions` : undefined}\n aria-activedescendant={activeSuggestion ? `${id}-suggestion-${activeSuggestion.id}` : undefined}\n aria-autocomplete={suggestions ? \"list\" : undefined}\n onChange={(event) => { changeDraft(event.target.value); setArmedIndex(null); setActiveSuggestionId(null); }}\n onKeyDown={onKeyDown}\n onBlur={() => { if (commitKeys.includes(\"Blur\")) commit(draft); setArmedIndex(null); }}\n />\n </div>\n {openSuggestions ? (\n <ul id={`${id}-suggestions`} role=\"listbox\" aria-label={suggestionsLabel} className=\"hjm-tags-input__suggestions\">\n {(suggestions ?? []).map((item) => (\n <li\n key={item.id}\n id={`${id}-suggestion-${item.id}`}\n role=\"option\"\n aria-selected={item.id === activeSuggestionId}\n aria-disabled={item.disabled || undefined}\n className=\"hjm-tags-input__suggestion\"\n onMouseDown={(event) => {\n // Commit before blur so the draft is still there to replace.\n event.preventDefault();\n if (!item.disabled) commit(item.value ?? item.label);\n }}\n onMouseEnter={() => { if (!item.disabled) setActiveSuggestionId(item.id); }}\n >\n {item.label}\n </li>\n ))}\n </ul>\n ) : null}\n {description ? <p id={`${id}-description`} className=\"hjm-tags-input__description\">{description}</p> : null}\n </div>\n );\n});\n"]}
1
+ {"version":3,"file":"tags-input.js","sourceRoot":"","sources":["../src/tags-input.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n removeTagAt,\n resolveTagsInputActiveSuggestion,\n resolveTagsInputCommit,\n tagsInputBehaviorDefaults,\n tagsInputRecipe,\n type TagsInputCommitKey,\n type TagsInputCommitResult,\n type TagsInputPolicy,\n type TagsInputSuggestion,\n} from \"@hjmds/design-contracts/components/tags-input\";\nimport {\n forwardRef,\n useId,\n useRef,\n useState,\n type CSSProperties,\n type KeyboardEvent,\n} from \"react\";\nimport { classNames, composeRefs, useControllableState } from \"./internal.js\";\nimport type { HjmCompositionStyleProp } from \"./composition-style.js\";\n\nexport type TagsInputProps = Readonly<{\n label: string;\n tags?: readonly string[];\n defaultTags?: readonly string[];\n onTagsChange?: (tags: readonly string[]) => void;\n /** Fires when a value could not be committed, with the contract's reason. */\n onReject?: (result: TagsInputCommitResult) => void;\n /**\n * The text being typed. A product filtering `suggestions` cannot do it\n * without this — the draft lives here, not in the product's state.\n */\n onDraftChange?: (draft: string) => void;\n policy?: TagsInputPolicy;\n commitKeys?: readonly TagsInputCommitKey[];\n /** Composes one tag's remove-control name from the tag text. */\n composeRemoveLabel: (tag: string) => string;\n /**\n * Candidates for the current draft, already filtered by the product. Present\n * them and the field becomes the multi-select combobox case without a second\n * value shape.\n */\n suggestions?: readonly TagsInputSuggestion[];\n /** Localized accessible name for the candidate list. */\n suggestionsLabel?: string;\n placeholder?: string;\n description?: string;\n disabled?: boolean;\n className?: string;\n /** Canonical layout-only placement on the root element. Controlled visual keys are excluded. */\n layoutStyle?: HjmCompositionStyleProp;\n}>;\n\nexport const TagsInput = forwardRef<HTMLInputElement, TagsInputProps>(function TagsInput(\n {\n label,\n tags: controlledTags,\n defaultTags,\n onTagsChange,\n onReject,\n onDraftChange,\n policy,\n commitKeys = tagsInputRecipe.defaults.commitKeys,\n suggestions,\n suggestionsLabel,\n composeRemoveLabel,\n placeholder,\n description,\n disabled = false,\n className,\n layoutStyle,\n },\n forwardedRef,\n) {\n const [tags, setTags] = useControllableState<readonly string[]>({\n ...(controlledTags === undefined ? {} : { value: controlledTags }),\n defaultValue: defaultTags ?? [],\n ...(onTagsChange === undefined ? {} : { onChange: onTagsChange }),\n });\n const [draft, setDraft] = useState(\"\");\n // Backspace on an empty field selects the last tag first; a second press\n // removes it. Removing on the first press loses work with no warning.\n const [armedIndex, setArmedIndex] = useState<number | null>(null);\n const [activeSuggestionId, setActiveSuggestionId] = useState<string | null>(null);\n const [suggestionsDismissed, setSuggestionsDismissed] = useState(false);\n const hasSuggestions = (suggestions?.length ?? 0) > 0 && draft.trim().length > 0;\n const openSuggestions = hasSuggestions && !suggestionsDismissed;\n const activeSuggestion = suggestions?.find((item) => item.id === activeSuggestionId && !item.disabled) ?? null;\n const inputRef = useRef<HTMLInputElement>(null);\n const id = `hjm-tags-${useId().replaceAll(\":\", \"\")}`;\n\n const changeDraft = (next: string) => {\n setDraft(next);\n setSuggestionsDismissed(false);\n onDraftChange?.(next);\n };\n const commit = (value: string) => {\n if (disabled) return;\n const result = resolveTagsInputCommit(tags, value, policy ?? {});\n if (!result.accepted) { onReject?.(result); return; }\n setTags([...tags, result.value]);\n setDraft(\"\");\n onDraftChange?.(\"\");\n setArmedIndex(null);\n setActiveSuggestionId(null);\n };\n const remove = (index: number) => {\n setTags(removeTagAt(tags, index));\n setArmedIndex(null);\n inputRef.current?.focus();\n };\n\n const onKeyDown = (event: KeyboardEvent<HTMLInputElement>) => {\n // IME confirmation keys belong to the composition, not tag submission.\n if (disabled || event.nativeEvent.isComposing || event.keyCode === 229) return;\n const key = event.key;\n if (hasSuggestions && (key === \"ArrowDown\" || key === \"ArrowUp\")) {\n event.preventDefault();\n setSuggestionsDismissed(false);\n setActiveSuggestionId(resolveTagsInputActiveSuggestion(\n suggestions ?? [],\n activeSuggestionId,\n key === \"ArrowDown\" ? \"next\" : \"previous\",\n ));\n return;\n }\n if (key === \"Escape\" && openSuggestions) {\n // Dismissing the candidate list must not clear what the user typed.\n event.preventDefault();\n setSuggestionsDismissed(true);\n setActiveSuggestionId(null);\n return;\n }\n const isCommitKey =\n (key === \"Enter\" && commitKeys.includes(\"Enter\")) ||\n (key === \",\" && commitKeys.includes(\"Comma\")) ||\n (key === \" \" && commitKeys.includes(\"Space\"));\n if (isCommitKey) {\n event.preventDefault();\n // A highlighted candidate wins over the raw text; otherwise the typed\n // value commits, which is what makes this different from a Select.\n commit(activeSuggestion ? activeSuggestion.value ?? activeSuggestion.label : draft);\n return;\n }\n if (key !== \"Backspace\" || draft.length > 0 || tags.length === 0) {\n if (key !== \"Backspace\") setArmedIndex(null);\n return;\n }\n event.preventDefault();\n const last = tags.length - 1;\n if (armedIndex === last || tagsInputBehaviorDefaults.backspaceRemovesLastTag) remove(last);\n else setArmedIndex(last);\n };\n\n return (\n <div style={layoutStyle} className={classNames(\"hjm-tags-input\", className)} data-disabled={disabled || undefined}>\n <label className=\"hjm-tags-input__label\" htmlFor={id}>{label}</label>\n <div\n className=\"hjm-tags-input__frame\"\n style={{\n \"--hjm-tags-min-height\": `${tagsInputRecipe.frame.minHeight}px`,\n \"--hjm-tags-gap\": `${tagsInputRecipe.frame.gap}px`,\n \"--hjm-tags-tag-min-height\": `${tagsInputRecipe.tag.minHeight}px`,\n \"--hjm-tags-remove-target\": `${tagsInputRecipe.remove.minTouchTarget}px`,\n } as CSSProperties}\n onClick={() => inputRef.current?.focus()}\n >\n <ul className=\"hjm-tags-input__list\">\n {tags.map((tag, index) => (\n <li key={`${tag}-${index}`} className=\"hjm-tags-input__tag\" data-armed={armedIndex === index || undefined}>\n <span>{tag}</span>\n <button\n type=\"button\"\n aria-label={composeRemoveLabel(tag)}\n className=\"hjm-tags-input__remove\"\n disabled={disabled}\n onClick={() => remove(index)}\n >\n ×\n </button>\n </li>\n ))}\n </ul>\n <input\n ref={composeRefs(inputRef, forwardedRef)}\n id={id}\n type=\"text\"\n className=\"hjm-tags-input__input\"\n value={draft}\n placeholder={placeholder}\n disabled={disabled}\n aria-describedby={description ? `${id}-description` : undefined}\n role={suggestions ? \"combobox\" : undefined}\n aria-expanded={suggestions ? openSuggestions : undefined}\n aria-controls={suggestions && openSuggestions ? `${id}-suggestions` : undefined}\n aria-activedescendant={openSuggestions && activeSuggestion ? `${id}-suggestion-${activeSuggestion.id}` : undefined}\n aria-autocomplete={suggestions ? \"list\" : undefined}\n onChange={(event) => { changeDraft(event.target.value); setArmedIndex(null); setActiveSuggestionId(null); }}\n onKeyDown={onKeyDown}\n onBlur={() => { if (commitKeys.includes(\"Blur\")) commit(draft); setArmedIndex(null); }}\n />\n </div>\n {openSuggestions ? (\n <ul id={`${id}-suggestions`} role=\"listbox\" aria-label={suggestionsLabel} className=\"hjm-tags-input__suggestions\">\n {(suggestions ?? []).map((item) => (\n <li\n key={item.id}\n id={`${id}-suggestion-${item.id}`}\n role=\"option\"\n aria-selected={item.id === activeSuggestionId}\n aria-disabled={item.disabled || undefined}\n className=\"hjm-tags-input__suggestion\"\n onMouseDown={(event) => {\n // Commit before blur so the draft is still there to replace.\n event.preventDefault();\n if (!disabled && !item.disabled) commit(item.value ?? item.label);\n }}\n onMouseEnter={() => { if (!item.disabled) setActiveSuggestionId(item.id); }}\n >\n {item.label}\n </li>\n ))}\n </ul>\n ) : null}\n {description ? <p id={`${id}-description`} className=\"hjm-tags-input__description\">{description}</p> : null}\n </div>\n );\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAgBnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAmB7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CA6Lf"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAgBnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,aAAa,GACvC,MAAM,CAAC,SAAS,MAAM,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC;AAmB7C,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,yBAAyB,GAC/B,aAAa,CA8Lf"}
package/dist/theme.js CHANGED
@@ -157,6 +157,7 @@ export function createHjmThemeStyle(value) {
157
157
  // Panel toast (2026-10-10): media column, step progress and action alignment come from the same recipe Native reads.
158
158
  style["--hjm-toast-media-size"] = `${toastRecipe.media.size}px`;
159
159
  style["--hjm-toast-action-align"] = toastRecipe.action.align;
160
+ style["--hjm-toast-pressed-opacity"] = toastRecipe.states.pressedOpacity;
160
161
  style["--hjm-toast-progress-gap"] = `${toastRecipe.progress.gap}px`;
161
162
  style["--hjm-toast-progress-dot"] = `${toastRecipe.progress.dotSize}px`;
162
163
  style["--hjm-toast-progress-current-scale"] = String(toastRecipe.progress.currentScale);