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