@estiva-app/ui 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AttachmentCard.d.ts +48 -6
- package/dist/AttachmentCard.d.ts.map +1 -1
- package/dist/Lightbox.d.ts +30 -0
- package/dist/Lightbox.d.ts.map +1 -0
- package/dist/eslint/index.js +4 -4
- package/dist/eslint/index.js.map +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +594 -464
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/registry.json +94 -4
- package/src/AttachmentCard.mdx +32 -8
- package/src/AttachmentCard.stories.tsx +54 -0
- package/src/AttachmentCard.test.tsx +115 -0
- package/src/AttachmentCard.tsx +212 -37
- package/src/Lightbox.mdx +71 -0
- package/src/Lightbox.stories.tsx +72 -0
- package/src/Lightbox.test.tsx +65 -0
- package/src/Lightbox.tsx +87 -0
- package/src/eslint/no-rebuilt-behaviour.ts +4 -4
- package/src/index.ts +1 -0
- package/src/registry/registry.test.ts +4 -4
- package/tailwind-preset.js +3 -0
- package/tokens.css +4 -0
package/dist/index.js
CHANGED
|
@@ -140,7 +140,7 @@ function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav
|
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
// src/AttachmentCard.tsx
|
|
143
|
-
import { useLayoutEffect, useRef, useState } from "react";
|
|
143
|
+
import { useEffect, useLayoutEffect, useRef as useRef2, useState } from "react";
|
|
144
144
|
import { Button as BaseButton2 } from "@base-ui/react/button";
|
|
145
145
|
import {
|
|
146
146
|
IconAlertCircle,
|
|
@@ -157,7 +157,7 @@ import {
|
|
|
157
157
|
IconJson,
|
|
158
158
|
IconLoader2,
|
|
159
159
|
IconMarkdown,
|
|
160
|
-
IconX
|
|
160
|
+
IconX as IconX2
|
|
161
161
|
} from "@tabler/icons-react";
|
|
162
162
|
|
|
163
163
|
// src/Link.tsx
|
|
@@ -406,8 +406,58 @@ function IconButton({
|
|
|
406
406
|
return button;
|
|
407
407
|
}
|
|
408
408
|
|
|
409
|
+
// src/Lightbox.tsx
|
|
410
|
+
import { useRef } from "react";
|
|
411
|
+
import { Dialog } from "@base-ui/react/dialog";
|
|
412
|
+
import { IconX } from "@tabler/icons-react";
|
|
413
|
+
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
414
|
+
function Lightbox({ src, alt, onClose, className }) {
|
|
415
|
+
const popupRef = useRef(null);
|
|
416
|
+
return /* @__PURE__ */ jsx9(
|
|
417
|
+
Dialog.Root,
|
|
418
|
+
{
|
|
419
|
+
open: true,
|
|
420
|
+
onOpenChange: (open) => {
|
|
421
|
+
if (!open) onClose();
|
|
422
|
+
},
|
|
423
|
+
children: /* @__PURE__ */ jsxs5(Dialog.Portal, { children: [
|
|
424
|
+
/* @__PURE__ */ jsx9(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim-strong" }),
|
|
425
|
+
/* @__PURE__ */ jsxs5(
|
|
426
|
+
Dialog.Popup,
|
|
427
|
+
{
|
|
428
|
+
ref: popupRef,
|
|
429
|
+
initialFocus: popupRef,
|
|
430
|
+
"aria-label": alt,
|
|
431
|
+
className: "fixed inset-0 z-50 flex items-center justify-center p-8 outline-none",
|
|
432
|
+
onClick: onClose,
|
|
433
|
+
children: [
|
|
434
|
+
/* @__PURE__ */ jsx9(
|
|
435
|
+
"img",
|
|
436
|
+
{
|
|
437
|
+
src,
|
|
438
|
+
alt,
|
|
439
|
+
onClick: (e) => e.stopPropagation(),
|
|
440
|
+
className: cn("max-w-full max-h-full object-contain rounded-lg", className)
|
|
441
|
+
}
|
|
442
|
+
),
|
|
443
|
+
/* @__PURE__ */ jsx9(
|
|
444
|
+
Dialog.Close,
|
|
445
|
+
{
|
|
446
|
+
"aria-label": "Close",
|
|
447
|
+
className: "absolute top-4 right-4 size-8 rounded-full bg-bg-elevated border border-border-strong flex items-center justify-center text-text-secondary hover:text-text-primary",
|
|
448
|
+
children: /* @__PURE__ */ jsx9(IconX, { size: 16, stroke: 1.5 })
|
|
449
|
+
}
|
|
450
|
+
)
|
|
451
|
+
]
|
|
452
|
+
}
|
|
453
|
+
)
|
|
454
|
+
] })
|
|
455
|
+
}
|
|
456
|
+
);
|
|
457
|
+
}
|
|
458
|
+
|
|
409
459
|
// src/AttachmentCard.tsx
|
|
410
|
-
import { Fragment, jsx as
|
|
460
|
+
import { Fragment, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
411
461
|
var ICON_BY_EXTENSION = {
|
|
412
462
|
pdf: IconFileTypePdf,
|
|
413
463
|
doc: IconFileTypeDocx,
|
|
@@ -441,10 +491,10 @@ var NAME_CLASSES = "text-caption font-medium text-text-primary truncate";
|
|
|
441
491
|
var NOTE_CLASSES = "text-small tracking-wide leading-tight truncate";
|
|
442
492
|
function TypeIcon({ name }) {
|
|
443
493
|
const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
|
|
444
|
-
return /* @__PURE__ */
|
|
494
|
+
return /* @__PURE__ */ jsx10(Icon, { size: 20, stroke: 1.5 });
|
|
445
495
|
}
|
|
446
496
|
function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
447
|
-
const ref =
|
|
497
|
+
const ref = useRef2(null);
|
|
448
498
|
const [cut, setCut] = useState(false);
|
|
449
499
|
useLayoutEffect(() => {
|
|
450
500
|
const el = ref.current;
|
|
@@ -463,9 +513,54 @@ function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
|
463
513
|
observer.disconnect();
|
|
464
514
|
};
|
|
465
515
|
}, [text, cut]);
|
|
466
|
-
const line = /* @__PURE__ */
|
|
516
|
+
const line = /* @__PURE__ */ jsx10("span", { ref, className, children: text });
|
|
467
517
|
if (!hint && !cut) return line;
|
|
468
|
-
return /* @__PURE__ */
|
|
518
|
+
return /* @__PURE__ */ jsx10(WithTooltip, { label: hint ?? text, placement, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
|
|
519
|
+
}
|
|
520
|
+
function useRemoteImage(url, fetchImage) {
|
|
521
|
+
const [result, setResult] = useState({});
|
|
522
|
+
const fetcher = useRef2(fetchImage);
|
|
523
|
+
fetcher.current = fetchImage;
|
|
524
|
+
useEffect(() => {
|
|
525
|
+
if (!url || !fetcher.current) return;
|
|
526
|
+
let live = true;
|
|
527
|
+
fetcher.current(url).then(
|
|
528
|
+
(src) => {
|
|
529
|
+
if (live) setResult({ for: url, src });
|
|
530
|
+
},
|
|
531
|
+
() => {
|
|
532
|
+
if (live) setResult({ for: url, failed: true });
|
|
533
|
+
}
|
|
534
|
+
);
|
|
535
|
+
return () => {
|
|
536
|
+
live = false;
|
|
537
|
+
};
|
|
538
|
+
}, [url]);
|
|
539
|
+
const current = result.for === url;
|
|
540
|
+
return { src: current ? result.src : void 0, failed: current ? !!result.failed : false };
|
|
541
|
+
}
|
|
542
|
+
async function saveFile(source, name) {
|
|
543
|
+
if (source.startsWith("blob:") || source.startsWith("data:")) {
|
|
544
|
+
handToAnchor(source, name);
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
try {
|
|
548
|
+
const res = await fetch(source);
|
|
549
|
+
if (!res.ok) throw new Error(String(res.status));
|
|
550
|
+
const objectUrl = URL.createObjectURL(await res.blob());
|
|
551
|
+
handToAnchor(objectUrl, name);
|
|
552
|
+
URL.revokeObjectURL(objectUrl);
|
|
553
|
+
} catch {
|
|
554
|
+
window.open(source, "_blank", "noopener");
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
function handToAnchor(url, name) {
|
|
558
|
+
const a = document.createElement("a");
|
|
559
|
+
a.href = url;
|
|
560
|
+
a.download = name;
|
|
561
|
+
document.body.appendChild(a);
|
|
562
|
+
a.click();
|
|
563
|
+
a.remove();
|
|
469
564
|
}
|
|
470
565
|
function AttachmentCard({
|
|
471
566
|
name,
|
|
@@ -473,8 +568,13 @@ function AttachmentCard({
|
|
|
473
568
|
contentType,
|
|
474
569
|
href,
|
|
475
570
|
src,
|
|
571
|
+
alt,
|
|
572
|
+
remoteSrc,
|
|
573
|
+
remoteFullSrc,
|
|
574
|
+
fetchImage,
|
|
476
575
|
onOpen,
|
|
477
576
|
onDownload,
|
|
577
|
+
download = false,
|
|
478
578
|
pending = false,
|
|
479
579
|
onRemove,
|
|
480
580
|
state = "ready",
|
|
@@ -485,22 +585,48 @@ function AttachmentCard({
|
|
|
485
585
|
}) {
|
|
486
586
|
const image = isImage(name, contentType);
|
|
487
587
|
const sizeText = size === void 0 ? "" : formatBytes(size);
|
|
588
|
+
const remote = useRemoteImage(src ? void 0 : remoteSrc, fetchImage);
|
|
589
|
+
const picture = image ? src ?? remote.src : void 0;
|
|
590
|
+
const fetching = !src && !!remoteSrc && !!fetchImage;
|
|
591
|
+
const drawnState = state !== "ready" ? state : image && fetching ? remote.failed ? "unreadable" : picture ? "ready" : "loading" : state;
|
|
592
|
+
const address = href ?? (!image && fetching ? remote.src : void 0);
|
|
593
|
+
const [opened, setOpened] = useState(false);
|
|
594
|
+
const full = useRemoteImage(opened ? remoteFullSrc : void 0, fetchImage);
|
|
595
|
+
const openable = image && !!picture && !pending;
|
|
596
|
+
const openPicture = onOpen ?? (openable ? () => setOpened(true) : void 0);
|
|
597
|
+
const viewer = opened && picture ? /* @__PURE__ */ jsx10(Lightbox, { src: full.src ?? picture, alt: alt ?? name, onClose: () => setOpened(false) }) : null;
|
|
598
|
+
const saveHere = download ? () => {
|
|
599
|
+
const source = remoteFullSrc ?? remoteSrc;
|
|
600
|
+
if (source && fetchImage) {
|
|
601
|
+
void fetchImage(source).then(
|
|
602
|
+
(resolved) => saveFile(resolved, name),
|
|
603
|
+
// Without this a refused read is an unhandled rejection in the page
|
|
604
|
+
// rather than a download that did not happen.
|
|
605
|
+
() => {
|
|
606
|
+
}
|
|
607
|
+
);
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
const local = address ?? picture;
|
|
611
|
+
if (local) void saveFile(local, name);
|
|
612
|
+
} : void 0;
|
|
613
|
+
const saving = onDownload ?? saveHere;
|
|
488
614
|
if (pending) {
|
|
489
615
|
const failed = state === "failed";
|
|
490
616
|
const warning = state === "warning";
|
|
491
617
|
return (
|
|
492
618
|
// @estiva-escape: a failed or warning file's strong hairline is AttachmentCard's own state; Card's attention hairlines are the soft ones (UIG-9, Katerina 17 September)
|
|
493
|
-
/* @__PURE__ */
|
|
619
|
+
/* @__PURE__ */ jsxs6(
|
|
494
620
|
Card,
|
|
495
621
|
{
|
|
496
622
|
fill: "elevated",
|
|
497
623
|
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),
|
|
498
624
|
...props,
|
|
499
625
|
children: [
|
|
500
|
-
/* @__PURE__ */
|
|
501
|
-
/* @__PURE__ */
|
|
502
|
-
/* @__PURE__ */
|
|
503
|
-
/* @__PURE__ */
|
|
626
|
+
/* @__PURE__ */ jsx10("div", { className: cn(TILE_CLASSES, "overflow-hidden"), children: state === "uploading" ? /* @__PURE__ */ jsx10(IconLoader2, { size: 16, stroke: 1.5, className: "animate-spin" }) : failed ? /* @__PURE__ */ jsx10(IconAlertCircle, { size: 16, stroke: 1.5, className: "text-error-default" }) : warning ? /* @__PURE__ */ jsx10(IconAlertTriangle, { size: 16, stroke: 1.5, className: "text-warning-default" }) : image && src ? /* @__PURE__ */ jsx10("img", { src, alt: name, className: "size-full object-cover" }) : /* @__PURE__ */ jsx10("span", { className: "text-menu font-semibold", children: typeLabelOf(name) }) }),
|
|
627
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
628
|
+
/* @__PURE__ */ jsx10(Truncating, { text: name, className: NAME_CLASSES, placement: onRemove ? "bottom" : void 0 }),
|
|
629
|
+
/* @__PURE__ */ jsx10(
|
|
504
630
|
Truncating,
|
|
505
631
|
{
|
|
506
632
|
text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
|
|
@@ -509,7 +635,7 @@ function AttachmentCard({
|
|
|
509
635
|
}
|
|
510
636
|
)
|
|
511
637
|
] }),
|
|
512
|
-
onRemove && /* @__PURE__ */
|
|
638
|
+
onRemove && /* @__PURE__ */ jsx10(
|
|
513
639
|
BaseButton2,
|
|
514
640
|
{
|
|
515
641
|
type: "button",
|
|
@@ -519,7 +645,7 @@ function AttachmentCard({
|
|
|
519
645
|
event.stopPropagation();
|
|
520
646
|
onRemove();
|
|
521
647
|
},
|
|
522
|
-
children: /* @__PURE__ */
|
|
648
|
+
children: /* @__PURE__ */ jsx10(IconX2, { size: 11, stroke: 1.75 })
|
|
523
649
|
}
|
|
524
650
|
)
|
|
525
651
|
]
|
|
@@ -527,9 +653,9 @@ function AttachmentCard({
|
|
|
527
653
|
)
|
|
528
654
|
);
|
|
529
655
|
}
|
|
530
|
-
const
|
|
656
|
+
const downloadControl = saving ? (
|
|
531
657
|
// @estiva-escape: Download shows when its card is pointed at or focused, AttachmentCard's own action; IconButton has no reveal on its card's hover (UIG-9, Katerina 17 September)
|
|
532
|
-
/* @__PURE__ */
|
|
658
|
+
/* @__PURE__ */ jsx10(
|
|
533
659
|
IconButton,
|
|
534
660
|
{
|
|
535
661
|
variant: "muted",
|
|
@@ -538,66 +664,69 @@ function AttachmentCard({
|
|
|
538
664
|
className: "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 transition-opacity",
|
|
539
665
|
onClick: (event) => {
|
|
540
666
|
event.stopPropagation();
|
|
541
|
-
|
|
667
|
+
saving();
|
|
542
668
|
},
|
|
543
|
-
children: /* @__PURE__ */
|
|
669
|
+
children: /* @__PURE__ */ jsx10(IconDownload, { size: 16, stroke: 1.5 })
|
|
544
670
|
}
|
|
545
671
|
)
|
|
546
672
|
) : null;
|
|
547
|
-
if (
|
|
673
|
+
if (drawnState === "loading") {
|
|
548
674
|
return (
|
|
549
675
|
// `role="status"`: a plain box may not carry a name (axe, aria-prohibited-attr), and a
|
|
550
676
|
// status says what it is doing — loading — to a reader that cannot see the pulse.
|
|
551
677
|
// @estiva-escape: the loading pulse is AttachmentCard's own state; Card has no loading state (UIG-9, Katerina 17 September)
|
|
552
|
-
/* @__PURE__ */
|
|
678
|
+
/* @__PURE__ */ jsx10(Card, { role: "status", fill: "inset", "aria-busy": "true", "aria-label": `Loading ${name}`, className: cn("w-[180px] h-28 animate-pulse", className), ...props, children: null })
|
|
553
679
|
);
|
|
554
680
|
}
|
|
555
|
-
if (
|
|
681
|
+
if (drawnState === "unreadable") {
|
|
556
682
|
return (
|
|
557
683
|
// @estiva-escape: a file that could not be read is faded as well as dashed, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
|
|
558
|
-
/* @__PURE__ */
|
|
559
|
-
/* @__PURE__ */
|
|
560
|
-
/* @__PURE__ */
|
|
561
|
-
/* @__PURE__ */
|
|
562
|
-
/* @__PURE__ */
|
|
684
|
+
/* @__PURE__ */ jsxs6(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
|
|
685
|
+
/* @__PURE__ */ jsx10("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx10(TypeIcon, { name }) }),
|
|
686
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
687
|
+
/* @__PURE__ */ jsx10(Truncating, { text: name, className: NAME_CLASSES }),
|
|
688
|
+
/* @__PURE__ */ jsx10("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? "Could not be loaded" })
|
|
563
689
|
] })
|
|
564
690
|
] })
|
|
565
691
|
);
|
|
566
692
|
}
|
|
567
|
-
if (image &&
|
|
568
|
-
const
|
|
569
|
-
return /* @__PURE__ */
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
event
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
/* @__PURE__ */
|
|
585
|
-
|
|
586
|
-
|
|
693
|
+
if (image && picture) {
|
|
694
|
+
const thumbnail = /* @__PURE__ */ jsx10("img", { src: picture, alt: alt ?? name, className: "w-full h-28 object-cover" });
|
|
695
|
+
return /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
696
|
+
/* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: "hairline", clip: true, className: cn("group relative flex flex-col w-[180px]", className), ...props, children: [
|
|
697
|
+
openPicture ? /* @__PURE__ */ jsx10(
|
|
698
|
+
BaseButton2,
|
|
699
|
+
{
|
|
700
|
+
type: "button",
|
|
701
|
+
className: "block w-full",
|
|
702
|
+
"aria-label": `Preview ${name}`,
|
|
703
|
+
onClick: (event) => {
|
|
704
|
+
event.stopPropagation();
|
|
705
|
+
openPicture();
|
|
706
|
+
},
|
|
707
|
+
children: thumbnail
|
|
708
|
+
}
|
|
709
|
+
) : /* @__PURE__ */ jsx10("div", { className: "block w-full", children: thumbnail }),
|
|
710
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
|
|
711
|
+
/* @__PURE__ */ jsx10(Truncating, { text: name, className: "flex-1 text-caption text-text-primary truncate", wrapperClassName: "flex-1" }),
|
|
712
|
+
downloadControl
|
|
713
|
+
] })
|
|
714
|
+
] }),
|
|
715
|
+
viewer
|
|
587
716
|
] });
|
|
588
717
|
}
|
|
589
|
-
const body = /* @__PURE__ */
|
|
590
|
-
/* @__PURE__ */
|
|
591
|
-
/* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
593
|
-
/* @__PURE__ */
|
|
718
|
+
const body = /* @__PURE__ */ jsxs6(Fragment, { children: [
|
|
719
|
+
/* @__PURE__ */ jsx10("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx10(TypeIcon, { name }) }),
|
|
720
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
721
|
+
/* @__PURE__ */ jsx10(Truncating, { text: name, className: NAME_CLASSES }),
|
|
722
|
+
/* @__PURE__ */ jsx10("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
|
|
594
723
|
] })
|
|
595
724
|
] });
|
|
596
725
|
return (
|
|
597
726
|
// @estiva-escape: a file that cannot be opened is faded, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
|
|
598
|
-
/* @__PURE__ */
|
|
599
|
-
|
|
600
|
-
|
|
727
|
+
/* @__PURE__ */ jsxs6(Card, { fill: "inset", hover: address ? "hairline" : "none", className: cn("group flex items-center gap-2 w-[240px] p-1.5 pr-1", !address && "opacity-70", className), ...props, children: [
|
|
728
|
+
address ? /* @__PURE__ */ jsx10(Link, { href: address, external: true, variant: "plain", className: "flex items-center gap-2 min-w-0 flex-1", onClick: (event) => event.stopPropagation(), children: body }) : /* @__PURE__ */ jsx10("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: body }),
|
|
729
|
+
downloadControl
|
|
601
730
|
] })
|
|
602
731
|
);
|
|
603
732
|
}
|
|
@@ -605,7 +734,7 @@ function AttachmentCard({
|
|
|
605
734
|
// src/Avatar.tsx
|
|
606
735
|
import { Avatar as BaseAvatar } from "@base-ui/react/avatar";
|
|
607
736
|
import { IconUserFilled } from "@tabler/icons-react";
|
|
608
|
-
import { jsx as
|
|
737
|
+
import { jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
609
738
|
var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
|
|
610
739
|
var hueFor = (key) => {
|
|
611
740
|
let h = 0;
|
|
@@ -619,15 +748,15 @@ var initialsFor = (name) => {
|
|
|
619
748
|
};
|
|
620
749
|
function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
621
750
|
const label = name || alt;
|
|
622
|
-
return /* @__PURE__ */
|
|
751
|
+
return /* @__PURE__ */ jsxs7(
|
|
623
752
|
BaseAvatar.Root,
|
|
624
753
|
{
|
|
625
|
-
render: /* @__PURE__ */
|
|
754
|
+
render: /* @__PURE__ */ jsx11("div", {}),
|
|
626
755
|
...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
|
|
627
756
|
className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
|
|
628
757
|
style: { width: size, height: size },
|
|
629
758
|
children: [
|
|
630
|
-
src && /* @__PURE__ */
|
|
759
|
+
src && /* @__PURE__ */ jsx11(
|
|
631
760
|
BaseAvatar.Image,
|
|
632
761
|
{
|
|
633
762
|
src,
|
|
@@ -636,10 +765,10 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
636
765
|
className: "w-full h-full object-cover data-[error]:hidden"
|
|
637
766
|
}
|
|
638
767
|
),
|
|
639
|
-
label ? /* @__PURE__ */
|
|
768
|
+
label ? /* @__PURE__ */ jsx11(
|
|
640
769
|
BaseAvatar.Fallback,
|
|
641
770
|
{
|
|
642
|
-
render: /* @__PURE__ */
|
|
771
|
+
render: /* @__PURE__ */ jsx11("div", {}),
|
|
643
772
|
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
644
773
|
style: {
|
|
645
774
|
/* eslint-disable no-restricted-syntax -- @estiva-escape: the per-person palette (the note at
|
|
@@ -653,32 +782,32 @@ function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
|
653
782
|
background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
|
|
654
783
|
/* eslint-enable no-restricted-syntax */
|
|
655
784
|
},
|
|
656
|
-
children: /* @__PURE__ */
|
|
785
|
+
children: /* @__PURE__ */ jsx11("span", { className: "[text-box:trim-both_cap_alphabetic]", children: initialsFor(label) })
|
|
657
786
|
}
|
|
658
|
-
) : /* @__PURE__ */
|
|
787
|
+
) : /* @__PURE__ */ jsx11(BaseAvatar.Fallback, { render: /* @__PURE__ */ jsx11("div", {}), className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx11(IconUserFilled, { size: Math.round(size * 0.5) }) })
|
|
659
788
|
]
|
|
660
789
|
}
|
|
661
790
|
);
|
|
662
791
|
}
|
|
663
792
|
|
|
664
793
|
// src/AvatarGroup.tsx
|
|
665
|
-
import { jsx as
|
|
794
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
666
795
|
function AvatarGroup({ members, size = 24 }) {
|
|
667
796
|
const visible = members.slice(0, 3);
|
|
668
797
|
const overlap = Math.round(size / 3);
|
|
669
798
|
const ring = size / 12;
|
|
670
|
-
return /* @__PURE__ */
|
|
799
|
+
return /* @__PURE__ */ jsx12("div", { className: "flex items-center", style: { paddingRight: overlap }, children: visible.map((member, i) => (
|
|
671
800
|
/*
|
|
672
801
|
The wrapper carries the overlap and the ring; the face carries
|
|
673
802
|
neither. It must never clip — see the note at the top of the file —
|
|
674
803
|
so it has the avatar's own radius and no overflow of its own.
|
|
675
804
|
*/
|
|
676
|
-
/* @__PURE__ */
|
|
805
|
+
/* @__PURE__ */ jsx12(
|
|
677
806
|
"span",
|
|
678
807
|
{
|
|
679
808
|
className: "relative flex rounded-sm",
|
|
680
809
|
style: { marginRight: -overlap, boxShadow: `0 0 0 ${ring}px var(--bg-surface)` },
|
|
681
|
-
children: /* @__PURE__ */
|
|
810
|
+
children: /* @__PURE__ */ jsx12(Avatar, { size, name: member.name, src: member.picture, label: member.name })
|
|
682
811
|
},
|
|
683
812
|
i
|
|
684
813
|
)
|
|
@@ -686,11 +815,11 @@ function AvatarGroup({ members, size = 24 }) {
|
|
|
686
815
|
}
|
|
687
816
|
|
|
688
817
|
// src/Banner.tsx
|
|
689
|
-
import { IconX as
|
|
818
|
+
import { IconX as IconX3 } from "@tabler/icons-react";
|
|
690
819
|
|
|
691
820
|
// src/Button.tsx
|
|
692
821
|
import { Button as BaseButton3 } from "@base-ui/react/button";
|
|
693
|
-
import { jsx as
|
|
822
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
694
823
|
function Button({
|
|
695
824
|
variant = "muted",
|
|
696
825
|
size = "default",
|
|
@@ -704,7 +833,7 @@ function Button({
|
|
|
704
833
|
}) {
|
|
705
834
|
const hasLeadingIcon = !!leadingIcon;
|
|
706
835
|
const formBusy = useFormBusy();
|
|
707
|
-
const button = /* @__PURE__ */
|
|
836
|
+
const button = /* @__PURE__ */ jsxs8(
|
|
708
837
|
BaseButton3,
|
|
709
838
|
{
|
|
710
839
|
type,
|
|
@@ -751,11 +880,11 @@ function Button({
|
|
|
751
880
|
]
|
|
752
881
|
}
|
|
753
882
|
);
|
|
754
|
-
return disabledReason ? /* @__PURE__ */
|
|
883
|
+
return disabledReason ? /* @__PURE__ */ jsx13(TooltipTrigger, { label: disabledReason, children: button }) : button;
|
|
755
884
|
}
|
|
756
885
|
|
|
757
886
|
// src/Banner.tsx
|
|
758
|
-
import { jsx as
|
|
887
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
759
888
|
var TONE_STYLES = {
|
|
760
889
|
ok: "bg-success-muted text-success-default",
|
|
761
890
|
error: "bg-error-muted text-error-default",
|
|
@@ -765,14 +894,14 @@ var TONE_STYLES = {
|
|
|
765
894
|
function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismiss", className }) {
|
|
766
895
|
const role = tone === "error" ? "alert" : "status";
|
|
767
896
|
if (!onDismiss && !icon && !action) {
|
|
768
|
-
return /* @__PURE__ */
|
|
897
|
+
return /* @__PURE__ */ jsx14("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
|
|
769
898
|
}
|
|
770
899
|
const oneLine = Boolean(icon || action);
|
|
771
|
-
return /* @__PURE__ */
|
|
772
|
-
icon && /* @__PURE__ */
|
|
773
|
-
/* @__PURE__ */
|
|
774
|
-
action && /* @__PURE__ */
|
|
775
|
-
onDismiss && /* @__PURE__ */
|
|
900
|
+
return /* @__PURE__ */ jsxs9("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
|
|
901
|
+
icon && /* @__PURE__ */ jsx14("span", { className: "flex shrink-0", children: icon }),
|
|
902
|
+
/* @__PURE__ */ jsx14("span", { className: cn("min-w-0 flex-1", oneLine && "truncate"), children }),
|
|
903
|
+
action && /* @__PURE__ */ jsx14(Button, { variant: "muted", size: "small", className: "shrink-0", onClick: action.onClick, children: action.label }),
|
|
904
|
+
onDismiss && /* @__PURE__ */ jsx14(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx14(IconX3, { size: 16, stroke: 1.5 }) })
|
|
776
905
|
] });
|
|
777
906
|
}
|
|
778
907
|
|
|
@@ -780,7 +909,7 @@ function Banner({ tone, children, icon, action, onDismiss, dismissLabel = "Dismi
|
|
|
780
909
|
import { Checkbox as BaseCheckbox } from "@base-ui/react/checkbox";
|
|
781
910
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
782
911
|
import { IconCheck } from "@tabler/icons-react";
|
|
783
|
-
import { jsx as
|
|
912
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
784
913
|
function squareClasses(checked, disabled, interactive, className) {
|
|
785
914
|
return cn(
|
|
786
915
|
"inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
|
|
@@ -797,14 +926,14 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
797
926
|
const formBusy = useFormBusy();
|
|
798
927
|
const disabled = ownDisabled || formBusy;
|
|
799
928
|
if (!onChange) {
|
|
800
|
-
const picture = /* @__PURE__ */
|
|
929
|
+
const picture = /* @__PURE__ */ jsx15("span", { "aria-hidden": "true", className: squareClasses(checked, disabled, false, className), children: /* @__PURE__ */ jsx15("span", { className: tickClasses(checked), children: /* @__PURE__ */ jsx15(IconCheck, { size: 12, stroke: 3 }) }) });
|
|
801
930
|
if (label === void 0) return picture;
|
|
802
|
-
return /* @__PURE__ */
|
|
931
|
+
return /* @__PURE__ */ jsxs10("span", { className: "flex items-center gap-2", children: [
|
|
803
932
|
picture,
|
|
804
|
-
/* @__PURE__ */
|
|
933
|
+
/* @__PURE__ */ jsx15("span", { className: WORDS_CLASSES, children: label })
|
|
805
934
|
] });
|
|
806
935
|
}
|
|
807
|
-
const box = /* @__PURE__ */
|
|
936
|
+
const box = /* @__PURE__ */ jsx15(
|
|
808
937
|
BaseCheckbox.Root,
|
|
809
938
|
{
|
|
810
939
|
checked,
|
|
@@ -814,25 +943,25 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
814
943
|
onCheckedChange: (next) => onChange(next),
|
|
815
944
|
onClick: (e) => e.stopPropagation(),
|
|
816
945
|
className: (state) => squareClasses(state.checked, state.disabled, true, className),
|
|
817
|
-
children: /* @__PURE__ */
|
|
946
|
+
children: /* @__PURE__ */ jsx15(BaseCheckbox.Indicator, { keepMounted: true, className: (state) => tickClasses(state.checked), children: /* @__PURE__ */ jsx15(IconCheck, { size: 12, stroke: 3 }) })
|
|
818
947
|
}
|
|
819
948
|
);
|
|
820
949
|
if (label === void 0) return box;
|
|
821
950
|
if (row) {
|
|
822
|
-
return /* @__PURE__ */
|
|
951
|
+
return /* @__PURE__ */ jsx15(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn(ROW_CLASSES, checked && "bg-bg-selected", !disabled && "cursor-pointer hover:bg-bg-hover"), children: [
|
|
823
952
|
leading,
|
|
824
|
-
/* @__PURE__ */
|
|
953
|
+
/* @__PURE__ */ jsx15("span", { className: cn("flex-1 min-w-0 truncate", WORDS_CLASSES), children: label }),
|
|
825
954
|
box
|
|
826
955
|
] }) });
|
|
827
956
|
}
|
|
828
|
-
return /* @__PURE__ */
|
|
957
|
+
return /* @__PURE__ */ jsx15(BaseField.Root, { disabled, children: /* @__PURE__ */ jsxs10(BaseField.Label, { className: cn("flex items-center gap-2", !disabled && "cursor-pointer"), children: [
|
|
829
958
|
box,
|
|
830
|
-
/* @__PURE__ */
|
|
959
|
+
/* @__PURE__ */ jsx15("span", { className: WORDS_CLASSES, children: label })
|
|
831
960
|
] }) });
|
|
832
961
|
}
|
|
833
962
|
|
|
834
963
|
// src/Chip.tsx
|
|
835
|
-
import { jsx as
|
|
964
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
836
965
|
var typeStyles = {
|
|
837
966
|
neutral: "bg-bg-inset text-text-primary",
|
|
838
967
|
brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
|
|
@@ -842,8 +971,8 @@ var typeStyles = {
|
|
|
842
971
|
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
843
972
|
};
|
|
844
973
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
845
|
-
return /* @__PURE__ */
|
|
846
|
-
leadingIcon && /* @__PURE__ */
|
|
974
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className), children: [
|
|
975
|
+
leadingIcon && /* @__PURE__ */ jsx16("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
847
976
|
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
848
977
|
// of growing past it — Ship's project chip on an issue row
|
|
849
978
|
// (2026-09-09). Clipped sideways only: `overflow-x-clip`, not
|
|
@@ -852,8 +981,8 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
852
981
|
// the screenshot diff caught every descender cut off. `clip` is the
|
|
853
982
|
// one overflow that leaves the other axis visible. A chip with no cap
|
|
854
983
|
// draws exactly as before.
|
|
855
|
-
/* @__PURE__ */
|
|
856
|
-
trailingIcon && /* @__PURE__ */
|
|
984
|
+
/* @__PURE__ */ jsx16("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-small signal:font-semibold signal:tracking-wide signal:tabular-nums", children: label }),
|
|
985
|
+
trailingIcon && /* @__PURE__ */ jsx16("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
857
986
|
] });
|
|
858
987
|
}
|
|
859
988
|
|
|
@@ -861,13 +990,13 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
861
990
|
import {
|
|
862
991
|
createContext as createContext4,
|
|
863
992
|
useContext as useContext4,
|
|
864
|
-
useEffect,
|
|
993
|
+
useEffect as useEffect2,
|
|
865
994
|
useLayoutEffect as useLayoutEffect3,
|
|
866
995
|
useMemo as useMemo2,
|
|
867
|
-
useRef as
|
|
996
|
+
useRef as useRef4,
|
|
868
997
|
useState as useState3
|
|
869
998
|
} from "react";
|
|
870
|
-
import { Dialog } from "@base-ui/react/dialog";
|
|
999
|
+
import { Dialog as Dialog2 } from "@base-ui/react/dialog";
|
|
871
1000
|
import { Autocomplete } from "@base-ui/react/autocomplete";
|
|
872
1001
|
import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
|
|
873
1002
|
|
|
@@ -875,7 +1004,7 @@ import { IconLoader2 as IconLoader22, IconSearch } from "@tabler/icons-react";
|
|
|
875
1004
|
import { useMemo, useState as useState2 } from "react";
|
|
876
1005
|
import { Button as BaseButton4 } from "@base-ui/react/button";
|
|
877
1006
|
import { Combobox } from "@base-ui/react/combobox";
|
|
878
|
-
import { IconX as
|
|
1007
|
+
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
879
1008
|
|
|
880
1009
|
// src/Menu.tsx
|
|
881
1010
|
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
@@ -885,27 +1014,27 @@ import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
|
885
1014
|
// src/Divider.tsx
|
|
886
1015
|
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
887
1016
|
import { Separator } from "@base-ui/react/separator";
|
|
888
|
-
import { jsx as
|
|
1017
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
889
1018
|
var DividerInPanel = createContext2(false);
|
|
890
1019
|
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
891
1020
|
const inset = useContext2(DividerInPanel) ? "mx-0" : "mx-3";
|
|
892
1021
|
if (label && orientation === "horizontal") {
|
|
893
1022
|
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
894
|
-
return /* @__PURE__ */
|
|
1023
|
+
return /* @__PURE__ */ jsxs12(
|
|
895
1024
|
Separator,
|
|
896
1025
|
{
|
|
897
1026
|
orientation: "horizontal",
|
|
898
1027
|
"aria-label": label,
|
|
899
1028
|
className: cn("flex shrink-0 items-center gap-2", inset, className),
|
|
900
1029
|
children: [
|
|
901
|
-
/* @__PURE__ */
|
|
902
|
-
/* @__PURE__ */
|
|
903
|
-
/* @__PURE__ */
|
|
1030
|
+
/* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
1031
|
+
/* @__PURE__ */ jsx17("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
1032
|
+
/* @__PURE__ */ jsx17("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
904
1033
|
]
|
|
905
1034
|
}
|
|
906
1035
|
);
|
|
907
1036
|
}
|
|
908
|
-
return /* @__PURE__ */
|
|
1037
|
+
return /* @__PURE__ */ jsx17(
|
|
909
1038
|
Separator,
|
|
910
1039
|
{
|
|
911
1040
|
orientation,
|
|
@@ -921,9 +1050,9 @@ function triggerDisabled(trigger) {
|
|
|
921
1050
|
}
|
|
922
1051
|
|
|
923
1052
|
// src/SectionLabel.tsx
|
|
924
|
-
import { jsx as
|
|
1053
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
925
1054
|
function SectionLabel({ children, tone = "primary", className }) {
|
|
926
|
-
return /* @__PURE__ */
|
|
1055
|
+
return /* @__PURE__ */ jsx18(
|
|
927
1056
|
"span",
|
|
928
1057
|
{
|
|
929
1058
|
className: cn(
|
|
@@ -937,10 +1066,10 @@ function SectionLabel({ children, tone = "primary", className }) {
|
|
|
937
1066
|
}
|
|
938
1067
|
|
|
939
1068
|
// src/Menu.tsx
|
|
940
|
-
import { Fragment as Fragment2, jsx as
|
|
1069
|
+
import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
941
1070
|
var MenuContext = createContext3(null);
|
|
942
1071
|
function MenuPanel({ children, className, ...props }) {
|
|
943
|
-
return /* @__PURE__ */
|
|
1072
|
+
return /* @__PURE__ */ jsx19(
|
|
944
1073
|
"div",
|
|
945
1074
|
{
|
|
946
1075
|
className: cn(
|
|
@@ -970,7 +1099,7 @@ var VIEWPORT_PAD2 = 8;
|
|
|
970
1099
|
var HOVER_OPEN_DELAY = 0;
|
|
971
1100
|
var HOVER_CLOSE_DELAY = 150;
|
|
972
1101
|
function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
|
|
973
|
-
return /* @__PURE__ */
|
|
1102
|
+
return /* @__PURE__ */ jsxs13(
|
|
974
1103
|
BaseMenu.Root,
|
|
975
1104
|
{
|
|
976
1105
|
open,
|
|
@@ -978,7 +1107,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
978
1107
|
actionsRef,
|
|
979
1108
|
modal: false,
|
|
980
1109
|
children: [
|
|
981
|
-
/* @__PURE__ */
|
|
1110
|
+
/* @__PURE__ */ jsx19(
|
|
982
1111
|
BaseMenu.Trigger,
|
|
983
1112
|
{
|
|
984
1113
|
render: trigger,
|
|
@@ -988,7 +1117,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
988
1117
|
closeDelay: HOVER_CLOSE_DELAY
|
|
989
1118
|
}
|
|
990
1119
|
),
|
|
991
|
-
/* @__PURE__ */
|
|
1120
|
+
/* @__PURE__ */ jsx19(BaseMenu.Portal, { children: /* @__PURE__ */ jsx19(
|
|
992
1121
|
BaseMenu.Positioner,
|
|
993
1122
|
{
|
|
994
1123
|
side: "bottom",
|
|
@@ -996,13 +1125,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
996
1125
|
sideOffset: GAP2,
|
|
997
1126
|
collisionPadding: VIEWPORT_PAD2,
|
|
998
1127
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
999
|
-
children: /* @__PURE__ */
|
|
1128
|
+
children: /* @__PURE__ */ jsx19(
|
|
1000
1129
|
BaseMenu.Popup,
|
|
1001
1130
|
{
|
|
1002
1131
|
"data-interactive": true,
|
|
1003
1132
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
1004
|
-
render: /* @__PURE__ */
|
|
1005
|
-
children: /* @__PURE__ */
|
|
1133
|
+
render: /* @__PURE__ */ jsx19(MenuPanel, {}),
|
|
1134
|
+
children: /* @__PURE__ */ jsx19(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx19(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx19(DividerInPanel.Provider, { value: true, children }) }) })
|
|
1006
1135
|
}
|
|
1007
1136
|
)
|
|
1008
1137
|
}
|
|
@@ -1018,20 +1147,20 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
1018
1147
|
'[@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".'
|
|
1019
1148
|
);
|
|
1020
1149
|
}
|
|
1021
|
-
return /* @__PURE__ */
|
|
1022
|
-
/* @__PURE__ */
|
|
1150
|
+
return /* @__PURE__ */ jsxs13(BaseMenu.SubmenuRoot, { children: [
|
|
1151
|
+
/* @__PURE__ */ jsx19(
|
|
1023
1152
|
BaseMenu.SubmenuTrigger,
|
|
1024
1153
|
{
|
|
1025
1154
|
openOnHover: true,
|
|
1026
1155
|
delay: 0,
|
|
1027
1156
|
closeDelay: 150,
|
|
1028
1157
|
nativeButton: true,
|
|
1029
|
-
render: /* @__PURE__ */
|
|
1158
|
+
render: /* @__PURE__ */ jsx19("button", { type: "button" }),
|
|
1030
1159
|
className: menuItemClassName({ size: "default", selected }),
|
|
1031
|
-
children: /* @__PURE__ */
|
|
1160
|
+
children: /* @__PURE__ */ jsx19(MenuItemBody, { label, leading, submenu: true })
|
|
1032
1161
|
}
|
|
1033
1162
|
),
|
|
1034
|
-
/* @__PURE__ */
|
|
1163
|
+
/* @__PURE__ */ jsx19(BaseMenu.Portal, { children: /* @__PURE__ */ jsx19(
|
|
1035
1164
|
BaseMenu.Positioner,
|
|
1036
1165
|
{
|
|
1037
1166
|
side: "inline-end",
|
|
@@ -1039,7 +1168,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
1039
1168
|
sideOffset: GAP2,
|
|
1040
1169
|
collisionPadding: VIEWPORT_PAD2,
|
|
1041
1170
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1042
|
-
children: /* @__PURE__ */
|
|
1171
|
+
children: /* @__PURE__ */ jsx19(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx19(MenuPanel, {}), children })
|
|
1043
1172
|
}
|
|
1044
1173
|
) })
|
|
1045
1174
|
] });
|
|
@@ -1074,25 +1203,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
1074
1203
|
);
|
|
1075
1204
|
}
|
|
1076
1205
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
1077
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
1078
|
-
return /* @__PURE__ */
|
|
1079
|
-
leading && /* @__PURE__ */
|
|
1080
|
-
children ?? /* @__PURE__ */
|
|
1081
|
-
/* @__PURE__ */
|
|
1082
|
-
description && /* @__PURE__ */
|
|
1206
|
+
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx19(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx19(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
1207
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
1208
|
+
leading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1209
|
+
children ?? /* @__PURE__ */ jsxs13("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
1210
|
+
/* @__PURE__ */ jsx19("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
1211
|
+
description && /* @__PURE__ */ jsx19("span", { className: "truncate text-caption text-text-secondary", children: description })
|
|
1083
1212
|
] }),
|
|
1084
1213
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
1085
1214
|
// the wider of the two and never changes, so revealing the hint moves
|
|
1086
1215
|
// nothing. No transition here either — the hint switches on the same
|
|
1087
1216
|
// :hover / `selected` as the fill, in the same frame.
|
|
1088
|
-
/* @__PURE__ */
|
|
1089
|
-
edge && /* @__PURE__ */
|
|
1090
|
-
hint && /* @__PURE__ */
|
|
1217
|
+
/* @__PURE__ */ jsxs13("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
1218
|
+
edge && /* @__PURE__ */ jsx19("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
1219
|
+
hint && /* @__PURE__ */ jsx19("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
1091
1220
|
] })
|
|
1092
1221
|
] });
|
|
1093
1222
|
}
|
|
1094
1223
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
1095
|
-
const body = /* @__PURE__ */
|
|
1224
|
+
const body = /* @__PURE__ */ jsx19(
|
|
1096
1225
|
MenuItemBody,
|
|
1097
1226
|
{
|
|
1098
1227
|
label,
|
|
@@ -1110,13 +1239,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1110
1239
|
);
|
|
1111
1240
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
1112
1241
|
if (!useContext3(MenuContext)) {
|
|
1113
|
-
return /* @__PURE__ */
|
|
1242
|
+
return /* @__PURE__ */ jsx19("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
1114
1243
|
}
|
|
1115
|
-
return /* @__PURE__ */
|
|
1244
|
+
return /* @__PURE__ */ jsx19(
|
|
1116
1245
|
BaseMenu.Item,
|
|
1117
1246
|
{
|
|
1118
1247
|
nativeButton: true,
|
|
1119
|
-
render: /* @__PURE__ */
|
|
1248
|
+
render: /* @__PURE__ */ jsx19("button", { type: "button" }),
|
|
1120
1249
|
className: rowClassName,
|
|
1121
1250
|
...props,
|
|
1122
1251
|
children: body
|
|
@@ -1124,34 +1253,34 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1124
1253
|
);
|
|
1125
1254
|
}
|
|
1126
1255
|
function EnterHint({ target }) {
|
|
1127
|
-
return /* @__PURE__ */
|
|
1128
|
-
/* @__PURE__ */
|
|
1129
|
-
target && /* @__PURE__ */
|
|
1256
|
+
return /* @__PURE__ */ jsxs13("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
1257
|
+
/* @__PURE__ */ jsx19(Kbd, { children: "\u21A9 Enter" }),
|
|
1258
|
+
target && /* @__PURE__ */ jsx19("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider", children: target })
|
|
1130
1259
|
] });
|
|
1131
1260
|
}
|
|
1132
1261
|
function MenuSection({ label, children, className }) {
|
|
1133
1262
|
const inMenu = useContext3(MenuContext) !== null;
|
|
1134
|
-
const heading = /* @__PURE__ */
|
|
1263
|
+
const heading = /* @__PURE__ */ jsx19("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx19(SectionLabel, { tone: "secondary", children: label }) });
|
|
1135
1264
|
if (!inMenu) {
|
|
1136
|
-
return /* @__PURE__ */
|
|
1265
|
+
return /* @__PURE__ */ jsxs13("div", { className: "flex flex-col", children: [
|
|
1137
1266
|
heading,
|
|
1138
1267
|
children
|
|
1139
1268
|
] });
|
|
1140
1269
|
}
|
|
1141
|
-
return /* @__PURE__ */
|
|
1142
|
-
/* @__PURE__ */
|
|
1270
|
+
return /* @__PURE__ */ jsxs13(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1271
|
+
/* @__PURE__ */ jsx19(BaseMenu.GroupLabel, { render: heading }),
|
|
1143
1272
|
children
|
|
1144
1273
|
] });
|
|
1145
1274
|
}
|
|
1146
1275
|
function MenuSeparator() {
|
|
1147
|
-
return /* @__PURE__ */
|
|
1276
|
+
return /* @__PURE__ */ jsx19(Divider, { className: "my-1" });
|
|
1148
1277
|
}
|
|
1149
1278
|
function MenuRow({ children, className }) {
|
|
1150
|
-
return /* @__PURE__ */
|
|
1279
|
+
return /* @__PURE__ */ jsx19("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
1151
1280
|
}
|
|
1152
1281
|
|
|
1153
1282
|
// src/ChipInput.tsx
|
|
1154
|
-
import { jsx as
|
|
1283
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1155
1284
|
var CHIP_BOX = (
|
|
1156
1285
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
1157
1286
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -1162,10 +1291,10 @@ var CHIP_LABEL = "text-caption font-medium text-text-primary";
|
|
|
1162
1291
|
var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
|
|
1163
1292
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
1164
1293
|
function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
|
|
1165
|
-
return /* @__PURE__ */
|
|
1166
|
-
leading && /* @__PURE__ */
|
|
1167
|
-
/* @__PURE__ */
|
|
1168
|
-
onRemove && /* @__PURE__ */
|
|
1294
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1295
|
+
leading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1296
|
+
/* @__PURE__ */ jsx20("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
|
|
1297
|
+
onRemove && /* @__PURE__ */ jsx20(
|
|
1169
1298
|
BaseButton4,
|
|
1170
1299
|
{
|
|
1171
1300
|
type: "button",
|
|
@@ -1175,7 +1304,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
|
|
|
1175
1304
|
},
|
|
1176
1305
|
className: cn(CHIP_REMOVE, truncate && "shrink-0"),
|
|
1177
1306
|
"aria-label": removeLabel ?? `Remove ${label}`,
|
|
1178
|
-
children: /* @__PURE__ */
|
|
1307
|
+
children: /* @__PURE__ */ jsx20(IconX4, { size: 10, stroke: 1.5 })
|
|
1179
1308
|
}
|
|
1180
1309
|
)
|
|
1181
1310
|
] });
|
|
@@ -1228,7 +1357,7 @@ function ChipInput({
|
|
|
1228
1357
|
setQuery("");
|
|
1229
1358
|
}
|
|
1230
1359
|
}
|
|
1231
|
-
return /* @__PURE__ */
|
|
1360
|
+
return /* @__PURE__ */ jsxs14(
|
|
1232
1361
|
Combobox.Root,
|
|
1233
1362
|
{
|
|
1234
1363
|
multiple: true,
|
|
@@ -1245,13 +1374,13 @@ function ChipInput({
|
|
|
1245
1374
|
filter,
|
|
1246
1375
|
itemToStringLabel: (option) => option.label,
|
|
1247
1376
|
children: [
|
|
1248
|
-
/* @__PURE__ */
|
|
1249
|
-
value.map((option) => /* @__PURE__ */
|
|
1250
|
-
chipLeading && /* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1377
|
+
/* @__PURE__ */ jsxs14(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: [
|
|
1378
|
+
value.map((option) => /* @__PURE__ */ jsxs14(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1379
|
+
chipLeading && /* @__PURE__ */ jsx20("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
|
|
1380
|
+
/* @__PURE__ */ jsx20("span", { className: CHIP_LABEL, children: option.label }),
|
|
1381
|
+
/* @__PURE__ */ jsx20(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx20(IconX4, { size: 10, stroke: 1.5 }) })
|
|
1253
1382
|
] }, option.id)),
|
|
1254
|
-
/* @__PURE__ */
|
|
1383
|
+
/* @__PURE__ */ jsx20(
|
|
1255
1384
|
Combobox.Input,
|
|
1256
1385
|
{
|
|
1257
1386
|
autoFocus,
|
|
@@ -1263,18 +1392,18 @@ function ChipInput({
|
|
|
1263
1392
|
}
|
|
1264
1393
|
)
|
|
1265
1394
|
] }),
|
|
1266
|
-
/* @__PURE__ */
|
|
1395
|
+
/* @__PURE__ */ jsx20(Combobox.Portal, { children: /* @__PURE__ */ jsx20(
|
|
1267
1396
|
Combobox.Positioner,
|
|
1268
1397
|
{
|
|
1269
1398
|
anchor: box,
|
|
1270
1399
|
sideOffset: GAP3,
|
|
1271
1400
|
collisionPadding: VIEWPORT_PAD3,
|
|
1272
1401
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1273
|
-
children: /* @__PURE__ */
|
|
1402
|
+
children: /* @__PURE__ */ jsx20(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx20(MenuPanel, {}), children: /* @__PURE__ */ jsx20(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx20(Combobox.List, { children: (option) => /* @__PURE__ */ jsx20(
|
|
1274
1403
|
Combobox.Item,
|
|
1275
1404
|
{
|
|
1276
1405
|
value: option,
|
|
1277
|
-
render: /* @__PURE__ */
|
|
1406
|
+
render: /* @__PURE__ */ jsx20(
|
|
1278
1407
|
MenuItem,
|
|
1279
1408
|
{
|
|
1280
1409
|
size: "tall",
|
|
@@ -1297,22 +1426,22 @@ var VIEWPORT_PAD3 = 8;
|
|
|
1297
1426
|
|
|
1298
1427
|
// src/EmptyState.tsx
|
|
1299
1428
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1300
|
-
import { jsx as
|
|
1429
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1301
1430
|
function EmptyState({ icon, message, scope = "page", action, className }) {
|
|
1302
1431
|
if (scope === "section") {
|
|
1303
|
-
return /* @__PURE__ */
|
|
1432
|
+
return /* @__PURE__ */ jsx21("p", { className: cn("text-caption text-text-muted", className), children: message });
|
|
1304
1433
|
}
|
|
1305
|
-
return /* @__PURE__ */
|
|
1306
|
-
/* @__PURE__ */
|
|
1307
|
-
/* @__PURE__ */
|
|
1308
|
-
action && /* @__PURE__ */
|
|
1434
|
+
return /* @__PURE__ */ jsxs15("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1435
|
+
/* @__PURE__ */ jsx21("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx21(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1436
|
+
/* @__PURE__ */ jsx21("p", { className: "text-body-2 text-text-secondary text-center", children: message }),
|
|
1437
|
+
action && /* @__PURE__ */ jsx21(Button, { variant: "outlined", className: "mt-2", onClick: action.onClick, children: action.label })
|
|
1309
1438
|
] });
|
|
1310
1439
|
}
|
|
1311
1440
|
|
|
1312
1441
|
// src/Field.tsx
|
|
1313
1442
|
import { cloneElement, isValidElement } from "react";
|
|
1314
1443
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1315
|
-
import { jsx as
|
|
1444
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1316
1445
|
var LINE_STYLES = {
|
|
1317
1446
|
helper: "text-caption text-text-muted",
|
|
1318
1447
|
warning: "text-caption text-warning-default",
|
|
@@ -1322,26 +1451,26 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1322
1451
|
const control = required && isValidElement(children) ? cloneElement(children, {
|
|
1323
1452
|
"aria-required": children.props["aria-required"] ?? true
|
|
1324
1453
|
}) : children;
|
|
1325
|
-
return /* @__PURE__ */
|
|
1326
|
-
/* @__PURE__ */
|
|
1454
|
+
return /* @__PURE__ */ jsxs16(BaseField2.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1455
|
+
/* @__PURE__ */ jsxs16(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1327
1456
|
label,
|
|
1328
|
-
required && /* @__PURE__ */
|
|
1457
|
+
required && /* @__PURE__ */ jsx22("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1329
1458
|
] }),
|
|
1330
|
-
/* @__PURE__ */
|
|
1459
|
+
/* @__PURE__ */ jsxs16("div", { className: "flex flex-col gap-1.5", children: [
|
|
1331
1460
|
control,
|
|
1332
|
-
error != null ? /* @__PURE__ */
|
|
1461
|
+
error != null ? /* @__PURE__ */ jsx22(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx22(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
|
|
1333
1462
|
] })
|
|
1334
1463
|
] });
|
|
1335
1464
|
}
|
|
1336
1465
|
function FieldLine({ tone = "helper", children, className }) {
|
|
1337
|
-
return /* @__PURE__ */
|
|
1466
|
+
return /* @__PURE__ */ jsx22("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
|
|
1338
1467
|
}
|
|
1339
1468
|
|
|
1340
1469
|
// src/Form.tsx
|
|
1341
|
-
import { useLayoutEffect as useLayoutEffect2, useRef as
|
|
1470
|
+
import { useLayoutEffect as useLayoutEffect2, useRef as useRef3 } from "react";
|
|
1342
1471
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
1343
1472
|
import { Form as BaseForm } from "@base-ui/react/form";
|
|
1344
|
-
import { jsx as
|
|
1473
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1345
1474
|
var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
|
|
1346
1475
|
var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1347
1476
|
function usable(element) {
|
|
@@ -1358,12 +1487,12 @@ function firstInvalid(form) {
|
|
|
1358
1487
|
function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, children, ...props }) {
|
|
1359
1488
|
const outerBusy = useFormBusy();
|
|
1360
1489
|
const busy = ownBusy || outerBusy;
|
|
1361
|
-
const form =
|
|
1362
|
-
const busyNow =
|
|
1490
|
+
const form = useRef3(null);
|
|
1491
|
+
const busyNow = useRef3(busy);
|
|
1363
1492
|
busyNow.current = busy;
|
|
1364
|
-
const sender =
|
|
1365
|
-
const holding =
|
|
1366
|
-
const lastInside =
|
|
1493
|
+
const sender = useRef3(null);
|
|
1494
|
+
const holding = useRef3(false);
|
|
1495
|
+
const lastInside = useRef3(null);
|
|
1367
1496
|
useLayoutEffect2(() => {
|
|
1368
1497
|
const element = form.current;
|
|
1369
1498
|
if (!element) return;
|
|
@@ -1400,7 +1529,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1400
1529
|
const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
|
|
1401
1530
|
if (enterSends && oneLine) form.current?.requestSubmit();
|
|
1402
1531
|
};
|
|
1403
|
-
return /* @__PURE__ */
|
|
1532
|
+
return /* @__PURE__ */ jsx23(
|
|
1404
1533
|
BaseForm,
|
|
1405
1534
|
{
|
|
1406
1535
|
ref: form,
|
|
@@ -1423,29 +1552,29 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1423
1552
|
if (busyNow.current) return;
|
|
1424
1553
|
void onSubmit();
|
|
1425
1554
|
},
|
|
1426
|
-
children: /* @__PURE__ */
|
|
1555
|
+
children: /* @__PURE__ */ jsx23(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx23(FormBusyContext.Provider, { value: busy, children }) })
|
|
1427
1556
|
}
|
|
1428
1557
|
);
|
|
1429
1558
|
}
|
|
1430
1559
|
|
|
1431
1560
|
// src/Skeleton.tsx
|
|
1432
|
-
import { jsx as
|
|
1561
|
+
import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1433
1562
|
function SkeletonBar({ className, style }) {
|
|
1434
|
-
return /* @__PURE__ */
|
|
1563
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1435
1564
|
}
|
|
1436
1565
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1437
1566
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1438
|
-
return /* @__PURE__ */
|
|
1439
|
-
/* @__PURE__ */
|
|
1440
|
-
/* @__PURE__ */
|
|
1567
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1568
|
+
/* @__PURE__ */ jsx24(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1569
|
+
/* @__PURE__ */ jsx24(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1441
1570
|
] });
|
|
1442
1571
|
}
|
|
1443
1572
|
function SkeletonList({ rows = 8, className }) {
|
|
1444
|
-
return /* @__PURE__ */
|
|
1573
|
+
return /* @__PURE__ */ jsx24("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx24(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
|
|
1445
1574
|
}
|
|
1446
1575
|
|
|
1447
1576
|
// src/CommandPalette.tsx
|
|
1448
|
-
import { Fragment as Fragment3, jsx as
|
|
1577
|
+
import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1449
1578
|
var PaletteContext = createContext4(null);
|
|
1450
1579
|
function usePalette(part) {
|
|
1451
1580
|
const palette = useContext4(PaletteContext);
|
|
@@ -1460,8 +1589,8 @@ function firstControl(popup) {
|
|
|
1460
1589
|
return popup.querySelector("[data-command-palette-fields]")?.querySelector(CONTROL2) ?? null;
|
|
1461
1590
|
}
|
|
1462
1591
|
function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", children }) {
|
|
1463
|
-
const popupRef =
|
|
1464
|
-
|
|
1592
|
+
const popupRef = useRef4(null);
|
|
1593
|
+
useEffect2(() => {
|
|
1465
1594
|
if (!open) return;
|
|
1466
1595
|
const frame = requestAnimationFrame(() => {
|
|
1467
1596
|
const popup = popupRef.current;
|
|
@@ -1471,10 +1600,10 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1471
1600
|
return () => cancelAnimationFrame(frame);
|
|
1472
1601
|
});
|
|
1473
1602
|
const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
|
|
1474
|
-
return /* @__PURE__ */
|
|
1475
|
-
/* @__PURE__ */
|
|
1476
|
-
/* @__PURE__ */
|
|
1477
|
-
|
|
1603
|
+
return /* @__PURE__ */ jsx25(Dialog2.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs18(Dialog2.Portal, { children: [
|
|
1604
|
+
/* @__PURE__ */ jsx25(Dialog2.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1605
|
+
/* @__PURE__ */ jsx25(Dialog2.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx25(
|
|
1606
|
+
Dialog2.Popup,
|
|
1478
1607
|
{
|
|
1479
1608
|
ref: popupRef,
|
|
1480
1609
|
"aria-label": label,
|
|
@@ -1483,13 +1612,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1483
1612
|
if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
|
|
1484
1613
|
},
|
|
1485
1614
|
className: "flex w-[658px] max-w-[calc(100vw-32px)] flex-col overflow-hidden rounded-lg border border-border-default bg-bg-elevated shadow-lg outline-none",
|
|
1486
|
-
children: /* @__PURE__ */
|
|
1615
|
+
children: /* @__PURE__ */ jsx25(PaletteContext.Provider, { value: context, children })
|
|
1487
1616
|
}
|
|
1488
1617
|
) })
|
|
1489
1618
|
] }) });
|
|
1490
1619
|
}
|
|
1491
1620
|
function LevelChip({ chip, onBack }) {
|
|
1492
|
-
return /* @__PURE__ */
|
|
1621
|
+
return /* @__PURE__ */ jsx25(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
|
|
1493
1622
|
}
|
|
1494
1623
|
function useBack(chip, popupRef) {
|
|
1495
1624
|
return () => {
|
|
@@ -1500,10 +1629,10 @@ function useBack(chip, popupRef) {
|
|
|
1500
1629
|
}
|
|
1501
1630
|
function Footer({ keys }) {
|
|
1502
1631
|
const { where } = usePalette("The footer");
|
|
1503
|
-
return /* @__PURE__ */
|
|
1504
|
-
/* @__PURE__ */
|
|
1505
|
-
keys.map(([key, word]) => /* @__PURE__ */
|
|
1506
|
-
/* @__PURE__ */
|
|
1632
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted", children: [
|
|
1633
|
+
/* @__PURE__ */ jsx25("span", { className: "min-w-0 flex-1 truncate", children: where }),
|
|
1634
|
+
keys.map(([key, word]) => /* @__PURE__ */ jsxs18("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
1635
|
+
/* @__PURE__ */ jsx25(Kbd, { children: key }),
|
|
1507
1636
|
" ",
|
|
1508
1637
|
word
|
|
1509
1638
|
] }, key))
|
|
@@ -1517,10 +1646,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1517
1646
|
const rows = items.flatMap((g) => g.items);
|
|
1518
1647
|
const [litId, setLitId] = useState3();
|
|
1519
1648
|
const lit = litId === void 0 ? void 0 : rows.find((r) => r.id === litId);
|
|
1520
|
-
const inputRef =
|
|
1521
|
-
const reported =
|
|
1522
|
-
const settled =
|
|
1523
|
-
const moved =
|
|
1649
|
+
const inputRef = useRef4(null);
|
|
1650
|
+
const reported = useRef4({});
|
|
1651
|
+
const settled = useRef4(null);
|
|
1652
|
+
const moved = useRef4(false);
|
|
1524
1653
|
useLayoutEffect3(() => {
|
|
1525
1654
|
const before = settled.current;
|
|
1526
1655
|
const now = reported.current;
|
|
@@ -1580,7 +1709,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1580
1709
|
...chip && query === "" ? [["Backspace", "back"]] : [],
|
|
1581
1710
|
["Esc", "close"]
|
|
1582
1711
|
];
|
|
1583
|
-
return /* @__PURE__ */
|
|
1712
|
+
return /* @__PURE__ */ jsxs18(
|
|
1584
1713
|
Autocomplete.Root,
|
|
1585
1714
|
{
|
|
1586
1715
|
items,
|
|
@@ -1603,10 +1732,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1603
1732
|
setLitId(id);
|
|
1604
1733
|
},
|
|
1605
1734
|
children: [
|
|
1606
|
-
/* @__PURE__ */
|
|
1607
|
-
/* @__PURE__ */
|
|
1608
|
-
chip && /* @__PURE__ */
|
|
1609
|
-
/* @__PURE__ */
|
|
1735
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1736
|
+
/* @__PURE__ */ jsx25(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
|
|
1737
|
+
chip && /* @__PURE__ */ jsx25(LevelChip, { chip, onBack: back }),
|
|
1738
|
+
/* @__PURE__ */ jsx25(
|
|
1610
1739
|
Autocomplete.Input,
|
|
1611
1740
|
{
|
|
1612
1741
|
ref: inputRef,
|
|
@@ -1618,43 +1747,43 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1618
1747
|
}
|
|
1619
1748
|
)
|
|
1620
1749
|
] }),
|
|
1621
|
-
/* @__PURE__ */
|
|
1622
|
-
children != null && /* @__PURE__ */
|
|
1623
|
-
/* @__PURE__ */
|
|
1624
|
-
/* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1750
|
+
/* @__PURE__ */ jsxs18(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
|
|
1751
|
+
children != null && /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
|
|
1752
|
+
/* @__PURE__ */ jsx25(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs18(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
|
|
1753
|
+
/* @__PURE__ */ jsx25(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx25(SectionLabel, { tone: "secondary", children: group.value }) }),
|
|
1754
|
+
/* @__PURE__ */ jsx25(Autocomplete.Collection, { children: (row) => (
|
|
1626
1755
|
/* The menu row, as the list's own option — the way Select
|
|
1627
1756
|
puts it on `Select.Item`. One row, two parts. */
|
|
1628
|
-
/* @__PURE__ */
|
|
1757
|
+
/* @__PURE__ */ jsx25(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx25(
|
|
1629
1758
|
MenuItemBody,
|
|
1630
1759
|
{
|
|
1631
1760
|
size: "tall",
|
|
1632
1761
|
label: row.label,
|
|
1633
1762
|
description: row.description,
|
|
1634
|
-
leading: /* @__PURE__ */
|
|
1763
|
+
leading: /* @__PURE__ */ jsx25(RowLeading, { row }),
|
|
1635
1764
|
submenu: !!row.onGoIn,
|
|
1636
|
-
hint: row.onGoIn ? /* @__PURE__ */
|
|
1765
|
+
hint: row.onGoIn ? /* @__PURE__ */ jsx25(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx25(EnterHint, {})
|
|
1637
1766
|
}
|
|
1638
1767
|
) }, row.id)
|
|
1639
1768
|
) })
|
|
1640
1769
|
] }, group.value) }),
|
|
1641
|
-
/* @__PURE__ */
|
|
1642
|
-
/* @__PURE__ */
|
|
1643
|
-
/* @__PURE__ */
|
|
1770
|
+
/* @__PURE__ */ jsx25(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs18(Fragment3, { children: [
|
|
1771
|
+
/* @__PURE__ */ jsx25(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
|
|
1772
|
+
/* @__PURE__ */ jsx25("span", { className: "text-caption text-text-muted", children: pending })
|
|
1644
1773
|
] }) }),
|
|
1645
|
-
notes.map((note) => /* @__PURE__ */
|
|
1646
|
-
/* @__PURE__ */
|
|
1774
|
+
notes.map((note) => /* @__PURE__ */ jsx25("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx25(FieldLine, { children: note }) }, note)),
|
|
1775
|
+
/* @__PURE__ */ jsx25(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx25(EmptyState, { scope: "section", message: empty }) })
|
|
1647
1776
|
] }),
|
|
1648
|
-
/* @__PURE__ */
|
|
1777
|
+
/* @__PURE__ */ jsx25(Footer, { keys })
|
|
1649
1778
|
]
|
|
1650
1779
|
}
|
|
1651
1780
|
);
|
|
1652
1781
|
}
|
|
1653
1782
|
function RowLeading({ row }) {
|
|
1654
1783
|
if (row.icon != null) {
|
|
1655
|
-
return /* @__PURE__ */
|
|
1784
|
+
return /* @__PURE__ */ jsx25("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
|
|
1656
1785
|
}
|
|
1657
|
-
return /* @__PURE__ */
|
|
1786
|
+
return /* @__PURE__ */ jsx25("span", { className: "flex size-8 items-center justify-center", children: row.leading });
|
|
1658
1787
|
}
|
|
1659
1788
|
var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1660
1789
|
function isTextField(el) {
|
|
@@ -1664,9 +1793,9 @@ function isTextField(el) {
|
|
|
1664
1793
|
function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, working, error, children }) {
|
|
1665
1794
|
const { modKey, popupRef } = usePalette("CommandPaletteForm");
|
|
1666
1795
|
const back = useBack(chip, popupRef);
|
|
1667
|
-
const frameRef =
|
|
1796
|
+
const frameRef = useRef4(null);
|
|
1668
1797
|
const busy = !!working;
|
|
1669
|
-
const busyRef =
|
|
1798
|
+
const busyRef = useRef4(busy);
|
|
1670
1799
|
busyRef.current = busy;
|
|
1671
1800
|
const firstInvalid2 = () => frameRef.current?.querySelector("[data-invalid]")?.querySelector(CONTROL2) ?? null;
|
|
1672
1801
|
const submit = () => {
|
|
@@ -1696,56 +1825,56 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
|
|
|
1696
1825
|
...backNamed ? [["Backspace", "back"]] : [],
|
|
1697
1826
|
["Esc", "close"]
|
|
1698
1827
|
];
|
|
1699
|
-
return /* @__PURE__ */
|
|
1700
|
-
/* @__PURE__ */
|
|
1701
|
-
icon != null && /* @__PURE__ */
|
|
1702
|
-
/* @__PURE__ */
|
|
1828
|
+
return /* @__PURE__ */ jsxs18("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
|
|
1829
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1830
|
+
icon != null && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
|
|
1831
|
+
/* @__PURE__ */ jsx25(LevelChip, { chip, onBack: back })
|
|
1703
1832
|
] }),
|
|
1704
|
-
/* @__PURE__ */
|
|
1705
|
-
/* @__PURE__ */
|
|
1706
|
-
/* @__PURE__ */
|
|
1707
|
-
/* @__PURE__ */
|
|
1708
|
-
/* @__PURE__ */
|
|
1833
|
+
/* @__PURE__ */ jsxs18(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, className: "flex min-h-0 flex-col", children: [
|
|
1834
|
+
/* @__PURE__ */ jsx25(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx25("div", { className: "flex flex-col gap-4", children }) }),
|
|
1835
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
|
|
1836
|
+
/* @__PURE__ */ jsx25("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx25(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx25(FieldLine, { tone: "error", children: error }) : null }),
|
|
1837
|
+
/* @__PURE__ */ jsx25(
|
|
1709
1838
|
Button,
|
|
1710
1839
|
{
|
|
1711
1840
|
type: "submit",
|
|
1712
1841
|
variant: "primary",
|
|
1713
1842
|
disabled: busy,
|
|
1714
1843
|
disabledReason: busy ? void 0 : submitWaits,
|
|
1715
|
-
leadingIcon: busy ? /* @__PURE__ */
|
|
1844
|
+
leadingIcon: busy ? /* @__PURE__ */ jsx25(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
|
|
1716
1845
|
children: working ? working.button : submitLabel
|
|
1717
1846
|
}
|
|
1718
1847
|
)
|
|
1719
1848
|
] })
|
|
1720
1849
|
] }),
|
|
1721
|
-
/* @__PURE__ */
|
|
1850
|
+
/* @__PURE__ */ jsx25(Footer, { keys })
|
|
1722
1851
|
] });
|
|
1723
1852
|
}
|
|
1724
1853
|
var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
|
|
1725
1854
|
function CommandPaletteWorking({ children, bars = 2 }) {
|
|
1726
|
-
return /* @__PURE__ */
|
|
1727
|
-
/* @__PURE__ */
|
|
1728
|
-
/* @__PURE__ */
|
|
1855
|
+
return /* @__PURE__ */ jsxs18("div", { role: "status", className: "flex flex-col gap-2", children: [
|
|
1856
|
+
/* @__PURE__ */ jsxs18("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
|
|
1857
|
+
/* @__PURE__ */ jsx25(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
|
|
1729
1858
|
children
|
|
1730
1859
|
] }),
|
|
1731
|
-
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */
|
|
1860
|
+
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx25(SkeletonBar, { className: cn("h-3", width) }, width))
|
|
1732
1861
|
] });
|
|
1733
1862
|
}
|
|
1734
1863
|
function CommandPaletteAnswer({ children, note }) {
|
|
1735
1864
|
const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
|
|
1736
|
-
return /* @__PURE__ */
|
|
1737
|
-
paragraphs.map((paragraph, i) => /* @__PURE__ */
|
|
1738
|
-
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */
|
|
1865
|
+
return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
|
|
1866
|
+
paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
|
|
1867
|
+
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx25("sup", { className: "ml-0.5 font-mono text-small text-accent-primary", children: part.slice(1, -1) }, j) : part
|
|
1739
1868
|
) }, i)),
|
|
1740
|
-
note && /* @__PURE__ */
|
|
1869
|
+
note && /* @__PURE__ */ jsx25(FieldLine, { children: note })
|
|
1741
1870
|
] });
|
|
1742
1871
|
}
|
|
1743
1872
|
function CommandPaletteQuote({ children }) {
|
|
1744
|
-
return /* @__PURE__ */
|
|
1873
|
+
return /* @__PURE__ */ jsx25("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
|
|
1745
1874
|
}
|
|
1746
1875
|
|
|
1747
1876
|
// src/InlineChip.tsx
|
|
1748
|
-
import { Fragment as Fragment4, jsx as
|
|
1877
|
+
import { Fragment as Fragment4, jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1749
1878
|
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";
|
|
1750
1879
|
var INLINE_CHIP_TONE_CLASSES = {
|
|
1751
1880
|
/** A thing or a place — anything that is not a person. */
|
|
@@ -1767,30 +1896,30 @@ function inlineChipClassName(tone, className) {
|
|
|
1767
1896
|
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1768
1897
|
}
|
|
1769
1898
|
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1770
|
-
const body = /* @__PURE__ */
|
|
1771
|
-
icon && /* @__PURE__ */
|
|
1899
|
+
const body = /* @__PURE__ */ jsxs19(Fragment4, { children: [
|
|
1900
|
+
icon && /* @__PURE__ */ jsx26("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
|
|
1772
1901
|
children
|
|
1773
1902
|
] });
|
|
1774
1903
|
const classes = inlineChipClassName(tone, className);
|
|
1775
1904
|
if (href === void 0) {
|
|
1776
|
-
return /* @__PURE__ */
|
|
1905
|
+
return /* @__PURE__ */ jsx26("span", { className: classes, ...props, children: body });
|
|
1777
1906
|
}
|
|
1778
|
-
return /* @__PURE__ */
|
|
1907
|
+
return /* @__PURE__ */ jsx26("a", { href, className: classes, ...props, children: body });
|
|
1779
1908
|
}
|
|
1780
1909
|
|
|
1781
1910
|
// src/IdentityMenu.tsx
|
|
1782
|
-
import { useCallback, useRef as
|
|
1911
|
+
import { useCallback, useRef as useRef5 } from "react";
|
|
1783
1912
|
|
|
1784
1913
|
// src/Person.tsx
|
|
1785
|
-
import { jsx as
|
|
1914
|
+
import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1786
1915
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
1787
1916
|
return (
|
|
1788
1917
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
1789
1918
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
1790
1919
|
// row agree by construction.
|
|
1791
|
-
/* @__PURE__ */
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */
|
|
1920
|
+
/* @__PURE__ */ jsxs20("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
1921
|
+
/* @__PURE__ */ jsx27(Avatar, { name, src: picture, size }),
|
|
1922
|
+
/* @__PURE__ */ jsx27("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
1794
1923
|
] })
|
|
1795
1924
|
);
|
|
1796
1925
|
}
|
|
@@ -1798,10 +1927,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
1798
1927
|
// src/PersonTrigger.tsx
|
|
1799
1928
|
import { Button as BaseButton5 } from "@base-ui/react/button";
|
|
1800
1929
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
1801
|
-
import { jsx as
|
|
1930
|
+
import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1802
1931
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
1803
1932
|
if (compact) {
|
|
1804
|
-
return /* @__PURE__ */
|
|
1933
|
+
return /* @__PURE__ */ jsx28(
|
|
1805
1934
|
BaseButton5,
|
|
1806
1935
|
{
|
|
1807
1936
|
type: "button",
|
|
@@ -1810,11 +1939,11 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1810
1939
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
1811
1940
|
className: cn("cursor-pointer rounded-full", className),
|
|
1812
1941
|
...props,
|
|
1813
|
-
children: /* @__PURE__ */
|
|
1942
|
+
children: /* @__PURE__ */ jsx28(Avatar, { name, src: picture, size: size ?? 36 })
|
|
1814
1943
|
}
|
|
1815
1944
|
);
|
|
1816
1945
|
}
|
|
1817
|
-
return /* @__PURE__ */
|
|
1946
|
+
return /* @__PURE__ */ jsxs21(
|
|
1818
1947
|
BaseButton5,
|
|
1819
1948
|
{
|
|
1820
1949
|
type: "button",
|
|
@@ -1832,18 +1961,18 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1832
1961
|
),
|
|
1833
1962
|
...props,
|
|
1834
1963
|
children: [
|
|
1835
|
-
/* @__PURE__ */
|
|
1836
|
-
/* @__PURE__ */
|
|
1964
|
+
/* @__PURE__ */ jsx28(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
1965
|
+
/* @__PURE__ */ jsx28(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
1837
1966
|
]
|
|
1838
1967
|
}
|
|
1839
1968
|
);
|
|
1840
1969
|
}
|
|
1841
1970
|
|
|
1842
1971
|
// src/IdentityMenu.tsx
|
|
1843
|
-
import { Fragment as Fragment5, jsx as
|
|
1972
|
+
import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1844
1973
|
function IdentityPanel({ className, onClose = () => {
|
|
1845
1974
|
}, ...rest }) {
|
|
1846
|
-
return /* @__PURE__ */
|
|
1975
|
+
return /* @__PURE__ */ jsx29(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx29(IdentityRows, { ...rest, onClose }) });
|
|
1847
1976
|
}
|
|
1848
1977
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
1849
1978
|
const act = (action) => () => {
|
|
@@ -1851,53 +1980,53 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
1851
1980
|
action();
|
|
1852
1981
|
};
|
|
1853
1982
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
1854
|
-
return /* @__PURE__ */
|
|
1855
|
-
/* @__PURE__ */
|
|
1856
|
-
/* @__PURE__ */
|
|
1857
|
-
/* @__PURE__ */
|
|
1858
|
-
me.email && /* @__PURE__ */
|
|
1983
|
+
return /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
1984
|
+
/* @__PURE__ */ jsxs22(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
1985
|
+
/* @__PURE__ */ jsx29(MenuRow, { children: /* @__PURE__ */ jsx29("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx29(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
|
|
1986
|
+
/* @__PURE__ */ jsx29(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." }),
|
|
1987
|
+
me.email && /* @__PURE__ */ jsxs22(Note, { children: [
|
|
1859
1988
|
me.email,
|
|
1860
1989
|
" \xB7 known to Estiva, never published to the relay"
|
|
1861
1990
|
] })
|
|
1862
1991
|
] }),
|
|
1863
|
-
relayUrl && /* @__PURE__ */
|
|
1864
|
-
/* @__PURE__ */
|
|
1865
|
-
/* @__PURE__ */
|
|
1866
|
-
/* @__PURE__ */
|
|
1867
|
-
/* @__PURE__ */
|
|
1992
|
+
relayUrl && /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
1993
|
+
/* @__PURE__ */ jsx29(Divider, { className: "mx-0 my-2" }),
|
|
1994
|
+
/* @__PURE__ */ jsxs22(MenuSection, { label: "Workspace", children: [
|
|
1995
|
+
/* @__PURE__ */ jsx29(MenuRow, { children: /* @__PURE__ */ jsx29("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
1996
|
+
/* @__PURE__ */ jsx29(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
1868
1997
|
] })
|
|
1869
1998
|
] }),
|
|
1870
|
-
appRows && /* @__PURE__ */
|
|
1871
|
-
/* @__PURE__ */
|
|
1999
|
+
appRows && /* @__PURE__ */ jsxs22(Fragment5, { children: [
|
|
2000
|
+
/* @__PURE__ */ jsx29(Divider, { className: "mx-0 my-2" }),
|
|
1872
2001
|
appRows
|
|
1873
2002
|
] }),
|
|
1874
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
1875
|
-
signedIn && idBase && /* @__PURE__ */
|
|
2003
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx29(Divider, { className: "mx-0 my-2" }) : null,
|
|
2004
|
+
signedIn && idBase && /* @__PURE__ */ jsx29(
|
|
1876
2005
|
MenuItem,
|
|
1877
2006
|
{
|
|
1878
2007
|
label: "Edit your profile in Estiva ID",
|
|
1879
2008
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
1880
2009
|
}
|
|
1881
2010
|
),
|
|
1882
|
-
onCopyKey && /* @__PURE__ */
|
|
1883
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
2011
|
+
onCopyKey && /* @__PURE__ */ jsx29(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
2012
|
+
idBase && onSignOut && /* @__PURE__ */ jsx29(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
1884
2013
|
] });
|
|
1885
2014
|
}
|
|
1886
2015
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
1887
|
-
const actions =
|
|
2016
|
+
const actions = useRef5(null);
|
|
1888
2017
|
const close = useCallback(() => actions.current?.close(), []);
|
|
1889
2018
|
return (
|
|
1890
2019
|
/* The wrapper carries the caller's `className` and nothing else. It used
|
|
1891
2020
|
to be `relative`, because the panel was positioned against it; the panel
|
|
1892
2021
|
hangs from the trigger and portals now, so a positioning context here
|
|
1893
2022
|
would only be a lie about what this box does. */
|
|
1894
|
-
/* @__PURE__ */
|
|
2023
|
+
/* @__PURE__ */ jsx29("div", { className, children: /* @__PURE__ */ jsx29(
|
|
1895
2024
|
Menu,
|
|
1896
2025
|
{
|
|
1897
2026
|
align: "right",
|
|
1898
2027
|
actionsRef: actions,
|
|
1899
2028
|
className: "w-72",
|
|
1900
|
-
trigger: /* @__PURE__ */
|
|
2029
|
+
trigger: /* @__PURE__ */ jsx29(
|
|
1901
2030
|
PersonTrigger,
|
|
1902
2031
|
{
|
|
1903
2032
|
name: me.name,
|
|
@@ -1908,7 +2037,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
1908
2037
|
"aria-label": compact ? "Account menu" : void 0
|
|
1909
2038
|
}
|
|
1910
2039
|
),
|
|
1911
|
-
children: /* @__PURE__ */
|
|
2040
|
+
children: /* @__PURE__ */ jsx29(
|
|
1912
2041
|
IdentityRows,
|
|
1913
2042
|
{
|
|
1914
2043
|
me,
|
|
@@ -1926,14 +2055,14 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
1926
2055
|
);
|
|
1927
2056
|
}
|
|
1928
2057
|
function Note({ children }) {
|
|
1929
|
-
return /* @__PURE__ */
|
|
2058
|
+
return /* @__PURE__ */ jsx29("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
1930
2059
|
}
|
|
1931
2060
|
|
|
1932
2061
|
// src/FilePicker.tsx
|
|
1933
2062
|
import { forwardRef } from "react";
|
|
1934
|
-
import { jsx as
|
|
2063
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1935
2064
|
var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
1936
|
-
return /* @__PURE__ */
|
|
2065
|
+
return /* @__PURE__ */ jsx30(
|
|
1937
2066
|
"input",
|
|
1938
2067
|
{
|
|
1939
2068
|
ref,
|
|
@@ -1954,13 +2083,13 @@ var FilePicker = forwardRef(function FilePicker2({ onPick, ...props }, ref) {
|
|
|
1954
2083
|
// src/Select.tsx
|
|
1955
2084
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
1956
2085
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
1957
|
-
import { jsx as
|
|
2086
|
+
import { jsx as jsx31, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1958
2087
|
var GAP4 = 4;
|
|
1959
2088
|
var VIEWPORT_PAD4 = 8;
|
|
1960
2089
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
|
|
1961
2090
|
const selected = options.find((o) => o.value === value);
|
|
1962
2091
|
const held = Boolean(disabledReason);
|
|
1963
|
-
const trigger = /* @__PURE__ */
|
|
2092
|
+
const trigger = /* @__PURE__ */ jsxs23(
|
|
1964
2093
|
BaseSelect.Trigger,
|
|
1965
2094
|
{
|
|
1966
2095
|
"aria-label": ariaLabel,
|
|
@@ -1990,20 +2119,20 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1990
2119
|
className
|
|
1991
2120
|
),
|
|
1992
2121
|
children: [
|
|
1993
|
-
/* @__PURE__ */
|
|
1994
|
-
selected?.leading && /* @__PURE__ */
|
|
1995
|
-
/* @__PURE__ */
|
|
2122
|
+
/* @__PURE__ */ jsxs23("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
2123
|
+
selected?.leading && /* @__PURE__ */ jsx31("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
2124
|
+
/* @__PURE__ */ jsx31(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
1996
2125
|
] }),
|
|
1997
|
-
/* @__PURE__ */
|
|
2126
|
+
/* @__PURE__ */ jsx31(
|
|
1998
2127
|
BaseSelect.Icon,
|
|
1999
2128
|
{
|
|
2000
|
-
render: /* @__PURE__ */
|
|
2129
|
+
render: /* @__PURE__ */ jsx31(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2001
2130
|
}
|
|
2002
2131
|
)
|
|
2003
2132
|
]
|
|
2004
2133
|
}
|
|
2005
2134
|
);
|
|
2006
|
-
return /* @__PURE__ */
|
|
2135
|
+
return /* @__PURE__ */ jsxs23(
|
|
2007
2136
|
BaseSelect.Root,
|
|
2008
2137
|
{
|
|
2009
2138
|
value,
|
|
@@ -2015,8 +2144,8 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2015
2144
|
disabled: disabled && !held,
|
|
2016
2145
|
modal: false,
|
|
2017
2146
|
children: [
|
|
2018
|
-
held ? /* @__PURE__ */
|
|
2019
|
-
/* @__PURE__ */
|
|
2147
|
+
held ? /* @__PURE__ */ jsx31(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
|
|
2148
|
+
/* @__PURE__ */ jsx31(BaseSelect.Portal, { children: /* @__PURE__ */ jsx31(
|
|
2020
2149
|
BaseSelect.Positioner,
|
|
2021
2150
|
{
|
|
2022
2151
|
side: "bottom",
|
|
@@ -2025,25 +2154,25 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2025
2154
|
collisionPadding: VIEWPORT_PAD4,
|
|
2026
2155
|
alignItemWithTrigger: false,
|
|
2027
2156
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2028
|
-
children: /* @__PURE__ */
|
|
2157
|
+
children: /* @__PURE__ */ jsx31(
|
|
2029
2158
|
BaseSelect.Popup,
|
|
2030
2159
|
{
|
|
2031
|
-
render: /* @__PURE__ */
|
|
2160
|
+
render: /* @__PURE__ */ jsx31(MenuPanel, {}),
|
|
2032
2161
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
2033
|
-
children: /* @__PURE__ */
|
|
2162
|
+
children: /* @__PURE__ */ jsx31(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs23(
|
|
2034
2163
|
BaseSelect.Item,
|
|
2035
2164
|
{
|
|
2036
2165
|
value: option.value,
|
|
2037
2166
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
2038
2167
|
children: [
|
|
2039
|
-
/* @__PURE__ */
|
|
2040
|
-
option.leading && /* @__PURE__ */
|
|
2041
|
-
/* @__PURE__ */
|
|
2168
|
+
/* @__PURE__ */ jsxs23("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
2169
|
+
option.leading && /* @__PURE__ */ jsx31("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
2170
|
+
/* @__PURE__ */ jsx31(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
|
|
2042
2171
|
] }),
|
|
2043
|
-
/* @__PURE__ */
|
|
2172
|
+
/* @__PURE__ */ jsx31(
|
|
2044
2173
|
BaseSelect.ItemIndicator,
|
|
2045
2174
|
{
|
|
2046
|
-
render: /* @__PURE__ */
|
|
2175
|
+
render: /* @__PURE__ */ jsx31(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2047
2176
|
}
|
|
2048
2177
|
)
|
|
2049
2178
|
]
|
|
@@ -2062,9 +2191,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
2062
2191
|
// src/TextInput.tsx
|
|
2063
2192
|
import { forwardRef as forwardRef2 } from "react";
|
|
2064
2193
|
import { Input } from "@base-ui/react/input";
|
|
2065
|
-
import { jsx as
|
|
2194
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
2066
2195
|
var TextInput = forwardRef2(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
|
|
2067
|
-
return /* @__PURE__ */
|
|
2196
|
+
return /* @__PURE__ */ jsx32(
|
|
2068
2197
|
Input,
|
|
2069
2198
|
{
|
|
2070
2199
|
ref,
|
|
@@ -2091,13 +2220,13 @@ var TextInput = forwardRef2(function TextInput2({ className, type = "text", size
|
|
|
2091
2220
|
// src/Textarea.tsx
|
|
2092
2221
|
import { forwardRef as forwardRef3 } from "react";
|
|
2093
2222
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
2094
|
-
import { jsx as
|
|
2223
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
2095
2224
|
var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
2096
|
-
return /* @__PURE__ */
|
|
2225
|
+
return /* @__PURE__ */ jsx33(
|
|
2097
2226
|
BaseField3.Control,
|
|
2098
2227
|
{
|
|
2099
2228
|
ref,
|
|
2100
|
-
render: /* @__PURE__ */
|
|
2229
|
+
render: /* @__PURE__ */ jsx33("textarea", {}),
|
|
2101
2230
|
className: cn(
|
|
2102
2231
|
// The border strengthens on hover, as Select's and ChipInput's do (Katerina, 16 September:
|
|
2103
2232
|
// "aren't there hover states in text input and text area?"). Focus comes after hover in
|
|
@@ -2118,24 +2247,24 @@ var Textarea = forwardRef3(function Textarea2({ className, ...props }, ref) {
|
|
|
2118
2247
|
import { useState as useState4 } from "react";
|
|
2119
2248
|
|
|
2120
2249
|
// src/DialogShell.tsx
|
|
2121
|
-
import { useRef as
|
|
2122
|
-
import { Dialog as
|
|
2250
|
+
import { useRef as useRef6 } from "react";
|
|
2251
|
+
import { Dialog as Dialog3 } from "@base-ui/react/dialog";
|
|
2123
2252
|
import { AlertDialog } from "@base-ui/react/alert-dialog";
|
|
2124
|
-
import { IconX as
|
|
2125
|
-
import { jsx as
|
|
2253
|
+
import { IconX as IconX5 } from "@tabler/icons-react";
|
|
2254
|
+
import { jsx as jsx34, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2126
2255
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
|
|
2127
|
-
const Parts = alert ? AlertDialog :
|
|
2128
|
-
const popupRef =
|
|
2129
|
-
return /* @__PURE__ */
|
|
2256
|
+
const Parts = alert ? AlertDialog : Dialog3;
|
|
2257
|
+
const popupRef = useRef6(null);
|
|
2258
|
+
return /* @__PURE__ */ jsx34(
|
|
2130
2259
|
Parts.Root,
|
|
2131
2260
|
{
|
|
2132
2261
|
open: true,
|
|
2133
2262
|
onOpenChange: (open) => {
|
|
2134
2263
|
if (!open) onClose();
|
|
2135
2264
|
},
|
|
2136
|
-
children: /* @__PURE__ */
|
|
2137
|
-
/* @__PURE__ */
|
|
2138
|
-
/* @__PURE__ */
|
|
2265
|
+
children: /* @__PURE__ */ jsxs24(Parts.Portal, { children: [
|
|
2266
|
+
/* @__PURE__ */ jsx34(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
2267
|
+
/* @__PURE__ */ jsx34("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs24(
|
|
2139
2268
|
Parts.Popup,
|
|
2140
2269
|
{
|
|
2141
2270
|
ref: popupRef,
|
|
@@ -2144,20 +2273,20 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2144
2273
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
2145
2274
|
style: { width },
|
|
2146
2275
|
children: [
|
|
2147
|
-
/* @__PURE__ */
|
|
2148
|
-
headerContent ?? /* @__PURE__ */
|
|
2149
|
-
/* @__PURE__ */
|
|
2276
|
+
/* @__PURE__ */ jsxs24("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
|
|
2277
|
+
headerContent ?? /* @__PURE__ */ jsx34(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx34("span", {}), children: title }),
|
|
2278
|
+
/* @__PURE__ */ jsx34(
|
|
2150
2279
|
Parts.Close,
|
|
2151
2280
|
{
|
|
2152
|
-
render: /* @__PURE__ */
|
|
2281
|
+
render: /* @__PURE__ */ jsx34(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx34(IconX5, { size: 16, stroke: 1.5 }) })
|
|
2153
2282
|
}
|
|
2154
2283
|
)
|
|
2155
2284
|
] }),
|
|
2156
2285
|
bodyMaxHeight ? (
|
|
2157
2286
|
// The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
|
|
2158
|
-
/* @__PURE__ */
|
|
2159
|
-
) : /* @__PURE__ */
|
|
2160
|
-
footer != null && /* @__PURE__ */
|
|
2287
|
+
/* @__PURE__ */ jsx34("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
|
|
2288
|
+
) : /* @__PURE__ */ jsx34("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
2289
|
+
footer != null && /* @__PURE__ */ jsx34("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
2161
2290
|
]
|
|
2162
2291
|
}
|
|
2163
2292
|
) })
|
|
@@ -2167,7 +2296,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2167
2296
|
}
|
|
2168
2297
|
|
|
2169
2298
|
// src/ConfirmDialog.tsx
|
|
2170
|
-
import { Fragment as Fragment6, jsx as
|
|
2299
|
+
import { Fragment as Fragment6, jsx as jsx35, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
2171
2300
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
2172
2301
|
const [busy, setBusy] = useState4(false);
|
|
2173
2302
|
const confirm = async () => {
|
|
@@ -2179,32 +2308,32 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2179
2308
|
setBusy(false);
|
|
2180
2309
|
}
|
|
2181
2310
|
};
|
|
2182
|
-
return /* @__PURE__ */
|
|
2311
|
+
return /* @__PURE__ */ jsx35(
|
|
2183
2312
|
DialogShell,
|
|
2184
2313
|
{
|
|
2185
2314
|
alert: true,
|
|
2186
2315
|
title,
|
|
2187
2316
|
onClose,
|
|
2188
|
-
footer: /* @__PURE__ */
|
|
2189
|
-
/* @__PURE__ */
|
|
2190
|
-
/* @__PURE__ */
|
|
2317
|
+
footer: /* @__PURE__ */ jsxs25(Fragment6, { children: [
|
|
2318
|
+
/* @__PURE__ */ jsx35(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
2319
|
+
/* @__PURE__ */ jsx35(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
2191
2320
|
] }),
|
|
2192
|
-
children: /* @__PURE__ */
|
|
2321
|
+
children: /* @__PURE__ */ jsx35("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
|
|
2193
2322
|
}
|
|
2194
2323
|
);
|
|
2195
2324
|
}
|
|
2196
2325
|
|
|
2197
2326
|
// src/EditableText.tsx
|
|
2198
|
-
import { useEffect as
|
|
2327
|
+
import { useEffect as useEffect3, useRef as useRef7, useState as useState5 } from "react";
|
|
2199
2328
|
import { Field as BaseField4 } from "@base-ui/react/field";
|
|
2200
2329
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
2201
|
-
import { jsx as
|
|
2330
|
+
import { jsx as jsx36 } from "react/jsx-runtime";
|
|
2202
2331
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
2203
2332
|
const [editing, setEditing] = useState5(false);
|
|
2204
2333
|
const [draft, setDraft] = useState5(value);
|
|
2205
2334
|
const [busy, setBusy] = useState5(false);
|
|
2206
|
-
const fieldRef =
|
|
2207
|
-
|
|
2335
|
+
const fieldRef = useRef7(null);
|
|
2336
|
+
useEffect3(() => {
|
|
2208
2337
|
if (editing) {
|
|
2209
2338
|
fieldRef.current?.focus();
|
|
2210
2339
|
fieldRef.current?.select();
|
|
@@ -2256,7 +2385,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2256
2385
|
written and never read. Read-only, this is a line of text: whatever
|
|
2257
2386
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
2258
2387
|
*/
|
|
2259
|
-
/* @__PURE__ */
|
|
2388
|
+
/* @__PURE__ */ jsx36(
|
|
2260
2389
|
"div",
|
|
2261
2390
|
{
|
|
2262
2391
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -2266,11 +2395,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2266
2395
|
);
|
|
2267
2396
|
}
|
|
2268
2397
|
if (editing) {
|
|
2269
|
-
return multiline ? /* @__PURE__ */
|
|
2398
|
+
return multiline ? /* @__PURE__ */ jsx36(
|
|
2270
2399
|
BaseField4.Control,
|
|
2271
2400
|
{
|
|
2272
2401
|
ref: fieldRef,
|
|
2273
|
-
render: /* @__PURE__ */
|
|
2402
|
+
render: /* @__PURE__ */ jsx36("textarea", { rows: 4 }),
|
|
2274
2403
|
"aria-label": label,
|
|
2275
2404
|
value: draft,
|
|
2276
2405
|
disabled: busy,
|
|
@@ -2279,7 +2408,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2279
2408
|
onBlur: () => void commit(),
|
|
2280
2409
|
className: fieldClass
|
|
2281
2410
|
}
|
|
2282
|
-
) : /* @__PURE__ */
|
|
2411
|
+
) : /* @__PURE__ */ jsx36(
|
|
2283
2412
|
Input2,
|
|
2284
2413
|
{
|
|
2285
2414
|
ref: fieldRef,
|
|
@@ -2293,7 +2422,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2293
2422
|
}
|
|
2294
2423
|
);
|
|
2295
2424
|
}
|
|
2296
|
-
return /* @__PURE__ */
|
|
2425
|
+
return /* @__PURE__ */ jsx36(
|
|
2297
2426
|
"button",
|
|
2298
2427
|
{
|
|
2299
2428
|
type: "button",
|
|
@@ -2313,7 +2442,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
2313
2442
|
// src/ErrorBoundary.tsx
|
|
2314
2443
|
import { Component } from "react";
|
|
2315
2444
|
import { IconAlertTriangle as IconAlertTriangle2 } from "@tabler/icons-react";
|
|
2316
|
-
import { jsx as
|
|
2445
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
2317
2446
|
var ErrorBoundary = class extends Component {
|
|
2318
2447
|
state = { hasError: false };
|
|
2319
2448
|
static getDerivedStateFromError() {
|
|
@@ -2324,22 +2453,22 @@ var ErrorBoundary = class extends Component {
|
|
|
2324
2453
|
}
|
|
2325
2454
|
render() {
|
|
2326
2455
|
if (!this.state.hasError) return this.props.children;
|
|
2327
|
-
const message = /* @__PURE__ */
|
|
2456
|
+
const message = /* @__PURE__ */ jsx37(
|
|
2328
2457
|
EmptyState,
|
|
2329
2458
|
{
|
|
2330
|
-
icon: /* @__PURE__ */
|
|
2459
|
+
icon: /* @__PURE__ */ jsx37(IconAlertTriangle2, { size: 16, stroke: 1.5 }),
|
|
2331
2460
|
message: `Something went wrong${this.props.label ? ` in the ${this.props.label}` : ""}. Your data is safe \u2014 try again.`,
|
|
2332
2461
|
action: { label: "Try again", onClick: () => this.setState({ hasError: false }) }
|
|
2333
2462
|
}
|
|
2334
2463
|
);
|
|
2335
2464
|
if (this.props.frame) return this.props.frame(message);
|
|
2336
|
-
return this.props.fallbackClassName ? /* @__PURE__ */
|
|
2465
|
+
return this.props.fallbackClassName ? /* @__PURE__ */ jsx37("div", { className: this.props.fallbackClassName, children: message }) : message;
|
|
2337
2466
|
}
|
|
2338
2467
|
};
|
|
2339
2468
|
|
|
2340
2469
|
// src/ProgressBar.tsx
|
|
2341
2470
|
import { Progress } from "@base-ui/react/progress";
|
|
2342
|
-
import { jsx as
|
|
2471
|
+
import { jsx as jsx38 } from "react/jsx-runtime";
|
|
2343
2472
|
var TRACK_CLASSES = {
|
|
2344
2473
|
default: "h-1.5 w-full overflow-hidden rounded-full bg-bg-inset",
|
|
2345
2474
|
// 4px, Katerina's ruling of 14 September; Peek's own bar is 3px until it takes this one.
|
|
@@ -2352,16 +2481,16 @@ var INDICATOR_CLASSES = {
|
|
|
2352
2481
|
function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
2353
2482
|
return (
|
|
2354
2483
|
// `max={0}` needs no guard: Base UI reads the 0/0 share as an empty bar.
|
|
2355
|
-
/* @__PURE__ */
|
|
2484
|
+
/* @__PURE__ */ jsx38(Progress.Root, { value, max, "aria-label": label, className, children: /* @__PURE__ */ jsx38(Progress.Track, { className: TRACK_CLASSES[variant], children: /* @__PURE__ */ jsx38(Progress.Indicator, { className: INDICATOR_CLASSES[variant] }) }) })
|
|
2356
2485
|
);
|
|
2357
2486
|
}
|
|
2358
2487
|
|
|
2359
2488
|
// src/Breadcrumb.tsx
|
|
2360
|
-
import { Fragment as Fragment7, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as
|
|
2361
|
-
import { jsx as
|
|
2489
|
+
import { Fragment as Fragment7, useCallback as useCallback2, useLayoutEffect as useLayoutEffect4, useRef as useRef8, useState as useState6 } from "react";
|
|
2490
|
+
import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2362
2491
|
function Breadcrumb({ items, className }) {
|
|
2363
|
-
const navRef =
|
|
2364
|
-
const labelRefs =
|
|
2492
|
+
const navRef = useRef8(null);
|
|
2493
|
+
const labelRefs = useRef8([]);
|
|
2365
2494
|
const [truncated, setTruncated] = useState6(/* @__PURE__ */ new Set());
|
|
2366
2495
|
const measure = useCallback2(() => {
|
|
2367
2496
|
const next = /* @__PURE__ */ new Set();
|
|
@@ -2378,7 +2507,7 @@ function Breadcrumb({ items, className }) {
|
|
|
2378
2507
|
observer.observe(nav);
|
|
2379
2508
|
return () => observer.disconnect();
|
|
2380
2509
|
}, [measure, items]);
|
|
2381
|
-
return /* @__PURE__ */
|
|
2510
|
+
return /* @__PURE__ */ jsx39("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-body-2", className), children: items.map((item, index) => {
|
|
2382
2511
|
const last = index === items.length - 1;
|
|
2383
2512
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
2384
2513
|
const text = cn(
|
|
@@ -2399,25 +2528,25 @@ function Breadcrumb({ items, className }) {
|
|
|
2399
2528
|
// on a box around it, which the link takes them from, rather than
|
|
2400
2529
|
// pushed into it (UIG-9); the link is still the one element that
|
|
2401
2530
|
// truncates and is measured.
|
|
2402
|
-
/* @__PURE__ */
|
|
2403
|
-
) : /* @__PURE__ */
|
|
2404
|
-
return /* @__PURE__ */
|
|
2405
|
-
index > 0 && /* @__PURE__ */
|
|
2406
|
-
item.icon && /* @__PURE__ */
|
|
2531
|
+
/* @__PURE__ */ jsx39("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx39(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
|
|
2532
|
+
) : /* @__PURE__ */ jsx39("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
2533
|
+
return /* @__PURE__ */ jsxs26(Fragment7, { children: [
|
|
2534
|
+
index > 0 && /* @__PURE__ */ jsx39("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
2535
|
+
item.icon && /* @__PURE__ */ jsx39("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
2407
2536
|
truncated.has(index) ? (
|
|
2408
2537
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
2409
2538
|
// must keep truncating inside it, or wrapping it would widen the
|
|
2410
2539
|
// trail and the tooltip would never be needed again.
|
|
2411
|
-
/* @__PURE__ */
|
|
2540
|
+
/* @__PURE__ */ jsx39(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
2412
2541
|
) : crumb
|
|
2413
2542
|
] }, `${item.label}-${index}`);
|
|
2414
2543
|
}) });
|
|
2415
2544
|
}
|
|
2416
2545
|
|
|
2417
2546
|
// src/NavItem.tsx
|
|
2418
|
-
import { jsx as
|
|
2547
|
+
import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2419
2548
|
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
2420
|
-
return /* @__PURE__ */
|
|
2549
|
+
return /* @__PURE__ */ jsxs27(
|
|
2421
2550
|
"a",
|
|
2422
2551
|
{
|
|
2423
2552
|
href,
|
|
@@ -2432,9 +2561,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
2432
2561
|
),
|
|
2433
2562
|
...props,
|
|
2434
2563
|
children: [
|
|
2435
|
-
icon && /* @__PURE__ */
|
|
2436
|
-
/* @__PURE__ */
|
|
2437
|
-
count ? /* @__PURE__ */
|
|
2564
|
+
icon && /* @__PURE__ */ jsx40("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
2565
|
+
/* @__PURE__ */ jsx40("span", { className: "flex-1 truncate", children: label }),
|
|
2566
|
+
count ? /* @__PURE__ */ jsx40(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx40("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
2438
2567
|
]
|
|
2439
2568
|
}
|
|
2440
2569
|
);
|
|
@@ -2443,7 +2572,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
2443
2572
|
// src/Popover.tsx
|
|
2444
2573
|
import { useMemo as useMemo3 } from "react";
|
|
2445
2574
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
2446
|
-
import { jsx as
|
|
2575
|
+
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2447
2576
|
var GAP5 = 4;
|
|
2448
2577
|
var VIEWPORT_PAD5 = 8;
|
|
2449
2578
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -2452,7 +2581,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2452
2581
|
if (anchor instanceof Element) return anchor;
|
|
2453
2582
|
return { getBoundingClientRect: () => anchor };
|
|
2454
2583
|
}, [anchor]);
|
|
2455
|
-
return /* @__PURE__ */
|
|
2584
|
+
return /* @__PURE__ */ jsxs28(
|
|
2456
2585
|
BasePopover.Root,
|
|
2457
2586
|
{
|
|
2458
2587
|
open,
|
|
@@ -2460,8 +2589,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2460
2589
|
actionsRef,
|
|
2461
2590
|
modal: false,
|
|
2462
2591
|
children: [
|
|
2463
|
-
trigger && /* @__PURE__ */
|
|
2464
|
-
/* @__PURE__ */
|
|
2592
|
+
trigger && /* @__PURE__ */ jsx41(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
2593
|
+
/* @__PURE__ */ jsx41(BasePopover.Portal, { children: /* @__PURE__ */ jsx41(
|
|
2465
2594
|
BasePopover.Positioner,
|
|
2466
2595
|
{
|
|
2467
2596
|
anchor: anchorTarget,
|
|
@@ -2470,20 +2599,20 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2470
2599
|
sideOffset: GAP5,
|
|
2471
2600
|
collisionPadding: VIEWPORT_PAD5,
|
|
2472
2601
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2473
|
-
children: /* @__PURE__ */
|
|
2602
|
+
children: /* @__PURE__ */ jsx41(
|
|
2474
2603
|
BasePopover.Popup,
|
|
2475
2604
|
{
|
|
2476
2605
|
"aria-label": ariaLabel,
|
|
2477
2606
|
initialFocus: trigger ? void 0 : false,
|
|
2478
2607
|
finalFocus,
|
|
2479
2608
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
2480
|
-
render: /* @__PURE__ */
|
|
2481
|
-
children: /* @__PURE__ */
|
|
2609
|
+
render: /* @__PURE__ */ jsx41(MenuPanel, {}),
|
|
2610
|
+
children: /* @__PURE__ */ jsx41(
|
|
2482
2611
|
ScrollArea,
|
|
2483
2612
|
{
|
|
2484
2613
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
2485
2614
|
contentClassName: cn("flex flex-col p-2", contentClassName),
|
|
2486
|
-
children: /* @__PURE__ */
|
|
2615
|
+
children: /* @__PURE__ */ jsx41(DividerInPanel.Provider, { value: true, children })
|
|
2487
2616
|
}
|
|
2488
2617
|
)
|
|
2489
2618
|
}
|
|
@@ -2497,9 +2626,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2497
2626
|
|
|
2498
2627
|
// src/Toolbar.tsx
|
|
2499
2628
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
2500
|
-
import { jsx as
|
|
2629
|
+
import { jsx as jsx42 } from "react/jsx-runtime";
|
|
2501
2630
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
2502
|
-
const strip = /* @__PURE__ */
|
|
2631
|
+
const strip = /* @__PURE__ */ jsx42(
|
|
2503
2632
|
BaseToolbar.Root,
|
|
2504
2633
|
{
|
|
2505
2634
|
"aria-label": ariaLabel,
|
|
@@ -2510,27 +2639,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
2510
2639
|
}
|
|
2511
2640
|
);
|
|
2512
2641
|
if (!surface) return strip;
|
|
2513
|
-
return /* @__PURE__ */
|
|
2642
|
+
return /* @__PURE__ */ jsx42(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
2514
2643
|
}
|
|
2515
2644
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
2516
|
-
return /* @__PURE__ */
|
|
2645
|
+
return /* @__PURE__ */ jsx42(
|
|
2517
2646
|
BaseToolbar.Button,
|
|
2518
2647
|
{
|
|
2519
2648
|
ref,
|
|
2520
2649
|
disabled: disabled || !!disabledReason,
|
|
2521
2650
|
focusableWhenDisabled: true,
|
|
2522
|
-
render: /* @__PURE__ */
|
|
2651
|
+
render: /* @__PURE__ */ jsx42(IconButton, { disabled, disabledReason, ...props })
|
|
2523
2652
|
}
|
|
2524
2653
|
);
|
|
2525
2654
|
}
|
|
2526
2655
|
function ToolbarLink({ ref, href, ...props }) {
|
|
2527
|
-
return /* @__PURE__ */
|
|
2656
|
+
return /* @__PURE__ */ jsx42(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx42(IconButton, { href, ...props }) });
|
|
2528
2657
|
}
|
|
2529
2658
|
function ToolbarInput({ size, ...props }) {
|
|
2530
|
-
return /* @__PURE__ */
|
|
2659
|
+
return /* @__PURE__ */ jsx42(BaseToolbar.Input, { render: /* @__PURE__ */ jsx42(TextInput, { size }), ...props });
|
|
2531
2660
|
}
|
|
2532
2661
|
function ToolbarSeparator({ className }) {
|
|
2533
|
-
return /* @__PURE__ */
|
|
2662
|
+
return /* @__PURE__ */ jsx42(
|
|
2534
2663
|
BaseToolbar.Separator,
|
|
2535
2664
|
{
|
|
2536
2665
|
orientation: "vertical",
|
|
@@ -2540,9 +2669,9 @@ function ToolbarSeparator({ className }) {
|
|
|
2540
2669
|
}
|
|
2541
2670
|
|
|
2542
2671
|
// src/ReactionPicker.tsx
|
|
2543
|
-
import { jsx as
|
|
2672
|
+
import { jsx as jsx43 } from "react/jsx-runtime";
|
|
2544
2673
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
2545
|
-
return /* @__PURE__ */
|
|
2674
|
+
return /* @__PURE__ */ jsx43(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
2546
2675
|
/*
|
|
2547
2676
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
2548
2677
|
would become the toolbar's item and the button inside it would never
|
|
@@ -2552,14 +2681,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2552
2681
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
2553
2682
|
and both say the meaning rather than the glyph.
|
|
2554
2683
|
*/
|
|
2555
|
-
/* @__PURE__ */
|
|
2684
|
+
/* @__PURE__ */ jsx43(
|
|
2556
2685
|
ToolbarButton,
|
|
2557
2686
|
{
|
|
2558
2687
|
"aria-label": option.label,
|
|
2559
2688
|
tooltip: option.label,
|
|
2560
2689
|
onClick: () => onSelect(option.emoji),
|
|
2561
2690
|
className: "size-7",
|
|
2562
|
-
children: /* @__PURE__ */
|
|
2691
|
+
children: /* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
2563
2692
|
},
|
|
2564
2693
|
option.emoji
|
|
2565
2694
|
)
|
|
@@ -2568,23 +2697,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2568
2697
|
|
|
2569
2698
|
// src/PreviewCard.tsx
|
|
2570
2699
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
2571
|
-
import { jsx as
|
|
2700
|
+
import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2572
2701
|
var GAP6 = 12;
|
|
2573
2702
|
var VIEWPORT_PAD6 = 8;
|
|
2574
2703
|
var OPEN_DELAY2 = 350;
|
|
2575
2704
|
var CLOSE_DELAY = 200;
|
|
2576
2705
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
2577
|
-
return /* @__PURE__ */
|
|
2578
|
-
/* @__PURE__ */
|
|
2706
|
+
return /* @__PURE__ */ jsxs29(BasePreviewCard.Root, { children: [
|
|
2707
|
+
/* @__PURE__ */ jsx44(
|
|
2579
2708
|
BasePreviewCard.Trigger,
|
|
2580
2709
|
{
|
|
2581
2710
|
delay,
|
|
2582
2711
|
closeDelay,
|
|
2583
|
-
render: /* @__PURE__ */
|
|
2712
|
+
render: /* @__PURE__ */ jsx44("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
2584
2713
|
children
|
|
2585
2714
|
}
|
|
2586
2715
|
),
|
|
2587
|
-
/* @__PURE__ */
|
|
2716
|
+
/* @__PURE__ */ jsx44(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx44(
|
|
2588
2717
|
BasePreviewCard.Positioner,
|
|
2589
2718
|
{
|
|
2590
2719
|
side,
|
|
@@ -2592,12 +2721,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2592
2721
|
sideOffset: GAP6,
|
|
2593
2722
|
collisionPadding: VIEWPORT_PAD6,
|
|
2594
2723
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2595
|
-
children: /* @__PURE__ */
|
|
2724
|
+
children: /* @__PURE__ */ jsx44(
|
|
2596
2725
|
BasePreviewCard.Popup,
|
|
2597
2726
|
{
|
|
2598
2727
|
className: cn("w-[360px] p-0 outline-none", className),
|
|
2599
|
-
render: /* @__PURE__ */
|
|
2600
|
-
children: /* @__PURE__ */
|
|
2728
|
+
render: /* @__PURE__ */ jsx44(MenuPanel, {}),
|
|
2729
|
+
children: /* @__PURE__ */ jsx44(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
2601
2730
|
}
|
|
2602
2731
|
)
|
|
2603
2732
|
}
|
|
@@ -2606,15 +2735,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2606
2735
|
}
|
|
2607
2736
|
|
|
2608
2737
|
// src/Rail.tsx
|
|
2609
|
-
import { jsx as
|
|
2738
|
+
import { jsx as jsx45 } from "react/jsx-runtime";
|
|
2610
2739
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
2611
|
-
return /* @__PURE__ */
|
|
2740
|
+
return /* @__PURE__ */ jsx45("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
2612
2741
|
}
|
|
2613
2742
|
|
|
2614
2743
|
// src/RailItem.tsx
|
|
2615
|
-
import { jsx as
|
|
2744
|
+
import { jsx as jsx46, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2616
2745
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
2617
|
-
return /* @__PURE__ */
|
|
2746
|
+
return /* @__PURE__ */ jsxs30(
|
|
2618
2747
|
"a",
|
|
2619
2748
|
{
|
|
2620
2749
|
href,
|
|
@@ -2622,14 +2751,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2622
2751
|
className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
2623
2752
|
...props,
|
|
2624
2753
|
children: [
|
|
2625
|
-
/* @__PURE__ */
|
|
2754
|
+
/* @__PURE__ */ jsx46(
|
|
2626
2755
|
"div",
|
|
2627
2756
|
{
|
|
2628
2757
|
className: cn(
|
|
2629
2758
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
2630
2759
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
2631
2760
|
),
|
|
2632
|
-
children: /* @__PURE__ */
|
|
2761
|
+
children: /* @__PURE__ */ jsx46(
|
|
2633
2762
|
"span",
|
|
2634
2763
|
{
|
|
2635
2764
|
className: cn(
|
|
@@ -2641,27 +2770,27 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2641
2770
|
)
|
|
2642
2771
|
}
|
|
2643
2772
|
),
|
|
2644
|
-
/* @__PURE__ */
|
|
2773
|
+
/* @__PURE__ */ jsx46("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
2645
2774
|
]
|
|
2646
2775
|
}
|
|
2647
2776
|
);
|
|
2648
2777
|
}
|
|
2649
2778
|
|
|
2650
2779
|
// src/Sidebar.tsx
|
|
2651
|
-
import { jsx as
|
|
2780
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
2652
2781
|
function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
|
|
2653
|
-
return /* @__PURE__ */
|
|
2782
|
+
return /* @__PURE__ */ jsx47(
|
|
2654
2783
|
"nav",
|
|
2655
2784
|
{
|
|
2656
2785
|
"aria-label": ariaLabel,
|
|
2657
2786
|
className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
|
|
2658
|
-
children: /* @__PURE__ */
|
|
2787
|
+
children: /* @__PURE__ */ jsx47(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
|
|
2659
2788
|
}
|
|
2660
2789
|
);
|
|
2661
2790
|
}
|
|
2662
2791
|
|
|
2663
2792
|
// src/Property.tsx
|
|
2664
|
-
import { jsx as
|
|
2793
|
+
import { jsx as jsx48, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2665
2794
|
var VALUE_CLASSES = "contents";
|
|
2666
2795
|
function Property({ label, layout = "row", children, className }) {
|
|
2667
2796
|
if (layout === "stacked") {
|
|
@@ -2669,23 +2798,23 @@ function Property({ label, layout = "row", children, className }) {
|
|
|
2669
2798
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
2670
2799
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
2671
2800
|
// 6px, and unifying means the bigger, calmer one.
|
|
2672
|
-
/* @__PURE__ */
|
|
2673
|
-
/* @__PURE__ */
|
|
2674
|
-
/* @__PURE__ */
|
|
2801
|
+
/* @__PURE__ */ jsxs31("dl", { className: cn("flex flex-col gap-3", className), children: [
|
|
2802
|
+
/* @__PURE__ */ jsx48("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
|
|
2803
|
+
/* @__PURE__ */ jsx48("dd", { className: VALUE_CLASSES, children })
|
|
2675
2804
|
] })
|
|
2676
2805
|
);
|
|
2677
2806
|
}
|
|
2678
|
-
return /* @__PURE__ */
|
|
2679
|
-
/* @__PURE__ */
|
|
2680
|
-
/* @__PURE__ */
|
|
2807
|
+
return /* @__PURE__ */ jsxs31("dl", { className: cn("flex items-center gap-2", className), children: [
|
|
2808
|
+
/* @__PURE__ */ jsx48("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
2809
|
+
/* @__PURE__ */ jsx48("dd", { className: VALUE_CLASSES, children })
|
|
2681
2810
|
] });
|
|
2682
2811
|
}
|
|
2683
2812
|
|
|
2684
2813
|
// src/Reaction.tsx
|
|
2685
2814
|
import { Toggle } from "@base-ui/react/toggle";
|
|
2686
|
-
import { jsx as
|
|
2815
|
+
import { jsx as jsx49, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2687
2816
|
function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
2688
|
-
return /* @__PURE__ */
|
|
2817
|
+
return /* @__PURE__ */ jsxs32(
|
|
2689
2818
|
Toggle,
|
|
2690
2819
|
{
|
|
2691
2820
|
pressed,
|
|
@@ -2707,8 +2836,8 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
2707
2836
|
),
|
|
2708
2837
|
...props,
|
|
2709
2838
|
children: [
|
|
2710
|
-
/* @__PURE__ */
|
|
2711
|
-
/* @__PURE__ */
|
|
2839
|
+
/* @__PURE__ */ jsx49("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
|
|
2840
|
+
/* @__PURE__ */ jsx49("span", { className: "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums", children: count })
|
|
2712
2841
|
]
|
|
2713
2842
|
}
|
|
2714
2843
|
);
|
|
@@ -2717,9 +2846,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
2717
2846
|
// src/SearchInput.tsx
|
|
2718
2847
|
import "react";
|
|
2719
2848
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
2720
|
-
import { jsx as
|
|
2849
|
+
import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2721
2850
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
2722
|
-
return /* @__PURE__ */
|
|
2851
|
+
return /* @__PURE__ */ jsxs33(
|
|
2723
2852
|
"div",
|
|
2724
2853
|
{
|
|
2725
2854
|
className: cn(
|
|
@@ -2731,7 +2860,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2731
2860
|
className
|
|
2732
2861
|
),
|
|
2733
2862
|
children: [
|
|
2734
|
-
/* @__PURE__ */
|
|
2863
|
+
/* @__PURE__ */ jsx50(
|
|
2735
2864
|
Input3,
|
|
2736
2865
|
{
|
|
2737
2866
|
className: "flex-1 min-w-0 bg-transparent text-input-value text-text-primary placeholder:text-text-muted outline-none",
|
|
@@ -2739,7 +2868,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2739
2868
|
...props
|
|
2740
2869
|
}
|
|
2741
2870
|
),
|
|
2742
|
-
shortcut && /* @__PURE__ */
|
|
2871
|
+
shortcut && /* @__PURE__ */ jsx50(Kbd, { children: shortcut })
|
|
2743
2872
|
]
|
|
2744
2873
|
}
|
|
2745
2874
|
);
|
|
@@ -2748,17 +2877,17 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2748
2877
|
// src/SectionHeader.tsx
|
|
2749
2878
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
2750
2879
|
import { useRender } from "@base-ui/react/use-render";
|
|
2751
|
-
import { Fragment as Fragment8, jsx as
|
|
2880
|
+
import { Fragment as Fragment8, jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2752
2881
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", render, className }) {
|
|
2753
2882
|
const titleElement = useRender({
|
|
2754
|
-
render: render ?? (chevron ? /* @__PURE__ */
|
|
2883
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx51("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx51("span", {})),
|
|
2755
2884
|
props: {
|
|
2756
2885
|
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
2757
2886
|
// whole row up to the actions is the hit target, as it was when the
|
|
2758
2887
|
// row itself carried the click.
|
|
2759
2888
|
className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
|
|
2760
|
-
children: /* @__PURE__ */
|
|
2761
|
-
chevron && /* @__PURE__ */
|
|
2889
|
+
children: /* @__PURE__ */ jsxs34(Fragment8, { children: [
|
|
2890
|
+
chevron && /* @__PURE__ */ jsx51(
|
|
2762
2891
|
IconChevronRight2,
|
|
2763
2892
|
{
|
|
2764
2893
|
size: 12,
|
|
@@ -2766,11 +2895,11 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2766
2895
|
className: cn("shrink-0 text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
|
|
2767
2896
|
}
|
|
2768
2897
|
),
|
|
2769
|
-
/* @__PURE__ */
|
|
2898
|
+
/* @__PURE__ */ jsx51(SectionLabel, { children: title })
|
|
2770
2899
|
] })
|
|
2771
2900
|
}
|
|
2772
2901
|
});
|
|
2773
|
-
return /* @__PURE__ */
|
|
2902
|
+
return /* @__PURE__ */ jsxs34(
|
|
2774
2903
|
"div",
|
|
2775
2904
|
{
|
|
2776
2905
|
className: cn(
|
|
@@ -2783,15 +2912,15 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2783
2912
|
),
|
|
2784
2913
|
children: [
|
|
2785
2914
|
titleElement,
|
|
2786
|
-
trailing != null && /* @__PURE__ */
|
|
2787
|
-
actions && actions.length > 0 && /* @__PURE__ */
|
|
2915
|
+
trailing != null && /* @__PURE__ */ jsx51("div", { className: "flex shrink-0 items-center", children: trailing }),
|
|
2916
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx51(
|
|
2788
2917
|
"div",
|
|
2789
2918
|
{
|
|
2790
2919
|
className: cn(
|
|
2791
2920
|
"-mr-1 flex shrink-0 items-center gap-1",
|
|
2792
2921
|
showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
2793
2922
|
),
|
|
2794
|
-
children: actions.map((action) => /* @__PURE__ */
|
|
2923
|
+
children: actions.map((action) => /* @__PURE__ */ jsx51(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
|
|
2795
2924
|
}
|
|
2796
2925
|
)
|
|
2797
2926
|
]
|
|
@@ -2801,22 +2930,22 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2801
2930
|
|
|
2802
2931
|
// src/ContainerHeader.tsx
|
|
2803
2932
|
import { IconChevronDown as IconChevronDown3 } from "@tabler/icons-react";
|
|
2804
|
-
import { jsx as
|
|
2933
|
+
import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
2805
2934
|
function ContainerHeader({ title, chevron = false, actions, className }) {
|
|
2806
2935
|
const text = typeof title === "string";
|
|
2807
|
-
return /* @__PURE__ */
|
|
2808
|
-
/* @__PURE__ */
|
|
2809
|
-
text ? /* @__PURE__ */
|
|
2810
|
-
chevron && /* @__PURE__ */
|
|
2936
|
+
return /* @__PURE__ */ jsxs35("div", { className: cn("flex h-12 shrink-0 items-center justify-between overflow-hidden border-b border-border-subtle py-2 pr-4 pl-5", className), children: [
|
|
2937
|
+
/* @__PURE__ */ jsx52("div", { className: cn("flex items-center gap-2 overflow-hidden", text ? "shrink-0" : "min-w-0 flex-1"), children: /* @__PURE__ */ jsxs35("div", { className: cn("flex items-center gap-1", text ? "shrink-0" : "min-w-0 flex-1"), children: [
|
|
2938
|
+
text ? /* @__PURE__ */ jsx52("span", { className: "whitespace-nowrap text-body-2-strong text-text-primary", children: title }) : /* @__PURE__ */ jsx52("div", { className: "min-w-0 flex-1", children: title }),
|
|
2939
|
+
chevron && /* @__PURE__ */ jsx52(IconChevronDown3, { size: 12, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
2811
2940
|
] }) }),
|
|
2812
|
-
actions && /* @__PURE__ */
|
|
2941
|
+
actions && /* @__PURE__ */ jsx52("div", { className: "flex shrink-0 items-center justify-end gap-3", children: /* @__PURE__ */ jsx52("div", { className: "flex shrink-0 items-center gap-1", children: actions }) })
|
|
2813
2942
|
] });
|
|
2814
2943
|
}
|
|
2815
2944
|
|
|
2816
2945
|
// src/ListColumn.tsx
|
|
2817
|
-
import { jsx as
|
|
2946
|
+
import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
2818
2947
|
function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
|
|
2819
|
-
return /* @__PURE__ */
|
|
2948
|
+
return /* @__PURE__ */ jsxs36(
|
|
2820
2949
|
"div",
|
|
2821
2950
|
{
|
|
2822
2951
|
className: cn(
|
|
@@ -2827,26 +2956,26 @@ function Column({ title, chevron = false, actions, above, collapsed = false, chi
|
|
|
2827
2956
|
),
|
|
2828
2957
|
"data-collapsed": collapsed || void 0,
|
|
2829
2958
|
children: [
|
|
2830
|
-
/* @__PURE__ */
|
|
2959
|
+
/* @__PURE__ */ jsx53(ContainerHeader, { title, chevron, actions }),
|
|
2831
2960
|
above,
|
|
2832
2961
|
broken ? (
|
|
2833
2962
|
// The message takes the room the list had and centres itself in it (Katerina, 19 September).
|
|
2834
|
-
/* @__PURE__ */
|
|
2835
|
-
) : /* @__PURE__ */
|
|
2963
|
+
/* @__PURE__ */ jsx53("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
|
|
2964
|
+
) : /* @__PURE__ */ jsx53(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
|
|
2836
2965
|
]
|
|
2837
2966
|
}
|
|
2838
2967
|
);
|
|
2839
2968
|
}
|
|
2840
2969
|
function ListColumn(props) {
|
|
2841
|
-
return /* @__PURE__ */
|
|
2970
|
+
return /* @__PURE__ */ jsx53(
|
|
2842
2971
|
ErrorBoundary,
|
|
2843
2972
|
{
|
|
2844
2973
|
label: "list panel",
|
|
2845
2974
|
frame: (message) => (
|
|
2846
2975
|
// Only the name comes back with the message: the actions and the row above may be what threw.
|
|
2847
|
-
/* @__PURE__ */
|
|
2976
|
+
/* @__PURE__ */ jsx53(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
|
|
2848
2977
|
),
|
|
2849
|
-
children: /* @__PURE__ */
|
|
2978
|
+
children: /* @__PURE__ */ jsx53(Column, { ...props })
|
|
2850
2979
|
}
|
|
2851
2980
|
);
|
|
2852
2981
|
}
|
|
@@ -2854,7 +2983,7 @@ function ListColumn(props) {
|
|
|
2854
2983
|
// src/CollapsibleSection.tsx
|
|
2855
2984
|
import { useState as useState7 } from "react";
|
|
2856
2985
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
2857
|
-
import { jsx as
|
|
2986
|
+
import { jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
2858
2987
|
var OPEN = "open";
|
|
2859
2988
|
var CLOSED = "closed";
|
|
2860
2989
|
function readStored(key) {
|
|
@@ -2881,14 +3010,14 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
2881
3010
|
writeStored(storageKey, next);
|
|
2882
3011
|
onOpenChange?.(next);
|
|
2883
3012
|
};
|
|
2884
|
-
return /* @__PURE__ */
|
|
2885
|
-
/* @__PURE__ */
|
|
2886
|
-
/* @__PURE__ */
|
|
3013
|
+
return /* @__PURE__ */ jsxs37(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
3014
|
+
/* @__PURE__ */ jsx54(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx54(Collapsible.Trigger, {}) }),
|
|
3015
|
+
/* @__PURE__ */ jsx54(
|
|
2887
3016
|
Collapsible.Panel,
|
|
2888
3017
|
{
|
|
2889
3018
|
hiddenUntilFound: true,
|
|
2890
3019
|
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",
|
|
2891
|
-
children: /* @__PURE__ */
|
|
3020
|
+
children: /* @__PURE__ */ jsx54("div", { className: cn("flex flex-col", contentClassName), children })
|
|
2892
3021
|
}
|
|
2893
3022
|
)
|
|
2894
3023
|
] });
|
|
@@ -2896,9 +3025,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
2896
3025
|
|
|
2897
3026
|
// src/Tabs.tsx
|
|
2898
3027
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
2899
|
-
import { jsx as
|
|
3028
|
+
import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
2900
3029
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
2901
|
-
return /* @__PURE__ */
|
|
3030
|
+
return /* @__PURE__ */ jsx55(
|
|
2902
3031
|
BaseTabs.Root,
|
|
2903
3032
|
{
|
|
2904
3033
|
value: active,
|
|
@@ -2906,14 +3035,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2906
3035
|
if (details.reason === "none") onChange(value);
|
|
2907
3036
|
},
|
|
2908
3037
|
className,
|
|
2909
|
-
children: /* @__PURE__ */
|
|
3038
|
+
children: /* @__PURE__ */ jsx55(
|
|
2910
3039
|
BaseTabs.List,
|
|
2911
3040
|
{
|
|
2912
3041
|
activateOnFocus: true,
|
|
2913
3042
|
"aria-label": aria["aria-label"],
|
|
2914
3043
|
"aria-labelledby": aria["aria-labelledby"],
|
|
2915
3044
|
className: "flex items-center gap-2",
|
|
2916
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
3045
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs38(
|
|
2917
3046
|
BaseTabs.Tab,
|
|
2918
3047
|
{
|
|
2919
3048
|
value: tab.id,
|
|
@@ -2926,9 +3055,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2926
3055
|
),
|
|
2927
3056
|
children: [
|
|
2928
3057
|
tab.icon,
|
|
2929
|
-
/* @__PURE__ */
|
|
3058
|
+
/* @__PURE__ */ jsxs38("span", { className: "flex items-baseline", children: [
|
|
2930
3059
|
tab.label,
|
|
2931
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
3060
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx55("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
2932
3061
|
] })
|
|
2933
3062
|
]
|
|
2934
3063
|
},
|
|
@@ -2944,7 +3073,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2944
3073
|
import { createContext as createContext5, useContext as useContext5, useMemo as useMemo4 } from "react";
|
|
2945
3074
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
2946
3075
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
2947
|
-
import { jsx as
|
|
3076
|
+
import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
2948
3077
|
var SURFACE_STYLES = {
|
|
2949
3078
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
2950
3079
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
@@ -2980,16 +3109,16 @@ var pillClassName = (type, hasAction, className) => cn(
|
|
|
2980
3109
|
);
|
|
2981
3110
|
function LeadingIcon({ type }) {
|
|
2982
3111
|
const Icon = ICONS[type];
|
|
2983
|
-
return /* @__PURE__ */
|
|
3112
|
+
return /* @__PURE__ */ jsx56(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
2984
3113
|
}
|
|
2985
3114
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
2986
3115
|
const hasAction = !!(actionLabel && onAction);
|
|
2987
|
-
return /* @__PURE__ */
|
|
2988
|
-
/* @__PURE__ */
|
|
2989
|
-
leadingIcon && /* @__PURE__ */
|
|
2990
|
-
/* @__PURE__ */
|
|
3116
|
+
return /* @__PURE__ */ jsxs39("div", { className: pillClassName(type, hasAction, className), children: [
|
|
3117
|
+
/* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3118
|
+
leadingIcon && /* @__PURE__ */ jsx56(LeadingIcon, { type }),
|
|
3119
|
+
/* @__PURE__ */ jsx56("span", { className: LABEL_CLASSES, children: label })
|
|
2991
3120
|
] }),
|
|
2992
|
-
hasAction && /* @__PURE__ */
|
|
3121
|
+
hasAction && /* @__PURE__ */ jsx56(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
2993
3122
|
] });
|
|
2994
3123
|
}
|
|
2995
3124
|
var ToastContext = createContext5(null);
|
|
@@ -3010,9 +3139,9 @@ function ToastProvider({ children }) {
|
|
|
3010
3139
|
}),
|
|
3011
3140
|
[manager]
|
|
3012
3141
|
);
|
|
3013
|
-
return /* @__PURE__ */
|
|
3142
|
+
return /* @__PURE__ */ jsx56(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs39(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
3014
3143
|
children,
|
|
3015
|
-
/* @__PURE__ */
|
|
3144
|
+
/* @__PURE__ */ jsx56(BaseToast.Portal, { children: /* @__PURE__ */ jsx56(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx56(ToastList, {}) }) })
|
|
3016
3145
|
] }) });
|
|
3017
3146
|
}
|
|
3018
3147
|
function ToastList() {
|
|
@@ -3020,25 +3149,25 @@ function ToastList() {
|
|
|
3020
3149
|
return toasts.map((toast) => {
|
|
3021
3150
|
const type = toast.type ?? "neutral";
|
|
3022
3151
|
const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
|
|
3023
|
-
return /* @__PURE__ */
|
|
3152
|
+
return /* @__PURE__ */ jsxs39(
|
|
3024
3153
|
BaseToast.Root,
|
|
3025
3154
|
{
|
|
3026
3155
|
toast,
|
|
3027
3156
|
swipeDirection: ["left", "down"],
|
|
3028
3157
|
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
3029
3158
|
children: [
|
|
3030
|
-
/* @__PURE__ */
|
|
3031
|
-
leadingIcon && /* @__PURE__ */
|
|
3032
|
-
/* @__PURE__ */
|
|
3159
|
+
/* @__PURE__ */ jsxs39("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3160
|
+
leadingIcon && /* @__PURE__ */ jsx56(LeadingIcon, { type }),
|
|
3161
|
+
/* @__PURE__ */ jsx56(BaseToast.Title, { render: /* @__PURE__ */ jsx56("span", {}), className: LABEL_CLASSES })
|
|
3033
3162
|
] }),
|
|
3034
|
-
actionLabel && /* @__PURE__ */
|
|
3163
|
+
actionLabel && /* @__PURE__ */ jsx56(
|
|
3035
3164
|
BaseToast.Action,
|
|
3036
3165
|
{
|
|
3037
3166
|
onClick: () => {
|
|
3038
3167
|
onAction?.();
|
|
3039
3168
|
close(toast.id);
|
|
3040
3169
|
},
|
|
3041
|
-
render: /* @__PURE__ */
|
|
3170
|
+
render: /* @__PURE__ */ jsx56(Button, { variant: "outlined", size: "small", children: actionLabel })
|
|
3042
3171
|
}
|
|
3043
3172
|
)
|
|
3044
3173
|
]
|
|
@@ -3091,6 +3220,7 @@ export {
|
|
|
3091
3220
|
InlineChip,
|
|
3092
3221
|
InputChip,
|
|
3093
3222
|
Kbd,
|
|
3223
|
+
Lightbox,
|
|
3094
3224
|
Link,
|
|
3095
3225
|
ListColumn,
|
|
3096
3226
|
Menu,
|