@proteos/ui 0.50.1 → 0.51.1

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
@@ -1,10 +1,10 @@
1
1
  import { cn, Button, Skeleton } from './chunk-IKAX76MB.js';
2
2
  export { Button, Skeleton, buttonStyles, cn, skeletonStyles } from './chunk-IKAX76MB.js';
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';
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, Pencil, 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,532 @@ 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
+ renderContent,
2152
+ onEdit,
2153
+ editor
2154
+ }) {
2155
+ const [pickedContactId, setPickedContactId] = useState("");
2156
+ const contact = contacts.find((entry) => entry.id === pickedContactId) ?? contacts[0] ?? null;
2157
+ const numbers = useMemo(() => contactPhoneNumbers(contact), [contact]);
2158
+ const [pickedNumber, setPickedNumber] = useState("");
2159
+ const phoneNumber = numbers.includes(pickedNumber) ? pickedNumber : numbers[0] || "";
2160
+ const isOpen = brief.status === "prepared";
2161
+ const names = contacts.map((entry) => entry.name).filter(Boolean).join(", ");
2162
+ const onSelectionChangeRef = useRef(onSelectionChange);
2163
+ onSelectionChangeRef.current = onSelectionChange;
2164
+ useEffect(() => {
2165
+ onSelectionChangeRef.current?.(contact, phoneNumber);
2166
+ }, [contact, phoneNumber]);
2167
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
2168
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
2169
+ /* @__PURE__ */ jsx("p", { className: "truncate text-[14px] font-semibold text-ink", children: brief.subject || names || "Prepared conversation" }),
2170
+ /* @__PURE__ */ jsx("p", { className: "font-mono text-[10.5px] text-ink-4", children: [
2171
+ brief.subject ? names : "",
2172
+ brief.channel ? `Channel ${brief.channel}` : "Any channel",
2173
+ brief.type_key ? `Type ${brief.type_key}` : "",
2174
+ brief.status === "prepared" ? "Prepared" : brief.status === "used" ? "Call held" : "Discarded"
2175
+ ].filter(Boolean).join(" \xB7 ") })
2176
+ ] }),
2177
+ editor ?? /* @__PURE__ */ jsxs("div", { className: "group/brief-content relative", children: [
2178
+ /* @__PURE__ */ jsx(
2179
+ "div",
2180
+ {
2181
+ className: cn(
2182
+ "rounded-md border border-rule-2 bg-surface-2/60 px-3 py-2.5",
2183
+ "text-[13px] leading-relaxed text-ink-2 overflow-y-auto [scrollbar-width:thin]",
2184
+ renderContent ? null : "whitespace-pre-wrap",
2185
+ contentClassName
2186
+ ),
2187
+ children: renderContent ? renderContent(brief.content) : brief.content
2188
+ }
2189
+ ),
2190
+ onEdit ? /* @__PURE__ */ jsx(
2191
+ Button$1,
2192
+ {
2193
+ "aria-label": "Edit brief",
2194
+ onPress: onEdit,
2195
+ className: cn(
2196
+ "absolute right-1.5 top-1.5 inline-flex size-7 cursor-pointer items-center justify-center",
2197
+ "rounded-md bg-surface/80 text-ink-3 outline-none transition-opacity",
2198
+ "opacity-0 group-hover/brief-content:opacity-100 focus-visible:opacity-100",
2199
+ "data-[hovered]:bg-surface-3 data-[hovered]:text-ink",
2200
+ "focus-visible:shadow-[var(--shadow-focus)]"
2201
+ ),
2202
+ children: /* @__PURE__ */ jsx(Pencil, { className: "size-3.5", "aria-hidden": true })
2203
+ }
2204
+ ) : null
2205
+ ] }),
2206
+ onCall ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 border-t border-rule-2 pt-3", children: [
2207
+ contacts.length > 1 ? /* @__PURE__ */ jsx(
2208
+ Select,
2209
+ {
2210
+ "aria-label": "Who to call",
2211
+ selectedKey: contact?.id ?? "",
2212
+ onSelectionChange: (key) => {
2213
+ setPickedContactId(String(key));
2214
+ setPickedNumber("");
2215
+ },
2216
+ options: contacts.map((entry) => ({ id: entry.id, label: entry.name || entry.id }))
2217
+ }
2218
+ ) : null,
2219
+ numbers.length > 1 ? /* @__PURE__ */ jsx(
2220
+ Select,
2221
+ {
2222
+ "aria-label": "Number to call",
2223
+ selectedKey: phoneNumber,
2224
+ onSelectionChange: (key) => setPickedNumber(String(key)),
2225
+ options: numbers.map((number) => ({ id: number, label: number }))
2226
+ }
2227
+ ) : /* @__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.") }),
2228
+ controls,
2229
+ callDisabledReason ? /* @__PURE__ */ jsx("p", { className: "text-[12px] text-warning", children: callDisabledReason }) : null,
2230
+ isCallButtonHidden ? null : /* @__PURE__ */ jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxs(
2231
+ Button,
2232
+ {
2233
+ isDisabled: isCallDisabled || !isOpen || phoneNumber === "" || !contact,
2234
+ onPress: () => contact && onCall(contact, phoneNumber),
2235
+ children: [
2236
+ /* @__PURE__ */ jsx(Phone, { className: "size-3.5", "aria-hidden": true }),
2237
+ callLabel
2238
+ ]
2239
+ }
2240
+ ) })
2241
+ ] }) : null
2242
+ ] });
2243
+ }
2244
+ function Modal(props) {
2245
+ return /* @__PURE__ */ jsx(DialogTrigger, { ...props });
2246
+ }
2247
+ function ModalContent({
2248
+ children,
2249
+ className,
2250
+ modalClassName,
2251
+ isDismissable = true,
2252
+ ...props
2253
+ }) {
2254
+ return /* @__PURE__ */ jsx(
2255
+ ModalOverlay,
2256
+ {
2257
+ isDismissable,
2258
+ ...props,
2259
+ className: (renderProps) => cn(
2260
+ "fixed inset-0 z-50 flex items-center justify-center p-4",
2261
+ // Warm ink scrim — stays in the Proteos palette (no pure black).
2262
+ "bg-[color-mix(in_oklab,var(--color-ink)_40%,transparent)]",
2263
+ "entering:animate-in entering:fade-in-0 entering:duration-150",
2264
+ "exiting:animate-out exiting:fade-out-0 exiting:duration-100",
2265
+ typeof className === "function" ? className(renderProps) : className
2266
+ ),
2267
+ children: /* @__PURE__ */ jsx(
2268
+ Modal$1,
2269
+ {
2270
+ className: cn(
2271
+ "w-full max-w-lg",
2272
+ // Cap the panel at the viewport (minus the overlay's p-4) and lay it
2273
+ // out as a column so a tall body scrolls instead of overflowing the
2274
+ // screen. Short modals are unaffected — height still tracks content.
2275
+ "flex flex-col max-h-[calc(100dvh-2rem)]",
2276
+ "bg-surface border border-rule rounded-lg",
2277
+ "shadow-[var(--shadow-float)]",
2278
+ "entering:animate-in entering:zoom-in-95 entering:slide-in-from-top-2 entering:duration-150",
2279
+ "exiting:animate-out exiting:zoom-out-95 exiting:duration-100",
2280
+ modalClassName
2281
+ ),
2282
+ children: /* @__PURE__ */ jsx(Dialog, { className: "outline-none flex flex-col min-h-0 overflow-hidden", children })
2283
+ }
2284
+ )
2285
+ }
2286
+ );
2287
+ }
2288
+ function ModalHeader({ className, ...props }) {
2289
+ return /* @__PURE__ */ jsx("div", { ...props, className: cn("shrink-0 px-5 pt-5 pb-3 flex flex-col gap-1.5", className) });
2290
+ }
2291
+ function ModalTitle({ className, ...props }) {
2292
+ return /* @__PURE__ */ jsx(
2293
+ Heading,
2294
+ {
2295
+ slot: "title",
2296
+ ...props,
2297
+ className: cn(
2298
+ "font-sans font-medium text-[20px] leading-[1.25] tracking-[-0.015em] text-ink",
2299
+ className
2300
+ )
2301
+ }
2302
+ );
2303
+ }
2304
+ function ModalDescription({ className, ...props }) {
2305
+ return /* @__PURE__ */ jsx("p", { ...props, className: cn("text-[14px] leading-[1.55] text-ink-3", className) });
2306
+ }
2307
+ function ModalBody({ className, ...props }) {
2308
+ return /* @__PURE__ */ jsx(
2309
+ "div",
2310
+ {
2311
+ ...props,
2312
+ className: cn(
2313
+ // The scroll region: caps at the panel's spare height and scrolls when
2314
+ // the content is taller, leaving header + footer pinned.
2315
+ "min-h-0 overflow-y-auto px-5 py-3 flex flex-col gap-3 text-[14px] text-ink-2",
2316
+ className
2317
+ )
2318
+ }
2319
+ );
2320
+ }
2321
+ function ModalFooter({ className, ...props }) {
2322
+ return /* @__PURE__ */ jsx(
2323
+ "div",
2324
+ {
2325
+ ...props,
2326
+ className: cn("shrink-0 flex justify-end items-center gap-2", "px-5 pt-3 pb-5", className)
2327
+ }
2328
+ );
2329
+ }
2330
+ function ConversationBriefReview({
2331
+ conversationBriefId,
2332
+ client,
2333
+ onOpenCall,
2334
+ onCall,
2335
+ isCallDisabled = false,
2336
+ callDisabledReason,
2337
+ onOutcome,
2338
+ onLoadError,
2339
+ modalTitle = "Prepared conversation",
2340
+ modalClassName = "max-w-2xl",
2341
+ overlayClassName,
2342
+ openLabel,
2343
+ className,
2344
+ renderContent
2345
+ }) {
2346
+ const [brief, setBrief] = useState(null);
2347
+ const [contacts, setContacts] = useState([]);
2348
+ const [isOpen, setIsOpen] = useState(false);
2349
+ const [outcome, setOutcome] = useState(null);
2350
+ const onOutcomeRef = useRef(onOutcome);
2351
+ onOutcomeRef.current = onOutcome;
2352
+ const onLoadErrorRef = useRef(onLoadError);
2353
+ onLoadErrorRef.current = onLoadError;
2354
+ const hasSettledRef = useRef(false);
2355
+ const settle = useCallback((next, settled) => {
2356
+ setOutcome(next);
2357
+ setIsOpen(false);
2358
+ if (hasSettledRef.current) return;
2359
+ hasSettledRef.current = true;
2360
+ onOutcomeRef.current?.(next, settled);
2361
+ }, []);
2362
+ useEffect(() => {
2363
+ let cancelled = false;
2364
+ void (async () => {
2365
+ try {
2366
+ const loaded = await client.getConversationBrief(conversationBriefId);
2367
+ if (cancelled) return;
2368
+ setBrief(loaded);
2369
+ const terminal = conversationBriefOutcomeFor(loaded.status);
2370
+ if (terminal) settle(terminal, loaded);
2371
+ const people = await Promise.all(
2372
+ loaded.contact_ids.map((contactId) => client.getContact(contactId).catch(() => null))
2373
+ );
2374
+ if (!cancelled) setContacts(people.filter((person) => person !== null));
2375
+ } catch (error) {
2376
+ if (cancelled) return;
2377
+ onLoadErrorRef.current?.(error instanceof Error ? error : new Error(String(error)));
2378
+ }
2379
+ })();
2380
+ return () => {
2381
+ cancelled = true;
2382
+ };
2383
+ }, [client, conversationBriefId, settle]);
2384
+ const open = () => {
2385
+ if (onOpenCall) {
2386
+ onOpenCall(conversationBriefId);
2387
+ return;
2388
+ }
2389
+ setIsOpen(true);
2390
+ };
2391
+ if (!brief) return null;
2392
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
2393
+ /* @__PURE__ */ jsx(
2394
+ ConversationBriefCard,
2395
+ {
2396
+ title: brief.subject || namesOf(contacts) || "Prepared conversation",
2397
+ summary: summaryFor(brief, contacts),
2398
+ outcome,
2399
+ onOpen: open,
2400
+ ...openLabel !== void 0 ? { openLabel } : {},
2401
+ ...className !== void 0 ? { className } : {}
2402
+ }
2403
+ ),
2404
+ onOpenCall ? null : /* @__PURE__ */ jsxs(
2405
+ ModalContent,
2406
+ {
2407
+ isOpen,
2408
+ onOpenChange: setIsOpen,
2409
+ modalClassName,
2410
+ ...overlayClassName !== void 0 ? { className: overlayClassName } : {},
2411
+ children: [
2412
+ /* @__PURE__ */ jsx(ModalHeader, { children: /* @__PURE__ */ jsx(ModalTitle, { children: modalTitle }) }),
2413
+ /* @__PURE__ */ jsx(ModalBody, { className: "min-h-0 overflow-y-auto", children: /* @__PURE__ */ jsx(
2414
+ ConversationBriefPreview,
2415
+ {
2416
+ brief,
2417
+ contacts,
2418
+ contentClassName: "max-h-[50dvh]",
2419
+ isCallDisabled,
2420
+ ...callDisabledReason !== void 0 ? { callDisabledReason } : {},
2421
+ ...renderContent !== void 0 ? { renderContent } : {},
2422
+ ...onCall && isDialableConversationBrief(brief) ? {
2423
+ onCall: (contact, phoneNumber) => {
2424
+ setIsOpen(false);
2425
+ onCall(brief, contact, phoneNumber);
2426
+ }
2427
+ } : {}
2428
+ }
2429
+ ) })
2430
+ ]
1909
2431
  }
1910
- ) : null
2432
+ )
1911
2433
  ] });
