@estiva-app/ui 0.13.1 → 0.15.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/README.md +28 -0
- package/dist/Avatar.d.ts +1 -1
- package/dist/Avatar.d.ts.map +1 -1
- package/dist/AvatarGroup.d.ts.map +1 -1
- package/dist/ChipInput.d.ts +14 -1
- package/dist/ChipInput.d.ts.map +1 -1
- package/dist/Divider.d.ts +5 -2
- package/dist/Divider.d.ts.map +1 -1
- package/dist/EmptyState.d.ts +3 -0
- package/dist/EmptyState.d.ts.map +1 -1
- package/dist/Property.d.ts +7 -0
- package/dist/Property.d.ts.map +1 -1
- package/dist/Reaction.d.ts +12 -6
- package/dist/Reaction.d.ts.map +1 -1
- package/dist/TextInput.d.ts +10 -1
- package/dist/TextInput.d.ts.map +1 -1
- package/dist/Toast.d.ts +19 -6
- package/dist/Toast.d.ts.map +1 -1
- package/dist/Toolbar.d.ts +1 -1
- package/dist/Toolbar.d.ts.map +1 -1
- package/dist/eslint/escape.d.ts +61 -0
- package/dist/eslint/escape.d.ts.map +1 -0
- package/dist/eslint/index.d.ts +45 -0
- package/dist/eslint/index.d.ts.map +1 -0
- package/dist/eslint/index.js +118 -0
- package/dist/eslint/index.js.map +7 -0
- package/dist/eslint/no-raw-button.d.ts +11 -0
- package/dist/eslint/no-raw-button.d.ts.map +1 -0
- package/dist/index.js +276 -249
- package/dist/index.js.map +3 -3
- package/package.json +5 -1
- package/src/AttachmentCard.tsx +14 -14
- package/src/Avatar.mdx +7 -2
- package/src/Avatar.picture.test.tsx +60 -0
- package/src/Avatar.stories.tsx +1 -1
- package/src/Avatar.tsx +50 -14
- package/src/AvatarGroup.tsx +1 -0
- package/src/Breadcrumb.tsx +2 -2
- package/src/Checkbox.tsx +1 -1
- package/src/Chip.tsx +1 -1
- package/src/ChipInput.mdx +9 -0
- package/src/ChipInput.stories.tsx +18 -0
- package/src/ChipInput.test.tsx +18 -0
- package/src/ChipInput.tsx +18 -4
- package/src/DialogShell.stories.tsx +1 -1
- package/src/Divider.mdx +3 -2
- package/src/Divider.test.tsx +15 -0
- package/src/Divider.tsx +11 -9
- package/src/EditableText.stories.tsx +2 -2
- package/src/EmptyState.mdx +3 -2
- package/src/EmptyState.stories.tsx +7 -3
- package/src/EmptyState.test.tsx +15 -0
- package/src/EmptyState.tsx +4 -1
- package/src/IconButton.stories.tsx +1 -1
- package/src/Kbd.tsx +3 -3
- package/src/Menu.stories.tsx +2 -2
- package/src/Menu.tsx +3 -3
- package/src/Popover.stories.tsx +1 -1
- package/src/PreviewCard.stories.tsx +5 -5
- package/src/Property.mdx +8 -0
- package/src/Property.stories.tsx +4 -4
- package/src/Property.test.tsx +44 -0
- package/src/Property.tsx +23 -8
- package/src/RailItem.tsx +1 -1
- package/src/Reaction.mdx +14 -3
- package/src/Reaction.test.tsx +62 -0
- package/src/Reaction.tsx +21 -12
- package/src/ReactionPicker.tsx +1 -1
- package/src/SectionLabel.stories.tsx +1 -1
- package/src/SectionLabel.tsx +1 -1
- package/src/Select.test.tsx +20 -3
- package/src/Select.tsx +3 -3
- package/src/TextInput.mdx +6 -0
- package/src/TextInput.stories.tsx +45 -0
- package/src/TextInput.test.tsx +38 -0
- package/src/TextInput.tsx +16 -4
- package/src/Textarea.tsx +1 -1
- package/src/Toast.mdx +28 -4
- package/src/Toast.stories.tsx +12 -1
- package/src/Toast.test.tsx +137 -0
- package/src/Toast.tsx +127 -83
- package/src/Toolbar.tsx +4 -2
- package/src/cn.ts +1 -1
- package/src/eslint/escape.ts +112 -0
- package/src/eslint/index.test.ts +82 -0
- package/src/eslint/index.ts +100 -0
- package/src/eslint/no-raw-button.test.ts +118 -0
- package/src/eslint/no-raw-button.ts +39 -0
- package/stories/Choosing.mdx +1 -0
- package/stories/TokensPage.tsx +6 -1
- package/tailwind-preset.js +7 -0
package/dist/index.js
CHANGED
|
@@ -17,7 +17,8 @@ var FONT_SIZE_TOKENS = [
|
|
|
17
17
|
"input-label",
|
|
18
18
|
"input-value",
|
|
19
19
|
"input-helper",
|
|
20
|
-
"chip"
|
|
20
|
+
"chip",
|
|
21
|
+
"small"
|
|
21
22
|
];
|
|
22
23
|
var BOX_SHADOW_TOKENS = ["sm", "md", "lg", "focus-ring", "glow-warning", "glow-success", "glow-accent", "highlight-inset"];
|
|
23
24
|
var DROP_SHADOW_TOKENS = ["glow-success", "glow-accent", "glow-warning"];
|
|
@@ -253,9 +254,9 @@ function Kbd({ children, className }) {
|
|
|
253
254
|
"kbd",
|
|
254
255
|
{
|
|
255
256
|
className: cn(
|
|
256
|
-
"inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-sm border border-border-strong bg-bg-inset px-1 py-px font-sans text-
|
|
257
|
-
"signal:border-b-2 signal:pt-[2px] signal:pb-px signal:bg-bg-wash signal:font-mono signal:text-
|
|
258
|
-
"ship:border-b-2 ship:pt-[2px] ship:pb-px ship:bg-bg-wash ship:font-mono ship:text-
|
|
257
|
+
"inline-flex shrink-0 items-center justify-center whitespace-nowrap rounded-sm border border-border-strong bg-bg-inset px-1 py-px font-sans text-caption text-text-secondary",
|
|
258
|
+
"signal:border-b-2 signal:pt-[2px] signal:pb-px signal:bg-bg-wash signal:font-mono signal:text-small",
|
|
259
|
+
"ship:border-b-2 ship:pt-[2px] ship:pb-px ship:bg-bg-wash ship:font-mono ship:text-small",
|
|
259
260
|
className
|
|
260
261
|
),
|
|
261
262
|
children
|
|
@@ -410,9 +411,9 @@ var formatBytes = (bytes) => {
|
|
|
410
411
|
return `${(kb / 1024).toFixed(1)} MB`;
|
|
411
412
|
};
|
|
412
413
|
var typeLabelOf = (name) => extensionOf(name).toUpperCase() || "FILE";
|
|
413
|
-
var
|
|
414
|
-
var
|
|
415
|
-
var
|
|
414
|
+
var TILE_CLASSES = "size-9 rounded-md bg-bg-active flex items-center justify-center shrink-0 text-text-secondary";
|
|
415
|
+
var NAME_CLASSES = "text-caption font-medium text-text-primary truncate";
|
|
416
|
+
var NOTE_CLASSES = "text-small tracking-wide leading-tight truncate";
|
|
416
417
|
function TypeIcon({ name }) {
|
|
417
418
|
const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
|
|
418
419
|
return /* @__PURE__ */ jsx9(Icon, { size: 20, stroke: 1.5 });
|
|
@@ -469,15 +470,15 @@ function AttachmentCard({
|
|
|
469
470
|
className: cn("group relative flex items-center gap-2 w-[200px] p-1.5 pr-3", failed ? "border-error-default" : warning && "border-warning-default", className),
|
|
470
471
|
...props,
|
|
471
472
|
children: [
|
|
472
|
-
/* @__PURE__ */ jsx9("div", { className: cn(
|
|
473
|
+
/* @__PURE__ */ jsx9("div", { className: cn(TILE_CLASSES, "overflow-hidden"), children: state === "uploading" ? /* @__PURE__ */ jsx9(IconLoader2, { size: 16, stroke: 1.5, className: "animate-spin" }) : failed ? /* @__PURE__ */ jsx9(IconAlertCircle, { size: 16, stroke: 1.5, className: "text-error-default" }) : warning ? /* @__PURE__ */ jsx9(IconAlertTriangle, { size: 16, stroke: 1.5, className: "text-warning-default" }) : image && src ? /* @__PURE__ */ jsx9("img", { src, alt: name, className: "size-full object-cover" }) : /* @__PURE__ */ jsx9("span", { className: "text-menu font-semibold", children: typeLabelOf(name) }) }),
|
|
473
474
|
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
474
|
-
/* @__PURE__ */ jsx9(Truncating, { text: name, className:
|
|
475
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
|
|
475
476
|
/* @__PURE__ */ jsx9(
|
|
476
477
|
Truncating,
|
|
477
478
|
{
|
|
478
479
|
text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
|
|
479
480
|
hint: noteHint,
|
|
480
|
-
className: cn(
|
|
481
|
+
className: cn(NOTE_CLASSES, failed ? "text-error-default" : warning ? "text-warning-default" : "text-text-secondary")
|
|
481
482
|
}
|
|
482
483
|
)
|
|
483
484
|
] }),
|
|
@@ -521,10 +522,10 @@ function AttachmentCard({
|
|
|
521
522
|
}
|
|
522
523
|
if (state === "unreadable") {
|
|
523
524
|
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
|
|
524
|
-
/* @__PURE__ */ jsx9("div", { className:
|
|
525
|
+
/* @__PURE__ */ jsx9("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
|
|
525
526
|
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
526
|
-
/* @__PURE__ */ jsx9(Truncating, { text: name, className:
|
|
527
|
-
/* @__PURE__ */ jsx9("span", { className: cn(
|
|
527
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
|
|
528
|
+
/* @__PURE__ */ jsx9("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? "Could not be loaded" })
|
|
528
529
|
] })
|
|
529
530
|
] });
|
|
530
531
|
}
|
|
@@ -545,16 +546,16 @@ function AttachmentCard({
|
|
|
545
546
|
}
|
|
546
547
|
) : /* @__PURE__ */ jsx9("div", { className: "block w-full", children: picture }),
|
|
547
548
|
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-1 pl-2 pr-1 py-1 min-w-0", children: [
|
|
548
|
-
/* @__PURE__ */ jsx9(Truncating, { text: name, className: "flex-1 text-
|
|
549
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: "flex-1 text-caption text-text-primary truncate", wrapperClassName: "flex-1" }),
|
|
549
550
|
download
|
|
550
551
|
] })
|
|
551
552
|
] });
|
|
552
553
|
}
|
|
553
554
|
const body = /* @__PURE__ */ jsxs5(Fragment, { children: [
|
|
554
|
-
/* @__PURE__ */ jsx9("div", { className:
|
|
555
|
+
/* @__PURE__ */ jsx9("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
|
|
555
556
|
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
556
|
-
/* @__PURE__ */ jsx9(Truncating, { text: name, className:
|
|
557
|
-
/* @__PURE__ */ jsx9("span", { className: cn(
|
|
557
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
|
|
558
|
+
/* @__PURE__ */ jsx9("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
|
|
558
559
|
] })
|
|
559
560
|
] });
|
|
560
561
|
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: href ? "hairline" : "none", className: cn("group flex items-center gap-2 w-[240px] p-1.5 pr-1", !href && "opacity-70", className), ...props, children: [
|
|
@@ -564,9 +565,9 @@ function AttachmentCard({
|
|
|
564
565
|
}
|
|
565
566
|
|
|
566
567
|
// src/Avatar.tsx
|
|
567
|
-
import {
|
|
568
|
+
import { Avatar as BaseAvatar } from "@base-ui/react/avatar";
|
|
568
569
|
import { IconUserFilled } from "@tabler/icons-react";
|
|
569
|
-
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
570
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
570
571
|
var HUES = ["#56c8ff", "#ff8f6b", "#4ade8c", "#b18cff", "#ffc94d", "#ff7eb0", "#7ea8ff", "#5fdfd6"];
|
|
571
572
|
var hueFor = (key) => {
|
|
572
573
|
let h = 0;
|
|
@@ -579,30 +580,45 @@ var initialsFor = (name) => {
|
|
|
579
580
|
return initials.toUpperCase();
|
|
580
581
|
};
|
|
581
582
|
function Avatar({ src, name, alt = "", size = 36, label: spoken, className }) {
|
|
582
|
-
const [broken, setBroken] = useState2(false);
|
|
583
583
|
const label = name || alt;
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
"div",
|
|
584
|
+
return /* @__PURE__ */ jsxs6(
|
|
585
|
+
BaseAvatar.Root,
|
|
587
586
|
{
|
|
587
|
+
render: /* @__PURE__ */ jsx10("div", {}),
|
|
588
588
|
...spoken ? { role: "img", "aria-label": spoken } : { "aria-hidden": true },
|
|
589
589
|
className: cn("rounded-sm overflow-hidden shrink-0 bg-bg-inset", className),
|
|
590
590
|
style: { width: size, height: size },
|
|
591
|
-
children:
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
591
|
+
children: [
|
|
592
|
+
src && /* @__PURE__ */ jsx10(
|
|
593
|
+
BaseAvatar.Image,
|
|
594
|
+
{
|
|
595
|
+
src,
|
|
596
|
+
alt: "",
|
|
597
|
+
keepMounted: true,
|
|
598
|
+
className: "w-full h-full object-cover data-[error]:hidden"
|
|
599
|
+
}
|
|
600
|
+
),
|
|
601
|
+
label ? /* @__PURE__ */ jsx10(
|
|
602
|
+
BaseAvatar.Fallback,
|
|
603
|
+
{
|
|
604
|
+
render: /* @__PURE__ */ jsx10("div", {}),
|
|
605
|
+
className: "w-full h-full flex items-center justify-center font-semibold leading-none",
|
|
606
|
+
style: {
|
|
607
|
+
/* eslint-disable no-restricted-syntax -- @estiva-escape: the per-person palette (the note at
|
|
608
|
+
the top): eight hues picked from the name, the one ink that reads on all
|
|
609
|
+
of them, and a size that follows `size`. None of it can be a token. */
|
|
610
|
+
// The one ink colour that reads on all eight hues, which are a
|
|
611
|
+
// palette rather than tokens (see the note at the top) — so its
|
|
612
|
+
// ink cannot be a token either.
|
|
613
|
+
color: "#08121c",
|
|
614
|
+
fontSize: Math.round(size * 0.36),
|
|
615
|
+
background: `linear-gradient(160deg, color-mix(in srgb, ${hueFor(label)} 92%, #fff) 0%, color-mix(in srgb, ${hueFor(label)} 70%, #0b0d11) 100%)`
|
|
616
|
+
/* eslint-enable no-restricted-syntax */
|
|
617
|
+
},
|
|
618
|
+
children: /* @__PURE__ */ jsx10("span", { className: "[text-box:trim-both_cap_alphabetic]", children: initialsFor(label) })
|
|
619
|
+
}
|
|
620
|
+
) : /* @__PURE__ */ jsx10(BaseAvatar.Fallback, { render: /* @__PURE__ */ jsx10("div", {}), className: "w-full h-full bg-accent-muted flex items-center justify-center text-text-muted", children: /* @__PURE__ */ jsx10(IconUserFilled, { size: Math.round(size * 0.5) }) })
|
|
621
|
+
]
|
|
606
622
|
}
|
|
607
623
|
);
|
|
608
624
|
}
|
|
@@ -633,7 +649,7 @@ function AvatarGroup({ members, size = 24 }) {
|
|
|
633
649
|
|
|
634
650
|
// src/Banner.tsx
|
|
635
651
|
import { IconX as IconX2 } from "@tabler/icons-react";
|
|
636
|
-
import { jsx as jsx12, jsxs as
|
|
652
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
637
653
|
var TONE_STYLES = {
|
|
638
654
|
ok: "bg-success-muted text-success-default",
|
|
639
655
|
error: "bg-error-muted text-error-default",
|
|
@@ -645,7 +661,7 @@ function Banner({ tone, children, onDismiss, dismissLabel = "Dismiss", className
|
|
|
645
661
|
if (!onDismiss) {
|
|
646
662
|
return /* @__PURE__ */ jsx12("div", { role, className: cn("px-4 py-2 text-body-2", TONE_STYLES[tone], className), children });
|
|
647
663
|
}
|
|
648
|
-
return /* @__PURE__ */
|
|
664
|
+
return /* @__PURE__ */ jsxs7("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
|
|
649
665
|
/* @__PURE__ */ jsx12("span", { className: "min-w-0 flex-1", children }),
|
|
650
666
|
/* @__PURE__ */ jsx12(IconButton, { "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0 text-current hover:text-current", children: /* @__PURE__ */ jsx12(IconX2, { size: 16, stroke: 1.5 }) })
|
|
651
667
|
] });
|
|
@@ -653,7 +669,7 @@ function Banner({ tone, children, onDismiss, dismissLabel = "Dismiss", className
|
|
|
653
669
|
|
|
654
670
|
// src/Button.tsx
|
|
655
671
|
import { Button as BaseButton3 } from "@base-ui/react/button";
|
|
656
|
-
import { jsx as jsx13, jsxs as
|
|
672
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
657
673
|
function Button({
|
|
658
674
|
variant = "muted",
|
|
659
675
|
size = "default",
|
|
@@ -666,7 +682,7 @@ function Button({
|
|
|
666
682
|
...props
|
|
667
683
|
}) {
|
|
668
684
|
const hasLeadingIcon = !!leadingIcon;
|
|
669
|
-
const button = /* @__PURE__ */
|
|
685
|
+
const button = /* @__PURE__ */ jsxs8(
|
|
670
686
|
BaseButton3,
|
|
671
687
|
{
|
|
672
688
|
type,
|
|
@@ -720,7 +736,7 @@ import { IconCheck } from "@tabler/icons-react";
|
|
|
720
736
|
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
721
737
|
function squareClasses(checked, disabled, interactive, className) {
|
|
722
738
|
return cn(
|
|
723
|
-
"inline-flex items-center justify-center size-4 shrink-0 rounded-
|
|
739
|
+
"inline-flex items-center justify-center size-4 shrink-0 rounded-sm border transition-colors",
|
|
724
740
|
checked ? "bg-accent-primary border-accent-primary text-text-inverse" : "bg-transparent border-border-strong hover:border-text-muted",
|
|
725
741
|
disabled && "opacity-50 pointer-events-none",
|
|
726
742
|
interactive ? "cursor-pointer" : "pointer-events-none",
|
|
@@ -748,7 +764,7 @@ function Checkbox({ checked, onChange, disabled = false, className, ...aria }) {
|
|
|
748
764
|
}
|
|
749
765
|
|
|
750
766
|
// src/Chip.tsx
|
|
751
|
-
import { jsx as jsx15, jsxs as
|
|
767
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
752
768
|
var typeStyles = {
|
|
753
769
|
neutral: "bg-bg-inset text-text-primary",
|
|
754
770
|
brand: "bg-accent-muted text-accent-primary signal:border signal:border-accent-outline",
|
|
@@ -758,7 +774,7 @@ var typeStyles = {
|
|
|
758
774
|
error: "bg-error-muted text-error-default signal:border signal:border-error-outline"
|
|
759
775
|
};
|
|
760
776
|
function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className }) {
|
|
761
|
-
return /* @__PURE__ */
|
|
777
|
+
return /* @__PURE__ */ jsxs9("div", { className: cn("inline-flex min-w-0 items-center justify-center gap-1.5 rounded-full max-h-[20px] px-2 py-1", typeStyles[type], className), children: [
|
|
762
778
|
leadingIcon && /* @__PURE__ */ jsx15("span", { className: "flex size-3 shrink-0 items-center justify-center", children: leadingIcon }),
|
|
763
779
|
label && // A chip given a `max-w-*` cuts a long label with an ellipsis instead
|
|
764
780
|
// of growing past it — Ship's project chip on an issue row
|
|
@@ -768,13 +784,13 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
768
784
|
// the screenshot diff caught every descender cut off. `clip` is the
|
|
769
785
|
// one overflow that leaves the other axis visible. A chip with no cap
|
|
770
786
|
// draws exactly as before.
|
|
771
|
-
/* @__PURE__ */ jsx15("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-
|
|
787
|
+
/* @__PURE__ */ jsx15("span", { className: "min-w-0 overflow-x-clip text-ellipsis whitespace-nowrap text-chip signal:font-mono signal:text-small signal:font-semibold signal:tracking-wide signal:tabular-nums", children: label }),
|
|
772
788
|
trailingIcon && /* @__PURE__ */ jsx15("span", { className: "flex size-3 shrink-0 items-center justify-center", children: trailingIcon })
|
|
773
789
|
] });
|
|
774
790
|
}
|
|
775
791
|
|
|
776
792
|
// src/ChipInput.tsx
|
|
777
|
-
import { useMemo, useState as
|
|
793
|
+
import { useMemo, useState as useState2 } from "react";
|
|
778
794
|
import { Button as BaseButton4 } from "@base-ui/react/button";
|
|
779
795
|
import { Combobox } from "@base-ui/react/combobox";
|
|
780
796
|
import { IconX as IconX3 } from "@tabler/icons-react";
|
|
@@ -797,7 +813,7 @@ function SectionLabel({ children, className }) {
|
|
|
797
813
|
"span",
|
|
798
814
|
{
|
|
799
815
|
className: cn(
|
|
800
|
-
"text-
|
|
816
|
+
"text-h5 leading-3 text-text-primary signal:font-mono signal:text-small signal:uppercase signal:tracking-widest",
|
|
801
817
|
className
|
|
802
818
|
),
|
|
803
819
|
children
|
|
@@ -806,7 +822,7 @@ function SectionLabel({ children, className }) {
|
|
|
806
822
|
}
|
|
807
823
|
|
|
808
824
|
// src/Menu.tsx
|
|
809
|
-
import { Fragment as Fragment2, jsx as jsx17, jsxs as
|
|
825
|
+
import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
810
826
|
var MenuContext = createContext(null);
|
|
811
827
|
function MenuPanel({ children, className, ...props }) {
|
|
812
828
|
return /* @__PURE__ */ jsx17(
|
|
@@ -839,7 +855,7 @@ var VIEWPORT_PAD2 = 8;
|
|
|
839
855
|
var HOVER_OPEN_DELAY = 0;
|
|
840
856
|
var HOVER_CLOSE_DELAY = 150;
|
|
841
857
|
function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
|
|
842
|
-
return /* @__PURE__ */
|
|
858
|
+
return /* @__PURE__ */ jsxs10(
|
|
843
859
|
BaseMenu.Root,
|
|
844
860
|
{
|
|
845
861
|
open,
|
|
@@ -887,7 +903,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
887
903
|
'[@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".'
|
|
888
904
|
);
|
|
889
905
|
}
|
|
890
|
-
return /* @__PURE__ */
|
|
906
|
+
return /* @__PURE__ */ jsxs10(BaseMenu.SubmenuRoot, { children: [
|
|
891
907
|
/* @__PURE__ */ jsx17(
|
|
892
908
|
BaseMenu.SubmenuTrigger,
|
|
893
909
|
{
|
|
@@ -944,17 +960,17 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
944
960
|
}
|
|
945
961
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
946
962
|
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx17(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx17(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
947
|
-
return /* @__PURE__ */
|
|
963
|
+
return /* @__PURE__ */ jsxs10(Fragment2, { children: [
|
|
948
964
|
leading && /* @__PURE__ */ jsx17("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
949
|
-
children ?? /* @__PURE__ */
|
|
950
|
-
/* @__PURE__ */ jsx17("span", { className: cn("truncate text-
|
|
951
|
-
description && /* @__PURE__ */ jsx17("span", { className: "truncate text-
|
|
965
|
+
children ?? /* @__PURE__ */ jsxs10("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
966
|
+
/* @__PURE__ */ jsx17("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
967
|
+
description && /* @__PURE__ */ jsx17("span", { className: "truncate text-caption text-text-secondary", children: description })
|
|
952
968
|
] }),
|
|
953
969
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
954
970
|
// the wider of the two and never changes, so revealing the hint moves
|
|
955
971
|
// nothing. No transition here either — the hint switches on the same
|
|
956
972
|
// :hover / `selected` as the fill, in the same frame.
|
|
957
|
-
/* @__PURE__ */
|
|
973
|
+
/* @__PURE__ */ jsxs10("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
958
974
|
edge && /* @__PURE__ */ jsx17("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
959
975
|
hint && /* @__PURE__ */ jsx17("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
960
976
|
] })
|
|
@@ -993,21 +1009,21 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
993
1009
|
);
|
|
994
1010
|
}
|
|
995
1011
|
function EnterHint({ target }) {
|
|
996
|
-
return /* @__PURE__ */
|
|
1012
|
+
return /* @__PURE__ */ jsxs10("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
997
1013
|
/* @__PURE__ */ jsx17(Kbd, { children: "\u21A9 Enter" }),
|
|
998
|
-
target && /* @__PURE__ */ jsx17("span", { className: "text-
|
|
1014
|
+
target && /* @__PURE__ */ jsx17("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider", children: target })
|
|
999
1015
|
] });
|
|
1000
1016
|
}
|
|
1001
1017
|
function MenuSection({ label, children, className }) {
|
|
1002
1018
|
const inMenu = useContext(MenuContext) !== null;
|
|
1003
1019
|
const heading = /* @__PURE__ */ jsx17("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx17(SectionLabel, { className: "text-text-secondary", children: label }) });
|
|
1004
1020
|
if (!inMenu) {
|
|
1005
|
-
return /* @__PURE__ */
|
|
1021
|
+
return /* @__PURE__ */ jsxs10("div", { className: "flex flex-col", children: [
|
|
1006
1022
|
heading,
|
|
1007
1023
|
children
|
|
1008
1024
|
] });
|
|
1009
1025
|
}
|
|
1010
|
-
return /* @__PURE__ */
|
|
1026
|
+
return /* @__PURE__ */ jsxs10(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1011
1027
|
/* @__PURE__ */ jsx17(BaseMenu.GroupLabel, { render: heading }),
|
|
1012
1028
|
children
|
|
1013
1029
|
] });
|
|
@@ -1017,7 +1033,7 @@ function MenuRow({ children, className }) {
|
|
|
1017
1033
|
}
|
|
1018
1034
|
|
|
1019
1035
|
// src/ChipInput.tsx
|
|
1020
|
-
import { jsx as jsx18, jsxs as
|
|
1036
|
+
import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1021
1037
|
var CHIP_BOX = (
|
|
1022
1038
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
1023
1039
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -1027,10 +1043,10 @@ var CHIP_BOX = (
|
|
|
1027
1043
|
var CHIP_LABEL = "text-caption font-medium text-text-primary";
|
|
1028
1044
|
var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
|
|
1029
1045
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
1030
|
-
function InputChip({ label, leading, onRemove, className }) {
|
|
1031
|
-
return /* @__PURE__ */
|
|
1046
|
+
function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
|
|
1047
|
+
return /* @__PURE__ */ jsxs11("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1032
1048
|
leading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1033
|
-
/* @__PURE__ */ jsx18("span", { className: CHIP_LABEL, children: label }),
|
|
1049
|
+
/* @__PURE__ */ jsx18("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
|
|
1034
1050
|
onRemove && /* @__PURE__ */ jsx18(
|
|
1035
1051
|
BaseButton4,
|
|
1036
1052
|
{
|
|
@@ -1039,8 +1055,8 @@ function InputChip({ label, leading, onRemove, className }) {
|
|
|
1039
1055
|
e.stopPropagation();
|
|
1040
1056
|
onRemove();
|
|
1041
1057
|
},
|
|
1042
|
-
className: CHIP_REMOVE,
|
|
1043
|
-
"aria-label": `Remove ${label}`,
|
|
1058
|
+
className: cn(CHIP_REMOVE, truncate && "shrink-0"),
|
|
1059
|
+
"aria-label": removeLabel ?? `Remove ${label}`,
|
|
1044
1060
|
children: /* @__PURE__ */ jsx18(IconX3, { size: 10, stroke: 1.5 })
|
|
1045
1061
|
}
|
|
1046
1062
|
)
|
|
@@ -1057,8 +1073,8 @@ function ChipInput({
|
|
|
1057
1073
|
rowLeading,
|
|
1058
1074
|
...aria
|
|
1059
1075
|
}) {
|
|
1060
|
-
const [query, setQuery] =
|
|
1061
|
-
const [box, setBox] =
|
|
1076
|
+
const [query, setQuery] = useState2("");
|
|
1077
|
+
const [box, setBox] = useState2(null);
|
|
1062
1078
|
const available = useMemo(() => {
|
|
1063
1079
|
const chosen = new Set(value.map((o) => o.id));
|
|
1064
1080
|
const excluded = new Set(excludeIds);
|
|
@@ -1094,7 +1110,7 @@ function ChipInput({
|
|
|
1094
1110
|
setQuery("");
|
|
1095
1111
|
}
|
|
1096
1112
|
}
|
|
1097
|
-
return /* @__PURE__ */
|
|
1113
|
+
return /* @__PURE__ */ jsxs11(
|
|
1098
1114
|
Combobox.Root,
|
|
1099
1115
|
{
|
|
1100
1116
|
multiple: true,
|
|
@@ -1111,8 +1127,8 @@ function ChipInput({
|
|
|
1111
1127
|
filter,
|
|
1112
1128
|
itemToStringLabel: (option) => option.label,
|
|
1113
1129
|
children: [
|
|
1114
|
-
/* @__PURE__ */
|
|
1115
|
-
value.map((option) => /* @__PURE__ */
|
|
1130
|
+
/* @__PURE__ */ jsxs11(Combobox.Chips, { ref: setBox, className: "bg-bg-inset border border-border-default hover:border-border-strong focus-within:border-border-focus focus-within:hover:border-border-focus rounded-lg px-3 py-1.5 flex flex-wrap items-center gap-1.5 transition-colors min-h-[38px] cursor-text signal:transition-shadow signal:focus-within:shadow-focus-ring", children: [
|
|
1131
|
+
value.map((option) => /* @__PURE__ */ jsxs11(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1116
1132
|
chipLeading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
|
|
1117
1133
|
/* @__PURE__ */ jsx18("span", { className: CHIP_LABEL, children: option.label }),
|
|
1118
1134
|
/* @__PURE__ */ jsx18(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx18(IconX3, { size: 10, stroke: 1.5 }) })
|
|
@@ -1162,7 +1178,7 @@ var GAP3 = 4;
|
|
|
1162
1178
|
var VIEWPORT_PAD3 = 8;
|
|
1163
1179
|
|
|
1164
1180
|
// src/InlineChip.tsx
|
|
1165
|
-
import { Fragment as Fragment3, jsx as jsx19, jsxs as
|
|
1181
|
+
import { Fragment as Fragment3, jsx as jsx19, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1166
1182
|
var INLINE_CHIP_CLASSES = "inline-flex h-[1.4em] items-center gap-1 rounded-sm px-1 mx-0.5 align-top text-body-2 font-normal select-none";
|
|
1167
1183
|
var INLINE_CHIP_TONE_CLASSES = {
|
|
1168
1184
|
/** A thing or a place — anything that is not a person. */
|
|
@@ -1184,7 +1200,7 @@ function inlineChipClassName(tone, className) {
|
|
|
1184
1200
|
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1185
1201
|
}
|
|
1186
1202
|
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1187
|
-
const body = /* @__PURE__ */
|
|
1203
|
+
const body = /* @__PURE__ */ jsxs12(Fragment3, { children: [
|
|
1188
1204
|
icon && /* @__PURE__ */ jsx19("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
|
|
1189
1205
|
children
|
|
1190
1206
|
] });
|
|
@@ -1199,15 +1215,15 @@ function InlineChip({ tone = "neutral", icon, href, className, children, ...prop
|
|
|
1199
1215
|
import { useCallback, useRef as useRef2 } from "react";
|
|
1200
1216
|
|
|
1201
1217
|
// src/Divider.tsx
|
|
1202
|
-
import {
|
|
1218
|
+
import { Separator } from "@base-ui/react/separator";
|
|
1219
|
+
import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1203
1220
|
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
1204
1221
|
if (label && orientation === "horizontal") {
|
|
1205
1222
|
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
1206
|
-
return /* @__PURE__ */
|
|
1207
|
-
|
|
1223
|
+
return /* @__PURE__ */ jsxs13(
|
|
1224
|
+
Separator,
|
|
1208
1225
|
{
|
|
1209
|
-
|
|
1210
|
-
"aria-orientation": "horizontal",
|
|
1226
|
+
orientation: "horizontal",
|
|
1211
1227
|
"aria-label": label,
|
|
1212
1228
|
className: cn("flex shrink-0 items-center gap-2 mx-3", className),
|
|
1213
1229
|
children: [
|
|
@@ -1219,23 +1235,22 @@ function Divider({ orientation = "horizontal", label, tone = "default", classNam
|
|
|
1219
1235
|
);
|
|
1220
1236
|
}
|
|
1221
1237
|
return /* @__PURE__ */ jsx20(
|
|
1222
|
-
|
|
1238
|
+
Separator,
|
|
1223
1239
|
{
|
|
1224
|
-
|
|
1225
|
-
"aria-orientation": orientation,
|
|
1240
|
+
orientation,
|
|
1226
1241
|
className: cn("shrink-0 bg-border-subtle", orientation === "horizontal" ? "h-px mx-3" : "w-px self-stretch", className)
|
|
1227
1242
|
}
|
|
1228
1243
|
);
|
|
1229
1244
|
}
|
|
1230
1245
|
|
|
1231
1246
|
// src/Person.tsx
|
|
1232
|
-
import { jsx as jsx21, jsxs as
|
|
1247
|
+
import { jsx as jsx21, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1233
1248
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
1234
1249
|
return (
|
|
1235
1250
|
// gap-2: the face-to-name distance is one rule (8px) wherever a person
|
|
1236
1251
|
// appears — Katerina, 2026-09-01, set on Person so PersonTrigger and every
|
|
1237
1252
|
// row agree by construction.
|
|
1238
|
-
/* @__PURE__ */
|
|
1253
|
+
/* @__PURE__ */ jsxs14("span", { className: cn("flex min-w-0 items-center gap-2", className), children: [
|
|
1239
1254
|
/* @__PURE__ */ jsx21(Avatar, { name, src: picture, size }),
|
|
1240
1255
|
/* @__PURE__ */ jsx21("span", { className: cn("truncate", !name && "text-text-muted"), children: name ?? fallback })
|
|
1241
1256
|
] })
|
|
@@ -1245,7 +1260,7 @@ function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
|
1245
1260
|
// src/PersonTrigger.tsx
|
|
1246
1261
|
import { Button as BaseButton5 } from "@base-ui/react/button";
|
|
1247
1262
|
import { IconChevronDown } from "@tabler/icons-react";
|
|
1248
|
-
import { jsx as jsx22, jsxs as
|
|
1263
|
+
import { jsx as jsx22, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1249
1264
|
function PersonTrigger({ name, picture, fallback, size, open = false, compact = false, className, ...props }) {
|
|
1250
1265
|
if (compact) {
|
|
1251
1266
|
return /* @__PURE__ */ jsx22(
|
|
@@ -1261,7 +1276,7 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1261
1276
|
}
|
|
1262
1277
|
);
|
|
1263
1278
|
}
|
|
1264
|
-
return /* @__PURE__ */
|
|
1279
|
+
return /* @__PURE__ */ jsxs15(
|
|
1265
1280
|
BaseButton5,
|
|
1266
1281
|
{
|
|
1267
1282
|
type: "button",
|
|
@@ -1287,7 +1302,7 @@ function PersonTrigger({ name, picture, fallback, size, open = false, compact =
|
|
|
1287
1302
|
}
|
|
1288
1303
|
|
|
1289
1304
|
// src/IdentityMenu.tsx
|
|
1290
|
-
import { Fragment as Fragment4, jsx as jsx23, jsxs as
|
|
1305
|
+
import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1291
1306
|
function IdentityPanel({ className, onClose = () => {
|
|
1292
1307
|
}, ...rest }) {
|
|
1293
1308
|
return /* @__PURE__ */ jsx23(MenuPanel, { className: cn("w-72", className), children: /* @__PURE__ */ jsx23(IdentityRows, { ...rest, onClose }) });
|
|
@@ -1298,23 +1313,23 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
1298
1313
|
action();
|
|
1299
1314
|
};
|
|
1300
1315
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
1301
|
-
return /* @__PURE__ */
|
|
1302
|
-
/* @__PURE__ */
|
|
1316
|
+
return /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
1317
|
+
/* @__PURE__ */ jsxs16(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
1303
1318
|
/* @__PURE__ */ jsx23(MenuRow, { children: /* @__PURE__ */ jsx23(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28, className: "text-body-2-strong" }) }),
|
|
1304
1319
|
/* @__PURE__ */ jsx23(Note, { children: signedIn ? "Your Estiva ID. The same person you are in every Estiva app." : "A key held by this browser only. Nobody else knows who you are." }),
|
|
1305
|
-
me.email && /* @__PURE__ */
|
|
1320
|
+
me.email && /* @__PURE__ */ jsxs16(Note, { children: [
|
|
1306
1321
|
me.email,
|
|
1307
1322
|
" \xB7 known to Estiva, never published to the relay"
|
|
1308
1323
|
] })
|
|
1309
1324
|
] }),
|
|
1310
|
-
relayUrl && /* @__PURE__ */
|
|
1325
|
+
relayUrl && /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
1311
1326
|
/* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }),
|
|
1312
|
-
/* @__PURE__ */
|
|
1327
|
+
/* @__PURE__ */ jsxs16(MenuSection, { label: "Workspace", children: [
|
|
1313
1328
|
/* @__PURE__ */ jsx23(MenuRow, { children: /* @__PURE__ */ jsx23("span", { className: "break-all font-mono text-caption text-text-primary", children: relayUrl }) }),
|
|
1314
1329
|
/* @__PURE__ */ jsx23(Note, { children: "Everyone on this relay shares this workspace, in every app." })
|
|
1315
1330
|
] })
|
|
1316
1331
|
] }),
|
|
1317
|
-
appRows && /* @__PURE__ */
|
|
1332
|
+
appRows && /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
1318
1333
|
/* @__PURE__ */ jsx23(Divider, { className: "mx-0 my-2" }),
|
|
1319
1334
|
appRows
|
|
1320
1335
|
] }),
|
|
@@ -1379,7 +1394,7 @@ function Note({ children }) {
|
|
|
1379
1394
|
// src/Field.tsx
|
|
1380
1395
|
import { cloneElement, isValidElement } from "react";
|
|
1381
1396
|
import { Field as BaseField } from "@base-ui/react/field";
|
|
1382
|
-
import { jsx as jsx24, jsxs as
|
|
1397
|
+
import { jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1383
1398
|
var LINE_STYLES = {
|
|
1384
1399
|
helper: "text-caption text-text-muted",
|
|
1385
1400
|
warning: "text-caption text-warning-default",
|
|
@@ -1389,12 +1404,12 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1389
1404
|
const control = required && isValidElement(children) ? cloneElement(children, {
|
|
1390
1405
|
"aria-required": children.props["aria-required"] ?? true
|
|
1391
1406
|
}) : children;
|
|
1392
|
-
return /* @__PURE__ */
|
|
1393
|
-
/* @__PURE__ */
|
|
1407
|
+
return /* @__PURE__ */ jsxs17(BaseField.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1408
|
+
/* @__PURE__ */ jsxs17(BaseField.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1394
1409
|
label,
|
|
1395
1410
|
required && /* @__PURE__ */ jsx24("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1396
1411
|
] }),
|
|
1397
|
-
/* @__PURE__ */
|
|
1412
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-1.5", children: [
|
|
1398
1413
|
control,
|
|
1399
1414
|
error != null ? /* @__PURE__ */ jsx24(BaseField.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx24(BaseField.Description, { className: LINE_STYLES.helper, children: helper }) : null
|
|
1400
1415
|
] })
|
|
@@ -1407,12 +1422,12 @@ function FieldLine({ tone = "helper", children, className }) {
|
|
|
1407
1422
|
// src/Select.tsx
|
|
1408
1423
|
import { IconCheck as IconCheck2, IconChevronDown as IconChevronDown2 } from "@tabler/icons-react";
|
|
1409
1424
|
import { Select as BaseSelect } from "@base-ui/react/select";
|
|
1410
|
-
import { jsx as jsx25, jsxs as
|
|
1425
|
+
import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1411
1426
|
var GAP4 = 4;
|
|
1412
1427
|
var VIEWPORT_PAD4 = 8;
|
|
1413
1428
|
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, className, ...aria }) {
|
|
1414
1429
|
const selected = options.find((o) => o.value === value);
|
|
1415
|
-
return /* @__PURE__ */
|
|
1430
|
+
return /* @__PURE__ */ jsxs18(
|
|
1416
1431
|
BaseSelect.Root,
|
|
1417
1432
|
{
|
|
1418
1433
|
value,
|
|
@@ -1420,7 +1435,7 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1420
1435
|
disabled,
|
|
1421
1436
|
modal: false,
|
|
1422
1437
|
children: [
|
|
1423
|
-
/* @__PURE__ */
|
|
1438
|
+
/* @__PURE__ */ jsxs18(
|
|
1424
1439
|
BaseSelect.Trigger,
|
|
1425
1440
|
{
|
|
1426
1441
|
"aria-label": ariaLabel,
|
|
@@ -1442,12 +1457,12 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1442
1457
|
"hover:border-border-strong focus-visible:hover:border-border-focus aria-expanded:hover:border-border-focus disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled",
|
|
1443
1458
|
"focus-visible:border-border-focus aria-expanded:border-border-focus",
|
|
1444
1459
|
"signal:transition-shadow signal:focus-visible:shadow-focus-ring",
|
|
1445
|
-
size === "default" && "px-3 py-2 text-
|
|
1446
|
-
size === "small" && "h-6 px-2 text-
|
|
1460
|
+
size === "default" && "px-3 py-2 text-input-value",
|
|
1461
|
+
size === "small" && "h-6 px-2 text-caption",
|
|
1447
1462
|
className
|
|
1448
1463
|
),
|
|
1449
1464
|
children: [
|
|
1450
|
-
/* @__PURE__ */
|
|
1465
|
+
/* @__PURE__ */ jsxs18("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
1451
1466
|
selected?.leading && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
1452
1467
|
/* @__PURE__ */ jsx25(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
1453
1468
|
] }),
|
|
@@ -1474,15 +1489,15 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1474
1489
|
{
|
|
1475
1490
|
render: /* @__PURE__ */ jsx25(MenuPanel, {}),
|
|
1476
1491
|
className: "min-w-[var(--anchor-width)] p-0",
|
|
1477
|
-
children: /* @__PURE__ */ jsx25(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */
|
|
1492
|
+
children: /* @__PURE__ */ jsx25(ScrollArea, { viewportClassName: "max-h-[min(288px,var(--available-height))]", contentClassName: "flex flex-col p-2", children: options.map((option) => /* @__PURE__ */ jsxs18(
|
|
1478
1493
|
BaseSelect.Item,
|
|
1479
1494
|
{
|
|
1480
1495
|
value: option.value,
|
|
1481
1496
|
className: cn(menuItemClassName({ size: "default" }), "justify-between data-[selected]:font-medium"),
|
|
1482
1497
|
children: [
|
|
1483
|
-
/* @__PURE__ */
|
|
1498
|
+
/* @__PURE__ */ jsxs18("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1484
1499
|
option.leading && /* @__PURE__ */ jsx25("span", { className: "flex shrink-0 items-center", children: option.leading }),
|
|
1485
|
-
/* @__PURE__ */ jsx25(BaseSelect.ItemText, { className: "truncate text-
|
|
1500
|
+
/* @__PURE__ */ jsx25(BaseSelect.ItemText, { className: "truncate text-body-2 text-text-primary", children: option.label })
|
|
1486
1501
|
] }),
|
|
1487
1502
|
/* @__PURE__ */ jsx25(
|
|
1488
1503
|
BaseSelect.ItemIndicator,
|
|
@@ -1507,15 +1522,18 @@ function Select({ value, onChange, options, size = "default", ariaLabel, placeho
|
|
|
1507
1522
|
import { forwardRef } from "react";
|
|
1508
1523
|
import { Input } from "@base-ui/react/input";
|
|
1509
1524
|
import { jsx as jsx26 } from "react/jsx-runtime";
|
|
1510
|
-
var TextInput = forwardRef(function TextInput2({ className, type = "text", ...props }, ref) {
|
|
1525
|
+
var TextInput = forwardRef(function TextInput2({ className, type = "text", size = "default", ...props }, ref) {
|
|
1511
1526
|
return /* @__PURE__ */ jsx26(
|
|
1512
1527
|
Input,
|
|
1513
1528
|
{
|
|
1514
1529
|
ref,
|
|
1515
1530
|
type,
|
|
1516
1531
|
className: cn(
|
|
1517
|
-
"bg-bg-inset border border-border-default focus:border-border-focus rounded-lg
|
|
1518
|
-
|
|
1532
|
+
"bg-bg-inset border border-border-default focus:border-border-focus rounded-lg",
|
|
1533
|
+
// The small size is the small Select's trigger, class for class.
|
|
1534
|
+
size === "default" && "px-3 py-2 text-input-value",
|
|
1535
|
+
size === "small" && "h-6 px-2 text-caption",
|
|
1536
|
+
"text-text-primary placeholder:text-text-muted",
|
|
1519
1537
|
"outline-none transition-colors",
|
|
1520
1538
|
"disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled",
|
|
1521
1539
|
"signal:transition-shadow signal:focus:shadow-focus-ring",
|
|
@@ -1538,7 +1556,7 @@ var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
|
|
|
1538
1556
|
render: /* @__PURE__ */ jsx27("textarea", {}),
|
|
1539
1557
|
className: cn(
|
|
1540
1558
|
"bg-bg-inset border border-border-default focus:border-border-focus rounded-lg px-3 py-2",
|
|
1541
|
-
"text-
|
|
1559
|
+
"text-input-value text-text-primary placeholder:text-text-muted",
|
|
1542
1560
|
"resize-none outline-none transition-colors",
|
|
1543
1561
|
"disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled",
|
|
1544
1562
|
"signal:transition-shadow signal:focus:shadow-focus-ring",
|
|
@@ -1550,14 +1568,14 @@ var Textarea = forwardRef2(function Textarea2({ className, ...props }, ref) {
|
|
|
1550
1568
|
});
|
|
1551
1569
|
|
|
1552
1570
|
// src/ConfirmDialog.tsx
|
|
1553
|
-
import { useState as
|
|
1571
|
+
import { useState as useState3 } from "react";
|
|
1554
1572
|
|
|
1555
1573
|
// src/DialogShell.tsx
|
|
1556
1574
|
import { useRef as useRef3 } from "react";
|
|
1557
1575
|
import { Dialog } from "@base-ui/react/dialog";
|
|
1558
1576
|
import { AlertDialog } from "@base-ui/react/alert-dialog";
|
|
1559
1577
|
import { IconX as IconX4 } from "@tabler/icons-react";
|
|
1560
|
-
import { jsx as jsx28, jsxs as
|
|
1578
|
+
import { jsx as jsx28, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1561
1579
|
function DialogShell({ title, onClose, headerContent, footer, children, bodyClassName, bodyMaxHeight, width = 502, alert = false }) {
|
|
1562
1580
|
const Parts = alert ? AlertDialog : Dialog;
|
|
1563
1581
|
const popupRef = useRef3(null);
|
|
@@ -1568,9 +1586,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1568
1586
|
onOpenChange: (open) => {
|
|
1569
1587
|
if (!open) onClose();
|
|
1570
1588
|
},
|
|
1571
|
-
children: /* @__PURE__ */
|
|
1589
|
+
children: /* @__PURE__ */ jsxs19(Parts.Portal, { children: [
|
|
1572
1590
|
/* @__PURE__ */ jsx28(Parts.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1573
|
-
/* @__PURE__ */ jsx28("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */
|
|
1591
|
+
/* @__PURE__ */ jsx28("div", { className: "fixed inset-0 z-50 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxs19(
|
|
1574
1592
|
Parts.Popup,
|
|
1575
1593
|
{
|
|
1576
1594
|
ref: popupRef,
|
|
@@ -1579,7 +1597,7 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1579
1597
|
className: "bg-bg-elevated border border-border-subtle rounded-lg shadow-lg pointer-events-auto flex flex-col overflow-hidden outline-none",
|
|
1580
1598
|
style: { width },
|
|
1581
1599
|
children: [
|
|
1582
|
-
/* @__PURE__ */
|
|
1600
|
+
/* @__PURE__ */ jsxs19("div", { className: "h-12 flex items-center justify-between pl-5 pr-4 border-b border-border-subtle shrink-0", children: [
|
|
1583
1601
|
headerContent ?? /* @__PURE__ */ jsx28(Parts.Title, { className: "text-h4 text-text-primary", render: /* @__PURE__ */ jsx28("span", {}), children: title }),
|
|
1584
1602
|
/* @__PURE__ */ jsx28(
|
|
1585
1603
|
Parts.Close,
|
|
@@ -1607,9 +1625,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
1607
1625
|
}
|
|
1608
1626
|
|
|
1609
1627
|
// src/ConfirmDialog.tsx
|
|
1610
|
-
import { Fragment as Fragment5, jsx as jsx29, jsxs as
|
|
1628
|
+
import { Fragment as Fragment5, jsx as jsx29, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
1611
1629
|
function ConfirmDialog({ title, children, confirmLabel, destructive = false, onConfirm, onClose }) {
|
|
1612
|
-
const [busy, setBusy] =
|
|
1630
|
+
const [busy, setBusy] = useState3(false);
|
|
1613
1631
|
const confirm = async () => {
|
|
1614
1632
|
setBusy(true);
|
|
1615
1633
|
try {
|
|
@@ -1626,7 +1644,7 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
1626
1644
|
title,
|
|
1627
1645
|
onClose,
|
|
1628
1646
|
bodyClassName: "flex flex-col gap-3 text-body-2 text-text-primary",
|
|
1629
|
-
footer: /* @__PURE__ */
|
|
1647
|
+
footer: /* @__PURE__ */ jsxs20(Fragment5, { children: [
|
|
1630
1648
|
/* @__PURE__ */ jsx29(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
1631
1649
|
/* @__PURE__ */ jsx29(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
1632
1650
|
] }),
|
|
@@ -1636,14 +1654,14 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
1636
1654
|
}
|
|
1637
1655
|
|
|
1638
1656
|
// src/EditableText.tsx
|
|
1639
|
-
import { useEffect, useRef as useRef4, useState as
|
|
1657
|
+
import { useEffect, useRef as useRef4, useState as useState4 } from "react";
|
|
1640
1658
|
import { Field as BaseField3 } from "@base-ui/react/field";
|
|
1641
1659
|
import { Input as Input2 } from "@base-ui/react/input";
|
|
1642
1660
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
1643
1661
|
function EditableText({ value, display, displayNode, placeholder, onCommit, multiline = false, className, label, readOnly = false }) {
|
|
1644
|
-
const [editing, setEditing] =
|
|
1645
|
-
const [draft, setDraft] =
|
|
1646
|
-
const [busy, setBusy] =
|
|
1662
|
+
const [editing, setEditing] = useState4(false);
|
|
1663
|
+
const [draft, setDraft] = useState4(value);
|
|
1664
|
+
const [busy, setBusy] = useState4(false);
|
|
1647
1665
|
const fieldRef = useRef4(null);
|
|
1648
1666
|
useEffect(() => {
|
|
1649
1667
|
if (editing) {
|
|
@@ -1753,12 +1771,12 @@ function EditableText({ value, display, displayNode, placeholder, onCommit, mult
|
|
|
1753
1771
|
|
|
1754
1772
|
// src/EmptyState.tsx
|
|
1755
1773
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1756
|
-
import { jsx as jsx31, jsxs as
|
|
1774
|
+
import { jsx as jsx31, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1757
1775
|
function EmptyState({ icon, message, scope = "page", className }) {
|
|
1758
1776
|
if (scope === "section") {
|
|
1759
|
-
return /* @__PURE__ */ jsx31("p", { className: cn("text-
|
|
1777
|
+
return /* @__PURE__ */ jsx31("p", { className: cn("text-caption text-text-muted", className), children: message });
|
|
1760
1778
|
}
|
|
1761
|
-
return /* @__PURE__ */
|
|
1779
|
+
return /* @__PURE__ */ jsxs21("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1762
1780
|
/* @__PURE__ */ jsx31("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx31(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1763
1781
|
/* @__PURE__ */ jsx31("p", { className: "text-body-2 text-text-secondary text-center", children: message })
|
|
1764
1782
|
] });
|
|
@@ -1784,13 +1802,13 @@ function ProgressBar({ value, max, label, variant = "default", className }) {
|
|
|
1784
1802
|
}
|
|
1785
1803
|
|
|
1786
1804
|
// src/Skeleton.tsx
|
|
1787
|
-
import { jsx as jsx33, jsxs as
|
|
1805
|
+
import { jsx as jsx33, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1788
1806
|
function SkeletonBar({ className, style }) {
|
|
1789
1807
|
return /* @__PURE__ */ jsx33("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1790
1808
|
}
|
|
1791
1809
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1792
1810
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1793
|
-
return /* @__PURE__ */
|
|
1811
|
+
return /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1794
1812
|
/* @__PURE__ */ jsx33(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1795
1813
|
/* @__PURE__ */ jsx33(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1796
1814
|
] });
|
|
@@ -1800,12 +1818,12 @@ function SkeletonList({ rows = 8, className }) {
|
|
|
1800
1818
|
}
|
|
1801
1819
|
|
|
1802
1820
|
// src/Breadcrumb.tsx
|
|
1803
|
-
import { Fragment as Fragment6, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as
|
|
1804
|
-
import { jsx as jsx34, jsxs as
|
|
1821
|
+
import { Fragment as Fragment6, useCallback as useCallback2, useLayoutEffect as useLayoutEffect2, useRef as useRef5, useState as useState5 } from "react";
|
|
1822
|
+
import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
1805
1823
|
function Breadcrumb({ items, className }) {
|
|
1806
1824
|
const navRef = useRef5(null);
|
|
1807
1825
|
const labelRefs = useRef5([]);
|
|
1808
|
-
const [truncated, setTruncated] =
|
|
1826
|
+
const [truncated, setTruncated] = useState5(/* @__PURE__ */ new Set());
|
|
1809
1827
|
const measure = useCallback2(() => {
|
|
1810
1828
|
const next = /* @__PURE__ */ new Set();
|
|
1811
1829
|
labelRefs.current.forEach((el, index) => {
|
|
@@ -1821,7 +1839,7 @@ function Breadcrumb({ items, className }) {
|
|
|
1821
1839
|
observer.observe(nav);
|
|
1822
1840
|
return () => observer.disconnect();
|
|
1823
1841
|
}, [measure, items]);
|
|
1824
|
-
return /* @__PURE__ */ jsx34("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-
|
|
1842
|
+
return /* @__PURE__ */ jsx34("nav", { ref: navRef, "aria-label": "Breadcrumb", className: cn("flex min-w-0 items-center gap-1.5 text-body-2", className), children: items.map((item, index) => {
|
|
1825
1843
|
const last = index === items.length - 1;
|
|
1826
1844
|
const tone = item.muted || last && item.mono ? "text-text-muted" : last ? "text-text-primary" : "text-text-secondary";
|
|
1827
1845
|
const text = cn(
|
|
@@ -1829,14 +1847,14 @@ function Breadcrumb({ items, className }) {
|
|
|
1829
1847
|
// A mono crumb is a ref — the identity. It never gives up width to a
|
|
1830
1848
|
// long name beside it (the LongName story always claimed "the ref
|
|
1831
1849
|
// stays"; flexbox was squeezing it anyway until this line).
|
|
1832
|
-
item.mono && "shrink-0 font-mono text-
|
|
1850
|
+
item.mono && "shrink-0 font-mono text-caption",
|
|
1833
1851
|
tone
|
|
1834
1852
|
);
|
|
1835
1853
|
const setLabelRef = (el) => {
|
|
1836
1854
|
labelRefs.current[index] = el;
|
|
1837
1855
|
};
|
|
1838
1856
|
const crumb = item.href ? /* @__PURE__ */ jsx34("a", { ref: setLabelRef, href: item.href, onClick: item.onClick, className: cn(text, "hover:text-text-primary"), children: item.label }) : /* @__PURE__ */ jsx34("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
1839
|
-
return /* @__PURE__ */
|
|
1857
|
+
return /* @__PURE__ */ jsxs23(Fragment6, { children: [
|
|
1840
1858
|
index > 0 && /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
1841
1859
|
item.icon && /* @__PURE__ */ jsx34("span", { "aria-hidden": "true", className: cn("flex shrink-0", tone), children: item.icon }),
|
|
1842
1860
|
truncated.has(index) ? (
|
|
@@ -1850,9 +1868,9 @@ function Breadcrumb({ items, className }) {
|
|
|
1850
1868
|
}
|
|
1851
1869
|
|
|
1852
1870
|
// src/NavItem.tsx
|
|
1853
|
-
import { jsx as jsx35, jsxs as
|
|
1871
|
+
import { jsx as jsx35, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
1854
1872
|
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
1855
|
-
return /* @__PURE__ */
|
|
1873
|
+
return /* @__PURE__ */ jsxs24(
|
|
1856
1874
|
"a",
|
|
1857
1875
|
{
|
|
1858
1876
|
href,
|
|
@@ -1878,7 +1896,7 @@ function NavItem({ label, href, count, countLabel, active = false, icon, classNa
|
|
|
1878
1896
|
// src/Popover.tsx
|
|
1879
1897
|
import { useMemo as useMemo2 } from "react";
|
|
1880
1898
|
import { Popover as BasePopover } from "@base-ui/react/popover";
|
|
1881
|
-
import { jsx as jsx36, jsxs as
|
|
1899
|
+
import { jsx as jsx36, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
1882
1900
|
var GAP5 = 4;
|
|
1883
1901
|
var VIEWPORT_PAD5 = 8;
|
|
1884
1902
|
function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpenChange, finalFocus, actionsRef, ariaLabel, children, className, contentClassName, maxHeight }) {
|
|
@@ -1887,7 +1905,7 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
1887
1905
|
if (anchor instanceof Element) return anchor;
|
|
1888
1906
|
return { getBoundingClientRect: () => anchor };
|
|
1889
1907
|
}, [anchor]);
|
|
1890
|
-
return /* @__PURE__ */
|
|
1908
|
+
return /* @__PURE__ */ jsxs25(
|
|
1891
1909
|
BasePopover.Root,
|
|
1892
1910
|
{
|
|
1893
1911
|
open,
|
|
@@ -1958,8 +1976,8 @@ function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
|
1958
1976
|
}
|
|
1959
1977
|
);
|
|
1960
1978
|
}
|
|
1961
|
-
function ToolbarInput(props) {
|
|
1962
|
-
return /* @__PURE__ */ jsx37(BaseToolbar.Input, { render: /* @__PURE__ */ jsx37(TextInput, {}), ...props });
|
|
1979
|
+
function ToolbarInput({ size, ...props }) {
|
|
1980
|
+
return /* @__PURE__ */ jsx37(BaseToolbar.Input, { render: /* @__PURE__ */ jsx37(TextInput, { size }), ...props });
|
|
1963
1981
|
}
|
|
1964
1982
|
function ToolbarSeparator({ className }) {
|
|
1965
1983
|
return /* @__PURE__ */ jsx37(
|
|
@@ -1990,7 +2008,7 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
1990
2008
|
"aria-label": option.label,
|
|
1991
2009
|
tooltip: option.label,
|
|
1992
2010
|
onClick: () => onSelect(option.emoji),
|
|
1993
|
-
className: "size-7 text-
|
|
2011
|
+
className: "size-7 text-h3 leading-none",
|
|
1994
2012
|
children: /* @__PURE__ */ jsx38("span", { "aria-hidden": "true", children: option.emoji })
|
|
1995
2013
|
},
|
|
1996
2014
|
option.emoji
|
|
@@ -2000,13 +2018,13 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2000
2018
|
|
|
2001
2019
|
// src/PreviewCard.tsx
|
|
2002
2020
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
2003
|
-
import { jsx as jsx39, jsxs as
|
|
2021
|
+
import { jsx as jsx39, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2004
2022
|
var GAP6 = 12;
|
|
2005
2023
|
var VIEWPORT_PAD6 = 8;
|
|
2006
2024
|
var OPEN_DELAY2 = 350;
|
|
2007
2025
|
var CLOSE_DELAY = 200;
|
|
2008
2026
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, wrapperClassName }) {
|
|
2009
|
-
return /* @__PURE__ */
|
|
2027
|
+
return /* @__PURE__ */ jsxs26(BasePreviewCard.Root, { children: [
|
|
2010
2028
|
/* @__PURE__ */ jsx39(
|
|
2011
2029
|
BasePreviewCard.Trigger,
|
|
2012
2030
|
{
|
|
@@ -2044,9 +2062,9 @@ function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
|
2044
2062
|
}
|
|
2045
2063
|
|
|
2046
2064
|
// src/RailItem.tsx
|
|
2047
|
-
import { jsx as jsx41, jsxs as
|
|
2065
|
+
import { jsx as jsx41, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2048
2066
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
2049
|
-
return /* @__PURE__ */
|
|
2067
|
+
return /* @__PURE__ */ jsxs27(
|
|
2050
2068
|
"a",
|
|
2051
2069
|
{
|
|
2052
2070
|
href,
|
|
@@ -2073,7 +2091,7 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
2073
2091
|
)
|
|
2074
2092
|
}
|
|
2075
2093
|
),
|
|
2076
|
-
/* @__PURE__ */ jsx41("span", { className: cn("text-center text-
|
|
2094
|
+
/* @__PURE__ */ jsx41("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
2077
2095
|
]
|
|
2078
2096
|
}
|
|
2079
2097
|
);
|
|
@@ -2093,33 +2111,34 @@ function Sidebar({ "aria-label": ariaLabel = "Workspace", children, className })
|
|
|
2093
2111
|
}
|
|
2094
2112
|
|
|
2095
2113
|
// src/Property.tsx
|
|
2096
|
-
import { jsx as jsx43, jsxs as
|
|
2114
|
+
import { jsx as jsx43, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2115
|
+
var VALUE_CLASSES = "contents";
|
|
2097
2116
|
function Property({ label, layout = "row", children, className }) {
|
|
2098
2117
|
if (layout === "stacked") {
|
|
2099
2118
|
return (
|
|
2100
2119
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
2101
2120
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
2102
2121
|
// 6px, and unifying means the bigger, calmer one.
|
|
2103
|
-
/* @__PURE__ */
|
|
2104
|
-
/* @__PURE__ */ jsx43("
|
|
2105
|
-
children
|
|
2122
|
+
/* @__PURE__ */ jsxs28("dl", { className: cn("flex flex-col gap-3", className), children: [
|
|
2123
|
+
/* @__PURE__ */ jsx43("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
|
|
2124
|
+
/* @__PURE__ */ jsx43("dd", { className: VALUE_CLASSES, children })
|
|
2106
2125
|
] })
|
|
2107
2126
|
);
|
|
2108
2127
|
}
|
|
2109
|
-
return /* @__PURE__ */
|
|
2110
|
-
/* @__PURE__ */ jsx43("
|
|
2111
|
-
children
|
|
2128
|
+
return /* @__PURE__ */ jsxs28("dl", { className: cn("flex items-center gap-2", className), children: [
|
|
2129
|
+
/* @__PURE__ */ jsx43("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
2130
|
+
/* @__PURE__ */ jsx43("dd", { className: VALUE_CLASSES, children })
|
|
2112
2131
|
] });
|
|
2113
2132
|
}
|
|
2114
2133
|
|
|
2115
2134
|
// src/Reaction.tsx
|
|
2116
|
-
import {
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2135
|
+
import { Toggle } from "@base-ui/react/toggle";
|
|
2136
|
+
import { jsx as jsx44, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2137
|
+
function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
2138
|
+
return /* @__PURE__ */ jsxs29(
|
|
2139
|
+
Toggle,
|
|
2120
2140
|
{
|
|
2121
|
-
|
|
2122
|
-
"aria-pressed": pressed,
|
|
2141
|
+
pressed,
|
|
2123
2142
|
className: cn(
|
|
2124
2143
|
// Chip's pill at a control's height, so a reaction and a status chip
|
|
2125
2144
|
// read as the same family — 24px matches Button `small`.
|
|
@@ -2138,8 +2157,8 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
|
|
|
2138
2157
|
),
|
|
2139
2158
|
...props,
|
|
2140
2159
|
children: [
|
|
2141
|
-
/* @__PURE__ */ jsx44("span", { "aria-hidden": "true", className: "shrink-0 text-
|
|
2142
|
-
/* @__PURE__ */ jsx44("span", { className: "text-chip signal:font-mono signal:text-
|
|
2160
|
+
/* @__PURE__ */ jsx44("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
|
|
2161
|
+
/* @__PURE__ */ jsx44("span", { className: "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums", children: count })
|
|
2143
2162
|
]
|
|
2144
2163
|
}
|
|
2145
2164
|
);
|
|
@@ -2148,9 +2167,9 @@ function Reaction({ emoji, count, pressed = false, className, type, ...props })
|
|
|
2148
2167
|
// src/SearchInput.tsx
|
|
2149
2168
|
import "react";
|
|
2150
2169
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
2151
|
-
import { jsx as jsx45, jsxs as
|
|
2170
|
+
import { jsx as jsx45, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2152
2171
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
2153
|
-
return /* @__PURE__ */
|
|
2172
|
+
return /* @__PURE__ */ jsxs30(
|
|
2154
2173
|
"div",
|
|
2155
2174
|
{
|
|
2156
2175
|
className: cn(
|
|
@@ -2177,7 +2196,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2177
2196
|
// src/SectionHeader.tsx
|
|
2178
2197
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
2179
2198
|
import { useRender } from "@base-ui/react/use-render";
|
|
2180
|
-
import { Fragment as Fragment7, jsx as jsx46, jsxs as
|
|
2199
|
+
import { Fragment as Fragment7, jsx as jsx46, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2181
2200
|
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", render, className }) {
|
|
2182
2201
|
const titleElement = useRender({
|
|
2183
2202
|
render: render ?? (chevron ? /* @__PURE__ */ jsx46("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx46("span", {})),
|
|
@@ -2186,7 +2205,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2186
2205
|
// whole row up to the actions is the hit target, as it was when the
|
|
2187
2206
|
// row itself carried the click.
|
|
2188
2207
|
className: "flex h-full min-w-0 flex-1 items-center gap-1 text-left",
|
|
2189
|
-
children: /* @__PURE__ */
|
|
2208
|
+
children: /* @__PURE__ */ jsxs31(Fragment7, { children: [
|
|
2190
2209
|
chevron && /* @__PURE__ */ jsx46(
|
|
2191
2210
|
IconChevronRight2,
|
|
2192
2211
|
{
|
|
@@ -2199,7 +2218,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2199
2218
|
] })
|
|
2200
2219
|
}
|
|
2201
2220
|
});
|
|
2202
|
-
return /* @__PURE__ */
|
|
2221
|
+
return /* @__PURE__ */ jsxs31(
|
|
2203
2222
|
"div",
|
|
2204
2223
|
{
|
|
2205
2224
|
className: cn(
|
|
@@ -2229,9 +2248,9 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2229
2248
|
}
|
|
2230
2249
|
|
|
2231
2250
|
// src/CollapsibleSection.tsx
|
|
2232
|
-
import { useState as
|
|
2251
|
+
import { useState as useState6 } from "react";
|
|
2233
2252
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
2234
|
-
import { jsx as jsx47, jsxs as
|
|
2253
|
+
import { jsx as jsx47, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2235
2254
|
var OPEN = "open";
|
|
2236
2255
|
var CLOSED = "closed";
|
|
2237
2256
|
function readStored(key) {
|
|
@@ -2251,14 +2270,14 @@ function writeStored(key, open) {
|
|
|
2251
2270
|
}
|
|
2252
2271
|
}
|
|
2253
2272
|
function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, children, className, contentClassName }) {
|
|
2254
|
-
const [openState, setOpenState] =
|
|
2273
|
+
const [openState, setOpenState] = useState6(() => readStored(storageKey) ?? defaultOpen);
|
|
2255
2274
|
const open = openProp ?? openState;
|
|
2256
2275
|
const setOpen = (next) => {
|
|
2257
2276
|
setOpenState(next);
|
|
2258
2277
|
writeStored(storageKey, next);
|
|
2259
2278
|
onOpenChange?.(next);
|
|
2260
2279
|
};
|
|
2261
|
-
return /* @__PURE__ */
|
|
2280
|
+
return /* @__PURE__ */ jsxs32(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
2262
2281
|
/* @__PURE__ */ jsx47(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, className: "shrink-0", render: /* @__PURE__ */ jsx47(Collapsible.Trigger, {}) }),
|
|
2263
2282
|
/* @__PURE__ */ jsx47(
|
|
2264
2283
|
Collapsible.Panel,
|
|
@@ -2273,7 +2292,7 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
2273
2292
|
|
|
2274
2293
|
// src/Tabs.tsx
|
|
2275
2294
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
2276
|
-
import { jsx as jsx48, jsxs as
|
|
2295
|
+
import { jsx as jsx48, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2277
2296
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
2278
2297
|
return /* @__PURE__ */ jsx48(
|
|
2279
2298
|
BaseTabs.Root,
|
|
@@ -2290,7 +2309,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2290
2309
|
"aria-label": aria["aria-label"],
|
|
2291
2310
|
"aria-labelledby": aria["aria-labelledby"],
|
|
2292
2311
|
className: "flex items-center gap-2",
|
|
2293
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
2312
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs33(
|
|
2294
2313
|
BaseTabs.Tab,
|
|
2295
2314
|
{
|
|
2296
2315
|
value: tab.id,
|
|
@@ -2303,7 +2322,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2303
2322
|
),
|
|
2304
2323
|
children: [
|
|
2305
2324
|
tab.icon,
|
|
2306
|
-
/* @__PURE__ */
|
|
2325
|
+
/* @__PURE__ */ jsxs33("span", { className: "flex items-baseline", children: [
|
|
2307
2326
|
tab.label,
|
|
2308
2327
|
tab.count !== void 0 ? /* @__PURE__ */ jsx48("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
2309
2328
|
] })
|
|
@@ -2318,16 +2337,16 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2318
2337
|
}
|
|
2319
2338
|
|
|
2320
2339
|
// src/Toast.tsx
|
|
2321
|
-
import { createContext as createContext2,
|
|
2322
|
-
import {
|
|
2340
|
+
import { createContext as createContext2, useContext as useContext2, useMemo as useMemo3 } from "react";
|
|
2341
|
+
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
2323
2342
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
2324
|
-
import { jsx as jsx49, jsxs as
|
|
2343
|
+
import { jsx as jsx49, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
2325
2344
|
var SURFACE_STYLES = {
|
|
2326
|
-
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-
|
|
2327
|
-
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-
|
|
2328
|
-
neutral: "bg-bg-inset border border-border-subtle signal:border-border-default signal:shadow-
|
|
2329
|
-
warning: "bg-warning-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-
|
|
2330
|
-
error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-
|
|
2345
|
+
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
2346
|
+
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
2347
|
+
neutral: "bg-bg-inset border border-border-subtle signal:border-border-default signal:shadow-md",
|
|
2348
|
+
warning: "bg-warning-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md",
|
|
2349
|
+
error: "bg-error-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md"
|
|
2331
2350
|
};
|
|
2332
2351
|
var ICONS = {
|
|
2333
2352
|
success: IconCircleCheck,
|
|
@@ -2353,82 +2372,90 @@ var ACTION_BORDER_STYLES = {
|
|
|
2353
2372
|
warning: "signal:border signal:border-border-default signal:hover:border-border-strong",
|
|
2354
2373
|
error: "signal:border signal:border-border-default signal:hover:border-border-strong"
|
|
2355
2374
|
};
|
|
2375
|
+
var LABEL_CLASSES = "text-body-2 text-text-primary whitespace-nowrap";
|
|
2376
|
+
var pillClassName = (type, hasAction, className) => cn(
|
|
2377
|
+
"inline-flex items-center min-h-[32px] pl-2 py-1 rounded-lg shadow-lg",
|
|
2378
|
+
// Without an action the label needs real right padding; the action
|
|
2379
|
+
// button brings its own edge, so the tight pr-1 only applies there.
|
|
2380
|
+
hasAction ? "pr-1 gap-[46px]" : "pr-3",
|
|
2381
|
+
SURFACE_STYLES[type],
|
|
2382
|
+
className
|
|
2383
|
+
);
|
|
2384
|
+
var actionClassName = (type) => cn(
|
|
2385
|
+
"h-6 flex items-center justify-center gap-1 px-1 py-1 rounded-md shrink-0 transition-colors",
|
|
2386
|
+
ACTION_BORDER_STYLES[type],
|
|
2387
|
+
type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
|
|
2388
|
+
);
|
|
2389
|
+
function LeadingIcon({ type }) {
|
|
2390
|
+
const Icon = ICONS[type];
|
|
2391
|
+
return /* @__PURE__ */ jsx49(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
2392
|
+
}
|
|
2393
|
+
var ACTION_LABEL_CLASSES = "text-btn-small text-text-primary whitespace-nowrap";
|
|
2356
2394
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
2357
2395
|
const hasAction = !!(actionLabel && onAction);
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
// button brings its own edge, so the tight pr-1 only applies there.
|
|
2366
|
-
hasAction ? "pr-1 gap-[46px]" : "pr-3",
|
|
2367
|
-
SURFACE_STYLES[type],
|
|
2368
|
-
className
|
|
2369
|
-
),
|
|
2370
|
-
children: [
|
|
2371
|
-
/* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2372
|
-
leadingIcon && /* @__PURE__ */ jsx49(LeadingIcon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) }),
|
|
2373
|
-
/* @__PURE__ */ jsx49("span", { className: "font-normal text-[14px] leading-[1.4] text-text-primary whitespace-nowrap", children: label })
|
|
2374
|
-
] }),
|
|
2375
|
-
hasAction && /* @__PURE__ */ jsx49(
|
|
2376
|
-
"button",
|
|
2377
|
-
{
|
|
2378
|
-
type: "button",
|
|
2379
|
-
onClick: onAction,
|
|
2380
|
-
className: cn(
|
|
2381
|
-
"h-6 flex items-center justify-center gap-1 px-1 py-1 rounded-md shrink-0 transition-colors",
|
|
2382
|
-
ACTION_BORDER_STYLES[type],
|
|
2383
|
-
type === "neutral" ? "hover:border-border-strong" : "hover:opacity-80"
|
|
2384
|
-
),
|
|
2385
|
-
children: /* @__PURE__ */ jsx49("span", { className: "font-medium text-[12px] leading-[12px] text-text-primary whitespace-nowrap", children: actionLabel })
|
|
2386
|
-
}
|
|
2387
|
-
)
|
|
2388
|
-
]
|
|
2389
|
-
}
|
|
2390
|
-
);
|
|
2396
|
+
return /* @__PURE__ */ jsxs34("div", { className: pillClassName(type, hasAction, className), children: [
|
|
2397
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2398
|
+
leadingIcon && /* @__PURE__ */ jsx49(LeadingIcon, { type }),
|
|
2399
|
+
/* @__PURE__ */ jsx49("span", { className: LABEL_CLASSES, children: label })
|
|
2400
|
+
] }),
|
|
2401
|
+
hasAction && /* @__PURE__ */ jsx49("button", { type: "button", onClick: onAction, className: actionClassName(type), children: /* @__PURE__ */ jsx49("span", { className: ACTION_LABEL_CLASSES, children: actionLabel }) })
|
|
2402
|
+
] });
|
|
2391
2403
|
}
|
|
2392
2404
|
var ToastContext = createContext2(null);
|
|
2393
|
-
var
|
|
2405
|
+
var VISIBLE_TOASTS = 3;
|
|
2394
2406
|
function ToastProvider({ children }) {
|
|
2395
|
-
const
|
|
2396
|
-
const
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
const value = useMemo3(() => ({ showToast, dismissToast }), [showToast, dismissToast]);
|
|
2412
|
-
return /* @__PURE__ */ jsxs33(ToastContext.Provider, { value, children: [
|
|
2407
|
+
const manager = useMemo3(() => BaseToast.createToastManager(), []);
|
|
2408
|
+
const value = useMemo3(
|
|
2409
|
+
() => ({
|
|
2410
|
+
showToast: ({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, durationMs = 5e3 }) => manager.add({
|
|
2411
|
+
title: label,
|
|
2412
|
+
type,
|
|
2413
|
+
timeout: durationMs,
|
|
2414
|
+
// A failure interrupts; everything else waits for a pause.
|
|
2415
|
+
priority: type === "error" ? "high" : "low",
|
|
2416
|
+
data: { leadingIcon, actionLabel, onAction }
|
|
2417
|
+
}),
|
|
2418
|
+
dismissToast: (id) => manager.close(id)
|
|
2419
|
+
}),
|
|
2420
|
+
[manager]
|
|
2421
|
+
);
|
|
2422
|
+
return /* @__PURE__ */ jsx49(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs34(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
2413
2423
|
children,
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2424
|
+
/* @__PURE__ */ jsx49(BaseToast.Portal, { children: /* @__PURE__ */ jsx49(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx49(ToastList, {}) }) })
|
|
2425
|
+
] }) });
|
|
2426
|
+
}
|
|
2427
|
+
function ToastList() {
|
|
2428
|
+
const { toasts, close } = BaseToast.useToastManager();
|
|
2429
|
+
return toasts.map((toast) => {
|
|
2430
|
+
const type = toast.type ?? "neutral";
|
|
2431
|
+
const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
|
|
2432
|
+
return /* @__PURE__ */ jsxs34(
|
|
2433
|
+
BaseToast.Root,
|
|
2434
|
+
{
|
|
2435
|
+
toast,
|
|
2436
|
+
swipeDirection: ["left", "down"],
|
|
2437
|
+
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
2438
|
+
children: [
|
|
2439
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
2440
|
+
leadingIcon && /* @__PURE__ */ jsx49(LeadingIcon, { type }),
|
|
2441
|
+
/* @__PURE__ */ jsx49(BaseToast.Title, { render: /* @__PURE__ */ jsx49("span", {}), className: LABEL_CLASSES })
|
|
2442
|
+
] }),
|
|
2443
|
+
actionLabel && /* @__PURE__ */ jsx49(
|
|
2444
|
+
BaseToast.Action,
|
|
2445
|
+
{
|
|
2446
|
+
onClick: () => {
|
|
2447
|
+
onAction?.();
|
|
2448
|
+
close(toast.id);
|
|
2449
|
+
},
|
|
2450
|
+
className: actionClassName(type),
|
|
2451
|
+
children: /* @__PURE__ */ jsx49("span", { className: ACTION_LABEL_CLASSES, children: actionLabel })
|
|
2452
|
+
}
|
|
2453
|
+
)
|
|
2454
|
+
]
|
|
2455
|
+
},
|
|
2456
|
+
toast.id
|
|
2457
|
+
);
|
|
2458
|
+
});
|
|
2432
2459
|
}
|
|
2433
2460
|
function useToast() {
|
|
2434
2461
|
const ctx = useContext2(ToastContext);
|