@estiva-app/ui 0.44.1 → 0.46.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/CollapsibleSection.d.ts +7 -1
- package/dist/CollapsibleSection.d.ts.map +1 -1
- package/dist/InlineChip.d.ts +1 -1
- package/dist/NavItem.d.ts +11 -1
- package/dist/NavItem.d.ts.map +1 -1
- package/dist/SectionHeader.d.ts +9 -1
- package/dist/SectionHeader.d.ts.map +1 -1
- package/dist/SelectionToolbar.d.ts +62 -0
- package/dist/SelectionToolbar.d.ts.map +1 -0
- package/dist/SuggestionMenu.d.ts +75 -0
- package/dist/SuggestionMenu.d.ts.map +1 -0
- package/dist/editor.d.ts +12 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +357 -0
- package/dist/editor.js.map +7 -0
- package/dist/eslint/index.js +4 -3
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-restyled-part.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +274 -133
- package/dist/index.js.map +4 -4
- package/dist/looks.d.ts +3 -0
- package/dist/looks.d.ts.map +1 -1
- package/dist/registry/{app-YMABQII6.js → app-LDGOH6UW.js} +3 -3
- package/dist/registry/{build-3EANARLQ.js → build-P6X3PTZP.js} +6 -2
- package/dist/registry/build.d.ts +4 -0
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/{chunk-SIB44CES.js → chunk-P55P2QFD.js} +9 -4
- package/dist/registry/chunk-P55P2QFD.js.map +7 -0
- package/dist/registry/{chunk-EVJW26UR.js → chunk-TQ6UQER3.js} +10 -10
- package/dist/registry/chunk-TQ6UQER3.js.map +7 -0
- package/dist/registry/cli.js +2 -2
- package/dist/registry/index.js +2 -2
- package/dist/shortcuts.d.ts +27 -0
- package/dist/shortcuts.d.ts.map +1 -0
- package/dist/suggestionPopup.d.ts +41 -0
- package/dist/suggestionPopup.d.ts.map +1 -0
- package/package.json +27 -2
- package/registry.json +391 -11
- package/src/Chip.tsx +1 -1
- package/src/CollapsibleSection.mdx +5 -0
- package/src/CollapsibleSection.stories.tsx +5 -0
- package/src/CollapsibleSection.tsx +10 -3
- package/src/CommandPalette.tsx +1 -1
- package/src/InlineChip.test.tsx +1 -1
- package/src/InlineChip.tsx +1 -1
- package/src/NavItem.mdx +9 -0
- package/src/NavItem.stories.tsx +23 -0
- package/src/NavItem.tsx +56 -6
- package/src/Reaction.tsx +1 -1
- package/src/SectionHeader.mdx +9 -0
- package/src/SectionHeader.stories.tsx +15 -0
- package/src/SectionHeader.tsx +28 -7
- package/src/SelectionToolbar.mdx +78 -0
- package/src/SelectionToolbar.stories.tsx +63 -0
- package/src/SelectionToolbar.test.ts +105 -0
- package/src/SelectionToolbar.tsx +487 -0
- package/src/SuggestionMenu.mdx +107 -0
- package/src/SuggestionMenu.stories.tsx +202 -0
- package/src/SuggestionMenu.test.tsx +128 -0
- package/src/SuggestionMenu.tsx +189 -0
- package/src/editor.ts +11 -0
- package/src/eslint/no-rebuilt-behaviour.test.ts +1 -1
- package/src/eslint/no-rebuilt-behaviour.ts +2 -2
- package/src/eslint/no-restyled-part.ts +2 -1
- package/src/how.test.ts +1 -1
- package/src/index.ts +2 -0
- package/src/keptSelection.test.ts +67 -0
- package/src/looks.ts +4 -0
- package/src/registry/app.ts +8 -8
- package/src/registry/build.ts +10 -2
- package/src/registry/registry.test.ts +14 -9
- package/src/shortcuts.ts +40 -0
- package/src/suggestionPopup.tsx +119 -0
- package/stories/Choosing.mdx +2 -0
- package/tailwind-preset.js +1 -0
- package/tokens.css +19 -4
- package/dist/registry/chunk-EVJW26UR.js.map +0 -7
- package/dist/registry/chunk-SIB44CES.js.map +0 -7
- /package/dist/registry/{app-YMABQII6.js.map → app-LDGOH6UW.js.map} +0 -0
- /package/dist/registry/{build-3EANARLQ.js.map → build-P6X3PTZP.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -319,6 +319,8 @@ var FIELD_SHELL_CLASSES = "bg-bg-field border border-border-field shadow-field h
|
|
|
319
319
|
var FLOATING_SURFACE_CLASSES = "rounded-lg border border-border-default bg-bg-elevated shadow-lg";
|
|
320
320
|
var CHIP_TEXT_CLASSES = "text-chip signal:font-mono signal:text-small signal:font-semibold signal:tabular-nums";
|
|
321
321
|
var BARE_INPUT_CLASSES = "bg-transparent text-text-primary placeholder:text-text-muted outline-none";
|
|
322
|
+
var SIDEBAR_ROW_CLASSES = "rounded-md transition-colors";
|
|
323
|
+
var SIDEBAR_ROW_TEXT_CLASSES = "text-text-secondary hover:text-text-primary";
|
|
322
324
|
|
|
323
325
|
// src/Tooltip.tsx
|
|
324
326
|
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
@@ -1004,7 +1006,7 @@ function Checkbox({ checked, onChange, disabled: ownDisabled = false, label, row
|
|
|
1004
1006
|
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1005
1007
|
var typeStyles = {
|
|
1006
1008
|
neutral: "bg-bg-inset text-text-primary",
|
|
1007
|
-
brand: "bg-accent-muted text-accent-
|
|
1009
|
+
brand: "bg-accent-muted text-accent-text signal:border signal:border-accent-outline",
|
|
1008
1010
|
info: "bg-info-muted text-info-default signal:border signal:border-info-outline",
|
|
1009
1011
|
warning: "bg-warning-muted text-warning-default signal:border signal:border-warning-outline signal:shadow-glow-warning",
|
|
1010
1012
|
success: "bg-success-muted text-success-default signal:border signal:border-success-outline",
|
|
@@ -1922,7 +1924,7 @@ function CommandPaletteAnswer({ children, note }) {
|
|
|
1922
1924
|
const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
|
|
1923
1925
|
return /* @__PURE__ */ jsxs18("div", { className: "flex flex-col gap-2", children: [
|
|
1924
1926
|
paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx26("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
|
|
1925
|
-
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx26("sup", { className: "ml-0.5 font-mono text-small text-accent-
|
|
1927
|
+
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx26("sup", { className: "ml-0.5 font-mono text-small text-accent-text", children: part.slice(1, -1) }, j) : part
|
|
1926
1928
|
) }, i)),
|
|
1927
1929
|
note && /* @__PURE__ */ jsx26(FieldLine, { children: note })
|
|
1928
1930
|
] });
|
|
@@ -1947,7 +1949,7 @@ var INLINE_CHIP_TONE_CLASSES = {
|
|
|
1947
1949
|
/** A thing or a place — anything that is not a person. */
|
|
1948
1950
|
neutral: "bg-bg-active text-text-primary",
|
|
1949
1951
|
/** A person. */
|
|
1950
|
-
person: "bg-accent-muted text-accent-
|
|
1952
|
+
person: "bg-accent-muted text-accent-text",
|
|
1951
1953
|
/** A person, called urgently. */
|
|
1952
1954
|
urgent: "bg-warning-muted text-warning-default",
|
|
1953
1955
|
/**
|
|
@@ -2792,32 +2794,61 @@ function Breadcrumb({ items, className }) {
|
|
|
2792
2794
|
}
|
|
2793
2795
|
|
|
2794
2796
|
// src/NavItem.tsx
|
|
2797
|
+
import { IconDotsVertical } from "@tabler/icons-react";
|
|
2795
2798
|
import { jsx as jsx43, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2796
|
-
function NavItem({ label, href, count, countLabel, active = false, icon, className, ...props }) {
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2799
|
+
function NavItem({ label, href, count, countLabel, active = false, icon, menu, menuLabel, className, ...props }) {
|
|
2800
|
+
const row = /* @__PURE__ */ jsxs29(
|
|
2801
|
+
"a",
|
|
2802
|
+
{
|
|
2803
|
+
href,
|
|
2804
|
+
"aria-current": active ? "page" : void 0,
|
|
2805
|
+
className: cn(
|
|
2806
|
+
// shrink-0: the row keeps its 32px inside an overflowing flex column
|
|
2807
|
+
// — without it the list compresses instead of scrolling (the missing-
|
|
2808
|
+
// shrink-0 family; Katerina, 2026-09-02).
|
|
2809
|
+
"flex h-8 min-w-0 shrink-0 items-center gap-2 px-2 text-body-2",
|
|
2810
|
+
SIDEBAR_ROW_CLASSES,
|
|
2811
|
+
active ? "bg-bg-active text-text-primary" : cn(SIDEBAR_ROW_TEXT_CLASSES, "hover:bg-bg-hover"),
|
|
2812
|
+
// With a menu the ⋮ sits beside the link, so the row keeps its hover
|
|
2813
|
+
// look while the ⋮ is pointed at and while its menu is open.
|
|
2814
|
+
menu != null && !active && "group-hover/nav:bg-bg-hover group-hover/nav:text-text-primary group-has-[[aria-expanded=true]]/nav:bg-bg-hover group-has-[[aria-expanded=true]]/nav:text-text-primary",
|
|
2815
|
+
className
|
|
2816
|
+
),
|
|
2817
|
+
...props,
|
|
2818
|
+
children: [
|
|
2819
|
+
icon && /* @__PURE__ */ jsx43("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
2820
|
+
/* @__PURE__ */ jsx43("span", { className: "flex-1 truncate", children: label }),
|
|
2821
|
+
count ? /* @__PURE__ */ jsx43(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx43(
|
|
2822
|
+
"span",
|
|
2823
|
+
{
|
|
2824
|
+
className: cn(
|
|
2825
|
+
"min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted",
|
|
2826
|
+
// With a menu, the ⋮ takes this place while it shows.
|
|
2827
|
+
menu != null && "transition-opacity group-hover/nav:opacity-0 group-focus-within/nav:opacity-0 group-has-[[aria-expanded=true]]/nav:opacity-0"
|
|
2828
|
+
),
|
|
2829
|
+
children: count
|
|
2830
|
+
}
|
|
2831
|
+
) }) : menu != null ? (
|
|
2832
|
+
// No count, but a menu: the count's place is kept free, so a long
|
|
2833
|
+
// label truncates before the ⋮ instead of running under it.
|
|
2834
|
+
/* @__PURE__ */ jsx43("span", { "aria-hidden": "true", className: "min-w-4 shrink-0" })
|
|
2835
|
+
) : null
|
|
2836
|
+
]
|
|
2837
|
+
}
|
|
2838
|
+
);
|
|
2839
|
+
if (menu == null) return row;
|
|
2840
|
+
const name = menuLabel ?? `More options for ${label}`;
|
|
2841
|
+
return /* @__PURE__ */ jsxs29("div", { className: "group/nav relative shrink-0", children: [
|
|
2842
|
+
row,
|
|
2843
|
+
/* @__PURE__ */ jsx43("div", { className: "absolute inset-y-0 right-1 flex items-center opacity-0 transition-opacity focus-within:opacity-100 group-hover/nav:opacity-100 has-[[aria-expanded=true]]:opacity-100", children: /* @__PURE__ */ jsx43(
|
|
2844
|
+
Menu,
|
|
2801
2845
|
{
|
|
2802
|
-
|
|
2803
|
-
"aria-
|
|
2804
|
-
|
|
2805
|
-
// shrink-0: the row keeps its 32px inside an overflowing flex column
|
|
2806
|
-
// — without it the list compresses instead of scrolling (the missing-
|
|
2807
|
-
// shrink-0 family; Katerina, 2026-09-02).
|
|
2808
|
-
"flex h-8 min-w-0 shrink-0 items-center gap-2 rounded-md px-2 text-body-2 transition-colors",
|
|
2809
|
-
active ? "bg-bg-active text-text-primary" : "text-text-secondary hover:bg-bg-hover hover:text-text-primary",
|
|
2810
|
-
className
|
|
2811
|
-
),
|
|
2812
|
-
...props,
|
|
2813
|
-
children: [
|
|
2814
|
-
icon && /* @__PURE__ */ jsx43("span", { className: "flex shrink-0 items-center", children: icon }),
|
|
2815
|
-
/* @__PURE__ */ jsx43("span", { className: "flex-1 truncate", children: label }),
|
|
2816
|
-
count ? /* @__PURE__ */ jsx43(WithTooltip, { label: countLabel ?? `${count} open`, children: /* @__PURE__ */ jsx43("span", { className: "min-w-4 shrink-0 text-center font-mono text-caption tabular-nums text-text-muted", children: count }) }) : null
|
|
2817
|
-
]
|
|
2846
|
+
align: "right",
|
|
2847
|
+
trigger: /* @__PURE__ */ jsx43(IconButton, { tooltip: "More options", "aria-label": name, children: /* @__PURE__ */ jsx43(IconDotsVertical, { size: 16, stroke: 1.5 }) }),
|
|
2848
|
+
children: menu
|
|
2818
2849
|
}
|
|
2819
|
-
)
|
|
2820
|
-
);
|
|
2850
|
+
) })
|
|
2851
|
+
] });
|
|
2821
2852
|
}
|
|
2822
2853
|
|
|
2823
2854
|
// src/Popover.tsx
|
|
@@ -2875,11 +2906,97 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2875
2906
|
);
|
|
2876
2907
|
}
|
|
2877
2908
|
|
|
2909
|
+
// src/SuggestionMenu.tsx
|
|
2910
|
+
import { useCallback as useCallback3, useEffect as useEffect4, useId, useImperativeHandle, useMemo as useMemo4, useState as useState7 } from "react";
|
|
2911
|
+
import { jsx as jsx45, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2912
|
+
function SuggestionMenu({ rect, editorElement, ariaLabel, width, maxHeight, sections, itemKey, row, onSelect, handle }) {
|
|
2913
|
+
const shown = useMemo4(() => sections.filter((section) => section.items.length > 0), [sections]);
|
|
2914
|
+
const items = useMemo4(() => shown.flatMap((section) => section.items), [shown]);
|
|
2915
|
+
const keys = items.map(itemKey).join("\n");
|
|
2916
|
+
const [highlight, setHighlight] = useState7(0);
|
|
2917
|
+
const base = useId();
|
|
2918
|
+
const listboxId = `${base}-list`;
|
|
2919
|
+
useEffect4(() => setHighlight(0), [keys]);
|
|
2920
|
+
useImperativeHandle(handle, () => ({
|
|
2921
|
+
// The editor hands its arrow keys to this list: Base UI's lists need a text field of their own, and an editor is not one.
|
|
2922
|
+
onKeyDown: (event) => {
|
|
2923
|
+
if (!items.length) return false;
|
|
2924
|
+
if (event.key === "ArrowDown") {
|
|
2925
|
+
setHighlight((h) => (h + 1) % items.length);
|
|
2926
|
+
return true;
|
|
2927
|
+
}
|
|
2928
|
+
if (event.key === "ArrowUp") {
|
|
2929
|
+
setHighlight((h) => (h - 1 + items.length) % items.length);
|
|
2930
|
+
return true;
|
|
2931
|
+
}
|
|
2932
|
+
if (event.key === "Enter") {
|
|
2933
|
+
const item = items[highlight];
|
|
2934
|
+
if (item !== void 0) onSelect(item);
|
|
2935
|
+
return true;
|
|
2936
|
+
}
|
|
2937
|
+
return false;
|
|
2938
|
+
}
|
|
2939
|
+
}), [items, highlight, onSelect]);
|
|
2940
|
+
const open = rect !== null && items.length > 0;
|
|
2941
|
+
useEffect4(() => {
|
|
2942
|
+
if (!editorElement || !open) return;
|
|
2943
|
+
editorElement.setAttribute("aria-autocomplete", "list");
|
|
2944
|
+
editorElement.setAttribute("aria-haspopup", "listbox");
|
|
2945
|
+
editorElement.setAttribute("aria-controls", listboxId);
|
|
2946
|
+
return () => {
|
|
2947
|
+
for (const name of ["aria-autocomplete", "aria-haspopup", "aria-controls", "aria-activedescendant"]) editorElement.removeAttribute(name);
|
|
2948
|
+
};
|
|
2949
|
+
}, [editorElement, open, listboxId]);
|
|
2950
|
+
useEffect4(() => {
|
|
2951
|
+
if (!editorElement || !open) return;
|
|
2952
|
+
editorElement.setAttribute("aria-activedescendant", `${base}-${highlight}`);
|
|
2953
|
+
}, [editorElement, open, base, highlight]);
|
|
2954
|
+
const scrollRef = useCallback3((el) => {
|
|
2955
|
+
el?.scrollIntoView({ block: "nearest" });
|
|
2956
|
+
}, []);
|
|
2957
|
+
if (items.length === 0) return null;
|
|
2958
|
+
const drawRow = (item) => {
|
|
2959
|
+
const index = items.indexOf(item);
|
|
2960
|
+
const selected = index === highlight;
|
|
2961
|
+
const { label, description, leading, shortcut, hint, size } = row(item);
|
|
2962
|
+
return (
|
|
2963
|
+
// A row of a list the editor drives from its caret: focus stays in the text, so the row is no Tab stop.
|
|
2964
|
+
/* @__PURE__ */ jsx45(
|
|
2965
|
+
MenuItem,
|
|
2966
|
+
{
|
|
2967
|
+
role: "option",
|
|
2968
|
+
id: `${base}-${index}`,
|
|
2969
|
+
"aria-selected": selected,
|
|
2970
|
+
tabIndex: -1,
|
|
2971
|
+
ref: selected ? scrollRef : void 0,
|
|
2972
|
+
size,
|
|
2973
|
+
label,
|
|
2974
|
+
description,
|
|
2975
|
+
leading,
|
|
2976
|
+
shortcut,
|
|
2977
|
+
hint,
|
|
2978
|
+
selected,
|
|
2979
|
+
onMouseEnter: () => setHighlight(index),
|
|
2980
|
+
onMouseDown: (event) => {
|
|
2981
|
+
event.preventDefault();
|
|
2982
|
+
onSelect(item);
|
|
2983
|
+
}
|
|
2984
|
+
},
|
|
2985
|
+
itemKey(item)
|
|
2986
|
+
)
|
|
2987
|
+
);
|
|
2988
|
+
};
|
|
2989
|
+
return /* @__PURE__ */ jsx45(Popover, { anchor: rect, open: rect !== null, side: "top", align: "left", className: width, maxHeight, ariaLabel, children: /* @__PURE__ */ jsx45("div", { id: listboxId, role: "listbox", "aria-label": ariaLabel, className: "flex flex-col", children: shown.map((section, i) => /* @__PURE__ */ jsxs31("div", { className: "contents", children: [
|
|
2990
|
+
i > 0 && /* @__PURE__ */ jsx45(MenuSeparator, {}),
|
|
2991
|
+
section.label ? /* @__PURE__ */ jsx45("div", { role: "group", "aria-label": section.label, children: /* @__PURE__ */ jsx45(MenuSection, { label: section.label, className: section.className, children: section.items.map(drawRow) }) }) : section.items.map(drawRow)
|
|
2992
|
+
] }, section.label ?? i)) }) });
|
|
2993
|
+
}
|
|
2994
|
+
|
|
2878
2995
|
// src/Toolbar.tsx
|
|
2879
2996
|
import { Toolbar as BaseToolbar } from "@base-ui/react/toolbar";
|
|
2880
|
-
import { jsx as
|
|
2997
|
+
import { jsx as jsx46 } from "react/jsx-runtime";
|
|
2881
2998
|
function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocus = true, surface = true, children, className }) {
|
|
2882
|
-
const strip = /* @__PURE__ */
|
|
2999
|
+
const strip = /* @__PURE__ */ jsx46(
|
|
2883
3000
|
BaseToolbar.Root,
|
|
2884
3001
|
{
|
|
2885
3002
|
"aria-label": ariaLabel,
|
|
@@ -2890,27 +3007,27 @@ function Toolbar({ "aria-label": ariaLabel, orientation = "horizontal", loopFocu
|
|
|
2890
3007
|
}
|
|
2891
3008
|
);
|
|
2892
3009
|
if (!surface) return strip;
|
|
2893
|
-
return /* @__PURE__ */
|
|
3010
|
+
return /* @__PURE__ */ jsx46(MenuPanel, { className: "w-fit p-1", children: strip });
|
|
2894
3011
|
}
|
|
2895
3012
|
function ToolbarButton({ ref, disabled, disabledReason, ...props }) {
|
|
2896
|
-
return /* @__PURE__ */
|
|
3013
|
+
return /* @__PURE__ */ jsx46(
|
|
2897
3014
|
BaseToolbar.Button,
|
|
2898
3015
|
{
|
|
2899
3016
|
ref,
|
|
2900
3017
|
disabled: disabled || !!disabledReason,
|
|
2901
3018
|
focusableWhenDisabled: true,
|
|
2902
|
-
render: /* @__PURE__ */
|
|
3019
|
+
render: /* @__PURE__ */ jsx46(IconButton, { disabled, disabledReason, ...props })
|
|
2903
3020
|
}
|
|
2904
3021
|
);
|
|
2905
3022
|
}
|
|
2906
3023
|
function ToolbarLink({ ref, href, ...props }) {
|
|
2907
|
-
return /* @__PURE__ */
|
|
3024
|
+
return /* @__PURE__ */ jsx46(BaseToolbar.Link, { ref, render: /* @__PURE__ */ jsx46(IconButton, { href, ...props }) });
|
|
2908
3025
|
}
|
|
2909
3026
|
function ToolbarInput({ size, ...props }) {
|
|
2910
|
-
return /* @__PURE__ */
|
|
3027
|
+
return /* @__PURE__ */ jsx46(BaseToolbar.Input, { render: /* @__PURE__ */ jsx46(TextInput, { size }), ...props });
|
|
2911
3028
|
}
|
|
2912
3029
|
function ToolbarSeparator({ className }) {
|
|
2913
|
-
return /* @__PURE__ */
|
|
3030
|
+
return /* @__PURE__ */ jsx46(
|
|
2914
3031
|
BaseToolbar.Separator,
|
|
2915
3032
|
{
|
|
2916
3033
|
orientation: "vertical",
|
|
@@ -2920,9 +3037,9 @@ function ToolbarSeparator({ className }) {
|
|
|
2920
3037
|
}
|
|
2921
3038
|
|
|
2922
3039
|
// src/ReactionPicker.tsx
|
|
2923
|
-
import { jsx as
|
|
3040
|
+
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
2924
3041
|
function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reactions", surface = true, className }) {
|
|
2925
|
-
return /* @__PURE__ */
|
|
3042
|
+
return /* @__PURE__ */ jsx47(Toolbar, { "aria-label": ariaLabel, surface, className: cn("gap-0.5", className), children: options.map((option) => (
|
|
2926
3043
|
/*
|
|
2927
3044
|
A `ToolbarButton`, not a button in a tooltip wrapper. The wrapper
|
|
2928
3045
|
would become the toolbar's item and the button inside it would never
|
|
@@ -2932,14 +3049,14 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2932
3049
|
The tooltip names it for a pointer, `aria-label` for everything else,
|
|
2933
3050
|
and both say the meaning rather than the glyph.
|
|
2934
3051
|
*/
|
|
2935
|
-
/* @__PURE__ */
|
|
3052
|
+
/* @__PURE__ */ jsx47(
|
|
2936
3053
|
ToolbarButton,
|
|
2937
3054
|
{
|
|
2938
3055
|
"aria-label": option.label,
|
|
2939
3056
|
tooltip: option.label,
|
|
2940
3057
|
onClick: () => onSelect(option.emoji),
|
|
2941
3058
|
className: "size-7",
|
|
2942
|
-
children: /* @__PURE__ */
|
|
3059
|
+
children: /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
2943
3060
|
},
|
|
2944
3061
|
option.emoji
|
|
2945
3062
|
)
|
|
@@ -2948,23 +3065,23 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2948
3065
|
|
|
2949
3066
|
// src/PreviewCard.tsx
|
|
2950
3067
|
import { PreviewCard as BasePreviewCard } from "@base-ui/react/preview-card";
|
|
2951
|
-
import { jsx as
|
|
3068
|
+
import { jsx as jsx48, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
2952
3069
|
var GAP6 = 12;
|
|
2953
3070
|
var VIEWPORT_PAD6 = 8;
|
|
2954
3071
|
var OPEN_DELAY2 = 350;
|
|
2955
3072
|
var CLOSE_DELAY = 200;
|
|
2956
3073
|
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
2957
|
-
return /* @__PURE__ */
|
|
2958
|
-
/* @__PURE__ */
|
|
3074
|
+
return /* @__PURE__ */ jsxs32(BasePreviewCard.Root, { children: [
|
|
3075
|
+
/* @__PURE__ */ jsx48(
|
|
2959
3076
|
BasePreviewCard.Trigger,
|
|
2960
3077
|
{
|
|
2961
3078
|
delay,
|
|
2962
3079
|
closeDelay,
|
|
2963
|
-
render: /* @__PURE__ */
|
|
3080
|
+
render: /* @__PURE__ */ jsx48("span", { className: cn("inline-flex", wrapperClassName) }),
|
|
2964
3081
|
children
|
|
2965
3082
|
}
|
|
2966
3083
|
),
|
|
2967
|
-
/* @__PURE__ */
|
|
3084
|
+
/* @__PURE__ */ jsx48(BasePreviewCard.Portal, { children: /* @__PURE__ */ jsx48(
|
|
2968
3085
|
BasePreviewCard.Positioner,
|
|
2969
3086
|
{
|
|
2970
3087
|
side,
|
|
@@ -2972,12 +3089,12 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2972
3089
|
sideOffset: GAP6,
|
|
2973
3090
|
collisionPadding: VIEWPORT_PAD6,
|
|
2974
3091
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
2975
|
-
children: /* @__PURE__ */
|
|
3092
|
+
children: /* @__PURE__ */ jsx48(
|
|
2976
3093
|
BasePreviewCard.Popup,
|
|
2977
3094
|
{
|
|
2978
3095
|
className: cn("w-[360px] p-0 outline-none", className),
|
|
2979
|
-
render: /* @__PURE__ */
|
|
2980
|
-
children: /* @__PURE__ */
|
|
3096
|
+
render: /* @__PURE__ */ jsx48(MenuPanel, {}),
|
|
3097
|
+
children: /* @__PURE__ */ jsx48(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
2981
3098
|
}
|
|
2982
3099
|
)
|
|
2983
3100
|
}
|
|
@@ -2986,15 +3103,15 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2986
3103
|
}
|
|
2987
3104
|
|
|
2988
3105
|
// src/Rail.tsx
|
|
2989
|
-
import { jsx as
|
|
3106
|
+
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
2990
3107
|
function Rail({ "aria-label": ariaLabel = "Navigation", children, className }) {
|
|
2991
|
-
return /* @__PURE__ */
|
|
3108
|
+
return /* @__PURE__ */ jsx49("nav", { "aria-label": ariaLabel, className: cn("flex w-16 shrink-0 flex-col items-start gap-2 px-2 py-3", className), children });
|
|
2992
3109
|
}
|
|
2993
3110
|
|
|
2994
3111
|
// src/RailItem.tsx
|
|
2995
|
-
import { jsx as
|
|
3112
|
+
import { jsx as jsx50, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2996
3113
|
function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
2997
|
-
return /* @__PURE__ */
|
|
3114
|
+
return /* @__PURE__ */ jsxs33(
|
|
2998
3115
|
"a",
|
|
2999
3116
|
{
|
|
3000
3117
|
href,
|
|
@@ -3002,14 +3119,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
3002
3119
|
className: cn("group flex h-12 w-full shrink-0 flex-col items-center gap-0.5 px-2 py-0.5", className),
|
|
3003
3120
|
...props,
|
|
3004
3121
|
children: [
|
|
3005
|
-
/* @__PURE__ */
|
|
3122
|
+
/* @__PURE__ */ jsx50(
|
|
3006
3123
|
"div",
|
|
3007
3124
|
{
|
|
3008
3125
|
className: cn(
|
|
3009
3126
|
"flex items-center justify-center rounded-lg p-2 transition-colors",
|
|
3010
3127
|
active ? "bg-bg-selected" : "group-hover:bg-bg-hover"
|
|
3011
3128
|
),
|
|
3012
|
-
children: /* @__PURE__ */
|
|
3129
|
+
children: /* @__PURE__ */ jsx50(
|
|
3013
3130
|
"span",
|
|
3014
3131
|
{
|
|
3015
3132
|
className: cn(
|
|
@@ -3021,14 +3138,14 @@ function RailItem({ href, icon, label, active = false, className, ...props }) {
|
|
|
3021
3138
|
)
|
|
3022
3139
|
}
|
|
3023
3140
|
),
|
|
3024
|
-
/* @__PURE__ */
|
|
3141
|
+
/* @__PURE__ */ jsx50("span", { className: cn("text-center text-menu", active ? "text-text-primary" : "text-text-secondary"), children: label })
|
|
3025
3142
|
]
|
|
3026
3143
|
}
|
|
3027
3144
|
);
|
|
3028
3145
|
}
|
|
3029
3146
|
|
|
3030
3147
|
// src/Property.tsx
|
|
3031
|
-
import { jsx as
|
|
3148
|
+
import { jsx as jsx51, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3032
3149
|
var VALUE_CLASSES = "contents";
|
|
3033
3150
|
function Property({ label, layout = "row", children, className }) {
|
|
3034
3151
|
if (layout === "stacked") {
|
|
@@ -3036,25 +3153,25 @@ function Property({ label, layout = "row", children, className }) {
|
|
|
3036
3153
|
// gap-3 — the one label-above-content distance (Katerina, 2026-09-01):
|
|
3037
3154
|
// Peek's topic-details sections already sit at 12px, Ship's rail was
|
|
3038
3155
|
// 6px, and unifying means the bigger, calmer one.
|
|
3039
|
-
/* @__PURE__ */
|
|
3040
|
-
/* @__PURE__ */
|
|
3041
|
-
/* @__PURE__ */
|
|
3156
|
+
/* @__PURE__ */ jsxs34("dl", { className: cn("flex flex-col gap-3", className), children: [
|
|
3157
|
+
/* @__PURE__ */ jsx51("dt", { className: "text-menu uppercase tracking-widest text-text-secondary", children: label }),
|
|
3158
|
+
/* @__PURE__ */ jsx51("dd", { className: VALUE_CLASSES, children })
|
|
3042
3159
|
] })
|
|
3043
3160
|
);
|
|
3044
3161
|
}
|
|
3045
|
-
return /* @__PURE__ */
|
|
3046
|
-
/* @__PURE__ */
|
|
3047
|
-
/* @__PURE__ */
|
|
3162
|
+
return /* @__PURE__ */ jsxs34("dl", { className: cn("flex items-center gap-2", className), children: [
|
|
3163
|
+
/* @__PURE__ */ jsx51("dt", { className: "w-[68px] shrink-0 text-caption text-text-secondary", children: label }),
|
|
3164
|
+
/* @__PURE__ */ jsx51("dd", { className: VALUE_CLASSES, children })
|
|
3048
3165
|
] });
|
|
3049
3166
|
}
|
|
3050
3167
|
|
|
3051
3168
|
// src/Reaction.tsx
|
|
3052
3169
|
import { Toggle } from "@base-ui/react/toggle";
|
|
3053
|
-
import { jsx as
|
|
3170
|
+
import { jsx as jsx52, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3054
3171
|
function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
3055
3172
|
return (
|
|
3056
3173
|
// @estiva-escape(no-copied-look): W1 (Katerina, 24 September: leave alone): a reaction pill shares four words with a field's box by coincidence
|
|
3057
|
-
/* @__PURE__ */
|
|
3174
|
+
/* @__PURE__ */ jsxs35(
|
|
3058
3175
|
Toggle,
|
|
3059
3176
|
{
|
|
3060
3177
|
pressed,
|
|
@@ -3070,14 +3187,14 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
3070
3187
|
(Katerina, 2026-09-08). The number reads in the text colour
|
|
3071
3188
|
there; the accent keeps the edge and the fill. Signal keeps
|
|
3072
3189
|
Peek's blue-on-wash, which reads. */
|
|
3073
|
-
"border-accent-primary bg-accent-muted text-accent-
|
|
3190
|
+
"border-accent-primary bg-accent-muted text-accent-text hover:border-accent-hover ship:text-text-primary"
|
|
3074
3191
|
) : "border-border-default bg-bg-inset text-text-primary hover:border-border-strong hover:bg-bg-hover",
|
|
3075
3192
|
className
|
|
3076
3193
|
),
|
|
3077
3194
|
...props,
|
|
3078
3195
|
children: [
|
|
3079
|
-
/* @__PURE__ */
|
|
3080
|
-
/* @__PURE__ */
|
|
3196
|
+
/* @__PURE__ */ jsx52("span", { "aria-hidden": "true", className: "shrink-0 text-body-1 leading-none", children: emoji }),
|
|
3197
|
+
/* @__PURE__ */ jsx52("span", { className: CHIP_TEXT_CLASSES, children: count })
|
|
3081
3198
|
]
|
|
3082
3199
|
}
|
|
3083
3200
|
)
|
|
@@ -3087,9 +3204,9 @@ function Reaction({ emoji, count, pressed = false, className, ...props }) {
|
|
|
3087
3204
|
// src/SearchInput.tsx
|
|
3088
3205
|
import "react";
|
|
3089
3206
|
import { Input as Input3 } from "@base-ui/react/input";
|
|
3090
|
-
import { jsx as
|
|
3207
|
+
import { jsx as jsx53, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3091
3208
|
function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...props }) {
|
|
3092
|
-
return /* @__PURE__ */
|
|
3209
|
+
return /* @__PURE__ */ jsxs36(
|
|
3093
3210
|
"div",
|
|
3094
3211
|
{
|
|
3095
3212
|
className: cn(
|
|
@@ -3101,7 +3218,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3101
3218
|
className
|
|
3102
3219
|
),
|
|
3103
3220
|
children: [
|
|
3104
|
-
/* @__PURE__ */
|
|
3221
|
+
/* @__PURE__ */ jsx53(
|
|
3105
3222
|
Input3,
|
|
3106
3223
|
{
|
|
3107
3224
|
className: cn("flex-1 min-w-0 text-input-value", BARE_INPUT_CLASSES),
|
|
@@ -3109,7 +3226,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3109
3226
|
...props
|
|
3110
3227
|
}
|
|
3111
3228
|
),
|
|
3112
|
-
shortcut && /* @__PURE__ */
|
|
3229
|
+
shortcut && /* @__PURE__ */ jsx53(Kbd, { children: shortcut })
|
|
3113
3230
|
]
|
|
3114
3231
|
}
|
|
3115
3232
|
);
|
|
@@ -3118,50 +3235,58 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
3118
3235
|
// src/SectionHeader.tsx
|
|
3119
3236
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
3120
3237
|
import { useRender } from "@base-ui/react/use-render";
|
|
3121
|
-
import { Fragment as Fragment11, jsx as
|
|
3122
|
-
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", render, className }) {
|
|
3238
|
+
import { Fragment as Fragment11, jsx as jsx54, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3239
|
+
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", look = "heading", render, className }) {
|
|
3240
|
+
const row = look === "row";
|
|
3123
3241
|
const titleElement = useRender({
|
|
3124
|
-
render: render ?? (chevron ? /* @__PURE__ */
|
|
3242
|
+
render: render ?? (chevron ? /* @__PURE__ */ jsx54("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx54("span", {})),
|
|
3125
3243
|
props: {
|
|
3126
3244
|
// `text-left`: a button centres its text. `h-full` and `flex-1`: the
|
|
3127
3245
|
// whole row up to the actions is the hit target, as it was when the
|
|
3128
3246
|
// row itself carried the click.
|
|
3129
|
-
className: "flex h-full min-w-0 flex-1 items-center gap-
|
|
3130
|
-
children: /* @__PURE__ */
|
|
3131
|
-
chevron && /* @__PURE__ */
|
|
3247
|
+
className: cn("flex h-full min-w-0 flex-1 items-center text-left", row ? "gap-2" : "gap-1"),
|
|
3248
|
+
children: /* @__PURE__ */ jsxs37(Fragment11, { children: [
|
|
3249
|
+
chevron && /* @__PURE__ */ jsx54(
|
|
3132
3250
|
IconChevronRight2,
|
|
3133
3251
|
{
|
|
3134
|
-
size: 12,
|
|
3252
|
+
size: row ? 16 : 12,
|
|
3135
3253
|
stroke: 1.5,
|
|
3136
|
-
className: cn("shrink-0
|
|
3254
|
+
className: cn("shrink-0 transition-transform duration-150", !row && "text-text-secondary", isExpanded && "rotate-90")
|
|
3137
3255
|
}
|
|
3138
3256
|
),
|
|
3139
|
-
/* @__PURE__ */
|
|
3257
|
+
look === "quiet" ? /* @__PURE__ */ jsx54("span", { className: "min-w-0 truncate text-caption text-text-muted", children: title }) : row ? (
|
|
3258
|
+
// A row's words: NavItem's size and colour, brightening under the pointer with the row.
|
|
3259
|
+
/* @__PURE__ */ jsx54("span", { className: "min-w-0 flex-1 truncate text-body-2", children: title })
|
|
3260
|
+
) : /* @__PURE__ */ jsx54(SectionLabel, { children: title })
|
|
3140
3261
|
] })
|
|
3141
3262
|
}
|
|
3142
3263
|
});
|
|
3143
|
-
return /* @__PURE__ */
|
|
3264
|
+
return /* @__PURE__ */ jsxs37(
|
|
3144
3265
|
"div",
|
|
3145
3266
|
{
|
|
3146
3267
|
className: cn(
|
|
3147
|
-
"group flex h-[32px] shrink-0 items-center gap-1
|
|
3268
|
+
"group flex h-[32px] shrink-0 items-center gap-1 px-2",
|
|
3269
|
+
!row && "transition-colors",
|
|
3270
|
+
// A row is NavItem's shape and colour: 6px corners, secondary words that brighten on hover.
|
|
3271
|
+
row ? cn(SIDEBAR_ROW_CLASSES, SIDEBAR_ROW_TEXT_CLASSES) : "rounded-lg",
|
|
3148
3272
|
// The fill says "this does something": a row with a toggle or actions
|
|
3149
3273
|
// lights up, a fixed heading over rows does not (2026-09-09, the
|
|
3150
3274
|
// Sidebar's fixed group).
|
|
3151
|
-
|
|
3275
|
+
// A quiet label never lights up: it is a label; its button does.
|
|
3276
|
+
hover === "fill" && look !== "quiet" && (chevron || actions && actions.length > 0) && "hover:bg-bg-hover",
|
|
3152
3277
|
className
|
|
3153
3278
|
),
|
|
3154
3279
|
children: [
|
|
3155
3280
|
titleElement,
|
|
3156
|
-
trailing != null && /* @__PURE__ */
|
|
3157
|
-
actions && actions.length > 0 && /* @__PURE__ */
|
|
3281
|
+
trailing != null && /* @__PURE__ */ jsx54("div", { className: "flex shrink-0 items-center", children: trailing }),
|
|
3282
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsx54(
|
|
3158
3283
|
"div",
|
|
3159
3284
|
{
|
|
3160
3285
|
className: cn(
|
|
3161
3286
|
"-mr-1 flex shrink-0 items-center gap-1",
|
|
3162
3287
|
showActions === "hover" && "opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100"
|
|
3163
3288
|
),
|
|
3164
|
-
children: actions.map((action) => /* @__PURE__ */
|
|
3289
|
+
children: actions.map((action) => /* @__PURE__ */ jsx54(IconButton, { tooltip: action.tooltip, "aria-label": action.tooltip, onClick: action.onClick, children: action.icon }, action.tooltip))
|
|
3165
3290
|
}
|
|
3166
3291
|
)
|
|
3167
3292
|
]
|
|
@@ -3170,35 +3295,35 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
3170
3295
|
}
|
|
3171
3296
|
|
|
3172
3297
|
// src/Panel.tsx
|
|
3173
|
-
import { jsx as
|
|
3298
|
+
import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3174
3299
|
function Frame({ title, chevron = false, actions, children, footer, bodyClassName, bodyRef, onBodyScroll, className, broken = false }) {
|
|
3175
|
-
return /* @__PURE__ */
|
|
3176
|
-
/* @__PURE__ */
|
|
3300
|
+
return /* @__PURE__ */ jsxs38("div", { className: cn("flex h-full min-h-0 flex-1 flex-col", className), children: [
|
|
3301
|
+
/* @__PURE__ */ jsx55(ContainerHeader, { title, chevron, actions }),
|
|
3177
3302
|
broken ? (
|
|
3178
3303
|
// The message takes the room the body had and centres itself in it.
|
|
3179
|
-
/* @__PURE__ */
|
|
3180
|
-
) : /* @__PURE__ */
|
|
3181
|
-
!broken && footer && /* @__PURE__ */
|
|
3304
|
+
/* @__PURE__ */ jsx55("div", { className: "flex min-h-0 flex-1 flex-col px-4", children })
|
|
3305
|
+
) : /* @__PURE__ */ jsx55(ScrollArea, { className: "min-h-0 flex-1", contentClassName: bodyClassName, viewportRef: bodyRef, onScroll: onBodyScroll, children }),
|
|
3306
|
+
!broken && footer && /* @__PURE__ */ jsx55("div", { className: "shrink-0", children: footer })
|
|
3182
3307
|
] });
|
|
3183
3308
|
}
|
|
3184
3309
|
function Panel(props) {
|
|
3185
|
-
return /* @__PURE__ */
|
|
3310
|
+
return /* @__PURE__ */ jsx55(
|
|
3186
3311
|
ErrorBoundary,
|
|
3187
3312
|
{
|
|
3188
3313
|
label: "panel",
|
|
3189
3314
|
frame: (message) => (
|
|
3190
3315
|
// Only the name comes back with the message: the actions and the footer may be what threw.
|
|
3191
|
-
/* @__PURE__ */
|
|
3316
|
+
/* @__PURE__ */ jsx55(Frame, { title: props.title, chevron: props.chevron, className: props.className, broken: true, children: message })
|
|
3192
3317
|
),
|
|
3193
|
-
children: /* @__PURE__ */
|
|
3318
|
+
children: /* @__PURE__ */ jsx55(Frame, { ...props })
|
|
3194
3319
|
}
|
|
3195
3320
|
);
|
|
3196
3321
|
}
|
|
3197
3322
|
|
|
3198
3323
|
// src/ListColumn.tsx
|
|
3199
|
-
import { jsx as
|
|
3324
|
+
import { jsx as jsx56, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3200
3325
|
function Column({ title, chevron = false, actions, above, collapsed = false, children, className, broken = false }) {
|
|
3201
|
-
return /* @__PURE__ */
|
|
3326
|
+
return /* @__PURE__ */ jsxs39(
|
|
3202
3327
|
"div",
|
|
3203
3328
|
{
|
|
3204
3329
|
className: cn(
|
|
@@ -3209,34 +3334,34 @@ function Column({ title, chevron = false, actions, above, collapsed = false, chi
|
|
|
3209
3334
|
),
|
|
3210
3335
|
"data-collapsed": collapsed || void 0,
|
|
3211
3336
|
children: [
|
|
3212
|
-
/* @__PURE__ */
|
|
3337
|
+
/* @__PURE__ */ jsx56(ContainerHeader, { title, chevron, actions }),
|
|
3213
3338
|
above,
|
|
3214
3339
|
broken ? (
|
|
3215
3340
|
// The message takes the room the list had and centres itself in it (Katerina, 19 September).
|
|
3216
|
-
/* @__PURE__ */
|
|
3217
|
-
) : /* @__PURE__ */
|
|
3341
|
+
/* @__PURE__ */ jsx56("div", { className: "flex min-h-0 flex-1 flex-col px-3", children })
|
|
3342
|
+
) : /* @__PURE__ */ jsx56(ScrollArea, { className: "flex-1", contentClassName: "flex flex-col gap-0.5 px-3 pt-4 pb-3", children })
|
|
3218
3343
|
]
|
|
3219
3344
|
}
|
|
3220
3345
|
);
|
|
3221
3346
|
}
|
|
3222
3347
|
function ListColumn(props) {
|
|
3223
|
-
return /* @__PURE__ */
|
|
3348
|
+
return /* @__PURE__ */ jsx56(
|
|
3224
3349
|
ErrorBoundary,
|
|
3225
3350
|
{
|
|
3226
3351
|
label: "list panel",
|
|
3227
3352
|
frame: (message) => (
|
|
3228
3353
|
// Only the name comes back with the message: the actions and the row above may be what threw.
|
|
3229
|
-
/* @__PURE__ */
|
|
3354
|
+
/* @__PURE__ */ jsx56(Column, { title: props.title, chevron: props.chevron, collapsed: props.collapsed, className: props.className, broken: true, children: message })
|
|
3230
3355
|
),
|
|
3231
|
-
children: /* @__PURE__ */
|
|
3356
|
+
children: /* @__PURE__ */ jsx56(Column, { ...props })
|
|
3232
3357
|
}
|
|
3233
3358
|
);
|
|
3234
3359
|
}
|
|
3235
3360
|
|
|
3236
3361
|
// src/CollapsibleSection.tsx
|
|
3237
|
-
import { useState as
|
|
3362
|
+
import { useState as useState8 } from "react";
|
|
3238
3363
|
import { Collapsible } from "@base-ui/react/collapsible";
|
|
3239
|
-
import { jsx as
|
|
3364
|
+
import { jsx as jsx57, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3240
3365
|
var OPEN = "open";
|
|
3241
3366
|
var CLOSED = "closed";
|
|
3242
3367
|
function readStored(key) {
|
|
@@ -3255,22 +3380,22 @@ function writeStored(key, open) {
|
|
|
3255
3380
|
} catch {
|
|
3256
3381
|
}
|
|
3257
3382
|
}
|
|
3258
|
-
function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, children, className, contentClassName }) {
|
|
3259
|
-
const [openState, setOpenState] =
|
|
3383
|
+
function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenChange, storageKey, trailing, actions, showActions, look = "heading", children, className, contentClassName }) {
|
|
3384
|
+
const [openState, setOpenState] = useState8(() => readStored(storageKey) ?? defaultOpen);
|
|
3260
3385
|
const open = openProp ?? openState;
|
|
3261
3386
|
const setOpen = (next) => {
|
|
3262
3387
|
setOpenState(next);
|
|
3263
3388
|
writeStored(storageKey, next);
|
|
3264
3389
|
onOpenChange?.(next);
|
|
3265
3390
|
};
|
|
3266
|
-
return /* @__PURE__ */
|
|
3267
|
-
/* @__PURE__ */
|
|
3268
|
-
/* @__PURE__ */
|
|
3391
|
+
return /* @__PURE__ */ jsxs40(Collapsible.Root, { open, onOpenChange: setOpen, className: cn("flex flex-col", className), children: [
|
|
3392
|
+
/* @__PURE__ */ jsx57(SectionHeader, { title, chevron: true, isExpanded: open, trailing, actions, showActions, look, className: "shrink-0", render: /* @__PURE__ */ jsx57(Collapsible.Trigger, {}) }),
|
|
3393
|
+
/* @__PURE__ */ jsx57(
|
|
3269
3394
|
Collapsible.Panel,
|
|
3270
3395
|
{
|
|
3271
3396
|
hiddenUntilFound: true,
|
|
3272
3397
|
className: "h-[var(--collapsible-panel-height)] overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0",
|
|
3273
|
-
children: /* @__PURE__ */
|
|
3398
|
+
children: /* @__PURE__ */ jsx57("div", { className: cn("flex flex-col", look === "row" && "pl-6", contentClassName), children })
|
|
3274
3399
|
}
|
|
3275
3400
|
)
|
|
3276
3401
|
] });
|
|
@@ -3278,9 +3403,9 @@ function CollapsibleSection({ title, defaultOpen = true, open: openProp, onOpenC
|
|
|
3278
3403
|
|
|
3279
3404
|
// src/Tabs.tsx
|
|
3280
3405
|
import { Tabs as BaseTabs } from "@base-ui/react/tabs";
|
|
3281
|
-
import { jsx as
|
|
3406
|
+
import { jsx as jsx58, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3282
3407
|
function Tabs({ tabs, active, onChange, size = "default", className, ...aria }) {
|
|
3283
|
-
return /* @__PURE__ */
|
|
3408
|
+
return /* @__PURE__ */ jsx58(
|
|
3284
3409
|
BaseTabs.Root,
|
|
3285
3410
|
{
|
|
3286
3411
|
value: active,
|
|
@@ -3288,14 +3413,14 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3288
3413
|
if (details.reason === "none") onChange(value);
|
|
3289
3414
|
},
|
|
3290
3415
|
className,
|
|
3291
|
-
children: /* @__PURE__ */
|
|
3416
|
+
children: /* @__PURE__ */ jsx58(
|
|
3292
3417
|
BaseTabs.List,
|
|
3293
3418
|
{
|
|
3294
3419
|
activateOnFocus: true,
|
|
3295
3420
|
"aria-label": aria["aria-label"],
|
|
3296
3421
|
"aria-labelledby": aria["aria-labelledby"],
|
|
3297
3422
|
className: "flex items-center gap-2",
|
|
3298
|
-
children: tabs.map((tab) => /* @__PURE__ */
|
|
3423
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsxs41(
|
|
3299
3424
|
BaseTabs.Tab,
|
|
3300
3425
|
{
|
|
3301
3426
|
value: tab.id,
|
|
@@ -3308,9 +3433,9 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3308
3433
|
),
|
|
3309
3434
|
children: [
|
|
3310
3435
|
tab.icon,
|
|
3311
|
-
/* @__PURE__ */
|
|
3436
|
+
/* @__PURE__ */ jsxs41("span", { className: "flex items-baseline", children: [
|
|
3312
3437
|
tab.label,
|
|
3313
|
-
tab.count !== void 0 ? /* @__PURE__ */
|
|
3438
|
+
tab.count !== void 0 ? /* @__PURE__ */ jsx58("span", { className: "ml-2.5 font-mono text-caption tabular-nums text-text-secondary", children: tab.count }) : null
|
|
3314
3439
|
] })
|
|
3315
3440
|
]
|
|
3316
3441
|
},
|
|
@@ -3323,10 +3448,10 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
3323
3448
|
}
|
|
3324
3449
|
|
|
3325
3450
|
// src/Toast.tsx
|
|
3326
|
-
import { createContext as createContext6, useContext as useContext6, useMemo as
|
|
3451
|
+
import { createContext as createContext6, useContext as useContext6, useMemo as useMemo5 } from "react";
|
|
3327
3452
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
3328
3453
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
3329
|
-
import { jsx as
|
|
3454
|
+
import { jsx as jsx59, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3330
3455
|
var SURFACE_STYLES = {
|
|
3331
3456
|
success: "bg-success-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
3332
3457
|
brand: "bg-accent-muted signal:bg-bg-inset signal:border signal:border-border-default signal:shadow-md leaf:bg-bg-inset leaf:border leaf:border-border-default leaf:shadow-md",
|
|
@@ -3362,23 +3487,23 @@ var pillClassName = (type, hasAction, className) => cn(
|
|
|
3362
3487
|
);
|
|
3363
3488
|
function LeadingIcon({ type }) {
|
|
3364
3489
|
const Icon = ICONS[type];
|
|
3365
|
-
return /* @__PURE__ */
|
|
3490
|
+
return /* @__PURE__ */ jsx59(Icon, { size: 16, stroke: 1.5, className: cn("text-text-primary shrink-0", ICON_STYLES[type]) });
|
|
3366
3491
|
}
|
|
3367
3492
|
function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, className }) {
|
|
3368
3493
|
const hasAction = !!(actionLabel && onAction);
|
|
3369
|
-
return /* @__PURE__ */
|
|
3370
|
-
/* @__PURE__ */
|
|
3371
|
-
leadingIcon && /* @__PURE__ */
|
|
3372
|
-
/* @__PURE__ */
|
|
3494
|
+
return /* @__PURE__ */ jsxs42("div", { className: pillClassName(type, hasAction, className), children: [
|
|
3495
|
+
/* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3496
|
+
leadingIcon && /* @__PURE__ */ jsx59(LeadingIcon, { type }),
|
|
3497
|
+
/* @__PURE__ */ jsx59("span", { className: LABEL_CLASSES, children: label })
|
|
3373
3498
|
] }),
|
|
3374
|
-
hasAction && /* @__PURE__ */
|
|
3499
|
+
hasAction && /* @__PURE__ */ jsx59(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
3375
3500
|
] });
|
|
3376
3501
|
}
|
|
3377
3502
|
var ToastContext = createContext6(null);
|
|
3378
3503
|
var VISIBLE_TOASTS = 3;
|
|
3379
3504
|
function ToastProvider({ children }) {
|
|
3380
|
-
const manager =
|
|
3381
|
-
const value =
|
|
3505
|
+
const manager = useMemo5(() => BaseToast.createToastManager(), []);
|
|
3506
|
+
const value = useMemo5(
|
|
3382
3507
|
() => ({
|
|
3383
3508
|
showToast: ({ label, type = "neutral", leadingIcon = true, actionLabel, onAction, durationMs = 5e3 }) => manager.add({
|
|
3384
3509
|
title: label,
|
|
@@ -3392,9 +3517,9 @@ function ToastProvider({ children }) {
|
|
|
3392
3517
|
}),
|
|
3393
3518
|
[manager]
|
|
3394
3519
|
);
|
|
3395
|
-
return /* @__PURE__ */
|
|
3520
|
+
return /* @__PURE__ */ jsx59(ToastContext.Provider, { value, children: /* @__PURE__ */ jsxs42(BaseToast.Provider, { toastManager: manager, limit: VISIBLE_TOASTS, children: [
|
|
3396
3521
|
children,
|
|
3397
|
-
/* @__PURE__ */
|
|
3522
|
+
/* @__PURE__ */ jsx59(BaseToast.Portal, { children: /* @__PURE__ */ jsx59(BaseToast.Viewport, { className: "fixed bottom-4 left-4 z-[100] flex flex-col-reverse items-start gap-2 pointer-events-none", children: /* @__PURE__ */ jsx59(ToastList, {}) }) })
|
|
3398
3523
|
] }) });
|
|
3399
3524
|
}
|
|
3400
3525
|
function ToastList() {
|
|
@@ -3402,25 +3527,25 @@ function ToastList() {
|
|
|
3402
3527
|
return toasts.map((toast) => {
|
|
3403
3528
|
const type = toast.type ?? "neutral";
|
|
3404
3529
|
const { leadingIcon = true, actionLabel, onAction } = toast.data ?? {};
|
|
3405
|
-
return /* @__PURE__ */
|
|
3530
|
+
return /* @__PURE__ */ jsxs42(
|
|
3406
3531
|
BaseToast.Root,
|
|
3407
3532
|
{
|
|
3408
3533
|
toast,
|
|
3409
3534
|
swipeDirection: ["left", "down"],
|
|
3410
3535
|
className: pillClassName(type, !!actionLabel, "pointer-events-auto data-[limited]:hidden"),
|
|
3411
3536
|
children: [
|
|
3412
|
-
/* @__PURE__ */
|
|
3413
|
-
leadingIcon && /* @__PURE__ */
|
|
3414
|
-
/* @__PURE__ */
|
|
3537
|
+
/* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2 shrink-0", children: [
|
|
3538
|
+
leadingIcon && /* @__PURE__ */ jsx59(LeadingIcon, { type }),
|
|
3539
|
+
/* @__PURE__ */ jsx59(BaseToast.Title, { render: /* @__PURE__ */ jsx59("span", {}), className: LABEL_CLASSES })
|
|
3415
3540
|
] }),
|
|
3416
|
-
actionLabel && /* @__PURE__ */
|
|
3541
|
+
actionLabel && /* @__PURE__ */ jsx59(
|
|
3417
3542
|
BaseToast.Action,
|
|
3418
3543
|
{
|
|
3419
3544
|
onClick: () => {
|
|
3420
3545
|
onAction?.();
|
|
3421
3546
|
close(toast.id);
|
|
3422
3547
|
},
|
|
3423
|
-
render: /* @__PURE__ */
|
|
3548
|
+
render: /* @__PURE__ */ jsx59(Button, { variant: "outlined", size: "small", children: actionLabel })
|
|
3424
3549
|
}
|
|
3425
3550
|
)
|
|
3426
3551
|
]
|
|
@@ -3434,6 +3559,19 @@ function useToast() {
|
|
|
3434
3559
|
if (!ctx) throw new Error("useToast must be used within ToastProvider");
|
|
3435
3560
|
return ctx;
|
|
3436
3561
|
}
|
|
3562
|
+
|
|
3563
|
+
// src/shortcuts.ts
|
|
3564
|
+
function isApplePlatform() {
|
|
3565
|
+
if (typeof navigator === "undefined") return false;
|
|
3566
|
+
return /Mac|iPhone|iPad|iPod/.test(navigator.platform || navigator.userAgent || "");
|
|
3567
|
+
}
|
|
3568
|
+
function shortcutLabel(keys, apple = isApplePlatform()) {
|
|
3569
|
+
return keys.split("-").map((part, i, all) => {
|
|
3570
|
+
if (i === all.length - 1) return part.length === 1 ? part.toUpperCase() : part;
|
|
3571
|
+
if (part === "Mod") return apple ? "Cmd" : "Ctrl";
|
|
3572
|
+
return part;
|
|
3573
|
+
}).join("+");
|
|
3574
|
+
}
|
|
3437
3575
|
export {
|
|
3438
3576
|
AppShell,
|
|
3439
3577
|
AttachmentCard,
|
|
@@ -3506,6 +3644,7 @@ export {
|
|
|
3506
3644
|
SkeletonBar,
|
|
3507
3645
|
SkeletonList,
|
|
3508
3646
|
SkeletonRow,
|
|
3647
|
+
SuggestionMenu,
|
|
3509
3648
|
Tabs,
|
|
3510
3649
|
TextInput,
|
|
3511
3650
|
Textarea,
|
|
@@ -3524,7 +3663,9 @@ export {
|
|
|
3524
3663
|
hueFor,
|
|
3525
3664
|
initialsFor,
|
|
3526
3665
|
inlineChipClassName,
|
|
3666
|
+
isApplePlatform,
|
|
3527
3667
|
richTextClassName,
|
|
3668
|
+
shortcutLabel,
|
|
3528
3669
|
useToast
|
|
3529
3670
|
};
|
|
3530
3671
|
//# sourceMappingURL=index.js.map
|