@estiva-app/ui 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AppShell.d.ts.map +1 -1
- package/dist/AttachmentCard.d.ts.map +1 -1
- package/dist/Form.d.ts.map +1 -1
- package/dist/IconButton.d.ts +9 -1
- package/dist/IconButton.d.ts.map +1 -1
- package/dist/PreviewCard.d.ts +9 -2
- package/dist/PreviewCard.d.ts.map +1 -1
- package/dist/SectionHeader.d.ts +7 -1
- package/dist/SectionHeader.d.ts.map +1 -1
- package/dist/Select.d.ts +11 -3
- package/dist/Select.d.ts.map +1 -1
- package/dist/Tooltip.d.ts +13 -1
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/eslint/index.js +2 -1
- package/dist/eslint/index.js.map +2 -2
- package/dist/eslint/no-restyled-part.d.ts.map +1 -1
- package/dist/index.js +127 -108
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
- package/registry.json +51 -8
- package/src/AppShell.mdx +10 -0
- package/src/AppShell.test.tsx +16 -0
- package/src/AppShell.tsx +4 -1
- package/src/AttachmentCard.mdx +9 -0
- package/src/AttachmentCard.test.tsx +10 -0
- package/src/AttachmentCard.tsx +8 -5
- package/src/Avatar.mdx +13 -3
- package/src/AvatarGroup.mdx +4 -0
- package/src/Banner.mdx +13 -3
- package/src/Breadcrumb.mdx +10 -0
- package/src/Button.mdx +14 -3
- package/src/Card.mdx +9 -0
- package/src/Checkbox.mdx +10 -0
- package/src/Chip.mdx +4 -0
- package/src/ChipInput.mdx +12 -0
- package/src/CollapsibleSection.mdx +9 -0
- package/src/CommandPalette.mdx +14 -2
- package/src/ConfirmDialog.mdx +11 -0
- package/src/ContainerHeader.mdx +4 -0
- package/src/DialogShell.mdx +14 -0
- package/src/Divider.mdx +9 -1
- package/src/EditableText.mdx +11 -0
- package/src/EmptyState.mdx +15 -4
- package/src/Field.mdx +10 -1
- package/src/FieldLine.mdx +9 -1
- package/src/FilePicker.mdx +8 -0
- package/src/Form.mdx +10 -0
- package/src/Form.test.tsx +26 -0
- package/src/Form.tsx +7 -0
- package/src/IconButton.mdx +16 -2
- package/src/IconButton.stories.tsx +3 -0
- package/src/IconButton.test.tsx +25 -0
- package/src/IconButton.tsx +61 -46
- package/src/IdentityMenu.mdx +9 -0
- package/src/InlineChip.mdx +8 -0
- package/src/Kbd.mdx +4 -0
- package/src/Link.mdx +10 -0
- package/src/Menu.mdx +16 -1
- package/src/MenuItem.mdx +12 -2
- package/src/NavItem.mdx +8 -0
- package/src/Person.mdx +4 -0
- package/src/PersonTrigger.mdx +9 -0
- package/src/Popover.mdx +21 -0
- package/src/PreviewCard.mdx +19 -4
- package/src/PreviewCard.tsx +11 -4
- package/src/ProgressBar.mdx +8 -0
- package/src/Property.mdx +4 -0
- package/src/Rail.mdx +9 -1
- package/src/RailItem.mdx +8 -0
- package/src/Reaction.mdx +9 -0
- package/src/ReactionPicker.mdx +8 -0
- package/src/ScrollArea.mdx +13 -2
- package/src/SearchInput.mdx +9 -0
- package/src/SectionHeader.mdx +13 -0
- package/src/SectionHeader.stories.tsx +9 -0
- package/src/SectionHeader.test.tsx +9 -0
- package/src/SectionHeader.tsx +8 -2
- package/src/SectionLabel.mdx +4 -0
- package/src/Select.mdx +21 -2
- package/src/Select.stories.tsx +4 -1
- package/src/Select.test.tsx +17 -0
- package/src/Select.tsx +34 -13
- package/src/Sidebar.mdx +8 -0
- package/src/Skeleton.mdx +4 -0
- package/src/Tabs.mdx +12 -1
- package/src/TextInput.mdx +8 -0
- package/src/Textarea.mdx +8 -0
- package/src/Toast.mdx +12 -1
- package/src/Toolbar.mdx +11 -0
- package/src/Tooltip.mdx +26 -2
- package/src/Tooltip.stories.tsx +26 -0
- package/src/Tooltip.test.tsx +29 -0
- package/src/Tooltip.tsx +17 -4
- package/src/TopBar.mdx +4 -0
- package/src/eslint/no-rebuilt-behaviour.ts +1 -1
- package/src/eslint/no-restyled-part.ts +1 -0
- package/src/pages.test.ts +142 -0
- package/tailwind-preset.js +22 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-restyled-part.d.ts","sourceRoot":"","sources":["../../src/eslint/no-restyled-part.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAGzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,6FAA6F;AAC7F,eAAO,MAAM,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAUxD,CAAA;AASD,oGAAoG;AACpG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAajF;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIlD;AAOD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"no-restyled-part.d.ts","sourceRoot":"","sources":["../../src/eslint/no-restyled-part.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAGzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAIH,6FAA6F;AAC7F,eAAO,MAAM,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,EAUxD,CAAA;AASD,oGAAoG;AACpG,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAajF;AAED,4CAA4C;AAC5C,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAIlD;AAOD;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAiCpD,CAAA;AAOD,UAAU,IAAI;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvB,GAAG,CAAC,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACnC,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAwBD;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AA8UD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC,KAAK,GAAG,IAAI,EAAE,KAAK,UAAQ,EAAE,IAAI,YAAkB,GAAG,MAAM,EAAE,CAqDtJ;AAOD,eAAO,MAAM,cAAc,EAAE,IAAI,CAAC,UAwEjC,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -91,25 +91,30 @@ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
|
91
91
|
function AppShell({ variant = "solid", menu, logo, search, identity, banner, nav, children }) {
|
|
92
92
|
const bar = /* @__PURE__ */ jsx3(TopBar, { variant, menu, logo, search, right: identity });
|
|
93
93
|
if (variant === "floating") {
|
|
94
|
-
return
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
94
|
+
return (
|
|
95
|
+
// `signal-canvas`: in the Signal theme, the preset draws the control-room dot
|
|
96
|
+
// grid behind everything in the frame (Peek's, moved here with the frame:
|
|
97
|
+
// UIG-14, Katerina, 19 September — the canvas is the theme's, not an app's).
|
|
98
|
+
/* @__PURE__ */ jsxs3("div", { className: "signal-canvas relative h-full min-h-0 overflow-hidden bg-bg-base", children: [
|
|
99
|
+
bar,
|
|
100
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex h-full pb-4 pr-4 pt-[52px]", children: [
|
|
101
|
+
nav,
|
|
102
|
+
/* @__PURE__ */ jsxs3(
|
|
103
|
+
"div",
|
|
104
|
+
{
|
|
105
|
+
className: cn(
|
|
106
|
+
"flex min-w-0 flex-1 flex-col overflow-hidden rounded-2xl bg-bg-surface",
|
|
107
|
+
"signal:border signal:border-border-subtle signal:shadow-highlight-inset"
|
|
108
|
+
),
|
|
109
|
+
children: [
|
|
110
|
+
banner,
|
|
111
|
+
/* @__PURE__ */ jsx3("main", { className: "flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden", children })
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
] })
|
|
111
116
|
] })
|
|
112
|
-
|
|
117
|
+
);
|
|
113
118
|
}
|
|
114
119
|
return (
|
|
115
120
|
/* `relative overflow-hidden` is the seal the floating manner already has
|
|
@@ -283,8 +288,8 @@ function TooltipProvider({ delay = OPEN_DELAY, closeDelay, timeout, children })
|
|
|
283
288
|
return /* @__PURE__ */ jsx7(BaseTooltip.Provider, { delay, closeDelay, timeout, children });
|
|
284
289
|
}
|
|
285
290
|
function Tooltip({ label, shortcut, className, ...props }) {
|
|
286
|
-
return /* @__PURE__ */ jsxs4("div", { role: "tooltip", className: cn("bg-bg-elevated border border-border-default rounded-lg h-[30px] flex items-center justify-center gap-1.5 px-2 shadow-lg", className), ...props, children: [
|
|
287
|
-
/* @__PURE__ */ jsx7("span", { className: "text-caption text-text-primary
|
|
291
|
+
return /* @__PURE__ */ jsxs4("div", { role: "tooltip", className: cn("bg-bg-elevated border border-border-default rounded-lg min-h-[30px] max-w-80 flex items-center justify-center gap-1.5 px-2 py-1 shadow-lg", className), ...props, children: [
|
|
292
|
+
/* @__PURE__ */ jsx7("span", { className: "min-w-0 text-caption text-text-primary break-words", children: label }),
|
|
288
293
|
shortcut && /* @__PURE__ */ jsx7(Kbd, { children: shortcut })
|
|
289
294
|
] });
|
|
290
295
|
}
|
|
@@ -316,9 +321,10 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
316
321
|
}
|
|
317
322
|
) });
|
|
318
323
|
}
|
|
319
|
-
function WithTooltip({ label, shortcut, placement = "top", wrapperClassName, children }) {
|
|
324
|
+
function WithTooltip({ label, shortcut, placement = "top", wrapperClassName, inline = false, children }) {
|
|
325
|
+
const Wrapper = inline ? "span" : "div";
|
|
320
326
|
return /* @__PURE__ */ jsxs4(BaseTooltip.Root, { disableHoverablePopup: true, children: [
|
|
321
|
-
/* @__PURE__ */ jsx7(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: /* @__PURE__ */ jsx7(
|
|
327
|
+
/* @__PURE__ */ jsx7(BaseTooltip.Trigger, { delay: OPEN_DELAY, render: /* @__PURE__ */ jsx7(Wrapper, { className: cn("inline-flex shrink-0", wrapperClassName) }), children }),
|
|
322
328
|
/* @__PURE__ */ jsx7(TooltipSurface, { label, shortcut, placement })
|
|
323
329
|
] });
|
|
324
330
|
}
|
|
@@ -343,48 +349,51 @@ function IconButton({
|
|
|
343
349
|
tooltipShortcut,
|
|
344
350
|
tooltipPlacement,
|
|
345
351
|
type = "button",
|
|
352
|
+
href,
|
|
346
353
|
...props
|
|
347
354
|
}) {
|
|
348
355
|
const formBusy = useFormBusy();
|
|
349
|
-
const
|
|
356
|
+
const unusable = disabled || !!disabledReason || formBusy;
|
|
357
|
+
const look = (off) => cn(
|
|
358
|
+
// `shrink-0` stops a flex parent squashing the button; `self-center`
|
|
359
|
+
// stops one stretching it. Two different failures, and both have
|
|
360
|
+
// happened here: a row with no `items-*` drew this 24 wide and 228
|
|
361
|
+
// tall in Peek's TopicMoreMenu story (Katerina, 2026-09-11). A button
|
|
362
|
+
// is the size of its icon and its padding, whatever box it lands in.
|
|
363
|
+
//
|
|
364
|
+
// This is the one of the two that needs it: an IconButton states no
|
|
365
|
+
// height, so its cross size is `auto` and a stretching parent takes
|
|
366
|
+
// it. Measured in the same 260px row on 2026-09-12: 24px with this
|
|
367
|
+
// class, 226px without. `Button` states `h-8`/`h-6`, so it cannot be
|
|
368
|
+
// stretched and carries no `self-center` — see the note there.
|
|
369
|
+
"flex items-center justify-center p-1 rounded-lg transition-colors shrink-0 self-center cursor-pointer",
|
|
370
|
+
!off && variant === "primary" && "bg-accent-primary hover:bg-accent-hover text-text-inverse",
|
|
371
|
+
!off && (variant === "muted" || variant === "resolve") && "text-text-secondary hover:bg-bg-hover hover:text-text-primary",
|
|
372
|
+
!off && variant === "outlined" && "border border-border-default hover:bg-bg-hover text-text-secondary",
|
|
373
|
+
!off && variant === "current" && "hover:bg-bg-hover",
|
|
374
|
+
off && variant === "primary" && "bg-bg-disabled text-text-disabled",
|
|
375
|
+
off && (variant === "muted" || variant === "resolve") && "text-text-disabled",
|
|
376
|
+
off && variant === "outlined" && "border border-border-default text-text-disabled",
|
|
377
|
+
// Always, disabled too: the colour of where it sits, and Resolve's green.
|
|
378
|
+
variant === "current" && "text-current",
|
|
379
|
+
variant === "resolve" && "signal:hover:bg-success-muted signal:hover:text-success-default",
|
|
380
|
+
pressed && "bg-bg-active text-text-primary",
|
|
381
|
+
glow && "signal:shadow-glow-accent",
|
|
382
|
+
// `pointer-events-none` only where the button is truly out of reach:
|
|
383
|
+
// with a `disabledReason` the button IS the tooltip's trigger, and a
|
|
384
|
+
// trigger the pointer cannot land on never opens one. Base UI already
|
|
385
|
+
// swallows the click.
|
|
386
|
+
off && !disabledReason && "pointer-events-none",
|
|
387
|
+
off && "cursor-not-allowed",
|
|
388
|
+
className
|
|
389
|
+
);
|
|
390
|
+
const button = href && !unusable ? /* @__PURE__ */ jsx8("a", { href, className: look(false), ...props, children }) : /* @__PURE__ */ jsx8(
|
|
350
391
|
BaseButton,
|
|
351
392
|
{
|
|
352
393
|
type,
|
|
353
|
-
disabled:
|
|
394
|
+
disabled: unusable,
|
|
354
395
|
focusableWhenDisabled: !!disabledReason,
|
|
355
|
-
className: (state) =>
|
|
356
|
-
// `shrink-0` stops a flex parent squashing the button; `self-center`
|
|
357
|
-
// stops one stretching it. Two different failures, and both have
|
|
358
|
-
// happened here: a row with no `items-*` drew this 24 wide and 228
|
|
359
|
-
// tall in Peek's TopicMoreMenu story (Katerina, 2026-09-11). A button
|
|
360
|
-
// is the size of its icon and its padding, whatever box it lands in.
|
|
361
|
-
//
|
|
362
|
-
// This is the one of the two that needs it: an IconButton states no
|
|
363
|
-
// height, so its cross size is `auto` and a stretching parent takes
|
|
364
|
-
// it. Measured in the same 260px row on 2026-09-12: 24px with this
|
|
365
|
-
// class, 226px without. `Button` states `h-8`/`h-6`, so it cannot be
|
|
366
|
-
// stretched and carries no `self-center` — see the note there.
|
|
367
|
-
"flex items-center justify-center p-1 rounded-lg transition-colors shrink-0 self-center cursor-pointer",
|
|
368
|
-
!state.disabled && variant === "primary" && "bg-accent-primary hover:bg-accent-hover text-text-inverse",
|
|
369
|
-
!state.disabled && (variant === "muted" || variant === "resolve") && "text-text-secondary hover:bg-bg-hover hover:text-text-primary",
|
|
370
|
-
!state.disabled && variant === "outlined" && "border border-border-default hover:bg-bg-hover text-text-secondary",
|
|
371
|
-
!state.disabled && variant === "current" && "hover:bg-bg-hover",
|
|
372
|
-
state.disabled && variant === "primary" && "bg-bg-disabled text-text-disabled",
|
|
373
|
-
state.disabled && (variant === "muted" || variant === "resolve") && "text-text-disabled",
|
|
374
|
-
state.disabled && variant === "outlined" && "border border-border-default text-text-disabled",
|
|
375
|
-
// Always, disabled too: the colour of where it sits, and Resolve's green.
|
|
376
|
-
variant === "current" && "text-current",
|
|
377
|
-
variant === "resolve" && "signal:hover:bg-success-muted signal:hover:text-success-default",
|
|
378
|
-
pressed && "bg-bg-active text-text-primary",
|
|
379
|
-
glow && "signal:shadow-glow-accent",
|
|
380
|
-
// `pointer-events-none` only where the button is truly out of reach:
|
|
381
|
-
// with a `disabledReason` the button IS the tooltip's trigger, and a
|
|
382
|
-
// trigger the pointer cannot land on never opens one. Base UI already
|
|
383
|
-
// swallows the click.
|
|
384
|
-
state.disabled && !disabledReason && "pointer-events-none",
|
|
385
|
-
state.disabled && "cursor-not-allowed",
|
|
386
|
-
className
|
|
387
|
-
),
|
|
396
|
+
className: (state) => look(state.disabled),
|
|
388
397
|
"aria-pressed": pressed,
|
|
389
398
|
...props,
|
|
390
399
|
children
|
|
@@ -434,7 +443,7 @@ function TypeIcon({ name }) {
|
|
|
434
443
|
const Icon = ICON_BY_EXTENSION[extensionOf(name)] ?? IconFile;
|
|
435
444
|
return /* @__PURE__ */ jsx9(Icon, { size: 20, stroke: 1.5 });
|
|
436
445
|
}
|
|
437
|
-
function Truncating({ text, hint, className, wrapperClassName }) {
|
|
446
|
+
function Truncating({ text, hint, className, wrapperClassName, placement }) {
|
|
438
447
|
const ref = useRef(null);
|
|
439
448
|
const [cut, setCut] = useState(false);
|
|
440
449
|
useLayoutEffect(() => {
|
|
@@ -456,7 +465,7 @@ function Truncating({ text, hint, className, wrapperClassName }) {
|
|
|
456
465
|
}, [text, cut]);
|
|
457
466
|
const line = /* @__PURE__ */ jsx9("span", { ref, className, children: text });
|
|
458
467
|
if (!hint && !cut) return line;
|
|
459
|
-
return /* @__PURE__ */ jsx9(WithTooltip, { label: hint ?? text, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
|
|
468
|
+
return /* @__PURE__ */ jsx9(WithTooltip, { label: hint ?? text, placement, wrapperClassName: cn("min-w-0 flex-col", wrapperClassName), children: line });
|
|
460
469
|
}
|
|
461
470
|
function AttachmentCard({
|
|
462
471
|
name,
|
|
@@ -490,7 +499,7 @@ function AttachmentCard({
|
|
|
490
499
|
children: [
|
|
491
500
|
/* @__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) }) }),
|
|
492
501
|
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
493
|
-
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
|
|
502
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES, placement: onRemove ? "bottom" : void 0 }),
|
|
494
503
|
/* @__PURE__ */ jsx9(
|
|
495
504
|
Truncating,
|
|
496
505
|
{
|
|
@@ -505,7 +514,7 @@ function AttachmentCard({
|
|
|
505
514
|
{
|
|
506
515
|
type: "button",
|
|
507
516
|
"aria-label": `Remove ${name}`,
|
|
508
|
-
className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-bg-elevated border border-border-strong flex items-center justify-center text-text-secondary hover:text-text-primary opacity-0 group-hover:opacity-100 transition-opacity",
|
|
517
|
+
className: "absolute -top-1.5 -right-1.5 size-5 rounded-full bg-bg-elevated border border-border-strong flex items-center justify-center text-text-secondary hover:text-text-primary opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 transition-opacity",
|
|
509
518
|
onClick: (event) => {
|
|
510
519
|
event.stopPropagation();
|
|
511
520
|
onRemove();
|
|
@@ -1406,6 +1415,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1406
1415
|
},
|
|
1407
1416
|
onKeyDown,
|
|
1408
1417
|
onSubmit: (event) => {
|
|
1418
|
+
if (event.target !== event.currentTarget) return;
|
|
1409
1419
|
event.preventDefault();
|
|
1410
1420
|
if (busyNow.current) return;
|
|
1411
1421
|
void onSubmit();
|
|
@@ -1944,56 +1954,65 @@ import { Select as BaseSelect } from "@base-ui/react/select";
|
|
|
1944
1954
|
import { jsx as jsx30, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
1945
1955
|
var GAP4 = 4;
|
|
1946
1956
|
var VIEWPORT_PAD4 = 8;
|
|
1947
|
-
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, className, ...aria }) {
|
|
1957
|
+
function Select({ value, onChange, options, size = "default", ariaLabel, placeholder = "Select\u2026", disabled, disabledReason, className, ...aria }) {
|
|
1948
1958
|
const selected = options.find((o) => o.value === value);
|
|
1959
|
+
const held = Boolean(disabledReason) && !disabled;
|
|
1960
|
+
const trigger = /* @__PURE__ */ jsxs22(
|
|
1961
|
+
BaseSelect.Trigger,
|
|
1962
|
+
{
|
|
1963
|
+
"aria-label": ariaLabel,
|
|
1964
|
+
"aria-required": aria["aria-required"],
|
|
1965
|
+
"aria-disabled": held || void 0,
|
|
1966
|
+
className: cn(
|
|
1967
|
+
/*
|
|
1968
|
+
* `min-w-0 max-w-full`: a trigger must never outgrow its container
|
|
1969
|
+
* (Katerina, 2026-09-01 — a long label stretched the files panel's
|
|
1970
|
+
* Lead row past its card). In a flex row the default min-width:auto
|
|
1971
|
+
* forbids shrinking below the label's width, which is what kept
|
|
1972
|
+
* `truncate` from ever engaging; in a block container max-w-full is
|
|
1973
|
+
* the cap. Full-width callers are unaffected.
|
|
1974
|
+
*/
|
|
1975
|
+
"flex w-full min-w-0 max-w-full items-center justify-between gap-2 rounded-lg border bg-bg-inset text-left",
|
|
1976
|
+
"border-border-default text-text-primary outline-none transition-colors",
|
|
1977
|
+
// The focused border survives a hover: hover alone strengthens the
|
|
1978
|
+
// hairline, but hover while focused must not grey the focus colour —
|
|
1979
|
+
// the stacked variant outranks plain hover by specificity.
|
|
1980
|
+
!held && "hover:border-border-strong focus-visible:hover:border-border-focus aria-expanded:hover:border-border-focus",
|
|
1981
|
+
"disabled:pointer-events-none disabled:bg-bg-disabled disabled:text-text-disabled",
|
|
1982
|
+
held && "cursor-not-allowed bg-bg-disabled text-text-disabled",
|
|
1983
|
+
"focus-visible:border-border-focus aria-expanded:border-border-focus",
|
|
1984
|
+
"signal:transition-shadow signal:focus-visible:shadow-focus-ring",
|
|
1985
|
+
size === "default" && "px-3 py-2 text-input-value",
|
|
1986
|
+
size === "small" && "h-6 px-2 text-caption",
|
|
1987
|
+
className
|
|
1988
|
+
),
|
|
1989
|
+
children: [
|
|
1990
|
+
/* @__PURE__ */ jsxs22("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
1991
|
+
selected?.leading && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
1992
|
+
/* @__PURE__ */ jsx30(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
1993
|
+
] }),
|
|
1994
|
+
/* @__PURE__ */ jsx30(
|
|
1995
|
+
BaseSelect.Icon,
|
|
1996
|
+
{
|
|
1997
|
+
render: /* @__PURE__ */ jsx30(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
1998
|
+
}
|
|
1999
|
+
)
|
|
2000
|
+
]
|
|
2001
|
+
}
|
|
2002
|
+
);
|
|
1949
2003
|
return /* @__PURE__ */ jsxs22(
|
|
1950
2004
|
BaseSelect.Root,
|
|
1951
2005
|
{
|
|
1952
2006
|
value,
|
|
1953
|
-
onValueChange: (next) =>
|
|
2007
|
+
onValueChange: (next) => {
|
|
2008
|
+
if (!held) onChange(next);
|
|
2009
|
+
},
|
|
2010
|
+
...held ? { open: false, onOpenChange: () => {
|
|
2011
|
+
} } : {},
|
|
1954
2012
|
disabled,
|
|
1955
2013
|
modal: false,
|
|
1956
2014
|
children: [
|
|
1957
|
-
/* @__PURE__ */
|
|
1958
|
-
BaseSelect.Trigger,
|
|
1959
|
-
{
|
|
1960
|
-
"aria-label": ariaLabel,
|
|
1961
|
-
"aria-required": aria["aria-required"],
|
|
1962
|
-
className: cn(
|
|
1963
|
-
/*
|
|
1964
|
-
* `min-w-0 max-w-full`: a trigger must never outgrow its container
|
|
1965
|
-
* (Katerina, 2026-09-01 — a long label stretched the files panel's
|
|
1966
|
-
* Lead row past its card). In a flex row the default min-width:auto
|
|
1967
|
-
* forbids shrinking below the label's width, which is what kept
|
|
1968
|
-
* `truncate` from ever engaging; in a block container max-w-full is
|
|
1969
|
-
* the cap. Full-width callers are unaffected.
|
|
1970
|
-
*/
|
|
1971
|
-
"flex w-full min-w-0 max-w-full items-center justify-between gap-2 rounded-lg border bg-bg-inset text-left",
|
|
1972
|
-
"border-border-default text-text-primary outline-none transition-colors",
|
|
1973
|
-
// The focused border survives a hover: hover alone strengthens the
|
|
1974
|
-
// hairline, but hover while focused must not grey the focus colour —
|
|
1975
|
-
// the stacked variant outranks plain hover by specificity.
|
|
1976
|
-
"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",
|
|
1977
|
-
"focus-visible:border-border-focus aria-expanded:border-border-focus",
|
|
1978
|
-
"signal:transition-shadow signal:focus-visible:shadow-focus-ring",
|
|
1979
|
-
size === "default" && "px-3 py-2 text-input-value",
|
|
1980
|
-
size === "small" && "h-6 px-2 text-caption",
|
|
1981
|
-
className
|
|
1982
|
-
),
|
|
1983
|
-
children: [
|
|
1984
|
-
/* @__PURE__ */ jsxs22("span", { className: cn("flex min-w-0 items-center gap-2", !selected && "text-text-muted"), children: [
|
|
1985
|
-
selected?.leading && /* @__PURE__ */ jsx30("span", { className: "flex shrink-0 items-center", children: selected.leading }),
|
|
1986
|
-
/* @__PURE__ */ jsx30(BaseSelect.Value, { className: "truncate", children: () => selected?.label ?? placeholder })
|
|
1987
|
-
] }),
|
|
1988
|
-
/* @__PURE__ */ jsx30(
|
|
1989
|
-
BaseSelect.Icon,
|
|
1990
|
-
{
|
|
1991
|
-
render: /* @__PURE__ */ jsx30(IconChevronDown2, { size: size === "small" ? 14 : 16, stroke: 1.5, className: "shrink-0 text-text-secondary" })
|
|
1992
|
-
}
|
|
1993
|
-
)
|
|
1994
|
-
]
|
|
1995
|
-
}
|
|
1996
|
-
),
|
|
2015
|
+
held ? /* @__PURE__ */ jsx30(TooltipTrigger, { label: disabledReason ?? "", children: trigger }) : trigger,
|
|
1997
2016
|
/* @__PURE__ */ jsx30(BaseSelect.Portal, { children: /* @__PURE__ */ jsx30(
|
|
1998
2017
|
BaseSelect.Positioner,
|
|
1999
2018
|
{
|
|
@@ -2521,7 +2540,7 @@ var GAP6 = 12;
|
|
|
2521
2540
|
var VIEWPORT_PAD6 = 8;
|
|
2522
2541
|
var OPEN_DELAY2 = 350;
|
|
2523
2542
|
var CLOSE_DELAY = 200;
|
|
2524
|
-
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, wrapperClassName }) {
|
|
2543
|
+
function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, closeDelay = CLOSE_DELAY, className, contentClassName, wrapperClassName }) {
|
|
2525
2544
|
return /* @__PURE__ */ jsxs28(BasePreviewCard.Root, { children: [
|
|
2526
2545
|
/* @__PURE__ */ jsx42(
|
|
2527
2546
|
BasePreviewCard.Trigger,
|
|
@@ -2543,9 +2562,9 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2543
2562
|
children: /* @__PURE__ */ jsx42(
|
|
2544
2563
|
BasePreviewCard.Popup,
|
|
2545
2564
|
{
|
|
2546
|
-
className: cn("w-[360px] p-
|
|
2565
|
+
className: cn("w-[360px] p-0 outline-none", className),
|
|
2547
2566
|
render: /* @__PURE__ */ jsx42(MenuPanel, {}),
|
|
2548
|
-
children: /* @__PURE__ */ jsx42(ScrollArea, { viewportClassName: "max-h-[
|
|
2567
|
+
children: /* @__PURE__ */ jsx42(ScrollArea, { viewportClassName: "max-h-[min(300px,var(--available-height))]", contentClassName: cn("flex flex-col gap-3 p-3", contentClassName), children: content })
|
|
2549
2568
|
}
|
|
2550
2569
|
)
|
|
2551
2570
|
}
|
|
@@ -2697,7 +2716,7 @@ function SearchInput({ shortcut, className, placeholder = "Search\u2026", ...pro
|
|
|
2697
2716
|
import { IconChevronRight as IconChevronRight2 } from "@tabler/icons-react";
|
|
2698
2717
|
import { useRender } from "@base-ui/react/use-render";
|
|
2699
2718
|
import { Fragment as Fragment8, jsx as jsx49, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2700
|
-
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", render, className }) {
|
|
2719
|
+
function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, trailing, actions, showActions = "hover", hover = "fill", render, className }) {
|
|
2701
2720
|
const titleElement = useRender({
|
|
2702
2721
|
render: render ?? (chevron ? /* @__PURE__ */ jsx49("button", { type: "button", onClick: onToggle, "aria-expanded": isExpanded }) : /* @__PURE__ */ jsx49("span", {})),
|
|
2703
2722
|
props: {
|
|
@@ -2726,7 +2745,7 @@ function SectionHeader({ title, chevron = false, isExpanded = true, onToggle, tr
|
|
|
2726
2745
|
// The fill says "this does something": a row with a toggle or actions
|
|
2727
2746
|
// lights up, a fixed heading over rows does not (2026-09-09, the
|
|
2728
2747
|
// Sidebar's fixed group).
|
|
2729
|
-
(chevron || actions && actions.length > 0) && "hover:bg-bg-hover",
|
|
2748
|
+
hover === "fill" && (chevron || actions && actions.length > 0) && "hover:bg-bg-hover",
|
|
2730
2749
|
className
|
|
2731
2750
|
),
|
|
2732
2751
|
children: [
|