@estiva-app/ui 0.54.0 → 0.55.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/BlockHandle.d.ts +47 -0
- package/dist/BlockHandle.d.ts.map +1 -0
- package/dist/EditorBlockHandle.d.ts +57 -0
- package/dist/EditorBlockHandle.d.ts.map +1 -0
- package/dist/editor.d.ts +1 -0
- package/dist/editor.d.ts.map +1 -1
- package/dist/editor.js +127 -11
- package/dist/editor.js.map +4 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +716 -573
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/registry.json +211 -3
- package/src/BlockHandle.mdx +58 -0
- package/src/BlockHandle.stories.tsx +44 -0
- package/src/BlockHandle.test.tsx +216 -0
- package/src/BlockHandle.tsx +220 -0
- package/src/EditorBlockHandle.mdx +65 -0
- package/src/EditorBlockHandle.stories.tsx +81 -0
- package/src/EditorBlockHandle.tsx +181 -0
- package/src/editor.ts +1 -0
- package/src/index.ts +1 -0
- package/src/registry/registry.test.ts +5 -5
- package/stories/Choosing.mdx +2 -0
package/dist/index.js
CHANGED
|
@@ -948,109 +948,9 @@ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismi
|
|
|
948
948
|
] });
|
|
949
949
|
}
|
|
950
950
|
|
|
951
|
-
// src/
|
|
952
|
-
import {
|
|
953
|
-
import {
|
|
954
|
-
import { IconCheck } from "@tabler/icons-react";
|
|
955
|
-
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
956
|
-
function squareClasses(checked, disabled, interactive, className) {
|
|
957
|
-
return cn(
|
|
958
|
-
"inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
|
|
959
|
-
checked ? "bg-accent-primary border-accent-primary text-text-inverse" : "bg-transparent border-border-strong hover:border-text-muted",
|
|
960
|
-
disabled && "opacity-50 pointer-events-none",
|
|
961
|
-
interactive ? "cursor-pointer" : "pointer-events-none",
|
|
962
|
-
className
|
|
963
|
-
);
|
|
964
|
-
}
|
|
965
|
-
var tickClasses = (checked) => cn("flex", !checked && "invisible");
|
|
966
|
-
var WORDS_CLASSES = "text-body-2 text-text-primary";
|
|
967
|
-
var ROW_CLASSES = "flex shrink-0 items-center gap-3 h-10 px-3 rounded-lg transition-colors";
|
|
968
|
-
function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row, leading, className, ...aria }) {
|
|
969
|
-
const formBusy = useFormBusy();
|
|
970
|
-
const disabled = ownDisabled || formBusy;
|
|
971
|
-
if (!onChange) {
|
|
972
|
-
const picture = /* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx16("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx16(IconCheck, { size: 12, stroke: 3 }) }) });
|
|
973
|
-
if (label === void 0) return picture;
|
|
974
|
-
return /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2", children: [
|
|
975
|
-
picture,
|
|
976
|
-
/* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
|
|
977
|
-
] });
|
|
978
|
-
}
|
|
979
|
-
const box = /* @__PURE__ */ jsx16(
|
|
980
|
-
BaseCheckbox.Root,
|
|
981
|
-
{
|
|
982
|
-
checked,
|
|
983
|
-
disabled,
|
|
984
|
-
"aria-label": aria["aria-label"],
|
|
985
|
-
"aria-required": aria["aria-required"],
|
|
986
|
-
onCheckedChange: (next) => onChange(next),
|
|
987
|
-
onClick: (e) => e.stopPropagation(),
|
|
988
|
-
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
989
|
-
children: /* @__PURE__ */ jsx16(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx16(IconCheck, { size: 12, stroke: 3 }) })
|
|
990
|
-
}
|
|
991
|
-
);
|
|
992
|
-
if (label === void 0) return box;
|
|
993
|
-
if (row) {
|
|
994
|
-
return /* @__PURE__ */ jsx16(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
|
|
995
|
-
leading,
|
|
996
|
-
/* @__PURE__ */ jsx16("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
|
|
997
|
-
box
|
|
998
|
-
] }) });
|
|
999
|
-
}
|
|
1000
|
-
return /* @__PURE__ */ jsx16(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
|
|
1001
|
-
box,
|
|
1002
|
-
/* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
|
|
1003
|
-
] }) });
|
|
1004
|
-
}
|
|
1005
|
-
|
|
1006
|
-
// src/Chip.tsx
|
|
1007
|
-
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1008
|
-
var typeStyles = {
|
|
1009
|
-
neutral: "bg-bg-inset text-text-primary",
|
|
1010
|
-
brand: "bg-accent-muted text-accent-text signal:border signal:border-accent-outline",
|
|
1011
|
-
info: "bg-info-muted text-info-default signal:border signal:border-info-outline",
|
|
1012
|
-
warning: "bg-warning-muted text-warning-default signal:border signal:border-warning-outline signal:shadow-glow-warning",
|
|
1013
|
-
success: "bg-success-muted text-success-default signal:border signal:border-success-outline",
|
|
1014
|
-
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
1015
|
-
};
|
|
1016
|
-
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, href, onClick, className }) {
|
|
1017
|
-
const classes = cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className);
|
|
1018
|
-
const inside = /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
1019
|
-
leadingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
1020
|
-
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
1021
|
-
// of growing past it — Ship's project chip on an issue row
|
|
1022
|
-
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
1023
|
-
// `truncate`, because `truncate` is `overflow: hidden` on both axes and
|
|
1024
|
-
// the label's line box (11px under Signal) is tighter than its glyphs —
|
|
1025
|
-
// the screenshot diff caught every descender cut off. `clip` is the
|
|
1026
|
-
// one overflow that leaves the other axis visible. A chip with no cap
|
|
1027
|
-
// draws exactly as before.
|
|
1028
|
-
/* @__PURE__ */ jsx17("span", { className: cn("min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap signal:tracking-wide", CHIP_TEXT_CLASSES), children: label }),
|
|
1029
|
-
trailingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
1030
|
-
] });
|
|
1031
|
-
if (href) return /* @__PURE__ */ jsx17("a", { href, onClick, className: cn("relative", classes), children: inside });
|
|
1032
|
-
return /* @__PURE__ */ jsx17("div", { className: classes, children: inside });
|
|
1033
|
-
}
|
|
1034
|
-
|
|
1035
|
-
// src/CommandPalette.tsx
|
|
1036
|
-
import {
|
|
1037
|
-
createContext as createContext5,
|
|
1038
|
-
useContext as useContext5,
|
|
1039
|
-
useEffect as useEffect2,
|
|
1040
|
-
useLayoutEffect as useLayoutEffect3,
|
|
1041
|
-
useMemo as useMemo2,
|
|
1042
|
-
useRef as useRef4,
|
|
1043
|
-
useState as useState3
|
|
1044
|
-
} from "react";
|
|
1045
|
-
import { Dialog as Dialog2 } from "@base-ui/react/dialog";
|
|
1046
|
-
import { Autocomplete } from "@base-ui/react/autocomplete";
|
|
1047
|
-
import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
|
|
1048
|
-
|
|
1049
|
-
// src/ChipInput.tsx
|
|
1050
|
-
import { useMemo, useState as useState2 } from "react";
|
|
1051
|
-
import { Button as BaseButton4 } from "@base-ui/react/button";
|
|
1052
|
-
import { Combobox } from "@base-ui/react/combobox";
|
|
1053
|
-
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
951
|
+
// src/BlockHandle.tsx
|
|
952
|
+
import { useCallback, useEffect as useEffect2, useRef as useRef3, useState as useState2 } from "react";
|
|
953
|
+
import { IconGripVertical } from "@tabler/icons-react";
|
|
1054
954
|
|
|
1055
955
|
// src/Menu.tsx
|
|
1056
956
|
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
@@ -1060,27 +960,27 @@ import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
|
1060
960
|
// src/Divider.tsx
|
|
1061
961
|
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
1062
962
|
import { Separator } from "@base-ui/react/separator";
|
|
1063
|
-
import { jsx as
|
|
963
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1064
964
|
var DividerInPanel = createContext3(false);
|
|
1065
965
|
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
1066
966
|
const inset = useContext3(DividerInPanel) ? "mx-0" : "mx-3";
|
|
1067
967
|
if (label && orientation === "horizontal") {
|
|
1068
968
|
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
1069
|
-
return /* @__PURE__ */
|
|
969
|
+
return /* @__PURE__ */ jsxs10(
|
|
1070
970
|
Separator,
|
|
1071
971
|
{
|
|
1072
972
|
orientation: "horizontal",
|
|
1073
973
|
"aria-label": label,
|
|
1074
974
|
className: cn("flex shrink-0 items-center gap-2", inset, className),
|
|
1075
975
|
children: [
|
|
1076
|
-
/* @__PURE__ */
|
|
1077
|
-
/* @__PURE__ */
|
|
1078
|
-
/* @__PURE__ */
|
|
976
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
977
|
+
/* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
978
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
1079
979
|
]
|
|
1080
980
|
}
|
|
1081
981
|
);
|
|
1082
982
|
}
|
|
1083
|
-
return /* @__PURE__ */
|
|
983
|
+
return /* @__PURE__ */ jsx16(
|
|
1084
984
|
Separator,
|
|
1085
985
|
{
|
|
1086
986
|
orientation,
|
|
@@ -1096,7 +996,7 @@ function triggerDisabled(trigger) {
|
|
|
1096
996
|
}
|
|
1097
997
|
|
|
1098
998
|
// src/SectionLabel.tsx
|
|
1099
|
-
import { jsx as
|
|
999
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
1100
1000
|
function SectionLabel({
|
|
1101
1001
|
children,
|
|
1102
1002
|
tone = "primary",
|
|
@@ -1104,7 +1004,7 @@ function SectionLabel({
|
|
|
1104
1004
|
folds = false,
|
|
1105
1005
|
className
|
|
1106
1006
|
}) {
|
|
1107
|
-
return /* @__PURE__ */
|
|
1007
|
+
return /* @__PURE__ */ jsx17(
|
|
1108
1008
|
"span",
|
|
1109
1009
|
{
|
|
1110
1010
|
className: cn(
|
|
@@ -1122,10 +1022,10 @@ function SectionLabel({
|
|
|
1122
1022
|
}
|
|
1123
1023
|
|
|
1124
1024
|
// src/Menu.tsx
|
|
1125
|
-
import { Fragment as
|
|
1025
|
+
import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1126
1026
|
var MenuContext = createContext4(null);
|
|
1127
1027
|
function MenuPanel({ children, className, ...props }) {
|
|
1128
|
-
return /* @__PURE__ */
|
|
1028
|
+
return /* @__PURE__ */ jsx18(
|
|
1129
1029
|
"div",
|
|
1130
1030
|
{
|
|
1131
1031
|
className: cn(
|
|
@@ -1156,7 +1056,7 @@ var VIEWPORT_PAD2 = 8;
|
|
|
1156
1056
|
var HOVER_OPEN_DELAY = 0;
|
|
1157
1057
|
var HOVER_CLOSE_DELAY = 150;
|
|
1158
1058
|
function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
|
|
1159
|
-
return /* @__PURE__ */
|
|
1059
|
+
return /* @__PURE__ */ jsxs11(
|
|
1160
1060
|
BaseMenu.Root,
|
|
1161
1061
|
{
|
|
1162
1062
|
open,
|
|
@@ -1164,7 +1064,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1164
1064
|
actionsRef,
|
|
1165
1065
|
modal: false,
|
|
1166
1066
|
children: [
|
|
1167
|
-
/* @__PURE__ */
|
|
1067
|
+
/* @__PURE__ */ jsx18(
|
|
1168
1068
|
BaseMenu.Trigger,
|
|
1169
1069
|
{
|
|
1170
1070
|
render: trigger,
|
|
@@ -1174,7 +1074,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1174
1074
|
closeDelay: HOVER_CLOSE_DELAY
|
|
1175
1075
|
}
|
|
1176
1076
|
),
|
|
1177
|
-
/* @__PURE__ */
|
|
1077
|
+
/* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
|
|
1178
1078
|
BaseMenu.Positioner,
|
|
1179
1079
|
{
|
|
1180
1080
|
side: "bottom",
|
|
@@ -1182,13 +1082,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1182
1082
|
sideOffset: GAP2,
|
|
1183
1083
|
collisionPadding: VIEWPORT_PAD2,
|
|
1184
1084
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1185
|
-
children: /* @__PURE__ */
|
|
1085
|
+
children: /* @__PURE__ */ jsx18(
|
|
1186
1086
|
BaseMenu.Popup,
|
|
1187
1087
|
{
|
|
1188
1088
|
"data-interactive": true,
|
|
1189
1089
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
1190
|
-
render: /* @__PURE__ */
|
|
1191
|
-
children: /* @__PURE__ */
|
|
1090
|
+
render: /* @__PURE__ */ jsx18(MenuPanel, {}),
|
|
1091
|
+
children: /* @__PURE__ */ jsx18(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx18(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx18(DividerInPanel.Provider, { value: true, children }) }) })
|
|
1192
1092
|
}
|
|
1193
1093
|
)
|
|
1194
1094
|
}
|
|
@@ -1204,20 +1104,20 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
1204
1104
|
'[@estiva-app/ui] Menu: `openOnHover` and `MenuSub` cannot be used together \u2014 leaving the submenu panel strands the menu open. Open this menu on a press instead. See Menu.mdx, "Hover-opened menus".'
|
|
1205
1105
|
);
|
|
1206
1106
|
}
|
|
1207
|
-
return /* @__PURE__ */
|
|
1208
|
-
/* @__PURE__ */
|
|
1107
|
+
return /* @__PURE__ */ jsxs11(BaseMenu.SubmenuRoot, { children: [
|
|
1108
|
+
/* @__PURE__ */ jsx18(
|
|
1209
1109
|
BaseMenu.SubmenuTrigger,
|
|
1210
1110
|
{
|
|
1211
1111
|
openOnHover: true,
|
|
1212
1112
|
delay: 0,
|
|
1213
1113
|
closeDelay: 150,
|
|
1214
1114
|
nativeButton: true,
|
|
1215
|
-
render: /* @__PURE__ */
|
|
1115
|
+
render: /* @__PURE__ */ jsx18("button", { type: "button" }),
|
|
1216
1116
|
className: menuItemClassName({ size: "default", selected }),
|
|
1217
|
-
children: /* @__PURE__ */
|
|
1117
|
+
children: /* @__PURE__ */ jsx18(MenuItemBody, { label, leading, submenu: true })
|
|
1218
1118
|
}
|
|
1219
1119
|
),
|
|
1220
|
-
/* @__PURE__ */
|
|
1120
|
+
/* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
|
|
1221
1121
|
BaseMenu.Positioner,
|
|
1222
1122
|
{
|
|
1223
1123
|
side: "inline-end",
|
|
@@ -1225,7 +1125,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
1225
1125
|
sideOffset: GAP2,
|
|
1226
1126
|
collisionPadding: VIEWPORT_PAD2,
|
|
1227
1127
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1228
|
-
children: /* @__PURE__ */
|
|
1128
|
+
children: /* @__PURE__ */ jsx18(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx18(MenuPanel, {}), children })
|
|
1229
1129
|
}
|
|
1230
1130
|
) })
|
|
1231
1131
|
] });
|
|
@@ -1260,25 +1160,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
1260
1160
|
);
|
|
1261
1161
|
}
|
|
1262
1162
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
1263
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
1264
|
-
return /* @__PURE__ */
|
|
1265
|
-
leading && /* @__PURE__ */
|
|
1266
|
-
children ?? /* @__PURE__ */
|
|
1267
|
-
/* @__PURE__ */
|
|
1268
|
-
description && /* @__PURE__ */
|
|
1163
|
+
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx18(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx18(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
1164
|
+
return /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
1165
|
+
leading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1166
|
+
children ?? /* @__PURE__ */ jsxs11("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
1167
|
+
/* @__PURE__ */ jsx18("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
1168
|
+
description && /* @__PURE__ */ jsx18("span", { className: "truncate text-caption text-text-secondary", children: description })
|
|
1269
1169
|
] }),
|
|
1270
1170
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
1271
1171
|
// the wider of the two and never changes, so revealing the hint moves
|
|
1272
1172
|
// nothing. No transition here either — the hint switches on the same
|
|
1273
1173
|
// :hover / `selected` as the fill, in the same frame.
|
|
1274
|
-
/* @__PURE__ */
|
|
1275
|
-
edge && /* @__PURE__ */
|
|
1276
|
-
hint && /* @__PURE__ */
|
|
1174
|
+
/* @__PURE__ */ jsxs11("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
1175
|
+
edge && /* @__PURE__ */ jsx18("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
1176
|
+
hint && /* @__PURE__ */ jsx18("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
1277
1177
|
] })
|
|
1278
1178
|
] });
|
|
1279
1179
|
}
|
|
1280
1180
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
1281
|
-
const body = /* @__PURE__ */
|
|
1181
|
+
const body = /* @__PURE__ */ jsx18(
|
|
1282
1182
|
MenuItemBody,
|
|
1283
1183
|
{
|
|
1284
1184
|
label,
|
|
@@ -1296,13 +1196,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1296
1196
|
);
|
|
1297
1197
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
1298
1198
|
if (!useContext4(MenuContext)) {
|
|
1299
|
-
return /* @__PURE__ */
|
|
1199
|
+
return /* @__PURE__ */ jsx18("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
1300
1200
|
}
|
|
1301
|
-
return /* @__PURE__ */
|
|
1201
|
+
return /* @__PURE__ */ jsx18(
|
|
1302
1202
|
BaseMenu.Item,
|
|
1303
1203
|
{
|
|
1304
1204
|
nativeButton: true,
|
|
1305
|
-
render: /* @__PURE__ */
|
|
1205
|
+
render: /* @__PURE__ */ jsx18("button", { type: "button" }),
|
|
1306
1206
|
className: rowClassName,
|
|
1307
1207
|
...props,
|
|
1308
1208
|
children: body
|
|
@@ -1310,34 +1210,275 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1310
1210
|
);
|
|
1311
1211
|
}
|
|
1312
1212
|
function EnterHint({ target }) {
|
|
1313
|
-
return /* @__PURE__ */
|
|
1314
|
-
/* @__PURE__ */
|
|
1315
|
-
target && /* @__PURE__ */
|
|
1213
|
+
return /* @__PURE__ */ jsxs11("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
1214
|
+
/* @__PURE__ */ jsx18(Kbd, { children: "\u21A9 Enter" }),
|
|
1215
|
+
target && /* @__PURE__ */ jsx18("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider leaf:font-mono leaf:text-small leaf:tracking-wider", children: target })
|
|
1316
1216
|
] });
|
|
1317
1217
|
}
|
|
1318
1218
|
function MenuSection({ label, children, className }) {
|
|
1319
1219
|
const inMenu = useContext4(MenuContext) !== null;
|
|
1320
|
-
const heading = /* @__PURE__ */
|
|
1220
|
+
const heading = /* @__PURE__ */ jsx18("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx18(SectionLabel, { tone: "secondary", children: label }) });
|
|
1321
1221
|
if (!inMenu) {
|
|
1322
|
-
return /* @__PURE__ */
|
|
1222
|
+
return /* @__PURE__ */ jsxs11("div", { className: "flex flex-col", children: [
|
|
1323
1223
|
heading,
|
|
1324
1224
|
children
|
|
1325
1225
|
] });
|
|
1326
1226
|
}
|
|
1327
|
-
return /* @__PURE__ */
|
|
1328
|
-
/* @__PURE__ */
|
|
1227
|
+
return /* @__PURE__ */ jsxs11(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1228
|
+
/* @__PURE__ */ jsx18(BaseMenu.GroupLabel, { render: heading }),
|
|
1329
1229
|
children
|
|
1330
1230
|
] });
|
|
1331
1231
|
}
|
|
1332
1232
|
function MenuSeparator() {
|
|
1333
|
-
return /* @__PURE__ */
|
|
1233
|
+
return /* @__PURE__ */ jsx18(Divider, { className: "my-1" });
|
|
1334
1234
|
}
|
|
1335
1235
|
function MenuRow({ children, className }) {
|
|
1336
|
-
return /* @__PURE__ */
|
|
1236
|
+
return /* @__PURE__ */ jsx18("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
1337
1237
|
}
|
|
1338
1238
|
|
|
1239
|
+
// src/BlockHandle.tsx
|
|
1240
|
+
import { jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1241
|
+
function readId(element) {
|
|
1242
|
+
const own = element.getAttribute("data-block-id") ?? element.querySelector("[data-block-id]")?.getAttribute("data-block-id");
|
|
1243
|
+
return own || void 0;
|
|
1244
|
+
}
|
|
1245
|
+
function blockAtY(blocks, y) {
|
|
1246
|
+
let found = null;
|
|
1247
|
+
for (const block of blocks) {
|
|
1248
|
+
if (block.element.getBoundingClientRect().top > y) break;
|
|
1249
|
+
found = block;
|
|
1250
|
+
}
|
|
1251
|
+
return found ?? blocks[0] ?? null;
|
|
1252
|
+
}
|
|
1253
|
+
function readingBlocks(root) {
|
|
1254
|
+
if (!root) return [];
|
|
1255
|
+
return Array.from(root.children).filter((el) => el instanceof HTMLElement).map((element) => ({ id: readId(element), element })).filter((b) => b.id !== void 0);
|
|
1256
|
+
}
|
|
1257
|
+
var HANDLE = 24;
|
|
1258
|
+
function firstLineOffset(element) {
|
|
1259
|
+
const text = element.querySelector("p, h1, h2, h3, pre, li") ?? element;
|
|
1260
|
+
const line = parseFloat(getComputedStyle(text).lineHeight);
|
|
1261
|
+
if (!Number.isFinite(line)) return 0;
|
|
1262
|
+
const inset = text === element ? 0 : text.getBoundingClientRect().top - element.getBoundingClientRect().top;
|
|
1263
|
+
return inset + (line - HANDLE) / 2;
|
|
1264
|
+
}
|
|
1265
|
+
function BlockHandle({ actions, editing, children, className }) {
|
|
1266
|
+
const frame = useRef3(null);
|
|
1267
|
+
const content = useRef3(null);
|
|
1268
|
+
const [block, setBlock] = useState2(null);
|
|
1269
|
+
const [top, setTop] = useState2(0);
|
|
1270
|
+
const [open, setOpen] = useState2(false);
|
|
1271
|
+
const follow = useCallback(
|
|
1272
|
+
(y) => {
|
|
1273
|
+
if (!content.current || !frame.current) return;
|
|
1274
|
+
const found = editing ? editing.find(y) : blockAtY(readingBlocks(content.current.firstElementChild), y);
|
|
1275
|
+
setBlock(found);
|
|
1276
|
+
if (found) setTop(found.element.getBoundingClientRect().top - frame.current.getBoundingClientRect().top + firstLineOffset(found.element));
|
|
1277
|
+
},
|
|
1278
|
+
[editing]
|
|
1279
|
+
);
|
|
1280
|
+
useEffect2(() => {
|
|
1281
|
+
if (!editing) return;
|
|
1282
|
+
return editing.onChange(() => {
|
|
1283
|
+
if (!open) setBlock(null);
|
|
1284
|
+
});
|
|
1285
|
+
}, [editing, open]);
|
|
1286
|
+
const rows = editing && block ? editing.rows(block) : null;
|
|
1287
|
+
const own = actions && block ? actions(block) : null;
|
|
1288
|
+
const dragging = useRef3(false);
|
|
1289
|
+
const [line, setLine] = useState2(null);
|
|
1290
|
+
const inGutter = (e) => dragging.current && !!editing && !!content.current && !content.current.contains(e.target);
|
|
1291
|
+
const landing = (y) => {
|
|
1292
|
+
const target = editing?.find(y);
|
|
1293
|
+
if (!target || !frame.current) return null;
|
|
1294
|
+
const box = target.element.getBoundingClientRect();
|
|
1295
|
+
const after = y > box.top + box.height / 2;
|
|
1296
|
+
const neighbour = (after ? target.element.nextElementSibling : target.element.previousElementSibling)?.getBoundingClientRect();
|
|
1297
|
+
const edge = after ? neighbour ? (box.bottom + neighbour.top) / 2 : box.bottom : neighbour ? (neighbour.bottom + box.top) / 2 : box.top;
|
|
1298
|
+
return { target, after, top: edge - frame.current.getBoundingClientRect().top };
|
|
1299
|
+
};
|
|
1300
|
+
const endDrag = () => {
|
|
1301
|
+
dragging.current = false;
|
|
1302
|
+
setLine(null);
|
|
1303
|
+
editing?.endDrag();
|
|
1304
|
+
};
|
|
1305
|
+
return /* @__PURE__ */ jsxs12(
|
|
1306
|
+
"div",
|
|
1307
|
+
{
|
|
1308
|
+
ref: frame,
|
|
1309
|
+
className: cn("relative", className),
|
|
1310
|
+
onMouseMove: (e) => {
|
|
1311
|
+
if (!open) follow(e.clientY);
|
|
1312
|
+
},
|
|
1313
|
+
onMouseLeave: () => {
|
|
1314
|
+
if (!open) setBlock(null);
|
|
1315
|
+
},
|
|
1316
|
+
onDragOver: (e) => {
|
|
1317
|
+
if (!inGutter(e)) return setLine(null);
|
|
1318
|
+
e.preventDefault();
|
|
1319
|
+
setLine(landing(e.clientY)?.top ?? null);
|
|
1320
|
+
},
|
|
1321
|
+
onDrop: (e) => {
|
|
1322
|
+
if (inGutter(e)) {
|
|
1323
|
+
e.preventDefault();
|
|
1324
|
+
const at = landing(e.clientY);
|
|
1325
|
+
if (at) editing?.drop(at.target, at.after);
|
|
1326
|
+
}
|
|
1327
|
+
endDrag();
|
|
1328
|
+
},
|
|
1329
|
+
onDragLeave: (e) => {
|
|
1330
|
+
if (!frame.current?.contains(e.relatedTarget)) setLine(null);
|
|
1331
|
+
},
|
|
1332
|
+
children: [
|
|
1333
|
+
/* @__PURE__ */ jsx19("div", { ref: content, children }),
|
|
1334
|
+
/* @__PURE__ */ jsx19("div", { "aria-hidden": true, className: "absolute inset-y-0 -left-7 w-7" }),
|
|
1335
|
+
line !== null && /* @__PURE__ */ jsx19("div", { "aria-hidden": true, className: "pointer-events-none absolute inset-x-0 h-px bg-accent-primary", style: { top: line } }),
|
|
1336
|
+
block && (rows || own) && // The top is the block's, measured: it depends on the document, not on a size of ours.
|
|
1337
|
+
/* @__PURE__ */ jsx19("div", { className: cn("absolute -left-7", rows && "cursor-grab active:cursor-grabbing"), style: { top }, children: /* @__PURE__ */ jsxs12(
|
|
1338
|
+
Menu,
|
|
1339
|
+
{
|
|
1340
|
+
open,
|
|
1341
|
+
onOpenChange: setOpen,
|
|
1342
|
+
trigger: /* @__PURE__ */ jsx19(
|
|
1343
|
+
IconButton,
|
|
1344
|
+
{
|
|
1345
|
+
"aria-label": "Block menu",
|
|
1346
|
+
tooltip: rows ? "Drag to move, click for the menu" : "Menu",
|
|
1347
|
+
draggable: !!rows,
|
|
1348
|
+
onMouseDown: (e) => e.preventBaseUIHandler(),
|
|
1349
|
+
onClick: (e) => {
|
|
1350
|
+
e.preventBaseUIHandler();
|
|
1351
|
+
setOpen((was) => !was);
|
|
1352
|
+
},
|
|
1353
|
+
onDragStart: (e) => {
|
|
1354
|
+
if (!editing || !rows) return;
|
|
1355
|
+
setOpen(false);
|
|
1356
|
+
dragging.current = true;
|
|
1357
|
+
editing.startDrag(block, e.nativeEvent);
|
|
1358
|
+
},
|
|
1359
|
+
onDragEnd: () => {
|
|
1360
|
+
endDrag();
|
|
1361
|
+
setBlock(null);
|
|
1362
|
+
},
|
|
1363
|
+
children: /* @__PURE__ */ jsx19(IconGripVertical, { size: 16, stroke: 1.5 })
|
|
1364
|
+
}
|
|
1365
|
+
),
|
|
1366
|
+
children: [
|
|
1367
|
+
rows,
|
|
1368
|
+
rows && own && /* @__PURE__ */ jsx19(MenuSeparator, {}),
|
|
1369
|
+
own
|
|
1370
|
+
]
|
|
1371
|
+
}
|
|
1372
|
+
) })
|
|
1373
|
+
]
|
|
1374
|
+
}
|
|
1375
|
+
);
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
// src/Checkbox.tsx
|
|
1379
|
+
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
1380
|
+
import { Field as BaseField } from "@base-ui/react/field";
|
|
1381
|
+
import { IconCheck } from "@tabler/icons-react";
|
|
1382
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1383
|
+
function squareClasses(checked, disabled, interactive, className) {
|
|
1384
|
+
return cn(
|
|
1385
|
+
"inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
|
|
1386
|
+
checked ? "bg-accent-primary border-accent-primary text-text-inverse" : "bg-transparent border-border-strong hover:border-text-muted",
|
|
1387
|
+
disabled && "opacity-50 pointer-events-none",
|
|
1388
|
+
interactive ? "cursor-pointer" : "pointer-events-none",
|
|
1389
|
+
className
|
|
1390
|
+
);
|
|
1391
|
+
}
|
|
1392
|
+
var tickClasses = (checked) => cn("flex", !checked && "invisible");
|
|
1393
|
+
var WORDS_CLASSES = "text-body-2 text-text-primary";
|
|
1394
|
+
var ROW_CLASSES = "flex shrink-0 items-center gap-3 h-10 px-3 rounded-lg transition-colors";
|
|
1395
|
+
function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row, leading, className, ...aria }) {
|
|
1396
|
+
const formBusy = useFormBusy();
|
|
1397
|
+
const disabled = ownDisabled || formBusy;
|
|
1398
|
+
if (!onChange) {
|
|
1399
|
+
const picture = /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx20("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx20(IconCheck, { size: 12, stroke: 3 }) }) });
|
|
1400
|
+
if (label === void 0) return picture;
|
|
1401
|
+
return /* @__PURE__ */ jsxs13("span", { className: "flex items-center gap-2", children: [
|
|
1402
|
+
picture,
|
|
1403
|
+
/* @__PURE__ */ jsx20("span", { className: WORDS_CLASSES, children: label })
|
|
1404
|
+
] });
|
|
1405
|
+
}
|
|
1406
|
+
const box = /* @__PURE__ */ jsx20(
|
|
1407
|
+
BaseCheckbox.Root,
|
|
1408
|
+
{
|
|
1409
|
+
checked,
|
|
1410
|
+
disabled,
|
|
1411
|
+
"aria-label": aria["aria-label"],
|
|
1412
|
+
"aria-required": aria["aria-required"],
|
|
1413
|
+
onCheckedChange: (next) => onChange(next),
|
|
1414
|
+
onClick: (e) => e.stopPropagation(),
|
|
1415
|
+
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
1416
|
+
children: /* @__PURE__ */ jsx20(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx20(IconCheck, { size: 12, stroke: 3 }) })
|
|
1417
|
+
}
|
|
1418
|
+
);
|
|
1419
|
+
if (label === void 0) return box;
|
|
1420
|
+
if (row) {
|
|
1421
|
+
return /* @__PURE__ */ jsx20(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs13(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
|
|
1422
|
+
leading,
|
|
1423
|
+
/* @__PURE__ */ jsx20("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
|
|
1424
|
+
box
|
|
1425
|
+
] }) });
|
|
1426
|
+
}
|
|
1427
|
+
return /* @__PURE__ */ jsx20(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs13(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
|
|
1428
|
+
box,
|
|
1429
|
+
/* @__PURE__ */ jsx20("span", { className: WORDS_CLASSES, children: label })
|
|
1430
|
+
] }) });
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
// src/Chip.tsx
|
|
1434
|
+
import { Fragment as Fragment4, jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1435
|
+
var typeStyles = {
|
|
1436
|
+
neutral: "bg-bg-inset text-text-primary",
|
|
1437
|
+
brand: "bg-accent-muted text-accent-text signal:border signal:border-accent-outline",
|
|
1438
|
+
info: "bg-info-muted text-info-default signal:border signal:border-info-outline",
|
|
1439
|
+
warning: "bg-warning-muted text-warning-default signal:border signal:border-warning-outline signal:shadow-glow-warning",
|
|
1440
|
+
success: "bg-success-muted text-success-default signal:border signal:border-success-outline",
|
|
1441
|
+
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
1442
|
+
};
|
|
1443
|
+
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, href, onClick, className }) {
|
|
1444
|
+
const classes = cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className);
|
|
1445
|
+
const inside = /* @__PURE__ */ jsxs14(Fragment4, { children: [
|
|
1446
|
+
leadingIcon && /* @__PURE__ */ jsx21("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
1447
|
+
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
1448
|
+
// of growing past it — Ship's project chip on an issue row
|
|
1449
|
+
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
1450
|
+
// `truncate`, because `truncate` is `overflow: hidden` on both axes and
|
|
1451
|
+
// the label's line box (11px under Signal) is tighter than its glyphs —
|
|
1452
|
+
// the screenshot diff caught every descender cut off. `clip` is the
|
|
1453
|
+
// one overflow that leaves the other axis visible. A chip with no cap
|
|
1454
|
+
// draws exactly as before.
|
|
1455
|
+
/* @__PURE__ */ jsx21("span", { className: cn("min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap signal:tracking-wide", CHIP_TEXT_CLASSES), children: label }),
|
|
1456
|
+
trailingIcon && /* @__PURE__ */ jsx21("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
1457
|
+
] });
|
|
1458
|
+
if (href) return /* @__PURE__ */ jsx21("a", { href, onClick, className: cn("relative", classes), children: inside });
|
|
1459
|
+
return /* @__PURE__ */ jsx21("div", { className: classes, children: inside });
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
// src/CommandPalette.tsx
|
|
1463
|
+
import {
|
|
1464
|
+
createContext as createContext5,
|
|
1465
|
+
useContext as useContext5,
|
|
1466
|
+
useEffect as useEffect3,
|
|
1467
|
+
useLayoutEffect as useLayoutEffect3,
|
|
1468
|
+
useMemo as useMemo2,
|
|
1469
|
+
useRef as useRef5,
|
|
1470
|
+
useState as useState4
|
|
1471
|
+
} from "react";
|
|
1472
|
+
import { Dialog as Dialog2 } from "@base-ui/react/dialog";
|
|
1473
|
+
import { Autocomplete } from "@base-ui/react/autocomplete";
|
|
1474
|
+
import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
|
|
1475
|
+
|
|
1339
1476
|
// src/ChipInput.tsx
|
|
1340
|
-
import {
|
|
1477
|
+
import { useMemo, useState as useState3 } from "react";
|
|
1478
|
+
import { Button as BaseButton4 } from "@base-ui/react/button";
|
|
1479
|
+
import { Combobox } from "@base-ui/react/combobox";
|
|
1480
|
+
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
1481
|
+
import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1341
1482
|
var CHIP_BOX = (
|
|
1342
1483
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
1343
1484
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -1348,10 +1489,10 @@ var CHIP_LABEL = "text-caption font-medium text-text-primary";
|
|
|
1348
1489
|
var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
|
|
1349
1490
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
1350
1491
|
function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
|
|
1351
|
-
return /* @__PURE__ */
|
|
1352
|
-
leading && /* @__PURE__ */
|
|
1353
|
-
/* @__PURE__ */
|
|
1354
|
-
onRemove && /* @__PURE__ */
|
|
1492
|
+
return /* @__PURE__ */ jsxs15("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1493
|
+
leading && /* @__PURE__ */ jsx22("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1494
|
+
/* @__PURE__ */ jsx22("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
|
|
1495
|
+
onRemove && /* @__PURE__ */ jsx22(
|
|
1355
1496
|
BaseButton4,
|
|
1356
1497
|
{
|
|
1357
1498
|
type: "button",
|
|
@@ -1361,7 +1502,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
|
|
|
1361
1502
|
},
|
|
1362
1503
|
className: cn(CHIP_REMOVE, truncate && "shrink-0"),
|
|
1363
1504
|
"aria-label": removeLabel ?? `Remove ${label}`,
|
|
1364
|
-
children: /* @__PURE__ */
|
|
1505
|
+
children: /* @__PURE__ */ jsx22(IconX4, { size: 10, stroke: 1.5 })
|
|
1365
1506
|
}
|
|
1366
1507
|
)
|
|
1367
1508
|
] });
|
|
@@ -1377,8 +1518,8 @@ function ChipInput({
|
|
|
1377
1518
|
rowLeading,
|
|
1378
1519
|
...aria
|
|
1379
1520
|
}) {
|
|
1380
|
-
const [query, setQuery] =
|
|
1381
|
-
const [box, setBox] =
|
|
1521
|
+
const [query, setQuery] = useState3("");
|
|
1522
|
+
const [box, setBox] = useState3(null);
|
|
1382
1523
|
const available = useMemo(() => {
|
|
1383
1524
|
const chosen = new Set(value.map((o) => o.id));
|
|
1384
1525
|
const excluded = new Set(excludeIds);
|
|
@@ -1414,7 +1555,7 @@ function ChipInput({
|
|
|
1414
1555
|
setQuery("");
|
|
1415
1556
|
}
|
|
1416
1557
|
}
|
|
1417
|
-
return /* @__PURE__ */
|
|
1558
|
+
return /* @__PURE__ */ jsxs15(
|
|
1418
1559
|
Combobox.Root,
|
|
1419
1560
|
{
|
|
1420
1561
|
multiple: true,
|
|
@@ -1431,13 +1572,13 @@ function ChipInput({
|
|
|
1431
1572
|
filter,
|
|
1432
1573
|
itemToStringLabel: (option) => option.label,
|
|
1433
1574
|
children: [
|
|
1434
|
-
/* @__PURE__ */
|
|
1435
|
-
value.map((option) => /* @__PURE__ */
|
|
1436
|
-
chipLeading && /* @__PURE__ */
|
|
1437
|
-
/* @__PURE__ */
|
|
1438
|
-
/* @__PURE__ */
|
|
1575
|
+
/* @__PURE__ */ jsxs15(Combobox.Chips, { ref: setBox, className: cn(FIELD_SHELL_CLASSES, "focus-within:border-border-focus focus-within:hover:border-border-focus group-hover/field:focus-within:border-border-focus px-3 py-1.5 flex flex-wrap items-center gap-1.5 min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring"), children: [
|
|
1576
|
+
value.map((option) => /* @__PURE__ */ jsxs15(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1577
|
+
chipLeading && /* @__PURE__ */ jsx22("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
|
|
1578
|
+
/* @__PURE__ */ jsx22("span", { className: CHIP_LABEL, children: option.label }),
|
|
1579
|
+
/* @__PURE__ */ jsx22(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx22(IconX4, { size: 10, stroke: 1.5 }) })
|
|
1439
1580
|
] }, option.id)),
|
|
1440
|
-
/* @__PURE__ */
|
|
1581
|
+
/* @__PURE__ */ jsx22(
|
|
1441
1582
|
Combobox.Input,
|
|
1442
1583
|
{
|
|
1443
1584
|
autoFocus,
|
|
@@ -1449,18 +1590,18 @@ function ChipInput({
|
|
|
1449
1590
|
}
|
|
1450
1591
|
)
|
|
1451
1592
|
] }),
|
|
1452
|
-
/* @__PURE__ */
|
|
1593
|
+
/* @__PURE__ */ jsx22(Combobox.Portal, { children: /* @__PURE__ */ jsx22(
|
|
1453
1594
|
Combobox.Positioner,
|
|
1454
1595
|
{
|
|
1455
1596
|
anchor: box,
|
|
1456
1597
|
sideOffset: GAP3,
|
|
1457
1598
|
collisionPadding: VIEWPORT_PAD3,
|
|
1458
1599
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1459
|
-
children: /* @__PURE__ */
|
|
1600
|
+
children: /* @__PURE__ */ jsx22(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx22(MenuPanel, {}), children: /* @__PURE__ */ jsx22(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx22(Combobox.List, { children: (option) => /* @__PURE__ */ jsx22(
|
|
1460
1601
|
Combobox.Item,
|
|
1461
1602
|
{
|
|
1462
1603
|
value: option,
|
|
1463
|
-
render: /* @__PURE__ */
|
|
1604
|
+
render: /* @__PURE__ */ jsx22(
|
|
1464
1605
|
MenuItem,
|
|
1465
1606
|
{
|
|
1466
1607
|
size: "tall",
|
|
@@ -1483,22 +1624,22 @@ var VIEWPORT_PAD3 = 8;
|
|
|
1483
1624
|
|
|
1484
1625
|
// src/EmptyState.tsx
|
|
1485
1626
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1486
|
-
import { jsx as
|
|
1627
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1487
1628
|
function EmptyState({ icon, message, scope = "page", action, className }) {
|
|
1488
1629
|
if (scope === "section") {
|
|
1489
|
-
return /* @__PURE__ */
|
|
1630
|
+
return /* @__PURE__ */ jsx23("p", { className: cn("text-caption text-text-muted", className), children: message });
|
|
1490
1631
|
}
|
|
1491
|
-
return /* @__PURE__ */
|
|
1492
|
-
/* @__PURE__ */
|
|
1493
|
-
/* @__PURE__ */
|
|
1494
|
-
action && /* @__PURE__ */
|
|
1632
|
+
return /* @__PURE__ */ jsxs16("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1633
|
+
/* @__PURE__ */ jsx23("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx23(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1634
|
+
/* @__PURE__ */ jsx23("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
|
|
1635
|
+
action && /* @__PURE__ */ jsx23(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
|
|
1495
1636
|
] });
|
|
1496
1637
|
}
|
|
1497
1638
|
|
|
1498
1639
|
// src/Field.tsx
|
|
1499
1640
|
import { cloneElement, isValidElement } from "react";
|
|
1500
1641
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1501
|
-
import { jsx as
|
|
1642
|
+
import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1502
1643
|
var LINE_STYLES = {
|
|
1503
1644
|
helper: "text-caption text-text-muted",
|
|
1504
1645
|
warning: "text-caption text-warning-default",
|
|
@@ -1512,27 +1653,27 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1512
1653
|
// `group/field`: the label, the box and the line under it are one thing under the pointer —
|
|
1513
1654
|
// anywhere in it strengthens the box's border, as hovering the box does (Katerina, 28 September).
|
|
1514
1655
|
// Before, the 8px between the label and the box was a gap where the border went out again.
|
|
1515
|
-
/* @__PURE__ */
|
|
1516
|
-
/* @__PURE__ */
|
|
1656
|
+
/* @__PURE__ */ jsxs17(BaseField2.Root, { invalid: !!error, className: "group/field flex flex-col gap-2", children: [
|
|
1657
|
+
/* @__PURE__ */ jsxs17(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1517
1658
|
label,
|
|
1518
|
-
required && /* @__PURE__ */
|
|
1659
|
+
required && /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1519
1660
|
] }),
|
|
1520
|
-
/* @__PURE__ */
|
|
1661
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1.5", children: [
|
|
1521
1662
|
control,
|
|
1522
|
-
error != null ? /* @__PURE__ */
|
|
1663
|
+
error != null ? /* @__PURE__ */ jsx24(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx24(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
|
|
1523
1664
|
] })
|
|
1524
1665
|
] })
|
|
1525
1666
|
);
|
|
1526
1667
|
}
|
|
1527
1668
|
function FieldLine({ tone = "helper", children, className }) {
|
|
1528
|
-
return /* @__PURE__ */
|
|
1669
|
+
return /* @__PURE__ */ jsx24("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
|
|
1529
1670
|
}
|
|
1530
1671
|
|
|
1531
1672
|
// src/Form.tsx
|
|
1532
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
1673
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef4 } from "react";
|
|
1533
1674
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
1534
1675
|
import { Form as BaseForm } from "@base-ui/react/form";
|
|
1535
|
-
import { jsx as
|
|
1676
|
+
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
1536
1677
|
var FIELDS_CLASSES = "flex flex-col gap-6";
|
|
1537
1678
|
var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
|
|
1538
1679
|
var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
@@ -1550,12 +1691,12 @@ function firstInvalid(form) {
|
|
|
1550
1691
|
function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fields", className, children, ...props }) {
|
|
1551
1692
|
const outerBusy = useFormBusy();
|
|
1552
1693
|
const busy = ownBusy || outerBusy;
|
|
1553
|
-
const form =
|
|
1554
|
-
const busyNow =
|
|
1694
|
+
const form = useRef4(null);
|
|
1695
|
+
const busyNow = useRef4(busy);
|
|
1555
1696
|
busyNow.current = busy;
|
|
1556
|
-
const sender =
|
|
1557
|
-
const holding =
|
|
1558
|
-
const lastInside =
|
|
1697
|
+
const sender = useRef4(null);
|
|
1698
|
+
const holding = useRef4(false);
|
|
1699
|
+
const lastInside = useRef4(null);
|
|
1559
1700
|
useLayoutEffect2(() => {
|
|
1560
1701
|
const element = form.current;
|
|
1561
1702
|
if (!element) return;
|
|
@@ -1592,7 +1733,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fi
|
|
|
1592
1733
|
const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
|
|
1593
1734
|
if (enterSends && oneLine) form.current?.requestSubmit();
|
|
1594
1735
|
};
|
|
1595
|
-
return /* @__PURE__ */
|
|
1736
|
+
return /* @__PURE__ */ jsx25(
|
|
1596
1737
|
BaseForm,
|
|
1597
1738
|
{
|
|
1598
1739
|
ref: form,
|
|
@@ -1615,29 +1756,29 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, layout = "fi
|
|
|
1615
1756
|
if (busyNow.current) return;
|
|
1616
1757
|
void onSubmit();
|
|
1617
1758
|
},
|
|
1618
|
-
children: /* @__PURE__ */
|
|
1759
|
+
children: /* @__PURE__ */ jsx25(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx25(FormBusyContext.Provider, { value: busy, children }) })
|
|
1619
1760
|
}
|
|
1620
1761
|
);
|
|
1621
1762
|
}
|
|
1622
1763
|
|
|
1623
1764
|
// src/Skeleton.tsx
|
|
1624
|
-
import { jsx as
|
|
1765
|
+
import { jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1625
1766
|
function SkeletonBar({ className, style }) {
|
|
1626
|
-
return /* @__PURE__ */
|
|
1767
|
+
return /* @__PURE__ */ jsx26("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1627
1768
|
}
|
|
1628
1769
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1629
1770
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1630
|
-
return /* @__PURE__ */
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
/* @__PURE__ */
|
|
1771
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1772
|
+
/* @__PURE__ */ jsx26(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1773
|
+
/* @__PURE__ */ jsx26(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1633
1774
|
] });
|
|
1634
1775
|
}
|
|
1635
1776
|
function SkeletonList({ rows = 8, className }) {
|
|
1636
|
-
return /* @__PURE__ */
|
|
1777
|
+
return /* @__PURE__ */ jsx26("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx26(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
|
|
1637
1778
|
}
|
|
1638
1779
|
|
|
1639
1780
|
// src/CommandPalette.tsx
|
|
1640
|
-
import { Fragment as Fragment5, jsx as
|
|
1781
|
+
import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1641
1782
|
var PaletteContext = createContext5(null);
|
|
1642
1783
|
function usePalette(part) {
|
|
1643
1784
|
const palette = useContext5(PaletteContext);
|
|
@@ -1652,8 +1793,8 @@ function firstControl(popup) {
|
|
|
1652
1793
|
return popup.querySelector("[data-command-palette-fields]")?.querySelector(CONTROL2) ?? null;
|
|
1653
1794
|
}
|
|
1654
1795
|
function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", children }) {
|
|
1655
|
-
const popupRef =
|
|
1656
|
-
|
|
1796
|
+
const popupRef = useRef5(null);
|
|
1797
|
+
useEffect3(() => {
|
|
1657
1798
|
if (!open) return;
|
|
1658
1799
|
const frame = requestAnimationFrame(() => {
|
|
1659
1800
|
const popup = popupRef.current;
|
|
@@ -1663,9 +1804,9 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1663
1804
|
return () => cancelAnimationFrame(frame);
|
|
1664
1805
|
});
|
|
1665
1806
|
const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
|
|
1666
|
-
return /* @__PURE__ */
|
|
1667
|
-
/* @__PURE__ */
|
|
1668
|
-
/* @__PURE__ */
|
|
1807
|
+
return /* @__PURE__ */ jsx27(Dialog2.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs19(Dialog2.Portal, { children: [
|
|
1808
|
+
/* @__PURE__ */ jsx27(Dialog2.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1809
|
+
/* @__PURE__ */ jsx27(Dialog2.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx27(
|
|
1669
1810
|
Dialog2.Popup,
|
|
1670
1811
|
{
|
|
1671
1812
|
ref: popupRef,
|
|
@@ -1675,13 +1816,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1675
1816
|
if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
|
|
1676
1817
|
},
|
|
1677
1818
|
className: "flex w-[658px] max-w-[calc(100vw-32px)] flex-col overflow-hidden rounded-lg border border-border-default bg-bg-elevated shadow-lg outline-none",
|
|
1678
|
-
children: /* @__PURE__ */
|
|
1819
|
+
children: /* @__PURE__ */ jsx27(PaletteContext.Provider, { value: context, children })
|
|
1679
1820
|
}
|
|
1680
1821
|
) })
|
|
1681
1822
|
] }) });
|
|
1682
1823
|
}
|
|
1683
1824
|
function LevelChip({ chip, onBack }) {
|
|
1684
|
-
return /* @__PURE__ */
|
|
1825
|
+
return /* @__PURE__ */ jsx27(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
|
|
1685
1826
|
}
|
|
1686
1827
|
function useBack(chip, popupRef) {
|
|
1687
1828
|
return () => {
|
|
@@ -1692,10 +1833,10 @@ function useBack(chip, popupRef) {
|
|
|
1692
1833
|
}
|
|
1693
1834
|
function Footer({ keys }) {
|
|
1694
1835
|
const { where } = usePalette("The footer");
|
|
1695
|
-
return /* @__PURE__ */
|
|
1696
|
-
/* @__PURE__ */
|
|
1697
|
-
keys.map(([key, word]) => /* @__PURE__ */
|
|
1698
|
-
/* @__PURE__ */
|
|
1836
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted leaf:font-mono leaf:text-small", children: [
|
|
1837
|
+
/* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 truncate", children: where }),
|
|
1838
|
+
keys.map(([key, word]) => /* @__PURE__ */ jsxs19("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
1839
|
+
/* @__PURE__ */ jsx27(Kbd, { children: key }),
|
|
1699
1840
|
" ",
|
|
1700
1841
|
word
|
|
1701
1842
|
] }, key))
|
|
@@ -1707,12 +1848,12 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1707
1848
|
const back = useBack(chip, popupRef);
|
|
1708
1849
|
const items = useMemo2(() => groups.filter((g) => g.rows.length > 0).map((g) => ({ value: g.label, items: g.rows })), [groups]);
|
|
1709
1850
|
const rows = items.flatMap((g) => g.items);
|
|
1710
|
-
const [litId, setLitId] =
|
|
1851
|
+
const [litId, setLitId] = useState4();
|
|
1711
1852
|
const lit = litId === void 0 ? void 0 : rows.find((r) => r.id === litId);
|
|
1712
|
-
const inputRef =
|
|
1713
|
-
const reported =
|
|
1714
|
-
const settled =
|
|
1715
|
-
const moved =
|
|
1853
|
+
const inputRef = useRef5(null);
|
|
1854
|
+
const reported = useRef5({});
|
|
1855
|
+
const settled = useRef5(null);
|
|
1856
|
+
const moved = useRef5(false);
|
|
1716
1857
|
useLayoutEffect3(() => {
|
|
1717
1858
|
const before = settled.current;
|
|
1718
1859
|
const now = reported.current;
|
|
@@ -1772,7 +1913,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1772
1913
|
...chip && query === "" ? [["Backspace", "back"]] : [],
|
|
1773
1914
|
["Esc", "close"]
|
|
1774
1915
|
];
|
|
1775
|
-
return /* @__PURE__ */
|
|
1916
|
+
return /* @__PURE__ */ jsxs19(
|
|
1776
1917
|
Autocomplete.Root,
|
|
1777
1918
|
{
|
|
1778
1919
|
items,
|
|
@@ -1795,10 +1936,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1795
1936
|
setLitId(id);
|
|
1796
1937
|
},
|
|
1797
1938
|
children: [
|
|
1798
|
-
/* @__PURE__ */
|
|
1799
|
-
/* @__PURE__ */
|
|
1800
|
-
chip && /* @__PURE__ */
|
|
1801
|
-
/* @__PURE__ */
|
|
1939
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1940
|
+
/* @__PURE__ */ jsx27(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
|
|
1941
|
+
chip && /* @__PURE__ */ jsx27(LevelChip, { chip, onBack: back }),
|
|
1942
|
+
/* @__PURE__ */ jsx27(
|
|
1802
1943
|
Autocomplete.Input,
|
|
1803
1944
|
{
|
|
1804
1945
|
ref: inputRef,
|
|
@@ -1810,43 +1951,43 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1810
1951
|
}
|
|
1811
1952
|
)
|
|
1812
1953
|
] }),
|
|
1813
|
-
/* @__PURE__ */
|
|
1814
|
-
children != null && /* @__PURE__ */
|
|
1815
|
-
/* @__PURE__ */
|
|
1816
|
-
/* @__PURE__ */
|
|
1817
|
-
/* @__PURE__ */
|
|
1954
|
+
/* @__PURE__ */ jsxs19(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
|
|
1955
|
+
children != null && /* @__PURE__ */ jsx27("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
|
|
1956
|
+
/* @__PURE__ */ jsx27(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs19(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
|
|
1957
|
+
/* @__PURE__ */ jsx27(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx27(SectionLabel, { tone: "secondary", children: group.value }) }),
|
|
1958
|
+
/* @__PURE__ */ jsx27(Autocomplete.Collection, { children: (row) => (
|
|
1818
1959
|
/* The menu row, as the list's own option — the way Select
|
|
1819
1960
|
puts it on `Select.Item`. One row, two parts. */
|
|
1820
|
-
/* @__PURE__ */
|
|
1961
|
+
/* @__PURE__ */ jsx27(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx27(
|
|
1821
1962
|
MenuItemBody,
|
|
1822
1963
|
{
|
|
1823
1964
|
size: "tall",
|
|
1824
1965
|
label: row.label,
|
|
1825
1966
|
description: row.description,
|
|
1826
|
-
leading: /* @__PURE__ */
|
|
1967
|
+
leading: /* @__PURE__ */ jsx27(RowLeading, { row }),
|
|
1827
1968
|
submenu: !!row.onGoIn,
|
|
1828
|
-
hint: row.onGoIn ? /* @__PURE__ */
|
|
1969
|
+
hint: row.onGoIn ? /* @__PURE__ */ jsx27(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx27(EnterHint, {})
|
|
1829
1970
|
}
|
|
1830
1971
|
) }, row.id)
|
|
1831
1972
|
) })
|
|
1832
1973
|
] }, group.value) }),
|
|
1833
|
-
/* @__PURE__ */
|
|
1834
|
-
/* @__PURE__ */
|
|
1835
|
-
/* @__PURE__ */
|
|
1974
|
+
/* @__PURE__ */ jsx27(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
1975
|
+
/* @__PURE__ */ jsx27(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
|
|
1976
|
+
/* @__PURE__ */ jsx27("span", { className: "text-caption text-text-muted", children: pending })
|
|
1836
1977
|
] }) }),
|
|
1837
|
-
notes.map((note) => /* @__PURE__ */
|
|
1838
|
-
/* @__PURE__ */
|
|
1978
|
+
notes.map((note) => /* @__PURE__ */ jsx27("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx27(FieldLine, { children: note }) }, note)),
|
|
1979
|
+
/* @__PURE__ */ jsx27(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx27(EmptyState, { scope: "section", message: empty }) })
|
|
1839
1980
|
] }),
|
|
1840
|
-
/* @__PURE__ */
|
|
1981
|
+
/* @__PURE__ */ jsx27(Footer, { keys })
|
|
1841
1982
|
]
|
|
1842
1983
|
}
|
|
1843
1984
|
);
|
|
1844
1985
|
}
|
|
1845
1986
|
function RowLeading({ row }) {
|
|
1846
1987
|
if (row.icon != null) {
|
|
1847
|
-
return /* @__PURE__ */
|
|
1988
|
+
return /* @__PURE__ */ jsx27("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
|
|
1848
1989
|
}
|
|
1849
|
-
return /* @__PURE__ */
|
|
1990
|
+
return /* @__PURE__ */ jsx27("span", { className: "flex size-8 items-center justify-center", children: row.leading });
|
|
1850
1991
|
}
|
|
1851
1992
|
var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1852
1993
|
function isTextField(el) {
|
|
@@ -1856,9 +1997,9 @@ function isTextField(el) {
|
|
|
1856
1997
|
function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, working, error, children }) {
|
|
1857
1998
|
const { modKey, popupRef } = usePalette("CommandPaletteForm");
|
|
1858
1999
|
const back = useBack(chip, popupRef);
|
|
1859
|
-
const frameRef =
|
|
2000
|
+
const frameRef = useRef5(null);
|
|
1860
2001
|
const busy = !!working;
|
|
1861
|
-
const busyRef =
|
|
2002
|
+
const busyRef = useRef5(busy);
|
|
1862
2003
|
busyRef.current = busy;
|
|
1863
2004
|
const firstInvalid2 = () => frameRef.current?.querySelector("[data-invalid]")?.querySelector(CONTROL2) ?? null;
|
|
1864
2005
|
const submit = () => {
|
|
@@ -1874,7 +2015,7 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
|
|
|
1874
2015
|
if (isTextField(el)) return el.value === "";
|
|
1875
2016
|
return ![...frame.querySelectorAll("input, textarea")].some(isTextField);
|
|
1876
2017
|
};
|
|
1877
|
-
const [backNamed, setBackNamed] =
|
|
2018
|
+
const [backNamed, setBackNamed] = useState4(false);
|
|
1878
2019
|
const measure = () => setBackNamed(backWorksFrom(document.activeElement));
|
|
1879
2020
|
useLayoutEffect3(measure);
|
|
1880
2021
|
const onKeyDown = (e) => {
|
|
@@ -1888,65 +2029,65 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
|
|
|
1888
2029
|
...backNamed ? [["Backspace", "back"]] : [],
|
|
1889
2030
|
["Esc", "close"]
|
|
1890
2031
|
];
|
|
1891
|
-
return /* @__PURE__ */
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
icon != null && /* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
2032
|
+
return /* @__PURE__ */ jsxs19("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
|
|
2033
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
2034
|
+
icon != null && /* @__PURE__ */ jsx27("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
|
|
2035
|
+
/* @__PURE__ */ jsx27(LevelChip, { chip, onBack: back })
|
|
1895
2036
|
] }),
|
|
1896
|
-
/* @__PURE__ */
|
|
1897
|
-
/* @__PURE__ */
|
|
1898
|
-
/* @__PURE__ */
|
|
1899
|
-
/* @__PURE__ */
|
|
1900
|
-
/* @__PURE__ */
|
|
2037
|
+
/* @__PURE__ */ jsxs19(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, layout: "free", className: "flex min-h-0 flex-col", children: [
|
|
2038
|
+
/* @__PURE__ */ jsx27(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx27("div", { className: FIELDS_CLASSES, children }) }),
|
|
2039
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
|
|
2040
|
+
/* @__PURE__ */ jsx27("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx27(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx27(FieldLine, { tone: "error", children: error }) : null }),
|
|
2041
|
+
/* @__PURE__ */ jsx27(
|
|
1901
2042
|
Button,
|
|
1902
2043
|
{
|
|
1903
2044
|
type: "submit",
|
|
1904
2045
|
variant: "primary",
|
|
1905
2046
|
disabled: busy,
|
|
1906
2047
|
disabledReason: busy ? void 0 : submitWaits,
|
|
1907
|
-
leadingIcon: busy ? /* @__PURE__ */
|
|
2048
|
+
leadingIcon: busy ? /* @__PURE__ */ jsx27(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
|
|
1908
2049
|
children: working ? working.button : submitLabel
|
|
1909
2050
|
}
|
|
1910
2051
|
)
|
|
1911
2052
|
] })
|
|
1912
2053
|
] }),
|
|
1913
|
-
/* @__PURE__ */
|
|
2054
|
+
/* @__PURE__ */ jsx27(Footer, { keys })
|
|
1914
2055
|
] });
|
|
1915
2056
|
}
|
|
1916
2057
|
var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
|
|
1917
2058
|
function CommandPaletteWorking({ children, bars = 2 }) {
|
|
1918
|
-
return /* @__PURE__ */
|
|
1919
|
-
/* @__PURE__ */
|
|
1920
|
-
/* @__PURE__ */
|
|
2059
|
+
return /* @__PURE__ */ jsxs19("div", { role: "status", className: "flex flex-col gap-2", children: [
|
|
2060
|
+
/* @__PURE__ */ jsxs19("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
|
|
2061
|
+
/* @__PURE__ */ jsx27(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
|
|
1921
2062
|
children
|
|
1922
2063
|
] }),
|
|
1923
|
-
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */
|
|
2064
|
+
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx27(SkeletonBar, { className: cn("h-3", width) }, width))
|
|
1924
2065
|
] });
|
|
1925
2066
|
}
|
|
1926
2067
|
function CommandPaletteAnswer({ children, note }) {
|
|
1927
2068
|
const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
|
|
1928
|
-
return /* @__PURE__ */
|
|
1929
|
-
paragraphs.map((paragraph, i) => /* @__PURE__ */
|
|
1930
|
-
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */
|
|
2069
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex flex-col gap-2", children: [
|
|
2070
|
+
paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx27("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
|
|
2071
|
+
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx27("sup", { className: "ml-0.5 font-mono text-small text-accent-text", children: part.slice(1, -1) }, j) : part
|
|
1931
2072
|
) }, i)),
|
|
1932
|
-
note && /* @__PURE__ */
|
|
2073
|
+
note && /* @__PURE__ */ jsx27(FieldLine, { children: note })
|
|
1933
2074
|
] });
|
|
1934
2075
|
}
|
|
1935
2076
|
function CommandPaletteQuote({ children }) {
|
|
1936
|
-
return /* @__PURE__ */
|
|
2077
|
+
return /* @__PURE__ */ jsx27("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
|
|
1937
2078
|
}
|
|
1938
2079
|
function CommandPaletteProposal({ source, mark, children }) {
|
|
1939
|
-
return /* @__PURE__ */
|
|
1940
|
-
/* @__PURE__ */
|
|
2080
|
+
return /* @__PURE__ */ jsxs19(Card, { fill: "surface", className: "flex flex-col gap-1 p-3", children: [
|
|
2081
|
+
/* @__PURE__ */ jsxs19("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
|
|
1941
2082
|
mark,
|
|
1942
2083
|
source
|
|
1943
2084
|
] }),
|
|
1944
|
-
/* @__PURE__ */
|
|
2085
|
+
/* @__PURE__ */ jsx27("span", { className: "text-body-2 text-text-primary", children })
|
|
1945
2086
|
] });
|
|
1946
2087
|
}
|
|
1947
2088
|
|
|
1948
2089
|
// src/InlineChip.tsx
|
|
1949
|
-
import { Fragment as Fragment6, jsx as
|
|
2090
|
+
import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1950
2091
|
var INLINE_CHIP_CLASSES = "inline-flex h-[1.4em] items-center gap-1 rounded-sm px-1 mx-0.5 align-top text-body-2 font-normal select-none";
|
|
1951
2092
|
var INLINE_CHIP_TONE_CLASSES = {
|
|
1952
2093
|
/** A thing or a place — anything that is not a person. */
|
|
@@ -1968,19 +2109,19 @@ function inlineChipClassName(tone, className) {
|
|
|
1968
2109
|
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1969
2110
|
}
|
|
1970
2111
|
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1971
|
-
const body = /* @__PURE__ */
|
|
1972
|
-
icon && /* @__PURE__ */
|
|
2112
|
+
const body = /* @__PURE__ */ jsxs20(Fragment6, { children: [
|
|
2113
|
+
icon && /* @__PURE__ */ jsx28("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
|
|
1973
2114
|
children
|
|
1974
2115
|
] });
|
|
1975
2116
|
const classes = inlineChipClassName(tone, className);
|
|
1976
2117
|
if (href === void 0) {
|
|
1977
|
-
return /* @__PURE__ */
|
|
2118
|
+
return /* @__PURE__ */ jsx28("span", { className: classes, ...props, children: body });
|
|
1978
2119
|
}
|
|
1979
|
-
return /* @__PURE__ */
|
|
2120
|
+
return /* @__PURE__ */ jsx28("a", { href, className: classes, ...props, children: body });
|
|
1980
2121
|
}
|
|
1981
2122
|
|
|
1982
2123
|
// src/RichText.tsx
|
|
1983
|
-
import { Fragment as Fragment7, jsx as
|
|
2124
|
+
import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1984
2125
|
var RICH_TEXT_CLASSES = {
|
|
1985
2126
|
base: "flex flex-col gap-1 break-words text-text-secondary",
|
|
1986
2127
|
/* A heading binds to what follows it: 12px above (8 and the 4px gap), 8px below (4 and the gap); two headings in a row, 12px apart. Level 3 keeps the text's colour, one step lower. */
|
|
@@ -2012,35 +2153,35 @@ function textWithLinks(text, renderText) {
|
|
|
2012
2153
|
return parts.map((part, i) => {
|
|
2013
2154
|
const written = part.match(WRITTEN_LINK);
|
|
2014
2155
|
if (written) {
|
|
2015
|
-
return /* @__PURE__ */
|
|
2156
|
+
return /* @__PURE__ */ jsx29("span", { className: "break-words", children: /* @__PURE__ */ jsx29(Link, { href: written[2], external: true, onClick: keepToLink, children: written[1] }) }, i);
|
|
2016
2157
|
}
|
|
2017
2158
|
const bare = i % 2 === 1 ? part.match(BARE_LINK) : null;
|
|
2018
2159
|
if (bare) {
|
|
2019
2160
|
return (
|
|
2020
2161
|
// An address has no spaces to wrap at, so it may break anywhere.
|
|
2021
|
-
/* @__PURE__ */
|
|
2022
|
-
/* @__PURE__ */
|
|
2162
|
+
/* @__PURE__ */ jsxs21("span", { className: "break-all", children: [
|
|
2163
|
+
/* @__PURE__ */ jsx29(Link, { href: bare[1], external: true, onClick: keepToLink, children: bare[1] }),
|
|
2023
2164
|
bare[2]
|
|
2024
2165
|
] }, i)
|
|
2025
2166
|
);
|
|
2026
2167
|
}
|
|
2027
|
-
return part ? /* @__PURE__ */
|
|
2168
|
+
return part ? /* @__PURE__ */ jsx29("span", { children: renderText(part) }, i) : null;
|
|
2028
2169
|
});
|
|
2029
2170
|
}
|
|
2030
2171
|
function Runs({ runs, draw }) {
|
|
2031
|
-
return /* @__PURE__ */
|
|
2032
|
-
if (run.reference) return /* @__PURE__ */
|
|
2172
|
+
return /* @__PURE__ */ jsx29(Fragment7, { children: (runs ?? []).map((run, i) => {
|
|
2173
|
+
if (run.reference) return /* @__PURE__ */ jsx29("span", { children: draw.renderReference(run.reference, run) }, i);
|
|
2033
2174
|
if (run.marks.includes("code")) {
|
|
2034
|
-
return /* @__PURE__ */
|
|
2175
|
+
return /* @__PURE__ */ jsx29("code", { children: run.text }, i);
|
|
2035
2176
|
}
|
|
2036
|
-
let node = run.text.split("\n").map((line, j) => /* @__PURE__ */
|
|
2037
|
-
j > 0 && /* @__PURE__ */
|
|
2177
|
+
let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs21("span", { children: [
|
|
2178
|
+
j > 0 && /* @__PURE__ */ jsx29("br", {}),
|
|
2038
2179
|
textWithLinks(line, draw.renderText)
|
|
2039
2180
|
] }, j));
|
|
2040
|
-
if (run.marks.includes("underline")) node = /* @__PURE__ */
|
|
2041
|
-
if (run.marks.includes("italic")) node = /* @__PURE__ */
|
|
2042
|
-
if (run.marks.includes("bold")) node = /* @__PURE__ */
|
|
2043
|
-
return /* @__PURE__ */
|
|
2181
|
+
if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx29("u", { children: node });
|
|
2182
|
+
if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx29("em", { children: node });
|
|
2183
|
+
if (run.marks.includes("bold")) node = /* @__PURE__ */ jsx29("strong", { children: node });
|
|
2184
|
+
return /* @__PURE__ */ jsx29("span", { children: node }, i);
|
|
2044
2185
|
}) });
|
|
2045
2186
|
}
|
|
2046
2187
|
var named = (block) => block.typeName ?? block.type;
|
|
@@ -2051,15 +2192,15 @@ function Table({ block, draw }) {
|
|
|
2051
2192
|
const header = named(cell) === "tableHeader";
|
|
2052
2193
|
const Cell = header ? "th" : "td";
|
|
2053
2194
|
const { colspan, rowspan } = cell.attrs ?? {};
|
|
2054
|
-
return /* @__PURE__ */
|
|
2195
|
+
return /* @__PURE__ */ jsxs21(
|
|
2055
2196
|
Cell,
|
|
2056
2197
|
{
|
|
2057
2198
|
"data-block-id": cell.id,
|
|
2058
2199
|
colSpan: colspan && colspan > 1 ? colspan : void 0,
|
|
2059
2200
|
rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
|
|
2060
2201
|
children: [
|
|
2061
|
-
(cell.children ?? []).map((child, j) => /* @__PURE__ */
|
|
2062
|
-
/* @__PURE__ */
|
|
2202
|
+
(cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx29(Runs, { runs: child.inline, draw }, j)),
|
|
2203
|
+
/* @__PURE__ */ jsx29(Runs, { runs: cell.inline, draw })
|
|
2063
2204
|
]
|
|
2064
2205
|
},
|
|
2065
2206
|
cell.id ?? i
|
|
@@ -2067,43 +2208,43 @@ function Table({ block, draw }) {
|
|
|
2067
2208
|
});
|
|
2068
2209
|
const first = rows[0].children ?? [];
|
|
2069
2210
|
const headerRow = first.length > 0 && first.every((cell) => named(cell) === "tableHeader");
|
|
2070
|
-
return /* @__PURE__ */
|
|
2071
|
-
headerRow && /* @__PURE__ */
|
|
2072
|
-
/* @__PURE__ */
|
|
2211
|
+
return /* @__PURE__ */ jsxs21("table", { "data-block-id": block.id, children: [
|
|
2212
|
+
headerRow && /* @__PURE__ */ jsx29("thead", { children: /* @__PURE__ */ jsx29("tr", { "data-block-id": rows[0].id, children: cells(rows[0]) }) }),
|
|
2213
|
+
/* @__PURE__ */ jsx29("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx29("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
|
|
2073
2214
|
] });
|
|
2074
2215
|
}
|
|
2075
2216
|
function Block({ block, draw }) {
|
|
2076
2217
|
const own = draw.renderBlock?.(block);
|
|
2077
2218
|
if (own !== void 0) return own;
|
|
2078
|
-
const runs = /* @__PURE__ */
|
|
2219
|
+
const runs = /* @__PURE__ */ jsx29(Runs, { runs: block.inline, draw });
|
|
2079
2220
|
switch (block.type) {
|
|
2080
2221
|
case "heading": {
|
|
2081
|
-
if (block.level === 1) return /* @__PURE__ */
|
|
2082
|
-
if (block.level === 3) return /* @__PURE__ */
|
|
2083
|
-
return /* @__PURE__ */
|
|
2222
|
+
if (block.level === 1) return /* @__PURE__ */ jsx29("h1", { "data-block-id": block.id, children: runs });
|
|
2223
|
+
if (block.level === 3) return /* @__PURE__ */ jsx29("h3", { "data-block-id": block.id, children: runs });
|
|
2224
|
+
return /* @__PURE__ */ jsx29("h2", { "data-block-id": block.id, children: runs });
|
|
2084
2225
|
}
|
|
2085
2226
|
case "paragraph":
|
|
2086
|
-
return /* @__PURE__ */
|
|
2227
|
+
return /* @__PURE__ */ jsx29("p", { "data-block-id": block.id, children: runs });
|
|
2087
2228
|
case "bulletList":
|
|
2088
2229
|
case "orderedList": {
|
|
2089
|
-
const items = (block.children ?? []).map((item, i) => /* @__PURE__ */
|
|
2090
|
-
return block.type === "bulletList" ? /* @__PURE__ */
|
|
2230
|
+
const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx29("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx29(Runs, { runs: item.inline, draw }) }, item.id ?? i));
|
|
2231
|
+
return block.type === "bulletList" ? /* @__PURE__ */ jsx29("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx29("ol", { "data-block-id": block.id, start: block.start, children: items });
|
|
2091
2232
|
}
|
|
2092
2233
|
case "blockquote":
|
|
2093
|
-
return /* @__PURE__ */
|
|
2234
|
+
return /* @__PURE__ */ jsx29("blockquote", { "data-block-id": block.id, children: runs });
|
|
2094
2235
|
case "codeBlock":
|
|
2095
|
-
return /* @__PURE__ */
|
|
2236
|
+
return /* @__PURE__ */ jsx29("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx29("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
|
|
2096
2237
|
case "horizontalRule":
|
|
2097
|
-
return /* @__PURE__ */
|
|
2238
|
+
return /* @__PURE__ */ jsx29("hr", { "data-block-id": block.id });
|
|
2098
2239
|
case "table": {
|
|
2099
|
-
const table = /* @__PURE__ */
|
|
2240
|
+
const table = /* @__PURE__ */ jsx29(Table, { block, draw });
|
|
2100
2241
|
if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
|
|
2101
2242
|
break;
|
|
2102
2243
|
}
|
|
2103
2244
|
}
|
|
2104
|
-
return /* @__PURE__ */
|
|
2245
|
+
return /* @__PURE__ */ jsxs21("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
|
|
2105
2246
|
runs,
|
|
2106
|
-
(block.children ?? []).map((child, i) => /* @__PURE__ */
|
|
2247
|
+
(block.children ?? []).map((child, i) => /* @__PURE__ */ jsx29(Block, { block: child, draw }, child.id ?? i))
|
|
2107
2248
|
] });
|
|
2108
2249
|
}
|
|
2109
2250
|
function RichText({
|
|
@@ -2115,22 +2256,22 @@ function RichText({
|
|
|
2115
2256
|
}) {
|
|
2116
2257
|
if (blocks.length === 0) return null;
|
|
2117
2258
|
const draw = { renderText, renderReference, renderBlock };
|
|
2118
|
-
return /* @__PURE__ */
|
|
2259
|
+
return /* @__PURE__ */ jsx29("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx29(Block, { block, draw }, block.id ?? i)) });
|
|
2119
2260
|
}
|
|
2120
2261
|
|
|
2121
2262
|
// src/IdentityMenu.tsx
|
|
2122
|
-
import { useCallback, useRef as
|
|
2263
|
+
import { useCallback as useCallback2, useRef as useRef6 } from "react";
|
|
2123
2264
|
|
|
2124
2265
|
// src/Person.tsx
|
|
2125
|
-
import { jsx as
|
|
2266
|
+
import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2126
2267
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
2127
2268
|
return (
|
|
2128
2269
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
2129
2270
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
2130
2271
|
// row agree by construction.
|
|
2131
|
-
/* @__PURE__ */
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2272
|
+
/* @__PURE__ */ jsxs22("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
2273
|
+
/* @__PURE__ */ jsx30(Avatar, { name, src: picture, size }),
|
|
2274
|
+
/* @__PURE__ */ jsx30("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
2134
2275
|
] })
|
|
2135
2276
|
);
|
|
2136
2277
|
}
|
|
@@ -2138,10 +2279,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
2138
2279
|
// src/PersonTrigger.tsx
|
|
2139
2280
|
import { Button as BaseButton5 } from "@base-ui/react/button";
|
|
2140
2281
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
2141
|
-
import { jsx as
|
|
2282
|
+
import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2142
2283
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
2143
2284
|
if (compact) {
|
|
2144
|
-
return /* @__PURE__ */
|
|
2285
|
+
return /* @__PURE__ */ jsx31(
|
|
2145
2286
|
BaseButton5,
|
|
2146
2287
|
{
|
|
2147
2288
|
type: "button",
|
|
@@ -2150,13 +2291,13 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2150
2291
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
2151
2292
|
className: cn("cursor-pointer rounded-full", className),
|
|
2152
2293
|
...props,
|
|
2153
|
-
children: /* @__PURE__ */
|
|
2294
|
+
children: /* @__PURE__ */ jsx31(Avatar, { name, src: picture, size: size ?? 36 })
|
|
2154
2295
|
}
|
|
2155
2296
|
);
|
|
2156
2297
|
}
|
|
2157
2298
|
return (
|
|
2158
2299
|
// @estiva-escape(no-copied-look): N5 (Katerina, 24 September: record only): a row that fills on hover, as NavItem also does
|
|
2159
|
-
/* @__PURE__ */
|
|
2300
|
+
/* @__PURE__ */ jsxs23(
|
|
2160
2301
|
BaseButton5,
|
|
2161
2302
|
{
|
|
2162
2303
|
type: "button",
|
|
@@ -2174,8 +2315,8 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2174
2315
|
),
|
|
2175
2316
|
...props,
|
|
2176
2317
|
children: [
|
|
2177
|
-
/* @__PURE__ */
|
|
2178
|
-
/* @__PURE__ */
|
|
2318
|
+
/* @__PURE__ */ jsx31(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
2319
|
+
/* @__PURE__ */ jsx31(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
2179
2320
|
]
|
|
2180
2321
|
}
|
|
2181
2322
|
)
|
|
@@ -2183,10 +2324,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2183
2324
|
}
|
|
2184
2325
|
|
|
2185
2326
|
// src/IdentityMenu.tsx
|
|
2186
|
-
import { Fragment as Fragment8, jsx as
|
|
2327
|
+
import { Fragment as Fragment8, jsx as jsx32, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2187
2328
|
function IdentityPanel({ className, onClose = () => {
|
|
2188
2329
|
}, ...rest }) {
|
|
2189
|
-
return /* @__PURE__ */
|
|
2330
|
+
return /* @__PURE__ */ jsx32(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx32(IdentityRows, { ...rest, onClose }) });
|
|
2190
2331
|
}
|
|
2191
2332
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
2192
2333
|
const act = (action) => () => {
|
|
@@ -2194,53 +2335,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
2194
2335
|
action();
|
|
2195
2336
|
};
|
|
2196
2337
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
2197
|
-
return /* @__PURE__ */
|
|
2198
|
-
/* @__PURE__ */
|
|
2199
|
-
/* @__PURE__ */
|
|
2200
|
-
/* @__PURE__ */
|
|
2201
|
-
me.email && /* @__PURE__ */
|
|
2338
|
+
return /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
2339
|
+
/* @__PURE__ */ jsxs24(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
2340
|
+
/* @__PURE__ */ jsx32(MenuRow, { children: /* @__PURE__ */ jsx32("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx32(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
|
|
2341
|
+
/* @__PURE__ */ jsx32(Note, { children: signedIn ? "Your Estiva ID. The same person you are in every Estiva app." : "A key held by this browser only. Nobody else knows who you are." }),
|
|
2342
|
+
me.email && /* @__PURE__ */ jsxs24(Note, { children: [
|
|
2202
2343
|
me.email,
|
|
2203
2344
|
" \xB7 known to Estiva, never published to the relay"
|
|
2204
2345
|
] })
|
|
2205
2346
|
] }),
|
|
2206
|
-
relayUrl && /* @__PURE__ */
|
|
2207
|
-
/* @__PURE__ */
|
|
2208
|
-
/* @__PURE__ */
|
|
2209
|
-
/* @__PURE__ */
|
|
2210
|
-
/* @__PURE__ */
|
|
2347
|
+
relayUrl && /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
2348
|
+
/* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }),
|
|
2349
|
+
/* @__PURE__ */ jsxs24(MenuSection, { label: "Workspace", children: [
|
|
2350
|
+
/* @__PURE__ */ jsx32(MenuRow, { children: /* @__PURE__ */ jsx32("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
2351
|
+
/* @__PURE__ */ jsx32(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
2211
2352
|
] })
|
|
2212
2353
|
] }),
|
|
2213
|
-
appRows && /* @__PURE__ */
|
|
2214
|
-
/* @__PURE__ */
|
|
2354
|
+
appRows && /* @__PURE__ */ jsxs24(Fragment8, { children: [
|
|
2355
|
+
/* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }),
|
|
2215
2356
|
appRows
|
|
2216
2357
|
] }),
|
|
2217
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
2218
|
-
signedIn && idBase && /* @__PURE__ */
|
|
2358
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx32(Divider, { className: "mx-0 my-2" }) : null,
|
|
2359
|
+
signedIn && idBase && /* @__PURE__ */ jsx32(
|
|
2219
2360
|
MenuItem,
|
|
2220
2361
|
{
|
|
2221
2362
|
label: "Edit your profile in Estiva ID",
|
|
2222
2363
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
2223
2364
|
}
|
|
2224
2365
|
),
|
|
2225
|
-
onCopyKey && /* @__PURE__ */
|
|
2226
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
2366
|
+
onCopyKey && /* @__PURE__ */ jsx32(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
2367
|
+
idBase && onSignOut && /* @__PURE__ */ jsx32(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
2227
2368
|
] });
|
|
2228
2369
|
}
|
|
2229
2370
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
2230
|
-
const actions =
|
|
2231
|
-
const close =
|
|
2371
|
+
const actions = useRef6(null);
|
|
2372
|
+
const close = useCallback2(() => actions.current?.close(), []);
|
|
2232
2373
|
return (
|
|
2233
2374
|
/* The wrapper carries the caller's `className` and nothing else. It used
|
|
2234
2375
|
to be `relative`, because the panel was positioned against it; the panel
|
|
2235
2376
|
hangs from the trigger and portals now, so a positioning context here
|
|
2236
2377
|
would only be a lie about what this box does. */
|
|
2237
|
-
/* @__PURE__ */
|
|
2378
|
+
/* @__PURE__ */ jsx32("div", { className, children: /* @__PURE__ */ jsx32(
|
|
2238
2379
|
Menu,
|
|
2239
2380
|
{
|
|
2240
2381
|
align: "right",
|
|
2241
2382
|
actionsRef: actions,
|
|
2242
2383
|
className: "w-72",
|
|
2243
|
-
trigger: /* @__PURE__ */
|
|
2384
|
+
trigger: /* @__PURE__ */ jsx32(
|
|
2244
2385
|
PersonTrigger,
|
|
2245
2386
|
{
|
|
2246
2387
|
name: me.name,
|
|
@@ -2251,7 +2392,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2251
2392
|
"aria-label": compact ? "Account menu" : void 0
|
|
2252
2393
|
}
|
|
2253
2394
|
),
|
|
2254
|
-
children: /* @__PURE__ */
|
|
2395
|
+
children: /* @__PURE__ */ jsx32(
|
|
2255
2396
|
IdentityRows,
|
|
2256
2397
|
{
|
|
2257
2398
|
me,
|
|
@@ -2269,14 +2410,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2269
2410
|
);
|
|
2270
2411
|
}
|
|
2271
2412
|
function Note({ children }) {
|
|
2272
|
-
return /* @__PURE__ */
|
|
2413
|
+
return /* @__PURE__ */ jsx32("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
2273
2414
|
}
|
|
2274
2415
|
|
|
2275
2416
|
// src/FilePicker.tsx
|
|
2276
2417
|
import { forwardRef } from "react";
|
|
2277
|
-
import { jsx as
|
|
2418
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
2278
2419
|
var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
2279
|
-
return /* @__PURE__ */
|
|
2420
|
+
return /* @__PURE__ */ jsx33(
|
|
2280
2421
|
"input",
|
|
2281
2422
|
{
|
|
2282
2423
|
ref,
|
|
@@ -2297,7 +2438,7 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
|
2297
2438
|
// src/Select.tsx
|
|
2298
2439
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
2299
2440
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
2300
|
-
import { jsx as
|
|
2441
|
+
import { jsx as jsx34, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2301
2442
|
var GAP4 = 4;
|
|
2302
2443
|
var VIEWPORT_PAD4 = 8;
|
|
2303
2444
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
|
|
@@ -2305,7 +2446,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2305
2446
|
const held = Boolean(disabledReason);
|
|
2306
2447
|
const trigger = (
|
|
2307
2448
|
// @estiva-escape(no-copied-look): N1 (Katerina, 24 September: record only): Select's box drops the hover while held, so it cannot take FIELD_SHELL_CLASSES as it is
|
|
2308
|
-
/* @__PURE__ */
|
|
2449
|
+
/* @__PURE__ */ jsxs25(
|
|
2309
2450
|
BaseSelect.Trigger,
|
|
2310
2451
|
{
|
|
2311
2452
|
"aria-label": ariaLabel,
|
|
@@ -2338,21 +2479,21 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2338
2479
|
className
|
|
2339
2480
|
),
|
|
2340
2481
|
children: [
|
|
2341
|
-
/* @__PURE__ */
|
|
2342
|
-
selected?.leading && /* @__PURE__ */
|
|
2343
|
-
/* @__PURE__ */
|
|
2482
|
+
/* @__PURE__ */ jsxs25("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
2483
|
+
selected?.leading && /* @__PURE__ */ jsx34("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
2484
|
+
/* @__PURE__ */ jsx34(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
2344
2485
|
] }),
|
|
2345
|
-
/* @__PURE__ */
|
|
2486
|
+
/* @__PURE__ */ jsx34(
|
|
2346
2487
|
BaseSelect.Icon,
|
|
2347
2488
|
{
|
|
2348
|
-
render: /* @__PURE__ */
|
|
2489
|
+
render: /* @__PURE__ */ jsx34(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2349
2490
|
}
|
|
2350
2491
|
)
|
|
2351
2492
|
]
|
|
2352
2493
|
}
|
|
2353
2494
|
)
|
|
2354
2495
|
);
|
|
2355
|
-
return /* @__PURE__ */
|
|
2496
|
+
return /* @__PURE__ */ jsxs25(
|
|
2356
2497
|
BaseSelect.Root,
|
|
2357
2498
|
{
|
|
2358
2499
|
value,
|
|
@@ -2364,8 +2505,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2364
2505
|
disabled: disabled && !held,
|
|
2365
2506
|
modal: false,
|
|
2366
2507
|
children: [
|
|
2367
|
-
held ? /* @__PURE__ */
|
|
2368
|
-
/* @__PURE__ */
|
|
2508
|
+
held ? /* @__PURE__ */ jsx34(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
|
|
2509
|
+
/* @__PURE__ */ jsx34(BaseSelect.Portal, { children: /* @__PURE__ */ jsx34(
|
|
2369
2510
|
BaseSelect.Positioner,
|
|
2370
2511
|
{
|
|
2371
2512
|
side: "bottom",
|
|
@@ -2374,25 +2515,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2374
2515
|
collisionPadding: VIEWPORT_PAD4,
|
|
2375
2516
|
alignItemWithTrigger: false,
|
|
2376
2517
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2377
|
-
children: /* @__PURE__ */
|
|
2518
|
+
children: /* @__PURE__ */ jsx34(
|
|
2378
2519
|
BaseSelect.Popup,
|
|
2379
2520
|
{
|
|
2380
|
-
render: /* @__PURE__ */
|
|
2521
|
+
render: /* @__PURE__ */ jsx34(MenuPanel, {}),
|
|
2381
2522
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
2382
|
-
children: /* @__PURE__ */
|
|
2523
|
+
children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs25(
|
|
2383
2524
|
BaseSelect.Item,
|
|
2384
2525
|
{
|
|
2385
2526
|
value: option.value,
|
|
2386
2527
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
2387
2528
|
children: [
|
|
2388
|
-
/* @__PURE__ */
|
|
2389
|
-
option.leading && /* @__PURE__ */
|
|
2390
|
-
/* @__PURE__ */
|
|
2529
|
+
/* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2530
|
+
option.leading && /* @__PURE__ */ jsx34("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
2531
|
+
/* @__PURE__ */ jsx34(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
|
|
2391
2532
|
] }),
|
|
2392
|
-
/* @__PURE__ */
|
|
2533
|
+
/* @__PURE__ */ jsx34(
|
|
2393
2534
|
BaseSelect.ItemIndicator,
|
|
2394
2535
|
{
|
|
2395
|
-
render: /* @__PURE__ */
|
|
2536
|
+
render: /* @__PURE__ */ jsx34(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2396
2537
|
}
|
|
2397
2538
|
)
|
|
2398
2539
|
]
|
|
@@ -2411,9 +2552,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2411
2552
|
// src/TextInput.tsx
|
|
2412
2553
|
import { forwardRef as forwardRef2 } from "react";
|
|
2413
2554
|
import { Input } from "@base-ui/react/input";
|
|
2414
|
-
import { jsx as
|
|
2555
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
2415
2556
|
var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
|
|
2416
|
-
return /* @__PURE__ */
|
|
2557
|
+
return /* @__PURE__ */ jsx35(
|
|
2417
2558
|
Input,
|
|
2418
2559
|
{
|
|
2419
2560
|
ref,
|
|
@@ -2439,13 +2580,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
|
|
|
2439
2580
|
// src/Textarea.tsx
|
|
2440
2581
|
import { forwardRef as forwardRef3 } from "react";
|
|
2441
2582
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
2442
|
-
import { jsx as
|
|
2583
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
2443
2584
|
var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
2444
|
-
return /* @__PURE__ */
|
|
2585
|
+
return /* @__PURE__ */ jsx36(
|
|
2445
2586
|
BaseField3.Control,
|
|
2446
2587
|
{
|
|
2447
2588
|
ref,
|
|
2448
|
-
render: /* @__PURE__ */
|
|
2589
|
+
render: /* @__PURE__ */ jsx36("textarea", {}),
|
|
2449
2590
|
className: cn(
|
|
2450
2591
|
// The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
|
|
2451
2592
|
// "aren't there hover states in text input and text area?"). Focus comes after hover in
|
|
@@ -2464,43 +2605,43 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
|
2464
2605
|
});
|
|
2465
2606
|
|
|
2466
2607
|
// src/ConfirmDialog.tsx
|
|
2467
|
-
import { useState as
|
|
2608
|
+
import { useState as useState5 } from "react";
|
|
2468
2609
|
|
|
2469
2610
|
// src/DialogShell.tsx
|
|
2470
|
-
import { useRef as
|
|
2611
|
+
import { useRef as useRef7 } from "react";
|
|
2471
2612
|
import { Dialog as Dialog3 } from "@base-ui/react/dialog";
|
|
2472
2613
|
import { AlertDialog } from "@base-ui/react/alert-dialog";
|
|
2473
2614
|
import { IconX as IconX5 } from "@tabler/icons-react";
|
|
2474
2615
|
|
|
2475
2616
|
// src/ContainerHeader.tsx
|
|
2476
2617
|
import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
|
|
2477
|
-
import { jsx as
|
|
2618
|
+
import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2478
2619
|
function ContainerHeader({ title, chevron = false, actions, className }) {
|
|
2479
2620
|
const text = typeof title === "string";
|
|
2480
|
-
return /* @__PURE__ */
|
|
2481
|
-
/* @__PURE__ */
|
|
2482
|
-
text ? /* @__PURE__ */
|
|
2483
|
-
chevron && /* @__PURE__ */
|
|
2621
|
+
return /* @__PURE__ */ jsxs26("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4 pl-5", className), children: [
|
|
2622
|
+
/* @__PURE__ */ jsx37("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs26("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
|
|
2623
|
+
text ? /* @__PURE__ */ jsx37("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx37("div", { className: "min-w-0 flex-1", children: title }),
|
|
2624
|
+
chevron && /* @__PURE__ */ jsx37(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2484
2625
|
] }) }),
|
|
2485
|
-
actions && /* @__PURE__ */
|
|
2626
|
+
actions && /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx37("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
|
|
2486
2627
|
] });
|
|
2487
2628
|
}
|
|
2488
2629
|
|
|
2489
2630
|
// src/DialogShell.tsx
|
|
2490
|
-
import { jsx as
|
|
2631
|
+
import { jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2491
2632
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
|
|
2492
2633
|
const Parts = alert ? AlertDialog : Dialog3;
|
|
2493
|
-
const popupRef =
|
|
2494
|
-
return /* @__PURE__ */
|
|
2634
|
+
const popupRef = useRef7(null);
|
|
2635
|
+
return /* @__PURE__ */ jsx38(
|
|
2495
2636
|
Parts.Root,
|
|
2496
2637
|
{
|
|
2497
2638
|
open: true,
|
|
2498
2639
|
onOpenChange: (open) => {
|
|
2499
2640
|
if (!open) onClose();
|
|
2500
2641
|
},
|
|
2501
|
-
children: /* @__PURE__ */
|
|
2502
|
-
/* @__PURE__ */
|
|
2503
|
-
/* @__PURE__ */
|
|
2642
|
+
children: /* @__PURE__ */ jsxs27(Parts.Portal, { children: [
|
|
2643
|
+
/* @__PURE__ */ jsx38(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
2644
|
+
/* @__PURE__ */ jsx38("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs27(
|
|
2504
2645
|
Parts.Popup,
|
|
2505
2646
|
{
|
|
2506
2647
|
ref: popupRef,
|
|
@@ -2509,10 +2650,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2509
2650
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
2510
2651
|
style: { width },
|
|
2511
2652
|
children: [
|
|
2512
|
-
/* @__PURE__ */
|
|
2653
|
+
/* @__PURE__ */ jsx38(
|
|
2513
2654
|
ContainerHeader,
|
|
2514
2655
|
{
|
|
2515
|
-
title: headerContent ?? /* @__PURE__ */
|
|
2656
|
+
title: headerContent ?? /* @__PURE__ */ jsx38(Parts.Title, { className: "block truncate text-h4 text-text-primary", render: /* @__PURE__ */ jsx38("span", {}), children: title }),
|
|
2516
2657
|
actions: (
|
|
2517
2658
|
/*
|
|
2518
2659
|
The ✕ IS the `Close` part now, rather than a button that calls
|
|
@@ -2526,10 +2667,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2526
2667
|
so the ✕, Escape and the outside press are one path with one
|
|
2527
2668
|
reason attached, instead of one of the three going around.
|
|
2528
2669
|
*/
|
|
2529
|
-
/* @__PURE__ */
|
|
2670
|
+
/* @__PURE__ */ jsx38(
|
|
2530
2671
|
Parts.Close,
|
|
2531
2672
|
{
|
|
2532
|
-
render: /* @__PURE__ */
|
|
2673
|
+
render: /* @__PURE__ */ jsx38(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx38(IconX5, { size: 16, stroke: 1.5 }) })
|
|
2533
2674
|
}
|
|
2534
2675
|
)
|
|
2535
2676
|
)
|
|
@@ -2537,9 +2678,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2537
2678
|
),
|
|
2538
2679
|
bodyMaxHeight ? (
|
|
2539
2680
|
// The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
|
|
2540
|
-
/* @__PURE__ */
|
|
2541
|
-
) : /* @__PURE__ */
|
|
2542
|
-
footer != null && /* @__PURE__ */
|
|
2681
|
+
/* @__PURE__ */ jsx38("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx38(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
|
|
2682
|
+
) : /* @__PURE__ */ jsx38("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
2683
|
+
footer != null && /* @__PURE__ */ jsx38("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
2543
2684
|
]
|
|
2544
2685
|
}
|
|
2545
2686
|
) })
|
|
@@ -2549,9 +2690,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2549
2690
|
}
|
|
2550
2691
|
|
|
2551
2692
|
// src/ConfirmDialog.tsx
|
|
2552
|
-
import { Fragment as Fragment9, jsx as
|
|
2693
|
+
import { Fragment as Fragment9, jsx as jsx39, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2553
2694
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
2554
|
-
const [busy, setBusy] =
|
|
2695
|
+
const [busy, setBusy] = useState5(false);
|
|
2555
2696
|
const confirm = async () => {
|
|
2556
2697
|
setBusy(true);
|
|
2557
2698
|
try {
|
|
@@ -2561,32 +2702,32 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2561
2702
|
setBusy(false);
|
|
2562
2703
|
}
|
|
2563
2704
|
};
|
|
2564
|
-
return /* @__PURE__ */
|
|
2705
|
+
return /* @__PURE__ */ jsx39(
|
|
2565
2706
|
DialogShell,
|
|
2566
2707
|
{
|
|
2567
2708
|
alert: true,
|
|
2568
2709
|
title,
|
|
2569
2710
|
onClose,
|
|
2570
|
-
footer: /* @__PURE__ */
|
|
2571
|
-
/* @__PURE__ */
|
|
2572
|
-
/* @__PURE__ */
|
|
2711
|
+
footer: /* @__PURE__ */ jsxs28(Fragment9, { children: [
|
|
2712
|
+
/* @__PURE__ */ jsx39(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
2713
|
+
/* @__PURE__ */ jsx39(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
2573
2714
|
] }),
|
|
2574
|
-
children: /* @__PURE__ */
|
|
2715
|
+
children: /* @__PURE__ */ jsx39("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
|
|
2575
2716
|
}
|
|
2576
2717
|
);
|
|
2577
2718
|
}
|
|
2578
2719
|
|
|
2579
2720
|
// src/EditableText.tsx
|
|
2580
|
-
import { useEffect as
|
|
2721
|
+
import { useEffect as useEffect4, useRef as useRef8, useState as useState6 } from "react";
|
|
2581
2722
|
import { Field as BaseField4 } from "@base-ui/react/field";
|
|
2582
2723
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
2583
|
-
import { jsx as
|
|
2724
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2584
2725
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
2585
|
-
const [editing, setEditing] =
|
|
2586
|
-
const [draft, setDraft] =
|
|
2587
|
-
const [busy, setBusy] =
|
|
2588
|
-
const fieldRef =
|
|
2589
|
-
|
|
2726
|
+
const [editing, setEditing] = useState6(false);
|
|
2727
|
+
const [draft, setDraft] = useState6(value);
|
|
2728
|
+
const [busy, setBusy] = useState6(false);
|
|
2729
|
+
const fieldRef = useRef8(null);
|
|
2730
|
+
useEffect4(() => {
|
|
2590
2731
|
if (editing) {
|
|
2591
2732
|
fieldRef.current?.focus();
|
|
2592
2733
|
fieldRef.current?.select();
|
|
@@ -2638,7 +2779,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2638
2779
|
written and never read. Read-only, this is a line of text: whatever
|
|
2639
2780
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
2640
2781
|
*/
|
|
2641
|
-
/* @__PURE__ */
|
|
2782
|
+
/* @__PURE__ */ jsx40(
|
|
2642
2783
|
"div",
|
|
2643
2784
|
{
|
|
2644
2785
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -2648,11 +2789,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2648
2789
|
);
|
|
2649
2790
|
}
|
|
2650
2791
|
if (editing) {
|
|
2651
|
-
return multiline ? /* @__PURE__ */
|
|
2792
|
+
return multiline ? /* @__PURE__ */ jsx40(
|
|
2652
2793
|
BaseField4.Control,
|
|
2653
2794
|
{
|
|
2654
2795
|
ref: fieldRef,
|
|
2655
|
-
render: /* @__PURE__ */
|
|
2796
|
+
render: /* @__PURE__ */ jsx40("textarea", { rows: 4 }),
|
|
2656
2797
|
"aria-label": label,
|
|
2657
2798
|
value: draft,
|
|
2658
2799
|
disabled: busy,
|
|
@@ -2661,7 +2802,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2661
2802
|
onBlur: () => void commit(),
|
|
2662
2803
|
className: fieldClass
|
|
2663
2804
|
}
|
|
2664
|
-
) : /* @__PURE__ */
|
|
2805
|
+
) : /* @__PURE__ */ jsx40(
|
|
2665
2806
|
Input2,
|
|
2666
2807
|
{
|
|
2667
2808
|
ref: fieldRef,
|
|
@@ -2675,7 +2816,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2675
2816
|
}
|
|
2676
2817
|
);
|
|
2677
2818
|
}
|
|
2678
|
-
return /* @__PURE__ */
|
|
2819
|
+
return /* @__PURE__ */ jsx40(
|
|
2679
2820
|
"button",
|
|
2680
2821
|
{
|
|
2681
2822
|
type: "button",
|
|
@@ -2695,7 +2836,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2695
2836
|
// src/ErrorBoundary.tsx
|
|
2696
2837
|
import { Component } from "react";
|
|
2697
2838
|
import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
|
|
2698
|
-
import { jsx as
|
|
2839
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
2699
2840
|
var ErrorBoundary = class extends Component {
|
|
2700
2841
|
state = { hasError: false };
|
|
2701
2842
|
static getDerivedStateFromError() {
|
|
@@ -2706,22 +2847,22 @@ var ErrorBoundary = class extends Component {
|
|
|
2706
2847
|
}
|
|
2707
2848
|
render() {
|
|
2708
2849
|
if (!this.state.hasError) return this.props.children;
|
|
2709
|
-
const message = /* @__PURE__ */
|
|
2850
|
+
const message = /* @__PURE__ */ jsx41(
|
|
2710
2851
|
EmptyState,
|
|
2711
2852
|
{
|
|
2712
|
-
icon: /* @__PURE__ */
|
|
2853
|
+
icon: /* @__PURE__ */ jsx41(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
|
|
2713
2854
|
message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
|
|
2714
2855
|
action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
|
|
2715
2856
|
}
|
|
2716
2857
|
);
|
|
2717
2858
|
if (this.props.frame) return this.props.frame(message);
|
|
2718
|
-
return this.props.fallbackClassName ? /* @__PURE__ */
|
|
2859
|
+
return this.props.fallbackClassName ? /* @__PURE__ */ jsx41("div", { className: this.props.fallbackClassName, children: message }) : message;
|
|
2719
2860
|
}
|
|
2720
2861
|
};
|
|
2721
2862
|
|
|
2722
2863
|
// src/ProgressBar.tsx
|
|
2723
2864
|
import { Progress } from "@base-ui/react/progress";
|
|
2724
|
-
import { jsx as
|
|
2865
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
2725
2866
|
var TRACK_CLASSES = {
|
|
2726
2867
|
default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
|
|
2727
2868
|
// 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
|
|
@@ -2734,18 +2875,18 @@ var INDICATOR_CLASSES = {
|
|
|
2734
2875
|
function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
2735
2876
|
return (
|
|
2736
2877
|
// `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
|
|
2737
|
-
/* @__PURE__ */
|
|
2878
|
+
/* @__PURE__ */ jsx42(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx42(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx42(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
|
|
2738
2879
|
);
|
|
2739
2880
|
}
|
|
2740
2881
|
|
|
2741
2882
|
// src/Breadcrumb.tsx
|
|
2742
|
-
import { Fragment as Fragment10, useCallback as
|
|
2743
|
-
import { jsx as
|
|
2883
|
+
import { Fragment as Fragment10, useCallback as useCallback3, useLayoutEffect as useLayoutEffect4, useRef as useRef9, useState as useState7 } from "react";
|
|
2884
|
+
import { jsx as jsx43, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2744
2885
|
function Breadcrumb({ items, className }) {
|
|
2745
|
-
const navRef =
|
|
2746
|
-
const labelRefs =
|
|
2747
|
-
const [truncated, setTruncated] =
|
|
2748
|
-
const measure =
|
|
2886
|
+
const navRef = useRef9(null);
|
|
2887
|
+
const labelRefs = useRef9([]);
|
|
2888
|
+
const [truncated, setTruncated] = useState7(/* @__PURE__ */ new Set());
|
|
2889
|
+
const measure = useCallback3(() => {
|
|
2749
2890
|
const next = /* @__PURE__ */ new Set();
|
|
2750
2891
|
labelRefs.current.forEach((el, index) => {
|
|
2751
2892
|
if (el && el.scrollWidth > el.clientWidth) next.add(index);
|
|
@@ -2760,7 +2901,7 @@ function Breadcrumb({ items, className }) {
|
|
|
2760
2901
|
observer.observe(nav);
|
|
2761
2902
|
return () => observer.disconnect();
|
|
2762
2903
|
}, [measure, items]);
|
|
2763
|
-
return /* @__PURE__ */
|
|
2904
|
+
return /* @__PURE__ */ jsx43("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-body-2", className), children: items.map((item, index) => {
|
|
2764
2905
|
const last = index === items.length - 1;
|
|
2765
2906
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
2766
2907
|
const text = cn(
|
|
@@ -2781,34 +2922,34 @@ function Breadcrumb({ items, className }) {
|
|
|
2781
2922
|
// on a box around it, which the link takes them from, rather than
|
|
2782
2923
|
// pushed into it (UIG-9); the link is still the one element that
|
|
2783
2924
|
// truncates and is measured.
|
|
2784
|
-
/* @__PURE__ */
|
|
2785
|
-
) : /* @__PURE__ */
|
|
2786
|
-
return /* @__PURE__ */
|
|
2787
|
-
index > 0 && /* @__PURE__ */
|
|
2788
|
-
item.icon && /* @__PURE__ */
|
|
2925
|
+
/* @__PURE__ */ jsx43("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx43(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
|
|
2926
|
+
) : /* @__PURE__ */ jsx43("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
2927
|
+
return /* @__PURE__ */ jsxs29(Fragment10, { children: [
|
|
2928
|
+
index > 0 && /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
2929
|
+
item.icon && /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
2789
2930
|
truncated.has(index) ? (
|
|
2790
2931
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
2791
2932
|
// must keep truncating inside it, or wrapping it would widen the
|
|
2792
2933
|
// trail and the tooltip would never be needed again.
|
|
2793
|
-
/* @__PURE__ */
|
|
2934
|
+
/* @__PURE__ */ jsx43(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
2794
2935
|
) : crumb
|
|
2795
2936
|
] }, `${item.label}-${index}`);
|
|
2796
2937
|
}) });
|
|
2797
2938
|
}
|
|
2798
2939
|
|
|
2799
2940
|
// src/NavItem.tsx
|
|
2800
|
-
import { useId, useState as
|
|
2941
|
+
import { useId, useState as useState8 } from "react";
|
|
2801
2942
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
2802
2943
|
import { IconAlertSquareRounded, IconChevronRight as IconChevronRight2, IconDotsVertical } from "@tabler/icons-react";
|
|
2803
2944
|
|
|
2804
2945
|
// src/UnreadDot.tsx
|
|
2805
|
-
import { jsx as
|
|
2946
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
2806
2947
|
function UnreadDot({ className }) {
|
|
2807
|
-
return /* @__PURE__ */
|
|
2948
|
+
return /* @__PURE__ */ jsx44("div", { className: cn("flex h-6 w-6 shrink-0 items-center justify-center", className), "data-unread": true, children: /* @__PURE__ */ jsx44("div", { className: "h-1.5 w-1.5 rounded-full bg-accent-primary" }) });
|
|
2808
2949
|
}
|
|
2809
2950
|
|
|
2810
2951
|
// src/NavItem.tsx
|
|
2811
|
-
import { jsx as
|
|
2952
|
+
import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2812
2953
|
function NavItem({
|
|
2813
2954
|
label,
|
|
2814
2955
|
href,
|
|
@@ -2828,7 +2969,7 @@ function NavItem({
|
|
|
2828
2969
|
className,
|
|
2829
2970
|
...props
|
|
2830
2971
|
}) {
|
|
2831
|
-
const [openState, setOpenState] =
|
|
2972
|
+
const [openState, setOpenState] = useState8(defaultOpen);
|
|
2832
2973
|
const panelId = useId();
|
|
2833
2974
|
const hasRows = children != null && children !== false;
|
|
2834
2975
|
const open = openProp ?? openState;
|
|
@@ -2837,9 +2978,9 @@ function NavItem({
|
|
|
2837
2978
|
onOpenChange?.(next);
|
|
2838
2979
|
};
|
|
2839
2980
|
const besides = menu != null || hasRows;
|
|
2840
|
-
const mark = unread ? urgent ? /* @__PURE__ */
|
|
2981
|
+
const mark = unread ? urgent ? /* @__PURE__ */ jsx45(UrgentMark, {}) : /* @__PURE__ */ jsx45(UnreadDot, {}) : null;
|
|
2841
2982
|
const stepsAside = menu != null && "transition-opacity group-hover/nav:opacity-0 group-focus-within/nav:opacity-0 group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:opacity-0";
|
|
2842
|
-
const row = /* @__PURE__ */
|
|
2983
|
+
const row = /* @__PURE__ */ jsxs30(
|
|
2843
2984
|
"a",
|
|
2844
2985
|
{
|
|
2845
2986
|
href,
|
|
@@ -2860,7 +3001,7 @@ function NavItem({
|
|
|
2860
3001
|
),
|
|
2861
3002
|
...props,
|
|
2862
3003
|
children: [
|
|
2863
|
-
(icon || hasRows) && /* @__PURE__ */
|
|
3004
|
+
(icon || hasRows) && /* @__PURE__ */ jsx45(
|
|
2864
3005
|
"span",
|
|
2865
3006
|
{
|
|
2866
3007
|
className: cn(
|
|
@@ -2871,10 +3012,10 @@ function NavItem({
|
|
|
2871
3012
|
children: icon
|
|
2872
3013
|
}
|
|
2873
3014
|
),
|
|
2874
|
-
/* @__PURE__ */
|
|
3015
|
+
/* @__PURE__ */ jsx45("span", { className: cn("flex-1 truncate", unread && "font-medium"), children: label }),
|
|
2875
3016
|
hint != null && // Takes room only while it shows, so the label gives way to it.
|
|
2876
|
-
/* @__PURE__ */
|
|
2877
|
-
count ? /* @__PURE__ */
|
|
3017
|
+
/* @__PURE__ */ jsx45("span", { className: "hidden shrink-0 items-center group-hover/nav:flex group-focus-within/nav:flex", children: hint }),
|
|
3018
|
+
count ? /* @__PURE__ */ jsx45(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx45(
|
|
2878
3019
|
"span",
|
|
2879
3020
|
{
|
|
2880
3021
|
className: cn(
|
|
@@ -2885,22 +3026,22 @@ function NavItem({
|
|
|
2885
3026
|
children: count
|
|
2886
3027
|
}
|
|
2887
3028
|
) }) : null,
|
|
2888
|
-
mark ? /* @__PURE__ */
|
|
3029
|
+
mark ? /* @__PURE__ */ jsx45("span", { className: cn("flex shrink-0", stepsAside), children: mark }) : menu != null && !count ? (
|
|
2889
3030
|
// Nothing at the right, but a menu: no room is kept at rest, so the
|
|
2890
3031
|
// label has the row's whole width; while the ⋮ shows, its 24px slot
|
|
2891
3032
|
// is kept, so a long label ends before it instead of running under it.
|
|
2892
|
-
/* @__PURE__ */
|
|
3033
|
+
/* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "hidden w-6 shrink-0 group-hover/nav:block group-focus-within/nav:block group-has-[[data-nav-menu]_[aria-expanded=true]]/nav:block" })
|
|
2893
3034
|
) : null
|
|
2894
3035
|
]
|
|
2895
3036
|
}
|
|
2896
3037
|
);
|
|
2897
3038
|
if (!besides && hint == null) return row;
|
|
2898
3039
|
const name = menuLabel ?? `More options for ${label}`;
|
|
2899
|
-
const line = /* @__PURE__ */
|
|
3040
|
+
const line = /* @__PURE__ */ jsxs30("div", { className: "group/nav relative shrink-0", children: [
|
|
2900
3041
|
row,
|
|
2901
3042
|
hasRows && // `left-1`: the 24px button's 16px arrow then sits where the icon
|
|
2902
3043
|
// sits (the row's px-2), so the icon turns into the arrow in place.
|
|
2903
|
-
/* @__PURE__ */
|
|
3044
|
+
/* @__PURE__ */ jsx45("div", { className: "absolute inset-y-0 left-1 flex items-center opacity-0 transition-opacity focus-within:opacity-100 group-hover/nav:opacity-100", children: /* @__PURE__ */ jsx45(
|
|
2904
3045
|
IconButton,
|
|
2905
3046
|
{
|
|
2906
3047
|
tooltip: open ? "Collapse" : "Expand",
|
|
@@ -2908,62 +3049,62 @@ function NavItem({
|
|
|
2908
3049
|
"aria-expanded": open,
|
|
2909
3050
|
"aria-controls": panelId,
|
|
2910
3051
|
onClick: () => setOpen(!open),
|
|
2911
|
-
children: /* @__PURE__ */
|
|
3052
|
+
children: /* @__PURE__ */ jsx45(IconChevronRight2, { size: 16, stroke: 1.5, className: cn("transition-transform duration-150", open && "rotate-90") })
|
|
2912
3053
|
}
|
|
2913
3054
|
) }),
|
|
2914
3055
|
menu != null && // On a count, `right-1`: the 24px button's 16px icon then ends 8px
|
|
2915
3056
|
// from the row's edge, where the count ends (px-2), so the ⋮ lands on
|
|
2916
3057
|
// the number. On the mark or the empty slot, `right-2`: the button
|
|
2917
3058
|
// sits in the 24px slot itself.
|
|
2918
|
-
/* @__PURE__ */
|
|
3059
|
+
/* @__PURE__ */ jsx45("div", { "data-nav-menu": true, className: cn("absolute inset-y-0 flex items-center", count && !mark ? "right-1" : "right-2", "opacity-0 transition-opacity focus-within:opacity-100 group-hover/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100"), children: /* @__PURE__ */ jsx45(
|
|
2919
3060
|
Menu,
|
|
2920
3061
|
{
|
|
2921
3062
|
align: "right",
|
|
2922
|
-
trigger: /* @__PURE__ */
|
|
3063
|
+
trigger: /* @__PURE__ */ jsx45(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx45(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
|
|
2923
3064
|
children: menu
|
|
2924
3065
|
}
|
|
2925
3066
|
) })
|
|
2926
3067
|
] });
|
|
2927
3068
|
if (!hasRows) return line;
|
|
2928
|
-
return /* @__PURE__ */
|
|
3069
|
+
return /* @__PURE__ */ jsxs30(Collapsible.Root, { open, onOpenChange: setOpen, className: "flex shrink-0 flex-col", children: [
|
|
2929
3070
|
line,
|
|
2930
|
-
/* @__PURE__ */
|
|
3071
|
+
/* @__PURE__ */ jsx45(
|
|
2931
3072
|
Collapsible.Panel,
|
|
2932
3073
|
{
|
|
2933
3074
|
id: panelId,
|
|
2934
3075
|
hiddenUntilFound: true,
|
|
2935
3076
|
className: COLLAPSIBLE_PANEL_CLASSES,
|
|
2936
|
-
children: /* @__PURE__ */
|
|
3077
|
+
children: /* @__PURE__ */ jsx45("div", { className: "flex flex-col gap-px pl-6", children })
|
|
2937
3078
|
}
|
|
2938
3079
|
)
|
|
2939
3080
|
] });
|
|
2940
3081
|
}
|
|
2941
3082
|
function UrgentMark() {
|
|
2942
|
-
return /* @__PURE__ */
|
|
3083
|
+
return /* @__PURE__ */ jsx45("div", { className: "flex h-6 w-6 shrink-0 items-center justify-center", "data-urgent": true, children: /* @__PURE__ */ jsx45("div", { className: "flex items-center rounded-full bg-warning-muted p-0.5 signal:shadow-glow-warning", children: /* @__PURE__ */ jsx45(IconAlertSquareRounded, { size: 12, stroke: 2.5, className: "text-warning-default" }) }) });
|
|
2943
3084
|
}
|
|
2944
3085
|
|
|
2945
3086
|
// src/NavTree.tsx
|
|
2946
|
-
import { useEffect as
|
|
3087
|
+
import { useEffect as useEffect5, useRef as useRef10 } from "react";
|
|
2947
3088
|
|
|
2948
3089
|
// src/CollapsibleSection.tsx
|
|
2949
|
-
import { useState as
|
|
3090
|
+
import { useState as useState9 } from "react";
|
|
2950
3091
|
import { Collapsible as Collapsible2 } from "@base-ui/react/collapsible";
|
|
2951
3092
|
|
|
2952
3093
|
// src/SectionHeader.tsx
|
|
2953
3094
|
import { IconChevronRight as IconChevronRight3 } from "@tabler/icons-react";
|
|
2954
3095
|
import { useRender } from "@base-ui/react/use-render";
|
|
2955
|
-
import { Fragment as Fragment11, jsx as
|
|
3096
|
+
import { Fragment as Fragment11, jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2956
3097
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", look = "heading", render, className }) {
|
|
2957
3098
|
const row = look === "row";
|
|
2958
3099
|
const titleElement = useRender({
|
|
2959
|
-
render: render ?? (chevron ? /* @__PURE__ */
|
|
3100
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
|
|
2960
3101
|
props: {
|
|
2961
3102
|
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
2962
3103
|
// whole row up to the actions is the hit target, as it was when the
|
|
2963
3104
|
// row itself carried the click.
|
|
2964
3105
|
className: cn("flex h-full min-w-0 flex-1 items-center text-left", row ? "gap-2" : "gap-1"),
|
|
2965
|
-
children: /* @__PURE__ */
|
|
2966
|
-
chevron && /* @__PURE__ */
|
|
3106
|
+
children: /* @__PURE__ */ jsxs31(Fragment11, { children: [
|
|
3107
|
+
chevron && /* @__PURE__ */ jsx46(
|
|
2967
3108
|
IconChevronRight3,
|
|
2968
3109
|
{
|
|
2969
3110
|
size: row ? 16 : 12,
|
|
@@ -2971,14 +3112,14 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2971
3112
|
className: cn("shrink-0 transition-transform duration-150", !row && "text-text-secondary", isExpanded && "rotate-90")
|
|
2972
3113
|
}
|
|
2973
3114
|
),
|
|
2974
|
-
look === "quiet" ? /* @__PURE__ */
|
|
3115
|
+
look === "quiet" ? /* @__PURE__ */ jsx46("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
|
|
2975
3116
|
// A row's words: NavItem's size and colour, brightening under the pointer with the row.
|
|
2976
|
-
/* @__PURE__ */
|
|
2977
|
-
) : /* @__PURE__ */
|
|
3117
|
+
/* @__PURE__ */ jsx46("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
|
|
3118
|
+
) : /* @__PURE__ */ jsx46(SectionLabel, { folds: chevron, children: title })
|
|
2978
3119
|
] })
|
|
2979
3120
|
}
|
|
2980
3121
|
});
|
|
2981
|
-
return /* @__PURE__ */
|
|
3122
|
+
return /* @__PURE__ */ jsxs31(
|
|
2982
3123
|
"div",
|
|
2983
3124
|
{
|
|
2984
3125
|
className: cn(
|
|
@@ -2995,15 +3136,15 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2995
3136
|
),
|
|
2996
3137
|
children: [
|
|
2997
3138
|
titleElement,
|
|
2998
|
-
trailing != null && /* @__PURE__ */
|
|
2999
|
-
actions && actions.length > 0 && /* @__PURE__ */
|
|
3139
|
+
trailing != null && /* @__PURE__ */ jsx46("div", { className: "flex shrink-0 items-center", children: trailing }),
|
|
3140
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx46(
|
|
3000
3141
|
"div",
|
|
3001
3142
|
{
|
|
3002
3143
|
className: cn(
|
|
3003
3144
|
"-mr-1 flex shrink-0 items-center gap-1",
|
|
3004
3145
|
showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
3005
3146
|
),
|
|
3006
|
-
children: actions.map((action) => /* @__PURE__ */
|
|
3147
|
+
children: actions.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
|
|
3007
3148
|
}
|
|
3008
3149
|
)
|
|
3009
3150
|
]
|
|
@@ -3012,7 +3153,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
3012
3153
|
}
|
|
3013
3154
|
|
|
3014
3155
|
// src/CollapsibleSection.tsx
|
|
3015
|
-
import { jsx as
|
|
3156
|
+
import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
3016
3157
|
var OPEN = "open";
|
|
3017
3158
|
var CLOSED = "closed";
|
|
3018
3159
|
function readStored(key) {
|
|
@@ -3032,38 +3173,38 @@ function writeStored(key, open) {
|
|
|
3032
3173
|
}
|
|
3033
3174
|
}
|
|
3034
3175
|
function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, look = "heading", indent = false, children, className, contentClassName }) {
|
|
3035
|
-
const [openState, setOpenState] =
|
|
3176
|
+
const [openState, setOpenState] = useState9(() => readStored(storageKey) ?? defaultOpen);
|
|
3036
3177
|
const open = openProp ?? openState;
|
|
3037
3178
|
const setOpen = (next) => {
|
|
3038
3179
|
setOpenState(next);
|
|
3039
3180
|
writeStored(storageKey, next);
|
|
3040
3181
|
onOpenChange?.(next);
|
|
3041
3182
|
};
|
|
3042
|
-
return /* @__PURE__ */
|
|
3043
|
-
/* @__PURE__ */
|
|
3044
|
-
/* @__PURE__ */
|
|
3183
|
+
return /* @__PURE__ */ jsxs32(Collapsible2.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
3184
|
+
/* @__PURE__ */ jsx47(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx47(Collapsible2.Trigger, {}) }),
|
|
3185
|
+
/* @__PURE__ */ jsx47(
|
|
3045
3186
|
Collapsible2.Panel,
|
|
3046
3187
|
{
|
|
3047
3188
|
hiddenUntilFound: true,
|
|
3048
3189
|
className: COLLAPSIBLE_PANEL_CLASSES,
|
|
3049
|
-
children: /* @__PURE__ */
|
|
3190
|
+
children: /* @__PURE__ */ jsx47("div", { className: cn("flex flex-col", look === "row" ? "pl-6" : indent && "pl-4", contentClassName), children })
|
|
3050
3191
|
}
|
|
3051
3192
|
)
|
|
3052
3193
|
] });
|
|
3053
3194
|
}
|
|
3054
3195
|
|
|
3055
3196
|
// src/NavTree.tsx
|
|
3056
|
-
import { Fragment as Fragment12, jsx as
|
|
3197
|
+
import { Fragment as Fragment12, jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
3057
3198
|
var NAV_TREE_INTENT_MS = 150;
|
|
3058
3199
|
function holds(nodes, id) {
|
|
3059
3200
|
return !!nodes && id !== void 0 && nodes.some((node) => node.id === id || holds(node.children ?? null, id));
|
|
3060
3201
|
}
|
|
3061
3202
|
function Line({ message }) {
|
|
3062
|
-
return /* @__PURE__ */
|
|
3203
|
+
return /* @__PURE__ */ jsx48("div", { className: "px-2 py-1", children: /* @__PURE__ */ jsx48(EmptyState, { scope: "section", message }) });
|
|
3063
3204
|
}
|
|
3064
3205
|
function Row({ node, selected, onSelect }) {
|
|
3065
|
-
const under = node.childrenMessage !== void 0 ? /* @__PURE__ */
|
|
3066
|
-
return /* @__PURE__ */
|
|
3206
|
+
const under = node.childrenMessage !== void 0 ? /* @__PURE__ */ jsx48(Line, { message: node.childrenMessage }) : node.children?.length ? node.children.map((child) => /* @__PURE__ */ jsx48(Row, { node: child, selected, onSelect }, child.id)) : node.children === null || node.hasChildren && node.children === void 0 ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 2 }) : void 0;
|
|
3207
|
+
return /* @__PURE__ */ jsx48(
|
|
3067
3208
|
NavItem,
|
|
3068
3209
|
{
|
|
3069
3210
|
href: node.href,
|
|
@@ -3085,7 +3226,7 @@ function Row({ node, selected, onSelect }) {
|
|
|
3085
3226
|
);
|
|
3086
3227
|
}
|
|
3087
3228
|
function Group({ group, selected, onSelect, storageKey }) {
|
|
3088
|
-
return /* @__PURE__ */
|
|
3229
|
+
return /* @__PURE__ */ jsx48(
|
|
3089
3230
|
NavTreeSection,
|
|
3090
3231
|
{
|
|
3091
3232
|
id: group.id,
|
|
@@ -3099,15 +3240,15 @@ function Group({ group, selected, onSelect, storageKey }) {
|
|
|
3099
3240
|
onOpenChange: group.onOpenChange,
|
|
3100
3241
|
storageKey: storageKey ? `${storageKey}.${group.id}` : void 0,
|
|
3101
3242
|
onIntent: group.onIntent,
|
|
3102
|
-
children: group.nodes?.map((node) => /* @__PURE__ */
|
|
3243
|
+
children: group.nodes?.map((node) => /* @__PURE__ */ jsx48(Row, { node, selected, onSelect }, node.id))
|
|
3103
3244
|
}
|
|
3104
3245
|
);
|
|
3105
3246
|
}
|
|
3106
3247
|
function NavTreeSection({ id, title, message, loading = false, trailing, actions, defaultOpen = true, open, onOpenChange, storageKey, onIntent, children }) {
|
|
3107
|
-
const timer =
|
|
3108
|
-
|
|
3248
|
+
const timer = useRef10(void 0);
|
|
3249
|
+
useEffect5(() => () => clearTimeout(timer.current), []);
|
|
3109
3250
|
const intent = onIntent;
|
|
3110
|
-
return /* @__PURE__ */
|
|
3251
|
+
return /* @__PURE__ */ jsx48(
|
|
3111
3252
|
"div",
|
|
3112
3253
|
{
|
|
3113
3254
|
className: "shrink-0",
|
|
@@ -3118,7 +3259,7 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
|
|
|
3118
3259
|
} : void 0,
|
|
3119
3260
|
onPointerLeave: intent ? () => clearTimeout(timer.current) : void 0,
|
|
3120
3261
|
onFocus: intent,
|
|
3121
|
-
children: /* @__PURE__ */
|
|
3262
|
+
children: /* @__PURE__ */ jsx48(
|
|
3122
3263
|
CollapsibleSection,
|
|
3123
3264
|
{
|
|
3124
3265
|
title,
|
|
@@ -3131,26 +3272,26 @@ function NavTreeSection({ id, title, message, loading = false, trailing, actions
|
|
|
3131
3272
|
actions,
|
|
3132
3273
|
className: "mt-2 shrink-0",
|
|
3133
3274
|
contentClassName: "gap-px",
|
|
3134
|
-
children: message !== void 0 ? /* @__PURE__ */
|
|
3275
|
+
children: message !== void 0 ? /* @__PURE__ */ jsx48(Line, { message }) : loading ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 3 }) : children
|
|
3135
3276
|
}
|
|
3136
3277
|
)
|
|
3137
3278
|
}
|
|
3138
3279
|
);
|
|
3139
3280
|
}
|
|
3140
3281
|
function NavTree({ title, titleActions, groups, children, selected, onSelect, emptyMessage = "", storageKey }) {
|
|
3141
|
-
return /* @__PURE__ */
|
|
3142
|
-
title && /* @__PURE__ */
|
|
3143
|
-
groups === void 0 ? children : groups === null ? /* @__PURE__ */
|
|
3282
|
+
return /* @__PURE__ */ jsxs33(Fragment12, { children: [
|
|
3283
|
+
title && /* @__PURE__ */ jsx48(SectionHeader, { title, look: "quiet", showActions: "always", actions: titleActions, className: "mt-4 shrink-0" }),
|
|
3284
|
+
groups === void 0 ? children : groups === null ? /* @__PURE__ */ jsx48(SkeletonList, { rows: 5 }) : groups.length === 0 ? (
|
|
3144
3285
|
// No words, no line: an app that says nothing when it has no groups.
|
|
3145
|
-
emptyMessage ? /* @__PURE__ */
|
|
3146
|
-
) : groups.map((group) => /* @__PURE__ */
|
|
3286
|
+
emptyMessage ? /* @__PURE__ */ jsx48(Line, { message: emptyMessage }) : null
|
|
3287
|
+
) : groups.map((group) => /* @__PURE__ */ jsx48(Group, { group, selected, onSelect, storageKey }, group.id))
|
|
3147
3288
|
] });
|
|
3148
3289
|
}
|
|
3149
3290
|
|
|
3150
3291
|
// src/Popover.tsx
|
|
3151
3292
|
import { useMemo as useMemo3 } from "react";
|
|
3152
3293
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
3153
|
-
import { jsx as
|
|
3294
|
+
import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3154
3295
|
var GAP5 = 4;
|
|
3155
3296
|
var VIEWPORT_PAD5 = 8;
|
|
3156
3297
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -3159,7 +3300,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3159
3300
|
if (anchor instanceof Element) return anchor;
|
|
3160
3301
|
return { getBoundingClientRect: () => anchor };
|
|
3161
3302
|
}, [anchor]);
|
|
3162
|
-
return /* @__PURE__ */
|
|
3303
|
+
return /* @__PURE__ */ jsxs34(
|
|
3163
3304
|
BasePopover.Root,
|
|
3164
3305
|
{
|
|
3165
3306
|
open,
|
|
@@ -3167,8 +3308,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3167
3308
|
actionsRef,
|
|
3168
3309
|
modal: false,
|
|
3169
3310
|
children: [
|
|
3170
|
-
trigger && /* @__PURE__ */
|
|
3171
|
-
/* @__PURE__ */
|
|
3311
|
+
trigger && /* @__PURE__ */ jsx49(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
3312
|
+
/* @__PURE__ */ jsx49(BasePopover.Portal, { children: /* @__PURE__ */ jsx49(
|
|
3172
3313
|
BasePopover.Positioner,
|
|
3173
3314
|
{
|
|
3174
3315
|
anchor: anchorTarget,
|
|
@@ -3177,20 +3318,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3177
3318
|
sideOffset: GAP5,
|
|
3178
3319
|
collisionPadding: VIEWPORT_PAD5,
|
|
3179
3320
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
3180
|
-
children: /* @__PURE__ */
|
|
3321
|
+
children: /* @__PURE__ */ jsx49(
|
|
3181
3322
|
BasePopover.Popup,
|
|
3182
3323
|
{
|
|
3183
3324
|
"aria-label": ariaLabel,
|
|
3184
3325
|
initialFocus: trigger ? void 0 : false,
|
|
3185
3326
|
finalFocus,
|
|
3186
3327
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
3187
|
-
render: /* @__PURE__ */
|
|
3188
|
-
children: /* @__PURE__ */
|
|
3328
|
+
render: /* @__PURE__ */ jsx49(MenuPanel, {}),
|
|
3329
|
+
children: /* @__PURE__ */ jsx49(
|
|
3189
3330
|
ScrollArea,
|
|
3190
3331
|
{
|
|
3191
3332
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
3192
3333
|
contentClassName: cn("flex flex-col p-2", contentClassName),
|
|
3193
|
-
children: /* @__PURE__ */
|
|
3334
|
+
children: /* @__PURE__ */ jsx49(DividerInPanel.Provider, { value: true, children })
|
|
3194
3335
|
}
|
|
3195
3336
|
)
|
|
3196
3337
|
}
|
|
@@ -3203,18 +3344,18 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
3203
3344
|
}
|
|
3204
3345
|
|
|
3205
3346
|
// src/SuggestionMenu.tsx
|
|
3206
|
-
import { useCallback as
|
|
3207
|
-
import { jsx as
|
|
3347
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useId as useId2, useImperativeHandle, useMemo as useMemo4, useRef as useRef11, useState as useState10 } from "react";
|
|
3348
|
+
import { jsx as jsx50, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3208
3349
|
function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sections, itemKey, row, onSelect, handle }) {
|
|
3209
3350
|
const shown = useMemo4(() => sections.filter((section) => section.items.length > 0), [sections]);
|
|
3210
3351
|
const items = useMemo4(() => shown.flatMap((section) => section.items), [shown]);
|
|
3211
3352
|
const keys = items.map(itemKey).join("\n");
|
|
3212
|
-
const [highlight, setHighlight] =
|
|
3353
|
+
const [highlight, setHighlight] = useState10(0);
|
|
3213
3354
|
const base = useId2();
|
|
3214
3355
|
const listboxId = `${base}-list`;
|
|
3215
|
-
const chosen =
|
|
3216
|
-
|
|
3217
|
-
|
|
3356
|
+
const chosen = useRef11(null);
|
|
3357
|
+
useEffect6(() => void (chosen.current = highlight > 0 ? keys.split("\n")[highlight] ?? null : null), [highlight]);
|
|
3358
|
+
useEffect6(() => {
|
|
3218
3359
|
const at = chosen.current ? keys.split("\n").indexOf(chosen.current) : -1;
|
|
3219
3360
|
setHighlight(at > 0 ? at : 0);
|
|
3220
3361
|
}, [keys]);
|
|
@@ -3239,7 +3380,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3239
3380
|
}
|
|
3240
3381
|
}), [items, highlight, onSelect]);
|
|
3241
3382
|
const open = rect !== null && items.length > 0;
|
|
3242
|
-
|
|
3383
|
+
useEffect6(() => {
|
|
3243
3384
|
if (!editorElement || !open) return;
|
|
3244
3385
|
editorElement.setAttribute("aria-autocomplete", "list");
|
|
3245
3386
|
editorElement.setAttribute("aria-haspopup", "listbox");
|
|
@@ -3248,11 +3389,11 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3248
3389
|
for (const name of ["aria-autocomplete", "aria-haspopup", "aria-controls", "aria-activedescendant"]) editorElement.removeAttribute(name);
|
|
3249
3390
|
};
|
|
3250
3391
|
}, [editorElement, open, listboxId]);
|
|
3251
|
-
|
|
3392
|
+
useEffect6(() => {
|
|
3252
3393
|
if (!editorElement || !open) return;
|
|
3253
3394
|
editorElement.setAttribute("aria-activedescendant", `${base}-${highlight}`);
|
|
3254
3395
|
}, [editorElement, open, base, highlight]);
|
|
3255
|
-
const scrollRef =
|
|
3396
|
+
const scrollRef = useCallback4((el) => {
|
|
3256
3397
|
el?.scrollIntoView({ block: "nearest" });
|
|
3257
3398
|
}, []);
|
|
3258
3399
|
if (items.length === 0) return null;
|
|
@@ -3262,7 +3403,7 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3262
3403
|
const { label, description, leading, shortcut, hint, size } = row(item);
|
|
3263
3404
|
return (
|
|
3264
3405
|
// A row of a list the editor drives from its caret: focus stays in the text, so the row is no Tab stop.
|
|
3265
|
-
/* @__PURE__ */
|
|
3406
|
+
/* @__PURE__ */ jsx50(
|
|
3266
3407
|
MenuItem,
|
|
3267
3408
|
{
|
|
3268
3409
|
role: "option",
|
|
@@ -3287,17 +3428,17 @@ function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sect
|
|
|
3287
3428
|
)
|
|
3288
3429
|
);
|
|
3289
3430
|
};
|
|
3290
|
-
return /* @__PURE__ */
|
|
3291
|
-
i > 0 && /* @__PURE__ */
|
|
3292
|
-
section.label ? /* @__PURE__ */
|
|
3431
|
+
return /* @__PURE__ */ jsx50(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, children: /* @__PURE__ */ jsx50("div", { id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col", children: shown.map((section, i) => /* @__PURE__ */ jsxs35("div", { className: "contents", children: [
|
|
3432
|
+
i > 0 && /* @__PURE__ */ jsx50(MenuSeparator, {}),
|
|
3433
|
+
section.label ? /* @__PURE__ */ jsx50("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx50(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
|
|
3293
3434
|
] }, section.label ?? i)) }) });
|
|
3294
3435
|
}
|
|
3295
3436
|
|
|
3296
3437
|
// src/Toolbar.tsx
|
|
3297
3438
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
3298
|
-
import { jsx as
|
|
3439
|
+
import { jsx as jsx51 } from "react/jsx-runtime";
|
|
3299
3440
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
3300
|
-
const strip = /* @__PURE__ */
|
|
3441
|
+
const strip = /* @__PURE__ */ jsx51(
|
|
3301
3442
|
BaseToolbar.Root,
|
|
3302
3443
|
{
|
|
3303
3444
|
"aria-label": ariaLabel,
|
|
@@ -3308,27 +3449,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
3308
3449
|
}
|
|
3309
3450
|
);
|
|
3310
3451
|
if (!surface) return strip;
|
|
3311
|
-
return /* @__PURE__ */
|
|
3452
|
+
return /* @__PURE__ */ jsx51(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
3312
3453
|
}
|
|
3313
3454
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
3314
|
-
return /* @__PURE__ */
|
|
3455
|
+
return /* @__PURE__ */ jsx51(
|
|
3315
3456
|
BaseToolbar.Button,
|
|
3316
3457
|
{
|
|
3317
3458
|
ref,
|
|
3318
3459
|
disabled: disabled || !!disabledReason,
|
|
3319
3460
|
focusableWhenDisabled: true,
|
|
3320
|
-
render: /* @__PURE__ */
|
|
3461
|
+
render: /* @__PURE__ */ jsx51(IconButton, { disabled, disabledReason, ...props })
|
|
3321
3462
|
}
|
|
3322
3463
|
);
|
|
3323
3464
|
}
|
|
3324
3465
|
function ToolbarLink({ ref, href, ...props }) {
|
|
3325
|
-
return /* @__PURE__ */
|
|
3466
|
+
return /* @__PURE__ */ jsx51(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx51(IconButton, { href, ...props }) });
|
|
3326
3467
|
}
|
|
3327
3468
|
function ToolbarInput({ size, ...props }) {
|
|
3328
|
-
return /* @__PURE__ */
|
|
3469
|
+
return /* @__PURE__ */ jsx51(BaseToolbar.Input, { render: /* @__PURE__ */ jsx51(TextInput, { size }), ...props });
|
|
3329
3470
|
}
|
|
3330
3471
|
function ToolbarSeparator({ className }) {
|
|
3331
|
-
return /* @__PURE__ */
|
|
3472
|
+
return /* @__PURE__ */ jsx51(
|
|
3332
3473
|
BaseToolbar.Separator,
|
|
3333
3474
|
{
|
|
3334
3475
|
orientation: "vertical",
|
|
@@ -3338,9 +3479,9 @@ function ToolbarSeparator({ className }) {
|
|
|
3338
3479
|
}
|
|
3339
3480
|
|
|
3340
3481
|
// src/ReactionPicker.tsx
|
|
3341
|
-
import { jsx as
|
|
3482
|
+
import { jsx as jsx52 } from "react/jsx-runtime";
|
|
3342
3483
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
3343
|
-
return /* @__PURE__ */
|
|
3484
|
+
return /* @__PURE__ */ jsx52(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
3344
3485
|
/*
|
|
3345
3486
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
3346
3487
|
would become the toolbar's item and the button inside it would never
|
|
@@ -3350,14 +3491,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
3350
3491
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
3351
3492
|
and both say the meaning rather than the glyph.
|
|
3352
3493
|
*/
|
|
3353
|
-
/* @__PURE__ */
|
|
3494
|
+
/* @__PURE__ */ jsx52(
|
|
3354
3495
|
ToolbarButton,
|
|
3355
3496
|
{
|
|
3356
3497
|
"aria-label": option.label,
|
|
3357
3498
|
tooltip: option.label,
|
|
3358
3499
|
onClick: () => onSelect(option.emoji),
|
|
3359
3500
|
className: "size-7",
|
|
3360
|
-
children: /* @__PURE__ */
|
|
3501
|
+
children: /* @__PURE__ */ jsx52("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
3361
3502
|
},
|
|
3362
3503
|
option.emoji
|
|
3363
3504
|
)
|
|
@@ -3366,23 +3507,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
3366
3507
|
|
|
3367
3508
|
// src/PreviewCard.tsx
|
|
3368
3509
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
3369
|
-
import { jsx as
|
|
3510
|
+
import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3370
3511
|
var GAP6 = 12;
|
|
3371
3512
|
var VIEWPORT_PAD6 = 8;
|
|
3372
3513
|
var OPEN_DELAY2 = 350;
|
|
3373
3514
|
var CLOSE_DELAY = 200;
|
|
3374
3515
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
3375
|
-
return /* @__PURE__ */
|
|
3376
|
-
/* @__PURE__ */
|
|
3516
|
+
return /* @__PURE__ */ jsxs36(BasePreviewCard.Root, { children: [
|
|
3517
|
+
/* @__PURE__ */ jsx53(
|
|
3377
3518
|
BasePreviewCard.Trigger,
|
|
3378
3519
|
{
|
|
3379
3520
|
delay,
|
|
3380
3521
|
closeDelay,
|
|
3381
|
-
render: /* @__PURE__ */
|
|
3522
|
+
render: /* @__PURE__ */ jsx53("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
3382
3523
|
children
|
|
3383
3524
|
}
|
|
3384
3525
|
),
|
|
3385
|
-
/* @__PURE__ */
|
|
3526
|
+
/* @__PURE__ */ jsx53(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx53(
|
|
3386
3527
|
BasePreviewCard.Positioner,
|
|
3387
3528
|
{
|
|
3388
3529
|
side,
|
|
@@ -3390,12 +3531,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
3390
3531
|
sideOffset: GAP6,
|
|
3391
3532
|
collisionPadding: VIEWPORT_PAD6,
|
|
3392
3533
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
3393
|
-
children: /* @__PURE__ */
|
|
3534
|
+
children: /* @__PURE__ */ jsx53(
|
|
3394
3535
|
BasePreviewCard.Popup,
|
|
3395
3536
|
{
|
|
3396
3537
|
className: cn("w-[360px] p-0 outline-none", className),
|
|
3397
|
-
render: /* @__PURE__ */
|
|
3398
|
-
children: /* @__PURE__ */
|
|
3538
|
+
render: /* @__PURE__ */ jsx53(MenuPanel, {}),
|
|
3539
|
+
children: /* @__PURE__ */ jsx53(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
3399
3540
|
}
|
|
3400
3541
|
)
|
|
3401
3542
|
}
|
|
@@ -3404,15 +3545,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
3404
3545
|
}
|
|
3405
3546
|
|
|
3406
3547
|
// src/Rail.tsx
|
|
3407
|
-
import { jsx as
|
|
3548
|
+
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
3408
3549
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
3409
|
-
return /* @__PURE__ */
|
|
3550
|
+
return /* @__PURE__ */ jsx54("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
3410
3551
|
}
|
|
3411
3552
|
|
|
3412
3553
|
// src/RailItem.tsx
|
|
3413
|
-
import { jsx as
|
|
3554
|
+
import { jsx as jsx55, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3414
3555
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
3415
|
-
return /* @__PURE__ */
|
|
3556
|
+
return /* @__PURE__ */ jsxs37(
|
|
3416
3557
|
"a",
|
|
3417
3558
|
{
|
|
3418
3559
|
href,
|
|
@@ -3420,14 +3561,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
3420
3561
|
className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
3421
3562
|
...props,
|
|
3422
3563
|
children: [
|
|
3423
|
-
/* @__PURE__ */
|
|
3564
|
+
/* @__PURE__ */ jsx55(
|
|
3424
3565
|
"div",
|
|
3425
3566
|
{
|
|
3426
3567
|
className: cn(
|
|
3427
3568
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
3428
3569
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
3429
3570
|
),
|
|
3430
|
-
children: /* @__PURE__ */
|
|
3571
|
+
children: /* @__PURE__ */ jsx55(
|
|
3431
3572
|
"span",
|
|
3432
3573
|
{
|
|
3433
3574
|
className: cn(
|
|
@@ -3439,14 +3580,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
3439
3580
|
)
|
|
3440
3581
|
}
|
|
3441
3582
|
),
|
|
3442
|
-
/* @__PURE__ */
|
|
3583
|
+
/* @__PURE__ */ jsx55("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
3443
3584
|
]
|
|
3444
3585
|
}
|
|
3445
3586
|
);
|
|
3446
3587
|
}
|
|
3447
3588
|
|
|
3448
3589
|
// src/Property.tsx
|
|
3449
|
-
import { jsx as
|
|
3590
|
+
import { jsx as jsx56, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3450
3591
|
var VALUE_CLASSES = "contents";
|
|
3451
3592
|
function Property({ label, layout = "row", children, className }) {
|
|
3452
3593
|
if (layout === "stacked") {
|
|
@@ -3454,25 +3595,25 @@ function Property({ label, layout = "row", children, className }) {
|
|
|
3454
3595
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
3455
3596
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
3456
3597
|
// 6px, and unifying means the bigger, calmer one.
|
|
3457
|
-
/* @__PURE__ */
|
|
3458
|
-
/* @__PURE__ */
|
|
3459
|
-
/* @__PURE__ */
|
|
3598
|
+
/* @__PURE__ */ jsxs38("dl", { className: cn("flex flex-col gap-3", className), children: [
|
|
3599
|
+
/* @__PURE__ */ jsx56("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
|
|
3600
|
+
/* @__PURE__ */ jsx56("dd", { className: VALUE_CLASSES, children })
|
|
3460
3601
|
] })
|
|
3461
3602
|
);
|
|
3462
3603
|
}
|
|
3463
|
-
return /* @__PURE__ */
|
|
3464
|
-
/* @__PURE__ */
|
|
3465
|
-
/* @__PURE__ */
|
|
3604
|
+
return /* @__PURE__ */ jsxs38("dl", { className: cn("flex items-center gap-2", className), children: [
|
|
3605
|
+
/* @__PURE__ */ jsx56("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
3606
|
+
/* @__PURE__ */ jsx56("dd", { className: VALUE_CLASSES, children })
|
|
3466
3607
|
] });
|
|
3467
3608
|
}
|
|
3468
3609
|
|
|
3469
3610
|
// src/Reaction.tsx
|
|
3470
3611
|
import { Toggle } from "@base-ui/react/toggle";
|
|
3471
|
-
import { jsx as
|
|
3612
|
+
import { jsx as jsx57, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3472
3613
|
function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
3473
3614
|
return (
|
|
3474
3615
|
// @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
|
|
3475
|
-
/* @__PURE__ */
|
|
3616
|
+
/* @__PURE__ */ jsxs39(
|
|
3476
3617
|
Toggle,
|
|
3477
3618
|
{
|
|
3478
3619
|
pressed,
|
|
@@ -3494,8 +3635,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
3494
3635
|
),
|
|
3495
3636
|
...props,
|
|
3496
3637
|
children: [
|
|
3497
|
-
/* @__PURE__ */
|
|
3498
|
-
/* @__PURE__ */
|
|
3638
|
+
/* @__PURE__ */ jsx57("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
|
|
3639
|
+
/* @__PURE__ */ jsx57("span", { className: CHIP_TEXT_CLASSES, children: count })
|
|
3499
3640
|
]
|
|
3500
3641
|
}
|
|
3501
3642
|
)
|
|
@@ -3505,9 +3646,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
3505
3646
|
// src/SearchInput.tsx
|
|
3506
3647
|
import "react";
|
|
3507
3648
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
3508
|
-
import { jsx as
|
|
3649
|
+
import { jsx as jsx58, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3509
3650
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
3510
|
-
return /* @__PURE__ */
|
|
3651
|
+
return /* @__PURE__ */ jsxs40(
|
|
3511
3652
|
"div",
|
|
3512
3653
|
{
|
|
3513
3654
|
className: cn(
|
|
@@ -3519,7 +3660,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3519
3660
|
className
|
|
3520
3661
|
),
|
|
3521
3662
|
children: [
|
|
3522
|
-
/* @__PURE__ */
|
|
3663
|
+
/* @__PURE__ */ jsx58(
|
|
3523
3664
|
Input3,
|
|
3524
3665
|
{
|
|
3525
3666
|
className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
|
|
@@ -3527,42 +3668,42 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3527
3668
|
...props
|
|
3528
3669
|
}
|
|
3529
3670
|
),
|
|
3530
|
-
shortcut && /* @__PURE__ */
|
|
3671
|
+
shortcut && /* @__PURE__ */ jsx58(Kbd, { children: shortcut })
|
|
3531
3672
|
]
|
|
3532
3673
|
}
|
|
3533
3674
|
);
|
|
3534
3675
|
}
|
|
3535
3676
|
|
|
3536
3677
|
// src/Panel.tsx
|
|
3537
|
-
import { jsx as
|
|
3678
|
+
import { jsx as jsx59, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3538
3679
|
function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
|
|
3539
|
-
return /* @__PURE__ */
|
|
3540
|
-
/* @__PURE__ */
|
|
3680
|
+
return /* @__PURE__ */ jsxs41("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
|
|
3681
|
+
/* @__PURE__ */ jsx59(ContainerHeader, { title, chevron, actions }),
|
|
3541
3682
|
broken ? (
|
|
3542
3683
|
// The message takes the room the body had and centres itself in it.
|
|
3543
|
-
/* @__PURE__ */
|
|
3544
|
-
) : /* @__PURE__ */
|
|
3545
|
-
!broken && footer && /* @__PURE__ */
|
|
3684
|
+
/* @__PURE__ */ jsx59("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
|
|
3685
|
+
) : /* @__PURE__ */ jsx59(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
|
|
3686
|
+
!broken && footer && /* @__PURE__ */ jsx59("div", { className: "shrink-0", children: footer })
|
|
3546
3687
|
] });
|
|
3547
3688
|
}
|
|
3548
3689
|
function Panel(props) {
|
|
3549
|
-
return /* @__PURE__ */
|
|
3690
|
+
return /* @__PURE__ */ jsx59(
|
|
3550
3691
|
ErrorBoundary,
|
|
3551
3692
|
{
|
|
3552
3693
|
label: "panel",
|
|
3553
3694
|
frame: (message) => (
|
|
3554
3695
|
// Only the name comes back with the message: the actions and the footer may be what threw.
|
|
3555
|
-
/* @__PURE__ */
|
|
3696
|
+
/* @__PURE__ */ jsx59(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
|
|
3556
3697
|
),
|
|
3557
|
-
children: /* @__PURE__ */
|
|
3698
|
+
children: /* @__PURE__ */ jsx59(Frame, { ...props })
|
|
3558
3699
|
}
|
|
3559
3700
|
);
|
|
3560
3701
|
}
|
|
3561
3702
|
|
|
3562
3703
|
// src/ListColumn.tsx
|
|
3563
|
-
import { jsx as
|
|
3704
|
+
import { jsx as jsx60, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3564
3705
|
function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
|
|
3565
|
-
return /* @__PURE__ */
|
|
3706
|
+
return /* @__PURE__ */ jsxs42(
|
|
3566
3707
|
"div",
|
|
3567
3708
|
{
|
|
3568
3709
|
className: cn(
|
|
@@ -3573,35 +3714,35 @@ function Column({ title, chevron = false, actions, above, collapsed = false, chi
|
|
|
3573
3714
|
),
|
|
3574
3715
|
"data-collapsed": collapsed || void 0,
|
|
3575
3716
|
children: [
|
|
3576
|
-
/* @__PURE__ */
|
|
3717
|
+
/* @__PURE__ */ jsx60(ContainerHeader, { title, chevron, actions }),
|
|
3577
3718
|
above,
|
|
3578
3719
|
broken ? (
|
|
3579
3720
|
// The message takes the room the list had and centres itself in it (Katerina, 19 September).
|
|
3580
|
-
/* @__PURE__ */
|
|
3581
|
-
) : /* @__PURE__ */
|
|
3721
|
+
/* @__PURE__ */ jsx60("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
|
|
3722
|
+
) : /* @__PURE__ */ jsx60(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
|
|
3582
3723
|
]
|
|
3583
3724
|
}
|
|
3584
3725
|
);
|
|
3585
3726
|
}
|
|
3586
3727
|
function ListColumn(props) {
|
|
3587
|
-
return /* @__PURE__ */
|
|
3728
|
+
return /* @__PURE__ */ jsx60(
|
|
3588
3729
|
ErrorBoundary,
|
|
3589
3730
|
{
|
|
3590
3731
|
label: "list panel",
|
|
3591
3732
|
frame: (message) => (
|
|
3592
3733
|
// Only the name comes back with the message: the actions and the row above may be what threw.
|
|
3593
|
-
/* @__PURE__ */
|
|
3734
|
+
/* @__PURE__ */ jsx60(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
|
|
3594
3735
|
),
|
|
3595
|
-
children: /* @__PURE__ */
|
|
3736
|
+
children: /* @__PURE__ */ jsx60(Column, { ...props })
|
|
3596
3737
|
}
|
|
3597
3738
|
);
|
|
3598
3739
|
}
|
|
3599
3740
|
|
|
3600
3741
|
// src/Tabs.tsx
|
|
3601
3742
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
3602
|
-
import { jsx as
|
|
3743
|
+
import { jsx as jsx61, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
3603
3744
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
3604
|
-
return /* @__PURE__ */
|
|
3745
|
+
return /* @__PURE__ */ jsx61(
|
|
3605
3746
|
BaseTabs.Root,
|
|
3606
3747
|
{
|
|
3607
3748
|
value: active,
|
|
@@ -3609,14 +3750,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3609
3750
|
if (details.reason === "none") onChange(value);
|
|
3610
3751
|
},
|
|
3611
3752
|
className,
|
|
3612
|
-
children: /* @__PURE__ */
|
|
3753
|
+
children: /* @__PURE__ */ jsx61(
|
|
3613
3754
|
BaseTabs.List,
|
|
3614
3755
|
{
|
|
3615
3756
|
activateOnFocus: true,
|
|
3616
3757
|
"aria-label": aria["aria-label"],
|
|
3617
3758
|
"aria-labelledby": aria["aria-labelledby"],
|
|
3618
3759
|
className: "flex items-center gap-2",
|
|
3619
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
3760
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs43(
|
|
3620
3761
|
BaseTabs.Tab,
|
|
3621
3762
|
{
|
|
3622
3763
|
value: tab.id,
|
|
@@ -3629,9 +3770,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3629
3770
|
),
|
|
3630
3771
|
children: [
|
|
3631
3772
|
tab.icon,
|
|
3632
|
-
/* @__PURE__ */
|
|
3773
|
+
/* @__PURE__ */ jsxs43("span", { className: "flex items-baseline", children: [
|
|
3633
3774
|
tab.label,
|
|
3634
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
3775
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx61("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
3635
3776
|
] })
|
|
3636
3777
|
]
|
|
3637
3778
|
},
|
|
@@ -3647,7 +3788,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3647
3788
|
import { createContext as createContext6, useContext as useContext6, useMemo as useMemo5 } from "react";
|
|
3648
3789
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
3649
3790
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
3650
|
-
import { jsx as
|
|
3791
|
+
import { jsx as jsx62, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
3651
3792
|
var SURFACE_STYLES = {
|
|
3652
3793
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
3653
3794
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
@@ -3683,16 +3824,16 @@ var pillClassName = (type, hasAction, className) => cn(
|
|
|
3683
3824
|
);
|
|
3684
3825
|
function LeadingIcon({ type }) {
|
|
3685
3826
|
const Icon = ICONS[type];
|
|
3686
|
-
return /* @__PURE__ */
|
|
3827
|
+
return /* @__PURE__ */ jsx62(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
3687
3828
|
}
|
|
3688
3829
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
3689
3830
|
const hasAction = !!(actionLabel && onAction);
|
|
3690
|
-
return /* @__PURE__ */
|
|
3691
|
-
/* @__PURE__ */
|
|
3692
|
-
leadingIcon && /* @__PURE__ */
|
|
3693
|
-
/* @__PURE__ */
|
|
3831
|
+
return /* @__PURE__ */ jsxs44("div", { className: pillClassName(type, hasAction, className), children: [
|
|
3832
|
+
/* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3833
|
+
leadingIcon && /* @__PURE__ */ jsx62(LeadingIcon, { type }),
|
|
3834
|
+
/* @__PURE__ */ jsx62("span", { className: LABEL_CLASSES, children: label })
|
|
3694
3835
|
] }),
|
|
3695
|
-
hasAction && /* @__PURE__ */
|
|
3836
|
+
hasAction && /* @__PURE__ */ jsx62(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
3696
3837
|
] });
|
|
3697
3838
|
}
|
|
3698
3839
|
var ToastContext = createContext6(null);
|
|
@@ -3713,9 +3854,9 @@ function ToastProvider({ children }) {
|
|
|
3713
3854
|
}),
|
|
3714
3855
|
[manager]
|
|
3715
3856
|
);
|
|
3716
|
-
return /* @__PURE__ */
|
|
3857
|
+
return /* @__PURE__ */ jsx62(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs44(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
3717
3858
|
children,
|
|
3718
|
-
/* @__PURE__ */
|
|
3859
|
+
/* @__PURE__ */ jsx62(BaseToast.Portal, { children: /* @__PURE__ */ jsx62(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx62(ToastList, {}) }) })
|
|
3719
3860
|
] }) });
|
|
3720
3861
|
}
|
|
3721
3862
|
function ToastList() {
|
|
@@ -3723,25 +3864,25 @@ function ToastList() {
|
|
|
3723
3864
|
return toasts.map((toast) => {
|
|
3724
3865
|
const type = toast.type ?? "neutral";
|
|
3725
3866
|
const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
|
|
3726
|
-
return /* @__PURE__ */
|
|
3867
|
+
return /* @__PURE__ */ jsxs44(
|
|
3727
3868
|
BaseToast.Root,
|
|
3728
3869
|
{
|
|
3729
3870
|
toast,
|
|
3730
3871
|
swipeDirection: ["left", "down"],
|
|
3731
3872
|
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
3732
3873
|
children: [
|
|
3733
|
-
/* @__PURE__ */
|
|
3734
|
-
leadingIcon && /* @__PURE__ */
|
|
3735
|
-
/* @__PURE__ */
|
|
3874
|
+
/* @__PURE__ */ jsxs44("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3875
|
+
leadingIcon && /* @__PURE__ */ jsx62(LeadingIcon, { type }),
|
|
3876
|
+
/* @__PURE__ */ jsx62(BaseToast.Title, { render: /* @__PURE__ */ jsx62("span", {}), className: LABEL_CLASSES })
|
|
3736
3877
|
] }),
|
|
3737
|
-
actionLabel && /* @__PURE__ */
|
|
3878
|
+
actionLabel && /* @__PURE__ */ jsx62(
|
|
3738
3879
|
BaseToast.Action,
|
|
3739
3880
|
{
|
|
3740
3881
|
onClick: () => {
|
|
3741
3882
|
onAction?.();
|
|
3742
3883
|
close(toast.id);
|
|
3743
3884
|
},
|
|
3744
|
-
render: /* @__PURE__ */
|
|
3885
|
+
render: /* @__PURE__ */ jsx62(Button, { variant: "outlined", size: "small", children: actionLabel })
|
|
3745
3886
|
}
|
|
3746
3887
|
)
|
|
3747
3888
|
]
|
|
@@ -3774,6 +3915,7 @@ export {
|
|
|
3774
3915
|
Avatar,
|
|
3775
3916
|
AvatarGroup,
|
|
3776
3917
|
Banner,
|
|
3918
|
+
BlockHandle,
|
|
3777
3919
|
Breadcrumb,
|
|
3778
3920
|
Button,
|
|
3779
3921
|
Card,
|
|
@@ -3858,6 +4000,7 @@ export {
|
|
|
3858
4000
|
TopBar,
|
|
3859
4001
|
UnreadDot,
|
|
3860
4002
|
WithTooltip,
|
|
4003
|
+
blockAtY,
|
|
3861
4004
|
cn,
|
|
3862
4005
|
hueFor,
|
|
3863
4006
|
initialsFor,
|