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