@hjmds/react 1.30.0 → 1.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/auth-screen.d.ts +18 -3
  2. package/dist/auth-screen.d.ts.map +1 -1
  3. package/dist/auth-screen.js +22 -6
  4. package/dist/auth-screen.js.map +1 -1
  5. package/dist/bottom-navigation.d.ts +7 -0
  6. package/dist/bottom-navigation.d.ts.map +1 -1
  7. package/dist/bottom-navigation.js +64 -8
  8. package/dist/bottom-navigation.js.map +1 -1
  9. package/dist/carousel.d.ts +29 -1
  10. package/dist/carousel.d.ts.map +1 -1
  11. package/dist/carousel.js +27 -3
  12. package/dist/carousel.js.map +1 -1
  13. package/dist/display.d.ts +8 -2
  14. package/dist/display.d.ts.map +1 -1
  15. package/dist/display.js +12 -7
  16. package/dist/display.js.map +1 -1
  17. package/dist/evidence.d.ts +1 -1
  18. package/dist/evidence.js +1 -1
  19. package/dist/evidence.js.map +1 -1
  20. package/dist/forms.d.ts.map +1 -1
  21. package/dist/forms.js +2 -1
  22. package/dist/forms.js.map +1 -1
  23. package/dist/image-choice.d.ts +5 -0
  24. package/dist/image-choice.d.ts.map +1 -1
  25. package/dist/image-choice.js +4 -3
  26. package/dist/image-choice.js.map +1 -1
  27. package/dist/index.d.ts +3 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +3 -3
  30. package/dist/index.js.map +1 -1
  31. package/dist/internal/field-error.d.ts +19 -0
  32. package/dist/internal/field-error.d.ts.map +1 -0
  33. package/dist/internal/field-error.js +19 -0
  34. package/dist/internal/field-error.js.map +1 -0
  35. package/dist/internal/initial-focus.d.ts.map +1 -1
  36. package/dist/internal/initial-focus.js +49 -7
  37. package/dist/internal/initial-focus.js.map +1 -1
  38. package/dist/internal/media-album.d.ts +49 -0
  39. package/dist/internal/media-album.d.ts.map +1 -0
  40. package/dist/internal/media-album.js +31 -0
  41. package/dist/internal/media-album.js.map +1 -0
  42. package/dist/internal/message-reactions.d.ts +28 -2
  43. package/dist/internal/message-reactions.d.ts.map +1 -1
  44. package/dist/internal/message-reactions.js +21 -5
  45. package/dist/internal/message-reactions.js.map +1 -1
  46. package/dist/layout.d.ts +19 -3
  47. package/dist/layout.d.ts.map +1 -1
  48. package/dist/layout.js +10 -3
  49. package/dist/layout.js.map +1 -1
  50. package/dist/navigation.d.ts +3 -1
  51. package/dist/navigation.d.ts.map +1 -1
  52. package/dist/navigation.js +4 -2
  53. package/dist/navigation.js.map +1 -1
  54. package/dist/number-field.d.ts.map +1 -1
  55. package/dist/number-field.js +2 -1
  56. package/dist/number-field.js.map +1 -1
  57. package/dist/overlays.d.ts +65 -0
  58. package/dist/overlays.d.ts.map +1 -1
  59. package/dist/overlays.js +36 -3
  60. package/dist/overlays.js.map +1 -1
  61. package/dist/public-exports.generated.d.ts +7 -0
  62. package/dist/public-exports.generated.d.ts.map +1 -1
  63. package/dist/public-exports.generated.js +21 -0
  64. package/dist/public-exports.generated.js.map +1 -1
  65. package/dist/screen-flows.d.ts +104 -12
  66. package/dist/screen-flows.d.ts.map +1 -1
  67. package/dist/screen-flows.js +87 -18
  68. package/dist/screen-flows.js.map +1 -1
  69. package/dist/screens.d.ts +59 -8
  70. package/dist/screens.d.ts.map +1 -1
  71. package/dist/screens.js +57 -15
  72. package/dist/screens.js.map +1 -1
  73. package/dist/select.d.ts.map +1 -1
  74. package/dist/select.js +2 -1
  75. package/dist/select.js.map +1 -1
  76. package/dist/selection.d.ts.map +1 -1
  77. package/dist/selection.js +3 -2
  78. package/dist/selection.js.map +1 -1
  79. package/dist/steps.d.ts +11 -1
  80. package/dist/steps.d.ts.map +1 -1
  81. package/dist/steps.js +11 -6
  82. package/dist/steps.js.map +1 -1
  83. package/dist/styles.css +139 -20
  84. package/dist/styles.layered.css +139 -20
  85. package/dist/supplemental-display.d.ts.map +1 -1
  86. package/dist/supplemental-display.js +2 -48
  87. package/dist/supplemental-display.js.map +1 -1
  88. package/dist/theme.d.ts.map +1 -1
  89. package/dist/theme.js +1 -0
  90. package/dist/theme.js.map +1 -1
  91. package/package.json +3 -3
@@ -373,7 +373,7 @@
373
373
  the support text fades, so a custom Field control dims without needing a class. A component
374
374
  recipe value (Select, NumberField, OtpField, SearchField, PasswordField) arrives as an
375
375
  inline --hjm-field-disabled-opacity on the root. */
376
- .hjm-field[data-state="disabled"] > :not(.hjm-field__description):not(.hjm-field__error) { opacity: var(--hjm-field-disabled-opacity); }
376
+ .hjm-field[data-state="disabled"] > :not(.hjm-field__description):not(.hjm-field__error):not([data-hjm-field-error]) { opacity: var(--hjm-field-disabled-opacity); }
377
377
  .hjm-field__input {
378
378
  inline-size: 100%;
379
379
  min-inline-size: 0;
@@ -601,6 +601,18 @@
601
601
  inset-block-start: 50%;
602
602
  translate: -50% -50%;
603
603
  }
604
+ /* Prominent center destination: bottomNavigationRecipe.prominentDestination, lifted so its label stays on the
605
+ other labels' line. The circle keeps brand fill in both states; the label carries selection. */
606
+ .hjm-bottom-navigation li[data-prominent="true"] .hjm-bottom-navigation__indicator {
607
+ inline-size: var(--hjm-bottom-navigation-prominent-diameter);
608
+ block-size: var(--hjm-bottom-navigation-prominent-diameter);
609
+ margin-block-start: calc(-1 * var(--hjm-bottom-navigation-prominent-lift));
610
+ border-radius: var(--hjm-radius-full);
611
+ color: var(--hjm-color-on-primary);
612
+ background: var(--hjm-color-primary);
613
+ box-shadow: var(--hjm-shadow-floating);
614
+ }
615
+ .hjm-bottom-navigation li[data-prominent="true"] .hjm-bottom-navigation__indicator > :first-child { transform: none; }
604
616
 
