@botiverse/raft-ui 0.20.0 → 0.21.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/dist/tokens.json CHANGED
@@ -2686,6 +2686,30 @@
2686
2686
  }
2687
2687
  }
2688
2688
  },
2689
+ "timeline": {
2690
+ "$type": "dimension",
2691
+ "gap-message": {
2692
+ "$value": {
2693
+ "value": 16,
2694
+ "unit": "px"
2695
+ },
2696
+ "$description": "The message step of a timeline: from the last line of one turn to the first line of the next (a sender line, an event line). Every row keeps the row inset above and below its text; the first row of a turn adds the rest above it."
2697
+ },
2698
+ "gap-section": {
2699
+ "$value": {
2700
+ "value": 24,
2701
+ "unit": "px"
2702
+ },
2703
+ "$description": "The section step of a timeline, one step wider than the message step: either side of a date line, from the top of the list to the first line, and from the last line to the composer, so a boundary reads as one and the last message never sits on the composer."
2704
+ },
2705
+ "row-inset": {
2706
+ "$value": {
2707
+ "value": 4,
2708
+ "unit": "px"
2709
+ },
2710
+ "$description": "How far a timeline row's hover and selected highlight reaches above and below its text. Two rows of one turn sit two insets apart."
2711
+ }
2712
+ },
2689
2713
  "sticker": {
2690
2714
  "$type": "color",
2691
2715
  "ink": {
@@ -12,6 +12,7 @@ import { Checkbox } from "@base-ui/react/checkbox";
12
12
  import { ScrollArea } from "@base-ui/react/scroll-area";
13
13
  import { Avatar } from "@base-ui/react";
14
14
  import { Menu } from "@base-ui/react/menu";
15
+ import { flushSync } from "react-dom";
15
16
  import { Toggle } from "@base-ui/react/toggle";
16
17
  import { Toolbar } from "@base-ui/react/toolbar";
17
18
  import { PointerSensor, TouchSensor, useSensor } from "@dnd-kit/core";
@@ -624,6 +625,7 @@ const badge = tv$1({
624
625
  "font-sans text-caption font-semibold normal-case tracking-normal",
625
626
  "transition-[filter,opacity] duration-100",
626
627
  "[&_svg]:size-3.5 [&_svg]:shrink-0 [&_[data-slot='spinner']]:size-3 [&_[data-slot='spinner']]:text-xs",
628
+ "*:data-[slot=status]:lead-dot",
627
629
  "disabled:cursor-not-allowed disabled:bg-fill-muted disabled:text-foreground-disabled disabled:opacity-100 disabled:inset-ring-0"
628
630
  ] },
629
631
  variants: {
@@ -797,6 +799,36 @@ function Experimental(props) {
797
799
  }
798
800
  const Badge = Object.assign(BadgeRoot, { Experimental });
799
801
  //#endregion
802
+ //#region src/components/text-link/text-link.tsx
803
+ const textLinkVariants = tv$1({
804
+ base: [
805
+ "rounded-[2px]",
806
+ "decoration-[1.5px] underline-offset-[3px] not-disabled:hover:underline",
807
+ "outline-none focus-visible:shadow-focus",
808
+ "disabled:cursor-not-allowed disabled:text-foreground-disabled"
809
+ ],
810
+ variants: { variant: {
811
+ muted: ["font-medium text-foreground-muted", "hover:text-foreground"],
812
+ strong: ["font-semibold text-foreground"]
813
+ } },
814
+ defaultVariants: { variant: "muted" }
815
+ });
816
+ function TextLink({ variant, className, render, ...props }) {
817
+ const defaultProps = {
818
+ className: textLinkVariants({
819
+ variant,
820
+ className
821
+ }),
822
+ ...render ? {} : { type: "button" }
823
+ };
824
+ return useRender({
825
+ defaultTagName: "button",
826
+ render,
827
+ props: mergeProps(defaultProps, props),
828
+ state: { slot: "text-link" }
829
+ });
830
+ }
831
+ //#endregion
800
832
  //#region src/components/tooltip/tooltip.tsx
801
833
  const tooltip = tv$1({
802
834
  slots: {
@@ -942,7 +974,7 @@ const CONTENT_COLLISION_AVOIDANCE = {
942
974
  align: "shift",
943
975
  fallbackAxisSide: "none"
944
976
  };
945
- function TooltipContent({ align = "center", alignOffset = 0, anchor, arrowPadding, collisionAvoidance = CONTENT_COLLISION_AVOIDANCE, collisionBoundary, collisionPadding, disableAnchorTracking = false, positionMethod = "fixed", side = "top", sideOffset, sticky, container, portalProps, className, children, ...props }) {
977
+ function TooltipContent({ align = "center", alignOffset = 0, anchor, arrowPadding, collisionAvoidance = CONTENT_COLLISION_AVOIDANCE, collisionBoundary, collisionPadding, disableAnchorTracking, positionMethod = "fixed", side = "top", sideOffset, sticky, container, portalProps, className, children, ...props }) {
946
978
  const { positioner, content } = tooltip();
947
979
  const portalContainer = container !== void 0 ? container : portalProps?.container;
948
980
  return /* @__PURE__ */ jsx(TooltipPortal, {
@@ -1050,7 +1082,9 @@ const checkbox = tv$1({ slots: {
1050
1082
  "relative inline-flex size-5 shrink-0 touch-manipulation items-center justify-center outline-none",
1051
1083
  "rounded-sticker focus-visible:shadow-focus",
1052
1084
  "data-disabled:cursor-not-allowed",
1053
- "after:absolute after:-inset-x-3 after:-inset-y-2 after:content-['']"
1085
+ "after:absolute after:-inset-x-3 after:-inset-y-2 after:content-[''] pointer-coarse:after:-inset-y-3",
1086
+ "[label>&]:my-[max(0px,calc((1lh-1.25rem)/2))]",
1087
+ "[label>&]:after:-inset-y-[calc(max(0px,(1lh-1.25rem)/2)+4px)]"
1054
1088
  ],
1055
1089
  indicator: "pointer-events-none"
1056
1090
  } });
@@ -1401,7 +1435,7 @@ function DropdownMenuPopup({ className, ...props }) {
1401
1435
  ...props
1402
1436
  });
1403
1437
  }
1404
- function DropdownMenuContent({ align = "start", alignOffset = 0, anchor, arrowPadding, collisionAvoidance, collisionBoundary, collisionPadding, disableAnchorTracking = false, positionMethod = "fixed", side = "bottom", sideOffset, sticky, portalProps, className, ...props }) {
1438
+ function DropdownMenuContent({ align = "start", alignOffset = 0, anchor, arrowPadding, collisionAvoidance, collisionBoundary, collisionPadding, disableAnchorTracking, positionMethod = "fixed", side = "bottom", sideOffset, sticky, portalProps, className, ...props }) {
1405
1439
  const resolvedSideOffset = sideOffset ?? 6;
1406
1440
  const { positioner, content } = dropdownMenu();
1407
1441
  return /* @__PURE__ */ jsx(DropdownMenuPortal, {
@@ -1589,10 +1623,157 @@ function DropdownMenuCheckboxItemIndicator({ className, ...props }) {
1589
1623
  ...props
1590
1624
  });
1591
1625
  }
1626
+ function contentBox(element) {
1627
+ const rect = element.getBoundingClientRect();
1628
+ if (rect.width === 0 && rect.height === 0) return void 0;
1629
+ const style = element.ownerDocument.defaultView?.getComputedStyle(element);
1630
+ const px = (value) => Number.parseFloat(value ?? "") || 0;
1631
+ return {
1632
+ left: rect.left + px(style?.borderLeftWidth) + px(style?.paddingLeft),
1633
+ right: rect.right - px(style?.borderRightWidth) - px(style?.paddingRight),
1634
+ top: rect.top + px(style?.borderTopWidth) + px(style?.paddingTop),
1635
+ bottom: rect.bottom - px(style?.borderBottomWidth) - px(style?.paddingBottom)
1636
+ };
1637
+ }
1638
+ /**
1639
+ * Whether laid-out text `rects` overflow `box`: past either inline edge, or
1640
+ * on a line whose middle is below the bottom edge (a clamped line is still
1641
+ * laid out, below the box; the middle, not the top, so a glyph box taller
1642
+ * than a tight line-height does not count as a cut).
1643
+ */
1644
+ function overflows(rects, box) {
1645
+ for (const rect of Array.from(rects)) {
1646
+ if (rect.width === 0 && rect.height === 0) continue;
1647
+ if (rect.right > box.right + .5 || rect.left < box.left - .5) return true;
1648
+ if (rect.top + rect.height / 2 > box.bottom + .5) return true;
1649
+ }
1650
+ return false;
1651
+ }
1652
+ /** Whether the text inside `element` overflows its content box. */
1653
+ function measureElement(element) {
1654
+ if (!element.isConnected) return void 0;
1655
+ const box = contentBox(element);
1656
+ if (!box) return void 0;
1657
+ const range = element.ownerDocument.createRange();
1658
+ range.selectNodeContents(element);
1659
+ return overflows(range.getClientRects(), box);
1660
+ }
1661
+ /**
1662
+ * Whether the inline `content` overflows `text`, the box that clips it.
1663
+ * Used where `text` holds more than the content (an Ellipsis's floats).
1664
+ */
1665
+ function measureContent(text, content) {
1666
+ if (!text.isConnected) return void 0;
1667
+ const box = contentBox(text);
1668
+ if (!box) return void 0;
1669
+ return overflows(content.getClientRects(), box);
1670
+ }
1671
+ /** Isolates, reads and restores one target now, outside the batch. */
1672
+ function readNow(target) {
1673
+ const restore = target.isolate?.();
1674
+ try {
1675
+ return target.read();
1676
+ } finally {
1677
+ restore?.();
1678
+ }
1679
+ }
1680
+ const targets = /* @__PURE__ */ new Set();
1681
+ const byElement = /* @__PURE__ */ new WeakMap();
1682
+ const pending = /* @__PURE__ */ new Set();
1683
+ let frame = 0;
1684
+ let resizeObserver;
1685
+ let mutationObserver;
1686
+ let fontsListening = false;
1687
+ function flush() {
1688
+ frame = 0;
1689
+ const batch = Array.from(pending).filter((target) => targets.has(target));
1690
+ pending.clear();
1691
+ const restores = batch.map((target) => target.isolate?.());
1692
+ const results = batch.map((target) => target.read());
1693
+ for (const restore of restores) restore?.();
1694
+ flushSync(() => {
1695
+ batch.forEach((target, index) => {
1696
+ if (targets.has(target)) target.commit(results[index]);
1697
+ });
1698
+ });
1699
+ }
1700
+ /** Asks for `target` to be measured in the next frame, before it paints. */
1701
+ function scheduleMeasure(target) {
1702
+ if (!targets.has(target)) return;
1703
+ pending.add(target);
1704
+ if (frame === 0 && typeof requestAnimationFrame === "function") frame = requestAnimationFrame(flush);
1705
+ }
1706
+ function scheduleAll() {
1707
+ for (const target of targets) scheduleMeasure(target);
1708
+ }
1709
+ function ownerOf(node) {
1710
+ for (let current = node; current; current = current.parentNode) {
1711
+ const target = byElement.get(current);
1712
+ if (target) return target;
1713
+ }
1714
+ }
1715
+ function observers(view) {
1716
+ if (!resizeObserver && "ResizeObserver" in view) resizeObserver = new view.ResizeObserver((entries) => {
1717
+ for (const entry of entries) {
1718
+ const target = byElement.get(entry.target);
1719
+ if (target) scheduleMeasure(target);
1720
+ }
1721
+ });
1722
+ if (!mutationObserver && "MutationObserver" in view) mutationObserver = new view.MutationObserver((records) => {
1723
+ for (const record of records) {
1724
+ const target = ownerOf(record.target);
1725
+ if (target) scheduleMeasure(target);
1726
+ }
1727
+ });
1728
+ const fonts = view.document.fonts;
1729
+ if (!fontsListening && fonts && typeof fonts.addEventListener === "function") {
1730
+ fonts.addEventListener("loadingdone", scheduleAll);
1731
+ fontsListening = true;
1732
+ }
1733
+ }
1734
+ /**
1735
+ * Starts watching `target`: the elements it names, the text under `watch`
1736
+ * and the page's fonts. Measures it in the next frame. Returns the cleanup.
1737
+ */
1738
+ function observeTruncation(target) {
1739
+ const observed = target.observe().filter((element) => element != null);
1740
+ const first = observed[0];
1741
+ const view = first?.ownerDocument.defaultView;
1742
+ if (!first || !view) return () => void 0;
1743
+ observers(view);
1744
+ targets.add(target);
1745
+ for (const element of observed) {
1746
+ byElement.set(element, target);
1747
+ resizeObserver?.observe(element);
1748
+ }
1749
+ const watched = target.watch();
1750
+ if (watched) {
1751
+ byElement.set(watched, target);
1752
+ mutationObserver?.observe(watched, {
1753
+ childList: true,
1754
+ characterData: true,
1755
+ subtree: true
1756
+ });
1757
+ }
1758
+ scheduleMeasure(target);
1759
+ return () => {
1760
+ targets.delete(target);
1761
+ pending.delete(target);
1762
+ for (const element of observed) {
1763
+ if (byElement.get(element) === target) byElement.delete(element);
1764
+ resizeObserver?.unobserve(element);
1765
+ }
1766
+ if (watched && byElement.get(watched) === target) byElement.delete(watched);
1767
+ if (targets.size === 0) {
1768
+ mutationObserver?.disconnect();
1769
+ mutationObserver = void 0;
1770
+ }
1771
+ };
1772
+ }
1592
1773
  //#endregion
1593
1774
  //#region src/lib/use-overflow-title.ts
1594
1775
  function cut(element) {
1595
- return element.scrollWidth > element.clientWidth + 1 || element.scrollHeight > element.clientHeight + 1;
1776
+ return measureElement(element) === true;
1596
1777
  }
1597
1778
  function assign(ref, node) {
1598
1779
  if (typeof ref === "function") ref(node);
@@ -1621,25 +1802,18 @@ function useOverflowTitle(ref, title) {
1621
1802
  cleanup.current = void 0;
1622
1803
  assign(ref, node);
1623
1804
  const view = node?.ownerDocument.defaultView;
1624
- if (!node || own || !view || !("ResizeObserver" in view)) return;
1625
- const update = () => {
1626
- const text = node.textContent?.trim() ?? "";
1627
- if (text && (cut(node) || Array.from(node.children).some(cut))) node.title = text;
1628
- else node.removeAttribute("title");
1629
- };
1630
- const resize = new view.ResizeObserver(update);
1631
- resize.observe(node);
1632
- for (const child of Array.from(node.children)) resize.observe(child);
1633
- const mutation = new view.MutationObserver(update);
1634
- mutation.observe(node, {
1635
- childList: true,
1636
- characterData: true,
1637
- subtree: true
1805
+ if (!node || own || !view) return;
1806
+ const children = Array.from(node.children);
1807
+ cleanup.current = observeTruncation({
1808
+ observe: () => [node, ...children],
1809
+ watch: () => node,
1810
+ read: () => cut(node) || children.some(cut),
1811
+ commit: (truncated) => {
1812
+ const text = node.textContent?.trim() ?? "";
1813
+ if (text && truncated) node.title = text;
1814
+ else node.removeAttribute("title");
1815
+ }
1638
1816
  });
1639
- cleanup.current = () => {
1640
- resize.disconnect();
1641
- mutation.disconnect();
1642
- };
1643
1817
  }, [own, ref]);
1644
1818
  }
1645
1819
  //#endregion
@@ -1936,7 +2110,7 @@ const messageItem = tv$1({
1936
2110
  "group/message relative flex h-fit gap-3",
1937
2111
  "hover:[--mi-toolbar-opacity:1] hover:[--mi-toolbar-pe:auto] focus-within:[--mi-toolbar-opacity:1] focus-within:[--mi-toolbar-pe:auto]",
1938
2112
  "has-data-popup-open:[--mi-toolbar-opacity:1] has-data-popup-open:[--mi-toolbar-pe:auto]",
1939
- "min-h-0 px-2 py-1 border-t-8 border-transparent bg-clip-padding",
2113
+ "min-h-0 px-2 py-timeline-row border-t-(length:--spacing-timeline-turn) border-transparent bg-clip-padding",
1940
2114
  "hover:[--mi-ct-color:var(--foreground-hint)] has-data-popup-open:[--mi-ct-color:var(--foreground-hint)]",
1941
2115
  "bg-(--mi-row-fill) [--mi-row-fill:initial]",
1942
2116
  "hover:[--mi-row-fill:var(--fill-subtle)]",
@@ -3115,10 +3289,15 @@ const messageList = tv$1({
3115
3289
  root: ["relative h-full min-h-0"],
3116
3290
  viewport: ["min-w-0 overscroll-none"],
3117
3291
  content: ["flex min-h-full w-full min-w-0 flex-col"],
3118
- dateDividerRoot: ["flex select-none items-center", "gap-2 px-4 py-3"],
3292
+ dateDividerRoot: [
3293
+ "flex select-none items-center",
3294
+ "gap-2 px-4",
3295
+ "pt-[calc(var(--spacing-timeline-section)-var(--spacing-timeline-row)-var(--text-mono-meta--line-height)/2)]",
3296
+ "pb-[calc(var(--spacing-timeline-section)-var(--spacing-timeline-lead)-var(--text-mono-meta--line-height)/2)]"
3297
+ ],
3119
3298
  dateDividerRule: ["flex-1", "min-w-3 border-t border-line-hairline"],
3120
3299
  dateDividerChip: ["inline-flex items-center", "font-mono text-mono-meta whitespace-nowrap text-foreground-hint"],
3121
- notice: ["text-center", "pb-2 font-mono text-mono-meta"],
3300
+ notice: ["text-center", "pt-timeline-lead pb-timeline-row font-mono text-mono-meta"],
3122
3301
  historyLimited: [
3123
3302
  "inline-flex items-center",
3124
3303
  "h-[22px] gap-1 rounded-chip px-1.5",
@@ -3407,4 +3586,4 @@ function useMouseOnlyPointerSensor(distance) {
3407
3586
  return useSensor(MouseOnlyPointerSensor, options);
3408
3587
  }
3409
3588
  //#endregion
3410
- export { MessageReactionTooltipContent as $, useTheme as $n, DropdownMenuRadioGroup as $t, messageEmbed as A, TooltipTrigger as An, MessageItemAvatarSlot as At, MessageReferenceLabel as B, DialogOverlay as Bn, AvatarImage as Bt, MessageQuotedPreviewThread as C, Checkbox$1 as Cn, MessageItemAttachments as Ct, MessageEmbedContent as D, TooltipContent as Dn, MessageItemEmbedded as Dt, MessageEmbed as E, Tooltip$1 as En, MessageItemEdited as Et, MessageMultiSelectCheckbox as F, DialogContent as Fn, Avatar$1 as Ft, MessageReactionChip as G, Button$1 as Gn, DropdownMenuContent as Gt, MessageReferenceText as H, DialogSurface as Hn, DropdownMenu as Ht, MessageMultiSelectToolbar as I, DialogDescription as In, AvatarBadge as It, MessageReactionGlyph as J, defaultNativeButton as Jn, DropdownMenuItemCount as Jt, MessageReactionCount as K, buttonVariants as Kn, DropdownMenuFooter as Kt, MessageMultiSelectToolbarActions as L, DialogFooter as Ln, AvatarFallback as Lt, MessageTextSelectionToolbarButton as M, Dialog$1 as Mn, MessageItemGutter as Mt, MessageTextSelectionToolbarSeparator as N, DialogBody as Nn, MessageItem as Nt, MessageEmbedFooter as O, TooltipPortal as On, MessageItemFooter as Ot, MessageMultiSelect as P, DialogClose as Pn, searchHit as Pt, MessageReactionQuickRow as Q, useThemeScopeProps as Qn, DropdownMenuPortal as Qt, MessageReferenceChip as R, DialogHeader as Rn, AvatarGroup as Rt, MessageQuotedPreviewText as S, useMobileViewport as Sn, MessageItemTime as St, MessageQuotedPreviewUnavailable as T, PRESENCE_COLOR as Tn, MessageItemContent as Tt, MessageReferenceUnavailable as U, DialogTitle as Un, DropdownMenuCheckboxItem as Ut, MessageReferencePending as V, DialogPortal as Vn, useOverflowTitle as Vt, MessageReactionAddButton as W, DialogTrigger as Wn, DropdownMenuCheckboxItemIndicator as Wt, MessageReactionPickerStatic as X, withOverlayLayer as Xn, DropdownMenuLabel as Xt, MessageReactionPickerContent as Y, useParentOverlayKind as Yn, DropdownMenuItemLabel as Yt, MessageReactionQuickButton as Z, resolveThemeScopeProps as Zn, DropdownMenuPopup as Zt, MessageQuotedPreviewAuthorName as _, ScrollAreaContent as _n, MessageItemMeta as _t, MessageListJumpPillDismiss as a, DropdownMenuSubmenuTrigger as an, decisionWidth as ar, MessageItemBadge as at, MessageQuotedPreviewHeader as b, ScrollAreaThumb as bn, MessageItemSenderButton as bt, MessageListHistoryLimited as c, KbdGroup as cn, MessageItemSavedIndicator as ct, MessageQuotedPreview as d, PanelFooter as dn, MessageItemDelegatedAvatar as dt, DropdownMenuRadioItem as en, ThemeStateContext as er, MessageReactionTooltipMeta as et, MessageQuotedPreviewAttachment as f, PanelHeaderRoot as fn, MessageItemDelegatedBy as ft, MessageQuotedPreviewAuthorMeta as g, ScrollArea$1 as gn, MessageItemInlineStatus as gt, MessageQuotedPreviewAuthorDelegatedBy as h, PanelSection as hn, MessageItemHeader as ht, MessageListJumpPill as i, DropdownMenuSubmenu as in, headEdges as ir, MessageReactionTooltipSeparator as it, MessageTextSelectionToolbar as j, Badge as jn, MessageItemContinuationTime as jt, MessageEmbedHeader as k, TooltipProvider as kn, MessageItemSearchMatch as kt, MessageListNotice as l, Panel as ln, MessageItemToolbar as lt, MessageQuotedPreviewAuthor as m, PanelScrollViewport as mn, MessageItemDelegatedByName as mt, useMouseOnlyPointerSensor as n, DropdownMenuSeparator as nn, controlIconInset as nr, MessageReactionTooltipNameText as nt, MessageListJumpPillGroup as o, DropdownMenuTrigger as on, MessageItemBadgeSeparator as ot, MessageQuotedPreviewAttachments as p, PanelScrollContent as pn, MessageItemDelegatedByButton as pt, MessageReactionErrorIndicator as q, Spinner as qn, DropdownMenuItem as qt, MessageListJumpControls as r, DropdownMenuShortcut as rn, headEdgePull as rr, MessageReactionTooltipNames as rt, MessageListDateDivider as s, Kbd as sn, MessageItemReadReceipt as st, useHoldThenMoveTouchSensor as t, DropdownMenuRadioItemIndicator as tn, tv$1 as tr, MessageReactionTooltipName as tt, MessageList as u, PanelBody as un, MessageItemToolbarButton as ut, MessageQuotedPreviewChannel as v, ScrollAreaCorner as vn, MessageItemSender as vt, MessageQuotedPreviewTimestamp as w, CheckboxIndicator as wn, MessageItemBody as wt, MessageQuotedPreviewLoading as x, ScrollAreaViewport as xn, MessageItemSenderGroup as xt, MessageQuotedPreviewContent as y, ScrollAreaScrollbar as yn, MessageItemSenderBadges as yt, MessageReferenceIndicator as z, DialogNav as zn, AvatarGroupCount as zt };
3589
+ export { MessageReactionTooltipContent as $, Spinner as $n, DropdownMenuItemLabel as $t, messageEmbed as A, Tooltip$1 as An, MessageItemAvatarSlot as At, MessageReferenceLabel as B, DialogClose as Bn, AvatarImage as Bt, MessageQuotedPreviewThread as C, ScrollAreaScrollbar as Cn, MessageItemAttachments as Ct, MessageEmbedContent as D, Checkbox$1 as Dn, MessageItemEmbedded as Dt, MessageEmbed as E, useMobileViewport as En, MessageItemEdited as Et, MessageMultiSelectCheckbox as F, TextLink as Fn, Avatar$1 as Ft, MessageReactionChip as G, DialogNav as Gn, readNow as Gt, MessageReferenceText as H, DialogDescription as Hn, measureContent as Ht, MessageMultiSelectToolbar as I, textLinkVariants as In, AvatarBadge as It, MessageReactionGlyph as J, DialogSurface as Jn, DropdownMenuCheckboxItemIndicator as Jt, MessageReactionCount as K, DialogOverlay as Kn, DropdownMenu as Kt, MessageMultiSelectToolbarActions as L, Badge as Ln, AvatarFallback as Lt, MessageTextSelectionToolbarButton as M, TooltipPortal as Mn, MessageItemGutter as Mt, MessageTextSelectionToolbarSeparator as N, TooltipProvider as Nn, MessageItem as Nt, MessageEmbedFooter as O, CheckboxIndicator as On, MessageItemFooter as Ot, MessageMultiSelect as P, TooltipTrigger as Pn, searchHit as Pt, MessageReactionQuickRow as Q, buttonVariants as Qn, DropdownMenuItemCount as Qt, MessageReferenceChip as R, Dialog$1 as Rn, AvatarGroup as Rt, MessageQuotedPreviewText as S, ScrollAreaCorner as Sn, MessageItemTime as St, MessageQuotedPreviewUnavailable as T, ScrollAreaViewport as Tn, MessageItemContent as Tt, MessageReferenceUnavailable as U, DialogFooter as Un, measureElement as Ut, MessageReferencePending as V, DialogContent as Vn, useOverflowTitle as Vt, MessageReactionAddButton as W, DialogHeader as Wn, observeTruncation as Wt, MessageReactionPickerStatic as X, DialogTrigger as Xn, DropdownMenuFooter as Xt, MessageReactionPickerContent as Y, DialogTitle as Yn, DropdownMenuContent as Yt, MessageReactionQuickButton as Z, Button$1 as Zn, DropdownMenuItem as Zt, MessageQuotedPreviewAuthorName as _, PanelScrollContent as _n, MessageItemMeta as _t, MessageListJumpPillDismiss as a, DropdownMenuRadioItemIndicator as an, useTheme as ar, MessageItemBadge as at, MessageQuotedPreviewHeader as b, ScrollArea$1 as bn, MessageItemSenderButton as bt, MessageListHistoryLimited as c, DropdownMenuSubmenu as cn, controlIconInset as cr, MessageItemSavedIndicator as ct, MessageQuotedPreview as d, Kbd as dn, decisionWidth as dr, MessageItemDelegatedAvatar as dt, DropdownMenuLabel as en, defaultNativeButton as er, MessageReactionTooltipMeta as et, MessageQuotedPreviewAttachment as f, KbdGroup as fn, MessageItemDelegatedBy as ft, MessageQuotedPreviewAuthorMeta as g, PanelHeaderRoot as gn, MessageItemInlineStatus as gt, MessageQuotedPreviewAuthorDelegatedBy as h, PanelFooter as hn, MessageItemHeader as ht, MessageListJumpPill as i, DropdownMenuRadioItem as in, useThemeScopeProps as ir, MessageReactionTooltipSeparator as it, MessageTextSelectionToolbar as j, TooltipContent as jn, MessageItemContinuationTime as jt, MessageEmbedHeader as k, PRESENCE_COLOR as kn, MessageItemSearchMatch as kt, MessageListNotice as l, DropdownMenuSubmenuTrigger as ln, headEdgePull as lr, MessageItemToolbar as lt, MessageQuotedPreviewAuthor as m, PanelBody as mn, MessageItemDelegatedByName as mt, useMouseOnlyPointerSensor as n, DropdownMenuPortal as nn, withOverlayLayer as nr, MessageReactionTooltipNameText as nt, MessageListJumpPillGroup as o, DropdownMenuSeparator as on, ThemeStateContext as or, MessageItemBadgeSeparator as ot, MessageQuotedPreviewAttachments as p, Panel as pn, MessageItemDelegatedByButton as pt, MessageReactionErrorIndicator as q, DialogPortal as qn, DropdownMenuCheckboxItem as qt, MessageListJumpControls as r, DropdownMenuRadioGroup as rn, resolveThemeScopeProps as rr, MessageReactionTooltipNames as rt, MessageListDateDivider as s, DropdownMenuShortcut as sn, tv$1 as sr, MessageItemReadReceipt as st, useHoldThenMoveTouchSensor as t, DropdownMenuPopup as tn, useParentOverlayKind as tr, MessageReactionTooltipName as tt, MessageList as u, DropdownMenuTrigger as un, headEdges as ur, MessageItemToolbarButton as ut, MessageQuotedPreviewChannel as v, PanelScrollViewport as vn, MessageItemSender as vt, MessageQuotedPreviewTimestamp as w, ScrollAreaThumb as wn, MessageItemBody as wt, MessageQuotedPreviewLoading as x, ScrollAreaContent as xn, MessageItemSenderGroup as xt, MessageQuotedPreviewContent as y, PanelSection as yn, MessageItemSenderBadges as yt, MessageReferenceIndicator as z, DialogBody as zn, AvatarGroupCount as zt };
package/dist/wip.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as MessageQuotedPreviewAuthorDelegatedBy, Di as DialogContentProps, Gi as DialogTrigger, Ji as ButtonProps, Qi as StyledProps, Wi as DialogTitleProps, Zi as DataAttributes, _n as MessageItemDelegatedByProps, a as MessageListJumpPillDismissProps, c as MessageListJumpPillProps, dn as MessageItemDelegatedAvatarProps, fn as MessageItemDelegatedBy, gn as MessageItemDelegatedByNameProps, hn as MessageItemDelegatedByName, i as MessageListJumpPillDismiss, mn as MessageItemDelegatedByButtonProps, n as MessageListJumpControlsProps, o as MessageListJumpPillGroup, pn as MessageItemDelegatedByButton, r as MessageListJumpPill, s as MessageListJumpPillGroupProps, t as MessageListJumpControls, un as MessageItemDelegatedAvatar, w as MessageQuotedPreviewAuthorDelegatedByProps, wi as DialogClose, xi as Dialog } from "./index-RFu5pOr7.mjs";
2
- import { CSSProperties, ComponentPropsWithRef, PointerEvent, ReactNode } from "react";
1
+ import { Ai as DialogContentProps, C as MessageQuotedPreviewAuthorDelegatedBy, Di as DialogClose, Ji as DialogTrigger, Si as TextLinkProps, Zi as ButtonProps, _n as MessageItemDelegatedByProps, a as MessageListJumpPillDismissProps, c as MessageListJumpPillProps, dn as MessageItemDelegatedAvatarProps, fn as MessageItemDelegatedBy, gn as MessageItemDelegatedByNameProps, hn as MessageItemDelegatedByName, i as MessageListJumpPillDismiss, mn as MessageItemDelegatedByButtonProps, n as MessageListJumpControlsProps, na as DataAttributes, o as MessageListJumpPillGroup, pn as MessageItemDelegatedByButton, qi as DialogTitleProps, r as MessageListJumpPill, ra as StyledProps, s as MessageListJumpPillGroupProps, t as MessageListJumpControls, un as MessageItemDelegatedAvatar, w as MessageQuotedPreviewAuthorDelegatedByProps, wi as Dialog } from "./index-CP05_pvu.mjs";
2
+ import { CSSProperties, ComponentProps, ComponentPropsWithRef, PointerEvent, ReactNode, RefObject } from "react";
3
3
  import { Button } from "@base-ui/react/button";
4
4
  import { useRender } from "@base-ui/react/use-render";
5
5
  import { Combobox } from "@base-ui/react/combobox";
@@ -282,4 +282,101 @@ type HoldThenMoveOptions = {
282
282
  */
283
283
  export declare function useHoldThenMoveTouchSensor({ holdMs, distance, tolerance }?: HoldThenMoveOptions): import("@dnd-kit/core").SensorDescriptor<TouchSensorOptions>;
284
284
  //#endregion
285
- export { Dialog as AnnouncementDialog, DialogClose as AnnouncementDialogClose, DialogTrigger as AnnouncementDialogTrigger, type ComboboxSelectGroup, type ComboboxSelectMessages, type ComboboxSelectOption, type ComboboxSelectProps, type ComboboxSelectSelection, type ComboboxSelectValue, type CommentCardMetaProps, type CommentCardProps, type CommentCardQuoteProps, type CommentCardTriggerProps, type CommentEntryAuthorProps, type CommentEntryBodyProps, type CommentEntryHeaderProps, type CommentEntryProps, type CommentEntryTimeProps, type CommentMarginItemProps, type CommentMarginLayout, type CommentMarginLayoutItem, type CommentMarginLayoutOptions, type CommentMarginProps, type CommentMarkerProps, type HoldThenMoveOptions, MessageItemDelegatedAvatar, type MessageItemDelegatedAvatarProps, MessageItemDelegatedBy, MessageItemDelegatedByButton, type MessageItemDelegatedByButtonProps, MessageItemDelegatedByName, type MessageItemDelegatedByNameProps, type MessageItemDelegatedByProps, MessageListJumpControls, type MessageListJumpControlsProps, MessageListJumpPill, MessageListJumpPillDismiss, type MessageListJumpPillDismissProps, MessageListJumpPillGroup, type MessageListJumpPillGroupProps, type MessageListJumpPillProps, MessageQuotedPreviewAuthorDelegatedBy, type MessageQuotedPreviewAuthorDelegatedByProps, type UseCommentMarginFitsOptions };
285
+ //#region src/components/ellipsis/ellipsis.d.ts
286
+ /** What a function passed as `after` receives. */
287
+ interface EllipsisState {
288
+ /** The text is cut off right now. `false` while it is expanded. */
289
+ truncated: boolean;
290
+ expanded: boolean;
291
+ /** Expands the text, or collapses it again. */
292
+ toggle: () => void;
293
+ }
294
+ interface EllipsisProps extends Omit<ComponentProps<"span">, "children"> {
295
+ /**
296
+ * The text. Inline content only (text, links, code, mentions): a block
297
+ * child such as `<p>` or `<div>` breaks the clamp.
298
+ */
299
+ children: ReactNode;
300
+ /** How many lines the text may take before it is cut. */
301
+ lines?: number;
302
+ /**
303
+ * The tooltip shown on hover, and on keyboard focus when the text is a
304
+ * button, while the text is cut: `true` shows the children, a node shows
305
+ * that node, `false` shows none. It never opens on a text that fits, or on
306
+ * a touch screen.
307
+ */
308
+ tooltip?: ReactNode;
309
+ /**
310
+ * Shown after the text, at the end of the last visible line, only while the
311
+ * text is cut or expanded; it takes no room while the text fits. A function
312
+ * receives the state, for an expand control (`EllipsisToggle`).
313
+ */
314
+ after?: ReactNode | ((state: EllipsisState) => ReactNode);
315
+ /** Whether the whole text shows (controlled). */
316
+ expanded?: boolean;
317
+ /** Whether the whole text shows at first (uncontrolled). */
318
+ defaultExpanded?: boolean;
319
+ onExpandedChange?: (expanded: boolean) => void;
320
+ /**
321
+ * Makes the cut text itself the button that expands it and collapses it
322
+ * again, for a keyboard and a touch screen as well as a pointer. Only plain
323
+ * text with no `after` takes it: a text with a link or another control
324
+ * inside stays text, and so does one with an `after`, whose control is the
325
+ * button instead (a button can't hold another).
326
+ */
327
+ expandOnClick?: boolean;
328
+ }
329
+ export declare function Ellipsis({ children, lines, tooltip, after, expanded: expandedProp, defaultExpanded, onExpandedChange, expandOnClick, className, style, ...props }: EllipsisProps): import("react").JSX.Element;
330
+ type EllipsisToggleProps = Omit<TextLinkProps, "aria-expanded" | "aria-controls">;
331
+ /**
332
+ * The control that expands an Ellipsis and collapses it again, for its
333
+ * `after`. A real button, with `aria-expanded` and `aria-controls` pointing
334
+ * at the text. The label is the caller's: "Show More" / "Show Less".
335
+ */
336
+ export declare function EllipsisToggle({ onClick, ...props }: EllipsisToggleProps): import("react").JSX.Element;
337
+ //#endregion
338
+ //#region src/lib/truncation.d.ts
339
+ /**
340
+ * Whether a text is cut off, and when to look again: the one way raft-ui
341
+ * measures truncation (Ellipsis, `useTruncated`, and the `title` that
342
+ * fields give a cut value).
343
+ *
344
+ * The truncation itself is CSS (`text-overflow: ellipsis`, `line-clamp`);
345
+ * this module only answers "did it cut?".
346
+ *
347
+ * - It compares fractional geometry with a 0.5px tolerance. `scrollWidth` and
348
+ * `clientWidth` are whole pixels, so at some widths (and page zooms) a text
349
+ * that shows an ellipsis reports that it fits.
350
+ * - Every measured element on a page shares one ResizeObserver, one
351
+ * MutationObserver and one font-loading listener. A web font that finishes
352
+ * loading widens the text without resizing its box, which no
353
+ * ResizeObserver would notice.
354
+ * - Requests are batched into one animation frame, before paint: every
355
+ * target is isolated (an Ellipsis hides its `after` so the text is measured
356
+ * alone), then every target is read, then restored, then every result is
357
+ * committed in one synchronous React update. Reads never interleave with
358
+ * writes, and a result shows in the same frame it was measured in. A
359
+ * request made while a frame is handled is queued for the next one.
360
+ */
361
+ /** `undefined`: not known yet, or the element has no box (hidden, not laid out). */
362
+ type Truncation = boolean | undefined;
363
+ //#endregion
364
+ //#region src/lib/use-truncated.d.ts
365
+ /**
366
+ * Whether the text in the element `ref` points at is cut off by its CSS
367
+ * (`truncate`, `line-clamp`, a fixed size with `overflow: hidden`): `true`,
368
+ * `false`, or `undefined` until it is measured or while it has no box.
369
+ *
370
+ * It measures fractional sizes with a 0.5px tolerance, past either inline
371
+ * edge and below the bottom edge, so it needs no line count. It measures again
372
+ * when the element changes size, when its text changes and when a web font
373
+ * finishes loading, in one batched frame for every measured element on the
374
+ * page (lib/truncation.ts), before that frame paints.
375
+ *
376
+ * The element is read when the component mounts: keep `ref` on one element
377
+ * for the component's life, or give the component a `key` that changes with
378
+ * the element.
379
+ */
380
+ export declare function useTruncated(ref: RefObject<Element | null>): Truncation;
381
+ //#endregion
382
+ export { Dialog as AnnouncementDialog, DialogClose as AnnouncementDialogClose, DialogTrigger as AnnouncementDialogTrigger, type ComboboxSelectGroup, type ComboboxSelectMessages, type ComboboxSelectOption, type ComboboxSelectProps, type ComboboxSelectSelection, type ComboboxSelectValue, type CommentCardMetaProps, type CommentCardProps, type CommentCardQuoteProps, type CommentCardTriggerProps, type CommentEntryAuthorProps, type CommentEntryBodyProps, type CommentEntryHeaderProps, type CommentEntryProps, type CommentEntryTimeProps, type CommentMarginItemProps, type CommentMarginLayout, type CommentMarginLayoutItem, type CommentMarginLayoutOptions, type CommentMarginProps, type CommentMarkerProps, type EllipsisProps, type EllipsisState, type EllipsisToggleProps, type HoldThenMoveOptions, MessageItemDelegatedAvatar, type MessageItemDelegatedAvatarProps, MessageItemDelegatedBy, MessageItemDelegatedByButton, type MessageItemDelegatedByButtonProps, MessageItemDelegatedByName, type MessageItemDelegatedByNameProps, type MessageItemDelegatedByProps, MessageListJumpControls, type MessageListJumpControlsProps, MessageListJumpPill, MessageListJumpPillDismiss, type MessageListJumpPillDismissProps, MessageListJumpPillGroup, type MessageListJumpPillGroupProps, type MessageListJumpPillProps, MessageQuotedPreviewAuthorDelegatedBy, type MessageQuotedPreviewAuthorDelegatedByProps, type UseCommentMarginFitsOptions };