@estiva-app/ui 0.12.10 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AttachmentCard.d.ts +52 -0
- package/dist/AttachmentCard.d.ts.map +1 -0
- package/dist/Card.d.ts +54 -0
- package/dist/Card.d.ts.map +1 -0
- package/dist/InlineChip.d.ts +59 -0
- package/dist/InlineChip.d.ts.map +1 -0
- package/dist/Link.d.ts +37 -0
- package/dist/Link.d.ts.map +1 -0
- package/dist/ProgressBar.d.ts +32 -0
- package/dist/ProgressBar.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +704 -355
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/src/AttachmentCard.mdx +62 -0
- package/src/AttachmentCard.stories.tsx +92 -0
- package/src/AttachmentCard.test.tsx +172 -0
- package/src/AttachmentCard.tsx +324 -0
- package/src/Card.mdx +74 -0
- package/src/Card.stories.tsx +112 -0
- package/src/Card.test.tsx +147 -0
- package/src/Card.tsx +133 -0
- package/src/EmptyState.mdx +14 -0
- package/src/EmptyState.stories.tsx +28 -7
- package/src/EmptyState.test.tsx +8 -0
- package/src/InlineChip.mdx +56 -0
- package/src/InlineChip.stories.tsx +59 -0
- package/src/InlineChip.test.tsx +81 -0
- package/src/InlineChip.tsx +90 -0
- package/src/Link.mdx +59 -0
- package/src/Link.stories.tsx +102 -0
- package/src/Link.test.tsx +100 -0
- package/src/Link.tsx +58 -0
- package/src/Person.stories.tsx +1 -1
- package/src/PersonTrigger.stories.tsx +1 -1
- package/src/ProgressBar.mdx +47 -0
- package/src/ProgressBar.stories.tsx +48 -0
- package/src/ProgressBar.test.tsx +62 -0
- package/src/ProgressBar.tsx +56 -0
- package/src/ReactionPicker.stories.tsx +1 -1
- package/src/index.ts +12 -0
- package/stories/Choosing.mdx +5 -0
package/dist/index.js
CHANGED
|
@@ -133,77 +133,113 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
133
133
|
);
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
// src/
|
|
137
|
-
import { useState } from "react";
|
|
138
|
-
import {
|
|
136
|
+
// src/AttachmentCard.tsx
|
|
137
|
+
import { useLayoutEffect, useRef, useState } from "react";
|
|
138
|
+
import { Button as BaseButton2 } from "@base-ui/react/button";
|
|
139
|
+
import {
|
|
140
|
+
IconAlertCircle,
|
|
141
|
+
IconAlertTriangle,
|
|
142
|
+
IconDownload,
|
|
143
|
+
IconFile,
|
|
144
|
+
IconFileTypeCsv,
|
|
145
|
+
IconFileTypeDocx,
|
|
146
|
+
IconFileTypePdf,
|
|
147
|
+
IconFileTypePpt,
|
|
148
|
+
IconFileTypeTxt,
|
|
149
|
+
IconFileTypeXls,
|
|
150
|
+
IconFileTypeZip,
|
|
151
|
+
IconJson,
|
|
152
|
+
IconLoader2,
|
|
153
|
+
IconMarkdown,
|
|
154
|
+
IconX
|
|
155
|
+
} from "@tabler/icons-react";
|
|
156
|
+
|
|
157
|
+
// src/Link.tsx
|
|
139
158
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
140
|
-
var
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
var VARIANT_CLASSES = {
|
|
160
|
+
text: "text-info-default underline underline-offset-2 hover:opacity-80",
|
|
161
|
+
quiet: "hover:underline",
|
|
162
|
+
underlined: "underline underline-offset-2 hover:text-text-primary",
|
|
163
|
+
plain: ""
|
|
145
164
|
};
|
|
146
|
-
|
|
147
|
-
const words = name.split(/\s+/).slice(0, 2).filter((w) => /^[\p{L}\p{N}]/u.test(w));
|
|
148
|
-
const initials = words.map((w) => w[0]).join("") || name.trim().charAt(0);
|
|
149
|
-
return initials.toUpperCase();
|
|
150
|
-
};
|
|
151
|
-
function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
152
|
-
const [broken, setBroken] = useState(false);
|
|
153
|
-
const label = name || alt;
|
|
154
|
-
const picture = src && !broken ? src : void 0;
|
|
165
|
+
function Link({ href, variant = "text", external = false, className, children, ...props }) {
|
|
155
166
|
return /* @__PURE__ */ jsx4(
|
|
156
|
-
"
|
|
167
|
+
"a",
|
|
157
168
|
{
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
{
|
|
164
|
-
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
165
|
-
style: {
|
|
166
|
-
// The one ink colour that reads on all eight hues, which are a
|
|
167
|
-
// palette rather than tokens (see the note at the top) — so its
|
|
168
|
-
// ink cannot be a token either.
|
|
169
|
-
color: "#08121c",
|
|
170
|
-
fontSize: Math.round(size * 0.36),
|
|
171
|
-
background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
|
|
172
|
-
},
|
|
173
|
-
children: initialsFor(label)
|
|
174
|
-
}
|
|
175
|
-
) : /* @__PURE__ */ jsx4("div", { className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx4(IconUserFilled, { size: Math.round(size * 0.5) }) })
|
|
169
|
+
href,
|
|
170
|
+
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
171
|
+
className: cn(VARIANT_CLASSES[variant], className),
|
|
172
|
+
...props,
|
|
173
|
+
children
|
|
176
174
|
}
|
|
177
175
|
);
|
|
178
176
|
}
|
|
179
177
|
|
|
180
|
-
// src/
|
|
178
|
+
// src/Card.tsx
|
|
181
179
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
180
|
+
var FILL_CLASSES = {
|
|
181
|
+
surface: "bg-bg-surface border-border-default",
|
|
182
|
+
elevated: "bg-bg-elevated border-border-default",
|
|
183
|
+
inset: "bg-bg-inset border-border-subtle",
|
|
184
|
+
none: "border-border-subtle"
|
|
185
|
+
};
|
|
186
|
+
var HAIRLINE_HOVER_CLASSES = {
|
|
187
|
+
surface: "hover:border-border-strong",
|
|
188
|
+
elevated: "hover:border-border-strong",
|
|
189
|
+
inset: "hover:border-border-default",
|
|
190
|
+
none: "hover:border-border-default"
|
|
191
|
+
};
|
|
192
|
+
var HAIRLINE_HELD_CLASSES = {
|
|
193
|
+
surface: "border-border-strong",
|
|
194
|
+
elevated: "border-border-strong",
|
|
195
|
+
inset: "border-border-default",
|
|
196
|
+
none: "border-border-default"
|
|
197
|
+
};
|
|
198
|
+
var ATTENTION_CLASSES = {
|
|
199
|
+
accent: "border-accent-muted hover:border-accent-muted",
|
|
200
|
+
warning: "border-warning-muted hover:border-warning-muted"
|
|
201
|
+
};
|
|
202
|
+
function Card({
|
|
203
|
+
fill = "surface",
|
|
204
|
+
href,
|
|
205
|
+
hover = href ? "hairline" : "none",
|
|
206
|
+
quietUntilHover = false,
|
|
207
|
+
hovered = false,
|
|
208
|
+
selected = false,
|
|
209
|
+
active = false,
|
|
210
|
+
attention,
|
|
211
|
+
unreadable = false,
|
|
212
|
+
className,
|
|
213
|
+
children,
|
|
214
|
+
...props
|
|
215
|
+
}) {
|
|
216
|
+
const still = selected || active;
|
|
217
|
+
const classes = cn(
|
|
218
|
+
"rounded-lg border",
|
|
219
|
+
// A card that never changes has nothing to ease between, and the apps' still cards carry no transition.
|
|
220
|
+
hover !== "none" && "transition-colors",
|
|
221
|
+
FILL_CLASSES[fill],
|
|
222
|
+
quietUntilHover && "border-transparent",
|
|
223
|
+
!still && hover === "hairline" && HAIRLINE_HOVER_CLASSES[fill],
|
|
224
|
+
!still && hover === "fill" && "hover:bg-bg-hover hover:border-border-default",
|
|
225
|
+
!still && hovered && hover === "hairline" && HAIRLINE_HELD_CLASSES[fill],
|
|
226
|
+
!still && hovered && hover === "fill" && "bg-bg-hover border-border-default",
|
|
227
|
+
// The one you are on can still be clicked (it opens again); the one being changed cannot.
|
|
228
|
+
!active && hover !== "none" && !href && props.onClick && "cursor-pointer",
|
|
229
|
+
selected && "bg-bg-selected border-border-subtle",
|
|
230
|
+
active && "bg-bg-selected border-accent-primary",
|
|
231
|
+
!active && attention && ATTENTION_CLASSES[attention],
|
|
232
|
+
unreadable && "border-dashed",
|
|
233
|
+
href && "block",
|
|
234
|
+
className
|
|
235
|
+
);
|
|
236
|
+
if (href !== void 0) {
|
|
237
|
+
const { ref, ...anchorProps } = props;
|
|
238
|
+
return /* @__PURE__ */ jsx5(Link, { href, variant: "plain", ref, className: classes, ...anchorProps, children });
|
|
239
|
+
}
|
|
240
|
+
return /* @__PURE__ */ jsx5("div", { className: classes, ...props, children });
|
|
202
241
|
}
|
|
203
242
|
|
|
204
|
-
// src/Banner.tsx
|
|
205
|
-
import { IconX } from "@tabler/icons-react";
|
|
206
|
-
|
|
207
243
|
// src/IconButton.tsx
|
|
208
244
|
import { Button as BaseButton } from "@base-ui/react/button";
|
|
209
245
|
|
|
@@ -344,8 +380,260 @@ function IconButton({
|
|
|
344
380
|
return button;
|
|
345
381
|
}
|
|
346
382
|
|
|
383
|
+
// src/AttachmentCard.tsx
|
|
384
|
+
import { Fragment, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
385
|
+
var ICON_BY_EXTENSION = {
|
|
386
|
+
pdf: IconFileTypePdf,
|
|
387
|
+
doc: IconFileTypeDocx,
|
|
388
|
+
docx: IconFileTypeDocx,
|
|
389
|
+
xls: IconFileTypeXls,
|
|
390
|
+
xlsx: IconFileTypeXls,
|
|
391
|
+
ppt: IconFileTypePpt,
|
|
392
|
+
pptx: IconFileTypePpt,
|
|
393
|
+
csv: IconFileTypeCsv,
|
|
394
|
+
txt: IconFileTypeTxt,
|
|
395
|
+
rtf: IconFileTypeTxt,
|
|
396
|
+
zip: IconFileTypeZip,
|
|
397
|
+
json: IconJson,
|
|
398
|
+
md: IconMarkdown
|
|
399
|
+
};
|
|
400
|
+
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Set(["png", "jpg", "jpeg", "gif", "webp", "heic", "heif", "svg"]);
|
|
401
|
+
var extensionOf = (name) => {
|
|
402
|
+
const dot = name.lastIndexOf(".");
|
|
403
|
+
return dot >= 0 ? name.slice(dot + 1).toLowerCase() : "";
|
|
404
|
+
};
|
|
405
|
+
var isImage = (name, contentType) => IMAGE_EXTENSIONS.has(extensionOf(name)) || (contentType?.startsWith("image/") ?? false);
|
|
406
|
+
var formatBytes = (bytes) => {
|
|
407
|
+
if (bytes < 1024) return `${bytes} bytes`;
|
|
408
|
+
const kb = bytes / 1024;
|
|
409
|
+
if (kb < 1024) return `${Math.round(kb)} KB`;
|
|
410
|
+
return `${(kb / 1024).toFixed(1)} MB`;
|
|
411
|
+
};
|
|
412
|
+
var typeLabelOf = (name) => extensionOf(name).toUpperCase() || "FILE";
|
|
413
|
+
var TILE = "size-9 rounded-md bg-bg-active flex items-center justify-center shrink-0 text-text-secondary";
|
|
414
|
+
var NAME = "text-[12px] font-medium leading-[1.3] text-text-primary truncate";
|
|
415
|
+
var NOTE = "text-[10px] leading-[1.2] truncate";
|
|
416
|
+
function TypeIcon({ name }) {
|
|
417
|
+
const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
|
|
418
|
+
return /* @__PURE__ */ jsx9(Icon, { size: 20, stroke: 1.5 });
|
|
419
|
+
}
|
|
420
|
+
function Truncating({ text, hint, className, wrapperClassName }) {
|
|
421
|
+
const ref = useRef(null);
|
|
422
|
+
const [cut, setCut] = useState(false);
|
|
423
|
+
useLayoutEffect(() => {
|
|
424
|
+
const el = ref.current;
|
|
425
|
+
if (!el) return;
|
|
426
|
+
let live = true;
|
|
427
|
+
const measure = () => {
|
|
428
|
+
if (live) setCut(el.scrollWidth > el.clientWidth);
|
|
429
|
+
};
|
|
430
|
+
measure();
|
|
431
|
+
void document.fonts?.ready.then(measure);
|
|
432
|
+
if (typeof ResizeObserver === "undefined") return () => void (live = false);
|
|
433
|
+
const observer = new ResizeObserver(measure);
|
|
434
|
+
observer.observe(el);
|
|
435
|
+
return () => {
|
|
436
|
+
live = false;
|
|
437
|
+
observer.disconnect();
|
|
438
|
+
};
|
|
439
|
+
}, [text, cut]);
|
|
440
|
+
const line = /* @__PURE__ */ jsx9("span", { ref, className, children: text });
|
|
441
|
+
if (!hint && !cut) return line;
|
|
442
|
+
return /* @__PURE__ */ jsx9(WithTooltip, { label: hint ?? text, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
|
|
443
|
+
}
|
|
444
|
+
function AttachmentCard({
|
|
445
|
+
name,
|
|
446
|
+
size,
|
|
447
|
+
contentType,
|
|
448
|
+
href,
|
|
449
|
+
src,
|
|
450
|
+
onOpen,
|
|
451
|
+
onDownload,
|
|
452
|
+
pending = false,
|
|
453
|
+
onRemove,
|
|
454
|
+
state = "ready",
|
|
455
|
+
note,
|
|
456
|
+
noteHint,
|
|
457
|
+
className,
|
|
458
|
+
...props
|
|
459
|
+
}) {
|
|
460
|
+
const image = isImage(name, contentType);
|
|
461
|
+
const sizeText = size === void 0 ? "" : formatBytes(size);
|
|
462
|
+
if (pending) {
|
|
463
|
+
const failed = state === "failed";
|
|
464
|
+
const warning = state === "warning";
|
|
465
|
+
return /* @__PURE__ */ jsxs5(
|
|
466
|
+
Card,
|
|
467
|
+
{
|
|
468
|
+
fill: "elevated",
|
|
469
|
+
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),
|
|
470
|
+
...props,
|
|
471
|
+
children: [
|
|
472
|
+
/* @__PURE__ */ jsx9("div", { className: cn(TILE, "overflow-hidden"), children: state === "uploading" ? /* @__PURE__ */ jsx9(IconLoader2, { size: 16, stroke: 1.5, className: "animate-spin" }) : failed ? /* @__PURE__ */ jsx9(IconAlertCircle, { size: 16, stroke: 1.5, className: "text-error-default" }) : warning ? /* @__PURE__ */ jsx9(IconAlertTriangle, { size: 16, stroke: 1.5, className: "text-warning-default" }) : image && src ? /* @__PURE__ */ jsx9("img", { src, alt: name, className: "size-full object-cover" }) : /* @__PURE__ */ jsx9("span", { className: "text-[9px] font-semibold", children: typeLabelOf(name) }) }),
|
|
473
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
474
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME }),
|
|
475
|
+
/* @__PURE__ */ jsx9(
|
|
476
|
+
Truncating,
|
|
477
|
+
{
|
|
478
|
+
text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
|
|
479
|
+
hint: noteHint,
|
|
480
|
+
className: cn(NOTE, failed ? "text-error-default" : warning ? "text-warning-default" : "text-text-secondary")
|
|
481
|
+
}
|
|
482
|
+
)
|
|
483
|
+
] }),
|
|
484
|
+
onRemove && /* @__PURE__ */ jsx9(
|
|
485
|
+
BaseButton2,
|
|
486
|
+
{
|
|
487
|
+
type: "button",
|
|
488
|
+
"aria-label": `Remove ${name}`,
|
|
489
|
+
className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-bg-elevated border border-border-strong flex items-center justify-center text-text-secondary hover:text-text-primary opacity-0 group-hover:opacity-100 transition-opacity",
|
|
490
|
+
onClick: (event) => {
|
|
491
|
+
event.stopPropagation();
|
|
492
|
+
onRemove();
|
|
493
|
+
},
|
|
494
|
+
children: /* @__PURE__ */ jsx9(IconX, { size: 11, stroke: 1.75 })
|
|
495
|
+
}
|
|
496
|
+
)
|
|
497
|
+
]
|
|
498
|
+
}
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
const download = onDownload ? /* @__PURE__ */ jsx9(
|
|
502
|
+
IconButton,
|
|
503
|
+
{
|
|
504
|
+
variant: "muted",
|
|
505
|
+
tooltip: "Download",
|
|
506
|
+
"aria-label": `Download ${name}`,
|
|
507
|
+
className: "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 transition-opacity",
|
|
508
|
+
onClick: (event) => {
|
|
509
|
+
event.stopPropagation();
|
|
510
|
+
onDownload();
|
|
511
|
+
},
|
|
512
|
+
children: /* @__PURE__ */ jsx9(IconDownload, { size: 16, stroke: 1.5 })
|
|
513
|
+
}
|
|
514
|
+
) : null;
|
|
515
|
+
if (state === "loading") {
|
|
516
|
+
return (
|
|
517
|
+
// `role="status"`: a plain box may not carry a name (axe, aria-prohibited-attr), and a
|
|
518
|
+
// status says what it is doing — loading — to a reader that cannot see the pulse.
|
|
519
|
+
/* @__PURE__ */ jsx9(Card, { role: "status", fill: "inset", "aria-busy": "true", "aria-label": `Loading ${name}`, className: cn("w-[180px] h-28 animate-pulse", className), ...props, children: null })
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
if (state === "unreadable") {
|
|
523
|
+
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
|
|
524
|
+
/* @__PURE__ */ jsx9("div", { className: TILE, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
|
|
525
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
526
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME }),
|
|
527
|
+
/* @__PURE__ */ jsx9("span", { className: cn(NOTE, "text-text-secondary"), children: note ?? "Could not be loaded" })
|
|
528
|
+
] })
|
|
529
|
+
] });
|
|
530
|
+
}
|
|
531
|
+
if (image && src) {
|
|
532
|
+
const picture = /* @__PURE__ */ jsx9("img", { src, alt: name, className: "w-full h-28 object-cover" });
|
|
533
|
+
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: "hairline", className: cn("group relative flex flex-col w-[180px] overflow-hidden", className), ...props, children: [
|
|
534
|
+
onOpen ? /* @__PURE__ */ jsx9(
|
|
535
|
+
BaseButton2,
|
|
536
|
+
{
|
|
537
|
+
type: "button",
|
|
538
|
+
className: "block w-full",
|
|
539
|
+
"aria-label": `Preview ${name}`,
|
|
540
|
+
onClick: (event) => {
|
|
541
|
+
event.stopPropagation();
|
|
542
|
+
onOpen();
|
|
543
|
+
},
|
|
544
|
+
children: picture
|
|
545
|
+
}
|
|
546
|
+
) : /* @__PURE__ */ jsx9("div", { className: "block w-full", children: picture }),
|
|
547
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
|
|
548
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: "flex-1 text-[12px] leading-[1.3] text-text-primary truncate", wrapperClassName: "flex-1" }),
|
|
549
|
+
download
|
|
550
|
+
] })
|
|
551
|
+
] });
|
|
552
|
+
}
|
|
553
|
+
const body = /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
554
|
+
/* @__PURE__ */ jsx9("div", { className: TILE, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
|
|
555
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
556
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME }),
|
|
557
|
+
/* @__PURE__ */ jsx9("span", { className: cn(NOTE, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
|
|
558
|
+
] })
|
|
559
|
+
] });
|
|
560
|
+
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: href ? "hairline" : "none", className: cn("group flex items-center gap-2 w-[240px] p-1.5 pr-1", !href && "opacity-70", className), ...props, children: [
|
|
561
|
+
href ? /* @__PURE__ */ jsx9(Link, { href, external: true, variant: "plain", className: "flex items-center gap-2 min-w-0 flex-1 cursor-pointer", onClick: (event) => event.stopPropagation(), children: body }) : /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: body }),
|
|
562
|
+
download
|
|
563
|
+
] });
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
// src/Avatar.tsx
|
|
567
|
+
import { useState as useState2 } from "react";
|
|
568
|
+
import { IconUserFilled } from "@tabler/icons-react";
|
|
569
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
570
|
+
var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
|
|
571
|
+
var hueFor = (key) => {
|
|
572
|
+
let h = 0;
|
|
573
|
+
for (let i = 0; i < key.length; i++) h = h * 31 + key.charCodeAt(i) | 0;
|
|
574
|
+
return HUES[Math.abs(h) % HUES.length];
|
|
575
|
+
};
|
|
576
|
+
var initialsFor = (name) => {
|
|
577
|
+
const words = name.split(/\s+/).slice(0, 2).filter((w) => /^[\p{L}\p{N}]/u.test(w));
|
|
578
|
+
const initials = words.map((w) => w[0]).join("") || name.trim().charAt(0);
|
|
579
|
+
return initials.toUpperCase();
|
|
580
|
+
};
|
|
581
|
+
function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
582
|
+
const [broken, setBroken] = useState2(false);
|
|
583
|
+
const label = name || alt;
|
|
584
|
+
const picture = src && !broken ? src : void 0;
|
|
585
|
+
return /* @__PURE__ */ jsx10(
|
|
586
|
+
"div",
|
|
587
|
+
{
|
|
588
|
+
...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
|
|
589
|
+
className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
|
|
590
|
+
style: { width: size, height: size },
|
|
591
|
+
children: picture ? /* @__PURE__ */ jsx10("img", { src: picture, alt: "", className: "w-full h-full object-cover", onError: () => setBroken(true) }) : label ? /* @__PURE__ */ jsx10(
|
|
592
|
+
"div",
|
|
593
|
+
{
|
|
594
|
+
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
595
|
+
style: {
|
|
596
|
+
// The one ink colour that reads on all eight hues, which are a
|
|
597
|
+
// palette rather than tokens (see the note at the top) — so its
|
|
598
|
+
// ink cannot be a token either.
|
|
599
|
+
color: "#08121c",
|
|
600
|
+
fontSize: Math.round(size * 0.36),
|
|
601
|
+
background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
|
|
602
|
+
},
|
|
603
|
+
children: initialsFor(label)
|
|
604
|
+
}
|
|
605
|
+
) : /* @__PURE__ */ jsx10("div", { className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx10(IconUserFilled, { size: Math.round(size * 0.5) }) })
|
|
606
|
+
}
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
// src/AvatarGroup.tsx
|
|
611
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
612
|
+
function AvatarGroup({ members, size = 24 }) {
|
|
613
|
+
const visible = members.slice(0, 3);
|
|
614
|
+
const overlap = Math.round(size / 3);
|
|
615
|
+
const ring = size / 12;
|
|
616
|
+
return /* @__PURE__ */ jsx11("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
|
|
617
|
+
/*
|
|
618
|
+
The wrapper carries the overlap and the ring; the face carries
|
|
619
|
+
neither. It must never clip — see the note at the top of the file —
|
|
620
|
+
so it has the avatar's own radius and no overflow of its own.
|
|
621
|
+
*/
|
|
622
|
+
/* @__PURE__ */ jsx11(
|
|
623
|
+
"span",
|
|
624
|
+
{
|
|
625
|
+
className: "relative flex rounded-sm",
|
|
626
|
+
style: { marginRight: -overlap, boxShadow: `0 0 0 ${ring}px var(--bg-surface)` },
|
|
627
|
+
children: /* @__PURE__ */ jsx11(Avatar, { size, name: member.name, src: member.picture, label: member.name })
|
|
628
|
+
},
|
|
629
|
+
i
|
|
630
|
+
)
|
|
631
|
+
)) });
|
|
632
|
+
}
|
|
633
|
+
|
|
347
634
|
// src/Banner.tsx
|
|
348
|
-
import {
|
|
635
|
+
import { IconX as IconX2 } from "@tabler/icons-react";
|
|
636
|
+
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
349
637
|
var TONE_STYLES = {
|
|
350
638
|
ok: "bg-success-muted text-success-default",
|
|
351
639
|
error: "bg-error-muted text-error-default",
|
|
@@ -355,17 +643,17 @@ var TONE_STYLES = {
|
|
|
355
643
|
function Banner({ tone, children, onDismiss, dismissLabel = "Dismiss", className }) {
|
|
356
644
|
const role = tone === "error" ? "alert" : "status";
|
|
357
645
|
if (!onDismiss) {
|
|
358
|
-
return /* @__PURE__ */
|
|
646
|
+
return /* @__PURE__ */ jsx12("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
|
|
359
647
|
}
|
|
360
|
-
return /* @__PURE__ */
|
|
361
|
-
/* @__PURE__ */
|
|
362
|
-
/* @__PURE__ */
|
|
648
|
+
return /* @__PURE__ */ jsxs6("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
|
|
649
|
+
/* @__PURE__ */ jsx12("span", { className: "min-w-0 flex-1", children }),
|
|
650
|
+
/* @__PURE__ */ jsx12(IconButton, { "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0 text-current hover:text-current", children: /* @__PURE__ */ jsx12(IconX2, { size: 16, stroke: 1.5 }) })
|
|
363
651
|
] });
|
|
364
652
|
}
|
|
365
653
|
|
|
366
654
|
// src/Button.tsx
|
|
367
|
-
import { Button as
|
|
368
|
-
import { jsx as
|
|
655
|
+
import { Button as BaseButton3 } from "@base-ui/react/button";
|
|
656
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
369
657
|
function Button({
|
|
370
658
|
variant = "muted",
|
|
371
659
|
size = "default",
|
|
@@ -378,8 +666,8 @@ function Button({
|
|
|
378
666
|
...props
|
|
379
667
|
}) {
|
|
380
668
|
const hasLeadingIcon = !!leadingIcon;
|
|
381
|
-
const button = /* @__PURE__ */
|
|
382
|
-
|
|
669
|
+
const button = /* @__PURE__ */ jsxs7(
|
|
670
|
+
BaseButton3,
|
|
383
671
|
{
|
|
384
672
|
type,
|
|
385
673
|
disabled: disabled || !!disabledReason,
|
|
@@ -423,13 +711,13 @@ function Button({
|
|
|
423
711
|
]
|
|
424
712
|
}
|
|
425
713
|
);
|
|
426
|
-
return disabledReason ? /* @__PURE__ */
|
|
714
|
+
return disabledReason ? /* @__PURE__ */ jsx13(TooltipTrigger, { label: disabledReason, children: button }) : button;
|
|
427
715
|
}
|
|
428
716
|
|
|
429
717
|
// src/Checkbox.tsx
|
|
430
718
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
431
719
|
import { IconCheck } from "@tabler/icons-react";
|
|
432
|
-
import { jsx as
|
|
720
|
+
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
433
721
|
function squareClasses(checked, disabled, interactive, className) {
|
|
434
722
|
return cn(
|
|
435
723
|
"inline-flex items-center justify-center size-4 shrink-0 rounded-[4px] border transition-colors",
|
|
@@ -442,9 +730,9 @@ function squareClasses(checked, disabled, interactive, className) {
|
|
|
442
730
|
var tickClasses = (checked) => cn("flex", !checked && "invisible");
|
|
443
731
|
function Checkbox({ checked, onChange, disabled = false, className, ...aria }) {
|
|
444
732
|
if (!onChange) {
|
|
445
|
-
return /* @__PURE__ */
|
|
733
|
+
return /* @__PURE__ */ jsx14("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx14("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx14(IconCheck, { size: 12, stroke: 3 }) }) });
|
|
446
734
|
}
|
|
447
|
-
return /* @__PURE__ */
|
|
735
|
+
return /* @__PURE__ */ jsx14(
|
|
448
736
|
BaseCheckbox.Root,
|
|
449
737
|
{
|
|
450
738
|
checked,
|
|
@@ -454,13 +742,13 @@ function Checkbox({ checked, onChange, disabled = false, className, ...aria }) {
|
|
|
454
742
|
onCheckedChange: (next) => onChange(next),
|
|
455
743
|
onClick: (e) => e.stopPropagation(),
|
|
456
744
|
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
457
|
-
children: /* @__PURE__ */
|
|
745
|
+
children: /* @__PURE__ */ jsx14(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx14(IconCheck, { size: 12, stroke: 3 }) })
|
|
458
746
|
}
|
|
459
747
|
);
|
|
460
748
|
}
|
|
461
749
|
|
|
462
750
|
// src/Chip.tsx
|
|
463
|
-
import { jsx as
|
|
751
|
+
import { jsx as jsx15, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
464
752
|
var typeStyles = {
|
|
465
753
|
neutral: "bg-bg-inset text-text-primary",
|
|
466
754
|
brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
|
|
@@ -470,8 +758,8 @@ var typeStyles = {
|
|
|
470
758
|
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
471
759
|
};
|
|
472
760
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
473
|
-
return /* @__PURE__ */
|
|
474
|
-
leadingIcon && /* @__PURE__ */
|
|
761
|
+
return /* @__PURE__ */ jsxs8("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: [
|
|
762
|
+
leadingIcon && /* @__PURE__ */ jsx15("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
475
763
|
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
476
764
|
// of growing past it — Ship's project chip on an issue row
|
|
477
765
|
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
@@ -480,16 +768,16 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
480
768
|
// the screenshot diff caught every descender cut off. `clip` is the
|
|
481
769
|
// one overflow that leaves the other axis visible. A chip with no cap
|
|
482
770
|
// draws exactly as before.
|
|
483
|
-
/* @__PURE__ */
|
|
484
|
-
trailingIcon && /* @__PURE__ */
|
|
771
|
+
/* @__PURE__ */ jsx15("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tracking-[0.02em] signal:tabular-nums", children: label }),
|
|
772
|
+
trailingIcon && /* @__PURE__ */ jsx15("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
485
773
|
] });
|
|
486
774
|
}
|
|
487
775
|
|
|
488
776
|
// src/ChipInput.tsx
|
|
489
|
-
import { useMemo, useState as
|
|
490
|
-
import { Button as
|
|
777
|
+
import { useMemo, useState as useState3 } from "react";
|
|
778
|
+
import { Button as BaseButton4 } from "@base-ui/react/button";
|
|
491
779
|
import { Combobox } from "@base-ui/react/combobox";
|
|
492
|
-
import { IconX as
|
|
780
|
+
import { IconX as IconX3 } from "@tabler/icons-react";
|
|
493
781
|
|
|
494
782
|
// src/Menu.tsx
|
|
495
783
|
import { createContext, useContext } from "react";
|
|
@@ -503,9 +791,9 @@ function triggerDisabled(trigger) {
|
|
|
503
791
|
}
|
|
504
792
|
|
|
505
793
|
// src/SectionLabel.tsx
|
|
506
|
-
import { jsx as
|
|
794
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
507
795
|
function SectionLabel({ children, className }) {
|
|
508
|
-
return /* @__PURE__ */
|
|
796
|
+
return /* @__PURE__ */ jsx16(
|
|
509
797
|
"span",
|
|
510
798
|
{
|
|
511
799
|
className: cn(
|
|
@@ -518,10 +806,10 @@ function SectionLabel({ children, className }) {
|
|
|
518
806
|
}
|
|
519
807
|
|
|
520
808
|
// src/Menu.tsx
|
|
521
|
-
import { Fragment, jsx as
|
|
809
|
+
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
522
810
|
var MenuContext = createContext(null);
|
|
523
811
|
function MenuPanel({ children, className, ...props }) {
|
|
524
|
-
return /* @__PURE__ */
|
|
812
|
+
return /* @__PURE__ */ jsx17(
|
|
525
813
|
"div",
|
|
526
814
|
{
|
|
527
815
|
className: cn(
|
|
@@ -551,7 +839,7 @@ var VIEWPORT_PAD2 = 8;
|
|
|
551
839
|
var HOVER_OPEN_DELAY = 0;
|
|
552
840
|
var HOVER_CLOSE_DELAY = 150;
|
|
553
841
|
function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
|
|
554
|
-
return /* @__PURE__ */
|
|
842
|
+
return /* @__PURE__ */ jsxs9(
|
|
555
843
|
BaseMenu.Root,
|
|
556
844
|
{
|
|
557
845
|
open,
|
|
@@ -559,7 +847,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
559
847
|
actionsRef,
|
|
560
848
|
modal: false,
|
|
561
849
|
children: [
|
|
562
|
-
/* @__PURE__ */
|
|
850
|
+
/* @__PURE__ */ jsx17(
|
|
563
851
|
BaseMenu.Trigger,
|
|
564
852
|
{
|
|
565
853
|
render: trigger,
|
|
@@ -569,7 +857,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
569
857
|
closeDelay: HOVER_CLOSE_DELAY
|
|
570
858
|
}
|
|
571
859
|
),
|
|
572
|
-
/* @__PURE__ */
|
|
860
|
+
/* @__PURE__ */ jsx17(BaseMenu.Portal, { children: /* @__PURE__ */ jsx17(
|
|
573
861
|
BaseMenu.Positioner,
|
|
574
862
|
{
|
|
575
863
|
side: "bottom",
|
|
@@ -577,13 +865,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
577
865
|
sideOffset: GAP2,
|
|
578
866
|
collisionPadding: VIEWPORT_PAD2,
|
|
579
867
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
580
|
-
children: /* @__PURE__ */
|
|
868
|
+
children: /* @__PURE__ */ jsx17(
|
|
581
869
|
BaseMenu.Popup,
|
|
582
870
|
{
|
|
583
871
|
"data-interactive": true,
|
|
584
872
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
585
|
-
render: /* @__PURE__ */
|
|
586
|
-
children: /* @__PURE__ */
|
|
873
|
+
render: /* @__PURE__ */ jsx17(MenuPanel, {}),
|
|
874
|
+
children: /* @__PURE__ */ jsx17(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2 [&>[role=separator]]:mx-0", contentClassName), children: /* @__PURE__ */ jsx17(MenuContext.Provider, { value: { openOnHover }, children }) })
|
|
587
875
|
}
|
|
588
876
|
)
|
|
589
877
|
}
|
|
@@ -599,20 +887,20 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
599
887
|
'[@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".'
|
|
600
888
|
);
|
|
601
889
|
}
|
|
602
|
-
return /* @__PURE__ */
|
|
603
|
-
/* @__PURE__ */
|
|
890
|
+
return /* @__PURE__ */ jsxs9(BaseMenu.SubmenuRoot, { children: [
|
|
891
|
+
/* @__PURE__ */ jsx17(
|
|
604
892
|
BaseMenu.SubmenuTrigger,
|
|
605
893
|
{
|
|
606
894
|
openOnHover: true,
|
|
607
895
|
delay: 0,
|
|
608
896
|
closeDelay: 150,
|
|
609
897
|
nativeButton: true,
|
|
610
|
-
render: /* @__PURE__ */
|
|
898
|
+
render: /* @__PURE__ */ jsx17("button", { type: "button" }),
|
|
611
899
|
className: menuItemClassName({ size: "default", selected }),
|
|
612
|
-
children: /* @__PURE__ */
|
|
900
|
+
children: /* @__PURE__ */ jsx17(MenuItemBody, { label, leading, submenu: true })
|
|
613
901
|
}
|
|
614
902
|
),
|
|
615
|
-
/* @__PURE__ */
|
|
903
|
+
/* @__PURE__ */ jsx17(BaseMenu.Portal, { children: /* @__PURE__ */ jsx17(
|
|
616
904
|
BaseMenu.Positioner,
|
|
617
905
|
{
|
|
618
906
|
side: "inline-end",
|
|
@@ -620,7 +908,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
620
908
|
sideOffset: GAP2,
|
|
621
909
|
collisionPadding: VIEWPORT_PAD2,
|
|
622
910
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
623
|
-
children: /* @__PURE__ */
|
|
911
|
+
children: /* @__PURE__ */ jsx17(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx17(MenuPanel, {}), children })
|
|
624
912
|
}
|
|
625
913
|
) })
|
|
626
914
|
] });
|
|
@@ -655,25 +943,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
655
943
|
);
|
|
656
944
|
}
|
|
657
945
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
658
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
659
|
-
return /* @__PURE__ */
|
|
660
|
-
leading && /* @__PURE__ */
|
|
661
|
-
children ?? /* @__PURE__ */
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
description && /* @__PURE__ */
|
|
946
|
+
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx17(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx17(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
947
|
+
return /* @__PURE__ */ jsxs9(Fragment2, { children: [
|
|
948
|
+
leading && /* @__PURE__ */ jsx17("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
949
|
+
children ?? /* @__PURE__ */ jsxs9("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
950
|
+
/* @__PURE__ */ jsx17("span", { className: cn("truncate text-[14px] leading-[140%]", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
951
|
+
description && /* @__PURE__ */ jsx17("span", { className: "truncate text-[12px] leading-[120%] text-text-secondary", children: description })
|
|
664
952
|
] }),
|
|
665
953
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
666
954
|
// the wider of the two and never changes, so revealing the hint moves
|
|
667
955
|
// nothing. No transition here either — the hint switches on the same
|
|
668
956
|
// :hover / `selected` as the fill, in the same frame.
|
|
669
|
-
/* @__PURE__ */
|
|
670
|
-
edge && /* @__PURE__ */
|
|
671
|
-
hint && /* @__PURE__ */
|
|
957
|
+
/* @__PURE__ */ jsxs9("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
958
|
+
edge && /* @__PURE__ */ jsx17("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
959
|
+
hint && /* @__PURE__ */ jsx17("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
672
960
|
] })
|
|
673
961
|
] });
|
|
674
962
|
}
|
|
675
963
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
676
|
-
const body = /* @__PURE__ */
|
|
964
|
+
const body = /* @__PURE__ */ jsx17(
|
|
677
965
|
MenuItemBody,
|
|
678
966
|
{
|
|
679
967
|
label,
|
|
@@ -691,13 +979,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
691
979
|
);
|
|
692
980
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
693
981
|
if (!useContext(MenuContext)) {
|
|
694
|
-
return /* @__PURE__ */
|
|
982
|
+
return /* @__PURE__ */ jsx17("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
695
983
|
}
|
|
696
|
-
return /* @__PURE__ */
|
|
984
|
+
return /* @__PURE__ */ jsx17(
|
|
697
985
|
BaseMenu.Item,
|
|
698
986
|
{
|
|
699
987
|
nativeButton: true,
|
|
700
|
-
render: /* @__PURE__ */
|
|
988
|
+
render: /* @__PURE__ */ jsx17("button", { type: "button" }),
|
|
701
989
|
className: rowClassName,
|
|
702
990
|
...props,
|
|
703
991
|
children: body
|
|
@@ -705,31 +993,31 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
705
993
|
);
|
|
706
994
|
}
|
|
707
995
|
function EnterHint({ target }) {
|
|
708
|
-
return /* @__PURE__ */
|
|
709
|
-
/* @__PURE__ */
|
|
710
|
-
target && /* @__PURE__ */
|
|
996
|
+
return /* @__PURE__ */ jsxs9("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
997
|
+
/* @__PURE__ */ jsx17(Kbd, { children: "\u21A9 Enter" }),
|
|
998
|
+
target && /* @__PURE__ */ jsx17("span", { className: "text-[9px] font-medium leading-[115%] signal:font-mono signal:text-[9.5px] signal:tracking-[0.04em]", children: target })
|
|
711
999
|
] });
|
|
712
1000
|
}
|
|
713
1001
|
function MenuSection({ label, children, className }) {
|
|
714
1002
|
const inMenu = useContext(MenuContext) !== null;
|
|
715
|
-
const heading = /* @__PURE__ */
|
|
1003
|
+
const heading = /* @__PURE__ */ jsx17("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx17(SectionLabel, { className: "text-text-secondary", children: label }) });
|
|
716
1004
|
if (!inMenu) {
|
|
717
|
-
return /* @__PURE__ */
|
|
1005
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
718
1006
|
heading,
|
|
719
1007
|
children
|
|
720
1008
|
] });
|
|
721
1009
|
}
|
|
722
|
-
return /* @__PURE__ */
|
|
723
|
-
/* @__PURE__ */
|
|
1010
|
+
return /* @__PURE__ */ jsxs9(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1011
|
+
/* @__PURE__ */ jsx17(BaseMenu.GroupLabel, { render: heading }),
|
|
724
1012
|
children
|
|
725
1013
|
] });
|
|
726
1014
|
}
|
|
727
1015
|
function MenuRow({ children, className }) {
|
|
728
|
-
return /* @__PURE__ */
|
|
1016
|
+
return /* @__PURE__ */ jsx17("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
729
1017
|
}
|
|
730
1018
|
|
|
731
1019
|
// src/ChipInput.tsx
|
|
732
|
-
import { jsx as
|
|
1020
|
+
import { jsx as jsx18, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
733
1021
|
var CHIP_BOX = (
|
|
734
1022
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
735
1023
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -740,11 +1028,11 @@ var CHIP_LABEL = "text-caption font-medium text-text-primary";
|
|
|
740
1028
|
var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
|
|
741
1029
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
742
1030
|
function InputChip({ label, leading, onRemove, className }) {
|
|
743
|
-
return /* @__PURE__ */
|
|
744
|
-
leading && /* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
746
|
-
onRemove && /* @__PURE__ */
|
|
747
|
-
|
|
1031
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1032
|
+
leading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1033
|
+
/* @__PURE__ */ jsx18("span", { className: CHIP_LABEL, children: label }),
|
|
1034
|
+
onRemove && /* @__PURE__ */ jsx18(
|
|
1035
|
+
BaseButton4,
|
|
748
1036
|
{
|
|
749
1037
|
type: "button",
|
|
750
1038
|
onClick: (e) => {
|
|
@@ -753,7 +1041,7 @@ function InputChip({ label, leading, onRemove, className }) {
|
|
|
753
1041
|
},
|
|
754
1042
|
className: CHIP_REMOVE,
|
|
755
1043
|
"aria-label": `Remove ${label}`,
|
|
756
|
-
children: /* @__PURE__ */
|
|
1044
|
+
children: /* @__PURE__ */ jsx18(IconX3, { size: 10, stroke: 1.5 })
|
|
757
1045
|
}
|
|
758
1046
|
)
|
|
759
1047
|
] });
|
|
@@ -769,8 +1057,8 @@ function ChipInput({
|
|
|
769
1057
|
rowLeading,
|
|
770
1058
|
...aria
|
|
771
1059
|
}) {
|
|
772
|
-
const [query, setQuery] =
|
|
773
|
-
const [box, setBox] =
|
|
1060
|
+
const [query, setQuery] = useState3("");
|
|
1061
|
+
const [box, setBox] = useState3(null);
|
|
774
1062
|
const available = useMemo(() => {
|
|
775
1063
|
const chosen = new Set(value.map((o) => o.id));
|
|
776
1064
|
const excluded = new Set(excludeIds);
|
|
@@ -806,7 +1094,7 @@ function ChipInput({
|
|
|
806
1094
|
setQuery("");
|
|
807
1095
|
}
|
|
808
1096
|
}
|
|
809
|
-
return /* @__PURE__ */
|
|
1097
|
+
return /* @__PURE__ */ jsxs10(
|
|
810
1098
|
Combobox.Root,
|
|
811
1099
|
{
|
|
812
1100
|
multiple: true,
|
|
@@ -823,13 +1111,13 @@ function ChipInput({
|
|
|
823
1111
|
filter,
|
|
824
1112
|
itemToStringLabel: (option) => option.label,
|
|
825
1113
|
children: [
|
|
826
|
-
/* @__PURE__ */
|
|
827
|
-
value.map((option) => /* @__PURE__ */
|
|
828
|
-
chipLeading && /* @__PURE__ */
|
|
829
|
-
/* @__PURE__ */
|
|
830
|
-
/* @__PURE__ */
|
|
1114
|
+
/* @__PURE__ */ jsxs10(Combobox.Chips, { ref: setBox, className: "bg-bg-inset border border-border-default hover:border-border-strong focus-within:border-border-focus focus-within:hover:border-border-focus rounded-lg px-3 py-1.5 flex flex-wrap items-center gap-1.5 transition-colors min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring", children: [
|
|
1115
|
+
value.map((option) => /* @__PURE__ */ jsxs10(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1116
|
+
chipLeading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
|
|
1117
|
+
/* @__PURE__ */ jsx18("span", { className: CHIP_LABEL, children: option.label }),
|
|
1118
|
+
/* @__PURE__ */ jsx18(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx18(IconX3, { size: 10, stroke: 1.5 }) })
|
|
831
1119
|
] }, option.id)),
|
|
832
|
-
/* @__PURE__ */
|
|
1120
|
+
/* @__PURE__ */ jsx18(
|
|
833
1121
|
Combobox.Input,
|
|
834
1122
|
{
|
|
835
1123
|
autoFocus,
|
|
@@ -841,18 +1129,18 @@ function ChipInput({
|
|
|
841
1129
|
}
|
|
842
1130
|
)
|
|
843
1131
|
] }),
|
|
844
|
-
/* @__PURE__ */
|
|
1132
|
+
/* @__PURE__ */ jsx18(Combobox.Portal, { children: /* @__PURE__ */ jsx18(
|
|
845
1133
|
Combobox.Positioner,
|
|
846
1134
|
{
|
|
847
1135
|
anchor: box,
|
|
848
1136
|
sideOffset: GAP3,
|
|
849
1137
|
collisionPadding: VIEWPORT_PAD3,
|
|
850
1138
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
851
|
-
children: /* @__PURE__ */
|
|
1139
|
+
children: /* @__PURE__ */ jsx18(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx18(MenuPanel, {}), children: /* @__PURE__ */ jsx18(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx18(Combobox.List, { children: (option) => /* @__PURE__ */ jsx18(
|
|
852
1140
|
Combobox.Item,
|
|
853
1141
|
{
|
|
854
1142
|
value: option,
|
|
855
|
-
render: /* @__PURE__ */
|
|
1143
|
+
render: /* @__PURE__ */ jsx18(
|
|
856
1144
|
MenuItem,
|
|
857
1145
|
{
|
|
858
1146
|
size: "tall",
|
|
@@ -873,15 +1161,49 @@ function ChipInput({
|
|
|
873
1161
|
var GAP3 = 4;
|
|
874
1162
|
var VIEWPORT_PAD3 = 8;
|
|
875
1163
|
|
|
1164
|
+
// src/InlineChip.tsx
|
|
1165
|
+
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1166
|
+
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";
|
|
1167
|
+
var INLINE_CHIP_TONE_CLASSES = {
|
|
1168
|
+
/** A thing or a place — anything that is not a person. */
|
|
1169
|
+
neutral: "bg-bg-active text-text-primary",
|
|
1170
|
+
/** A person. */
|
|
1171
|
+
person: "bg-accent-muted text-accent-primary",
|
|
1172
|
+
/** A person, called urgently. */
|
|
1173
|
+
urgent: "bg-warning-muted text-warning-default",
|
|
1174
|
+
/**
|
|
1175
|
+
* A reference nobody could resolve — still a mention, just an anonymous one.
|
|
1176
|
+
* Its height is the body line's 19.6px written out, because `1.4em` here is
|
|
1177
|
+
* the caption's em: 16.8px, with the letters 1.8px above the sentence's
|
|
1178
|
+
* baseline. At 19.6px they sit 0.4px off it (measured 2026-09-14; Peek's
|
|
1179
|
+
* copy of this chip still has the 16.8px box).
|
|
1180
|
+
*/
|
|
1181
|
+
quiet: "h-[19.6px] bg-bg-active text-text-muted font-mono text-caption"
|
|
1182
|
+
};
|
|
1183
|
+
function inlineChipClassName(tone, className) {
|
|
1184
|
+
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1185
|
+
}
|
|
1186
|
+
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1187
|
+
const body = /* @__PURE__ */ jsxs11(Fragment3, { children: [
|
|
1188
|
+
icon && /* @__PURE__ */ jsx19("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
|
|
1189
|
+
children
|
|
1190
|
+
] });
|
|
1191
|
+
const classes = inlineChipClassName(tone, className);
|
|
1192
|
+
if (href === void 0) {
|
|
1193
|
+
return /* @__PURE__ */ jsx19("span", { className: classes, ...props, children: body });
|
|
1194
|
+
}
|
|
1195
|
+
return /* @__PURE__ */ jsx19("a", { href, className: classes, ...props, children: body });
|
|
1196
|
+
}
|
|
1197
|
+
|
|
876
1198
|
// src/IdentityMenu.tsx
|
|
877
|
-
import { useCallback, useRef } from "react";
|
|
1199
|
+
import { useCallback, useRef as useRef2 } from "react";
|
|
878
1200
|
|
|
879
1201
|
// src/Divider.tsx
|
|
880
|
-
import { jsx as
|
|
1202
|
+
import { jsx as jsx20, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
881
1203
|
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
882
1204
|
if (label && orientation === "horizontal") {
|
|
883
1205
|
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
884
|
-
return /* @__PURE__ */
|
|
1206
|
+
return /* @__PURE__ */ jsxs12(
|
|
885
1207
|
"div",
|
|
886
1208
|
{
|
|
887
1209
|
role: "separator",
|
|
@@ -889,14 +1211,14 @@ function Divider({ orientation = "horizontal", label, tone = "default", classNam
|
|
|
889
1211
|
"aria-label": label,
|
|
890
1212
|
className: cn("flex shrink-0 items-center gap-2 mx-3", className),
|
|
891
1213
|
children: [
|
|
892
|
-
/* @__PURE__ */
|
|
893
|
-
/* @__PURE__ */
|
|
894
|
-
/* @__PURE__ */
|
|
1214
|
+
/* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
1215
|
+
/* @__PURE__ */ jsx20("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
1216
|
+
/* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
895
1217
|
]
|
|
896
1218
|
}
|
|
897
1219
|
);
|
|
898
1220
|
}
|
|
899
|
-
return /* @__PURE__ */
|
|
1221
|
+
return /* @__PURE__ */ jsx20(
|
|
900
1222
|
"div",
|
|
901
1223
|
{
|
|
902
1224
|
role: "separator",
|
|
@@ -907,27 +1229,27 @@ function Divider({ orientation = "horizontal", label, tone = "default", classNam
|
|
|
907
1229
|
}
|
|
908
1230
|
|
|
909
1231
|
// src/Person.tsx
|
|
910
|
-
import { jsx as
|
|
1232
|
+
import { jsx as jsx21, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
911
1233
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
912
1234
|
return (
|
|
913
1235
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
914
1236
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
915
1237
|
// row agree by construction.
|
|
916
|
-
/* @__PURE__ */
|
|
917
|
-
/* @__PURE__ */
|
|
918
|
-
/* @__PURE__ */
|
|
1238
|
+
/* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
1239
|
+
/* @__PURE__ */ jsx21(Avatar, { name, src: picture, size }),
|
|
1240
|
+
/* @__PURE__ */ jsx21("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
919
1241
|
] })
|
|
920
1242
|
);
|
|
921
1243
|
}
|
|
922
1244
|
|
|
923
1245
|
// src/PersonTrigger.tsx
|
|
924
|
-
import { Button as
|
|
1246
|
+
import { Button as BaseButton5 } from "@base-ui/react/button";
|
|
925
1247
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
926
|
-
import { jsx as
|
|
1248
|
+
import { jsx as jsx22, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
927
1249
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
928
1250
|
if (compact) {
|
|
929
|
-
return /* @__PURE__ */
|
|
930
|
-
|
|
1251
|
+
return /* @__PURE__ */ jsx22(
|
|
1252
|
+
BaseButton5,
|
|
931
1253
|
{
|
|
932
1254
|
type: "button",
|
|
933
1255
|
"aria-haspopup": "menu",
|
|
@@ -935,12 +1257,12 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
935
1257
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
936
1258
|
className: cn("cursor-pointer rounded-full", className),
|
|
937
1259
|
...props,
|
|
938
|
-
children: /* @__PURE__ */
|
|
1260
|
+
children: /* @__PURE__ */ jsx22(Avatar, { name, src: picture, size: size ?? 36 })
|
|
939
1261
|
}
|
|
940
1262
|
);
|
|
941
1263
|
}
|
|
942
|
-
return /* @__PURE__ */
|
|
943
|
-
|
|
1264
|
+
return /* @__PURE__ */ jsxs14(
|
|
1265
|
+
BaseButton5,
|
|
944
1266
|
{
|
|
945
1267
|
type: "button",
|
|
946
1268
|
"aria-haspopup": "menu",
|
|
@@ -957,18 +1279,18 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
957
1279
|
),
|
|
958
1280
|
...props,
|
|
959
1281
|
children: [
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
/* @__PURE__ */
|
|
1282
|
+
/* @__PURE__ */ jsx22(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
1283
|
+
/* @__PURE__ */ jsx22(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
962
1284
|
]
|
|
963
1285
|
}
|
|
964
1286
|
);
|
|
965
1287
|
}
|
|
966
1288
|
|
|
967
1289
|
// src/IdentityMenu.tsx
|
|
968
|
-
import { Fragment as
|
|
1290
|
+
import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
969
1291
|
function IdentityPanel({ className, onClose = () => {
|
|
970
1292
|
}, ...rest }) {
|
|
971
|
-
return /* @__PURE__ */
|
|
1293
|
+
return /* @__PURE__ */ jsx23(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx23(IdentityRows, { ...rest, onClose }) });
|
|
972
1294
|
}
|
|
973
1295
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
974
1296
|
const act = (action) => () => {
|
|
@@ -976,53 +1298,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
976
1298
|
action();
|
|
977
1299
|
};
|
|
978
1300
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
979
|
-
return /* @__PURE__ */
|
|
980
|
-
/* @__PURE__ */
|
|
981
|
-
/* @__PURE__ */
|
|
982
|
-
/* @__PURE__ */
|
|
983
|
-
me.email && /* @__PURE__ */
|
|
1301
|
+
return /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
1302
|
+
/* @__PURE__ */ jsxs15(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
1303
|
+
/* @__PURE__ */ jsx23(MenuRow, { children: /* @__PURE__ */ jsx23(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
|
|
1304
|
+
/* @__PURE__ */ jsx23(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." }),
|
|
1305
|
+
me.email && /* @__PURE__ */ jsxs15(Note, { children: [
|
|
984
1306
|
me.email,
|
|
985
1307
|
" \xB7 known to Estiva, never published to the relay"
|
|
986
1308
|
] })
|
|
987
1309
|
] }),
|
|
988
|
-
relayUrl && /* @__PURE__ */
|
|
989
|
-
/* @__PURE__ */
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
1310
|
+
relayUrl && /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
1311
|
+
/* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }),
|
|
1312
|
+
/* @__PURE__ */ jsxs15(MenuSection, { label: "Workspace", children: [
|
|
1313
|
+
/* @__PURE__ */ jsx23(MenuRow, { children: /* @__PURE__ */ jsx23("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
1314
|
+
/* @__PURE__ */ jsx23(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
993
1315
|
] })
|
|
994
1316
|
] }),
|
|
995
|
-
appRows && /* @__PURE__ */
|
|
996
|
-
/* @__PURE__ */
|
|
1317
|
+
appRows && /* @__PURE__ */ jsxs15(Fragment4, { children: [
|
|
1318
|
+
/* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }),
|
|
997
1319
|
appRows
|
|
998
1320
|
] }),
|
|
999
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
1000
|
-
signedIn && idBase && /* @__PURE__ */
|
|
1321
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }) : null,
|
|
1322
|
+
signedIn && idBase && /* @__PURE__ */ jsx23(
|
|
1001
1323
|
MenuItem,
|
|
1002
1324
|
{
|
|
1003
1325
|
label: "Edit your profile in Estiva ID",
|
|
1004
1326
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
1005
1327
|
}
|
|
1006
1328
|
),
|
|
1007
|
-
onCopyKey && /* @__PURE__ */
|
|
1008
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
1329
|
+
onCopyKey && /* @__PURE__ */ jsx23(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
1330
|
+
idBase && onSignOut && /* @__PURE__ */ jsx23(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
1009
1331
|
] });
|
|
1010
1332
|
}
|
|
1011
1333
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
1012
|
-
const actions =
|
|
1334
|
+
const actions = useRef2(null);
|
|
1013
1335
|
const close = useCallback(() => actions.current?.close(), []);
|
|
1014
1336
|
return (
|
|
1015
1337
|
/* The wrapper carries the caller's `className` and nothing else. It used
|
|
1016
1338
|
to be `relative`, because the panel was positioned against it; the panel
|
|
1017
1339
|
hangs from the trigger and portals now, so a positioning context here
|
|
1018
1340
|
would only be a lie about what this box does. */
|
|
1019
|
-
/* @__PURE__ */
|
|
1341
|
+
/* @__PURE__ */ jsx23("div", { className, children: /* @__PURE__ */ jsx23(
|
|
1020
1342
|
Menu,
|
|
1021
1343
|
{
|
|
1022
1344
|
align: "right",
|
|
1023
1345
|
actionsRef: actions,
|
|
1024
1346
|
className: "w-72",
|
|
1025
|
-
trigger: /* @__PURE__ */
|
|
1347
|
+
trigger: /* @__PURE__ */ jsx23(
|
|
1026
1348
|
PersonTrigger,
|
|
1027
1349
|
{
|
|
1028
1350
|
name: me.name,
|
|
@@ -1033,7 +1355,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
1033
1355
|
"aria-label": compact ? "Account menu" : void 0
|
|
1034
1356
|
}
|
|
1035
1357
|
),
|
|
1036
|
-
children: /* @__PURE__ */
|
|
1358
|
+
children: /* @__PURE__ */ jsx23(
|
|
1037
1359
|
IdentityRows,
|
|
1038
1360
|
{
|
|
1039
1361
|
me,
|
|
@@ -1051,13 +1373,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
1051
1373
|
);
|
|
1052
1374
|
}
|
|
1053
1375
|
function Note({ children }) {
|
|
1054
|
-
return /* @__PURE__ */
|
|
1376
|
+
return /* @__PURE__ */ jsx23("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
1055
1377
|
}
|
|
1056
1378
|
|
|
1057
1379
|
// src/Field.tsx
|
|
1058
1380
|
import { cloneElement, isValidElement } from "react";
|
|
1059
1381
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
1060
|
-
import { jsx as
|
|
1382
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1061
1383
|
var LINE_STYLES = {
|
|
1062
1384
|
helper: "text-caption text-text-muted",
|
|
1063
1385
|
warning: "text-caption text-warning-default",
|
|
@@ -1067,30 +1389,30 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1067
1389
|
const control = required && isValidElement(children) ? cloneElement(children, {
|
|
1068
1390
|
"aria-required": children.props["aria-required"] ?? true
|
|
1069
1391
|
}) : children;
|
|
1070
|
-
return /* @__PURE__ */
|
|
1071
|
-
/* @__PURE__ */
|
|
1392
|
+
return /* @__PURE__ */ jsxs16(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1393
|
+
/* @__PURE__ */ jsxs16(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1072
1394
|
label,
|
|
1073
|
-
required && /* @__PURE__ */
|
|
1395
|
+
required && /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1074
1396
|
] }),
|
|
1075
|
-
/* @__PURE__ */
|
|
1397
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1076
1398
|
control,
|
|
1077
|
-
error != null ? /* @__PURE__ */
|
|
1399
|
+
error != null ? /* @__PURE__ */ jsx24(BaseField.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx24(BaseField.Description, { className: LINE_STYLES.helper, children: helper }) : null
|
|
1078
1400
|
] })
|
|
1079
1401
|
] });
|
|
1080
1402
|
}
|
|
1081
1403
|
function FieldLine({ tone = "helper", children, className }) {
|
|
1082
|
-
return /* @__PURE__ */
|
|
1404
|
+
return /* @__PURE__ */ jsx24("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
|
|
1083
1405
|
}
|
|
1084
1406
|
|
|
1085
1407
|
// src/Select.tsx
|
|
1086
1408
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
1087
1409
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
1088
|
-
import { jsx as
|
|
1410
|
+
import { jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1089
1411
|
var GAP4 = 4;
|
|
1090
1412
|
var VIEWPORT_PAD4 = 8;
|
|
1091
1413
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, className, ...aria }) {
|
|
1092
1414
|
const selected = options.find((o) => o.value === value);
|
|
1093
|
-
return /* @__PURE__ */
|
|
1415
|
+
return /* @__PURE__ */ jsxs17(
|
|
1094
1416
|
BaseSelect.Root,
|
|
1095
1417
|
{
|
|
1096
1418
|
value,
|
|
@@ -1098,7 +1420,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1098
1420
|
disabled,
|
|
1099
1421
|
modal: false,
|
|
1100
1422
|
children: [
|
|
1101
|
-
/* @__PURE__ */
|
|
1423
|
+
/* @__PURE__ */ jsxs17(
|
|
1102
1424
|
BaseSelect.Trigger,
|
|
1103
1425
|
{
|
|
1104
1426
|
"aria-label": ariaLabel,
|
|
@@ -1125,20 +1447,20 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1125
1447
|
className
|
|
1126
1448
|
),
|
|
1127
1449
|
children: [
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
selected?.leading && /* @__PURE__ */
|
|
1130
|
-
/* @__PURE__ */
|
|
1450
|
+
/* @__PURE__ */ jsxs17("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
1451
|
+
selected?.leading && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
1452
|
+
/* @__PURE__ */ jsx25(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
1131
1453
|
] }),
|
|
1132
|
-
/* @__PURE__ */
|
|
1454
|
+
/* @__PURE__ */ jsx25(
|
|
1133
1455
|
BaseSelect.Icon,
|
|
1134
1456
|
{
|
|
1135
|
-
render: /* @__PURE__ */
|
|
1457
|
+
render: /* @__PURE__ */ jsx25(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
1136
1458
|
}
|
|
1137
1459
|
)
|
|
1138
1460
|
]
|
|
1139
1461
|
}
|
|
1140
1462
|
),
|
|
1141
|
-
/* @__PURE__ */
|
|
1463
|
+
/* @__PURE__ */ jsx25(BaseSelect.Portal, { children: /* @__PURE__ */ jsx25(
|
|
1142
1464
|
BaseSelect.Positioner,
|
|
1143
1465
|
{
|
|
1144
1466
|
side: "bottom",
|
|
@@ -1147,25 +1469,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1147
1469
|
collisionPadding: VIEWPORT_PAD4,
|
|
1148
1470
|
alignItemWithTrigger: false,
|
|
1149
1471
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1150
|
-
children: /* @__PURE__ */
|
|
1472
|
+
children: /* @__PURE__ */ jsx25(
|
|
1151
1473
|
BaseSelect.Popup,
|
|
1152
1474
|
{
|
|
1153
|
-
render: /* @__PURE__ */
|
|
1475
|
+
render: /* @__PURE__ */ jsx25(MenuPanel, {}),
|
|
1154
1476
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
1155
|
-
children: /* @__PURE__ */
|
|
1477
|
+
children: /* @__PURE__ */ jsx25(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs17(
|
|
1156
1478
|
BaseSelect.Item,
|
|
1157
1479
|
{
|
|
1158
1480
|
value: option.value,
|
|
1159
1481
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
1160
1482
|
children: [
|
|
1161
|
-
/* @__PURE__ */
|
|
1162
|
-
option.leading && /* @__PURE__ */
|
|
1163
|
-
/* @__PURE__ */
|
|
1483
|
+
/* @__PURE__ */ jsxs17("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1484
|
+
option.leading && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
1485
|
+
/* @__PURE__ */ jsx25(BaseSelect.ItemText, { className: "truncate text-[14px] leading-[140%] text-text-primary", children: option.label })
|
|
1164
1486
|
] }),
|
|
1165
|
-
/* @__PURE__ */
|
|
1487
|
+
/* @__PURE__ */ jsx25(
|
|
1166
1488
|
BaseSelect.ItemIndicator,
|
|
1167
1489
|
{
|
|
1168
|
-
render: /* @__PURE__ */
|
|
1490
|
+
render: /* @__PURE__ */ jsx25(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
1169
1491
|
}
|
|
1170
1492
|
)
|
|
1171
1493
|
]
|
|
@@ -1184,9 +1506,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1184
1506
|
// src/TextInput.tsx
|
|
1185
1507
|
import { forwardRef } from "react";
|
|
1186
1508
|
import { Input } from "@base-ui/react/input";
|
|
1187
|
-
import { jsx as
|
|
1509
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1188
1510
|
var TextInput = forwardRef(function TextInput2({ className, type = "text", ...props }, ref) {
|
|
1189
|
-
return /* @__PURE__ */
|
|
1511
|
+
return /* @__PURE__ */ jsx26(
|
|
1190
1512
|
Input,
|
|
1191
1513
|
{
|
|
1192
1514
|
ref,
|
|
@@ -1207,13 +1529,13 @@ var TextInput = forwardRef(function TextInput2({ className, type = "text", ...pr
|
|
|
1207
1529
|
// src/Textarea.tsx
|
|
1208
1530
|
import { forwardRef as forwardRef2 } from "react";
|
|
1209
1531
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1210
|
-
import { jsx as
|
|
1532
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
1211
1533
|
var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
|
|
1212
|
-
return /* @__PURE__ */
|
|
1534
|
+
return /* @__PURE__ */ jsx27(
|
|
1213
1535
|
BaseField2.Control,
|
|
1214
1536
|
{
|
|
1215
1537
|
ref,
|
|
1216
|
-
render: /* @__PURE__ */
|
|
1538
|
+
render: /* @__PURE__ */ jsx27("textarea", {}),
|
|
1217
1539
|
className: cn(
|
|
1218
1540
|
"bg-bg-inset border border-border-default focus:border-border-focus rounded-lg px-3 py-2",
|
|
1219
1541
|
"text-[14px] leading-[1.4] font-normal text-text-primary placeholder:text-text-muted",
|
|
@@ -1228,27 +1550,27 @@ var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
|
|
|
1228
1550
|
});
|
|
1229
1551
|
|
|
1230
1552
|
// src/ConfirmDialog.tsx
|
|
1231
|
-
import { useState as
|
|
1553
|
+
import { useState as useState4 } from "react";
|
|
1232
1554
|
|
|
1233
1555
|
// src/DialogShell.tsx
|
|
1234
|
-
import { useRef as
|
|
1556
|
+
import { useRef as useRef3 } from "react";
|
|
1235
1557
|
import { Dialog } from "@base-ui/react/dialog";
|
|
1236
1558
|
import { AlertDialog } from "@base-ui/react/alert-dialog";
|
|
1237
|
-
import { IconX as
|
|
1238
|
-
import { jsx as
|
|
1559
|
+
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
1560
|
+
import { jsx as jsx28, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1239
1561
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
|
|
1240
1562
|
const Parts = alert ? AlertDialog : Dialog;
|
|
1241
|
-
const popupRef =
|
|
1242
|
-
return /* @__PURE__ */
|
|
1563
|
+
const popupRef = useRef3(null);
|
|
1564
|
+
return /* @__PURE__ */ jsx28(
|
|
1243
1565
|
Parts.Root,
|
|
1244
1566
|
{
|
|
1245
1567
|
open: true,
|
|
1246
1568
|
onOpenChange: (open) => {
|
|
1247
1569
|
if (!open) onClose();
|
|
1248
1570
|
},
|
|
1249
|
-
children: /* @__PURE__ */
|
|
1250
|
-
/* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1571
|
+
children: /* @__PURE__ */ jsxs18(Parts.Portal, { children: [
|
|
1572
|
+
/* @__PURE__ */ jsx28(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1573
|
+
/* @__PURE__ */ jsx28("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs18(
|
|
1252
1574
|
Parts.Popup,
|
|
1253
1575
|
{
|
|
1254
1576
|
ref: popupRef,
|
|
@@ -1257,16 +1579,16 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1257
1579
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
1258
1580
|
style: { width },
|
|
1259
1581
|
children: [
|
|
1260
|
-
/* @__PURE__ */
|
|
1261
|
-
headerContent ?? /* @__PURE__ */
|
|
1262
|
-
/* @__PURE__ */
|
|
1582
|
+
/* @__PURE__ */ jsxs18("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
|
|
1583
|
+
headerContent ?? /* @__PURE__ */ jsx28(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx28("span", {}), children: title }),
|
|
1584
|
+
/* @__PURE__ */ jsx28(
|
|
1263
1585
|
Parts.Close,
|
|
1264
1586
|
{
|
|
1265
|
-
render: /* @__PURE__ */
|
|
1587
|
+
render: /* @__PURE__ */ jsx28(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx28(IconX4, { size: 16, stroke: 1.5 }) })
|
|
1266
1588
|
}
|
|
1267
1589
|
)
|
|
1268
1590
|
] }),
|
|
1269
|
-
bodyMaxHeight ? /* @__PURE__ */
|
|
1591
|
+
bodyMaxHeight ? /* @__PURE__ */ jsx28(
|
|
1270
1592
|
ScrollArea,
|
|
1271
1593
|
{
|
|
1272
1594
|
className: cn(footer != null && "border-b border-border-subtle"),
|
|
@@ -1274,8 +1596,8 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1274
1596
|
contentClassName: cn("pl-5 pr-4 py-4", bodyClassName),
|
|
1275
1597
|
children
|
|
1276
1598
|
}
|
|
1277
|
-
) : /* @__PURE__ */
|
|
1278
|
-
footer != null && /* @__PURE__ */
|
|
1599
|
+
) : /* @__PURE__ */ jsx28("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
1600
|
+
footer != null && /* @__PURE__ */ jsx28("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
1279
1601
|
]
|
|
1280
1602
|
}
|
|
1281
1603
|
) })
|
|
@@ -1285,9 +1607,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1285
1607
|
}
|
|
1286
1608
|
|
|
1287
1609
|
// src/ConfirmDialog.tsx
|
|
1288
|
-
import { Fragment as
|
|
1610
|
+
import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1289
1611
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
1290
|
-
const [busy, setBusy] =
|
|
1612
|
+
const [busy, setBusy] = useState4(false);
|
|
1291
1613
|
const confirm = async () => {
|
|
1292
1614
|
setBusy(true);
|
|
1293
1615
|
try {
|
|
@@ -1297,16 +1619,16 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
1297
1619
|
setBusy(false);
|
|
1298
1620
|
}
|
|
1299
1621
|
};
|
|
1300
|
-
return /* @__PURE__ */
|
|
1622
|
+
return /* @__PURE__ */ jsx29(
|
|
1301
1623
|
DialogShell,
|
|
1302
1624
|
{
|
|
1303
1625
|
alert: true,
|
|
1304
1626
|
title,
|
|
1305
1627
|
onClose,
|
|
1306
1628
|
bodyClassName: "flex flex-col gap-3 text-body-2 text-text-primary",
|
|
1307
|
-
footer: /* @__PURE__ */
|
|
1308
|
-
/* @__PURE__ */
|
|
1309
|
-
/* @__PURE__ */
|
|
1629
|
+
footer: /* @__PURE__ */ jsxs19(Fragment5, { children: [
|
|
1630
|
+
/* @__PURE__ */ jsx29(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
1631
|
+
/* @__PURE__ */ jsx29(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
1310
1632
|
] }),
|
|
1311
1633
|
children
|
|
1312
1634
|
}
|
|
@@ -1314,15 +1636,15 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
1314
1636
|
}
|
|
1315
1637
|
|
|
1316
1638
|
// src/EditableText.tsx
|
|
1317
|
-
import { useEffect, useRef as
|
|
1639
|
+
import { useEffect, useRef as useRef4, useState as useState5 } from "react";
|
|
1318
1640
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
1319
1641
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
1320
|
-
import { jsx as
|
|
1642
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1321
1643
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
1322
|
-
const [editing, setEditing] =
|
|
1323
|
-
const [draft, setDraft] =
|
|
1324
|
-
const [busy, setBusy] =
|
|
1325
|
-
const fieldRef =
|
|
1644
|
+
const [editing, setEditing] = useState5(false);
|
|
1645
|
+
const [draft, setDraft] = useState5(value);
|
|
1646
|
+
const [busy, setBusy] = useState5(false);
|
|
1647
|
+
const fieldRef = useRef4(null);
|
|
1326
1648
|
useEffect(() => {
|
|
1327
1649
|
if (editing) {
|
|
1328
1650
|
fieldRef.current?.focus();
|
|
@@ -1375,7 +1697,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1375
1697
|
written and never read. Read-only, this is a line of text: whatever
|
|
1376
1698
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
1377
1699
|
*/
|
|
1378
|
-
/* @__PURE__ */
|
|
1700
|
+
/* @__PURE__ */ jsx30(
|
|
1379
1701
|
"div",
|
|
1380
1702
|
{
|
|
1381
1703
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -1385,11 +1707,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1385
1707
|
);
|
|
1386
1708
|
}
|
|
1387
1709
|
if (editing) {
|
|
1388
|
-
return multiline ? /* @__PURE__ */
|
|
1710
|
+
return multiline ? /* @__PURE__ */ jsx30(
|
|
1389
1711
|
BaseField3.Control,
|
|
1390
1712
|
{
|
|
1391
1713
|
ref: fieldRef,
|
|
1392
|
-
render: /* @__PURE__ */
|
|
1714
|
+
render: /* @__PURE__ */ jsx30("textarea", { rows: 4 }),
|
|
1393
1715
|
"aria-label": label,
|
|
1394
1716
|
value: draft,
|
|
1395
1717
|
disabled: busy,
|
|
@@ -1398,7 +1720,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1398
1720
|
onBlur: () => void commit(),
|
|
1399
1721
|
className: fieldClass
|
|
1400
1722
|
}
|
|
1401
|
-
) : /* @__PURE__ */
|
|
1723
|
+
) : /* @__PURE__ */ jsx30(
|
|
1402
1724
|
Input2,
|
|
1403
1725
|
{
|
|
1404
1726
|
ref: fieldRef,
|
|
@@ -1412,7 +1734,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1412
1734
|
}
|
|
1413
1735
|
);
|
|
1414
1736
|
}
|
|
1415
|
-
return /* @__PURE__ */
|
|
1737
|
+
return /* @__PURE__ */ jsx30(
|
|
1416
1738
|
"button",
|
|
1417
1739
|
{
|
|
1418
1740
|
type: "button",
|
|
@@ -1431,40 +1753,59 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1431
1753
|
|
|
1432
1754
|
// src/EmptyState.tsx
|
|
1433
1755
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1434
|
-
import { jsx as
|
|
1756
|
+
import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1435
1757
|
function EmptyState({ icon, message, scope = "page", className }) {
|
|
1436
1758
|
if (scope === "section") {
|
|
1437
|
-
return /* @__PURE__ */
|
|
1759
|
+
return /* @__PURE__ */ jsx31("p", { className: cn("text-body-2 text-text-secondary", className), children: message });
|
|
1438
1760
|
}
|
|
1439
|
-
return /* @__PURE__ */
|
|
1440
|
-
/* @__PURE__ */
|
|
1441
|
-
/* @__PURE__ */
|
|
1761
|
+
return /* @__PURE__ */ jsxs20("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1762
|
+
/* @__PURE__ */ jsx31("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx31(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1763
|
+
/* @__PURE__ */ jsx31("p", { className: "text-body-2 text-text-secondary text-center", children: message })
|
|
1442
1764
|
] });
|
|
1443
1765
|
}
|
|
1444
1766
|
|
|
1767
|
+
// src/ProgressBar.tsx
|
|
1768
|
+
import { Progress } from "@base-ui/react/progress";
|
|
1769
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
1770
|
+
var TRACK_CLASSES = {
|
|
1771
|
+
default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
|
|
1772
|
+
// 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
|
|
1773
|
+
quiet: "h-1 w-full overflow-hidden rounded-full bg-bg-inset"
|
|
1774
|
+
};
|
|
1775
|
+
var INDICATOR_CLASSES = {
|
|
1776
|
+
default: "h-full rounded-full bg-success-default transition-[width]",
|
|
1777
|
+
quiet: "h-full rounded-full bg-success-muted transition-[width] duration-300"
|
|
1778
|
+
};
|
|
1779
|
+
function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
1780
|
+
return (
|
|
1781
|
+
// `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
|
|
1782
|
+
/* @__PURE__ */ jsx32(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx32(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx32(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
|
|
1783
|
+
);
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1445
1786
|
// src/Skeleton.tsx
|
|
1446
|
-
import { jsx as
|
|
1787
|
+
import { jsx as jsx33, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1447
1788
|
function SkeletonBar({ className, style }) {
|
|
1448
|
-
return /* @__PURE__ */
|
|
1789
|
+
return /* @__PURE__ */ jsx33("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1449
1790
|
}
|
|
1450
1791
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1451
1792
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1452
|
-
return /* @__PURE__ */
|
|
1453
|
-
/* @__PURE__ */
|
|
1454
|
-
/* @__PURE__ */
|
|
1793
|
+
return /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1794
|
+
/* @__PURE__ */ jsx33(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1795
|
+
/* @__PURE__ */ jsx33(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1455
1796
|
] });
|
|
1456
1797
|
}
|
|
1457
1798
|
function SkeletonList({ rows = 8, className }) {
|
|
1458
|
-
return /* @__PURE__ */
|
|
1799
|
+
return /* @__PURE__ */ jsx33("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx33(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
|
|
1459
1800
|
}
|
|
1460
1801
|
|
|
1461
1802
|
// src/Breadcrumb.tsx
|
|
1462
|
-
import { Fragment as
|
|
1463
|
-
import { jsx as
|
|
1803
|
+
import { Fragment as Fragment6, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState6 } from "react";
|
|
1804
|
+
import { jsx as jsx34, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1464
1805
|
function Breadcrumb({ items, className }) {
|
|
1465
|
-
const navRef =
|
|
1466
|
-
const labelRefs =
|
|
1467
|
-
const [truncated, setTruncated] =
|
|
1806
|
+
const navRef = useRef5(null);
|
|
1807
|
+
const labelRefs = useRef5([]);
|
|
1808
|
+
const [truncated, setTruncated] = useState6(/* @__PURE__ */ new Set());
|
|
1468
1809
|
const measure = useCallback2(() => {
|
|
1469
1810
|
const next = /* @__PURE__ */ new Set();
|
|
1470
1811
|
labelRefs.current.forEach((el, index) => {
|
|
@@ -1472,7 +1813,7 @@ function Breadcrumb({ items, className }) {
|
|
|
1472
1813
|
});
|
|
1473
1814
|
setTruncated((prev) => prev.size === next.size && [...next].every((i) => prev.has(i)) ? prev : next);
|
|
1474
1815
|
}, []);
|
|
1475
|
-
|
|
1816
|
+
useLayoutEffect2(() => {
|
|
1476
1817
|
measure();
|
|
1477
1818
|
const nav = navRef.current;
|
|
1478
1819
|
if (!nav || typeof ResizeObserver === "undefined") return;
|
|
@@ -1480,7 +1821,7 @@ function Breadcrumb({ items, className }) {
|
|
|
1480
1821
|
observer.observe(nav);
|
|
1481
1822
|
return () => observer.disconnect();
|
|
1482
1823
|
}, [measure, items]);
|
|
1483
|
-
return /* @__PURE__ */
|
|
1824
|
+
return /* @__PURE__ */ jsx34("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-[14px] leading-[140%]", className), children: items.map((item, index) => {
|
|
1484
1825
|
const last = index === items.length - 1;
|
|
1485
1826
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
1486
1827
|
const text = cn(
|
|
@@ -1494,24 +1835,24 @@ function Breadcrumb({ items, className }) {
|
|
|
1494
1835
|
const setLabelRef = (el) => {
|
|
1495
1836
|
labelRefs.current[index] = el;
|
|
1496
1837
|
};
|
|
1497
|
-
const crumb = item.href ? /* @__PURE__ */
|
|
1498
|
-
return /* @__PURE__ */
|
|
1499
|
-
index > 0 && /* @__PURE__ */
|
|
1500
|
-
item.icon && /* @__PURE__ */
|
|
1838
|
+
const crumb = item.href ? /* @__PURE__ */ jsx34("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx34("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
1839
|
+
return /* @__PURE__ */ jsxs22(Fragment6, { children: [
|
|
1840
|
+
index > 0 && /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
1841
|
+
item.icon && /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
1501
1842
|
truncated.has(index) ? (
|
|
1502
1843
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
1503
1844
|
// must keep truncating inside it, or wrapping it would widen the
|
|
1504
1845
|
// trail and the tooltip would never be needed again.
|
|
1505
|
-
/* @__PURE__ */
|
|
1846
|
+
/* @__PURE__ */ jsx34(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
1506
1847
|
) : crumb
|
|
1507
1848
|
] }, `${item.label}-${index}`);
|
|
1508
1849
|
}) });
|
|
1509
1850
|
}
|
|
1510
1851
|
|
|
1511
1852
|
// src/NavItem.tsx
|
|
1512
|
-
import { jsx as
|
|
1853
|
+
import { jsx as jsx35, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1513
1854
|
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
1514
|
-
return /* @__PURE__ */
|
|
1855
|
+
return /* @__PURE__ */ jsxs23(
|
|
1515
1856
|
"a",
|
|
1516
1857
|
{
|
|
1517
1858
|
href,
|
|
@@ -1526,9 +1867,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
1526
1867
|
),
|
|
1527
1868
|
...props,
|
|
1528
1869
|
children: [
|
|
1529
|
-
icon && /* @__PURE__ */
|
|
1530
|
-
/* @__PURE__ */
|
|
1531
|
-
count ? /* @__PURE__ */
|
|
1870
|
+
icon && /* @__PURE__ */ jsx35("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
1871
|
+
/* @__PURE__ */ jsx35("span", { className: "flex-1 truncate", children: label }),
|
|
1872
|
+
count ? /* @__PURE__ */ jsx35(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx35("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
1532
1873
|
]
|
|
1533
1874
|
}
|
|
1534
1875
|
);
|
|
@@ -1537,7 +1878,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
1537
1878
|
// src/Popover.tsx
|
|
1538
1879
|
import { useMemo as useMemo2 } from "react";
|
|
1539
1880
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
1540
|
-
import { jsx as
|
|
1881
|
+
import { jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1541
1882
|
var GAP5 = 4;
|
|
1542
1883
|
var VIEWPORT_PAD5 = 8;
|
|
1543
1884
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -1546,7 +1887,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1546
1887
|
if (anchor instanceof Element) return anchor;
|
|
1547
1888
|
return { getBoundingClientRect: () => anchor };
|
|
1548
1889
|
}, [anchor]);
|
|
1549
|
-
return /* @__PURE__ */
|
|
1890
|
+
return /* @__PURE__ */ jsxs24(
|
|
1550
1891
|
BasePopover.Root,
|
|
1551
1892
|
{
|
|
1552
1893
|
open,
|
|
@@ -1554,8 +1895,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1554
1895
|
actionsRef,
|
|
1555
1896
|
modal: false,
|
|
1556
1897
|
children: [
|
|
1557
|
-
trigger && /* @__PURE__ */
|
|
1558
|
-
/* @__PURE__ */
|
|
1898
|
+
trigger && /* @__PURE__ */ jsx36(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
1899
|
+
/* @__PURE__ */ jsx36(BasePopover.Portal, { children: /* @__PURE__ */ jsx36(
|
|
1559
1900
|
BasePopover.Positioner,
|
|
1560
1901
|
{
|
|
1561
1902
|
anchor: anchorTarget,
|
|
@@ -1564,15 +1905,15 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1564
1905
|
sideOffset: GAP5,
|
|
1565
1906
|
collisionPadding: VIEWPORT_PAD5,
|
|
1566
1907
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1567
|
-
children: /* @__PURE__ */
|
|
1908
|
+
children: /* @__PURE__ */ jsx36(
|
|
1568
1909
|
BasePopover.Popup,
|
|
1569
1910
|
{
|
|
1570
1911
|
"aria-label": ariaLabel,
|
|
1571
1912
|
initialFocus: trigger ? void 0 : false,
|
|
1572
1913
|
finalFocus,
|
|
1573
1914
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
1574
|
-
render: /* @__PURE__ */
|
|
1575
|
-
children: /* @__PURE__ */
|
|
1915
|
+
render: /* @__PURE__ */ jsx36(MenuPanel, {}),
|
|
1916
|
+
children: /* @__PURE__ */ jsx36(
|
|
1576
1917
|
ScrollArea,
|
|
1577
1918
|
{
|
|
1578
1919
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
@@ -1591,9 +1932,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1591
1932
|
|
|
1592
1933
|
// src/Toolbar.tsx
|
|
1593
1934
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
1594
|
-
import { jsx as
|
|
1935
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
1595
1936
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
1596
|
-
const strip = /* @__PURE__ */
|
|
1937
|
+
const strip = /* @__PURE__ */ jsx37(
|
|
1597
1938
|
BaseToolbar.Root,
|
|
1598
1939
|
{
|
|
1599
1940
|
"aria-label": ariaLabel,
|
|
@@ -1604,24 +1945,24 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
1604
1945
|
}
|
|
1605
1946
|
);
|
|
1606
1947
|
if (!surface) return strip;
|
|
1607
|
-
return /* @__PURE__ */
|
|
1948
|
+
return /* @__PURE__ */ jsx37(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
1608
1949
|
}
|
|
1609
1950
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
1610
|
-
return /* @__PURE__ */
|
|
1951
|
+
return /* @__PURE__ */ jsx37(
|
|
1611
1952
|
BaseToolbar.Button,
|
|
1612
1953
|
{
|
|
1613
1954
|
ref,
|
|
1614
1955
|
disabled: disabled || !!disabledReason,
|
|
1615
1956
|
focusableWhenDisabled: true,
|
|
1616
|
-
render: /* @__PURE__ */
|
|
1957
|
+
render: /* @__PURE__ */ jsx37(IconButton, { disabled, disabledReason, ...props })
|
|
1617
1958
|
}
|
|
1618
1959
|
);
|
|
1619
1960
|
}
|
|
1620
1961
|
function ToolbarInput(props) {
|
|
1621
|
-
return /* @__PURE__ */
|
|
1962
|
+
return /* @__PURE__ */ jsx37(BaseToolbar.Input, { render: /* @__PURE__ */ jsx37(TextInput, {}), ...props });
|
|
1622
1963
|
}
|
|
1623
1964
|
function ToolbarSeparator({ className }) {
|
|
1624
|
-
return /* @__PURE__ */
|
|
1965
|
+
return /* @__PURE__ */ jsx37(
|
|
1625
1966
|
BaseToolbar.Separator,
|
|
1626
1967
|
{
|
|
1627
1968
|
orientation: "vertical",
|
|
@@ -1631,9 +1972,9 @@ function ToolbarSeparator({ className }) {
|
|
|
1631
1972
|
}
|
|
1632
1973
|
|
|
1633
1974
|
// src/ReactionPicker.tsx
|
|
1634
|
-
import { jsx as
|
|
1975
|
+
import { jsx as jsx38 } from "react/jsx-runtime";
|
|
1635
1976
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
1636
|
-
return /* @__PURE__ */
|
|
1977
|
+
return /* @__PURE__ */ jsx38(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
1637
1978
|
/*
|
|
1638
1979
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
1639
1980
|
would become the toolbar's item and the button inside it would never
|
|
@@ -1643,14 +1984,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
1643
1984
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
1644
1985
|
and both say the meaning rather than the glyph.
|
|
1645
1986
|
*/
|
|
1646
|
-
/* @__PURE__ */
|
|
1987
|
+
/* @__PURE__ */ jsx38(
|
|
1647
1988
|
ToolbarButton,
|
|
1648
1989
|
{
|
|
1649
1990
|
"aria-label": option.label,
|
|
1650
1991
|
tooltip: option.label,
|
|
1651
1992
|
onClick: () => onSelect(option.emoji),
|
|
1652
1993
|
className: "size-7 text-[18px] leading-none",
|
|
1653
|
-
children: /* @__PURE__ */
|
|
1994
|
+
children: /* @__PURE__ */ jsx38("span", { "aria-hidden": "true", children: option.emoji })
|
|
1654
1995
|
},
|
|
1655
1996
|
option.emoji
|
|
1656
1997
|
)
|
|
@@ -1659,23 +2000,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
1659
2000
|
|
|
1660
2001
|
// src/PreviewCard.tsx
|
|
1661
2002
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
1662
|
-
import { jsx as
|
|
2003
|
+
import { jsx as jsx39, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1663
2004
|
var GAP6 = 12;
|
|
1664
2005
|
var VIEWPORT_PAD6 = 8;
|
|
1665
2006
|
var OPEN_DELAY2 = 350;
|
|
1666
2007
|
var CLOSE_DELAY = 200;
|
|
1667
2008
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, wrapperClassName }) {
|
|
1668
|
-
return /* @__PURE__ */
|
|
1669
|
-
/* @__PURE__ */
|
|
2009
|
+
return /* @__PURE__ */ jsxs25(BasePreviewCard.Root, { children: [
|
|
2010
|
+
/* @__PURE__ */ jsx39(
|
|
1670
2011
|
BasePreviewCard.Trigger,
|
|
1671
2012
|
{
|
|
1672
2013
|
delay,
|
|
1673
2014
|
closeDelay,
|
|
1674
|
-
render: /* @__PURE__ */
|
|
2015
|
+
render: /* @__PURE__ */ jsx39("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
1675
2016
|
children
|
|
1676
2017
|
}
|
|
1677
2018
|
),
|
|
1678
|
-
/* @__PURE__ */
|
|
2019
|
+
/* @__PURE__ */ jsx39(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx39(
|
|
1679
2020
|
BasePreviewCard.Positioner,
|
|
1680
2021
|
{
|
|
1681
2022
|
side,
|
|
@@ -1683,12 +2024,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
1683
2024
|
sideOffset: GAP6,
|
|
1684
2025
|
collisionPadding: VIEWPORT_PAD6,
|
|
1685
2026
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1686
|
-
children: /* @__PURE__ */
|
|
2027
|
+
children: /* @__PURE__ */ jsx39(
|
|
1687
2028
|
BasePreviewCard.Popup,
|
|
1688
2029
|
{
|
|
1689
2030
|
className: cn("w-[360px] p-3 outline-none", className),
|
|
1690
|
-
render: /* @__PURE__ */
|
|
1691
|
-
children: /* @__PURE__ */
|
|
2031
|
+
render: /* @__PURE__ */ jsx39(MenuPanel, {}),
|
|
2032
|
+
children: /* @__PURE__ */ jsx39(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3 [&>*]:shrink-0", children: content })
|
|
1692
2033
|
}
|
|
1693
2034
|
)
|
|
1694
2035
|
}
|
|
@@ -1697,15 +2038,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
1697
2038
|
}
|
|
1698
2039
|
|
|
1699
2040
|
// src/Rail.tsx
|
|
1700
|
-
import { jsx as
|
|
2041
|
+
import { jsx as jsx40 } from "react/jsx-runtime";
|
|
1701
2042
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
1702
|
-
return /* @__PURE__ */
|
|
2043
|
+
return /* @__PURE__ */ jsx40("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
1703
2044
|
}
|
|
1704
2045
|
|
|
1705
2046
|
// src/RailItem.tsx
|
|
1706
|
-
import { jsx as
|
|
2047
|
+
import { jsx as jsx41, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1707
2048
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
1708
|
-
return /* @__PURE__ */
|
|
2049
|
+
return /* @__PURE__ */ jsxs26(
|
|
1709
2050
|
"a",
|
|
1710
2051
|
{
|
|
1711
2052
|
href,
|
|
@@ -1713,14 +2054,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
1713
2054
|
className: cn("group flex w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
1714
2055
|
...props,
|
|
1715
2056
|
children: [
|
|
1716
|
-
/* @__PURE__ */
|
|
2057
|
+
/* @__PURE__ */ jsx41(
|
|
1717
2058
|
"div",
|
|
1718
2059
|
{
|
|
1719
2060
|
className: cn(
|
|
1720
2061
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
1721
2062
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
1722
2063
|
),
|
|
1723
|
-
children: /* @__PURE__ */
|
|
2064
|
+
children: /* @__PURE__ */ jsx41(
|
|
1724
2065
|
"span",
|
|
1725
2066
|
{
|
|
1726
2067
|
className: cn(
|
|
@@ -1732,49 +2073,49 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
1732
2073
|
)
|
|
1733
2074
|
}
|
|
1734
2075
|
),
|
|
1735
|
-
/* @__PURE__ */
|
|
2076
|
+
/* @__PURE__ */ jsx41("span", { className: cn("text-center text-[9px] font-medium leading-[115%]", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
1736
2077
|
]
|
|
1737
2078
|
}
|
|
1738
2079
|
);
|
|
1739
2080
|
}
|
|
1740
2081
|
|
|
1741
2082
|
// src/Sidebar.tsx
|
|
1742
|
-
import { jsx as
|
|
2083
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
1743
2084
|
function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
|
|
1744
|
-
return /* @__PURE__ */
|
|
2085
|
+
return /* @__PURE__ */ jsx42(
|
|
1745
2086
|
"nav",
|
|
1746
2087
|
{
|
|
1747
2088
|
"aria-label": ariaLabel,
|
|
1748
2089
|
className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
|
|
1749
|
-
children: /* @__PURE__ */
|
|
2090
|
+
children: /* @__PURE__ */ jsx42(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
|
|
1750
2091
|
}
|
|
1751
2092
|
);
|
|
1752
2093
|
}
|
|
1753
2094
|
|
|
1754
2095
|
// src/Property.tsx
|
|
1755
|
-
import { jsx as
|
|
2096
|
+
import { jsx as jsx43, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1756
2097
|
function Property({ label, layout = "row", children, className }) {
|
|
1757
2098
|
if (layout === "stacked") {
|
|
1758
2099
|
return (
|
|
1759
2100
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
1760
2101
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
1761
2102
|
// 6px, and unifying means the bigger, calmer one.
|
|
1762
|
-
/* @__PURE__ */
|
|
1763
|
-
/* @__PURE__ */
|
|
2103
|
+
/* @__PURE__ */ jsxs27("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
2104
|
+
/* @__PURE__ */ jsx43("span", { className: "text-menu uppercase tracking-[0.08em] text-text-secondary", children: label }),
|
|
1764
2105
|
children
|
|
1765
2106
|
] })
|
|
1766
2107
|
);
|
|
1767
2108
|
}
|
|
1768
|
-
return /* @__PURE__ */
|
|
1769
|
-
/* @__PURE__ */
|
|
2109
|
+
return /* @__PURE__ */ jsxs27("div", { className: cn("flex items-center gap-2", className), children: [
|
|
2110
|
+
/* @__PURE__ */ jsx43("span", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
1770
2111
|
children
|
|
1771
2112
|
] });
|
|
1772
2113
|
}
|
|
1773
2114
|
|
|
1774
2115
|
// src/Reaction.tsx
|
|
1775
|
-
import { jsx as
|
|
2116
|
+
import { jsx as jsx44, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1776
2117
|
function Reaction({ emoji, count, pressed = false, className, type, ...props }) {
|
|
1777
|
-
return /* @__PURE__ */
|
|
2118
|
+
return /* @__PURE__ */ jsxs28(
|
|
1778
2119
|
"button",
|
|
1779
2120
|
{
|
|
1780
2121
|
type: type ?? "button",
|
|
@@ -1797,8 +2138,8 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
|
|
|
1797
2138
|
),
|
|
1798
2139
|
...props,
|
|
1799
2140
|
children: [
|
|
1800
|
-
/* @__PURE__ */
|
|
1801
|
-
/* @__PURE__ */
|
|
2141
|
+
/* @__PURE__ */ jsx44("span", { "aria-hidden": "true", className: "shrink-0 text-[16px] leading-none", children: emoji }),
|
|
2142
|
+
/* @__PURE__ */ jsx44("span", { className: "text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tabular-nums", children: count })
|
|
1802
2143
|
]
|
|
1803
2144
|
}
|
|
1804
2145
|
);
|
|
@@ -1807,9 +2148,9 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
|
|
|
1807
2148
|
// src/SearchInput.tsx
|
|
1808
2149
|
import "react";
|
|
1809
2150
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
1810
|
-
import { jsx as
|
|
2151
|
+
import { jsx as jsx45, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
1811
2152
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
1812
|
-
return /* @__PURE__ */
|
|
2153
|
+
return /* @__PURE__ */ jsxs29(
|
|
1813
2154
|
"div",
|
|
1814
2155
|
{
|
|
1815
2156
|
className: cn(
|
|
@@ -1819,7 +2160,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1819
2160
|
className
|
|
1820
2161
|
),
|
|
1821
2162
|
children: [
|
|
1822
|
-
/* @__PURE__ */
|
|
2163
|
+
/* @__PURE__ */ jsx45(
|
|
1823
2164
|
Input3,
|
|
1824
2165
|
{
|
|
1825
2166
|
className: "flex-1 min-w-0 bg-transparent text-input-value text-text-primary placeholder:text-text-muted outline-none",
|
|
@@ -1827,7 +2168,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1827
2168
|
...props
|
|
1828
2169
|
}
|
|
1829
2170
|
),
|
|
1830
|
-
shortcut && /* @__PURE__ */
|
|
2171
|
+
shortcut && /* @__PURE__ */ jsx45(Kbd, { children: shortcut })
|
|
1831
2172
|
]
|
|
1832
2173
|
}
|
|
1833
2174
|
);
|
|
@@ -1836,17 +2177,17 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1836
2177
|
// src/SectionHeader.tsx
|
|
1837
2178
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
1838
2179
|
import { useRender } from "@base-ui/react/use-render";
|
|
1839
|
-
import { Fragment as
|
|
2180
|
+
import { Fragment as Fragment7, jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
1840
2181
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", render, className }) {
|
|
1841
2182
|
const titleElement = useRender({
|
|
1842
|
-
render: render ?? (chevron ? /* @__PURE__ */
|
|
2183
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
|
|
1843
2184
|
props: {
|
|
1844
2185
|
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
1845
2186
|
// whole row up to the actions is the hit target, as it was when the
|
|
1846
2187
|
// row itself carried the click.
|
|
1847
2188
|
className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
|
|
1848
|
-
children: /* @__PURE__ */
|
|
1849
|
-
chevron && /* @__PURE__ */
|
|
2189
|
+
children: /* @__PURE__ */ jsxs30(Fragment7, { children: [
|
|
2190
|
+
chevron && /* @__PURE__ */ jsx46(
|
|
1850
2191
|
IconChevronRight2,
|
|
1851
2192
|
{
|
|
1852
2193
|
size: 12,
|
|
@@ -1854,11 +2195,11 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
1854
2195
|
className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
|
|
1855
2196
|
}
|
|
1856
2197
|
),
|
|
1857
|
-
/* @__PURE__ */
|
|
2198
|
+
/* @__PURE__ */ jsx46(SectionLabel, { children: title })
|
|
1858
2199
|
] })
|
|
1859
2200
|
}
|
|
1860
2201
|
});
|
|
1861
|
-
return /* @__PURE__ */
|
|
2202
|
+
return /* @__PURE__ */ jsxs30(
|
|
1862
2203
|
"div",
|
|
1863
2204
|
{
|
|
1864
2205
|
className: cn(
|
|
@@ -1871,15 +2212,15 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
1871
2212
|
),
|
|
1872
2213
|
children: [
|
|
1873
2214
|
titleElement,
|
|
1874
|
-
trailing != null && /* @__PURE__ */
|
|
1875
|
-
actions && actions.length > 0 && /* @__PURE__ */
|
|
2215
|
+
trailing != null && /* @__PURE__ */ jsx46("div", { className: "flex shrink-0 items-center", children: trailing }),
|
|
2216
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx46(
|
|
1876
2217
|
"div",
|
|
1877
2218
|
{
|
|
1878
2219
|
className: cn(
|
|
1879
2220
|
"-mr-1 flex shrink-0 items-center gap-1",
|
|
1880
2221
|
showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
1881
2222
|
),
|
|
1882
|
-
children: actions.map((action) => /* @__PURE__ */
|
|
2223
|
+
children: actions.map((action) => /* @__PURE__ */ jsx46(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
|
|
1883
2224
|
}
|
|
1884
2225
|
)
|
|
1885
2226
|
]
|
|
@@ -1888,9 +2229,9 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
1888
2229
|
}
|
|
1889
2230
|
|
|
1890
2231
|
// src/CollapsibleSection.tsx
|
|
1891
|
-
import { useState as
|
|
2232
|
+
import { useState as useState7 } from "react";
|
|
1892
2233
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
1893
|
-
import { jsx as
|
|
2234
|
+
import { jsx as jsx47, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
1894
2235
|
var OPEN = "open";
|
|
1895
2236
|
var CLOSED = "closed";
|
|
1896
2237
|
function readStored(key) {
|
|
@@ -1910,21 +2251,21 @@ function writeStored(key, open) {
|
|
|
1910
2251
|
}
|
|
1911
2252
|
}
|
|
1912
2253
|
function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, children, className, contentClassName }) {
|
|
1913
|
-
const [openState, setOpenState] =
|
|
2254
|
+
const [openState, setOpenState] = useState7(() => readStored(storageKey) ?? defaultOpen);
|
|
1914
2255
|
const open = openProp ?? openState;
|
|
1915
2256
|
const setOpen = (next) => {
|
|
1916
2257
|
setOpenState(next);
|
|
1917
2258
|
writeStored(storageKey, next);
|
|
1918
2259
|
onOpenChange?.(next);
|
|
1919
2260
|
};
|
|
1920
|
-
return /* @__PURE__ */
|
|
1921
|
-
/* @__PURE__ */
|
|
1922
|
-
/* @__PURE__ */
|
|
2261
|
+
return /* @__PURE__ */ jsxs31(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
2262
|
+
/* @__PURE__ */ jsx47(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx47(Collapsible.Trigger, {}) }),
|
|
2263
|
+
/* @__PURE__ */ jsx47(
|
|
1923
2264
|
Collapsible.Panel,
|
|
1924
2265
|
{
|
|
1925
2266
|
hiddenUntilFound: true,
|
|
1926
2267
|
className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
|
|
1927
|
-
children: /* @__PURE__ */
|
|
2268
|
+
children: /* @__PURE__ */ jsx47("div", { className: cn("flex flex-col", contentClassName), children })
|
|
1928
2269
|
}
|
|
1929
2270
|
)
|
|
1930
2271
|
] });
|
|
@@ -1932,9 +2273,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
1932
2273
|
|
|
1933
2274
|
// src/Tabs.tsx
|
|
1934
2275
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
1935
|
-
import { jsx as
|
|
2276
|
+
import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
1936
2277
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
1937
|
-
return /* @__PURE__ */
|
|
2278
|
+
return /* @__PURE__ */ jsx48(
|
|
1938
2279
|
BaseTabs.Root,
|
|
1939
2280
|
{
|
|
1940
2281
|
value: active,
|
|
@@ -1942,14 +2283,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1942
2283
|
if (details.reason === "none") onChange(value);
|
|
1943
2284
|
},
|
|
1944
2285
|
className,
|
|
1945
|
-
children: /* @__PURE__ */
|
|
2286
|
+
children: /* @__PURE__ */ jsx48(
|
|
1946
2287
|
BaseTabs.List,
|
|
1947
2288
|
{
|
|
1948
2289
|
activateOnFocus: true,
|
|
1949
2290
|
"aria-label": aria["aria-label"],
|
|
1950
2291
|
"aria-labelledby": aria["aria-labelledby"],
|
|
1951
2292
|
className: "flex items-center gap-2",
|
|
1952
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
2293
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs32(
|
|
1953
2294
|
BaseTabs.Tab,
|
|
1954
2295
|
{
|
|
1955
2296
|
value: tab.id,
|
|
@@ -1962,9 +2303,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1962
2303
|
),
|
|
1963
2304
|
children: [
|
|
1964
2305
|
tab.icon,
|
|
1965
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ jsxs32("span", { className: "flex items-baseline", children: [
|
|
1966
2307
|
tab.label,
|
|
1967
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
2308
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx48("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
1968
2309
|
] })
|
|
1969
2310
|
]
|
|
1970
2311
|
},
|
|
@@ -1977,10 +2318,10 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1977
2318
|
}
|
|
1978
2319
|
|
|
1979
2320
|
// src/Toast.tsx
|
|
1980
|
-
import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect2, useMemo as useMemo3, useState as
|
|
2321
|
+
import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect2, useMemo as useMemo3, useState as useState8 } from "react";
|
|
1981
2322
|
import { createPortal } from "react-dom";
|
|
1982
|
-
import { IconAlertCircle, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
1983
|
-
import { jsx as
|
|
2323
|
+
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
2324
|
+
import { jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
1984
2325
|
var SURFACE_STYLES = {
|
|
1985
2326
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
|
|
1986
2327
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
|
|
@@ -1992,7 +2333,7 @@ var ICONS = {
|
|
|
1992
2333
|
success: IconCircleCheck,
|
|
1993
2334
|
brand: IconCircleCheck,
|
|
1994
2335
|
neutral: IconCircleCheck,
|
|
1995
|
-
warning:
|
|
2336
|
+
warning: IconAlertCircle2,
|
|
1996
2337
|
error: IconCircleX
|
|
1997
2338
|
};
|
|
1998
2339
|
var ICON_STYLES = {
|
|
@@ -2015,7 +2356,7 @@ var ACTION_BORDER_STYLES = {
|
|
|
2015
2356
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
2016
2357
|
const hasAction = !!(actionLabel && onAction);
|
|
2017
2358
|
const LeadingIcon = ICONS[type];
|
|
2018
|
-
return /* @__PURE__ */
|
|
2359
|
+
return /* @__PURE__ */ jsxs33(
|
|
2019
2360
|
"div",
|
|
2020
2361
|
{
|
|
2021
2362
|
className: cn(
|
|
@@ -2027,11 +2368,11 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
2027
2368
|
className
|
|
2028
2369
|
),
|
|
2029
2370
|
children: [
|
|
2030
|
-
/* @__PURE__ */
|
|
2031
|
-
leadingIcon && /* @__PURE__ */
|
|
2032
|
-
/* @__PURE__ */
|
|
2371
|
+
/* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2372
|
+
leadingIcon && /* @__PURE__ */ jsx49(LeadingIcon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
|
|
2373
|
+
/* @__PURE__ */ jsx49("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
|
|
2033
2374
|
] }),
|
|
2034
|
-
hasAction && /* @__PURE__ */
|
|
2375
|
+
hasAction && /* @__PURE__ */ jsx49(
|
|
2035
2376
|
"button",
|
|
2036
2377
|
{
|
|
2037
2378
|
type: "button",
|
|
@@ -2041,7 +2382,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
2041
2382
|
ACTION_BORDER_STYLES[type],
|
|
2042
2383
|
type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
|
|
2043
2384
|
),
|
|
2044
|
-
children: /* @__PURE__ */
|
|
2385
|
+
children: /* @__PURE__ */ jsx49("span", { className: "font-medium text-[12px] leading-[12px] text-text-primary whitespace-nowrap", children: actionLabel })
|
|
2045
2386
|
}
|
|
2046
2387
|
)
|
|
2047
2388
|
]
|
|
@@ -2051,7 +2392,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
2051
2392
|
var ToastContext = createContext2(null);
|
|
2052
2393
|
var toastSeq = 0;
|
|
2053
2394
|
function ToastProvider({ children }) {
|
|
2054
|
-
const [toast, setToast] =
|
|
2395
|
+
const [toast, setToast] = useState8(null);
|
|
2055
2396
|
const showToast = useCallback3((opts) => {
|
|
2056
2397
|
setToast({ ...opts, id: ++toastSeq });
|
|
2057
2398
|
}, []);
|
|
@@ -2068,10 +2409,10 @@ function ToastProvider({ children }) {
|
|
|
2068
2409
|
return () => clearTimeout(timer);
|
|
2069
2410
|
}, [toast]);
|
|
2070
2411
|
const value = useMemo3(() => ({ showToast, dismissToast }), [showToast, dismissToast]);
|
|
2071
|
-
return /* @__PURE__ */
|
|
2412
|
+
return /* @__PURE__ */ jsxs33(ToastContext.Provider, { value, children: [
|
|
2072
2413
|
children,
|
|
2073
2414
|
toast && createPortal(
|
|
2074
|
-
/* @__PURE__ */
|
|
2415
|
+
/* @__PURE__ */ jsx49("div", { className: "fixed bottom-4 left-4 z-[100] pointer-events-none", children: /* @__PURE__ */ jsx49(
|
|
2075
2416
|
Toast,
|
|
2076
2417
|
{
|
|
2077
2418
|
className: "pointer-events-auto",
|
|
@@ -2096,11 +2437,13 @@ function useToast() {
|
|
|
2096
2437
|
}
|
|
2097
2438
|
export {
|
|
2098
2439
|
AppShell,
|
|
2440
|
+
AttachmentCard,
|
|
2099
2441
|
Avatar,
|
|
2100
2442
|
AvatarGroup,
|
|
2101
2443
|
Banner,
|
|
2102
2444
|
Breadcrumb,
|
|
2103
2445
|
Button,
|
|
2446
|
+
Card,
|
|
2104
2447
|
Checkbox,
|
|
2105
2448
|
Chip,
|
|
2106
2449
|
ChipInput,
|
|
@@ -2113,11 +2456,15 @@ export {
|
|
|
2113
2456
|
EnterHint,
|
|
2114
2457
|
Field,
|
|
2115
2458
|
FieldLine,
|
|
2459
|
+
INLINE_CHIP_CLASSES,
|
|
2460
|
+
INLINE_CHIP_TONE_CLASSES,
|
|
2116
2461
|
IconButton,
|
|
2117
2462
|
IdentityMenu,
|
|
2118
2463
|
IdentityPanel,
|
|
2464
|
+
InlineChip,
|
|
2119
2465
|
InputChip,
|
|
2120
2466
|
Kbd,
|
|
2467
|
+
Link,
|
|
2121
2468
|
Menu,
|
|
2122
2469
|
MenuItem,
|
|
2123
2470
|
MenuPanel,
|
|
@@ -2129,6 +2476,7 @@ export {
|
|
|
2129
2476
|
PersonTrigger,
|
|
2130
2477
|
Popover,
|
|
2131
2478
|
PreviewCard,
|
|
2479
|
+
ProgressBar,
|
|
2132
2480
|
Property,
|
|
2133
2481
|
Rail,
|
|
2134
2482
|
RailItem,
|
|
@@ -2159,6 +2507,7 @@ export {
|
|
|
2159
2507
|
cn,
|
|
2160
2508
|
hueFor,
|
|
2161
2509
|
initialsFor,
|
|
2510
|
+
inlineChipClassName,
|
|
2162
2511
|
useToast
|
|
2163
2512
|
};
|
|
2164
2513
|
//# sourceMappingURL=index.js.map
|