1912
2434
  }
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);
2435
+ function namesOf(contacts) {
2436
+ return contacts.map((contact) => contact.name).filter(Boolean).join(", ");
1921
2437
  }
1922
- function ensureListener2() {
1923
- if (listenerInstalled2) return;
1924
- if (typeof window === "undefined") return;
1925
- window.addEventListener("keydown", onWindowKeyDown2, { capture: true });
1926
- listenerInstalled2 = true;
2438
+ function summaryFor(brief, contacts) {
2439
+ const firstLine = brief.content.split("\n").find((line) => line.trim() !== "")?.trim() ?? "";
2440
+ return [
2441
+ brief.subject ? namesOf(contacts) : "",
2442
+ brief.channel ?? "",
2443
+ brief.type_key ?? "",
2444
+ firstLine
2445
+ ].filter(Boolean).join(" \xB7 ");
1927
2446
  }
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]);
2447
+
2448
+ // src/components/conversation-brief-card/create-conversation-brief-client.ts
2449
+ function createConversationBriefClient(conversation) {
2450
+ return {
2451
+ getConversationBrief: (conversationBriefId) => conversation.conversationBriefs.get(conversationBriefId),
2452
+ getContact: (contactId) => conversation.contacts.get(contactId)
2453
+ };
1946
2454
  }
