@proteos/ui 0.50.1 → 0.51.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/index.js CHANGED
@@ -2,9 +2,9 @@ import { cn, Button, Skeleton } from './chunk-IKAX76MB.js';
2
2
  export { Button, Skeleton, buttonStyles, cn, skeletonStyles } from './chunk-IKAX76MB.js';
3
3
  import { icons, Paperclip, BookText, Banknote, UsersRound, User, Link2, Braces, Brackets, ToggleLeft, CircleDot, Calendar, Hash, Type, File, FileImage, FileText, FileSpreadsheet, FileArchive, Loader2, X, Shapes, Search, Phone, AudioLines, Video, Mic, AtSign, MessagesSquare, Camera, Send, Linkedin, MessageCircle, Mail, Pipette, ChevronDown, GripVertical, SendHorizontal, CircleX, Download, ChevronRight as ChevronRight$1, CircleCheck, CircleAlert, Info } from 'lucide-react';
4
4
  import { tv } from 'tailwind-variants';
5
- import { Tabs as Tabs$1, TabPanel, Tab, TabList, MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1, DialogTrigger, Popover as Popover$1, Dialog, DropZone, Text, FileTrigger, Heading, Label, Input as Input$1, ListBox, ListBoxItem, Breadcrumbs as Breadcrumbs$1, Breadcrumb, Link, Button as Button$1, Checkbox as Checkbox$1, CheckboxGroup as CheckboxGroup$1, FieldError, TextField, ComboBox, ComboBoxStateContext, Select as Select$1, DatePicker as DatePicker$1, Group, DateInput, DateSegment, SelectValue, ModalOverlay, Modal as Modal$1, Menu as Menu$1, MenuItem as MenuItem$1, Disclosure, DisclosurePanel, ProgressBar as ProgressBar$1, RadioGroup as RadioGroup$1, Radio as Radio$1, Separator as Separator$1, Switch as Switch$1, TextArea, TimeField as TimeField$1, UNSTABLE_ToastQueue, UNSTABLE_ToastRegion, UNSTABLE_Toast, UNSTABLE_ToastContent, TooltipTrigger as TooltipTrigger$1, Tooltip as Tooltip$1, Calendar as Calendar$1, CalendarGrid, CalendarGridHeader, CalendarHeaderCell, CalendarGridBody, CalendarCell, DatePickerStateContext } from 'react-aria-components';
5
+ import { Tabs as Tabs$1, TabPanel, Tab, TabList, MenuTrigger as MenuTrigger$1, SubmenuTrigger as SubmenuTrigger$1, DialogTrigger, Popover as Popover$1, Dialog, DropZone, Text, FileTrigger, Heading, Label, Input as Input$1, ListBox, ListBoxItem, Breadcrumbs as Breadcrumbs$1, Breadcrumb, Link, Button as Button$1, Checkbox as Checkbox$1, CheckboxGroup as CheckboxGroup$1, FieldError, TextField, ComboBox, ComboBoxStateContext, Select as Select$1, SelectValue, ModalOverlay, Modal as Modal$1, DatePicker as DatePicker$1, Group, DateInput, DateSegment, Menu as Menu$1, MenuItem as MenuItem$1, Disclosure, DisclosurePanel, ProgressBar as ProgressBar$1, RadioGroup as RadioGroup$1, Radio as Radio$1, Separator as Separator$1, Switch as Switch$1, TextArea, TimeField as TimeField$1, UNSTABLE_ToastQueue, UNSTABLE_ToastRegion, UNSTABLE_Toast, UNSTABLE_ToastContent, TooltipTrigger as TooltipTrigger$1, Tooltip as Tooltip$1, Calendar as Calendar$1, CalendarGrid, CalendarGridHeader, CalendarHeaderCell, CalendarGridBody, CalendarCell, DatePickerStateContext } from 'react-aria-components';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
- import { lazy, createContext, useState, useRef, useMemo, useEffect, useContext, useSyncExternalStore, useLayoutEffect, useCallback, Suspense, useId, Fragment as Fragment$1 } from 'react';
7
+ import { lazy, createContext, useState, useRef, useMemo, useEffect, useContext, useSyncExternalStore, useCallback, useLayoutEffect, Suspense, useId, Fragment as Fragment$1 } from 'react';
8
8
  import { formatAmount, parseAmount } from '@proteos/sdk';