605
617
  .hjm-number-field__control {
606
618
  padding-inline: 0;
@@ -1720,6 +1732,22 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1720
1732
  AuthScreenLayout safeAreaBottom (2026-10-17 1.28 adoption: products wrapped the layout in their own inset). */
1721
1733
  padding-block-end: max(var(--hjm-auth-screen-padding-block), env(safe-area-inset-bottom, 0px));
1722
1734
  }
1735
+ /* With title/exit the layout owns the ScreenLayout centered header band: full-bleed over the inline padding, at the
1736
+ shared screen gutter, with the former top padding moved below it (2026-10-18: products kept a TopBar above). */
1737
+ .hjm-auth-screen[data-header] { padding-block-start: 0; }
1738
+ .hjm-auth-screen__header {
1739
+ display: grid;
1740
+ grid-template-columns: 1fr minmax(0, auto) 1fr;
1741
+ align-items: center;
1742
+ box-sizing: border-box;
1743
+ min-block-size: var(--hjm-auth-screen-header-min-height);
1744
+ margin-inline: calc(var(--hjm-auth-screen-padding-inline) * -1);
1745
+ margin-block-end: var(--hjm-auth-screen-padding-block);
1746
+ padding-inline: var(--hjm-auth-screen-header-padding-inline);
1747
+ padding-block: var(--hjm-auth-screen-header-padding-block);
1748
+ }
1749
+ .hjm-auth-screen__header-title { min-inline-size: 0; text-align: center; overflow-wrap: anywhere; }
1750
+ .hjm-auth-screen__header-title > * { margin: 0; }
1723
1751
  .hjm-auth-screen__block {
1724
1752
  display: flex;
1725
1753
  flex: 1;
@@ -1771,17 +1799,18 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1771
1799
  flex-wrap: wrap;
1772
1800
  justify-content: center;
1773
1801
  align-items: center;
1774
- column-gap: var(--hjm-auth-screen-link-gap);
1775
1802
  }
1776
- /* 2026-10-17 "간격 줄여": 보이는 간격은 gap + 구분점뿐이다. 44 터치 높이는 배경 없는 min-block-size,
1777
- 가로 터치 폭은 보이지 않는 가상 요소가 구분점 앞까지 넓힌다 — 버튼 안쪽 여백으로 만들면 글자 사이가 다시 벌어진다. */
1803
+ /* 2026-10-17 "간격 줄여": 보이는 간격은 linkGap + 구분점뿐이다. 44 터치 높이는 배경 없는 min-block-size다.
1804
+ 2026-10-18 링크 사이 간격을 flex column-gap에서 링크의 inline 여백으로 옮겼다. 보이는 간격은 같고(column-gap 0),
1805
+ 가로 터치 폭이 그 여백만큼 링크 상자 안에 든다. 예전 가상 요소는 상자 밖으로 linkGap만큼 뻗어, 긴 링크가 푸터 폭을
1806
+ 다 쓰면 푸터의 스크롤 폭을 넓혔다(웹 scenario-matrix auth-screen long-copy 288 > 282). 여백을 gap과 함께 두면
1807
+ 글자 사이가 두 배로 벌어지므로 gap은 두지 않는다. */
1778
1808
  .hjm-auth-screen__link {
1779
- position: relative;
1780
1809
  display: inline-flex;
1781
1810
  align-items: center;
1782
1811
  min-block-size: var(--hjm-auth-screen-link-target);
1783
1812
  margin: 0;
1784
- padding: 0;
1813
+ padding: 0 var(--hjm-auth-screen-link-gap);
1785
1814
  border: 0;
1786
1815
  background: none;
1787
1816
  font-family: var(--hjm-font-family-ui, inherit);
@@ -1789,12 +1818,6 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
1789
1818
  text-underline-offset: 0.18em;
1790
1819
  cursor: pointer;
1791
1820
  }
1792
- .hjm-auth-screen__link::after {
1793
- content: "";
1794
- position: absolute;
1795
- inset-block: 0;
1796
- inset-inline: calc(var(--hjm-auth-screen-link-gap) * -1);
1797
- }
1798
1821
  .hjm-auth-screen__link:focus-visible {
1799
1822
  outline: var(--hjm-focus-width) solid var(--hjm-color-focus);
1800
1823
  outline-offset: var(--hjm-focus-offset);
@@ -2192,6 +2215,46 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2192
2215
  background: var(--hjm-backdrop-modal);
2193
2216
  overscroll-behavior: contain;
2194
2217
  }
2218
+ /* Dialog overlayLayer: viewport-sized, decorative, above the card (later sibling) and never a pointer target. */
2219
+ .hjm-dialog__overlay-layer {
2220
+ position: absolute;
2221
+ inset: 0;
2222
+ pointer-events: none;
2223
+ }
2224
+ /* ImmersiveOverlay: an edge-to-edge stage and control bar with no scrim, card or gutter. */
2225
+ .hjm-overlay.hjm-immersive-positioner {
2226
+ align-items: stretch;
2227
+ padding: 0;
2228
+ background: var(--hjm-immersive-background);
2229
+ }
2230
+ .hjm-immersive {
2231
+ display: flex;
2232
+ flex-direction: column;
2233
+ inline-size: 100%;
2234
+ block-size: 100%;
2235
+ color: var(--hjm-color-text);
2236
+ background: var(--hjm-immersive-background);
2237
+ outline: none;
2238
+ }
2239
+ .hjm-immersive__stage {
2240
+ position: relative;
2241
+ flex: 1 1 auto;
2242
+ min-block-size: 0;
2243
+ overflow: hidden;
2244
+ }
2245
+ .hjm-immersive__controls {
2246
+ display: flex;
2247
+ flex-direction: column;
2248
+ gap: var(--hjm-immersive-gap);
2249
+ padding: var(--hjm-immersive-padding);
2250
+ padding-inline: max(var(--hjm-immersive-padding), env(safe-area-inset-left)) max(var(--hjm-immersive-padding), env(safe-area-inset-right));
2251
+ padding-block-end: max(var(--hjm-immersive-padding), env(safe-area-inset-bottom));
2252
+ }
2253
+ .hjm-immersive__actions {
2254
+ display: flex;
2255
+ align-items: center;
2256
+ gap: var(--hjm-immersive-action-gap);
2257
+ }
2195
2258
  .hjm-dialog,