1947
2455
  function CurrencyInput({
1948
2456
  value,
@@ -1975,16 +2483,16 @@ function CurrencyInput({
1975
2483
  onChange({ amount: nextAmount, currency_code: nextCode });
1976
2484
  };
1977
2485
  const selectedSymbol = currencyOptions.find((option) => option.code === code)?.symbol ?? code;
1978
- const styles3 = fieldControlStyles({ size, appearance, ...isInvalid ? { invalid: true } : {} });
2486
+ const styles4 = fieldControlStyles({ size, appearance, ...isInvalid ? { invalid: true } : {} });
1979
2487
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
1980
2488
  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: [
2489
+ /* @__PURE__ */ jsxs("div", { className: cn(styles4.box(), "flex items-center gap-1 pr-1", focusWithin), children: [
1982
2490
  /* @__PURE__ */ jsx(
1983
2491
  "input",
1984
2492
  {
1985
2493
  className: cn(
1986
2494
  "min-w-0 flex-1 bg-transparent text-ink outline-none tabular-nums",
1987
- styles3.content(),
2495
+ styles4.content(),
1988
2496
  // Sit a touch lower than a standard field by trimming the vertical
1989
2497
  // padding (cell mode keeps the fixed 29px row-editor height).
1990
2498
  appearance === "cell" ? "" : size === "sm" ? "py-1" : "py-1.5"
@@ -2650,7 +3158,9 @@ function DataTable({
2650
3158
  selectionMode = "none",
2651
3159
  selectedIds,
2652
3160
  onSelectionChange,
2653
- columnBorders = false
3161
+ columnBorders = false,
3162
+ groupBy,
3163
+ groupHeaderHeight
2654
3164
  }) {
2655
3165
  const rows = useMemo(() => {
2656
3166
  const pages = query.data?.pages;
@@ -2769,6 +3279,24 @@ function DataTable({
2769
3279
  });
2770
3280
  const tableRows = table.getRowModel().rows;
2771
3281
  const tableRowCount = tableRows.length;
3282
+ const listItems = useMemo(() => {
3283
+ if (!groupBy) {
3284
+ return tableRows.map((row, dataIndex) => ({ kind: "row", row, dataIndex }));
3285
+ }
3286
+ const items = [];
3287
+ let currentGroupId = null;
3288
+ tableRows.forEach((row, dataIndex) => {
3289
+ const group = groupBy(row.original);
3290
+ if (group && group.id !== currentGroupId) {
3291
+ currentGroupId = group.id;
3292
+ items.push({ kind: "group", id: group.id, label: group.label });
3293
+ } else if (!group) {
3294
+ currentGroupId = null;
3295
+ }
3296
+ items.push({ kind: "row", row, dataIndex });
3297
+ });
3298
+ return items;
3299
+ }, [tableRows, groupBy]);
2772
3300
  const scrollerRef = useRef(null);
2773
3301
  useEffect(() => {
2774
3302
  scrollerRef.current?.scrollTo({ top: 0 });
@@ -2779,10 +3307,11 @@ function DataTable({
2779
3307
  const top = listRef.current?.offsetTop ?? 0;
2780
3308
  setListOffset((prev) => prev === top ? prev : top);
2781
3309
  });
3310
+ const headingHeight = groupHeaderHeight ?? rowHeight;
2782
3311
  const virtualizer = useVirtualizer({
2783
- count: tableRowCount,
3312
+ count: listItems.length,
2784
3313
  getScrollElement: () => scrollerRef.current,
2785
- estimateSize: () => rowHeight,
3314
+ estimateSize: (index) => listItems[index]?.kind === "group" ? headingHeight : rowHeight,
2786
3315
  overscan,
2787
3316
  scrollMargin: listOffset
2788
3317
  });
@@ -2889,8 +3418,8 @@ function DataTable({
2889
3418
  role: "presentation",
2890
3419
  style: { height: totalSize, position: "relative", width: "100%" },
2891
3420
  children: virtualItems.map((vRow) => {
2892
- const row = tableRows[vRow.index];
2893
- if (!row) return null;
3421
+ const item = listItems[vRow.index];
3422
+ if (!item) return null;
2894
3423
  const rowStyle = {
2895
3424
  // Items' `start` includes the virtualizer's scrollMargin
2896
3425
  // (the list's offset below the sticky header); subtract
@@ -2898,18 +3427,21 @@ function DataTable({
2898
3427
  transform: `translateY(${vRow.start - listOffset}px)`,
2899
3428
  height: vRow.size
2900
3429
  };
3430
+ if (item.kind === "group") {
3431
+ return /* @__PURE__ */ jsx(GroupHeaderRow, { style: rowStyle, children: item.label }, `group:${item.id}`);
3432
+ }
2901
3433
  return /* @__PURE__ */ jsx(
2902
3434
  DataRow,
2903
3435
  {
2904
- row,
2905
- index: vRow.index,
3436
+ row: item.row,
3437
+ index: item.dataIndex,
2906
3438
  zebra,
2907
3439
  onRowClick,
2908
3440
  style: rowStyle,
2909
3441
  columnBorders,
2910
3442
  ...rowWrapper ? { rowWrapper } : {}
2911
3443
  },
2912
- row.id
3444
+ item.row.id
2913
3445
  );
2914
3446
  })
2915
3447
  }
@@ -2923,6 +3455,20 @@ function DataTable({
2923
3455
  }
2924
3456
  );
2925
3457
  }
3458
+ function GroupHeaderRow({ style, children }) {
3459
+ return /* @__PURE__ */ jsx(
3460
+ TableRow,
3461
+ {
3462
+ absolute: true,
3463
+ style,
3464
+ className: cn(
3465
+ "bg-surface-2 border-b border-rule",
3466
+ "font-mono text-[11px] uppercase tracking-[0.06em] text-ink-3"
3467
+ ),
3468
+ children: /* @__PURE__ */ jsx(TableCell, { className: "gap-2 text-inherit", children })
3469
+ }
3470
+ );
3471
+ }
2926
3472
  function DataRow({
2927
3473
  row,
2928
3474
  index,
@@ -3155,7 +3701,7 @@ function DatePicker({
3155
3701
  className,
3156
3702
  ...props
3157
3703
  }) {
3158
- const styles3 = fieldControlStyles({ size, appearance });
3704
+ const styles4 = fieldControlStyles({ size, appearance });
3159
3705
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
3160
3706
  return /* @__PURE__ */ jsxs(
3161
3707
  DatePicker$1,
@@ -3173,7 +3719,7 @@ function DatePicker({
3173
3719
  className: cn(
3174
3720
  // Box chrome on the wrapper; the DateInput inside carries padding +
3175
3721
  // font so the calendar trigger sits inside the same border + ring.
3176
- styles3.box(),
3722
+ styles4.box(),
3177
3723
  "flex items-center gap-1 pr-1",
3178
3724
  focusWithin
3179
3725
  ),
@@ -3183,7 +3729,7 @@ function DatePicker({
3183
3729
  {
3184
3730
  className: cn(
3185
3731
  "flex-1 flex items-center min-w-0 text-ink",
3186
- styles3.content(),
3732
+ styles4.content(),
3187
3733
  // Tabular alignment for date segments — overrides content's
3188
3734
  // font-sans on purpose.
3189
3735
  "font-mono"
@@ -3305,7 +3851,7 @@ function DateTimePicker({
3305
3851
  shouldCloseOnSelect = false,
3306
3852
  ...props
3307
3853
  }) {
3308
- const styles3 = fieldControlStyles({ size, appearance });
3854
+ const styles4 = fieldControlStyles({ size, appearance });
3309
3855
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
3310
3856
  const timeGranularity = granularity === "day" ? "minute" : granularity;
3311
3857
  const { hourCycle } = props;
@@ -3328,7 +3874,7 @@ function DateTimePicker({
3328
3874
  className: cn(
3329
3875
  // Box chrome on the wrapper; the DateInput inside carries padding +
3330
3876
  // font so the calendar trigger sits inside the same border + ring.
3331
- styles3.box(),
3877
+ styles4.box(),
3332
3878
  "flex items-center gap-1 pr-1",
3333
3879
  focusWithin
3334
3880
  ),
@@ -3338,7 +3884,7 @@ function DateTimePicker({
3338
3884
  {
3339
3885
  className: cn(
3340
3886
  "flex-1 flex items-center min-w-0 text-ink",
3341
- styles3.content(),
3887
+ styles4.content(),
3342
3888
  // Tabular alignment for date/time segments — overrides content's
3343
3889
  // font-sans on purpose.
3344
3890
  "font-mono"
@@ -3422,7 +3968,7 @@ var draftMessageCardStyles = tv({
3422
3968
  outcome: "shrink-0 font-mono text-[11px] text-ink-3"
3423
3969
  }
3424
3970
  });
3425
- var styles = draftMessageCardStyles();
3971
+ var styles2 = draftMessageCardStyles();
3426
3972
  var DRAFT_OUTCOME_LABEL = {
3427
3973
  sent: "Sent",
3428
3974
  rejected: "Rejected",
@@ -3439,23 +3985,23 @@ function DraftMessageCard({
3439
3985
  isPreviewDisabled = false,
3440
3986
  className
3441
3987
  }) {
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: [
3988
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles2.root(), className), children: [
3989
+ /* @__PURE__ */ jsx("span", { className: styles2.icon(), children: /* @__PURE__ */ jsx(ChannelIcon, { channel }) }),
3990
+ /* @__PURE__ */ jsxs("div", { className: styles2.body(), children: [
3991
+ /* @__PURE__ */ jsx("p", { className: styles2.eyebrow(), children: eyebrow }),
3992
+ /* @__PURE__ */ jsx("p", { className: styles2.title(), children: title }),
3993
+ recipients && recipients.length > 0 ? /* @__PURE__ */ jsxs("p", { className: styles2.recipients(), children: [
3448
3994
  "To ",
3449
3995
  recipients.join(", ")
3450
3996
  ] }) : null
3451
3997
  ] }),
3452
- outcome ? /* @__PURE__ */ jsx("span", { className: styles.outcome(), children: DRAFT_OUTCOME_LABEL[outcome] }) : /* @__PURE__ */ jsx(
3998
+ outcome ? /* @__PURE__ */ jsx("span", { className: styles2.outcome(), children: DRAFT_OUTCOME_LABEL[outcome] }) : /* @__PURE__ */ jsx(
3453
3999
  Button$1,
3454
4000
  {
3455
4001
  onPress: onPreview ?? (() => {
3456
4002
  }),
3457
4003
  isDisabled: isPreviewDisabled,
3458
- className: styles.action(),
4004
+ className: styles2.action(),
3459
4005
  children: previewLabel
3460
4006
  }
3461
4007
  )
@@ -3530,7 +4076,7 @@ function MultiSelect({
3530
4076
  appearance,
3531
4077
  className
3532
4078
  }) {
3533
- const styles3 = fieldControlStyles({ size, invalid: isInvalid, appearance });
4079
+ const styles4 = fieldControlStyles({ size, invalid: isInvalid, appearance });
3534
4080
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
3535
4081
  const minHeight = appearance === "cell" ? "min-h-[29px]" : fieldMinHeight[size];
3536
4082
  const [isOpen, setIsOpen] = useState(false);
@@ -3577,7 +4123,7 @@ function MultiSelect({
3577
4123
  "data-invalid": isInvalid || void 0,
3578
4124
  "data-disabled": isDisabled || void 0,
3579
4125
  className: cn(
3580
- styles3.box(),
4126
+ styles4.box(),
3581
4127
  "flex flex-wrap items-center gap-1.5 cursor-pointer",
3582
4128
  minHeight,
3583
4129
  fieldChipPadding[size],
@@ -3813,101 +4359,6 @@ function RecipientSelect({
3813
4359
  }
3814
4360
  );
3815
4361
  }
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
4362
  var MAX_COMPOSER_ATTACHMENT_BYTES = 25 * 1024 * 1024;
3912
4363
  var messageComposerStyles = tv({
3913
4364
  base: [
@@ -4274,7 +4725,7 @@ var draftMessageComposerStyles = tv({
4274
4725
  error: "px-[18px] font-mono text-[11px] text-danger"
4275
4726
  }
4276
4727
  });
4277
- var styles2 = draftMessageComposerStyles();
4728
+ var styles3 = draftMessageComposerStyles();
4278
4729
  function sendRecipientsFromMessage(message, role) {
4279
4730
  return (message.recipients ?? []).filter((recipient) => recipient.role === role && !!recipient.external_id).map((recipient) => ({
4280
4731
  kind: "contact-address",
@@ -4490,10 +4941,10 @@ function DraftMessageComposer({
4490
4941
  [message?.attachments]
4491
4942
  );
4492
4943
  if (phase === "loading") {
4493
- return /* @__PURE__ */ jsx("div", { className: cn(styles2.root(), className), children: /* @__PURE__ */ jsx("p", { className: styles2.terminal(), children: "Loading draft\u2026" }) });
4944
+ return /* @__PURE__ */ jsx("div", { className: cn(styles3.root(), className), children: /* @__PURE__ */ jsx("p", { className: styles3.terminal(), children: "Loading draft\u2026" }) });
4494
4945
  }
4495
4946
  if (phase === "load-error") {
4496
- return /* @__PURE__ */ jsx("div", { className: cn(styles2.root(), className), children: /* @__PURE__ */ jsxs("p", { className: styles2.terminal(), children: [
4947
+ return /* @__PURE__ */ jsx("div", { className: cn(styles3.root(), className), children: /* @__PURE__ */ jsxs("p", { className: styles3.terminal(), children: [
4497
4948
  loadError ?? "Loading the draft failed.",
4498
4949
  " ",
4499
4950
  /* @__PURE__ */ jsx(
@@ -4508,12 +4959,12 @@ function DraftMessageComposer({
4508
4959
  }
4509
4960
  if (phase === "terminal" || !message) {
4510
4961
  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 }) });
4962
+ return /* @__PURE__ */ jsx("div", { className: cn(styles3.root(), className), "data-draft-terminal": terminalKind, children: /* @__PURE__ */ jsx("p", { className: styles3.terminal(), children: line }) });
4512
4963
  }
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: [
4964
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles3.root(), className), children: [
4965
+ /* @__PURE__ */ jsxs("div", { className: styles3.header(), children: [
4966
+ /* @__PURE__ */ jsx("span", { className: styles3.badge(), children: "Draft \xB7 awaiting review" }),
4967
+ /* @__PURE__ */ jsxs("span", { className: styles3.sender(), children: [
4517
4968
  "from ",
4518
4969
  message.sender.name
4519
4970
  ] })
@@ -4544,11 +4995,11 @@ function DraftMessageComposer({
4544
4995
  showSendButton: showActions
4545
4996
  }
4546
4997
  ),
4547
- actionError ? /* @__PURE__ */ jsxs("p", { className: styles2.error(), children: [
4998
+ actionError ? /* @__PURE__ */ jsxs("p", { className: styles3.error(), children: [
4548
4999
  actionError,
4549
5000
  " \u2014 your edits are kept."
4550
5001
  ] }) : null,
4551
- showActions ? /* @__PURE__ */ jsxs("div", { className: styles2.actions(), children: [
5002
+ showActions ? /* @__PURE__ */ jsxs("div", { className: styles3.actions(), children: [
4552
5003
  isConfirmingReject ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
4553
5004
  /* @__PURE__ */ jsx("span", { className: "text-[12.5px] text-ink-3", children: "Reject draft?" }),
4554
5005
  /* @__PURE__ */ jsx(
@@ -4585,92 +5036,6 @@ function DraftMessageComposer({
4585
5036
  ] }) : null
4586
5037
  ] });
4587
5038
  }
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
5039
  function DraftMessageReview({
4675
5040
  messageId,
4676
5041
  client,
@@ -4816,12 +5181,12 @@ function EmptyState({
4816
5181
  size,
4817
5182
  className
4818
5183
  }) {
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
5184
+ const styles4 = emptyStateStyles({ size });
5185
+ return /* @__PURE__ */ jsxs("div", { className: cn(styles4.root(), className), children: [
5186
+ icon ? /* @__PURE__ */ jsx("div", { className: styles4.art(), children: icon }) : null,
5187
+ /* @__PURE__ */ jsx("div", { className: styles4.title(), children: title }),
5188
+ description ? /* @__PURE__ */ jsx("div", { className: styles4.description(), children: description }) : null,
5189
+ action ? /* @__PURE__ */ jsx("div", { className: styles4.actions(), children: action }) : null
4825
5190
  ] });
4826
5191
  }
4827
5192
  function ErrorAnimation({ className }) {
@@ -5062,7 +5427,7 @@ function Input({
5062
5427
  className,
5063
5428
  ...props
5064
5429
  }) {
5065
- const styles3 = fieldControlStyles({ size, appearance, hasFocusRing });
5430
+ const styles4 = fieldControlStyles({ size, appearance, hasFocusRing });
5066
5431
  return /* @__PURE__ */ jsxs(
5067
5432
  TextField,
5068
5433
  {
@@ -5078,7 +5443,7 @@ function Input({
5078
5443
  {
5079
5444
  ...inputProps,
5080
5445
  placeholder: placeholder ?? "",
5081
- className: cn(styles3.box(), styles3.content(), inputClassName)
5446
+ className: cn(styles4.box(), styles4.content(), inputClassName)
5082
5447
  }
5083
5448
  ),
5084
5449
  description ? /* @__PURE__ */ jsx(Text, { slot: "description", className: fieldHintStyles, children: description }) : null,
@@ -5588,6 +5953,8 @@ function ChipItem({
5588
5953
  Badge,
5589
5954
  {
5590
5955
  variant: option?.variant,
5956
+ shape: "rounded",
5957
+ hasDot: false,
5591
5958
  ...option?.color ? { color: option.color } : {},
5592
5959
  ...option?.icon ? { icon: option.icon } : {},
5593
5960
  children: option?.label ?? value
@@ -5664,7 +6031,7 @@ function SegmentedControl({
5664
6031
  orientation = "horizontal",
5665
6032
  ...props
5666
6033
  }) {
5667
- const styles3 = segmentedControlStyles({ size });
6034
+ const styles4 = segmentedControlStyles({ size });
5668
6035
  return /* @__PURE__ */ jsx(
5669
6036
  RadioGroup$1,
5670
6037
  {
@@ -5672,14 +6039,14 @@ function SegmentedControl({
5672
6039
  orientation,
5673
6040
  value: String(value),
5674
6041
  onChange: (next) => onChange(next),
5675
- className: cn(styles3.group(), className),
6042
+ className: cn(styles4.group(), className),
5676
6043
  children: options.map((option) => /* @__PURE__ */ jsx(
5677
6044
  Radio$1,
5678
6045
  {
5679
6046
  value: String(option.id),
5680
6047
  ...option.isDisabled ? { isDisabled: true } : {},
5681
6048
  ...autoFocus && option.id === value ? { autoFocus: true } : {},
5682
- className: styles3.segment(),
6049
+ className: styles4.segment(),
5683
6050
  children: option.label
5684
6051
  },
5685
6052
  String(option.id)
@@ -5702,7 +6069,7 @@ function TagInput({
5702
6069
  autoFocus = false,
5703
6070
  className
5704
6071
  }) {
5705
- const styles3 = fieldControlStyles({ size, invalid: isInvalid, appearance });
6072
+ const styles4 = fieldControlStyles({ size, invalid: isInvalid, appearance });
5706
6073
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
5707
6074
  const minHeight = appearance === "cell" ? "min-h-[29px]" : fieldMinHeight[size];
5708
6075
  const inputRef = useRef(null);
@@ -5743,7 +6110,7 @@ function TagInput({
5743
6110
  "data-invalid": isInvalid || void 0,
5744
6111
  "data-disabled": isDisabled || void 0,
5745
6112
  className: cn(
5746
- styles3.box(),
6113
+ styles4.box(),
5747
6114
  "flex flex-wrap items-center gap-1",
5748
6115
  minHeight,
5749
6116
  fieldChipPadding[size],
@@ -7493,45 +7860,45 @@ var tabsStyles = tv({
7493
7860
  defaultVariants: { size: "md" }
7494
7861
  });
7495
7862
  function Root({ size, className, children, ...props }) {
7496
- const styles3 = tabsStyles({ size });
7863
+ const styles4 = tabsStyles({ size });
7497
7864
  return /* @__PURE__ */ jsx(
7498
7865
  Tabs$1,
7499
7866
  {
7500
7867
  ...props,
7501
- className: (rp) => cn(styles3.root(), typeof className === "function" ? className(rp) : className),
7868
+ className: (rp) => cn(styles4.root(), typeof className === "function" ? className(rp) : className),
7502
7869
  children
7503
7870
  }
7504
7871
  );
7505
7872
  }
7506
7873
  function List({ size, className, children, ...props }) {
7507
- const styles3 = tabsStyles({ size });
7874
+ const styles4 = tabsStyles({ size });
7508
7875
  return /* @__PURE__ */ jsx(
7509
7876
  TabList,
7510
7877
  {
7511
7878
  ...props,
7512
- className: (rp) => cn(styles3.list(), typeof className === "function" ? className(rp) : className),
7879
+ className: (rp) => cn(styles4.list(), typeof className === "function" ? className(rp) : className),
7513
7880
  children
7514
7881
  }
7515
7882
  );
7516
7883
  }
7517
7884
  function Trigger({ size, className, children, ...props }) {
7518
- const styles3 = tabsStyles({ size });
7885
+ const styles4 = tabsStyles({ size });
7519
7886
  return /* @__PURE__ */ jsx(
7520
7887
  Tab,
7521
7888
  {
7522
7889
  ...props,
7523
- className: (rp) => cn(styles3.trigger(), typeof className === "function" ? className(rp) : className),
7890
+ className: (rp) => cn(styles4.trigger(), typeof className === "function" ? className(rp) : className),
7524
7891
  children
7525
7892
  }
7526
7893
  );
7527
7894
  }
7528
7895
  function Panel({ className, children, ...props }) {
7529
- const styles3 = tabsStyles({});
7896
+ const styles4 = tabsStyles({});
7530
7897
  return /* @__PURE__ */ jsx(
7531
7898
  TabPanel,
7532
7899
  {
7533
7900
  ...props,
7534
- className: (rp) => cn(styles3.panel(), typeof className === "function" ? className(rp) : className),
7901
+ className: (rp) => cn(styles4.panel(), typeof className === "function" ? className(rp) : className),
7535
7902
  children
7536
7903
  }
7537
7904
  );
@@ -7555,7 +7922,7 @@ function Textarea({
7555
7922
  className,
7556
7923
  ...props
7557
7924
  }) {
7558
- const styles3 = fieldControlStyles({ size, appearance });
7925
+ const styles4 = fieldControlStyles({ size, appearance });
7559
7926
  return /* @__PURE__ */ jsxs(
7560
7927
  TextField,
7561
7928
  {
@@ -7575,8 +7942,8 @@ function Textarea({
7575
7942
  className: cn(
7576
7943
  // Same hairline chrome as Input, but allow vertical resize and set a
7577
7944
  // sensible minimum height so short content doesn't collapse.
7578
- styles3.box(),
7579
- styles3.content(),
7945
+ styles4.box(),
7946
+ styles4.content(),
7580
7947
  "min-h-[100px] resize-y",
7581
7948
  textareaClassName
7582
7949
  )
@@ -7597,7 +7964,7 @@ function TimeField({
7597
7964
  className,
7598
7965
  ...props
7599
7966
  }) {
7600
- const styles3 = fieldControlStyles({ size, appearance });
7967
+ const styles4 = fieldControlStyles({ size, appearance });
7601
7968
  const focusWithin = appearance === "cell" ? "focus-within:border-accent focus-within:shadow-none" : "focus-within:border-accent focus-within:shadow-[var(--shadow-focus)]";
7602
7969
  return /* @__PURE__ */ jsxs(
7603
7970
  TimeField$1,
@@ -7613,8 +7980,8 @@ function TimeField({
7613
7980
  DateInput,
7614
7981
  {
7615
7982
  className: cn(
7616
- styles3.box(),
7617
- styles3.content(),
7983
+ styles4.box(),
7984
+ styles4.content(),
7618
7985
  "flex items-center min-w-0 text-ink",
7619
7986
  // Tabular alignment for time segments — overrides content's
7620
7987
  // font-sans on purpose.
@@ -7737,6 +8104,6 @@ function Tooltip({ className, offset = 6, ...props }) {
7737
8104
  );
7738
8105
  }
7739
8106
 
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 };
8107
+ 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
8108
  //# sourceMappingURL=index.js.map
7742
8109
  //# sourceMappingURL=index.js.map