@estiva-app/ui 0.38.0 → 0.40.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/AppShell.d.ts +5 -2
- package/dist/AppShell.d.ts.map +1 -1
- package/dist/RichText.d.ts +78 -0
- package/dist/RichText.d.ts.map +1 -0
- package/dist/Sidebar.d.ts +7 -1
- package/dist/Sidebar.d.ts.map +1 -1
- package/dist/TopBar.d.ts +5 -2
- package/dist/TopBar.d.ts.map +1 -1
- package/dist/eslint/index.js +1 -0
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-restyled-part.d.ts.map +1 -1
- package/dist/gates/app-checks.d.ts.map +1 -1
- package/dist/gates/index.js +11 -1
- package/dist/gates/index.js.map +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +688 -542
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/registry.json +97 -8
- package/src/AppShell.mdx +11 -3
- package/src/AppShell.stories.tsx +19 -0
- package/src/AppShell.test.tsx +20 -0
- package/src/AppShell.tsx +43 -24
- package/src/RichText.mdx +79 -0
- package/src/RichText.stories.tsx +91 -0
- package/src/RichText.test.tsx +149 -0
- package/src/RichText.tsx +294 -0
- package/src/Sidebar.tsx +10 -2
- package/src/TopBar.mdx +6 -4
- package/src/TopBar.tsx +6 -3
- package/src/eslint/no-restyled-part.ts +1 -0
- package/src/gates/app-checks.ts +7 -0
- package/src/index.ts +1 -0
- package/src/registry/registry.test.ts +5 -5
- package/stories/Choosing.mdx +1 -0
- package/tailwind-preset.js +1 -0
- package/tokens.css +15 -0
package/dist/index.js
CHANGED
|
@@ -35,16 +35,110 @@ function cn(...inputs) {
|
|
|
35
35
|
return twMerge(clsx(inputs));
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
// src/Link.tsx
|
|
39
|
+
import { jsx } from "react/jsx-runtime";
|
|
40
|
+
var VARIANT_CLASSES = {
|
|
41
|
+
text: "text-info-default underline underline-offset-2 hover:opacity-80",
|
|
42
|
+
quiet: "hover:underline",
|
|
43
|
+
underlined: "underline underline-offset-2 hover:text-text-primary",
|
|
44
|
+
plain: ""
|
|
45
|
+
};
|
|
46
|
+
function Link({ href, variant = "text", external = false, truncate = false, className, children, ...props }) {
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
"a",
|
|
49
|
+
{
|
|
50
|
+
href,
|
|
51
|
+
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
52
|
+
className: cn(VARIANT_CLASSES[variant], truncate && "truncate", className),
|
|
53
|
+
...props,
|
|
54
|
+
children
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/Card.tsx
|
|
60
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
61
|
+
var FILL_CLASSES = {
|
|
62
|
+
surface: "bg-bg-surface border-border-default",
|
|
63
|
+
elevated: "bg-bg-elevated border-border-default",
|
|
64
|
+
inset: "bg-bg-inset border-border-subtle",
|
|
65
|
+
none: "border-border-subtle"
|
|
66
|
+
};
|
|
67
|
+
var HAIRLINE_HOVER_CLASSES = {
|
|
68
|
+
surface: "hover:border-border-strong",
|
|
69
|
+
elevated: "hover:border-border-strong",
|
|
70
|
+
inset: "hover:border-border-default",
|
|
71
|
+
none: "hover:border-border-default"
|
|
72
|
+
};
|
|
73
|
+
var HAIRLINE_HELD_CLASSES = {
|
|
74
|
+
surface: "border-border-strong",
|
|
75
|
+
elevated: "border-border-strong",
|
|
76
|
+
inset: "border-border-default",
|
|
77
|
+
none: "border-border-default"
|
|
78
|
+
};
|
|
79
|
+
var ATTENTION_CLASSES = {
|
|
80
|
+
accent: "border-accent-muted hover:border-accent-muted",
|
|
81
|
+
warning: "border-warning-muted hover:border-warning-muted"
|
|
82
|
+
};
|
|
83
|
+
function Card({
|
|
84
|
+
fill = "surface",
|
|
85
|
+
href,
|
|
86
|
+
hover = href ? "hairline" : "none",
|
|
87
|
+
quietUntilHover = false,
|
|
88
|
+
hovered = false,
|
|
89
|
+
selected = false,
|
|
90
|
+
active = false,
|
|
91
|
+
attention,
|
|
92
|
+
unreadable = false,
|
|
93
|
+
clip = false,
|
|
94
|
+
className,
|
|
95
|
+
children,
|
|
96
|
+
...props
|
|
97
|
+
}) {
|
|
98
|
+
const still = selected || active;
|
|
99
|
+
const classes = cn(
|
|
100
|
+
"rounded-lg border",
|
|
101
|
+
// A card that never changes has nothing to ease between, and the apps' still cards carry no transition.
|
|
102
|
+
hover !== "none" && "transition-colors",
|
|
103
|
+
FILL_CLASSES[fill],
|
|
104
|
+
quietUntilHover && "border-transparent",
|
|
105
|
+
!still && hover === "hairline" && HAIRLINE_HOVER_CLASSES[fill],
|
|
106
|
+
!still && hover === "fill" && "hover:bg-bg-hover hover:border-border-default",
|
|
107
|
+
!still && hovered && hover === "hairline" && HAIRLINE_HELD_CLASSES[fill],
|
|
108
|
+
!still && hovered && hover === "fill" && "bg-bg-hover border-border-default",
|
|
109
|
+
// The one you are on can still be clicked (it opens again); the one being changed cannot.
|
|
110
|
+
!active && hover !== "none" && !href && props.onClick && "cursor-pointer",
|
|
111
|
+
selected && "bg-bg-selected border-border-subtle",
|
|
112
|
+
active && "bg-bg-selected border-accent-primary",
|
|
113
|
+
!active && attention && ATTENTION_CLASSES[attention],
|
|
114
|
+
unreadable && "border-dashed",
|
|
115
|
+
clip && "overflow-hidden",
|
|
116
|
+
href && "block",
|
|
117
|
+
className
|
|
118
|
+
);
|
|
119
|
+
if (href !== void 0) {
|
|
120
|
+
const { ref, ...anchorProps } = props;
|
|
121
|
+
return (
|
|
122
|
+
// @estiva-escape(no-copied-look, no-restyled-part): a card that leads somewhere is drawn on Link's anchor (UIG-27 ruling 1), so this frame is Card's own look, not Link restyled
|
|
123
|
+
/* @__PURE__ */ jsx2(Link, { href, variant: "plain", ref, className: classes, ...anchorProps, children })
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
return (
|
|
127
|
+
// @estiva-escape(no-copied-look): N6 (Katerina, 24 September: leave alone): a card that cuts its content to its corners shares four words with the palette's window by coincidence
|
|
128
|
+
/* @__PURE__ */ jsx2("div", { className: classes, ...props, children })
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
38
132
|
// src/ScrollArea.tsx
|
|
39
133
|
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
|
|
40
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
134
|
+
import { jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
41
135
|
var BAR = "z-10 flex touch-none select-none rounded-full opacity-0 transition-opacity delay-300 data-[hovering]:opacity-100 data-[hovering]:delay-0 data-[scrolling]:opacity-100 data-[scrolling]:delay-0";
|
|
42
136
|
var THUMB = "rounded-full bg-border-strong";
|
|
43
137
|
function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, viewportRef, onScroll, children }) {
|
|
44
138
|
const vertical = orientation !== "horizontal";
|
|
45
139
|
const horizontal = orientation !== "vertical";
|
|
46
140
|
return /* @__PURE__ */ jsxs(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
|
|
47
|
-
/* @__PURE__ */
|
|
141
|
+
/* @__PURE__ */ jsx3(
|
|
48
142
|
BaseScrollArea.Viewport,
|
|
49
143
|
{
|
|
50
144
|
ref: viewportRef,
|
|
@@ -53,17 +147,33 @@ function ScrollArea({ orientation = "vertical", className, viewportClassName, co
|
|
|
53
147
|
"h-full w-full outline-none data-[has-overflow-x]:overscroll-x-contain data-[has-overflow-y]:overscroll-y-contain",
|
|
54
148
|
viewportClassName
|
|
55
149
|
),
|
|
56
|
-
children: /* @__PURE__ */
|
|
150
|
+
children: /* @__PURE__ */ jsx3(BaseScrollArea.Content, { className: contentClassName, style: horizontal ? void 0 : { minWidth: 0 }, children })
|
|
57
151
|
}
|
|
58
152
|
),
|
|
59
|
-
vertical && /* @__PURE__ */
|
|
60
|
-
horizontal && /* @__PURE__ */
|
|
61
|
-
vertical && horizontal && /* @__PURE__ */
|
|
153
|
+
vertical && /* @__PURE__ */ jsx3(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5 data-[has-overflow-y]:opacity-100"), children: /* @__PURE__ */ jsx3(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
|
|
154
|
+
horizontal && /* @__PURE__ */ jsx3(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5 data-[has-overflow-x]:opacity-100"), children: /* @__PURE__ */ jsx3(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
|
|
155
|
+
vertical && horizontal && /* @__PURE__ */ jsx3(BaseScrollArea.Corner, {})
|
|
62
156
|
] });
|
|
63
157
|
}
|
|
64
158
|
|
|
159
|
+
// src/Sidebar.tsx
|
|
160
|
+
import { createContext, useContext } from "react";
|
|
161
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
162
|
+
var SidebarOnGround = createContext(false);
|
|
163
|
+
function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
|
|
164
|
+
const onGround = useContext(SidebarOnGround);
|
|
165
|
+
return /* @__PURE__ */ jsx4(
|
|
166
|
+
"nav",
|
|
167
|
+
{
|
|
168
|
+
"aria-label": ariaLabel,
|
|
169
|
+
className: cn("flex w-60 shrink-0 flex-col", !onGround && "border-r border-border-default bg-bg-surface", className),
|
|
170
|
+
children: /* @__PURE__ */ jsx4(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
|
|
171
|
+
}
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
65
175
|
// src/TopBar.tsx
|
|
66
|
-
import { jsx as
|
|
176
|
+
import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
67
177
|
function TopBar({ variant = "solid", menu, logo, search, right, className }) {
|
|
68
178
|
const floating = variant === "floating";
|
|
69
179
|
return /* @__PURE__ */ jsxs2(
|
|
@@ -71,25 +181,26 @@ function TopBar({ variant = "solid", menu, logo, search, right, className }) {
|
|
|
71
181
|
{
|
|
72
182
|
className: cn(
|
|
73
183
|
"flex h-[52px] items-center pl-5 pr-[26px]",
|
|
74
|
-
floating ? "pointer-events-none absolute left-0 right-0 top-0 z-10" : "shrink-0 gap-4 border-b border-border-default bg-bg-surface",
|
|
184
|
+
floating ? "pointer-events-none absolute left-0 right-0 top-0 z-10" : cn("shrink-0 gap-4", variant === "solid" && "border-b border-border-default bg-bg-surface"),
|
|
75
185
|
className
|
|
76
186
|
),
|
|
77
187
|
children: [
|
|
78
188
|
(menu || logo) && /* @__PURE__ */ jsxs2("div", { className: cn("flex shrink-0 items-center gap-2", floating && "pointer-events-auto"), children: [
|
|
79
189
|
menu,
|
|
80
|
-
logo && /* @__PURE__ */
|
|
190
|
+
logo && /* @__PURE__ */ jsx5("div", { className: "flex items-center text-body-2-strong text-text-primary", children: logo })
|
|
81
191
|
] }),
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
-
/* @__PURE__ */
|
|
192
|
+
/* @__PURE__ */ jsx5("div", { className: cn("flex min-w-0 flex-1 items-center justify-center", floating && "pointer-events-auto"), children: search }),
|
|
193
|
+
/* @__PURE__ */ jsx5("div", { className: cn("flex shrink-0 items-center gap-[6px]", floating && "pointer-events-auto"), children: right })
|
|
84
194
|
]
|
|
85
195
|
}
|
|
86
196
|
);
|
|
87
197
|
}
|
|
88
198
|
|
|
89
199
|
// src/AppShell.tsx
|
|
90
|
-
import { jsx as
|
|
200
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
91
201
|
function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav, children }) {
|
|
92
|
-
const bar = /* @__PURE__ */
|
|
202
|
+
const bar = /* @__PURE__ */ jsx6(TopBar, { variant, menu, logo, search, right: identity });
|
|
203
|
+
const inset = variant === "inset";
|
|
93
204
|
if (variant === "floating") {
|
|
94
205
|
return (
|
|
95
206
|
// `signal-canvas`: in the Signal theme, the preset draws the control-room dot
|
|
@@ -108,7 +219,7 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
108
219
|
),
|
|
109
220
|
children: [
|
|
110
221
|
banner,
|
|
111
|
-
/* @__PURE__ */
|
|
222
|
+
/* @__PURE__ */ jsx6("main", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children })
|
|
112
223
|
]
|
|
113
224
|
}
|
|
114
225
|
)
|
|
@@ -116,6 +227,10 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
116
227
|
] })
|
|
117
228
|
);
|
|
118
229
|
}
|
|
230
|
+
const column = /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
231
|
+
banner,
|
|
232
|
+
/* @__PURE__ */ jsx6(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex min-h-full flex-col", children: /* @__PURE__ */ jsx6("main", { className: "flex min-w-0 flex-1 flex-col", children }) })
|
|
233
|
+
] });
|
|
119
234
|
return (
|
|
120
235
|
/* `relative overflow-hidden` is the seal the floating manner already has
|
|
121
236
|
(and the ScrollArea's own root is `relative`, so an absolutely placed
|
|
@@ -129,11 +244,8 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
129
244
|
/* @__PURE__ */ jsxs3("div", { className: "relative flex h-full min-h-0 flex-col overflow-hidden bg-bg-base text-text-primary", children: [
|
|
130
245
|
bar,
|
|
131
246
|
/* @__PURE__ */ jsxs3("div", { className: "flex min-h-0 flex-1", children: [
|
|
132
|
-
nav,
|
|
133
|
-
/* @__PURE__ */
|
|
134
|
-
banner,
|
|
135
|
-
/* @__PURE__ */ jsx3(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex min-h-full flex-col", children: /* @__PURE__ */ jsx3("main", { className: "flex min-w-0 flex-1 flex-col", children }) })
|
|
136
|
-
] })
|
|
247
|
+
/* @__PURE__ */ jsx6(SidebarOnGround.Provider, { value: inset, children: nav }),
|
|
248
|
+
inset ? /* @__PURE__ */ jsx6(Card, { fill: "surface", clip: true, className: "mb-4 mr-4 flex min-h-0 min-w-0 flex-1 flex-col", children: column }) : /* @__PURE__ */ jsx6("div", { className: "flex min-h-0 min-w-0 flex-1 flex-col", children: column })
|
|
137
249
|
] })
|
|
138
250
|
] })
|
|
139
251
|
);
|
|
@@ -160,117 +272,23 @@ import {
|
|
|
160
272
|
IconX as IconX2
|
|
161
273
|
} from "@tabler/icons-react";
|
|
162
274
|
|
|
163
|
-
// src/Link.tsx
|
|
164
|
-
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
165
|
-
var VARIANT_CLASSES = {
|
|
166
|
-
text: "text-info-default underline underline-offset-2 hover:opacity-80",
|
|
167
|
-
quiet: "hover:underline",
|
|
168
|
-
underlined: "underline underline-offset-2 hover:text-text-primary",
|
|
169
|
-
plain: ""
|
|
170
|
-
};
|
|
171
|
-
function Link({ href, variant = "text", external = false, truncate = false, className, children, ...props }) {
|
|
172
|
-
return /* @__PURE__ */ jsx4(
|
|
173
|
-
"a",
|
|
174
|
-
{
|
|
175
|
-
href,
|
|
176
|
-
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
177
|
-
className: cn(VARIANT_CLASSES[variant], truncate && "truncate", className),
|
|
178
|
-
...props,
|
|
179
|
-
children
|
|
180
|
-
}
|
|
181
|
-
);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// src/Card.tsx
|
|
185
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
186
|
-
var FILL_CLASSES = {
|
|
187
|
-
surface: "bg-bg-surface border-border-default",
|
|
188
|
-
elevated: "bg-bg-elevated border-border-default",
|
|
189
|
-
inset: "bg-bg-inset border-border-subtle",
|
|
190
|
-
none: "border-border-subtle"
|
|
191
|
-
};
|
|
192
|
-
var HAIRLINE_HOVER_CLASSES = {
|
|
193
|
-
surface: "hover:border-border-strong",
|
|
194
|
-
elevated: "hover:border-border-strong",
|
|
195
|
-
inset: "hover:border-border-default",
|
|
196
|
-
none: "hover:border-border-default"
|
|
197
|
-
};
|
|
198
|
-
var HAIRLINE_HELD_CLASSES = {
|
|
199
|
-
surface: "border-border-strong",
|
|
200
|
-
elevated: "border-border-strong",
|
|
201
|
-
inset: "border-border-default",
|
|
202
|
-
none: "border-border-default"
|
|
203
|
-
};
|
|
204
|
-
var ATTENTION_CLASSES = {
|
|
205
|
-
accent: "border-accent-muted hover:border-accent-muted",
|
|
206
|
-
warning: "border-warning-muted hover:border-warning-muted"
|
|
207
|
-
};
|
|
208
|
-
function Card({
|
|
209
|
-
fill = "surface",
|
|
210
|
-
href,
|
|
211
|
-
hover = href ? "hairline" : "none",
|
|
212
|
-
quietUntilHover = false,
|
|
213
|
-
hovered = false,
|
|
214
|
-
selected = false,
|
|
215
|
-
active = false,
|
|
216
|
-
attention,
|
|
217
|
-
unreadable = false,
|
|
218
|
-
clip = false,
|
|
219
|
-
className,
|
|
220
|
-
children,
|
|
221
|
-
...props
|
|
222
|
-
}) {
|
|
223
|
-
const still = selected || active;
|
|
224
|
-
const classes = cn(
|
|
225
|
-
"rounded-lg border",
|
|
226
|
-
// A card that never changes has nothing to ease between, and the apps' still cards carry no transition.
|
|
227
|
-
hover !== "none" && "transition-colors",
|
|
228
|
-
FILL_CLASSES[fill],
|
|
229
|
-
quietUntilHover && "border-transparent",
|
|
230
|
-
!still && hover === "hairline" && HAIRLINE_HOVER_CLASSES[fill],
|
|
231
|
-
!still && hover === "fill" && "hover:bg-bg-hover hover:border-border-default",
|
|
232
|
-
!still && hovered && hover === "hairline" && HAIRLINE_HELD_CLASSES[fill],
|
|
233
|
-
!still && hovered && hover === "fill" && "bg-bg-hover border-border-default",
|
|
234
|
-
// The one you are on can still be clicked (it opens again); the one being changed cannot.
|
|
235
|
-
!active && hover !== "none" && !href && props.onClick && "cursor-pointer",
|
|
236
|
-
selected && "bg-bg-selected border-border-subtle",
|
|
237
|
-
active && "bg-bg-selected border-accent-primary",
|
|
238
|
-
!active && attention && ATTENTION_CLASSES[attention],
|
|
239
|
-
unreadable && "border-dashed",
|
|
240
|
-
clip && "overflow-hidden",
|
|
241
|
-
href && "block",
|
|
242
|
-
className
|
|
243
|
-
);
|
|
244
|
-
if (href !== void 0) {
|
|
245
|
-
const { ref, ...anchorProps } = props;
|
|
246
|
-
return (
|
|
247
|
-
// @estiva-escape(no-copied-look, no-restyled-part): a card that leads somewhere is drawn on Link's anchor (UIG-27 ruling 1), so this frame is Card's own look, not Link restyled
|
|
248
|
-
/* @__PURE__ */ jsx5(Link, { href, variant: "plain", ref, className: classes, ...anchorProps, children })
|
|
249
|
-
);
|
|
250
|
-
}
|
|
251
|
-
return (
|
|
252
|
-
// @estiva-escape(no-copied-look): N6 (Katerina, 24 September: leave alone): a card that cuts its content to its corners shares four words with the palette's window by coincidence
|
|
253
|
-
/* @__PURE__ */ jsx5("div", { className: classes, ...props, children })
|
|
254
|
-
);
|
|
255
|
-
}
|
|
256
|
-
|
|
257
275
|
// src/IconButton.tsx
|
|
258
276
|
import { Button as BaseButton } from "@base-ui/react/button";
|
|
259
277
|
|
|
260
278
|
// src/formBusy.ts
|
|
261
|
-
import { createContext, useContext } from "react";
|
|
262
|
-
var FormBusyContext =
|
|
279
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
280
|
+
var FormBusyContext = createContext2(false);
|
|
263
281
|
function useFormBusy() {
|
|
264
|
-
return
|
|
282
|
+
return useContext2(FormBusyContext);
|
|
265
283
|
}
|
|
266
284
|
|
|
267
285
|
// src/Tooltip.tsx
|
|
268
286
|
import { Tooltip as BaseTooltip } from "@base-ui/react/tooltip";
|
|
269
287
|
|
|
270
288
|
// src/Kbd.tsx
|
|
271
|
-
import { jsx as
|
|
289
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
272
290
|
function Kbd({ children, className, tone = "default" }) {
|
|
273
|
-
return /* @__PURE__ */
|
|
291
|
+
return /* @__PURE__ */ jsx7(
|
|
274
292
|
"kbd",
|
|
275
293
|
{
|
|
276
294
|
className: cn(
|
|
@@ -302,21 +320,21 @@ var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:fon
|
|
|
302
320
|
var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
|
|
303
321
|
|
|
304
322
|
// src/Tooltip.tsx
|
|
305
|
-
import { jsx as
|
|
323
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
306
324
|
var OPEN_DELAY = 300;
|
|
307
325
|
function TooltipProvider({ delay = OPEN_DELAY, closeDelay, timeout, children }) {
|
|
308
|
-
return /* @__PURE__ */
|
|
326
|
+
return /* @__PURE__ */ jsx8(BaseTooltip.Provider, { delay, closeDelay, timeout, children });
|
|
309
327
|
}
|
|
310
328
|
function Tooltip({ label, shortcut, className, ...props }) {
|
|
311
329
|
return /* @__PURE__ */ jsxs4("div", { role: "tooltip", className: cn(FLOATING_SURFACE_CLASSES, "border-border-tooltip bg-bg-tooltip", "min-h-[30px] max-w-80 flex items-center justify-center gap-1.5 px-2 py-1", className), ...props, children: [
|
|
312
|
-
/* @__PURE__ */
|
|
313
|
-
shortcut && /* @__PURE__ */
|
|
330
|
+
/* @__PURE__ */ jsx8("span", { className: "min-w-0 text-caption text-text-tooltip break-words", children: label }),
|
|
331
|
+
shortcut && /* @__PURE__ */ jsx8(Kbd, { tone: "tooltip", children: shortcut })
|
|
314
332
|
] });
|
|
315
333
|
}
|
|
316
334
|
var GAP = 6;
|
|
317
335
|
var VIEWPORT_PAD = 8;
|
|
318
336
|
function TooltipSurface({ label, shortcut, placement }) {
|
|
319
|
-
return /* @__PURE__ */
|
|
337
|
+
return /* @__PURE__ */ jsx8(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx8(
|
|
320
338
|
BaseTooltip.Positioner,
|
|
321
339
|
{
|
|
322
340
|
side: placement,
|
|
@@ -325,10 +343,10 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
325
343
|
collisionPadding: VIEWPORT_PAD,
|
|
326
344
|
positionMethod: "fixed",
|
|
327
345
|
className: "pointer-events-none z-[9999]",
|
|
328
|
-
children: /* @__PURE__ */
|
|
346
|
+
children: /* @__PURE__ */ jsx8(
|
|
329
347
|
BaseTooltip.Popup,
|
|
330
348
|
{
|
|
331
|
-
render: /* @__PURE__ */
|
|
349
|
+
render: /* @__PURE__ */ jsx8(Tooltip, { label, shortcut }),
|
|
332
350
|
className: cn(
|
|
333
351
|
"transition-[opacity,transform] duration-[120ms] ease-out motion-reduce:transition-none",
|
|
334
352
|
"data-[ending-style]:duration-[80ms] data-[instant]:duration-0",
|
|
@@ -344,19 +362,19 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
344
362
|
function WithTooltip({ label, shortcut, placement = "top", wrapperClassName, inline = false, children }) {
|
|
345
363
|
const Wrapper = inline ? "span" : "div";
|
|
346
364
|
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
347
|
-
/* @__PURE__ */
|
|
348
|
-
/* @__PURE__ */
|
|
365
|
+
/* @__PURE__ */ jsx8(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: /* @__PURE__ */ jsx8(Wrapper, { className: cn("inline-flex shrink-0", inline && "align-top", wrapperClassName) }), children }),
|
|
366
|
+
/* @__PURE__ */ jsx8(TooltipSurface, { label, shortcut, placement })
|
|
349
367
|
] });
|
|
350
368
|
}
|
|
351
369
|
function TooltipTrigger({ label, shortcut, placement = "top", children }) {
|
|
352
370
|
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
353
|
-
/* @__PURE__ */
|
|
354
|
-
/* @__PURE__ */
|
|
371
|
+
/* @__PURE__ */ jsx8(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: children }),
|
|
372
|
+
/* @__PURE__ */ jsx8(TooltipSurface, { label, shortcut, placement })
|
|
355
373
|
] });
|
|
356
374
|
}
|
|
357
375
|
|
|
358
376
|
// src/IconButton.tsx
|
|
359
|
-
import { jsx as
|
|
377
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
360
378
|
function IconButton({
|
|
361
379
|
variant = "muted",
|
|
362
380
|
pressed,
|
|
@@ -407,7 +425,7 @@ function IconButton({
|
|
|
407
425
|
off && "cursor-not-allowed",
|
|
408
426
|
className
|
|
409
427
|
);
|
|
410
|
-
const button = href && !unusable ? /* @__PURE__ */
|
|
428
|
+
const button = href && !unusable ? /* @__PURE__ */ jsx9("a", { href, className: look(false), ...props, children }) : /* @__PURE__ */ jsx9(
|
|
411
429
|
BaseButton,
|
|
412
430
|
{
|
|
413
431
|
type,
|
|
@@ -421,7 +439,7 @@ function IconButton({
|
|
|
421
439
|
);
|
|
422
440
|
const label = disabledReason ?? tooltip;
|
|
423
441
|
if (label) {
|
|
424
|
-
return /* @__PURE__ */
|
|
442
|
+
return /* @__PURE__ */ jsx9(TooltipTrigger, { label, shortcut: disabledReason ? void 0 : tooltipShortcut, placement: tooltipPlacement, children: button });
|
|
425
443
|
}
|
|
426
444
|
return button;
|
|
427
445
|
}
|
|
@@ -430,10 +448,10 @@ function IconButton({
|
|
|
430
448
|
import { useRef } from "react";
|
|
431
449
|
import { Dialog } from "@base-ui/react/dialog";
|
|
432
450
|
import { IconX } from "@tabler/icons-react";
|
|
433
|
-
import { jsx as
|
|
451
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
434
452
|
function Lightbox({ src, alt, onClose, className }) {
|
|
435
453
|
const popupRef = useRef(null);
|
|
436
|
-
return /* @__PURE__ */
|
|
454
|
+
return /* @__PURE__ */ jsx10(
|
|
437
455
|
Dialog.Root,
|
|
438
456
|
{
|
|
439
457
|
open: true,
|
|
@@ -441,7 +459,7 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
441
459
|
if (!open) onClose();
|
|
442
460
|
},
|
|
443
461
|
children: /* @__PURE__ */ jsxs5(Dialog.Portal, { children: [
|
|
444
|
-
/* @__PURE__ */
|
|
462
|
+
/* @__PURE__ */ jsx10(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim-strong" }),
|
|
445
463
|
/* @__PURE__ */ jsxs5(
|
|
446
464
|
Dialog.Popup,
|
|
447
465
|
{
|
|
@@ -451,7 +469,7 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
451
469
|
className: "fixed inset-0 z-50 flex items-center justify-center p-8 outline-none",
|
|
452
470
|
onClick: onClose,
|
|
453
471
|
children: [
|
|
454
|
-
/* @__PURE__ */
|
|
472
|
+
/* @__PURE__ */ jsx10(
|
|
455
473
|
"img",
|
|
456
474
|
{
|
|
457
475
|
src,
|
|
@@ -460,12 +478,12 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
460
478
|
className: cn("max-w-full max-h-full object-contain rounded-lg", className)
|
|
461
479
|
}
|
|
462
480
|
),
|
|
463
|
-
/* @__PURE__ */
|
|
481
|
+
/* @__PURE__ */ jsx10(
|
|
464
482
|
Dialog.Close,
|
|
465
483
|
{
|
|
466
484
|
"aria-label": "Close",
|
|
467
485
|
className: "absolute top-4 right-4 size-8 rounded-full bg-bg-tooltip border border-border-tooltip-key flex items-center justify-center text-text-tooltip-key hover:text-text-tooltip",
|
|
468
|
-
children: /* @__PURE__ */
|
|
486
|
+
children: /* @__PURE__ */ jsx10(IconX, { size: 16, stroke: 1.5 })
|
|
469
487
|
}
|
|
470
488
|
)
|
|
471
489
|
]
|
|
@@ -477,7 +495,7 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
477
495
|
}
|
|
478
496
|
|
|
479
497
|
// src/AttachmentCard.tsx
|
|
480
|
-
import { Fragment, jsx as
|
|
498
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
481
499
|
var ICON_BY_EXTENSION = {
|
|
482
500
|
pdf: IconFileTypePdf,
|
|
483
501
|
doc: IconFileTypeDocx,
|
|
@@ -511,7 +529,7 @@ var NAME_CLASSES = "text-caption font-medium text-text-primary truncate";
|
|
|
511
529
|
var NOTE_CLASSES = "text-small tracking-wide leading-tight truncate";
|
|
512
530
|
function TypeIcon({ name }) {
|
|
513
531
|
const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
|
|
514
|
-
return /* @__PURE__ */
|
|
532
|
+
return /* @__PURE__ */ jsx11(Icon, { size: 20, stroke: 1.5 });
|
|
515
533
|
}
|
|
516
534
|
function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
517
535
|
const ref = useRef2(null);
|
|
@@ -533,9 +551,9 @@ function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
|
533
551
|
observer.disconnect();
|
|
534
552
|
};
|
|
535
553
|
}, [text, cut]);
|
|
536
|
-
const line = /* @__PURE__ */
|
|
554
|
+
const line = /* @__PURE__ */ jsx11("span", { ref, className, children: text });
|
|
537
555
|
if (!hint && !cut) return line;
|
|
538
|
-
return /* @__PURE__ */
|
|
556
|
+
return /* @__PURE__ */ jsx11(WithTooltip, { label: hint ?? text, placement, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
|
|
539
557
|
}
|
|
540
558
|
function useRemoteImage(url, fetchImage) {
|
|
541
559
|
const [result, setResult] = useState({});
|
|
@@ -614,7 +632,7 @@ function AttachmentCard({
|
|
|
614
632
|
const full = useRemoteImage(opened ? remoteFullSrc : void 0, fetchImage);
|
|
615
633
|
const openable = image && !!picture && !pending;
|
|
616
634
|
const openPicture = onOpen ?? (openable ? () => setOpened(true) : void 0);
|
|
617
|
-
const viewer = opened && picture ? /* @__PURE__ */
|
|
635
|
+
const viewer = opened && picture ? /* @__PURE__ */ jsx11(Lightbox, { src: full.src ?? picture, alt: alt ?? name, onClose: () => setOpened(false) }) : null;
|
|
618
636
|
const saveHere = download ? () => {
|
|
619
637
|
const source = remoteFullSrc ?? remoteSrc;
|
|
620
638
|
if (source && fetchImage) {
|
|
@@ -643,10 +661,10 @@ function AttachmentCard({
|
|
|
643
661
|
className: cn("group relative flex items-center gap-2 w-[200px] p-1.5 pr-3", failed ? "border-error-default" : warning && "border-warning-default", className),
|
|
644
662
|
...props,
|
|
645
663
|
children: [
|
|
646
|
-
/* @__PURE__ */
|
|
664
|
+
/* @__PURE__ */ jsx11("div", { className: cn(TILE_CLASSES, "overflow-hidden"), children: state === "uploading" ? /* @__PURE__ */ jsx11(IconLoader2, { size: 16, stroke: 1.5, className: "animate-spin" }) : failed ? /* @__PURE__ */ jsx11(IconAlertCircle, { size: 16, stroke: 1.5, className: "text-error-default" }) : warning ? /* @__PURE__ */ jsx11(IconAlertTriangle, { size: 16, stroke: 1.5, className: "text-warning-default" }) : image && src ? /* @__PURE__ */ jsx11("img", { src, alt: name, className: "size-full object-cover" }) : /* @__PURE__ */ jsx11("span", { className: "text-menu font-semibold", children: typeLabelOf(name) }) }),
|
|
647
665
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
648
|
-
/* @__PURE__ */
|
|
649
|
-
/* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ jsx11(Truncating, { text: name, className: NAME_CLASSES, placement: onRemove ? "bottom" : void 0 }),
|
|
667
|
+
/* @__PURE__ */ jsx11(
|
|
650
668
|
Truncating,
|
|
651
669
|
{
|
|
652
670
|
text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
|
|
@@ -655,7 +673,7 @@ function AttachmentCard({
|
|
|
655
673
|
}
|
|
656
674
|
)
|
|
657
675
|
] }),
|
|
658
|
-
onRemove && /* @__PURE__ */
|
|
676
|
+
onRemove && /* @__PURE__ */ jsx11(
|
|
659
677
|
BaseButton2,
|
|
660
678
|
{
|
|
661
679
|
type: "button",
|
|
@@ -665,7 +683,7 @@ function AttachmentCard({
|
|
|
665
683
|
event.stopPropagation();
|
|
666
684
|
onRemove();
|
|
667
685
|
},
|
|
668
|
-
children: /* @__PURE__ */
|
|
686
|
+
children: /* @__PURE__ */ jsx11(IconX2, { size: 11, stroke: 1.75 })
|
|
669
687
|
}
|
|
670
688
|
)
|
|
671
689
|
]
|
|
@@ -675,7 +693,7 @@ function AttachmentCard({
|
|
|
675
693
|
}
|
|
676
694
|
const downloadControl = saving ? (
|
|
677
695
|
// @estiva-escape(no-restyled-part): Download shows when its card is pointed at or focused, AttachmentCard's own action; IconButton has no reveal on its card's hover (UIG-9, Katerina 17 September)
|
|
678
|
-
/* @__PURE__ */
|
|
696
|
+
/* @__PURE__ */ jsx11(
|
|
679
697
|
IconButton,
|
|
680
698
|
{
|
|
681
699
|
variant: "muted",
|
|
@@ -686,7 +704,7 @@ function AttachmentCard({
|
|
|
686
704
|
event.stopPropagation();
|
|
687
705
|
saving();
|
|
688
706
|
},
|
|
689
|
-
children: /* @__PURE__ */
|
|
707
|
+
children: /* @__PURE__ */ jsx11(IconDownload, { size: 16, stroke: 1.5 })
|
|
690
708
|
}
|
|
691
709
|
)
|
|
692
710
|
) : null;
|
|
@@ -695,26 +713,26 @@ function AttachmentCard({
|
|
|
695
713
|
// `role="status"`: a plain box may not carry a name (axe, aria-prohibited-attr), and a
|
|
696
714
|
// status says what it is doing — loading — to a reader that cannot see the pulse.
|
|
697
715
|
// @estiva-escape(no-restyled-part): the loading pulse is AttachmentCard's own state; Card has no loading state (UIG-9, Katerina 17 September)
|
|
698
|
-
/* @__PURE__ */
|
|
716
|
+
/* @__PURE__ */ jsx11(Card, { role: "status", fill: "inset", "aria-busy": "true", "aria-label": `Loading ${name}`, className: cn("w-[180px] h-28 animate-pulse", className), ...props, children: null })
|
|
699
717
|
);
|
|
700
718
|
}
|
|
701
719
|
if (drawnState === "unreadable") {
|
|
702
720
|
return (
|
|
703
721
|
// @estiva-escape(no-restyled-part): a file that could not be read is faded as well as dashed, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
|
|
704
722
|
/* @__PURE__ */ jsxs6(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
|
|
705
|
-
/* @__PURE__ */
|
|
723
|
+
/* @__PURE__ */ jsx11("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx11(TypeIcon, { name }) }),
|
|
706
724
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
707
|
-
/* @__PURE__ */
|
|
708
|
-
/* @__PURE__ */
|
|
725
|
+
/* @__PURE__ */ jsx11(Truncating, { text: name, className: NAME_CLASSES }),
|
|
726
|
+
/* @__PURE__ */ jsx11("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? "Could not be loaded" })
|
|
709
727
|
] })
|
|
710
728
|
] })
|
|
711
729
|
);
|
|
712
730
|
}
|
|
713
731
|
if (image && picture) {
|
|
714
|
-
const thumbnail = /* @__PURE__ */
|
|
715
|
-
return /* @__PURE__ */ jsxs6(
|
|
732
|
+
const thumbnail = /* @__PURE__ */ jsx11("img", { src: picture, alt: alt ?? name, className: "w-full h-28 object-cover" });
|
|
733
|
+
return /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
716
734
|
/* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: "hairline", clip: true, className: cn("group relative flex flex-col w-[180px]", className), ...props, children: [
|
|
717
|
-
openPicture ? /* @__PURE__ */
|
|
735
|
+
openPicture ? /* @__PURE__ */ jsx11(
|
|
718
736
|
BaseButton2,
|
|
719
737
|
{
|
|
720
738
|
type: "button",
|
|
@@ -726,26 +744,26 @@ function AttachmentCard({
|
|
|
726
744
|
},
|
|
727
745
|
children: thumbnail
|
|
728
746
|
}
|
|
729
|
-
) : /* @__PURE__ */
|
|
747
|
+
) : /* @__PURE__ */ jsx11("div", { className: "block w-full", children: thumbnail }),
|
|
730
748
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
|
|
731
|
-
/* @__PURE__ */
|
|
749
|
+
/* @__PURE__ */ jsx11(Truncating, { text: name, className: "flex-1 text-caption text-text-primary truncate", wrapperClassName: "flex-1" }),
|
|
732
750
|
downloadControl
|
|
733
751
|
] })
|
|
734
752
|
] }),
|
|
735
753
|
viewer
|
|
736
754
|
] });
|
|
737
755
|
}
|
|
738
|
-
const body = /* @__PURE__ */ jsxs6(
|
|
739
|
-
/* @__PURE__ */
|
|
756
|
+
const body = /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
757
|
+
/* @__PURE__ */ jsx11("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx11(TypeIcon, { name }) }),
|
|
740
758
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
741
|
-
/* @__PURE__ */
|
|
742
|
-
/* @__PURE__ */
|
|
759
|
+
/* @__PURE__ */ jsx11(Truncating, { text: name, className: NAME_CLASSES }),
|
|
760
|
+
/* @__PURE__ */ jsx11("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
|
|
743
761
|
] })
|
|
744
762
|
] });
|
|
745
763
|
return (
|
|
746
764
|
// @estiva-escape(no-restyled-part): a file that cannot be opened is faded, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
|
|
747
765
|
/* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: address ? "hairline" : "none", className: cn("group flex items-center gap-2 w-[240px] p-1.5 pr-1", !address && "opacity-70", className), ...props, children: [
|
|
748
|
-
address ? /* @__PURE__ */
|
|
766
|
+
address ? /* @__PURE__ */ jsx11(Link, { href: address, external: true, variant: "plain", className: "flex items-center gap-2 min-w-0 flex-1", onClick: (event) => event.stopPropagation(), children: body }) : /* @__PURE__ */ jsx11("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: body }),
|
|
749
767
|
downloadControl
|
|
750
768
|
] })
|
|
751
769
|
);
|
|
@@ -754,7 +772,7 @@ function AttachmentCard({
|
|
|
754
772
|
// src/Avatar.tsx
|
|
755
773
|
import { Avatar as BaseAvatar } from "@base-ui/react/avatar";
|
|
756
774
|
import { IconUserFilled } from "@tabler/icons-react";
|
|
757
|
-
import { jsx as
|
|
775
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
758
776
|
var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
|
|
759
777
|
var hueFor = (key) => {
|
|
760
778
|
let h = 0;
|
|
@@ -771,12 +789,12 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
771
789
|
return /* @__PURE__ */ jsxs7(
|
|
772
790
|
BaseAvatar.Root,
|
|
773
791
|
{
|
|
774
|
-
render: /* @__PURE__ */
|
|
792
|
+
render: /* @__PURE__ */ jsx12("div", {}),
|
|
775
793
|
...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
|
|
776
794
|
className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
|
|
777
795
|
style: { width: size, height: size },
|
|
778
796
|
children: [
|
|
779
|
-
src && /* @__PURE__ */
|
|
797
|
+
src && /* @__PURE__ */ jsx12(
|
|
780
798
|
BaseAvatar.Image,
|
|
781
799
|
{
|
|
782
800
|
src,
|
|
@@ -785,10 +803,10 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
785
803
|
className: "w-full h-full object-cover data-[error]:hidden"
|
|
786
804
|
}
|
|
787
805
|
),
|
|
788
|
-
label ? /* @__PURE__ */
|
|
806
|
+
label ? /* @__PURE__ */ jsx12(
|
|
789
807
|
BaseAvatar.Fallback,
|
|
790
808
|
{
|
|
791
|
-
render: /* @__PURE__ */
|
|
809
|
+
render: /* @__PURE__ */ jsx12("div", {}),
|
|
792
810
|
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
793
811
|
style: {
|
|
794
812
|
/* eslint-disable no-restricted-syntax -- @estiva-escape: the per-person palette (the note at
|
|
@@ -802,32 +820,32 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
802
820
|
background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
|
|
803
821
|
/* eslint-enable no-restricted-syntax */
|
|
804
822
|
},
|
|
805
|
-
children: /* @__PURE__ */
|
|
823
|
+
children: /* @__PURE__ */ jsx12("span", { className: "[text-box:trim-both_cap_alphabetic]", children: initialsFor(label) })
|
|
806
824
|
}
|
|
807
|
-
) : /* @__PURE__ */
|
|
825
|
+
) : /* @__PURE__ */ jsx12(BaseAvatar.Fallback, { render: /* @__PURE__ */ jsx12("div", {}), className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx12(IconUserFilled, { size: Math.round(size * 0.5) }) })
|
|
808
826
|
]
|
|
809
827
|
}
|
|
810
828
|
);
|
|
811
829
|
}
|
|
812
830
|
|
|
813
831
|
// src/AvatarGroup.tsx
|
|
814
|
-
import { jsx as
|
|
832
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
815
833
|
function AvatarGroup({ members, size = 24 }) {
|
|
816
834
|
const visible = members.slice(0, 3);
|
|
817
835
|
const overlap = Math.round(size / 3);
|
|
818
836
|
const ring = size / 12;
|
|
819
|
-
return /* @__PURE__ */
|
|
837
|
+
return /* @__PURE__ */ jsx13("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
|
|
820
838
|
/*
|
|
821
839
|
The wrapper carries the overlap and the ring; the face carries
|
|
822
840
|
neither. It must never clip — see the note at the top of the file —
|
|
823
841
|
so it has the avatar's own radius and no overflow of its own.
|
|
824
842
|
*/
|
|
825
|
-
/* @__PURE__ */
|
|
843
|
+
/* @__PURE__ */ jsx13(
|
|
826
844
|
"span",
|
|
827
845
|
{
|
|
828
846
|
className: "relative flex rounded-sm",
|
|
829
847
|
style: { marginRight: -overlap, boxShadow: `0 0 0 ${ring}px var(--bg-surface)` },
|
|
830
|
-
children: /* @__PURE__ */
|
|
848
|
+
children: /* @__PURE__ */ jsx13(Avatar, { size, name: member.name, src: member.picture, label: member.name })
|
|
831
849
|
},
|
|
832
850
|
i
|
|
833
851
|
)
|
|
@@ -839,7 +857,7 @@ import { IconX as IconX3 } from "@tabler/icons-react";
|
|
|
839
857
|
|
|
840
858
|
// src/Button.tsx
|
|
841
859
|
import { Button as BaseButton3 } from "@base-ui/react/button";
|
|
842
|
-
import { jsx as
|
|
860
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
843
861
|
function Button({
|
|
844
862
|
variant = "muted",
|
|
845
863
|
size = "default",
|
|
@@ -901,11 +919,11 @@ function Button({
|
|
|
901
919
|
]
|
|
902
920
|
}
|
|
903
921
|
);
|
|
904
|
-
return disabledReason ? /* @__PURE__ */
|
|
922
|
+
return disabledReason ? /* @__PURE__ */ jsx14(TooltipTrigger, { label: disabledReason, children: button }) : button;
|
|
905
923
|
}
|
|
906
924
|
|
|
907
925
|
// src/Banner.tsx
|
|
908
|
-
import { jsx as
|
|
926
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
909
927
|
var TONE_STYLES = {
|
|
910
928
|
ok: "bg-success-muted text-success-default",
|
|
911
929
|
error: "bg-error-muted text-error-default",
|
|
@@ -915,14 +933,14 @@ var TONE_STYLES = {
|
|
|
915
933
|
function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismiss", className }) {
|
|
916
934
|
const role = tone === "error" ? "alert" : "status";
|
|
917
935
|
if (!onDismiss && !icon && !action) {
|
|
918
|
-
return /* @__PURE__ */
|
|
936
|
+
return /* @__PURE__ */ jsx15("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
|
|
919
937
|
}
|
|
920
938
|
const oneLine = Boolean(icon || action);
|
|
921
939
|
return /* @__PURE__ */ jsxs9("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
|
|
922
|
-
icon && /* @__PURE__ */
|
|
923
|
-
/* @__PURE__ */
|
|
924
|
-
action && /* @__PURE__ */
|
|
925
|
-
onDismiss && /* @__PURE__ */
|
|
940
|
+
icon && /* @__PURE__ */ jsx15("span", { className: "flex shrink-0", children: icon }),
|
|
941
|
+
/* @__PURE__ */ jsx15("span", { className: cn("min-w-0 flex-1", oneLine && "truncate"), children }),
|
|
942
|
+
action && /* @__PURE__ */ jsx15(Button, { variant: "muted", size: "small", className: "shrink-0", onClick: action.onClick, children: action.label }),
|
|
943
|
+
onDismiss && /* @__PURE__ */ jsx15(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx15(IconX3, { size: 16, stroke: 1.5 }) })
|
|
926
944
|
] });
|
|
927
945
|
}
|
|
928
946
|
|
|
@@ -930,7 +948,7 @@ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismi
|
|
|
930
948
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
931
949
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
932
950
|
import { IconCheck } from "@tabler/icons-react";
|
|
933
|
-
import { jsx as
|
|
951
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
934
952
|
function squareClasses(checked, disabled, interactive, className) {
|
|
935
953
|
return cn(
|
|
936
954
|
"inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
|
|
@@ -947,14 +965,14 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
947
965
|
const formBusy = useFormBusy();
|
|
948
966
|
const disabled = ownDisabled || formBusy;
|
|
949
967
|
if (!onChange) {
|
|
950
|
-
const picture = /* @__PURE__ */
|
|
968
|
+
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 }) }) });
|
|
951
969
|
if (label === void 0) return picture;
|
|
952
970
|
return /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2", children: [
|
|
953
971
|
picture,
|
|
954
|
-
/* @__PURE__ */
|
|
972
|
+
/* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
|
|
955
973
|
] });
|
|
956
974
|
}
|
|
957
|
-
const box = /* @__PURE__ */
|
|
975
|
+
const box = /* @__PURE__ */ jsx16(
|
|
958
976
|
BaseCheckbox.Root,
|
|
959
977
|
{
|
|
960
978
|
checked,
|
|
@@ -964,25 +982,25 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
964
982
|
onCheckedChange: (next) => onChange(next),
|
|
965
983
|
onClick: (e) => e.stopPropagation(),
|
|
966
984
|
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
967
|
-
children: /* @__PURE__ */
|
|
985
|
+
children: /* @__PURE__ */ jsx16(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx16(IconCheck, { size: 12, stroke: 3 }) })
|
|
968
986
|
}
|
|
969
987
|
);
|
|
970
988
|
if (label === void 0) return box;
|
|
971
989
|
if (row) {
|
|
972
|
-
return /* @__PURE__ */
|
|
990
|
+
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: [
|
|
973
991
|
leading,
|
|
974
|
-
/* @__PURE__ */
|
|
992
|
+
/* @__PURE__ */ jsx16("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
|
|
975
993
|
box
|
|
976
994
|
] }) });
|
|
977
995
|
}
|
|
978
|
-
return /* @__PURE__ */
|
|
996
|
+
return /* @__PURE__ */ jsx16(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
|
|
979
997
|
box,
|
|
980
|
-
/* @__PURE__ */
|
|
998
|
+
/* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
|
|
981
999
|
] }) });
|
|
982
1000
|
}
|
|
983
1001
|
|
|
984
1002
|
// src/Chip.tsx
|
|
985
|
-
import { jsx as
|
|
1003
|
+
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
986
1004
|
var typeStyles = {
|
|
987
1005
|
neutral: "bg-bg-inset text-text-primary",
|
|
988
1006
|
brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
|
|
@@ -993,7 +1011,7 @@ var typeStyles = {
|
|
|
993
1011
|
};
|
|
994
1012
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
995
1013
|
return /* @__PURE__ */ jsxs11("div", { className: 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), children: [
|
|
996
|
-
leadingIcon && /* @__PURE__ */
|
|
1014
|
+
leadingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
997
1015
|
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
998
1016
|
// of growing past it — Ship's project chip on an issue row
|
|
999
1017
|
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
@@ -1002,15 +1020,15 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
1002
1020
|
// the screenshot diff caught every descender cut off. `clip` is the
|
|
1003
1021
|
// one overflow that leaves the other axis visible. A chip with no cap
|
|
1004
1022
|
// draws exactly as before.
|
|
1005
|
-
/* @__PURE__ */
|
|
1006
|
-
trailingIcon && /* @__PURE__ */
|
|
1023
|
+
/* @__PURE__ */ jsx17("span", { className: cn("min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap signal:tracking-wide", CHIP_TEXT_CLASSES), children: label }),
|
|
1024
|
+
trailingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
1007
1025
|
] });
|
|
1008
1026
|
}
|
|
1009
1027
|
|
|
1010
1028
|
// src/CommandPalette.tsx
|
|
1011
1029
|
import {
|
|
1012
|
-
createContext as
|
|
1013
|
-
useContext as
|
|
1030
|
+
createContext as createContext5,
|
|
1031
|
+
useContext as useContext5,
|
|
1014
1032
|
useEffect as useEffect2,
|
|
1015
1033
|
useLayoutEffect as useLayoutEffect3,
|
|
1016
1034
|
useMemo as useMemo2,
|
|
@@ -1028,17 +1046,17 @@ import { Combobox } from "@base-ui/react/combobox";
|
|
|
1028
1046
|
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
1029
1047
|
|
|
1030
1048
|
// src/Menu.tsx
|
|
1031
|
-
import { createContext as
|
|
1049
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1032
1050
|
import { IconChevronRight } from "@tabler/icons-react";
|
|
1033
1051
|
import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
1034
1052
|
|
|
1035
1053
|
// src/Divider.tsx
|
|
1036
|
-
import { createContext as
|
|
1054
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
1037
1055
|
import { Separator } from "@base-ui/react/separator";
|
|
1038
|
-
import { jsx as
|
|
1039
|
-
var DividerInPanel =
|
|
1056
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1057
|
+
var DividerInPanel = createContext3(false);
|
|
1040
1058
|
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
1041
|
-
const inset =
|
|
1059
|
+
const inset = useContext3(DividerInPanel) ? "mx-0" : "mx-3";
|
|
1042
1060
|
if (label && orientation === "horizontal") {
|
|
1043
1061
|
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
1044
1062
|
return /* @__PURE__ */ jsxs12(
|
|
@@ -1048,14 +1066,14 @@ function Divider({ orientation = "horizontal", label, tone = "default", classNam
|
|
|
1048
1066
|
"aria-label": label,
|
|
1049
1067
|
className: cn("flex shrink-0 items-center gap-2", inset, className),
|
|
1050
1068
|
children: [
|
|
1051
|
-
/* @__PURE__ */
|
|
1052
|
-
/* @__PURE__ */
|
|
1053
|
-
/* @__PURE__ */
|
|
1069
|
+
/* @__PURE__ */ jsx18("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
1070
|
+
/* @__PURE__ */ jsx18("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
1071
|
+
/* @__PURE__ */ jsx18("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
1054
1072
|
]
|
|
1055
1073
|
}
|
|
1056
1074
|
);
|
|
1057
1075
|
}
|
|
1058
|
-
return /* @__PURE__ */
|
|
1076
|
+
return /* @__PURE__ */ jsx18(
|
|
1059
1077
|
Separator,
|
|
1060
1078
|
{
|
|
1061
1079
|
orientation,
|
|
@@ -1071,14 +1089,14 @@ function triggerDisabled(trigger) {
|
|
|
1071
1089
|
}
|
|
1072
1090
|
|
|
1073
1091
|
// src/SectionLabel.tsx
|
|
1074
|
-
import { jsx as
|
|
1092
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1075
1093
|
function SectionLabel({
|
|
1076
1094
|
children,
|
|
1077
1095
|
tone = "primary",
|
|
1078
1096
|
truncate = false,
|
|
1079
1097
|
className
|
|
1080
1098
|
}) {
|
|
1081
|
-
return /* @__PURE__ */
|
|
1099
|
+
return /* @__PURE__ */ jsx19(
|
|
1082
1100
|
"span",
|
|
1083
1101
|
{
|
|
1084
1102
|
className: cn(
|
|
@@ -1095,10 +1113,10 @@ function SectionLabel({
|
|
|
1095
1113
|
}
|
|
1096
1114
|
|
|
1097
1115
|
// src/Menu.tsx
|
|
1098
|
-
import { Fragment as
|
|
1099
|
-
var MenuContext =
|
|
1116
|
+
import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1117
|
+
var MenuContext = createContext4(null);
|
|
1100
1118
|
function MenuPanel({ children, className, ...props }) {
|
|
1101
|
-
return /* @__PURE__ */
|
|
1119
|
+
return /* @__PURE__ */ jsx20(
|
|
1102
1120
|
"div",
|
|
1103
1121
|
{
|
|
1104
1122
|
className: cn(
|
|
@@ -1137,7 +1155,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1137
1155
|
actionsRef,
|
|
1138
1156
|
modal: false,
|
|
1139
1157
|
children: [
|
|
1140
|
-
/* @__PURE__ */
|
|
1158
|
+
/* @__PURE__ */ jsx20(
|
|
1141
1159
|
BaseMenu.Trigger,
|
|
1142
1160
|
{
|
|
1143
1161
|
render: trigger,
|
|
@@ -1147,7 +1165,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1147
1165
|
closeDelay: HOVER_CLOSE_DELAY
|
|
1148
1166
|
}
|
|
1149
1167
|
),
|
|
1150
|
-
/* @__PURE__ */
|
|
1168
|
+
/* @__PURE__ */ jsx20(BaseMenu.Portal, { children: /* @__PURE__ */ jsx20(
|
|
1151
1169
|
BaseMenu.Positioner,
|
|
1152
1170
|
{
|
|
1153
1171
|
side: "bottom",
|
|
@@ -1155,13 +1173,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1155
1173
|
sideOffset: GAP2,
|
|
1156
1174
|
collisionPadding: VIEWPORT_PAD2,
|
|
1157
1175
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1158
|
-
children: /* @__PURE__ */
|
|
1176
|
+
children: /* @__PURE__ */ jsx20(
|
|
1159
1177
|
BaseMenu.Popup,
|
|
1160
1178
|
{
|
|
1161
1179
|
"data-interactive": true,
|
|
1162
1180
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
1163
|
-
render: /* @__PURE__ */
|
|
1164
|
-
children: /* @__PURE__ */
|
|
1181
|
+
render: /* @__PURE__ */ jsx20(MenuPanel, {}),
|
|
1182
|
+
children: /* @__PURE__ */ jsx20(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx20(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx20(DividerInPanel.Provider, { value: true, children }) }) })
|
|
1165
1183
|
}
|
|
1166
1184
|
)
|
|
1167
1185
|
}
|
|
@@ -1171,26 +1189,26 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1171
1189
|
);
|
|
1172
1190
|
}
|
|
1173
1191
|
function MenuSub({ label, leading, selected, children, className }) {
|
|
1174
|
-
const menu =
|
|
1192
|
+
const menu = useContext4(MenuContext);
|
|
1175
1193
|
if (!isProduction() && menu?.openOnHover) {
|
|
1176
1194
|
console.error(
|
|
1177
1195
|
'[@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".'
|
|
1178
1196
|
);
|
|
1179
1197
|
}
|
|
1180
1198
|
return /* @__PURE__ */ jsxs13(BaseMenu.SubmenuRoot, { children: [
|
|
1181
|
-
/* @__PURE__ */
|
|
1199
|
+
/* @__PURE__ */ jsx20(
|
|
1182
1200
|
BaseMenu.SubmenuTrigger,
|
|
1183
1201
|
{
|
|
1184
1202
|
openOnHover: true,
|
|
1185
1203
|
delay: 0,
|
|
1186
1204
|
closeDelay: 150,
|
|
1187
1205
|
nativeButton: true,
|
|
1188
|
-
render: /* @__PURE__ */
|
|
1206
|
+
render: /* @__PURE__ */ jsx20("button", { type: "button" }),
|
|
1189
1207
|
className: menuItemClassName({ size: "default", selected }),
|
|
1190
|
-
children: /* @__PURE__ */
|
|
1208
|
+
children: /* @__PURE__ */ jsx20(MenuItemBody, { label, leading, submenu: true })
|
|
1191
1209
|
}
|
|
1192
1210
|
),
|
|
1193
|
-
/* @__PURE__ */
|
|
1211
|
+
/* @__PURE__ */ jsx20(BaseMenu.Portal, { children: /* @__PURE__ */ jsx20(
|
|
1194
1212
|
BaseMenu.Positioner,
|
|
1195
1213
|
{
|
|
1196
1214
|
side: "inline-end",
|
|
@@ -1198,7 +1216,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
1198
1216
|
sideOffset: GAP2,
|
|
1199
1217
|
collisionPadding: VIEWPORT_PAD2,
|
|
1200
1218
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1201
|
-
children: /* @__PURE__ */
|
|
1219
|
+
children: /* @__PURE__ */ jsx20(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx20(MenuPanel, {}), children })
|
|
1202
1220
|
}
|
|
1203
1221
|
) })
|
|
1204
1222
|
] });
|
|
@@ -1233,25 +1251,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
1233
1251
|
);
|
|
1234
1252
|
}
|
|
1235
1253
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
1236
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
1237
|
-
return /* @__PURE__ */ jsxs13(
|
|
1238
|
-
leading && /* @__PURE__ */
|
|
1254
|
+
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx20(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx20(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
1255
|
+
return /* @__PURE__ */ jsxs13(Fragment3, { children: [
|
|
1256
|
+
leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1239
1257
|
children ?? /* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
description && /* @__PURE__ */
|
|
1258
|
+
/* @__PURE__ */ jsx20("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
1259
|
+
description && /* @__PURE__ */ jsx20("span", { className: "truncate text-caption text-text-secondary", children: description })
|
|
1242
1260
|
] }),
|
|
1243
1261
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
1244
1262
|
// the wider of the two and never changes, so revealing the hint moves
|
|
1245
1263
|
// nothing. No transition here either — the hint switches on the same
|
|
1246
1264
|
// :hover / `selected` as the fill, in the same frame.
|
|
1247
1265
|
/* @__PURE__ */ jsxs13("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
1248
|
-
edge && /* @__PURE__ */
|
|
1249
|
-
hint && /* @__PURE__ */
|
|
1266
|
+
edge && /* @__PURE__ */ jsx20("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
1267
|
+
hint && /* @__PURE__ */ jsx20("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
1250
1268
|
] })
|
|
1251
1269
|
] });
|
|
1252
1270
|
}
|
|
1253
1271
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
1254
|
-
const body = /* @__PURE__ */
|
|
1272
|
+
const body = /* @__PURE__ */ jsx20(
|
|
1255
1273
|
MenuItemBody,
|
|
1256
1274
|
{
|
|
1257
1275
|
label,
|
|
@@ -1268,14 +1286,14 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1268
1286
|
}
|
|
1269
1287
|
);
|
|
1270
1288
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
1271
|
-
if (!
|
|
1272
|
-
return /* @__PURE__ */
|
|
1289
|
+
if (!useContext4(MenuContext)) {
|
|
1290
|
+
return /* @__PURE__ */ jsx20("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
1273
1291
|
}
|
|
1274
|
-
return /* @__PURE__ */
|
|
1292
|
+
return /* @__PURE__ */ jsx20(
|
|
1275
1293
|
BaseMenu.Item,
|
|
1276
1294
|
{
|
|
1277
1295
|
nativeButton: true,
|
|
1278
|
-
render: /* @__PURE__ */
|
|
1296
|
+
render: /* @__PURE__ */ jsx20("button", { type: "button" }),
|
|
1279
1297
|
className: rowClassName,
|
|
1280
1298
|
...props,
|
|
1281
1299
|
children: body
|
|
@@ -1284,13 +1302,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1284
1302
|
}
|
|
1285
1303
|
function EnterHint({ target }) {
|
|
1286
1304
|
return /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
1287
|
-
/* @__PURE__ */
|
|
1288
|
-
target && /* @__PURE__ */
|
|
1305
|
+
/* @__PURE__ */ jsx20(Kbd, { children: "\u21A9 Enter" }),
|
|
1306
|
+
target && /* @__PURE__ */ jsx20("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider leaf:font-mono leaf:text-small leaf:tracking-wider", children: target })
|
|
1289
1307
|
] });
|
|
1290
1308
|
}
|
|
1291
1309
|
function MenuSection({ label, children, className }) {
|
|
1292
|
-
const inMenu =
|
|
1293
|
-
const heading = /* @__PURE__ */
|
|
1310
|
+
const inMenu = useContext4(MenuContext) !== null;
|
|
1311
|
+
const heading = /* @__PURE__ */ jsx20("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx20(SectionLabel, { tone: "secondary", children: label }) });
|
|
1294
1312
|
if (!inMenu) {
|
|
1295
1313
|
return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col", children: [
|
|
1296
1314
|
heading,
|
|
@@ -1298,19 +1316,19 @@ function MenuSection({ label, children, className }) {
|
|
|
1298
1316
|
] });
|
|
1299
1317
|
}
|
|
1300
1318
|
return /* @__PURE__ */ jsxs13(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1301
|
-
/* @__PURE__ */
|
|
1319
|
+
/* @__PURE__ */ jsx20(BaseMenu.GroupLabel, { render: heading }),
|
|
1302
1320
|
children
|
|
1303
1321
|
] });
|
|
1304
1322
|
}
|
|
1305
1323
|
function MenuSeparator() {
|
|
1306
|
-
return /* @__PURE__ */
|
|
1324
|
+
return /* @__PURE__ */ jsx20(Divider, { className: "my-1" });
|
|
1307
1325
|
}
|
|
1308
1326
|
function MenuRow({ children, className }) {
|
|
1309
|
-
return /* @__PURE__ */
|
|
1327
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
1310
1328
|
}
|
|
1311
1329
|
|
|
1312
1330
|
// src/ChipInput.tsx
|
|
1313
|
-
import { jsx as
|
|
1331
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1314
1332
|
var CHIP_BOX = (
|
|
1315
1333
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
1316
1334
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -1322,9 +1340,9 @@ var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg
|
|
|
1322
1340
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
1323
1341
|
function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
|
|
1324
1342
|
return /* @__PURE__ */ jsxs14("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1325
|
-
leading && /* @__PURE__ */
|
|
1326
|
-
/* @__PURE__ */
|
|
1327
|
-
onRemove && /* @__PURE__ */
|
|
1343
|
+
leading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1344
|
+
/* @__PURE__ */ jsx21("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
|
|
1345
|
+
onRemove && /* @__PURE__ */ jsx21(
|
|
1328
1346
|
BaseButton4,
|
|
1329
1347
|
{
|
|
1330
1348
|
type: "button",
|
|
@@ -1334,7 +1352,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
|
|
|
1334
1352
|
},
|
|
1335
1353
|
className: cn(CHIP_REMOVE, truncate && "shrink-0"),
|
|
1336
1354
|
"aria-label": removeLabel ?? `Remove ${label}`,
|
|
1337
|
-
children: /* @__PURE__ */
|
|
1355
|
+
children: /* @__PURE__ */ jsx21(IconX4, { size: 10, stroke: 1.5 })
|
|
1338
1356
|
}
|
|
1339
1357
|
)
|
|
1340
1358
|
] });
|
|
@@ -1406,11 +1424,11 @@ function ChipInput({
|
|
|
1406
1424
|
children: [
|
|
1407
1425
|
/* @__PURE__ */ jsxs14(Combobox.Chips, { ref: setBox, className: cn(FIELD_SHELL_CLASSES, "focus-within:border-border-focus focus-within:hover: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: [
|
|
1408
1426
|
value.map((option) => /* @__PURE__ */ jsxs14(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1409
|
-
chipLeading && /* @__PURE__ */
|
|
1410
|
-
/* @__PURE__ */
|
|
1411
|
-
/* @__PURE__ */
|
|
1427
|
+
chipLeading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
|
|
1428
|
+
/* @__PURE__ */ jsx21("span", { className: CHIP_LABEL, children: option.label }),
|
|
1429
|
+
/* @__PURE__ */ jsx21(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx21(IconX4, { size: 10, stroke: 1.5 }) })
|
|
1412
1430
|
] }, option.id)),
|
|
1413
|
-
/* @__PURE__ */
|
|
1431
|
+
/* @__PURE__ */ jsx21(
|
|
1414
1432
|
Combobox.Input,
|
|
1415
1433
|
{
|
|
1416
1434
|
autoFocus,
|
|
@@ -1422,18 +1440,18 @@ function ChipInput({
|
|
|
1422
1440
|
}
|
|
1423
1441
|
)
|
|
1424
1442
|
] }),
|
|
1425
|
-
/* @__PURE__ */
|
|
1443
|
+
/* @__PURE__ */ jsx21(Combobox.Portal, { children: /* @__PURE__ */ jsx21(
|
|
1426
1444
|
Combobox.Positioner,
|
|
1427
1445
|
{
|
|
1428
1446
|
anchor: box,
|
|
1429
1447
|
sideOffset: GAP3,
|
|
1430
1448
|
collisionPadding: VIEWPORT_PAD3,
|
|
1431
1449
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1432
|
-
children: /* @__PURE__ */
|
|
1450
|
+
children: /* @__PURE__ */ jsx21(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx21(MenuPanel, {}), children: /* @__PURE__ */ jsx21(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx21(Combobox.List, { children: (option) => /* @__PURE__ */ jsx21(
|
|
1433
1451
|
Combobox.Item,
|
|
1434
1452
|
{
|
|
1435
1453
|
value: option,
|
|
1436
|
-
render: /* @__PURE__ */
|
|
1454
|
+
render: /* @__PURE__ */ jsx21(
|
|
1437
1455
|
MenuItem,
|
|
1438
1456
|
{
|
|
1439
1457
|
size: "tall",
|
|
@@ -1456,22 +1474,22 @@ var VIEWPORT_PAD3 = 8;
|
|
|
1456
1474
|
|
|
1457
1475
|
// src/EmptyState.tsx
|
|
1458
1476
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1459
|
-
import { jsx as
|
|
1477
|
+
import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1460
1478
|
function EmptyState({ icon, message, scope = "page", action, className }) {
|
|
1461
1479
|
if (scope === "section") {
|
|
1462
|
-
return /* @__PURE__ */
|
|
1480
|
+
return /* @__PURE__ */ jsx22("p", { className: cn("text-caption text-text-muted", className), children: message });
|
|
1463
1481
|
}
|
|
1464
1482
|
return /* @__PURE__ */ jsxs15("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1465
|
-
/* @__PURE__ */
|
|
1466
|
-
/* @__PURE__ */
|
|
1467
|
-
action && /* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsx22("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx22(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1484
|
+
/* @__PURE__ */ jsx22("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
|
|
1485
|
+
action && /* @__PURE__ */ jsx22(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
|
|
1468
1486
|
] });
|
|
1469
1487
|
}
|
|
1470
1488
|
|
|
1471
1489
|
// src/Field.tsx
|
|
1472
1490
|
import { cloneElement, isValidElement } from "react";
|
|
1473
1491
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1474
|
-
import { jsx as
|
|
1492
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1475
1493
|
var LINE_STYLES = {
|
|
1476
1494
|
helper: "text-caption text-text-muted",
|
|
1477
1495
|
warning: "text-caption text-warning-default",
|
|
@@ -1484,23 +1502,23 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1484
1502
|
return /* @__PURE__ */ jsxs16(BaseField2.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1485
1503
|
/* @__PURE__ */ jsxs16(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1486
1504
|
label,
|
|
1487
|
-
required && /* @__PURE__ */
|
|
1505
|
+
required && /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1488
1506
|
] }),
|
|
1489
1507
|
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1490
1508
|
control,
|
|
1491
|
-
error != null ? /* @__PURE__ */
|
|
1509
|
+
error != null ? /* @__PURE__ */ jsx23(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx23(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
|
|
1492
1510
|
] })
|
|
1493
1511
|
] });
|
|
1494
1512
|
}
|
|
1495
1513
|
function FieldLine({ tone = "helper", children, className }) {
|
|
1496
|
-
return /* @__PURE__ */
|
|
1514
|
+
return /* @__PURE__ */ jsx23("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
|
|
1497
1515
|
}
|
|
1498
1516
|
|
|
1499
1517
|
// src/Form.tsx
|
|
1500
1518
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
|
|
1501
1519
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
1502
1520
|
import { Form as BaseForm } from "@base-ui/react/form";
|
|
1503
|
-
import { jsx as
|
|
1521
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1504
1522
|
var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
|
|
1505
1523
|
var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1506
1524
|
function usable(element) {
|
|
@@ -1559,7 +1577,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1559
1577
|
const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
|
|
1560
1578
|
if (enterSends && oneLine) form.current?.requestSubmit();
|
|
1561
1579
|
};
|
|
1562
|
-
return /* @__PURE__ */
|
|
1580
|
+
return /* @__PURE__ */ jsx24(
|
|
1563
1581
|
BaseForm,
|
|
1564
1582
|
{
|
|
1565
1583
|
ref: form,
|
|
@@ -1582,32 +1600,32 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1582
1600
|
if (busyNow.current) return;
|
|
1583
1601
|
void onSubmit();
|
|
1584
1602
|
},
|
|
1585
|
-
children: /* @__PURE__ */
|
|
1603
|
+
children: /* @__PURE__ */ jsx24(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx24(FormBusyContext.Provider, { value: busy, children }) })
|
|
1586
1604
|
}
|
|
1587
1605
|
);
|
|
1588
1606
|
}
|
|
1589
1607
|
|
|
1590
1608
|
// src/Skeleton.tsx
|
|
1591
|
-
import { jsx as
|
|
1609
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1592
1610
|
function SkeletonBar({ className, style }) {
|
|
1593
|
-
return /* @__PURE__ */
|
|
1611
|
+
return /* @__PURE__ */ jsx25("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1594
1612
|
}
|
|
1595
1613
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1596
1614
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1597
1615
|
return /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1598
|
-
/* @__PURE__ */
|
|
1599
|
-
/* @__PURE__ */
|
|
1616
|
+
/* @__PURE__ */ jsx25(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1617
|
+
/* @__PURE__ */ jsx25(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1600
1618
|
] });
|
|
1601
1619
|
}
|
|
1602
1620
|
function SkeletonList({ rows = 8, className }) {
|
|
1603
|
-
return /* @__PURE__ */
|
|
1621
|
+
return /* @__PURE__ */ jsx25("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx25(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
|
|
1604
1622
|
}
|
|
1605
1623
|
|
|
1606
1624
|
// src/CommandPalette.tsx
|
|
1607
|
-
import { Fragment as
|
|
1608
|
-
var PaletteContext =
|
|
1625
|
+
import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1626
|
+
var PaletteContext = createContext5(null);
|
|
1609
1627
|
function usePalette(part) {
|
|
1610
|
-
const palette =
|
|
1628
|
+
const palette = useContext5(PaletteContext);
|
|
1611
1629
|
if (!palette) throw new Error(`[@estiva-app/ui] ${part} must be inside a CommandPalette.`);
|
|
1612
1630
|
return palette;
|
|
1613
1631
|
}
|
|
@@ -1630,9 +1648,9 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1630
1648
|
return () => cancelAnimationFrame(frame);
|
|
1631
1649
|
});
|
|
1632
1650
|
const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
|
|
1633
|
-
return /* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
1635
|
-
/* @__PURE__ */
|
|
1651
|
+
return /* @__PURE__ */ jsx26(Dialog2.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs18(Dialog2.Portal, { children: [
|
|
1652
|
+
/* @__PURE__ */ jsx26(Dialog2.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1653
|
+
/* @__PURE__ */ jsx26(Dialog2.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx26(
|
|
1636
1654
|
Dialog2.Popup,
|
|
1637
1655
|
{
|
|
1638
1656
|
ref: popupRef,
|
|
@@ -1642,13 +1660,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1642
1660
|
if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
|
|
1643
1661
|
},
|
|
1644
1662
|
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",
|
|
1645
|
-
children: /* @__PURE__ */
|
|
1663
|
+
children: /* @__PURE__ */ jsx26(PaletteContext.Provider, { value: context, children })
|
|
1646
1664
|
}
|
|
1647
1665
|
) })
|
|
1648
1666
|
] }) });
|
|
1649
1667
|
}
|
|
1650
1668
|
function LevelChip({ chip, onBack }) {
|
|
1651
|
-
return /* @__PURE__ */
|
|
1669
|
+
return /* @__PURE__ */ jsx26(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
|
|
1652
1670
|
}
|
|
1653
1671
|
function useBack(chip, popupRef) {
|
|
1654
1672
|
return () => {
|
|
@@ -1660,9 +1678,9 @@ function useBack(chip, popupRef) {
|
|
|
1660
1678
|
function Footer({ keys }) {
|
|
1661
1679
|
const { where } = usePalette("The footer");
|
|
1662
1680
|
return /* @__PURE__ */ jsxs18("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: [
|
|
1663
|
-
/* @__PURE__ */
|
|
1681
|
+
/* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate", children: where }),
|
|
1664
1682
|
keys.map(([key, word]) => /* @__PURE__ */ jsxs18("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
1665
|
-
/* @__PURE__ */
|
|
1683
|
+
/* @__PURE__ */ jsx26(Kbd, { children: key }),
|
|
1666
1684
|
" ",
|
|
1667
1685
|
word
|
|
1668
1686
|
] }, key))
|
|
@@ -1763,9 +1781,9 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1763
1781
|
},
|
|
1764
1782
|
children: [
|
|
1765
1783
|
/* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1766
|
-
/* @__PURE__ */
|
|
1767
|
-
chip && /* @__PURE__ */
|
|
1768
|
-
/* @__PURE__ */
|
|
1784
|
+
/* @__PURE__ */ jsx26(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
|
|
1785
|
+
chip && /* @__PURE__ */ jsx26(LevelChip, { chip, onBack: back }),
|
|
1786
|
+
/* @__PURE__ */ jsx26(
|
|
1769
1787
|
Autocomplete.Input,
|
|
1770
1788
|
{
|
|
1771
1789
|
ref: inputRef,
|
|
@@ -1778,42 +1796,42 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1778
1796
|
)
|
|
1779
1797
|
] }),
|
|
1780
1798
|
/* @__PURE__ */ jsxs18(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
|
|
1781
|
-
children != null && /* @__PURE__ */
|
|
1782
|
-
/* @__PURE__ */
|
|
1783
|
-
/* @__PURE__ */
|
|
1784
|
-
/* @__PURE__ */
|
|
1799
|
+
children != null && /* @__PURE__ */ jsx26("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
|
|
1800
|
+
/* @__PURE__ */ jsx26(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs18(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
|
|
1801
|
+
/* @__PURE__ */ jsx26(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx26(SectionLabel, { tone: "secondary", children: group.value }) }),
|
|
1802
|
+
/* @__PURE__ */ jsx26(Autocomplete.Collection, { children: (row) => (
|
|
1785
1803
|
/* The menu row, as the list's own option — the way Select
|
|
1786
1804
|
puts it on `Select.Item`. One row, two parts. */
|
|
1787
|
-
/* @__PURE__ */
|
|
1805
|
+
/* @__PURE__ */ jsx26(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx26(
|
|
1788
1806
|
MenuItemBody,
|
|
1789
1807
|
{
|
|
1790
1808
|
size: "tall",
|
|
1791
1809
|
label: row.label,
|
|
1792
1810
|
description: row.description,
|
|
1793
|
-
leading: /* @__PURE__ */
|
|
1811
|
+
leading: /* @__PURE__ */ jsx26(RowLeading, { row }),
|
|
1794
1812
|
submenu: !!row.onGoIn,
|
|
1795
|
-
hint: row.onGoIn ? /* @__PURE__ */
|
|
1813
|
+
hint: row.onGoIn ? /* @__PURE__ */ jsx26(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx26(EnterHint, {})
|
|
1796
1814
|
}
|
|
1797
1815
|
) }, row.id)
|
|
1798
1816
|
) })
|
|
1799
1817
|
] }, group.value) }),
|
|
1800
|
-
/* @__PURE__ */
|
|
1801
|
-
/* @__PURE__ */
|
|
1802
|
-
/* @__PURE__ */
|
|
1818
|
+
/* @__PURE__ */ jsx26(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
1819
|
+
/* @__PURE__ */ jsx26(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
|
|
1820
|
+
/* @__PURE__ */ jsx26("span", { className: "text-caption text-text-muted", children: pending })
|
|
1803
1821
|
] }) }),
|
|
1804
|
-
notes.map((note) => /* @__PURE__ */
|
|
1805
|
-
/* @__PURE__ */
|
|
1822
|
+
notes.map((note) => /* @__PURE__ */ jsx26("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx26(FieldLine, { children: note }) }, note)),
|
|
1823
|
+
/* @__PURE__ */ jsx26(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx26(EmptyState, { scope: "section", message: empty }) })
|
|
1806
1824
|
] }),
|
|
1807
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsx26(Footer, { keys })
|
|
1808
1826
|
]
|
|
1809
1827
|
}
|
|
1810
1828
|
);
|
|
1811
1829
|
}
|
|
1812
1830
|
function RowLeading({ row }) {
|
|
1813
1831
|
if (row.icon != null) {
|
|
1814
|
-
return /* @__PURE__ */
|
|
1832
|
+
return /* @__PURE__ */ jsx26("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
|
|
1815
1833
|
}
|
|
1816
|
-
return /* @__PURE__ */
|
|
1834
|
+
return /* @__PURE__ */ jsx26("span", { className: "flex size-8 items-center justify-center", children: row.leading });
|
|
1817
1835
|
}
|
|
1818
1836
|
var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1819
1837
|
function isTextField(el) {
|
|
@@ -1857,54 +1875,54 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
|
|
|
1857
1875
|
];
|
|
1858
1876
|
return /* @__PURE__ */ jsxs18("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
|
|
1859
1877
|
/* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1860
|
-
icon != null && /* @__PURE__ */
|
|
1861
|
-
/* @__PURE__ */
|
|
1878
|
+
icon != null && /* @__PURE__ */ jsx26("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
|
|
1879
|
+
/* @__PURE__ */ jsx26(LevelChip, { chip, onBack: back })
|
|
1862
1880
|
] }),
|
|
1863
1881
|
/* @__PURE__ */ jsxs18(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, className: "flex min-h-0 flex-col", children: [
|
|
1864
|
-
/* @__PURE__ */
|
|
1882
|
+
/* @__PURE__ */ jsx26(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx26("div", { className: "flex flex-col gap-4", children }) }),
|
|
1865
1883
|
/* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
|
|
1866
|
-
/* @__PURE__ */
|
|
1867
|
-
/* @__PURE__ */
|
|
1884
|
+
/* @__PURE__ */ jsx26("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx26(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx26(FieldLine, { tone: "error", children: error }) : null }),
|
|
1885
|
+
/* @__PURE__ */ jsx26(
|
|
1868
1886
|
Button,
|
|
1869
1887
|
{
|
|
1870
1888
|
type: "submit",
|
|
1871
1889
|
variant: "primary",
|
|
1872
1890
|
disabled: busy,
|
|
1873
1891
|
disabledReason: busy ? void 0 : submitWaits,
|
|
1874
|
-
leadingIcon: busy ? /* @__PURE__ */
|
|
1892
|
+
leadingIcon: busy ? /* @__PURE__ */ jsx26(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
|
|
1875
1893
|
children: working ? working.button : submitLabel
|
|
1876
1894
|
}
|
|
1877
1895
|
)
|
|
1878
1896
|
] })
|
|
1879
1897
|
] }),
|
|
1880
|
-
/* @__PURE__ */
|
|
1898
|
+
/* @__PURE__ */ jsx26(Footer, { keys })
|
|
1881
1899
|
] });
|
|
1882
1900
|
}
|
|
1883
1901
|
var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
|
|
1884
1902
|
function CommandPaletteWorking({ children, bars = 2 }) {
|
|
1885
1903
|
return /* @__PURE__ */ jsxs18("div", { role: "status", className: "flex flex-col gap-2", children: [
|
|
1886
1904
|
/* @__PURE__ */ jsxs18("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
|
|
1887
|
-
/* @__PURE__ */
|
|
1905
|
+
/* @__PURE__ */ jsx26(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
|
|
1888
1906
|
children
|
|
1889
1907
|
] }),
|
|
1890
|
-
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */
|
|
1908
|
+
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx26(SkeletonBar, { className: cn("h-3", width) }, width))
|
|
1891
1909
|
] });
|
|
1892
1910
|
}
|
|
1893
1911
|
function CommandPaletteAnswer({ children, note }) {
|
|
1894
1912
|
const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
|
|
1895
1913
|
return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
|
|
1896
|
-
paragraphs.map((paragraph, i) => /* @__PURE__ */
|
|
1897
|
-
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */
|
|
1914
|
+
paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx26("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
|
|
1915
|
+
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx26("sup", { className: "ml-0.5 font-mono text-small text-accent-primary", children: part.slice(1, -1) }, j) : part
|
|
1898
1916
|
) }, i)),
|
|
1899
|
-
note && /* @__PURE__ */
|
|
1917
|
+
note && /* @__PURE__ */ jsx26(FieldLine, { children: note })
|
|
1900
1918
|
] });
|
|
1901
1919
|
}
|
|
1902
1920
|
function CommandPaletteQuote({ children }) {
|
|
1903
|
-
return /* @__PURE__ */
|
|
1921
|
+
return /* @__PURE__ */ jsx26("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
|
|
1904
1922
|
}
|
|
1905
1923
|
|
|
1906
1924
|
// src/InlineChip.tsx
|
|
1907
|
-
import { Fragment as
|
|
1925
|
+
import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1908
1926
|
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";
|
|
1909
1927
|
var INLINE_CHIP_TONE_CLASSES = {
|
|
1910
1928
|
/** A thing or a place — anything that is not a person. */
|
|
@@ -1926,30 +1944,169 @@ function inlineChipClassName(tone, className) {
|
|
|
1926
1944
|
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1927
1945
|
}
|
|
1928
1946
|
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1929
|
-
const body = /* @__PURE__ */ jsxs19(
|
|
1930
|
-
icon && /* @__PURE__ */
|
|
1947
|
+
const body = /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
1948
|
+
icon && /* @__PURE__ */ jsx27("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
|
|
1931
1949
|
children
|
|
1932
1950
|
] });
|
|
1933
1951
|
const classes = inlineChipClassName(tone, className);
|
|
1934
1952
|
if (href === void 0) {
|
|
1935
|
-
return /* @__PURE__ */
|
|
1953
|
+
return /* @__PURE__ */ jsx27("span", { className: classes, ...props, children: body });
|
|
1936
1954
|
}
|
|
1937
|
-
return /* @__PURE__ */
|
|
1955
|
+
return /* @__PURE__ */ jsx27("a", { href, className: classes, ...props, children: body });
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1958
|
+
// src/RichText.tsx
|
|
1959
|
+
import { Fragment as Fragment6, jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1960
|
+
var RICH_TEXT_CLASSES = {
|
|
1961
|
+
base: "flex flex-col gap-1 break-words text-text-secondary",
|
|
1962
|
+
/* 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. */
|
|
1963
|
+
headings: "[&>:is(h1,h2,h3)]:mb-1 [&>:is(h1,h2,h3)]:mt-2 [&>:is(h1,h2,h3):first-child]:mt-0 [&>:is(h1,h2,h3):last-child]:mb-0 [&>:is(h1,h2,h3)+:is(h1,h2,h3)]:mt-1 [&>:is(h1,h2)]:text-text-primary",
|
|
1964
|
+
lists: "[&_:is(ul,ol)]:pl-5 [&_li>p]:m-0 [&_li]:break-words [&_li]:marker:text-text-muted [&_ol]:list-decimal [&_ul]:list-disc",
|
|
1965
|
+
// eslint-disable-next-line token-spacing/no-restricted-classes -- @estiva-escape: the quote line is Peek's, 3px, between the ramp's 2 and 4
|
|
1966
|
+
quote: "[&_blockquote>p]:m-0 [&_blockquote]:border-l-[3px] [&_blockquote]:border-border-strong [&_blockquote]:pl-2.5",
|
|
1967
|
+
// eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.9 of the text around it, so it scales with a heading and with `small`; a named size is fixed
|
|
1968
|
+
code: "[&_:not(pre)>code]:rounded-sm [&_:not(pre)>code]:bg-bg-code [&_:not(pre)>code]:px-1 [&_:not(pre)>code]:py-0.5 [&_code]:font-mono [&_code]:text-[0.9em] [&_code]:text-text-primary",
|
|
1969
|
+
// eslint-disable-next-line token-values/no-restricted-classes -- @estiva-escape: code is 0.9 of the text around it; the code inside the block is the block's own size, not 0.9 of it again
|
|
1970
|
+
codeBlock: "[&_pre>code]:text-[1em] [&_pre]:whitespace-pre-wrap [&_pre]:break-words [&_pre]:rounded-md [&_pre]:bg-bg-code [&_pre]:p-2 [&_pre]:font-mono [&_pre]:text-[0.9em] [&_pre]:text-text-primary",
|
|
1971
|
+
divider: "[&_hr]:border-border-default",
|
|
1972
|
+
table: "[&_:is(th,td)>p]:m-0 [&_:is(th,td)]:border [&_:is(th,td)]:border-border-default [&_:is(th,td)]:px-2 [&_:is(th,td)]:py-1 [&_:is(th,td)]:text-left [&_:is(th,td)]:align-top [&_table]:w-full [&_table]:border-collapse [&_th]:bg-bg-code [&_th]:font-medium [&_th]:text-text-primary",
|
|
1973
|
+
marks: "[&_em]:italic [&_strong]:font-semibold [&_u]:underline [&_u]:underline-offset-2",
|
|
1974
|
+
default: "text-body-2 [&>:is(h2,h3)]:text-body-2 [&>:is(h2,h3)]:font-semibold [&>h1]:text-h4",
|
|
1975
|
+
small: "text-caption leading-snug [&>:is(h2,h3)]:text-caption [&>:is(h2,h3)]:font-semibold [&>h1]:text-body-2 [&>h1]:font-semibold"
|
|
1976
|
+
};
|
|
1977
|
+
function richTextClassName(size = "default", className) {
|
|
1978
|
+
const { base, headings, lists, quote, code, codeBlock, divider, table, marks } = RICH_TEXT_CLASSES;
|
|
1979
|
+
return cn(base, headings, lists, quote, code, codeBlock, divider, table, marks, RICH_TEXT_CLASSES[size], className);
|
|
1980
|
+
}
|
|
1981
|
+
var LINK_SPLIT = /(\[[^[\]\n]+\]\((?:https?:\/\/|mailto:)[^\s)]+\)|https?:\/\/[^\s]+)/g;
|
|
1982
|
+
var WRITTEN_LINK = /^\[([^[\]\n]+)\]\(((?:https?:\/\/|mailto:)[^\s)]+)\)$/;
|
|
1983
|
+
var BARE_LINK = /^(https?:\/\/\S+?)([.,;:!?)\]]*)$/;
|
|
1984
|
+
var keepToLink = (event) => event.stopPropagation();
|
|
1985
|
+
function textWithLinks(text, renderText) {
|
|
1986
|
+
const parts = text.split(LINK_SPLIT);
|
|
1987
|
+
if (parts.length === 1) return renderText(text);
|
|
1988
|
+
return parts.map((part, i) => {
|
|
1989
|
+
const written = part.match(WRITTEN_LINK);
|
|
1990
|
+
if (written) {
|
|
1991
|
+
return /* @__PURE__ */ jsx28("span", { className: "break-words", children: /* @__PURE__ */ jsx28(Link, { href: written[2], external: true, onClick: keepToLink, children: written[1] }) }, i);
|
|
1992
|
+
}
|
|
1993
|
+
const bare = i % 2 === 1 ? part.match(BARE_LINK) : null;
|
|
1994
|
+
if (bare) {
|
|
1995
|
+
return (
|
|
1996
|
+
// An address has no spaces to wrap at, so it may break anywhere.
|
|
1997
|
+
/* @__PURE__ */ jsxs20("span", { className: "break-all", children: [
|
|
1998
|
+
/* @__PURE__ */ jsx28(Link, { href: bare[1], external: true, onClick: keepToLink, children: bare[1] }),
|
|
1999
|
+
bare[2]
|
|
2000
|
+
] }, i)
|
|
2001
|
+
);
|
|
2002
|
+
}
|
|
2003
|
+
return part ? /* @__PURE__ */ jsx28("span", { children: renderText(part) }, i) : null;
|
|
2004
|
+
});
|
|
2005
|
+
}
|
|
2006
|
+
function Runs({ runs, draw }) {
|
|
2007
|
+
return /* @__PURE__ */ jsx28(Fragment6, { children: (runs ?? []).map((run, i) => {
|
|
2008
|
+
if (run.reference) return /* @__PURE__ */ jsx28("span", { children: draw.renderReference(run.reference, run) }, i);
|
|
2009
|
+
if (run.marks.includes("code")) {
|
|
2010
|
+
return /* @__PURE__ */ jsx28("code", { children: run.text }, i);
|
|
2011
|
+
}
|
|
2012
|
+
let node = run.text.split("\n").map((line, j) => /* @__PURE__ */ jsxs20("span", { children: [
|
|
2013
|
+
j > 0 && /* @__PURE__ */ jsx28("br", {}),
|
|
2014
|
+
textWithLinks(line, draw.renderText)
|
|
2015
|
+
] }, j));
|
|
2016
|
+
if (run.marks.includes("underline")) node = /* @__PURE__ */ jsx28("u", { children: node });
|
|
2017
|
+
if (run.marks.includes("italic")) node = /* @__PURE__ */ jsx28("em", { children: node });
|
|
2018
|
+
if (run.marks.includes("bold")) node = /* @__PURE__ */ jsx28("strong", { children: node });
|
|
2019
|
+
return /* @__PURE__ */ jsx28("span", { children: node }, i);
|
|
2020
|
+
}) });
|
|
2021
|
+
}
|
|
2022
|
+
var named = (block) => block.typeName ?? block.type;
|
|
2023
|
+
function Table({ block, draw }) {
|
|
2024
|
+
const rows = (block.children ?? []).filter((row) => named(row) === "tableRow");
|
|
2025
|
+
if (!rows.length) return null;
|
|
2026
|
+
const cells = (row) => (row.children ?? []).map((cell, i) => {
|
|
2027
|
+
const header = named(cell) === "tableHeader";
|
|
2028
|
+
const Cell = header ? "th" : "td";
|
|
2029
|
+
const { colspan, rowspan } = cell.attrs ?? {};
|
|
2030
|
+
return /* @__PURE__ */ jsxs20(
|
|
2031
|
+
Cell,
|
|
2032
|
+
{
|
|
2033
|
+
"data-block-id": cell.id,
|
|
2034
|
+
colSpan: colspan && colspan > 1 ? colspan : void 0,
|
|
2035
|
+
rowSpan: rowspan && rowspan > 1 ? rowspan : void 0,
|
|
2036
|
+
children: [
|
|
2037
|
+
(cell.children ?? []).map((child, j) => /* @__PURE__ */ jsx28(Runs, { runs: child.inline, draw }, j)),
|
|
2038
|
+
/* @__PURE__ */ jsx28(Runs, { runs: cell.inline, draw })
|
|
2039
|
+
]
|
|
2040
|
+
},
|
|
2041
|
+
cell.id ?? i
|
|
2042
|
+
);
|
|
2043
|
+
});
|
|
2044
|
+
const first = rows[0].children ?? [];
|
|
2045
|
+
const headerRow = first.length > 0 && first.every((cell) => named(cell) === "tableHeader");
|
|
2046
|
+
return /* @__PURE__ */ jsxs20("table", { "data-block-id": block.id, children: [
|
|
2047
|
+
headerRow && /* @__PURE__ */ jsx28("thead", { children: /* @__PURE__ */ jsx28("tr", { "data-block-id": rows[0].id, children: cells(rows[0]) }) }),
|
|
2048
|
+
/* @__PURE__ */ jsx28("tbody", { children: (headerRow ? rows.slice(1) : rows).map((row, i) => /* @__PURE__ */ jsx28("tr", { "data-block-id": row.id, children: cells(row) }, row.id ?? i)) })
|
|
2049
|
+
] });
|
|
2050
|
+
}
|
|
2051
|
+
function Block({ block, draw }) {
|
|
2052
|
+
const own = draw.renderBlock?.(block);
|
|
2053
|
+
if (own !== void 0) return own;
|
|
2054
|
+
const runs = /* @__PURE__ */ jsx28(Runs, { runs: block.inline, draw });
|
|
2055
|
+
switch (block.type) {
|
|
2056
|
+
case "heading": {
|
|
2057
|
+
if (block.level === 1) return /* @__PURE__ */ jsx28("h1", { "data-block-id": block.id, children: runs });
|
|
2058
|
+
if (block.level === 3) return /* @__PURE__ */ jsx28("h3", { "data-block-id": block.id, children: runs });
|
|
2059
|
+
return /* @__PURE__ */ jsx28("h2", { "data-block-id": block.id, children: runs });
|
|
2060
|
+
}
|
|
2061
|
+
case "paragraph":
|
|
2062
|
+
return /* @__PURE__ */ jsx28("p", { "data-block-id": block.id, children: runs });
|
|
2063
|
+
case "bulletList":
|
|
2064
|
+
case "orderedList": {
|
|
2065
|
+
const items = (block.children ?? []).map((item, i) => /* @__PURE__ */ jsx28("li", { "data-block-id": item.id, children: /* @__PURE__ */ jsx28(Runs, { runs: item.inline, draw }) }, item.id ?? i));
|
|
2066
|
+
return block.type === "bulletList" ? /* @__PURE__ */ jsx28("ul", { "data-block-id": block.id, children: items }) : /* @__PURE__ */ jsx28("ol", { "data-block-id": block.id, start: block.start, children: items });
|
|
2067
|
+
}
|
|
2068
|
+
case "blockquote":
|
|
2069
|
+
return /* @__PURE__ */ jsx28("blockquote", { "data-block-id": block.id, children: runs });
|
|
2070
|
+
case "codeBlock":
|
|
2071
|
+
return /* @__PURE__ */ jsx28("pre", { "data-block-id": block.id, "data-language": block.language, children: /* @__PURE__ */ jsx28("code", { children: (block.inline ?? []).map((run) => run.text).join("") }) });
|
|
2072
|
+
case "horizontalRule":
|
|
2073
|
+
return /* @__PURE__ */ jsx28("hr", { "data-block-id": block.id });
|
|
2074
|
+
case "table": {
|
|
2075
|
+
const table = /* @__PURE__ */ jsx28(Table, { block, draw });
|
|
2076
|
+
if ((block.children ?? []).some((row) => named(row) === "tableRow")) return table;
|
|
2077
|
+
break;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
return /* @__PURE__ */ jsxs20("div", { "data-block-id": block.id, "data-block-type": named(block), children: [
|
|
2081
|
+
runs,
|
|
2082
|
+
(block.children ?? []).map((child, i) => /* @__PURE__ */ jsx28(Block, { block: child, draw }, child.id ?? i))
|
|
2083
|
+
] });
|
|
2084
|
+
}
|
|
2085
|
+
function RichText({
|
|
2086
|
+
blocks,
|
|
2087
|
+
size = "default",
|
|
2088
|
+
renderText = (text) => text,
|
|
2089
|
+
renderReference = (_reference, run) => run.text,
|
|
2090
|
+
renderBlock
|
|
2091
|
+
}) {
|
|
2092
|
+
if (blocks.length === 0) return null;
|
|
2093
|
+
const draw = { renderText, renderReference, renderBlock };
|
|
2094
|
+
return /* @__PURE__ */ jsx28("div", { "data-rich-text": true, className: richTextClassName(size), children: blocks.map((block, i) => /* @__PURE__ */ jsx28(Block, { block, draw }, block.id ?? i)) });
|
|
1938
2095
|
}
|
|
1939
2096
|
|
|
1940
2097
|
// src/IdentityMenu.tsx
|
|
1941
2098
|
import { useCallback, useRef as useRef5 } from "react";
|
|
1942
2099
|
|
|
1943
2100
|
// src/Person.tsx
|
|
1944
|
-
import { jsx as
|
|
2101
|
+
import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1945
2102
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
1946
2103
|
return (
|
|
1947
2104
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
1948
2105
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
1949
2106
|
// row agree by construction.
|
|
1950
|
-
/* @__PURE__ */
|
|
1951
|
-
/* @__PURE__ */
|
|
1952
|
-
/* @__PURE__ */
|
|
2107
|
+
/* @__PURE__ */ jsxs21("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
2108
|
+
/* @__PURE__ */ jsx29(Avatar, { name, src: picture, size }),
|
|
2109
|
+
/* @__PURE__ */ jsx29("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
1953
2110
|
] })
|
|
1954
2111
|
);
|
|
1955
2112
|
}
|
|
@@ -1957,10 +2114,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
1957
2114
|
// src/PersonTrigger.tsx
|
|
1958
2115
|
import { Button as BaseButton5 } from "@base-ui/react/button";
|
|
1959
2116
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
1960
|
-
import { jsx as
|
|
2117
|
+
import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1961
2118
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
1962
2119
|
if (compact) {
|
|
1963
|
-
return /* @__PURE__ */
|
|
2120
|
+
return /* @__PURE__ */ jsx30(
|
|
1964
2121
|
BaseButton5,
|
|
1965
2122
|
{
|
|
1966
2123
|
type: "button",
|
|
@@ -1969,13 +2126,13 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1969
2126
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
1970
2127
|
className: cn("cursor-pointer rounded-full", className),
|
|
1971
2128
|
...props,
|
|
1972
|
-
children: /* @__PURE__ */
|
|
2129
|
+
children: /* @__PURE__ */ jsx30(Avatar, { name, src: picture, size: size ?? 36 })
|
|
1973
2130
|
}
|
|
1974
2131
|
);
|
|
1975
2132
|
}
|
|
1976
2133
|
return (
|
|
1977
2134
|
// @estiva-escape(no-copied-look): N5 (Katerina, 24 September: record only): a row that fills on hover, as NavItem also does
|
|
1978
|
-
/* @__PURE__ */
|
|
2135
|
+
/* @__PURE__ */ jsxs22(
|
|
1979
2136
|
BaseButton5,
|
|
1980
2137
|
{
|
|
1981
2138
|
type: "button",
|
|
@@ -1993,8 +2150,8 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1993
2150
|
),
|
|
1994
2151
|
...props,
|
|
1995
2152
|
children: [
|
|
1996
|
-
/* @__PURE__ */
|
|
1997
|
-
/* @__PURE__ */
|
|
2153
|
+
/* @__PURE__ */ jsx30(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
2154
|
+
/* @__PURE__ */ jsx30(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
1998
2155
|
]
|
|
1999
2156
|
}
|
|
2000
2157
|
)
|
|
@@ -2002,10 +2159,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
2002
2159
|
}
|
|
2003
2160
|
|
|
2004
2161
|
// src/IdentityMenu.tsx
|
|
2005
|
-
import { Fragment as
|
|
2162
|
+
import { Fragment as Fragment7, jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2006
2163
|
function IdentityPanel({ className, onClose = () => {
|
|
2007
2164
|
}, ...rest }) {
|
|
2008
|
-
return /* @__PURE__ */
|
|
2165
|
+
return /* @__PURE__ */ jsx31(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx31(IdentityRows, { ...rest, onClose }) });
|
|
2009
2166
|
}
|
|
2010
2167
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
2011
2168
|
const act = (action) => () => {
|
|
@@ -2013,36 +2170,36 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
2013
2170
|
action();
|
|
2014
2171
|
};
|
|
2015
2172
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
2016
|
-
return /* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2018
|
-
/* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
me.email && /* @__PURE__ */
|
|
2173
|
+
return /* @__PURE__ */ jsxs23(Fragment7, { children: [
|
|
2174
|
+
/* @__PURE__ */ jsxs23(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
2175
|
+
/* @__PURE__ */ jsx31(MenuRow, { children: /* @__PURE__ */ jsx31("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx31(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
|
|
2176
|
+
/* @__PURE__ */ jsx31(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." }),
|
|
2177
|
+
me.email && /* @__PURE__ */ jsxs23(Note, { children: [
|
|
2021
2178
|
me.email,
|
|
2022
2179
|
" \xB7 known to Estiva, never published to the relay"
|
|
2023
2180
|
] })
|
|
2024
2181
|
] }),
|
|
2025
|
-
relayUrl && /* @__PURE__ */
|
|
2026
|
-
/* @__PURE__ */
|
|
2027
|
-
/* @__PURE__ */
|
|
2028
|
-
/* @__PURE__ */
|
|
2029
|
-
/* @__PURE__ */
|
|
2182
|
+
relayUrl && /* @__PURE__ */ jsxs23(Fragment7, { children: [
|
|
2183
|
+
/* @__PURE__ */ jsx31(Divider, { className: "mx-0 my-2" }),
|
|
2184
|
+
/* @__PURE__ */ jsxs23(MenuSection, { label: "Workspace", children: [
|
|
2185
|
+
/* @__PURE__ */ jsx31(MenuRow, { children: /* @__PURE__ */ jsx31("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
2186
|
+
/* @__PURE__ */ jsx31(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
2030
2187
|
] })
|
|
2031
2188
|
] }),
|
|
2032
|
-
appRows && /* @__PURE__ */
|
|
2033
|
-
/* @__PURE__ */
|
|
2189
|
+
appRows && /* @__PURE__ */ jsxs23(Fragment7, { children: [
|
|
2190
|
+
/* @__PURE__ */ jsx31(Divider, { className: "mx-0 my-2" }),
|
|
2034
2191
|
appRows
|
|
2035
2192
|
] }),
|
|
2036
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
2037
|
-
signedIn && idBase && /* @__PURE__ */
|
|
2193
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx31(Divider, { className: "mx-0 my-2" }) : null,
|
|
2194
|
+
signedIn && idBase && /* @__PURE__ */ jsx31(
|
|
2038
2195
|
MenuItem,
|
|
2039
2196
|
{
|
|
2040
2197
|
label: "Edit your profile in Estiva ID",
|
|
2041
2198
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
2042
2199
|
}
|
|
2043
2200
|
),
|
|
2044
|
-
onCopyKey && /* @__PURE__ */
|
|
2045
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
2201
|
+
onCopyKey && /* @__PURE__ */ jsx31(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
2202
|
+
idBase && onSignOut && /* @__PURE__ */ jsx31(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
2046
2203
|
] });
|
|
2047
2204
|
}
|
|
2048
2205
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
@@ -2053,13 +2210,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2053
2210
|
to be `relative`, because the panel was positioned against it; the panel
|
|
2054
2211
|
hangs from the trigger and portals now, so a positioning context here
|
|
2055
2212
|
would only be a lie about what this box does. */
|
|
2056
|
-
/* @__PURE__ */
|
|
2213
|
+
/* @__PURE__ */ jsx31("div", { className, children: /* @__PURE__ */ jsx31(
|
|
2057
2214
|
Menu,
|
|
2058
2215
|
{
|
|
2059
2216
|
align: "right",
|
|
2060
2217
|
actionsRef: actions,
|
|
2061
2218
|
className: "w-72",
|
|
2062
|
-
trigger: /* @__PURE__ */
|
|
2219
|
+
trigger: /* @__PURE__ */ jsx31(
|
|
2063
2220
|
PersonTrigger,
|
|
2064
2221
|
{
|
|
2065
2222
|
name: me.name,
|
|
@@ -2070,7 +2227,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2070
2227
|
"aria-label": compact ? "Account menu" : void 0
|
|
2071
2228
|
}
|
|
2072
2229
|
),
|
|
2073
|
-
children: /* @__PURE__ */
|
|
2230
|
+
children: /* @__PURE__ */ jsx31(
|
|
2074
2231
|
IdentityRows,
|
|
2075
2232
|
{
|
|
2076
2233
|
me,
|
|
@@ -2088,14 +2245,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2088
2245
|
);
|
|
2089
2246
|
}
|
|
2090
2247
|
function Note({ children }) {
|
|
2091
|
-
return /* @__PURE__ */
|
|
2248
|
+
return /* @__PURE__ */ jsx31("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
2092
2249
|
}
|
|
2093
2250
|
|
|
2094
2251
|
// src/FilePicker.tsx
|
|
2095
2252
|
import { forwardRef } from "react";
|
|
2096
|
-
import { jsx as
|
|
2253
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
2097
2254
|
var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
2098
|
-
return /* @__PURE__ */
|
|
2255
|
+
return /* @__PURE__ */ jsx32(
|
|
2099
2256
|
"input",
|
|
2100
2257
|
{
|
|
2101
2258
|
ref,
|
|
@@ -2116,7 +2273,7 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
|
2116
2273
|
// src/Select.tsx
|
|
2117
2274
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
2118
2275
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
2119
|
-
import { jsx as
|
|
2276
|
+
import { jsx as jsx33, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2120
2277
|
var GAP4 = 4;
|
|
2121
2278
|
var VIEWPORT_PAD4 = 8;
|
|
2122
2279
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
|
|
@@ -2124,7 +2281,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2124
2281
|
const held = Boolean(disabledReason);
|
|
2125
2282
|
const trigger = (
|
|
2126
2283
|
// @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
|
|
2127
|
-
/* @__PURE__ */
|
|
2284
|
+
/* @__PURE__ */ jsxs24(
|
|
2128
2285
|
BaseSelect.Trigger,
|
|
2129
2286
|
{
|
|
2130
2287
|
"aria-label": ariaLabel,
|
|
@@ -2154,21 +2311,21 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2154
2311
|
className
|
|
2155
2312
|
),
|
|
2156
2313
|
children: [
|
|
2157
|
-
/* @__PURE__ */
|
|
2158
|
-
selected?.leading && /* @__PURE__ */
|
|
2159
|
-
/* @__PURE__ */
|
|
2314
|
+
/* @__PURE__ */ jsxs24("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
2315
|
+
selected?.leading && /* @__PURE__ */ jsx33("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
2316
|
+
/* @__PURE__ */ jsx33(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
2160
2317
|
] }),
|
|
2161
|
-
/* @__PURE__ */
|
|
2318
|
+
/* @__PURE__ */ jsx33(
|
|
2162
2319
|
BaseSelect.Icon,
|
|
2163
2320
|
{
|
|
2164
|
-
render: /* @__PURE__ */
|
|
2321
|
+
render: /* @__PURE__ */ jsx33(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2165
2322
|
}
|
|
2166
2323
|
)
|
|
2167
2324
|
]
|
|
2168
2325
|
}
|
|
2169
2326
|
)
|
|
2170
2327
|
);
|
|
2171
|
-
return /* @__PURE__ */
|
|
2328
|
+
return /* @__PURE__ */ jsxs24(
|
|
2172
2329
|
BaseSelect.Root,
|
|
2173
2330
|
{
|
|
2174
2331
|
value,
|
|
@@ -2180,8 +2337,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2180
2337
|
disabled: disabled && !held,
|
|
2181
2338
|
modal: false,
|
|
2182
2339
|
children: [
|
|
2183
|
-
held ? /* @__PURE__ */
|
|
2184
|
-
/* @__PURE__ */
|
|
2340
|
+
held ? /* @__PURE__ */ jsx33(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
|
|
2341
|
+
/* @__PURE__ */ jsx33(BaseSelect.Portal, { children: /* @__PURE__ */ jsx33(
|
|
2185
2342
|
BaseSelect.Positioner,
|
|
2186
2343
|
{
|
|
2187
2344
|
side: "bottom",
|
|
@@ -2190,25 +2347,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2190
2347
|
collisionPadding: VIEWPORT_PAD4,
|
|
2191
2348
|
alignItemWithTrigger: false,
|
|
2192
2349
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2193
|
-
children: /* @__PURE__ */
|
|
2350
|
+
children: /* @__PURE__ */ jsx33(
|
|
2194
2351
|
BaseSelect.Popup,
|
|
2195
2352
|
{
|
|
2196
|
-
render: /* @__PURE__ */
|
|
2353
|
+
render: /* @__PURE__ */ jsx33(MenuPanel, {}),
|
|
2197
2354
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
2198
|
-
children: /* @__PURE__ */
|
|
2355
|
+
children: /* @__PURE__ */ jsx33(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs24(
|
|
2199
2356
|
BaseSelect.Item,
|
|
2200
2357
|
{
|
|
2201
2358
|
value: option.value,
|
|
2202
2359
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
2203
2360
|
children: [
|
|
2204
|
-
/* @__PURE__ */
|
|
2205
|
-
option.leading && /* @__PURE__ */
|
|
2206
|
-
/* @__PURE__ */
|
|
2361
|
+
/* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2362
|
+
option.leading && /* @__PURE__ */ jsx33("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
2363
|
+
/* @__PURE__ */ jsx33(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
|
|
2207
2364
|
] }),
|
|
2208
|
-
/* @__PURE__ */
|
|
2365
|
+
/* @__PURE__ */ jsx33(
|
|
2209
2366
|
BaseSelect.ItemIndicator,
|
|
2210
2367
|
{
|
|
2211
|
-
render: /* @__PURE__ */
|
|
2368
|
+
render: /* @__PURE__ */ jsx33(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2212
2369
|
}
|
|
2213
2370
|
)
|
|
2214
2371
|
]
|
|
@@ -2227,9 +2384,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2227
2384
|
// src/TextInput.tsx
|
|
2228
2385
|
import { forwardRef as forwardRef2 } from "react";
|
|
2229
2386
|
import { Input } from "@base-ui/react/input";
|
|
2230
|
-
import { jsx as
|
|
2387
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2231
2388
|
var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
|
|
2232
|
-
return /* @__PURE__ */
|
|
2389
|
+
return /* @__PURE__ */ jsx34(
|
|
2233
2390
|
Input,
|
|
2234
2391
|
{
|
|
2235
2392
|
ref,
|
|
@@ -2255,13 +2412,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
|
|
|
2255
2412
|
// src/Textarea.tsx
|
|
2256
2413
|
import { forwardRef as forwardRef3 } from "react";
|
|
2257
2414
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
2258
|
-
import { jsx as
|
|
2415
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
2259
2416
|
var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
2260
|
-
return /* @__PURE__ */
|
|
2417
|
+
return /* @__PURE__ */ jsx35(
|
|
2261
2418
|
BaseField3.Control,
|
|
2262
2419
|
{
|
|
2263
2420
|
ref,
|
|
2264
|
-
render: /* @__PURE__ */
|
|
2421
|
+
render: /* @__PURE__ */ jsx35("textarea", {}),
|
|
2265
2422
|
className: cn(
|
|
2266
2423
|
// The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
|
|
2267
2424
|
// "aren't there hover states in text input and text area?"). Focus comes after hover in
|
|
@@ -2290,33 +2447,33 @@ import { IconX as IconX5 } from "@tabler/icons-react";
|
|
|
2290
2447
|
|
|
2291
2448
|
// src/ContainerHeader.tsx
|
|
2292
2449
|
import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
|
|
2293
|
-
import { jsx as
|
|
2450
|
+
import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2294
2451
|
function ContainerHeader({ title, chevron = false, actions, className }) {
|
|
2295
2452
|
const text = typeof title === "string";
|
|
2296
|
-
return /* @__PURE__ */
|
|
2297
|
-
/* @__PURE__ */
|
|
2298
|
-
text ? /* @__PURE__ */
|
|
2299
|
-
chevron && /* @__PURE__ */
|
|
2453
|
+
return /* @__PURE__ */ jsxs25("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: [
|
|
2454
|
+
/* @__PURE__ */ jsx36("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs25("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
|
|
2455
|
+
text ? /* @__PURE__ */ jsx36("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx36("div", { className: "min-w-0 flex-1", children: title }),
|
|
2456
|
+
chevron && /* @__PURE__ */ jsx36(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2300
2457
|
] }) }),
|
|
2301
|
-
actions && /* @__PURE__ */
|
|
2458
|
+
actions && /* @__PURE__ */ jsx36("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx36("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
|
|
2302
2459
|
] });
|
|
2303
2460
|
}
|
|
2304
2461
|
|
|
2305
2462
|
// src/DialogShell.tsx
|
|
2306
|
-
import { jsx as
|
|
2463
|
+
import { jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2307
2464
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
|
|
2308
2465
|
const Parts = alert ? AlertDialog : Dialog3;
|
|
2309
2466
|
const popupRef = useRef6(null);
|
|
2310
|
-
return /* @__PURE__ */
|
|
2467
|
+
return /* @__PURE__ */ jsx37(
|
|
2311
2468
|
Parts.Root,
|
|
2312
2469
|
{
|
|
2313
2470
|
open: true,
|
|
2314
2471
|
onOpenChange: (open) => {
|
|
2315
2472
|
if (!open) onClose();
|
|
2316
2473
|
},
|
|
2317
|
-
children: /* @__PURE__ */
|
|
2318
|
-
/* @__PURE__ */
|
|
2319
|
-
/* @__PURE__ */
|
|
2474
|
+
children: /* @__PURE__ */ jsxs26(Parts.Portal, { children: [
|
|
2475
|
+
/* @__PURE__ */ jsx37(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
2476
|
+
/* @__PURE__ */ jsx37("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs26(
|
|
2320
2477
|
Parts.Popup,
|
|
2321
2478
|
{
|
|
2322
2479
|
ref: popupRef,
|
|
@@ -2325,10 +2482,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2325
2482
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
2326
2483
|
style: { width },
|
|
2327
2484
|
children: [
|
|
2328
|
-
/* @__PURE__ */
|
|
2485
|
+
/* @__PURE__ */ jsx37(
|
|
2329
2486
|
ContainerHeader,
|
|
2330
2487
|
{
|
|
2331
|
-
title: headerContent ?? /* @__PURE__ */
|
|
2488
|
+
title: headerContent ?? /* @__PURE__ */ jsx37(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx37("span", {}), children: title }),
|
|
2332
2489
|
actions: (
|
|
2333
2490
|
/*
|
|
2334
2491
|
The ✕ IS the `Close` part now, rather than a button that calls
|
|
@@ -2342,10 +2499,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2342
2499
|
so the ✕, Escape and the outside press are one path with one
|
|
2343
2500
|
reason attached, instead of one of the three going around.
|
|
2344
2501
|
*/
|
|
2345
|
-
/* @__PURE__ */
|
|
2502
|
+
/* @__PURE__ */ jsx37(
|
|
2346
2503
|
Parts.Close,
|
|
2347
2504
|
{
|
|
2348
|
-
render: /* @__PURE__ */
|
|
2505
|
+
render: /* @__PURE__ */ jsx37(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx37(IconX5, { size: 16, stroke: 1.5 }) })
|
|
2349
2506
|
}
|
|
2350
2507
|
)
|
|
2351
2508
|
)
|
|
@@ -2353,9 +2510,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2353
2510
|
),
|
|
2354
2511
|
bodyMaxHeight ? (
|
|
2355
2512
|
// The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
|
|
2356
|
-
/* @__PURE__ */
|
|
2357
|
-
) : /* @__PURE__ */
|
|
2358
|
-
footer != null && /* @__PURE__ */
|
|
2513
|
+
/* @__PURE__ */ jsx37("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx37(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
|
|
2514
|
+
) : /* @__PURE__ */ jsx37("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
2515
|
+
footer != null && /* @__PURE__ */ jsx37("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
2359
2516
|
]
|
|
2360
2517
|
}
|
|
2361
2518
|
) })
|
|
@@ -2365,7 +2522,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2365
2522
|
}
|
|
2366
2523
|
|
|
2367
2524
|
// src/ConfirmDialog.tsx
|
|
2368
|
-
import { Fragment as
|
|
2525
|
+
import { Fragment as Fragment8, jsx as jsx38, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2369
2526
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
2370
2527
|
const [busy, setBusy] = useState4(false);
|
|
2371
2528
|
const confirm = async () => {
|
|
@@ -2377,17 +2534,17 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2377
2534
|
setBusy(false);
|
|
2378
2535
|
}
|
|
2379
2536
|
};
|
|
2380
|
-
return /* @__PURE__ */
|
|
2537
|
+
return /* @__PURE__ */ jsx38(
|
|
2381
2538
|
DialogShell,
|
|
2382
2539
|
{
|
|
2383
2540
|
alert: true,
|
|
2384
2541
|
title,
|
|
2385
2542
|
onClose,
|
|
2386
|
-
footer: /* @__PURE__ */
|
|
2387
|
-
/* @__PURE__ */
|
|
2388
|
-
/* @__PURE__ */
|
|
2543
|
+
footer: /* @__PURE__ */ jsxs27(Fragment8, { children: [
|
|
2544
|
+
/* @__PURE__ */ jsx38(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
2545
|
+
/* @__PURE__ */ jsx38(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
2389
2546
|
] }),
|
|
2390
|
-
children: /* @__PURE__ */
|
|
2547
|
+
children: /* @__PURE__ */ jsx38("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
|
|
2391
2548
|
}
|
|
2392
2549
|
);
|
|
2393
2550
|
}
|
|
@@ -2396,7 +2553,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2396
2553
|
import { useEffect as useEffect3, useRef as useRef7, useState as useState5 } from "react";
|
|
2397
2554
|
import { Field as BaseField4 } from "@base-ui/react/field";
|
|
2398
2555
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
2399
|
-
import { jsx as
|
|
2556
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
2400
2557
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
2401
2558
|
const [editing, setEditing] = useState5(false);
|
|
2402
2559
|
const [draft, setDraft] = useState5(value);
|
|
@@ -2454,7 +2611,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2454
2611
|
written and never read. Read-only, this is a line of text: whatever
|
|
2455
2612
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
2456
2613
|
*/
|
|
2457
|
-
/* @__PURE__ */
|
|
2614
|
+
/* @__PURE__ */ jsx39(
|
|
2458
2615
|
"div",
|
|
2459
2616
|
{
|
|
2460
2617
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -2464,11 +2621,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2464
2621
|
);
|
|
2465
2622
|
}
|
|
2466
2623
|
if (editing) {
|
|
2467
|
-
return multiline ? /* @__PURE__ */
|
|
2624
|
+
return multiline ? /* @__PURE__ */ jsx39(
|
|
2468
2625
|
BaseField4.Control,
|
|
2469
2626
|
{
|
|
2470
2627
|
ref: fieldRef,
|
|
2471
|
-
render: /* @__PURE__ */
|
|
2628
|
+
render: /* @__PURE__ */ jsx39("textarea", { rows: 4 }),
|
|
2472
2629
|
"aria-label": label,
|
|
2473
2630
|
value: draft,
|
|
2474
2631
|
disabled: busy,
|
|
@@ -2477,7 +2634,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2477
2634
|
onBlur: () => void commit(),
|
|
2478
2635
|
className: fieldClass
|
|
2479
2636
|
}
|
|
2480
|
-
) : /* @__PURE__ */
|
|
2637
|
+
) : /* @__PURE__ */ jsx39(
|
|
2481
2638
|
Input2,
|
|
2482
2639
|
{
|
|
2483
2640
|
ref: fieldRef,
|
|
@@ -2491,7 +2648,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2491
2648
|
}
|
|
2492
2649
|
);
|
|
2493
2650
|
}
|
|
2494
|
-
return /* @__PURE__ */
|
|
2651
|
+
return /* @__PURE__ */ jsx39(
|
|
2495
2652
|
"button",
|
|
2496
2653
|
{
|
|
2497
2654
|
type: "button",
|
|
@@ -2511,7 +2668,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2511
2668
|
// src/ErrorBoundary.tsx
|
|
2512
2669
|
import { Component } from "react";
|
|
2513
2670
|
import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
|
|
2514
|
-
import { jsx as
|
|
2671
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2515
2672
|
var ErrorBoundary = class extends Component {
|
|
2516
2673
|
state = { hasError: false };
|
|
2517
2674
|
static getDerivedStateFromError() {
|
|
@@ -2522,22 +2679,22 @@ var ErrorBoundary = class extends Component {
|
|
|
2522
2679
|
}
|
|
2523
2680
|
render() {
|
|
2524
2681
|
if (!this.state.hasError) return this.props.children;
|
|
2525
|
-
const message = /* @__PURE__ */
|
|
2682
|
+
const message = /* @__PURE__ */ jsx40(
|
|
2526
2683
|
EmptyState,
|
|
2527
2684
|
{
|
|
2528
|
-
icon: /* @__PURE__ */
|
|
2685
|
+
icon: /* @__PURE__ */ jsx40(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
|
|
2529
2686
|
message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
|
|
2530
2687
|
action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
|
|
2531
2688
|
}
|
|
2532
2689
|
);
|
|
2533
2690
|
if (this.props.frame) return this.props.frame(message);
|
|
2534
|
-
return this.props.fallbackClassName ? /* @__PURE__ */
|
|
2691
|
+
return this.props.fallbackClassName ? /* @__PURE__ */ jsx40("div", { className: this.props.fallbackClassName, children: message }) : message;
|
|
2535
2692
|
}
|
|
2536
2693
|
};
|
|
2537
2694
|
|
|
2538
2695
|
// src/ProgressBar.tsx
|
|
2539
2696
|
import { Progress } from "@base-ui/react/progress";
|
|
2540
|
-
import { jsx as
|
|
2697
|
+
import { jsx as jsx41 } from "react/jsx-runtime";
|
|
2541
2698
|
var TRACK_CLASSES = {
|
|
2542
2699
|
default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
|
|
2543
2700
|
// 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
|
|
@@ -2550,13 +2707,13 @@ var INDICATOR_CLASSES = {
|
|
|
2550
2707
|
function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
2551
2708
|
return (
|
|
2552
2709
|
// `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
|
|
2553
|
-
/* @__PURE__ */
|
|
2710
|
+
/* @__PURE__ */ jsx41(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx41(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx41(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
|
|
2554
2711
|
);
|
|
2555
2712
|
}
|
|
2556
2713
|
|
|
2557
2714
|
// src/Breadcrumb.tsx
|
|
2558
|
-
import { Fragment as
|
|
2559
|
-
import { jsx as
|
|
2715
|
+
import { Fragment as Fragment9, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as useRef8, useState as useState6 } from "react";
|
|
2716
|
+
import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2560
2717
|
function Breadcrumb({ items, className }) {
|
|
2561
2718
|
const navRef = useRef8(null);
|
|
2562
2719
|
const labelRefs = useRef8([]);
|
|
@@ -2576,7 +2733,7 @@ function Breadcrumb({ items, className }) {
|
|
|
2576
2733
|
observer.observe(nav);
|
|
2577
2734
|
return () => observer.disconnect();
|
|
2578
2735
|
}, [measure, items]);
|
|
2579
|
-
return /* @__PURE__ */
|
|
2736
|
+
return /* @__PURE__ */ jsx42("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) => {
|
|
2580
2737
|
const last = index === items.length - 1;
|
|
2581
2738
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
2582
2739
|
const text = cn(
|
|
@@ -2597,27 +2754,27 @@ function Breadcrumb({ items, className }) {
|
|
|
2597
2754
|
// on a box around it, which the link takes them from, rather than
|
|
2598
2755
|
// pushed into it (UIG-9); the link is still the one element that
|
|
2599
2756
|
// truncates and is measured.
|
|
2600
|
-
/* @__PURE__ */
|
|
2601
|
-
) : /* @__PURE__ */
|
|
2602
|
-
return /* @__PURE__ */
|
|
2603
|
-
index > 0 && /* @__PURE__ */
|
|
2604
|
-
item.icon && /* @__PURE__ */
|
|
2757
|
+
/* @__PURE__ */ jsx42("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx42(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
|
|
2758
|
+
) : /* @__PURE__ */ jsx42("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
2759
|
+
return /* @__PURE__ */ jsxs28(Fragment9, { children: [
|
|
2760
|
+
index > 0 && /* @__PURE__ */ jsx42("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
2761
|
+
item.icon && /* @__PURE__ */ jsx42("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
2605
2762
|
truncated.has(index) ? (
|
|
2606
2763
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
2607
2764
|
// must keep truncating inside it, or wrapping it would widen the
|
|
2608
2765
|
// trail and the tooltip would never be needed again.
|
|
2609
|
-
/* @__PURE__ */
|
|
2766
|
+
/* @__PURE__ */ jsx42(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
2610
2767
|
) : crumb
|
|
2611
2768
|
] }, `${item.label}-${index}`);
|
|
2612
2769
|
}) });
|
|
2613
2770
|
}
|
|
2614
2771
|
|
|
2615
2772
|
// src/NavItem.tsx
|
|
2616
|
-
import { jsx as
|
|
2773
|
+
import { jsx as jsx43, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2617
2774
|
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
2618
2775
|
return (
|
|
2619
2776
|
// @estiva-escape(no-copied-look): N5 (Katerina, 24 September: record only): a row that fills on hover, as PersonTrigger's row also does
|
|
2620
|
-
/* @__PURE__ */
|
|
2777
|
+
/* @__PURE__ */ jsxs29(
|
|
2621
2778
|
"a",
|
|
2622
2779
|
{
|
|
2623
2780
|
href,
|
|
@@ -2632,9 +2789,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
2632
2789
|
),
|
|
2633
2790
|
...props,
|
|
2634
2791
|
children: [
|
|
2635
|
-
icon && /* @__PURE__ */
|
|
2636
|
-
/* @__PURE__ */
|
|
2637
|
-
count ? /* @__PURE__ */
|
|
2792
|
+
icon && /* @__PURE__ */ jsx43("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
2793
|
+
/* @__PURE__ */ jsx43("span", { className: "flex-1 truncate", children: label }),
|
|
2794
|
+
count ? /* @__PURE__ */ jsx43(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx43("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
2638
2795
|
]
|
|
2639
2796
|
}
|
|
2640
2797
|
)
|
|
@@ -2644,7 +2801,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
2644
2801
|
// src/Popover.tsx
|
|
2645
2802
|
import { useMemo as useMemo3 } from "react";
|
|
2646
2803
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
2647
|
-
import { jsx as
|
|
2804
|
+
import { jsx as jsx44, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2648
2805
|
var GAP5 = 4;
|
|
2649
2806
|
var VIEWPORT_PAD5 = 8;
|
|
2650
2807
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -2653,7 +2810,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2653
2810
|
if (anchor instanceof Element) return anchor;
|
|
2654
2811
|
return { getBoundingClientRect: () => anchor };
|
|
2655
2812
|
}, [anchor]);
|
|
2656
|
-
return /* @__PURE__ */
|
|
2813
|
+
return /* @__PURE__ */ jsxs30(
|
|
2657
2814
|
BasePopover.Root,
|
|
2658
2815
|
{
|
|
2659
2816
|
open,
|
|
@@ -2661,8 +2818,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2661
2818
|
actionsRef,
|
|
2662
2819
|
modal: false,
|
|
2663
2820
|
children: [
|
|
2664
|
-
trigger && /* @__PURE__ */
|
|
2665
|
-
/* @__PURE__ */
|
|
2821
|
+
trigger && /* @__PURE__ */ jsx44(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
2822
|
+
/* @__PURE__ */ jsx44(BasePopover.Portal, { children: /* @__PURE__ */ jsx44(
|
|
2666
2823
|
BasePopover.Positioner,
|
|
2667
2824
|
{
|
|
2668
2825
|
anchor: anchorTarget,
|
|
@@ -2671,20 +2828,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2671
2828
|
sideOffset: GAP5,
|
|
2672
2829
|
collisionPadding: VIEWPORT_PAD5,
|
|
2673
2830
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2674
|
-
children: /* @__PURE__ */
|
|
2831
|
+
children: /* @__PURE__ */ jsx44(
|
|
2675
2832
|
BasePopover.Popup,
|
|
2676
2833
|
{
|
|
2677
2834
|
"aria-label": ariaLabel,
|
|
2678
2835
|
initialFocus: trigger ? void 0 : false,
|
|
2679
2836
|
finalFocus,
|
|
2680
2837
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
2681
|
-
render: /* @__PURE__ */
|
|
2682
|
-
children: /* @__PURE__ */
|
|
2838
|
+
render: /* @__PURE__ */ jsx44(MenuPanel, {}),
|
|
2839
|
+
children: /* @__PURE__ */ jsx44(
|
|
2683
2840
|
ScrollArea,
|
|
2684
2841
|
{
|
|
2685
2842
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
2686
2843
|
contentClassName: cn("flex flex-col p-2", contentClassName),
|
|
2687
|
-
children: /* @__PURE__ */
|
|
2844
|
+
children: /* @__PURE__ */ jsx44(DividerInPanel.Provider, { value: true, children })
|
|
2688
2845
|
}
|
|
2689
2846
|
)
|
|
2690
2847
|
}
|
|
@@ -2698,9 +2855,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2698
2855
|
|
|
2699
2856
|
// src/Toolbar.tsx
|
|
2700
2857
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
2701
|
-
import { jsx as
|
|
2858
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
2702
2859
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
2703
|
-
const strip = /* @__PURE__ */
|
|
2860
|
+
const strip = /* @__PURE__ */ jsx45(
|
|
2704
2861
|
BaseToolbar.Root,
|
|
2705
2862
|
{
|
|
2706
2863
|
"aria-label": ariaLabel,
|
|
@@ -2711,27 +2868,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
2711
2868
|
}
|
|
2712
2869
|
);
|
|
2713
2870
|
if (!surface) return strip;
|
|
2714
|
-
return /* @__PURE__ */
|
|
2871
|
+
return /* @__PURE__ */ jsx45(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
2715
2872
|
}
|
|
2716
2873
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
2717
|
-
return /* @__PURE__ */
|
|
2874
|
+
return /* @__PURE__ */ jsx45(
|
|
2718
2875
|
BaseToolbar.Button,
|
|
2719
2876
|
{
|
|
2720
2877
|
ref,
|
|
2721
2878
|
disabled: disabled || !!disabledReason,
|
|
2722
2879
|
focusableWhenDisabled: true,
|
|
2723
|
-
render: /* @__PURE__ */
|
|
2880
|
+
render: /* @__PURE__ */ jsx45(IconButton, { disabled, disabledReason, ...props })
|
|
2724
2881
|
}
|
|
2725
2882
|
);
|
|
2726
2883
|
}
|
|
2727
2884
|
function ToolbarLink({ ref, href, ...props }) {
|
|
2728
|
-
return /* @__PURE__ */
|
|
2885
|
+
return /* @__PURE__ */ jsx45(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx45(IconButton, { href, ...props }) });
|
|
2729
2886
|
}
|
|
2730
2887
|
function ToolbarInput({ size, ...props }) {
|
|
2731
|
-
return /* @__PURE__ */
|
|
2888
|
+
return /* @__PURE__ */ jsx45(BaseToolbar.Input, { render: /* @__PURE__ */ jsx45(TextInput, { size }), ...props });
|
|
2732
2889
|
}
|
|
2733
2890
|
function ToolbarSeparator({ className }) {
|
|
2734
|
-
return /* @__PURE__ */
|
|
2891
|
+
return /* @__PURE__ */ jsx45(
|
|
2735
2892
|
BaseToolbar.Separator,
|
|
2736
2893
|
{
|
|
2737
2894
|
orientation: "vertical",
|
|
@@ -2741,9 +2898,9 @@ function ToolbarSeparator({ className }) {
|
|
|
2741
2898
|
}
|
|
2742
2899
|
|
|
2743
2900
|
// src/ReactionPicker.tsx
|
|
2744
|
-
import { jsx as
|
|
2901
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
2745
2902
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
2746
|
-
return /* @__PURE__ */
|
|
2903
|
+
return /* @__PURE__ */ jsx46(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
2747
2904
|
/*
|
|
2748
2905
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
2749
2906
|
would become the toolbar's item and the button inside it would never
|
|
@@ -2753,14 +2910,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2753
2910
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
2754
2911
|
and both say the meaning rather than the glyph.
|
|
2755
2912
|
*/
|
|
2756
|
-
/* @__PURE__ */
|
|
2913
|
+
/* @__PURE__ */ jsx46(
|
|
2757
2914
|
ToolbarButton,
|
|
2758
2915
|
{
|
|
2759
2916
|
"aria-label": option.label,
|
|
2760
2917
|
tooltip: option.label,
|
|
2761
2918
|
onClick: () => onSelect(option.emoji),
|
|
2762
2919
|
className: "size-7",
|
|
2763
|
-
children: /* @__PURE__ */
|
|
2920
|
+
children: /* @__PURE__ */ jsx46("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
2764
2921
|
},
|
|
2765
2922
|
option.emoji
|
|
2766
2923
|
)
|
|
@@ -2769,23 +2926,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2769
2926
|
|
|
2770
2927
|
// src/PreviewCard.tsx
|
|
2771
2928
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
2772
|
-
import { jsx as
|
|
2929
|
+
import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2773
2930
|
var GAP6 = 12;
|
|
2774
2931
|
var VIEWPORT_PAD6 = 8;
|
|
2775
2932
|
var OPEN_DELAY2 = 350;
|
|
2776
2933
|
var CLOSE_DELAY = 200;
|
|
2777
2934
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
2778
|
-
return /* @__PURE__ */
|
|
2779
|
-
/* @__PURE__ */
|
|
2935
|
+
return /* @__PURE__ */ jsxs31(BasePreviewCard.Root, { children: [
|
|
2936
|
+
/* @__PURE__ */ jsx47(
|
|
2780
2937
|
BasePreviewCard.Trigger,
|
|
2781
2938
|
{
|
|
2782
2939
|
delay,
|
|
2783
2940
|
closeDelay,
|
|
2784
|
-
render: /* @__PURE__ */
|
|
2941
|
+
render: /* @__PURE__ */ jsx47("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
2785
2942
|
children
|
|
2786
2943
|
}
|
|
2787
2944
|
),
|
|
2788
|
-
/* @__PURE__ */
|
|
2945
|
+
/* @__PURE__ */ jsx47(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx47(
|
|
2789
2946
|
BasePreviewCard.Positioner,
|
|
2790
2947
|
{
|
|
2791
2948
|
side,
|
|
@@ -2793,12 +2950,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2793
2950
|
sideOffset: GAP6,
|
|
2794
2951
|
collisionPadding: VIEWPORT_PAD6,
|
|
2795
2952
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2796
|
-
children: /* @__PURE__ */
|
|
2953
|
+
children: /* @__PURE__ */ jsx47(
|
|
2797
2954
|
BasePreviewCard.Popup,
|
|
2798
2955
|
{
|
|
2799
2956
|
className: cn("w-[360px] p-0 outline-none", className),
|
|
2800
|
-
render: /* @__PURE__ */
|
|
2801
|
-
children: /* @__PURE__ */
|
|
2957
|
+
render: /* @__PURE__ */ jsx47(MenuPanel, {}),
|
|
2958
|
+
children: /* @__PURE__ */ jsx47(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
2802
2959
|
}
|
|
2803
2960
|
)
|
|
2804
2961
|
}
|
|
@@ -2807,15 +2964,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2807
2964
|
}
|
|
2808
2965
|
|
|
2809
2966
|
// src/Rail.tsx
|
|
2810
|
-
import { jsx as
|
|
2967
|
+
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
2811
2968
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
2812
|
-
return /* @__PURE__ */
|
|
2969
|
+
return /* @__PURE__ */ jsx48("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
2813
2970
|
}
|
|
2814
2971
|
|
|
2815
2972
|
// src/RailItem.tsx
|
|
2816
|
-
import { jsx as
|
|
2973
|
+
import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2817
2974
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
2818
|
-
return /* @__PURE__ */
|
|
2975
|
+
return /* @__PURE__ */ jsxs32(
|
|
2819
2976
|
"a",
|
|
2820
2977
|
{
|
|
2821
2978
|
href,
|
|
@@ -2823,14 +2980,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2823
2980
|
className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
2824
2981
|
...props,
|
|
2825
2982
|
children: [
|
|
2826
|
-
/* @__PURE__ */
|
|
2983
|
+
/* @__PURE__ */ jsx49(
|
|
2827
2984
|
"div",
|
|
2828
2985
|
{
|
|
2829
2986
|
className: cn(
|
|
2830
2987
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
2831
2988
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
2832
2989
|
),
|
|
2833
|
-
children: /* @__PURE__ */
|
|
2990
|
+
children: /* @__PURE__ */ jsx49(
|
|
2834
2991
|
"span",
|
|
2835
2992
|
{
|
|
2836
2993
|
className: cn(
|
|
@@ -2842,27 +2999,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2842
2999
|
)
|
|
2843
3000
|
}
|
|
2844
3001
|
),
|
|
2845
|
-
/* @__PURE__ */
|
|
3002
|
+
/* @__PURE__ */ jsx49("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
2846
3003
|
]
|
|
2847
3004
|
}
|
|
2848
3005
|
);
|
|
2849
3006
|
}
|
|
2850
3007
|
|
|
2851
|
-
// src/Sidebar.tsx
|
|
2852
|
-
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
2853
|
-
function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
|
|
2854
|
-
return /* @__PURE__ */ jsx48(
|
|
2855
|
-
"nav",
|
|
2856
|
-
{
|
|
2857
|
-
"aria-label": ariaLabel,
|
|
2858
|
-
className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
|
|
2859
|
-
children: /* @__PURE__ */ jsx48(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
|
|
2860
|
-
}
|
|
2861
|
-
);
|
|
2862
|
-
}
|
|
2863
|
-
|
|
2864
3008
|
// src/Property.tsx
|
|
2865
|
-
import { jsx as
|
|
3009
|
+
import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2866
3010
|
var VALUE_CLASSES = "contents";
|
|
2867
3011
|
function Property({ label, layout = "row", children, className }) {
|
|
2868
3012
|
if (layout === "stacked") {
|
|
@@ -2870,25 +3014,25 @@ function Property({ label, layout = "row", children, className }) {
|
|
|
2870
3014
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
2871
3015
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
2872
3016
|
// 6px, and unifying means the bigger, calmer one.
|
|
2873
|
-
/* @__PURE__ */
|
|
2874
|
-
/* @__PURE__ */
|
|
2875
|
-
/* @__PURE__ */
|
|
3017
|
+
/* @__PURE__ */ jsxs33("dl", { className: cn("flex flex-col gap-3", className), children: [
|
|
3018
|
+
/* @__PURE__ */ jsx50("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
|
|
3019
|
+
/* @__PURE__ */ jsx50("dd", { className: VALUE_CLASSES, children })
|
|
2876
3020
|
] })
|
|
2877
3021
|
);
|
|
2878
3022
|
}
|
|
2879
|
-
return /* @__PURE__ */
|
|
2880
|
-
/* @__PURE__ */
|
|
2881
|
-
/* @__PURE__ */
|
|
3023
|
+
return /* @__PURE__ */ jsxs33("dl", { className: cn("flex items-center gap-2", className), children: [
|
|
3024
|
+
/* @__PURE__ */ jsx50("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
3025
|
+
/* @__PURE__ */ jsx50("dd", { className: VALUE_CLASSES, children })
|
|
2882
3026
|
] });
|
|
2883
3027
|
}
|
|
2884
3028
|
|
|
2885
3029
|
// src/Reaction.tsx
|
|
2886
3030
|
import { Toggle } from "@base-ui/react/toggle";
|
|
2887
|
-
import { jsx as
|
|
3031
|
+
import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2888
3032
|
function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
2889
3033
|
return (
|
|
2890
3034
|
// @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
|
|
2891
|
-
/* @__PURE__ */
|
|
3035
|
+
/* @__PURE__ */ jsxs34(
|
|
2892
3036
|
Toggle,
|
|
2893
3037
|
{
|
|
2894
3038
|
pressed,
|
|
@@ -2910,8 +3054,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
2910
3054
|
),
|
|
2911
3055
|
...props,
|
|
2912
3056
|
children: [
|
|
2913
|
-
/* @__PURE__ */
|
|
2914
|
-
/* @__PURE__ */
|
|
3057
|
+
/* @__PURE__ */ jsx51("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
|
|
3058
|
+
/* @__PURE__ */ jsx51("span", { className: CHIP_TEXT_CLASSES, children: count })
|
|
2915
3059
|
]
|
|
2916
3060
|
}
|
|
2917
3061
|
)
|
|
@@ -2921,9 +3065,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
2921
3065
|
// src/SearchInput.tsx
|
|
2922
3066
|
import "react";
|
|
2923
3067
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
2924
|
-
import { jsx as
|
|
3068
|
+
import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2925
3069
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
2926
|
-
return /* @__PURE__ */
|
|
3070
|
+
return /* @__PURE__ */ jsxs35(
|
|
2927
3071
|
"div",
|
|
2928
3072
|
{
|
|
2929
3073
|
className: cn(
|
|
@@ -2935,7 +3079,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2935
3079
|
className
|
|
2936
3080
|
),
|
|
2937
3081
|
children: [
|
|
2938
|
-
/* @__PURE__ */
|
|
3082
|
+
/* @__PURE__ */ jsx52(
|
|
2939
3083
|
Input3,
|
|
2940
3084
|
{
|
|
2941
3085
|
className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
|
|
@@ -2943,7 +3087,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2943
3087
|
...props
|
|
2944
3088
|
}
|
|
2945
3089
|
),
|
|
2946
|
-
shortcut && /* @__PURE__ */
|
|
3090
|
+
shortcut && /* @__PURE__ */ jsx52(Kbd, { children: shortcut })
|
|
2947
3091
|
]
|
|
2948
3092
|
}
|
|
2949
3093
|
);
|
|
@@ -2952,17 +3096,17 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2952
3096
|
// src/SectionHeader.tsx
|
|
2953
3097
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
2954
3098
|
import { useRender } from "@base-ui/react/use-render";
|
|
2955
|
-
import { Fragment as
|
|
3099
|
+
import { Fragment as Fragment10, jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2956
3100
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", render, className }) {
|
|
2957
3101
|
const titleElement = useRender({
|
|
2958
|
-
render: render ?? (chevron ? /* @__PURE__ */
|
|
3102
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx53("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx53("span", {})),
|
|
2959
3103
|
props: {
|
|
2960
3104
|
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
2961
3105
|
// whole row up to the actions is the hit target, as it was when the
|
|
2962
3106
|
// row itself carried the click.
|
|
2963
3107
|
className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
|
|
2964
|
-
children: /* @__PURE__ */
|
|
2965
|
-
chevron && /* @__PURE__ */
|
|
3108
|
+
children: /* @__PURE__ */ jsxs36(Fragment10, { children: [
|
|
3109
|
+
chevron && /* @__PURE__ */ jsx53(
|
|
2966
3110
|
IconChevronRight2,
|
|
2967
3111
|
{
|
|
2968
3112
|
size: 12,
|
|
@@ -2970,11 +3114,11 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2970
3114
|
className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
|
|
2971
3115
|
}
|
|
2972
3116
|
),
|
|
2973
|
-
/* @__PURE__ */
|
|
3117
|
+
/* @__PURE__ */ jsx53(SectionLabel, { children: title })
|
|
2974
3118
|
] })
|
|
2975
3119
|
}
|
|
2976
3120
|
});
|
|
2977
|
-
return /* @__PURE__ */
|
|
3121
|
+
return /* @__PURE__ */ jsxs36(
|
|
2978
3122
|
"div",
|
|
2979
3123
|
{
|
|
2980
3124
|
className: cn(
|
|
@@ -2987,15 +3131,15 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2987
3131
|
),
|
|
2988
3132
|
children: [
|
|
2989
3133
|
titleElement,
|
|
2990
|
-
trailing != null && /* @__PURE__ */
|
|
2991
|
-
actions && actions.length > 0 && /* @__PURE__ */
|
|
3134
|
+
trailing != null && /* @__PURE__ */ jsx53("div", { className: "flex shrink-0 items-center", children: trailing }),
|
|
3135
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx53(
|
|
2992
3136
|
"div",
|
|
2993
3137
|
{
|
|
2994
3138
|
className: cn(
|
|
2995
3139
|
"-mr-1 flex shrink-0 items-center gap-1",
|
|
2996
3140
|
showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
2997
3141
|
),
|
|
2998
|
-
children: actions.map((action) => /* @__PURE__ */
|
|
3142
|
+
children: actions.map((action) => /* @__PURE__ */ jsx53(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
|
|
2999
3143
|
}
|
|
3000
3144
|
)
|
|
3001
3145
|
]
|
|
@@ -3004,35 +3148,35 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
3004
3148
|
}
|
|
3005
3149
|
|
|
3006
3150
|
// src/Panel.tsx
|
|
3007
|
-
import { jsx as
|
|
3151
|
+
import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3008
3152
|
function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
|
|
3009
|
-
return /* @__PURE__ */
|
|
3010
|
-
/* @__PURE__ */
|
|
3153
|
+
return /* @__PURE__ */ jsxs37("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
|
|
3154
|
+
/* @__PURE__ */ jsx54(ContainerHeader, { title, chevron, actions }),
|
|
3011
3155
|
broken ? (
|
|
3012
3156
|
// The message takes the room the body had and centres itself in it.
|
|
3013
|
-
/* @__PURE__ */
|
|
3014
|
-
) : /* @__PURE__ */
|
|
3015
|
-
!broken && footer && /* @__PURE__ */
|
|
3157
|
+
/* @__PURE__ */ jsx54("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
|
|
3158
|
+
) : /* @__PURE__ */ jsx54(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
|
|
3159
|
+
!broken && footer && /* @__PURE__ */ jsx54("div", { className: "shrink-0", children: footer })
|
|
3016
3160
|
] });
|
|
3017
3161
|
}
|
|
3018
3162
|
function Panel(props) {
|
|
3019
|
-
return /* @__PURE__ */
|
|
3163
|
+
return /* @__PURE__ */ jsx54(
|
|
3020
3164
|
ErrorBoundary,
|
|
3021
3165
|
{
|
|
3022
3166
|
label: "panel",
|
|
3023
3167
|
frame: (message) => (
|
|
3024
3168
|
// Only the name comes back with the message: the actions and the footer may be what threw.
|
|
3025
|
-
/* @__PURE__ */
|
|
3169
|
+
/* @__PURE__ */ jsx54(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
|
|
3026
3170
|
),
|
|
3027
|
-
children: /* @__PURE__ */
|
|
3171
|
+
children: /* @__PURE__ */ jsx54(Frame, { ...props })
|
|
3028
3172
|
}
|
|
3029
3173
|
);
|
|
3030
3174
|
}
|
|
3031
3175
|
|
|
3032
3176
|
// src/ListColumn.tsx
|
|
3033
|
-
import { jsx as
|
|
3177
|
+
import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3034
3178
|
function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
|
|
3035
|
-
return /* @__PURE__ */
|
|
3179
|
+
return /* @__PURE__ */ jsxs38(
|
|
3036
3180
|
"div",
|
|
3037
3181
|
{
|
|
3038
3182
|
className: cn(
|
|
@@ -3043,26 +3187,26 @@ function Column({ title, chevron = false, actions, above, collapsed = false, chi
|
|
|
3043
3187
|
),
|
|
3044
3188
|
"data-collapsed": collapsed || void 0,
|
|
3045
3189
|
children: [
|
|
3046
|
-
/* @__PURE__ */
|
|
3190
|
+
/* @__PURE__ */ jsx55(ContainerHeader, { title, chevron, actions }),
|
|
3047
3191
|
above,
|
|
3048
3192
|
broken ? (
|
|
3049
3193
|
// The message takes the room the list had and centres itself in it (Katerina, 19 September).
|
|
3050
|
-
/* @__PURE__ */
|
|
3051
|
-
) : /* @__PURE__ */
|
|
3194
|
+
/* @__PURE__ */ jsx55("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
|
|
3195
|
+
) : /* @__PURE__ */ jsx55(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
|
|
3052
3196
|
]
|
|
3053
3197
|
}
|
|
3054
3198
|
);
|
|
3055
3199
|
}
|
|
3056
3200
|
function ListColumn(props) {
|
|
3057
|
-
return /* @__PURE__ */
|
|
3201
|
+
return /* @__PURE__ */ jsx55(
|
|
3058
3202
|
ErrorBoundary,
|
|
3059
3203
|
{
|
|
3060
3204
|
label: "list panel",
|
|
3061
3205
|
frame: (message) => (
|
|
3062
3206
|
// Only the name comes back with the message: the actions and the row above may be what threw.
|
|
3063
|
-
/* @__PURE__ */
|
|
3207
|
+
/* @__PURE__ */ jsx55(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
|
|
3064
3208
|
),
|
|
3065
|
-
children: /* @__PURE__ */
|
|
3209
|
+
children: /* @__PURE__ */ jsx55(Column, { ...props })
|
|
3066
3210
|
}
|
|
3067
3211
|
);
|
|
3068
3212
|
}
|
|
@@ -3070,7 +3214,7 @@ function ListColumn(props) {
|
|
|
3070
3214
|
// src/CollapsibleSection.tsx
|
|
3071
3215
|
import { useState as useState7 } from "react";
|
|
3072
3216
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
3073
|
-
import { jsx as
|
|
3217
|
+
import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3074
3218
|
var OPEN = "open";
|
|
3075
3219
|
var CLOSED = "closed";
|
|
3076
3220
|
function readStored(key) {
|
|
@@ -3097,14 +3241,14 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
3097
3241
|
writeStored(storageKey, next);
|
|
3098
3242
|
onOpenChange?.(next);
|
|
3099
3243
|
};
|
|
3100
|
-
return /* @__PURE__ */
|
|
3101
|
-
/* @__PURE__ */
|
|
3102
|
-
/* @__PURE__ */
|
|
3244
|
+
return /* @__PURE__ */ jsxs39(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
3245
|
+
/* @__PURE__ */ jsx56(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx56(Collapsible.Trigger, {}) }),
|
|
3246
|
+
/* @__PURE__ */ jsx56(
|
|
3103
3247
|
Collapsible.Panel,
|
|
3104
3248
|
{
|
|
3105
3249
|
hiddenUntilFound: true,
|
|
3106
3250
|
className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
|
|
3107
|
-
children: /* @__PURE__ */
|
|
3251
|
+
children: /* @__PURE__ */ jsx56("div", { className: cn("flex flex-col", contentClassName), children })
|
|
3108
3252
|
}
|
|
3109
3253
|
)
|
|
3110
3254
|
] });
|
|
@@ -3112,9 +3256,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
3112
3256
|
|
|
3113
3257
|
// src/Tabs.tsx
|
|
3114
3258
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
3115
|
-
import { jsx as
|
|
3259
|
+
import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3116
3260
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
3117
|
-
return /* @__PURE__ */
|
|
3261
|
+
return /* @__PURE__ */ jsx57(
|
|
3118
3262
|
BaseTabs.Root,
|
|
3119
3263
|
{
|
|
3120
3264
|
value: active,
|
|
@@ -3122,14 +3266,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3122
3266
|
if (details.reason === "none") onChange(value);
|
|
3123
3267
|
},
|
|
3124
3268
|
className,
|
|
3125
|
-
children: /* @__PURE__ */
|
|
3269
|
+
children: /* @__PURE__ */ jsx57(
|
|
3126
3270
|
BaseTabs.List,
|
|
3127
3271
|
{
|
|
3128
3272
|
activateOnFocus: true,
|
|
3129
3273
|
"aria-label": aria["aria-label"],
|
|
3130
3274
|
"aria-labelledby": aria["aria-labelledby"],
|
|
3131
3275
|
className: "flex items-center gap-2",
|
|
3132
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
3276
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs40(
|
|
3133
3277
|
BaseTabs.Tab,
|
|
3134
3278
|
{
|
|
3135
3279
|
value: tab.id,
|
|
@@ -3142,9 +3286,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3142
3286
|
),
|
|
3143
3287
|
children: [
|
|
3144
3288
|
tab.icon,
|
|
3145
|
-
/* @__PURE__ */
|
|
3289
|
+
/* @__PURE__ */ jsxs40("span", { className: "flex items-baseline", children: [
|
|
3146
3290
|
tab.label,
|
|
3147
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
3291
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx57("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
3148
3292
|
] })
|
|
3149
3293
|
]
|
|
3150
3294
|
},
|
|
@@ -3157,10 +3301,10 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3157
3301
|
}
|
|
3158
3302
|
|
|
3159
3303
|
// src/Toast.tsx
|
|
3160
|
-
import { createContext as
|
|
3304
|
+
import { createContext as createContext6, useContext as useContext6, useMemo as useMemo4 } from "react";
|
|
3161
3305
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
3162
3306
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
3163
|
-
import { jsx as
|
|
3307
|
+
import { jsx as jsx58, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3164
3308
|
var SURFACE_STYLES = {
|
|
3165
3309
|
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",
|
|
3166
3310
|
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",
|
|
@@ -3196,19 +3340,19 @@ var pillClassName = (type, hasAction, className) => cn(
|
|
|
3196
3340
|
);
|
|
3197
3341
|
function LeadingIcon({ type }) {
|
|
3198
3342
|
const Icon = ICONS[type];
|
|
3199
|
-
return /* @__PURE__ */
|
|
3343
|
+
return /* @__PURE__ */ jsx58(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
3200
3344
|
}
|
|
3201
3345
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
3202
3346
|
const hasAction = !!(actionLabel && onAction);
|
|
3203
|
-
return /* @__PURE__ */
|
|
3204
|
-
/* @__PURE__ */
|
|
3205
|
-
leadingIcon && /* @__PURE__ */
|
|
3206
|
-
/* @__PURE__ */
|
|
3347
|
+
return /* @__PURE__ */ jsxs41("div", { className: pillClassName(type, hasAction, className), children: [
|
|
3348
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3349
|
+
leadingIcon && /* @__PURE__ */ jsx58(LeadingIcon, { type }),
|
|
3350
|
+
/* @__PURE__ */ jsx58("span", { className: LABEL_CLASSES, children: label })
|
|
3207
3351
|
] }),
|
|
3208
|
-
hasAction && /* @__PURE__ */
|
|
3352
|
+
hasAction && /* @__PURE__ */ jsx58(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
3209
3353
|
] });
|
|
3210
3354
|
}
|
|
3211
|
-
var ToastContext =
|
|
3355
|
+
var ToastContext = createContext6(null);
|
|
3212
3356
|
var VISIBLE_TOASTS = 3;
|
|
3213
3357
|
function ToastProvider({ children }) {
|
|
3214
3358
|
const manager = useMemo4(() => BaseToast.createToastManager(), []);
|
|
@@ -3226,9 +3370,9 @@ function ToastProvider({ children }) {
|
|
|
3226
3370
|
}),
|
|
3227
3371
|
[manager]
|
|
3228
3372
|
);
|
|
3229
|
-
return /* @__PURE__ */
|
|
3373
|
+
return /* @__PURE__ */ jsx58(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs41(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
3230
3374
|
children,
|
|
3231
|
-
/* @__PURE__ */
|
|
3375
|
+
/* @__PURE__ */ jsx58(BaseToast.Portal, { children: /* @__PURE__ */ jsx58(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx58(ToastList, {}) }) })
|
|
3232
3376
|
] }) });
|
|
3233
3377
|
}
|
|
3234
3378
|
function ToastList() {
|
|
@@ -3236,25 +3380,25 @@ function ToastList() {
|
|
|
3236
3380
|
return toasts.map((toast) => {
|
|
3237
3381
|
const type = toast.type ?? "neutral";
|
|
3238
3382
|
const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
|
|
3239
|
-
return /* @__PURE__ */
|
|
3383
|
+
return /* @__PURE__ */ jsxs41(
|
|
3240
3384
|
BaseToast.Root,
|
|
3241
3385
|
{
|
|
3242
3386
|
toast,
|
|
3243
3387
|
swipeDirection: ["left", "down"],
|
|
3244
3388
|
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
3245
3389
|
children: [
|
|
3246
|
-
/* @__PURE__ */
|
|
3247
|
-
leadingIcon && /* @__PURE__ */
|
|
3248
|
-
/* @__PURE__ */
|
|
3390
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3391
|
+
leadingIcon && /* @__PURE__ */ jsx58(LeadingIcon, { type }),
|
|
3392
|
+
/* @__PURE__ */ jsx58(BaseToast.Title, { render: /* @__PURE__ */ jsx58("span", {}), className: LABEL_CLASSES })
|
|
3249
3393
|
] }),
|
|
3250
|
-
actionLabel && /* @__PURE__ */
|
|
3394
|
+
actionLabel && /* @__PURE__ */ jsx58(
|
|
3251
3395
|
BaseToast.Action,
|
|
3252
3396
|
{
|
|
3253
3397
|
onClick: () => {
|
|
3254
3398
|
onAction?.();
|
|
3255
3399
|
close(toast.id);
|
|
3256
3400
|
},
|
|
3257
|
-
render: /* @__PURE__ */
|
|
3401
|
+
render: /* @__PURE__ */ jsx58(Button, { variant: "outlined", size: "small", children: actionLabel })
|
|
3258
3402
|
}
|
|
3259
3403
|
)
|
|
3260
3404
|
]
|
|
@@ -3264,7 +3408,7 @@ function ToastList() {
|
|
|
3264
3408
|
});
|
|
3265
3409
|
}
|
|
3266
3410
|
function useToast() {
|
|
3267
|
-
const ctx =
|
|
3411
|
+
const ctx = useContext6(ToastContext);
|
|
3268
3412
|
if (!ctx) throw new Error("useToast must be used within ToastProvider");
|
|
3269
3413
|
return ctx;
|
|
3270
3414
|
}
|
|
@@ -3329,6 +3473,7 @@ export {
|
|
|
3329
3473
|
RailItem,
|
|
3330
3474
|
Reaction,
|
|
3331
3475
|
ReactionPicker,
|
|
3476
|
+
RichText,
|
|
3332
3477
|
ScrollArea,
|
|
3333
3478
|
SearchInput,
|
|
3334
3479
|
SectionHeader,
|
|
@@ -3356,6 +3501,7 @@ export {
|
|
|
3356
3501
|
hueFor,
|
|
3357
3502
|
initialsFor,
|
|
3358
3503
|
inlineChipClassName,
|
|
3504
|
+
richTextClassName,
|
|
3359
3505
|
useToast
|
|
3360
3506
|
};
|
|
3361
3507
|
//# sourceMappingURL=index.js.map
|