@estiva-app/ui 0.10.1 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AppShell.d.ts.map +1 -1
- package/dist/Divider.d.ts +15 -1
- package/dist/Divider.d.ts.map +1 -1
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Popover.d.ts.map +1 -1
- package/dist/PreviewCard.d.ts.map +1 -1
- package/dist/Reaction.d.ts.map +1 -1
- package/dist/ScrollArea.d.ts +46 -0
- package/dist/ScrollArea.d.ts.map +1 -0
- package/dist/Select.d.ts.map +1 -1
- package/dist/Sidebar.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +272 -234
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/src/AppShell.tsx +5 -0
- package/src/Divider.mdx +9 -0
- package/src/Divider.stories.tsx +25 -0
- package/src/Divider.test.tsx +26 -0
- package/src/Divider.tsx +30 -1
- package/src/Menu.tsx +11 -2
- package/src/Popover.tsx +6 -2
- package/src/PreviewCard.tsx +5 -2
- package/src/Reaction.tsx +6 -1
- package/src/ScrollArea.mdx +59 -0
- package/src/ScrollArea.stories.tsx +75 -0
- package/src/ScrollArea.test.tsx +50 -0
- package/src/ScrollArea.tsx +81 -0
- package/src/Select.tsx +8 -1
- package/src/Sidebar.tsx +8 -5
- package/src/index.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -459,10 +459,26 @@ function triggerDisabled(trigger) {
|
|
|
459
459
|
return !!(props.disabled || props.disabledReason);
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
+
// src/ScrollArea.tsx
|
|
463
|
+
import { ScrollArea as BaseScrollArea } from "@base-ui/react/scroll-area";
|
|
464
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
465
|
+
var BAR = "flex touch-none select-none rounded-full opacity-0 transition-opacity delay-300 data-[hovering]:opacity-100 data-[hovering]:delay-0 data-[scrolling]:opacity-100 data-[scrolling]:delay-0";
|
|
466
|
+
var THUMB = "rounded-full bg-border-strong";
|
|
467
|
+
function ScrollArea({ orientation = "vertical", className, viewportClassName, contentClassName, children }) {
|
|
468
|
+
const vertical = orientation !== "horizontal";
|
|
469
|
+
const horizontal = orientation !== "vertical";
|
|
470
|
+
return /* @__PURE__ */ jsxs7(BaseScrollArea.Root, { className: cn("relative min-h-0 min-w-0", className), children: [
|
|
471
|
+
/* @__PURE__ */ jsx12(BaseScrollArea.Viewport, { className: cn("h-full w-full overscroll-contain outline-none", viewportClassName), children: /* @__PURE__ */ jsx12(BaseScrollArea.Content, { className: contentClassName, style: horizontal ? void 0 : { minWidth: 0 }, children }) }),
|
|
472
|
+
vertical && /* @__PURE__ */ jsx12(BaseScrollArea.Scrollbar, { orientation: "vertical", className: cn(BAR, "w-1.5 justify-center py-0.5 pr-0.5"), children: /* @__PURE__ */ jsx12(BaseScrollArea.Thumb, { className: cn(THUMB, "w-full") }) }),
|
|
473
|
+
horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Scrollbar, { orientation: "horizontal", className: cn(BAR, "h-1.5 flex-col justify-center px-0.5 pb-0.5"), children: /* @__PURE__ */ jsx12(BaseScrollArea.Thumb, { className: cn(THUMB, "h-full") }) }),
|
|
474
|
+
vertical && horizontal && /* @__PURE__ */ jsx12(BaseScrollArea.Corner, {})
|
|
475
|
+
] });
|
|
476
|
+
}
|
|
477
|
+
|
|
462
478
|
// src/SectionLabel.tsx
|
|
463
|
-
import { jsx as
|
|
479
|
+
import { jsx as jsx13 } from "react/jsx-runtime";
|
|
464
480
|
function SectionLabel({ children, className }) {
|
|
465
|
-
return /* @__PURE__ */
|
|
481
|
+
return /* @__PURE__ */ jsx13(
|
|
466
482
|
"span",
|
|
467
483
|
{
|
|
468
484
|
className: cn(
|
|
@@ -475,10 +491,10 @@ function SectionLabel({ children, className }) {
|
|
|
475
491
|
}
|
|
476
492
|
|
|
477
493
|
// src/Menu.tsx
|
|
478
|
-
import { Fragment, jsx as
|
|
494
|
+
import { Fragment, jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
479
495
|
var MenuContext = createContext(null);
|
|
480
496
|
function MenuPanel({ children, className, ...props }) {
|
|
481
|
-
return /* @__PURE__ */
|
|
497
|
+
return /* @__PURE__ */ jsx14(
|
|
482
498
|
"div",
|
|
483
499
|
{
|
|
484
500
|
className: cn(
|
|
@@ -508,7 +524,7 @@ var VIEWPORT_PAD2 = 8;
|
|
|
508
524
|
var HOVER_OPEN_DELAY = 0;
|
|
509
525
|
var HOVER_CLOSE_DELAY = 150;
|
|
510
526
|
function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className }) {
|
|
511
|
-
return /* @__PURE__ */
|
|
527
|
+
return /* @__PURE__ */ jsxs8(
|
|
512
528
|
BaseMenu.Root,
|
|
513
529
|
{
|
|
514
530
|
open,
|
|
@@ -516,7 +532,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
516
532
|
actionsRef,
|
|
517
533
|
modal: false,
|
|
518
534
|
children: [
|
|
519
|
-
/* @__PURE__ */
|
|
535
|
+
/* @__PURE__ */ jsx14(
|
|
520
536
|
BaseMenu.Trigger,
|
|
521
537
|
{
|
|
522
538
|
render: trigger,
|
|
@@ -526,7 +542,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
526
542
|
closeDelay: HOVER_CLOSE_DELAY
|
|
527
543
|
}
|
|
528
544
|
),
|
|
529
|
-
/* @__PURE__ */
|
|
545
|
+
/* @__PURE__ */ jsx14(BaseMenu.Portal, { children: /* @__PURE__ */ jsx14(
|
|
530
546
|
BaseMenu.Positioner,
|
|
531
547
|
{
|
|
532
548
|
side: "bottom",
|
|
@@ -534,13 +550,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
534
550
|
sideOffset: GAP3,
|
|
535
551
|
collisionPadding: VIEWPORT_PAD2,
|
|
536
552
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
537
|
-
children: /* @__PURE__ */
|
|
553
|
+
children: /* @__PURE__ */ jsx14(
|
|
538
554
|
BaseMenu.Popup,
|
|
539
555
|
{
|
|
540
556
|
"data-interactive": true,
|
|
541
|
-
className: cn("min-w-[180px]
|
|
542
|
-
render: /* @__PURE__ */
|
|
543
|
-
children: /* @__PURE__ */
|
|
557
|
+
className: cn("min-w-[180px] outline-none", className),
|
|
558
|
+
render: /* @__PURE__ */ jsx14(MenuPanel, {}),
|
|
559
|
+
children: /* @__PURE__ */ jsx14(ScrollArea, { viewportClassName: "max-h-[calc(var(--available-height)_-_1rem)]", contentClassName: "flex flex-col [&>[role=separator]]:mx-0", children: /* @__PURE__ */ jsx14(MenuContext.Provider, { value: { openOnHover }, children }) })
|
|
544
560
|
}
|
|
545
561
|
)
|
|
546
562
|
}
|
|
@@ -556,20 +572,20 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
556
572
|
'[@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".'
|
|
557
573
|
);
|
|
558
574
|
}
|
|
559
|
-
return /* @__PURE__ */
|
|
560
|
-
/* @__PURE__ */
|
|
575
|
+
return /* @__PURE__ */ jsxs8(BaseMenu.SubmenuRoot, { children: [
|
|
576
|
+
/* @__PURE__ */ jsx14(
|
|
561
577
|
BaseMenu.SubmenuTrigger,
|
|
562
578
|
{
|
|
563
579
|
openOnHover: true,
|
|
564
580
|
delay: 0,
|
|
565
581
|
closeDelay: 150,
|
|
566
582
|
nativeButton: true,
|
|
567
|
-
render: /* @__PURE__ */
|
|
583
|
+
render: /* @__PURE__ */ jsx14("button", { type: "button" }),
|
|
568
584
|
className: menuItemClassName({ size: "default", selected }),
|
|
569
|
-
children: /* @__PURE__ */
|
|
585
|
+
children: /* @__PURE__ */ jsx14(MenuItemBody, { label, leading, submenu: true })
|
|
570
586
|
}
|
|
571
587
|
),
|
|
572
|
-
/* @__PURE__ */
|
|
588
|
+
/* @__PURE__ */ jsx14(BaseMenu.Portal, { children: /* @__PURE__ */ jsx14(
|
|
573
589
|
BaseMenu.Positioner,
|
|
574
590
|
{
|
|
575
591
|
side: "inline-end",
|
|
@@ -577,7 +593,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
577
593
|
sideOffset: GAP3,
|
|
578
594
|
collisionPadding: VIEWPORT_PAD2,
|
|
579
595
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
580
|
-
children: /* @__PURE__ */
|
|
596
|
+
children: /* @__PURE__ */ jsx14(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx14(MenuPanel, {}), children })
|
|
581
597
|
}
|
|
582
598
|
) })
|
|
583
599
|
] });
|
|
@@ -609,25 +625,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
609
625
|
);
|
|
610
626
|
}
|
|
611
627
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
612
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
613
|
-
return /* @__PURE__ */
|
|
614
|
-
leading && /* @__PURE__ */
|
|
615
|
-
children ?? /* @__PURE__ */
|
|
616
|
-
/* @__PURE__ */
|
|
617
|
-
description && /* @__PURE__ */
|
|
628
|
+
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx14(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx14(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
629
|
+
return /* @__PURE__ */ jsxs8(Fragment, { children: [
|
|
630
|
+
leading && /* @__PURE__ */ jsx14("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
631
|
+
children ?? /* @__PURE__ */ jsxs8("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
632
|
+
/* @__PURE__ */ jsx14("span", { className: cn("truncate text-[14px] leading-[140%]", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
633
|
+
description && /* @__PURE__ */ jsx14("span", { className: "truncate text-[12px] leading-[120%] text-text-secondary", children: description })
|
|
618
634
|
] }),
|
|
619
635
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
620
636
|
// the wider of the two and never changes, so revealing the hint moves
|
|
621
637
|
// nothing. No transition here either — the hint switches on the same
|
|
622
638
|
// :hover / `selected` as the fill, in the same frame.
|
|
623
|
-
/* @__PURE__ */
|
|
624
|
-
edge && /* @__PURE__ */
|
|
625
|
-
hint && /* @__PURE__ */
|
|
639
|
+
/* @__PURE__ */ jsxs8("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
640
|
+
edge && /* @__PURE__ */ jsx14("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
641
|
+
hint && /* @__PURE__ */ jsx14("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
626
642
|
] })
|
|
627
643
|
] });
|
|
628
644
|
}
|
|
629
645
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
630
|
-
const body = /* @__PURE__ */
|
|
646
|
+
const body = /* @__PURE__ */ jsx14(
|
|
631
647
|
MenuItemBody,
|
|
632
648
|
{
|
|
633
649
|
label,
|
|
@@ -645,13 +661,13 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
645
661
|
);
|
|
646
662
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
647
663
|
if (!useContext(MenuContext)) {
|
|
648
|
-
return /* @__PURE__ */
|
|
664
|
+
return /* @__PURE__ */ jsx14("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
649
665
|
}
|
|
650
|
-
return /* @__PURE__ */
|
|
666
|
+
return /* @__PURE__ */ jsx14(
|
|
651
667
|
BaseMenu.Item,
|
|
652
668
|
{
|
|
653
669
|
nativeButton: true,
|
|
654
|
-
render: /* @__PURE__ */
|
|
670
|
+
render: /* @__PURE__ */ jsx14("button", { type: "button" }),
|
|
655
671
|
className: rowClassName,
|
|
656
672
|
...props,
|
|
657
673
|
children: body
|
|
@@ -659,33 +675,33 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
659
675
|
);
|
|
660
676
|
}
|
|
661
677
|
function EnterHint({ target }) {
|
|
662
|
-
return /* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
target && /* @__PURE__ */
|
|
678
|
+
return /* @__PURE__ */ jsxs8("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
679
|
+
/* @__PURE__ */ jsx14(Kbd, { children: "\u21A9 Enter" }),
|
|
680
|
+
target && /* @__PURE__ */ jsx14("span", { className: "text-[9px] font-medium leading-[115%] signal:font-mono signal:text-[9.5px] signal:tracking-[0.04em]", children: target })
|
|
665
681
|
] });
|
|
666
682
|
}
|
|
667
683
|
function MenuSection({ label, children, className }) {
|
|
668
684
|
const inMenu = useContext(MenuContext) !== null;
|
|
669
|
-
const heading = /* @__PURE__ */
|
|
685
|
+
const heading = /* @__PURE__ */ jsx14("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx14(SectionLabel, { className: "text-text-secondary", children: label }) });
|
|
670
686
|
if (!inMenu) {
|
|
671
|
-
return /* @__PURE__ */
|
|
687
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
|
|
672
688
|
heading,
|
|
673
689
|
children
|
|
674
690
|
] });
|
|
675
691
|
}
|
|
676
|
-
return /* @__PURE__ */
|
|
677
|
-
/* @__PURE__ */
|
|
692
|
+
return /* @__PURE__ */ jsxs8(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
693
|
+
/* @__PURE__ */ jsx14(BaseMenu.GroupLabel, { render: heading }),
|
|
678
694
|
children
|
|
679
695
|
] });
|
|
680
696
|
}
|
|
681
697
|
function MenuRow({ children, className }) {
|
|
682
|
-
return /* @__PURE__ */
|
|
698
|
+
return /* @__PURE__ */ jsx14("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
683
699
|
}
|
|
684
700
|
|
|
685
701
|
// src/ChipInput.tsx
|
|
686
|
-
import { jsx as
|
|
702
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
687
703
|
function InputChip({ label, leading, onRemove, className }) {
|
|
688
|
-
return /* @__PURE__ */
|
|
704
|
+
return /* @__PURE__ */ jsxs9(
|
|
689
705
|
"div",
|
|
690
706
|
{
|
|
691
707
|
className: cn(
|
|
@@ -701,9 +717,9 @@ function InputChip({ label, leading, onRemove, className }) {
|
|
|
701
717
|
className
|
|
702
718
|
),
|
|
703
719
|
children: [
|
|
704
|
-
leading && /* @__PURE__ */
|
|
705
|
-
/* @__PURE__ */
|
|
706
|
-
onRemove && /* @__PURE__ */
|
|
720
|
+
leading && /* @__PURE__ */ jsx15("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
721
|
+
/* @__PURE__ */ jsx15("span", { className: "text-caption font-medium text-text-primary", children: label }),
|
|
722
|
+
onRemove && /* @__PURE__ */ jsx15(
|
|
707
723
|
"button",
|
|
708
724
|
{
|
|
709
725
|
type: "button",
|
|
@@ -713,7 +729,7 @@ function InputChip({ label, leading, onRemove, className }) {
|
|
|
713
729
|
},
|
|
714
730
|
className: "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary",
|
|
715
731
|
"aria-label": `Remove ${label}`,
|
|
716
|
-
children: /* @__PURE__ */
|
|
732
|
+
children: /* @__PURE__ */ jsx15(IconX2, { size: 10, stroke: 1.5 })
|
|
717
733
|
}
|
|
718
734
|
)
|
|
719
735
|
]
|
|
@@ -802,16 +818,16 @@ function ChipInput({
|
|
|
802
818
|
}
|
|
803
819
|
}
|
|
804
820
|
}
|
|
805
|
-
return /* @__PURE__ */
|
|
806
|
-
/* @__PURE__ */
|
|
821
|
+
return /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
|
|
822
|
+
/* @__PURE__ */ jsxs9(
|
|
807
823
|
"div",
|
|
808
824
|
{
|
|
809
825
|
ref: wrapperRef,
|
|
810
826
|
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",
|
|
811
827
|
onClick: () => inputRef.current?.focus(),
|
|
812
828
|
children: [
|
|
813
|
-
value.map((o) => /* @__PURE__ */
|
|
814
|
-
/* @__PURE__ */
|
|
829
|
+
value.map((o) => /* @__PURE__ */ jsx15(InputChip, { label: o.label, leading: chipLeading?.(o), onRemove: () => removeOption(o.id) }, o.id)),
|
|
830
|
+
/* @__PURE__ */ jsx15(
|
|
815
831
|
"input",
|
|
816
832
|
{
|
|
817
833
|
ref: inputRef,
|
|
@@ -833,7 +849,7 @@ function ChipInput({
|
|
|
833
849
|
}
|
|
834
850
|
),
|
|
835
851
|
showDropdown && anchorRect && createPortal(
|
|
836
|
-
/* @__PURE__ */
|
|
852
|
+
/* @__PURE__ */ jsx15(
|
|
837
853
|
"div",
|
|
838
854
|
{
|
|
839
855
|
className: "fixed z-[60] overflow-y-auto bg-bg-elevated border border-border-default rounded-lg shadow-lg",
|
|
@@ -846,7 +862,7 @@ function ChipInput({
|
|
|
846
862
|
}),
|
|
847
863
|
width: anchorRect.width
|
|
848
864
|
},
|
|
849
|
-
children: matches.map((o, i) => /* @__PURE__ */
|
|
865
|
+
children: matches.map((o, i) => /* @__PURE__ */ jsx15(
|
|
850
866
|
MenuItem,
|
|
851
867
|
{
|
|
852
868
|
size: "tall",
|
|
@@ -874,9 +890,26 @@ function ChipInput({
|
|
|
874
890
|
import { useCallback, useRef as useRef2 } from "react";
|
|
875
891
|
|
|
876
892
|
// src/Divider.tsx
|
|
877
|
-
import { jsx as
|
|
878
|
-
function Divider({ orientation = "horizontal", className }) {
|
|
879
|
-
|
|
893
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
894
|
+
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
895
|
+
if (label && orientation === "horizontal") {
|
|
896
|
+
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
897
|
+
return /* @__PURE__ */ jsxs10(
|
|
898
|
+
"div",
|
|
899
|
+
{
|
|
900
|
+
role: "separator",
|
|
901
|
+
"aria-orientation": "horizontal",
|
|
902
|
+
"aria-label": label,
|
|
903
|
+
className: cn("flex shrink-0 items-center gap-2 mx-3", className),
|
|
904
|
+
children: [
|
|
905
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
906
|
+
/* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
907
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
908
|
+
]
|
|
909
|
+
}
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
return /* @__PURE__ */ jsx16(
|
|
880
913
|
"div",
|
|
881
914
|
{
|
|
882
915
|
role: "separator",
|
|
@@ -887,15 +920,15 @@ function Divider({ orientation = "horizontal", className }) {
|
|
|
887
920
|
}
|
|
888
921
|
|
|
889
922
|
// src/Person.tsx
|
|
890
|
-
import { jsx as
|
|
923
|
+
import { jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
891
924
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
892
925
|
return (
|
|
893
926
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
894
927
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
895
928
|
// row agree by construction.
|
|
896
|
-
/* @__PURE__ */
|
|
897
|
-
/* @__PURE__ */
|
|
898
|
-
/* @__PURE__ */
|
|
929
|
+
/* @__PURE__ */ jsxs11("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
930
|
+
/* @__PURE__ */ jsx17(Avatar, { name, src: picture, size }),
|
|
931
|
+
/* @__PURE__ */ jsx17("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
899
932
|
] })
|
|
900
933
|
);
|
|
901
934
|
}
|
|
@@ -903,10 +936,10 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
903
936
|
// src/PersonTrigger.tsx
|
|
904
937
|
import { Button as BaseButton3 } from "@base-ui/react/button";
|
|
905
938
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
906
|
-
import { jsx as
|
|
939
|
+
import { jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
907
940
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
908
941
|
if (compact) {
|
|
909
|
-
return /* @__PURE__ */
|
|
942
|
+
return /* @__PURE__ */ jsx18(
|
|
910
943
|
BaseButton3,
|
|
911
944
|
{
|
|
912
945
|
type: "button",
|
|
@@ -915,11 +948,11 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
915
948
|
"aria-label": props["aria-label"] ?? name ?? fallback,
|
|
916
949
|
className: cn("cursor-pointer rounded-full", className),
|
|
917
950
|
...props,
|
|
918
|
-
children: /* @__PURE__ */
|
|
951
|
+
children: /* @__PURE__ */ jsx18(Avatar, { name, src: picture, size: size ?? 36 })
|
|
919
952
|
}
|
|
920
953
|
);
|
|
921
954
|
}
|
|
922
|
-
return /* @__PURE__ */
|
|
955
|
+
return /* @__PURE__ */ jsxs12(
|
|
923
956
|
BaseButton3,
|
|
924
957
|
{
|
|
925
958
|
type: "button",
|
|
@@ -937,18 +970,18 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
937
970
|
),
|
|
938
971
|
...props,
|
|
939
972
|
children: [
|
|
940
|
-
/* @__PURE__ */
|
|
941
|
-
/* @__PURE__ */
|
|
973
|
+
/* @__PURE__ */ jsx18(Person, { name, picture, fallback, size: size ?? 22 }),
|
|
974
|
+
/* @__PURE__ */ jsx18(IconChevronDown, { size: 14, stroke: 1.5, className: "shrink-0 text-text-muted" })
|
|
942
975
|
]
|
|
943
976
|
}
|
|
944
977
|
);
|
|
945
978
|
}
|
|
946
979
|
|
|
947
980
|
// src/IdentityMenu.tsx
|
|
948
|
-
import { Fragment as Fragment2, jsx as
|
|
981
|
+
import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
949
982
|
function IdentityPanel({ className, onClose = () => {
|
|
950
983
|
}, ...rest }) {
|
|
951
|
-
return /* @__PURE__ */
|
|
984
|
+
return /* @__PURE__ */ jsx19(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx19(IdentityRows, { ...rest, onClose }) });
|
|
952
985
|
}
|
|
953
986
|
function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, onClose, children }) {
|
|
954
987
|
const act = (action) => () => {
|
|
@@ -956,36 +989,36 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
956
989
|
action();
|
|
957
990
|
};
|
|
958
991
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
959
|
-
return /* @__PURE__ */
|
|
960
|
-
/* @__PURE__ */
|
|
961
|
-
/* @__PURE__ */
|
|
962
|
-
/* @__PURE__ */
|
|
963
|
-
me.email && /* @__PURE__ */
|
|
992
|
+
return /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
993
|
+
/* @__PURE__ */ jsxs13(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
994
|
+
/* @__PURE__ */ jsx19(MenuRow, { children: /* @__PURE__ */ jsx19(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
|
|
995
|
+
/* @__PURE__ */ jsx19(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." }),
|
|
996
|
+
me.email && /* @__PURE__ */ jsxs13(Note, { children: [
|
|
964
997
|
me.email,
|
|
965
998
|
" \xB7 known to Estiva, never published to the relay"
|
|
966
999
|
] })
|
|
967
1000
|
] }),
|
|
968
|
-
relayUrl && /* @__PURE__ */
|
|
969
|
-
/* @__PURE__ */
|
|
970
|
-
/* @__PURE__ */
|
|
971
|
-
/* @__PURE__ */
|
|
972
|
-
/* @__PURE__ */
|
|
1001
|
+
relayUrl && /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
1002
|
+
/* @__PURE__ */ jsx19(Divider, { className: "mx-0 my-2" }),
|
|
1003
|
+
/* @__PURE__ */ jsxs13(MenuSection, { label: "Workspace", children: [
|
|
1004
|
+
/* @__PURE__ */ jsx19(MenuRow, { children: /* @__PURE__ */ jsx19("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
1005
|
+
/* @__PURE__ */ jsx19(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
973
1006
|
] })
|
|
974
1007
|
] }),
|
|
975
|
-
appRows && /* @__PURE__ */
|
|
976
|
-
/* @__PURE__ */
|
|
1008
|
+
appRows && /* @__PURE__ */ jsxs13(Fragment2, { children: [
|
|
1009
|
+
/* @__PURE__ */ jsx19(Divider, { className: "mx-0 my-2" }),
|
|
977
1010
|
appRows
|
|
978
1011
|
] }),
|
|
979
|
-
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */
|
|
980
|
-
signedIn && idBase && /* @__PURE__ */
|
|
1012
|
+
signedIn && idBase || onCopyKey || idBase && onSignOut ? /* @__PURE__ */ jsx19(Divider, { className: "mx-0 my-2" }) : null,
|
|
1013
|
+
signedIn && idBase && /* @__PURE__ */ jsx19(
|
|
981
1014
|
MenuItem,
|
|
982
1015
|
{
|
|
983
1016
|
label: "Edit your profile in Estiva ID",
|
|
984
1017
|
onClick: act(() => window.open(idBase, "_blank", "noopener,noreferrer"))
|
|
985
1018
|
}
|
|
986
1019
|
),
|
|
987
|
-
onCopyKey && /* @__PURE__ */
|
|
988
|
-
idBase && onSignOut && /* @__PURE__ */
|
|
1020
|
+
onCopyKey && /* @__PURE__ */ jsx19(MenuItem, { label: "Copy public key", onClick: act(onCopyKey) }),
|
|
1021
|
+
idBase && onSignOut && /* @__PURE__ */ jsx19(MenuItem, { label: "Sign out", onClick: act(onSignOut) })
|
|
989
1022
|
] });
|
|
990
1023
|
}
|
|
991
1024
|
function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, compact = false, className, children }) {
|
|
@@ -996,13 +1029,13 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
996
1029
|
to be `relative`, because the panel was positioned against it; the panel
|
|
997
1030
|
hangs from the trigger and portals now, so a positioning context here
|
|
998
1031
|
would only be a lie about what this box does. */
|
|
999
|
-
/* @__PURE__ */
|
|
1032
|
+
/* @__PURE__ */ jsx19("div", { className, children: /* @__PURE__ */ jsx19(
|
|
1000
1033
|
Menu,
|
|
1001
1034
|
{
|
|
1002
1035
|
align: "right",
|
|
1003
1036
|
actionsRef: actions,
|
|
1004
1037
|
className: "w-72",
|
|
1005
|
-
trigger: /* @__PURE__ */
|
|
1038
|
+
trigger: /* @__PURE__ */ jsx19(
|
|
1006
1039
|
PersonTrigger,
|
|
1007
1040
|
{
|
|
1008
1041
|
name: me.name,
|
|
@@ -1013,7 +1046,7 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
1013
1046
|
"aria-label": compact ? "Account menu" : void 0
|
|
1014
1047
|
}
|
|
1015
1048
|
),
|
|
1016
|
-
children: /* @__PURE__ */
|
|
1049
|
+
children: /* @__PURE__ */ jsx19(
|
|
1017
1050
|
IdentityRows,
|
|
1018
1051
|
{
|
|
1019
1052
|
me,
|
|
@@ -1031,25 +1064,25 @@ function IdentityMenu({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, co
|
|
|
1031
1064
|
);
|
|
1032
1065
|
}
|
|
1033
1066
|
function Note({ children }) {
|
|
1034
|
-
return /* @__PURE__ */
|
|
1067
|
+
return /* @__PURE__ */ jsx19("span", { className: "px-2 pb-1.5 text-caption text-text-secondary", children });
|
|
1035
1068
|
}
|
|
1036
1069
|
|
|
1037
1070
|
// src/Field.tsx
|
|
1038
1071
|
import { cloneElement, isValidElement } from "react";
|
|
1039
1072
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
1040
|
-
import { jsx as
|
|
1073
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1041
1074
|
function Field({ label, required = false, helper, error, children }) {
|
|
1042
1075
|
const control = required && isValidElement(children) ? cloneElement(children, {
|
|
1043
1076
|
"aria-required": children.props["aria-required"] ?? true
|
|
1044
1077
|
}) : children;
|
|
1045
|
-
return /* @__PURE__ */
|
|
1046
|
-
/* @__PURE__ */
|
|
1078
|
+
return /* @__PURE__ */ jsxs14(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1079
|
+
/* @__PURE__ */ jsxs14(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1047
1080
|
label,
|
|
1048
|
-
required && /* @__PURE__ */
|
|
1081
|
+
required && /* @__PURE__ */ jsx20("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1049
1082
|
] }),
|
|
1050
|
-
/* @__PURE__ */
|
|
1083
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex flex-col gap-1.5", children: [
|
|
1051
1084
|
control,
|
|
1052
|
-
error != null ? /* @__PURE__ */
|
|
1085
|
+
error != null ? /* @__PURE__ */ jsx20(BaseField.Error, { match: true, className: "text-caption text-error-default", children: error }) : helper != null ? /* @__PURE__ */ jsx20(BaseField.Description, { className: "text-caption text-text-muted", children: helper }) : null
|
|
1053
1086
|
] })
|
|
1054
1087
|
] });
|
|
1055
1088
|
}
|
|
@@ -1057,12 +1090,12 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1057
1090
|
// src/Select.tsx
|
|
1058
1091
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
1059
1092
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
1060
|
-
import { jsx as
|
|
1093
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1061
1094
|
var GAP4 = 4;
|
|
1062
1095
|
var VIEWPORT_PAD3 = 8;
|
|
1063
1096
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, className, ...aria }) {
|
|
1064
1097
|
const selected = options.find((o) => o.value === value);
|
|
1065
|
-
return /* @__PURE__ */
|
|
1098
|
+
return /* @__PURE__ */ jsxs15(
|
|
1066
1099
|
BaseSelect.Root,
|
|
1067
1100
|
{
|
|
1068
1101
|
value,
|
|
@@ -1070,7 +1103,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1070
1103
|
disabled,
|
|
1071
1104
|
modal: false,
|
|
1072
1105
|
children: [
|
|
1073
|
-
/* @__PURE__ */
|
|
1106
|
+
/* @__PURE__ */ jsxs15(
|
|
1074
1107
|
BaseSelect.Trigger,
|
|
1075
1108
|
{
|
|
1076
1109
|
"aria-label": ariaLabel,
|
|
@@ -1097,20 +1130,20 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1097
1130
|
className
|
|
1098
1131
|
),
|
|
1099
1132
|
children: [
|
|
1100
|
-
/* @__PURE__ */
|
|
1101
|
-
selected?.leading && /* @__PURE__ */
|
|
1102
|
-
/* @__PURE__ */
|
|
1133
|
+
/* @__PURE__ */ jsxs15("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
1134
|
+
selected?.leading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
1135
|
+
/* @__PURE__ */ jsx21(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
1103
1136
|
] }),
|
|
1104
|
-
/* @__PURE__ */
|
|
1137
|
+
/* @__PURE__ */ jsx21(
|
|
1105
1138
|
BaseSelect.Icon,
|
|
1106
1139
|
{
|
|
1107
|
-
render: /* @__PURE__ */
|
|
1140
|
+
render: /* @__PURE__ */ jsx21(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
1108
1141
|
}
|
|
1109
1142
|
)
|
|
1110
1143
|
]
|
|
1111
1144
|
}
|
|
1112
1145
|
),
|
|
1113
|
-
/* @__PURE__ */
|
|
1146
|
+
/* @__PURE__ */ jsx21(BaseSelect.Portal, { children: /* @__PURE__ */ jsx21(
|
|
1114
1147
|
BaseSelect.Positioner,
|
|
1115
1148
|
{
|
|
1116
1149
|
side: "bottom",
|
|
@@ -1119,30 +1152,30 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1119
1152
|
collisionPadding: VIEWPORT_PAD3,
|
|
1120
1153
|
alignItemWithTrigger: false,
|
|
1121
1154
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1122
|
-
children: /* @__PURE__ */
|
|
1155
|
+
children: /* @__PURE__ */ jsx21(
|
|
1123
1156
|
BaseSelect.Popup,
|
|
1124
1157
|
{
|
|
1125
|
-
className: "
|
|
1126
|
-
children: options.map((option) => /* @__PURE__ */
|
|
1158
|
+
className: "min-w-[var(--anchor-width)] rounded-lg border border-border-default bg-bg-elevated p-1 shadow-lg",
|
|
1159
|
+
children: /* @__PURE__ */ jsx21(ScrollArea, { viewportClassName: "max-h-[calc(min(288px,var(--available-height))_-_0.5rem)]", contentClassName: "flex flex-col", children: options.map((option) => /* @__PURE__ */ jsxs15(
|
|
1127
1160
|
BaseSelect.Item,
|
|
1128
1161
|
{
|
|
1129
1162
|
value: option.value,
|
|
1130
1163
|
className: "flex h-9 cursor-pointer items-center justify-between gap-2 rounded-lg px-3 text-[14px] font-normal leading-[1.4] text-text-primary transition-colors data-[highlighted]:bg-bg-hover data-[selected]:font-medium",
|
|
1131
1164
|
children: [
|
|
1132
|
-
/* @__PURE__ */
|
|
1133
|
-
option.leading && /* @__PURE__ */
|
|
1134
|
-
/* @__PURE__ */
|
|
1165
|
+
/* @__PURE__ */ jsxs15("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1166
|
+
option.leading && /* @__PURE__ */ jsx21("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
1167
|
+
/* @__PURE__ */ jsx21(BaseSelect.ItemText, { className: "truncate", children: option.label })
|
|
1135
1168
|
] }),
|
|
1136
|
-
/* @__PURE__ */
|
|
1169
|
+
/* @__PURE__ */ jsx21(
|
|
1137
1170
|
BaseSelect.ItemIndicator,
|
|
1138
1171
|
{
|
|
1139
|
-
render: /* @__PURE__ */
|
|
1172
|
+
render: /* @__PURE__ */ jsx21(IconCheck2, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
1140
1173
|
}
|
|
1141
1174
|
)
|
|
1142
1175
|
]
|
|
1143
1176
|
},
|
|
1144
1177
|
option.value
|
|
1145
|
-
))
|
|
1178
|
+
)) })
|
|
1146
1179
|
}
|
|
1147
1180
|
)
|
|
1148
1181
|
}
|
|
@@ -1155,9 +1188,9 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1155
1188
|
// src/TextInput.tsx
|
|
1156
1189
|
import { forwardRef } from "react";
|
|
1157
1190
|
import { Input } from "@base-ui/react/input";
|
|
1158
|
-
import { jsx as
|
|
1191
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1159
1192
|
var TextInput = forwardRef(function TextInput2({ className, type = "text", ...props }, ref) {
|
|
1160
|
-
return /* @__PURE__ */
|
|
1193
|
+
return /* @__PURE__ */ jsx22(
|
|
1161
1194
|
Input,
|
|
1162
1195
|
{
|
|
1163
1196
|
ref,
|
|
@@ -1178,13 +1211,13 @@ var TextInput = forwardRef(function TextInput2({ className, type = "text", ...pr
|
|
|
1178
1211
|
// src/Textarea.tsx
|
|
1179
1212
|
import { forwardRef as forwardRef2 } from "react";
|
|
1180
1213
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1181
|
-
import { jsx as
|
|
1214
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
1182
1215
|
var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
|
|
1183
|
-
return /* @__PURE__ */
|
|
1216
|
+
return /* @__PURE__ */ jsx23(
|
|
1184
1217
|
BaseField2.Control,
|
|
1185
1218
|
{
|
|
1186
1219
|
ref,
|
|
1187
|
-
render: /* @__PURE__ */
|
|
1220
|
+
render: /* @__PURE__ */ jsx23("textarea", {}),
|
|
1188
1221
|
className: cn(
|
|
1189
1222
|
"bg-bg-inset border border-border-default focus:border-border-focus rounded-lg px-3 py-2",
|
|
1190
1223
|
"text-[14px] leading-[1.4] font-normal text-text-primary placeholder:text-text-muted",
|
|
@@ -1206,20 +1239,20 @@ import { useRef as useRef3 } from "react";
|
|
|
1206
1239
|
import { Dialog } from "@base-ui/react/dialog";
|
|
1207
1240
|
import { AlertDialog } from "@base-ui/react/alert-dialog";
|
|
1208
1241
|
import { IconX as IconX3 } from "@tabler/icons-react";
|
|
1209
|
-
import { jsx as
|
|
1242
|
+
import { jsx as jsx24, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1210
1243
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, width = 502, alert = false }) {
|
|
1211
1244
|
const Parts = alert ? AlertDialog : Dialog;
|
|
1212
1245
|
const popupRef = useRef3(null);
|
|
1213
|
-
return /* @__PURE__ */
|
|
1246
|
+
return /* @__PURE__ */ jsx24(
|
|
1214
1247
|
Parts.Root,
|
|
1215
1248
|
{
|
|
1216
1249
|
open: true,
|
|
1217
1250
|
onOpenChange: (open) => {
|
|
1218
1251
|
if (!open) onClose();
|
|
1219
1252
|
},
|
|
1220
|
-
children: /* @__PURE__ */
|
|
1221
|
-
/* @__PURE__ */
|
|
1222
|
-
/* @__PURE__ */
|
|
1253
|
+
children: /* @__PURE__ */ jsxs16(Parts.Portal, { children: [
|
|
1254
|
+
/* @__PURE__ */ jsx24(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1255
|
+
/* @__PURE__ */ jsx24("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs16(
|
|
1223
1256
|
Parts.Popup,
|
|
1224
1257
|
{
|
|
1225
1258
|
ref: popupRef,
|
|
@@ -1228,17 +1261,17 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1228
1261
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
1229
1262
|
style: { width },
|
|
1230
1263
|
children: [
|
|
1231
|
-
/* @__PURE__ */
|
|
1232
|
-
headerContent ?? /* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1264
|
+
/* @__PURE__ */ jsxs16("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
|
|
1265
|
+
headerContent ?? /* @__PURE__ */ jsx24(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx24("span", {}), children: title }),
|
|
1266
|
+
/* @__PURE__ */ jsx24(
|
|
1234
1267
|
Parts.Close,
|
|
1235
1268
|
{
|
|
1236
|
-
render: /* @__PURE__ */
|
|
1269
|
+
render: /* @__PURE__ */ jsx24(IconButton, { tooltip: "Close", "aria-label": "Close", children: /* @__PURE__ */ jsx24(IconX3, { size: 16, stroke: 1.5 }) })
|
|
1237
1270
|
}
|
|
1238
1271
|
)
|
|
1239
1272
|
] }),
|
|
1240
|
-
/* @__PURE__ */
|
|
1241
|
-
footer != null && /* @__PURE__ */
|
|
1273
|
+
/* @__PURE__ */ jsx24("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
1274
|
+
footer != null && /* @__PURE__ */ jsx24("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
1242
1275
|
]
|
|
1243
1276
|
}
|
|
1244
1277
|
) })
|
|
@@ -1248,7 +1281,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1248
1281
|
}
|
|
1249
1282
|
|
|
1250
1283
|
// src/ConfirmDialog.tsx
|
|
1251
|
-
import { Fragment as Fragment3, jsx as
|
|
1284
|
+
import { Fragment as Fragment3, jsx as jsx25, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1252
1285
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
1253
1286
|
const [busy, setBusy] = useState3(false);
|
|
1254
1287
|
const confirm = async () => {
|
|
@@ -1260,16 +1293,16 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
1260
1293
|
setBusy(false);
|
|
1261
1294
|
}
|
|
1262
1295
|
};
|
|
1263
|
-
return /* @__PURE__ */
|
|
1296
|
+
return /* @__PURE__ */ jsx25(
|
|
1264
1297
|
DialogShell,
|
|
1265
1298
|
{
|
|
1266
1299
|
alert: true,
|
|
1267
1300
|
title,
|
|
1268
1301
|
onClose,
|
|
1269
1302
|
bodyClassName: "flex flex-col gap-3 text-body-2 text-text-primary",
|
|
1270
|
-
footer: /* @__PURE__ */
|
|
1271
|
-
/* @__PURE__ */
|
|
1272
|
-
/* @__PURE__ */
|
|
1303
|
+
footer: /* @__PURE__ */ jsxs17(Fragment3, { children: [
|
|
1304
|
+
/* @__PURE__ */ jsx25(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
1305
|
+
/* @__PURE__ */ jsx25(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
1273
1306
|
] }),
|
|
1274
1307
|
children
|
|
1275
1308
|
}
|
|
@@ -1280,7 +1313,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
1280
1313
|
import { useEffect as useEffect2, useRef as useRef4, useState as useState4 } from "react";
|
|
1281
1314
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
1282
1315
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
1283
|
-
import { jsx as
|
|
1316
|
+
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1284
1317
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
1285
1318
|
const [editing, setEditing] = useState4(false);
|
|
1286
1319
|
const [draft, setDraft] = useState4(value);
|
|
@@ -1338,7 +1371,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1338
1371
|
written and never read. Read-only, this is a line of text: whatever
|
|
1339
1372
|
names the region around it (a `Field`, a `Property`) names this too.
|
|
1340
1373
|
*/
|
|
1341
|
-
/* @__PURE__ */
|
|
1374
|
+
/* @__PURE__ */ jsx26(
|
|
1342
1375
|
"div",
|
|
1343
1376
|
{
|
|
1344
1377
|
className: cn("w-full px-2 py-1", multiline && !displayNode && "whitespace-pre-wrap", display ?? value ? "text-text-primary" : "text-text-muted", className),
|
|
@@ -1348,11 +1381,11 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1348
1381
|
);
|
|
1349
1382
|
}
|
|
1350
1383
|
if (editing) {
|
|
1351
|
-
return multiline ? /* @__PURE__ */
|
|
1384
|
+
return multiline ? /* @__PURE__ */ jsx26(
|
|
1352
1385
|
BaseField3.Control,
|
|
1353
1386
|
{
|
|
1354
1387
|
ref: fieldRef,
|
|
1355
|
-
render: /* @__PURE__ */
|
|
1388
|
+
render: /* @__PURE__ */ jsx26("textarea", { rows: 4 }),
|
|
1356
1389
|
"aria-label": label,
|
|
1357
1390
|
value: draft,
|
|
1358
1391
|
disabled: busy,
|
|
@@ -1361,7 +1394,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1361
1394
|
onBlur: () => void commit(),
|
|
1362
1395
|
className: fieldClass
|
|
1363
1396
|
}
|
|
1364
|
-
) : /* @__PURE__ */
|
|
1397
|
+
) : /* @__PURE__ */ jsx26(
|
|
1365
1398
|
Input2,
|
|
1366
1399
|
{
|
|
1367
1400
|
ref: fieldRef,
|
|
@@ -1375,7 +1408,7 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1375
1408
|
}
|
|
1376
1409
|
);
|
|
1377
1410
|
}
|
|
1378
|
-
return /* @__PURE__ */
|
|
1411
|
+
return /* @__PURE__ */ jsx26(
|
|
1379
1412
|
"button",
|
|
1380
1413
|
{
|
|
1381
1414
|
type: "button",
|
|
@@ -1394,33 +1427,33 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1394
1427
|
|
|
1395
1428
|
// src/EmptyState.tsx
|
|
1396
1429
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1397
|
-
import { jsx as
|
|
1430
|
+
import { jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1398
1431
|
function EmptyState({ icon, message, className }) {
|
|
1399
|
-
return /* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1432
|
+
return /* @__PURE__ */ jsxs18("div", { className: cn("flex flex-col gap-2 items-center", className), children: [
|
|
1433
|
+
/* @__PURE__ */ jsx27("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx27(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1434
|
+
/* @__PURE__ */ jsx27("p", { className: "text-body-2 text-text-secondary text-center", children: message })
|
|
1402
1435
|
] });
|
|
1403
1436
|
}
|
|
1404
1437
|
|
|
1405
1438
|
// src/Skeleton.tsx
|
|
1406
|
-
import { jsx as
|
|
1439
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1407
1440
|
function SkeletonBar({ className, style }) {
|
|
1408
|
-
return /* @__PURE__ */
|
|
1441
|
+
return /* @__PURE__ */ jsx28("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1409
1442
|
}
|
|
1410
1443
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1411
1444
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1412
|
-
return /* @__PURE__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
1445
|
+
return /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1446
|
+
/* @__PURE__ */ jsx28(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1447
|
+
/* @__PURE__ */ jsx28(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1415
1448
|
] });
|
|
1416
1449
|
}
|
|
1417
1450
|
function SkeletonList({ rows = 8, className }) {
|
|
1418
|
-
return /* @__PURE__ */
|
|
1451
|
+
return /* @__PURE__ */ jsx28("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx28(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
|
|
1419
1452
|
}
|
|
1420
1453
|
|
|
1421
1454
|
// src/Breadcrumb.tsx
|
|
1422
1455
|
import { Fragment as Fragment4, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState5 } from "react";
|
|
1423
|
-
import { jsx as
|
|
1456
|
+
import { jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1424
1457
|
function Breadcrumb({ items, className }) {
|
|
1425
1458
|
const navRef = useRef5(null);
|
|
1426
1459
|
const labelRefs = useRef5([]);
|
|
@@ -1440,7 +1473,7 @@ function Breadcrumb({ items, className }) {
|
|
|
1440
1473
|
observer.observe(nav);
|
|
1441
1474
|
return () => observer.disconnect();
|
|
1442
1475
|
}, [measure, items]);
|
|
1443
|
-
return /* @__PURE__ */
|
|
1476
|
+
return /* @__PURE__ */ jsx29("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-[14px] leading-[140%]", className), children: items.map((item, index) => {
|
|
1444
1477
|
const last = index === items.length - 1;
|
|
1445
1478
|
const text = cn(
|
|
1446
1479
|
"truncate",
|
|
@@ -1453,23 +1486,23 @@ function Breadcrumb({ items, className }) {
|
|
|
1453
1486
|
const setLabelRef = (el) => {
|
|
1454
1487
|
labelRefs.current[index] = el;
|
|
1455
1488
|
};
|
|
1456
|
-
const crumb = item.href ? /* @__PURE__ */
|
|
1457
|
-
return /* @__PURE__ */
|
|
1458
|
-
index > 0 && /* @__PURE__ */
|
|
1489
|
+
const crumb = item.href ? /* @__PURE__ */ jsx29("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx29("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
1490
|
+
return /* @__PURE__ */ jsxs20(Fragment4, { children: [
|
|
1491
|
+
index > 0 && /* @__PURE__ */ jsx29("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
1459
1492
|
truncated.has(index) ? (
|
|
1460
1493
|
// `min-w-0 shrink` undoes the wrapper's own shrink-0 — the crumb
|
|
1461
1494
|
// must keep truncating inside it, or wrapping it would widen the
|
|
1462
1495
|
// trail and the tooltip would never be needed again.
|
|
1463
|
-
/* @__PURE__ */
|
|
1496
|
+
/* @__PURE__ */ jsx29(WithTooltip, { label: item.label, wrapperClassName: "min-w-0 shrink", children: crumb })
|
|
1464
1497
|
) : crumb
|
|
1465
1498
|
] }, `${item.label}-${index}`);
|
|
1466
1499
|
}) });
|
|
1467
1500
|
}
|
|
1468
1501
|
|
|
1469
1502
|
// src/NavItem.tsx
|
|
1470
|
-
import { jsx as
|
|
1503
|
+
import { jsx as jsx30, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1471
1504
|
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
1472
|
-
return /* @__PURE__ */
|
|
1505
|
+
return /* @__PURE__ */ jsxs21(
|
|
1473
1506
|
"a",
|
|
1474
1507
|
{
|
|
1475
1508
|
href,
|
|
@@ -1484,9 +1517,9 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
1484
1517
|
),
|
|
1485
1518
|
...props,
|
|
1486
1519
|
children: [
|
|
1487
|
-
icon && /* @__PURE__ */
|
|
1488
|
-
/* @__PURE__ */
|
|
1489
|
-
count ? /* @__PURE__ */
|
|
1520
|
+
icon && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
1521
|
+
/* @__PURE__ */ jsx30("span", { className: "flex-1 truncate", children: label }),
|
|
1522
|
+
count ? /* @__PURE__ */ jsx30(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx30("span", { className: "shrink-0 font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
1490
1523
|
]
|
|
1491
1524
|
}
|
|
1492
1525
|
);
|
|
@@ -1495,7 +1528,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
1495
1528
|
// src/Popover.tsx
|
|
1496
1529
|
import { useMemo as useMemo2 } from "react";
|
|
1497
1530
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
1498
|
-
import { jsx as
|
|
1531
|
+
import { jsx as jsx31, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1499
1532
|
var GAP5 = 4;
|
|
1500
1533
|
var VIEWPORT_PAD4 = 8;
|
|
1501
1534
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className }) {
|
|
@@ -1504,7 +1537,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1504
1537
|
if (anchor instanceof Element) return anchor;
|
|
1505
1538
|
return { getBoundingClientRect: () => anchor };
|
|
1506
1539
|
}, [anchor]);
|
|
1507
|
-
return /* @__PURE__ */
|
|
1540
|
+
return /* @__PURE__ */ jsxs22(
|
|
1508
1541
|
BasePopover.Root,
|
|
1509
1542
|
{
|
|
1510
1543
|
open,
|
|
@@ -1512,8 +1545,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1512
1545
|
actionsRef,
|
|
1513
1546
|
modal: false,
|
|
1514
1547
|
children: [
|
|
1515
|
-
trigger && /* @__PURE__ */
|
|
1516
|
-
/* @__PURE__ */
|
|
1548
|
+
trigger && /* @__PURE__ */ jsx31(BasePopover.Trigger, { render: trigger, disabled: triggerDisabled(trigger) }),
|
|
1549
|
+
/* @__PURE__ */ jsx31(BasePopover.Portal, { children: /* @__PURE__ */ jsx31(
|
|
1517
1550
|
BasePopover.Positioner,
|
|
1518
1551
|
{
|
|
1519
1552
|
anchor: anchorTarget,
|
|
@@ -1522,15 +1555,15 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1522
1555
|
sideOffset: GAP5,
|
|
1523
1556
|
collisionPadding: VIEWPORT_PAD4,
|
|
1524
1557
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1525
|
-
children: /* @__PURE__ */
|
|
1558
|
+
children: /* @__PURE__ */ jsx31(
|
|
1526
1559
|
BasePopover.Popup,
|
|
1527
1560
|
{
|
|
1528
1561
|
"aria-label": ariaLabel,
|
|
1529
1562
|
initialFocus: trigger ? void 0 : false,
|
|
1530
1563
|
finalFocus,
|
|
1531
|
-
className: cn("min-w-[180px]
|
|
1532
|
-
render: /* @__PURE__ */
|
|
1533
|
-
children
|
|
1564
|
+
className: cn("min-w-[180px] outline-none", className),
|
|
1565
|
+
render: /* @__PURE__ */ jsx31(MenuPanel, {}),
|
|
1566
|
+
children: /* @__PURE__ */ jsx31(ScrollArea, { viewportClassName: "max-h-[calc(var(--available-height)_-_1rem)]", contentClassName: "flex flex-col [&>[role=separator]]:mx-0", children })
|
|
1534
1567
|
}
|
|
1535
1568
|
)
|
|
1536
1569
|
}
|
|
@@ -1542,9 +1575,9 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1542
1575
|
|
|
1543
1576
|
// src/Toolbar.tsx
|
|
1544
1577
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
1545
|
-
import { jsx as
|
|
1578
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
1546
1579
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
1547
|
-
const strip = /* @__PURE__ */
|
|
1580
|
+
const strip = /* @__PURE__ */ jsx32(
|
|
1548
1581
|
BaseToolbar.Root,
|
|
1549
1582
|
{
|
|
1550
1583
|
"aria-label": ariaLabel,
|
|
@@ -1555,24 +1588,24 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
1555
1588
|
}
|
|
1556
1589
|
);
|
|
1557
1590
|
if (!surface) return strip;
|
|
1558
|
-
return /* @__PURE__ */
|
|
1591
|
+
return /* @__PURE__ */ jsx32(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
1559
1592
|
}
|
|
1560
1593
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
1561
|
-
return /* @__PURE__ */
|
|
1594
|
+
return /* @__PURE__ */ jsx32(
|
|
1562
1595
|
BaseToolbar.Button,
|
|
1563
1596
|
{
|
|
1564
1597
|
ref,
|
|
1565
1598
|
disabled: disabled || !!disabledReason,
|
|
1566
1599
|
focusableWhenDisabled: true,
|
|
1567
|
-
render: /* @__PURE__ */
|
|
1600
|
+
render: /* @__PURE__ */ jsx32(IconButton, { disabled, disabledReason, ...props })
|
|
1568
1601
|
}
|
|
1569
1602
|
);
|
|
1570
1603
|
}
|
|
1571
1604
|
function ToolbarInput(props) {
|
|
1572
|
-
return /* @__PURE__ */
|
|
1605
|
+
return /* @__PURE__ */ jsx32(BaseToolbar.Input, { render: /* @__PURE__ */ jsx32(TextInput, {}), ...props });
|
|
1573
1606
|
}
|
|
1574
1607
|
function ToolbarSeparator({ className }) {
|
|
1575
|
-
return /* @__PURE__ */
|
|
1608
|
+
return /* @__PURE__ */ jsx32(
|
|
1576
1609
|
BaseToolbar.Separator,
|
|
1577
1610
|
{
|
|
1578
1611
|
orientation: "vertical",
|
|
@@ -1582,9 +1615,9 @@ function ToolbarSeparator({ className }) {
|
|
|
1582
1615
|
}
|
|
1583
1616
|
|
|
1584
1617
|
// src/ReactionPicker.tsx
|
|
1585
|
-
import { jsx as
|
|
1618
|
+
import { jsx as jsx33 } from "react/jsx-runtime";
|
|
1586
1619
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
1587
|
-
return /* @__PURE__ */
|
|
1620
|
+
return /* @__PURE__ */ jsx33(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
1588
1621
|
/*
|
|
1589
1622
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
1590
1623
|
would become the toolbar's item and the button inside it would never
|
|
@@ -1594,14 +1627,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
1594
1627
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
1595
1628
|
and both say the meaning rather than the glyph.
|
|
1596
1629
|
*/
|
|
1597
|
-
/* @__PURE__ */
|
|
1630
|
+
/* @__PURE__ */ jsx33(
|
|
1598
1631
|
ToolbarButton,
|
|
1599
1632
|
{
|
|
1600
1633
|
"aria-label": option.label,
|
|
1601
1634
|
tooltip: option.label,
|
|
1602
1635
|
onClick: () => onSelect(option.emoji),
|
|
1603
1636
|
className: "size-7 text-[18px] leading-none",
|
|
1604
|
-
children: /* @__PURE__ */
|
|
1637
|
+
children: /* @__PURE__ */ jsx33("span", { "aria-hidden": "true", children: option.emoji })
|
|
1605
1638
|
},
|
|
1606
1639
|
option.emoji
|
|
1607
1640
|
)
|
|
@@ -1610,23 +1643,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
1610
1643
|
|
|
1611
1644
|
// src/PreviewCard.tsx
|
|
1612
1645
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
1613
|
-
import { jsx as
|
|
1646
|
+
import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1614
1647
|
var GAP6 = 12;
|
|
1615
1648
|
var VIEWPORT_PAD5 = 8;
|
|
1616
1649
|
var OPEN_DELAY2 = 350;
|
|
1617
1650
|
var CLOSE_DELAY = 200;
|
|
1618
1651
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, wrapperClassName }) {
|
|
1619
|
-
return /* @__PURE__ */
|
|
1620
|
-
/* @__PURE__ */
|
|
1652
|
+
return /* @__PURE__ */ jsxs23(BasePreviewCard.Root, { children: [
|
|
1653
|
+
/* @__PURE__ */ jsx34(
|
|
1621
1654
|
BasePreviewCard.Trigger,
|
|
1622
1655
|
{
|
|
1623
1656
|
delay,
|
|
1624
1657
|
closeDelay,
|
|
1625
|
-
render: /* @__PURE__ */
|
|
1658
|
+
render: /* @__PURE__ */ jsx34("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
1626
1659
|
children
|
|
1627
1660
|
}
|
|
1628
1661
|
),
|
|
1629
|
-
/* @__PURE__ */
|
|
1662
|
+
/* @__PURE__ */ jsx34(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx34(
|
|
1630
1663
|
BasePreviewCard.Positioner,
|
|
1631
1664
|
{
|
|
1632
1665
|
side,
|
|
@@ -1634,12 +1667,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
1634
1667
|
sideOffset: GAP6,
|
|
1635
1668
|
collisionPadding: VIEWPORT_PAD5,
|
|
1636
1669
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1637
|
-
children: /* @__PURE__ */
|
|
1670
|
+
children: /* @__PURE__ */ jsx34(
|
|
1638
1671
|
BasePreviewCard.Popup,
|
|
1639
1672
|
{
|
|
1640
|
-
className: cn("w-[360px]
|
|
1641
|
-
render: /* @__PURE__ */
|
|
1642
|
-
children: content
|
|
1673
|
+
className: cn("w-[360px] p-3 outline-none", className),
|
|
1674
|
+
render: /* @__PURE__ */ jsx34(MenuPanel, {}),
|
|
1675
|
+
children: /* @__PURE__ */ jsx34(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3 [&>*]:shrink-0", children: content })
|
|
1643
1676
|
}
|
|
1644
1677
|
)
|
|
1645
1678
|
}
|
|
@@ -1648,15 +1681,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
1648
1681
|
}
|
|
1649
1682
|
|
|
1650
1683
|
// src/Rail.tsx
|
|
1651
|
-
import { jsx as
|
|
1684
|
+
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1652
1685
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
1653
|
-
return /* @__PURE__ */
|
|
1686
|
+
return /* @__PURE__ */ jsx35("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
1654
1687
|
}
|
|
1655
1688
|
|
|
1656
1689
|
// src/RailItem.tsx
|
|
1657
|
-
import { jsx as
|
|
1690
|
+
import { jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1658
1691
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
1659
|
-
return /* @__PURE__ */
|
|
1692
|
+
return /* @__PURE__ */ jsxs24(
|
|
1660
1693
|
"a",
|
|
1661
1694
|
{
|
|
1662
1695
|
href,
|
|
@@ -1664,14 +1697,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
1664
1697
|
className: cn("group flex w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
1665
1698
|
...props,
|
|
1666
1699
|
children: [
|
|
1667
|
-
/* @__PURE__ */
|
|
1700
|
+
/* @__PURE__ */ jsx36(
|
|
1668
1701
|
"div",
|
|
1669
1702
|
{
|
|
1670
1703
|
className: cn(
|
|
1671
1704
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
1672
1705
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
1673
1706
|
),
|
|
1674
|
-
children: /* @__PURE__ */
|
|
1707
|
+
children: /* @__PURE__ */ jsx36(
|
|
1675
1708
|
"span",
|
|
1676
1709
|
{
|
|
1677
1710
|
className: cn(
|
|
@@ -1683,52 +1716,49 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
1683
1716
|
)
|
|
1684
1717
|
}
|
|
1685
1718
|
),
|
|
1686
|
-
/* @__PURE__ */
|
|
1719
|
+
/* @__PURE__ */ jsx36("span", { className: cn("text-center text-[9px] font-medium leading-[115%]", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
1687
1720
|
]
|
|
1688
1721
|
}
|
|
1689
1722
|
);
|
|
1690
1723
|
}
|
|
1691
1724
|
|
|
1692
1725
|
// src/Sidebar.tsx
|
|
1693
|
-
import { jsx as
|
|
1726
|
+
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
1694
1727
|
function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className }) {
|
|
1695
|
-
return /* @__PURE__ */
|
|
1728
|
+
return /* @__PURE__ */ jsx37(
|
|
1696
1729
|
"nav",
|
|
1697
1730
|
{
|
|
1698
1731
|
"aria-label": ariaLabel,
|
|
1699
|
-
className: cn(
|
|
1700
|
-
|
|
1701
|
-
className
|
|
1702
|
-
),
|
|
1703
|
-
children
|
|
1732
|
+
className: cn("flex w-60 shrink-0 flex-col border-r border-border-default bg-bg-surface", className),
|
|
1733
|
+
children: /* @__PURE__ */ jsx37(ScrollArea, { className: "min-h-0 flex-1", contentClassName: "flex flex-col gap-px px-2.5 py-3", children })
|
|
1704
1734
|
}
|
|
1705
1735
|
);
|
|
1706
1736
|
}
|
|
1707
1737
|
|
|
1708
1738
|
// src/Property.tsx
|
|
1709
|
-
import { jsx as
|
|
1739
|
+
import { jsx as jsx38, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1710
1740
|
function Property({ label, layout = "row", children, className }) {
|
|
1711
1741
|
if (layout === "stacked") {
|
|
1712
1742
|
return (
|
|
1713
1743
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
1714
1744
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
1715
1745
|
// 6px, and unifying means the bigger, calmer one.
|
|
1716
|
-
/* @__PURE__ */
|
|
1717
|
-
/* @__PURE__ */
|
|
1746
|
+
/* @__PURE__ */ jsxs25("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
1747
|
+
/* @__PURE__ */ jsx38("span", { className: "text-menu uppercase tracking-[0.08em] text-text-secondary", children: label }),
|
|
1718
1748
|
children
|
|
1719
1749
|
] })
|
|
1720
1750
|
);
|
|
1721
1751
|
}
|
|
1722
|
-
return /* @__PURE__ */
|
|
1723
|
-
/* @__PURE__ */
|
|
1752
|
+
return /* @__PURE__ */ jsxs25("div", { className: cn("flex items-center gap-2", className), children: [
|
|
1753
|
+
/* @__PURE__ */ jsx38("span", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
1724
1754
|
children
|
|
1725
1755
|
] });
|
|
1726
1756
|
}
|
|
1727
1757
|
|
|
1728
1758
|
// src/Reaction.tsx
|
|
1729
|
-
import { jsx as
|
|
1759
|
+
import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
1730
1760
|
function Reaction({ emoji, count, pressed = false, className, type, ...props }) {
|
|
1731
|
-
return /* @__PURE__ */
|
|
1761
|
+
return /* @__PURE__ */ jsxs26(
|
|
1732
1762
|
"button",
|
|
1733
1763
|
{
|
|
1734
1764
|
type: type ?? "button",
|
|
@@ -1739,13 +1769,20 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
|
|
|
1739
1769
|
"inline-flex h-6 items-center justify-center gap-1.5 rounded-full px-2",
|
|
1740
1770
|
"border transition-colors",
|
|
1741
1771
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
1742
|
-
pressed ?
|
|
1772
|
+
pressed ? (
|
|
1773
|
+
/* In the ship theme the accent on its own wash measures 2.70:1
|
|
1774
|
+
(Finding 4), and the count was the thing that vanished
|
|
1775
|
+
(Katerina, 2026-09-08). The number reads in the text colour
|
|
1776
|
+
there; the accent keeps the edge and the fill. Signal keeps
|
|
1777
|
+
Peek's blue-on-wash, which reads. */
|
|
1778
|
+
"border-accent-primary bg-accent-muted text-accent-primary hover:border-accent-hover ship:text-text-primary"
|
|
1779
|
+
) : "border-border-default bg-bg-inset text-text-primary hover:border-border-strong hover:bg-bg-hover",
|
|
1743
1780
|
className
|
|
1744
1781
|
),
|
|
1745
1782
|
...props,
|
|
1746
1783
|
children: [
|
|
1747
|
-
/* @__PURE__ */
|
|
1748
|
-
/* @__PURE__ */
|
|
1784
|
+
/* @__PURE__ */ jsx39("span", { "aria-hidden": "true", className: "shrink-0 text-[16px] leading-none", children: emoji }),
|
|
1785
|
+
/* @__PURE__ */ jsx39("span", { className: "text-chip signal:font-mono signal:text-[10px] signal:font-semibold signal:tabular-nums", children: count })
|
|
1749
1786
|
]
|
|
1750
1787
|
}
|
|
1751
1788
|
);
|
|
@@ -1754,9 +1791,9 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
|
|
|
1754
1791
|
// src/SearchInput.tsx
|
|
1755
1792
|
import "react";
|
|
1756
1793
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
1757
|
-
import { jsx as
|
|
1794
|
+
import { jsx as jsx40, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
1758
1795
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
1759
|
-
return /* @__PURE__ */
|
|
1796
|
+
return /* @__PURE__ */ jsxs27(
|
|
1760
1797
|
"div",
|
|
1761
1798
|
{
|
|
1762
1799
|
className: cn(
|
|
@@ -1766,7 +1803,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1766
1803
|
className
|
|
1767
1804
|
),
|
|
1768
1805
|
children: [
|
|
1769
|
-
/* @__PURE__ */
|
|
1806
|
+
/* @__PURE__ */ jsx40(
|
|
1770
1807
|
Input3,
|
|
1771
1808
|
{
|
|
1772
1809
|
className: "flex-1 min-w-0 bg-transparent text-input-value text-text-primary placeholder:text-text-muted outline-none",
|
|
@@ -1774,7 +1811,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1774
1811
|
...props
|
|
1775
1812
|
}
|
|
1776
1813
|
),
|
|
1777
|
-
shortcut && /* @__PURE__ */
|
|
1814
|
+
shortcut && /* @__PURE__ */ jsx40(Kbd, { children: shortcut })
|
|
1778
1815
|
]
|
|
1779
1816
|
}
|
|
1780
1817
|
);
|
|
@@ -1783,10 +1820,10 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
1783
1820
|
// src/SectionHeader.tsx
|
|
1784
1821
|
import { useState as useState6 } from "react";
|
|
1785
1822
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
1786
|
-
import { jsx as
|
|
1823
|
+
import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
1787
1824
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, actions, showActions = "hover", className }) {
|
|
1788
1825
|
const [isHovered, setIsHovered] = useState6(false);
|
|
1789
|
-
return /* @__PURE__ */
|
|
1826
|
+
return /* @__PURE__ */ jsxs28(
|
|
1790
1827
|
"div",
|
|
1791
1828
|
{
|
|
1792
1829
|
className: cn(
|
|
@@ -1799,8 +1836,8 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, ac
|
|
|
1799
1836
|
onMouseEnter: () => setIsHovered(true),
|
|
1800
1837
|
onMouseLeave: () => setIsHovered(false),
|
|
1801
1838
|
children: [
|
|
1802
|
-
/* @__PURE__ */
|
|
1803
|
-
chevron && /* @__PURE__ */
|
|
1839
|
+
/* @__PURE__ */ jsxs28("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
1840
|
+
chevron && /* @__PURE__ */ jsx41(
|
|
1804
1841
|
IconChevronRight2,
|
|
1805
1842
|
{
|
|
1806
1843
|
size: 12,
|
|
@@ -1808,9 +1845,9 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, ac
|
|
|
1808
1845
|
className: cn("text-text-secondary transition-transform duration-150", isExpanded && "rotate-90")
|
|
1809
1846
|
}
|
|
1810
1847
|
),
|
|
1811
|
-
/* @__PURE__ */
|
|
1848
|
+
/* @__PURE__ */ jsx41(SectionLabel, { children: title })
|
|
1812
1849
|
] }),
|
|
1813
|
-
(showActions === "always" || isHovered) && actions && actions.length > 0 && /* @__PURE__ */
|
|
1850
|
+
(showActions === "always" || isHovered) && actions && actions.length > 0 && /* @__PURE__ */ jsx41("div", { className: "flex items-center gap-1", children: actions.map((action) => /* @__PURE__ */ jsx41(
|
|
1814
1851
|
IconButton,
|
|
1815
1852
|
{
|
|
1816
1853
|
tooltip: action.tooltip,
|
|
@@ -1830,9 +1867,9 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, ac
|
|
|
1830
1867
|
|
|
1831
1868
|
// src/Tabs.tsx
|
|
1832
1869
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
1833
|
-
import { jsx as
|
|
1870
|
+
import { jsx as jsx42, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
1834
1871
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
1835
|
-
return /* @__PURE__ */
|
|
1872
|
+
return /* @__PURE__ */ jsx42(
|
|
1836
1873
|
BaseTabs.Root,
|
|
1837
1874
|
{
|
|
1838
1875
|
value: active,
|
|
@@ -1840,14 +1877,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1840
1877
|
if (details.reason === "none") onChange(value);
|
|
1841
1878
|
},
|
|
1842
1879
|
className,
|
|
1843
|
-
children: /* @__PURE__ */
|
|
1880
|
+
children: /* @__PURE__ */ jsx42(
|
|
1844
1881
|
BaseTabs.List,
|
|
1845
1882
|
{
|
|
1846
1883
|
activateOnFocus: true,
|
|
1847
1884
|
"aria-label": aria["aria-label"],
|
|
1848
1885
|
"aria-labelledby": aria["aria-labelledby"],
|
|
1849
1886
|
className: "flex items-center gap-2",
|
|
1850
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
1887
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs29(
|
|
1851
1888
|
BaseTabs.Tab,
|
|
1852
1889
|
{
|
|
1853
1890
|
value: tab.id,
|
|
@@ -1860,9 +1897,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1860
1897
|
),
|
|
1861
1898
|
children: [
|
|
1862
1899
|
tab.icon,
|
|
1863
|
-
/* @__PURE__ */
|
|
1900
|
+
/* @__PURE__ */ jsxs29("span", { className: "flex items-baseline", children: [
|
|
1864
1901
|
tab.label,
|
|
1865
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
1902
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx42("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
1866
1903
|
] })
|
|
1867
1904
|
]
|
|
1868
1905
|
},
|
|
@@ -1878,7 +1915,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
1878
1915
|
import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo3, useState as useState7 } from "react";
|
|
1879
1916
|
import { createPortal as createPortal2 } from "react-dom";
|
|
1880
1917
|
import { IconCircleCheck } from "@tabler/icons-react";
|
|
1881
|
-
import { jsx as
|
|
1918
|
+
import { jsx as jsx43, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
1882
1919
|
var SURFACE_STYLES = {
|
|
1883
1920
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
|
|
1884
1921
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-[shadow:var(--shadow-md)]",
|
|
@@ -1896,7 +1933,7 @@ var ACTION_BORDER_STYLES = {
|
|
|
1896
1933
|
};
|
|
1897
1934
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
1898
1935
|
const hasAction = !!(actionLabel && onAction);
|
|
1899
|
-
return /* @__PURE__ */
|
|
1936
|
+
return /* @__PURE__ */ jsxs30(
|
|
1900
1937
|
"div",
|
|
1901
1938
|
{
|
|
1902
1939
|
className: cn(
|
|
@@ -1908,11 +1945,11 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
1908
1945
|
className
|
|
1909
1946
|
),
|
|
1910
1947
|
children: [
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
leadingIcon && /* @__PURE__ */
|
|
1913
|
-
/* @__PURE__ */
|
|
1948
|
+
/* @__PURE__ */ jsxs30("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
1949
|
+
leadingIcon && /* @__PURE__ */ jsx43(IconCircleCheck, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
|
|
1950
|
+
/* @__PURE__ */ jsx43("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
|
|
1914
1951
|
] }),
|
|
1915
|
-
hasAction && /* @__PURE__ */
|
|
1952
|
+
hasAction && /* @__PURE__ */ jsx43(
|
|
1916
1953
|
"button",
|
|
1917
1954
|
{
|
|
1918
1955
|
type: "button",
|
|
@@ -1922,7 +1959,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
1922
1959
|
ACTION_BORDER_STYLES[type],
|
|
1923
1960
|
type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
|
|
1924
1961
|
),
|
|
1925
|
-
children: /* @__PURE__ */
|
|
1962
|
+
children: /* @__PURE__ */ jsx43("span", { className: "font-medium text-[12px] leading-[12px] text-text-primary whitespace-nowrap", children: actionLabel })
|
|
1926
1963
|
}
|
|
1927
1964
|
)
|
|
1928
1965
|
]
|
|
@@ -1949,10 +1986,10 @@ function ToastProvider({ children }) {
|
|
|
1949
1986
|
return () => clearTimeout(timer);
|
|
1950
1987
|
}, [toast]);
|
|
1951
1988
|
const value = useMemo3(() => ({ showToast, dismissToast }), [showToast, dismissToast]);
|
|
1952
|
-
return /* @__PURE__ */
|
|
1989
|
+
return /* @__PURE__ */ jsxs30(ToastContext.Provider, { value, children: [
|
|
1953
1990
|
children,
|
|
1954
1991
|
toast && createPortal2(
|
|
1955
|
-
/* @__PURE__ */
|
|
1992
|
+
/* @__PURE__ */ jsx43("div", { className: "fixed bottom-4 left-4 z-[100] pointer-events-none", children: /* @__PURE__ */ jsx43(
|
|
1956
1993
|
Toast,
|
|
1957
1994
|
{
|
|
1958
1995
|
className: "pointer-events-auto",
|
|
@@ -2013,6 +2050,7 @@ export {
|
|
|
2013
2050
|
RailItem,
|
|
2014
2051
|
Reaction,
|
|
2015
2052
|
ReactionPicker,
|
|
2053
|
+
ScrollArea,
|
|
2016
2054
|
SearchInput,
|
|
2017
2055
|
SectionHeader,
|
|
2018
2056
|
SectionLabel,
|