9
9
  import { draggable, dropTargetForElements, monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
10
10
  import { extractClosestEdge, attachClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
@@ -609,7 +609,7 @@ function IconPicker({
609
609
  const [query, setQuery] = useState("");
610
610
  const [limit, setLimit] = useState(GRID_PAGE);
611
611
  const triggerRef = useRef(null);
612
- const styles3 = fieldControlStyles({ size, invalid: isInvalid, appearance });
612
+ const styles4 = fieldControlStyles({ size, invalid: isInvalid, appearance });
613
613
  const selectedName = resolveLucideIconName(value);
614
614
  const SelectedIcon = selectedName ? icons[selectedName] : null;
615
615
  const matches2 = useMemo(() => {
@@ -654,7 +654,7 @@ function IconPicker({
654
654
  onClick: () => open(!isOpen),
655
655
  "data-invalid": isInvalid || void 0,
656
656
  className: cn(
657
- styles3.box(),
657
+ styles4.box(),
658
658
  "flex shrink-0 items-center justify-center cursor-pointer",
659
659
  appearance === "cell" ? "size-[29px]" : COMPACT_SIZE[size],
660
660
  "disabled:cursor-not-allowed disabled:opacity-45"
@@ -675,8 +675,8 @@ function IconPicker({
675
675
  className: cn(
676
676
  // box carries no padding by contract — content is what gives a
677
677
  // single-element control its interior (padding, font, text-size).
678
- styles3.box(),
679
- styles3.content(),
678
+ styles4.box(),
679
+ styles4.content(),
680
680
  "flex w-full items-center gap-2 text-left cursor-pointer",
681
681
  "disabled:cursor-not-allowed disabled:opacity-45"
682
682
  ),
@@ -808,9 +808,7 @@ var badgeStyles = tv({
808
808
  base: [
809
809
  "inline-flex items-center gap-1.5",
810
810
  "font-mono text-[11.5px] tracking-[-0.005em]",
811
- "px-2.5 py-0.5 rounded-pill border",
812
- // Leading dot
813
- 'before:content-[""] before:block before:size-1.5 before:rounded-full'
811
+ "px-2.5 py-0.5 border"
814
812
  ],
815
813
  variants: {
816
814
  variant: {
@@ -844,9 +842,18 @@ var badgeStyles = tv({
844
842
  "border-[color-mix(in_oklab,var(--badge-color)_35%,var(--color-rule))]",
845
843
  "bg-[color-mix(in_oklab,var(--badge-color)_12%,var(--color-surface))]"
846
844
  ]
845
+ },
846
+ shape: {
847
+ pill: "rounded-pill",
848
+ rounded: "rounded-chip"
849
+ },
850
+ // Leading dot — its color comes from the register's `before:bg-*`.
851
+ hasDot: {
852
+ true: 'before:content-[""] before:block before:size-1.5 before:rounded-full',
853
+ false: ""
847
854
  }
848
855
  },
849
- defaultVariants: { variant: "default" }
856
+ defaultVariants: { variant: "default", shape: "pill", hasDot: true }
850
857
  });
851
858
  var ICON_TONE = {
852
859
  default: "text-ink-4",
@@ -857,16 +864,31 @@ var ICON_TONE = {
857
864
  danger: "text-danger",
858
865
  custom: "text-[var(--badge-color)]"
859
866
  };
860
- function Badge({ variant, color, icon, className, style, children, ...props }) {
867
+ function Badge({
868
+ variant,
869
+ shape,
870
+ hasDot,
871
+ color,
872
+ icon,
873
+ className,
874
+ style,
875
+ children,
876
+ ...props
877
+ }) {
861
878
  const Icon = icon ? resolveLucideIcon(icon) : null;
862
879
  const register2 = color ? "custom" : variant ?? "default";
863
880
  const mergedStyle = color ? { ...style, "--badge-color": color } : style;
881
+ const showDot = hasDot !== false && !Icon;
864
882
  return /* @__PURE__ */ jsxs(
865
883
  "span",
866
884
  {
867
885
  ...props,
868
886
  style: mergedStyle,
869
- className: cn(badgeStyles({ variant: register2 }), Icon ? "before:hidden" : null, className),
887
+ className: cn(
888
+ badgeStyles({ variant: register2, shape, hasDot }),
889
+ showDot ? null : "before:hidden",
890
+ className
891
+ ),
870
892
  children: [
871
893
  Icon ? /* @__PURE__ */ jsx(Icon, { "aria-hidden": true, className: cn("size-3 shrink-0", ICON_TONE[register2]) }) : null,
872
894
  children
@@ -877,6 +899,8 @@ function Badge({ variant, color, icon, className, style, children, ...props }) {
877
899
  function badgeChrome(option) {
878
900
  return {
879
901
  ...option.variant ? { variant: option.variant } : {},
902
+ ...option.shape ? { shape: option.shape } : {},
903
+ ...option.hasDot !== void 0 ? { hasDot: option.hasDot } : {},
880
904
  ...option.color ? { color: option.color } : {},
881
905
  ...option.icon ? { icon: option.icon } : {}
882
906
  };
@@ -897,7 +921,7 @@ function BadgeMultiSelect({
897
921
  autoFocus = false,
898
922
  className
899
923
  }) {
900
- const styles3 = fieldControlStyles({ size, invalid: isInvalid, appearance });
924
+ const styles4 = fieldControlStyles({ size, invalid: isInvalid, appearance });
901
925
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
902
926
  const minHeight = appearance === "cell" ? "min-h-[29px]" : fieldMinHeight[size];
903
927
  const [isOpen, setIsOpen] = useState(false);
@@ -937,7 +961,7 @@ function BadgeMultiSelect({
937
961
  "data-invalid": isInvalid || void 0,
938
962
  "data-disabled": isDisabled || void 0,
939
963
  className: cn(
940
- styles3.box(),
964
+ styles4.box(),
941
965
  "flex flex-wrap items-center gap-1.5 cursor-pointer",
942
966
  minHeight,
943
967
  fieldChipPadding[size],
@@ -1023,13 +1047,11 @@ function BadgeMultiSelect({
1023
1047
  }
1024
1048
  function RemovableBadge({
1025
1049
  children,
1026
- variant,
1027
- color,
1028
- icon,
1029
1050
  onRemove,
1030
- isDisabled
1051
+ isDisabled,
1052
+ ...chrome
1031
1053
  }) {
1032
- return /* @__PURE__ */ jsxs(Badge, { ...badgeChrome({ variant, color, icon }), children: [
1054
+ return /* @__PURE__ */ jsxs(Badge, { ...badgeChrome(chrome), children: [
1033
1055
  /* @__PURE__ */ jsx("span", { children }),
1034
1056
  /* @__PURE__ */ jsx(
1035
1057
  "button",
@@ -1383,7 +1405,7 @@ function ColorInput({
1383
1405
  }, [committed]);
1384
1406
  const isDraftInvalid = draft.trim() !== "" && normalizeHexColor(draft) === null;
1385
1407
  const invalid = isInvalid || isDraftInvalid;
1386
- const styles3 = fieldControlStyles({ size, invalid, appearance });
1408
+ const styles4 = fieldControlStyles({ size, invalid, appearance });
1387
1409
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
1388
1410
  const edit = (next) => {
1389
1411
  setDraft(next);
@@ -1424,7 +1446,7 @@ function ColorInput({
1424
1446
  {
1425
1447
  "data-disabled": isDisabled || void 0,
1426
1448
  className: cn(
1427
- styles3.box(),
1449
+ styles4.box(),
1428
1450
  "flex items-center gap-2",
1429
1451
  size === "sm" ? "pl-2" : "pl-2.5",
1430
1452
  focusWithin
@@ -1471,7 +1493,7 @@ function ColorInput({
1471
1493
  spellCheck: false,
1472
1494
  autoComplete: "off",
1473
1495
  className: cn(
1474
- styles3.content(),
1496
+ styles4.content(),
1475
1497
  "min-w-0 flex-1 bg-transparent font-mono outline-none",
1476
1498
  "pl-0",
1477
1499
  fieldTextStyles[size]
@@ -1504,7 +1526,7 @@ function Combobox({
1504
1526
  allowsEmptyCollection = true,
1505
1527
  ...props
1506
1528
  }) {
1507
- const styles3 = fieldControlStyles({ size, appearance });
1529
+ const styles4 = fieldControlStyles({ size, appearance });
1508
1530
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
1509
1531
  return /* @__PURE__ */ jsxs(
1510
1532
  ComboBox,
@@ -1523,7 +1545,7 @@ function Combobox({
1523
1545
  className: cn(
1524
1546
  // Box chrome on the wrapper; the inner <input> carries the padding
1525
1547
  // + font so the chevron button sits inside the same border + ring.
1526
- styles3.box(),
1548
+ styles4.box(),
1527
1549
  "flex items-center gap-1 pr-2",
1528
1550
  focusWithin,
1529
1551
  inputWrapperClassName
@@ -1535,7 +1557,7 @@ function Combobox({
1535
1557
  placeholder,
1536
1558
  className: cn(
1537
1559
  "flex-1 min-w-0 bg-transparent outline-none",
1538
- styles3.content(),
1560
+ styles4.content(),
1539
1561
  inputClassName
1540
1562
  )
1541
1563
  }
@@ -1903,46 +1925,509 @@ function Command({ combo, target, className, children }) {
1903
1925
  discoveryActive ? /* @__PURE__ */ jsx(
1904
1926
  "div",
1905
1927
  {
1906
- "aria-hidden": true,
1907
- className: "absolute -inset-2 rounded-md bg-[color-mix(in_oklab,var(--color-ink)_28%,transparent)] pointer-events-none transition-opacity z-40",
1908
- children: /* @__PURE__ */ jsx("span", { className: "absolute -top-2.5 -left-2 pointer-events-none z-50", children: /* @__PURE__ */ jsx(CommandHint, { combo, tone: "prominent" }) })
1928
+ "aria-hidden": true,
1929
+ className: "absolute -inset-2 rounded-md bg-[color-mix(in_oklab,var(--color-ink)_28%,transparent)] pointer-events-none transition-opacity z-40",
1930
+ children: /* @__PURE__ */ jsx("span", { className: "absolute -top-2.5 -left-2 pointer-events-none z-50", children: /* @__PURE__ */ jsx(CommandHint, { combo, tone: "prominent" }) })
1931
+ }
1932
+ ) : null
1933
+ ] });
1934
+ }
1935
+ var stack = [];
1936
+ var listenerInstalled2 = false;
1937
+ function onWindowKeyDown2(event) {
1938
+ if (event.key !== "Escape") return;
1939
+ if (isEditableTarget(event.target)) return;
1940
+ const top = stack[stack.length - 1];
1941
+ if (!top) return;
1942
+ top.handler(event);
1943
+ }
1944
+ function ensureListener2() {
1945
+ if (listenerInstalled2) return;
1946
+ if (typeof window === "undefined") return;
1947
+ window.addEventListener("keydown", onWindowKeyDown2, { capture: true });
1948
+ listenerInstalled2 = true;
1949
+ }
1950
+ function useEscapeKey(handler, options) {
1951
+ const enabled = options?.enabled ?? true;
1952
+ const handlerRef = useRef(handler);
1953
+ useEffect(() => {
1954
+ handlerRef.current = handler;
1955
+ });
1956
+ useEffect(() => {
1957
+ if (!enabled) return void 0;
1958
+ ensureListener2();
1959
+ const entry = {
1960
+ handler: (event) => handlerRef.current(event)
1961
+ };
1962
+ stack.push(entry);
1963
+ return () => {
1964
+ const idx = stack.lastIndexOf(entry);
1965
+ if (idx >= 0) stack.splice(idx, 1);
1966
+ };
1967
+ }, [enabled]);
1968
+ }
1969
+ var conversationBriefCardStyles = tv({
1970
+ slots: {
1971
+ root: [
1972
+ "flex items-center gap-2.5 rounded-md border border-accent/40 px-3 py-2",
1973
+ "bg-[color-mix(in_oklab,var(--color-accent)_6%,var(--color-surface))]"
1974
+ ],
1975
+ icon: [
1976
+ "grid size-8 shrink-0 place-items-center rounded-full text-accent",
1977
+ "bg-[color-mix(in_oklab,var(--color-accent)_12%,transparent)]"
1978
+ ],
1979
+ body: "min-w-0 flex-1",
1980
+ eyebrow: "font-mono text-[10px] uppercase tracking-[0.08em] text-accent",
1981
+ title: "truncate text-[13px] font-medium text-ink",
1982
+ summary: "truncate text-[12px] text-ink-3",
1983
+ action: [
1984
+ "shrink-0 cursor-pointer rounded-sm border border-accent/50 px-2.5 py-1",
1985
+ "font-mono text-[11px] text-accent outline-none",
1986
+ "hover:bg-[color-mix(in_oklab,var(--color-accent)_12%,transparent)]",
1987
+ "focus-visible:shadow-[var(--shadow-focus)]",
1988
+ "disabled:cursor-default disabled:opacity-50"
1989
+ ],
1990
+ outcome: "shrink-0 font-mono text-[11px] text-ink-3"
1991
+ }
1992
+ });
1993
+ var styles = conversationBriefCardStyles();
1994
+ var CONVERSATION_BRIEF_OUTCOME_LABEL = {
1995
+ used: "Call held",
1996
+ discarded: "Discarded"
1997
+ };
1998
+ function ConversationBriefCard({
1999
+ title,
2000
+ summary,
2001
+ eyebrow = "Conversation brief \u2014 prepared",
2002
+ openLabel = "Open Brief",
2003
+ outcome,
2004
+ onOpen,
2005
+ isOpenDisabled = false,
2006
+ className
2007
+ }) {
2008
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles.root(), className), children: [
2009
+ /* @__PURE__ */ jsx("span", { className: styles.icon(), children: /* @__PURE__ */ jsx(Phone, { className: "size-4", "aria-hidden": true }) }),
2010
+ /* @__PURE__ */ jsxs("div", { className: styles.body(), children: [
2011
+ /* @__PURE__ */ jsx("p", { className: styles.eyebrow(), children: eyebrow }),
2012
+ /* @__PURE__ */ jsx("p", { className: styles.title(), children: title }),
2013
+ summary ? /* @__PURE__ */ jsx("p", { className: styles.summary(), children: summary }) : null
2014
+ ] }),
2015
+ outcome ? /* @__PURE__ */ jsx("span", { className: styles.outcome(), children: CONVERSATION_BRIEF_OUTCOME_LABEL[outcome] }) : /* @__PURE__ */ jsx(
2016
+ Button$1,
2017
+ {
2018
+ onPress: onOpen ?? (() => {
2019
+ }),
2020
+ isDisabled: isOpenDisabled,
2021
+ className: styles.action(),
2022
+ children: openLabel
2023
+ }
2024
+ )
2025
+ ] });
2026
+ }
2027
+ function Select({
2028
+ label,
2029
+ description,
2030
+ errorMessage,
2031
+ placeholder = "Select\u2026",
2032
+ options,
2033
+ renderItem,
2034
+ size,
2035
+ appearance,
2036
+ triggerClassName,
2037
+ popoverClassName,
2038
+ className,
2039
+ ...props
2040
+ }) {
2041
+ const styles4 = fieldControlStyles({ size, appearance });
2042
+ return /* @__PURE__ */ jsxs(
2043
+ Select$1,
2044
+ {
2045
+ ...props,
2046
+ className: (renderProps) => cn(
2047
+ "grid grid-cols-1 gap-1.5",
2048
+ typeof className === "function" ? className(renderProps) : className
2049
+ ),
2050
+ children: [
2051
+ label ? /* @__PURE__ */ jsx(Label, { className: fieldLabelStyles, children: label }) : null,
2052
+ /* @__PURE__ */ jsxs(
2053
+ Button$1,
2054
+ {
2055
+ className: cn(
2056
+ styles4.box(),
2057
+ styles4.content(),
2058
+ "flex items-center justify-between gap-3 text-left cursor-pointer",
2059
+ triggerClassName
2060
+ ),
2061
+ children: [
2062
+ /* @__PURE__ */ jsx(SelectValue, { className: "truncate", children: ({ defaultChildren, isPlaceholder }) => isPlaceholder ? /* @__PURE__ */ jsx("span", { className: "text-ink-4", children: placeholder }) : defaultChildren }),
2063
+ /* @__PURE__ */ jsx(FieldCaret, {})
2064
+ ]
2065
+ }
2066
+ ),
2067
+ description ? /* @__PURE__ */ jsx(Text, { slot: "description", className: fieldHintStyles, children: description }) : null,
2068
+ errorMessage && appearance !== "cell" ? /* @__PURE__ */ jsx(FieldError, { className: fieldErrorStyles, children: errorMessage }) : null,
2069
+ /* @__PURE__ */ jsxs(
2070
+ Popover$1,
2071
+ {
2072
+ offset: 6,
2073
+ className: cn(
2074
+ // Match the trigger width exactly (RAC exposes --trigger-width on
2075
+ // the Popover when anchored to a Select button).
2076
+ "w-[var(--trigger-width)]",
2077
+ // Float above modals + full-screen editors (e.g. agent-studio's
2078
+ // .as-editor z-1000 / a raised modal overlay), matching Menu's z-[1200].
2079
+ "z-[1300]",
2080
+ "rounded-md border border-rule bg-surface p-1",
2081
+ "shadow-[var(--shadow-raised)]",
2082
+ "entering:animate-in entering:fade-in-0 entering:slide-in-from-top-1",
2083
+ "exiting:animate-out exiting:fade-out-0 exiting:slide-out-to-top-1",
2084
+ popoverClassName
2085
+ ),
2086
+ children: [
2087
+ /* @__PURE__ */ jsx(ListBox, { className: "outline-none max-h-72 overflow-auto", children: options.map((option) => /* @__PURE__ */ jsx(
2088
+ SelectItem,
2089
+ {
2090
+ id: option.id,
2091
+ ...option.textValue ? { textValue: option.textValue } : {},
2092
+ ...option.isDisabled ? { isDisabled: true } : {},
2093
+ children: renderItem ? renderItem(option) : option.label
2094
+ },
2095
+ option.id
2096
+ )) }),
2097
+ options.length === 0 ? /* @__PURE__ */ jsx("div", { className: cn("px-3 py-2", fieldHintStyles), children: placeholder }) : null
2098
+ ]
2099
+ }
2100
+ )
2101
+ ]
2102
+ }
2103
+ );
2104
+ }
2105
+ function SelectItem(props) {
2106
+ return /* @__PURE__ */ jsx(
2107
+ ListBoxItem,
2108
+ {
2109
+ ...props,
2110
+ className: cn(
2111
+ "flex items-center justify-between gap-3",
2112
+ "rounded-[6px] px-3 py-2 text-[14px] text-ink-2",
2113
+ "cursor-pointer outline-none select-none",
2114
+ "data-[hovered]:bg-surface-2 data-[hovered]:text-ink",
2115
+ "data-[focused]:bg-surface-2 data-[focused]:text-ink",
2116
+ "data-[selected]:bg-surface-3 data-[selected]:text-ink",
2117
+ "data-[disabled]:opacity-45 data-[disabled]:cursor-not-allowed"
2118
+ )
2119
+ }
2120
+ );
2121
+ }
2122
+
2123
+ // src/components/conversation-brief-card/types.ts
2124
+ function conversationBriefOutcomeFor(status) {
2125
+ if (status === "used" || status === "discarded") return status;
2126
+ return null;
2127
+ }
2128
+ function isDialableConversationBrief(brief) {
2129
+ return !brief.channel || brief.channel === "phone";
2130
+ }
2131
+ function contactPhoneNumbers(contact) {
2132
+ const numbers = [];
2133
+ for (const address of contact?.addresses ?? []) {
2134
+ if (address.kind !== "phone" || !address.value) continue;
2135
+ if (!numbers.includes(address.value)) numbers.push(address.value);
2136
+ }
2137
+ return numbers;
2138
+ }
2139
+ function ConversationBriefPreview({
2140
+ brief,
2141
+ contacts,
2142
+ onCall,
2143
+ isCallDisabled = false,
2144
+ callDisabledReason,
2145
+ controls,
2146
+ isCallButtonHidden = false,
2147
+ onSelectionChange,
2148
+ callLabel = "Call",
2149
+ className,
2150
+ contentClassName
2151
+ }) {
2152
+ const [pickedContactId, setPickedContactId] = useState("");
2153
+ const contact = contacts.find((entry) => entry.id === pickedContactId) ?? contacts[0] ?? null;
2154
+ const numbers = useMemo(() => contactPhoneNumbers(contact), [contact]);
2155
+ const [pickedNumber, setPickedNumber] = useState("");
2156
+ const phoneNumber = numbers.includes(pickedNumber) ? pickedNumber : numbers[0] || "";
2157
+ const isOpen = brief.status === "prepared";
2158
+ const names = contacts.map((entry) => entry.name).filter(Boolean).join(", ");
2159
+ const onSelectionChangeRef = useRef(onSelectionChange);
2160
+ onSelectionChangeRef.current = onSelectionChange;
2161
+ useEffect(() => {
2162
+ onSelectionChangeRef.current?.(contact, phoneNumber);
2163
+ }, [contact, phoneNumber]);
2164
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
2165
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2166
+ /* @__PURE__ */ jsx("p", { className: "truncate text-[14px] font-semibold text-ink", children: brief.subject || names || "Prepared conversation" }),
2167
+ /* @__PURE__ */ jsx("p", { className: "font-mono text-[10.5px] text-ink-4", children: [
2168
+ brief.subject ? names : "",
2169
+ brief.channel ? `Channel ${brief.channel}` : "Any channel",
2170
+ brief.type_key ? `Type ${brief.type_key}` : "",
2171
+ brief.status === "prepared" ? "Prepared" : brief.status === "used" ? "Call held" : "Discarded"
2172
+ ].filter(Boolean).join(" \xB7 ") })
2173
+ ] }),
2174
+ /* @__PURE__ */ jsx(
2175
+ "div",
2176
+ {
2177
+ className: cn(
2178
+ "whitespace-pre-wrap rounded-md border border-rule-2 bg-surface-2/60 px-3 py-2.5",
2179
+ "text-[13px] leading-relaxed text-ink-2 overflow-y-auto [scrollbar-width:thin]",
2180
+ contentClassName
2181
+ ),
2182
+ children: brief.content
2183
+ }
2184
+ ),
2185
+ onCall ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 border-t border-rule-2 pt-3", children: [
2186
+ contacts.length > 1 ? /* @__PURE__ */ jsx(
2187
+ Select,
2188
+ {
2189
+ "aria-label": "Who to call",
2190
+ selectedKey: contact?.id ?? "",
2191
+ onSelectionChange: (key) => {
2192
+ setPickedContactId(String(key));
2193
+ setPickedNumber("");
2194
+ },
2195
+ options: contacts.map((entry) => ({ id: entry.id, label: entry.name || entry.id }))
2196
+ }
2197
+ ) : null,
2198
+ numbers.length > 1 ? /* @__PURE__ */ jsx(
2199
+ Select,
2200
+ {
2201
+ "aria-label": "Number to call",
2202
+ selectedKey: phoneNumber,
2203
+ onSelectionChange: (key) => setPickedNumber(String(key)),
2204
+ options: numbers.map((number) => ({ id: number, label: number }))
2205
+ }
2206
+ ) : /* @__PURE__ */ jsx("p", { className: "font-mono text-[12px] text-ink-3", children: phoneNumber || (contact ? "This contact has no phone number on file." : "No contact to call.") }),
2207
+ controls,
2208
+ callDisabledReason ? /* @__PURE__ */ jsx("p", { className: "text-[12px] text-warning", children: callDisabledReason }) : null,
2209
+ isCallButtonHidden ? null : /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(
2210
+ Button,
2211
+ {
2212
+ isDisabled: isCallDisabled || !isOpen || phoneNumber === "" || !contact,
2213
+ onPress: () => contact && onCall(contact, phoneNumber),
2214
+ children: [
2215
+ /* @__PURE__ */ jsx(Phone, { className: "size-3.5", "aria-hidden": true }),
2216
+ callLabel
2217
+ ]
2218
+ }
2219
+ ) })
2220
+ ] }) : null
2221
+ ] });
2222
+ }
2223
+ function Modal(props) {
2224
+ return /* @__PURE__ */ jsx(DialogTrigger, { ...props });
2225
+ }
2226
+ function ModalContent({
2227
+ children,
2228
+ className,
2229
+ modalClassName,
2230
+ isDismissable = true,
2231
+ ...props
2232
+ }) {
2233
+ return /* @__PURE__ */ jsx(
2234
+ ModalOverlay,
2235
+ {
2236
+ isDismissable,
2237
+ ...props,
2238
+ className: (renderProps) => cn(
2239
+ "fixed inset-0 z-50 flex items-center justify-center p-4",
2240
+ // Warm ink scrim — stays in the Proteos palette (no pure black).
2241
+ "bg-[color-mix(in_oklab,var(--color-ink)_40%,transparent)]",
2242
+ "entering:animate-in entering:fade-in-0 entering:duration-150",
2243
+ "exiting:animate-out exiting:fade-out-0 exiting:duration-100",
2244
+ typeof className === "function" ? className(renderProps) : className
2245
+ ),
2246
+ children: /* @__PURE__ */ jsx(
2247
+ Modal$1,
2248
+ {
2249
+ className: cn(
2250
+ "w-full max-w-lg",
2251
+ // Cap the panel at the viewport (minus the overlay's p-4) and lay it
2252
+ // out as a column so a tall body scrolls instead of overflowing the
2253
+ // screen. Short modals are unaffected — height still tracks content.
2254
+ "flex flex-col max-h-[calc(100dvh-2rem)]",
2255
+ "bg-surface border border-rule rounded-lg",
2256
+ "shadow-[var(--shadow-float)]",
2257
+ "entering:animate-in entering:zoom-in-95 entering:slide-in-from-top-2 entering:duration-150",
2258
+ "exiting:animate-out exiting:zoom-out-95 exiting:duration-100",
2259
+ modalClassName
2260
+ ),
2261
+ children: /* @__PURE__ */ jsx(Dialog, { className: "outline-none flex flex-col min-h-0 overflow-hidden", children })
2262
+ }
2263
+ )
2264
+ }
2265
+ );
2266
+ }
2267
+ function ModalHeader({ className, ...props }) {
2268
+ return /* @__PURE__ */ jsx("div", { ...props, className: cn("shrink-0 px-5 pt-5 pb-3 flex flex-col gap-1.5", className) });
2269
+ }
2270
+ function ModalTitle({ className, ...props }) {
2271
+ return /* @__PURE__ */ jsx(
2272
+ Heading,
2273
+ {
2274
+ slot: "title",
2275
+ ...props,
2276
+ className: cn(
2277
+ "font-sans font-medium text-[20px] leading-[1.25] tracking-[-0.015em] text-ink",
2278
+ className
2279
+ )
2280
+ }
2281
+ );
2282
+ }
2283
+ function ModalDescription({ className, ...props }) {
2284
+ return /* @__PURE__ */ jsx("p", { ...props, className: cn("text-[14px] leading-[1.55] text-ink-3", className) });
2285
+ }
2286
+ function ModalBody({ className, ...props }) {
2287
+ return /* @__PURE__ */ jsx(
2288
+ "div",
2289
+ {
2290
+ ...props,
2291
+ className: cn(
2292
+ // The scroll region: caps at the panel's spare height and scrolls when
2293
+ // the content is taller, leaving header + footer pinned.
2294
+ "min-h-0 overflow-y-auto px-5 py-3 flex flex-col gap-3 text-[14px] text-ink-2",
2295
+ className
2296
+ )
2297
+ }
2298
+ );
2299
+ }
2300
+ function ModalFooter({ className, ...props }) {
2301
+ return /* @__PURE__ */ jsx(
2302
+ "div",
2303
+ {
2304
+ ...props,
2305
+ className: cn("shrink-0 flex justify-end items-center gap-2", "px-5 pt-3 pb-5", className)
2306
+ }
2307
+ );
2308
+ }
2309
+ function ConversationBriefReview({
2310
+ conversationBriefId,
2311
+ client,
2312
+ onOpenCall,
2313
+ onCall,
2314
+ isCallDisabled = false,
2315
+ callDisabledReason,
2316
+ onOutcome,
2317
+ onLoadError,
2318
+ modalTitle = "Prepared conversation",
2319
+ modalClassName = "max-w-2xl",
2320
+ overlayClassName,
2321
+ openLabel,
2322
+ className
2323
+ }) {
2324
+ const [brief, setBrief] = useState(null);
2325
+ const [contacts, setContacts] = useState([]);
2326
+ const [isOpen, setIsOpen] = useState(false);
2327
+ const [outcome, setOutcome] = useState(null);
2328
+ const onOutcomeRef = useRef(onOutcome);
2329
+ onOutcomeRef.current = onOutcome;
2330
+ const onLoadErrorRef = useRef(onLoadError);
2331
+ onLoadErrorRef.current = onLoadError;
2332
+ const hasSettledRef = useRef(false);
2333
+ const settle = useCallback((next, settled) => {
2334
+ setOutcome(next);
2335
+ setIsOpen(false);
2336
+ if (hasSettledRef.current) return;
2337
+ hasSettledRef.current = true;
2338
+ onOutcomeRef.current?.(next, settled);
2339
+ }, []);
2340
+ useEffect(() => {
2341
+ let cancelled = false;
2342
+ void (async () => {
2343
+ try {
2344
+ const loaded = await client.getConversationBrief(conversationBriefId);
2345
+ if (cancelled) return;
2346
+ setBrief(loaded);
2347
+ const terminal = conversationBriefOutcomeFor(loaded.status);
2348
+ if (terminal) settle(terminal, loaded);
2349
+ const people = await Promise.all(
2350
+ loaded.contact_ids.map((contactId) => client.getContact(contactId).catch(() => null))
2351
+ );
2352
+ if (!cancelled) setContacts(people.filter((person) => person !== null));
2353
+ } catch (error) {
2354
+ if (cancelled) return;
2355
+ onLoadErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));
2356
+ }
2357
+ })();
2358
+ return () => {
2359
+ cancelled = true;
2360
+ };
2361
+ }, [client, conversationBriefId, settle]);
2362
+ const open = () => {
2363
+ if (onOpenCall) {
2364
+ onOpenCall(conversationBriefId);
2365
+ return;
2366
+ }
2367
+ setIsOpen(true);
2368
+ };
2369
+ if (!brief) return null;
2370
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2371
+ /* @__PURE__ */ jsx(
2372
+ ConversationBriefCard,
2373
+ {
2374
+ title: brief.subject || namesOf(contacts) || "Prepared conversation",
2375
+ summary: summaryFor(brief, contacts),
2376
+ outcome,
2377
+ onOpen: open,
2378
+ ...openLabel !== void 0 ? { openLabel } : {},
2379
+ ...className !== void 0 ? { className } : {}
2380
+ }
2381
+ ),
2382
+ onOpenCall ? null : /* @__PURE__ */ jsxs(
2383
+ ModalContent,
2384
+ {
2385
+ isOpen,
2386
+ onOpenChange: setIsOpen,
2387
+ modalClassName,
2388
+ ...overlayClassName !== void 0 ? { className: overlayClassName } : {},
2389
+ children: [
2390
+ /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(ModalTitle, { children: modalTitle }) }),
2391
+ /* @__PURE__ */ jsx(ModalBody, { className: "min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
2392
+ ConversationBriefPreview,
2393
+ {
2394
+ brief,
2395
+ contacts,
2396
+ contentClassName: "max-h-[50dvh]",
2397
+ isCallDisabled,
2398
+ ...callDisabledReason !== void 0 ? { callDisabledReason } : {},
2399
+ ...onCall && isDialableConversationBrief(brief) ? {
2400
+ onCall: (contact, phoneNumber) => {
2401
+ setIsOpen(false);
2402
+ onCall(brief, contact, phoneNumber);
2403
+ }
2404
+ } : {}
2405
+ }
2406
+ ) })
2407
+ ]
1909
2408
  }
1910
- ) : null
2409
+ )
1911
2410
  ] });
1912
2411
  }
1913
- var stack = [];
1914
- var listenerInstalled2 = false;
1915
- function onWindowKeyDown2(event) {
1916
- if (event.key !== "Escape") return;
1917
- if (isEditableTarget(event.target)) return;
1918
- const top = stack[stack.length - 1];
1919
- if (!top) return;
1920
- top.handler(event);
2412
+ function namesOf(contacts) {
2413
+ return contacts.map((contact) => contact.name).filter(Boolean).join(", ");
1921
2414
  }
1922
- function ensureListener2() {
1923
- if (listenerInstalled2) return;
1924
- if (typeof window === "undefined") return;
1925
- window.addEventListener("keydown", onWindowKeyDown2, { capture: true });
1926
- listenerInstalled2 = true;
2415
+ function summaryFor(brief, contacts) {
2416
+ const firstLine = brief.content.split("\n").find((line) => line.trim() !== "")?.trim() ?? "";
2417
+ return [
2418
+ brief.subject ? namesOf(contacts) : "",
2419
+ brief.channel ?? "",
2420
+ brief.type_key ?? "",
2421
+ firstLine
2422
+ ].filter(Boolean).join(" \xB7 ");
1927
2423
  }
1928
- function useEscapeKey(handler, options) {
1929
- const enabled = options?.enabled ?? true;
1930
- const handlerRef = useRef(handler);
1931
- useEffect(() => {
1932
- handlerRef.current = handler;
1933
- });
1934
- useEffect(() => {
1935
- if (!enabled) return void 0;
1936
- ensureListener2();
1937
- const entry = {
1938
- handler: (event) => handlerRef.current(event)
1939
- };
1940
- stack.push(entry);
1941
- return () => {
1942
- const idx = stack.lastIndexOf(entry);
1943
- if (idx >= 0) stack.splice(idx, 1);
1944
- };
1945
- }, [enabled]);
2424
+
2425
+ // src/components/conversation-brief-card/create-conversation-brief-client.ts
2426
+ function createConversationBriefClient(conversation) {
2427
+ return {
2428
+ getConversationBrief: (conversationBriefId) => conversation.conversationBriefs.get(conversationBriefId),
2429
+ getContact: (contactId) => conversation.contacts.get(contactId)
2430
+ };
1946
2431
  }
1947
2432
  function CurrencyInput({
1948
2433
  value,
@@ -1975,16 +2460,16 @@ function CurrencyInput({
1975
2460
  onChange({ amount: nextAmount, currency_code: nextCode });
1976
2461
  };
1977
2462
  const selectedSymbol = currencyOptions.find((option) => option.code === code)?.symbol ?? code;
1978
- const styles3 = fieldControlStyles({ size, appearance, ...isInvalid ? { invalid: true } : {} });
2463
+ const styles4 = fieldControlStyles({ size, appearance, ...isInvalid ? { invalid: true } : {} });
1979
2464
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
1980
2465
  return /* @__PURE__ */ jsxs("div", { className: cn("grid grid-cols-1 gap-1.5", className), children: [
1981
- /* @__PURE__ */ jsxs("div", { className: cn(styles3.box(), "flex items-center gap-1 pr-1", focusWithin), children: [
2466
+ /* @__PURE__ */ jsxs("div", { className: cn(styles4.box(), "flex items-center gap-1 pr-1", focusWithin), children: [
1982
2467
  /* @__PURE__ */ jsx(
1983
2468
  "input",
1984
2469
  {
1985
2470
  className: cn(
1986
2471
  "min-w-0 flex-1 bg-transparent text-ink outline-none tabular-nums",
1987
- styles3.content(),
2472
+ styles4.content(),
1988
2473
  // Sit a touch lower than a standard field by trimming the vertical
1989
2474
  // padding (cell mode keeps the fixed 29px row-editor height).
1990
2475
  appearance === "cell" ? "" : size === "sm" ? "py-1" : "py-1.5"
@@ -2650,7 +3135,9 @@ function DataTable({
2650
3135
  selectionMode = "none",
2651
3136
  selectedIds,
2652
3137
  onSelectionChange,
2653
- columnBorders = false
3138
+ columnBorders = false,
3139
+ groupBy,
3140
+ groupHeaderHeight
2654
3141
  }) {
2655
3142
  const rows = useMemo(() => {
2656
3143
  const pages = query.data?.pages;
@@ -2769,6 +3256,24 @@ function DataTable({
2769
3256
  });
2770
3257
  const tableRows = table.getRowModel().rows;
2771
3258
  const tableRowCount = tableRows.length;
3259
+ const listItems = useMemo(() => {
3260
+ if (!groupBy) {
3261
+ return tableRows.map((row, dataIndex) => ({ kind: "row", row, dataIndex }));
3262
+ }
3263
+ const items = [];
3264
+ let currentGroupId = null;
3265
+ tableRows.forEach((row, dataIndex) => {
3266
+ const group = groupBy(row.original);
3267
+ if (group && group.id !== currentGroupId) {
3268
+ currentGroupId = group.id;
3269
+ items.push({ kind: "group", id: group.id, label: group.label });
3270
+ } else if (!group) {
3271
+ currentGroupId = null;
3272
+ }
3273
+ items.push({ kind: "row", row, dataIndex });
3274
+ });
3275
+ return items;
3276
+ }, [tableRows, groupBy]);
2772
3277
  const scrollerRef = useRef(null);
2773
3278
  useEffect(() => {
2774
3279
  scrollerRef.current?.scrollTo({ top: 0 });
@@ -2779,10 +3284,11 @@ function DataTable({
2779
3284
  const top = listRef.current?.offsetTop ?? 0;
2780
3285
  setListOffset((prev) => prev === top ? prev : top);
2781
3286
  });
3287
+ const headingHeight = groupHeaderHeight ?? rowHeight;
2782
3288
  const virtualizer = useVirtualizer({
2783
- count: tableRowCount,
3289
+ count: listItems.length,
2784
3290
  getScrollElement: () => scrollerRef.current,
2785
- estimateSize: () => rowHeight,
3291
+ estimateSize: (index) => listItems[index]?.kind === "group" ? headingHeight : rowHeight,
2786
3292
  overscan,
2787
3293
  scrollMargin: listOffset
2788
3294
  });
@@ -2889,8 +3395,8 @@ function DataTable({
2889
3395
  role: "presentation",
2890
3396
  style: { height: totalSize, position: "relative", width: "100%" },
2891
3397
  children: virtualItems.map((vRow) => {
2892
- const row = tableRows[vRow.index];
2893
- if (!row) return null;
3398
+ const item = listItems[vRow.index];
3399
+ if (!item) return null;
2894
3400
  const rowStyle = {
2895
3401
  // Items' `start` includes the virtualizer's scrollMargin
2896
3402
  // (the list's offset below the sticky header); subtract
@@ -2898,18 +3404,21 @@ function DataTable({
2898
3404
  transform: `translateY(${vRow.start - listOffset}px)`,
2899
3405
  height: vRow.size
2900
3406
  };
3407
+ if (item.kind === "group") {
3408
+ return /* @__PURE__ */ jsx(GroupHeaderRow, { style: rowStyle, children: item.label }, `group:${item.id}`);
3409
+ }
2901
3410
  return /* @__PURE__ */ jsx(
2902
3411
  DataRow,
2903
3412
  {
2904
- row,
2905
- index: vRow.index,
3413
+ row: item.row,
3414
+ index: item.dataIndex,
2906
3415
  zebra,
2907
3416
  onRowClick,
2908
3417
  style: rowStyle,
2909
3418
  columnBorders,
2910
3419
  ...rowWrapper ? { rowWrapper } : {}
2911
3420
  },
2912
- row.id
3421
+ item.row.id
2913
3422
  );
2914
3423
  })
2915
3424
  }
@@ -2923,6 +3432,20 @@ function DataTable({
2923
3432
  }
2924
3433
  );
2925
3434
  }
3435
+ function GroupHeaderRow({ style, children }) {
3436
+ return /* @__PURE__ */ jsx(
3437
+ TableRow,
3438
+ {
3439
+ absolute: true,
3440
+ style,
3441
+ className: cn(
3442
+ "bg-surface-2 border-b border-rule",
3443
+ "font-mono text-[11px] uppercase tracking-[0.06em] text-ink-3"
3444
+ ),
3445
+ children: /* @__PURE__ */ jsx(TableCell, { className: "gap-2 text-inherit", children })
3446
+ }
3447
+ );
3448
+ }
2926
3449
  function DataRow({
2927
3450
  row,
2928
3451
  index,
@@ -3155,7 +3678,7 @@ function DatePicker({
3155
3678
  className,
3156
3679
  ...props
3157
3680
  }) {
3158
- const styles3 = fieldControlStyles({ size, appearance });
3681
+ const styles4 = fieldControlStyles({ size, appearance });
3159
3682
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
3160
3683
  return /* @__PURE__ */ jsxs(
3161
3684
  DatePicker$1,
@@ -3173,7 +3696,7 @@ function DatePicker({
3173
3696
  className: cn(
3174
3697
  // Box chrome on the wrapper; the DateInput inside carries padding +
3175
3698
  // font so the calendar trigger sits inside the same border + ring.
3176
- styles3.box(),
3699
+ styles4.box(),
3177
3700
  "flex items-center gap-1 pr-1",
3178
3701
  focusWithin
3179
3702
  ),
@@ -3183,7 +3706,7 @@ function DatePicker({
3183
3706
  {
3184
3707
  className: cn(
3185
3708
  "flex-1 flex items-center min-w-0 text-ink",
3186
- styles3.content(),
3709
+ styles4.content(),
3187
3710
  // Tabular alignment for date segments — overrides content's
3188
3711
  // font-sans on purpose.
3189
3712
  "font-mono"
@@ -3305,7 +3828,7 @@ function DateTimePicker({
3305
3828
  shouldCloseOnSelect = false,
3306
3829
  ...props
3307
3830
  }) {
3308
- const styles3 = fieldControlStyles({ size, appearance });
3831
+ const styles4 = fieldControlStyles({ size, appearance });
3309
3832
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
3310
3833
  const timeGranularity = granularity === "day" ? "minute" : granularity;
3311
3834
  const { hourCycle } = props;
@@ -3328,7 +3851,7 @@ function DateTimePicker({
3328
3851
  className: cn(
3329
3852
  // Box chrome on the wrapper; the DateInput inside carries padding +
3330
3853
  // font so the calendar trigger sits inside the same border + ring.
3331
- styles3.box(),
3854
+ styles4.box(),
3332
3855
  "flex items-center gap-1 pr-1",
3333
3856
  focusWithin
3334
3857
  ),
@@ -3338,7 +3861,7 @@ function DateTimePicker({
3338
3861
  {
3339
3862
  className: cn(
3340
3863
  "flex-1 flex items-center min-w-0 text-ink",
3341
- styles3.content(),
3864
+ styles4.content(),
3342
3865
  // Tabular alignment for date/time segments — overrides content's
3343
3866
  // font-sans on purpose.
3344
3867
  "font-mono"
@@ -3422,7 +3945,7 @@ var draftMessageCardStyles = tv({
3422
3945
  outcome: "shrink-0 font-mono text-[11px] text-ink-3"
3423
3946
  }
3424
3947
  });
3425
- var styles = draftMessageCardStyles();
3948
+ var styles2 = draftMessageCardStyles();
3426
3949
  var DRAFT_OUTCOME_LABEL = {
3427
3950
  sent: "Sent",
3428
3951
  rejected: "Rejected",
@@ -3439,23 +3962,23 @@ function DraftMessageCard({
3439
3962
  isPreviewDisabled = false,
3440
3963
  className
3441
3964
  }) {
3442
- return /* @__PURE__ */ jsxs("div", { className: cn(styles.root(), className), children: [
3443
- /* @__PURE__ */ jsx("span", { className: styles.icon(), children: /* @__PURE__ */ jsx(ChannelIcon, { channel }) }),
3444
- /* @__PURE__ */ jsxs("div", { className: styles.body(), children: [
3445
- /* @__PURE__ */ jsx("p", { className: styles.eyebrow(), children: eyebrow }),
3446
- /* @__PURE__ */ jsx("p", { className: styles.title(), children: title }),
3447
- recipients && recipients.length > 0 ? /* @__PURE__ */ jsxs("p", { className: styles.recipients(), children: [
3965
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles2.root(), className), children: [
3966
+ /* @__PURE__ */ jsx("span", { className: styles2.icon(), children: /* @__PURE__ */ jsx(ChannelIcon, { channel }) }),
3967
+ /* @__PURE__ */ jsxs("div", { className: styles2.body(), children: [
3968
+ /* @__PURE__ */ jsx("p", { className: styles2.eyebrow(), children: eyebrow }),
3969
+ /* @__PURE__ */ jsx("p", { className: styles2.title(), children: title }),
3970
+ recipients && recipients.length > 0 ? /* @__PURE__ */ jsxs("p", { className: styles2.recipients(), children: [
3448
3971
  "To ",
3449
3972
  recipients.join(", ")
3450
3973
  ] }) : null
3451
3974
  ] }),
3452
- outcome ? /* @__PURE__ */ jsx("span", { className: styles.outcome(), children: DRAFT_OUTCOME_LABEL[outcome] }) : /* @__PURE__ */ jsx(
3975
+ outcome ? /* @__PURE__ */ jsx("span", { className: styles2.outcome(), children: DRAFT_OUTCOME_LABEL[outcome] }) : /* @__PURE__ */ jsx(
3453
3976
  Button$1,
3454
3977
  {
3455
3978
  onPress: onPreview ?? (() => {
3456
3979
  }),
3457
3980
  isDisabled: isPreviewDisabled,
3458
- className: styles.action(),
3981
+ className: styles2.action(),
3459
3982
  children: previewLabel
3460
3983
  }
3461
3984
  )
@@ -3530,7 +4053,7 @@ function MultiSelect({
3530
4053
  appearance,
3531
4054
  className
3532
4055
  }) {
3533
- const styles3 = fieldControlStyles({ size, invalid: isInvalid, appearance });
4056
+ const styles4 = fieldControlStyles({ size, invalid: isInvalid, appearance });
3534
4057
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
3535
4058
  const minHeight = appearance === "cell" ? "min-h-[29px]" : fieldMinHeight[size];
3536
4059
  const [isOpen, setIsOpen] = useState(false);
@@ -3577,7 +4100,7 @@ function MultiSelect({
3577
4100
  "data-invalid": isInvalid || void 0,
3578
4101
  "data-disabled": isDisabled || void 0,
3579
4102
  className: cn(
3580
- styles3.box(),
4103
+ styles4.box(),
3581
4104
  "flex flex-wrap items-center gap-1.5 cursor-pointer",
3582
4105
  minHeight,
3583
4106
  fieldChipPadding[size],
@@ -3813,101 +4336,6 @@ function RecipientSelect({
3813
4336
  }
3814
4337
  );
3815
4338
  }
3816
- function Select({
3817
- label,
3818
- description,
3819
- errorMessage,
3820
- placeholder = "Select\u2026",
3821
- options,
3822
- renderItem,
3823
- size,
3824
- appearance,
3825
- triggerClassName,
3826
- popoverClassName,
3827
- className,
3828
- ...props
3829
- }) {
3830
- const styles3 = fieldControlStyles({ size, appearance });
3831
- return /* @__PURE__ */ jsxs(
3832
- Select$1,
3833
- {
3834
- ...props,
3835
- className: (renderProps) => cn(
3836
- "grid grid-cols-1 gap-1.5",
3837
- typeof className === "function" ? className(renderProps) : className
3838
- ),
3839
- children: [
3840
- label ? /* @__PURE__ */ jsx(Label, { className: fieldLabelStyles, children: label }) : null,
3841
- /* @__PURE__ */ jsxs(
3842
- Button$1,
3843
- {
3844
- className: cn(
3845
- styles3.box(),
3846
- styles3.content(),
3847
- "flex items-center justify-between gap-3 text-left cursor-pointer",
3848
- triggerClassName
3849
- ),
3850
- children: [
3851
- /* @__PURE__ */ jsx(SelectValue, { className: "truncate", children: ({ defaultChildren, isPlaceholder }) => isPlaceholder ? /* @__PURE__ */ jsx("span", { className: "text-ink-4", children: placeholder }) : defaultChildren }),
3852
- /* @__PURE__ */ jsx(FieldCaret, {})
3853
- ]
3854
- }
3855
- ),
3856
- description ? /* @__PURE__ */ jsx(Text, { slot: "description", className: fieldHintStyles, children: description }) : null,
3857
- errorMessage && appearance !== "cell" ? /* @__PURE__ */ jsx(FieldError, { className: fieldErrorStyles, children: errorMessage }) : null,
3858
- /* @__PURE__ */ jsxs(
3859
- Popover$1,
3860
- {
3861
- offset: 6,
3862
- className: cn(
3863
- // Match the trigger width exactly (RAC exposes --trigger-width on
3864
- // the Popover when anchored to a Select button).
3865
- "w-[var(--trigger-width)]",
3866
- // Float above modals + full-screen editors (e.g. agent-studio's
3867
- // .as-editor z-1000 / a raised modal overlay), matching Menu's z-[1200].
3868
- "z-[1300]",
3869
- "rounded-md border border-rule bg-surface p-1",
3870
- "shadow-[var(--shadow-raised)]",
3871
- "entering:animate-in entering:fade-in-0 entering:slide-in-from-top-1",
3872
- "exiting:animate-out exiting:fade-out-0 exiting:slide-out-to-top-1",
3873
- popoverClassName
3874
- ),
3875
- children: [
3876
- /* @__PURE__ */ jsx(ListBox, { className: "outline-none max-h-72 overflow-auto", children: options.map((option) => /* @__PURE__ */ jsx(
3877
- SelectItem,
3878
- {
3879
- id: option.id,
3880
- ...option.textValue ? { textValue: option.textValue } : {},
3881
- ...option.isDisabled ? { isDisabled: true } : {},
3882
- children: renderItem ? renderItem(option) : option.label
3883
- },
3884
- option.id
3885
- )) }),
3886
- options.length === 0 ? /* @__PURE__ */ jsx("div", { className: cn("px-3 py-2", fieldHintStyles), children: placeholder }) : null
3887
- ]
3888
- }
3889
- )
3890
- ]
3891
- }
3892
- );
3893
- }
3894
- function SelectItem(props) {
3895
- return /* @__PURE__ */ jsx(
3896
- ListBoxItem,
3897
- {
3898
- ...props,
3899
- className: cn(
3900
- "flex items-center justify-between gap-3",
3901
- "rounded-[6px] px-3 py-2 text-[14px] text-ink-2",
3902
- "cursor-pointer outline-none select-none",
3903
- "data-[hovered]:bg-surface-2 data-[hovered]:text-ink",
3904
- "data-[focused]:bg-surface-2 data-[focused]:text-ink",
3905
- "data-[selected]:bg-surface-3 data-[selected]:text-ink",
3906
- "data-[disabled]:opacity-45 data-[disabled]:cursor-not-allowed"
3907
- )
3908
- }
3909
- );
3910
- }
3911
4339
  var MAX_COMPOSER_ATTACHMENT_BYTES = 25 * 1024 * 1024;
3912
4340
  var messageComposerStyles = tv({
3913
4341
  base: [
@@ -4274,7 +4702,7 @@ var draftMessageComposerStyles = tv({
4274
4702
  error: "px-[18px] font-mono text-[11px] text-danger"
4275
4703
  }
4276
4704
  });
4277
- var styles2 = draftMessageComposerStyles();
4705
+ var styles3 = draftMessageComposerStyles();
4278
4706
  function sendRecipientsFromMessage(message, role) {
4279
4707
  return (message.recipients ?? []).filter((recipient) => recipient.role === role && !!recipient.external_id).map((recipient) => ({
4280
4708
  kind: "contact-address",
@@ -4490,10 +4918,10 @@ function DraftMessageComposer({
4490
4918
  [message?.attachments]
4491
4919
  );
4492
4920
  if (phase === "loading") {
4493
- return /* @__PURE__ */ jsx("div", { className: cn(styles2.root(), className), children: /* @__PURE__ */ jsx("p", { className: styles2.terminal(), children: "Loading draft\u2026" }) });
4921
+ return /* @__PURE__ */ jsx("div", { className: cn(styles3.root(), className), children: /* @__PURE__ */ jsx("p", { className: styles3.terminal(), children: "Loading draft\u2026" }) });
4494
4922
  }
4495
4923
  if (phase === "load-error") {
4496
- return /* @__PURE__ */ jsx("div", { className: cn(styles2.root(), className), children: /* @__PURE__ */ jsxs("p", { className: styles2.terminal(), children: [
4924
+ return /* @__PURE__ */ jsx("div", { className: cn(styles3.root(), className), children: /* @__PURE__ */ jsxs("p", { className: styles3.terminal(), children: [
4497
4925
  loadError ?? "Loading the draft failed.",
4498
4926
  " ",
4499
4927
  /* @__PURE__ */ jsx(
@@ -4508,12 +4936,12 @@ function DraftMessageComposer({
4508
4936
  }
4509
4937
  if (phase === "terminal" || !message) {
4510
4938
  const line = terminalKind === "sent" ? "This draft was sent." : terminalKind === "rejected" ? "This draft was rejected." : terminalKind === "failed" ? `Sending failed${message?.error ? ` \u2014 ${message.error}` : ""}.` : "This message is not a reviewable draft.";
4511
- return /* @__PURE__ */ jsx("div", { className: cn(styles2.root(), className), "data-draft-terminal": terminalKind, children: /* @__PURE__ */ jsx("p", { className: styles2.terminal(), children: line }) });
4939
+ return /* @__PURE__ */ jsx("div", { className: cn(styles3.root(), className), "data-draft-terminal": terminalKind, children: /* @__PURE__ */ jsx("p", { className: styles3.terminal(), children: line }) });
4512
4940
  }
4513
- return /* @__PURE__ */ jsxs("div", { className: cn(styles2.root(), className), children: [
4514
- /* @__PURE__ */ jsxs("div", { className: styles2.header(), children: [
4515
- /* @__PURE__ */ jsx("span", { className: styles2.badge(), children: "Draft \xB7 awaiting review" }),
4516
- /* @__PURE__ */ jsxs("span", { className: styles2.sender(), children: [
4941
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles3.root(), className), children: [
4942
+ /* @__PURE__ */ jsxs("div", { className: styles3.header(), children: [
4943
+ /* @__PURE__ */ jsx("span", { className: styles3.badge(), children: "Draft \xB7 awaiting review" }),
4944
+ /* @__PURE__ */ jsxs("span", { className: styles3.sender(), children: [
4517
4945
  "from ",
4518
4946
  message.sender.name
4519
4947
  ] })
@@ -4544,11 +4972,11 @@ function DraftMessageComposer({
4544
4972
  showSendButton: showActions
4545
4973
  }
4546
4974
  ),
4547
- actionError ? /* @__PURE__ */ jsxs("p", { className: styles2.error(), children: [
4975
+ actionError ? /* @__PURE__ */ jsxs("p", { className: styles3.error(), children: [
4548
4976
  actionError,
4549
4977
  " \u2014 your edits are kept."
4550
4978
  ] }) : null,
4551
- showActions ? /* @__PURE__ */ jsxs("div", { className: styles2.actions(), children: [
4979
+ showActions ? /* @__PURE__ */ jsxs("div", { className: styles3.actions(), children: [
4552
4980
  isConfirmingReject ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4553
4981
  /* @__PURE__ */ jsx("span", { className: "text-[12.5px] text-ink-3", children: "Reject draft?" }),
4554
4982
  /* @__PURE__ */ jsx(
@@ -4585,92 +5013,6 @@ function DraftMessageComposer({
4585
5013
  ] }) : null
4586
5014
  ] });
4587
5015
  }
4588
- function Modal(props) {
4589
- return /* @__PURE__ */ jsx(DialogTrigger, { ...props });
4590
- }
4591
- function ModalContent({
4592
- children,
4593
- className,
4594
- modalClassName,
4595
- isDismissable = true,
4596
- ...props
4597
- }) {
4598
- return /* @__PURE__ */ jsx(
4599
- ModalOverlay,
4600
- {
4601
- isDismissable,
4602
- ...props,
4603
- className: (renderProps) => cn(
4604
- "fixed inset-0 z-50 flex items-center justify-center p-4",
4605
- // Warm ink scrim — stays in the Proteos palette (no pure black).
4606
- "bg-[color-mix(in_oklab,var(--color-ink)_40%,transparent)]",
4607
- "entering:animate-in entering:fade-in-0 entering:duration-150",
4608
- "exiting:animate-out exiting:fade-out-0 exiting:duration-100",
4609
- typeof className === "function" ? className(renderProps) : className
4610
- ),
4611
- children: /* @__PURE__ */ jsx(
4612
- Modal$1,
4613
- {
4614
- className: cn(
4615
- "w-full max-w-lg",
4616
- // Cap the panel at the viewport (minus the overlay's p-4) and lay it
4617
- // out as a column so a tall body scrolls instead of overflowing the
4618
- // screen. Short modals are unaffected — height still tracks content.
4619
- "flex flex-col max-h-[calc(100dvh-2rem)]",
4620
- "bg-surface border border-rule rounded-lg",
4621
- "shadow-[var(--shadow-float)]",
4622
- "entering:animate-in entering:zoom-in-95 entering:slide-in-from-top-2 entering:duration-150",
4623
- "exiting:animate-out exiting:zoom-out-95 exiting:duration-100",
4624
- modalClassName
4625
- ),
4626
- children: /* @__PURE__ */ jsx(Dialog, { className: "outline-none flex flex-col min-h-0 overflow-hidden", children })
4627
- }
4628
- )
4629
- }
4630
- );
4631
- }
4632
- function ModalHeader({ className, ...props }) {
4633
- return /* @__PURE__ */ jsx("div", { ...props, className: cn("shrink-0 px-5 pt-5 pb-3 flex flex-col gap-1.5", className) });
4634
- }
4635
- function ModalTitle({ className, ...props }) {
4636
- return /* @__PURE__ */ jsx(
4637
- Heading,
4638
- {
4639
- slot: "title",
4640
- ...props,
4641
- className: cn(
4642
- "font-sans font-medium text-[20px] leading-[1.25] tracking-[-0.015em] text-ink",
4643
- className
4644
- )
4645
- }
4646
- );
4647
- }
4648
- function ModalDescription({ className, ...props }) {
4649
- return /* @__PURE__ */ jsx("p", { ...props, className: cn("text-[14px] leading-[1.55] text-ink-3", className) });
4650
- }
4651
- function ModalBody({ className, ...props }) {
4652
- return /* @__PURE__ */ jsx(
4653
- "div",
4654
- {
4655
- ...props,
4656
- className: cn(
4657
- // The scroll region: caps at the panel's spare height and scrolls when
4658
- // the content is taller, leaving header + footer pinned.
4659
- "min-h-0 overflow-y-auto px-5 py-3 flex flex-col gap-3 text-[14px] text-ink-2",
4660
- className
4661
- )
4662
- }
4663
- );
4664
- }
4665
- function ModalFooter({ className, ...props }) {
4666
- return /* @__PURE__ */ jsx(
4667
- "div",
4668
- {
4669
- ...props,
4670
- className: cn("shrink-0 flex justify-end items-center gap-2", "px-5 pt-3 pb-5", className)
4671
- }
4672
- );
4673
- }
4674
5016
  function DraftMessageReview({
4675
5017
  messageId,
4676
5018
  client,
@@ -4816,12 +5158,12 @@ function EmptyState({
4816
5158
  size,
4817
5159
  className
4818
5160
  }) {
4819
- const styles3 = emptyStateStyles({ size });
4820
- return /* @__PURE__ */ jsxs("div", { className: cn(styles3.root(), className), children: [
4821
- icon ? /* @__PURE__ */ jsx("div", { className: styles3.art(), children: icon }) : null,
4822
- /* @__PURE__ */ jsx("div", { className: styles3.title(), children: title }),
4823
- description ? /* @__PURE__ */ jsx("div", { className: styles3.description(), children: description }) : null,
4824
- action ? /* @__PURE__ */ jsx("div", { className: styles3.actions(), children: action }) : null
5161
+ const styles4 = emptyStateStyles({ size });
5162
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles4.root(), className), children: [
5163
+ icon ? /* @__PURE__ */ jsx("div", { className: styles4.art(), children: icon }) : null,
5164
+ /* @__PURE__ */ jsx("div", { className: styles4.title(), children: title }),
5165
+ description ? /* @__PURE__ */ jsx("div", { className: styles4.description(), children: description }) : null,
5166
+ action ? /* @__PURE__ */ jsx("div", { className: styles4.actions(), children: action }) : null
4825
5167
  ] });
4826
5168
  }
4827
5169
  function ErrorAnimation({ className }) {
@@ -5062,7 +5404,7 @@ function Input({
5062
5404
  className,
5063
5405
  ...props
5064
5406
  }) {
5065
- const styles3 = fieldControlStyles({ size, appearance, hasFocusRing });
5407
+ const styles4 = fieldControlStyles({ size, appearance, hasFocusRing });
5066
5408
  return /* @__PURE__ */ jsxs(
5067
5409
  TextField,
5068
5410
  {
@@ -5078,7 +5420,7 @@ function Input({
5078
5420
  {
5079
5421
  ...inputProps,
5080
5422
  placeholder: placeholder ?? "",
5081
- className: cn(styles3.box(), styles3.content(), inputClassName)
5423
+ className: cn(styles4.box(), styles4.content(), inputClassName)
5082
5424
  }
5083
5425
  ),
5084
5426
  description ? /* @__PURE__ */ jsx(Text, { slot: "description", className: fieldHintStyles, children: description }) : null,
@@ -5588,6 +5930,8 @@ function ChipItem({
5588
5930
  Badge,
5589
5931
  {
5590
5932
  variant: option?.variant,
5933
+ shape: "rounded",
5934
+ hasDot: false,
5591
5935
  ...option?.color ? { color: option.color } : {},
5592
5936
  ...option?.icon ? { icon: option.icon } : {},
5593
5937
  children: option?.label ?? value
@@ -5664,7 +6008,7 @@ function SegmentedControl({
5664
6008
  orientation = "horizontal",
5665
6009
  ...props
5666
6010
  }) {
5667
- const styles3 = segmentedControlStyles({ size });
6011
+ const styles4 = segmentedControlStyles({ size });
5668
6012
  return /* @__PURE__ */ jsx(
5669
6013
  RadioGroup$1,
5670
6014
  {
@@ -5672,14 +6016,14 @@ function SegmentedControl({
5672
6016
  orientation,
5673
6017
  value: String(value),
5674
6018
  onChange: (next) => onChange(next),
5675
- className: cn(styles3.group(), className),
6019
+ className: cn(styles4.group(), className),
5676
6020
  children: options.map((option) => /* @__PURE__ */ jsx(
5677
6021
  Radio$1,
5678
6022
  {
5679
6023
  value: String(option.id),
5680
6024
  ...option.isDisabled ? { isDisabled: true } : {},
5681
6025
  ...autoFocus && option.id === value ? { autoFocus: true } : {},
5682
- className: styles3.segment(),
6026
+ className: styles4.segment(),
5683
6027
  children: option.label
5684
6028
  },
5685
6029
  String(option.id)
@@ -5702,7 +6046,7 @@ function TagInput({
5702
6046
  autoFocus = false,
5703
6047
  className
5704
6048
  }) {
5705
- const styles3 = fieldControlStyles({ size, invalid: isInvalid, appearance });
6049
+ const styles4 = fieldControlStyles({ size, invalid: isInvalid, appearance });
5706
6050
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
5707
6051
  const minHeight = appearance === "cell" ? "min-h-[29px]" : fieldMinHeight[size];
5708
6052
  const inputRef = useRef(null);
@@ -5743,7 +6087,7 @@ function TagInput({
5743
6087
  "data-invalid": isInvalid || void 0,
5744
6088
  "data-disabled": isDisabled || void 0,
5745
6089
  className: cn(
5746
- styles3.box(),
6090
+ styles4.box(),
5747
6091
  "flex flex-wrap items-center gap-1",
5748
6092
  minHeight,
5749
6093
  fieldChipPadding[size],
@@ -7493,45 +7837,45 @@ var tabsStyles = tv({
7493
7837
  defaultVariants: { size: "md" }
7494
7838
  });
7495
7839
  function Root({ size, className, children, ...props }) {
7496
- const styles3 = tabsStyles({ size });
7840
+ const styles4 = tabsStyles({ size });
7497
7841
  return /* @__PURE__ */ jsx(
7498
7842
  Tabs$1,
7499
7843
  {
7500
7844
  ...props,
7501
- className: (rp) => cn(styles3.root(), typeof className === "function" ? className(rp) : className),
7845
+ className: (rp) => cn(styles4.root(), typeof className === "function" ? className(rp) : className),
7502
7846
  children
7503
7847
  }
7504
7848
  );
7505
7849
  }
7506
7850
  function List({ size, className, children, ...props }) {
7507
- const styles3 = tabsStyles({ size });
7851
+ const styles4 = tabsStyles({ size });
7508
7852
  return /* @__PURE__ */ jsx(
7509
7853
  TabList,
7510
7854
  {
7511
7855
  ...props,
7512
- className: (rp) => cn(styles3.list(), typeof className === "function" ? className(rp) : className),
7856
+ className: (rp) => cn(styles4.list(), typeof className === "function" ? className(rp) : className),
7513
7857
  children
7514
7858
  }
7515
7859
  );
7516
7860
  }
7517
7861
  function Trigger({ size, className, children, ...props }) {
7518
- const styles3 = tabsStyles({ size });
7862
+ const styles4 = tabsStyles({ size });
7519
7863
  return /* @__PURE__ */ jsx(
7520
7864
  Tab,
7521
7865
  {
7522
7866
  ...props,
7523
- className: (rp) => cn(styles3.trigger(), typeof className === "function" ? className(rp) : className),
7867
+ className: (rp) => cn(styles4.trigger(), typeof className === "function" ? className(rp) : className),
7524
7868
  children
7525
7869
  }
7526
7870
  );
7527
7871
  }
7528
7872
  function Panel({ className, children, ...props }) {
7529
- const styles3 = tabsStyles({});
7873
+ const styles4 = tabsStyles({});
7530
7874
  return /* @__PURE__ */ jsx(
7531
7875
  TabPanel,
7532
7876
  {
7533
7877
  ...props,
7534
- className: (rp) => cn(styles3.panel(), typeof className === "function" ? className(rp) : className),
7878
+ className: (rp) => cn(styles4.panel(), typeof className === "function" ? className(rp) : className),
7535
7879
  children
7536
7880
  }
7537
7881
  );
@@ -7555,7 +7899,7 @@ function Textarea({
7555
7899
  className,
7556
7900
  ...props
7557
7901
  }) {
7558
- const styles3 = fieldControlStyles({ size, appearance });
7902
+ const styles4 = fieldControlStyles({ size, appearance });
7559
7903
  return /* @__PURE__ */ jsxs(
7560
7904
  TextField,
7561
7905
  {
@@ -7575,8 +7919,8 @@ function Textarea({
7575
7919
  className: cn(
7576
7920
  // Same hairline chrome as Input, but allow vertical resize and set a
7577
7921
  // sensible minimum height so short content doesn't collapse.
7578
- styles3.box(),
7579
- styles3.content(),
7922
+ styles4.box(),
7923
+ styles4.content(),
7580
7924
  "min-h-[100px] resize-y",
7581
7925
  textareaClassName
7582
7926
  )
@@ -7597,7 +7941,7 @@ function TimeField({
7597
7941
  className,
7598
7942
  ...props
7599
7943
  }) {
7600
- const styles3 = fieldControlStyles({ size, appearance });
7944
+ const styles4 = fieldControlStyles({ size, appearance });
7601
7945
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
7602
7946
  return /* @__PURE__ */ jsxs(
7603
7947
  TimeField$1,
@@ -7613,8 +7957,8 @@ function TimeField({
7613
7957
  DateInput,
7614
7958
  {
7615
7959
  className: cn(
7616
- styles3.box(),
7617
- styles3.content(),
7960
+ styles4.box(),
7961
+ styles4.content(),
7618
7962
  "flex items-center min-w-0 text-ink",
7619
7963
  // Tabular alignment for time segments — overrides content's
7620
7964
  // font-sans on purpose.
@@ -7737,6 +8081,6 @@ function Tooltip({ className, offset = 6, ...props }) {
7737
8081
  );
7738
8082
  }
7739
8083
 
7740
- export { ATTRIBUTE_TYPES, ATTRIBUTE_TYPE_ICONS, AttachmentChip, AttributePicker, AttributeType, AttributeTypeIcon, Avatar, AvatarGroup, Badge, BadgeMultiSelect, BooleanCell, Breadcrumbs, COLUMN_DRAG_KIND, Card, CardBody, CardContent, CardEyebrow, CardFeatureTitle, CardFooter, CardHeader, CardTitle, ChannelIcon, Checkbox, CheckboxGroup, ChipValue, ColorInput, Combobox, Command, CommandHint, CurrencyInput, DRAFT_OUTCOME_LABEL, DataTable, DataTableEmpty, DataTableError, DataTableSkeleton, DateCell, DatePicker, DateTimeCell, DateTimePicker, DraftMessageCard, DraftMessageComposer, DraftMessageReview, EmptyState, ErrorAnimation, FIELD_LABEL_SEPARATOR, FieldCaret, FileField, FileViewer, FileViewerFallbackCard, FilterRow, FilterValueInput, IconPicker, ImageAttachment, ImageLightbox, Input, Kbd, LinkCell, MAX_COMPOSER_ATTACHMENT_BYTES, Menu, MenuItem, MenuPopover, MenuTrigger, MessageComposer, Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, MultiSelect, NavGroup, NavItem, NavSection, OPERATORS, OperatorPicker, Orb, PROTECTED_COMBOS, Popover, PopoverContent, PopoverPanelBody, PopoverPanelFooter, PopoverPanelHeader, PressableCard, ProgressBar, Radio, RadioGroup, RecipientSelect, RecordFilterBuilderPanel, RecordFilterButton, RecordFilterChips, RecordFilterEditor, RenderChipItemProvider, RenderValueInputProvider, SELECTION_COLUMN_ID, SegmentedControl, Select, Separator, SubmenuTrigger, SuccessAnimation, Switch, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableHeaderSpacer, TableRow, TableScroller, Tabs, TagInput, Textarea, TimeField, ToastRegion, Tooltip, TooltipTrigger, TruncateCell, __resetDraftMessageActions, __resetDraftMessageOutcomes, addLeaf as addFilterLeaf, addPendingLeaf, addSubgroup, arityOf, attachmentChipStyles, avatarGroupStyles, avatarStyles, badgeStyles, cardStyles2 as cardStyles, channelIcon, countLeaves, createDraftMessageClient, createToastQueue, defaultValueFor, draftMessageCardStyles, draftMessageComposerStyles, draftOutcomeFor, emptyStateStyles, fieldControlStyles, fieldErrorStyles, fieldHintStyles, fieldLabelStyles, fileViewerFallbackCardStyles, fileViewerStyles, formatFileSize, formatValue, iconForContentType, imageAttachmentStyles, imageLightboxStyles, isColumnDragData, isDraftReviewOutcome, isEditableTarget, isPreviewableImageName, joinFieldLabel, makeActionsColumn, messageComposerStyles, navItemStyles, normalizeHexColor, operatorById, operatorsForType, parseCombo, progressBarStyles, publishDraftMessageOutcome, rebaseRowOnFieldChange, rebaseRowOnOperatorChange, registerDraftMessageActions, removeLeaf, removeSubgroup, replaceLeaf, resolveLucideIcon, resolveLucideIconName, segmentedControlStyles, setJoiner, subscribeDraftMessageOutcome, tableCellStyles, tableHeaderCellStyles, tabsStyles, terminalKindFor, toastStyles, updateLeaf, updateSubgroup, useAttributeTypeIcon, useCommand, useDiscoveryActive, useDraftMessageActions, useDraftMessageOutcome, useEscapeKey, useInfiniteScrollSentinel, useRenderChipItem, useRenderValueInput, useShowDetails, viewerKindForContentType, wrapLeafInGroup };
8084
+ export { ATTRIBUTE_TYPES, ATTRIBUTE_TYPE_ICONS, AttachmentChip, AttributePicker, AttributeType, AttributeTypeIcon, Avatar, AvatarGroup, Badge, BadgeMultiSelect, BooleanCell, Breadcrumbs, COLUMN_DRAG_KIND, CONVERSATION_BRIEF_OUTCOME_LABEL, Card, CardBody, CardContent, CardEyebrow, CardFeatureTitle, CardFooter, CardHeader, CardTitle, ChannelIcon, Checkbox, CheckboxGroup, ChipValue, ColorInput, Combobox, Command, CommandHint, ConversationBriefCard, ConversationBriefPreview, ConversationBriefReview, CurrencyInput, DRAFT_OUTCOME_LABEL, DataTable, DataTableEmpty, DataTableError, DataTableSkeleton, DateCell, DatePicker, DateTimeCell, DateTimePicker, DraftMessageCard, DraftMessageComposer, DraftMessageReview, EmptyState, ErrorAnimation, FIELD_LABEL_SEPARATOR, FieldCaret, FileField, FileViewer, FileViewerFallbackCard, FilterRow, FilterValueInput, IconPicker, ImageAttachment, ImageLightbox, Input, Kbd, LinkCell, MAX_COMPOSER_ATTACHMENT_BYTES, Menu, MenuItem, MenuPopover, MenuTrigger, MessageComposer, Modal, ModalBody, ModalContent, ModalDescription, ModalFooter, ModalHeader, ModalTitle, MultiSelect, NavGroup, NavItem, NavSection, OPERATORS, OperatorPicker, Orb, PROTECTED_COMBOS, Popover, PopoverContent, PopoverPanelBody, PopoverPanelFooter, PopoverPanelHeader, PressableCard, ProgressBar, Radio, RadioGroup, RecipientSelect, RecordFilterBuilderPanel, RecordFilterButton, RecordFilterChips, RecordFilterEditor, RenderChipItemProvider, RenderValueInputProvider, SELECTION_COLUMN_ID, SegmentedControl, Select, Separator, SubmenuTrigger, SuccessAnimation, Switch, Table, TableBody, TableCell, TableHeader, TableHeaderCell, TableHeaderSpacer, TableRow, TableScroller, Tabs, TagInput, Textarea, TimeField, ToastRegion, Tooltip, TooltipTrigger, TruncateCell, __resetDraftMessageActions, __resetDraftMessageOutcomes, addLeaf as addFilterLeaf, addPendingLeaf, addSubgroup, arityOf, attachmentChipStyles, avatarGroupStyles, avatarStyles, badgeStyles, cardStyles2 as cardStyles, channelIcon, contactPhoneNumbers, conversationBriefCardStyles, conversationBriefOutcomeFor, countLeaves, createConversationBriefClient, createDraftMessageClient, createToastQueue, defaultValueFor, draftMessageCardStyles, draftMessageComposerStyles, draftOutcomeFor, emptyStateStyles, fieldControlStyles, fieldErrorStyles, fieldHintStyles, fieldLabelStyles, fileViewerFallbackCardStyles, fileViewerStyles, formatFileSize, formatValue, iconForContentType, imageAttachmentStyles, imageLightboxStyles, isColumnDragData, isDialableConversationBrief, isDraftReviewOutcome, isEditableTarget, isPreviewableImageName, joinFieldLabel, makeActionsColumn, messageComposerStyles, namesOf, navItemStyles, normalizeHexColor, operatorById, operatorsForType, parseCombo, progressBarStyles, publishDraftMessageOutcome, rebaseRowOnFieldChange, rebaseRowOnOperatorChange, registerDraftMessageActions, removeLeaf, removeSubgroup, replaceLeaf, resolveLucideIcon, resolveLucideIconName, segmentedControlStyles, setJoiner, subscribeDraftMessageOutcome, summaryFor, tableCellStyles, tableHeaderCellStyles, tabsStyles, terminalKindFor, toastStyles, updateLeaf, updateSubgroup, useAttributeTypeIcon, useCommand, useDiscoveryActive, useDraftMessageActions, useDraftMessageOutcome, useEscapeKey, useInfiniteScrollSentinel, useRenderChipItem, useRenderValueInput, useShowDetails, viewerKindForContentType, wrapLeafInGroup };
7741
8085
  //# sourceMappingURL=index.js.map
7742
8086
  //# sourceMappingURL=index.js.map