2196
2259
  .hjm-alert-dialog,
2197
2260
  .hjm-sheet {
@@ -2208,6 +2271,8 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2208
2271
  .hjm-dialog { inline-size: min(36rem, 100%); }
2209
2272
  .hjm-dialog[data-size="small"] { inline-size: min(28rem, 100%); }
2210
2273
  .hjm-dialog[data-size="large"] { inline-size: min(48rem, 100%); }
2274
+ /* Dialog scrollEnabled={false}: the card keeps its scroll offset while a gesture in the body owns the pointer. */
2275
+ .hjm-dialog[data-scroll="locked"] { overflow: hidden; overscroll-behavior: contain; touch-action: none; }
2211
2276
  .hjm-alert-dialog[data-size="small"] { inline-size: min(28rem, 100%); }
2212
2277
  .hjm-alert-dialog[data-size="large"] { inline-size: min(48rem, 100%); }
2213
2278
  .hjm-dialog__header,
@@ -2749,6 +2814,9 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2749
2814
  .hjm-steps__step[data-status="pending"] .hjm-steps__label { color: var(--hjm-color-text-muted); }
2750
2815
  .hjm-steps__step[data-status="error"] .hjm-steps__label { color: var(--hjm-color-danger); }
2751
2816
  .hjm-steps__description { color: var(--hjm-color-text-muted); font-size: var(--hjm-type-caption-size); overflow-wrap: anywhere; }
2817
+ /* A step before the cursor is one button over marker and label (Steps onStepPress); the cell keeps its static layout. */
2818
+ .hjm-steps__press { display: grid; align-content: start; gap: var(--hjm-space-xs); min-inline-size: 0; min-block-size: var(--hjm-steps-press-target); margin: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: start; cursor: pointer; }
2819
+ .hjm-steps__press:focus-visible { outline: var(--hjm-focus-width) solid var(--hjm-color-focus); outline-offset: var(--hjm-focus-offset); }
2752
2820
 
2753
2821
  .hjm-file-picker { display: grid; gap: var(--hjm-space-xs); }
2754
2822
  .hjm-file-picker__label { color: var(--hjm-color-text); font-weight: var(--hjm-text-emphasis-medium); }
@@ -2935,10 +3003,12 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
2935
3003
  .hjm-carousel__rotation { justify-self: start; }
2936
3004
  .hjm-carousel__controls, .hjm-carousel__dots { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: var(--hjm-space-xs); }
2937
3005
  .hjm-carousel__controls { flex-wrap: nowrap; } .hjm-carousel__dots { flex-shrink: 1; min-inline-size: 0; }
2938
- .hjm-carousel__dot { display: grid; place-items: center; min-inline-size: var(--hjm-control-min-touch-target); min-block-size: var(--hjm-control-min-touch-target); border: 0; border-radius: var(--hjm-radius-full); background: transparent; cursor: pointer; }
2939
- .hjm-carousel__dot > span { inline-size: var(--hjm-space-xs); block-size: var(--hjm-space-xs); border-radius: var(--hjm-radius-full); background: var(--hjm-color-text-weak); } /* carouselRecipe.dot.color.inactive (border.strong), as Native */
2940
- .hjm-carousel__dot[data-current="true"] > span { background: var(--hjm-color-content-brand); }
2941
- .hjm-carousel__dot:focus-visible { outline: 2px solid var(--hjm-color-content-brand); outline-offset: 2px; }
3006
+ /* PageIndicator is the same dot row for a product-owned pager (carouselRecipe.dot). */
3007
+ .hjm-page-indicator { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: var(--hjm-space-xs); min-inline-size: 0; }
3008
+ .hjm-carousel__dot, .hjm-page-indicator__dot { display: grid; place-items: center; min-inline-size: var(--hjm-control-min-touch-target); min-block-size: var(--hjm-control-min-touch-target); border: 0; border-radius: var(--hjm-radius-full); background: transparent; cursor: pointer; }
3009
+ .hjm-carousel__dot > span, .hjm-page-indicator__dot > span { inline-size: var(--hjm-space-xs); block-size: var(--hjm-space-xs); border-radius: var(--hjm-radius-full); background: var(--hjm-color-text-weak); } /* carouselRecipe.dot.color.inactive (border.strong), as Native */
3010
+ .hjm-carousel__dot[data-current="true"] > span, .hjm-page-indicator__dot[data-current="true"] > span { background: var(--hjm-color-content-brand); }
3011
+ .hjm-carousel__dot:focus-visible, .hjm-page-indicator__dot:focus-visible { outline: 2px solid var(--hjm-color-content-brand); outline-offset: 2px; }
2942
3012
 
2943
3013
  /* The viewport action follows the content in DOM order. Its measured clearance
2944
3014
  belongs on the scroll content, not on the fixed button (docs/floating-action-button.md). */
@@ -3114,6 +3184,16 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3114
3184
  .hjm-tabs:is([data-appearance="gooey"], [data-appearance="slide"]) .hjm-tabs__list { position: relative; }
3115
3185
  .hjm-tabs:is([data-appearance="gooey"], [data-appearance="slide"]) .hjm-tabs__tab[data-state="selected"]::after { display: none; }
3116
3186
  .hjm-tabs__indicator { position: absolute; bottom: 0; height: 2px; border-radius: var(--hjm-radius-full); background: var(--hjm-color-content-brand); pointer-events: none; }
3187
+ /* indicator="filled" (tabsRecipe.indicators.filled): a surface-accent pill behind the selected tab, no list divider.
3188
+ The moving pill spans the tab height and sits under the labels. */
3189
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__list { border: 0; }
3190
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__tab { border-radius: var(--hjm-radius-full); }
3191
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__tab[data-state="selected"] { color: var(--hjm-color-content-brand); }
3192
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__tab[data-state="selected"]::after { display: none; }
3193
+ .hjm-tabs[data-indicator="filled"]:not([data-indicator-motion="moving"]) .hjm-tabs__tab[data-state="selected"] { background: var(--hjm-color-surface-accent); }
3194
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__indicator { top: 0; bottom: 0; height: auto; border-radius: var(--hjm-radius-full); background: var(--hjm-color-surface-accent); z-index: 0; }
3195
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__list { position: relative; }
3196
+ .hjm-tabs[data-indicator="filled"] .hjm-tabs__tab { z-index: 1; }
3117
3197
  .hjm-tabs__gooey { height: 6px; }
3118
3198
 
3119
3199
  /* Capsule destinations retain route/link semantics. At larger text sizes we show
@@ -3168,6 +3248,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3168
3248
  .hjm-screen__header { display: flex; flex-wrap: wrap; align-items: center; gap: var(--hjm-screen-item-gap, var(--hjm-space-sm)); padding: var(--hjm-screen-padding); flex: 0 0 auto; }
3169
3249
  .hjm-screen__heading { flex: 1 1 calc(var(--hjm-screen-header-min) * var(--hjm-text-scale, 1)); min-inline-size: 0; overflow-wrap: anywhere; }
3170
3250
  .hjm-screen__heading > * { margin: 0; }
3251
+ .hjm-screen__title-leading { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; }
3171
3252
  .hjm-screen__notice { padding-inline: var(--hjm-screen-padding); flex: 0 0 auto; }
3172
3253
  /* --hjm-screen-body-inline is the body's inline padding and the distance a bleeding CollectionRail crosses (Native
3173
3254
  ScreenBodyInsetContext); inset variants change this one value instead of the padding itself. */
@@ -3176,7 +3257,7 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3176
3257
  (review S5#9: body 16 + row 16 put DM avatars ~32 from the edge). "none" keeps its host-owns-all meaning. */
3177
3258
  .hjm-screen[data-content-inset="body-edge"] > .hjm-screen__body { --hjm-screen-body-inline: 0px; }
3178
3259
  /* Overlay content is not in the screen body, even when rendered inside it: a bleeding rail there stays in its box. */
3179
- .hjm-sheet, .hjm-dialog, .hjm-alert-dialog, .hjm-popover { --hjm-screen-body-inline: 0px; }
3260
+ .hjm-sheet, .hjm-dialog, .hjm-alert-dialog, .hjm-popover { --hjm-screen-body-inline: 0px; --hjm-bottom-navigation-inset: 0px; }
3180
3261
  /* contentInset="none" hands every inset to the host: no footer rule, as on Native (BottomCTA then draws its own bar). */
3181
3262
  .hjm-screen[data-content-inset="none"] > .hjm-screen__footer { border-block-start: 0; }
3182
3263
  .hjm-screen__body[data-scroll="screen"] { overflow-y: auto; }
@@ -3185,7 +3266,10 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3185
3266
  .hjm-screen__centered-content { margin-block: auto; flex-shrink: 0; inline-size: 100%; }
3186
3267
  .hjm-screen__body[data-replacement="true"] { display: flex; flex-direction: column; }
3187
3268
  .hjm-screen__state { margin-block: auto; flex-shrink: 0; display: flex; flex-direction: column; align-items: center; gap: var(--hjm-screen-state-gap, var(--hjm-space-md)); padding-block: var(--hjm-screen-gap); text-align: center; }
3188
- .hjm-screen__footer { flex: 0 0 auto; padding: var(--hjm-screen-padding); padding-block-end: max(var(--hjm-screen-padding), env(safe-area-inset-bottom)); border-block-start: 1px solid var(--hjm-color-border); }
3269
+ .hjm-screen__footer { flex: 0 0 auto; padding: var(--hjm-screen-padding); padding-block-end: max(var(--hjm-screen-padding), env(safe-area-inset-bottom), calc(var(--hjm-screen-padding) + var(--hjm-bottom-navigation-inset, 0px))); border-block-start: 1px solid var(--hjm-color-border); }
3270
+ /* --hjm-bottom-navigation-inset (BottomNavigationInsetProvider) is the viewport bottom the fixed bar covers. The last
3271
+ region keeps its gutter above the bar; without a provider the value is 0 and the padding is unchanged. */
3272
+ .hjm-screen__body:last-child { padding-block-end: calc(var(--hjm-screen-padding) + var(--hjm-bottom-navigation-inset, 0px)); }
3189
3273
  /* SearchScreen filtersOverflow=scroll; why: screen-flows.tsx. Block padding keeps focus rings unclipped.
3190
3274
  --hjm-search-filters-bleed = screen padding + hostGutter (1.13.1), set inline by SearchScreen. */
3191
3275
  .hjm-search-screen__filters { --f: calc(var(--hjm-focus-width) + var(--hjm-focus-offset)); --b: var(--hjm-search-filters-bleed, var(--hjm-screen-padding)); overflow-x: auto; margin: calc(-1 * var(--f)) calc(-1 * var(--b)); padding: var(--f) var(--b); scroll-padding-inline: var(--b); scrollbar-width: none; }
@@ -3233,6 +3317,17 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3233
3317
  [dir="rtl"] .hjm-chat-message[data-tail] .hjm-chat-message__bubble::before { transform: scaleX(-1); }
3234
3318
 
3235
3319
  .hjm-chat-message__meta { display: flex; flex-shrink: 0; align-items: center; gap: var(--hjm-space-xs); }
3320
+ /* Reaction summary pill (sizes inline from chatMessageRecipe.reactionSummary); own reaction shows the brand border. */
3321
+ .hjm-chat-message__reaction-summary { display: inline-flex; align-items: center; box-sizing: border-box; border: 1px solid var(--hjm-color-border); border-radius: var(--hjm-radius-full); background: var(--hjm-color-surface); color: var(--hjm-color-text); font: inherit; line-height: 1; cursor: pointer; }
3322
+ .hjm-chat-message__reaction-summary[data-selected] { border-color: var(--hjm-color-content-brand); }
3323
+ .hjm-chat-message__reaction-summary:hover:not(:disabled) { background: var(--hjm-color-surface-alt); }
3324
+ .hjm-chat-message__reaction-summary:focus-visible { outline: 2px solid var(--hjm-color-focus, currentColor); outline-offset: 2px; }
3325
+ .hjm-chat-message__reaction-summary:disabled { opacity: 0.5; cursor: default; }
3326
+ /* Typing dots (typingIndicatorRecipe via custom properties): staggered pulse, static under reduced motion. */
3327
+ .hjm-typing-indicator__dot { inline-size: var(--hjm-typing-dot); block-size: var(--hjm-typing-dot); border-radius: 50%; background: var(--hjm-color-text-muted); animation: hjm-typing-pulse var(--hjm-typing-cycle) ease-in-out infinite both; }
3328
+ .hjm-typing-indicator[data-reduced-motion] .hjm-typing-indicator__dot { animation: none; }
3329
+ @media (prefers-reduced-motion: reduce) { .hjm-typing-indicator__dot { animation: none; } }
3330
+ @keyframes hjm-typing-pulse { 0%, 100% { opacity: var(--hjm-typing-rest); } 50% { opacity: 1; } }
3236
3331
  /* A quoted reply heads the bubble and is divided from the answer. */
3237
3332
  .hjm-chat-message__reply { border-block-end: 1px solid var(--hjm-color-border); padding-block-end: var(--hjm-space-xs); margin-block-end: var(--hjm-space-xs); display: flex; flex-direction: column; gap: 2px; min-inline-size: 0; }
3238
3333
  .hjm-chat-message__quote { inline-size: 100%; border-inline: 0; border-block-start: 0; background: none; padding-inline: 0; padding-block-start: 0; color: inherit; font: inherit; text-align: start; cursor: pointer; }
@@ -3243,6 +3338,13 @@ button.hjm-list-row, a.hjm-list-row { cursor: pointer; }
3243
3338
  .hjm-chat-message__media-item > img { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
3244
3339
  button.hjm-chat-message__media-item { cursor: pointer; }
3245
3340
  button.hjm-chat-message__media-item:focus-visible { outline: 2px solid var(--hjm-color-focus, currentColor); outline-offset: -2px; }
3341
+ /* Paged media album (2026-10-18, mediaAlbumRecipe): one mounted page in the host's media width, counter row below. */
3342
+ .hjm-media-album { display: flex; flex-direction: column; max-inline-size: 100%; }
3343
+ .hjm-media-album__page { display: block; inline-size: 100%; overflow: hidden; padding: 0; border: 0; background: var(--hjm-color-surface-alt); }
3344
+ .hjm-media-album__page > img { display: block; inline-size: 100%; block-size: 100%; object-fit: cover; }
3345
+ button.hjm-media-album__page { cursor: pointer; }
3346
+ button.hjm-media-album__page:focus-visible { outline: 2px solid var(--hjm-color-focus, currentColor); outline-offset: -2px; }
3347
+ .hjm-media-album__controls { display: flex; align-items: center; justify-content: space-between; }
3246
3348
  .hjm-chat-message__bubble[data-photo-only] { background: none; padding: 0; }
3247
3349
  .hjm-chat-message__bubble[data-photo-only]::before { display: none; }
3248
3350
  /* Only the shared default gutter narrows to the timeline gutter; "none" and "body-edge" keep their own meaning. */
@@ -3255,8 +3357,12 @@ button.hjm-chat-message__media-item:focus-visible { outline: 2px solid var(--hjm
3255
3357
  .hjm-image-choice { display: flex; flex-direction: column; gap: var(--hjm-space-xs); }
3256
3358
  .hjm-image-choice__label { font-weight: var(--hjm-text-emphasis-medium); }
3257
3359
  .hjm-image-choice__tiles { display: flex; flex-wrap: wrap; gap: var(--hjm-image-choice-gap); }
3258
- .hjm-image-choice__tile { position: relative; inline-size: calc(var(--hjm-image-choice-size) + (var(--hjm-image-choice-ring) + var(--hjm-image-choice-offset)) * 2); aspect-ratio: 1; padding: var(--hjm-image-choice-offset); border: var(--hjm-image-choice-ring) solid transparent; border-radius: calc(var(--hjm-image-choice-radius) + var(--hjm-image-choice-ring) + var(--hjm-image-choice-offset)); background: none; cursor: pointer; }
3259
- .hjm-image-choice__tile[data-selected] { border-color: var(--hjm-color-content-brand); }
3360
+ /* The button is a column (ring frame, optional item label) so the label shares the tap target; the ring is drawn on
3361
+ the inner frame (2026-10-18 showItemLabels). */
3362
+ .hjm-image-choice__tile { display: flex; flex-direction: column; gap: var(--hjm-image-choice-item-label-gap); inline-size: calc(var(--hjm-image-choice-size) + (var(--hjm-image-choice-ring) + var(--hjm-image-choice-offset)) * 2); padding: 0; border: 0; border-radius: calc(var(--hjm-image-choice-radius) + var(--hjm-image-choice-ring) + var(--hjm-image-choice-offset)); background: none; color: inherit; cursor: pointer; }
3363
+ .hjm-image-choice__ring { position: relative; display: block; inline-size: 100%; aspect-ratio: 1; padding: var(--hjm-image-choice-offset); border: var(--hjm-image-choice-ring) solid transparent; border-radius: inherit; }
3364
+ .hjm-image-choice__tile[data-selected] .hjm-image-choice__ring { border-color: var(--hjm-color-content-brand); }
3365
+ .hjm-image-choice__item-label { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: center; }
3260
3366
  .hjm-image-choice__tile:focus-visible { outline: 2px solid var(--hjm-color-focus, currentColor); outline-offset: 2px; }
3261
3367
  .hjm-image-choice__tile:disabled { opacity: 0.5; cursor: default; }
3262
3368
  .hjm-image-choice__image { display: block; inline-size: 100%; block-size: 100%; overflow: hidden; border-radius: var(--hjm-image-choice-radius); background: var(--hjm-color-surface); }
@@ -3304,6 +3410,8 @@ button.hjm-chat-message__media-item:focus-visible { outline: 2px solid var(--hjm
3304
3410
  .hjm-comment-row__reactions:focus-visible { outline: 2px solid var(--hjm-color-focus, currentColor); outline-offset: 2px; }
3305
3411
  .hjm-comment-row__media { align-self: flex-start; overflow: hidden; margin-block-start: 4px; }
3306
3412
  .hjm-comment-row__media > img { display: block; inline-size: 100%; block-size: auto; }
3413
+ .hjm-comment-row__album { align-self: flex-start; margin-block-start: 4px; }
3414
+ .hjm-comment-row__panel { min-inline-size: 0; }
3307
3415
  /* commentThreadRecipe.actionAnchor (2026-10-17 measured audit): the 44 targets centre on the identity's first line
3308
3416
  (--hjm-comment-anchor-line, set per row), so like/more glyphs share the author line's centre instead of sitting
3309
3417
  12px below it. When HJM's own like/more is the last control (data-edge), the whole column takes the IconButton edge
@@ -3417,6 +3525,17 @@ button.hjm-chat-message__media-item:focus-visible { outline: 2px solid var(--hjm
3417
3525
  .hjm-card[data-interactive="true"] { font: inherit; color: inherit; text-align: inherit; cursor: pointer; min-inline-size: var(--hjm-control-min-touch-target); min-block-size: var(--hjm-control-min-touch-target); }
3418
3526
  .hjm-card[data-interactive="true"]:active:not(:disabled) { opacity: var(--hjm-card-pressed-opacity); }
3419
3527
  .hjm-card[data-interactive="true"]:disabled { opacity: var(--hjm-card-disabled-opacity); cursor: default; }
3528
+ /* Whole-card activation beside actions: the article keeps its semantics, a transparent button covers it, and only the
3529
+ action controls rise above that button, so the gaps around them still open the card. */
3530
+ .hjm-card[data-activation="overlay"] { position: relative; }
3531
+ .hjm-card__activator { position: absolute; inset: 0; z-index: 0; margin: 0; padding: 0; border: 0; border-radius: inherit; background: transparent; cursor: pointer; }
3532
+ .hjm-card__activator:disabled { cursor: default; }
3533
+ .hjm-card[data-activation="overlay"] > .hjm-card__actions { position: relative; z-index: 1; pointer-events: none; }
3534
+ .hjm-card[data-activation="overlay"] > .hjm-card__actions > * { pointer-events: auto; }
3535
+ /* Press/disabled feedback belongs to the card target (media and body); action controls keep their own states. */
3536
+ .hjm-card[data-activation="overlay"]:has(> .hjm-card__activator:active:not(:disabled)) > :is(.hjm-card__media, .hjm-card__body) { opacity: var(--hjm-card-pressed-opacity); }
3537
+ .hjm-card[data-activation="overlay"]:has(> .hjm-card__activator:disabled) > :is(.hjm-card__media, .hjm-card__body) { opacity: var(--hjm-card-disabled-opacity); }
3538
+ .hjm-card[data-activation="overlay"]:has(> .hjm-card__activator:focus-visible) { outline: var(--hjm-focus-width) solid var(--hjm-color-focus); outline-offset: var(--hjm-focus-offset); }
3420
3539
 
3421
3540
  /* Full destination cards keep all names and widths stable; colors remain product semantic roles. */
3422
3541
  .hjm-bottom-navigation[data-selection="tile"] .hjm-bottom-navigation__surface { background: var(--hjm-color-surface-accent); }
@@ -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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"}
@@ -1,56 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { getIconTransform, resolveIconDescriptor, } from "@hjmds/design-contracts/components/icon";
2
+ import { getIconTransform, resolveIconDescriptor, semanticIconPaths, } 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
5
  import { forwardRef, useState, useMemo, useRef, useLayoutEffect, } from "react";
6
6
  import { classNames } from "./internal.js";
7
7
  import { useOptionalHjmTheme } from "./provider.js";
8
- /** Internal, dependency-free semantic glyph registry. All marks share one 24px stroke grid. */
9
- const iconPaths = {
10
- add: "M12 5v14M5 12h14",
11
- 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",
12
- alert: "M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01",
13
- back: "M15 18 9 12l6-6M9 12h10",
14
- 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",
15
- check: "m5 12 4 4L19 6",
16
- chevronDown: "m6 9 6 6 6-6",
17
- chevronEnd: "m9 6 6 6-6 6",
18
- chevronStart: "m15 6-6 6 6 6",
19
- chevronUp: "m6 15 6-6 6 6",
20
- close: "M6 6l12 12M18 6 6 18",
21
- compare: "M8 7h11m0 0-3-3m3 3-3 3M16 17H5m0 0 3-3m-3 3 3 3",
22
- 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",
23
- delete: "M4 7h16M9 7V4h6v3m3 0-1 14H7L6 7m4 4v6m4-6v6",
24
- download: "M12 3v12m0 0 5-5m-5 5-5-5M4 19v2h16v-2",
25
- edit: "m4 16-1 5 5-1L19 9l-4-4L4 16Zm9-9 4 4",
26
- error: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-14v5m0 3h.01",
27
- 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",
28
- filter: "M3 5h18l-7 8v6l-4 2v-8L3 5Z",
29
- forward: "m9 6 6 6-6 6m6-6H5",
30
- 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",
31
- home: "m3 11 9-8 9 8v10h-6v-6H9v6H3V11Z",
32
- info: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm0-11v6m0-10h.01",
33
- lock: "M6 10h12v11H6V10Zm3 0V7a3 3 0 0 1 6 0v3",
34
- menu: "M4 6h16M4 12h16M4 18h16",
35
- more: "M5 12h.01M12 12h.01M19 12h.01",
36
- notifications: "M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9Zm-8 12h4",
37
- pause: "M8 5v14m8-14v14",
38
- play: "m8 5 11 7-11 7V5Z",
39
- 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",
40
- search: "m21 21-4.4-4.4M19 11a8 8 0 1 1-16 0 8 8 0 0 1 16 0Z",
41
- 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",
42
- 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",
43
- success: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20Zm-5-10 3 3 7-7",
44
- trendDown: "M3 7l7 7 4-4 7 7m0 0v-6m0 6h-6",
45
- trendFlat: "M4 12h16m0 0-4-4m4 4-4 4",
46
- trendUp: "M3 17l7-7 4 4 7-7m0 0v6m0-6h-6",
47
- upload: "M12 21V9m0 0-5 5m5-5 5 5M4 5V3h16v2",
48
- user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm-8 9a8 8 0 0 1 16 0",
49
- 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",
50
- 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",
51
- 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",
52
- warning: "M12 3 2.7 20h18.6L12 3Zm0 6v4m0 3h.01",
53
- };
54
8
  export const Icon = forwardRef(function Icon({ name, size, tone, weight, directionality, decorative, accessibilityLabel, renderGlyph, className, style, layoutStyle, ...props }, ref) {
55
9
  const descriptor = resolveIconDescriptor({
56
10
  name,
@@ -64,7 +18,7 @@ export const Icon = forwardRef(function Icon({ name, size, tone, weight, directi
64
18
  const theme = useOptionalHjmTheme();
65
19
  const transform = getIconTransform(descriptor.directionality, theme?.environment.direction ?? "ltr");
66
20
  const dimension = iconRecipe.sizes[descriptor.size];
67
- return (_jsx("svg", { ...props, ref: ref, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: classNames("hjm-icon", className), "data-name": descriptor.name, "data-size": descriptor.size, "data-tone": descriptor.tone, "data-weight": descriptor.weight, "data-transform": transform, width: dimension, height: dimension, stroke: "currentColor", strokeWidth: iconRecipe.weights[descriptor.weight], strokeLinecap: "round", strokeLinejoin: "round", role: descriptor.decorative ? undefined : "img", "aria-hidden": descriptor.decorative || undefined, "aria-label": descriptor.decorative ? undefined : descriptor.accessibilityLabel, focusable: "false", style: { ...style, ...layoutStyle }, children: renderGlyph?.({ name: descriptor.name, size: 24, color: "currentColor", strokeWidth: iconRecipe.weights[descriptor.weight] }) ?? _jsx("path", { d: iconPaths[descriptor.name] }) }));
21
+ return (_jsx("svg", { ...props, ref: ref, viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", className: classNames("hjm-icon", className), "data-name": descriptor.name, "data-size": descriptor.size, "data-tone": descriptor.tone, "data-weight": descriptor.weight, "data-transform": transform, width: dimension, height: dimension, stroke: "currentColor", strokeWidth: iconRecipe.weights[descriptor.weight], strokeLinecap: "round", strokeLinejoin: "round", role: descriptor.decorative ? undefined : "img", "aria-hidden": descriptor.decorative || undefined, "aria-label": descriptor.decorative ? undefined : descriptor.accessibilityLabel, focusable: "false", style: { ...style, ...layoutStyle }, children: renderGlyph?.({ name: descriptor.name, size: 24, color: "currentColor", strokeWidth: iconRecipe.weights[descriptor.weight] }) ?? _jsx("path", { d: semanticIconPaths[descriptor.name] }) }));
68
22
  });
69
23
  /** Intrinsic-size image with canonical alt semantics and an accessible fallback. */
70
24
  export const Image = forwardRef(function Image({ src, width, height, fit, decorative, accessibilityLabel, imageProps, renderImage, fallback, imageRef, onLoad, onError, onLoadStatusChange, className, style, layoutStyle, ...props }, ref) {
@@ -1 +1 @@
1
- {"version":3,"file":"supplemental-display.js","sourceRoot":"","sources":["../src/supplemental-display.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,gBAAgB,EAChB,qBAAqB,GAGtB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACtB,sCAAsC,GAGvC,MAAM,0CAA0C,CAAC;AAClD,OAAO,EACL,kBAAkB,EAClB,uBAAuB,EACvB,UAAU,GAIX,MAAM,iCAAiC,CAAC;AACzC,OAAO,EACL,UAAU,EACV,QAAQ,EACR,OAAO,EACP,MAAM,EACN,eAAe,GAShB,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,+FAA+F;AAC/F,MAAM,SAAS,GAAG;IAChB,GAAG,EAAE,kBAAkB;IACvB,EAAE,EAAE,iIAAiI;IACrI,KAAK,EAAE,uCAAuC;IAC9C,IAAI,EAAE,yBAAyB;IAC/B,QAAQ,EAAE,6FAA6F;IACvG,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,cAAc;IAC3B,UAAU,EAAE,cAAc;IAC1B,YAAY,EAAE,eAAe;IAC7B,SAAS,EAAE,eAAe;IAC1B,KAAK,EAAE,sBAAsB;IAC7B,OAAO,EAAE,kDAAkD;IAC3D,IAAI,EAAE,iHAAiH;IACvH,MAAM,EAAE,8CAA8C;IACtD,QAAQ,EAAE,wCAAwC;IAClD,IAAI,EAAE,uCAAuC;IAC7C,KAAK,EAAE,0DAA0D;IACjE,QAAQ,EAAE,wGAAwG;IAClH,MAAM,EAAE,6BAA6B;IACrC,OAAO,EAAE,oBAAoB;IAC7B,IAAI,EAAE,iGAAiG;IACvG,IAAI,EAAE,kCAAkC;IACxC,IAAI,EAAE,2DAA2D;IACjE,IAAI,EAAE,yCAAyC;IAC/C,IAAI,EAAE,yBAAyB;IAC/B,IAAI,EAAE,+BAA+B;IACrC,aAAa,EAAE,0DAA0D;IACzE,KAAK,EAAE,iBAAiB;IACxB,IAAI,EAAE,mBAAmB;IACzB,OAAO,EAAE,yEAAyE;IAClF,MAAM,EAAE,qDAAqD;IAC7D,QAAQ,EAAE,+PAA+P;IACzQ,KAAK,EAAE,uIAAuI;IAC9I,OAAO,EAAE,yDAAyD;IAClE,SAAS,EAAE,gCAAgC;IAC3C,SAAS,EAAE,0BAA0B;IACrC,OAAO,EAAE,gCAAgC;IACzC,MAAM,EAAE,qCAAqC;IAC7C,IAAI,EAAE,yDAAyD;IAC/D,KAAK,EAAE,8FAA8F;IACrG,UAAU,EAAE,gFAAgF;IAC5F,aAAa,EAAE,kJAAkJ;IACjK,OAAO,EAAE,uCAAuC;CACG,CAAC;AAYtD,MAAM,CAAC,MAAM,IAAI,GAAG,UAAU,CAA2B,SAAS,IAAI,CACpE,EACE,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,EACN,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,WAAW,EACX,SAAS,EACT,KAAK,EACL,WAAW,EACX,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,UAAU,GAAG,qBAAqB,CAAC;QACvC,IAAI;QACJ,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;QACvC,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;QAC3C,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC;QAC3D,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;QACnD,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC;KAClD,CAAC,CAAC;IACrB,MAAM,KAAK,GAAG,mBAAmB,EAAE,CAAC;IACpC,MAAM,SAAS,GAAG,gBAAgB,CAChC,UAAU,CAAC,cAAc,EACzB,KAAK,EAAE,WAAW,CAAC,SAAS,IAAI,KAAK,CACtC,CAAC;IACF,MAAM,SAAS,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,CACL,iBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,KAAK,EAAC,4BAA4B,EAClC,SAAS,EAAE,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,eACjC,UAAU,CAAC,IAAI,eACf,UAAU,CAAC,IAAI,eACf,UAAU,CAAC,IAAI,iBACb,UAAU,CAAC,MAAM,oBACd,SAAS,EACzB,KAAK,EAAE,SAAS,EAChB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAC,cAAc,EACrB,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAClD,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,EACtB,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,iBAClC,UAAU,CAAC,UAAU,IAAI,SAAS,gBACnC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,EAC7E,SAAS,EAAC,OAAO,EACjB,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE,YAElC,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,eAAM,CAAC,EAAE,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,GAAI,GACrK,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAsEH,oFAAoF;AACpF,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAA8B,SAAS,KAAK,CACzE,EACE,GAAG,EACH,KAAK,EACL,MAAM,EACN,GAAG,EACH,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,OAAO,EACP,kBAAkB,EAClB,SAAS,EACT,KAAK,EACL,WAAW,EACX,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,UAAU,GAAG,sBAAsB,CAAC;QACxC,GAAG;QACH,KAAK;QACL,MAAM;QACN,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC;QACrC,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC;QACnD,GAAG,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC;KACjD,CAAC,CAAC;IACtB,6EAA6E;IAC7E,oFAAoF;IACpF,8EAA8E;IAC9E,qEAAqE;IACrE,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC;IACrJ,MAAM,gBAAgB,GAAG,MAAM,CAAgB,UAAU,CAAC,CAAC;IAC3D,eAAe,CAAC,GAAG,EAAE;QACnB,gBAAgB,CAAC,OAAO,GAAG,UAAU,CAAC;QACtC,OAAO,GAAG,EAAE,GAAG,gBAAgB,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;IACjB,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAa,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAClF,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1E,MAAM,EACJ,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,UAAU,EACjB,GAAG,cAAc,EAClB,GAAG,UAAU,IAAI,EAAE,CAAC;IAErB,MAAM,UAAU,GAAwC,CAAC,KAAK,EAAE,EAAE;QAChE,IAAI,gBAAgB,CAAC,OAAO,KAAK,UAAU;YAAE,OAAO;QACpD,QAAQ,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3C,kBAAkB,EAAE,CAAC,QAAQ,CAAC,CAAC;QAC/B,MAAM,EAAE,CAAC,KAAK,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,MAAM,WAAW,GAAwC,CAAC,KAAK,EAAE,EAAE;QACjE,IAAI,gBAAgB,CAAC,OAAO,KAAK,UAAU;YAAE,OAAO;QACpD,QAAQ,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;QAC1C,kBAAkB,EAAE,CAAC,OAAO,CAAC,CAAC;QAC9B,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,YAAY,GAAsB;QACtC,GAAG,cAAc;QACjB,GAAG,EAAE,UAAU,CAAC,GAAG;QACnB,GAAG,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB;QAC/D,KAAK,EAAE,UAAU,CAAC,KAAK;QACvB,MAAM,EAAE,UAAU,CAAC,MAAM;QACzB,SAAS,EAAE,UAAU,CAAC,kBAAkB,EAAE,cAAc,CAAC;YACvD,kBAAkB;QACpB,KAAK,EAAE,EAAE,GAAG,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,EAAE;QACnD,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzD,MAAM,EAAE,UAAU;QAClB,OAAO,EAAE,WAAW;QACpB,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;KACrD,CAAC;IAEF,IAAI,MAAiB,CAAC;IACtB,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QACvB,MAAM,aAAa,GAAG,sCAAsC,CAAC,UAAU,CAAC,CAAC;QACzE,MAAM,GAAG,CACP,eACE,SAAS,EAAC,qBAAqB,EAC/B,IAAI,EAAE,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,gBACnC,aAAa,iBACZ,UAAU,CAAC,UAAU,IAAI,SAAS,YAE/C,eAAM,SAAS,EAAC,0BAA0B,iBAAa,MAAM,YAC1D,QAAQ,IAAI,CACX,KAAC,IAAI,IACH,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EACpC,IAAI,EAAE,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EACpC,UAAU,SACV,CACH,GACI,GACF,CACR,CAAC;IACJ,CAAC;SAAM,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,gBAAgB,EAAE,GAAG,YAAY,CAAC;QAC5D,MAAM,GAAG,iBAAS,gBAAgB,EAAE,GAAG,EAAE,QAAQ,GAAI,CAAC;IACxD,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;IACrC,CAAC;IAED,OAAO,CACL,kBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE,SAAS,CAAC,cACnC,UAAU,CAAC,GAAG,iBACX,MAAM,EACnB,KAAK,EAAE;YACL,UAAU,EAAE,UAAU,CAAC,KAAK;YAC5B,GAAG,KAAK;YACR,GAAG,WAAW;YACd,WAAW,EAAE,uBAAuB,CAClC,UAAU,CAAC,KAAK,EAChB,UAAU,CAAC,MAAM,CAClB;SACF,YAEA,MAAM,GACF,CACR,CAAC;AACJ,CAAC,CAAC,CAAC;AAoBH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CACpC,SAAS,YAAY,CACnB,EACE,KAAK,EACL,GAAG,GAAG,kBAAkB,CAAC,QAAQ,CAAC,GAAG,EACrC,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EACvC,IAAI,GAAG,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EACvC,OAAO,GAAG,kBAAkB,CAAC,QAAQ,CAAC,OAAO,EAC7C,GAAG,GAAG,KAAK,EACX,kBAAkB,EAClB,SAAS,EACT,WAAW,EACX,KAAK,EACL,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,KAAK,GAAG,uBAAuB,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAClD,IAAI,kBAAkB,KAAK,SAAS,IAAI,kBAAkB,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/E,MAAM,IAAI,SAAS,CAAC,mDAAmD,CAAC,CAAC;IAC3E,CAAC;IACD,IAAI,GAAG,IAAI,kBAAkB,KAAK,SAAS,EAAE,CAAC;QAC5C,2DAA2D;QAC3D,MAAM,IAAI,SAAS,CAAC,iDAAiD,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,OAAO,CACL,kBACM,KAAK,EACT,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,UAAU,CAAC,mBAAmB,EAAE,SAAS,CAAC,eAC1C,IAAI,eACJ,IAAI,kBACD,OAAO,cACX,GAAG,IAAI,SAAS,EAC1B,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE,wBAAwB,EAAE,GAAG,kBAAkB,CAAC,OAAO,IAAI,EAAkB,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,WAAW,EAAE,iBACxI,kBAAkB,KAAK,SAAS,IAAI,SAAS;QAC1D,8EAA8E;QAC9E,IAAI,EAAE,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,gBAC9C,kBAAkB,YAE7B,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GACd,CACR,CAAC;AACJ,CAAC,CACF,CAAC","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
+ {"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 semanticIconPaths,\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\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={semanticIconPaths[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":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAoBnE,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,CAoOf"}
1
+ {"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAkBA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,2DAA2D,CAAC;AAoBnE,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,CAqOf"}
package/dist/theme.js CHANGED
@@ -157,6 +157,7 @@ export function createHjmThemeStyle(value) {
157
157
  // dialogs, sheets and toasts cannot retain neutral shadows after a theme switch.
158
158
  style[`--hjm-${name}-shadow`] = shadowCss(profileTokens?.shadow.floating ?? chrome.shadow);
159
159
  }
160
+ style["--hjm-immersive-background"] = resolveColorReference(dialogRecipe.immersive.background, palette);
160
161
  style["--hjm-sheet-max-height"] = `${sheetRecipe.content.maxHeightRatio * 100}dvh`;
161
162
  style["--hjm-sheet-max-width"] = `${sheetRecipe.web.maxWidth}px`;
162
163
  style["--hjm-sheet-handle-width"] = `${sheetRecipe.handle.width}px`;