@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
package/dist/screens.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- import { type ScreenInitialFocus } from "@hjmds/design-contracts/screen-patterns";
1
+ import { type ScreenInitialFocus, type IconTileFrame, type IconTileShape, type IconTileSize } from "@hjmds/design-contracts/screen-patterns";
2
2
  import { type ComposerLengthFeedback } from "@hjmds/design-contracts/communication";
3
3
  import { type DesignProfileScreenPresentation } from "@hjmds/design-contracts/design-profile-layout";
4
4
  import { type MessageMenuAction } from "./internal/message-reactions.js";
5
+ import { type MediaAlbum } from "./internal/media-album.js";
6
+ export type { MediaAlbum } from "./internal/media-album.js";
5
7
  import type { ReactionPickerProps } from "./reaction-picker.js";
6
8
  import { type Ref, type ReactNode } from "react";
7
- import { type MessageAttachmentDescriptor, type ChatMessageDescriptor, type MessageComposerDescriptor, type ScreenContentState, type ScreenContentInset } from "@hjmds/design-contracts/screen-patterns";
9
+ import { type MessageAttachmentDescriptor, type ChatReactionSummary, type ChatMessageDescriptor, type MessageComposerDescriptor, type ScreenContentState, type ScreenContentInset } from "@hjmds/design-contracts/screen-patterns";
8
10
  import { type ScreenExit } from "./internal/screen-exit.js";
9
11
  import { type ListRowProps } from "./display.js";
10
12
  import type { HjmCompositionStyleProp } from "./composition-style.js";
