@estiva-app/ui 0.37.2 → 0.39.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/AttachmentCard.d.ts.map +1 -1
- package/dist/Kbd.d.ts +7 -1
- package/dist/Kbd.d.ts.map +1 -1
- package/dist/Lightbox.d.ts.map +1 -1
- package/dist/SectionLabel.d.ts.map +1 -1
- package/dist/Sidebar.d.ts +7 -1
- package/dist/Sidebar.d.ts.map +1 -1
- package/dist/Toast.d.ts.map +1 -1
- package/dist/TopBar.d.ts +5 -2
- package/dist/TopBar.d.ts.map +1 -1
- package/dist/cn.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/index.js +486 -477
- package/dist/index.js.map +4 -4
- package/dist/looks.d.ts +2 -2
- package/dist/looks.d.ts.map +1 -1
- package/package.json +2 -1
- package/registry.json +62 -43
- package/src/AppShell.mdx +11 -3
- package/src/AppShell.stories.tsx +23 -12
- package/src/AppShell.test.tsx +20 -0
- package/src/AppShell.tsx +43 -24
- package/src/AttachmentCard.tsx +0 -1
- package/src/CommandPalette.tsx +1 -1
- package/src/ErrorBoundary.mdx +2 -2
- package/src/Kbd.tsx +10 -1
- package/src/Lightbox.tsx +4 -2
- package/src/Menu.tsx +1 -1
- package/src/MenuItem.stories.tsx +4 -9
- package/src/Popover.stories.tsx +3 -0
- package/src/SectionLabel.tsx +2 -0
- package/src/Select.tsx +2 -2
- package/src/Sidebar.tsx +10 -2
- package/src/TextInput.test.tsx +1 -1
- package/src/Toast.tsx +7 -6
- package/src/Tooltip.stories.tsx +9 -9
- package/src/Tooltip.test.tsx +1 -1
- package/src/Tooltip.tsx +3 -3
- package/src/TopBar.mdx +6 -4
- package/src/TopBar.tsx +6 -3
- package/src/cn.ts +1 -1
- package/src/eslint/no-restyled-part.ts +1 -0
- package/src/looks.ts +2 -2
- package/stories/TokensPage.tsx +17 -3
- package/tailwind-preset.js +10 -0
- package/tokens.css +144 -0
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var FONT_SIZE_TOKENS = [
|
|
|
20
20
|
"chip",
|
|
21
21
|
"small"
|
|
22
22
|
];
|
|
23
|
-
var BOX_SHADOW_TOKENS = ["sm", "md", "lg", "focus-ring", "glow-warning", "glow-success", "glow-accent", "highlight-inset"];
|
|
23
|
+
var BOX_SHADOW_TOKENS = ["sm", "md", "lg", "focus-ring", "field", "glow-warning", "glow-success", "glow-accent", "highlight-inset"];
|
|
24
24
|
var DROP_SHADOW_TOKENS = ["glow-success", "glow-accent", "glow-warning"];
|
|
25
25
|
var twMerge = extendTailwindMerge({
|
|
26
26
|
extend: {
|
|
@@ -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,123 +272,32 @@ 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
|
|
272
|
-
function Kbd({ children, className }) {
|
|
273
|
-
return /* @__PURE__ */
|
|
289
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
290
|
+
function Kbd({ children, className, tone = "default" }) {
|
|
291
|
+
return /* @__PURE__ */ jsx7(
|
|
274
292
|
"kbd",
|
|
275
293
|
{
|
|
276
294
|
className: cn(
|
|
277
295
|
"inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-sm border border-border-strong bg-bg-inset px-1 py-px font-sans text-caption text-text-secondary",
|
|
278
296
|
"signal:border-b-2 signal:pt-[2px] signal:pb-px signal:bg-bg-wash signal:font-mono signal:text-small",
|
|
279
297
|
"ship:border-b-2 ship:pt-[2px] ship:pb-px ship:bg-bg-wash ship:font-mono ship:text-small",
|
|
298
|
+
// Leaf sets its keys in mono, as Signal does (Katerina, 28 September): the type, not the key's shape.
|
|
299
|
+
"leaf:font-mono leaf:text-small",
|
|
300
|
+
tone === "tooltip" && "border-border-tooltip-key bg-bg-tooltip-key text-text-tooltip-key signal:bg-bg-tooltip-key ship:bg-bg-tooltip-key",
|
|
280
301
|
className
|
|
281
302
|
),
|
|
282
303
|
children
|
|
@@ -285,7 +306,7 @@ function Kbd({ children, className }) {
|
|
|
285
306
|
}
|
|
286
307
|
|
|
287
308
|
// src/looks.ts
|
|
288
|
-
var FIELD_BOX_CLASSES = "bg-bg-
|
|
309
|
+
var FIELD_BOX_CLASSES = "bg-bg-field border border-border-field shadow-field hover:border-border-strong focus:border-border-focus rounded-lg";
|
|
289
310
|
var FIELD_TEXT_CLASSES = "text-text-primary placeholder:text-text-muted";
|
|
290
311
|
var FIELD_DISABLED_CLASSES = "disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled";
|
|
291
312
|
var FIELD_FOCUS_RING_CLASSES = "signal:transition-shadow signal:focus:shadow-focus-ring";
|
|
@@ -293,27 +314,27 @@ var FIELD_SIZE_CLASSES = {
|
|
|
293
314
|
default: "px-3 py-2 text-input-value",
|
|
294
315
|
small: "h-6 min-h-6 px-2 text-caption"
|
|
295
316
|
};
|
|
296
|
-
var FIELD_SHELL_CLASSES = "bg-bg-
|
|
317
|
+
var FIELD_SHELL_CLASSES = "bg-bg-field border border-border-field shadow-field hover:border-border-strong rounded-lg transition-colors";
|
|
297
318
|
var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
|
|
298
319
|
var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums";
|
|
299
320
|
var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
|
|
300
321
|
|
|
301
322
|
// src/Tooltip.tsx
|
|
302
|
-
import { jsx as
|
|
323
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
303
324
|
var OPEN_DELAY = 300;
|
|
304
325
|
function TooltipProvider({ delay = OPEN_DELAY, closeDelay, timeout, children }) {
|
|
305
|
-
return /* @__PURE__ */
|
|
326
|
+
return /* @__PURE__ */ jsx8(BaseTooltip.Provider, { delay, closeDelay, timeout, children });
|
|
306
327
|
}
|
|
307
328
|
function Tooltip({ label, shortcut, className, ...props }) {
|
|
308
|
-
return /* @__PURE__ */ jsxs4("div", { role: "tooltip", className: cn(FLOATING_SURFACE_CLASSES, "min-h-[30px] max-w-80 flex items-center justify-center gap-1.5 px-2 py-1", className), ...props, children: [
|
|
309
|
-
/* @__PURE__ */
|
|
310
|
-
shortcut && /* @__PURE__ */
|
|
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: [
|
|
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 })
|
|
311
332
|
] });
|
|
312
333
|
}
|
|
313
334
|
var GAP = 6;
|
|
314
335
|
var VIEWPORT_PAD = 8;
|
|
315
336
|
function TooltipSurface({ label, shortcut, placement }) {
|
|
316
|
-
return /* @__PURE__ */
|
|
337
|
+
return /* @__PURE__ */ jsx8(BaseTooltip.Portal, { children: /* @__PURE__ */ jsx8(
|
|
317
338
|
BaseTooltip.Positioner,
|
|
318
339
|
{
|
|
319
340
|
side: placement,
|
|
@@ -322,10 +343,10 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
322
343
|
collisionPadding: VIEWPORT_PAD,
|
|
323
344
|
positionMethod: "fixed",
|
|
324
345
|
className: "pointer-events-none z-[9999]",
|
|
325
|
-
children: /* @__PURE__ */
|
|
346
|
+
children: /* @__PURE__ */ jsx8(
|
|
326
347
|
BaseTooltip.Popup,
|
|
327
348
|
{
|
|
328
|
-
render: /* @__PURE__ */
|
|
349
|
+
render: /* @__PURE__ */ jsx8(Tooltip, { label, shortcut }),
|
|
329
350
|
className: cn(
|
|
330
351
|
"transition-[opacity,transform] duration-[120ms] ease-out motion-reduce:transition-none",
|
|
331
352
|
"data-[ending-style]:duration-[80ms] data-[instant]:duration-0",
|
|
@@ -341,19 +362,19 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
341
362
|
function WithTooltip({ label, shortcut, placement = "top", wrapperClassName, inline = false, children }) {
|
|
342
363
|
const Wrapper = inline ? "span" : "div";
|
|
343
364
|
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
344
|
-
/* @__PURE__ */
|
|
345
|
-
/* @__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 })
|
|
346
367
|
] });
|
|
347
368
|
}
|
|
348
369
|
function TooltipTrigger({ label, shortcut, placement = "top", children }) {
|
|
349
370
|
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
/* @__PURE__ */
|
|
371
|
+
/* @__PURE__ */ jsx8(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: children }),
|
|
372
|
+
/* @__PURE__ */ jsx8(TooltipSurface, { label, shortcut, placement })
|
|
352
373
|
] });
|
|
353
374
|
}
|
|
354
375
|
|
|
355
376
|
// src/IconButton.tsx
|
|
356
|
-
import { jsx as
|
|
377
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
357
378
|
function IconButton({
|
|
358
379
|
variant = "muted",
|
|
359
380
|
pressed,
|
|
@@ -404,7 +425,7 @@ function IconButton({
|
|
|
404
425
|
off && "cursor-not-allowed",
|
|
405
426
|
className
|
|
406
427
|
);
|
|
407
|
-
const button = href && !unusable ? /* @__PURE__ */
|
|
428
|
+
const button = href && !unusable ? /* @__PURE__ */ jsx9("a", { href, className: look(false), ...props, children }) : /* @__PURE__ */ jsx9(
|
|
408
429
|
BaseButton,
|
|
409
430
|
{
|
|
410
431
|
type,
|
|
@@ -418,7 +439,7 @@ function IconButton({
|
|
|
418
439
|
);
|
|
419
440
|
const label = disabledReason ?? tooltip;
|
|
420
441
|
if (label) {
|
|
421
|
-
return /* @__PURE__ */
|
|
442
|
+
return /* @__PURE__ */ jsx9(TooltipTrigger, { label, shortcut: disabledReason ? void 0 : tooltipShortcut, placement: tooltipPlacement, children: button });
|
|
422
443
|
}
|
|
423
444
|
return button;
|
|
424
445
|
}
|
|
@@ -427,10 +448,10 @@ function IconButton({
|
|
|
427
448
|
import { useRef } from "react";
|
|
428
449
|
import { Dialog } from "@base-ui/react/dialog";
|
|
429
450
|
import { IconX } from "@tabler/icons-react";
|
|
430
|
-
import { jsx as
|
|
451
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
431
452
|
function Lightbox({ src, alt, onClose, className }) {
|
|
432
453
|
const popupRef = useRef(null);
|
|
433
|
-
return /* @__PURE__ */
|
|
454
|
+
return /* @__PURE__ */ jsx10(
|
|
434
455
|
Dialog.Root,
|
|
435
456
|
{
|
|
436
457
|
open: true,
|
|
@@ -438,7 +459,7 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
438
459
|
if (!open) onClose();
|
|
439
460
|
},
|
|
440
461
|
children: /* @__PURE__ */ jsxs5(Dialog.Portal, { children: [
|
|
441
|
-
/* @__PURE__ */
|
|
462
|
+
/* @__PURE__ */ jsx10(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim-strong" }),
|
|
442
463
|
/* @__PURE__ */ jsxs5(
|
|
443
464
|
Dialog.Popup,
|
|
444
465
|
{
|
|
@@ -448,7 +469,7 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
448
469
|
className: "fixed inset-0 z-50 flex items-center justify-center p-8 outline-none",
|
|
449
470
|
onClick: onClose,
|
|
450
471
|
children: [
|
|
451
|
-
/* @__PURE__ */
|
|
472
|
+
/* @__PURE__ */ jsx10(
|
|
452
473
|
"img",
|
|
453
474
|
{
|
|
454
475
|
src,
|
|
@@ -457,12 +478,12 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
457
478
|
className: cn("max-w-full max-h-full object-contain rounded-lg", className)
|
|
458
479
|
}
|
|
459
480
|
),
|
|
460
|
-
/* @__PURE__ */
|
|
481
|
+
/* @__PURE__ */ jsx10(
|
|
461
482
|
Dialog.Close,
|
|
462
483
|
{
|
|
463
484
|
"aria-label": "Close",
|
|
464
|
-
className: "absolute top-4 right-4 size-8 rounded-full bg-bg-
|
|
465
|
-
children: /* @__PURE__ */
|
|
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",
|
|
486
|
+
children: /* @__PURE__ */ jsx10(IconX, { size: 16, stroke: 1.5 })
|
|
466
487
|
}
|
|
467
488
|
)
|
|
468
489
|
]
|
|
@@ -474,7 +495,7 @@ function Lightbox({ src, alt, onClose, className }) {
|
|
|
474
495
|
}
|
|
475
496
|
|
|
476
497
|
// src/AttachmentCard.tsx
|
|
477
|
-
import { Fragment, jsx as
|
|
498
|
+
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
478
499
|
var ICON_BY_EXTENSION = {
|
|
479
500
|
pdf: IconFileTypePdf,
|
|
480
501
|
doc: IconFileTypeDocx,
|
|
@@ -508,7 +529,7 @@ var NAME_CLASSES = "text-caption font-medium text-text-primary truncate";
|
|
|
508
529
|
var NOTE_CLASSES = "text-small tracking-wide leading-tight truncate";
|
|
509
530
|
function TypeIcon({ name }) {
|
|
510
531
|
const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
|
|
511
|
-
return /* @__PURE__ */
|
|
532
|
+
return /* @__PURE__ */ jsx11(Icon, { size: 20, stroke: 1.5 });
|
|
512
533
|
}
|
|
513
534
|
function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
514
535
|
const ref = useRef2(null);
|
|
@@ -530,9 +551,9 @@ function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
|
530
551
|
observer.disconnect();
|
|
531
552
|
};
|
|
532
553
|
}, [text, cut]);
|
|
533
|
-
const line = /* @__PURE__ */
|
|
554
|
+
const line = /* @__PURE__ */ jsx11("span", { ref, className, children: text });
|
|
534
555
|
if (!hint && !cut) return line;
|
|
535
|
-
return /* @__PURE__ */
|
|
556
|
+
return /* @__PURE__ */ jsx11(WithTooltip, { label: hint ?? text, placement, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
|
|
536
557
|
}
|
|
537
558
|
function useRemoteImage(url, fetchImage) {
|
|
538
559
|
const [result, setResult] = useState({});
|
|
@@ -611,7 +632,7 @@ function AttachmentCard({
|
|
|
611
632
|
const full = useRemoteImage(opened ? remoteFullSrc : void 0, fetchImage);
|
|
612
633
|
const openable = image && !!picture && !pending;
|
|
613
634
|
const openPicture = onOpen ?? (openable ? () => setOpened(true) : void 0);
|
|
614
|
-
const viewer = opened && picture ? /* @__PURE__ */
|
|
635
|
+
const viewer = opened && picture ? /* @__PURE__ */ jsx11(Lightbox, { src: full.src ?? picture, alt: alt ?? name, onClose: () => setOpened(false) }) : null;
|
|
615
636
|
const saveHere = download ? () => {
|
|
616
637
|
const source = remoteFullSrc ?? remoteSrc;
|
|
617
638
|
if (source && fetchImage) {
|
|
@@ -640,10 +661,10 @@ function AttachmentCard({
|
|
|
640
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),
|
|
641
662
|
...props,
|
|
642
663
|
children: [
|
|
643
|
-
/* @__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) }) }),
|
|
644
665
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
645
|
-
/* @__PURE__ */
|
|
646
|
-
/* @__PURE__ */
|
|
666
|
+
/* @__PURE__ */ jsx11(Truncating, { text: name, className: NAME_CLASSES, placement: onRemove ? "bottom" : void 0 }),
|
|
667
|
+
/* @__PURE__ */ jsx11(
|
|
647
668
|
Truncating,
|
|
648
669
|
{
|
|
649
670
|
text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
|
|
@@ -652,8 +673,7 @@ function AttachmentCard({
|
|
|
652
673
|
}
|
|
653
674
|
)
|
|
654
675
|
] }),
|
|
655
|
-
onRemove &&
|
|
656
|
-
/* @__PURE__ */ jsx10(
|
|
676
|
+
onRemove && /* @__PURE__ */ jsx11(
|
|
657
677
|
BaseButton2,
|
|
658
678
|
{
|
|
659
679
|
type: "button",
|
|
@@ -663,7 +683,7 @@ function AttachmentCard({
|
|
|
663
683
|
event.stopPropagation();
|
|
664
684
|
onRemove();
|
|
665
685
|
},
|
|
666
|
-
children: /* @__PURE__ */
|
|
686
|
+
children: /* @__PURE__ */ jsx11(IconX2, { size: 11, stroke: 1.75 })
|
|
667
687
|
}
|
|
668
688
|
)
|
|
669
689
|
]
|
|
@@ -673,7 +693,7 @@ function AttachmentCard({
|
|
|
673
693
|
}
|
|
674
694
|
const downloadControl = saving ? (
|
|
675
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)
|
|
676
|
-
/* @__PURE__ */
|
|
696
|
+
/* @__PURE__ */ jsx11(
|
|
677
697
|
IconButton,
|
|
678
698
|
{
|
|
679
699
|
variant: "muted",
|
|
@@ -684,7 +704,7 @@ function AttachmentCard({
|
|
|
684
704
|
event.stopPropagation();
|
|
685
705
|
saving();
|
|
686
706
|
},
|
|
687
|
-
children: /* @__PURE__ */
|
|
707
|
+
children: /* @__PURE__ */ jsx11(IconDownload, { size: 16, stroke: 1.5 })
|
|
688
708
|
}
|
|
689
709
|
)
|
|
690
710
|
) : null;
|
|
@@ -693,26 +713,26 @@ function AttachmentCard({
|
|
|
693
713
|
// `role="status"`: a plain box may not carry a name (axe, aria-prohibited-attr), and a
|
|
694
714
|
// status says what it is doing — loading — to a reader that cannot see the pulse.
|
|
695
715
|
// @estiva-escape(no-restyled-part): the loading pulse is AttachmentCard's own state; Card has no loading state (UIG-9, Katerina 17 September)
|
|
696
|
-
/* @__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 })
|
|
697
717
|
);
|
|
698
718
|
}
|
|
699
719
|
if (drawnState === "unreadable") {
|
|
700
720
|
return (
|
|
701
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)
|
|
702
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: [
|
|
703
|
-
/* @__PURE__ */
|
|
723
|
+
/* @__PURE__ */ jsx11("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx11(TypeIcon, { name }) }),
|
|
704
724
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
705
|
-
/* @__PURE__ */
|
|
706
|
-
/* @__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" })
|
|
707
727
|
] })
|
|
708
728
|
] })
|
|
709
729
|
);
|
|
710
730
|
}
|
|
711
731
|
if (image && picture) {
|
|
712
|
-
const thumbnail = /* @__PURE__ */
|
|
713
|
-
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: [
|
|
714
734
|
/* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: "hairline", clip: true, className: cn("group relative flex flex-col w-[180px]", className), ...props, children: [
|
|
715
|
-
openPicture ? /* @__PURE__ */
|
|
735
|
+
openPicture ? /* @__PURE__ */ jsx11(
|
|
716
736
|
BaseButton2,
|
|
717
737
|
{
|
|
718
738
|
type: "button",
|
|
@@ -724,26 +744,26 @@ function AttachmentCard({
|
|
|
724
744
|
},
|
|
725
745
|
children: thumbnail
|
|
726
746
|
}
|
|
727
|
-
) : /* @__PURE__ */
|
|
747
|
+
) : /* @__PURE__ */ jsx11("div", { className: "block w-full", children: thumbnail }),
|
|
728
748
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
|
|
729
|
-
/* @__PURE__ */
|
|
749
|
+
/* @__PURE__ */ jsx11(Truncating, { text: name, className: "flex-1 text-caption text-text-primary truncate", wrapperClassName: "flex-1" }),
|
|
730
750
|
downloadControl
|
|
731
751
|
] })
|
|
732
752
|
] }),
|
|
733
753
|
viewer
|
|
734
754
|
] });
|
|
735
755
|
}
|
|
736
|
-
const body = /* @__PURE__ */ jsxs6(
|
|
737
|
-
/* @__PURE__ */
|
|
756
|
+
const body = /* @__PURE__ */ jsxs6(Fragment2, { children: [
|
|
757
|
+
/* @__PURE__ */ jsx11("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx11(TypeIcon, { name }) }),
|
|
738
758
|
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
739
|
-
/* @__PURE__ */
|
|
740
|
-
/* @__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}` })
|
|
741
761
|
] })
|
|
742
762
|
] });
|
|
743
763
|
return (
|
|
744
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)
|
|
745
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: [
|
|
746
|
-
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 }),
|
|
747
767
|
downloadControl
|
|
748
768
|
] })
|
|
749
769
|
);
|
|
@@ -752,7 +772,7 @@ function AttachmentCard({
|
|
|
752
772
|
// src/Avatar.tsx
|
|
753
773
|
import { Avatar as BaseAvatar } from "@base-ui/react/avatar";
|
|
754
774
|
import { IconUserFilled } from "@tabler/icons-react";
|
|
755
|
-
import { jsx as
|
|
775
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
756
776
|
var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
|
|
757
777
|
var hueFor = (key) => {
|
|
758
778
|
let h = 0;
|
|
@@ -769,12 +789,12 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
769
789
|
return /* @__PURE__ */ jsxs7(
|
|
770
790
|
BaseAvatar.Root,
|
|
771
791
|
{
|
|
772
|
-
render: /* @__PURE__ */
|
|
792
|
+
render: /* @__PURE__ */ jsx12("div", {}),
|
|
773
793
|
...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
|
|
774
794
|
className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
|
|
775
795
|
style: { width: size, height: size },
|
|
776
796
|
children: [
|
|
777
|
-
src && /* @__PURE__ */
|
|
797
|
+
src && /* @__PURE__ */ jsx12(
|
|
778
798
|
BaseAvatar.Image,
|
|
779
799
|
{
|
|
780
800
|
src,
|
|
@@ -783,10 +803,10 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
783
803
|
className: "w-full h-full object-cover data-[error]:hidden"
|
|
784
804
|
}
|
|
785
805
|
),
|
|
786
|
-
label ? /* @__PURE__ */
|
|
806
|
+
label ? /* @__PURE__ */ jsx12(
|
|
787
807
|
BaseAvatar.Fallback,
|
|
788
808
|
{
|
|
789
|
-
render: /* @__PURE__ */
|
|
809
|
+
render: /* @__PURE__ */ jsx12("div", {}),
|
|
790
810
|
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
791
811
|
style: {
|
|
792
812
|
/* eslint-disable no-restricted-syntax -- @estiva-escape: the per-person palette (the note at
|
|
@@ -800,32 +820,32 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
800
820
|
background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
|
|
801
821
|
/* eslint-enable no-restricted-syntax */
|
|
802
822
|
},
|
|
803
|
-
children: /* @__PURE__ */
|
|
823
|
+
children: /* @__PURE__ */ jsx12("span", { className: "[text-box:trim-both_cap_alphabetic]", children: initialsFor(label) })
|
|
804
824
|
}
|
|
805
|
-
) : /* @__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) }) })
|
|
806
826
|
]
|
|
807
827
|
}
|
|
808
828
|
);
|
|
809
829
|
}
|
|
810
830
|
|
|
811
831
|
// src/AvatarGroup.tsx
|
|
812
|
-
import { jsx as
|
|
832
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
813
833
|
function AvatarGroup({ members, size = 24 }) {
|
|
814
834
|
const visible = members.slice(0, 3);
|
|
815
835
|
const overlap = Math.round(size / 3);
|
|
816
836
|
const ring = size / 12;
|
|
817
|
-
return /* @__PURE__ */
|
|
837
|
+
return /* @__PURE__ */ jsx13("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
|
|
818
838
|
/*
|
|
819
839
|
The wrapper carries the overlap and the ring; the face carries
|
|
820
840
|
neither. It must never clip — see the note at the top of the file —
|
|
821
841
|
so it has the avatar's own radius and no overflow of its own.
|
|
822
842
|
*/
|
|
823
|
-
/* @__PURE__ */
|
|
843
|
+
/* @__PURE__ */ jsx13(
|
|
824
844
|
"span",
|
|
825
845
|
{
|
|
826
846
|
className: "relative flex rounded-sm",
|
|
827
847
|
style: { marginRight: -overlap, boxShadow: `0 0 0 ${ring}px var(--bg-surface)` },
|
|
828
|
-
children: /* @__PURE__ */
|
|
848
|
+
children: /* @__PURE__ */ jsx13(Avatar, { size, name: member.name, src: member.picture, label: member.name })
|
|
829
849
|
},
|
|
830
850
|
i
|
|
831
851
|
)
|
|
@@ -837,7 +857,7 @@ import { IconX as IconX3 } from "@tabler/icons-react";
|
|
|
837
857
|
|
|
838
858
|
// src/Button.tsx
|
|
839
859
|
import { Button as BaseButton3 } from "@base-ui/react/button";
|
|
840
|
-
import { jsx as
|
|
860
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
841
861
|
function Button({
|
|
842
862
|
variant = "muted",
|
|
843
863
|
size = "default",
|
|
@@ -899,11 +919,11 @@ function Button({
|
|
|
899
919
|
]
|
|
900
920
|
}
|
|
901
921
|
);
|
|
902
|
-
return disabledReason ? /* @__PURE__ */
|
|
922
|
+
return disabledReason ? /* @__PURE__ */ jsx14(TooltipTrigger, { label: disabledReason, children: button }) : button;
|
|
903
923
|
}
|
|
904
924
|
|
|
905
925
|
// src/Banner.tsx
|
|
906
|
-
import { jsx as
|
|
926
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
907
927
|
var TONE_STYLES = {
|
|
908
928
|
ok: "bg-success-muted text-success-default",
|
|
909
929
|
error: "bg-error-muted text-error-default",
|
|
@@ -913,14 +933,14 @@ var TONE_STYLES = {
|
|
|
913
933
|
function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismiss", className }) {
|
|
914
934
|
const role = tone === "error" ? "alert" : "status";
|
|
915
935
|
if (!onDismiss && !icon && !action) {
|
|
916
|
-
return /* @__PURE__ */
|
|
936
|
+
return /* @__PURE__ */ jsx15("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
|
|
917
937
|
}
|
|
918
938
|
const oneLine = Boolean(icon || action);
|
|
919
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: [
|
|
920
|
-
icon && /* @__PURE__ */
|
|
921
|
-
/* @__PURE__ */
|
|
922
|
-
action && /* @__PURE__ */
|
|
923
|
-
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 }) })
|
|
924
944
|
] });
|
|
925
945
|
}
|
|
926
946
|
|
|
@@ -928,7 +948,7 @@ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismi
|
|
|
928
948
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
929
949
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
930
950
|
import { IconCheck } from "@tabler/icons-react";
|
|
931
|
-
import { jsx as
|
|
951
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
932
952
|
function squareClasses(checked, disabled, interactive, className) {
|
|
933
953
|
return cn(
|
|
934
954
|
"inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
|
|
@@ -945,14 +965,14 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
945
965
|
const formBusy = useFormBusy();
|
|
946
966
|
const disabled = ownDisabled || formBusy;
|
|
947
967
|
if (!onChange) {
|
|
948
|
-
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 }) }) });
|
|
949
969
|
if (label === void 0) return picture;
|
|
950
970
|
return /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2", children: [
|
|
951
971
|
picture,
|
|
952
|
-
/* @__PURE__ */
|
|
972
|
+
/* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
|
|
953
973
|
] });
|
|
954
974
|
}
|
|
955
|
-
const box = /* @__PURE__ */
|
|
975
|
+
const box = /* @__PURE__ */ jsx16(
|
|
956
976
|
BaseCheckbox.Root,
|
|
957
977
|
{
|
|
958
978
|
checked,
|
|
@@ -962,25 +982,25 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
962
982
|
onCheckedChange: (next) => onChange(next),
|
|
963
983
|
onClick: (e) => e.stopPropagation(),
|
|
964
984
|
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
965
|
-
children: /* @__PURE__ */
|
|
985
|
+
children: /* @__PURE__ */ jsx16(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx16(IconCheck, { size: 12, stroke: 3 }) })
|
|
966
986
|
}
|
|
967
987
|
);
|
|
968
988
|
if (label === void 0) return box;
|
|
969
989
|
if (row) {
|
|
970
|
-
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: [
|
|
971
991
|
leading,
|
|
972
|
-
/* @__PURE__ */
|
|
992
|
+
/* @__PURE__ */ jsx16("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
|
|
973
993
|
box
|
|
974
994
|
] }) });
|
|
975
995
|
}
|
|
976
|
-
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: [
|
|
977
997
|
box,
|
|
978
|
-
/* @__PURE__ */
|
|
998
|
+
/* @__PURE__ */ jsx16("span", { className: WORDS_CLASSES, children: label })
|
|
979
999
|
] }) });
|
|
980
1000
|
}
|
|
981
1001
|
|
|
982
1002
|
// src/Chip.tsx
|
|
983
|
-
import { jsx as
|
|
1003
|
+
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
984
1004
|
var typeStyles = {
|
|
985
1005
|
neutral: "bg-bg-inset text-text-primary",
|
|
986
1006
|
brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
|
|
@@ -991,7 +1011,7 @@ var typeStyles = {
|
|
|
991
1011
|
};
|
|
992
1012
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
993
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: [
|
|
994
|
-
leadingIcon && /* @__PURE__ */
|
|
1014
|
+
leadingIcon && /* @__PURE__ */ jsx17("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
995
1015
|
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
996
1016
|
// of growing past it — Ship's project chip on an issue row
|
|
997
1017
|
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
@@ -1000,15 +1020,15 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
1000
1020
|
// the screenshot diff caught every descender cut off. `clip` is the
|
|
1001
1021
|
// one overflow that leaves the other axis visible. A chip with no cap
|
|
1002
1022
|
// draws exactly as before.
|
|
1003
|
-
/* @__PURE__ */
|
|
1004
|
-
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 })
|
|
1005
1025
|
] });
|
|
1006
1026
|
}
|
|
1007
1027
|
|
|
1008
1028
|
// src/CommandPalette.tsx
|
|
1009
1029
|
import {
|
|
1010
|
-
createContext as
|
|
1011
|
-
useContext as
|
|
1030
|
+
createContext as createContext5,
|
|
1031
|
+
useContext as useContext5,
|
|
1012
1032
|
useEffect as useEffect2,
|
|
1013
1033
|
useLayoutEffect as useLayoutEffect3,
|
|
1014
1034
|
useMemo as useMemo2,
|
|
@@ -1026,17 +1046,17 @@ import { Combobox } from "@base-ui/react/combobox";
|
|
|
1026
1046
|
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
1027
1047
|
|
|
1028
1048
|
// src/Menu.tsx
|
|
1029
|
-
import { createContext as
|
|
1049
|
+
import { createContext as createContext4, useContext as useContext4 } from "react";
|
|
1030
1050
|
import { IconChevronRight } from "@tabler/icons-react";
|
|
1031
1051
|
import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
1032
1052
|
|
|
1033
1053
|
// src/Divider.tsx
|
|
1034
|
-
import { createContext as
|
|
1054
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
1035
1055
|
import { Separator } from "@base-ui/react/separator";
|
|
1036
|
-
import { jsx as
|
|
1037
|
-
var DividerInPanel =
|
|
1056
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1057
|
+
var DividerInPanel = createContext3(false);
|
|
1038
1058
|
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
1039
|
-
const inset =
|
|
1059
|
+
const inset = useContext3(DividerInPanel) ? "mx-0" : "mx-3";
|
|
1040
1060
|
if (label && orientation === "horizontal") {
|
|
1041
1061
|
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
1042
1062
|
return /* @__PURE__ */ jsxs12(
|
|
@@ -1046,14 +1066,14 @@ function Divider({ orientation = "horizontal", label, tone = "default", classNam
|
|
|
1046
1066
|
"aria-label": label,
|
|
1047
1067
|
className: cn("flex shrink-0 items-center gap-2", inset, className),
|
|
1048
1068
|
children: [
|
|
1049
|
-
/* @__PURE__ */
|
|
1050
|
-
/* @__PURE__ */
|
|
1051
|
-
/* @__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) })
|
|
1052
1072
|
]
|
|
1053
1073
|
}
|
|
1054
1074
|
);
|
|
1055
1075
|
}
|
|
1056
|
-
return /* @__PURE__ */
|
|
1076
|
+
return /* @__PURE__ */ jsx18(
|
|
1057
1077
|
Separator,
|
|
1058
1078
|
{
|
|
1059
1079
|
orientation,
|
|
@@ -1069,18 +1089,20 @@ function triggerDisabled(trigger) {
|
|
|
1069
1089
|
}
|
|
1070
1090
|
|
|
1071
1091
|
// src/SectionLabel.tsx
|
|
1072
|
-
import { jsx as
|
|
1092
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
1073
1093
|
function SectionLabel({
|
|
1074
1094
|
children,
|
|
1075
1095
|
tone = "primary",
|
|
1076
1096
|
truncate = false,
|
|
1077
1097
|
className
|
|
1078
1098
|
}) {
|
|
1079
|
-
return /* @__PURE__ */
|
|
1099
|
+
return /* @__PURE__ */ jsx19(
|
|
1080
1100
|
"span",
|
|
1081
1101
|
{
|
|
1082
1102
|
className: cn(
|
|
1083
1103
|
"text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest",
|
|
1104
|
+
// Leaf's section labels are Signal's type (Katerina, 28 September).
|
|
1105
|
+
"leaf:font-mono leaf:text-small leaf:uppercase leaf:tracking-widest",
|
|
1084
1106
|
tone === "secondary" ? "text-text-secondary" : tone === "muted" ? "text-text-muted" : "text-text-primary",
|
|
1085
1107
|
truncate && "min-w-0 truncate",
|
|
1086
1108
|
className
|
|
@@ -1091,10 +1113,10 @@ function SectionLabel({
|
|
|
1091
1113
|
}
|
|
1092
1114
|
|
|
1093
1115
|
// src/Menu.tsx
|
|
1094
|
-
import { Fragment as
|
|
1095
|
-
var MenuContext =
|
|
1116
|
+
import { Fragment as Fragment3, jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1117
|
+
var MenuContext = createContext4(null);
|
|
1096
1118
|
function MenuPanel({ children, className, ...props }) {
|
|
1097
|
-
return /* @__PURE__ */
|
|
1119
|
+
return /* @__PURE__ */ jsx20(
|
|
1098
1120
|
"div",
|
|
1099
1121
|
{
|
|
1100
1122
|
className: cn(
|
|
@@ -1133,7 +1155,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1133
1155
|
actionsRef,
|
|
1134
1156
|
modal: false,
|
|
1135
1157
|
children: [
|
|
1136
|
-
/* @__PURE__ */
|
|
1158
|
+
/* @__PURE__ */ jsx20(
|
|
1137
1159
|
BaseMenu.Trigger,
|
|
1138
1160
|
{
|
|
1139
1161
|
render: trigger,
|
|
@@ -1143,7 +1165,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1143
1165
|
closeDelay: HOVER_CLOSE_DELAY
|
|
1144
1166
|
}
|
|
1145
1167
|
),
|
|
1146
|
-
/* @__PURE__ */
|
|
1168
|
+
/* @__PURE__ */ jsx20(BaseMenu.Portal, { children: /* @__PURE__ */ jsx20(
|
|
1147
1169
|
BaseMenu.Positioner,
|
|
1148
1170
|
{
|
|
1149
1171
|
side: "bottom",
|
|
@@ -1151,13 +1173,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1151
1173
|
sideOffset: GAP2,
|
|
1152
1174
|
collisionPadding: VIEWPORT_PAD2,
|
|
1153
1175
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1154
|
-
children: /* @__PURE__ */
|
|
1176
|
+
children: /* @__PURE__ */ jsx20(
|
|
1155
1177
|
BaseMenu.Popup,
|
|
1156
1178
|
{
|
|
1157
1179
|
"data-interactive": true,
|
|
1158
1180
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
1159
|
-
render: /* @__PURE__ */
|
|
1160
|
-
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 }) }) })
|
|
1161
1183
|
}
|
|
1162
1184
|
)
|
|
1163
1185
|
}
|
|
@@ -1167,26 +1189,26 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
1167
1189
|
);
|
|
1168
1190
|
}
|
|
1169
1191
|
function MenuSub({ label, leading, selected, children, className }) {
|
|
1170
|
-
const menu =
|
|
1192
|
+
const menu = useContext4(MenuContext);
|
|
1171
1193
|
if (!isProduction() && menu?.openOnHover) {
|
|
1172
1194
|
console.error(
|
|
1173
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".'
|
|
1174
1196
|
);
|
|
1175
1197
|
}
|
|
1176
1198
|
return /* @__PURE__ */ jsxs13(BaseMenu.SubmenuRoot, { children: [
|
|
1177
|
-
/* @__PURE__ */
|
|
1199
|
+
/* @__PURE__ */ jsx20(
|
|
1178
1200
|
BaseMenu.SubmenuTrigger,
|
|
1179
1201
|
{
|
|
1180
1202
|
openOnHover: true,
|
|
1181
1203
|
delay: 0,
|
|
1182
1204
|
closeDelay: 150,
|
|
1183
1205
|
nativeButton: true,
|
|
1184
|
-
render: /* @__PURE__ */
|
|
1206
|
+
render: /* @__PURE__ */ jsx20("button", { type: "button" }),
|
|
1185
1207
|
className: menuItemClassName({ size: "default", selected }),
|
|
1186
|
-
children: /* @__PURE__ */
|
|
1208
|
+
children: /* @__PURE__ */ jsx20(MenuItemBody, { label, leading, submenu: true })
|
|
1187
1209
|
}
|
|
1188
1210
|
),
|
|
1189
|
-
/* @__PURE__ */
|
|
1211
|
+
/* @__PURE__ */ jsx20(BaseMenu.Portal, { children: /* @__PURE__ */ jsx20(
|
|
1190
1212
|
BaseMenu.Positioner,
|
|
1191
1213
|
{
|
|
1192
1214
|
side: "inline-end",
|
|
@@ -1194,7 +1216,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
1194
1216
|
sideOffset: GAP2,
|
|
1195
1217
|
collisionPadding: VIEWPORT_PAD2,
|
|
1196
1218
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1197
|
-
children: /* @__PURE__ */
|
|
1219
|
+
children: /* @__PURE__ */ jsx20(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx20(MenuPanel, {}), children })
|
|
1198
1220
|
}
|
|
1199
1221
|
) })
|
|
1200
1222
|
] });
|
|
@@ -1229,25 +1251,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
1229
1251
|
);
|
|
1230
1252
|
}
|
|
1231
1253
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
1232
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
1233
|
-
return /* @__PURE__ */ jsxs13(
|
|
1234
|
-
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 }),
|
|
1235
1257
|
children ?? /* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
1236
|
-
/* @__PURE__ */
|
|
1237
|
-
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 })
|
|
1238
1260
|
] }),
|
|
1239
1261
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
1240
1262
|
// the wider of the two and never changes, so revealing the hint moves
|
|
1241
1263
|
// nothing. No transition here either — the hint switches on the same
|
|
1242
1264
|
// :hover / `selected` as the fill, in the same frame.
|
|
1243
1265
|
/* @__PURE__ */ jsxs13("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
1244
|
-
edge && /* @__PURE__ */
|
|
1245
|
-
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 })
|
|
1246
1268
|
] })
|
|
1247
1269
|
] });
|
|
1248
1270
|
}
|
|
1249
1271
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
1250
|
-
const body = /* @__PURE__ */
|
|
1272
|
+
const body = /* @__PURE__ */ jsx20(
|
|
1251
1273
|
MenuItemBody,
|
|
1252
1274
|
{
|
|
1253
1275
|
label,
|
|
@@ -1264,14 +1286,14 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1264
1286
|
}
|
|
1265
1287
|
);
|
|
1266
1288
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
1267
|
-
if (!
|
|
1268
|
-
return /* @__PURE__ */
|
|
1289
|
+
if (!useContext4(MenuContext)) {
|
|
1290
|
+
return /* @__PURE__ */ jsx20("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
1269
1291
|
}
|
|
1270
|
-
return /* @__PURE__ */
|
|
1292
|
+
return /* @__PURE__ */ jsx20(
|
|
1271
1293
|
BaseMenu.Item,
|
|
1272
1294
|
{
|
|
1273
1295
|
nativeButton: true,
|
|
1274
|
-
render: /* @__PURE__ */
|
|
1296
|
+
render: /* @__PURE__ */ jsx20("button", { type: "button" }),
|
|
1275
1297
|
className: rowClassName,
|
|
1276
1298
|
...props,
|
|
1277
1299
|
children: body
|
|
@@ -1280,13 +1302,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1280
1302
|
}
|
|
1281
1303
|
function EnterHint({ target }) {
|
|
1282
1304
|
return /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
1283
|
-
/* @__PURE__ */
|
|
1284
|
-
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 })
|
|
1285
1307
|
] });
|
|
1286
1308
|
}
|
|
1287
1309
|
function MenuSection({ label, children, className }) {
|
|
1288
|
-
const inMenu =
|
|
1289
|
-
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 }) });
|
|
1290
1312
|
if (!inMenu) {
|
|
1291
1313
|
return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col", children: [
|
|
1292
1314
|
heading,
|
|
@@ -1294,19 +1316,19 @@ function MenuSection({ label, children, className }) {
|
|
|
1294
1316
|
] });
|
|
1295
1317
|
}
|
|
1296
1318
|
return /* @__PURE__ */ jsxs13(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1297
|
-
/* @__PURE__ */
|
|
1319
|
+
/* @__PURE__ */ jsx20(BaseMenu.GroupLabel, { render: heading }),
|
|
1298
1320
|
children
|
|
1299
1321
|
] });
|
|
1300
1322
|
}
|
|
1301
1323
|
function MenuSeparator() {
|
|
1302
|
-
return /* @__PURE__ */
|
|
1324
|
+
return /* @__PURE__ */ jsx20(Divider, { className: "my-1" });
|
|
1303
1325
|
}
|
|
1304
1326
|
function MenuRow({ children, className }) {
|
|
1305
|
-
return /* @__PURE__ */
|
|
1327
|
+
return /* @__PURE__ */ jsx20("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
1306
1328
|
}
|
|
1307
1329
|
|
|
1308
1330
|
// src/ChipInput.tsx
|
|
1309
|
-
import { jsx as
|
|
1331
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1310
1332
|
var CHIP_BOX = (
|
|
1311
1333
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
1312
1334
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -1318,9 +1340,9 @@ var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg
|
|
|
1318
1340
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
1319
1341
|
function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
|
|
1320
1342
|
return /* @__PURE__ */ jsxs14("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1321
|
-
leading && /* @__PURE__ */
|
|
1322
|
-
/* @__PURE__ */
|
|
1323
|
-
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(
|
|
1324
1346
|
BaseButton4,
|
|
1325
1347
|
{
|
|
1326
1348
|
type: "button",
|
|
@@ -1330,7 +1352,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
|
|
|
1330
1352
|
},
|
|
1331
1353
|
className: cn(CHIP_REMOVE, truncate && "shrink-0"),
|
|
1332
1354
|
"aria-label": removeLabel ?? `Remove ${label}`,
|
|
1333
|
-
children: /* @__PURE__ */
|
|
1355
|
+
children: /* @__PURE__ */ jsx21(IconX4, { size: 10, stroke: 1.5 })
|
|
1334
1356
|
}
|
|
1335
1357
|
)
|
|
1336
1358
|
] });
|
|
@@ -1402,11 +1424,11 @@ function ChipInput({
|
|
|
1402
1424
|
children: [
|
|
1403
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: [
|
|
1404
1426
|
value.map((option) => /* @__PURE__ */ jsxs14(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1405
|
-
chipLeading && /* @__PURE__ */
|
|
1406
|
-
/* @__PURE__ */
|
|
1407
|
-
/* @__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 }) })
|
|
1408
1430
|
] }, option.id)),
|
|
1409
|
-
/* @__PURE__ */
|
|
1431
|
+
/* @__PURE__ */ jsx21(
|
|
1410
1432
|
Combobox.Input,
|
|
1411
1433
|
{
|
|
1412
1434
|
autoFocus,
|
|
@@ -1418,18 +1440,18 @@ function ChipInput({
|
|
|
1418
1440
|
}
|
|
1419
1441
|
)
|
|
1420
1442
|
] }),
|
|
1421
|
-
/* @__PURE__ */
|
|
1443
|
+
/* @__PURE__ */ jsx21(Combobox.Portal, { children: /* @__PURE__ */ jsx21(
|
|
1422
1444
|
Combobox.Positioner,
|
|
1423
1445
|
{
|
|
1424
1446
|
anchor: box,
|
|
1425
1447
|
sideOffset: GAP3,
|
|
1426
1448
|
collisionPadding: VIEWPORT_PAD3,
|
|
1427
1449
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1428
|
-
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(
|
|
1429
1451
|
Combobox.Item,
|
|
1430
1452
|
{
|
|
1431
1453
|
value: option,
|
|
1432
|
-
render: /* @__PURE__ */
|
|
1454
|
+
render: /* @__PURE__ */ jsx21(
|
|
1433
1455
|
MenuItem,
|
|
1434
1456
|
{
|
|
1435
1457
|
size: "tall",
|
|
@@ -1452,22 +1474,22 @@ var VIEWPORT_PAD3 = 8;
|
|
|
1452
1474
|
|
|
1453
1475
|
// src/EmptyState.tsx
|
|
1454
1476
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1455
|
-
import { jsx as
|
|
1477
|
+
import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1456
1478
|
function EmptyState({ icon, message, scope = "page", action, className }) {
|
|
1457
1479
|
if (scope === "section") {
|
|
1458
|
-
return /* @__PURE__ */
|
|
1480
|
+
return /* @__PURE__ */ jsx22("p", { className: cn("text-caption text-text-muted", className), children: message });
|
|
1459
1481
|
}
|
|
1460
1482
|
return /* @__PURE__ */ jsxs15("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1461
|
-
/* @__PURE__ */
|
|
1462
|
-
/* @__PURE__ */
|
|
1463
|
-
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 })
|
|
1464
1486
|
] });
|
|
1465
1487
|
}
|
|
1466
1488
|
|
|
1467
1489
|
// src/Field.tsx
|
|
1468
1490
|
import { cloneElement, isValidElement } from "react";
|
|
1469
1491
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1470
|
-
import { jsx as
|
|
1492
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1471
1493
|
var LINE_STYLES = {
|
|
1472
1494
|
helper: "text-caption text-text-muted",
|
|
1473
1495
|
warning: "text-caption text-warning-default",
|
|
@@ -1480,23 +1502,23 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1480
1502
|
return /* @__PURE__ */ jsxs16(BaseField2.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1481
1503
|
/* @__PURE__ */ jsxs16(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1482
1504
|
label,
|
|
1483
|
-
required && /* @__PURE__ */
|
|
1505
|
+
required && /* @__PURE__ */ jsx23("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1484
1506
|
] }),
|
|
1485
1507
|
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1486
1508
|
control,
|
|
1487
|
-
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
|
|
1488
1510
|
] })
|
|
1489
1511
|
] });
|
|
1490
1512
|
}
|
|
1491
1513
|
function FieldLine({ tone = "helper", children, className }) {
|
|
1492
|
-
return /* @__PURE__ */
|
|
1514
|
+
return /* @__PURE__ */ jsx23("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
|
|
1493
1515
|
}
|
|
1494
1516
|
|
|
1495
1517
|
// src/Form.tsx
|
|
1496
1518
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
|
|
1497
1519
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
1498
1520
|
import { Form as BaseForm } from "@base-ui/react/form";
|
|
1499
|
-
import { jsx as
|
|
1521
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
1500
1522
|
var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
|
|
1501
1523
|
var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1502
1524
|
function usable(element) {
|
|
@@ -1555,7 +1577,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1555
1577
|
const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
|
|
1556
1578
|
if (enterSends && oneLine) form.current?.requestSubmit();
|
|
1557
1579
|
};
|
|
1558
|
-
return /* @__PURE__ */
|
|
1580
|
+
return /* @__PURE__ */ jsx24(
|
|
1559
1581
|
BaseForm,
|
|
1560
1582
|
{
|
|
1561
1583
|
ref: form,
|
|
@@ -1578,32 +1600,32 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1578
1600
|
if (busyNow.current) return;
|
|
1579
1601
|
void onSubmit();
|
|
1580
1602
|
},
|
|
1581
|
-
children: /* @__PURE__ */
|
|
1603
|
+
children: /* @__PURE__ */ jsx24(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx24(FormBusyContext.Provider, { value: busy, children }) })
|
|
1582
1604
|
}
|
|
1583
1605
|
);
|
|
1584
1606
|
}
|
|
1585
1607
|
|
|
1586
1608
|
// src/Skeleton.tsx
|
|
1587
|
-
import { jsx as
|
|
1609
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1588
1610
|
function SkeletonBar({ className, style }) {
|
|
1589
|
-
return /* @__PURE__ */
|
|
1611
|
+
return /* @__PURE__ */ jsx25("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1590
1612
|
}
|
|
1591
1613
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1592
1614
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1593
1615
|
return /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1594
|
-
/* @__PURE__ */
|
|
1595
|
-
/* @__PURE__ */
|
|
1616
|
+
/* @__PURE__ */ jsx25(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1617
|
+
/* @__PURE__ */ jsx25(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1596
1618
|
] });
|
|
1597
1619
|
}
|
|
1598
1620
|
function SkeletonList({ rows = 8, className }) {
|
|
1599
|
-
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)) });
|
|
1600
1622
|
}
|
|
1601
1623
|
|
|
1602
1624
|
// src/CommandPalette.tsx
|
|
1603
|
-
import { Fragment as
|
|
1604
|
-
var PaletteContext =
|
|
1625
|
+
import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1626
|
+
var PaletteContext = createContext5(null);
|
|
1605
1627
|
function usePalette(part) {
|
|
1606
|
-
const palette =
|
|
1628
|
+
const palette = useContext5(PaletteContext);
|
|
1607
1629
|
if (!palette) throw new Error(`[@estiva-app/ui] ${part} must be inside a CommandPalette.`);
|
|
1608
1630
|
return palette;
|
|
1609
1631
|
}
|
|
@@ -1626,9 +1648,9 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1626
1648
|
return () => cancelAnimationFrame(frame);
|
|
1627
1649
|
});
|
|
1628
1650
|
const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
|
|
1629
|
-
return /* @__PURE__ */
|
|
1630
|
-
/* @__PURE__ */
|
|
1631
|
-
/* @__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(
|
|
1632
1654
|
Dialog2.Popup,
|
|
1633
1655
|
{
|
|
1634
1656
|
ref: popupRef,
|
|
@@ -1638,13 +1660,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1638
1660
|
if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
|
|
1639
1661
|
},
|
|
1640
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",
|
|
1641
|
-
children: /* @__PURE__ */
|
|
1663
|
+
children: /* @__PURE__ */ jsx26(PaletteContext.Provider, { value: context, children })
|
|
1642
1664
|
}
|
|
1643
1665
|
) })
|
|
1644
1666
|
] }) });
|
|
1645
1667
|
}
|
|
1646
1668
|
function LevelChip({ chip, onBack }) {
|
|
1647
|
-
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" });
|
|
1648
1670
|
}
|
|
1649
1671
|
function useBack(chip, popupRef) {
|
|
1650
1672
|
return () => {
|
|
@@ -1655,10 +1677,10 @@ function useBack(chip, popupRef) {
|
|
|
1655
1677
|
}
|
|
1656
1678
|
function Footer({ keys }) {
|
|
1657
1679
|
const { where } = usePalette("The footer");
|
|
1658
|
-
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", children: [
|
|
1659
|
-
/* @__PURE__ */
|
|
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: [
|
|
1681
|
+
/* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate", children: where }),
|
|
1660
1682
|
keys.map(([key, word]) => /* @__PURE__ */ jsxs18("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
1661
|
-
/* @__PURE__ */
|
|
1683
|
+
/* @__PURE__ */ jsx26(Kbd, { children: key }),
|
|
1662
1684
|
" ",
|
|
1663
1685
|
word
|
|
1664
1686
|
] }, key))
|
|
@@ -1759,9 +1781,9 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1759
1781
|
},
|
|
1760
1782
|
children: [
|
|
1761
1783
|
/* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1762
|
-
/* @__PURE__ */
|
|
1763
|
-
chip && /* @__PURE__ */
|
|
1764
|
-
/* @__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(
|
|
1765
1787
|
Autocomplete.Input,
|
|
1766
1788
|
{
|
|
1767
1789
|
ref: inputRef,
|
|
@@ -1774,42 +1796,42 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1774
1796
|
)
|
|
1775
1797
|
] }),
|
|
1776
1798
|
/* @__PURE__ */ jsxs18(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
|
|
1777
|
-
children != null && /* @__PURE__ */
|
|
1778
|
-
/* @__PURE__ */
|
|
1779
|
-
/* @__PURE__ */
|
|
1780
|
-
/* @__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) => (
|
|
1781
1803
|
/* The menu row, as the list's own option — the way Select
|
|
1782
1804
|
puts it on `Select.Item`. One row, two parts. */
|
|
1783
|
-
/* @__PURE__ */
|
|
1805
|
+
/* @__PURE__ */ jsx26(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx26(
|
|
1784
1806
|
MenuItemBody,
|
|
1785
1807
|
{
|
|
1786
1808
|
size: "tall",
|
|
1787
1809
|
label: row.label,
|
|
1788
1810
|
description: row.description,
|
|
1789
|
-
leading: /* @__PURE__ */
|
|
1811
|
+
leading: /* @__PURE__ */ jsx26(RowLeading, { row }),
|
|
1790
1812
|
submenu: !!row.onGoIn,
|
|
1791
|
-
hint: row.onGoIn ? /* @__PURE__ */
|
|
1813
|
+
hint: row.onGoIn ? /* @__PURE__ */ jsx26(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx26(EnterHint, {})
|
|
1792
1814
|
}
|
|
1793
1815
|
) }, row.id)
|
|
1794
1816
|
) })
|
|
1795
1817
|
] }, group.value) }),
|
|
1796
|
-
/* @__PURE__ */
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__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 })
|
|
1799
1821
|
] }) }),
|
|
1800
|
-
notes.map((note) => /* @__PURE__ */
|
|
1801
|
-
/* @__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 }) })
|
|
1802
1824
|
] }),
|
|
1803
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsx26(Footer, { keys })
|
|
1804
1826
|
]
|
|
1805
1827
|
}
|
|
1806
1828
|
);
|
|
1807
1829
|
}
|
|
1808
1830
|
function RowLeading({ row }) {
|
|
1809
1831
|
if (row.icon != null) {
|
|
1810
|
-
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 });
|
|
1811
1833
|
}
|
|
1812
|
-
return /* @__PURE__ */
|
|
1834
|
+
return /* @__PURE__ */ jsx26("span", { className: "flex size-8 items-center justify-center", children: row.leading });
|
|
1813
1835
|
}
|
|
1814
1836
|
var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1815
1837
|
function isTextField(el) {
|
|
@@ -1853,54 +1875,54 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
|
|
|
1853
1875
|
];
|
|
1854
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: [
|
|
1855
1877
|
/* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1856
|
-
icon != null && /* @__PURE__ */
|
|
1857
|
-
/* @__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 })
|
|
1858
1880
|
] }),
|
|
1859
1881
|
/* @__PURE__ */ jsxs18(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, className: "flex min-h-0 flex-col", children: [
|
|
1860
|
-
/* @__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 }) }),
|
|
1861
1883
|
/* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
|
|
1862
|
-
/* @__PURE__ */
|
|
1863
|
-
/* @__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(
|
|
1864
1886
|
Button,
|
|
1865
1887
|
{
|
|
1866
1888
|
type: "submit",
|
|
1867
1889
|
variant: "primary",
|
|
1868
1890
|
disabled: busy,
|
|
1869
1891
|
disabledReason: busy ? void 0 : submitWaits,
|
|
1870
|
-
leadingIcon: busy ? /* @__PURE__ */
|
|
1892
|
+
leadingIcon: busy ? /* @__PURE__ */ jsx26(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
|
|
1871
1893
|
children: working ? working.button : submitLabel
|
|
1872
1894
|
}
|
|
1873
1895
|
)
|
|
1874
1896
|
] })
|
|
1875
1897
|
] }),
|
|
1876
|
-
/* @__PURE__ */
|
|
1898
|
+
/* @__PURE__ */ jsx26(Footer, { keys })
|
|
1877
1899
|
] });
|
|
1878
1900
|
}
|
|
1879
1901
|
var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
|
|
1880
1902
|
function CommandPaletteWorking({ children, bars = 2 }) {
|
|
1881
1903
|
return /* @__PURE__ */ jsxs18("div", { role: "status", className: "flex flex-col gap-2", children: [
|
|
1882
1904
|
/* @__PURE__ */ jsxs18("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
|
|
1883
|
-
/* @__PURE__ */
|
|
1905
|
+
/* @__PURE__ */ jsx26(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
|
|
1884
1906
|
children
|
|
1885
1907
|
] }),
|
|
1886
|
-
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))
|
|
1887
1909
|
] });
|
|
1888
1910
|
}
|
|
1889
1911
|
function CommandPaletteAnswer({ children, note }) {
|
|
1890
1912
|
const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
|
|
1891
1913
|
return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
|
|
1892
|
-
paragraphs.map((paragraph, i) => /* @__PURE__ */
|
|
1893
|
-
(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
|
|
1894
1916
|
) }, i)),
|
|
1895
|
-
note && /* @__PURE__ */
|
|
1917
|
+
note && /* @__PURE__ */ jsx26(FieldLine, { children: note })
|
|
1896
1918
|
] });
|
|
1897
1919
|
}
|
|
1898
1920
|
function CommandPaletteQuote({ children }) {
|
|
1899
|
-
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 });
|
|
1900
1922
|
}
|
|
1901
1923
|
|
|
1902
1924
|
// src/InlineChip.tsx
|
|
1903
|
-
import { Fragment as
|
|
1925
|
+
import { Fragment as Fragment5, jsx as jsx27, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1904
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";
|
|
1905
1927
|
var INLINE_CHIP_TONE_CLASSES = {
|
|
1906
1928
|
/** A thing or a place — anything that is not a person. */
|
|
@@ -1922,30 +1944,30 @@ function inlineChipClassName(tone, className) {
|
|
|
1922
1944
|
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1923
1945
|
}
|
|
1924
1946
|
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1925
|
-
const body = /* @__PURE__ */ jsxs19(
|
|
1926
|
-
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 }),
|
|
1927
1949
|
children
|
|
1928
1950
|
] });
|
|
1929
1951
|
const classes = inlineChipClassName(tone, className);
|
|
1930
1952
|
if (href === void 0) {
|
|
1931
|
-
return /* @__PURE__ */
|
|
1953
|
+
return /* @__PURE__ */ jsx27("span", { className: classes, ...props, children: body });
|
|
1932
1954
|
}
|
|
1933
|
-
return /* @__PURE__ */
|
|
1955
|
+
return /* @__PURE__ */ jsx27("a", { href, className: classes, ...props, children: body });
|
|
1934
1956
|
}
|
|
1935
1957
|
|
|
1936
1958
|
// src/IdentityMenu.tsx
|
|
1937
1959
|
import { useCallback, useRef as useRef5 } from "react";
|
|
1938
1960
|
|
|
1939
1961
|
// src/Person.tsx
|
|
1940
|
-
import { jsx as
|
|
1962
|
+
import { jsx as jsx28, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1941
1963
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
1942
1964
|
return (
|
|
1943
1965
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
1944
1966
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
1945
1967
|
// row agree by construction.
|
|
1946
1968
|
/* @__PURE__ */ jsxs20("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
1947
|
-
/* @__PURE__ */
|
|
1948
|
-
/* @__PURE__ */
|
|
1969
|
+
/* @__PURE__ */ jsx28(Avatar, { name, src: picture, size }),
|
|
1970
|
+
/* @__PURE__ */ jsx28("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
1949
1971
|
] })
|
|
1950
1972
|
);
|
|
1951
1973
|
}
|
|
@@ -1953,10 +1975,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
1953
1975
|
// src/PersonTrigger.tsx
|
|
1954
1976
|
import { Button as BaseButton5 } from "@base-ui/react/button";
|
|
1955
1977
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
1956
|
-
import { jsx as
|
|
1978
|
+
import { jsx as jsx29, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1957
1979
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
1958
1980
|
if (compact) {
|
|
1959
|
-
return /* @__PURE__ */
|
|
1981
|
+
return /* @__PURE__ */ jsx29(
|
|
1960
1982
|
BaseButton5,
|
|
1961
1983
|
{
|
|
1962
1984
|
type: "button",
|
|
@@ -1965,7 +1987,7 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1965
1987
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
1966
1988
|
className: cn("cursor-pointer rounded-full", className),
|
|
1967
1989
|
...props,
|
|
1968
|
-
children: /* @__PURE__ */
|
|
1990
|
+
children: /* @__PURE__ */ jsx29(Avatar, { name, src: picture, size: size ?? 36 })
|
|
1969
1991
|
}
|
|
1970
1992
|
);
|
|
1971
1993
|
}
|
|
@@ -1989,8 +2011,8 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1989
2011
|
),
|
|
1990
2012
|
...props,
|
|
1991
2013
|
children: [
|
|
1992
|
-
/* @__PURE__ */
|
|
1993
|
-
/* @__PURE__ */
|
|
2014
|
+
/* @__PURE__ */ jsx29(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
2015
|
+
/* @__PURE__ */ jsx29(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
1994
2016
|
]
|
|
1995
2017
|
}
|
|
1996
2018
|
)
|
|
@@ -1998,10 +2020,10 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1998
2020
|
}
|
|
1999
2021
|
|
|
2000
2022
|
// src/IdentityMenu.tsx
|
|
2001
|
-
import { Fragment as
|
|
2023
|
+
import { Fragment as Fragment6, jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
2002
2024
|
function IdentityPanel({ className, onClose = () => {
|
|
2003
2025
|
}, ...rest }) {
|
|
2004
|
-
return /* @__PURE__ */
|
|
2026
|
+
return /* @__PURE__ */ jsx30(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx30(IdentityRows, { ...rest, onClose }) });
|
|
2005
2027
|
}
|
|
2006
2028
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
2007
2029
|
const act = (action) => () => {
|
|
@@ -2009,36 +2031,36 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
2009
2031
|
action();
|
|
2010
2032
|
};
|
|
2011
2033
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
2012
|
-
return /* @__PURE__ */ jsxs22(
|
|
2034
|
+
return /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
2013
2035
|
/* @__PURE__ */ jsxs22(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
2014
|
-
/* @__PURE__ */
|
|
2015
|
-
/* @__PURE__ */
|
|
2036
|
+
/* @__PURE__ */ jsx30(MenuRow, { children: /* @__PURE__ */ jsx30("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx30(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
|
|
2037
|
+
/* @__PURE__ */ jsx30(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." }),
|
|
2016
2038
|
me.email && /* @__PURE__ */ jsxs22(Note, { children: [
|
|
2017
2039
|
me.email,
|
|
2018
2040
|
" \xB7 known to Estiva, never published to the relay"
|
|
2019
2041
|
] })
|
|
2020
2042
|
] }),
|
|
2021
|
-
relayUrl && /* @__PURE__ */ jsxs22(
|
|
2022
|
-
/* @__PURE__ */
|
|
2043
|
+
relayUrl && /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
2044
|
+
/* @__PURE__ */ jsx30(Divider, { className: "mx-0 my-2" }),
|
|
2023
2045
|
/* @__PURE__ */ jsxs22(MenuSection, { label: "Workspace", children: [
|
|
2024
|
-
/* @__PURE__ */
|
|
2025
|
-
/* @__PURE__ */
|
|
2046
|
+
/* @__PURE__ */ jsx30(MenuRow, { children: /* @__PURE__ */ jsx30("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
2047
|
+
/* @__PURE__ */ jsx30(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
2026
2048
|
] })
|
|
2027
2049
|
] }),
|
|
2028
|
-
appRows && /* @__PURE__ */ jsxs22(
|
|
2029
|
-
/* @__PURE__ */
|
|
2050
|
+
appRows && /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
2051
|
+
/* @__PURE__ */ jsx30(Divider, { className: "mx-0 my-2" }),
|
|
2030
2052
|
appRows
|
|
2031
2053
|
] }),
|
|
2032
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
2033
|
-
signedIn && idBase && /* @__PURE__ */
|
|
2054
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx30(Divider, { className: "mx-0 my-2" }) : null,
|
|
2055
|
+
signedIn && idBase && /* @__PURE__ */ jsx30(
|
|
2034
2056
|
MenuItem,
|
|
2035
2057
|
{
|
|
2036
2058
|
label: "Edit your profile in Estiva ID",
|
|
2037
2059
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
2038
2060
|
}
|
|
2039
2061
|
),
|
|
2040
|
-
onCopyKey && /* @__PURE__ */
|
|
2041
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
2062
|
+
onCopyKey && /* @__PURE__ */ jsx30(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
2063
|
+
idBase && onSignOut && /* @__PURE__ */ jsx30(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
2042
2064
|
] });
|
|
2043
2065
|
}
|
|
2044
2066
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
@@ -2049,13 +2071,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2049
2071
|
to be `relative`, because the panel was positioned against it; the panel
|
|
2050
2072
|
hangs from the trigger and portals now, so a positioning context here
|
|
2051
2073
|
would only be a lie about what this box does. */
|
|
2052
|
-
/* @__PURE__ */
|
|
2074
|
+
/* @__PURE__ */ jsx30("div", { className, children: /* @__PURE__ */ jsx30(
|
|
2053
2075
|
Menu,
|
|
2054
2076
|
{
|
|
2055
2077
|
align: "right",
|
|
2056
2078
|
actionsRef: actions,
|
|
2057
2079
|
className: "w-72",
|
|
2058
|
-
trigger: /* @__PURE__ */
|
|
2080
|
+
trigger: /* @__PURE__ */ jsx30(
|
|
2059
2081
|
PersonTrigger,
|
|
2060
2082
|
{
|
|
2061
2083
|
name: me.name,
|
|
@@ -2066,7 +2088,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2066
2088
|
"aria-label": compact ? "Account menu" : void 0
|
|
2067
2089
|
}
|
|
2068
2090
|
),
|
|
2069
|
-
children: /* @__PURE__ */
|
|
2091
|
+
children: /* @__PURE__ */ jsx30(
|
|
2070
2092
|
IdentityRows,
|
|
2071
2093
|
{
|
|
2072
2094
|
me,
|
|
@@ -2084,14 +2106,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
2084
2106
|
);
|
|
2085
2107
|
}
|
|
2086
2108
|
function Note({ children }) {
|
|
2087
|
-
return /* @__PURE__ */
|
|
2109
|
+
return /* @__PURE__ */ jsx30("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
2088
2110
|
}
|
|
2089
2111
|
|
|
2090
2112
|
// src/FilePicker.tsx
|
|
2091
2113
|
import { forwardRef } from "react";
|
|
2092
|
-
import { jsx as
|
|
2114
|
+
import { jsx as jsx31 } from "react/jsx-runtime";
|
|
2093
2115
|
var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
2094
|
-
return /* @__PURE__ */
|
|
2116
|
+
return /* @__PURE__ */ jsx31(
|
|
2095
2117
|
"input",
|
|
2096
2118
|
{
|
|
2097
2119
|
ref,
|
|
@@ -2112,7 +2134,7 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
|
2112
2134
|
// src/Select.tsx
|
|
2113
2135
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
2114
2136
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
2115
|
-
import { jsx as
|
|
2137
|
+
import { jsx as jsx32, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
2116
2138
|
var GAP4 = 4;
|
|
2117
2139
|
var VIEWPORT_PAD4 = 8;
|
|
2118
2140
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
|
|
@@ -2135,8 +2157,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2135
2157
|
* `truncate` from ever engaging; in a block container max-w-full is
|
|
2136
2158
|
* the cap. Full-width callers are unaffected.
|
|
2137
2159
|
*/
|
|
2138
|
-
"flex w-full min-w-0 max-w-full items-center justify-between gap-2 rounded-lg border bg-bg-
|
|
2139
|
-
"border-border-
|
|
2160
|
+
"flex w-full min-w-0 max-w-full items-center justify-between gap-2 rounded-lg border bg-bg-field shadow-field text-left",
|
|
2161
|
+
"border-border-field outline-none transition-colors",
|
|
2140
2162
|
FIELD_TEXT_CLASSES,
|
|
2141
2163
|
// The focused border survives a hover: hover alone strengthens the
|
|
2142
2164
|
// hairline, but hover while focused must not grey the focus colour —
|
|
@@ -2151,13 +2173,13 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2151
2173
|
),
|
|
2152
2174
|
children: [
|
|
2153
2175
|
/* @__PURE__ */ jsxs23("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
2154
|
-
selected?.leading && /* @__PURE__ */
|
|
2155
|
-
/* @__PURE__ */
|
|
2176
|
+
selected?.leading && /* @__PURE__ */ jsx32("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
2177
|
+
/* @__PURE__ */ jsx32(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
2156
2178
|
] }),
|
|
2157
|
-
/* @__PURE__ */
|
|
2179
|
+
/* @__PURE__ */ jsx32(
|
|
2158
2180
|
BaseSelect.Icon,
|
|
2159
2181
|
{
|
|
2160
|
-
render: /* @__PURE__ */
|
|
2182
|
+
render: /* @__PURE__ */ jsx32(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2161
2183
|
}
|
|
2162
2184
|
)
|
|
2163
2185
|
]
|
|
@@ -2176,8 +2198,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2176
2198
|
disabled: disabled && !held,
|
|
2177
2199
|
modal: false,
|
|
2178
2200
|
children: [
|
|
2179
|
-
held ? /* @__PURE__ */
|
|
2180
|
-
/* @__PURE__ */
|
|
2201
|
+
held ? /* @__PURE__ */ jsx32(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
|
|
2202
|
+
/* @__PURE__ */ jsx32(BaseSelect.Portal, { children: /* @__PURE__ */ jsx32(
|
|
2181
2203
|
BaseSelect.Positioner,
|
|
2182
2204
|
{
|
|
2183
2205
|
side: "bottom",
|
|
@@ -2186,25 +2208,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2186
2208
|
collisionPadding: VIEWPORT_PAD4,
|
|
2187
2209
|
alignItemWithTrigger: false,
|
|
2188
2210
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2189
|
-
children: /* @__PURE__ */
|
|
2211
|
+
children: /* @__PURE__ */ jsx32(
|
|
2190
2212
|
BaseSelect.Popup,
|
|
2191
2213
|
{
|
|
2192
|
-
render: /* @__PURE__ */
|
|
2214
|
+
render: /* @__PURE__ */ jsx32(MenuPanel, {}),
|
|
2193
2215
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
2194
|
-
children: /* @__PURE__ */
|
|
2216
|
+
children: /* @__PURE__ */ jsx32(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs23(
|
|
2195
2217
|
BaseSelect.Item,
|
|
2196
2218
|
{
|
|
2197
2219
|
value: option.value,
|
|
2198
2220
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
2199
2221
|
children: [
|
|
2200
2222
|
/* @__PURE__ */ jsxs23("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2201
|
-
option.leading && /* @__PURE__ */
|
|
2202
|
-
/* @__PURE__ */
|
|
2223
|
+
option.leading && /* @__PURE__ */ jsx32("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
2224
|
+
/* @__PURE__ */ jsx32(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
|
|
2203
2225
|
] }),
|
|
2204
|
-
/* @__PURE__ */
|
|
2226
|
+
/* @__PURE__ */ jsx32(
|
|
2205
2227
|
BaseSelect.ItemIndicator,
|
|
2206
2228
|
{
|
|
2207
|
-
render: /* @__PURE__ */
|
|
2229
|
+
render: /* @__PURE__ */ jsx32(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2208
2230
|
}
|
|
2209
2231
|
)
|
|
2210
2232
|
]
|
|
@@ -2223,9 +2245,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2223
2245
|
// src/TextInput.tsx
|
|
2224
2246
|
import { forwardRef as forwardRef2 } from "react";
|
|
2225
2247
|
import { Input } from "@base-ui/react/input";
|
|
2226
|
-
import { jsx as
|
|
2248
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
2227
2249
|
var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
|
|
2228
|
-
return /* @__PURE__ */
|
|
2250
|
+
return /* @__PURE__ */ jsx33(
|
|
2229
2251
|
Input,
|
|
2230
2252
|
{
|
|
2231
2253
|
ref,
|
|
@@ -2251,13 +2273,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
|
|
|
2251
2273
|
// src/Textarea.tsx
|
|
2252
2274
|
import { forwardRef as forwardRef3 } from "react";
|
|
2253
2275
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
2254
|
-
import { jsx as
|
|
2276
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2255
2277
|
var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
2256
|
-
return /* @__PURE__ */
|
|
2278
|
+
return /* @__PURE__ */ jsx34(
|
|
2257
2279
|
BaseField3.Control,
|
|
2258
2280
|
{
|
|
2259
2281
|
ref,
|
|
2260
|
-
render: /* @__PURE__ */
|
|
2282
|
+
render: /* @__PURE__ */ jsx34("textarea", {}),
|
|
2261
2283
|
className: cn(
|
|
2262
2284
|
// The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
|
|
2263
2285
|
// "aren't there hover states in text input and text area?"). Focus comes after hover in
|
|
@@ -2286,24 +2308,24 @@ import { IconX as IconX5 } from "@tabler/icons-react";
|
|
|
2286
2308
|
|
|
2287
2309
|
// src/ContainerHeader.tsx
|
|
2288
2310
|
import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
|
|
2289
|
-
import { jsx as
|
|
2311
|
+
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2290
2312
|
function ContainerHeader({ title, chevron = false, actions, className }) {
|
|
2291
2313
|
const text = typeof title === "string";
|
|
2292
2314
|
return /* @__PURE__ */ jsxs24("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: [
|
|
2293
|
-
/* @__PURE__ */
|
|
2294
|
-
text ? /* @__PURE__ */
|
|
2295
|
-
chevron && /* @__PURE__ */
|
|
2315
|
+
/* @__PURE__ */ jsx35("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs24("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
|
|
2316
|
+
text ? /* @__PURE__ */ jsx35("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx35("div", { className: "min-w-0 flex-1", children: title }),
|
|
2317
|
+
chevron && /* @__PURE__ */ jsx35(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2296
2318
|
] }) }),
|
|
2297
|
-
actions && /* @__PURE__ */
|
|
2319
|
+
actions && /* @__PURE__ */ jsx35("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx35("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
|
|
2298
2320
|
] });
|
|
2299
2321
|
}
|
|
2300
2322
|
|
|
2301
2323
|
// src/DialogShell.tsx
|
|
2302
|
-
import { jsx as
|
|
2324
|
+
import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2303
2325
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
|
|
2304
2326
|
const Parts = alert ? AlertDialog : Dialog3;
|
|
2305
2327
|
const popupRef = useRef6(null);
|
|
2306
|
-
return /* @__PURE__ */
|
|
2328
|
+
return /* @__PURE__ */ jsx36(
|
|
2307
2329
|
Parts.Root,
|
|
2308
2330
|
{
|
|
2309
2331
|
open: true,
|
|
@@ -2311,8 +2333,8 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2311
2333
|
if (!open) onClose();
|
|
2312
2334
|
},
|
|
2313
2335
|
children: /* @__PURE__ */ jsxs25(Parts.Portal, { children: [
|
|
2314
|
-
/* @__PURE__ */
|
|
2315
|
-
/* @__PURE__ */
|
|
2336
|
+
/* @__PURE__ */ jsx36(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
2337
|
+
/* @__PURE__ */ jsx36("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs25(
|
|
2316
2338
|
Parts.Popup,
|
|
2317
2339
|
{
|
|
2318
2340
|
ref: popupRef,
|
|
@@ -2321,10 +2343,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2321
2343
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
2322
2344
|
style: { width },
|
|
2323
2345
|
children: [
|
|
2324
|
-
/* @__PURE__ */
|
|
2346
|
+
/* @__PURE__ */ jsx36(
|
|
2325
2347
|
ContainerHeader,
|
|
2326
2348
|
{
|
|
2327
|
-
title: headerContent ?? /* @__PURE__ */
|
|
2349
|
+
title: headerContent ?? /* @__PURE__ */ jsx36(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx36("span", {}), children: title }),
|
|
2328
2350
|
actions: (
|
|
2329
2351
|
/*
|
|
2330
2352
|
The ✕ IS the `Close` part now, rather than a button that calls
|
|
@@ -2338,10 +2360,10 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2338
2360
|
so the ✕, Escape and the outside press are one path with one
|
|
2339
2361
|
reason attached, instead of one of the three going around.
|
|
2340
2362
|
*/
|
|
2341
|
-
/* @__PURE__ */
|
|
2363
|
+
/* @__PURE__ */ jsx36(
|
|
2342
2364
|
Parts.Close,
|
|
2343
2365
|
{
|
|
2344
|
-
render: /* @__PURE__ */
|
|
2366
|
+
render: /* @__PURE__ */ jsx36(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx36(IconX5, { size: 16, stroke: 1.5 }) })
|
|
2345
2367
|
}
|
|
2346
2368
|
)
|
|
2347
2369
|
)
|
|
@@ -2349,9 +2371,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2349
2371
|
),
|
|
2350
2372
|
bodyMaxHeight ? (
|
|
2351
2373
|
// The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
|
|
2352
|
-
/* @__PURE__ */
|
|
2353
|
-
) : /* @__PURE__ */
|
|
2354
|
-
footer != null && /* @__PURE__ */
|
|
2374
|
+
/* @__PURE__ */ jsx36("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx36(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
|
|
2375
|
+
) : /* @__PURE__ */ jsx36("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
2376
|
+
footer != null && /* @__PURE__ */ jsx36("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
2355
2377
|
]
|
|
2356
2378
|
}
|
|
2357
2379
|
) })
|
|
@@ -2361,7 +2383,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2361
2383
|
}
|
|
2362
2384
|
|
|
2363
2385
|
// src/ConfirmDialog.tsx
|
|
2364
|
-
import { Fragment as
|
|
2386
|
+
import { Fragment as Fragment7, jsx as jsx37, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2365
2387
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
2366
2388
|
const [busy, setBusy] = useState4(false);
|
|
2367
2389
|
const confirm = async () => {
|
|
@@ -2373,17 +2395,17 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2373
2395
|
setBusy(false);
|
|
2374
2396
|
}
|
|
2375
2397
|
};
|
|
2376
|
-
return /* @__PURE__ */
|
|
2398
|
+
return /* @__PURE__ */ jsx37(
|
|
2377
2399
|
DialogShell,
|
|
2378
2400
|
{
|
|
2379
2401
|
alert: true,
|
|
2380
2402
|
title,
|
|
2381
2403
|
onClose,
|
|
2382
|
-
footer: /* @__PURE__ */ jsxs26(
|
|
2383
|
-
/* @__PURE__ */
|
|
2384
|
-
/* @__PURE__ */
|
|
2404
|
+
footer: /* @__PURE__ */ jsxs26(Fragment7, { children: [
|
|
2405
|
+
/* @__PURE__ */ jsx37(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
2406
|
+
/* @__PURE__ */ jsx37(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
2385
2407
|
] }),
|
|
2386
|
-
children: /* @__PURE__ */
|
|
2408
|
+
children: /* @__PURE__ */ jsx37("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
|
|
2387
2409
|
}
|
|
2388
2410
|
);
|
|
2389
2411
|
}
|
|
@@ -2392,7 +2414,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2392
2414
|
import { useEffect as useEffect3, useRef as useRef7, useState as useState5 } from "react";
|
|
2393
2415
|
import { Field as BaseField4 } from "@base-ui/react/field";
|
|
2394
2416
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
2395
|
-
import { jsx as
|
|
2417
|
+
import { jsx as jsx38 } from "react/jsx-runtime";
|
|
2396
2418
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
2397
2419
|
const [editing, setEditing] = useState5(false);
|
|
2398
2420
|
const [draft, setDraft] = useState5(value);
|
|
@@ -2450,7 +2472,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2450
2472
|
written and never read. Read-only, this is a line of text: whatever
|
|
2451
2473
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
2452
2474
|
*/
|
|
2453
|
-
/* @__PURE__ */
|
|
2475
|
+
/* @__PURE__ */ jsx38(
|
|
2454
2476
|
"div",
|
|
2455
2477
|
{
|
|
2456
2478
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -2460,11 +2482,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2460
2482
|
);
|
|
2461
2483
|
}
|
|
2462
2484
|
if (editing) {
|
|
2463
|
-
return multiline ? /* @__PURE__ */
|
|
2485
|
+
return multiline ? /* @__PURE__ */ jsx38(
|
|
2464
2486
|
BaseField4.Control,
|
|
2465
2487
|
{
|
|
2466
2488
|
ref: fieldRef,
|
|
2467
|
-
render: /* @__PURE__ */
|
|
2489
|
+
render: /* @__PURE__ */ jsx38("textarea", { rows: 4 }),
|
|
2468
2490
|
"aria-label": label,
|
|
2469
2491
|
value: draft,
|
|
2470
2492
|
disabled: busy,
|
|
@@ -2473,7 +2495,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2473
2495
|
onBlur: () => void commit(),
|
|
2474
2496
|
className: fieldClass
|
|
2475
2497
|
}
|
|
2476
|
-
) : /* @__PURE__ */
|
|
2498
|
+
) : /* @__PURE__ */ jsx38(
|
|
2477
2499
|
Input2,
|
|
2478
2500
|
{
|
|
2479
2501
|
ref: fieldRef,
|
|
@@ -2487,7 +2509,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2487
2509
|
}
|
|
2488
2510
|
);
|
|
2489
2511
|
}
|
|
2490
|
-
return /* @__PURE__ */
|
|
2512
|
+
return /* @__PURE__ */ jsx38(
|
|
2491
2513
|
"button",
|
|
2492
2514
|
{
|
|
2493
2515
|
type: "button",
|
|
@@ -2507,7 +2529,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2507
2529
|
// src/ErrorBoundary.tsx
|
|
2508
2530
|
import { Component } from "react";
|
|
2509
2531
|
import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
|
|
2510
|
-
import { jsx as
|
|
2532
|
+
import { jsx as jsx39 } from "react/jsx-runtime";
|
|
2511
2533
|
var ErrorBoundary = class extends Component {
|
|
2512
2534
|
state = { hasError: false };
|
|
2513
2535
|
static getDerivedStateFromError() {
|
|
@@ -2518,22 +2540,22 @@ var ErrorBoundary = class extends Component {
|
|
|
2518
2540
|
}
|
|
2519
2541
|
render() {
|
|
2520
2542
|
if (!this.state.hasError) return this.props.children;
|
|
2521
|
-
const message = /* @__PURE__ */
|
|
2543
|
+
const message = /* @__PURE__ */ jsx39(
|
|
2522
2544
|
EmptyState,
|
|
2523
2545
|
{
|
|
2524
|
-
icon: /* @__PURE__ */
|
|
2546
|
+
icon: /* @__PURE__ */ jsx39(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
|
|
2525
2547
|
message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
|
|
2526
2548
|
action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
|
|
2527
2549
|
}
|
|
2528
2550
|
);
|
|
2529
2551
|
if (this.props.frame) return this.props.frame(message);
|
|
2530
|
-
return this.props.fallbackClassName ? /* @__PURE__ */
|
|
2552
|
+
return this.props.fallbackClassName ? /* @__PURE__ */ jsx39("div", { className: this.props.fallbackClassName, children: message }) : message;
|
|
2531
2553
|
}
|
|
2532
2554
|
};
|
|
2533
2555
|
|
|
2534
2556
|
// src/ProgressBar.tsx
|
|
2535
2557
|
import { Progress } from "@base-ui/react/progress";
|
|
2536
|
-
import { jsx as
|
|
2558
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
2537
2559
|
var TRACK_CLASSES = {
|
|
2538
2560
|
default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
|
|
2539
2561
|
// 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
|
|
@@ -2546,13 +2568,13 @@ var INDICATOR_CLASSES = {
|
|
|
2546
2568
|
function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
2547
2569
|
return (
|
|
2548
2570
|
// `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
|
|
2549
|
-
/* @__PURE__ */
|
|
2571
|
+
/* @__PURE__ */ jsx40(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx40(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx40(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
|
|
2550
2572
|
);
|
|
2551
2573
|
}
|
|
2552
2574
|
|
|
2553
2575
|
// src/Breadcrumb.tsx
|
|
2554
|
-
import { Fragment as
|
|
2555
|
-
import { jsx as
|
|
2576
|
+
import { Fragment as Fragment8, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as useRef8, useState as useState6 } from "react";
|
|
2577
|
+
import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2556
2578
|
function Breadcrumb({ items, className }) {
|
|
2557
2579
|
const navRef = useRef8(null);
|
|
2558
2580
|
const labelRefs = useRef8([]);
|
|
@@ -2572,7 +2594,7 @@ function Breadcrumb({ items, className }) {
|
|
|
2572
2594
|
observer.observe(nav);
|
|
2573
2595
|
return () => observer.disconnect();
|
|
2574
2596
|
}, [measure, items]);
|
|
2575
|
-
return /* @__PURE__ */
|
|
2597
|
+
return /* @__PURE__ */ jsx41("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) => {
|
|
2576
2598
|
const last = index === items.length - 1;
|
|
2577
2599
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
2578
2600
|
const text = cn(
|
|
@@ -2593,23 +2615,23 @@ function Breadcrumb({ items, className }) {
|
|
|
2593
2615
|
// on a box around it, which the link takes them from, rather than
|
|
2594
2616
|
// pushed into it (UIG-9); the link is still the one element that
|
|
2595
2617
|
// truncates and is measured.
|
|
2596
|
-
/* @__PURE__ */
|
|
2597
|
-
) : /* @__PURE__ */
|
|
2598
|
-
return /* @__PURE__ */ jsxs27(
|
|
2599
|
-
index > 0 && /* @__PURE__ */
|
|
2600
|
-
item.icon && /* @__PURE__ */
|
|
2618
|
+
/* @__PURE__ */ jsx41("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx41(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
|
|
2619
|
+
) : /* @__PURE__ */ jsx41("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
2620
|
+
return /* @__PURE__ */ jsxs27(Fragment8, { children: [
|
|
2621
|
+
index > 0 && /* @__PURE__ */ jsx41("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
2622
|
+
item.icon && /* @__PURE__ */ jsx41("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
2601
2623
|
truncated.has(index) ? (
|
|
2602
2624
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
2603
2625
|
// must keep truncating inside it, or wrapping it would widen the
|
|
2604
2626
|
// trail and the tooltip would never be needed again.
|
|
2605
|
-
/* @__PURE__ */
|
|
2627
|
+
/* @__PURE__ */ jsx41(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
2606
2628
|
) : crumb
|
|
2607
2629
|
] }, `${item.label}-${index}`);
|
|
2608
2630
|
}) });
|
|
2609
2631
|
}
|
|
2610
2632
|
|
|
2611
2633
|
// src/NavItem.tsx
|
|
2612
|
-
import { jsx as
|
|
2634
|
+
import { jsx as jsx42, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2613
2635
|
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
2614
2636
|
return (
|
|
2615
2637
|
// @estiva-escape(no-copied-look): N5 (Katerina, 24 September: record only): a row that fills on hover, as PersonTrigger's row also does
|
|
@@ -2628,9 +2650,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
2628
2650
|
),
|
|
2629
2651
|
...props,
|
|
2630
2652
|
children: [
|
|
2631
|
-
icon && /* @__PURE__ */
|
|
2632
|
-
/* @__PURE__ */
|
|
2633
|
-
count ? /* @__PURE__ */
|
|
2653
|
+
icon && /* @__PURE__ */ jsx42("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
2654
|
+
/* @__PURE__ */ jsx42("span", { className: "flex-1 truncate", children: label }),
|
|
2655
|
+
count ? /* @__PURE__ */ jsx42(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx42("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
2634
2656
|
]
|
|
2635
2657
|
}
|
|
2636
2658
|
)
|
|
@@ -2640,7 +2662,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
2640
2662
|
// src/Popover.tsx
|
|
2641
2663
|
import { useMemo as useMemo3 } from "react";
|
|
2642
2664
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
2643
|
-
import { jsx as
|
|
2665
|
+
import { jsx as jsx43, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2644
2666
|
var GAP5 = 4;
|
|
2645
2667
|
var VIEWPORT_PAD5 = 8;
|
|
2646
2668
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -2657,8 +2679,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2657
2679
|
actionsRef,
|
|
2658
2680
|
modal: false,
|
|
2659
2681
|
children: [
|
|
2660
|
-
trigger && /* @__PURE__ */
|
|
2661
|
-
/* @__PURE__ */
|
|
2682
|
+
trigger && /* @__PURE__ */ jsx43(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
2683
|
+
/* @__PURE__ */ jsx43(BasePopover.Portal, { children: /* @__PURE__ */ jsx43(
|
|
2662
2684
|
BasePopover.Positioner,
|
|
2663
2685
|
{
|
|
2664
2686
|
anchor: anchorTarget,
|
|
@@ -2667,20 +2689,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2667
2689
|
sideOffset: GAP5,
|
|
2668
2690
|
collisionPadding: VIEWPORT_PAD5,
|
|
2669
2691
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2670
|
-
children: /* @__PURE__ */
|
|
2692
|
+
children: /* @__PURE__ */ jsx43(
|
|
2671
2693
|
BasePopover.Popup,
|
|
2672
2694
|
{
|
|
2673
2695
|
"aria-label": ariaLabel,
|
|
2674
2696
|
initialFocus: trigger ? void 0 : false,
|
|
2675
2697
|
finalFocus,
|
|
2676
2698
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
2677
|
-
render: /* @__PURE__ */
|
|
2678
|
-
children: /* @__PURE__ */
|
|
2699
|
+
render: /* @__PURE__ */ jsx43(MenuPanel, {}),
|
|
2700
|
+
children: /* @__PURE__ */ jsx43(
|
|
2679
2701
|
ScrollArea,
|
|
2680
2702
|
{
|
|
2681
2703
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
2682
2704
|
contentClassName: cn("flex flex-col p-2", contentClassName),
|
|
2683
|
-
children: /* @__PURE__ */
|
|
2705
|
+
children: /* @__PURE__ */ jsx43(DividerInPanel.Provider, { value: true, children })
|
|
2684
2706
|
}
|
|
2685
2707
|
)
|
|
2686
2708
|
}
|
|
@@ -2694,9 +2716,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2694
2716
|
|
|
2695
2717
|
// src/Toolbar.tsx
|
|
2696
2718
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
2697
|
-
import { jsx as
|
|
2719
|
+
import { jsx as jsx44 } from "react/jsx-runtime";
|
|
2698
2720
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
2699
|
-
const strip = /* @__PURE__ */
|
|
2721
|
+
const strip = /* @__PURE__ */ jsx44(
|
|
2700
2722
|
BaseToolbar.Root,
|
|
2701
2723
|
{
|
|
2702
2724
|
"aria-label": ariaLabel,
|
|
@@ -2707,27 +2729,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
2707
2729
|
}
|
|
2708
2730
|
);
|
|
2709
2731
|
if (!surface) return strip;
|
|
2710
|
-
return /* @__PURE__ */
|
|
2732
|
+
return /* @__PURE__ */ jsx44(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
2711
2733
|
}
|
|
2712
2734
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
2713
|
-
return /* @__PURE__ */
|
|
2735
|
+
return /* @__PURE__ */ jsx44(
|
|
2714
2736
|
BaseToolbar.Button,
|
|
2715
2737
|
{
|
|
2716
2738
|
ref,
|
|
2717
2739
|
disabled: disabled || !!disabledReason,
|
|
2718
2740
|
focusableWhenDisabled: true,
|
|
2719
|
-
render: /* @__PURE__ */
|
|
2741
|
+
render: /* @__PURE__ */ jsx44(IconButton, { disabled, disabledReason, ...props })
|
|
2720
2742
|
}
|
|
2721
2743
|
);
|
|
2722
2744
|
}
|
|
2723
2745
|
function ToolbarLink({ ref, href, ...props }) {
|
|
2724
|
-
return /* @__PURE__ */
|
|
2746
|
+
return /* @__PURE__ */ jsx44(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx44(IconButton, { href, ...props }) });
|
|
2725
2747
|
}
|
|
2726
2748
|
function ToolbarInput({ size, ...props }) {
|
|
2727
|
-
return /* @__PURE__ */
|
|
2749
|
+
return /* @__PURE__ */ jsx44(BaseToolbar.Input, { render: /* @__PURE__ */ jsx44(TextInput, { size }), ...props });
|
|
2728
2750
|
}
|
|
2729
2751
|
function ToolbarSeparator({ className }) {
|
|
2730
|
-
return /* @__PURE__ */
|
|
2752
|
+
return /* @__PURE__ */ jsx44(
|
|
2731
2753
|
BaseToolbar.Separator,
|
|
2732
2754
|
{
|
|
2733
2755
|
orientation: "vertical",
|
|
@@ -2737,9 +2759,9 @@ function ToolbarSeparator({ className }) {
|
|
|
2737
2759
|
}
|
|
2738
2760
|
|
|
2739
2761
|
// src/ReactionPicker.tsx
|
|
2740
|
-
import { jsx as
|
|
2762
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
2741
2763
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
2742
|
-
return /* @__PURE__ */
|
|
2764
|
+
return /* @__PURE__ */ jsx45(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
2743
2765
|
/*
|
|
2744
2766
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
2745
2767
|
would become the toolbar's item and the button inside it would never
|
|
@@ -2749,14 +2771,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2749
2771
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
2750
2772
|
and both say the meaning rather than the glyph.
|
|
2751
2773
|
*/
|
|
2752
|
-
/* @__PURE__ */
|
|
2774
|
+
/* @__PURE__ */ jsx45(
|
|
2753
2775
|
ToolbarButton,
|
|
2754
2776
|
{
|
|
2755
2777
|
"aria-label": option.label,
|
|
2756
2778
|
tooltip: option.label,
|
|
2757
2779
|
onClick: () => onSelect(option.emoji),
|
|
2758
2780
|
className: "size-7",
|
|
2759
|
-
children: /* @__PURE__ */
|
|
2781
|
+
children: /* @__PURE__ */ jsx45("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
2760
2782
|
},
|
|
2761
2783
|
option.emoji
|
|
2762
2784
|
)
|
|
@@ -2765,23 +2787,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2765
2787
|
|
|
2766
2788
|
// src/PreviewCard.tsx
|
|
2767
2789
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
2768
|
-
import { jsx as
|
|
2790
|
+
import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2769
2791
|
var GAP6 = 12;
|
|
2770
2792
|
var VIEWPORT_PAD6 = 8;
|
|
2771
2793
|
var OPEN_DELAY2 = 350;
|
|
2772
2794
|
var CLOSE_DELAY = 200;
|
|
2773
2795
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
2774
2796
|
return /* @__PURE__ */ jsxs30(BasePreviewCard.Root, { children: [
|
|
2775
|
-
/* @__PURE__ */
|
|
2797
|
+
/* @__PURE__ */ jsx46(
|
|
2776
2798
|
BasePreviewCard.Trigger,
|
|
2777
2799
|
{
|
|
2778
2800
|
delay,
|
|
2779
2801
|
closeDelay,
|
|
2780
|
-
render: /* @__PURE__ */
|
|
2802
|
+
render: /* @__PURE__ */ jsx46("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
2781
2803
|
children
|
|
2782
2804
|
}
|
|
2783
2805
|
),
|
|
2784
|
-
/* @__PURE__ */
|
|
2806
|
+
/* @__PURE__ */ jsx46(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx46(
|
|
2785
2807
|
BasePreviewCard.Positioner,
|
|
2786
2808
|
{
|
|
2787
2809
|
side,
|
|
@@ -2789,12 +2811,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2789
2811
|
sideOffset: GAP6,
|
|
2790
2812
|
collisionPadding: VIEWPORT_PAD6,
|
|
2791
2813
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2792
|
-
children: /* @__PURE__ */
|
|
2814
|
+
children: /* @__PURE__ */ jsx46(
|
|
2793
2815
|
BasePreviewCard.Popup,
|
|
2794
2816
|
{
|
|
2795
2817
|
className: cn("w-[360px] p-0 outline-none", className),
|
|
2796
|
-
render: /* @__PURE__ */
|
|
2797
|
-
children: /* @__PURE__ */
|
|
2818
|
+
render: /* @__PURE__ */ jsx46(MenuPanel, {}),
|
|
2819
|
+
children: /* @__PURE__ */ jsx46(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
2798
2820
|
}
|
|
2799
2821
|
)
|
|
2800
2822
|
}
|
|
@@ -2803,13 +2825,13 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2803
2825
|
}
|
|
2804
2826
|
|
|
2805
2827
|
// src/Rail.tsx
|
|
2806
|
-
import { jsx as
|
|
2828
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
2807
2829
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
2808
|
-
return /* @__PURE__ */
|
|
2830
|
+
return /* @__PURE__ */ jsx47("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
2809
2831
|
}
|
|
2810
2832
|
|
|
2811
2833
|
// src/RailItem.tsx
|
|
2812
|
-
import { jsx as
|
|
2834
|
+
import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2813
2835
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
2814
2836
|
return /* @__PURE__ */ jsxs31(
|
|
2815
2837
|
"a",
|
|
@@ -2819,14 +2841,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2819
2841
|
className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
2820
2842
|
...props,
|
|
2821
2843
|
children: [
|
|
2822
|
-
/* @__PURE__ */
|
|
2844
|
+
/* @__PURE__ */ jsx48(
|
|
2823
2845
|
"div",
|
|
2824
2846
|
{
|
|
2825
2847
|
className: cn(
|
|
2826
2848
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
2827
2849
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
2828
2850
|
),
|
|
2829
|
-
children: /* @__PURE__ */
|
|
2851
|
+
children: /* @__PURE__ */ jsx48(
|
|
2830
2852
|
"span",
|
|
2831
2853
|
{
|
|
2832
2854
|
className: cn(
|
|
@@ -2838,25 +2860,12 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2838
2860
|
)
|
|
2839
2861
|
}
|
|
2840
2862
|
),
|
|
2841
|
-
/* @__PURE__ */
|
|
2863
|
+
/* @__PURE__ */ jsx48("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
2842
2864
|
]
|
|
2843
2865
|
}
|
|
2844
2866
|
);
|
|
2845
2867
|
}
|
|
2846
2868
|
|
|
2847
|
-
// src/Sidebar.tsx
|
|
2848
|
-
import { jsx as jsx48 } from "react/jsx-runtime";
|
|
2849
|
-
function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
|
|
2850
|
-
return /* @__PURE__ */ jsx48(
|
|
2851
|
-
"nav",
|
|
2852
|
-
{
|
|
2853
|
-
"aria-label": ariaLabel,
|
|
2854
|
-
className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
|
|
2855
|
-
children: /* @__PURE__ */ jsx48(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
|
|
2856
|
-
}
|
|
2857
|
-
);
|
|
2858
|
-
}
|
|
2859
|
-
|
|
2860
2869
|
// src/Property.tsx
|
|
2861
2870
|
import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2862
2871
|
var VALUE_CLASSES = "contents";
|
|
@@ -2948,7 +2957,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2948
2957
|
// src/SectionHeader.tsx
|
|
2949
2958
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
2950
2959
|
import { useRender } from "@base-ui/react/use-render";
|
|
2951
|
-
import { Fragment as
|
|
2960
|
+
import { Fragment as Fragment9, jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2952
2961
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", render, className }) {
|
|
2953
2962
|
const titleElement = useRender({
|
|
2954
2963
|
render: render ?? (chevron ? /* @__PURE__ */ jsx52("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx52("span", {})),
|
|
@@ -2957,7 +2966,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2957
2966
|
// whole row up to the actions is the hit target, as it was when the
|
|
2958
2967
|
// row itself carried the click.
|
|
2959
2968
|
className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
|
|
2960
|
-
children: /* @__PURE__ */ jsxs35(
|
|
2969
|
+
children: /* @__PURE__ */ jsxs35(Fragment9, { children: [
|
|
2961
2970
|
chevron && /* @__PURE__ */ jsx52(
|
|
2962
2971
|
IconChevronRight2,
|
|
2963
2972
|
{
|
|
@@ -3153,16 +3162,16 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3153
3162
|
}
|
|
3154
3163
|
|
|
3155
3164
|
// src/Toast.tsx
|
|
3156
|
-
import { createContext as
|
|
3165
|
+
import { createContext as createContext6, useContext as useContext6, useMemo as useMemo4 } from "react";
|
|
3157
3166
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
3158
3167
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
3159
3168
|
import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3160
3169
|
var SURFACE_STYLES = {
|
|
3161
|
-
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
3162
|
-
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
3163
|
-
neutral: "bg-bg-inset border border-border-subtle signal:border-border-default signal:shadow-md",
|
|
3164
|
-
warning: "bg-warning-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
3165
|
-
error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md"
|
|
3170
|
+
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",
|
|
3171
|
+
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",
|
|
3172
|
+
neutral: "bg-bg-inset border border-border-subtle signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
3173
|
+
warning: "bg-warning-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",
|
|
3174
|
+
error: "bg-error-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
3175
|
};
|
|
3167
3176
|
var ICONS = {
|
|
3168
3177
|
success: IconCircleCheck,
|
|
@@ -3204,7 +3213,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
3204
3213
|
hasAction && /* @__PURE__ */ jsx57(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
3205
3214
|
] });
|
|
3206
3215
|
}
|
|
3207
|
-
var ToastContext =
|
|
3216
|
+
var ToastContext = createContext6(null);
|
|
3208
3217
|
var VISIBLE_TOASTS = 3;
|
|
3209
3218
|
function ToastProvider({ children }) {
|
|
3210
3219
|
const manager = useMemo4(() => BaseToast.createToastManager(), []);
|
|
@@ -3260,7 +3269,7 @@ function ToastList() {
|
|
|
3260
3269
|
});
|
|
3261
3270
|
}
|
|
3262
3271
|
function useToast() {
|
|
3263
|
-
const ctx =
|
|
3272
|
+
const ctx = useContext6(ToastContext);
|
|
3264
3273
|
if (!ctx) throw new Error("useToast must be used within ToastProvider");
|
|
3265
3274
|
return ctx;
|
|
3266
3275
|
}
|