@botiverse/raft-ui 0.23.1 → 0.25.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,128 @@
1
+ ## [0.25.0](https://github.com/botiverse/raft-design/compare/v0.24.0...v0.25.0) (2026-10-23)
2
+
3
+ ### Design System
4
+
5
+ - **Themes: a frame, never a new palette**: a person can pick a theme for themselves, and it follows their account to every server. Raft Yellow, the foundation itself, stays the default; beside it are Boring Gray and nine avatar-series themes (Bots, Critters, Space, Desk, Food, Quest, Weather, Plants, Spooky). A theme may recolor only the frame (rail, web top bar, phone top bar), the sidebar and, in dark mode, the canvas, cards and popups, tinted to its hue. The pink primary button, unread and @ counts, status lights, warnings and errors look the same in every theme. Every theme has a light and a dark version. An avatar-series theme can draw its series' pixel sprites on the empty parts of the frame, and the person can turn them off. Boring Gray is the one theme that also changes the brand: where you are is a gray fill with ink type, not yellow. It applies to AppRail and SidebarItem. ([#754](https://github.com/botiverse/raft-design/pull/754))
6
+ - Why: the frame is on every screen but nobody reads it, so it can carry a person's choice of look; keeping every meaning fixed means someone who switches themes doesn't have to learn the product again. In dark mode the surfaces take the theme's hue because a neutral black panel inside a colored frame looked pasted on.
7
+ - Affects: Navigation and States: "where you are is always yellow" now has one exception, Boring Gray, where `brand` and its washes are neutral grays and `brand-edge` is transparent. Sprites go only on the web top bar right of the search field (from 1024px) and on the desktop rail under its items, never where they could be taken for a control, an avatar or a status, and never behind text.
8
+ - Docs: https://raft-design.botiverse.build/foundations/themes/#principles
9
+ - **The first frame is the settled one**: draw the first frame the way it will stay. Read what decides a layout (a remembered width, a collapsed section, a view mode, the viewport, the pointer, the platform) before the first paint, not in an effect after mount. Measure and decide in a layout effect, not in the next animation frame. While data reloads, keep a part's presence and size, such as counts and the controls that depend on them, at their last values until the new answer arrives. A placeholder, such as the fallback of a lazily loaded panel, takes the size and place of what it stands for. ([#748](https://github.com/botiverse/raft-design/pull/748))
10
+ - Why: a frame drawn from a "not known yet" default and corrected a moment later is a flash: a row grows and shrinks back, a panel snaps to another width, and controls move under the pointer.
11
+ - Affects: a rule for products; nothing in raft-ui changes. Feedback's skeleton rule now points to it.
12
+ - Docs: https://raft-design.botiverse.build/patterns/responsive/#the-first-frame-is-the-settled-one
13
+ - **A row with a fill: one line height, no mark taller than the line**: in a row whose items share the first baseline, such as a task row, every text takes the main text's line height, and a taller hit area hangs into the padding instead of making the row taller. A row that centers its items (`items-center`), as every raft-ui list row does, needs neither. ([#750](https://github.com/botiverse/raft-design/pull/750))
14
+ - Why: a smaller text has a shorter line box, so a Space Mono group sat 3px lower than the title and a mark centered in it sat 1.5px below the row's center; a 32px button made the row taller and the text sat 2.5px above the center of the hover fill.
15
+ - Affects: give the row `leading-(--text-callout--line-height)` (and set it on sizes that set their own); `text-mono-meta` and `text-caption` 18px → 22px line on such a row.
16
+ - Docs: https://raft-design.botiverse.build/foundations/alignment/#text-of-different-sizes-on-one-line
17
+ - **Grab handles have round ends**: round is now for switches, radios and grab handles: the bar at a bottom sheet's top edge and the bar in a gap between side cards. It applies to Drawer. ([#747](https://github.com/botiverse/raft-design/pull/747))
18
+ - Why: every platform draws a grab handle with round ends (the iOS sheet grabber, Material's drag handle), and square ends on a 4px bar read as a cut edge, not something to take hold of.
19
+ - Affects: `rounded-full`: switches and radios only → switches, radios and grab handles. A bottom sheet's grab handle is a 36 × 4px bar in `line-seam`.
20
+ - Docs: https://raft-design.botiverse.build/foundations/shape/#principles
21
+ - **The gap handle's bar follows the pointer**: on hover, the 56 × 4px bar in a gap between side cards is centered on the pointer along the gap, kept half a bar inside each end, with round ends; while dragging it stays where the drag started, and with keyboard focus it sits in the middle. Where two gaps cross, the crossing gap's bar lights at the pointer and the other at its end against the corner. `ResizableHandle` still draws only the seam handle; products draw the gap handle themselves. ([#746](https://github.com/botiverse/raft-design/pull/746))
22
+ - Why: a gap has no line, so the bar is the only thing that shows where the hand is, and a bar fixed in the middle of a long edge looked unrelated to the pointer.
23
+ - Affects: hover bar: middle of the gap, `rounded-[1px]` → at the pointer, `rounded-full`. Touch has no hover, so there the bar stays in the middle.
24
+ - Docs: https://raft-design.botiverse.build/components/resizable/#the-gap-handle
25
+ - **An app link shows its host wherever a touch can open it**: a chip for a link that an app previews shows the link's host after its title (`MessageReferenceSuffix`) on any device with touch input, including a laptop with a touch screen. Write the full host, dropping only a leading `www.`, never shortened to the registered domain, and an internationalized host in its ASCII form (`xn--…`). The title truncates first; if the host alone still doesn't fit, it loses its start, never its end. It applies to MessageItem and MessageReference. ([#749](https://github.com/botiverse/raft-design/pull/749), [#753](https://github.com/botiverse/raft-design/pull/753), [#755](https://github.com/botiverse/raft-design/pull/755))
26
+ - Why: the title is the app's own words and may say anything, and a tap opens the link without the hover card that shows where it goes on a desktop. A link someone can open without seeing where it goes is a safety problem, and the end of a host (`…review.attacker.example`) is the part that says where.
27
+ - Affects: suffix `hidden any-pointer-coarse:inline` (any touch input, not only the main pointer). A host that overflows is truncated at its start: `dir="ltr"` and `unicode-bidi: isolate` inside a right-to-left box, so the ellipsis lands at the start.
28
+ - Docs: https://raft-design.botiverse.build/components/message-item/#app-links
29
+ - **An app link is a plain link until Raft knows an app previews it**: before a message's previews are first read, an app's link is an ordinary link. Once someone allows an app's previews and Raft reads them again, each of that app's links is `MessageReferencePending capped` until its preview arrives. It applies to MessageItem. ([#753](https://github.com/botiverse/raft-design/pull/753))
30
+ - Why: until the previews are read, the client can't tell an app's link from any other.
31
+ - Affects: pending chip shown while any preview loads → only for links of an app whose previews are allowed, after they are read again.
32
+ - Docs: https://raft-design.botiverse.build/components/message-item/#app-links
33
+ - **Read receipts on a mention: on a touch screen the check alone says it**: there is no hover card on a touch screen, and tapping a mention opens the agent's profile, so the check is the whole answer there: no mark means not read yet. Don't add a long press or a popup only for this line. It applies to MessageItem. ([#745](https://github.com/botiverse/raft-design/pull/745))
34
+ - Why: a gesture for one line of text is more to learn than it tells.
35
+ - Affects: a rule for products; the check's own word ("Read") still reaches a screen reader.
36
+ - Docs: https://raft-design.botiverse.build/components/message-item/#read-receipts-on-a-mention
37
+ - **The message menu: its order written down**: the menu opens with the message's full date and time as a label that can't be chosen, then the 7 quick reactions and a `smile-plus` button that opens every emoji, then the actions in three sections by what they do to the message: keep going on it (Reply in Thread, Follow or Unfollow Thread, the task action), take it elsewhere (Copy Link, Copy Markdown, Forward, Select Message), and just for me (Save or Remove from Saved, Translate). A section with nothing in it is left out with its separator. It applies to DropdownMenu, ContextMenu and MessageReactionQuickRow. ([#751](https://github.com/botiverse/raft-design/pull/751))
38
+ - Why: the order lived only in the compositions; it is now a rule, grouped by what each action does to the message.
39
+ - Affects: 8 buttons of 36px make the menu 316px wide, wider than its 240px minimum; the actions take the same width.
40
+ - Docs: https://raft-design.botiverse.build/components/dropdown-menu/#the-message-menu
41
+
42
+ ### Added
43
+
44
+ - **Themes**: a new export, `@botiverse/raft-ui/themes.css`, with Boring Gray (`boring`) and the nine avatar-series themes (`bots`, `critters`, `space`, `desk`, `food`, `quest`, `weather`, `plants`, `spooky`), each with a light and a dark version. Import it after `foundation.css` and put `data-theme="<id>"` on the element that carries the mode class (`.light` / `.dark`); without `data-theme` the app is Raft Yellow. Put `data-theme-decor="off"` on the same element to turn the sprites off and keep the colors. A top bar you draw yourself takes the new `frame-decor-top` utility for its sprites; `frame-decor-rail` is the rail's, which AppRail already draws. ([#754](https://github.com/botiverse/raft-design/pull/754))
45
+ - Why: see Themes: a frame, never a new palette, above.
46
+ - Affects: a theme overrides only `layer-frame`, `layer-frame-active`, `foreground-on-frame` (and `-muted`, `-active`), `fill-frame-medium`, `line-frame-active` and `layer-sidebar`; in dark mode also `layer-canvas`, `layer-card` and `layer-popover`; Boring Gray also `brand`, `brand-soft`, `brand-strong`, `brand-glow`, `brand-edge` and `selection`. `frame-decor-top` paints `--frame-decor-top` 72px from the right end, from 1024px wide only; both are `none` without a decorated theme. Themes are generated from `themes.json` (`vp run @botiverse/raft-ui#build:themes`).
47
+ - Docs: https://raft-design.botiverse.build/foundations/themes/#using-themes
48
+ - **`brand-edge`** Tailwind color: `--color-brand-edge` maps the existing `--brand-edge` token (`border-brand-edge`, `ring-brand-edge`). ([#754](https://github.com/botiverse/raft-design/pull/754))
49
+ - Why: the edge of a selected navigation item has to follow the theme: ink by default, transparent in Boring Gray.
50
+ - Affects: `var(--brand-edge)`, which is `var(--sticker-ink)` in the foundation and `transparent` in Boring Gray.
51
+ - Docs: https://raft-design.botiverse.build/foundations/themes/#what-a-theme-may-change
52
+
53
+ ### Changed
54
+
55
+ - **SidebarItem**: the active item's border takes `brand-edge` instead of `sticker-ink`, so in Boring Gray the selected row is a plain gray fill. It renders the same in Raft Yellow and the avatar-series themes. ([#754](https://github.com/botiverse/raft-design/pull/754))
56
+ - Why: see Themes: a frame, never a new palette, above.
57
+ - Affects: `data-active:border-sticker-ink` → `data-active:border-brand-edge`.
58
+ - Docs: https://raft-design.botiverse.build/foundations/themes/#the-themes
59
+ - **AppRail**: the nav draws the theme's rail sprites as its last flex item, an `::after` pushed to the bottom under the items, up to 48 × 112px, which shrinks when the rail has less room so it never sits behind an item. Without a decorated theme it is empty. ([#754](https://github.com/botiverse/raft-design/pull/754))
60
+ - Why: see Themes: a frame, never a new palette, above.
61
+ - Affects: nav gains `after:mt-auto after:h-28 after:min-h-0 after:w-12 after:shrink after:content-[''] after:frame-decor-rail`. A nav `::after` of your own would replace it.
62
+ - Docs: https://raft-design.botiverse.build/foundations/themes/#decorations
63
+ - **Drawer**: a bottom or top sheet's grab handle has round ends. ([#747](https://github.com/botiverse/raft-design/pull/747))
64
+ - Why: see Grab handles have round ends, above.
65
+ - Affects: handle `before:rounded-[1px]` → `before:rounded-full`.
66
+ - Docs: https://raft-design.botiverse.build/components/drawer/#rules
67
+ - **MessageIcon**, **ChatIcon** and **ThreadIcon**: their lines are drawn at Lucide's weight. ([#751](https://github.com/botiverse/raft-design/pull/751))
68
+ - Why: at 1 they drew 0.89px at 16px, thinner than every Lucide icon beside them in a menu or a toolbar.
69
+ - Affects: `strokeWidth` 1 → 1.5 on the 18px grid (1.33px at 16px, as Lucide's 2 on its 24px grid).
70
+ - Docs: https://raft-design.botiverse.build/components/icons/#anatomy
71
+ - **ThreadIcon**: both bubbles are outlined; the back one stops a stroke's width short of the front one on both sides, and both stay inside the 18px box with their stroke. ([#752](https://github.com/botiverse/raft-design/pull/752))
72
+ - Why: every icon in Raft is a line drawing at one weight, and a filled bubble read heavier than the Lucide icons beside it.
73
+ - Affects: front bubble `fill="currentColor"` → outline; the paths are redrawn, so the icon's shape changes slightly.
74
+ - Docs: https://raft-design.botiverse.build/components/icons/#anatomy
75
+
76
+ ### Fixed
77
+
78
+ - **MessageReactionQuickRow**: the quick reactions line up with the menu's items: the first drawing starts 10px in, where the items' icons do. ([#751](https://github.com/botiverse/raft-design/pull/751))
79
+ - Why: with no side padding the reactions stood 3px left of the icons below them, so the column the eye follows down the menu stepped out at the top.
80
+ - Affects: `p-0` → `px-0.75 py-0` (3px at each side).
81
+ - Docs: https://raft-design.botiverse.build/components/dropdown-menu/#the-message-menu
82
+ - **Banner** `size="sm"`: with a × (and no action button), the banner keeps the same room above and below as with a button, so the ×'s 32px hover fill stays 4px inside the banner's edges. ([#677](https://github.com/botiverse/raft-design/pull/677))
83
+ - Why: the room was kept only for an action button, so the ×'s hover fill reached the banner's edge.
84
+ - Affects: padding above and below with a × only: 8px → (32px − one line) / 2 + 4px, 9px on a desktop and 10px on a phone.
85
+ - Docs: https://raft-design.botiverse.build/components/banner/#sizes
86
+ - **VirtualList**: scrolling up near the end of a list no longer snaps back, and on iOS the rows stay painted when older rows land at the top while the finger is still down. `onContentResize` is no longer called for rows above the view that the list measures and scrolls away exactly as you scroll up, since nothing in view moves and neither does the distance to the end. ([#683](https://github.com/botiverse/raft-design/pull/683))
87
+ - Why: a chat that follows the end from `onContentResize` and still counted the person as at the bottom scrolled back to the end, taking back the scroll that had mounted those rows; and when rows above the view shrank near the end, the browser's clamp and the list's own compensation both moved the view, so the rows in view jumped down. On iOS, at the top with the finger down, the pending compensation wasn't applied as a transform, so the rows were drawn below the view and a newly loaded older page showed blank.
88
+ - Affects: `onContentResize` still runs when content in view or below it changes, and when a pending scroll is replayed. The clamp is subtracted from the scroll compensation instead of being applied twice.
89
+ - Docs: https://raft-design.botiverse.build/components/virtual-list/#following-the-end
90
+
91
+ ## [0.24.0](https://github.com/botiverse/raft-design/compare/v0.23.1...v0.24.0) (2026-10-23)
92
+
93
+ ### Design System
94
+
95
+ - **Phone popups 8px from each screen edge**: on a phone, a popup about as wide as the screen is the screen's width less 8px on each side, at most 480px, and stops 8px from the edge it is pushed against, measured from the screen's edge, not the safe area. Its width comes from the positioner's `--available-width`, not `100vw`. It applies to NotificationCenter. ([#737](https://github.com/botiverse/raft-design/pull/737))
96
+ - Why: popups that open from the same phone top bar sat at different insets and widths, so they didn't line up with each other or sit evenly between the screen's edges; every popup that wide now takes the server list's 8px inset.
97
+ - Affects: inset 8px from both screen edges; width `min(var(--available-width), 480px)`. The 480px cap only reaches a phone on its side.
98
+ - Docs: https://raft-design.botiverse.build/foundations/elevation/#popups
99
+ - **Located: focus on the item is the inset ring, and a message is an article**: an item that a keyboard jump focuses draws the 2px inset ring in `foreground`, inside the item and with its corners, only after keyboard input, never the browser's outline. A message is announced as an article named by its sender and its time. It applies to MessageItem. ([#740](https://github.com/botiverse/raft-design/pull/740))
100
+ - Why: the browser's outline is drawn outside the item with its own rounded corners, so on a message it framed the transparent gap above the row and a scroller cut it off, and a screen reader landing on a message heard its text with no sender or time; the ring now sits inside the item and the row carries its own name.
101
+ - Affects: focus on a jumped-to item: browser outline → `inset-ring-2 inset-ring-foreground` after keyboard input.
102
+ - Docs: https://raft-design.botiverse.build/foundations/states/#located
103
+
104
+ ### Breaking Changes
105
+
106
+ - **MessageItem**: the row is an `article` named by its sender and its time. When it holds a `MessageItemSender` or `MessageItemSenderButton`, a `MessageItemTime` or a `MessageItemContinuationTime`, the row gets `role="article"` and `aria-labelledby` pointing at them, in that order, and those parts get ids raft-ui generates (an `id` you pass is kept and is the one the row points at). A screen reader announces, for example, "Atlas 2:20 PM" before the text; a continuation row is named by its time. A row with none of these parts and no `aria-label` or `aria-labelledby` stays a plain `div`. ([#740](https://github.com/botiverse/raft-design/pull/740))
107
+ - Why: a screen reader landing on a message, after a jump or with its reading keys, read the text with no sender or time; the row now carries its own role and name.
108
+ - Affects: every row with a sender or time part, role none (`div`) → `article`, with `aria-labelledby`; the sender and time parts gain an `id`. Your own `role` or `aria-labelledby` on `MessageItem` or its `render` element is left as is; your own `aria-label` drops the generated `aria-labelledby`, and a role that takes no name (`none`, `presentation`, `generic`) gets none.
109
+ - Migrate: don't render `MessageItem` as an `li` or put rows in a `list`: `role="article"` replaces `listitem`, and a list may hold only list items. Remove the list role from the timeline, or pass `role="listitem"` on `MessageItem` to keep the old semantics. Update tests and selectors that find rows by role or expect no `role` on the row. When `render` is a function, pass `role`, `aria-label` and `aria-labelledby` on `MessageItem`, since a function's props can't be read. Don't give `MessageItemSenderButton` an `aria-label` of its own: the row would read that instead of the visible name.
110
+ - Docs: https://raft-design.botiverse.build/components/message-item/#accessibility
111
+
112
+ ### Changed
113
+
114
+ - **MessageItem**: a focused row (`tabIndex={-1}`, set by the caller when a keyboard jump lands on it) shows the 2px inset ring in `foreground`, square like its hover, after keyboard input, and shows its toolbar; it never shows the browser's outline. After a click, nothing shows. raft-ui still doesn't make the row focusable. ([#740](https://github.com/botiverse/raft-design/pull/740))
115
+ - Why: see Located: focus on the item is the inset ring, above.
116
+ - Affects: focused row: browser outline → `outline-none focus-visible:keyboard:inset-ring-2 focus-visible:keyboard:inset-ring-foreground`. While the toolbar shows, its card covers part of the ring's top edge at the right.
117
+ - Docs: https://raft-design.botiverse.build/components/message-item/#states
118
+
119
+ ### Fixed
120
+
121
+ - **NotificationCenterPopup** `viewport="mobile"`: the popup is the screen's width less 8px on each side, at most 480px, and sits 8px from both screen edges, though it hangs from a bell at the right, lined up with the server list under the same top bar. Pass `collisionPadding` to change the inset. On desktop it is unchanged: 380px with Base UI's default collision padding. ([#737](https://github.com/botiverse/raft-design/pull/737))
122
+ - Why: see Phone popups 8px from each screen edge, above.
123
+ - Affects: width `min(92vw, 360px)` → `min(var(--available-width), 480px)`; collision padding Base UI's default → 8px with `viewport="mobile"`.
124
+ - Docs: https://raft-design.botiverse.build/components/notification-center/#behavior
125
+
1
126
  ## [0.23.1](https://github.com/botiverse/raft-design/compare/v0.23.0...v0.23.1) (2026-10-22)
2
127
 
3
128
  ### Fixed
@@ -1271,7 +1271,17 @@ type MessageItemProps = useRender.ComponentProps<"div"> & Pick<MessageItemVarian
1271
1271
  */
1272
1272
  located?: boolean;
1273
1273
  };
1274
- declare function MessageItem({ className, compact, located, render, ...props }: MessageItemProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1274
+ /**
1275
+ * One message: an `article` named by its sender and its time
1276
+ * (`aria-labelledby` pointing at `MessageItemSender` or
1277
+ * `MessageItemSenderButton`, then `MessageItemTime` or
1278
+ * `MessageItemContinuationTime`). A row with neither, and no `aria-label` or
1279
+ * `aria-labelledby`, is a plain `div`. Pass `role`, `aria-label` or
1280
+ * `aria-labelledby` on MessageItem or on a `render` element to override
1281
+ * either; a `render` function's props can't be read, so pass them on
1282
+ * MessageItem then.
1283
+ */
1284
+ declare function MessageItem({ className, compact, located, render, ...props }: MessageItemProps): import("react").JSX.Element;
1275
1285
  //#endregion
1276
1286
  //#region src/components/message-item/message-item-gutter.d.ts
1277
1287
  type MessageItemGutterProps = useRender.ComponentProps<"div">;
@@ -1280,7 +1290,7 @@ type MessageItemAvatarSlotProps = useRender.ComponentProps<"div">;
1280
1290
  declare function MessageItemAvatarSlot({ className, render, ...props }: MessageItemAvatarSlotProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1281
1291
  type MessageItemContinuationTimeProps = useRender.ComponentProps<"time">;
1282
1292
  /** Left-gutter hover clock for continuation rows, a `<time>`: pass the moment in `dateTime`. Show the hour and minute only, in the person's 12h/24h format, with no AM/PM (`6:35`, `18:35`). */
1283
- declare function MessageItemContinuationTime({ className, render, ...props }: MessageItemContinuationTimeProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1293
+ declare function MessageItemContinuationTime({ className, id, render, ...props }: MessageItemContinuationTimeProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1284
1294
  //#endregion
1285
1295
  //#region src/components/message-item/message-item-content.d.ts
1286
1296
  type MessageItemContentProps = useRender.ComponentProps<"div">;
@@ -1315,9 +1325,9 @@ type MessageItemSenderGroupProps = useRender.ComponentProps<"span">;
1315
1325
  */
1316
1326
  declare function MessageItemSenderGroup({ className, render, ...props }: MessageItemSenderGroupProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1317
1327
  type MessageItemSenderProps = useRender.ComponentProps<"span">;
1318
- declare function MessageItemSender({ className, render, ...props }: MessageItemSenderProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1328
+ declare function MessageItemSender({ className, id, render, ...props }: MessageItemSenderProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1319
1329
  type MessageItemSenderButtonProps = useRender.ComponentProps<"button">;
1320
- declare function MessageItemSenderButton({ className, render, ...props }: MessageItemSenderButtonProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1330
+ declare function MessageItemSenderButton({ className, id, render, ...props }: MessageItemSenderButtonProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1321
1331
  type MessageItemSenderBadgesProps = useRender.ComponentProps<"span">;
1322
1332
  declare function MessageItemSenderBadges({ className, render, ...props }: MessageItemSenderBadgesProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1323
1333
  type MessageItemMetaProps = useRender.ComponentProps<"span">;
@@ -1327,7 +1337,7 @@ type MessageItemTimeProps = useRender.ComponentProps<"time">;
1327
1337
  * The message's time, right after the sender. A `<time>`: pass the moment in
1328
1338
  * `dateTime` (ISO 8601) and the full date and time as its tooltip.
1329
1339
  */
1330
- declare function MessageItemTime({ className, render, ...props }: MessageItemTimeProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1340
+ declare function MessageItemTime({ className, id, render, ...props }: MessageItemTimeProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1331
1341
  type MessageItemInlineStatusProps = useRender.ComponentProps<"span">;
1332
1342
  declare function MessageItemInlineStatus({ className, render, ...props }: MessageItemInlineStatusProps): import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>>;
1333
1343
  //#endregion
@@ -3707,6 +3707,117 @@ const searchHit = [
3707
3707
  "text-sticker-ink inset-ring-[1.5px] inset-ring-sticker-ink ring-[1.5px] ring-sticker-edge"
3708
3708
  ];
3709
3709
  //#endregion
3710
+ //#region src/components/message-item/message-item-label.ts
3711
+ const MessageItemLabelContext = createContext(null);
3712
+ const MessageItemLabelProvider = MessageItemLabelContext.Provider;
3713
+ /**
3714
+ * The id of a sender or time part, registered with the MessageItem around it.
3715
+ * A consumer's own `id` wins and is the one registered. Outside a MessageItem
3716
+ * the part gets no id.
3717
+ */
3718
+ function useMessageItemLabelId(part, id) {
3719
+ const registry = useContext(MessageItemLabelContext);
3720
+ const generatedId = useId();
3721
+ const resolvedId = id ?? (registry ? generatedId : void 0);
3722
+ useLayoutEffect(() => {
3723
+ if (!registry || !resolvedId) return void 0;
3724
+ return registry.register(part, resolvedId);
3725
+ }, [
3726
+ registry,
3727
+ part,
3728
+ resolvedId
3729
+ ]);
3730
+ return resolvedId;
3731
+ }
3732
+ /** Roles that can't be named: on them the row writes no `aria-labelledby`. */
3733
+ const NAMELESS_ROLES = /* @__PURE__ */ new Set([
3734
+ "none",
3735
+ "presentation",
3736
+ "generic"
3737
+ ]);
3738
+ /**
3739
+ * The row's side: a stable registry for its parts and a ref for its element.
3740
+ * The row writes `role="article"` and `aria-labelledby` itself, and only once
3741
+ * something names it: a sender or time part, or the consumer's `aria-label` or
3742
+ * `aria-labelledby`. A row with none of them (a receipt card in the text
3743
+ * column, say) stays a plain `div`, not an article with no name.
3744
+ *
3745
+ * A consumer's `role` or `aria-labelledby` is rendered by React and left
3746
+ * alone. A consumer's `aria-label`, or a role that takes no name, turns the
3747
+ * parts' `aria-labelledby` off, since it would win over the label.
3748
+ */
3749
+ function useMessageItemLabel(consumer) {
3750
+ const consumerRef = useRef(consumer);
3751
+ const [label] = useState(() => {
3752
+ const parts = {
3753
+ sender: [],
3754
+ time: []
3755
+ };
3756
+ let element = null;
3757
+ const write = (name, value) => {
3758
+ if (!element) return;
3759
+ if (!value) element.removeAttribute(name);
3760
+ else if (element.getAttribute(name) !== value) element.setAttribute(name, value);
3761
+ };
3762
+ const sync = () => {
3763
+ const { role, ariaLabel, ariaLabelledBy } = consumerRef.current;
3764
+ const ids = [...parts.sender, ...parts.time].join(" ");
3765
+ if (role === void 0) write("role", ids !== "" || ariaLabel !== void 0 || ariaLabelledBy !== void 0 ? "article" : "");
3766
+ if (ariaLabelledBy === void 0) {
3767
+ const nameable = role === void 0 || !NAMELESS_ROLES.has(role);
3768
+ write("aria-labelledby", ariaLabel === void 0 && nameable ? ids : "");
3769
+ }
3770
+ };
3771
+ const registry = { register(part, id) {
3772
+ parts[part].push(id);
3773
+ sync();
3774
+ return () => {
3775
+ const index = parts[part].indexOf(id);
3776
+ if (index !== -1) parts[part].splice(index, 1);
3777
+ sync();
3778
+ };
3779
+ } };
3780
+ const ref = (node) => {
3781
+ element = node;
3782
+ sync();
3783
+ };
3784
+ return {
3785
+ registry,
3786
+ ref,
3787
+ sync
3788
+ };
3789
+ });
3790
+ const { role, ariaLabel, ariaLabelledBy } = consumer;
3791
+ useLayoutEffect(() => {
3792
+ consumerRef.current = {
3793
+ role,
3794
+ ariaLabel,
3795
+ ariaLabelledBy
3796
+ };
3797
+ label.sync();
3798
+ }, [
3799
+ role,
3800
+ ariaLabel,
3801
+ ariaLabelledBy,
3802
+ label
3803
+ ]);
3804
+ return label;
3805
+ }
3806
+ /**
3807
+ * The consumer's role and name, from MessageItem's props and, where `render`
3808
+ * is an element, from that element's props, which Base UI merges over them.
3809
+ * A `render` function's props can't be read: pass them to MessageItem.
3810
+ */
3811
+ function readConsumerLabel(props, render) {
3812
+ const own = isValidElement(render) ? render.props : {};
3813
+ const pick = (key) => key in own ? own[key] : props[key];
3814
+ return {
3815
+ role: pick("role"),
3816
+ ariaLabel: pick("aria-label"),
3817
+ ariaLabelledBy: pick("aria-labelledby")
3818
+ };
3819
+ }
3820
+ //#endregion
3710
3821
  //#region src/components/message-item/message-item.recipe.ts
3711
3822
  const sender = [
3712
3823
  "min-w-0 truncate",
@@ -3729,7 +3840,8 @@ const messageItem = tv$1({
3729
3840
  "data-popup-open:[--mi-row-fill:var(--fill-subtle)] has-data-popup-open:[--mi-row-fill:var(--fill-subtle)]",
3730
3841
  "has-data-[slot=message-item-search-match]:[--mi-row-fill:var(--info-soft)] has-data-[slot=message-item-search-match]:hover:[--mi-row-fill:var(--info-soft)]",
3731
3842
  "has-[[data-slot=message-multi-select-checkbox][data-checked]]:[--mi-row-fill:var(--info-soft)]",
3732
- "has-[[data-slot=message-multi-select-checkbox][data-checked]]:hover:[--mi-row-fill:var(--info-soft)]"
3843
+ "has-[[data-slot=message-multi-select-checkbox][data-checked]]:hover:[--mi-row-fill:var(--info-soft)]",
3844
+ "outline-none focus-visible:keyboard:inset-ring-2 focus-visible:keyboard:inset-ring-foreground"
3733
3845
  ],
3734
3846
  gutter: ["relative shrink-0 self-stretch", "w-[35px]"],
3735
3847
  avatarSlot: [
@@ -3818,20 +3930,36 @@ const messageItem = tv$1({
3818
3930
  });
3819
3931
  //#endregion
3820
3932
  //#region src/components/message-item/message-item-root.tsx
3933
+ /**
3934
+ * One message: an `article` named by its sender and its time
3935
+ * (`aria-labelledby` pointing at `MessageItemSender` or
3936
+ * `MessageItemSenderButton`, then `MessageItemTime` or
3937
+ * `MessageItemContinuationTime`). A row with neither, and no `aria-label` or
3938
+ * `aria-labelledby`, is a plain `div`. Pass `role`, `aria-label` or
3939
+ * `aria-labelledby` on MessageItem or on a `render` element to override
3940
+ * either; a `render` function's props can't be read, so pass them on
3941
+ * MessageItem then.
3942
+ */
3821
3943
  function MessageItem({ className, compact, located = false, render, ...props }) {
3822
3944
  const { root } = messageItem({ compact });
3945
+ const label = useMessageItemLabel(readConsumerLabel(props, render));
3823
3946
  const defaultProps = {
3824
3947
  "data-message-item": "",
3825
3948
  "data-compact": compact ? "true" : void 0,
3826
3949
  "data-located": located ? "" : void 0,
3827
3950
  className: root({ className })
3828
3951
  };
3829
- return useRender({
3952
+ const element = useRender({
3830
3953
  defaultTagName: "div",
3831
3954
  render,
3955
+ ref: label.ref,
3832
3956
  props: mergeProps(defaultProps, props),
3833
3957
  state: { slot: "message-item" }
3834
3958
  });
3959
+ return /* @__PURE__ */ jsx(MessageItemLabelProvider, {
3960
+ value: label.registry,
3961
+ children: element
3962
+ });
3835
3963
  }
3836
3964
  //#endregion
3837
3965
  //#region src/components/message-item/message-item-gutter.tsx
@@ -3856,9 +3984,12 @@ function MessageItemAvatarSlot({ className, render, ...props }) {
3856
3984
  });
3857
3985
  }
3858
3986
  /** Left-gutter hover clock for continuation rows, a `<time>`: pass the moment in `dateTime`. Show the hour and minute only, in the person's 12h/24h format, with no AM/PM (`6:35`, `18:35`). */
3859
- function MessageItemContinuationTime({ className, render, ...props }) {
3987
+ function MessageItemContinuationTime({ className, id, render, ...props }) {
3860
3988
  const { continuationTime } = messageItem();
3861
- const defaultProps = { className: continuationTime({ className }) };
3989
+ const defaultProps = {
3990
+ id: useMessageItemLabelId("time", id),
3991
+ className: continuationTime({ className })
3992
+ };
3862
3993
  return useRender({
3863
3994
  defaultTagName: "time",
3864
3995
  render,
@@ -3971,9 +4102,12 @@ function MessageItemSenderGroup({ className, render, ...props }) {
3971
4102
  state: { slot: "message-item-sender-group" }
3972
4103
  });
3973
4104
  }
3974
- function MessageItemSender({ className, render, ...props }) {
4105
+ function MessageItemSender({ className, id, render, ...props }) {
3975
4106
  const { sender } = messageItem();
3976
- const defaultProps = { className: sender({ className }) };
4107
+ const defaultProps = {
4108
+ id: useMessageItemLabelId("sender", id),
4109
+ className: sender({ className })
4110
+ };
3977
4111
  return useRender({
3978
4112
  defaultTagName: "span",
3979
4113
  render,
@@ -3981,10 +4115,11 @@ function MessageItemSender({ className, render, ...props }) {
3981
4115
  state: { slot: "message-item-sender" }
3982
4116
  });
3983
4117
  }
3984
- function MessageItemSenderButton({ className, render, ...props }) {
4118
+ function MessageItemSenderButton({ className, id, render, ...props }) {
3985
4119
  const { senderButton } = messageItem();
3986
4120
  const defaultProps = {
3987
4121
  type: "button",
4122
+ id: useMessageItemLabelId("sender", id),
3988
4123
  className: senderButton({ className })
3989
4124
  };
3990
4125
  return useRender({
@@ -4018,9 +4153,12 @@ function MessageItemMeta({ className, render, ...props }) {
4018
4153
  * The message's time, right after the sender. A `<time>`: pass the moment in
4019
4154
  * `dateTime` (ISO 8601) and the full date and time as its tooltip.
4020
4155
  */
4021
- function MessageItemTime({ className, render, ...props }) {
4156
+ function MessageItemTime({ className, id, render, ...props }) {
4022
4157
  const { time } = messageItem();
4023
- const defaultProps = { className: time({ className }) };
4158
+ const defaultProps = {
4159
+ id: useMessageItemLabelId("time", id),
4160
+ className: time({ className })
4161
+ };
4024
4162
  return useRender({
4025
4163
  defaultTagName: "time",
4026
4164
  render,
@@ -4370,7 +4508,7 @@ const messageReaction = tv$1({ slots: {
4370
4508
  ],
4371
4509
  quickRow: [
4372
4510
  "flex shrink-0 items-center",
4373
- "justify-between gap-0.5 bg-layer-popover p-0",
4511
+ "justify-between gap-0.5 bg-layer-popover px-0.75 py-0",
4374
4512
  "[&>[role=menuitem]]:size-9 [&>[role=menuitem]]:p-0 *:[[role=menuitem]]:justify-center"
4375
4513
  ],
4376
4514
  quickButton: [
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as MessageListNoticeProps, $a as DropdownMenuCheckboxItemIndicator, $n as MessageItemToolbarButtonProps, $o as ListRowChevron, $r as AvatarGroup, $s as DialogTriggerProps, $t as MessageReferenceLabelProps, A as InboxItemTimestamp, Aa as PopoverHeader, Ai as PreviewCardProps, An as MessageReactionTooltipContent, Ao as DropdownMenuShortcutProps, Ar as MessageItemContentProps, As as DialogContentProps, At as MessageQuotedPreviewUnavailable, Ba as PopoverTitleProps, Bi as TooltipPortal, Bn as MessageReactionTooltipSeparator, Bo as KbdProps, Br as MessageItemAvatarSlotProps, Bs as DialogNavProps, Bt as MessageMultiSelectCheckboxProps, C as InboxItemProps, Ci as PreviewCardHeaderProps, Cn as MessageReactionPickerContentProps, Co as DropdownMenuRadioItem, Cr as MessageItemTime, Ct as MessageQuotedPreviewProps, D as InboxItemSenderProps, Da as PopoverContentProps, Di as PreviewCardPopupProps, Dn as MessageReactionQuickButtonProps, Do as DropdownMenuSeparator, Dr as MessageItemBody, Ds as DialogClose, Dt as MessageQuotedPreviewThreadProps, E as InboxItemSender, Ea as PopoverContent, Ei as PreviewCardPopup, En as MessageReactionQuickButton, Eo as DropdownMenuRadioItemProps, Er as MessageItemAttachmentsProps, Es as DialogBodyProps, Et as MessageQuotedPreviewThread, F as InboxItemTrailingProps, Fa as PopoverPortalProps, Fi as PreviewCardTrigger, Fn as MessageReactionTooltipNameProps, Fo as DropdownMenuTrigger, Fr as MessageItemFooter, Ft as MessageTextSelectionToolbarProps, Ga as MobileNavItem, Gi as TooltipTrigger, Gn as MessageItemBadgeSeparatorProps, Go as Checkbox, Gr as MessageItem, Gs as DialogProps, Gt as MessageMultiSelectToolbarProps, Ha as PopoverTriggerProps, Hi as TooltipProps, Hn as MessageItemBadge, Ho as BadgeProps, Hr as MessageItemContinuationTimeProps, Hs as DialogOverlayProps, Ht as MessageMultiSelectToolbar, I as InboxItemTrigger, Ia as PopoverProps, Ii as PreviewCardTriggerProps, In as MessageReactionTooltipNameText, Io as DropdownMenuTriggerProps, Ir as MessageItemFooterProps, Is as DialogFooterProps, It as MessageTextSelectionToolbarSeparator, J as MessageListEndFade, Ja as MobileNavLabelProps, Jn as MessageItemReadReceiptProps, Jo as ListRow, Jr as AvatarBadge, Js as DialogSurface, K as MessageListDateDivider, Ka as MobileNavItemProps, Ki as TooltipTriggerProps, Kn as MessageItemBadgeStatus, Ko as CheckboxProps, Kr as MessageItemProps, Kt as MessageReferenceChip, L as InboxItemTriggerProps, La as PopoverSeparator, Li as Tooltip, Ln as MessageReactionTooltipNameTextProps, Lo as Kbd, Lr as MessageItemSearchMatch, Ls as DialogHeader, Lt as MessageTextSelectionToolbarSeparatorProps, M as InboxItemTitle, Ma as PopoverPopup, Mi as PreviewCardSeparatorProps, Mn as MessageReactionTooltipMeta, Mo as DropdownMenuSubmenuProps, Mr as MessageItemEditedProps, Ms as DialogDescriptionProps, Mt as MessageTextSelectionToolbar, N as InboxItemTitleProps, Na as PopoverPopupProps, Ni as PreviewCardTitle, Nn as MessageReactionTooltipMetaProps, No as DropdownMenuSubmenuTrigger, Nr as MessageItemEmbedded, Ns as DialogFooter, Nt as MessageTextSelectionToolbarButton, O as InboxItemSubtitle, Oa as PopoverDescription, Oi as PreviewCardPortal, On as MessageReactionQuickRow, Oo as DropdownMenuSeparatorProps, Or as MessageItemBodyProps, Os as DialogCloseProps, Ot as MessageQuotedPreviewTimestamp, P as InboxItemTrailing, Pa as PopoverPortal, Pi as PreviewCardTitleProps, Pn as MessageReactionTooltipName, Po as DropdownMenuSubmenuTriggerProps, Pr as MessageItemEmbeddedProps, Pt as MessageTextSelectionToolbarButtonProps, Q as MessageListNotice, Qa as DropdownMenuCheckboxItem, Qn as MessageItemToolbarButton, Qo as ListRowBottomProps, Qr as AvatarFallbackProps, Qs as DialogTrigger, Qt as MessageReferenceLabel, Ra as PopoverSeparatorProps, Ri as TooltipContent, Rn as MessageReactionTooltipNames, Ro as KbdGroup, Rr as MessageItemSearchMatchProps, Rs as DialogHeaderProps, Rt as MessageMultiSelect, S as InboxItemMetadataProps, Si as PreviewCardHeader, Sn as MessageReactionPickerContent, So as DropdownMenuRadioGroupProps, Sr as MessageItemSenderProps, St as MessageQuotedPreviewLoadingProps, T as InboxItemSelectionProps, Ta as PopoverCloseProps, Tn as MessageReactionPickerStaticProps, To as DropdownMenuRadioItemIndicatorProps, Tr as MessageItemAttachments, Ts as DialogBody, Tt as MessageQuotedPreviewTextProps, Ua as PopoverViewport, Ui as TooltipProvider, Un as MessageItemBadgeProps, Uo as CheckboxIndicator, Ur as MessageItemGutter, Us as DialogPortal, Ut as MessageMultiSelectToolbarActions, Va as PopoverTrigger, Vi as TooltipPortalProps, Vn as MessageReactionTooltipSeparatorProps, Vo as Badge, Vr as MessageItemContinuationTime, Vs as DialogOverlay, Vt as MessageMultiSelectProps, Wa as PopoverViewportProps, Wi as TooltipProviderProps, Wn as MessageItemBadgeSeparator, Wo as CheckboxIndicatorProps, Wr as MessageItemGutterProps, Ws as DialogPortalProps, Wt as MessageMultiSelectToolbarActionsProps, X as MessageListHistoryLimited, Xa as MobileNavRootProps, Xn as MessageItemSavedIndicatorProps, Xo as ListRowBodyProps, Xr as AvatarBadgeProps, Xs as DialogTitle, Xt as MessageReferenceIndicator, Y as MessageListEndFadeProps, Ya as MobileNavRoot, Yn as MessageItemSavedIndicator, Yo as ListRowBody, Yr as AvatarBadgeOffset, Ys as DialogSurfaceProps, Z as MessageListHistoryLimitedProps, Za as DropdownMenu, Zn as MessageItemToolbar, Zo as ListRowBottom, Zr as AvatarFallback, Zs as DialogTitleProps, Zt as MessageReferenceIndicatorProps, _ as InboxItemMarks, _i as PreviewCardDescriptionProps, _n as MessageReactionCountProps, _o as DropdownMenuPopupProps, _r as MessageItemSenderBadgesProps, _s as TextLink, _t as MessageQuotedPreviewContent, a as InboxItemBodyProps, ac as DeprecatedButtonSize, ai as AvatarProps, an as MessageReferenceSuffixProps, ao as DropdownMenuFooterProps, as as ListRowIcon, at as MessageQuotedPreviewAttachments, b as InboxItemMessageProps, ba as PopoverBackdrop, bn as MessageReactionGlyph, bo as DropdownMenuProps, br as MessageItemSenderGroup, bt as MessageQuotedPreviewHeaderProps, c as InboxItemContext, cc as DataAttributes$1, cn as MessageReferenceUnavailable, co as DropdownMenuItemCountProps, cs as ListRowMetaProps, d as InboxItemHeading, di as PreviewCardArrowProps, dn as MessageReferenceTextVariant, do as DropdownMenuItemProps, dr as MessageItemInlineStatus, ds as ListRowTitleProps, dt as MessageQuotedPreviewAuthorMetaProps, ec as PanelAction, ei as AvatarGroupCount, en as MessageReferencePending, eo as DropdownMenuCheckboxItemIndicatorProps, er as MessageItemToolbarProps, es as ListRowChevronProps, et as MessageList, f as InboxItemHeadingProps, fn as MessageReactionAddButton, fo as DropdownMenuLabel, fr as MessageItemInlineStatusProps, fs as ListRowTop, ft as MessageQuotedPreviewAuthorName, g as InboxItemLeadingProps, gi as PreviewCardDescription, gn as MessageReactionCount, go as DropdownMenuPopup, gr as MessageItemSenderBadges, gs as RowTone, gt as MessageQuotedPreviewChannelProps, h as InboxItemLeading, ha as Popover, hi as PreviewCardContentProps, hn as MessageReactionChipProps, hr as MessageItemSender, hs as ListRowValueProps, ht as MessageQuotedPreviewChannel, i as InboxItemBody, ic as ButtonSize, ii as AvatarImageProps, in as MessageReferenceSuffix, io as DropdownMenuFooter, is as ListRowGroupProps, it as MessageQuotedPreviewAttachmentProps, j as InboxItemTimestampProps, ja as PopoverHeaderProps, ji as PreviewCardSeparator, jn as MessageReactionTooltipContentProps, jo as DropdownMenuSubmenu, jr as MessageItemEdited, js as DialogDescription, jt as MessageQuotedPreviewUnavailableProps, k as InboxItemSubtitleProps, ka as PopoverDescriptionProps, ki as PreviewCardPortalProps, kn as MessageReactionQuickRowProps, ko as DropdownMenuShortcut, kr as MessageItemContent, ks as DialogContent, kt as MessageQuotedPreviewTimestampProps, l as InboxItemContextProps, lc as StyledProps, ln as MessageReferenceUnavailableProps, lo as DropdownMenuItemLabel, lr as MessageItemHeader, ls as ListRowProps, m as InboxItemHoverTargetProps, mi as PreviewCardContent, mn as MessageReactionChip, mr as MessageItemMetaProps, ms as ListRowValue, mt as MessageQuotedPreviewAuthorProps, n as InboxItemActions, nc as Button, ni as AvatarGroupProps, no as DropdownMenuContent, ns as ListRowDescriptionProps, nt as MessageQuotedPreview, o as InboxItemContent, oc as buttonVariants, oi as AvatarSize, on as MessageReferenceText, oo as DropdownMenuItem, os as ListRowIconProps, ot as MessageQuotedPreviewAttachmentsProps, p as InboxItemHoverTarget, pn as MessageReactionAddButtonProps, po as DropdownMenuLabelProps, pr as MessageItemMeta, ps as ListRowTopProps, pt as MessageQuotedPreviewAuthorNameProps, q as MessageListDateDividerProps, qa as MobileNavLabel, qn as MessageItemReadReceipt, qo as Presence, qr as Avatar, qt as MessageReferenceChipProps, r as InboxItemActionsProps, rc as ButtonProps, ri as AvatarImage, ro as DropdownMenuContentProps, rs as ListRowGroup, rt as MessageQuotedPreviewAttachment, s as InboxItemContentProps, sc as VariantProps, si as PreviewCard, sn as MessageReferenceTextProps, so as DropdownMenuItemCount, ss as ListRowMeta, st as MessageQuotedPreviewAuthor, t as InboxItem, tc as PanelActionProps, ti as AvatarGroupCountProps, tn as MessageReferencePendingProps, to as DropdownMenuCheckboxItemProps, ts as ListRowDescription, tt as MessageListProps, u as InboxItemDensity, ui as PreviewCardArrow, un as MessageReferenceChipVariant, uo as DropdownMenuItemLabelProps, ur as MessageItemHeaderProps, us as ListRowTitle, ut as MessageQuotedPreviewAuthorMeta, v as InboxItemMarksProps, va as PopoverArrow, vn as MessageReactionErrorIndicator, vo as DropdownMenuPortal, vr as MessageItemSenderButton, vs as TextLinkProps, vt as MessageQuotedPreviewContentProps, w as InboxItemSelection, wa as PopoverClose, wn as MessageReactionPickerStatic, wo as DropdownMenuRadioItemIndicator, wr as MessageItemTimeProps, ws as Dialog, wt as MessageQuotedPreviewText, x as InboxItemMetadata, xa as PopoverBackdropProps, xn as MessageReactionGlyphProps, xo as DropdownMenuRadioGroup, xr as MessageItemSenderGroupProps, xt as MessageQuotedPreviewLoading, y as InboxItemMessage, ya as PopoverArrowProps, yn as MessageReactionErrorIndicatorProps, yo as DropdownMenuPortalProps, yr as MessageItemSenderButtonProps, ys as textLinkVariants, yt as MessageQuotedPreviewHeader, za as PopoverTitle, zi as TooltipContentProps, zn as MessageReactionTooltipNamesProps, zo as KbdGroupProps, zr as MessageItemAvatarSlot, zs as DialogNav, zt as MessageMultiSelectCheckbox } from "./inbox-item-ChGeZBFb.mjs";
1
+ import { $ as MessageListNoticeProps, $a as DropdownMenuCheckboxItemIndicator, $n as MessageItemToolbarButtonProps, $o as ListRowChevron, $r as AvatarGroup, $s as DialogTriggerProps, $t as MessageReferenceLabelProps, A as InboxItemTimestamp, Aa as PopoverHeader, Ai as PreviewCardProps, An as MessageReactionTooltipContent, Ao as DropdownMenuShortcutProps, Ar as MessageItemContentProps, As as DialogContentProps, At as MessageQuotedPreviewUnavailable, Ba as PopoverTitleProps, Bi as TooltipPortal, Bn as MessageReactionTooltipSeparator, Bo as KbdProps, Br as MessageItemAvatarSlotProps, Bs as DialogNavProps, Bt as MessageMultiSelectCheckboxProps, C as InboxItemProps, Ci as PreviewCardHeaderProps, Cn as MessageReactionPickerContentProps, Co as DropdownMenuRadioItem, Cr as MessageItemTime, Ct as MessageQuotedPreviewProps, D as InboxItemSenderProps, Da as PopoverContentProps, Di as PreviewCardPopupProps, Dn as MessageReactionQuickButtonProps, Do as DropdownMenuSeparator, Dr as MessageItemBody, Ds as DialogClose, Dt as MessageQuotedPreviewThreadProps, E as InboxItemSender, Ea as PopoverContent, Ei as PreviewCardPopup, En as MessageReactionQuickButton, Eo as DropdownMenuRadioItemProps, Er as MessageItemAttachmentsProps, Es as DialogBodyProps, Et as MessageQuotedPreviewThread, F as InboxItemTrailingProps, Fa as PopoverPortalProps, Fi as PreviewCardTrigger, Fn as MessageReactionTooltipNameProps, Fo as DropdownMenuTrigger, Fr as MessageItemFooter, Ft as MessageTextSelectionToolbarProps, Ga as MobileNavItem, Gi as TooltipTrigger, Gn as MessageItemBadgeSeparatorProps, Go as Checkbox, Gr as MessageItem, Gs as DialogProps, Gt as MessageMultiSelectToolbarProps, Ha as PopoverTriggerProps, Hi as TooltipProps, Hn as MessageItemBadge, Ho as BadgeProps, Hr as MessageItemContinuationTimeProps, Hs as DialogOverlayProps, Ht as MessageMultiSelectToolbar, I as InboxItemTrigger, Ia as PopoverProps, Ii as PreviewCardTriggerProps, In as MessageReactionTooltipNameText, Io as DropdownMenuTriggerProps, Ir as MessageItemFooterProps, Is as DialogFooterProps, It as MessageTextSelectionToolbarSeparator, J as MessageListEndFade, Ja as MobileNavLabelProps, Jn as MessageItemReadReceiptProps, Jo as ListRow, Jr as AvatarBadge, Js as DialogSurface, K as MessageListDateDivider, Ka as MobileNavItemProps, Ki as TooltipTriggerProps, Kn as MessageItemBadgeStatus, Ko as CheckboxProps, Kr as MessageItemProps, Kt as MessageReferenceChip, L as InboxItemTriggerProps, La as PopoverSeparator, Li as Tooltip, Ln as MessageReactionTooltipNameTextProps, Lo as Kbd, Lr as MessageItemSearchMatch, Ls as DialogHeader, Lt as MessageTextSelectionToolbarSeparatorProps, M as InboxItemTitle, Ma as PopoverPopup, Mi as PreviewCardSeparatorProps, Mn as MessageReactionTooltipMeta, Mo as DropdownMenuSubmenuProps, Mr as MessageItemEditedProps, Ms as DialogDescriptionProps, Mt as MessageTextSelectionToolbar, N as InboxItemTitleProps, Na as PopoverPopupProps, Ni as PreviewCardTitle, Nn as MessageReactionTooltipMetaProps, No as DropdownMenuSubmenuTrigger, Nr as MessageItemEmbedded, Ns as DialogFooter, Nt as MessageTextSelectionToolbarButton, O as InboxItemSubtitle, Oa as PopoverDescription, Oi as PreviewCardPortal, On as MessageReactionQuickRow, Oo as DropdownMenuSeparatorProps, Or as MessageItemBodyProps, Os as DialogCloseProps, Ot as MessageQuotedPreviewTimestamp, P as InboxItemTrailing, Pa as PopoverPortal, Pi as PreviewCardTitleProps, Pn as MessageReactionTooltipName, Po as DropdownMenuSubmenuTriggerProps, Pr as MessageItemEmbeddedProps, Pt as MessageTextSelectionToolbarButtonProps, Q as MessageListNotice, Qa as DropdownMenuCheckboxItem, Qn as MessageItemToolbarButton, Qo as ListRowBottomProps, Qr as AvatarFallbackProps, Qs as DialogTrigger, Qt as MessageReferenceLabel, Ra as PopoverSeparatorProps, Ri as TooltipContent, Rn as MessageReactionTooltipNames, Ro as KbdGroup, Rr as MessageItemSearchMatchProps, Rs as DialogHeaderProps, Rt as MessageMultiSelect, S as InboxItemMetadataProps, Si as PreviewCardHeader, Sn as MessageReactionPickerContent, So as DropdownMenuRadioGroupProps, Sr as MessageItemSenderProps, St as MessageQuotedPreviewLoadingProps, T as InboxItemSelectionProps, Ta as PopoverCloseProps, Tn as MessageReactionPickerStaticProps, To as DropdownMenuRadioItemIndicatorProps, Tr as MessageItemAttachments, Ts as DialogBody, Tt as MessageQuotedPreviewTextProps, Ua as PopoverViewport, Ui as TooltipProvider, Un as MessageItemBadgeProps, Uo as CheckboxIndicator, Ur as MessageItemGutter, Us as DialogPortal, Ut as MessageMultiSelectToolbarActions, Va as PopoverTrigger, Vi as TooltipPortalProps, Vn as MessageReactionTooltipSeparatorProps, Vo as Badge, Vr as MessageItemContinuationTime, Vs as DialogOverlay, Vt as MessageMultiSelectProps, Wa as PopoverViewportProps, Wi as TooltipProviderProps, Wn as MessageItemBadgeSeparator, Wo as CheckboxIndicatorProps, Wr as MessageItemGutterProps, Ws as DialogPortalProps, Wt as MessageMultiSelectToolbarActionsProps, X as MessageListHistoryLimited, Xa as MobileNavRootProps, Xn as MessageItemSavedIndicatorProps, Xo as ListRowBodyProps, Xr as AvatarBadgeProps, Xs as DialogTitle, Xt as MessageReferenceIndicator, Y as MessageListEndFadeProps, Ya as MobileNavRoot, Yn as MessageItemSavedIndicator, Yo as ListRowBody, Yr as AvatarBadgeOffset, Ys as DialogSurfaceProps, Z as MessageListHistoryLimitedProps, Za as DropdownMenu, Zn as MessageItemToolbar, Zo as ListRowBottom, Zr as AvatarFallback, Zs as DialogTitleProps, Zt as MessageReferenceIndicatorProps, _ as InboxItemMarks, _i as PreviewCardDescriptionProps, _n as MessageReactionCountProps, _o as DropdownMenuPopupProps, _r as MessageItemSenderBadgesProps, _s as TextLink, _t as MessageQuotedPreviewContent, a as InboxItemBodyProps, ac as DeprecatedButtonSize, ai as AvatarProps, an as MessageReferenceSuffixProps, ao as DropdownMenuFooterProps, as as ListRowIcon, at as MessageQuotedPreviewAttachments, b as InboxItemMessageProps, ba as PopoverBackdrop, bn as MessageReactionGlyph, bo as DropdownMenuProps, br as MessageItemSenderGroup, bt as MessageQuotedPreviewHeaderProps, c as InboxItemContext, cc as DataAttributes$1, cn as MessageReferenceUnavailable, co as DropdownMenuItemCountProps, cs as ListRowMetaProps, d as InboxItemHeading, di as PreviewCardArrowProps, dn as MessageReferenceTextVariant, do as DropdownMenuItemProps, dr as MessageItemInlineStatus, ds as ListRowTitleProps, dt as MessageQuotedPreviewAuthorMetaProps, ec as PanelAction, ei as AvatarGroupCount, en as MessageReferencePending, eo as DropdownMenuCheckboxItemIndicatorProps, er as MessageItemToolbarProps, es as ListRowChevronProps, et as MessageList, f as InboxItemHeadingProps, fn as MessageReactionAddButton, fo as DropdownMenuLabel, fr as MessageItemInlineStatusProps, fs as ListRowTop, ft as MessageQuotedPreviewAuthorName, g as InboxItemLeadingProps, gi as PreviewCardDescription, gn as MessageReactionCount, go as DropdownMenuPopup, gr as MessageItemSenderBadges, gs as RowTone, gt as MessageQuotedPreviewChannelProps, h as InboxItemLeading, ha as Popover, hi as PreviewCardContentProps, hn as MessageReactionChipProps, hr as MessageItemSender, hs as ListRowValueProps, ht as MessageQuotedPreviewChannel, i as InboxItemBody, ic as ButtonSize, ii as AvatarImageProps, in as MessageReferenceSuffix, io as DropdownMenuFooter, is as ListRowGroupProps, it as MessageQuotedPreviewAttachmentProps, j as InboxItemTimestampProps, ja as PopoverHeaderProps, ji as PreviewCardSeparator, jn as MessageReactionTooltipContentProps, jo as DropdownMenuSubmenu, jr as MessageItemEdited, js as DialogDescription, jt as MessageQuotedPreviewUnavailableProps, k as InboxItemSubtitleProps, ka as PopoverDescriptionProps, ki as PreviewCardPortalProps, kn as MessageReactionQuickRowProps, ko as DropdownMenuShortcut, kr as MessageItemContent, ks as DialogContent, kt as MessageQuotedPreviewTimestampProps, l as InboxItemContextProps, lc as StyledProps, ln as MessageReferenceUnavailableProps, lo as DropdownMenuItemLabel, lr as MessageItemHeader, ls as ListRowProps, m as InboxItemHoverTargetProps, mi as PreviewCardContent, mn as MessageReactionChip, mr as MessageItemMetaProps, ms as ListRowValue, mt as MessageQuotedPreviewAuthorProps, n as InboxItemActions, nc as Button, ni as AvatarGroupProps, no as DropdownMenuContent, ns as ListRowDescriptionProps, nt as MessageQuotedPreview, o as InboxItemContent, oc as buttonVariants, oi as AvatarSize, on as MessageReferenceText, oo as DropdownMenuItem, os as ListRowIconProps, ot as MessageQuotedPreviewAttachmentsProps, p as InboxItemHoverTarget, pn as MessageReactionAddButtonProps, po as DropdownMenuLabelProps, pr as MessageItemMeta, ps as ListRowTopProps, pt as MessageQuotedPreviewAuthorNameProps, q as MessageListDateDividerProps, qa as MobileNavLabel, qn as MessageItemReadReceipt, qo as Presence, qr as Avatar, qt as MessageReferenceChipProps, r as InboxItemActionsProps, rc as ButtonProps, ri as AvatarImage, ro as DropdownMenuContentProps, rs as ListRowGroup, rt as MessageQuotedPreviewAttachment, s as InboxItemContentProps, sc as VariantProps, si as PreviewCard, sn as MessageReferenceTextProps, so as DropdownMenuItemCount, ss as ListRowMeta, st as MessageQuotedPreviewAuthor, t as InboxItem, tc as PanelActionProps, ti as AvatarGroupCountProps, tn as MessageReferencePendingProps, to as DropdownMenuCheckboxItemProps, ts as ListRowDescription, tt as MessageListProps, u as InboxItemDensity, ui as PreviewCardArrow, un as MessageReferenceChipVariant, uo as DropdownMenuItemLabelProps, ur as MessageItemHeaderProps, us as ListRowTitle, ut as MessageQuotedPreviewAuthorMeta, v as InboxItemMarksProps, va as PopoverArrow, vn as MessageReactionErrorIndicator, vo as DropdownMenuPortal, vr as MessageItemSenderButton, vs as TextLinkProps, vt as MessageQuotedPreviewContentProps, w as InboxItemSelection, wa as PopoverClose, wn as MessageReactionPickerStatic, wo as DropdownMenuRadioItemIndicator, wr as MessageItemTimeProps, ws as Dialog, wt as MessageQuotedPreviewText, x as InboxItemMetadata, xa as PopoverBackdropProps, xn as MessageReactionGlyphProps, xo as DropdownMenuRadioGroup, xr as MessageItemSenderGroupProps, xt as MessageQuotedPreviewLoading, y as InboxItemMessage, ya as PopoverArrowProps, yn as MessageReactionErrorIndicatorProps, yo as DropdownMenuPortalProps, yr as MessageItemSenderButtonProps, ys as textLinkVariants, yt as MessageQuotedPreviewHeader, za as PopoverTitle, zi as TooltipContentProps, zn as MessageReactionTooltipNamesProps, zo as KbdGroupProps, zr as MessageItemAvatarSlot, zs as DialogNav, zt as MessageMultiSelectCheckbox } from "./inbox-item-CiTYKTly.mjs";
2
2
  import { cn } from "./cn.mjs";
3
3
  import { Dialog as Dialog$1 } from "@base-ui/react/dialog";
4
4
  import { CSSProperties, ComponentProps, ComponentPropsWithRef, ComponentPropsWithoutRef, ComponentType, CompositionEventHandler, ElementType, FocusEventHandler, FormEventHandler, HTMLAttributes, KeyboardEventHandler, PointerEvent, ReactElement, ReactNode, Ref, RefObject, SVGProps } from "react";
@@ -4287,7 +4287,9 @@ interface VirtualListProps<T> extends VirtualListNativeProps {
4287
4287
  ref?: never;
4288
4288
  /**
4289
4289
  * Called when the content's height changes: a row resizes or mounts measured, the spacer's
4290
- * height changes, or the `footer` / `empty` element resizes (to follow the end of a chat).
4290
+ * height changes, or the `footer` / `empty` element resizes (to follow the end of a chat). Not
4291
+ * called for a change the list scrolls away exactly (rows above the view measured as it scrolls
4292
+ * up): it moves nothing in view, nor the distance from the view to the end.
4291
4293
  */
4292
4294
  onContentResize?: (() => void) | undefined;
4293
4295
  /**