@@ -12,6 +14,12 @@ export type ScreenLayoutProps = Readonly<{
12
14
  title: string;
13
15
  /** The shared header owns badge placement; the product supplies its meaning and label. */
14
16
  titleBadge?: ReactNode;
17
+ /**
18
+ * Identity mark or artwork before the title (team logo, tool artwork). Decorative: the title stays the heading and
19
+ * the accessible name. With `titleVisibility="hidden"` the mark stands alone in the title slot as the heading,
20
+ * named by `title` (2026-10-18: yajalal team detail and Utilverse tool headers rebuilt the header to get this).
21
+ */
22
+ titleLeading?: ReactNode;
15
23
  /** Hide redundant route names while retaining descriptions and a named screen. */
16
24
  titleVisibility?: "visible" | "hidden";
17
25
  /** Centered by default (2026-10-17 user rule); `start` remains available. Extra actions sit at the trailing edge. */
@@ -37,6 +45,8 @@ export type ScreenLayoutProps = Readonly<{
37
45
  footer?: ReactNode;
38
46
  state?: ScreenContentState;
39
47
  stateAction?: ReactNode;
48
+ /** Brand visual for `state.kind === "loading"`; the shared state group keeps copy, centering and announcement (as CompositionLayout). */
49
+ loadingIndicator?: ReactNode;
40
50
  children?: ReactNode;
41
51
  /** A virtualized list must own scrolling; never nest it inside a second scroll container. */
42
52
  scroll?: "screen" | "content";
@@ -57,9 +67,7 @@ export type ScreenLayoutProps = Readonly<{
57
67
  initialFocus?: ScreenInitialFocus;
58
68
  }>;
59
69
  /** Shared screen shell. Routing, data, permission checks and mutation state remain product-owned. */
60
- export declare function ScreenLayout({ title, titleBadge, titleVisibility, headerAlignment, header, contentInset, contentAlignment, surface, presentation: suppliedPresentation, description, exit, actions, notice, footer, state, stateAction, children, scroll, as: Element, className, layoutStyle, initialFocus, hjmTitleLeading }: ScreenLayoutProps & Readonly<{
61
- hjmTitleLeading?: ReactNode;
62
- }>): import("react").JSX.Element;
70
+ export declare function ScreenLayout({ title, titleBadge, titleLeading, titleVisibility, headerAlignment, header, contentInset, contentAlignment, surface, presentation: suppliedPresentation, description, exit, actions, notice, footer, state, stateAction, loadingIndicator, children, scroll, as: Element, className, layoutStyle, initialFocus }: ScreenLayoutProps): import("react").JSX.Element;
63
71
  /**
64
72
  * Style for a product scroller that owns the body with `scroll="content"`: it reaches across the body gutter
65
73
  * (`--hjm-screen-body-inline`) and pads it back, so items stay on the gutter while the clip moves to the screen edges and
@@ -93,7 +101,7 @@ export type NotificationItemProps = Omit<ListRowProps, "description" | "selected
93
101
  description?: ReactNode;
94
102
  }>;
95
103
  export declare function NotificationItem({ read, statusLabel, timestamp, description, title, className, ...props }: NotificationItemProps): import("react").JSX.Element;
96
- export type ChatScreenProps = Omit<ScreenLayoutProps, "footer"> & Readonly<{
104
+ export type ChatScreenProps = Omit<ScreenLayoutProps, "footer" | "titleLeading"> & Readonly<{
97
105
  composer: ReactNode;
98
106
  /** Shown while the reader is away from the latest message; the host owns scroll position and visibility. */
99
107
  jumpToLatest?: Readonly<{
@@ -195,11 +203,24 @@ export type ChatMessageProps = ChatMessageDescriptor & Readonly<{
195
203
  disabled?: boolean;
196
204
  icon?: ReactNode;
197
205
  }>;
206
+ summary?: ChatMessageReactionSummary;
198
207
  }>;
199
208
  /** Canonical layout-only placement on the message row. The swipe offset still owns `transform`. */
200
209
  layoutStyle?: HjmCompositionStyleProp;
210
+ }> & Readonly<{
211
+ /**
212
+ * Paged alternative to `media` (2026-10-18, Utilverse): HJM mounts only the shown photo, so a product that authorizes
213
+ * each image fetches one page at a time. Exclusive with `media` (validated at render): one message has one photo set.
214
+ */
215
+ mediaAlbum?: MediaAlbum;
201
216
  }>;
202
- export declare function ChatMessage({ direction, author, timestamp, timestampPresentation, bubbleTail, groupPosition, deliveryLabel, avatar, reply, replyQuote, media, actions, replyAction, replyLink, reactions, children, interactiveContent, layoutStyle }: ChatMessageProps): import("react").JSX.Element;
217
+ /**
218
+ * Current reactions drawn beside the time as one button that opens the same hold menu (2026-10-18 BurnTok DM, which
219
+ * showed counts as status tags because the menu could not be opened from outside). Counts and the localized
220
+ * accessible name ("Reactions: heart 2. Open menu") come from the product; `items` in display order.
221
+ */
222
+ export type ChatMessageReactionSummary = ChatReactionSummary;
223
+ export declare function ChatMessage({ direction, author, timestamp, timestampPresentation, bubbleTail, groupPosition, deliveryLabel, avatar, reply, replyQuote, media, mediaAlbum, actions, replyAction, replyLink, reactions, children, interactiveContent, layoutStyle }: ChatMessageProps): import("react").JSX.Element;
203
224
  /** Shared structure for embedded compositions. The parent supplies size; this never creates a second scroller. */
204
225
  export type CompositionLayoutProps = Readonly<{
205
226
  title?: string;
@@ -236,7 +257,37 @@ export type IconTileProps = Readonly<{
236
257
  overlay?: ReactNode;
237
258
  labelLines?: 1 | 2;
238
259
  ghost?: boolean;
260
+ /** `none`: the icon is complete product artwork, so no frame fill or hairline is drawn. */
261
+ frame?: IconTileFrame;
262
+ /** Frame (and ghost outline) corner shape from the product's icon theme. */
263
+ shape?: IconTileShape;
264
+ /** `fill`: the icon spans the grid cell between iconTileRecipe.fillMinSize and fillMaxSize. */
265
+ size?: IconTileSize;
239
266
  }>;
240
267
  /** Presentation shared by launcher and profile grids; the host owns navigation or drag behavior. */
241
- export declare function IconTile({ icon, label, overlay, labelLines, ghost }: IconTileProps): import("react").JSX.Element;
268
+ export declare function IconTile({ icon, label, overlay, labelLines, ghost, frame, shape, size }: IconTileProps): import("react").JSX.Element;
269
+ export type TypingIndicatorProps = Readonly<{
270
+ /** Localized status read by assistive tech ("Seoyeon is typing"); the visible row shows only the dots. */
271
+ label: string;
272
+ /** Typer's photo in a group room, sized like ChatMessage avatars (`chatMessageRecipe.avatarSize`). */
273
+ avatar?: ReactNode;
274
+ layoutStyle?: HjmCompositionStyleProp;
275
+ }>;
276
+ /**
277
+ * Incoming "is typing" row for a ChatScreen timeline (2026-10-18 BurnTok DM drew its own). The host shows it only while
278
+ * presence says someone is typing and places it after the last message; HJM owns the bubble, dots and announcement.
279
+ */
280
+ export declare function TypingIndicator({ label, avatar, layoutStyle }: TypingIndicatorProps): import("react").JSX.Element;
281
+ export type ChatDateSeparatorProps = Readonly<{
282
+ /** Product-formatted date or time ("Today", "Oct 18", "3:04 PM"). */
283
+ label: string;
284
+ /** Machine-readable value for the Web `<time>` element; Native ignores it. */
285
+ dateTime?: string;
286
+ layoutStyle?: HjmCompositionStyleProp;
287
+ }>;
288
+ /**
289
+ * Centered date (or time) row between ChatScreen timeline groups (2026-10-18 Utilverse chat drew a caption). Grouping
290
+ * rules stay with the product; the next message keeps its own group gap, so this row adds only the space before it.
291
+ */
292
+ export declare function ChatDateSeparator({ label, dateTime, layoutStyle }: ChatDateSeparatorProps): import("react").JSX.Element;
242
293
  //# sourceMappingURL=screens.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"screens.d.ts","sourceRoot":"","sources":["../src/screens.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"screens.d.ts","sourceRoot":"","sources":["../src/screens.tsx"],"names":[],"mappings":"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"}
package/dist/screens.js CHANGED
@@ -5,29 +5,32 @@ import { iconButtonRecipe, listRowRecipe } from "@hjmds/design-contracts/recipes
5
5
  import { resolveComposerLimit } from "@hjmds/design-contracts/communication";
6
6
  import { Progress } from "./feedback.js";
7
7
  import { resolveDesignProfileScreen } from "@hjmds/design-contracts/design-profile-layout";
8
- import { MessageReactions } from "./internal/message-reactions.js";
8
+ import { MessageReactions, ReactionSummaryButton, omitReactionSummary } from "./internal/message-reactions.js";
9
+ import { MediaAlbumView, useMediaAlbumIndex } from "./internal/media-album.js";
10
+ import { validateMediaSetChoice } from "@hjmds/design-contracts/screen-patterns";
9
11
  import { Button, IconButton } from "./actions.js";
10
12
  import { useOptionalHjmTheme } from "./provider.js";
11
13
  import { TextArea } from "./forms.js";
12
14
  import { useId, useLayoutEffect, useRef, useState } from "react";
13
- import { isReplySwipe, timestampRevealOffset, shouldSubmitMessageKey, canSubmitMessage, validateMessageAttachments, resolveScreenContentState, screenPatternRecipe, chatMessageRecipe, composerQuickInsertRecipe, resolveChatMessageGroupDisplay, resolveChatMediaColumns, screenHeaderRecipe, validateScreenExit } from "@hjmds/design-contracts/screen-patterns";
15
+ import { isReplySwipe, timestampRevealOffset, shouldSubmitMessageKey, canSubmitMessage, validateMessageAttachments, resolveScreenContentState, screenPatternRecipe, chatMessageRecipe, composerQuickInsertRecipe, resolveChatMessageGroupDisplay, resolveChatMediaColumns, resolveChatReactionSummary, typingIndicatorRecipe, chatDateSeparatorRecipe, screenHeaderRecipe, validateScreenExit } from "@hjmds/design-contracts/screen-patterns";
14
16
  import { Heading } from "./heading.js";
15
17
  import { Spinner } from "./internal/spinner.js";
16
18
  import { ScreenExitButton } from "./internal/screen-exit.js";
17
19
  import { ScreenFooterContext } from "./internal/screen-footer.js";
18
- import { Section, Stack, Text } from "./layout.js";
20
+ import { Section, Stack, Text, VisuallyHidden } from "./layout.js";
19
21
  import { ListRow } from "./display.js";
20
22
  import { classNames, useDesignProfileDefaults } from "./internal.js";
21
23
  /** Shared screen shell. Routing, data, permission checks and mutation state remain product-owned. */
22
- export function ScreenLayout({ title, titleBadge, titleVisibility = "visible", headerAlignment = "center", header, contentInset = "default", contentAlignment = "start", surface = "default", presentation: suppliedPresentation, description, exit, actions, notice, footer, state = { kind: "ready" }, stateAction, children, scroll = "screen", as: Element = "main", className, layoutStyle, initialFocus = initialFocusDefaults.screen, hjmTitleLeading }) {
24
+ export function ScreenLayout({ title, titleBadge, titleLeading, titleVisibility = "visible", headerAlignment = "center", header, contentInset = "default", contentAlignment = "start", surface = "default", presentation: suppliedPresentation, description, exit, actions, notice, footer, state = { kind: "ready" }, stateAction, loadingIndicator, children, scroll = "screen", as: Element = "main", className, layoutStyle, initialFocus = initialFocusDefaults.screen }) {
23
25
  const id = useId();
24
26
  if (exit)
25
27
  validateScreenExit(exit, false);
26
28
  const leading = exit ? _jsx(ScreenExitButton, { ...exit }) : null;
27
- const showHeader = titleVisibility === "visible" || !!description || !!leading || !!actions;
29
+ const hasMark = titleLeading !== undefined && titleLeading !== null && titleLeading !== false;
30
+ const showHeader = titleVisibility === "visible" || hasMark || !!description || !!leading || !!actions;
28
31
  // Same header band as Native (screenHeaderRecipe): a fixed 52 band (48 icon-only) so the title sits at the same
29
32
  // height with or without exit/actions buttons (2026-10-17: Web grew 58→76 when a 44 button was present).
30
- const compactHeader = header == null && headerAlignment === "center" && titleVisibility === "hidden" && !description;
33
+ const compactHeader = header == null && headerAlignment === "center" && titleVisibility === "hidden" && !hasMark && !description;
31
34
  // Screens historically work with the stylesheet alone. Optional context keeps
32
35
  // that path while inheriting profiles from an enclosing Provider when present.
33
36
  const designProfile = useDesignProfileDefaults();
@@ -50,13 +53,18 @@ export function ScreenLayout({ title, titleBadge, titleVisibility = "visible", h
50
53
  lastBodyFocus.current = null;
51
54
  });
52
55
  const recipe = screenPatternRecipe;
53
- return _jsx(Element, { "aria-labelledby": header || titleVisibility === "hidden" ? undefined : id, "aria-label": header || titleVisibility === "hidden" ? title : undefined, "data-content-inset": contentInset, "data-presentation": presentation, className: classNames("hjm-screen", className), style: { backgroundColor: surface === "transparent" || designProfile?.material.canvas ? "transparent" : undefined, "--hjm-screen-width": `${profileLayout?.maxWidth ?? recipe.maxWidth}px`, "--hjm-screen-padding": `${contentInset === "none" ? 0 : recipe.padding}px`, "--hjm-screen-gap": `${profileLayout?.gap ?? recipe.sectionGap}px`, "--hjm-screen-item-gap": `${recipe.itemGap}px`, "--hjm-screen-state-gap": `${recipe.stateGap}px`, "--hjm-screen-header-min": `${recipe.headerMinWidth}px`, ...layoutStyle }, children: _jsxs(InitialFocusScope, { mode: initialFocus, children: [header ?? (showHeader ? headerAlignment === "center" ? _jsxs("header", { className: "hjm-screen__header", style: { display: "grid", gridTemplateColumns: "1fr minmax(0, auto) 1fr", alignItems: "center", boxSizing: "border-box", minBlockSize: compactHeader ? screenHeaderRecipe.compactMinHeight : screenHeaderRecipe.minHeight, paddingBlock: compactHeader ? screenHeaderRecipe.compactPaddingVertical : screenHeaderRecipe.paddingVertical }, children: [_jsx("div", { children: leading }), _jsxs("div", { className: "hjm-screen__heading", style: { textAlign: "center", minWidth: 0 }, children: [titleVisibility === "visible" && _jsxs(Stack, { axis: "inline", gap: "xs", align: "center", justify: "center", wrap: true, children: [hjmTitleLeading, _jsx(Heading, { level: screenHeaderRecipe.centeredTitleLevel, semanticLevel: 1, id: id, children: title }), titleBadge] }), description ? _jsx(Text, { as: "p", tone: "muted", children: description }) : null] }), _jsx("div", { style: { justifySelf: "end" }, children: actions })] }) : _jsxs("header", { className: "hjm-screen__header", style: profileLayout ? { flexDirection: profileLayout.headerAxis, alignItems: profileLayout.centered ? "center" : undefined, textAlign: profileLayout.centered ? "center" : undefined } : undefined, children: [leading, _jsxs("div", { className: "hjm-screen__heading", children: [titleVisibility === "visible" && _jsxs(Stack, { axis: "inline", gap: "xs", align: "center", justify: profileLayout?.centered ? "center" : "start", wrap: true, children: [_jsx(Heading, { level: screenHeaderRecipe.titleLevel, semanticLevel: 1, id: id, children: title }), titleBadge] }), description ? _jsx(Text, { as: "p", tone: "muted", children: description }) : null] }), actions] }) : null), notice ? _jsx("div", { className: "hjm-screen__notice", children: notice }) : null, _jsx("div", { ref: bodyRef, role: "region", "aria-label": title, tabIndex: bodyScroll === "content" ? -1 : 0, onFocusCapture: event => { lastBodyFocus.current = event.target; }, onBlurCapture: event => {
56
+ // The mark is decorative beside a visible title; standing alone it becomes the heading, named by `title`.
57
+ const mark = hasMark ? _jsx("span", { className: "hjm-screen__title-leading", "aria-hidden": "true", children: titleLeading }) : null;
58
+ const titleRow = (level, justify) => titleVisibility === "visible"
59
+ ? _jsxs(Stack, { axis: "inline", gap: "xs", align: "center", justify: justify, wrap: true, children: [mark, _jsx(Heading, { level: level, semanticLevel: 1, id: id, children: title }), titleBadge] })
60
+ : mark ? _jsx("div", { role: "heading", "aria-level": 1, "aria-label": title, style: { display: "flex", justifyContent: justify === "center" ? "center" : "flex-start" }, children: mark }) : null;
61
+ return _jsx(Element, { "aria-labelledby": header || titleVisibility === "hidden" ? undefined : id, "aria-label": header || titleVisibility === "hidden" ? title : undefined, "data-content-inset": contentInset, "data-presentation": presentation, className: classNames("hjm-screen", className), style: { backgroundColor: surface === "transparent" || designProfile?.material.canvas ? "transparent" : undefined, "--hjm-screen-width": `${profileLayout?.maxWidth ?? recipe.maxWidth}px`, "--hjm-screen-padding": `${contentInset === "none" ? 0 : recipe.padding}px`, "--hjm-screen-gap": `${profileLayout?.gap ?? recipe.sectionGap}px`, "--hjm-screen-item-gap": `${recipe.itemGap}px`, "--hjm-screen-state-gap": `${recipe.stateGap}px`, "--hjm-screen-header-min": `${recipe.headerMinWidth}px`, ...layoutStyle }, children: _jsxs(InitialFocusScope, { mode: initialFocus, children: [header ?? (showHeader ? headerAlignment === "center" ? _jsxs("header", { className: "hjm-screen__header", style: { display: "grid", gridTemplateColumns: "1fr minmax(0, auto) 1fr", alignItems: "center", boxSizing: "border-box", minBlockSize: compactHeader ? screenHeaderRecipe.compactMinHeight : screenHeaderRecipe.minHeight, paddingBlock: compactHeader ? screenHeaderRecipe.compactPaddingVertical : screenHeaderRecipe.paddingVertical }, children: [_jsx("div", { children: leading }), _jsxs("div", { className: "hjm-screen__heading", style: { textAlign: "center", minWidth: 0 }, children: [titleRow(screenHeaderRecipe.centeredTitleLevel, "center"), description ? _jsx(Text, { as: "p", tone: "muted", children: description }) : null] }), _jsx("div", { style: { justifySelf: "end" }, children: actions })] }) : _jsxs("header", { className: "hjm-screen__header", style: profileLayout ? { flexDirection: profileLayout.headerAxis, alignItems: profileLayout.centered ? "center" : undefined, textAlign: profileLayout.centered ? "center" : undefined } : undefined, children: [leading, _jsxs("div", { className: "hjm-screen__heading", children: [titleRow(screenHeaderRecipe.titleLevel, profileLayout?.centered ? "center" : "start"), description ? _jsx(Text, { as: "p", tone: "muted", children: description }) : null] }), actions] }) : null), notice ? _jsx("div", { className: "hjm-screen__notice", children: notice }) : null, _jsx("div", { ref: bodyRef, role: "region", "aria-label": title, tabIndex: bodyScroll === "content" ? -1 : 0, onFocusCapture: event => { lastBodyFocus.current = event.target; }, onBlurCapture: event => {
54
62
  // A connected input blurred to the document intentionally relinquishes
55
63
  // focus too; only removal of the currently focused node needs recovery.
56
64
  if (event.relatedTarget ? !event.currentTarget.contains(event.relatedTarget) : event.target.isConnected) {
57
65
  lastBodyFocus.current = null;
58
66
  }
59
- }, className: "hjm-screen__body", "data-content-alignment": contentAlignment, "data-scroll": bodyScroll, "data-replacement": resolved.replacesContent || undefined, "aria-busy": resolved.busy || undefined, children: state.kind === "ready" ? (contentAlignment === "center" ? _jsx("div", { className: "hjm-screen__centered-content", children: children }) : children) : _jsxs("div", { className: "hjm-screen__state", children: [resolved.busy ? _jsx(Spinner, { label: [state.title, state.description].filter(Boolean).join(". ") }) : _jsx("div", { role: state.kind === "error" ? "alert" : "status", children: _jsxs(Stack, { gap: "sm", align: "center", children: [_jsx(Text, { variant: "title", children: state.title }), state.description ? _jsx(Text, { tone: "muted", children: state.description }) : null] }) }), stateAction] }) }), footer ? _jsx("footer", { className: "hjm-screen__footer", children: _jsx(ScreenFooterContext.Provider, { value: contentInset !== "none", children: footer }) }) : null] }) });
67
+ }, className: "hjm-screen__body", "data-content-alignment": contentAlignment, "data-scroll": bodyScroll, "data-replacement": resolved.replacesContent || undefined, "aria-busy": resolved.busy || undefined, children: state.kind === "ready" ? (contentAlignment === "center" ? _jsx("div", { className: "hjm-screen__centered-content", children: children }) : children) : _jsxs("div", { className: "hjm-screen__state", children: [resolved.busy ? (loadingIndicator ? _jsx("div", { role: "status", "aria-busy": "true", "aria-label": [state.title, state.description].filter(Boolean).join(". "), children: _jsx("div", { "aria-hidden": "true", children: loadingIndicator }) }) : _jsx(Spinner, { label: [state.title, state.description].filter(Boolean).join(". ") })) : _jsx("div", { role: state.kind === "error" ? "alert" : "status", children: _jsxs(Stack, { gap: "sm", align: "center", children: [_jsx(Text, { variant: "title", children: state.title }), state.description ? _jsx(Text, { tone: "muted", children: state.description }) : null] }) }), stateAction] }) }), footer ? _jsx("footer", { className: "hjm-screen__footer", children: _jsx(ScreenFooterContext.Provider, { value: contentInset !== "none", children: footer }) }) : null] }) });
60
68
  }
61
69
  /**
62
70
  * Style for a product scroller that owns the body with `scroll="content"`: it reaches across the body gutter
@@ -83,7 +91,7 @@ export function ChatScreen({ composer, jumpToLatest, avatar, scroll = "content",
83
91
  const showComposer = !props.state || props.state.kind === "ready" || props.state.kind === "empty";
84
92
  // Anchor the jump control to the composer edge so it floats over the timeline without measuring the footer.
85
93
  // Conversations center the peer between back and tools and use the measured 10px timeline gutter (2026-10-16).
86
- return _jsx(ScreenLayout, { ...props, className: classNames("hjm-chat-screen", props.className) ?? "hjm-chat-screen", hjmTitleLeading: avatar, scroll: scroll, footer: showComposer ? _jsxs("div", { className: "hjm-chat-screen__footer", children: [jumpToLatest ? _jsx("div", { className: "hjm-chat-screen__jump", children: _jsx(IconButton, { label: jumpToLatest.label, size: "small", shape: "circle", tone: "secondary", onClick: jumpToLatest.onPress, children: jumpToLatest.icon }) }) : null, composer] }) : null });
94
+ return _jsx(ScreenLayout, { ...props, className: classNames("hjm-chat-screen", props.className) ?? "hjm-chat-screen", titleLeading: avatar, scroll: scroll, footer: showComposer ? _jsxs("div", { className: "hjm-chat-screen__footer", children: [jumpToLatest ? _jsx("div", { className: "hjm-chat-screen__jump", children: _jsx(IconButton, { label: jumpToLatest.label, size: "small", shape: "circle", tone: "secondary", onClick: jumpToLatest.onPress, children: jumpToLatest.icon }) }) : null, composer] }) : null });
87
95
  }
88
96
  export function MessageComposer({ leading, quickInserts, value, label, sendLabel, placeholder = label, description, error, invalid = false, submitMode = "newline", onBlur, disabled = false, pending = false, onValueChange, onSend, maxLength, lengthFeedback, sendDisabled = false, additionalContent = false, leadingAction, inputRef, context, replyTo, sendIcon, sendPresentation = "inline", attachmentAction, attachments = [], onRemoveAttachment, layoutStyle }) {
89
97
  validateMessageAttachments(attachments);
@@ -111,24 +119,33 @@ export function MessageComposer({ leading, quickInserts, value, label, sendLabel
111
119
  } }, onChange: event => { if (!locked)
112
120
  onValueChange(event.currentTarget.value); }, minVisibleLines: screenPatternRecipe.composerMinLines, maxVisibleLines: screenPatternRecipe.composerMaxLines, ...(sendIcon ? { trailing: _jsx("span", { className: "hjm-message-composer__trailing", style: { minInlineSize: sendDiameter, minBlockSize: sendDiameter }, children: _jsx("span", { className: "hjm-message-composer__visible", children: hasContent || pending ? send : attach }) }) } : {}) }), sendIcon ? null : send] })] });
113
121
  const quickRow = quickInserts?.items.length ? _jsx("div", { className: "hjm-message-composer__quick", role: "group", "aria-label": quickInserts.label, style: { "--hjm-quick-size": `${composerQuickInsertRecipe.itemSize}px`, "--hjm-quick-emoji": `${composerQuickInsertRecipe.emojiSize}px` }, children: quickInserts.items.map(item => _jsx("button", { type: "button", className: "hjm-message-composer__quick-item", "aria-label": item.label, disabled: locked, onClick: () => onValueChange(value + item.emoji), children: item.emoji }, item.id)) }) : null;
122
+ // The error is announced by TextArea's shared Field error region (internal/field-error.tsx); no composer-only copy.
114
123
  return _jsxs("div", { className: "hjm-message-composer", "data-send-presentation": sendPresentation, style: { "--hjm-message-composer-gap": `${screenPatternRecipe.itemGap}px`, "--hjm-attachment-size": `${screenPatternRecipe.attachmentSize}px`, "--hjm-attachment-remove-size": `${screenPatternRecipe.attachmentRemoveSize}px`, ...layoutStyle }, children: [context, quickRow, _jsxs("div", { className: "hjm-message-composer__reply-card", "data-replying": replyTo ? true : undefined, children: [replyTo ? _jsxs("div", { className: "hjm-message-composer__reply", children: [_jsxs("div", { className: "hjm-message-composer__reply-text", children: [_jsx(Text, { emphasis: "strong", children: replyTo.author }), _jsx(Text, { variant: "caption", tone: "muted", className: "hjm-message-composer__reply-excerpt", children: replyTo.excerpt })] }), _jsx(IconButton, { label: replyTo.cancelLabel, tone: "secondary", size: "small", shape: "circle", disabled: locked, onClick: replyTo.onCancel, children: _jsx(Text, { children: "\u00D7" }) })] }) : null, composerBody] }), lengthFeedback && limit?.near ? _jsx(Progress, { shape: "circular", label: lengthFeedback.label, value: Math.min(limit.used, limit.max), max: limit.max, valueText: lengthFeedback.formatCount(limit.used, limit.max), children: _jsx(Text, { variant: "caption", children: lengthFeedback.formatCount(limit.used, limit.max) }) }) : null] });
115
124
  }
116
- export function ChatMessage({ direction, author, timestamp, timestampPresentation = "always", bubbleTail = true, groupPosition = "single", deliveryLabel, avatar, reply, replyQuote, media = [], actions, replyAction, replyLink, reactions, children, interactiveContent = false, layoutStyle }) {
125
+ export function ChatMessage({ direction, author, timestamp, timestampPresentation = "always", bubbleTail = true, groupPosition = "single", deliveryLabel, avatar, reply, replyQuote, media = [], mediaAlbum, actions, replyAction, replyLink, reactions, children, interactiveContent = false, layoutStyle }) {
117
126
  const theme = useOptionalHjmTheme();
118
127
  const display = resolveChatMessageGroupDisplay(groupPosition);
119
128
  // A run shows its time once, beside its last bubble; delivery state stays on every bubble.
120
129
  const visibleTime = display.showTimestamp ? timestamp : "";
121
130
  const quote = replyQuote ? _jsxs(_Fragment, { children: [_jsx(Text, { emphasis: "strong", children: replyQuote.title }), _jsx(Text, { tone: "muted", className: "hjm-chat-message__quote-excerpt", children: replyQuote.excerpt })] }) : reply;
122
131
  // The quote stays inside the bubble; with replyLink a click on it jumps to the original (2026-10-16 reference).
123
- const mediaBlock = media.length ? _jsx("div", { className: "hjm-chat-message__media", style: { inlineSize: chatMessageRecipe.mediaWidth, gap: chatMessageRecipe.mediaGap, gridTemplateColumns: `repeat(${resolveChatMediaColumns(media.length)}, minmax(0, 1fr))` }, children: media.map(item => { const style = { aspectRatio: media.length > 1 ? 1 : item.aspectRatio ?? 1 }; return item.onPress ? _jsx("button", { type: "button", className: "hjm-chat-message__media-item", "aria-label": item.label, style: style, onClick: item.onPress, children: item.preview }, item.id) : _jsx("div", { role: "img", "aria-label": item.label, className: "hjm-chat-message__media-item", style: style, children: item.preview }, item.id); }) }) : null;
132
+ validateMediaSetChoice(media.length > 0, mediaAlbum !== undefined);
133
+ const [albumIndex, setAlbumIndex] = useMediaAlbumIndex(mediaAlbum);
134
+ const mediaBlock = mediaAlbum ? _jsx(MediaAlbumView, { album: mediaAlbum, index: albumIndex, onIndexChange: setAlbumIndex, width: chatMessageRecipe.mediaWidth, radius: chatMessageRecipe.bubbleRadius })
135
+ : media.length ? _jsx("div", { className: "hjm-chat-message__media", style: { inlineSize: chatMessageRecipe.mediaWidth, gap: chatMessageRecipe.mediaGap, gridTemplateColumns: `repeat(${resolveChatMediaColumns(media.length)}, minmax(0, 1fr))` }, children: media.map(item => { const style = { aspectRatio: media.length > 1 ? 1 : item.aspectRatio ?? 1 }; return item.onPress ? _jsx("button", { type: "button", className: "hjm-chat-message__media-item", "aria-label": item.label, style: style, onClick: item.onPress, children: item.preview }, item.id) : _jsx("div", { role: "img", "aria-label": item.label, className: "hjm-chat-message__media-item", style: style, children: item.preview }, item.id); }) }) : null;
124
136
  // A photo-only message drops the bubble surface so the photo itself is the message.
125
- const photoOnly = media.length > 0 && !reply && !replyQuote && (children === null || children === undefined || children === false || children === "");
137
+ const photoOnly = (media.length > 0 || mediaAlbum !== undefined) && !reply && !replyQuote && (children === null || children === undefined || children === false || children === "");
126
138
  const quoteBlock = quote ? (replyLink ? _jsx("button", { type: "button", className: "hjm-chat-message__reply hjm-chat-message__quote", "aria-label": replyLink.label, onClick: replyLink.onPress, children: quote }) : _jsx("div", { className: "hjm-chat-message__reply", children: quote })) : null;
127
139
  const revealTime = timestampPresentation === "swipe" && !!timestamp;
128
140
  // Only the pointer that began a drag can finish it; another touch must not reply or cancel it.
129
141
  const start = useRef(null);
130
142
  const [offset, setOffset] = useState(0);
131
143
  const finish = () => { start.current = null; setOffset(0); };
144
+ const menu = useRef(null);
145
+ const summary = reactions?.summary;
146
+ const reactionMenu = reactions ? omitReactionSummary(reactions) : undefined;
147
+ const summaryItems = summary ? resolveChatReactionSummary(summary) : [];
148
+ const summaryButton = reactions && summary && summaryItems.length ? _jsx(ReactionSummaryButton, { label: summary.label, items: summaryItems, selected: reactions.value, disabled: reactions.disabled ?? false, onPress: () => menu.current?.open() }) : null;
132
149
  return _jsxs("article", { tabIndex: replyAction && !replyAction.disabled ? 0 : undefined, "aria-keyshortcuts": replyAction ? "Alt+ArrowLeft Alt+ArrowRight" : undefined, "aria-description": replyAction?.label, onKeyDown: event => { if (event.target === event.currentTarget && event.altKey && (event.key === "ArrowLeft" || event.key === "ArrowRight") && replyAction && !replyAction.disabled) {
133
150
  event.preventDefault();
134
151
  replyAction.onPress();
@@ -146,7 +163,7 @@ export function ChatMessage({ direction, author, timestamp, timestampPresentatio
146
163
  finish(); }, onPointerLeave: event => { if (start.current?.pointerId === event.pointerId)
147
164
  finish(); }, style: { ...layoutStyle, position: "relative", overflow: "hidden", marginBlockStart: display.spacingBefore,
148
165
  // Reserve tip room only where it protrudes (own trailing edge, or leading edge without an avatar column).
149
- ...(bubbleTail ? (direction === "outgoing" ? { paddingInlineEnd: chatMessageRecipe.tailWidth } : avatar ? {} : { paddingInlineStart: chatMessageRecipe.tailWidth }) : {}), touchAction: revealTime || replyAction ? "pan-y" : undefined }, "aria-label": author, children: [revealTime ? _jsx("time", { style: { position: "absolute", ...(direction === "outgoing" ? { right: 0, justifyContent: "flex-end" } : { left: 0 }), top: 0, bottom: 0, width: 80, display: "flex", alignItems: "center", opacity: offset !== 0 ? 1 : 0, pointerEvents: "none" }, children: _jsx(Text, { variant: "caption", tone: "muted", children: timestamp }) }) : null, _jsxs("div", { className: "hjm-chat-message", style: { transform: `translateX(${offset}px)`, transition: start.current || theme?.environment.reducedMotion ? "none" : "transform var(--hjm-motion-normal, 200ms) ease-out", "--hjm-message-max-width": screenPatternRecipe.messageMaxWidth, "--hjm-chat-avatar-size": `${chatMessageRecipe.avatarSize}px` }, "data-direction": direction, "data-tail": (bubbleTail && display.showTail) || undefined, children: [avatar ? _jsx("div", { className: "hjm-chat-message__avatar", "aria-hidden": display.showAvatar ? undefined : true, children: display.showAvatar ? avatar : null }) : null, _jsxs("div", { className: "hjm-chat-message__content", children: [author && display.showAuthor && direction !== "outgoing" ? _jsx(Text, { variant: "caption", tone: "muted", children: author }) : null, _jsxs("div", { className: "hjm-chat-message__body", children: [reactions ? _jsxs(MessageReactions, { ...reactions, interactiveContent: interactiveContent, ...(timestamp ? { menuTitle: timestamp } : {}), ...(replyAction && !replyAction.disabled ? { replyAction } : {}), children: [quoteBlock, mediaBlock, photoOnly ? null : children] }) : _jsxs("div", { className: "hjm-chat-message__bubble", "data-photo-only": photoOnly || undefined, children: [quoteBlock, mediaBlock, photoOnly ? null : children] }), (!revealTime && visibleTime) || deliveryLabel || actions ? _jsxs("div", { className: "hjm-chat-message__meta", children: [(!revealTime && visibleTime) || deliveryLabel ? _jsx(Text, { variant: "caption", tone: "muted", children: [revealTime ? "" : visibleTime, deliveryLabel].filter(Boolean).join(" · ") }) : null, actions] }) : null] })] })] })] });
166
+ ...(bubbleTail ? (direction === "outgoing" ? { paddingInlineEnd: chatMessageRecipe.tailWidth } : avatar ? {} : { paddingInlineStart: chatMessageRecipe.tailWidth }) : {}), touchAction: revealTime || replyAction ? "pan-y" : undefined }, "aria-label": author, children: [revealTime ? _jsx("time", { style: { position: "absolute", ...(direction === "outgoing" ? { right: 0, justifyContent: "flex-end" } : { left: 0 }), top: 0, bottom: 0, width: 80, display: "flex", alignItems: "center", opacity: offset !== 0 ? 1 : 0, pointerEvents: "none" }, children: _jsx(Text, { variant: "caption", tone: "muted", children: timestamp }) }) : null, _jsxs("div", { className: "hjm-chat-message", style: { transform: `translateX(${offset}px)`, transition: start.current || theme?.environment.reducedMotion ? "none" : "transform var(--hjm-motion-normal, 200ms) ease-out", "--hjm-message-max-width": screenPatternRecipe.messageMaxWidth, "--hjm-chat-avatar-size": `${chatMessageRecipe.avatarSize}px` }, "data-direction": direction, "data-tail": (bubbleTail && display.showTail) || undefined, children: [avatar ? _jsx("div", { className: "hjm-chat-message__avatar", "aria-hidden": display.showAvatar ? undefined : true, children: display.showAvatar ? avatar : null }) : null, _jsxs("div", { className: "hjm-chat-message__content", children: [author && display.showAuthor && direction !== "outgoing" ? _jsx(Text, { variant: "caption", tone: "muted", children: author }) : null, _jsxs("div", { className: "hjm-chat-message__body", children: [reactionMenu ? _jsxs(MessageReactions, { ...reactionMenu, menuRef: menu, interactiveContent: interactiveContent || mediaAlbum !== undefined, ...(timestamp ? { menuTitle: timestamp } : {}), ...(replyAction && !replyAction.disabled ? { replyAction } : {}), children: [quoteBlock, mediaBlock, photoOnly ? null : children] }) : _jsxs("div", { className: "hjm-chat-message__bubble", "data-photo-only": photoOnly || undefined, children: [quoteBlock, mediaBlock, photoOnly ? null : children] }), (!revealTime && visibleTime) || deliveryLabel || actions || summaryButton ? _jsxs("div", { className: "hjm-chat-message__meta", children: [summaryButton, (!revealTime && visibleTime) || deliveryLabel ? _jsx(Text, { variant: "caption", tone: "muted", children: [revealTime ? "" : visibleTime, deliveryLabel].filter(Boolean).join(" · ") }) : null, actions] }) : null] })] })] })] });
150
167
  }
151
168
  export function CompositionLayout({ title, headingLevel = 3, description, badge, leading, actions, notice, children, footer, state = { kind: "ready" }, stateAction, loadingIndicator, layoutStyle }) {
152
169
  const resolved = resolveScreenContentState(state);
@@ -158,8 +175,33 @@ export function NotificationRow({ preview, metadata, avatar, avatarBadge, thumbn
158
175
  return _jsxs("span", { "aria-hidden": "true", "data-hjm-notification-row": "true", style: { display: "flex", alignItems: "center", gap: r.gap, padding: `${r.paddingBlock}px ${r.paddingInline}px`, width: "100%", minWidth: 0, boxSizing: "border-box" }, children: [_jsxs("span", { style: { position: "relative", width: r.avatarSize, height: r.avatarSize, flexShrink: 0 }, children: [_jsx("span", { style: { display: "flex", width: "100%", height: "100%", overflow: "hidden", borderRadius: "50%" }, children: avatar }), avatarBadge ? _jsx("span", { style: { position: "absolute", bottom: 0, right: 0, display: "flex", alignItems: "center", justifyContent: "center", width: r.avatarBadgeSize, height: r.avatarBadgeSize, borderRadius: "50%", background: "var(--hjm-color-surface)", border: "2px solid var(--hjm-color-surface)", boxSizing: "border-box" }, children: avatarBadge }) : null] }), _jsxs("span", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: r.contentGap }, children: [_jsx(Text, { style: { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: r.previewLines, overflow: "hidden" }, children: preview }), _jsxs("span", { style: { display: "flex", alignItems: "center", gap: r.contentGap }, children: [_jsx(Text, { variant: "caption", tone: "muted", children: metadata }), unread ? _jsx("span", { "data-hjm-unread-dot": "true", style: { width: r.unreadSize, height: r.unreadSize, borderRadius: "50%", flexShrink: 0, background: "var(--hjm-color-content-brand)" } }) : null] })] }), thumbnail ? _jsx("span", { style: { width: r.thumbnailSize, height: r.thumbnailSize, flexShrink: 0, overflow: "hidden", borderRadius: "var(--hjm-radius-sm)" }, children: thumbnail }) : null] });
159
176
  }
160
177
  /** Presentation shared by launcher and profile grids; the host owns navigation or drag behavior. */
161
- export function IconTile({ icon, label, overlay, labelLines = 1, ghost = false }) {
178
+ export function IconTile({ icon, label, overlay, labelLines = 1, ghost = false, frame = iconTileRecipe.defaults.frame, shape = iconTileRecipe.defaults.shape, size = iconTileRecipe.defaults.size }) {
162
179
  const r = iconTileRecipe;
163
- return _jsxs("span", { "data-hjm-icon-tile": "true", style: { display: "flex", flexDirection: "column", alignItems: "center", gap: r.gap, minWidth: 0, width: "100%", overflow: "visible" }, children: [_jsxs("span", { style: { position: "relative", display: "flex", alignItems: "center", justifyContent: "center", width: r.iconSize, height: r.iconSize, flexShrink: 0, borderRadius: r.iconRadius, background: "var(--hjm-color-surface-alt)", color: "var(--hjm-color-text)", boxShadow: ghost ? undefined : "0 0 0 1px var(--hjm-color-border)", outline: ghost ? "1px dashed var(--hjm-color-text-muted)" : undefined, opacity: ghost ? r.ghostOpacity : 1, fontSize: 32 }, children: [icon, overlay] }), _jsx(Text, { variant: "caption", style: { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: labelLines, width: "100%", maxWidth: labelLines === 2 ? r.multilineLabelMaxWidth : r.labelMaxWidth, minHeight: labelLines === 2 ? r.multilineLabelMinHeight : undefined, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "normal", overflowWrap: "anywhere", textAlign: "center", fontWeight: 500 }, children: label })] });
180
+ const framed = frame === "surface";
181
+ // Percent radius follows the rendered size, so a filling icon keeps its shape at every cell width.
182
+ const dimensions = size === "fill" ? { width: "100%", minWidth: r.fillMinSize, maxWidth: r.fillMaxSize, aspectRatio: "1" } : { width: r.iconSize, height: r.iconSize };
183
+ return _jsxs("span", { "data-hjm-icon-tile": "true", "data-frame": frame, "data-shape": shape, "data-size": size, style: { display: "flex", flexDirection: "column", alignItems: "center", gap: r.gap, minWidth: 0, width: "100%", overflow: "visible" }, children: [_jsxs("span", { style: { position: "relative", display: "flex", alignItems: "center", justifyContent: "center", ...dimensions, boxSizing: "border-box", flexShrink: 0, borderRadius: `${Math.round(r.shapes[shape] * 100)}%`, background: framed ? "var(--hjm-color-surface-alt)" : undefined, color: "var(--hjm-color-text)", boxShadow: ghost || !framed ? undefined : "0 0 0 1px var(--hjm-color-border)", outline: ghost ? "1px dashed var(--hjm-color-text-muted)" : undefined, opacity: ghost ? r.ghostOpacity : 1, fontSize: 32 }, children: [icon, overlay] }), _jsx(Text, { variant: "caption", style: { display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: labelLines, width: "100%", maxWidth: labelLines === 2 ? r.multilineLabelMaxWidth : r.labelMaxWidth, minHeight: labelLines === 2 ? r.multilineLabelMinHeight : undefined, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "normal", overflowWrap: "anywhere", textAlign: "center", fontWeight: 500 }, children: label })] });
184
+ }
185
+ /**
186
+ * Incoming "is typing" row for a ChatScreen timeline (2026-10-18 BurnTok DM drew its own). The host shows it only while
187
+ * presence says someone is typing and places it after the last message; HJM owns the bubble, dots and announcement.
188
+ */
189
+ export function TypingIndicator({ label, avatar, layoutStyle }) {
190
+ if (!label.trim())
191
+ throw new TypeError("TypingIndicator requires a localized label");
192
+ const theme = useOptionalHjmTheme();
193
+ const r = typingIndicatorRecipe, m = chatMessageRecipe;
194
+ // A polite status: appearing is announced once without interrupting, and the dots stay hidden from assistive tech.
195
+ return _jsxs("div", { role: "status", className: "hjm-typing-indicator", "data-reduced-motion": theme?.environment.reducedMotion || undefined, style: { display: "flex", alignItems: "flex-start", gap: m.avatarGap, marginBlockStart: m.groupGap, paddingInlineStart: avatar ? 0 : m.tailWidth, ...layoutStyle, "--hjm-typing-dot": `${r.dotSize}px`, "--hjm-typing-cycle": `${r.cycleMs}ms`, "--hjm-typing-rest": r.restOpacity }, children: [avatar ? _jsx("span", { "aria-hidden": "true", style: { display: "flex", justifyContent: "center", flex: `0 0 ${m.avatarSize}px`, inlineSize: m.avatarSize }, children: avatar }) : null, _jsx("span", { "aria-hidden": "true", className: "hjm-typing-indicator__bubble", style: { display: "inline-flex", alignItems: "center", gap: r.dotGap, boxSizing: "border-box", minBlockSize: `calc(var(--hjm-type-body-line-height) + ${m.bubblePaddingBlock * 2}px)`, paddingBlock: m.bubblePaddingBlock, paddingInline: m.bubblePaddingInline, borderRadius: m.bubbleRadius, background: "var(--hjm-color-surface)" }, children: [0, 1, 2].map(index => _jsx("span", { className: "hjm-typing-indicator__dot", style: { animationDelay: `${index * r.staggerMs}ms` } }, index)) }), _jsx(VisuallyHidden, { children: label })] });
196
+ }
197
+ /**
198
+ * Centered date (or time) row between ChatScreen timeline groups (2026-10-18 Utilverse chat drew a caption). Grouping
199
+ * rules stay with the product; the next message keeps its own group gap, so this row adds only the space before it.
200
+ */
201
+ export function ChatDateSeparator({ label, dateTime, layoutStyle }) {
202
+ if (!label.trim())
203
+ throw new TypeError("ChatDateSeparator requires a localized label");
204
+ const r = chatDateSeparatorRecipe;
205
+ return _jsx("div", { className: "hjm-chat-date-separator", style: { display: "flex", justifyContent: "center", textAlign: "center", paddingBlockStart: r.paddingTop, paddingBlockEnd: r.paddingBottom, ...layoutStyle }, children: _jsx(Text, { variant: r.textVariant, tone: r.tone, children: dateTime ? _jsx("time", { dateTime: dateTime, children: label }) : label }) });
164
206
  }
165
207
  //# sourceMappingURL=screens.js.map