@estiva-app/ui 0.19.0 → 0.21.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 +38 -2
- package/dist/AttachmentCard.d.ts.map +1 -1
- package/dist/Breadcrumb.d.ts.map +1 -1
- package/dist/Button.d.ts +6 -1
- package/dist/Button.d.ts.map +1 -1
- package/dist/Card.d.ts +6 -1
- package/dist/Card.d.ts.map +1 -1
- package/dist/DialogShell.d.ts.map +1 -1
- package/dist/Divider.d.ts +7 -0
- package/dist/Divider.d.ts.map +1 -1
- package/dist/IconButton.d.ts +12 -2
- package/dist/IconButton.d.ts.map +1 -1
- package/dist/IdentityMenu.d.ts.map +1 -1
- package/dist/Link.d.ts +6 -1
- package/dist/Link.d.ts.map +1 -1
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Popover.d.ts.map +1 -1
- package/dist/ReactionPicker.d.ts.map +1 -1
- package/dist/SectionLabel.d.ts +6 -1
- package/dist/SectionLabel.d.ts.map +1 -1
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/eslint/index.d.ts +2 -0
- package/dist/eslint/index.d.ts.map +1 -1
- package/dist/eslint/index.js +514 -6
- package/dist/eslint/index.js.map +4 -4
- package/dist/eslint/no-restyled-part.d.ts +81 -0
- package/dist/eslint/no-restyled-part.d.ts.map +1 -0
- package/dist/gates/app-checks.d.ts +40 -0
- package/dist/gates/app-checks.d.ts.map +1 -0
- package/dist/gates/chunk-AWO7SZSA.js +477 -0
- package/dist/gates/chunk-AWO7SZSA.js.map +7 -0
- package/dist/gates/chunk-ZGJ2J5NU.js +754 -0
- package/dist/gates/chunk-ZGJ2J5NU.js.map +7 -0
- package/dist/gates/cli.d.ts +2 -0
- package/dist/gates/cli.d.ts.map +1 -0
- package/dist/gates/cli.js +46 -0
- package/dist/gates/cli.js.map +7 -0
- package/dist/gates/count.d.ts +20 -0
- package/dist/gates/count.d.ts.map +1 -0
- package/dist/gates/create-app-cli.d.ts +2 -0
- package/dist/gates/create-app-cli.d.ts.map +1 -0
- package/dist/gates/create-app.d.ts +23 -0
- package/dist/gates/create-app.d.ts.map +1 -0
- package/dist/gates/create-app.js +30 -0
- package/dist/gates/create-app.js.map +7 -0
- package/dist/gates/gate-config.d.ts +44 -0
- package/dist/gates/gate-config.d.ts.map +1 -0
- package/dist/gates/hook.d.ts +18 -0
- package/dist/gates/hook.d.ts.map +1 -0
- package/dist/gates/index.d.ts +30 -0
- package/dist/gates/index.d.ts.map +1 -0
- package/dist/gates/index.js +415 -0
- package/dist/gates/index.js.map +7 -0
- package/dist/gates/status.d.ts +84 -0
- package/dist/gates/status.d.ts.map +1 -0
- package/dist/gates/token-lint.d.ts +26 -0
- package/dist/gates/token-lint.d.ts.map +1 -0
- package/dist/index.js +290 -266
- package/dist/index.js.map +4 -4
- package/package.json +30 -4
- package/src/AttachmentCard.tsx +7 -2
- package/src/Banner.tsx +2 -2
- package/src/Breadcrumb.tsx +9 -4
- package/src/Button.mdx +7 -0
- package/src/Button.stories.tsx +4 -1
- package/src/Button.tsx +10 -2
- package/src/Card.mdx +7 -0
- package/src/Card.stories.tsx +11 -0
- package/src/Card.tsx +8 -0
- package/src/CommandPalette.tsx +1 -1
- package/src/ConfirmDialog.tsx +2 -2
- package/src/DialogShell.tsx +6 -7
- package/src/Divider.mdx +3 -0
- package/src/Divider.tsx +12 -2
- package/src/EditableText.mdx +5 -0
- package/src/IconButton.mdx +9 -0
- package/src/IconButton.stories.tsx +10 -1
- package/src/IconButton.tsx +22 -3
- package/src/IdentityMenu.tsx +4 -1
- package/src/Link.mdx +6 -0
- package/src/Link.stories.tsx +12 -0
- package/src/Link.tsx +7 -2
- package/src/Menu.stories.tsx +1 -1
- package/src/Menu.test.tsx +2 -2
- package/src/Menu.tsx +6 -3
- package/src/Person.stories.tsx +5 -5
- package/src/Popover.test.tsx +2 -2
- package/src/Popover.tsx +3 -2
- package/src/PreviewCard.tsx +1 -1
- package/src/Property.stories.tsx +2 -2
- package/src/ReactionPicker.tsx +6 -3
- package/src/ScrollArea.stories.tsx +21 -7
- package/src/SectionLabel.mdx +3 -2
- package/src/SectionLabel.stories.tsx +3 -0
- package/src/SectionLabel.tsx +7 -2
- package/src/Tooltip.tsx +12 -14
- package/src/eslint/index.test.ts +32 -7
- package/src/eslint/index.ts +10 -1
- package/src/eslint/no-restyled-part.test.ts +301 -0
- package/src/eslint/no-restyled-part.ts +647 -0
- package/src/gates/app-checks.ts +224 -0
- package/src/gates/cli.ts +55 -0
- package/src/gates/count.ts +76 -0
- package/src/gates/create-app-cli.ts +25 -0
- package/src/gates/create-app.test.ts +72 -0
- package/src/gates/create-app.ts +797 -0
- package/src/gates/gate-config.ts +78 -0
- package/src/gates/gates.test.ts +183 -0
- package/src/gates/hook.ts +111 -0
- package/src/gates/index.ts +30 -0
- package/src/gates/status.ts +532 -0
- package/src/gates/token-lint.ts +231 -0
package/dist/index.js
CHANGED
|
@@ -163,13 +163,13 @@ var VARIANT_CLASSES = {
|
|
|
163
163
|
underlined: "underline underline-offset-2 hover:text-text-primary",
|
|
164
164
|
plain: ""
|
|
165
165
|
};
|
|
166
|
-
function Link({ href, variant = "text", external = false, className, children, ...props }) {
|
|
166
|
+
function Link({ href, variant = "text", external = false, truncate = false, className, children, ...props }) {
|
|
167
167
|
return /* @__PURE__ */ jsx4(
|
|
168
168
|
"a",
|
|
169
169
|
{
|
|
170
170
|
href,
|
|
171
171
|
...external ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
172
|
-
className: cn(VARIANT_CLASSES[variant], className),
|
|
172
|
+
className: cn(VARIANT_CLASSES[variant], truncate && "truncate", className),
|
|
173
173
|
...props,
|
|
174
174
|
children
|
|
175
175
|
}
|
|
@@ -210,6 +210,7 @@ function Card({
|
|
|
210
210
|
active = false,
|
|
211
211
|
attention,
|
|
212
212
|
unreadable = false,
|
|
213
|
+
clip = false,
|
|
213
214
|
className,
|
|
214
215
|
children,
|
|
215
216
|
...props
|
|
@@ -231,12 +232,16 @@ function Card({
|
|
|
231
232
|
active && "bg-bg-selected border-accent-primary",
|
|
232
233
|
!active && attention && ATTENTION_CLASSES[attention],
|
|
233
234
|
unreadable && "border-dashed",
|
|
235
|
+
clip && "overflow-hidden",
|
|
234
236
|
href && "block",
|
|
235
237
|
className
|
|
236
238
|
);
|
|
237
239
|
if (href !== void 0) {
|
|
238
240
|
const { ref, ...anchorProps } = props;
|
|
239
|
-
return
|
|
241
|
+
return (
|
|
242
|
+
// @estiva-escape: a card that leads somewhere is drawn on Link's anchor (UIG-27 ruling 1), so this frame is Card's own look, not Link restyled
|
|
243
|
+
/* @__PURE__ */ jsx5(Link, { href, variant: "plain", ref, className: classes, ...anchorProps, children })
|
|
244
|
+
);
|
|
240
245
|
}
|
|
241
246
|
return /* @__PURE__ */ jsx5("div", { className: classes, ...props, children });
|
|
242
247
|
}
|
|
@@ -298,19 +303,13 @@ function TooltipSurface({ label, shortcut, placement }) {
|
|
|
298
303
|
children: /* @__PURE__ */ jsx7(
|
|
299
304
|
BaseTooltip.Popup,
|
|
300
305
|
{
|
|
301
|
-
render: /* @__PURE__ */ jsx7(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
"data-[ending-style]:duration-[80ms] data-[instant]:duration-0",
|
|
309
|
-
"data-[starting-style]:opacity-0 data-[ending-style]:opacity-0",
|
|
310
|
-
"data-[side=top]:data-[starting-style]:translate-y-[4px] data-[side=top]:data-[ending-style]:translate-y-[4px]",
|
|
311
|
-
"data-[side=bottom]:data-[starting-style]:-translate-y-[4px] data-[side=bottom]:data-[ending-style]:-translate-y-[4px]"
|
|
312
|
-
)
|
|
313
|
-
}
|
|
306
|
+
render: /* @__PURE__ */ jsx7(Tooltip, { label, shortcut }),
|
|
307
|
+
className: cn(
|
|
308
|
+
"transition-[opacity,transform] duration-[120ms] ease-out motion-reduce:transition-none",
|
|
309
|
+
"data-[ending-style]:duration-[80ms] data-[instant]:duration-0",
|
|
310
|
+
"data-[starting-style]:opacity-0 data-[ending-style]:opacity-0",
|
|
311
|
+
"data-[side=top]:data-[starting-style]:translate-y-[4px] data-[side=top]:data-[ending-style]:translate-y-[4px]",
|
|
312
|
+
"data-[side=bottom]:data-[starting-style]:-translate-y-[4px] data-[side=bottom]:data-[ending-style]:-translate-y-[4px]"
|
|
314
313
|
)
|
|
315
314
|
}
|
|
316
315
|
)
|
|
@@ -334,6 +333,8 @@ function TooltipTrigger({ label, shortcut, placement = "top", children }) {
|
|
|
334
333
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
335
334
|
function IconButton({
|
|
336
335
|
variant = "muted",
|
|
336
|
+
pressed,
|
|
337
|
+
glow = false,
|
|
337
338
|
className,
|
|
338
339
|
children,
|
|
339
340
|
disabled,
|
|
@@ -365,11 +366,17 @@ function IconButton({
|
|
|
365
366
|
// stretched and carries no `self-center` — see the note there.
|
|
366
367
|
"flex items-center justify-center p-1 rounded-lg transition-colors shrink-0 self-center cursor-pointer",
|
|
367
368
|
!state.disabled && variant === "primary" && "bg-accent-primary hover:bg-accent-hover text-text-inverse",
|
|
368
|
-
!state.disabled && variant === "muted" && "text-text-secondary hover:bg-bg-hover hover:text-text-primary",
|
|
369
|
+
!state.disabled && (variant === "muted" || variant === "resolve") && "text-text-secondary hover:bg-bg-hover hover:text-text-primary",
|
|
369
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",
|
|
370
372
|
state.disabled && variant === "primary" && "bg-bg-disabled text-text-disabled",
|
|
371
|
-
state.disabled && variant === "muted" && "text-text-disabled",
|
|
373
|
+
state.disabled && (variant === "muted" || variant === "resolve") && "text-text-disabled",
|
|
372
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",
|
|
373
380
|
// `pointer-events-none` only where the button is truly out of reach:
|
|
374
381
|
// with a `disabledReason` the button IS the tooltip's trigger, and a
|
|
375
382
|
// trigger the pointer cannot land on never opens one. Base UI already
|
|
@@ -378,6 +385,7 @@ function IconButton({
|
|
|
378
385
|
state.disabled && "cursor-not-allowed",
|
|
379
386
|
className
|
|
380
387
|
),
|
|
388
|
+
"aria-pressed": pressed,
|
|
381
389
|
...props,
|
|
382
390
|
children
|
|
383
391
|
}
|
|
@@ -471,75 +479,85 @@ function AttachmentCard({
|
|
|
471
479
|
if (pending) {
|
|
472
480
|
const failed = state === "failed";
|
|
473
481
|
const warning = state === "warning";
|
|
474
|
-
return
|
|
475
|
-
Card,
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
/* @__PURE__ */ jsx9(
|
|
484
|
-
/* @__PURE__ */
|
|
485
|
-
Truncating,
|
|
482
|
+
return (
|
|
483
|
+
// @estiva-escape: a failed or warning file's strong hairline is AttachmentCard's own state; Card's attention hairlines are the soft ones (UIG-9, Katerina 17 September)
|
|
484
|
+
/* @__PURE__ */ jsxs5(
|
|
485
|
+
Card,
|
|
486
|
+
{
|
|
487
|
+
fill: "elevated",
|
|
488
|
+
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),
|
|
489
|
+
...props,
|
|
490
|
+
children: [
|
|
491
|
+
/* @__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
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0", children: [
|
|
493
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
|
|
494
|
+
/* @__PURE__ */ jsx9(
|
|
495
|
+
Truncating,
|
|
496
|
+
{
|
|
497
|
+
text: (failed || warning ? note : state === "uploading" ? note ?? "Uploading\u2026" : note ?? sizeText) ?? "",
|
|
498
|
+
hint: noteHint,
|
|
499
|
+
className: cn(NOTE_CLASSES, failed ? "text-error-default" : warning ? "text-warning-default" : "text-text-secondary")
|
|
500
|
+
}
|
|
501
|
+
)
|
|
502
|
+
] }),
|
|
503
|
+
onRemove && /* @__PURE__ */ jsx9(
|
|
504
|
+
BaseButton2,
|
|
486
505
|
{
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
className:
|
|
506
|
+
type: "button",
|
|
507
|
+
"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",
|
|
509
|
+
onClick: (event) => {
|
|
510
|
+
event.stopPropagation();
|
|
511
|
+
onRemove();
|
|
512
|
+
},
|
|
513
|
+
children: /* @__PURE__ */ jsx9(IconX, { size: 11, stroke: 1.75 })
|
|
490
514
|
}
|
|
491
515
|
)
|
|
492
|
-
]
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
{
|
|
496
|
-
type: "button",
|
|
497
|
-
"aria-label": `Remove ${name}`,
|
|
498
|
-
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",
|
|
499
|
-
onClick: (event) => {
|
|
500
|
-
event.stopPropagation();
|
|
501
|
-
onRemove();
|
|
502
|
-
},
|
|
503
|
-
children: /* @__PURE__ */ jsx9(IconX, { size: 11, stroke: 1.75 })
|
|
504
|
-
}
|
|
505
|
-
)
|
|
506
|
-
]
|
|
507
|
-
}
|
|
516
|
+
]
|
|
517
|
+
}
|
|
518
|
+
)
|
|
508
519
|
);
|
|
509
520
|
}
|
|
510
|
-
const download = onDownload ?
|
|
511
|
-
IconButton,
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
521
|
+
const download = onDownload ? (
|
|
522
|
+
// @estiva-escape: Download shows when its card is pointed at or focused, AttachmentCard's own action; IconButton has no reveal on its card's hover (UIG-9, Katerina 17 September)
|
|
523
|
+
/* @__PURE__ */ jsx9(
|
|
524
|
+
IconButton,
|
|
525
|
+
{
|
|
526
|
+
variant: "muted",
|
|
527
|
+
tooltip: "Download",
|
|
528
|
+
"aria-label": `Download ${name}`,
|
|
529
|
+
className: "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 focus-visible:opacity-100 transition-opacity",
|
|
530
|
+
onClick: (event) => {
|
|
531
|
+
event.stopPropagation();
|
|
532
|
+
onDownload();
|
|
533
|
+
},
|
|
534
|
+
children: /* @__PURE__ */ jsx9(IconDownload, { size: 16, stroke: 1.5 })
|
|
535
|
+
}
|
|
536
|
+
)
|
|
523
537
|
) : null;
|
|
524
538
|
if (state === "loading") {
|
|
525
539
|
return (
|
|
526
540
|
// `role="status"`: a plain box may not carry a name (axe, aria-prohibited-attr), and a
|
|
527
541
|
// status says what it is doing — loading — to a reader that cannot see the pulse.
|
|
542
|
+
// @estiva-escape: the loading pulse is AttachmentCard's own state; Card has no loading state (UIG-9, Katerina 17 September)
|
|
528
543
|
/* @__PURE__ */ jsx9(Card, { role: "status", fill: "inset", "aria-busy": "true", "aria-label": `Loading ${name}`, className: cn("w-[180px] h-28 animate-pulse", className), ...props, children: null })
|
|
529
544
|
);
|
|
530
545
|
}
|
|
531
546
|
if (state === "unreadable") {
|
|
532
|
-
return
|
|
533
|
-
|
|
534
|
-
/* @__PURE__ */ jsxs5("
|
|
535
|
-
/* @__PURE__ */ jsx9(
|
|
536
|
-
/* @__PURE__ */
|
|
547
|
+
return (
|
|
548
|
+
// @estiva-escape: a file that could not be read is faded as well as dashed, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
|
|
549
|
+
/* @__PURE__ */ jsxs5(Card, { fill: "inset", unreadable: true, className: cn("flex items-center gap-2 w-[240px] p-1.5 opacity-70", className), ...props, children: [
|
|
550
|
+
/* @__PURE__ */ jsx9("div", { className: TILE_CLASSES, children: /* @__PURE__ */ jsx9(TypeIcon, { name }) }),
|
|
551
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex flex-col gap-[1px] min-w-0 text-left", children: [
|
|
552
|
+
/* @__PURE__ */ jsx9(Truncating, { text: name, className: NAME_CLASSES }),
|
|
553
|
+
/* @__PURE__ */ jsx9("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? "Could not be loaded" })
|
|
554
|
+
] })
|
|
537
555
|
] })
|
|
538
|
-
|
|
556
|
+
);
|
|
539
557
|
}
|
|
540
558
|
if (image && src) {
|
|
541
559
|
const picture = /* @__PURE__ */ jsx9("img", { src, alt: name, className: "w-full h-28 object-cover" });
|
|
542
|
-
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: "hairline", className: cn("group relative flex flex-col w-[180px]
|
|
560
|
+
return /* @__PURE__ */ jsxs5(Card, { fill: "inset", hover: "hairline", clip: true, className: cn("group relative flex flex-col w-[180px]", className), ...props, children: [
|
|
543
561
|
onOpen ? /* @__PURE__ */ jsx9(
|
|
544
562
|
BaseButton2,
|
|
545
563
|
{
|
|
@@ -566,10 +584,13 @@ function AttachmentCard({
|
|
|
566
584
|
/* @__PURE__ */ jsx9("span", { className: cn(NOTE_CLASSES, "text-text-secondary"), children: note ?? `${typeLabelOf(name)} \xB7 ${sizeText}` })
|
|
567
585
|
] })
|
|
568
586
|
] });
|
|
569
|
-
return
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
587
|
+
return (
|
|
588
|
+
// @estiva-escape: a file that cannot be opened is faded, AttachmentCard's own state; Card has no faded state (UIG-9, Katerina 17 September)
|
|
589
|
+
/* @__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: [
|
|
590
|
+
href ? /* @__PURE__ */ jsx9(Link, { href, external: true, variant: "plain", className: "flex items-center gap-2 min-w-0 flex-1", onClick: (event) => event.stopPropagation(), children: body }) : /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2 min-w-0 flex-1", children: body }),
|
|
591
|
+
download
|
|
592
|
+
] })
|
|
593
|
+
);
|
|
573
594
|
}
|
|
574
595
|
|
|
575
596
|
// src/Avatar.tsx
|
|
@@ -671,7 +692,7 @@ function Banner({ tone, children, onDismiss, dismissLabel = "Dismiss", className
|
|
|
671
692
|
}
|
|
672
693
|
return /* @__PURE__ */ jsxs7("div", { role, className: cn("flex items-center gap-3 px-4 py-2 text-body-2", TONE_STYLES[tone], className), children: [
|
|
673
694
|
/* @__PURE__ */ jsx12("span", { className: "min-w-0 flex-1", children }),
|
|
674
|
-
/* @__PURE__ */ jsx12(IconButton, { "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0
|
|
695
|
+
/* @__PURE__ */ jsx12(IconButton, { variant: "current", "aria-label": dismissLabel, onClick: onDismiss, className: "-mr-1 shrink-0", children: /* @__PURE__ */ jsx12(IconX2, { size: 16, stroke: 1.5 }) })
|
|
675
696
|
] });
|
|
676
697
|
}
|
|
677
698
|
|
|
@@ -715,7 +736,7 @@ function Button({
|
|
|
715
736
|
// Extra right padding beside a leading icon, for optical balance.
|
|
716
737
|
size === "default" && (hasLeadingIcon ? "pl-2 pr-3" : "px-2"),
|
|
717
738
|
size === "small" && (hasLeadingIcon ? "pl-1.5 pr-2" : "px-1.5"),
|
|
718
|
-
!state.disabled && variant === "primary" && "bg-accent-primary hover:bg-accent-hover text-text-inverse cursor-pointer signal:font-semibold",
|
|
739
|
+
!state.disabled && (variant === "primary" || variant === "resolve") && "bg-accent-primary hover:bg-accent-hover text-text-inverse cursor-pointer signal:font-semibold",
|
|
719
740
|
!state.disabled && variant === "outlined" && "border border-border-default hover:bg-bg-hover text-text-primary cursor-pointer",
|
|
720
741
|
!state.disabled && variant === "muted" && "hover:bg-bg-hover text-text-primary cursor-pointer",
|
|
721
742
|
!state.disabled && variant === "destructive" && "hover:bg-error-muted text-error-default cursor-pointer",
|
|
@@ -727,6 +748,8 @@ function Button({
|
|
|
727
748
|
// and a prevented `onClick`), so nothing else needs it.
|
|
728
749
|
state.disabled && !disabledReason && "pointer-events-none",
|
|
729
750
|
state.disabled && variant === "outlined" && "border border-border-default",
|
|
751
|
+
// Disabled too, as it always drew.
|
|
752
|
+
variant === "resolve" && "signal:bg-transparent signal:border signal:border-border-default signal:text-text-primary signal:shadow-none signal:hover:bg-success-muted signal:hover:border-success-outline signal:hover:text-success-default signal:transition-colors",
|
|
730
753
|
className
|
|
731
754
|
),
|
|
732
755
|
...props,
|
|
@@ -822,8 +845,8 @@ function Chip({ type = "neutral", label, leadingIcon, trailingIcon, className })
|
|
|
822
845
|
|
|
823
846
|
// src/CommandPalette.tsx
|
|
824
847
|
import {
|
|
825
|
-
createContext as
|
|
826
|
-
useContext as
|
|
848
|
+
createContext as createContext4,
|
|
849
|
+
useContext as useContext4,
|
|
827
850
|
useEffect,
|
|
828
851
|
useLayoutEffect as useLayoutEffect3,
|
|
829
852
|
useMemo as useMemo2,
|
|
@@ -841,10 +864,42 @@ import { Combobox } from "@base-ui/react/combobox";
|
|
|
841
864
|
import { IconX as IconX3 } from "@tabler/icons-react";
|
|
842
865
|
|
|
843
866
|
// src/Menu.tsx
|
|
844
|
-
import { createContext as
|
|
867
|
+
import { createContext as createContext3, useContext as useContext3 } from "react";
|
|
845
868
|
import { IconChevronRight } from "@tabler/icons-react";
|
|
846
869
|
import { Menu as BaseMenu } from "@base-ui/react/menu";
|
|
847
870
|
|
|
871
|
+
// src/Divider.tsx
|
|
872
|
+
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
873
|
+
import { Separator } from "@base-ui/react/separator";
|
|
874
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
875
|
+
var DividerInPanel = createContext2(false);
|
|
876
|
+
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
877
|
+
const inset = useContext2(DividerInPanel) ? "mx-0" : "mx-3";
|
|
878
|
+
if (label && orientation === "horizontal") {
|
|
879
|
+
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
880
|
+
return /* @__PURE__ */ jsxs11(
|
|
881
|
+
Separator,
|
|
882
|
+
{
|
|
883
|
+
orientation: "horizontal",
|
|
884
|
+
"aria-label": label,
|
|
885
|
+
className: cn("flex shrink-0 items-center gap-2", inset, className),
|
|
886
|
+
children: [
|
|
887
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
888
|
+
/* @__PURE__ */ jsx16("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
889
|
+
/* @__PURE__ */ jsx16("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
890
|
+
]
|
|
891
|
+
}
|
|
892
|
+
);
|
|
893
|
+
}
|
|
894
|
+
return /* @__PURE__ */ jsx16(
|
|
895
|
+
Separator,
|
|
896
|
+
{
|
|
897
|
+
orientation,
|
|
898
|
+
className: cn("shrink-0 bg-border-subtle", orientation === "horizontal" ? cn("h-px", inset) : "w-px self-stretch", className)
|
|
899
|
+
}
|
|
900
|
+
);
|
|
901
|
+
}
|
|
902
|
+
|
|
848
903
|
// src/triggerDisabled.ts
|
|
849
904
|
function triggerDisabled(trigger) {
|
|
850
905
|
const props = trigger.props;
|
|
@@ -852,13 +907,14 @@ function triggerDisabled(trigger) {
|
|
|
852
907
|
}
|
|
853
908
|
|
|
854
909
|
// src/SectionLabel.tsx
|
|
855
|
-
import { jsx as
|
|
856
|
-
function SectionLabel({ children, className }) {
|
|
857
|
-
return /* @__PURE__ */
|
|
910
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
911
|
+
function SectionLabel({ children, tone = "primary", className }) {
|
|
912
|
+
return /* @__PURE__ */ jsx17(
|
|
858
913
|
"span",
|
|
859
914
|
{
|
|
860
915
|
className: cn(
|
|
861
|
-
"text-h5 leading-3
|
|
916
|
+
"text-h5 leading-3 signal:font-mono signal:text-small signal:uppercase signal:tracking-widest",
|
|
917
|
+
tone === "secondary" ? "text-text-secondary" : "text-text-primary",
|
|
862
918
|
className
|
|
863
919
|
),
|
|
864
920
|
children
|
|
@@ -867,10 +923,10 @@ function SectionLabel({ children, className }) {
|
|
|
867
923
|
}
|
|
868
924
|
|
|
869
925
|
// src/Menu.tsx
|
|
870
|
-
import { Fragment as Fragment2, jsx as
|
|
871
|
-
var MenuContext =
|
|
926
|
+
import { Fragment as Fragment2, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
927
|
+
var MenuContext = createContext3(null);
|
|
872
928
|
function MenuPanel({ children, className, ...props }) {
|
|
873
|
-
return /* @__PURE__ */
|
|
929
|
+
return /* @__PURE__ */ jsx18(
|
|
874
930
|
"div",
|
|
875
931
|
{
|
|
876
932
|
className: cn(
|
|
@@ -900,7 +956,7 @@ var VIEWPORT_PAD2 = 8;
|
|
|
900
956
|
var HOVER_OPEN_DELAY = 0;
|
|
901
957
|
var HOVER_CLOSE_DELAY = 150;
|
|
902
958
|
function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange, actionsRef, children, className, contentClassName }) {
|
|
903
|
-
return /* @__PURE__ */
|
|
959
|
+
return /* @__PURE__ */ jsxs12(
|
|
904
960
|
BaseMenu.Root,
|
|
905
961
|
{
|
|
906
962
|
open,
|
|
@@ -908,7 +964,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
908
964
|
actionsRef,
|
|
909
965
|
modal: false,
|
|
910
966
|
children: [
|
|
911
|
-
/* @__PURE__ */
|
|
967
|
+
/* @__PURE__ */ jsx18(
|
|
912
968
|
BaseMenu.Trigger,
|
|
913
969
|
{
|
|
914
970
|
render: trigger,
|
|
@@ -918,7 +974,7 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
918
974
|
closeDelay: HOVER_CLOSE_DELAY
|
|
919
975
|
}
|
|
920
976
|
),
|
|
921
|
-
/* @__PURE__ */
|
|
977
|
+
/* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
|
|
922
978
|
BaseMenu.Positioner,
|
|
923
979
|
{
|
|
924
980
|
side: "bottom",
|
|
@@ -926,13 +982,13 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
926
982
|
sideOffset: GAP2,
|
|
927
983
|
collisionPadding: VIEWPORT_PAD2,
|
|
928
984
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
929
|
-
children: /* @__PURE__ */
|
|
985
|
+
children: /* @__PURE__ */ jsx18(
|
|
930
986
|
BaseMenu.Popup,
|
|
931
987
|
{
|
|
932
988
|
"data-interactive": true,
|
|
933
989
|
className: cn("min-w-[180px] outline-none p-0", className),
|
|
934
|
-
render: /* @__PURE__ */
|
|
935
|
-
children: /* @__PURE__ */
|
|
990
|
+
render: /* @__PURE__ */ jsx18(MenuPanel, {}),
|
|
991
|
+
children: /* @__PURE__ */ jsx18(ScrollArea, { viewportClassName: "max-h-[var(--available-height)]", contentClassName: cn("flex flex-col p-2", contentClassName), children: /* @__PURE__ */ jsx18(MenuContext.Provider, { value: { openOnHover }, children: /* @__PURE__ */ jsx18(DividerInPanel.Provider, { value: true, children }) }) })
|
|
936
992
|
}
|
|
937
993
|
)
|
|
938
994
|
}
|
|
@@ -942,26 +998,26 @@ function Menu({ trigger, align = "left", openOnHover = false, open, onOpenChange
|
|
|
942
998
|
);
|
|
943
999
|
}
|
|
944
1000
|
function MenuSub({ label, leading, selected, children, className }) {
|
|
945
|
-
const menu =
|
|
1001
|
+
const menu = useContext3(MenuContext);
|
|
946
1002
|
if (!isProduction() && menu?.openOnHover) {
|
|
947
1003
|
console.error(
|
|
948
1004
|
'[@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".'
|
|
949
1005
|
);
|
|
950
1006
|
}
|
|
951
|
-
return /* @__PURE__ */
|
|
952
|
-
/* @__PURE__ */
|
|
1007
|
+
return /* @__PURE__ */ jsxs12(BaseMenu.SubmenuRoot, { children: [
|
|
1008
|
+
/* @__PURE__ */ jsx18(
|
|
953
1009
|
BaseMenu.SubmenuTrigger,
|
|
954
1010
|
{
|
|
955
1011
|
openOnHover: true,
|
|
956
1012
|
delay: 0,
|
|
957
1013
|
closeDelay: 150,
|
|
958
1014
|
nativeButton: true,
|
|
959
|
-
render: /* @__PURE__ */
|
|
1015
|
+
render: /* @__PURE__ */ jsx18("button", { type: "button" }),
|
|
960
1016
|
className: menuItemClassName({ size: "default", selected }),
|
|
961
|
-
children: /* @__PURE__ */
|
|
1017
|
+
children: /* @__PURE__ */ jsx18(MenuItemBody, { label, leading, submenu: true })
|
|
962
1018
|
}
|
|
963
1019
|
),
|
|
964
|
-
/* @__PURE__ */
|
|
1020
|
+
/* @__PURE__ */ jsx18(BaseMenu.Portal, { children: /* @__PURE__ */ jsx18(
|
|
965
1021
|
BaseMenu.Positioner,
|
|
966
1022
|
{
|
|
967
1023
|
side: "inline-end",
|
|
@@ -969,7 +1025,7 @@ function MenuSub({ label, leading, selected, children, className }) {
|
|
|
969
1025
|
sideOffset: GAP2,
|
|
970
1026
|
collisionPadding: VIEWPORT_PAD2,
|
|
971
1027
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
972
|
-
children: /* @__PURE__ */
|
|
1028
|
+
children: /* @__PURE__ */ jsx18(BaseMenu.Popup, { className: cn("w-[160px]", className), "data-interactive": true, render: /* @__PURE__ */ jsx18(MenuPanel, {}), children })
|
|
973
1029
|
}
|
|
974
1030
|
) })
|
|
975
1031
|
] });
|
|
@@ -1004,25 +1060,25 @@ function menuItemClassName({ size, selected, className }) {
|
|
|
1004
1060
|
);
|
|
1005
1061
|
}
|
|
1006
1062
|
function MenuItemBody({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected }) {
|
|
1007
|
-
const edge = trailing ?? (shortcut ? /* @__PURE__ */
|
|
1008
|
-
return /* @__PURE__ */
|
|
1009
|
-
leading && /* @__PURE__ */
|
|
1010
|
-
children ?? /* @__PURE__ */
|
|
1011
|
-
/* @__PURE__ */
|
|
1012
|
-
description && /* @__PURE__ */
|
|
1063
|
+
const edge = trailing ?? (shortcut ? /* @__PURE__ */ jsx18(Kbd, { children: shortcut }) : submenu ? /* @__PURE__ */ jsx18(IconChevronRight, { size: 16, stroke: 1.5, className: "shrink-0 text-text-muted" }) : null);
|
|
1064
|
+
return /* @__PURE__ */ jsxs12(Fragment2, { children: [
|
|
1065
|
+
leading && /* @__PURE__ */ jsx18("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1066
|
+
children ?? /* @__PURE__ */ jsxs12("span", { className: cn("flex min-w-0 flex-1 flex-col", size === "tall" && "gap-[2px]"), children: [
|
|
1067
|
+
/* @__PURE__ */ jsx18("span", { className: cn("truncate text-body-2", destructive ? "text-error-default" : "text-text-primary"), children: label }),
|
|
1068
|
+
description && /* @__PURE__ */ jsx18("span", { className: "truncate text-caption text-text-secondary", children: description })
|
|
1013
1069
|
] }),
|
|
1014
1070
|
(edge || hint) && // One grid cell holding both, right-aligned: the slot is as wide as
|
|
1015
1071
|
// the wider of the two and never changes, so revealing the hint moves
|
|
1016
1072
|
// nothing. No transition here either — the hint switches on the same
|
|
1017
1073
|
// :hover / `selected` as the fill, in the same frame.
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
edge && /* @__PURE__ */
|
|
1020
|
-
hint && /* @__PURE__ */
|
|
1074
|
+
/* @__PURE__ */ jsxs12("span", { className: "grid shrink-0 items-center justify-items-end [&>*]:col-start-1 [&>*]:row-start-1", children: [
|
|
1075
|
+
edge && /* @__PURE__ */ jsx18("span", { className: cn("flex items-center", hint && "group-hover:opacity-0 group-data-[highlighted]:opacity-0", hint && selected && "opacity-0"), children: edge }),
|
|
1076
|
+
hint && /* @__PURE__ */ jsx18("span", { className: cn("flex items-center opacity-0 group-hover:opacity-100 group-data-[highlighted]:opacity-100", selected && "opacity-100"), children: hint })
|
|
1021
1077
|
] })
|
|
1022
1078
|
] });
|
|
1023
1079
|
}
|
|
1024
1080
|
function MenuItem({ label, children, size = "default", description, leading, trailing, hint, shortcut, submenu, destructive, selected, className, ...props }) {
|
|
1025
|
-
const body = /* @__PURE__ */
|
|
1081
|
+
const body = /* @__PURE__ */ jsx18(
|
|
1026
1082
|
MenuItemBody,
|
|
1027
1083
|
{
|
|
1028
1084
|
label,
|
|
@@ -1039,14 +1095,14 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1039
1095
|
}
|
|
1040
1096
|
);
|
|
1041
1097
|
const rowClassName = menuItemClassName({ size, selected, className });
|
|
1042
|
-
if (!
|
|
1043
|
-
return /* @__PURE__ */
|
|
1098
|
+
if (!useContext3(MenuContext)) {
|
|
1099
|
+
return /* @__PURE__ */ jsx18("button", { type: "button", className: rowClassName, ...props, children: body });
|
|
1044
1100
|
}
|
|
1045
|
-
return /* @__PURE__ */
|
|
1101
|
+
return /* @__PURE__ */ jsx18(
|
|
1046
1102
|
BaseMenu.Item,
|
|
1047
1103
|
{
|
|
1048
1104
|
nativeButton: true,
|
|
1049
|
-
render: /* @__PURE__ */
|
|
1105
|
+
render: /* @__PURE__ */ jsx18("button", { type: "button" }),
|
|
1050
1106
|
className: rowClassName,
|
|
1051
1107
|
...props,
|
|
1052
1108
|
children: body
|
|
@@ -1054,31 +1110,31 @@ function MenuItem({ label, children, size = "default", description, leading, tra
|
|
|
1054
1110
|
);
|
|
1055
1111
|
}
|
|
1056
1112
|
function EnterHint({ target }) {
|
|
1057
|
-
return /* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
target && /* @__PURE__ */
|
|
1113
|
+
return /* @__PURE__ */ jsxs12("span", { className: "flex shrink-0 items-center gap-1.5 text-text-muted", children: [
|
|
1114
|
+
/* @__PURE__ */ jsx18(Kbd, { children: "\u21A9 Enter" }),
|
|
1115
|
+
target && /* @__PURE__ */ jsx18("span", { className: "text-menu signal:font-mono signal:text-small signal:tracking-wider", children: target })
|
|
1060
1116
|
] });
|
|
1061
1117
|
}
|
|
1062
1118
|
function MenuSection({ label, children, className }) {
|
|
1063
|
-
const inMenu =
|
|
1064
|
-
const heading = /* @__PURE__ */
|
|
1119
|
+
const inMenu = useContext3(MenuContext) !== null;
|
|
1120
|
+
const heading = /* @__PURE__ */ jsx18("div", { className: cn("flex h-8 items-center px-2", className), children: /* @__PURE__ */ jsx18(SectionLabel, { tone: "secondary", children: label }) });
|
|
1065
1121
|
if (!inMenu) {
|
|
1066
|
-
return /* @__PURE__ */
|
|
1122
|
+
return /* @__PURE__ */ jsxs12("div", { className: "flex flex-col", children: [
|
|
1067
1123
|
heading,
|
|
1068
1124
|
children
|
|
1069
1125
|
] });
|
|
1070
1126
|
}
|
|
1071
|
-
return /* @__PURE__ */
|
|
1072
|
-
/* @__PURE__ */
|
|
1127
|
+
return /* @__PURE__ */ jsxs12(BaseMenu.Group, { className: "flex flex-col", children: [
|
|
1128
|
+
/* @__PURE__ */ jsx18(BaseMenu.GroupLabel, { render: heading }),
|
|
1073
1129
|
children
|
|
1074
1130
|
] });
|
|
1075
1131
|
}
|
|
1076
1132
|
function MenuRow({ children, className }) {
|
|
1077
|
-
return /* @__PURE__ */
|
|
1133
|
+
return /* @__PURE__ */ jsx18("div", { className: cn("flex items-center gap-2 px-2 py-1.5", className), children });
|
|
1078
1134
|
}
|
|
1079
1135
|
|
|
1080
1136
|
// src/ChipInput.tsx
|
|
1081
|
-
import { jsx as
|
|
1137
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1082
1138
|
var CHIP_BOX = (
|
|
1083
1139
|
// Curved, not a pill (Katerina, 2026-09-01): the Avatar keeps its own
|
|
1084
1140
|
// rounded-sm corners — never a forced circle — and the chip's corner
|
|
@@ -1089,10 +1145,10 @@ var CHIP_LABEL = "text-caption font-medium text-text-primary";
|
|
|
1089
1145
|
var CHIP_REMOVE = "size-4 flex items-center justify-center rounded-full hover:bg-bg-hover text-text-secondary";
|
|
1090
1146
|
var chipPadding = (leading, removable) => cn(leading ? "pl-[2px]" : "pl-2", removable ? "pr-1" : "pr-2");
|
|
1091
1147
|
function InputChip({ label, leading, onRemove, removeLabel, truncate, className }) {
|
|
1092
|
-
return /* @__PURE__ */
|
|
1093
|
-
leading && /* @__PURE__ */
|
|
1094
|
-
/* @__PURE__ */
|
|
1095
|
-
onRemove && /* @__PURE__ */
|
|
1148
|
+
return /* @__PURE__ */ jsxs13("div", { className: cn(CHIP_BOX, chipPadding(!!leading, !!onRemove), className), children: [
|
|
1149
|
+
leading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: leading }),
|
|
1150
|
+
/* @__PURE__ */ jsx19("span", { className: cn(CHIP_LABEL, truncate && "min-w-0 truncate"), children: label }),
|
|
1151
|
+
onRemove && /* @__PURE__ */ jsx19(
|
|
1096
1152
|
BaseButton4,
|
|
1097
1153
|
{
|
|
1098
1154
|
type: "button",
|
|
@@ -1102,7 +1158,7 @@ function InputChip({ label, leading, onRemove, removeLabel, truncate, className
|
|
|
1102
1158
|
},
|
|
1103
1159
|
className: cn(CHIP_REMOVE, truncate && "shrink-0"),
|
|
1104
1160
|
"aria-label": removeLabel ?? `Remove ${label}`,
|
|
1105
|
-
children: /* @__PURE__ */
|
|
1161
|
+
children: /* @__PURE__ */ jsx19(IconX3, { size: 10, stroke: 1.5 })
|
|
1106
1162
|
}
|
|
1107
1163
|
)
|
|
1108
1164
|
] });
|
|
@@ -1155,7 +1211,7 @@ function ChipInput({
|
|
|
1155
1211
|
setQuery("");
|
|
1156
1212
|
}
|
|
1157
1213
|
}
|
|
1158
|
-
return /* @__PURE__ */
|
|
1214
|
+
return /* @__PURE__ */ jsxs13(
|
|
1159
1215
|
Combobox.Root,
|
|
1160
1216
|
{
|
|
1161
1217
|
multiple: true,
|
|
@@ -1172,13 +1228,13 @@ function ChipInput({
|
|
|
1172
1228
|
filter,
|
|
1173
1229
|
itemToStringLabel: (option) => option.label,
|
|
1174
1230
|
children: [
|
|
1175
|
-
/* @__PURE__ */
|
|
1176
|
-
value.map((option) => /* @__PURE__ */
|
|
1177
|
-
chipLeading && /* @__PURE__ */
|
|
1178
|
-
/* @__PURE__ */
|
|
1179
|
-
/* @__PURE__ */
|
|
1231
|
+
/* @__PURE__ */ jsxs13(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: [
|
|
1232
|
+
value.map((option) => /* @__PURE__ */ jsxs13(Combobox.Chip, { className: cn(CHIP_BOX, chipPadding(!!chipLeading, true)), children: [
|
|
1233
|
+
chipLeading && /* @__PURE__ */ jsx19("span", { className: "flex shrink-0 items-center", children: chipLeading(option) }),
|
|
1234
|
+
/* @__PURE__ */ jsx19("span", { className: CHIP_LABEL, children: option.label }),
|
|
1235
|
+
/* @__PURE__ */ jsx19(Combobox.ChipRemove, { className: CHIP_REMOVE, "aria-label": `Remove ${option.label}`, children: /* @__PURE__ */ jsx19(IconX3, { size: 10, stroke: 1.5 }) })
|
|
1180
1236
|
] }, option.id)),
|
|
1181
|
-
/* @__PURE__ */
|
|
1237
|
+
/* @__PURE__ */ jsx19(
|
|
1182
1238
|
Combobox.Input,
|
|
1183
1239
|
{
|
|
1184
1240
|
autoFocus,
|
|
@@ -1190,18 +1246,18 @@ function ChipInput({
|
|
|
1190
1246
|
}
|
|
1191
1247
|
)
|
|
1192
1248
|
] }),
|
|
1193
|
-
/* @__PURE__ */
|
|
1249
|
+
/* @__PURE__ */ jsx19(Combobox.Portal, { children: /* @__PURE__ */ jsx19(
|
|
1194
1250
|
Combobox.Positioner,
|
|
1195
1251
|
{
|
|
1196
1252
|
anchor: box,
|
|
1197
1253
|
sideOffset: GAP3,
|
|
1198
1254
|
collisionPadding: VIEWPORT_PAD3,
|
|
1199
1255
|
className: "z-50 data-[anchor-hidden]:hidden",
|
|
1200
|
-
children: /* @__PURE__ */
|
|
1256
|
+
children: /* @__PURE__ */ jsx19(Combobox.Popup, { className: "w-[var(--anchor-width)] p-0", render: /* @__PURE__ */ jsx19(MenuPanel, {}), children: /* @__PURE__ */ jsx19(ScrollArea, { viewportClassName: "max-h-[240px]", contentClassName: "flex flex-col p-2", children: /* @__PURE__ */ jsx19(Combobox.List, { children: (option) => /* @__PURE__ */ jsx19(
|
|
1201
1257
|
Combobox.Item,
|
|
1202
1258
|
{
|
|
1203
1259
|
value: option,
|
|
1204
|
-
render: /* @__PURE__ */
|
|
1260
|
+
render: /* @__PURE__ */ jsx19(
|
|
1205
1261
|
MenuItem,
|
|
1206
1262
|
{
|
|
1207
1263
|
size: "tall",
|
|
@@ -1224,21 +1280,21 @@ var VIEWPORT_PAD3 = 8;
|
|
|
1224
1280
|
|
|
1225
1281
|
// src/EmptyState.tsx
|
|
1226
1282
|
import { IconMessage2 } from "@tabler/icons-react";
|
|
1227
|
-
import { jsx as
|
|
1283
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1228
1284
|
function EmptyState({ icon, message, scope = "page", className }) {
|
|
1229
1285
|
if (scope === "section") {
|
|
1230
|
-
return /* @__PURE__ */
|
|
1286
|
+
return /* @__PURE__ */ jsx20("p", { className: cn("text-caption text-text-muted", className), children: message });
|
|
1231
1287
|
}
|
|
1232
|
-
return /* @__PURE__ */
|
|
1233
|
-
/* @__PURE__ */
|
|
1234
|
-
/* @__PURE__ */
|
|
1288
|
+
return /* @__PURE__ */ jsxs14("div", { className: cn("flex flex-1 flex-col items-center justify-center gap-2", className), children: [
|
|
1289
|
+
/* @__PURE__ */ jsx20("span", { className: "text-text-secondary", children: icon ?? /* @__PURE__ */ jsx20(IconMessage2, { size: 16, stroke: 1.5 }) }),
|
|
1290
|
+
/* @__PURE__ */ jsx20("p", { className: "text-body-2 text-text-secondary text-center", children: message })
|
|
1235
1291
|
] });
|
|
1236
1292
|
}
|
|
1237
1293
|
|
|
1238
1294
|
// src/Field.tsx
|
|
1239
1295
|
import { cloneElement, isValidElement } from "react";
|
|
1240
1296
|
import { Field as BaseField2 } from "@base-ui/react/field";
|
|
1241
|
-
import { jsx as
|
|
1297
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
1242
1298
|
var LINE_STYLES = {
|
|
1243
1299
|
helper: "text-caption text-text-muted",
|
|
1244
1300
|
warning: "text-caption text-warning-default",
|
|
@@ -1248,26 +1304,26 @@ function Field({ label, required = false, helper, error, children }) {
|
|
|
1248
1304
|
const control = required && isValidElement(children) ? cloneElement(children, {
|
|
1249
1305
|
"aria-required": children.props["aria-required"] ?? true
|
|
1250
1306
|
}) : children;
|
|
1251
|
-
return /* @__PURE__ */
|
|
1252
|
-
/* @__PURE__ */
|
|
1307
|
+
return /* @__PURE__ */ jsxs15(BaseField2.Root, { invalid: !!error, className: "flex flex-col gap-2", children: [
|
|
1308
|
+
/* @__PURE__ */ jsxs15(BaseField2.Label, { className: cn("text-input-label text-text-primary", required && "flex items-center"), children: [
|
|
1253
1309
|
label,
|
|
1254
|
-
required && /* @__PURE__ */
|
|
1310
|
+
required && /* @__PURE__ */ jsx21("span", { "aria-hidden": "true", className: "text-error-default ml-0.5", children: "*" })
|
|
1255
1311
|
] }),
|
|
1256
|
-
/* @__PURE__ */
|
|
1312
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex flex-col gap-1.5", children: [
|
|
1257
1313
|
control,
|
|
1258
|
-
error != null ? /* @__PURE__ */
|
|
1314
|
+
error != null ? /* @__PURE__ */ jsx21(BaseField2.Error, { match: true, className: LINE_STYLES.error, children: error }) : helper != null ? /* @__PURE__ */ jsx21(BaseField2.Description, { className: LINE_STYLES.helper, children: helper }) : null
|
|
1259
1315
|
] })
|
|
1260
1316
|
] });
|
|
1261
1317
|
}
|
|
1262
1318
|
function FieldLine({ tone = "helper", children, className }) {
|
|
1263
|
-
return /* @__PURE__ */
|
|
1319
|
+
return /* @__PURE__ */ jsx21("p", { role: tone === "error" ? "alert" : "status", className: cn(LINE_STYLES[tone], className), children });
|
|
1264
1320
|
}
|
|
1265
1321
|
|
|
1266
1322
|
// src/Form.tsx
|
|
1267
1323
|
import { useLayoutEffect as useLayoutEffect2, useRef as useRef2 } from "react";
|
|
1268
1324
|
import { Fieldset } from "@base-ui/react/fieldset";
|
|
1269
1325
|
import { Form as BaseForm } from "@base-ui/react/form";
|
|
1270
|
-
import { jsx as
|
|
1326
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
1271
1327
|
var CONTROL = 'input:not([type="hidden"]), textarea, select, button, [role="checkbox"], [role="combobox"], [tabindex]:not([tabindex="-1"])';
|
|
1272
1328
|
var ONE_LINE = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1273
1329
|
function usable(element) {
|
|
@@ -1326,7 +1382,7 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1326
1382
|
const oneLine = ONE_LINE.has((target.getAttribute("type") ?? "").toLowerCase()) && target.getAttribute("role") !== "combobox";
|
|
1327
1383
|
if (enterSends && oneLine) form.current?.requestSubmit();
|
|
1328
1384
|
};
|
|
1329
|
-
return /* @__PURE__ */
|
|
1385
|
+
return /* @__PURE__ */ jsx22(
|
|
1330
1386
|
BaseForm,
|
|
1331
1387
|
{
|
|
1332
1388
|
ref: form,
|
|
@@ -1348,32 +1404,32 @@ function Form({ onSubmit, busy: ownBusy = false, enterSends = true, className, c
|
|
|
1348
1404
|
if (busyNow.current) return;
|
|
1349
1405
|
void onSubmit();
|
|
1350
1406
|
},
|
|
1351
|
-
children: /* @__PURE__ */
|
|
1407
|
+
children: /* @__PURE__ */ jsx22(Fieldset.Root, { disabled: busy, className: "contents", children: /* @__PURE__ */ jsx22(FormBusyContext.Provider, { value: busy, children }) })
|
|
1352
1408
|
}
|
|
1353
1409
|
);
|
|
1354
1410
|
}
|
|
1355
1411
|
|
|
1356
1412
|
// src/Skeleton.tsx
|
|
1357
|
-
import { jsx as
|
|
1413
|
+
import { jsx as jsx23, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
1358
1414
|
function SkeletonBar({ className, style }) {
|
|
1359
|
-
return /* @__PURE__ */
|
|
1415
|
+
return /* @__PURE__ */ jsx23("div", { className: cn("bg-bg-inset rounded-sm animate-pulse", className), style });
|
|
1360
1416
|
}
|
|
1361
1417
|
var ROW_BAR_WIDTHS = [150, 100, 170, 120, 90, 140, 110, 160];
|
|
1362
1418
|
function SkeletonRow({ barWidth = 130 }) {
|
|
1363
|
-
return /* @__PURE__ */
|
|
1364
|
-
/* @__PURE__ */
|
|
1365
|
-
/* @__PURE__ */
|
|
1419
|
+
return /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2 px-2 h-[32px] rounded-lg", children: [
|
|
1420
|
+
/* @__PURE__ */ jsx23(SkeletonBar, { className: "w-4 h-4 shrink-0" }),
|
|
1421
|
+
/* @__PURE__ */ jsx23(SkeletonBar, { className: "h-3.5", style: { width: barWidth } })
|
|
1366
1422
|
] });
|
|
1367
1423
|
}
|
|
1368
1424
|
function SkeletonList({ rows = 8, className }) {
|
|
1369
|
-
return /* @__PURE__ */
|
|
1425
|
+
return /* @__PURE__ */ jsx23("div", { className: cn("flex flex-col gap-0.5 animate-skeleton-in", className), "aria-hidden": true, children: Array.from({ length: rows }, (_, i) => /* @__PURE__ */ jsx23(SkeletonRow, { barWidth: ROW_BAR_WIDTHS[i % ROW_BAR_WIDTHS.length] }, i)) });
|
|
1370
1426
|
}
|
|
1371
1427
|
|
|
1372
1428
|
// src/CommandPalette.tsx
|
|
1373
|
-
import { Fragment as Fragment3, jsx as
|
|
1374
|
-
var PaletteContext =
|
|
1429
|
+
import { Fragment as Fragment3, jsx as jsx24, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
1430
|
+
var PaletteContext = createContext4(null);
|
|
1375
1431
|
function usePalette(part) {
|
|
1376
|
-
const palette =
|
|
1432
|
+
const palette = useContext4(PaletteContext);
|
|
1377
1433
|
if (!palette) throw new Error(`[@estiva-app/ui] ${part} must be inside a CommandPalette.`);
|
|
1378
1434
|
return palette;
|
|
1379
1435
|
}
|
|
@@ -1396,9 +1452,9 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1396
1452
|
return () => cancelAnimationFrame(frame);
|
|
1397
1453
|
});
|
|
1398
1454
|
const context = useMemo2(() => ({ where, modKey, popupRef }), [where, modKey]);
|
|
1399
|
-
return /* @__PURE__ */
|
|
1400
|
-
/* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1455
|
+
return /* @__PURE__ */ jsx24(Dialog.Root, { open, onOpenChange: (next) => onOpenChange(next), children: /* @__PURE__ */ jsxs17(Dialog.Portal, { children: [
|
|
1456
|
+
/* @__PURE__ */ jsx24(Dialog.Backdrop, { className: "fixed inset-0 z-40 bg-scrim" }),
|
|
1457
|
+
/* @__PURE__ */ jsx24(Dialog.Viewport, { className: "fixed inset-0 z-50 flex items-start justify-center pt-[16vh]", children: /* @__PURE__ */ jsx24(
|
|
1402
1458
|
Dialog.Popup,
|
|
1403
1459
|
{
|
|
1404
1460
|
ref: popupRef,
|
|
@@ -1408,13 +1464,13 @@ function CommandPalette({ open, onOpenChange, label, where, modKey = "Ctrl", chi
|
|
|
1408
1464
|
if (e.target === popupRef.current) firstControl(popupRef.current)?.focus();
|
|
1409
1465
|
},
|
|
1410
1466
|
className: "flex w-[658px] max-w-[calc(100vw-32px)] flex-col overflow-hidden rounded-lg border border-border-default bg-bg-elevated shadow-lg outline-none",
|
|
1411
|
-
children: /* @__PURE__ */
|
|
1467
|
+
children: /* @__PURE__ */ jsx24(PaletteContext.Provider, { value: context, children })
|
|
1412
1468
|
}
|
|
1413
1469
|
) })
|
|
1414
1470
|
] }) });
|
|
1415
1471
|
}
|
|
1416
1472
|
function LevelChip({ chip, onBack }) {
|
|
1417
|
-
return /* @__PURE__ */
|
|
1473
|
+
return /* @__PURE__ */ jsx24(InputChip, { label: chip.label, leading: chip.leading, onRemove: onBack, removeLabel: `Leave ${chip.label}`, truncate: true, className: "max-w-[272px] shrink-0" });
|
|
1418
1474
|
}
|
|
1419
1475
|
function useBack(chip, popupRef) {
|
|
1420
1476
|
return () => {
|
|
@@ -1425,10 +1481,10 @@ function useBack(chip, popupRef) {
|
|
|
1425
1481
|
}
|
|
1426
1482
|
function Footer({ keys }) {
|
|
1427
1483
|
const { where } = usePalette("The footer");
|
|
1428
|
-
return /* @__PURE__ */
|
|
1429
|
-
/* @__PURE__ */
|
|
1430
|
-
keys.map(([key, word]) => /* @__PURE__ */
|
|
1431
|
-
/* @__PURE__ */
|
|
1484
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex h-9 shrink-0 items-center gap-4 border-t border-border-subtle px-5 text-caption text-text-secondary signal:font-mono signal:text-small signal:text-text-muted", children: [
|
|
1485
|
+
/* @__PURE__ */ jsx24("span", { className: "min-w-0 flex-1 truncate", children: where }),
|
|
1486
|
+
keys.map(([key, word]) => /* @__PURE__ */ jsxs17("span", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
1487
|
+
/* @__PURE__ */ jsx24(Kbd, { children: key }),
|
|
1432
1488
|
" ",
|
|
1433
1489
|
word
|
|
1434
1490
|
] }, key))
|
|
@@ -1505,7 +1561,7 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1505
1561
|
...chip && query === "" ? [["Backspace", "back"]] : [],
|
|
1506
1562
|
["Esc", "close"]
|
|
1507
1563
|
];
|
|
1508
|
-
return /* @__PURE__ */
|
|
1564
|
+
return /* @__PURE__ */ jsxs17(
|
|
1509
1565
|
Autocomplete.Root,
|
|
1510
1566
|
{
|
|
1511
1567
|
items,
|
|
@@ -1528,10 +1584,10 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1528
1584
|
setLitId(id);
|
|
1529
1585
|
},
|
|
1530
1586
|
children: [
|
|
1531
|
-
/* @__PURE__ */
|
|
1532
|
-
/* @__PURE__ */
|
|
1533
|
-
chip && /* @__PURE__ */
|
|
1534
|
-
/* @__PURE__ */
|
|
1587
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1588
|
+
/* @__PURE__ */ jsx24(IconSearch, { size: 16, stroke: 1.5, className: "shrink-0 text-text-secondary" }),
|
|
1589
|
+
chip && /* @__PURE__ */ jsx24(LevelChip, { chip, onBack: back }),
|
|
1590
|
+
/* @__PURE__ */ jsx24(
|
|
1535
1591
|
Autocomplete.Input,
|
|
1536
1592
|
{
|
|
1537
1593
|
ref: inputRef,
|
|
@@ -1543,43 +1599,43 @@ function CommandPaletteSearch({ query, onQueryChange, placeholder, groups, chip,
|
|
|
1543
1599
|
}
|
|
1544
1600
|
)
|
|
1545
1601
|
] }),
|
|
1546
|
-
/* @__PURE__ */
|
|
1547
|
-
children != null && /* @__PURE__ */
|
|
1548
|
-
/* @__PURE__ */
|
|
1549
|
-
/* @__PURE__ */
|
|
1550
|
-
/* @__PURE__ */
|
|
1602
|
+
/* @__PURE__ */ jsxs17(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col p-2", children: [
|
|
1603
|
+
children != null && /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children }),
|
|
1604
|
+
/* @__PURE__ */ jsx24(Autocomplete.List, { className: "flex flex-col", children: (group) => /* @__PURE__ */ jsxs17(Autocomplete.Group, { items: group.items, className: "flex flex-col", children: [
|
|
1605
|
+
/* @__PURE__ */ jsx24(Autocomplete.GroupLabel, { className: "flex h-7 shrink-0 items-center px-3", children: /* @__PURE__ */ jsx24(SectionLabel, { tone: "secondary", children: group.value }) }),
|
|
1606
|
+
/* @__PURE__ */ jsx24(Autocomplete.Collection, { children: (row) => (
|
|
1551
1607
|
/* The menu row, as the list's own option — the way Select
|
|
1552
1608
|
puts it on `Select.Item`. One row, two parts. */
|
|
1553
|
-
/* @__PURE__ */
|
|
1609
|
+
/* @__PURE__ */ jsx24(Autocomplete.Item, { value: row, onClick: () => row.onSelect(), className: menuItemClassName({ size: "tall" }), children: /* @__PURE__ */ jsx24(
|
|
1554
1610
|
MenuItemBody,
|
|
1555
1611
|
{
|
|
1556
1612
|
size: "tall",
|
|
1557
1613
|
label: row.label,
|
|
1558
1614
|
description: row.description,
|
|
1559
|
-
leading: /* @__PURE__ */
|
|
1615
|
+
leading: /* @__PURE__ */ jsx24(RowLeading, { row }),
|
|
1560
1616
|
submenu: !!row.onGoIn,
|
|
1561
|
-
hint: row.onGoIn ? /* @__PURE__ */
|
|
1617
|
+
hint: row.onGoIn ? /* @__PURE__ */ jsx24(Kbd, { children: "Tab" }) : /* @__PURE__ */ jsx24(EnterHint, {})
|
|
1562
1618
|
}
|
|
1563
1619
|
) }, row.id)
|
|
1564
1620
|
) })
|
|
1565
1621
|
] }, group.value) }),
|
|
1566
|
-
/* @__PURE__ */
|
|
1567
|
-
/* @__PURE__ */
|
|
1568
|
-
/* @__PURE__ */
|
|
1622
|
+
/* @__PURE__ */ jsx24(Autocomplete.Status, { className: "flex items-center gap-2 px-3 [&:not(:empty)]:h-8", children: pending && /* @__PURE__ */ jsxs17(Fragment3, { children: [
|
|
1623
|
+
/* @__PURE__ */ jsx24(IconLoader22, { size: 12, stroke: 1.5, className: "shrink-0 animate-spin text-text-muted" }),
|
|
1624
|
+
/* @__PURE__ */ jsx24("span", { className: "text-caption text-text-muted", children: pending })
|
|
1569
1625
|
] }) }),
|
|
1570
|
-
notes.map((note) => /* @__PURE__ */
|
|
1571
|
-
/* @__PURE__ */
|
|
1626
|
+
notes.map((note) => /* @__PURE__ */ jsx24("div", { className: "flex min-h-8 items-center px-3", children: /* @__PURE__ */ jsx24(FieldLine, { children: note }) }, note)),
|
|
1627
|
+
/* @__PURE__ */ jsx24(Autocomplete.Empty, { className: "flex items-center px-3 [&:not(:empty)]:min-h-10", children: empty && /* @__PURE__ */ jsx24(EmptyState, { scope: "section", message: empty }) })
|
|
1572
1628
|
] }),
|
|
1573
|
-
/* @__PURE__ */
|
|
1629
|
+
/* @__PURE__ */ jsx24(Footer, { keys })
|
|
1574
1630
|
]
|
|
1575
1631
|
}
|
|
1576
1632
|
);
|
|
1577
1633
|
}
|
|
1578
1634
|
function RowLeading({ row }) {
|
|
1579
1635
|
if (row.icon != null) {
|
|
1580
|
-
return /* @__PURE__ */
|
|
1636
|
+
return /* @__PURE__ */ jsx24("span", { className: "flex size-8 items-center justify-center rounded-sm bg-bg-inset text-text-secondary", children: row.icon });
|
|
1581
1637
|
}
|
|
1582
|
-
return /* @__PURE__ */
|
|
1638
|
+
return /* @__PURE__ */ jsx24("span", { className: "flex size-8 items-center justify-center", children: row.leading });
|
|
1583
1639
|
}
|
|
1584
1640
|
var TEXT_TYPES = /* @__PURE__ */ new Set(["", "text", "search", "email", "url", "tel", "password", "number"]);
|
|
1585
1641
|
function isTextField(el) {
|
|
@@ -1621,56 +1677,56 @@ function CommandPaletteForm({ chip, icon, submitLabel, onSubmit, submitWaits, wo
|
|
|
1621
1677
|
...backNamed ? [["Backspace", "back"]] : [],
|
|
1622
1678
|
["Esc", "close"]
|
|
1623
1679
|
];
|
|
1624
|
-
return /* @__PURE__ */
|
|
1625
|
-
/* @__PURE__ */
|
|
1626
|
-
icon != null && /* @__PURE__ */
|
|
1627
|
-
/* @__PURE__ */
|
|
1680
|
+
return /* @__PURE__ */ jsxs17("div", { ref: frameRef, tabIndex: -1, onKeyDown, onFocus: measure, onBlur: measure, onInput: measure, className: "flex min-h-0 flex-col outline-none", children: [
|
|
1681
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex h-12 shrink-0 items-center gap-3 border-b border-border-subtle px-5", children: [
|
|
1682
|
+
icon != null && /* @__PURE__ */ jsx24("span", { className: "flex shrink-0 items-center text-text-secondary", children: icon }),
|
|
1683
|
+
/* @__PURE__ */ jsx24(LevelChip, { chip, onBack: back })
|
|
1628
1684
|
] }),
|
|
1629
|
-
/* @__PURE__ */
|
|
1630
|
-
/* @__PURE__ */
|
|
1631
|
-
/* @__PURE__ */
|
|
1632
|
-
/* @__PURE__ */
|
|
1633
|
-
/* @__PURE__ */
|
|
1685
|
+
/* @__PURE__ */ jsxs17(Form, { "data-command-palette-fields": "", busy, enterSends: false, onSubmit: submit, className: "flex min-h-0 flex-col", children: [
|
|
1686
|
+
/* @__PURE__ */ jsx24(ScrollArea, { viewportClassName: "max-h-[420px]", contentClassName: "flex flex-col px-5 py-4", children: /* @__PURE__ */ jsx24("div", { className: "flex flex-col gap-4", children }) }),
|
|
1687
|
+
/* @__PURE__ */ jsxs17("div", { className: "flex shrink-0 items-center gap-3 px-5 pb-4", children: [
|
|
1688
|
+
/* @__PURE__ */ jsx24("div", { className: "min-w-0 flex-1", children: working ? /* @__PURE__ */ jsx24(FieldLine, { children: working.line }) : error ? /* @__PURE__ */ jsx24(FieldLine, { tone: "error", children: error }) : null }),
|
|
1689
|
+
/* @__PURE__ */ jsx24(
|
|
1634
1690
|
Button,
|
|
1635
1691
|
{
|
|
1636
1692
|
type: "submit",
|
|
1637
1693
|
variant: "primary",
|
|
1638
1694
|
disabled: busy,
|
|
1639
1695
|
disabledReason: busy ? void 0 : submitWaits,
|
|
1640
|
-
leadingIcon: busy ? /* @__PURE__ */
|
|
1696
|
+
leadingIcon: busy ? /* @__PURE__ */ jsx24(IconLoader22, { size: 16, stroke: 1.5, className: "animate-spin" }) : void 0,
|
|
1641
1697
|
children: working ? working.button : submitLabel
|
|
1642
1698
|
}
|
|
1643
1699
|
)
|
|
1644
1700
|
] })
|
|
1645
1701
|
] }),
|
|
1646
|
-
/* @__PURE__ */
|
|
1702
|
+
/* @__PURE__ */ jsx24(Footer, { keys })
|
|
1647
1703
|
] });
|
|
1648
1704
|
}
|
|
1649
1705
|
var BAR_WIDTHS = ["w-4/5", "w-3/5", "w-2/3"];
|
|
1650
1706
|
function CommandPaletteWorking({ children, bars = 2 }) {
|
|
1651
|
-
return /* @__PURE__ */
|
|
1652
|
-
/* @__PURE__ */
|
|
1653
|
-
/* @__PURE__ */
|
|
1707
|
+
return /* @__PURE__ */ jsxs17("div", { role: "status", className: "flex flex-col gap-2", children: [
|
|
1708
|
+
/* @__PURE__ */ jsxs17("span", { className: "flex items-center gap-2 text-caption text-text-secondary", children: [
|
|
1709
|
+
/* @__PURE__ */ jsx24(IconLoader22, { size: 14, stroke: 1.5, className: "shrink-0 animate-spin" }),
|
|
1654
1710
|
children
|
|
1655
1711
|
] }),
|
|
1656
|
-
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */
|
|
1712
|
+
BAR_WIDTHS.slice(0, bars).map((width) => /* @__PURE__ */ jsx24(SkeletonBar, { className: cn("h-3", width) }, width))
|
|
1657
1713
|
] });
|
|
1658
1714
|
}
|
|
1659
1715
|
function CommandPaletteAnswer({ children, note }) {
|
|
1660
1716
|
const paragraphs = children.split(/\n\s*\n/).filter((p) => p.trim() !== "");
|
|
1661
|
-
return /* @__PURE__ */
|
|
1662
|
-
paragraphs.map((paragraph, i) => /* @__PURE__ */
|
|
1663
|
-
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */
|
|
1717
|
+
return /* @__PURE__ */ jsxs17("div", { className: "flex flex-col gap-2", children: [
|
|
1718
|
+
paragraphs.map((paragraph, i) => /* @__PURE__ */ jsx24("p", { className: "whitespace-pre-wrap text-body-2 text-text-primary", children: paragraph.split(/\s*(\[\d+\])/).map(
|
|
1719
|
+
(part, j) => /^\[\d+\]$/.test(part) ? /* @__PURE__ */ jsx24("sup", { className: "ml-0.5 font-mono text-small text-accent-primary", children: part.slice(1, -1) }, j) : part
|
|
1664
1720
|
) }, i)),
|
|
1665
|
-
note && /* @__PURE__ */
|
|
1721
|
+
note && /* @__PURE__ */ jsx24(FieldLine, { children: note })
|
|
1666
1722
|
] });
|
|
1667
1723
|
}
|
|
1668
1724
|
function CommandPaletteQuote({ children }) {
|
|
1669
|
-
return /* @__PURE__ */
|
|
1725
|
+
return /* @__PURE__ */ jsx24("p", { className: "whitespace-pre-wrap border-l-2 border-border-default pl-3 text-body-2 text-text-primary", children });
|
|
1670
1726
|
}
|
|
1671
1727
|
|
|
1672
1728
|
// src/InlineChip.tsx
|
|
1673
|
-
import { Fragment as Fragment4, jsx as
|
|
1729
|
+
import { Fragment as Fragment4, jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1674
1730
|
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";
|
|
1675
1731
|
var INLINE_CHIP_TONE_CLASSES = {
|
|
1676
1732
|
/** A thing or a place — anything that is not a person. */
|
|
@@ -1692,49 +1748,20 @@ function inlineChipClassName(tone, className) {
|
|
|
1692
1748
|
return cn(INLINE_CHIP_CLASSES, INLINE_CHIP_TONE_CLASSES[tone], className);
|
|
1693
1749
|
}
|
|
1694
1750
|
function InlineChip({ tone = "neutral", icon, href, className, children, ...props }) {
|
|
1695
|
-
const body = /* @__PURE__ */
|
|
1696
|
-
icon && /* @__PURE__ */
|
|
1751
|
+
const body = /* @__PURE__ */ jsxs18(Fragment4, { children: [
|
|
1752
|
+
icon && /* @__PURE__ */ jsx25("span", { className: "flex size-4 shrink-0 items-center justify-center text-text-secondary", children: icon }),
|
|
1697
1753
|
children
|
|
1698
1754
|
] });
|
|
1699
1755
|
const classes = inlineChipClassName(tone, className);
|
|
1700
1756
|
if (href === void 0) {
|
|
1701
|
-
return /* @__PURE__ */
|
|
1757
|
+
return /* @__PURE__ */ jsx25("span", { className: classes, ...props, children: body });
|
|
1702
1758
|
}
|
|
1703
|
-
return /* @__PURE__ */
|
|
1759
|
+
return /* @__PURE__ */ jsx25("a", { href, className: classes, ...props, children: body });
|
|
1704
1760
|
}
|
|
1705
1761
|
|
|
1706
1762
|
// src/IdentityMenu.tsx
|
|
1707
1763
|
import { useCallback, useRef as useRef4 } from "react";
|
|
1708
1764
|
|
|
1709
|
-
// src/Divider.tsx
|
|
1710
|
-
import { Separator } from "@base-ui/react/separator";
|
|
1711
|
-
import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
1712
|
-
function Divider({ orientation = "horizontal", label, tone = "default", className }) {
|
|
1713
|
-
if (label && orientation === "horizontal") {
|
|
1714
|
-
const line = tone === "warning" ? "bg-warning-muted" : "bg-border-subtle";
|
|
1715
|
-
return /* @__PURE__ */ jsxs18(
|
|
1716
|
-
Separator,
|
|
1717
|
-
{
|
|
1718
|
-
orientation: "horizontal",
|
|
1719
|
-
"aria-label": label,
|
|
1720
|
-
className: cn("flex shrink-0 items-center gap-2 mx-3", className),
|
|
1721
|
-
children: [
|
|
1722
|
-
/* @__PURE__ */ jsx25("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) }),
|
|
1723
|
-
/* @__PURE__ */ jsx25("span", { className: cn("shrink-0 text-caption", tone === "warning" ? "text-warning-default" : "text-text-muted"), children: label }),
|
|
1724
|
-
/* @__PURE__ */ jsx25("span", { "aria-hidden": "true", className: cn("h-px flex-1", line) })
|
|
1725
|
-
]
|
|
1726
|
-
}
|
|
1727
|
-
);
|
|
1728
|
-
}
|
|
1729
|
-
return /* @__PURE__ */ jsx25(
|
|
1730
|
-
Separator,
|
|
1731
|
-
{
|
|
1732
|
-
orientation,
|
|
1733
|
-
className: cn("shrink-0 bg-border-subtle", orientation === "horizontal" ? "h-px mx-3" : "w-px self-stretch", className)
|
|
1734
|
-
}
|
|
1735
|
-
);
|
|
1736
|
-
}
|
|
1737
|
-
|
|
1738
1765
|
// src/Person.tsx
|
|
1739
1766
|
import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
1740
1767
|
function Person({ name, picture, fallback = "\u2014", size = 20, className }) {
|
|
@@ -1807,7 +1834,7 @@ function IdentityRows({ me, signedIn, relayUrl, idBase, onCopyKey, onSignOut, on
|
|
|
1807
1834
|
const appRows = typeof children === "function" ? children(onClose) : children;
|
|
1808
1835
|
return /* @__PURE__ */ jsxs21(Fragment5, { children: [
|
|
1809
1836
|
/* @__PURE__ */ jsxs21(MenuSection, { label: signedIn ? "Signed in as" : "Acting as", children: [
|
|
1810
|
-
/* @__PURE__ */ jsx28(MenuRow, { children: /* @__PURE__ */ jsx28(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28
|
|
1837
|
+
/* @__PURE__ */ jsx28(MenuRow, { children: /* @__PURE__ */ jsx28("div", { className: "flex min-w-0 text-body-2-strong", children: /* @__PURE__ */ jsx28(Person, { name: me.name, picture: me.picture, fallback: "Anonymous", size: 28 }) }) }),
|
|
1811
1838
|
/* @__PURE__ */ jsx28(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." }),
|
|
1812
1839
|
me.email && /* @__PURE__ */ jsxs21(Note, { children: [
|
|
1813
1840
|
me.email,
|
|
@@ -2098,14 +2125,9 @@ function DialogShell({ title, onClose, headerContent, footer, children, bodyClas
|
|
|
2098
2125
|
}
|
|
2099
2126
|
)
|
|
2100
2127
|
] }),
|
|
2101
|
-
bodyMaxHeight ?
|
|
2102
|
-
ScrollArea
|
|
2103
|
-
{
|
|
2104
|
-
className: cn(footer != null && "border-b border-border-subtle"),
|
|
2105
|
-
viewportClassName: bodyMaxHeight,
|
|
2106
|
-
contentClassName: cn("pl-5 pr-4 py-4", bodyClassName),
|
|
2107
|
-
children
|
|
2108
|
-
}
|
|
2128
|
+
bodyMaxHeight ? (
|
|
2129
|
+
// The line above the footer on a box of the shell's own, not pushed into ScrollArea (UIG-9).
|
|
2130
|
+
/* @__PURE__ */ jsx33("div", { className: cn(footer != null && "border-b border-border-subtle"), children: /* @__PURE__ */ jsx33(ScrollArea, { viewportClassName: bodyMaxHeight, contentClassName: cn("pl-5 pr-4 py-4", bodyClassName), children }) })
|
|
2109
2131
|
) : /* @__PURE__ */ jsx33("div", { className: cn("pl-5 pr-4 py-4", footer != null && "border-b border-border-subtle", bodyClassName), children }),
|
|
2110
2132
|
footer != null && /* @__PURE__ */ jsx33("div", { className: "h-12 flex items-center justify-end gap-2 pl-5 pr-4 shrink-0", children: footer })
|
|
2111
2133
|
]
|
|
@@ -2135,12 +2157,11 @@ function ConfirmDialog({ title, children, confirmLabel, destructive = false, onC
|
|
|
2135
2157
|
alert: true,
|
|
2136
2158
|
title,
|
|
2137
2159
|
onClose,
|
|
2138
|
-
bodyClassName: "flex flex-col gap-3 text-body-2 text-text-primary",
|
|
2139
2160
|
footer: /* @__PURE__ */ jsxs24(Fragment6, { children: [
|
|
2140
2161
|
/* @__PURE__ */ jsx34(Button, { variant: "muted", onClick: onClose, disabled: busy, children: "Cancel" }),
|
|
2141
2162
|
/* @__PURE__ */ jsx34(Button, { variant: destructive ? "destructive" : "primary", onClick: () => void confirm(), disabled: busy, children: confirmLabel })
|
|
2142
2163
|
] }),
|
|
2143
|
-
children
|
|
2164
|
+
children: /* @__PURE__ */ jsx34("div", { className: "flex flex-col gap-3 text-body-2 text-text-primary", children })
|
|
2144
2165
|
}
|
|
2145
2166
|
);
|
|
2146
2167
|
}
|
|
@@ -2319,8 +2340,11 @@ function Breadcrumb({ items, className }) {
|
|
|
2319
2340
|
const crumb = item.href ? (
|
|
2320
2341
|
// `plain` adds no look of its own: a crumb keeps the trail's size and
|
|
2321
2342
|
// tone, and brightens on hover. The package's own Link, so a trail
|
|
2322
|
-
// follows whatever a link learns to do (UIG-5).
|
|
2323
|
-
|
|
2343
|
+
// follows whatever a link learns to do (UIG-5). The size and tone are
|
|
2344
|
+
// on a box around it, which the link takes them from, rather than
|
|
2345
|
+
// pushed into it (UIG-9); the link is still the one element that
|
|
2346
|
+
// truncates and is measured.
|
|
2347
|
+
/* @__PURE__ */ jsx37("span", { className: cn("flex min-w-0", item.mono && "shrink-0 font-mono text-caption", tone, "hover:text-text-primary"), children: /* @__PURE__ */ jsx37(Link, { ref: setLabelRef, variant: "plain", truncate: true, href: item.href, onClick: item.onClick, children: item.label }) })
|
|
2324
2348
|
) : /* @__PURE__ */ jsx37("span", { ref: setLabelRef, className: text, "aria-current": last ? "page" : void 0, children: item.label });
|
|
2325
2349
|
return /* @__PURE__ */ jsxs25(Fragment7, { children: [
|
|
2326
2350
|
index > 0 && /* @__PURE__ */ jsx37("span", { "aria-hidden": "true", className: "shrink-0 text-text-muted", children: "/" }),
|
|
@@ -2403,8 +2427,8 @@ function Popover({ trigger, anchor, align = "left", side = "bottom", open, onOpe
|
|
|
2403
2427
|
ScrollArea,
|
|
2404
2428
|
{
|
|
2405
2429
|
viewportClassName: maxHeight ?? "max-h-[var(--available-height)]",
|
|
2406
|
-
contentClassName: cn("flex flex-col p-2
|
|
2407
|
-
children
|
|
2430
|
+
contentClassName: cn("flex flex-col p-2", contentClassName),
|
|
2431
|
+
children: /* @__PURE__ */ jsx39(DividerInPanel.Provider, { value: true, children })
|
|
2408
2432
|
}
|
|
2409
2433
|
)
|
|
2410
2434
|
}
|
|
@@ -2476,8 +2500,8 @@ function ReactionPicker({ options, onSelect, "aria-label": ariaLabel = "Reaction
|
|
|
2476
2500
|
"aria-label": option.label,
|
|
2477
2501
|
tooltip: option.label,
|
|
2478
2502
|
onClick: () => onSelect(option.emoji),
|
|
2479
|
-
className: "size-7
|
|
2480
|
-
children: /* @__PURE__ */ jsx41("span", { "aria-hidden": "true", children: option.emoji })
|
|
2503
|
+
className: "size-7",
|
|
2504
|
+
children: /* @__PURE__ */ jsx41("span", { "aria-hidden": "true", className: "text-h3 leading-none", children: option.emoji })
|
|
2481
2505
|
},
|
|
2482
2506
|
option.emoji
|
|
2483
2507
|
)
|
|
@@ -2515,7 +2539,7 @@ function PreviewCard({ content, children, side = "right", delay = OPEN_DELAY2, c
|
|
|
2515
2539
|
{
|
|
2516
2540
|
className: cn("w-[360px] p-3 outline-none", className),
|
|
2517
2541
|
render: /* @__PURE__ */ jsx42(MenuPanel, {}),
|
|
2518
|
-
children: /* @__PURE__ */ jsx42(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3
|
|
2542
|
+
children: /* @__PURE__ */ jsx42(ScrollArea, { viewportClassName: "max-h-[calc(min(300px,var(--available-height))_-_1.5rem)]", contentClassName: "flex flex-col gap-3", children: content })
|
|
2519
2543
|
}
|
|
2520
2544
|
)
|
|
2521
2545
|
}
|
|
@@ -2807,7 +2831,7 @@ function Tabs({ tabs, active, onChange, size = "default", className, ...aria })
|
|
|
2807
2831
|
}
|
|
2808
2832
|
|
|
2809
2833
|
// src/Toast.tsx
|
|
2810
|
-
import { createContext as
|
|
2834
|
+
import { createContext as createContext5, useContext as useContext5, useMemo as useMemo4 } from "react";
|
|
2811
2835
|
import { Toast as BaseToast } from "@base-ui/react/toast";
|
|
2812
2836
|
import { IconAlertCircle as IconAlertCircle2, IconCircleCheck, IconCircleX } from "@tabler/icons-react";
|
|
2813
2837
|
import { jsx as jsx52, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
@@ -2858,7 +2882,7 @@ function Toast({ label, type = "neutral", leadingIcon = true, actionLabel, onAct
|
|
|
2858
2882
|
hasAction && /* @__PURE__ */ jsx52(Button, { variant: "outlined", size: "small", onClick: onAction, children: actionLabel })
|
|
2859
2883
|
] });
|
|
2860
2884
|
}
|
|
2861
|
-
var ToastContext =
|
|
2885
|
+
var ToastContext = createContext5(null);
|
|
2862
2886
|
var VISIBLE_TOASTS = 3;
|
|
2863
2887
|
function ToastProvider({ children }) {
|
|
2864
2888
|
const manager = useMemo4(() => BaseToast.createToastManager(), []);
|
|
@@ -2914,7 +2938,7 @@ function ToastList() {
|
|
|
2914
2938
|
});
|
|
2915
2939
|
}
|
|
2916
2940
|
function useToast() {
|
|
2917
|
-
const ctx =
|
|
2941
|
+
const ctx = useContext5(ToastContext);
|
|
2918
2942
|
if (!ctx) throw new Error("useToast must be used within ToastProvider");
|
|
2919
2943
|
return ctx;
|
|
2920
2944
|
}
|