@lessly/ui 2.3.1 → 4.0.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/{chunk-CEXND5YW.js → chunk-DYHP7W3X.js} +175 -28
- package/dist/index.d.ts +339 -60
- package/dist/index.js +882 -689
- package/dist/router.d.ts +27 -17
- package/dist/router.js +69 -94
- package/dist/styles-federated.css +45 -9
- package/dist/styles.css +45 -9
- package/package.json +17 -12
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Button,
|
|
3
|
+
EntityRow,
|
|
3
4
|
NavRow,
|
|
5
|
+
RailToggle,
|
|
4
6
|
Sheet,
|
|
5
7
|
SheetClose,
|
|
6
8
|
SheetContent,
|
|
@@ -19,7 +21,7 @@ import {
|
|
|
19
21
|
cn,
|
|
20
22
|
useIsMobile,
|
|
21
23
|
useSidebar
|
|
22
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-DYHP7W3X.js";
|
|
23
25
|
|
|
24
26
|
// src/components/auto-height.tsx
|
|
25
27
|
import * as React from "react";
|
|
@@ -82,9 +84,10 @@ var Card = React2.forwardRef(
|
|
|
82
84
|
"div",
|
|
83
85
|
{
|
|
84
86
|
ref,
|
|
87
|
+
"data-slot": "card",
|
|
85
88
|
title: tooltip,
|
|
86
89
|
className: cn(
|
|
87
|
-
"rounded-xl border border-border-subtle bg-bg-
|
|
90
|
+
"rounded-xl border border-border-subtle bg-bg-overlay text-text-primary shadow-sm",
|
|
88
91
|
variant === "list" && "overflow-hidden",
|
|
89
92
|
variant === "nested" && "rounded-md bg-bg-secondary p-3 shadow-none",
|
|
90
93
|
className
|
|
@@ -170,7 +173,7 @@ var DialogContent = React3.forwardRef(({ className, children, showClose = true,
|
|
|
170
173
|
...props,
|
|
171
174
|
children: [
|
|
172
175
|
children,
|
|
173
|
-
showClose && /* @__PURE__ */ jsxs2(DialogPrimitive.Close, { className: "absolute right-4 top-4 rounded-sm text-text-tertiary opacity-70 transition-opacity duration-fast hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-border-focus disabled:pointer-events-none", children: [
|
|
176
|
+
showClose && /* @__PURE__ */ jsxs2(DialogPrimitive.Close, { className: "absolute right-4 top-4 cursor-pointer rounded-sm text-text-tertiary opacity-70 transition-opacity duration-fast hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-border-focus disabled:pointer-events-none", children: [
|
|
174
177
|
/* @__PURE__ */ jsx3(X, { className: "h-4 w-4" }),
|
|
175
178
|
/* @__PURE__ */ jsx3("span", { className: "sr-only", children: "Close" })
|
|
176
179
|
] })
|
|
@@ -231,10 +234,17 @@ var DropdownMenuTrigger = React4.forwardRef(({ variant = "bare", chevron = true,
|
|
|
231
234
|
...props,
|
|
232
235
|
...variant === "quiet" ? {
|
|
233
236
|
className: cn(
|
|
234
|
-
"inline-flex min-h-9 items-center gap-1.5 rounded-md px-2 py-1.5 text-sm hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
237
|
+
"inline-flex min-h-9 cursor-pointer items-center gap-1.5 rounded-md px-2 py-1.5 text-sm hover:bg-bg-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
235
238
|
props.className
|
|
236
239
|
)
|
|
237
|
-
} :
|
|
240
|
+
} : (
|
|
241
|
+
// A trigger the call site styles is a control the call site drew, so the cursor its own
|
|
242
|
+
// guideline asks for comes with the class list rather than from four call sites remembering
|
|
243
|
+
// it (Guidelines/Controls/What the cursor says). A trigger given no className still renders
|
|
244
|
+
// with no `class` attribute at all, which is what `bare` promises and what the test below
|
|
245
|
+
// pins — and whatever it wraps through `asChild` carries its own.
|
|
246
|
+
props.className !== void 0 ? { className: cn("cursor-pointer", props.className) } : null
|
|
247
|
+
),
|
|
238
248
|
children: variant === "quiet" ? /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
239
249
|
children,
|
|
240
250
|
chevron && /* @__PURE__ */ jsx4(ChevronDown, { className: "size-3.5 shrink-0 text-text-tertiary", "aria-hidden": true })
|
|
@@ -293,9 +303,10 @@ var DropdownMenuItem = React4.forwardRef(({ className, inset, variant = "default
|
|
|
293
303
|
className: cn(
|
|
294
304
|
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors duration-fast focus:bg-bg-secondary focus:text-text-primary focus:ring-1 focus:ring-inset data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
295
305
|
inset && "pl-8",
|
|
296
|
-
// Destructive reddens — wash and label — under the pointer or the keyboard, and
|
|
297
|
-
// frame a destructive Button rests on, because a row repeated
|
|
298
|
-
// feel dangerous (Guidelines/Controls/Destructive actions).
|
|
306
|
+
// Destructive reddens — wash and label — under the pointer or the keyboard, and carries nothing
|
|
307
|
+
// at rest: it drops the frame and the wash a destructive Button rests on, because a row repeated
|
|
308
|
+
// down a menu makes the whole menu feel dangerous (Guidelines/Controls/Destructive actions).
|
|
309
|
+
// The opaque plate is a dialog's confirm alone.
|
|
299
310
|
variant === "destructive" ? "focus:bg-bg-danger-subtle focus:text-text-danger focus:ring-border-danger" : "focus:ring-border-selected",
|
|
300
311
|
className
|
|
301
312
|
),
|
|
@@ -479,7 +490,7 @@ import { cva as cva2 } from "class-variance-authority";
|
|
|
479
490
|
import { Check as Check2 } from "lucide-react";
|
|
480
491
|
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
481
492
|
var optionCardVariants = cva2(
|
|
482
|
-
"flex w-full items-center gap-3 rounded-lg border border-border-default p-3 text-left transition-colors duration-fast hover:bg-bg
|
|
493
|
+
"flex w-full cursor-pointer items-center gap-3 rounded-lg border border-border-default p-3 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
483
494
|
{
|
|
484
495
|
variants: {
|
|
485
496
|
selected: {
|
|
@@ -523,7 +534,7 @@ var Medallion = React9.forwardRef(
|
|
|
523
534
|
"aria-hidden": true,
|
|
524
535
|
className: cn(
|
|
525
536
|
"inline-flex size-12 shrink-0 items-center justify-center rounded-full border border-border-subtle",
|
|
526
|
-
filled ? "border-transparent bg-text-primary text-text-inverse" : "bg-bg-
|
|
537
|
+
filled ? "border-transparent bg-text-primary text-text-inverse" : "bg-bg-overlay text-text-secondary",
|
|
527
538
|
className
|
|
528
539
|
),
|
|
529
540
|
...props,
|
|
@@ -535,11 +546,12 @@ Medallion.displayName = "Medallion";
|
|
|
535
546
|
|
|
536
547
|
// src/components/page-header.tsx
|
|
537
548
|
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
538
|
-
function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, id }) {
|
|
539
|
-
|
|
549
|
+
function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, size = "page", id }) {
|
|
550
|
+
const compact = size === "compact";
|
|
551
|
+
if (Icon && !subtitle && !media && !compact && process.env.NODE_ENV !== "production") {
|
|
540
552
|
console.warn("PageHeader: `icon` needs a `subtitle` to render the medallion; medallion dropped.");
|
|
541
553
|
}
|
|
542
|
-
const leading = media ?? (Icon && subtitle ? /* @__PURE__ */ jsx10(Medallion, { icon: Icon, "data-slot": "page-header-medallion" }) : null);
|
|
554
|
+
const leading = media ?? (Icon && subtitle && !compact ? /* @__PURE__ */ jsx10(Medallion, { icon: Icon, "data-slot": "page-header-medallion" }) : null);
|
|
543
555
|
const heading = /* @__PURE__ */ jsx10("h2", { id, className: "text-lg font-semibold text-text-primary", children: title });
|
|
544
556
|
return /* @__PURE__ */ jsxs6("div", { className: "flex min-h-9 items-center gap-3", children: [
|
|
545
557
|
leading,
|
|
@@ -548,7 +560,7 @@ function PageHeader({ title, subtitle, icon: Icon, media, badge, actions, id })
|
|
|
548
560
|
heading,
|
|
549
561
|
badge
|
|
550
562
|
] }),
|
|
551
|
-
subtitle && /* @__PURE__ */ jsx10("p", { className: "text-sm text-text-secondary", children: subtitle })
|
|
563
|
+
subtitle && !compact && /* @__PURE__ */ jsx10("p", { className: "text-sm text-text-secondary", children: subtitle })
|
|
552
564
|
] }),
|
|
553
565
|
actions && /* @__PURE__ */ jsx10("div", { className: "ml-auto shrink-0", children: actions })
|
|
554
566
|
] });
|
|
@@ -653,8 +665,9 @@ function Select({
|
|
|
653
665
|
|
|
654
666
|
// src/components/setting-row.tsx
|
|
655
667
|
import * as React10 from "react";
|
|
668
|
+
import { Lock } from "lucide-react";
|
|
656
669
|
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
657
|
-
var SettingRow = React10.forwardRef(function SettingRow2({ icon: Icon, label, description, labelTone = "primary", htmlFor, children, className, ...props }, ref) {
|
|
670
|
+
var SettingRow = React10.forwardRef(function SettingRow2({ icon: Icon, label, description, labelTone = "primary", locked, htmlFor, children, className, ...props }, ref) {
|
|
658
671
|
const Label5 = htmlFor ? "label" : "span";
|
|
659
672
|
const quiet = labelTone === "secondary";
|
|
660
673
|
return /* @__PURE__ */ jsxs9(
|
|
@@ -694,7 +707,10 @@ var SettingRow = React10.forwardRef(function SettingRow2({ icon: Icon, label, de
|
|
|
694
707
|
description && /* @__PURE__ */ jsx13("span", { className: "block text-xs text-text-tertiary", children: description })
|
|
695
708
|
] })
|
|
696
709
|
] }),
|
|
697
|
-
/* @__PURE__ */
|
|
710
|
+
/* @__PURE__ */ jsxs9("span", { className: "flex shrink-0 items-center gap-2", children: [
|
|
711
|
+
locked && /* @__PURE__ */ jsx13(Lock, { className: "size-3.5 text-text-tertiary", "aria-hidden": "true" }),
|
|
712
|
+
children
|
|
713
|
+
] })
|
|
698
714
|
]
|
|
699
715
|
}
|
|
700
716
|
);
|
|
@@ -724,7 +740,7 @@ function Switch({
|
|
|
724
740
|
"data-testid": testId,
|
|
725
741
|
disabled,
|
|
726
742
|
onClick: () => onCheckedChange(!checked),
|
|
727
|
-
className: `relative inline-flex h-6 w-10 shrink-0
|
|
743
|
+
className: `relative inline-flex h-6 w-10 shrink-0 rounded-full transition-colors duration-fast outline-none focus-visible:ring-2 focus-visible:ring-border-focus focus-visible:ring-offset-2 focus-visible:ring-offset-bg-surface ${checked ? "bg-text-brand" : "bg-bg-surface"} ${disabled ? "cursor-not-allowed opacity-50" : "cursor-pointer"} ${className}`,
|
|
728
744
|
children: [
|
|
729
745
|
/* @__PURE__ */ jsx14(
|
|
730
746
|
"span",
|
|
@@ -764,7 +780,7 @@ var Checkbox = React11.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
764
780
|
// A field takes the field border (`Guidelines/Look/Borders`, #417). No hover step and no
|
|
765
781
|
// filled step: a 16px box's hover reading is the label beside it, and "answered" is already
|
|
766
782
|
// the checked mark, which paints the whole box.
|
|
767
|
-
"peer size-4 shrink-0 rounded-sm border border-field-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-400 data-[state=checked]:text-text-on-brand data-[state=checked]:border-blue-400",
|
|
783
|
+
"peer size-4 shrink-0 cursor-pointer rounded-sm border border-field-border focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-blue-400 data-[state=checked]:text-text-on-brand data-[state=checked]:border-blue-400",
|
|
768
784
|
className
|
|
769
785
|
),
|
|
770
786
|
...props,
|
|
@@ -786,7 +802,7 @@ var RadioGroupItem = React12.forwardRef(({ className, ...props }, ref) => /* @__
|
|
|
786
802
|
ref,
|
|
787
803
|
className: cn(
|
|
788
804
|
// The same field edge a `Checkbox` takes, and for the same reasons (#417).
|
|
789
|
-
"aspect-square size-4 rounded-full border border-field-border text-blue-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-blue-400",
|
|
805
|
+
"aspect-square size-4 cursor-pointer rounded-full border border-field-border text-blue-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-blue-400",
|
|
790
806
|
className
|
|
791
807
|
),
|
|
792
808
|
...props,
|
|
@@ -825,7 +841,7 @@ var Slider = React14.forwardRef(({ className, ...props }, ref) => {
|
|
|
825
841
|
SliderPrimitive.Root,
|
|
826
842
|
{
|
|
827
843
|
ref,
|
|
828
|
-
className: cn("relative flex w-full touch-none select-none items-center", className),
|
|
844
|
+
className: cn("relative flex w-full cursor-pointer touch-none select-none items-center", className),
|
|
829
845
|
...props,
|
|
830
846
|
children: [
|
|
831
847
|
/* @__PURE__ */ jsx18(SliderPrimitive.Track, { className: "relative h-1.5 w-full grow overflow-hidden rounded-full bg-bg-secondary", children: /* @__PURE__ */ jsx18(SliderPrimitive.Range, { className: "absolute h-full bg-blue-400" }) }),
|
|
@@ -848,7 +864,7 @@ import * as TogglePrimitive from "@radix-ui/react-toggle";
|
|
|
848
864
|
import { cva as cva3 } from "class-variance-authority";
|
|
849
865
|
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
850
866
|
var toggleVariants = cva3(
|
|
851
|
-
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium data-[state=on]:font-semibold text-text-secondary transition-colors duration-fast focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
867
|
+
"inline-flex cursor-pointer items-center justify-center gap-2 rounded-md text-sm font-medium data-[state=on]:font-semibold text-text-secondary transition-colors duration-fast focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
852
868
|
{
|
|
853
869
|
variants: {
|
|
854
870
|
/**
|
|
@@ -1518,11 +1534,11 @@ var badgeVariants = cva4(
|
|
|
1518
1534
|
default: "border-transparent bg-blue-400 text-text-on-brand",
|
|
1519
1535
|
secondary: "border-transparent bg-bg-secondary text-text-primary",
|
|
1520
1536
|
outline: "border-border-default text-text-primary",
|
|
1521
|
-
status: "border-
|
|
1537
|
+
status: "border-border-subtle bg-bg-overlay text-text-primary",
|
|
1522
1538
|
destructive: "border-transparent bg-bg-danger text-text-on-danger",
|
|
1523
1539
|
"danger-subtle": "border-transparent bg-bg-danger-subtle text-text-danger",
|
|
1524
1540
|
"warning-subtle": "border-transparent bg-bg-warning-subtle text-text-warning",
|
|
1525
|
-
"neutral-subtle": "border-
|
|
1541
|
+
"neutral-subtle": "border-border-subtle bg-bg-overlay text-text-tertiary",
|
|
1526
1542
|
success: "border-transparent bg-bg-success text-text-on-success",
|
|
1527
1543
|
warning: "border-transparent bg-bg-warning text-text-on-warning"
|
|
1528
1544
|
}
|
|
@@ -1662,7 +1678,7 @@ var GLYPH_SIZE = {
|
|
|
1662
1678
|
lg: "size-6"
|
|
1663
1679
|
};
|
|
1664
1680
|
var TONE = {
|
|
1665
|
-
neutral: "bg-bg-
|
|
1681
|
+
neutral: "bg-bg-overlay text-text-secondary",
|
|
1666
1682
|
teal: "bg-bg-teal-subtle text-text-teal",
|
|
1667
1683
|
violet: "bg-bg-violet-subtle text-text-violet",
|
|
1668
1684
|
rose: "bg-bg-rose-subtle text-text-rose"
|
|
@@ -1728,12 +1744,12 @@ function GlyphAvatar({ kind, size = "sm", label }) {
|
|
|
1728
1744
|
// src/components/entity-tile.tsx
|
|
1729
1745
|
import * as React28 from "react";
|
|
1730
1746
|
import { jsx as jsx35 } from "react/jsx-runtime";
|
|
1731
|
-
function EntityTile({ name, glyph, src, size = "sm", label }) {
|
|
1732
|
-
const
|
|
1747
|
+
function EntityTile({ name, glyph, tone = "auto", src, size = "sm", label }) {
|
|
1748
|
+
const painted = tone === "auto" && !glyph && name ? tintFor(name) : "neutral";
|
|
1733
1749
|
const sizedGlyph = React28.isValidElement(glyph) ? React28.cloneElement(glyph, {
|
|
1734
1750
|
className: cn(GLYPH_SIZE[size], glyph.props.className)
|
|
1735
1751
|
}) : glyph;
|
|
1736
|
-
return /* @__PURE__ */ jsx35(Mark, { shape: "square", size, tone, src, label, children: sizedGlyph ?? (name ? initialOf(name) : null) });
|
|
1752
|
+
return /* @__PURE__ */ jsx35(Mark, { shape: "square", size, tone: painted, src, label, children: sizedGlyph ?? (name ? initialOf(name) : null) });
|
|
1737
1753
|
}
|
|
1738
1754
|
|
|
1739
1755
|
// src/components/separator.tsx
|
|
@@ -1804,7 +1820,7 @@ var TabsTrigger = React31.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
1804
1820
|
{
|
|
1805
1821
|
ref,
|
|
1806
1822
|
className: cn(
|
|
1807
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-bg-sunken data-[state=active]:font-semibold data-[state=active]:text-text-primary",
|
|
1823
|
+
"inline-flex cursor-pointer items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium transition-all duration-fast focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-bg-sunken data-[state=active]:font-semibold data-[state=active]:text-text-primary",
|
|
1808
1824
|
className
|
|
1809
1825
|
),
|
|
1810
1826
|
...props
|
|
@@ -1844,7 +1860,7 @@ var AccordionTrigger = React32.forwardRef(({ className, children, ...props }, re
|
|
|
1844
1860
|
{
|
|
1845
1861
|
ref,
|
|
1846
1862
|
className: cn(
|
|
1847
|
-
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all duration-fast hover:underline [&[data-state=open]>svg]:rotate-180",
|
|
1863
|
+
"flex flex-1 cursor-pointer items-center justify-between py-4 text-sm font-medium transition-all duration-fast hover:underline [&[data-state=open]>svg]:rotate-180",
|
|
1848
1864
|
className
|
|
1849
1865
|
),
|
|
1850
1866
|
...props,
|
|
@@ -1927,14 +1943,14 @@ import * as React35 from "react";
|
|
|
1927
1943
|
import { cva as cva5 } from "class-variance-authority";
|
|
1928
1944
|
import { jsx as jsx42, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
1929
1945
|
var alertVariants = cva5(
|
|
1930
|
-
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4",
|
|
1946
|
+
"relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:size-4",
|
|
1931
1947
|
{
|
|
1932
1948
|
variants: {
|
|
1933
1949
|
variant: {
|
|
1934
|
-
default: "bg-bg-elevated border-border-
|
|
1935
|
-
destructive: "bg-bg-danger border-border-danger text-text-
|
|
1936
|
-
success: "bg-bg-success border-border-success text-text-
|
|
1937
|
-
warning: "bg-bg-warning border-border-warning text-text-
|
|
1950
|
+
default: "bg-bg-elevated border-border-default text-text-primary [&>svg]:text-text-secondary",
|
|
1951
|
+
destructive: "bg-bg-danger-subtle border-border-danger text-text-primary [&>svg]:text-text-danger",
|
|
1952
|
+
success: "bg-bg-success-subtle border-border-success text-text-primary [&>svg]:text-text-success",
|
|
1953
|
+
warning: "bg-bg-warning-subtle border-border-warning text-text-primary [&>svg]:text-text-warning"
|
|
1938
1954
|
}
|
|
1939
1955
|
},
|
|
1940
1956
|
defaultVariants: { variant: "default" }
|
|
@@ -1963,7 +1979,7 @@ var AlertTitle = React35.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
1963
1979
|
"h5",
|
|
1964
1980
|
{
|
|
1965
1981
|
ref,
|
|
1966
|
-
className: cn("mb-1 font-
|
|
1982
|
+
className: cn("mb-1 text-sm font-semibold leading-none tracking-tight", className),
|
|
1967
1983
|
...props
|
|
1968
1984
|
}
|
|
1969
1985
|
));
|
|
@@ -1972,7 +1988,7 @@ var AlertDescription = React35.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
1972
1988
|
"div",
|
|
1973
1989
|
{
|
|
1974
1990
|
ref,
|
|
1975
|
-
className: cn("text-sm [&_p]:leading-relaxed", className),
|
|
1991
|
+
className: cn("text-sm text-text-secondary [&_p]:leading-relaxed", className),
|
|
1976
1992
|
...props
|
|
1977
1993
|
}
|
|
1978
1994
|
));
|
|
@@ -2137,9 +2153,9 @@ PaginationEllipsis.displayName = "PaginationEllipsis";
|
|
|
2137
2153
|
|
|
2138
2154
|
// src/components/command.tsx
|
|
2139
2155
|
import * as React38 from "react";
|
|
2140
|
-
import { Command as CommandPrimitive } from "cmdk";
|
|
2156
|
+
import { Command as CommandPrimitive, useCommandState } from "cmdk";
|
|
2141
2157
|
import { Search } from "lucide-react";
|
|
2142
|
-
import { jsx as jsx45, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2158
|
+
import { Fragment as Fragment2, jsx as jsx45, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
2143
2159
|
var Command = React38.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx45(
|
|
2144
2160
|
CommandPrimitive,
|
|
2145
2161
|
{
|
|
@@ -2152,7 +2168,58 @@ var Command = React38.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
2152
2168
|
}
|
|
2153
2169
|
));
|
|
2154
2170
|
Command.displayName = CommandPrimitive.displayName;
|
|
2155
|
-
var
|
|
2171
|
+
var KeyCap = ({ children }) => /* @__PURE__ */ jsx45("kbd", { className: "inline-flex h-5 min-w-5 items-center justify-center rounded-sm border border-border-default bg-bg-elevated px-1 font-sans text-xs text-text-secondary", children });
|
|
2172
|
+
var CommandKeyHints = () => /* @__PURE__ */ jsx45("div", { className: "flex items-center gap-4 border-t border-border-subtle bg-bg-sunken px-3 py-2 text-xs text-text-tertiary", children: [[["\u2191", "\u2193"], "to navigate"], [["\u21B5"], "to select"]].map(([keys, verb]) => /* @__PURE__ */ jsxs24("span", { className: "flex items-center gap-1.5", children: [
|
|
2173
|
+
/* @__PURE__ */ jsx45("span", { className: "flex items-center gap-1", children: keys.map((key) => /* @__PURE__ */ jsx45(KeyCap, { children: key }, key)) }),
|
|
2174
|
+
" ",
|
|
2175
|
+
verb
|
|
2176
|
+
] }, verb)) });
|
|
2177
|
+
var CommandKeyHintsSlot = ({ children }) => {
|
|
2178
|
+
const count = useCommandState((state) => state.filtered.count);
|
|
2179
|
+
return count > 0 ? /* @__PURE__ */ jsx45(Fragment2, { children }) : null;
|
|
2180
|
+
};
|
|
2181
|
+
var CommandDialog = ({
|
|
2182
|
+
children,
|
|
2183
|
+
groups,
|
|
2184
|
+
placeholder,
|
|
2185
|
+
empty,
|
|
2186
|
+
keyHints = /* @__PURE__ */ jsx45(CommandKeyHints, {}),
|
|
2187
|
+
shortcut = false,
|
|
2188
|
+
open,
|
|
2189
|
+
onOpenChange,
|
|
2190
|
+
...props
|
|
2191
|
+
}) => {
|
|
2192
|
+
React38.useEffect(() => {
|
|
2193
|
+
if (!shortcut || !onOpenChange) return;
|
|
2194
|
+
const onKey = (e) => {
|
|
2195
|
+
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
|
|
2196
|
+
e.preventDefault();
|
|
2197
|
+
onOpenChange(!open);
|
|
2198
|
+
}
|
|
2199
|
+
};
|
|
2200
|
+
document.addEventListener("keydown", onKey);
|
|
2201
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
2202
|
+
}, [shortcut, open, onOpenChange]);
|
|
2203
|
+
return /* @__PURE__ */ jsx45(Dialog, { open, onOpenChange, ...props, children: /* @__PURE__ */ jsx45(DialogContent, { className: "overflow-hidden p-0", children: /* @__PURE__ */ jsx45(Command, { className: "[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-text-tertiary [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5", children: groups ? /* @__PURE__ */ jsxs24(Fragment2, { children: [
|
|
2204
|
+
/* @__PURE__ */ jsx45(CommandInput, { placeholder }),
|
|
2205
|
+
/* @__PURE__ */ jsxs24(CommandList, { className: "max-h-[420px]", children: [
|
|
2206
|
+
/* @__PURE__ */ jsx45(CommandEmpty, { children: empty }),
|
|
2207
|
+
groups.map((group) => /* @__PURE__ */ jsx45(CommandGroup, { heading: group.heading, children: group.items.map((item) => /* @__PURE__ */ jsx45(
|
|
2208
|
+
CommandItem,
|
|
2209
|
+
{
|
|
2210
|
+
value: item.value ?? [group.heading, item.sub, item.label].filter(Boolean).join(" "),
|
|
2211
|
+
mark: item.mark,
|
|
2212
|
+
sub: item.sub,
|
|
2213
|
+
className: item.sub ? void 0 : "items-center",
|
|
2214
|
+
onSelect: item.onSelect,
|
|
2215
|
+
children: item.label
|
|
2216
|
+
},
|
|
2217
|
+
item.id ?? `${group.heading}:${String(item.label)}`
|
|
2218
|
+
)) }, group.heading))
|
|
2219
|
+
] }),
|
|
2220
|
+
/* @__PURE__ */ jsx45(CommandKeyHintsSlot, { children: keyHints })
|
|
2221
|
+
] }) : children }) }) });
|
|
2222
|
+
};
|
|
2156
2223
|
var CommandInput = React38.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxs24("div", { className: "flex items-center border-b border-border-subtle px-3", "cmdk-input-wrapper": "", children: [
|
|
2157
2224
|
/* @__PURE__ */ jsx45(Search, { className: "mr-2 h-4 w-4 shrink-0 opacity-50" }),
|
|
2158
2225
|
/* @__PURE__ */ jsx45(
|
|
@@ -2172,7 +2239,7 @@ var CommandList = React38.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
2172
2239
|
CommandPrimitive.List,
|
|
2173
2240
|
{
|
|
2174
2241
|
ref,
|
|
2175
|
-
className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className),
|
|
2242
|
+
className: cn("max-h-[300px] overflow-y-auto overflow-x-hidden pb-2", className),
|
|
2176
2243
|
...props
|
|
2177
2244
|
}
|
|
2178
2245
|
));
|
|
@@ -2213,7 +2280,7 @@ var CommandItem = React38.forwardRef(
|
|
|
2213
2280
|
{
|
|
2214
2281
|
ref,
|
|
2215
2282
|
className: cn(
|
|
2216
|
-
"relative flex cursor-default select-none gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-bg
|
|
2283
|
+
"relative flex cursor-default select-none gap-2 rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-[selected=true]:bg-[var(--hov-bg)] data-[selected=true]:text-text-primary",
|
|
2217
2284
|
mark ? "items-start" : "items-center",
|
|
2218
2285
|
className
|
|
2219
2286
|
),
|
|
@@ -2268,7 +2335,7 @@ var NavigationMenuList = React39.forwardRef(({ className, ...props }, ref) => /*
|
|
|
2268
2335
|
NavigationMenuList.displayName = NavigationMenuPrimitive.List.displayName;
|
|
2269
2336
|
var NavigationMenuItem = NavigationMenuPrimitive.Item;
|
|
2270
2337
|
var navigationMenuTriggerStyle = cva6(
|
|
2271
|
-
"group inline-flex h-10 w-max items-center justify-center rounded-md bg-bg-elevated px-4 py-2 text-sm font-medium transition-colors duration-fast hover:bg-bg-secondary hover:text-text-primary focus:bg-bg-secondary focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-bg-secondary"
|
|
2338
|
+
"group inline-flex h-10 w-max cursor-pointer items-center justify-center rounded-md bg-bg-elevated px-4 py-2 text-sm font-medium transition-colors duration-fast hover:bg-bg-secondary hover:text-text-primary focus:bg-bg-secondary focus:outline-none disabled:pointer-events-none disabled:opacity-50 data-[state=open]:bg-bg-secondary"
|
|
2272
2339
|
);
|
|
2273
2340
|
var NavigationMenuTrigger = React39.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs25(
|
|
2274
2341
|
NavigationMenuPrimitive.Trigger,
|
|
@@ -2330,7 +2397,7 @@ var NavigationMenuIndicator = React39.forwardRef(({ className, ...props }, ref)
|
|
|
2330
2397
|
NavigationMenuIndicator.displayName = NavigationMenuPrimitive.Indicator.displayName;
|
|
2331
2398
|
|
|
2332
2399
|
// src/hooks/useTheme.ts
|
|
2333
|
-
import { useEffect as
|
|
2400
|
+
import { useEffect as useEffect3, useState as useState2, useCallback } from "react";
|
|
2334
2401
|
var STORAGE_KEY = "lessly_theme";
|
|
2335
2402
|
var THEMES = ["light", "dark", "system"];
|
|
2336
2403
|
function parseStoredTheme(stored) {
|
|
@@ -2364,10 +2431,10 @@ function useTheme() {
|
|
|
2364
2431
|
applyTheme(resolveTheme(newTheme));
|
|
2365
2432
|
window.dispatchEvent(new CustomEvent("lessly-theme-change", { detail: newTheme }));
|
|
2366
2433
|
}, []);
|
|
2367
|
-
|
|
2434
|
+
useEffect3(() => {
|
|
2368
2435
|
applyTheme(resolvedTheme);
|
|
2369
2436
|
}, [resolvedTheme]);
|
|
2370
|
-
|
|
2437
|
+
useEffect3(() => {
|
|
2371
2438
|
const handler = (e) => {
|
|
2372
2439
|
const newTheme = e.detail;
|
|
2373
2440
|
setThemeState(newTheme);
|
|
@@ -2375,7 +2442,7 @@ function useTheme() {
|
|
|
2375
2442
|
window.addEventListener("lessly-theme-change", handler);
|
|
2376
2443
|
return () => window.removeEventListener("lessly-theme-change", handler);
|
|
2377
2444
|
}, []);
|
|
2378
|
-
|
|
2445
|
+
useEffect3(() => {
|
|
2379
2446
|
if (theme !== "system") return;
|
|
2380
2447
|
const mql = window.matchMedia("(prefers-color-scheme: light)");
|
|
2381
2448
|
const handler = () => applyTheme(getSystemTheme());
|
|
@@ -2410,7 +2477,21 @@ var Toaster = ({ ...props }) => {
|
|
|
2410
2477
|
|
|
2411
2478
|
// src/components/theme-toggle.tsx
|
|
2412
2479
|
import { Sun, Moon } from "lucide-react";
|
|
2413
|
-
|
|
2480
|
+
|
|
2481
|
+
// src/components/top-bar-utilities.tsx
|
|
2482
|
+
import * as React40 from "react";
|
|
2483
|
+
import { jsx as jsx48, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
2484
|
+
var topBarMarkClass = "relative flex size-8 shrink-0 cursor-pointer items-center justify-center rounded-lg text-text-secondary transition-colors duration-fast hover:bg-[var(--hov-bg)] hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus [&>svg]:size-[18px]";
|
|
2485
|
+
var TopBarUtilities = React40.forwardRef(
|
|
2486
|
+
({ items, className, ...props }, ref) => /* @__PURE__ */ jsx48("div", { ref, className: cn("flex items-center gap-1", className), ...props, children: items.map(({ name, icon, onClick }) => /* @__PURE__ */ jsxs26(Tooltip, { children: [
|
|
2487
|
+
/* @__PURE__ */ jsx48(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx48("button", { type: "button", className: topBarMarkClass, "aria-label": name, onClick, children: icon }) }),
|
|
2488
|
+
/* @__PURE__ */ jsx48(TooltipContent, { children: name })
|
|
2489
|
+
] }, name)) })
|
|
2490
|
+
);
|
|
2491
|
+
TopBarUtilities.displayName = "TopBarUtilities";
|
|
2492
|
+
|
|
2493
|
+
// src/components/theme-toggle.tsx
|
|
2494
|
+
import { jsx as jsx49 } from "react/jsx-runtime";
|
|
2414
2495
|
var icons = {
|
|
2415
2496
|
light: Sun,
|
|
2416
2497
|
dark: Moon
|
|
@@ -2420,14 +2501,15 @@ function ThemeToggle() {
|
|
|
2420
2501
|
const Icon = icons[resolvedTheme];
|
|
2421
2502
|
const next = resolvedTheme === "light" ? "dark" : "light";
|
|
2422
2503
|
const label = theme === "system" ? `Following your device (${resolvedTheme}). Switch to ${next}.` : `Switch to ${next} theme`;
|
|
2423
|
-
return /* @__PURE__ */
|
|
2504
|
+
return /* @__PURE__ */ jsx49(
|
|
2424
2505
|
"button",
|
|
2425
2506
|
{
|
|
2507
|
+
type: "button",
|
|
2426
2508
|
onClick: () => setTheme(next),
|
|
2427
|
-
className:
|
|
2509
|
+
className: topBarMarkClass,
|
|
2428
2510
|
"aria-label": label,
|
|
2429
2511
|
title: label,
|
|
2430
|
-
children: /* @__PURE__ */
|
|
2512
|
+
children: /* @__PURE__ */ jsx49(Icon, {})
|
|
2431
2513
|
}
|
|
2432
2514
|
);
|
|
2433
2515
|
}
|
|
@@ -2435,9 +2517,9 @@ function ThemeToggle() {
|
|
|
2435
2517
|
// src/components/calendar.tsx
|
|
2436
2518
|
import { ChevronLeft as ChevronLeft2, ChevronRight as ChevronRight6 } from "lucide-react";
|
|
2437
2519
|
import { DayPicker } from "react-day-picker";
|
|
2438
|
-
import { jsx as
|
|
2520
|
+
import { jsx as jsx50 } from "react/jsx-runtime";
|
|
2439
2521
|
function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
|
|
2440
|
-
return /* @__PURE__ */
|
|
2522
|
+
return /* @__PURE__ */ jsx50(
|
|
2441
2523
|
DayPicker,
|
|
2442
2524
|
{
|
|
2443
2525
|
showOutsideDays,
|
|
@@ -2495,7 +2577,7 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
|
|
|
2495
2577
|
...classNames
|
|
2496
2578
|
},
|
|
2497
2579
|
components: {
|
|
2498
|
-
Chevron: ({ className: cls, orientation, ...rest }) => orientation === "left" ? /* @__PURE__ */
|
|
2580
|
+
Chevron: ({ className: cls, orientation, ...rest }) => orientation === "left" ? /* @__PURE__ */ jsx50(ChevronLeft2, { className: cn("size-4", cls), ...rest }) : /* @__PURE__ */ jsx50(ChevronRight6, { className: cn("size-4", cls), ...rest })
|
|
2499
2581
|
},
|
|
2500
2582
|
...props
|
|
2501
2583
|
}
|
|
@@ -2504,9 +2586,9 @@ function Calendar({ className, classNames, showOutsideDays = true, ...props }) {
|
|
|
2504
2586
|
Calendar.displayName = "Calendar";
|
|
2505
2587
|
|
|
2506
2588
|
// src/components/date-picker.tsx
|
|
2507
|
-
import * as
|
|
2589
|
+
import * as React41 from "react";
|
|
2508
2590
|
import { Calendar as CalendarIcon } from "lucide-react";
|
|
2509
|
-
import { jsx as
|
|
2591
|
+
import { jsx as jsx51, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
2510
2592
|
var DEFAULT_FORMAT = {
|
|
2511
2593
|
year: "numeric",
|
|
2512
2594
|
month: "long",
|
|
@@ -2519,9 +2601,9 @@ function DatePicker({
|
|
|
2519
2601
|
disabled,
|
|
2520
2602
|
className
|
|
2521
2603
|
}) {
|
|
2522
|
-
const [open, setOpen] =
|
|
2523
|
-
return /* @__PURE__ */
|
|
2524
|
-
/* @__PURE__ */
|
|
2604
|
+
const [open, setOpen] = React41.useState(false);
|
|
2605
|
+
return /* @__PURE__ */ jsxs27(Popover, { open, onOpenChange: setOpen, children: [
|
|
2606
|
+
/* @__PURE__ */ jsx51(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs27(
|
|
2525
2607
|
Button,
|
|
2526
2608
|
{
|
|
2527
2609
|
type: "button",
|
|
@@ -2529,12 +2611,12 @@ function DatePicker({
|
|
|
2529
2611
|
disabled,
|
|
2530
2612
|
className: cn("w-[240px] justify-start gap-2 text-left font-regular", !value && "text-text-tertiary", className),
|
|
2531
2613
|
children: [
|
|
2532
|
-
/* @__PURE__ */
|
|
2614
|
+
/* @__PURE__ */ jsx51(CalendarIcon, { className: "size-4 shrink-0" }),
|
|
2533
2615
|
value ? value.toLocaleDateString(void 0, DEFAULT_FORMAT) : placeholder
|
|
2534
2616
|
]
|
|
2535
2617
|
}
|
|
2536
2618
|
) }),
|
|
2537
|
-
/* @__PURE__ */
|
|
2619
|
+
/* @__PURE__ */ jsx51(PopoverContent, { className: "w-auto p-0", align: "start", children: /* @__PURE__ */ jsx51(
|
|
2538
2620
|
Calendar,
|
|
2539
2621
|
{
|
|
2540
2622
|
mode: "single",
|
|
@@ -2551,20 +2633,20 @@ function DatePicker({
|
|
|
2551
2633
|
DatePicker.displayName = "DatePicker";
|
|
2552
2634
|
|
|
2553
2635
|
// src/components/add-picker.tsx
|
|
2554
|
-
import * as
|
|
2636
|
+
import * as React42 from "react";
|
|
2555
2637
|
import { Plus } from "lucide-react";
|
|
2556
|
-
import { jsx as
|
|
2557
|
-
var AddPicker =
|
|
2638
|
+
import { jsx as jsx52, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
2639
|
+
var AddPicker = React42.forwardRef(
|
|
2558
2640
|
({ label, noun, items, exclude, onPick, className }, ref) => {
|
|
2559
|
-
const [open, setOpen] =
|
|
2560
|
-
const [q, setQ] =
|
|
2641
|
+
const [open, setOpen] = React42.useState(false);
|
|
2642
|
+
const [q, setQ] = React42.useState("");
|
|
2561
2643
|
const taken = exclude ?? [];
|
|
2562
2644
|
const needle = q.toLowerCase();
|
|
2563
2645
|
const matches = items.filter(
|
|
2564
2646
|
(item) => !taken.includes(item.id) && (item.name.toLowerCase().includes(needle) || !!item.sub?.toLowerCase().includes(needle))
|
|
2565
2647
|
);
|
|
2566
2648
|
const search = items.length > 1 ? `Search ${items.length} ${noun}` : `Search ${noun}`;
|
|
2567
|
-
return /* @__PURE__ */
|
|
2649
|
+
return /* @__PURE__ */ jsxs28(
|
|
2568
2650
|
Popover,
|
|
2569
2651
|
{
|
|
2570
2652
|
open,
|
|
@@ -2573,15 +2655,15 @@ var AddPicker = React41.forwardRef(
|
|
|
2573
2655
|
if (!next) setQ("");
|
|
2574
2656
|
},
|
|
2575
2657
|
children: [
|
|
2576
|
-
/* @__PURE__ */
|
|
2577
|
-
/* @__PURE__ */
|
|
2658
|
+
/* @__PURE__ */ jsx52(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs28(Button, { ref, variant: "ghost", size: "xs", className: cn("shrink-0", className), children: [
|
|
2659
|
+
/* @__PURE__ */ jsx52(Plus, { className: "size-4", "aria-hidden": true }),
|
|
2578
2660
|
label
|
|
2579
2661
|
] }) }),
|
|
2580
|
-
/* @__PURE__ */
|
|
2581
|
-
/* @__PURE__ */
|
|
2582
|
-
/* @__PURE__ */
|
|
2583
|
-
/* @__PURE__ */
|
|
2584
|
-
matches.map((item) => /* @__PURE__ */
|
|
2662
|
+
/* @__PURE__ */ jsx52(PopoverContent, { align: "end", className: "w-72 p-0", children: /* @__PURE__ */ jsxs28(Command, { shouldFilter: false, label: search, children: [
|
|
2663
|
+
/* @__PURE__ */ jsx52(CommandInput, { autoFocus: true, value: q, onValueChange: setQ, placeholder: search }),
|
|
2664
|
+
/* @__PURE__ */ jsxs28(CommandList, { className: "max-h-[18rem] p-1", children: [
|
|
2665
|
+
/* @__PURE__ */ jsx52(CommandEmpty, { children: q ? `No ${noun} match.` : `No ${noun} left to add.` }),
|
|
2666
|
+
matches.map((item) => /* @__PURE__ */ jsx52(
|
|
2585
2667
|
CommandItem,
|
|
2586
2668
|
{
|
|
2587
2669
|
value: item.id,
|
|
@@ -2592,7 +2674,7 @@ var AddPicker = React41.forwardRef(
|
|
|
2592
2674
|
setOpen(false);
|
|
2593
2675
|
setQ("");
|
|
2594
2676
|
},
|
|
2595
|
-
children: /* @__PURE__ */
|
|
2677
|
+
children: /* @__PURE__ */ jsx52("span", { className: "truncate", children: item.name })
|
|
2596
2678
|
},
|
|
2597
2679
|
item.id
|
|
2598
2680
|
))
|
|
@@ -2606,31 +2688,31 @@ var AddPicker = React41.forwardRef(
|
|
|
2606
2688
|
AddPicker.displayName = "AddPicker";
|
|
2607
2689
|
|
|
2608
2690
|
// src/components/carousel.tsx
|
|
2609
|
-
import * as
|
|
2691
|
+
import * as React43 from "react";
|
|
2610
2692
|
import useEmblaCarousel from "embla-carousel-react";
|
|
2611
2693
|
import { ArrowLeft, ArrowRight } from "lucide-react";
|
|
2612
|
-
import { jsx as
|
|
2613
|
-
var CarouselContext =
|
|
2694
|
+
import { jsx as jsx53, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
2695
|
+
var CarouselContext = React43.createContext(null);
|
|
2614
2696
|
function useCarousel() {
|
|
2615
|
-
const context =
|
|
2697
|
+
const context = React43.useContext(CarouselContext);
|
|
2616
2698
|
if (!context) throw new Error("useCarousel must be used within a <Carousel />");
|
|
2617
2699
|
return context;
|
|
2618
2700
|
}
|
|
2619
|
-
var Carousel =
|
|
2701
|
+
var Carousel = React43.forwardRef(({ orientation = "horizontal", opts, setApi, plugins, className, children, ...props }, ref) => {
|
|
2620
2702
|
const [carouselRef, api] = useEmblaCarousel(
|
|
2621
2703
|
{ ...opts, axis: orientation === "horizontal" ? "x" : "y" },
|
|
2622
2704
|
plugins
|
|
2623
2705
|
);
|
|
2624
|
-
const [canScrollPrev, setCanScrollPrev] =
|
|
2625
|
-
const [canScrollNext, setCanScrollNext] =
|
|
2626
|
-
const onSelect =
|
|
2706
|
+
const [canScrollPrev, setCanScrollPrev] = React43.useState(false);
|
|
2707
|
+
const [canScrollNext, setCanScrollNext] = React43.useState(false);
|
|
2708
|
+
const onSelect = React43.useCallback((emblaApi) => {
|
|
2627
2709
|
if (!emblaApi) return;
|
|
2628
2710
|
setCanScrollPrev(emblaApi.canScrollPrev());
|
|
2629
2711
|
setCanScrollNext(emblaApi.canScrollNext());
|
|
2630
2712
|
}, []);
|
|
2631
|
-
const scrollPrev =
|
|
2632
|
-
const scrollNext =
|
|
2633
|
-
const handleKeyDown =
|
|
2713
|
+
const scrollPrev = React43.useCallback(() => api?.scrollPrev(), [api]);
|
|
2714
|
+
const scrollNext = React43.useCallback(() => api?.scrollNext(), [api]);
|
|
2715
|
+
const handleKeyDown = React43.useCallback(
|
|
2634
2716
|
(event) => {
|
|
2635
2717
|
if (event.key === "ArrowLeft") {
|
|
2636
2718
|
event.preventDefault();
|
|
@@ -2642,11 +2724,11 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
|
|
|
2642
2724
|
},
|
|
2643
2725
|
[scrollPrev, scrollNext]
|
|
2644
2726
|
);
|
|
2645
|
-
|
|
2727
|
+
React43.useEffect(() => {
|
|
2646
2728
|
if (!api || !setApi) return;
|
|
2647
2729
|
setApi(api);
|
|
2648
2730
|
}, [api, setApi]);
|
|
2649
|
-
|
|
2731
|
+
React43.useEffect(() => {
|
|
2650
2732
|
if (!api) return;
|
|
2651
2733
|
onSelect(api);
|
|
2652
2734
|
api.on("reInit", onSelect);
|
|
@@ -2656,7 +2738,7 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
|
|
|
2656
2738
|
api.off("select", onSelect);
|
|
2657
2739
|
};
|
|
2658
2740
|
}, [api, onSelect]);
|
|
2659
|
-
return /* @__PURE__ */
|
|
2741
|
+
return /* @__PURE__ */ jsx53(
|
|
2660
2742
|
CarouselContext.Provider,
|
|
2661
2743
|
{
|
|
2662
2744
|
value: {
|
|
@@ -2669,7 +2751,7 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
|
|
|
2669
2751
|
canScrollPrev,
|
|
2670
2752
|
canScrollNext
|
|
2671
2753
|
},
|
|
2672
|
-
children: /* @__PURE__ */
|
|
2754
|
+
children: /* @__PURE__ */ jsx53(
|
|
2673
2755
|
"div",
|
|
2674
2756
|
{
|
|
2675
2757
|
ref,
|
|
@@ -2685,10 +2767,10 @@ var Carousel = React42.forwardRef(({ orientation = "horizontal", opts, setApi, p
|
|
|
2685
2767
|
);
|
|
2686
2768
|
});
|
|
2687
2769
|
Carousel.displayName = "Carousel";
|
|
2688
|
-
var CarouselContent =
|
|
2770
|
+
var CarouselContent = React43.forwardRef(
|
|
2689
2771
|
({ className, ...props }, ref) => {
|
|
2690
2772
|
const { carouselRef, orientation } = useCarousel();
|
|
2691
|
-
return /* @__PURE__ */
|
|
2773
|
+
return /* @__PURE__ */ jsx53("div", { ref: carouselRef, className: "overflow-hidden", children: /* @__PURE__ */ jsx53(
|
|
2692
2774
|
"div",
|
|
2693
2775
|
{
|
|
2694
2776
|
ref,
|
|
@@ -2699,10 +2781,10 @@ var CarouselContent = React42.forwardRef(
|
|
|
2699
2781
|
}
|
|
2700
2782
|
);
|
|
2701
2783
|
CarouselContent.displayName = "CarouselContent";
|
|
2702
|
-
var CarouselItem =
|
|
2784
|
+
var CarouselItem = React43.forwardRef(
|
|
2703
2785
|
({ className, ...props }, ref) => {
|
|
2704
2786
|
const { orientation } = useCarousel();
|
|
2705
|
-
return /* @__PURE__ */
|
|
2787
|
+
return /* @__PURE__ */ jsx53(
|
|
2706
2788
|
"div",
|
|
2707
2789
|
{
|
|
2708
2790
|
ref,
|
|
@@ -2719,9 +2801,9 @@ var CarouselItem = React42.forwardRef(
|
|
|
2719
2801
|
}
|
|
2720
2802
|
);
|
|
2721
2803
|
CarouselItem.displayName = "CarouselItem";
|
|
2722
|
-
var CarouselPrevious =
|
|
2804
|
+
var CarouselPrevious = React43.forwardRef(({ className, ...props }, ref) => {
|
|
2723
2805
|
const { orientation, scrollPrev, canScrollPrev } = useCarousel();
|
|
2724
|
-
return /* @__PURE__ */
|
|
2806
|
+
return /* @__PURE__ */ jsxs29(
|
|
2725
2807
|
"button",
|
|
2726
2808
|
{
|
|
2727
2809
|
ref,
|
|
@@ -2736,16 +2818,16 @@ var CarouselPrevious = React42.forwardRef(({ className, ...props }, ref) => {
|
|
|
2736
2818
|
onClick: scrollPrev,
|
|
2737
2819
|
...props,
|
|
2738
2820
|
children: [
|
|
2739
|
-
/* @__PURE__ */
|
|
2740
|
-
/* @__PURE__ */
|
|
2821
|
+
/* @__PURE__ */ jsx53(ArrowLeft, { className: "size-4" }),
|
|
2822
|
+
/* @__PURE__ */ jsx53("span", { className: "sr-only", children: "Previous slide" })
|
|
2741
2823
|
]
|
|
2742
2824
|
}
|
|
2743
2825
|
);
|
|
2744
2826
|
});
|
|
2745
2827
|
CarouselPrevious.displayName = "CarouselPrevious";
|
|
2746
|
-
var CarouselNext =
|
|
2828
|
+
var CarouselNext = React43.forwardRef(({ className, ...props }, ref) => {
|
|
2747
2829
|
const { orientation, scrollNext, canScrollNext } = useCarousel();
|
|
2748
|
-
return /* @__PURE__ */
|
|
2830
|
+
return /* @__PURE__ */ jsxs29(
|
|
2749
2831
|
"button",
|
|
2750
2832
|
{
|
|
2751
2833
|
ref,
|
|
@@ -2760,8 +2842,8 @@ var CarouselNext = React42.forwardRef(({ className, ...props }, ref) => {
|
|
|
2760
2842
|
onClick: scrollNext,
|
|
2761
2843
|
...props,
|
|
2762
2844
|
children: [
|
|
2763
|
-
/* @__PURE__ */
|
|
2764
|
-
/* @__PURE__ */
|
|
2845
|
+
/* @__PURE__ */ jsx53(ArrowRight, { className: "size-4" }),
|
|
2846
|
+
/* @__PURE__ */ jsx53("span", { className: "sr-only", children: "Next slide" })
|
|
2765
2847
|
]
|
|
2766
2848
|
}
|
|
2767
2849
|
);
|
|
@@ -2769,7 +2851,7 @@ var CarouselNext = React42.forwardRef(({ className, ...props }, ref) => {
|
|
|
2769
2851
|
CarouselNext.displayName = "CarouselNext";
|
|
2770
2852
|
|
|
2771
2853
|
// src/components/form.tsx
|
|
2772
|
-
import * as
|
|
2854
|
+
import * as React44 from "react";
|
|
2773
2855
|
import { Slot as Slot2 } from "@radix-ui/react-slot";
|
|
2774
2856
|
import {
|
|
2775
2857
|
Controller,
|
|
@@ -2777,16 +2859,16 @@ import {
|
|
|
2777
2859
|
useFormContext,
|
|
2778
2860
|
useFormState
|
|
2779
2861
|
} from "react-hook-form";
|
|
2780
|
-
import { jsx as
|
|
2862
|
+
import { jsx as jsx54 } from "react/jsx-runtime";
|
|
2781
2863
|
var Form = FormProvider;
|
|
2782
|
-
var FormFieldContext =
|
|
2864
|
+
var FormFieldContext = React44.createContext(null);
|
|
2783
2865
|
function FormField({ ...props }) {
|
|
2784
|
-
return /* @__PURE__ */
|
|
2866
|
+
return /* @__PURE__ */ jsx54(FormFieldContext.Provider, { value: { name: props.name }, children: /* @__PURE__ */ jsx54(Controller, { ...props }) });
|
|
2785
2867
|
}
|
|
2786
|
-
var FormItemContext =
|
|
2868
|
+
var FormItemContext = React44.createContext(null);
|
|
2787
2869
|
function useFormField() {
|
|
2788
|
-
const fieldContext =
|
|
2789
|
-
const itemContext =
|
|
2870
|
+
const fieldContext = React44.useContext(FormFieldContext);
|
|
2871
|
+
const itemContext = React44.useContext(FormItemContext);
|
|
2790
2872
|
const { getFieldState } = useFormContext();
|
|
2791
2873
|
const formState = useFormState({ name: fieldContext?.name });
|
|
2792
2874
|
if (!fieldContext) throw new Error("useFormField should be used within <FormField>");
|
|
@@ -2801,16 +2883,16 @@ function useFormField() {
|
|
|
2801
2883
|
...fieldState
|
|
2802
2884
|
};
|
|
2803
2885
|
}
|
|
2804
|
-
var FormItem =
|
|
2886
|
+
var FormItem = React44.forwardRef(
|
|
2805
2887
|
({ className, ...props }, ref) => {
|
|
2806
|
-
const id =
|
|
2807
|
-
return /* @__PURE__ */
|
|
2888
|
+
const id = React44.useId();
|
|
2889
|
+
return /* @__PURE__ */ jsx54(FormItemContext.Provider, { value: { id }, children: /* @__PURE__ */ jsx54("div", { ref, className: cn("space-y-2", className), ...props }) });
|
|
2808
2890
|
}
|
|
2809
2891
|
);
|
|
2810
2892
|
FormItem.displayName = "FormItem";
|
|
2811
|
-
var FormLabel =
|
|
2893
|
+
var FormLabel = React44.forwardRef(({ className, ...props }, ref) => {
|
|
2812
2894
|
const { error, formItemId } = useFormField();
|
|
2813
|
-
return /* @__PURE__ */
|
|
2895
|
+
return /* @__PURE__ */ jsx54(
|
|
2814
2896
|
Label2,
|
|
2815
2897
|
{
|
|
2816
2898
|
ref,
|
|
@@ -2821,9 +2903,9 @@ var FormLabel = React43.forwardRef(({ className, ...props }, ref) => {
|
|
|
2821
2903
|
);
|
|
2822
2904
|
});
|
|
2823
2905
|
FormLabel.displayName = "FormLabel";
|
|
2824
|
-
var FormControl =
|
|
2906
|
+
var FormControl = React44.forwardRef(({ ...props }, ref) => {
|
|
2825
2907
|
const { error, formItemId, formDescriptionId, formMessageId } = useFormField();
|
|
2826
|
-
return /* @__PURE__ */
|
|
2908
|
+
return /* @__PURE__ */ jsx54(
|
|
2827
2909
|
Slot2,
|
|
2828
2910
|
{
|
|
2829
2911
|
ref,
|
|
@@ -2835,9 +2917,9 @@ var FormControl = React43.forwardRef(({ ...props }, ref) => {
|
|
|
2835
2917
|
);
|
|
2836
2918
|
});
|
|
2837
2919
|
FormControl.displayName = "FormControl";
|
|
2838
|
-
var FormDescription =
|
|
2920
|
+
var FormDescription = React44.forwardRef(({ className, ...props }, ref) => {
|
|
2839
2921
|
const { formDescriptionId } = useFormField();
|
|
2840
|
-
return /* @__PURE__ */
|
|
2922
|
+
return /* @__PURE__ */ jsx54(
|
|
2841
2923
|
"p",
|
|
2842
2924
|
{
|
|
2843
2925
|
ref,
|
|
@@ -2848,11 +2930,11 @@ var FormDescription = React43.forwardRef(({ className, ...props }, ref) => {
|
|
|
2848
2930
|
);
|
|
2849
2931
|
});
|
|
2850
2932
|
FormDescription.displayName = "FormDescription";
|
|
2851
|
-
var FormMessage =
|
|
2933
|
+
var FormMessage = React44.forwardRef(({ className, children, ...props }, ref) => {
|
|
2852
2934
|
const { error, formMessageId } = useFormField();
|
|
2853
2935
|
const body = error ? String(error?.message ?? "") : children;
|
|
2854
2936
|
if (!body) return null;
|
|
2855
|
-
return /* @__PURE__ */
|
|
2937
|
+
return /* @__PURE__ */ jsx54(
|
|
2856
2938
|
"p",
|
|
2857
2939
|
{
|
|
2858
2940
|
ref,
|
|
@@ -2866,9 +2948,9 @@ var FormMessage = React43.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
2866
2948
|
FormMessage.displayName = "FormMessage";
|
|
2867
2949
|
|
|
2868
2950
|
// src/components/status-dot.tsx
|
|
2869
|
-
import * as
|
|
2951
|
+
import * as React45 from "react";
|
|
2870
2952
|
import { cva as cva7 } from "class-variance-authority";
|
|
2871
|
-
import { jsx as
|
|
2953
|
+
import { jsx as jsx55, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
2872
2954
|
var statusDotVariants = cva7("inline-block shrink-0 rounded-full", {
|
|
2873
2955
|
variants: {
|
|
2874
2956
|
status: {
|
|
@@ -2882,8 +2964,8 @@ var statusDotVariants = cva7("inline-block shrink-0 rounded-full", {
|
|
|
2882
2964
|
},
|
|
2883
2965
|
defaultVariants: { status: "neutral", size: "md" }
|
|
2884
2966
|
});
|
|
2885
|
-
var StatusDot =
|
|
2886
|
-
({ className, status, size, pulse = false, label, ...props }, ref) => /* @__PURE__ */
|
|
2967
|
+
var StatusDot = React45.forwardRef(
|
|
2968
|
+
({ className, status, size, pulse = false, label, ...props }, ref) => /* @__PURE__ */ jsxs30(
|
|
2887
2969
|
"span",
|
|
2888
2970
|
{
|
|
2889
2971
|
ref,
|
|
@@ -2891,14 +2973,14 @@ var StatusDot = React44.forwardRef(
|
|
|
2891
2973
|
className: cn("relative inline-flex", className),
|
|
2892
2974
|
...props,
|
|
2893
2975
|
children: [
|
|
2894
|
-
pulse && /* @__PURE__ */
|
|
2976
|
+
pulse && /* @__PURE__ */ jsx55(
|
|
2895
2977
|
"span",
|
|
2896
2978
|
{
|
|
2897
2979
|
"aria-hidden": "true",
|
|
2898
2980
|
className: cn(statusDotVariants({ status, size }), "absolute inset-0 animate-ping opacity-75")
|
|
2899
2981
|
}
|
|
2900
2982
|
),
|
|
2901
|
-
/* @__PURE__ */
|
|
2983
|
+
/* @__PURE__ */ jsx55("span", { className: cn(statusDotVariants({ status, size })) })
|
|
2902
2984
|
]
|
|
2903
2985
|
}
|
|
2904
2986
|
)
|
|
@@ -2906,11 +2988,11 @@ var StatusDot = React44.forwardRef(
|
|
|
2906
2988
|
StatusDot.displayName = "StatusDot";
|
|
2907
2989
|
|
|
2908
2990
|
// src/components/docs-link.tsx
|
|
2909
|
-
import * as
|
|
2991
|
+
import * as React46 from "react";
|
|
2910
2992
|
import { BookOpen, ExternalLink } from "lucide-react";
|
|
2911
|
-
import { jsx as
|
|
2912
|
-
var DocsLink =
|
|
2913
|
-
({ href = "https://docs.lessly.com", label = "Docs", showLeadingIcon = true, className, ...props }, ref) => /* @__PURE__ */
|
|
2993
|
+
import { jsx as jsx56, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
2994
|
+
var DocsLink = React46.forwardRef(
|
|
2995
|
+
({ href = "https://docs.lessly.com", label = "Docs", showLeadingIcon = true, className, ...props }, ref) => /* @__PURE__ */ jsxs31(
|
|
2914
2996
|
"a",
|
|
2915
2997
|
{
|
|
2916
2998
|
ref,
|
|
@@ -2923,9 +3005,9 @@ var DocsLink = React45.forwardRef(
|
|
|
2923
3005
|
),
|
|
2924
3006
|
...props,
|
|
2925
3007
|
children: [
|
|
2926
|
-
showLeadingIcon && /* @__PURE__ */
|
|
3008
|
+
showLeadingIcon && /* @__PURE__ */ jsx56(BookOpen, { className: "size-4", "aria-hidden": "true" }),
|
|
2927
3009
|
label,
|
|
2928
|
-
/* @__PURE__ */
|
|
3010
|
+
/* @__PURE__ */ jsx56(ExternalLink, { className: "size-3 text-text-tertiary", "aria-hidden": "true" })
|
|
2929
3011
|
]
|
|
2930
3012
|
}
|
|
2931
3013
|
)
|
|
@@ -2933,28 +3015,28 @@ var DocsLink = React45.forwardRef(
|
|
|
2933
3015
|
DocsLink.displayName = "DocsLink";
|
|
2934
3016
|
|
|
2935
3017
|
// src/components/empty-state.tsx
|
|
2936
|
-
import * as
|
|
2937
|
-
import { jsx as
|
|
2938
|
-
var EmptyState =
|
|
2939
|
-
({ icon: Icon, title, titleAs: TitleTag = "p", description, action, className, ...props }, ref) => /* @__PURE__ */
|
|
2940
|
-
Icon && /* @__PURE__ */
|
|
2941
|
-
/* @__PURE__ */
|
|
2942
|
-
description && /* @__PURE__ */
|
|
2943
|
-
action && /* @__PURE__ */
|
|
3018
|
+
import * as React47 from "react";
|
|
3019
|
+
import { jsx as jsx57, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
3020
|
+
var EmptyState = React47.forwardRef(
|
|
3021
|
+
({ icon: Icon, title, titleAs: TitleTag = "p", description, action, className, ...props }, ref) => /* @__PURE__ */ jsxs32("div", { ref, className: cn("flex flex-col items-center px-4 py-10 text-center", className), ...props, children: [
|
|
3022
|
+
Icon && /* @__PURE__ */ jsx57(Icon, { className: "mb-3 size-6 text-text-tertiary", "aria-hidden": "true" }),
|
|
3023
|
+
/* @__PURE__ */ jsx57(TitleTag, { className: "text-sm text-text-secondary", children: title }),
|
|
3024
|
+
description && /* @__PURE__ */ jsx57("p", { className: "mt-1 max-w-sm text-sm text-text-tertiary", children: description }),
|
|
3025
|
+
action && /* @__PURE__ */ jsx57("div", { className: "mt-3", children: action })
|
|
2944
3026
|
] })
|
|
2945
3027
|
);
|
|
2946
3028
|
EmptyState.displayName = "EmptyState";
|
|
2947
3029
|
|
|
2948
3030
|
// src/components/copy-button.tsx
|
|
2949
|
-
import * as
|
|
3031
|
+
import * as React48 from "react";
|
|
2950
3032
|
import { Check as Check7, Copy } from "lucide-react";
|
|
2951
|
-
import { jsx as
|
|
3033
|
+
import { jsx as jsx58, jsxs as jsxs33 } from "react/jsx-runtime";
|
|
2952
3034
|
var MASK = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
2953
|
-
var CopyButton =
|
|
3035
|
+
var CopyButton = React48.forwardRef(
|
|
2954
3036
|
({ value, label = "Copy", masked = false, className, variant = "ghost", size = "icon", onClick, ...props }, ref) => {
|
|
2955
|
-
const [copied, setCopied] =
|
|
2956
|
-
const timer =
|
|
2957
|
-
|
|
3037
|
+
const [copied, setCopied] = React48.useState(false);
|
|
3038
|
+
const timer = React48.useRef(void 0);
|
|
3039
|
+
React48.useEffect(() => () => clearTimeout(timer.current), []);
|
|
2958
3040
|
const handleClick = async (e) => {
|
|
2959
3041
|
onClick?.(e);
|
|
2960
3042
|
if (!navigator.clipboard?.writeText) return;
|
|
@@ -2972,7 +3054,7 @@ var CopyButton = React47.forwardRef(
|
|
|
2972
3054
|
// itself at the height `size` already declares instead of taking a label's padding. At the
|
|
2973
3055
|
// default `size="icon"` that is the same 40px square it always was; at `xs`/`sm` it is now
|
|
2974
3056
|
// square rather than a wide pill (#432).
|
|
2975
|
-
/* @__PURE__ */
|
|
3057
|
+
/* @__PURE__ */ jsx58(
|
|
2976
3058
|
Button,
|
|
2977
3059
|
{
|
|
2978
3060
|
ref,
|
|
@@ -2983,13 +3065,13 @@ var CopyButton = React47.forwardRef(
|
|
|
2983
3065
|
className: cn(className),
|
|
2984
3066
|
...props,
|
|
2985
3067
|
"aria-label": copied ? "Copied" : masked ? `${label} ending ${tail}` : label,
|
|
2986
|
-
icon: copied ? /* @__PURE__ */
|
|
3068
|
+
icon: copied ? /* @__PURE__ */ jsx58(Check7, { className: "text-text-success" }) : /* @__PURE__ */ jsx58(Copy, {})
|
|
2987
3069
|
}
|
|
2988
3070
|
)
|
|
2989
3071
|
);
|
|
2990
3072
|
if (!masked) return button;
|
|
2991
|
-
return /* @__PURE__ */
|
|
2992
|
-
/* @__PURE__ */
|
|
3073
|
+
return /* @__PURE__ */ jsxs33("span", { className: "inline-flex items-center gap-1.5", children: [
|
|
3074
|
+
/* @__PURE__ */ jsx58("code", { "aria-hidden": true, className: "font-mono text-xs text-text-tertiary", children: `${MASK}${tail}` }),
|
|
2993
3075
|
button
|
|
2994
3076
|
] });
|
|
2995
3077
|
}
|
|
@@ -2997,9 +3079,9 @@ var CopyButton = React47.forwardRef(
|
|
|
2997
3079
|
CopyButton.displayName = "CopyButton";
|
|
2998
3080
|
|
|
2999
3081
|
// src/components/stat-card.tsx
|
|
3000
|
-
import * as
|
|
3082
|
+
import * as React49 from "react";
|
|
3001
3083
|
import { ArrowDown, ArrowUp, Info as Info2, Minus as Minus2 } from "lucide-react";
|
|
3002
|
-
import { jsx as
|
|
3084
|
+
import { jsx as jsx59, jsxs as jsxs34 } from "react/jsx-runtime";
|
|
3003
3085
|
var directionIcons = {
|
|
3004
3086
|
up: ArrowUp,
|
|
3005
3087
|
down: ArrowDown,
|
|
@@ -3015,37 +3097,39 @@ var toneFromDirection = {
|
|
|
3015
3097
|
down: "negative",
|
|
3016
3098
|
neutral: "neutral"
|
|
3017
3099
|
};
|
|
3018
|
-
var StatCard =
|
|
3019
|
-
({ label, value, delta, hint, sub, icon: Icon, className, ...props }, ref) => {
|
|
3100
|
+
var StatCard = React49.forwardRef(
|
|
3101
|
+
({ label, value, delta, hint, sub, icon: Icon, trend, className, ...props }, ref) => {
|
|
3020
3102
|
const direction = delta?.direction ?? "neutral";
|
|
3021
3103
|
const tone = delta?.tone ?? toneFromDirection[direction];
|
|
3022
3104
|
const DeltaIcon = directionIcons[direction];
|
|
3023
3105
|
const deltaClass = toneClasses[tone];
|
|
3024
|
-
return /* @__PURE__ */
|
|
3106
|
+
return /* @__PURE__ */ jsxs34(
|
|
3025
3107
|
"div",
|
|
3026
3108
|
{
|
|
3027
3109
|
ref,
|
|
3028
|
-
|
|
3110
|
+
"data-slot": "stat-card",
|
|
3111
|
+
className: cn("rounded-xl border border-border-subtle bg-bg-overlay p-5", className),
|
|
3029
3112
|
...props,
|
|
3030
3113
|
children: [
|
|
3031
|
-
/* @__PURE__ */
|
|
3032
|
-
/* @__PURE__ */
|
|
3033
|
-
/* @__PURE__ */
|
|
3034
|
-
hint && /* @__PURE__ */
|
|
3035
|
-
/* @__PURE__ */
|
|
3036
|
-
/* @__PURE__ */
|
|
3114
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center justify-between gap-2", children: [
|
|
3115
|
+
/* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-1.5", children: [
|
|
3116
|
+
/* @__PURE__ */ jsx59("span", { className: "text-xs font-medium text-text-tertiary", children: label }),
|
|
3117
|
+
hint && /* @__PURE__ */ jsx59(TooltipProvider, { children: /* @__PURE__ */ jsxs34(Tooltip, { children: [
|
|
3118
|
+
/* @__PURE__ */ jsx59(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx59("button", { type: "button", "aria-label": "More info", className: "inline-flex cursor-pointer text-icon-secondary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus rounded-sm", children: /* @__PURE__ */ jsx59(Info2, { className: "size-3.5", "aria-hidden": "true" }) }) }),
|
|
3119
|
+
/* @__PURE__ */ jsx59(TooltipContent, { children: hint })
|
|
3037
3120
|
] }) })
|
|
3038
3121
|
] }),
|
|
3039
|
-
Icon && /* @__PURE__ */
|
|
3122
|
+
Icon && /* @__PURE__ */ jsx59(Icon, { className: "size-4 text-icon-secondary", "aria-hidden": "true" })
|
|
3040
3123
|
] }),
|
|
3041
|
-
/* @__PURE__ */
|
|
3042
|
-
(delta || sub) && /* @__PURE__ */
|
|
3043
|
-
delta && /* @__PURE__ */
|
|
3044
|
-
/* @__PURE__ */
|
|
3124
|
+
/* @__PURE__ */ jsx59("div", { className: "mt-2 text-3xl font-semibold text-text-primary", children: value }),
|
|
3125
|
+
(delta || sub) && /* @__PURE__ */ jsxs34("div", { className: "mt-2 flex items-center gap-2 text-sm", children: [
|
|
3126
|
+
delta && /* @__PURE__ */ jsxs34("span", { className: cn("inline-flex items-center gap-0.5 font-medium", deltaClass), children: [
|
|
3127
|
+
/* @__PURE__ */ jsx59(DeltaIcon, { className: "size-3.5", "aria-hidden": "true" }),
|
|
3045
3128
|
delta.value
|
|
3046
3129
|
] }),
|
|
3047
|
-
sub && /* @__PURE__ */
|
|
3048
|
-
] })
|
|
3130
|
+
sub && /* @__PURE__ */ jsx59("span", { className: "text-text-tertiary", children: sub })
|
|
3131
|
+
] }),
|
|
3132
|
+
trend !== void 0 && /* @__PURE__ */ jsx59("div", { "data-slot": "stat-card-trend", className: "mt-3 min-h-10", children: trend })
|
|
3049
3133
|
]
|
|
3050
3134
|
}
|
|
3051
3135
|
);
|
|
@@ -3054,17 +3138,17 @@ var StatCard = React48.forwardRef(
|
|
|
3054
3138
|
StatCard.displayName = "StatCard";
|
|
3055
3139
|
|
|
3056
3140
|
// src/components/confirm-dialog.tsx
|
|
3057
|
-
import * as
|
|
3141
|
+
import * as React51 from "react";
|
|
3058
3142
|
import { Loader2 as Loader22 } from "lucide-react";
|
|
3059
3143
|
|
|
3060
3144
|
// src/components/step-up-challenge.tsx
|
|
3061
|
-
import * as
|
|
3145
|
+
import * as React50 from "react";
|
|
3062
3146
|
import { Fingerprint, Loader2 } from "lucide-react";
|
|
3063
|
-
import { jsx as
|
|
3147
|
+
import { jsx as jsx60, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3064
3148
|
var DEFAULT_METHODS = ["passkey", "code"];
|
|
3065
3149
|
var ATTEMPT_GAP_MS = 500;
|
|
3066
|
-
var FACTOR_SWITCH = "w-fit rounded-sm text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50";
|
|
3067
|
-
var StepUpChallenge =
|
|
3150
|
+
var FACTOR_SWITCH = "w-fit cursor-pointer rounded-sm text-sm text-text-secondary underline-offset-2 hover:text-text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus disabled:pointer-events-none disabled:opacity-50";
|
|
3151
|
+
var StepUpChallenge = React50.forwardRef((props, ref) => {
|
|
3068
3152
|
const {
|
|
3069
3153
|
methods,
|
|
3070
3154
|
defaultMethod,
|
|
@@ -3084,28 +3168,28 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3084
3168
|
const offered = methods && methods.length > 0 ? methods : DEFAULT_METHODS;
|
|
3085
3169
|
const first = offered[0] ?? "passkey";
|
|
3086
3170
|
const initial = defaultMethod && offered.includes(defaultMethod) ? defaultMethod : first;
|
|
3087
|
-
const [method, setMethod] =
|
|
3088
|
-
const [code, setCode] =
|
|
3089
|
-
const [errorFactor, setErrorFactor] =
|
|
3090
|
-
const [attempted, setAttempted] =
|
|
3091
|
-
const fieldRef =
|
|
3092
|
-
const mounted =
|
|
3093
|
-
const pending =
|
|
3094
|
-
const attemptedAt =
|
|
3171
|
+
const [method, setMethod] = React50.useState(initial);
|
|
3172
|
+
const [code, setCode] = React50.useState("");
|
|
3173
|
+
const [errorFactor, setErrorFactor] = React50.useState(initial);
|
|
3174
|
+
const [attempted, setAttempted] = React50.useState(false);
|
|
3175
|
+
const fieldRef = React50.useRef(null);
|
|
3176
|
+
const mounted = React50.useRef(false);
|
|
3177
|
+
const pending = React50.useRef(false);
|
|
3178
|
+
const attemptedAt = React50.useRef(0);
|
|
3095
3179
|
const active = offered.includes(method) ? method : first;
|
|
3096
3180
|
const other = offered.find((m) => m !== active);
|
|
3097
3181
|
const showError = Boolean(error) && errorFactor === active;
|
|
3098
|
-
const reactId =
|
|
3182
|
+
const reactId = React50.useId();
|
|
3099
3183
|
const fieldId = `${reactId}-code`;
|
|
3100
3184
|
const errorId = `${reactId}-error`;
|
|
3101
|
-
|
|
3185
|
+
React50.useEffect(() => {
|
|
3102
3186
|
pending.current = false;
|
|
3103
3187
|
}, [verifying, error]);
|
|
3104
|
-
|
|
3188
|
+
React50.useEffect(() => {
|
|
3105
3189
|
if (!error) return;
|
|
3106
3190
|
fieldRef.current?.focus();
|
|
3107
3191
|
}, [error]);
|
|
3108
|
-
|
|
3192
|
+
React50.useEffect(() => {
|
|
3109
3193
|
if (!mounted.current) {
|
|
3110
3194
|
mounted.current = true;
|
|
3111
3195
|
return;
|
|
@@ -3140,7 +3224,7 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3140
3224
|
const stopCodeBearingEvent = (event) => {
|
|
3141
3225
|
event.stopPropagation();
|
|
3142
3226
|
};
|
|
3143
|
-
return /* @__PURE__ */
|
|
3227
|
+
return /* @__PURE__ */ jsxs35(
|
|
3144
3228
|
"div",
|
|
3145
3229
|
{
|
|
3146
3230
|
...rest,
|
|
@@ -3148,15 +3232,15 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3148
3232
|
"aria-busy": verifying || void 0,
|
|
3149
3233
|
className: cn("grid gap-4", className),
|
|
3150
3234
|
children: [
|
|
3151
|
-
active === "passkey" ? /* @__PURE__ */
|
|
3152
|
-
/* @__PURE__ */
|
|
3153
|
-
/* @__PURE__ */
|
|
3235
|
+
active === "passkey" ? /* @__PURE__ */ jsxs35("div", { className: "grid justify-items-start gap-2", children: [
|
|
3236
|
+
/* @__PURE__ */ jsx60(Fingerprint, { className: "size-5 text-text-secondary", "aria-hidden": "true" }),
|
|
3237
|
+
/* @__PURE__ */ jsx60("p", { className: "text-sm text-text-secondary", children: "Your device will ask for your fingerprint, face or PIN." }),
|
|
3154
3238
|
other === "code" && // Not a `Button` (Guidelines/When it isn't a Button): a `Button` here would read as a
|
|
3155
3239
|
// second action competing with the confirm below.
|
|
3156
|
-
/* @__PURE__ */
|
|
3157
|
-
] }) : /* @__PURE__ */
|
|
3158
|
-
/* @__PURE__ */
|
|
3159
|
-
/* @__PURE__ */
|
|
3240
|
+
/* @__PURE__ */ jsx60("button", { type: "button", className: FACTOR_SWITCH, disabled: verifying, onClick: () => switchTo("code"), children: `Use a ${codeLength}-digit code instead` })
|
|
3241
|
+
] }) : /* @__PURE__ */ jsxs35("div", { className: "grid justify-items-start gap-2", children: [
|
|
3242
|
+
/* @__PURE__ */ jsx60("label", { htmlFor: fieldId, className: "text-sm font-medium text-text-primary", children: `${codeLength}-digit code` }),
|
|
3243
|
+
/* @__PURE__ */ jsx60(
|
|
3160
3244
|
"div",
|
|
3161
3245
|
{
|
|
3162
3246
|
"data-sensitive": "one-time-code",
|
|
@@ -3169,7 +3253,7 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3169
3253
|
onDrop: stopCodeBearingEvent,
|
|
3170
3254
|
onKeyDown: stopCodeBearingKey,
|
|
3171
3255
|
onKeyUp: stopCodeBearingKey,
|
|
3172
|
-
children: /* @__PURE__ */
|
|
3256
|
+
children: /* @__PURE__ */ jsx60(
|
|
3173
3257
|
InputOTP,
|
|
3174
3258
|
{
|
|
3175
3259
|
ref: fieldRef,
|
|
@@ -3190,18 +3274,18 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3190
3274
|
event.preventDefault();
|
|
3191
3275
|
submit();
|
|
3192
3276
|
},
|
|
3193
|
-
children: /* @__PURE__ */
|
|
3277
|
+
children: /* @__PURE__ */ jsx60(InputOTPGroup, { children: Array.from({ length: codeLength }, (_, index) => /* @__PURE__ */ jsx60(InputOTPSlot, { index }, index)) })
|
|
3194
3278
|
}
|
|
3195
3279
|
)
|
|
3196
3280
|
}
|
|
3197
3281
|
),
|
|
3198
3282
|
other === "passkey" && // The mirror of the line in the passkey pane — see the note there.
|
|
3199
|
-
/* @__PURE__ */
|
|
3283
|
+
/* @__PURE__ */ jsx60("button", { type: "button", className: FACTOR_SWITCH, disabled: verifying, onClick: () => switchTo("passkey"), children: "Use a passkey instead" })
|
|
3200
3284
|
] }),
|
|
3201
|
-
showError && /* @__PURE__ */
|
|
3202
|
-
/* @__PURE__ */
|
|
3203
|
-
onBack && /* @__PURE__ */
|
|
3204
|
-
/* @__PURE__ */
|
|
3285
|
+
showError && /* @__PURE__ */ jsx60(InlineError, { id: errorId, children: error }),
|
|
3286
|
+
/* @__PURE__ */ jsxs35(DialogFooter, { children: [
|
|
3287
|
+
onBack && /* @__PURE__ */ jsx60(Button, { type: "button", variant: "outline", size: "sm", disabled: verifying, onClick: onBack, children: backLabel }),
|
|
3288
|
+
/* @__PURE__ */ jsx60(
|
|
3205
3289
|
Button,
|
|
3206
3290
|
{
|
|
3207
3291
|
type: "button",
|
|
@@ -3211,7 +3295,7 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3211
3295
|
"aria-disabled": !canSubmit || void 0,
|
|
3212
3296
|
"aria-busy": verifying || void 0,
|
|
3213
3297
|
className: cn(!canSubmit && "opacity-50"),
|
|
3214
|
-
icon: verifying ? /* @__PURE__ */
|
|
3298
|
+
icon: verifying ? /* @__PURE__ */ jsx60(Loader2, { className: "animate-spin" }) : void 0,
|
|
3215
3299
|
onClick: submit,
|
|
3216
3300
|
children: confirmLabel
|
|
3217
3301
|
}
|
|
@@ -3224,9 +3308,9 @@ var StepUpChallenge = React49.forwardRef((props, ref) => {
|
|
|
3224
3308
|
StepUpChallenge.displayName = "StepUpChallenge";
|
|
3225
3309
|
|
|
3226
3310
|
// src/components/confirm-dialog.tsx
|
|
3227
|
-
import { jsx as
|
|
3228
|
-
var InlineError =
|
|
3229
|
-
({ children, className, ...props }, ref) => /* @__PURE__ */
|
|
3311
|
+
import { jsx as jsx61, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3312
|
+
var InlineError = React51.forwardRef(
|
|
3313
|
+
({ children, className, ...props }, ref) => /* @__PURE__ */ jsx61(
|
|
3230
3314
|
"div",
|
|
3231
3315
|
{
|
|
3232
3316
|
ref,
|
|
@@ -3256,14 +3340,14 @@ function ConfirmDialog({
|
|
|
3256
3340
|
onConfirm,
|
|
3257
3341
|
onError
|
|
3258
3342
|
}) {
|
|
3259
|
-
const [internalOpen, setInternalOpen] =
|
|
3343
|
+
const [internalOpen, setInternalOpen] = React51.useState(false);
|
|
3260
3344
|
const isControlled = open !== void 0;
|
|
3261
3345
|
const actualOpen = isControlled ? open : internalOpen;
|
|
3262
|
-
const [busy, setBusy] =
|
|
3263
|
-
const [error, setError] =
|
|
3264
|
-
const [typed, setTyped] =
|
|
3265
|
-
const [stepped, setStepped] =
|
|
3266
|
-
const phraseId = `${
|
|
3346
|
+
const [busy, setBusy] = React51.useState(false);
|
|
3347
|
+
const [error, setError] = React51.useState(null);
|
|
3348
|
+
const [typed, setTyped] = React51.useState("");
|
|
3349
|
+
const [stepped, setStepped] = React51.useState(false);
|
|
3350
|
+
const phraseId = `${React51.useId()}-phrase`;
|
|
3267
3351
|
const phraseMet = !confirmPhrase || typed.trim().toLowerCase() === confirmPhrase.trim().toLowerCase();
|
|
3268
3352
|
const challenging = Boolean(stepUp) && (!confirmPhrase || stepped);
|
|
3269
3353
|
const panelTitle = challenging ? stepUp?.title ?? title : title;
|
|
@@ -3273,7 +3357,7 @@ function ConfirmDialog({
|
|
|
3273
3357
|
setTyped("");
|
|
3274
3358
|
setStepped(false);
|
|
3275
3359
|
};
|
|
3276
|
-
|
|
3360
|
+
React51.useEffect(() => {
|
|
3277
3361
|
if (!actualOpen) reset();
|
|
3278
3362
|
}, [actualOpen]);
|
|
3279
3363
|
const setOpen = (next) => {
|
|
@@ -3293,22 +3377,22 @@ function ConfirmDialog({
|
|
|
3293
3377
|
setBusy(false);
|
|
3294
3378
|
}
|
|
3295
3379
|
};
|
|
3296
|
-
return /* @__PURE__ */
|
|
3380
|
+
return /* @__PURE__ */ jsxs36(Dialog, { open: actualOpen, onOpenChange: (next) => {
|
|
3297
3381
|
if (!busy) setOpen(next);
|
|
3298
3382
|
}, children: [
|
|
3299
|
-
trigger && /* @__PURE__ */
|
|
3300
|
-
/* @__PURE__ */
|
|
3301
|
-
/* @__PURE__ */
|
|
3302
|
-
/* @__PURE__ */
|
|
3303
|
-
panelDescription && /* @__PURE__ */
|
|
3383
|
+
trigger && /* @__PURE__ */ jsx61(DialogTrigger, { asChild: true, children: trigger }),
|
|
3384
|
+
/* @__PURE__ */ jsxs36(DialogContent, { children: [
|
|
3385
|
+
/* @__PURE__ */ jsxs36(DialogHeader, { children: [
|
|
3386
|
+
/* @__PURE__ */ jsx61(DialogTitle, { children: panelTitle }),
|
|
3387
|
+
panelDescription && /* @__PURE__ */ jsx61(DialogDescription, { children: panelDescription })
|
|
3304
3388
|
] }),
|
|
3305
|
-
confirmPhrase && !challenging && /* @__PURE__ */
|
|
3306
|
-
/* @__PURE__ */
|
|
3389
|
+
confirmPhrase && !challenging && /* @__PURE__ */ jsxs36("div", { className: "grid gap-1.5", children: [
|
|
3390
|
+
/* @__PURE__ */ jsxs36("label", { htmlFor: phraseId, className: "text-xs font-medium text-text-secondary", children: [
|
|
3307
3391
|
"Type ",
|
|
3308
|
-
/* @__PURE__ */
|
|
3392
|
+
/* @__PURE__ */ jsx61("span", { className: "font-mono text-text-primary", children: confirmPhrase }),
|
|
3309
3393
|
" to confirm"
|
|
3310
3394
|
] }),
|
|
3311
|
-
/* @__PURE__ */
|
|
3395
|
+
/* @__PURE__ */ jsx61(
|
|
3312
3396
|
Input,
|
|
3313
3397
|
{
|
|
3314
3398
|
id: phraseId,
|
|
@@ -3319,8 +3403,8 @@ function ConfirmDialog({
|
|
|
3319
3403
|
}
|
|
3320
3404
|
)
|
|
3321
3405
|
] }),
|
|
3322
|
-
error && !challenging && /* @__PURE__ */
|
|
3323
|
-
challenging ? /* @__PURE__ */
|
|
3406
|
+
error && !challenging && /* @__PURE__ */ jsx61(InlineError, { children: error }),
|
|
3407
|
+
challenging ? /* @__PURE__ */ jsx61(
|
|
3324
3408
|
StepUpChallenge,
|
|
3325
3409
|
{
|
|
3326
3410
|
methods: stepUp?.methods,
|
|
@@ -3339,16 +3423,16 @@ function ConfirmDialog({
|
|
|
3339
3423
|
onVerifyPasskey: () => void handleConfirm({ method: "passkey" }),
|
|
3340
3424
|
onVerifyCode: (code) => void handleConfirm({ method: "code", code })
|
|
3341
3425
|
}
|
|
3342
|
-
) : /* @__PURE__ */
|
|
3343
|
-
/* @__PURE__ */
|
|
3344
|
-
/* @__PURE__ */
|
|
3426
|
+
) : /* @__PURE__ */ jsxs36(DialogFooter, { children: [
|
|
3427
|
+
/* @__PURE__ */ jsx61(Button, { variant: "outline", disabled: busy, onClick: () => setOpen(false), children: cancelLabel }),
|
|
3428
|
+
/* @__PURE__ */ jsxs36(
|
|
3345
3429
|
Button,
|
|
3346
3430
|
{
|
|
3347
3431
|
variant: destructive ? "destructive-solid" : "default",
|
|
3348
3432
|
disabled: busy || !phraseMet,
|
|
3349
3433
|
onClick: () => stepUp ? setStepped(true) : void handleConfirm(),
|
|
3350
3434
|
children: [
|
|
3351
|
-
busy && /* @__PURE__ */
|
|
3435
|
+
busy && /* @__PURE__ */ jsx61(Loader22, { className: "size-4 animate-spin", "aria-hidden": "true" }),
|
|
3352
3436
|
confirmLabel
|
|
3353
3437
|
]
|
|
3354
3438
|
}
|
|
@@ -3359,59 +3443,81 @@ function ConfirmDialog({
|
|
|
3359
3443
|
}
|
|
3360
3444
|
|
|
3361
3445
|
// src/components/user-menu.tsx
|
|
3446
|
+
import * as React52 from "react";
|
|
3362
3447
|
import { ChevronsUpDown } from "lucide-react";
|
|
3363
|
-
import { Fragment as
|
|
3364
|
-
function UserMenu({ user, items, collapsed = false, align = "start" }) {
|
|
3448
|
+
import { Fragment as Fragment3, jsx as jsx62, jsxs as jsxs37 } from "react/jsx-runtime";
|
|
3449
|
+
function UserMenu({ user, items, collapsed = false, tooltip = true, align = "start" }) {
|
|
3450
|
+
const openedByPointer = React52.useRef(false);
|
|
3365
3451
|
const secondLine = user.subtitle ?? user.email;
|
|
3366
|
-
const avatar = /* @__PURE__ */
|
|
3367
|
-
const trigger = collapsed ?
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3452
|
+
const avatar = /* @__PURE__ */ jsx62(PersonAvatar, { name: user.name, id: user.id, src: user.avatarUrl, size: "sm" });
|
|
3453
|
+
const trigger = collapsed ? (
|
|
3454
|
+
// The plate every other mark in a top bar gets, drawn outside the avatar instead of behind it:
|
|
3455
|
+
// a round mark fills its own box, so a background under one is a background nobody sees, and
|
|
3456
|
+
// this trigger rested with no hover at all beside four icon buttons that all had one.
|
|
3457
|
+
/* @__PURE__ */ jsx62(
|
|
3458
|
+
"button",
|
|
3459
|
+
{
|
|
3460
|
+
type: "button",
|
|
3461
|
+
"aria-label": user.name,
|
|
3462
|
+
className: "cursor-pointer rounded-full ring-0 ring-bg-secondary transition-[box-shadow] duration-fast hover:ring-4 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
3463
|
+
children: avatar
|
|
3464
|
+
}
|
|
3465
|
+
)
|
|
3466
|
+
) : /* @__PURE__ */ jsxs37(
|
|
3376
3467
|
"button",
|
|
3377
3468
|
{
|
|
3378
3469
|
type: "button",
|
|
3379
|
-
className: "flex w-full items-center gap-2.5 rounded-xl px-1.5 py-[5px] text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
3470
|
+
className: "flex w-full cursor-pointer items-center gap-2.5 rounded-xl px-1.5 py-[5px] text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus",
|
|
3380
3471
|
children: [
|
|
3381
3472
|
avatar,
|
|
3382
|
-
/* @__PURE__ */
|
|
3383
|
-
/* @__PURE__ */
|
|
3384
|
-
secondLine && /* @__PURE__ */
|
|
3473
|
+
/* @__PURE__ */ jsxs37("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
3474
|
+
/* @__PURE__ */ jsx62("span", { className: "truncate text-sm leading-[normal] font-medium text-text-primary", children: user.name }),
|
|
3475
|
+
secondLine && /* @__PURE__ */ jsx62("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: secondLine })
|
|
3385
3476
|
] }),
|
|
3386
|
-
/* @__PURE__ */
|
|
3477
|
+
/* @__PURE__ */ jsx62(ChevronsUpDown, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
|
|
3387
3478
|
]
|
|
3388
3479
|
}
|
|
3389
3480
|
);
|
|
3390
|
-
const menuTrigger = /* @__PURE__ */
|
|
3391
|
-
|
|
3392
|
-
|
|
3393
|
-
|
|
3394
|
-
|
|
3481
|
+
const menuTrigger = /* @__PURE__ */ jsx62(
|
|
3482
|
+
DropdownMenuTrigger,
|
|
3483
|
+
{
|
|
3484
|
+
asChild: true,
|
|
3485
|
+
onPointerDown: () => {
|
|
3486
|
+
openedByPointer.current = true;
|
|
3487
|
+
},
|
|
3488
|
+
onKeyDown: () => {
|
|
3489
|
+
openedByPointer.current = false;
|
|
3490
|
+
},
|
|
3491
|
+
children: trigger
|
|
3492
|
+
}
|
|
3493
|
+
);
|
|
3494
|
+
const menu = /* @__PURE__ */ jsxs37(DropdownMenu, { children: [
|
|
3495
|
+
collapsed && tooltip ? /* @__PURE__ */ jsx62(TooltipProvider, { children: /* @__PURE__ */ jsxs37(Tooltip, { children: [
|
|
3496
|
+
/* @__PURE__ */ jsx62(TooltipTrigger, { asChild: true, children: menuTrigger }),
|
|
3497
|
+
/* @__PURE__ */ jsx62(TooltipContent, { side: "right", children: user.name })
|
|
3395
3498
|
] }) }) : menuTrigger,
|
|
3396
|
-
/* @__PURE__ */
|
|
3499
|
+
/* @__PURE__ */ jsxs37(
|
|
3397
3500
|
DropdownMenuContent,
|
|
3398
3501
|
{
|
|
3399
3502
|
align,
|
|
3400
3503
|
sideOffset: 6,
|
|
3504
|
+
onCloseAutoFocus: (e) => {
|
|
3505
|
+
if (openedByPointer.current) e.preventDefault();
|
|
3506
|
+
},
|
|
3401
3507
|
className: "flex w-[var(--radix-dropdown-menu-trigger-width)] min-w-56 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
|
|
3402
3508
|
children: [
|
|
3403
|
-
/* @__PURE__ */
|
|
3404
|
-
/* @__PURE__ */
|
|
3405
|
-
collapsed && secondLine && /* @__PURE__ */
|
|
3509
|
+
/* @__PURE__ */ jsxs37(DropdownMenuLabel, { className: "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary", children: [
|
|
3510
|
+
/* @__PURE__ */ jsx62("span", { className: "block truncate text-sm font-medium text-text-primary", children: user.name }),
|
|
3511
|
+
collapsed && secondLine && /* @__PURE__ */ jsx62("span", { className: "block truncate text-xs font-regular text-text-tertiary", children: secondLine })
|
|
3406
3512
|
] }),
|
|
3407
|
-
/* @__PURE__ */
|
|
3513
|
+
/* @__PURE__ */ jsx62(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
|
|
3408
3514
|
items.map((item, i) => {
|
|
3409
3515
|
const Icon = item.icon;
|
|
3410
|
-
const content = /* @__PURE__ */
|
|
3411
|
-
Icon && /* @__PURE__ */
|
|
3516
|
+
const content = /* @__PURE__ */ jsxs37(Fragment3, { children: [
|
|
3517
|
+
Icon && /* @__PURE__ */ jsx62(Icon, { className: "size-4", "aria-hidden": "true" }),
|
|
3412
3518
|
item.label
|
|
3413
3519
|
] });
|
|
3414
|
-
return /* @__PURE__ */
|
|
3520
|
+
return /* @__PURE__ */ jsx62(
|
|
3415
3521
|
DropdownMenuItem,
|
|
3416
3522
|
{
|
|
3417
3523
|
onSelect: item.onSelect,
|
|
@@ -3420,7 +3526,7 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
|
|
|
3420
3526
|
item.destructive && "text-text-danger focus:text-text-danger"
|
|
3421
3527
|
),
|
|
3422
3528
|
asChild: Boolean(item.href),
|
|
3423
|
-
children: item.href ? /* @__PURE__ */
|
|
3529
|
+
children: item.href ? /* @__PURE__ */ jsx62("a", { href: item.href, children: content }) : content
|
|
3424
3530
|
},
|
|
3425
3531
|
`${item.label}-${i}`
|
|
3426
3532
|
);
|
|
@@ -3433,10 +3539,10 @@ function UserMenu({ user, items, collapsed = false, align = "start" }) {
|
|
|
3433
3539
|
}
|
|
3434
3540
|
|
|
3435
3541
|
// src/components/extension-icon.tsx
|
|
3436
|
-
import * as
|
|
3542
|
+
import * as React53 from "react";
|
|
3437
3543
|
import * as LucideIcons from "lucide-react";
|
|
3438
3544
|
import { Puzzle } from "lucide-react";
|
|
3439
|
-
import { jsx as
|
|
3545
|
+
import { jsx as jsx63 } from "react/jsx-runtime";
|
|
3440
3546
|
var FORWARD_REF = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
3441
3547
|
var catalog = LucideIcons;
|
|
3442
3548
|
function toPascalCase(name) {
|
|
@@ -3461,22 +3567,22 @@ function warnUnknownIconOnce(name) {
|
|
|
3461
3567
|
warnedUnknownIcons.add(name);
|
|
3462
3568
|
console.warn(`[@lessly/ui] ExtensionIcon: unknown icon "${name}" \u2014 falling back to Puzzle.`);
|
|
3463
3569
|
}
|
|
3464
|
-
var ExtensionIcon =
|
|
3570
|
+
var ExtensionIcon = React53.forwardRef(
|
|
3465
3571
|
({ name, ...props }, ref) => {
|
|
3466
3572
|
const Icon = resolveIcon(name);
|
|
3467
3573
|
if (!Icon) {
|
|
3468
3574
|
warnUnknownIconOnce(name);
|
|
3469
|
-
return /* @__PURE__ */
|
|
3575
|
+
return /* @__PURE__ */ jsx63(Puzzle, { ref, ...props, "data-icon-fallback": name });
|
|
3470
3576
|
}
|
|
3471
|
-
return /* @__PURE__ */
|
|
3577
|
+
return /* @__PURE__ */ jsx63(Icon, { ref, ...props });
|
|
3472
3578
|
}
|
|
3473
3579
|
);
|
|
3474
3580
|
ExtensionIcon.displayName = "ExtensionIcon";
|
|
3475
3581
|
|
|
3476
3582
|
// src/components/icon-hint.tsx
|
|
3477
|
-
import * as
|
|
3478
|
-
import { jsx as
|
|
3479
|
-
var IconHint =
|
|
3583
|
+
import * as React54 from "react";
|
|
3584
|
+
import { jsx as jsx64, jsxs as jsxs38 } from "react/jsx-runtime";
|
|
3585
|
+
var IconHint = React54.forwardRef(
|
|
3480
3586
|
({ children, label, side = "top", align = "center", className, ...props }, ref) => {
|
|
3481
3587
|
if (label.trim().length === 0) {
|
|
3482
3588
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -3484,7 +3590,7 @@ var IconHint = React52.forwardRef(
|
|
|
3484
3590
|
'[IconHint] `label` is blank: there is no name to expose and no sentence to show, and a focusable role="img" with no name is a WCAG 4.1.2 failure. Rendering the glyph as decorative instead \u2014 pass a sentence, or use DecorativeIcon if it needs none.'
|
|
3485
3591
|
);
|
|
3486
3592
|
}
|
|
3487
|
-
return /* @__PURE__ */
|
|
3593
|
+
return /* @__PURE__ */ jsx64(
|
|
3488
3594
|
"span",
|
|
3489
3595
|
{
|
|
3490
3596
|
ref,
|
|
@@ -3498,8 +3604,8 @@ var IconHint = React52.forwardRef(
|
|
|
3498
3604
|
}
|
|
3499
3605
|
);
|
|
3500
3606
|
}
|
|
3501
|
-
return /* @__PURE__ */
|
|
3502
|
-
/* @__PURE__ */
|
|
3607
|
+
return /* @__PURE__ */ jsxs38(Tooltip, { children: [
|
|
3608
|
+
/* @__PURE__ */ jsx64(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx64(
|
|
3503
3609
|
"span",
|
|
3504
3610
|
{
|
|
3505
3611
|
ref,
|
|
@@ -3516,16 +3622,16 @@ var IconHint = React52.forwardRef(
|
|
|
3516
3622
|
children
|
|
3517
3623
|
}
|
|
3518
3624
|
) }),
|
|
3519
|
-
/* @__PURE__ */
|
|
3625
|
+
/* @__PURE__ */ jsx64(TooltipContent, { side, align, "aria-hidden": true, children: label })
|
|
3520
3626
|
] });
|
|
3521
3627
|
}
|
|
3522
3628
|
);
|
|
3523
3629
|
IconHint.displayName = "IconHint";
|
|
3524
3630
|
|
|
3525
3631
|
// src/components/decorative-icon.tsx
|
|
3526
|
-
import * as
|
|
3527
|
-
import { jsx as
|
|
3528
|
-
var DecorativeIcon =
|
|
3632
|
+
import * as React55 from "react";
|
|
3633
|
+
import { jsx as jsx65, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
3634
|
+
var DecorativeIcon = React55.forwardRef(
|
|
3529
3635
|
({ children, label, side = "top", align = "center", className, ...props }, ref) => {
|
|
3530
3636
|
if (label.trim().length === 0) {
|
|
3531
3637
|
if (process.env.NODE_ENV !== "production") {
|
|
@@ -3533,7 +3639,7 @@ var DecorativeIcon = React53.forwardRef(
|
|
|
3533
3639
|
"[DecorativeIcon] `label` is blank, so the tooltip would open on an empty bubble. Rendering the bare glyph instead \u2014 pass a sentence, or drop the wrapper if the glyph has nothing to add."
|
|
3534
3640
|
);
|
|
3535
3641
|
}
|
|
3536
|
-
return /* @__PURE__ */
|
|
3642
|
+
return /* @__PURE__ */ jsx65(
|
|
3537
3643
|
"span",
|
|
3538
3644
|
{
|
|
3539
3645
|
ref,
|
|
@@ -3547,8 +3653,8 @@ var DecorativeIcon = React53.forwardRef(
|
|
|
3547
3653
|
}
|
|
3548
3654
|
);
|
|
3549
3655
|
}
|
|
3550
|
-
return /* @__PURE__ */
|
|
3551
|
-
/* @__PURE__ */
|
|
3656
|
+
return /* @__PURE__ */ jsxs39(Tooltip, { children: [
|
|
3657
|
+
/* @__PURE__ */ jsx65(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx65(
|
|
3552
3658
|
"span",
|
|
3553
3659
|
{
|
|
3554
3660
|
ref,
|
|
@@ -3564,15 +3670,15 @@ var DecorativeIcon = React53.forwardRef(
|
|
|
3564
3670
|
children
|
|
3565
3671
|
}
|
|
3566
3672
|
) }),
|
|
3567
|
-
/* @__PURE__ */
|
|
3673
|
+
/* @__PURE__ */ jsx65(TooltipContent, { side, align, "aria-hidden": true, children: label })
|
|
3568
3674
|
] });
|
|
3569
3675
|
}
|
|
3570
3676
|
);
|
|
3571
3677
|
DecorativeIcon.displayName = "DecorativeIcon";
|
|
3572
3678
|
|
|
3573
3679
|
// src/components/image-cropper.tsx
|
|
3574
|
-
import * as
|
|
3575
|
-
import { Fragment as
|
|
3680
|
+
import * as React56 from "react";
|
|
3681
|
+
import { Fragment as Fragment4, jsx as jsx66, jsxs as jsxs40 } from "react/jsx-runtime";
|
|
3576
3682
|
var FALLBACK_STAGE_W = 360;
|
|
3577
3683
|
var FALLBACK_STAGE_H = 270;
|
|
3578
3684
|
var STEP = 8;
|
|
@@ -3605,7 +3711,7 @@ var MASK_CLASS = {
|
|
|
3605
3711
|
circle: "rounded-full"
|
|
3606
3712
|
};
|
|
3607
3713
|
var clampTo = (value, min, max) => Math.min(Math.max(value, min), max);
|
|
3608
|
-
var ImageCropper =
|
|
3714
|
+
var ImageCropper = React56.forwardRef(
|
|
3609
3715
|
({
|
|
3610
3716
|
src,
|
|
3611
3717
|
shape = "square",
|
|
@@ -3625,21 +3731,21 @@ var ImageCropper = React54.forwardRef(
|
|
|
3625
3731
|
className,
|
|
3626
3732
|
...props
|
|
3627
3733
|
}, ref) => {
|
|
3628
|
-
const [nat, setNat] =
|
|
3629
|
-
const [error, setError] =
|
|
3630
|
-
const [focused, setFocused] =
|
|
3631
|
-
const [stage, setStage] =
|
|
3632
|
-
const [crop, setCrop] =
|
|
3633
|
-
const imgRef =
|
|
3634
|
-
const stageRef =
|
|
3635
|
-
const framed =
|
|
3636
|
-
const inset =
|
|
3637
|
-
|
|
3734
|
+
const [nat, setNat] = React56.useState(null);
|
|
3735
|
+
const [error, setError] = React56.useState(null);
|
|
3736
|
+
const [focused, setFocused] = React56.useState(false);
|
|
3737
|
+
const [stage, setStage] = React56.useState({ w: FALLBACK_STAGE_W, h: FALLBACK_STAGE_H });
|
|
3738
|
+
const [crop, setCrop] = React56.useState({ x: 0, y: 0, size: 0 });
|
|
3739
|
+
const imgRef = React56.useRef(null);
|
|
3740
|
+
const stageRef = React56.useRef(null);
|
|
3741
|
+
const framed = React56.useRef(false);
|
|
3742
|
+
const inset = React56.useRef({ left: 0, top: 0 });
|
|
3743
|
+
React56.useEffect(() => {
|
|
3638
3744
|
framed.current = false;
|
|
3639
3745
|
setNat(null);
|
|
3640
3746
|
setError(null);
|
|
3641
3747
|
}, [src]);
|
|
3642
|
-
|
|
3748
|
+
React56.useLayoutEffect(() => {
|
|
3643
3749
|
const el = stageRef.current;
|
|
3644
3750
|
if (!el) return void 0;
|
|
3645
3751
|
const read = (entry) => {
|
|
@@ -3665,13 +3771,13 @@ var ImageCropper = React54.forwardRef(
|
|
|
3665
3771
|
const drawH = nat ? nat.h * fit : stage.h;
|
|
3666
3772
|
const padX = (stage.w - drawW) / 2;
|
|
3667
3773
|
const padY = (stage.h - drawH) / 2;
|
|
3668
|
-
|
|
3774
|
+
React56.useEffect(() => {
|
|
3669
3775
|
if (!nat || framed.current) return;
|
|
3670
3776
|
framed.current = true;
|
|
3671
3777
|
const size = Math.min(nat.w, nat.h);
|
|
3672
3778
|
setCrop({ x: (nat.w - size) / 2, y: (nat.h - size) / 2, size });
|
|
3673
3779
|
}, [nat]);
|
|
3674
|
-
const clampCrop =
|
|
3780
|
+
const clampCrop = React56.useCallback(
|
|
3675
3781
|
(x, y, size) => {
|
|
3676
3782
|
if (!nat) return { x, y, size };
|
|
3677
3783
|
const max = Math.min(nat.w, nat.h);
|
|
@@ -3681,8 +3787,8 @@ var ImageCropper = React54.forwardRef(
|
|
|
3681
3787
|
},
|
|
3682
3788
|
[nat, fit, minCropSize]
|
|
3683
3789
|
);
|
|
3684
|
-
const moving =
|
|
3685
|
-
const resizing =
|
|
3790
|
+
const moving = React56.useRef(null);
|
|
3791
|
+
const resizing = React56.useRef(null);
|
|
3686
3792
|
const onMoveDown = (e) => {
|
|
3687
3793
|
e.target.setPointerCapture(e.pointerId);
|
|
3688
3794
|
moving.current = { px: e.clientX, py: e.clientY, cx: crop.x, cy: crop.y };
|
|
@@ -3799,8 +3905,8 @@ var ImageCropper = React54.forwardRef(
|
|
|
3799
3905
|
const percent = nat ? Math.round(crop.size / Math.min(nat.w, nat.h) * 100) : 100;
|
|
3800
3906
|
const fromLeft = nat ? Math.round(crop.x / nat.w * 100) : 0;
|
|
3801
3907
|
const fromTop = nat ? Math.round(crop.y / nat.h * 100) : 0;
|
|
3802
|
-
return /* @__PURE__ */
|
|
3803
|
-
/* @__PURE__ */
|
|
3908
|
+
return /* @__PURE__ */ jsxs40("div", { ref, className: cn("flex flex-col gap-3", className), ...props, children: [
|
|
3909
|
+
/* @__PURE__ */ jsxs40(
|
|
3804
3910
|
"div",
|
|
3805
3911
|
{
|
|
3806
3912
|
ref: stageRef,
|
|
@@ -3809,7 +3915,7 @@ var ImageCropper = React54.forwardRef(
|
|
|
3809
3915
|
onPointerMove,
|
|
3810
3916
|
onPointerUp,
|
|
3811
3917
|
children: [
|
|
3812
|
-
/* @__PURE__ */
|
|
3918
|
+
/* @__PURE__ */ jsx66(
|
|
3813
3919
|
"img",
|
|
3814
3920
|
{
|
|
3815
3921
|
ref: imgRef,
|
|
@@ -3822,8 +3928,8 @@ var ImageCropper = React54.forwardRef(
|
|
|
3822
3928
|
className: "pointer-events-none absolute inset-0 size-full object-contain"
|
|
3823
3929
|
}
|
|
3824
3930
|
),
|
|
3825
|
-
!nat && !error && /* @__PURE__ */
|
|
3826
|
-
error === "load" && /* @__PURE__ */
|
|
3931
|
+
!nat && !error && /* @__PURE__ */ jsx66("div", { className: "absolute inset-0 flex items-center justify-center text-sm text-text-tertiary", children: "Loading\u2026" }),
|
|
3932
|
+
error === "load" && /* @__PURE__ */ jsx66(
|
|
3827
3933
|
"div",
|
|
3828
3934
|
{
|
|
3829
3935
|
role: "alert",
|
|
@@ -3831,8 +3937,8 @@ var ImageCropper = React54.forwardRef(
|
|
|
3831
3937
|
children: errorMessage
|
|
3832
3938
|
}
|
|
3833
3939
|
),
|
|
3834
|
-
nat && error !== "load" && /* @__PURE__ */
|
|
3835
|
-
/* @__PURE__ */
|
|
3940
|
+
nat && error !== "load" && /* @__PURE__ */ jsxs40(Fragment4, { children: [
|
|
3941
|
+
/* @__PURE__ */ jsx66(
|
|
3836
3942
|
"div",
|
|
3837
3943
|
{
|
|
3838
3944
|
tabIndex: 0,
|
|
@@ -3854,15 +3960,15 @@ var ImageCropper = React54.forwardRef(
|
|
|
3854
3960
|
cursor: "move",
|
|
3855
3961
|
boxShadow: (focused ? FOCUS_SHADOW : "") + RING_SHADOW
|
|
3856
3962
|
},
|
|
3857
|
-
children: /* @__PURE__ */
|
|
3858
|
-
/* @__PURE__ */
|
|
3859
|
-
/* @__PURE__ */
|
|
3860
|
-
/* @__PURE__ */
|
|
3861
|
-
/* @__PURE__ */
|
|
3963
|
+
children: /* @__PURE__ */ jsxs40("div", { className: "pointer-events-none absolute inset-0 opacity-40", children: [
|
|
3964
|
+
/* @__PURE__ */ jsx66("div", { className: "absolute left-1/3 top-0 h-full w-px bg-white/60" }),
|
|
3965
|
+
/* @__PURE__ */ jsx66("div", { className: "absolute left-2/3 top-0 h-full w-px bg-white/60" }),
|
|
3966
|
+
/* @__PURE__ */ jsx66("div", { className: "absolute left-0 top-1/3 h-px w-full bg-white/60" }),
|
|
3967
|
+
/* @__PURE__ */ jsx66("div", { className: "absolute left-0 top-2/3 h-px w-full bg-white/60" })
|
|
3862
3968
|
] })
|
|
3863
3969
|
}
|
|
3864
3970
|
),
|
|
3865
|
-
CORNERS.map((corner) => /* @__PURE__ */
|
|
3971
|
+
CORNERS.map((corner) => /* @__PURE__ */ jsx66(
|
|
3866
3972
|
"div",
|
|
3867
3973
|
{
|
|
3868
3974
|
"data-grip": corner,
|
|
@@ -3875,7 +3981,7 @@ var ImageCropper = React54.forwardRef(
|
|
|
3875
3981
|
padding: BRACKET.inset
|
|
3876
3982
|
},
|
|
3877
3983
|
onPointerDown: onResizeDown(corner),
|
|
3878
|
-
children: /* @__PURE__ */
|
|
3984
|
+
children: /* @__PURE__ */ jsx66(
|
|
3879
3985
|
"span",
|
|
3880
3986
|
{
|
|
3881
3987
|
className: "block border-solid border-white",
|
|
@@ -3897,10 +4003,10 @@ var ImageCropper = React54.forwardRef(
|
|
|
3897
4003
|
]
|
|
3898
4004
|
}
|
|
3899
4005
|
),
|
|
3900
|
-
error === "export" ? /* @__PURE__ */
|
|
3901
|
-
/* @__PURE__ */
|
|
3902
|
-
onCancel && /* @__PURE__ */
|
|
3903
|
-
/* @__PURE__ */
|
|
4006
|
+
error === "export" ? /* @__PURE__ */ jsx66("p", { role: "alert", className: "text-xs text-text-danger", children: exportErrorMessage }) : hint != null && !error ? /* @__PURE__ */ jsx66("p", { className: "text-xs text-text-tertiary", children: hint }) : null,
|
|
4007
|
+
/* @__PURE__ */ jsxs40("div", { className: "flex justify-end gap-2", children: [
|
|
4008
|
+
onCancel && /* @__PURE__ */ jsx66(Button, { type: "button", variant: "outline", size: "sm", onClick: onCancel, children: cancelLabel }),
|
|
4009
|
+
/* @__PURE__ */ jsx66(Button, { type: "button", size: "sm", onClick: save, disabled: !nat || error != null, children: saveLabel })
|
|
3904
4010
|
] })
|
|
3905
4011
|
] });
|
|
3906
4012
|
}
|
|
@@ -3908,7 +4014,7 @@ var ImageCropper = React54.forwardRef(
|
|
|
3908
4014
|
ImageCropper.displayName = "ImageCropper";
|
|
3909
4015
|
|
|
3910
4016
|
// src/components/image-crop-dialog.tsx
|
|
3911
|
-
import { jsx as
|
|
4017
|
+
import { jsx as jsx67, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
3912
4018
|
function ImageCropDialog({
|
|
3913
4019
|
open,
|
|
3914
4020
|
onOpenChange,
|
|
@@ -3919,17 +4025,17 @@ function ImageCropDialog({
|
|
|
3919
4025
|
onCrop,
|
|
3920
4026
|
...cropperProps
|
|
3921
4027
|
}) {
|
|
3922
|
-
return /* @__PURE__ */
|
|
4028
|
+
return /* @__PURE__ */ jsx67(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs41(
|
|
3923
4029
|
DialogContent,
|
|
3924
4030
|
{
|
|
3925
4031
|
className: "sm:max-w-md",
|
|
3926
4032
|
...description ? {} : { "aria-describedby": void 0 },
|
|
3927
4033
|
children: [
|
|
3928
|
-
/* @__PURE__ */
|
|
3929
|
-
/* @__PURE__ */
|
|
3930
|
-
description && /* @__PURE__ */
|
|
4034
|
+
/* @__PURE__ */ jsxs41(DialogHeader, { children: [
|
|
4035
|
+
/* @__PURE__ */ jsx67(DialogTitle, { children: title ?? `Crop ${label.toLowerCase()}` }),
|
|
4036
|
+
description && /* @__PURE__ */ jsx67(DialogDescription, { children: description })
|
|
3931
4037
|
] }),
|
|
3932
|
-
src && /* @__PURE__ */
|
|
4038
|
+
src && /* @__PURE__ */ jsx67(
|
|
3933
4039
|
ImageCropper,
|
|
3934
4040
|
{
|
|
3935
4041
|
src,
|
|
@@ -3948,9 +4054,9 @@ function ImageCropDialog({
|
|
|
3948
4054
|
ImageCropDialog.displayName = "ImageCropDialog";
|
|
3949
4055
|
|
|
3950
4056
|
// src/components/image-upload.tsx
|
|
3951
|
-
import * as
|
|
4057
|
+
import * as React57 from "react";
|
|
3952
4058
|
import { Image as ImageIcon } from "lucide-react";
|
|
3953
|
-
import { jsx as
|
|
4059
|
+
import { jsx as jsx68, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
3954
4060
|
var PREVIEW_BOX = {
|
|
3955
4061
|
sm: "size-8",
|
|
3956
4062
|
md: "size-12",
|
|
@@ -3965,7 +4071,7 @@ function formatSize(bytes) {
|
|
|
3965
4071
|
if (bytes >= 1024) return `${Math.floor(bytes / 1024)} KB`;
|
|
3966
4072
|
return `${bytes} B`;
|
|
3967
4073
|
}
|
|
3968
|
-
var ImageUpload =
|
|
4074
|
+
var ImageUpload = React57.forwardRef(
|
|
3969
4075
|
({
|
|
3970
4076
|
value,
|
|
3971
4077
|
onChange,
|
|
@@ -3988,11 +4094,11 @@ var ImageUpload = React55.forwardRef(
|
|
|
3988
4094
|
className,
|
|
3989
4095
|
...props
|
|
3990
4096
|
}, ref) => {
|
|
3991
|
-
const inputRef =
|
|
3992
|
-
const [picked, setPicked] =
|
|
3993
|
-
const [cropOpen, setCropOpen] =
|
|
3994
|
-
const [error, setError] =
|
|
3995
|
-
const pickSeq =
|
|
4097
|
+
const inputRef = React57.useRef(null);
|
|
4098
|
+
const [picked, setPicked] = React57.useState(null);
|
|
4099
|
+
const [cropOpen, setCropOpen] = React57.useState(false);
|
|
4100
|
+
const [error, setError] = React57.useState(null);
|
|
4101
|
+
const pickSeq = React57.useRef(0);
|
|
3996
4102
|
const refuse = (message) => {
|
|
3997
4103
|
setError(message);
|
|
3998
4104
|
onError?.(message);
|
|
@@ -4035,8 +4141,8 @@ var ImageUpload = React55.forwardRef(
|
|
|
4035
4141
|
reader.readAsDataURL(file);
|
|
4036
4142
|
};
|
|
4037
4143
|
const framed = value != null || fallback == null;
|
|
4038
|
-
return /* @__PURE__ */
|
|
4039
|
-
/* @__PURE__ */
|
|
4144
|
+
return /* @__PURE__ */ jsxs42("div", { ref, className: cn("flex items-start gap-3", className), ...props, children: [
|
|
4145
|
+
/* @__PURE__ */ jsx68(
|
|
4040
4146
|
"span",
|
|
4041
4147
|
{
|
|
4042
4148
|
className: cn(
|
|
@@ -4045,12 +4151,12 @@ var ImageUpload = React55.forwardRef(
|
|
|
4045
4151
|
PREVIEW_MASK[shape],
|
|
4046
4152
|
framed && "border border-border-default bg-bg-secondary text-text-secondary"
|
|
4047
4153
|
),
|
|
4048
|
-
children: value ? /* @__PURE__ */
|
|
4154
|
+
children: value ? /* @__PURE__ */ jsx68("img", { src: value, alt: `${label} preview`, className: "size-full object-cover" }) : fallback ?? /* @__PURE__ */ jsx68(ImageIcon, { className: "size-5", "aria-hidden": true })
|
|
4049
4155
|
}
|
|
4050
4156
|
),
|
|
4051
|
-
/* @__PURE__ */
|
|
4052
|
-
/* @__PURE__ */
|
|
4053
|
-
/* @__PURE__ */
|
|
4157
|
+
/* @__PURE__ */ jsxs42("div", { className: "min-w-0 flex-1", children: [
|
|
4158
|
+
/* @__PURE__ */ jsxs42("div", { className: "flex items-center gap-2", children: [
|
|
4159
|
+
/* @__PURE__ */ jsx68(
|
|
4054
4160
|
Button,
|
|
4055
4161
|
{
|
|
4056
4162
|
type: "button",
|
|
@@ -4061,7 +4167,7 @@ var ImageUpload = React55.forwardRef(
|
|
|
4061
4167
|
children: value ? changeLabel : uploadLabel
|
|
4062
4168
|
}
|
|
4063
4169
|
),
|
|
4064
|
-
value && /* @__PURE__ */
|
|
4170
|
+
value && /* @__PURE__ */ jsx68(
|
|
4065
4171
|
Button,
|
|
4066
4172
|
{
|
|
4067
4173
|
type: "button",
|
|
@@ -4076,10 +4182,10 @@ var ImageUpload = React55.forwardRef(
|
|
|
4076
4182
|
}
|
|
4077
4183
|
)
|
|
4078
4184
|
] }),
|
|
4079
|
-
hint != null && /* @__PURE__ */
|
|
4080
|
-
error && /* @__PURE__ */
|
|
4185
|
+
hint != null && /* @__PURE__ */ jsx68("p", { className: "mt-1 text-xs text-text-tertiary", children: hint }),
|
|
4186
|
+
error && /* @__PURE__ */ jsx68("p", { role: "alert", className: "mt-1 text-xs text-text-danger", children: error })
|
|
4081
4187
|
] }),
|
|
4082
|
-
/* @__PURE__ */
|
|
4188
|
+
/* @__PURE__ */ jsx68(
|
|
4083
4189
|
"input",
|
|
4084
4190
|
{
|
|
4085
4191
|
ref: inputRef,
|
|
@@ -4094,7 +4200,7 @@ var ImageUpload = React55.forwardRef(
|
|
|
4094
4200
|
}
|
|
4095
4201
|
}
|
|
4096
4202
|
),
|
|
4097
|
-
crop && /* @__PURE__ */
|
|
4203
|
+
crop && /* @__PURE__ */ jsx68(
|
|
4098
4204
|
ImageCropDialog,
|
|
4099
4205
|
{
|
|
4100
4206
|
open: cropOpen,
|
|
@@ -4116,75 +4222,15 @@ var ImageUpload = React55.forwardRef(
|
|
|
4116
4222
|
);
|
|
4117
4223
|
ImageUpload.displayName = "ImageUpload";
|
|
4118
4224
|
|
|
4119
|
-
// src/components/entity-row.tsx
|
|
4120
|
-
import * as React56 from "react";
|
|
4121
|
-
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
4122
|
-
import { ChevronDown as ChevronDown5, ChevronRight as ChevronRight7 } from "lucide-react";
|
|
4123
|
-
import { Fragment as Fragment4, jsx as jsx68, jsxs as jsxs42 } from "react/jsx-runtime";
|
|
4124
|
-
var rowClass = "flex w-full items-center gap-3 px-4 py-2.5 text-left";
|
|
4125
|
-
var plateClass = "relative isolate after:pointer-events-none after:absolute after:inset-x-1.5 after:inset-y-1 after:-z-10 after:rounded-lg hover:after:bg-bg-elevated disabled:hover:after:bg-transparent focus-visible:outline-none focus-visible:after:ring-2 focus-visible:after:ring-inset focus-visible:after:ring-border-focus";
|
|
4126
|
-
var stackClass = "flex-col items-stretch gap-1";
|
|
4127
|
-
var caretMotion = {
|
|
4128
|
-
transitionDuration: "var(--motion-duration-normal)",
|
|
4129
|
-
transitionTimingFunction: "var(--motion-easing-standard)"
|
|
4130
|
-
};
|
|
4131
|
-
var EntityRow = React56.forwardRef(function EntityRow2({ mark, title, badge, sub, meta, summary, opens = "page", expanded, asChild = false, className, children, ...props }, ref) {
|
|
4132
|
-
if (process.env.NODE_ENV !== "production" && opens === "disclosure" && expanded === void 0) {
|
|
4133
|
-
console.warn(
|
|
4134
|
-
'[EntityRow] `opens="disclosure"` needs `expanded`: it draws the caret AND sets `aria-expanded`, and without it the row renders a caret that never turns and states no state at all. Pass `expanded={open}`, or use `opens="page"` / `opens="modal"`.'
|
|
4135
|
-
);
|
|
4136
|
-
}
|
|
4137
|
-
const line = /* @__PURE__ */ jsxs42(Fragment4, { children: [
|
|
4138
|
-
mark,
|
|
4139
|
-
/* @__PURE__ */ jsxs42("span", { className: "min-w-0 flex-1", children: [
|
|
4140
|
-
/* @__PURE__ */ jsxs42("span", { className: "flex min-h-5 items-center gap-2", children: [
|
|
4141
|
-
/* @__PURE__ */ jsx68("span", { className: cn("truncate text-sm text-text-primary", opens !== "none" && "font-medium"), children: title }),
|
|
4142
|
-
badge != null && /* @__PURE__ */ jsx68("span", { className: "flex h-5 shrink-0 items-center", children: badge })
|
|
4143
|
-
] }),
|
|
4144
|
-
sub != null && /* @__PURE__ */ jsx68("span", { className: "block truncate text-xs text-text-secondary", children: sub })
|
|
4145
|
-
] }),
|
|
4146
|
-
meta != null && /* @__PURE__ */ jsx68("span", { className: "shrink-0 text-sm text-text-secondary", children: meta }),
|
|
4147
|
-
opens !== "none" && /* @__PURE__ */ jsxs42("span", { className: "flex size-4 shrink-0 items-center justify-center", children: [
|
|
4148
|
-
opens === "page" && /* @__PURE__ */ jsx68(ChevronRight7, { className: "size-4 text-text-tertiary", "aria-hidden": true }),
|
|
4149
|
-
opens === "disclosure" && /* @__PURE__ */ jsx68(
|
|
4150
|
-
ChevronDown5,
|
|
4151
|
-
{
|
|
4152
|
-
className: cn(
|
|
4153
|
-
"size-4 shrink-0 text-text-tertiary transition-transform",
|
|
4154
|
-
expanded ? "rotate-180" : "rotate-0"
|
|
4155
|
-
),
|
|
4156
|
-
style: caretMotion,
|
|
4157
|
-
"aria-hidden": true
|
|
4158
|
-
}
|
|
4159
|
-
)
|
|
4160
|
-
] })
|
|
4161
|
-
] });
|
|
4162
|
-
const content = summary == null ? line : /* @__PURE__ */ jsxs42(Fragment4, { children: [
|
|
4163
|
-
/* @__PURE__ */ jsx68("span", { className: "flex w-full items-center gap-3", children: line }),
|
|
4164
|
-
/* @__PURE__ */ jsx68("span", { className: "block w-full text-xs text-text-secondary", children: summary })
|
|
4165
|
-
] });
|
|
4166
|
-
const classes = cn(rowClass, opens !== "none" && plateClass, summary != null && stackClass, className);
|
|
4167
|
-
const stateProps = opens === "disclosure" ? { "aria-expanded": expanded } : void 0;
|
|
4168
|
-
if (opens === "none") {
|
|
4169
|
-
return /* @__PURE__ */ jsx68("div", { ...props, ref, className: classes, children: content });
|
|
4170
|
-
}
|
|
4171
|
-
if (asChild) {
|
|
4172
|
-
const child = React56.Children.only(children);
|
|
4173
|
-
return /* @__PURE__ */ jsx68(Slot3, { ...props, ref, className: classes, ...stateProps, children: React56.cloneElement(child, stateProps, content) });
|
|
4174
|
-
}
|
|
4175
|
-
return /* @__PURE__ */ jsx68("button", { ...props, ref, type: "button", className: classes, ...stateProps, children: content });
|
|
4176
|
-
});
|
|
4177
|
-
EntityRow.displayName = "EntityRow";
|
|
4178
|
-
|
|
4179
4225
|
// src/components/back-link.tsx
|
|
4180
|
-
import * as
|
|
4226
|
+
import * as React58 from "react";
|
|
4181
4227
|
import { ArrowLeft as ArrowLeft2 } from "lucide-react";
|
|
4182
4228
|
import { Slottable } from "@radix-ui/react-slot";
|
|
4183
4229
|
import { jsx as jsx69, jsxs as jsxs43 } from "react/jsx-runtime";
|
|
4184
4230
|
var SLOTTED_GLYPH = "inline-flex shrink-0 items-center justify-center [&>svg]:size-3.5";
|
|
4185
|
-
var BackLink =
|
|
4231
|
+
var BackLink = React58.forwardRef(
|
|
4186
4232
|
({ parent, asChild = false, children, className, onClick, ...props }, ref) => {
|
|
4187
|
-
const slotted = asChild &&
|
|
4233
|
+
const slotted = asChild && React58.isValidElement(children);
|
|
4188
4234
|
if (!slotted && !onClick) return null;
|
|
4189
4235
|
const shell = {
|
|
4190
4236
|
variant: "ghost",
|
|
@@ -4204,10 +4250,10 @@ var BackLink = React57.forwardRef(
|
|
|
4204
4250
|
BackLink.displayName = "BackLink";
|
|
4205
4251
|
|
|
4206
4252
|
// src/components/card-note.tsx
|
|
4207
|
-
import * as
|
|
4208
|
-
import { Lock } from "lucide-react";
|
|
4253
|
+
import * as React59 from "react";
|
|
4254
|
+
import { Lock as Lock2 } from "lucide-react";
|
|
4209
4255
|
import { jsx as jsx70, jsxs as jsxs44 } from "react/jsx-runtime";
|
|
4210
|
-
var CardNote =
|
|
4256
|
+
var CardNote = React59.forwardRef(
|
|
4211
4257
|
({ className, children, ...props }, ref) => /* @__PURE__ */ jsxs44(
|
|
4212
4258
|
"p",
|
|
4213
4259
|
{
|
|
@@ -4218,7 +4264,7 @@ var CardNote = React58.forwardRef(
|
|
|
4218
4264
|
className
|
|
4219
4265
|
),
|
|
4220
4266
|
children: [
|
|
4221
|
-
/* @__PURE__ */ jsx70(
|
|
4267
|
+
/* @__PURE__ */ jsx70(Lock2, { className: "mt-0.5 size-3 shrink-0", "aria-hidden": true }),
|
|
4222
4268
|
children
|
|
4223
4269
|
]
|
|
4224
4270
|
}
|
|
@@ -4227,10 +4273,10 @@ var CardNote = React58.forwardRef(
|
|
|
4227
4273
|
CardNote.displayName = "CardNote";
|
|
4228
4274
|
|
|
4229
4275
|
// src/components/remove-button.tsx
|
|
4230
|
-
import * as
|
|
4276
|
+
import * as React60 from "react";
|
|
4231
4277
|
import { X as X2 } from "lucide-react";
|
|
4232
4278
|
import { jsx as jsx71, jsxs as jsxs45 } from "react/jsx-runtime";
|
|
4233
|
-
var RemoveButton =
|
|
4279
|
+
var RemoveButton = React60.forwardRef(
|
|
4234
4280
|
({ label, size = "sm", side = "top", className, ...props }, ref) => {
|
|
4235
4281
|
const button = /* @__PURE__ */ jsx71(
|
|
4236
4282
|
Button,
|
|
@@ -4255,7 +4301,7 @@ var RemoveButton = React59.forwardRef(
|
|
|
4255
4301
|
RemoveButton.displayName = "RemoveButton";
|
|
4256
4302
|
|
|
4257
4303
|
// src/components/grant-role-picker.tsx
|
|
4258
|
-
import * as
|
|
4304
|
+
import * as React61 from "react";
|
|
4259
4305
|
import { Check as Check8 } from "lucide-react";
|
|
4260
4306
|
import { Fragment as Fragment6, jsx as jsx72, jsxs as jsxs46 } from "react/jsx-runtime";
|
|
4261
4307
|
var WEIGHT_TONE = {
|
|
@@ -4270,7 +4316,7 @@ var grantRemoveLabel = (detail, notInForce) => {
|
|
|
4270
4316
|
if (!detail) return words;
|
|
4271
4317
|
return detail.startsWith(",") ? `${words}${detail}` : `${words} ${detail}`;
|
|
4272
4318
|
};
|
|
4273
|
-
var GrantRolePicker =
|
|
4319
|
+
var GrantRolePicker = React61.forwardRef(
|
|
4274
4320
|
({
|
|
4275
4321
|
value,
|
|
4276
4322
|
roles,
|
|
@@ -4319,7 +4365,7 @@ var GrantRolePicker = React60.forwardRef(
|
|
|
4319
4365
|
valueNote !== void 0 && /* @__PURE__ */ jsx72("div", { className: MENU_STATEMENT, children: valueNote }),
|
|
4320
4366
|
rungs && pickable.filter((r) => !r.group).map(item),
|
|
4321
4367
|
rungs && // Bands in the order the roles list states them, so a caller decides the order once.
|
|
4322
|
-
[...new Set(pickable.map((r) => r.group).filter((g) => !!g))].map((band) => /* @__PURE__ */ jsxs46(
|
|
4368
|
+
[...new Set(pickable.map((r) => r.group).filter((g) => !!g))].map((band) => /* @__PURE__ */ jsxs46(React61.Fragment, { children: [
|
|
4323
4369
|
/* @__PURE__ */ jsx72(DropdownMenuSeparator, {}),
|
|
4324
4370
|
/* @__PURE__ */ jsx72(DropdownMenuLabel, { className: "px-2 py-1 text-xs font-medium text-text-tertiary", children: band }),
|
|
4325
4371
|
pickable.filter((r) => r.group === band).map(item)
|
|
@@ -4353,9 +4399,9 @@ var GrantRolePicker = React60.forwardRef(
|
|
|
4353
4399
|
GrantRolePicker.displayName = "GrantRolePicker";
|
|
4354
4400
|
|
|
4355
4401
|
// src/components/grant-row.tsx
|
|
4356
|
-
import * as
|
|
4402
|
+
import * as React62 from "react";
|
|
4357
4403
|
import { jsx as jsx73, jsxs as jsxs47 } from "react/jsx-runtime";
|
|
4358
|
-
var GrantRow =
|
|
4404
|
+
var GrantRow = React62.forwardRef((props, ref) => {
|
|
4359
4405
|
const {
|
|
4360
4406
|
name,
|
|
4361
4407
|
role,
|
|
@@ -4449,10 +4495,10 @@ var GrantRow = React61.forwardRef((props, ref) => {
|
|
|
4449
4495
|
GrantRow.displayName = "GrantRow";
|
|
4450
4496
|
|
|
4451
4497
|
// src/components/removable-chip.tsx
|
|
4452
|
-
import * as
|
|
4498
|
+
import * as React63 from "react";
|
|
4453
4499
|
import { X as X3 } from "lucide-react";
|
|
4454
4500
|
import { jsx as jsx74, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
4455
|
-
var RemovableChip =
|
|
4501
|
+
var RemovableChip = React63.forwardRef(
|
|
4456
4502
|
({ label, onRemove, leading, removeLabel, className, ...props }, ref) => /* @__PURE__ */ jsxs48(
|
|
4457
4503
|
"span",
|
|
4458
4504
|
{
|
|
@@ -4486,22 +4532,22 @@ var RemovableChip = React62.forwardRef(
|
|
|
4486
4532
|
RemovableChip.displayName = "RemovableChip";
|
|
4487
4533
|
|
|
4488
4534
|
// src/hooks/use-fresh-highlight.ts
|
|
4489
|
-
import * as
|
|
4535
|
+
import * as React64 from "react";
|
|
4490
4536
|
var HOLD_MS = 3200;
|
|
4491
4537
|
var CLEAR_MS = HOLD_MS + 900;
|
|
4492
4538
|
function useFreshHighlight() {
|
|
4493
|
-
const [freshId, setFreshId] =
|
|
4494
|
-
const [message, setMessage] =
|
|
4495
|
-
const timer =
|
|
4496
|
-
|
|
4497
|
-
const markFresh =
|
|
4539
|
+
const [freshId, setFreshId] = React64.useState(null);
|
|
4540
|
+
const [message, setMessage] = React64.useState("");
|
|
4541
|
+
const timer = React64.useRef(void 0);
|
|
4542
|
+
React64.useEffect(() => () => clearTimeout(timer.current), []);
|
|
4543
|
+
const markFresh = React64.useCallback((id, announce) => {
|
|
4498
4544
|
clearTimeout(timer.current);
|
|
4499
4545
|
setFreshId(id);
|
|
4500
4546
|
if (announce) setMessage(announce);
|
|
4501
4547
|
timer.current = setTimeout(() => setFreshId(null), CLEAR_MS);
|
|
4502
4548
|
}, []);
|
|
4503
|
-
const isFresh =
|
|
4504
|
-
const freshRef =
|
|
4549
|
+
const isFresh = React64.useCallback((id) => id === freshId, [freshId]);
|
|
4550
|
+
const freshRef = React64.useCallback((el) => {
|
|
4505
4551
|
if (!el) return;
|
|
4506
4552
|
const rect = el.getBoundingClientRect();
|
|
4507
4553
|
const viewportH = window.innerHeight || document.documentElement.clientHeight;
|
|
@@ -4510,7 +4556,7 @@ function useFreshHighlight() {
|
|
|
4510
4556
|
const reduce = window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
|
|
4511
4557
|
el.scrollIntoView({ block: "nearest", behavior: reduce ? "auto" : "smooth" });
|
|
4512
4558
|
}, []);
|
|
4513
|
-
const announcer =
|
|
4559
|
+
const announcer = React64.createElement(
|
|
4514
4560
|
"span",
|
|
4515
4561
|
{ role: "status", "aria-live": "polite", className: "sr-only" },
|
|
4516
4562
|
message
|
|
@@ -4518,12 +4564,64 @@ function useFreshHighlight() {
|
|
|
4518
4564
|
return { isFresh, markFresh, freshRef, announcer };
|
|
4519
4565
|
}
|
|
4520
4566
|
|
|
4567
|
+
// src/components/quick-search-row.tsx
|
|
4568
|
+
import { Search as Search2 } from "lucide-react";
|
|
4569
|
+
import { jsx as jsx75, jsxs as jsxs49 } from "react/jsx-runtime";
|
|
4570
|
+
function QuickSearchRow({
|
|
4571
|
+
onOpen,
|
|
4572
|
+
label = "Quick search",
|
|
4573
|
+
shortcut = "\u2318K",
|
|
4574
|
+
collapsed = false,
|
|
4575
|
+
icon
|
|
4576
|
+
}) {
|
|
4577
|
+
const name = shortcut ? `${label} ${shortcut}` : label;
|
|
4578
|
+
if (!collapsed) {
|
|
4579
|
+
return /* @__PURE__ */ jsxs49(
|
|
4580
|
+
"button",
|
|
4581
|
+
{
|
|
4582
|
+
type: "button",
|
|
4583
|
+
onClick: onOpen,
|
|
4584
|
+
"aria-label": name,
|
|
4585
|
+
className: cn(
|
|
4586
|
+
// `bg-bg-overlay` where every other field in the kit takes `bg-bg-primary`, because every
|
|
4587
|
+
// other field sits on a card or a page and this one sits on the rail — which IS
|
|
4588
|
+
// `bg-bg-primary`, so the field's own fill would be its ground and only the border would
|
|
4589
|
+
// say it is there. Lifted, it is 1.073:1 above the rail in light and 1.184:1 in dark
|
|
4590
|
+
// (`Guidelines/Look/Surface tone`), and the field edge still reads at 2.348 and 2.611.
|
|
4591
|
+
"flex h-9 w-full cursor-pointer items-center gap-2 rounded-md border border-field-border bg-bg-overlay px-2.5",
|
|
4592
|
+
"text-left text-sm text-text-tertiary transition-colors duration-fast",
|
|
4593
|
+
"hover:border-field-border-hover hover:text-text-secondary",
|
|
4594
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus"
|
|
4595
|
+
),
|
|
4596
|
+
children: [
|
|
4597
|
+
/* @__PURE__ */ jsx75("span", { className: "flex size-4 shrink-0 items-center justify-center [&_svg]:size-4", "aria-hidden": "true", children: icon ?? /* @__PURE__ */ jsx75(Search2, {}) }),
|
|
4598
|
+
/* @__PURE__ */ jsx75("span", { className: "min-w-0 flex-1 truncate", children: label }),
|
|
4599
|
+
shortcut && /* @__PURE__ */ jsx75("span", { className: "shrink-0 text-xs font-medium text-text-tertiary", children: shortcut })
|
|
4600
|
+
]
|
|
4601
|
+
}
|
|
4602
|
+
);
|
|
4603
|
+
}
|
|
4604
|
+
return /* @__PURE__ */ jsxs49(Tooltip, { children: [
|
|
4605
|
+
/* @__PURE__ */ jsx75(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx75(
|
|
4606
|
+
NavRow,
|
|
4607
|
+
{
|
|
4608
|
+
variant: "rail",
|
|
4609
|
+
icon: icon ?? /* @__PURE__ */ jsx75(Search2, { "aria-hidden": "true" }),
|
|
4610
|
+
label,
|
|
4611
|
+
onClick: onOpen
|
|
4612
|
+
}
|
|
4613
|
+
) }),
|
|
4614
|
+
/* @__PURE__ */ jsx75(TooltipContent, { side: "right", children: name })
|
|
4615
|
+
] });
|
|
4616
|
+
}
|
|
4617
|
+
QuickSearchRow.displayName = "QuickSearchRow";
|
|
4618
|
+
|
|
4521
4619
|
// src/components/nav-section-label.tsx
|
|
4522
|
-
import * as
|
|
4523
|
-
import { jsx as
|
|
4524
|
-
var NavSectionLabel =
|
|
4620
|
+
import * as React65 from "react";
|
|
4621
|
+
import { jsx as jsx76 } from "react/jsx-runtime";
|
|
4622
|
+
var NavSectionLabel = React65.forwardRef(
|
|
4525
4623
|
function NavSectionLabel2({ className, ...props }, ref) {
|
|
4526
|
-
return /* @__PURE__ */
|
|
4624
|
+
return /* @__PURE__ */ jsx76(
|
|
4527
4625
|
"div",
|
|
4528
4626
|
{
|
|
4529
4627
|
ref,
|
|
@@ -4536,8 +4634,8 @@ var NavSectionLabel = React64.forwardRef(
|
|
|
4536
4634
|
NavSectionLabel.displayName = "NavSectionLabel";
|
|
4537
4635
|
|
|
4538
4636
|
// src/components/menu-popup.tsx
|
|
4539
|
-
import * as
|
|
4540
|
-
import { jsx as
|
|
4637
|
+
import * as React66 from "react";
|
|
4638
|
+
import { jsx as jsx77, jsxs as jsxs50 } from "react/jsx-runtime";
|
|
4541
4639
|
function MenuPopup({
|
|
4542
4640
|
trigger,
|
|
4543
4641
|
children,
|
|
@@ -4549,9 +4647,9 @@ function MenuPopup({
|
|
|
4549
4647
|
sideOffset = 6,
|
|
4550
4648
|
className
|
|
4551
4649
|
}) {
|
|
4552
|
-
return /* @__PURE__ */
|
|
4553
|
-
/* @__PURE__ */
|
|
4554
|
-
/* @__PURE__ */
|
|
4650
|
+
return /* @__PURE__ */ jsxs50(Popover, { open, defaultOpen, onOpenChange, children: [
|
|
4651
|
+
/* @__PURE__ */ jsx77(PopoverTrigger, { asChild: true, children: trigger }),
|
|
4652
|
+
/* @__PURE__ */ jsx77(
|
|
4555
4653
|
PopoverContent,
|
|
4556
4654
|
{
|
|
4557
4655
|
side: direction === "up" ? "top" : "bottom",
|
|
@@ -4566,9 +4664,9 @@ function MenuPopup({
|
|
|
4566
4664
|
)
|
|
4567
4665
|
] });
|
|
4568
4666
|
}
|
|
4569
|
-
var MenuDivider =
|
|
4667
|
+
var MenuDivider = React66.forwardRef(
|
|
4570
4668
|
function MenuDivider2({ className, ...props }, ref) {
|
|
4571
|
-
return /* @__PURE__ */
|
|
4669
|
+
return /* @__PURE__ */ jsx77(
|
|
4572
4670
|
"div",
|
|
4573
4671
|
{
|
|
4574
4672
|
ref,
|
|
@@ -4582,72 +4680,86 @@ var MenuDivider = React65.forwardRef(
|
|
|
4582
4680
|
MenuDivider.displayName = "MenuDivider";
|
|
4583
4681
|
|
|
4584
4682
|
// src/components/sidebar-product-header.tsx
|
|
4585
|
-
import * as
|
|
4586
|
-
import { Slot as
|
|
4683
|
+
import * as React67 from "react";
|
|
4684
|
+
import { Slot as Slot3 } from "@radix-ui/react-slot";
|
|
4587
4685
|
import { ChevronsUpDown as ChevronsUpDown2 } from "lucide-react";
|
|
4588
|
-
import { Fragment as Fragment7, jsx as
|
|
4589
|
-
var SidebarProductHeader =
|
|
4686
|
+
import { Fragment as Fragment7, jsx as jsx78, jsxs as jsxs51 } from "react/jsx-runtime";
|
|
4687
|
+
var SidebarProductHeader = React67.forwardRef(
|
|
4590
4688
|
function SidebarProductHeader2({ name, icon, trailing, asChild = false, className, children, ...props }, ref) {
|
|
4591
|
-
const adornment = trailing === void 0 ? /* @__PURE__ */
|
|
4592
|
-
const content = /* @__PURE__ */
|
|
4593
|
-
icon && /* @__PURE__ */
|
|
4594
|
-
/* @__PURE__ */
|
|
4595
|
-
adornment && /* @__PURE__ */
|
|
4689
|
+
const adornment = trailing === void 0 ? /* @__PURE__ */ jsx78(ChevronsUpDown2, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }) : trailing;
|
|
4690
|
+
const content = /* @__PURE__ */ jsxs51(Fragment7, { children: [
|
|
4691
|
+
icon && /* @__PURE__ */ jsx78("span", { className: "flex size-7 shrink-0 items-center justify-center overflow-hidden rounded-md", "aria-hidden": "true", children: icon }),
|
|
4692
|
+
/* @__PURE__ */ jsx78("span", { className: "min-w-0 flex-1 truncate text-sm font-semibold text-text-primary", children: name }),
|
|
4693
|
+
adornment && /* @__PURE__ */ jsx78("span", { className: "flex shrink-0 items-center", children: adornment })
|
|
4596
4694
|
] });
|
|
4597
|
-
const classes = cn("flex w-full items-center gap-2.5 rounded-xl px-1.5 py-0 text-left", className);
|
|
4695
|
+
const classes = cn("flex w-full cursor-pointer items-center gap-2.5 rounded-xl px-1.5 py-0 text-left", className);
|
|
4598
4696
|
if (asChild) {
|
|
4599
|
-
const child =
|
|
4600
|
-
return /* @__PURE__ */
|
|
4697
|
+
const child = React67.Children.only(children);
|
|
4698
|
+
return /* @__PURE__ */ jsx78(Slot3, { ref, className: classes, ...props, children: React67.cloneElement(child, void 0, content) });
|
|
4601
4699
|
}
|
|
4602
|
-
return /* @__PURE__ */
|
|
4700
|
+
return /* @__PURE__ */ jsx78("button", { ref, type: "button", className: classes, ...props, children: content });
|
|
4603
4701
|
}
|
|
4604
4702
|
);
|
|
4605
4703
|
SidebarProductHeader.displayName = "SidebarProductHeader";
|
|
4606
4704
|
|
|
4607
4705
|
// src/components/org-product-switcher.tsx
|
|
4608
|
-
import
|
|
4609
|
-
import {
|
|
4610
|
-
|
|
4706
|
+
import * as React68 from "react";
|
|
4707
|
+
import { ChevronsUpDown as ChevronsUpDown3, Check as Check9, Search as Search3 } from "lucide-react";
|
|
4708
|
+
import { Fragment as Fragment8, jsx as jsx79, jsxs as jsxs52 } from "react/jsx-runtime";
|
|
4709
|
+
var PRODUCT_STATUS_LABEL = {
|
|
4710
|
+
blocked: "Blocked",
|
|
4711
|
+
archived: "Archived"
|
|
4712
|
+
};
|
|
4713
|
+
function productStatusBadge(status) {
|
|
4714
|
+
if (status === "active") return void 0;
|
|
4715
|
+
return /* @__PURE__ */ jsx79(Badge, { variant: "status", children: PRODUCT_STATUS_LABEL[status] });
|
|
4716
|
+
}
|
|
4717
|
+
var triggerBox = "flex min-h-[40px] w-full items-center gap-2.5 rounded-xl px-1.5 py-1 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
|
|
4718
|
+
var inlineTriggerBox = "flex items-center gap-1.5 rounded-lg px-2 py-1 text-sm font-semibold text-text-primary transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
|
|
4611
4719
|
var menuItem = "gap-2 rounded-md px-2 py-1.5 text-sm font-medium text-text-secondary focus:bg-[var(--menu-hov)] focus:text-text-primary";
|
|
4612
4720
|
var sectionLabel = "px-2 pt-1.5 pb-1 text-xs font-medium text-text-tertiary";
|
|
4721
|
+
var searchBox = "mx-1 mb-1 flex h-8 shrink-0 items-center gap-2 rounded-md border border-field-border bg-bg-primary px-2 focus-within:ring-2 focus-within:ring-border-focus";
|
|
4722
|
+
var rowScroller = "flex max-h-[18rem] min-h-0 flex-col gap-px overflow-y-auto overscroll-contain";
|
|
4613
4723
|
var NO_ORG_LABEL = "Select an organization\u2026";
|
|
4614
4724
|
var nameOf = (item) => item?.name.trim() ? item.name : void 0;
|
|
4615
4725
|
var UNNAMED = { organization: "Unnamed organization", product: "Unnamed product" };
|
|
4726
|
+
function NameLine({ className, children }) {
|
|
4727
|
+
return /* @__PURE__ */ jsxs52("span", { className: "flex min-w-0 items-center gap-1", children: [
|
|
4728
|
+
/* @__PURE__ */ jsx79("span", { className: cn("min-w-0 truncate text-sm leading-[normal]", className), children }),
|
|
4729
|
+
/* @__PURE__ */ jsx79(ChevronsUpDown3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
|
|
4730
|
+
] });
|
|
4731
|
+
}
|
|
4732
|
+
var SEARCH_NOUN = { organization: "organizations", product: "products" };
|
|
4616
4733
|
function ItemLabel({ item, kind }) {
|
|
4617
4734
|
const name = nameOf(item);
|
|
4618
|
-
return /* @__PURE__ */
|
|
4735
|
+
return /* @__PURE__ */ jsx79("span", { className: cn("min-w-0 flex-1 truncate", !name && "text-text-tertiary"), children: name ?? UNNAMED[kind] });
|
|
4619
4736
|
}
|
|
4620
|
-
|
|
4621
|
-
|
|
4737
|
+
var MARK_SIZE = { md: "sm", sm: "xs" };
|
|
4738
|
+
var ICON_BOX = { md: "size-8 rounded-md", sm: "size-6 rounded-sm" };
|
|
4739
|
+
function Mark2({ item, kind, size, reserve }) {
|
|
4622
4740
|
if (item.icon) {
|
|
4623
|
-
return /* @__PURE__ */
|
|
4741
|
+
return /* @__PURE__ */ jsx79("span", { className: cn("flex shrink-0 items-center justify-center overflow-hidden", ICON_BOX[size]), "aria-hidden": "true", children: item.icon });
|
|
4624
4742
|
}
|
|
4625
|
-
const
|
|
4626
|
-
if (!
|
|
4627
|
-
return /* @__PURE__ */
|
|
4628
|
-
"span",
|
|
4629
|
-
{
|
|
4630
|
-
"aria-hidden": "true",
|
|
4631
|
-
className: cn(
|
|
4632
|
-
"flex shrink-0 items-center justify-center rounded-md bg-[var(--menu-hov)] font-semibold text-text-secondary",
|
|
4633
|
-
box,
|
|
4634
|
-
size === "md" ? "text-sm" : "text-xs"
|
|
4635
|
-
),
|
|
4636
|
-
children: initial
|
|
4637
|
-
}
|
|
4638
|
-
);
|
|
4743
|
+
const name = nameOf(item);
|
|
4744
|
+
if (!name) return reserve ? /* @__PURE__ */ jsx79("span", { "aria-hidden": "true", className: cn("shrink-0", ICON_BOX[size]) }) : null;
|
|
4745
|
+
return /* @__PURE__ */ jsx79(EntityTile, { name, tone: kind === "product" ? "auto" : "neutral", size: MARK_SIZE[size] });
|
|
4639
4746
|
}
|
|
4640
4747
|
function OrgProductSwitcher({
|
|
4641
|
-
organizations,
|
|
4748
|
+
organizations = [],
|
|
4642
4749
|
activeOrgId,
|
|
4643
4750
|
onOrgSelect,
|
|
4644
4751
|
products = [],
|
|
4645
4752
|
activeProductId,
|
|
4646
4753
|
onProductSelect,
|
|
4647
4754
|
actions,
|
|
4755
|
+
trigger = "stacked",
|
|
4648
4756
|
className,
|
|
4649
4757
|
...props
|
|
4650
4758
|
}) {
|
|
4759
|
+
const [open, setOpen] = React68.useState(false);
|
|
4760
|
+
const [query, setQuery] = React68.useState("");
|
|
4761
|
+
const contentRef = React68.useRef(null);
|
|
4762
|
+
const searchRef = React68.useRef(null);
|
|
4651
4763
|
const activeOrg = organizations.find((o) => o.id === activeOrgId);
|
|
4652
4764
|
const activeProduct = products.find((p) => p.id === activeProductId);
|
|
4653
4765
|
const orgName = nameOf(activeOrg);
|
|
@@ -4655,63 +4767,112 @@ function OrgProductSwitcher({
|
|
|
4655
4767
|
const orgLevel = !activeProduct;
|
|
4656
4768
|
const productLabel = activeProduct && (productName ?? UNNAMED.product);
|
|
4657
4769
|
const markItem = activeProduct?.icon || productName ? activeProduct : activeOrg;
|
|
4770
|
+
const markKind = markItem === activeProduct ? "product" : "organization";
|
|
4658
4771
|
const trail = [orgName, productLabel].filter(Boolean).join(" / ");
|
|
4659
4772
|
const ariaLabel = props["aria-label"] ?? (trail || NO_ORG_LABEL);
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4773
|
+
const inlineName = productLabel ?? orgName;
|
|
4774
|
+
const menuKind = organizations.length > 0 ? "organization" : "product";
|
|
4775
|
+
const items = menuKind === "organization" ? organizations : products;
|
|
4776
|
+
const activeItemId = menuKind === "organization" ? activeOrgId : activeProductId;
|
|
4777
|
+
const triggerMark = menuKind === "organization" && markItem;
|
|
4778
|
+
const noun = SEARCH_NOUN[menuKind];
|
|
4779
|
+
const searchLabel = items.length > 1 ? `Search ${items.length} ${noun}` : `Search ${noun}`;
|
|
4780
|
+
const needle = query.trim().toLowerCase();
|
|
4781
|
+
const matches = needle ? items.filter((i) => (nameOf(i) ?? UNNAMED[menuKind]).toLowerCase().includes(needle)) : items;
|
|
4782
|
+
const hasList = items.length > 0;
|
|
4783
|
+
React68.useEffect(() => {
|
|
4784
|
+
if (!open || !hasList) return;
|
|
4785
|
+
const id = window.setTimeout(() => searchRef.current?.focus());
|
|
4786
|
+
return () => window.clearTimeout(id);
|
|
4787
|
+
}, [open, hasList]);
|
|
4788
|
+
const setMenuOpen = (next) => {
|
|
4789
|
+
setOpen(next);
|
|
4790
|
+
if (!next) setQuery("");
|
|
4791
|
+
};
|
|
4792
|
+
const pick = (id) => {
|
|
4793
|
+
setMenuOpen(false);
|
|
4794
|
+
if (menuKind === "organization") onOrgSelect?.(id);
|
|
4795
|
+
else onProductSelect?.(id);
|
|
4796
|
+
};
|
|
4797
|
+
const onSearchKeyDown = (e) => {
|
|
4798
|
+
if (e.key === "ArrowDown") {
|
|
4799
|
+
e.preventDefault();
|
|
4800
|
+
contentRef.current?.querySelector("[data-menu-row]")?.focus();
|
|
4801
|
+
return;
|
|
4802
|
+
}
|
|
4803
|
+
if (e.key === "Enter") {
|
|
4804
|
+
const first = matches[0];
|
|
4805
|
+
if (first) {
|
|
4806
|
+
e.preventDefault();
|
|
4807
|
+
pick(first.id);
|
|
4808
|
+
}
|
|
4809
|
+
return;
|
|
4810
|
+
}
|
|
4811
|
+
if (e.key.length === 1) e.stopPropagation();
|
|
4812
|
+
};
|
|
4813
|
+
return /* @__PURE__ */ jsxs52(DropdownMenu, { open, onOpenChange: setMenuOpen, children: [
|
|
4814
|
+
trigger === "inline" ? (
|
|
4815
|
+
// One line, and the words are the whole trigger: the product where one has resolved, the
|
|
4816
|
+
// org where it has not, and the same tertiary placeholder as the stacked form where neither
|
|
4817
|
+
// has. Nothing is truncated — a bar sizes to its contents, and a name cut short in a bar is
|
|
4818
|
+
// a name nowhere else on the page repeats.
|
|
4819
|
+
/* @__PURE__ */ jsxs52(DropdownMenuTrigger, { "aria-label": ariaLabel, className: cn(inlineTriggerBox, className), children: [
|
|
4820
|
+
/* @__PURE__ */ jsx79("span", { className: cn(!inlineName && "font-medium text-text-tertiary"), children: inlineName ?? NO_ORG_LABEL }),
|
|
4821
|
+
/* @__PURE__ */ jsx79(ChevronsUpDown3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" })
|
|
4822
|
+
] })
|
|
4823
|
+
) : /* @__PURE__ */ jsxs52(DropdownMenuTrigger, { "aria-label": ariaLabel, className: cn(triggerBox, className), children: [
|
|
4824
|
+
triggerMark && /* @__PURE__ */ jsx79(Mark2, { item: triggerMark, kind: markKind, size: "md" }),
|
|
4825
|
+
orgLevel ? /* @__PURE__ */ jsx79("span", { className: "flex min-w-0 flex-1 flex-col", children: /* @__PURE__ */ jsx79(NameLine, { className: orgName ? "font-semibold text-text-primary" : "text-text-tertiary", children: orgName ?? NO_ORG_LABEL }) }) : /* @__PURE__ */ jsxs52("span", { className: "flex min-w-0 flex-1 flex-col gap-0.5", children: [
|
|
4826
|
+
orgName && /* @__PURE__ */ jsx79("span", { className: "truncate text-xs leading-[normal] text-text-tertiary", children: orgName }),
|
|
4827
|
+
/* @__PURE__ */ jsx79(NameLine, { className: productName ? "font-semibold text-text-primary" : "text-text-tertiary", children: productLabel })
|
|
4828
|
+
] })
|
|
4686
4829
|
] }),
|
|
4687
|
-
/* @__PURE__ */
|
|
4830
|
+
/* @__PURE__ */ jsxs52(
|
|
4688
4831
|
DropdownMenuContent,
|
|
4689
4832
|
{
|
|
4833
|
+
ref: contentRef,
|
|
4690
4834
|
align: "start",
|
|
4691
4835
|
sideOffset: 6,
|
|
4692
|
-
className: "flex w-[var(--radix-dropdown-menu-trigger-width)] min-w-
|
|
4836
|
+
className: "flex w-[var(--radix-dropdown-menu-trigger-width)] min-w-64 flex-col gap-px rounded-xl border-border-subtle bg-[var(--menu-bg)] p-1 shadow-(--menu-shadow)",
|
|
4693
4837
|
children: [
|
|
4694
|
-
/* @__PURE__ */
|
|
4695
|
-
|
|
4696
|
-
/* @__PURE__ */
|
|
4697
|
-
|
|
4698
|
-
|
|
4699
|
-
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
|
|
4706
|
-
|
|
4707
|
-
|
|
4838
|
+
items.length > 0 && /* @__PURE__ */ jsxs52(Fragment8, { children: [
|
|
4839
|
+
/* @__PURE__ */ jsx79(DropdownMenuLabel, { className: sectionLabel, children: menuKind === "organization" ? "Organizations" : "Products" }),
|
|
4840
|
+
/* @__PURE__ */ jsxs52("div", { className: searchBox, onKeyDown: onSearchKeyDown, children: [
|
|
4841
|
+
/* @__PURE__ */ jsx79(Search3, { size: 14, "aria-hidden": "true", className: "shrink-0 text-text-tertiary" }),
|
|
4842
|
+
/* @__PURE__ */ jsx79(
|
|
4843
|
+
"input",
|
|
4844
|
+
{
|
|
4845
|
+
ref: searchRef,
|
|
4846
|
+
type: "text",
|
|
4847
|
+
value: query,
|
|
4848
|
+
onChange: (e) => setQuery(e.target.value),
|
|
4849
|
+
placeholder: searchLabel,
|
|
4850
|
+
"aria-label": searchLabel,
|
|
4851
|
+
className: "min-w-0 flex-1 bg-transparent text-sm text-text-primary placeholder:text-text-tertiary focus:outline-none"
|
|
4852
|
+
}
|
|
4853
|
+
)
|
|
4854
|
+
] }),
|
|
4855
|
+
/* @__PURE__ */ jsx79("div", { role: "group", className: rowScroller, children: matches.map((item) => {
|
|
4856
|
+
const status = menuKind === "product" && productStatusBadge(item.status ?? "active");
|
|
4857
|
+
return /* @__PURE__ */ jsxs52(DropdownMenuItem, { "data-menu-row": "", className: menuItem, onSelect: () => pick(item.id), children: [
|
|
4858
|
+
/* @__PURE__ */ jsx79(Mark2, { item, kind: menuKind, size: "sm", reserve: true }),
|
|
4859
|
+
/* @__PURE__ */ jsx79(ItemLabel, { item, kind: menuKind }),
|
|
4860
|
+
status && /* @__PURE__ */ jsx79("span", { className: "shrink-0", children: status }),
|
|
4861
|
+
item.id === activeItemId && /* @__PURE__ */ jsx79(Check9, { className: "size-4 shrink-0 text-text-secondary", "aria-hidden": "true" })
|
|
4862
|
+
] }, item.id);
|
|
4863
|
+
}) }),
|
|
4864
|
+
matches.length === 0 && /* @__PURE__ */ jsxs52("div", { className: "px-2 py-1.5 text-sm text-text-tertiary", children: [
|
|
4865
|
+
"No ",
|
|
4866
|
+
noun,
|
|
4867
|
+
" match."
|
|
4868
|
+
] })
|
|
4708
4869
|
] }),
|
|
4709
|
-
actions && actions.length > 0 && /* @__PURE__ */
|
|
4710
|
-
/* @__PURE__ */
|
|
4711
|
-
actions.map((a) => /* @__PURE__ */
|
|
4870
|
+
actions && actions.length > 0 && /* @__PURE__ */ jsxs52(Fragment8, { children: [
|
|
4871
|
+
items.length > 0 && /* @__PURE__ */ jsx79(DropdownMenuSeparator, { className: "mx-0 shrink-0" }),
|
|
4872
|
+
actions.map((a) => /* @__PURE__ */ jsx79(DropdownMenuItem, { className: menuItem, onSelect: a.onSelect, asChild: Boolean(a.href), children: a.href ? /* @__PURE__ */ jsxs52("a", { href: a.href, children: [
|
|
4712
4873
|
a.icon,
|
|
4713
4874
|
a.label
|
|
4714
|
-
] }) : /* @__PURE__ */
|
|
4875
|
+
] }) : /* @__PURE__ */ jsxs52(Fragment8, { children: [
|
|
4715
4876
|
a.icon,
|
|
4716
4877
|
a.label
|
|
4717
4878
|
] }) }, a.id))
|
|
@@ -4725,12 +4886,13 @@ OrgProductSwitcher.displayName = "OrgProductSwitcher";
|
|
|
4725
4886
|
|
|
4726
4887
|
// src/components/sidebar-back-header.tsx
|
|
4727
4888
|
import { ArrowLeft as ArrowLeft3 } from "lucide-react";
|
|
4728
|
-
import { jsx as
|
|
4889
|
+
import { jsx as jsx80, jsxs as jsxs53 } from "react/jsx-runtime";
|
|
4729
4890
|
var focusRing = "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-border-focus";
|
|
4730
4891
|
var arrowPlate = "flex size-5 items-center justify-center rounded-md transition-colors duration-fast hover:bg-[color-mix(in_srgb,var(--text-primary)_12%,transparent)] hover:text-text-primary";
|
|
4892
|
+
var rowPlate = "transition-colors duration-fast hover:bg-[color-mix(in_srgb,var(--text-primary)_7%,transparent)]";
|
|
4731
4893
|
var arrowBox = "flex shrink-0 cursor-pointer items-center rounded-xl py-2 pr-0 pl-2.5 text-text-secondary";
|
|
4732
4894
|
var titleBox = "min-w-0 flex-1 cursor-pointer truncate rounded-xl py-2 pr-2.5 pl-[14px] text-left text-sm font-semibold text-text-primary";
|
|
4733
|
-
var Arrow = () => /* @__PURE__ */
|
|
4895
|
+
var Arrow = () => /* @__PURE__ */ jsx80(ArrowLeft3, { size: 16, "aria-hidden": "true" });
|
|
4734
4896
|
function SidebarBackHeader({
|
|
4735
4897
|
title,
|
|
4736
4898
|
onBack,
|
|
@@ -4744,22 +4906,22 @@ function SidebarBackHeader({
|
|
|
4744
4906
|
const { className: arrowClassName, ...arrowRest } = arrowProps ?? {};
|
|
4745
4907
|
const { className: titleClassName, ...titleRest } = titleProps ?? {};
|
|
4746
4908
|
if (!onTitleClick) {
|
|
4747
|
-
return /* @__PURE__ */
|
|
4909
|
+
return /* @__PURE__ */ jsxs53(
|
|
4748
4910
|
"button",
|
|
4749
4911
|
{
|
|
4750
4912
|
type: "button",
|
|
4751
4913
|
onClick: onBack,
|
|
4752
|
-
className: cn("flex items-center rounded-xl", focusRing, className),
|
|
4914
|
+
className: cn("flex cursor-pointer items-center rounded-xl", rowPlate, focusRing, className),
|
|
4753
4915
|
...rowProps,
|
|
4754
4916
|
children: [
|
|
4755
|
-
/* @__PURE__ */
|
|
4756
|
-
/* @__PURE__ */
|
|
4917
|
+
/* @__PURE__ */ jsx80("span", { className: arrowBox, children: /* @__PURE__ */ jsx80("span", { className: cn(arrowPlate, arrowClassName), ...arrowRest, children: /* @__PURE__ */ jsx80(Arrow, {}) }) }),
|
|
4918
|
+
/* @__PURE__ */ jsx80("span", { className: cn(titleBox, titleClassName), ...titleRest, children: title })
|
|
4757
4919
|
]
|
|
4758
4920
|
}
|
|
4759
4921
|
);
|
|
4760
4922
|
}
|
|
4761
|
-
return /* @__PURE__ */
|
|
4762
|
-
/* @__PURE__ */
|
|
4923
|
+
return /* @__PURE__ */ jsxs53("div", { className: cn("flex items-center rounded-xl", rowPlate, className), ...rowProps, children: [
|
|
4924
|
+
/* @__PURE__ */ jsx80(
|
|
4763
4925
|
"button",
|
|
4764
4926
|
{
|
|
4765
4927
|
type: "button",
|
|
@@ -4767,10 +4929,10 @@ function SidebarBackHeader({
|
|
|
4767
4929
|
onClick: onBack,
|
|
4768
4930
|
className: cn(arrowBox, focusRing, arrowClassName),
|
|
4769
4931
|
...arrowRest,
|
|
4770
|
-
children: /* @__PURE__ */
|
|
4932
|
+
children: /* @__PURE__ */ jsx80("span", { className: arrowPlate, children: /* @__PURE__ */ jsx80(Arrow, {}) })
|
|
4771
4933
|
}
|
|
4772
4934
|
),
|
|
4773
|
-
/* @__PURE__ */
|
|
4935
|
+
/* @__PURE__ */ jsx80(
|
|
4774
4936
|
"button",
|
|
4775
4937
|
{
|
|
4776
4938
|
type: "button",
|
|
@@ -4785,34 +4947,23 @@ function SidebarBackHeader({
|
|
|
4785
4947
|
SidebarBackHeader.displayName = "SidebarBackHeader";
|
|
4786
4948
|
|
|
4787
4949
|
// src/components/top-bar.tsx
|
|
4788
|
-
import * as
|
|
4789
|
-
import { jsx as
|
|
4790
|
-
var TopBar =
|
|
4791
|
-
({ left, right, className, ...props }, ref) => /* @__PURE__ */
|
|
4950
|
+
import * as React69 from "react";
|
|
4951
|
+
import { jsx as jsx81, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
4952
|
+
var TopBar = React69.forwardRef(
|
|
4953
|
+
({ left, right, className, ...props }, ref) => /* @__PURE__ */ jsxs54("div", { ref, className: cn("flex w-full items-center gap-1", className), ...props, children: [
|
|
4792
4954
|
left,
|
|
4793
|
-
right && /* @__PURE__ */
|
|
4955
|
+
right && /* @__PURE__ */ jsx81("div", { className: "ml-auto flex items-center gap-2", children: right })
|
|
4794
4956
|
] })
|
|
4795
4957
|
);
|
|
4796
4958
|
TopBar.displayName = "TopBar";
|
|
4797
4959
|
|
|
4798
|
-
// src/components/top-bar-utilities.tsx
|
|
4799
|
-
import * as React68 from "react";
|
|
4800
|
-
import { jsx as jsx81, jsxs as jsxs54 } from "react/jsx-runtime";
|
|
4801
|
-
var TopBarUtilities = React68.forwardRef(
|
|
4802
|
-
({ items, className, ...props }, ref) => /* @__PURE__ */ jsx81("div", { ref, className: cn("flex items-center gap-1", className), ...props, children: items.map(({ name, icon, onClick }) => /* @__PURE__ */ jsxs54(Tooltip, { children: [
|
|
4803
|
-
/* @__PURE__ */ jsx81(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx81(Button, { variant: "ghost", size: "sm", icon, "aria-label": name, onClick }) }),
|
|
4804
|
-
/* @__PURE__ */ jsx81(TooltipContent, { children: name })
|
|
4805
|
-
] }, name)) })
|
|
4806
|
-
);
|
|
4807
|
-
TopBarUtilities.displayName = "TopBarUtilities";
|
|
4808
|
-
|
|
4809
4960
|
// src/components/grid.tsx
|
|
4810
|
-
import * as
|
|
4811
|
-
import { Slot as
|
|
4961
|
+
import * as React70 from "react";
|
|
4962
|
+
import { Slot as Slot4 } from "@radix-ui/react-slot";
|
|
4812
4963
|
import { jsx as jsx82 } from "react/jsx-runtime";
|
|
4813
|
-
var Grid =
|
|
4964
|
+
var Grid = React70.forwardRef(
|
|
4814
4965
|
({ fluid = false, asChild = false, className, ...props }, ref) => {
|
|
4815
|
-
const Comp = asChild ?
|
|
4966
|
+
const Comp = asChild ? Slot4 : "div";
|
|
4816
4967
|
return /* @__PURE__ */ jsx82(
|
|
4817
4968
|
Comp,
|
|
4818
4969
|
{
|
|
@@ -4831,8 +4982,8 @@ var Grid = React69.forwardRef(
|
|
|
4831
4982
|
Grid.displayName = "Grid";
|
|
4832
4983
|
|
|
4833
4984
|
// src/components/col.tsx
|
|
4834
|
-
import * as
|
|
4835
|
-
import { Slot as
|
|
4985
|
+
import * as React71 from "react";
|
|
4986
|
+
import { Slot as Slot5 } from "@radix-ui/react-slot";
|
|
4836
4987
|
import { jsx as jsx83 } from "react/jsx-runtime";
|
|
4837
4988
|
var TIER_MAX = { base: 4, md: 8, xl: 12 };
|
|
4838
4989
|
var SPAN = {
|
|
@@ -4953,9 +5104,9 @@ function responsiveClasses(span, offset) {
|
|
|
4953
5104
|
}
|
|
4954
5105
|
return cn(...spanClasses, ...startClasses);
|
|
4955
5106
|
}
|
|
4956
|
-
var Col =
|
|
5107
|
+
var Col = React71.forwardRef(
|
|
4957
5108
|
({ span, offset, asChild = false, className, ...props }, ref) => {
|
|
4958
|
-
const Comp = asChild ?
|
|
5109
|
+
const Comp = asChild ? Slot5 : "div";
|
|
4959
5110
|
return /* @__PURE__ */ jsx83(Comp, { ref, className: cn(responsiveClasses(span, offset), className), ...props });
|
|
4960
5111
|
}
|
|
4961
5112
|
);
|
|
@@ -4972,7 +5123,7 @@ function PageColumn({ className, width = "reading", ...props }) {
|
|
|
4972
5123
|
}
|
|
4973
5124
|
|
|
4974
5125
|
// src/components/code-block.tsx
|
|
4975
|
-
import * as
|
|
5126
|
+
import * as React72 from "react";
|
|
4976
5127
|
import { jsx as jsx85, jsxs as jsxs55 } from "react/jsx-runtime";
|
|
4977
5128
|
var TOKEN_CLASS = {
|
|
4978
5129
|
comment: "text-text-tertiary italic",
|
|
@@ -5144,11 +5295,11 @@ function dropLeading(tokens, count) {
|
|
|
5144
5295
|
}
|
|
5145
5296
|
return out;
|
|
5146
5297
|
}
|
|
5147
|
-
var CodeBlock =
|
|
5298
|
+
var CodeBlock = React72.forwardRef(
|
|
5148
5299
|
({ code, lang = "tsx", variant = "default", copy = false, filename, scroll = false, highlightLines, showLineNumbers = false, className, ...props }, ref) => {
|
|
5149
|
-
const lines =
|
|
5150
|
-
const rawLines =
|
|
5151
|
-
const highlighted =
|
|
5300
|
+
const lines = React72.useMemo(() => tokenizeLines(code, lang), [code, lang]);
|
|
5301
|
+
const rawLines = React72.useMemo(() => code.split("\n"), [code]);
|
|
5302
|
+
const highlighted = React72.useMemo(() => parseHighlightLines(highlightLines), [highlightLines]);
|
|
5152
5303
|
const isDiff = variant === "diff";
|
|
5153
5304
|
const isTerminal = variant === "terminal";
|
|
5154
5305
|
const showCopy = copy && !isTerminal;
|
|
@@ -5223,7 +5374,7 @@ var CodeBlock = React71.forwardRef(
|
|
|
5223
5374
|
}
|
|
5224
5375
|
);
|
|
5225
5376
|
CodeBlock.displayName = "CodeBlock";
|
|
5226
|
-
var Code =
|
|
5377
|
+
var Code = React72.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx85(
|
|
5227
5378
|
"code",
|
|
5228
5379
|
{
|
|
5229
5380
|
ref,
|
|
@@ -5237,10 +5388,10 @@ var Code = React71.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
5237
5388
|
Code.displayName = "Code";
|
|
5238
5389
|
|
|
5239
5390
|
// src/components/grid-overlay.tsx
|
|
5240
|
-
import * as
|
|
5391
|
+
import * as React73 from "react";
|
|
5241
5392
|
import { jsx as jsx86 } from "react/jsx-runtime";
|
|
5242
5393
|
var BASELINE = "var(--grid-gutter) / 2";
|
|
5243
|
-
var GridOverlay =
|
|
5394
|
+
var GridOverlay = React73.forwardRef(
|
|
5244
5395
|
({ columns, baseline = false, className, style, ...props }, ref) => {
|
|
5245
5396
|
const count = Number.isFinite(columns) ? Math.max(1, Math.floor(columns)) : 1;
|
|
5246
5397
|
return /* @__PURE__ */ jsx86(
|
|
@@ -5268,7 +5419,7 @@ var GridOverlay = React72.forwardRef(
|
|
|
5268
5419
|
GridOverlay.displayName = "GridOverlay";
|
|
5269
5420
|
|
|
5270
5421
|
// src/components/attachment-chip.tsx
|
|
5271
|
-
import * as
|
|
5422
|
+
import * as React74 from "react";
|
|
5272
5423
|
import { cva as cva8 } from "class-variance-authority";
|
|
5273
5424
|
import { Link2, Clock, Plus as Plus2 } from "lucide-react";
|
|
5274
5425
|
import { jsx as jsx87, jsxs as jsxs56 } from "react/jsx-runtime";
|
|
@@ -5290,7 +5441,7 @@ var stateIcons = {
|
|
|
5290
5441
|
requested: Clock,
|
|
5291
5442
|
available: Plus2
|
|
5292
5443
|
};
|
|
5293
|
-
var AttachmentChip =
|
|
5444
|
+
var AttachmentChip = React74.forwardRef(
|
|
5294
5445
|
({ state, account, icon, hideIcon = false, className, ...props }, ref) => {
|
|
5295
5446
|
const Icon = icon ?? stateIcons[state ?? "attached"];
|
|
5296
5447
|
return /* @__PURE__ */ jsxs56("span", { ref, className: cn(attachmentChipVariants({ state }), className), ...props, children: [
|
|
@@ -5302,8 +5453,8 @@ var AttachmentChip = React73.forwardRef(
|
|
|
5302
5453
|
AttachmentChip.displayName = "AttachmentChip";
|
|
5303
5454
|
|
|
5304
5455
|
// src/components/connector-card.tsx
|
|
5305
|
-
import * as
|
|
5306
|
-
import { AlertTriangle, ChevronDown as
|
|
5456
|
+
import * as React75 from "react";
|
|
5457
|
+
import { AlertTriangle, ChevronDown as ChevronDown5 } from "lucide-react";
|
|
5307
5458
|
import { Fragment as Fragment9, jsx as jsx88, jsxs as jsxs57 } from "react/jsx-runtime";
|
|
5308
5459
|
var originLabels = {
|
|
5309
5460
|
org: "Attached by the organization",
|
|
@@ -5317,7 +5468,7 @@ var statusLabels = {
|
|
|
5317
5468
|
function monogram(name) {
|
|
5318
5469
|
return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
5319
5470
|
}
|
|
5320
|
-
var ConnectorCard =
|
|
5471
|
+
var ConnectorCard = React75.forwardRef(
|
|
5321
5472
|
({
|
|
5322
5473
|
name,
|
|
5323
5474
|
kind,
|
|
@@ -5342,7 +5493,7 @@ var ConnectorCard = React74.forwardRef(
|
|
|
5342
5493
|
"div",
|
|
5343
5494
|
{
|
|
5344
5495
|
"aria-hidden": "true",
|
|
5345
|
-
className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-
|
|
5496
|
+
className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-secondary text-sm font-bold text-text-secondary",
|
|
5346
5497
|
children: glyph ?? monogram(name)
|
|
5347
5498
|
}
|
|
5348
5499
|
);
|
|
@@ -5418,7 +5569,7 @@ var ConnectorCard = React74.forwardRef(
|
|
|
5418
5569
|
/* @__PURE__ */ jsxs57("div", { className: "ml-auto flex shrink-0 items-center gap-2", children: [
|
|
5419
5570
|
statusBadge,
|
|
5420
5571
|
/* @__PURE__ */ jsx88(
|
|
5421
|
-
|
|
5572
|
+
ChevronDown5,
|
|
5422
5573
|
{
|
|
5423
5574
|
"aria-hidden": "true",
|
|
5424
5575
|
className: "size-4 shrink-0 text-text-tertiary transition-transform duration-fast group-data-[state=open]:rotate-180"
|
|
@@ -5441,12 +5592,12 @@ var ConnectorCard = React74.forwardRef(
|
|
|
5441
5592
|
ConnectorCard.displayName = "ConnectorCard";
|
|
5442
5593
|
|
|
5443
5594
|
// src/components/request-row.tsx
|
|
5444
|
-
import * as
|
|
5595
|
+
import * as React76 from "react";
|
|
5445
5596
|
import { Fragment as Fragment10, jsx as jsx89, jsxs as jsxs58 } from "react/jsx-runtime";
|
|
5446
5597
|
function monogram2(name) {
|
|
5447
5598
|
return name.replace(/[^a-zA-Z0-9 ]/g, " ").split(/\s+/).filter(Boolean).slice(0, 2).map((w) => w[0].toUpperCase()).join("");
|
|
5448
5599
|
}
|
|
5449
|
-
var RequestRow =
|
|
5600
|
+
var RequestRow = React76.forwardRef(
|
|
5450
5601
|
({ surface, name, state, glyph, subtitle, account, onApprove, onDeny, onRequest, onRevoke, action, className, ...props }, ref) => {
|
|
5451
5602
|
let controls = action;
|
|
5452
5603
|
if (controls === void 0) {
|
|
@@ -5481,7 +5632,7 @@ var RequestRow = React75.forwardRef(
|
|
|
5481
5632
|
"div",
|
|
5482
5633
|
{
|
|
5483
5634
|
"aria-hidden": "true",
|
|
5484
|
-
className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-
|
|
5635
|
+
className: "flex size-8 shrink-0 items-center justify-center rounded-lg border border-border-subtle bg-bg-secondary text-sm font-bold text-text-secondary",
|
|
5485
5636
|
children: glyph ?? monogram2(name)
|
|
5486
5637
|
}
|
|
5487
5638
|
),
|
|
@@ -5498,7 +5649,7 @@ var RequestRow = React75.forwardRef(
|
|
|
5498
5649
|
RequestRow.displayName = "RequestRow";
|
|
5499
5650
|
|
|
5500
5651
|
// src/components/feedback-button.tsx
|
|
5501
|
-
import * as
|
|
5652
|
+
import * as React77 from "react";
|
|
5502
5653
|
import { MessageSquare, Loader2 as Loader23, CheckCircle2 } from "lucide-react";
|
|
5503
5654
|
import { jsx as jsx90, jsxs as jsxs59 } from "react/jsx-runtime";
|
|
5504
5655
|
var TITLE_MAX = 256;
|
|
@@ -5514,15 +5665,15 @@ var DEFAULT_LABELS = {
|
|
|
5514
5665
|
};
|
|
5515
5666
|
function FeedbackButton({ onSubmit, labels, className }) {
|
|
5516
5667
|
const l = { ...DEFAULT_LABELS, ...labels };
|
|
5517
|
-
const uid =
|
|
5668
|
+
const uid = React77.useId();
|
|
5518
5669
|
const titleId = `${uid}-title`;
|
|
5519
5670
|
const detailsId = `${uid}-details`;
|
|
5520
5671
|
const titleErrId = `${uid}-title-error`;
|
|
5521
5672
|
const detailsErrId = `${uid}-details-error`;
|
|
5522
|
-
const [open, setOpen] =
|
|
5523
|
-
const [status, setStatus] =
|
|
5524
|
-
const [title, setTitle] =
|
|
5525
|
-
const [details, setDetails] =
|
|
5673
|
+
const [open, setOpen] = React77.useState(false);
|
|
5674
|
+
const [status, setStatus] = React77.useState("idle");
|
|
5675
|
+
const [title, setTitle] = React77.useState("");
|
|
5676
|
+
const [details, setDetails] = React77.useState("");
|
|
5526
5677
|
const titleTooLong = title.length > TITLE_MAX;
|
|
5527
5678
|
const detailsTooLong = details.length > DETAILS_MAX;
|
|
5528
5679
|
const titleEmpty = title.trim().length === 0;
|
|
@@ -5656,11 +5807,11 @@ function isNotificationSettled(item) {
|
|
|
5656
5807
|
}
|
|
5657
5808
|
|
|
5658
5809
|
// src/components/notification-bell.tsx
|
|
5659
|
-
import * as
|
|
5810
|
+
import * as React79 from "react";
|
|
5660
5811
|
import { BellRing, Settings } from "lucide-react";
|
|
5661
5812
|
|
|
5662
5813
|
// src/components/notification-row.tsx
|
|
5663
|
-
import * as
|
|
5814
|
+
import * as React78 from "react";
|
|
5664
5815
|
|
|
5665
5816
|
// src/components/notification-parts.tsx
|
|
5666
5817
|
import { Check as Check10 } from "lucide-react";
|
|
@@ -5690,12 +5841,12 @@ function DeepLinkControl({
|
|
|
5690
5841
|
onClick
|
|
5691
5842
|
}) {
|
|
5692
5843
|
const name = rowControlName(link.label, title);
|
|
5693
|
-
return link.href ? /* @__PURE__ */ jsx91("a", { href: link.href, "aria-label": name, onClick, className, children: link.label }) : /* @__PURE__ */ jsx91("button", { type: "button", "aria-label": name, onClick, className, children: link.label });
|
|
5844
|
+
return link.href ? /* @__PURE__ */ jsx91("a", { href: link.href, "aria-label": name, onClick, className, children: link.label }) : /* @__PURE__ */ jsx91("button", { type: "button", "aria-label": name, onClick, className: cn("cursor-pointer", className), children: link.label });
|
|
5694
5845
|
}
|
|
5695
5846
|
|
|
5696
5847
|
// src/components/notification-row.tsx
|
|
5697
5848
|
import { jsx as jsx92, jsxs as jsxs60 } from "react/jsx-runtime";
|
|
5698
|
-
var NotificationRow =
|
|
5849
|
+
var NotificationRow = React78.forwardRef(
|
|
5699
5850
|
({ item, onItemClick, onActionClick, onMarkRead, formatAge, className, ...props }, ref) => {
|
|
5700
5851
|
const settled = isNotificationSettled(item);
|
|
5701
5852
|
const unread = !settled && !item.read;
|
|
@@ -5717,7 +5868,7 @@ var NotificationRow = React77.forwardRef(
|
|
|
5717
5868
|
/* @__PURE__ */ jsxs60("div", { className: "flex items-start gap-2.5", children: [
|
|
5718
5869
|
/* @__PURE__ */ jsxs60("div", { className: "min-w-0 flex-1", children: [
|
|
5719
5870
|
/* @__PURE__ */ jsxs60("p", { className: "truncate text-xs text-text-tertiary", children: [
|
|
5720
|
-
/* @__PURE__ */ jsx92("span", { className: "font-semibold
|
|
5871
|
+
/* @__PURE__ */ jsx92("span", { className: "font-semibold", children: item.source }),
|
|
5721
5872
|
item.receipt ? `, ${item.receipt}` : ""
|
|
5722
5873
|
] }),
|
|
5723
5874
|
/* @__PURE__ */ jsx92(
|
|
@@ -5726,7 +5877,7 @@ var NotificationRow = React77.forwardRef(
|
|
|
5726
5877
|
type: "button",
|
|
5727
5878
|
onClick: () => onItemClick?.(item),
|
|
5728
5879
|
className: cn(
|
|
5729
|
-
"mt-0.5 block text-left text-sm leading-tight underline-offset-2 hover:underline",
|
|
5880
|
+
"mt-0.5 block cursor-pointer text-left text-sm leading-tight underline-offset-2 hover:underline",
|
|
5730
5881
|
settled ? "text-text-tertiary" : unread ? "font-semibold text-text-primary" : "text-text-secondary"
|
|
5731
5882
|
),
|
|
5732
5883
|
children: item.title
|
|
@@ -5759,6 +5910,7 @@ var NotificationRow = React77.forwardRef(
|
|
|
5759
5910
|
onClick: () => onActionClick?.(item, action),
|
|
5760
5911
|
className: cn(
|
|
5761
5912
|
rowControlHitArea,
|
|
5913
|
+
"cursor-pointer",
|
|
5762
5914
|
chip ? "rounded-md px-2.5 py-1 text-xs font-medium transition-colors duration-fast" : "text-xs font-semibold text-text-secondary transition-opacity duration-fast hover:opacity-80",
|
|
5763
5915
|
action.variant === "primary" && "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover",
|
|
5764
5916
|
action.variant === "destructive" && "bg-bg-elevated text-text-danger hover:bg-bg-sunken"
|
|
@@ -5791,7 +5943,7 @@ NotificationRow.displayName = "NotificationRow";
|
|
|
5791
5943
|
|
|
5792
5944
|
// src/components/notification-bell.tsx
|
|
5793
5945
|
import { jsx as jsx93, jsxs as jsxs61 } from "react/jsx-runtime";
|
|
5794
|
-
var NotificationBell =
|
|
5946
|
+
var NotificationBell = React79.forwardRef(
|
|
5795
5947
|
({
|
|
5796
5948
|
items,
|
|
5797
5949
|
unreadCount,
|
|
@@ -5819,11 +5971,12 @@ var NotificationBell = React78.forwardRef(
|
|
|
5819
5971
|
type: "button",
|
|
5820
5972
|
"aria-label": "Notifications",
|
|
5821
5973
|
className: cn(
|
|
5822
|
-
|
|
5974
|
+
topBarMarkClass,
|
|
5975
|
+
"data-[state=open]:bg-[var(--hov-bg)] data-[state=open]:text-text-primary",
|
|
5823
5976
|
className
|
|
5824
5977
|
),
|
|
5825
5978
|
children: [
|
|
5826
|
-
/* @__PURE__ */ jsx93(BellRing, {
|
|
5979
|
+
/* @__PURE__ */ jsx93(BellRing, { "aria-hidden": "true" }),
|
|
5827
5980
|
unread > 0 && /* @__PURE__ */ jsx93("span", { className: "absolute -right-1.5 -top-1.5 flex size-[17px] items-center justify-center rounded-full bg-bg-brand text-xs font-bold leading-none text-text-on-brand ring-2 ring-bg-surface", children: unread })
|
|
5828
5981
|
]
|
|
5829
5982
|
}
|
|
@@ -5833,7 +5986,10 @@ var NotificationBell = React78.forwardRef(
|
|
|
5833
5986
|
{
|
|
5834
5987
|
align: "end",
|
|
5835
5988
|
collisionPadding: 12,
|
|
5836
|
-
style: {
|
|
5989
|
+
style: {
|
|
5990
|
+
maxHeight: "var(--radix-popover-content-available-height, 32rem)",
|
|
5991
|
+
maxWidth: "var(--radix-popover-content-available-width, 380px)"
|
|
5992
|
+
},
|
|
5837
5993
|
className: "flex w-[380px] flex-col overflow-hidden p-0",
|
|
5838
5994
|
children: [
|
|
5839
5995
|
/* @__PURE__ */ jsxs61("div", { className: "flex shrink-0 items-center justify-between px-5 py-3", children: [
|
|
@@ -5844,7 +6000,7 @@ var NotificationBell = React78.forwardRef(
|
|
|
5844
6000
|
{
|
|
5845
6001
|
type: "button",
|
|
5846
6002
|
onClick: () => onMarkAllRead?.(),
|
|
5847
|
-
className: "text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
|
|
6003
|
+
className: "cursor-pointer text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
|
|
5848
6004
|
children: "Mark all read"
|
|
5849
6005
|
}
|
|
5850
6006
|
),
|
|
@@ -5854,7 +6010,7 @@ var NotificationBell = React78.forwardRef(
|
|
|
5854
6010
|
type: "button",
|
|
5855
6011
|
"aria-label": "Notification settings",
|
|
5856
6012
|
onClick: () => onOpenSettings(),
|
|
5857
|
-
className: "flex size-6 items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
|
|
6013
|
+
className: "flex size-6 cursor-pointer items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
|
|
5858
6014
|
children: /* @__PURE__ */ jsx93(Settings, { className: "size-[15px]", "aria-hidden": "true" })
|
|
5859
6015
|
}
|
|
5860
6016
|
)
|
|
@@ -5877,7 +6033,7 @@ var NotificationBell = React78.forwardRef(
|
|
|
5877
6033
|
{
|
|
5878
6034
|
type: "button",
|
|
5879
6035
|
onClick: () => onOpenArchive(),
|
|
5880
|
-
className: "flex w-full shrink-0 items-center justify-center px-5 py-2.5 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
|
|
6036
|
+
className: "flex w-full shrink-0 cursor-pointer items-center justify-center px-5 py-2.5 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
|
|
5881
6037
|
children: hidden > 0 ? `Open notifications archive, ${hidden} more` : "Open notifications archive"
|
|
5882
6038
|
}
|
|
5883
6039
|
)
|
|
@@ -5890,10 +6046,10 @@ var NotificationBell = React78.forwardRef(
|
|
|
5890
6046
|
NotificationBell.displayName = "NotificationBell";
|
|
5891
6047
|
|
|
5892
6048
|
// src/components/notification-center.tsx
|
|
5893
|
-
import * as
|
|
5894
|
-
import { Check as Check11, Search as
|
|
6049
|
+
import * as React80 from "react";
|
|
6050
|
+
import { Check as Check11, Search as Search4 } from "lucide-react";
|
|
5895
6051
|
import { jsx as jsx94, jsxs as jsxs62 } from "react/jsx-runtime";
|
|
5896
|
-
var chipBase = "rounded-md px-3 py-1.5 text-sm font-medium transition-colors duration-fast";
|
|
6052
|
+
var chipBase = "cursor-pointer rounded-md px-3 py-1.5 text-sm font-medium transition-colors duration-fast";
|
|
5897
6053
|
var chipOn = "bg-bg-sunken font-semibold text-text-primary";
|
|
5898
6054
|
var chipOff = "bg-bg-elevated text-text-secondary hover:text-text-primary";
|
|
5899
6055
|
function CenterRow({
|
|
@@ -5909,7 +6065,7 @@ function CenterRow({
|
|
|
5909
6065
|
const age = stamp ? formatAge(stamp) : null;
|
|
5910
6066
|
return /* @__PURE__ */ jsxs62("article", { className: "group rounded-lg bg-bg-elevated px-4 py-3", children: [
|
|
5911
6067
|
/* @__PURE__ */ jsxs62("div", { className: "flex items-center gap-2", children: [
|
|
5912
|
-
/* @__PURE__ */ jsx94("span", { className: "text-xs font-semibold
|
|
6068
|
+
/* @__PURE__ */ jsx94("span", { className: "text-xs font-semibold text-text-tertiary", children: item.source }),
|
|
5913
6069
|
/* @__PURE__ */ jsx94(Badge, { variant: severityBadgeVariant(item.severity), children: severityLabels[item.severity] }),
|
|
5914
6070
|
(age || markable) && /* @__PURE__ */ jsxs62("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
|
|
5915
6071
|
stamp && age && /* @__PURE__ */ jsx94(
|
|
@@ -5929,7 +6085,7 @@ function CenterRow({
|
|
|
5929
6085
|
type: "button",
|
|
5930
6086
|
onClick: () => onItemClick?.(item),
|
|
5931
6087
|
className: cn(
|
|
5932
|
-
"mt-1 block text-left text-sm leading-snug underline-offset-2 hover:underline",
|
|
6088
|
+
"mt-1 block cursor-pointer text-left text-sm leading-snug underline-offset-2 hover:underline",
|
|
5933
6089
|
unread ? "font-semibold text-text-primary" : "font-medium text-text-secondary"
|
|
5934
6090
|
),
|
|
5935
6091
|
children: item.title
|
|
@@ -5956,7 +6112,7 @@ function CenterRow({
|
|
|
5956
6112
|
] })
|
|
5957
6113
|
] });
|
|
5958
6114
|
}
|
|
5959
|
-
var NotificationCenter =
|
|
6115
|
+
var NotificationCenter = React80.forwardRef(
|
|
5960
6116
|
({
|
|
5961
6117
|
items,
|
|
5962
6118
|
header = true,
|
|
@@ -5973,16 +6129,16 @@ var NotificationCenter = React79.forwardRef(
|
|
|
5973
6129
|
formatAge,
|
|
5974
6130
|
className
|
|
5975
6131
|
}, ref) => {
|
|
5976
|
-
const [status, setStatus] =
|
|
5977
|
-
const [source, setSource] =
|
|
5978
|
-
const [product, setProduct] =
|
|
5979
|
-
const [query, setQuery] =
|
|
5980
|
-
const [limit, setLimit] =
|
|
5981
|
-
const age =
|
|
6132
|
+
const [status, setStatus] = React80.useState("all");
|
|
6133
|
+
const [source, setSource] = React80.useState("all");
|
|
6134
|
+
const [product, setProduct] = React80.useState("all");
|
|
6135
|
+
const [query, setQuery] = React80.useState("");
|
|
6136
|
+
const [limit, setLimit] = React80.useState(pageSize);
|
|
6137
|
+
const age = React80.useCallback(
|
|
5982
6138
|
(createdAt) => formatAge ? formatAge(createdAt) : formatRelativeAge(createdAt),
|
|
5983
6139
|
[formatAge]
|
|
5984
6140
|
);
|
|
5985
|
-
const sourceChips =
|
|
6141
|
+
const sourceChips = React80.useMemo(
|
|
5986
6142
|
() => sources ?? Array.from(new Set(items.map((n) => n.source))),
|
|
5987
6143
|
[sources, items]
|
|
5988
6144
|
);
|
|
@@ -6004,13 +6160,13 @@ var NotificationCenter = React79.forwardRef(
|
|
|
6004
6160
|
{
|
|
6005
6161
|
type: "button",
|
|
6006
6162
|
onClick: () => onMarkAllRead(),
|
|
6007
|
-
className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
|
|
6163
|
+
className: "shrink-0 cursor-pointer rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-primary",
|
|
6008
6164
|
children: "Read all"
|
|
6009
6165
|
}
|
|
6010
6166
|
)
|
|
6011
6167
|
] }),
|
|
6012
6168
|
searchable && /* @__PURE__ */ jsxs62("div", { className: "mb-3 flex items-center gap-2 rounded-lg bg-bg-elevated px-3 py-2", children: [
|
|
6013
|
-
/* @__PURE__ */ jsx94(
|
|
6169
|
+
/* @__PURE__ */ jsx94(Search4, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
|
|
6014
6170
|
/* @__PURE__ */ jsx94(
|
|
6015
6171
|
"input",
|
|
6016
6172
|
{
|
|
@@ -6101,7 +6257,7 @@ var NotificationCenter = React79.forwardRef(
|
|
|
6101
6257
|
{
|
|
6102
6258
|
type: "button",
|
|
6103
6259
|
onClick: () => setLimit((l) => l + pageSize),
|
|
6104
|
-
className: "mt-1 rounded-lg bg-bg-elevated px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
|
|
6260
|
+
className: "mt-1 cursor-pointer rounded-lg bg-bg-elevated px-4 py-2.5 text-sm font-medium text-text-secondary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
|
|
6105
6261
|
children: [
|
|
6106
6262
|
"Load ",
|
|
6107
6263
|
remaining,
|
|
@@ -6116,7 +6272,7 @@ var NotificationCenter = React79.forwardRef(
|
|
|
6116
6272
|
NotificationCenter.displayName = "NotificationCenter";
|
|
6117
6273
|
|
|
6118
6274
|
// src/components/notification-settings.tsx
|
|
6119
|
-
import * as
|
|
6275
|
+
import * as React81 from "react";
|
|
6120
6276
|
import { Moon as Moon2, Plus as Plus3, Volume2 } from "lucide-react";
|
|
6121
6277
|
import { Fragment as Fragment11, jsx as jsx95, jsxs as jsxs63 } from "react/jsx-runtime";
|
|
6122
6278
|
var THRESHOLDS = [
|
|
@@ -6143,7 +6299,7 @@ function ThresholdControl({
|
|
|
6143
6299
|
}
|
|
6144
6300
|
);
|
|
6145
6301
|
}
|
|
6146
|
-
var NotificationSettings =
|
|
6302
|
+
var NotificationSettings = React81.forwardRef(
|
|
6147
6303
|
({
|
|
6148
6304
|
subscriptions,
|
|
6149
6305
|
value,
|
|
@@ -6156,7 +6312,7 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6156
6312
|
pushSlot,
|
|
6157
6313
|
className
|
|
6158
6314
|
}, ref) => {
|
|
6159
|
-
const [tab, setTab] =
|
|
6315
|
+
const [tab, setTab] = React81.useState(DEFAULT_KEY);
|
|
6160
6316
|
const isDefault = tab === DEFAULT_KEY;
|
|
6161
6317
|
const defaults = value[DEFAULT_KEY] ?? { thresholds: {} };
|
|
6162
6318
|
const customized = !isDefault && Object.prototype.hasOwnProperty.call(value, tab);
|
|
@@ -6177,7 +6333,7 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6177
6333
|
const rows = subscriptions.filter((s) => s.scope === scope);
|
|
6178
6334
|
if (rows.length === 0) return null;
|
|
6179
6335
|
return /* @__PURE__ */ jsxs63("div", { children: [
|
|
6180
|
-
/* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-
|
|
6336
|
+
/* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-medium text-text-tertiary", children: scope === "product" ? "This product" : "Organization" }),
|
|
6181
6337
|
/* @__PURE__ */ jsx95("div", { className: "space-y-2", children: rows.map((sub) => /* @__PURE__ */ jsxs63(
|
|
6182
6338
|
"div",
|
|
6183
6339
|
{
|
|
@@ -6200,7 +6356,7 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6200
6356
|
};
|
|
6201
6357
|
return /* @__PURE__ */ jsxs63("div", { ref, className: cn("space-y-5", className), children: [
|
|
6202
6358
|
products && products.length > 0 && /* @__PURE__ */ jsxs63("div", { children: [
|
|
6203
|
-
/* @__PURE__ */ jsx95("p", { className: "mb-2 px-0.5 text-xs font-
|
|
6359
|
+
/* @__PURE__ */ jsx95("p", { className: "mb-2 px-0.5 text-xs font-medium text-text-tertiary", children: "Preferences for" }),
|
|
6204
6360
|
/* @__PURE__ */ jsx95(
|
|
6205
6361
|
ToggleGroup,
|
|
6206
6362
|
{
|
|
@@ -6217,18 +6373,18 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6217
6373
|
isDefault ? /* @__PURE__ */ jsxs63(Fragment11, { children: [
|
|
6218
6374
|
/* @__PURE__ */ jsx95("p", { className: "text-sm leading-relaxed text-text-secondary", children: "Your defaults, applied to every product unless you customize one. Everything addressed to you always lands in the in-app record; that cannot be turned off." }),
|
|
6219
6375
|
/* @__PURE__ */ jsxs63(Card, { className: "border-none bg-bg-elevated p-5", children: [
|
|
6220
|
-
/* @__PURE__ */ jsx95("p",
|
|
6376
|
+
/* @__PURE__ */ jsx95(CardTitle, { as: "p", className: "mb-1.5", children: "Push to" }),
|
|
6221
6377
|
/* @__PURE__ */ jsx95("p", { className: "mb-3 text-sm leading-relaxed text-text-secondary", children: "Forward notifications beyond the in-app record to a connected integration." }),
|
|
6222
6378
|
pushSlot ?? /* @__PURE__ */ jsx95("div", { className: "rounded-lg bg-bg-surface px-4 py-6 text-center", children: /* @__PURE__ */ jsx95("p", { className: "text-sm text-text-tertiary", children: "No integrations connected." }) })
|
|
6223
6379
|
] }),
|
|
6224
6380
|
mutes.length > 0 && /* @__PURE__ */ jsxs63("div", { children: [
|
|
6225
|
-
/* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-
|
|
6381
|
+
/* @__PURE__ */ jsx95("p", { className: "mb-1.5 px-0.5 text-xs font-medium text-text-tertiary", children: "Muted" }),
|
|
6226
6382
|
/* @__PURE__ */ jsx95(Card, { className: "border-none bg-bg-elevated p-2", children: mutes.map((m) => /* @__PURE__ */ jsxs63("div", { className: "flex items-center gap-3 rounded-lg px-3 py-2.5", children: [
|
|
6227
6383
|
/* @__PURE__ */ jsx95(Moon2, { className: "size-4 shrink-0 text-text-tertiary", "aria-hidden": "true" }),
|
|
6228
6384
|
/* @__PURE__ */ jsxs63("div", { className: "min-w-0 flex-1", children: [
|
|
6229
6385
|
/* @__PURE__ */ jsx95("p", { className: "text-sm font-medium text-text-primary", children: m.source }),
|
|
6230
6386
|
/* @__PURE__ */ jsxs63("p", { className: "text-sm text-text-tertiary", children: [
|
|
6231
|
-
"Muted
|
|
6387
|
+
"Muted, ",
|
|
6232
6388
|
m.label,
|
|
6233
6389
|
". Critical still comes through."
|
|
6234
6390
|
] })
|
|
@@ -6238,7 +6394,7 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6238
6394
|
{
|
|
6239
6395
|
type: "button",
|
|
6240
6396
|
onClick: () => onUnmute?.(m.source),
|
|
6241
|
-
className: "rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
|
|
6397
|
+
className: "cursor-pointer rounded-md px-2.5 py-1 text-sm font-medium text-text-brand transition-colors duration-fast hover:bg-bg-surface",
|
|
6242
6398
|
children: "Unmute"
|
|
6243
6399
|
}
|
|
6244
6400
|
)
|
|
@@ -6272,7 +6428,7 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6272
6428
|
{
|
|
6273
6429
|
type: "button",
|
|
6274
6430
|
onClick: customize,
|
|
6275
|
-
className: "mt-5 inline-flex items-center gap-1.5 rounded-lg bg-bg-brand px-3.5 py-2 text-sm font-semibold text-text-on-brand transition-colors duration-fast hover:bg-bg-brand-hover",
|
|
6431
|
+
className: "mt-5 inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-bg-brand px-3.5 py-2 text-sm font-semibold text-text-on-brand transition-colors duration-fast hover:bg-bg-brand-hover",
|
|
6276
6432
|
children: [
|
|
6277
6433
|
/* @__PURE__ */ jsx95(Plus3, { className: "size-4", "aria-hidden": "true" }),
|
|
6278
6434
|
" Customize for ",
|
|
@@ -6294,7 +6450,7 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6294
6450
|
{
|
|
6295
6451
|
type: "button",
|
|
6296
6452
|
onClick: resetToDefault,
|
|
6297
|
-
className: "shrink-0 rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-danger",
|
|
6453
|
+
className: "shrink-0 cursor-pointer rounded-md px-2.5 py-1 text-sm font-medium text-text-tertiary transition-colors duration-fast hover:text-text-danger",
|
|
6298
6454
|
children: "Reset to Default"
|
|
6299
6455
|
}
|
|
6300
6456
|
)
|
|
@@ -6307,14 +6463,14 @@ var NotificationSettings = React80.forwardRef(
|
|
|
6307
6463
|
NotificationSettings.displayName = "NotificationSettings";
|
|
6308
6464
|
|
|
6309
6465
|
// src/components/notification-toast.tsx
|
|
6310
|
-
import * as
|
|
6466
|
+
import * as React82 from "react";
|
|
6311
6467
|
import { X as X4 } from "lucide-react";
|
|
6312
6468
|
import { jsx as jsx96, jsxs as jsxs64 } from "react/jsx-runtime";
|
|
6313
|
-
var chipBase2 = "rounded-lg px-2.5 py-1 text-sm font-medium transition-colors duration-fast";
|
|
6469
|
+
var chipBase2 = "cursor-pointer rounded-lg px-2.5 py-1 text-sm font-medium transition-colors duration-fast";
|
|
6314
6470
|
var chipPrimary = "bg-bg-brand text-text-on-brand hover:bg-bg-brand-hover";
|
|
6315
6471
|
var chipDestructive = "bg-bg-elevated text-text-danger hover:bg-bg-surface";
|
|
6316
|
-
var linkAction = "text-sm font-semibold text-text-brand transition-colors duration-fast hover:text-text-primary";
|
|
6317
|
-
var NotificationToast =
|
|
6472
|
+
var linkAction = "cursor-pointer text-sm font-semibold text-text-brand transition-colors duration-fast hover:text-text-primary";
|
|
6473
|
+
var NotificationToast = React82.forwardRef(
|
|
6318
6474
|
({
|
|
6319
6475
|
item,
|
|
6320
6476
|
showSource = true,
|
|
@@ -6331,7 +6487,7 @@ var NotificationToast = React81.forwardRef(
|
|
|
6331
6487
|
const actions = item.actions ?? [];
|
|
6332
6488
|
const percent = progress === void 0 || !Number.isFinite(progress) ? void 0 : Math.min(100, Math.max(0, progress));
|
|
6333
6489
|
const progressLine = progressLabel === void 0 && percent !== void 0 ? `live, ${Math.round(percent)}%` : progressLabel;
|
|
6334
|
-
const barId =
|
|
6490
|
+
const barId = React82.useId();
|
|
6335
6491
|
const hasProgressLine = progressLine !== null && progressLine !== void 0;
|
|
6336
6492
|
return /* @__PURE__ */ jsxs64(
|
|
6337
6493
|
"div",
|
|
@@ -6345,7 +6501,7 @@ var NotificationToast = React81.forwardRef(
|
|
|
6345
6501
|
),
|
|
6346
6502
|
children: [
|
|
6347
6503
|
/* @__PURE__ */ jsxs64("div", { className: "flex items-center gap-2", children: [
|
|
6348
|
-
showSource && /* @__PURE__ */ jsx96("span", { className: "text-xs font-semibold
|
|
6504
|
+
showSource && /* @__PURE__ */ jsx96("span", { className: "text-xs font-semibold text-text-tertiary", children: item.source }),
|
|
6349
6505
|
/* @__PURE__ */ jsx96(Badge, { variant: severityBadgeVariant(item.severity), children: severityLabels[item.severity] }),
|
|
6350
6506
|
(overflow || onDismiss) && /* @__PURE__ */ jsxs64("span", { className: "-mr-1 ml-auto flex shrink-0 items-center gap-1", children: [
|
|
6351
6507
|
overflow,
|
|
@@ -6355,7 +6511,7 @@ var NotificationToast = React81.forwardRef(
|
|
|
6355
6511
|
type: "button",
|
|
6356
6512
|
"aria-label": dismissLabel,
|
|
6357
6513
|
onClick: () => onDismiss(item),
|
|
6358
|
-
className: "flex size-5 shrink-0 items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
|
|
6514
|
+
className: "flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-md text-text-tertiary transition-colors duration-fast hover:bg-bg-surface hover:text-text-primary",
|
|
6359
6515
|
children: /* @__PURE__ */ jsx96(X4, { className: "size-3.5", "aria-hidden": "true" })
|
|
6360
6516
|
}
|
|
6361
6517
|
)
|
|
@@ -6366,7 +6522,7 @@ var NotificationToast = React81.forwardRef(
|
|
|
6366
6522
|
{
|
|
6367
6523
|
type: "button",
|
|
6368
6524
|
onClick: () => onItemClick(item),
|
|
6369
|
-
className: "mt-1 block text-left text-sm font-semibold leading-snug text-text-primary underline-offset-2 hover:underline",
|
|
6525
|
+
className: "mt-1 block cursor-pointer text-left text-sm font-semibold leading-snug text-text-primary underline-offset-2 hover:underline",
|
|
6370
6526
|
children: item.title
|
|
6371
6527
|
}
|
|
6372
6528
|
) : /* @__PURE__ */ jsx96("p", { className: "mt-1 text-sm font-semibold leading-snug text-text-primary", children: item.title }),
|
|
@@ -6409,7 +6565,7 @@ var NotificationToast = React81.forwardRef(
|
|
|
6409
6565
|
NotificationToast.displayName = "NotificationToast";
|
|
6410
6566
|
|
|
6411
6567
|
// src/components/notification-toaster.tsx
|
|
6412
|
-
import * as
|
|
6568
|
+
import * as React83 from "react";
|
|
6413
6569
|
import { jsx as jsx97 } from "react/jsx-runtime";
|
|
6414
6570
|
var positions = {
|
|
6415
6571
|
"bottom-right": "bottom-6 right-6 flex-col",
|
|
@@ -6417,7 +6573,7 @@ var positions = {
|
|
|
6417
6573
|
"top-right": "top-6 right-6 flex-col-reverse",
|
|
6418
6574
|
"top-left": "top-6 left-6 flex-col-reverse"
|
|
6419
6575
|
};
|
|
6420
|
-
var NotificationToaster =
|
|
6576
|
+
var NotificationToaster = React83.forwardRef(
|
|
6421
6577
|
({
|
|
6422
6578
|
items,
|
|
6423
6579
|
dwell,
|
|
@@ -6434,15 +6590,15 @@ var NotificationToaster = React82.forwardRef(
|
|
|
6434
6590
|
className
|
|
6435
6591
|
}, ref) => {
|
|
6436
6592
|
const shown = items.slice(0, max);
|
|
6437
|
-
const [paused, setPaused] =
|
|
6438
|
-
const onDismissRef =
|
|
6593
|
+
const [paused, setPaused] = React83.useState(false);
|
|
6594
|
+
const onDismissRef = React83.useRef(onDismiss);
|
|
6439
6595
|
onDismissRef.current = onDismiss;
|
|
6440
6596
|
const fyiDwell = dwell?.fyi;
|
|
6441
6597
|
const importantDwell = dwell?.important;
|
|
6442
6598
|
const criticalDwell = dwell?.critical;
|
|
6443
|
-
const remaining =
|
|
6599
|
+
const remaining = React83.useRef(/* @__PURE__ */ new Map());
|
|
6444
6600
|
const liveIds = shown.map((item) => `${item.id}:${item.severity}`).join(" ");
|
|
6445
|
-
|
|
6601
|
+
React83.useEffect(() => {
|
|
6446
6602
|
const owedById = remaining.current;
|
|
6447
6603
|
const dwellSeconds = {
|
|
6448
6604
|
fyi: fyiDwell ?? TOAST_DWELL.fyi,
|
|
@@ -6770,7 +6926,7 @@ var COUNTRY_OPTIONS = [
|
|
|
6770
6926
|
];
|
|
6771
6927
|
|
|
6772
6928
|
// src/components/organization-onboarding-form.tsx
|
|
6773
|
-
import * as
|
|
6929
|
+
import * as React84 from "react";
|
|
6774
6930
|
|
|
6775
6931
|
// src/lib/auth-surface.ts
|
|
6776
6932
|
var AUTH_FILLED_BUTTON = "flex h-[46px] w-full items-center justify-center gap-[11px] rounded-[10px] border border-transparent bg-text-primary px-[14px] text-[14.5px] font-semibold tracking-[-0.005em] text-bg-sunken transition-opacity duration-fast hover:opacity-[0.92] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-text-brand active:translate-y-px disabled:cursor-not-allowed disabled:opacity-[0.55]";
|
|
@@ -6781,10 +6937,20 @@ var AUTH_BUTTON_SHADOW = "var(--auth-btn-shadow)";
|
|
|
6781
6937
|
import { jsx as jsx98, jsxs as jsxs65 } from "react/jsx-runtime";
|
|
6782
6938
|
var CONTROLLER_SHARE_PCT = 50;
|
|
6783
6939
|
var MAX_BENEFICIAL_OWNERS = 50;
|
|
6940
|
+
var REQUIRED_FIELD_LABELS = {
|
|
6941
|
+
name: "Organization name",
|
|
6942
|
+
legalName: "Legal name",
|
|
6943
|
+
ownerName: "Owner name",
|
|
6944
|
+
countryOfIncorporation: "Country of incorporation",
|
|
6945
|
+
residencyCountry: "Country of residency"
|
|
6946
|
+
};
|
|
6784
6947
|
var OWNERSHIP_CONFIRMATION_MESSAGE = "Please confirm the ownership details by ticking the box";
|
|
6785
6948
|
function isOwnershipViolation(violation) {
|
|
6786
6949
|
return /ownership[_\s-]?confirmed/i.test(violation);
|
|
6787
6950
|
}
|
|
6951
|
+
function RequiredMark() {
|
|
6952
|
+
return /* @__PURE__ */ jsx98("span", { className: "text-text-danger", children: " *" });
|
|
6953
|
+
}
|
|
6788
6954
|
function parseShare(raw) {
|
|
6789
6955
|
if (!/^\d{1,3}$/.test(raw.trim())) return null;
|
|
6790
6956
|
const n = Number(raw);
|
|
@@ -6802,7 +6968,6 @@ function initialRows(owners) {
|
|
|
6802
6968
|
}));
|
|
6803
6969
|
}
|
|
6804
6970
|
function OrganizationOnboardingForm({
|
|
6805
|
-
requireSanctionsFields,
|
|
6806
6971
|
onSubmit,
|
|
6807
6972
|
defaultValues,
|
|
6808
6973
|
submitting,
|
|
@@ -6813,22 +6978,23 @@ function OrganizationOnboardingForm({
|
|
|
6813
6978
|
onCancel,
|
|
6814
6979
|
className
|
|
6815
6980
|
}) {
|
|
6816
|
-
const [name, setName] =
|
|
6817
|
-
const [legalName, setLegalName] =
|
|
6818
|
-
const [ownerName, setOwnerName] =
|
|
6819
|
-
const [countryOfIncorporation, setCountryOfIncorporation] =
|
|
6981
|
+
const [name, setName] = React84.useState(defaultValues?.name ?? "");
|
|
6982
|
+
const [legalName, setLegalName] = React84.useState(defaultValues?.legal_name ?? "");
|
|
6983
|
+
const [ownerName, setOwnerName] = React84.useState(defaultValues?.owner_name ?? "");
|
|
6984
|
+
const [countryOfIncorporation, setCountryOfIncorporation] = React84.useState(
|
|
6820
6985
|
defaultValues?.country_of_incorporation ?? ""
|
|
6821
6986
|
);
|
|
6822
|
-
const [residencyCountry, setResidencyCountry] =
|
|
6987
|
+
const [residencyCountry, setResidencyCountry] = React84.useState(
|
|
6823
6988
|
defaultValues?.residency_country ?? ""
|
|
6824
6989
|
);
|
|
6825
|
-
const [owners, setOwners] =
|
|
6990
|
+
const [owners, setOwners] = React84.useState(
|
|
6826
6991
|
() => initialRows(defaultValues?.beneficial_owners)
|
|
6827
6992
|
);
|
|
6828
|
-
const [ownershipConfirmed, setOwnershipConfirmed] =
|
|
6829
|
-
const [confirmationAttempted, setConfirmationAttempted] =
|
|
6830
|
-
const
|
|
6831
|
-
const
|
|
6993
|
+
const [ownershipConfirmed, setOwnershipConfirmed] = React84.useState(false);
|
|
6994
|
+
const [confirmationAttempted, setConfirmationAttempted] = React84.useState(false);
|
|
6995
|
+
const [requiredAttempted, setRequiredAttempted] = React84.useState(false);
|
|
6996
|
+
const nextKeyRef = React84.useRef(owners.length);
|
|
6997
|
+
const submittingRef = React84.useRef(false);
|
|
6832
6998
|
const trimmed = name.trim();
|
|
6833
6999
|
const filledOwners = owners.filter((row) => !isRowBlank(row));
|
|
6834
7000
|
const ownerShares = filledOwners.map((row) => parseShare(row.share));
|
|
@@ -6840,9 +7006,16 @@ function OrganizationOnboardingForm({
|
|
|
6840
7006
|
(share) => share !== null && share >= CONTROLLER_SHARE_PCT
|
|
6841
7007
|
);
|
|
6842
7008
|
const needsOwnershipConfirmation = !hasController;
|
|
6843
|
-
const
|
|
7009
|
+
const missingRequired = [
|
|
7010
|
+
[trimmed, REQUIRED_FIELD_LABELS.name],
|
|
7011
|
+
[legalName.trim(), REQUIRED_FIELD_LABELS.legalName],
|
|
7012
|
+
[ownerName.trim(), REQUIRED_FIELD_LABELS.ownerName],
|
|
7013
|
+
[countryOfIncorporation, REQUIRED_FIELD_LABELS.countryOfIncorporation],
|
|
7014
|
+
[residencyCountry, REQUIRED_FIELD_LABELS.residencyCountry]
|
|
7015
|
+
].filter(([value]) => value === "").map(([, label]) => label);
|
|
6844
7016
|
const missingConfirmation = needsOwnershipConfirmation && !ownershipConfirmed;
|
|
6845
|
-
const canSubmit =
|
|
7017
|
+
const canSubmit = ownersValid && !submitting;
|
|
7018
|
+
const showRequiredError = requiredAttempted && missingRequired.length > 0;
|
|
6846
7019
|
const ownershipViolations = needsOwnershipConfirmation ? (violations ?? []).filter(isOwnershipViolation) : [];
|
|
6847
7020
|
const otherViolations = (violations ?? []).filter(
|
|
6848
7021
|
(violation) => !ownershipViolations.includes(violation)
|
|
@@ -6861,7 +7034,8 @@ function OrganizationOnboardingForm({
|
|
|
6861
7034
|
const handleSubmit = (event) => {
|
|
6862
7035
|
event.preventDefault();
|
|
6863
7036
|
if (!canSubmit || submittingRef.current) return;
|
|
6864
|
-
if (missingConfirmation) {
|
|
7037
|
+
if (missingRequired.length > 0 || missingConfirmation) {
|
|
7038
|
+
setRequiredAttempted(true);
|
|
6865
7039
|
setConfirmationAttempted(true);
|
|
6866
7040
|
return;
|
|
6867
7041
|
}
|
|
@@ -6873,16 +7047,16 @@ function OrganizationOnboardingForm({
|
|
|
6873
7047
|
}));
|
|
6874
7048
|
onSubmit({
|
|
6875
7049
|
name: trimmed,
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
7050
|
+
legal_name: legalName.trim(),
|
|
7051
|
+
owner_name: ownerName.trim(),
|
|
7052
|
+
country_of_incorporation: countryOfIncorporation,
|
|
7053
|
+
residency_country: residencyCountry,
|
|
6880
7054
|
beneficial_owners: beneficialOwners,
|
|
6881
7055
|
// Only meaningful — and only collected — when the list shows no controlling owner.
|
|
6882
7056
|
...needsOwnershipConfirmation ? { ownership_confirmed: ownershipConfirmed } : {}
|
|
6883
7057
|
});
|
|
6884
7058
|
};
|
|
6885
|
-
|
|
7059
|
+
React84.useEffect(() => {
|
|
6886
7060
|
submittingRef.current = false;
|
|
6887
7061
|
}, [
|
|
6888
7062
|
name,
|
|
@@ -6898,7 +7072,7 @@ function OrganizationOnboardingForm({
|
|
|
6898
7072
|
const countryField = (params) => /* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
|
|
6899
7073
|
/* @__PURE__ */ jsxs65(Label2, { htmlFor: params.id, children: [
|
|
6900
7074
|
params.label,
|
|
6901
|
-
|
|
7075
|
+
/* @__PURE__ */ jsx98(RequiredMark, {})
|
|
6902
7076
|
] }),
|
|
6903
7077
|
/* @__PURE__ */ jsx98(
|
|
6904
7078
|
Select,
|
|
@@ -6915,7 +7089,10 @@ function OrganizationOnboardingForm({
|
|
|
6915
7089
|
] });
|
|
6916
7090
|
return /* @__PURE__ */ jsxs65("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
|
|
6917
7091
|
/* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
|
|
6918
|
-
/* @__PURE__ */
|
|
7092
|
+
/* @__PURE__ */ jsxs65(Label2, { htmlFor: "create-org-name", children: [
|
|
7093
|
+
REQUIRED_FIELD_LABELS.name,
|
|
7094
|
+
/* @__PURE__ */ jsx98(RequiredMark, {})
|
|
7095
|
+
] }),
|
|
6919
7096
|
/* @__PURE__ */ jsx98(
|
|
6920
7097
|
Input,
|
|
6921
7098
|
{
|
|
@@ -6928,7 +7105,10 @@ function OrganizationOnboardingForm({
|
|
|
6928
7105
|
)
|
|
6929
7106
|
] }),
|
|
6930
7107
|
/* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
|
|
6931
|
-
/* @__PURE__ */
|
|
7108
|
+
/* @__PURE__ */ jsxs65(Label2, { htmlFor: "create-org-legal-name", children: [
|
|
7109
|
+
REQUIRED_FIELD_LABELS.legalName,
|
|
7110
|
+
/* @__PURE__ */ jsx98(RequiredMark, {})
|
|
7111
|
+
] }),
|
|
6932
7112
|
/* @__PURE__ */ jsx98(
|
|
6933
7113
|
Input,
|
|
6934
7114
|
{
|
|
@@ -6941,7 +7121,10 @@ function OrganizationOnboardingForm({
|
|
|
6941
7121
|
)
|
|
6942
7122
|
] }),
|
|
6943
7123
|
/* @__PURE__ */ jsxs65("div", { className: "space-y-1.5", children: [
|
|
6944
|
-
/* @__PURE__ */
|
|
7124
|
+
/* @__PURE__ */ jsxs65(Label2, { htmlFor: "create-org-owner-name", children: [
|
|
7125
|
+
REQUIRED_FIELD_LABELS.ownerName,
|
|
7126
|
+
/* @__PURE__ */ jsx98(RequiredMark, {})
|
|
7127
|
+
] }),
|
|
6945
7128
|
/* @__PURE__ */ jsx98(
|
|
6946
7129
|
Input,
|
|
6947
7130
|
{
|
|
@@ -6955,17 +7138,15 @@ function OrganizationOnboardingForm({
|
|
|
6955
7138
|
] }),
|
|
6956
7139
|
countryField({
|
|
6957
7140
|
id: "create-org-country",
|
|
6958
|
-
label:
|
|
7141
|
+
label: REQUIRED_FIELD_LABELS.countryOfIncorporation,
|
|
6959
7142
|
value: countryOfIncorporation,
|
|
6960
|
-
onChange: setCountryOfIncorporation
|
|
6961
|
-
required: requireSanctionsFields
|
|
7143
|
+
onChange: setCountryOfIncorporation
|
|
6962
7144
|
}),
|
|
6963
7145
|
countryField({
|
|
6964
7146
|
id: "create-org-residency",
|
|
6965
|
-
label:
|
|
7147
|
+
label: REQUIRED_FIELD_LABELS.residencyCountry,
|
|
6966
7148
|
value: residencyCountry,
|
|
6967
|
-
onChange: setResidencyCountry
|
|
6968
|
-
required: false
|
|
7149
|
+
onChange: setResidencyCountry
|
|
6969
7150
|
}),
|
|
6970
7151
|
/* @__PURE__ */ jsxs65("div", { className: "space-y-2", children: [
|
|
6971
7152
|
/* @__PURE__ */ jsxs65("div", { className: "flex items-center justify-between", children: [
|
|
@@ -7071,7 +7252,7 @@ function OrganizationOnboardingForm({
|
|
|
7071
7252
|
className: "text-xs font-regular leading-snug",
|
|
7072
7253
|
children: [
|
|
7073
7254
|
"I confirm the ownership structure above is complete and correct",
|
|
7074
|
-
/* @__PURE__ */ jsx98(
|
|
7255
|
+
/* @__PURE__ */ jsx98(RequiredMark, {})
|
|
7075
7256
|
]
|
|
7076
7257
|
}
|
|
7077
7258
|
)
|
|
@@ -7086,7 +7267,8 @@ function OrganizationOnboardingForm({
|
|
|
7086
7267
|
}
|
|
7087
7268
|
)
|
|
7088
7269
|
] }),
|
|
7089
|
-
|
|
7270
|
+
showRequiredError && /* @__PURE__ */ jsx98(InlineError, { "data-testid": "create-org-required-error", children: missingRequired.length === 1 ? `${missingRequired[0]} is required` : `These fields are required: ${missingRequired.join(", ")}` }),
|
|
7271
|
+
(serverError || otherViolations.length > 0) && /* @__PURE__ */ jsxs65(InlineError, { "data-testid": "create-org-server-error", children: [
|
|
7090
7272
|
serverError,
|
|
7091
7273
|
otherViolations.length > 0 && /* @__PURE__ */ jsx98("ul", { "data-testid": "create-org-violations", className: "mt-1 list-disc pl-4", children: otherViolations.map((violation) => /* @__PURE__ */ jsx98("li", { children: violation }, violation)) })
|
|
7092
7274
|
] }),
|
|
@@ -7097,18 +7279,18 @@ function OrganizationOnboardingForm({
|
|
|
7097
7279
|
type: "submit",
|
|
7098
7280
|
"data-testid": "submit-create-org",
|
|
7099
7281
|
disabled: !canSubmit,
|
|
7100
|
-
className: AUTH_FILLED_BUTTON,
|
|
7282
|
+
className: cn("cursor-pointer", AUTH_FILLED_BUTTON),
|
|
7101
7283
|
style: { boxShadow: AUTH_BUTTON_SHADOW },
|
|
7102
7284
|
children: submitting ? "Creating\u2026" : submitLabel
|
|
7103
7285
|
}
|
|
7104
7286
|
),
|
|
7105
|
-
onCancel && /* @__PURE__ */ jsx98("button", { type: "button", onClick: onCancel, className: AUTH_QUIET_BUTTON, children: "Cancel" })
|
|
7287
|
+
onCancel && /* @__PURE__ */ jsx98("button", { type: "button", onClick: onCancel, className: cn("cursor-pointer", AUTH_QUIET_BUTTON), children: "Cancel" })
|
|
7106
7288
|
] })
|
|
7107
7289
|
] });
|
|
7108
7290
|
}
|
|
7109
7291
|
|
|
7110
7292
|
// src/components/list-columns.tsx
|
|
7111
|
-
import * as
|
|
7293
|
+
import * as React85 from "react";
|
|
7112
7294
|
import { jsx as jsx99, jsxs as jsxs66 } from "react/jsx-runtime";
|
|
7113
7295
|
var CELL_WIDTH = { 20: "w-20", 24: "w-24", 28: "w-28", 32: "w-32" };
|
|
7114
7296
|
var headerClass = "flex items-center gap-3 border-b border-border-subtle bg-bg-secondary px-4 py-1.5 text-xs text-text-tertiary";
|
|
@@ -7127,7 +7309,7 @@ function warnDuplicateKeys(columns, where) {
|
|
|
7127
7309
|
seen.add(c.key);
|
|
7128
7310
|
}
|
|
7129
7311
|
}
|
|
7130
|
-
var ListHeader =
|
|
7312
|
+
var ListHeader = React85.forwardRef(function ListHeader2({ lead, columns, mark = true, trailing = true, className, ...props }, ref) {
|
|
7131
7313
|
warnDuplicateKeys(columns, "ListHeader");
|
|
7132
7314
|
return /* @__PURE__ */ jsxs66("div", { ref, className: cn(headerClass, className), ...props, children: [
|
|
7133
7315
|
mark && /* @__PURE__ */ jsx99("span", { className: "size-8 shrink-0", "aria-hidden": true }),
|
|
@@ -7141,7 +7323,7 @@ function cellValue(values, column) {
|
|
|
7141
7323
|
const value = values[column.key];
|
|
7142
7324
|
return value === void 0 || value === null || value === "" ? column.fallback : value;
|
|
7143
7325
|
}
|
|
7144
|
-
var ListCells =
|
|
7326
|
+
var ListCells = React85.forwardRef(function ListCells2({ columns, values, className, ...props }, ref) {
|
|
7145
7327
|
warnDuplicateKeys(columns, "ListCells");
|
|
7146
7328
|
return /* @__PURE__ */ jsx99("span", { ref, className: cn(cellsClass, className), ...props, children: columns.map((c) => /* @__PURE__ */ jsx99(
|
|
7147
7329
|
"span",
|
|
@@ -7156,8 +7338,8 @@ ListHeader.displayName = "ListHeader";
|
|
|
7156
7338
|
ListCells.displayName = "ListCells";
|
|
7157
7339
|
|
|
7158
7340
|
// src/components/theme-picker.tsx
|
|
7159
|
-
import * as
|
|
7160
|
-
import { Check as Check12
|
|
7341
|
+
import * as React86 from "react";
|
|
7342
|
+
import { Check as Check12 } from "lucide-react";
|
|
7161
7343
|
import { jsx as jsx100, jsxs as jsxs67 } from "react/jsx-runtime";
|
|
7162
7344
|
var THEME_SWATCHES = {
|
|
7163
7345
|
// --bg-surface --bg-sunken --bg-overlay --border-default --text-tertiary
|
|
@@ -7205,11 +7387,17 @@ function Panels({ palette }) {
|
|
|
7205
7387
|
)
|
|
7206
7388
|
] });
|
|
7207
7389
|
}
|
|
7208
|
-
var
|
|
7390
|
+
var CUT = "polygon(0 0, -8px 0, -8px calc(100% + 8px), calc(100% + 8px) calc(100% + 8px), calc(100% + 8px) calc(100% - 16px), 100% calc(100% - 16px))";
|
|
7391
|
+
function AutoPanels() {
|
|
7392
|
+
return /* @__PURE__ */ jsxs67("span", { className: "relative block h-full", children: [
|
|
7393
|
+
/* @__PURE__ */ jsx100("span", { className: "absolute inset-0", children: /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES.light }) }),
|
|
7394
|
+
/* @__PURE__ */ jsx100("span", { className: "absolute inset-0", style: { clipPath: CUT }, children: /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES.dark }) })
|
|
7395
|
+
] });
|
|
7396
|
+
}
|
|
7209
7397
|
var previewClass = "block h-28 overflow-hidden rounded-lg border border-border-default";
|
|
7210
|
-
var cardClass = "grid gap-2 rounded-lg p-1.5 text-left transition-colors duration-fast hover:bg-bg
|
|
7398
|
+
var cardClass = "grid cursor-pointer gap-2 rounded-lg p-1.5 text-left transition-colors duration-fast hover:bg-[var(--hov-bg)] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus";
|
|
7211
7399
|
var TRACK = { gridTemplateColumns: "repeat(auto-fit, minmax(8rem, 1fr))" };
|
|
7212
|
-
var Picker =
|
|
7400
|
+
var Picker = React86.forwardRef(function Picker2({ value, onValueChange, className, ...props }, ref) {
|
|
7213
7401
|
return /* @__PURE__ */ jsx100("div", { role: "group", "aria-label": "Theme", ...props, ref, className: cn("grid gap-4", className), style: { ...TRACK, ...props.style }, children: OPTIONS.map((o) => {
|
|
7214
7402
|
const selected = o.value === value;
|
|
7215
7403
|
return (
|
|
@@ -7224,7 +7412,7 @@ var Picker = React85.forwardRef(function Picker2({ value, onValueChange, classNa
|
|
|
7224
7412
|
onClick: () => onValueChange(o.value),
|
|
7225
7413
|
className: cardClass,
|
|
7226
7414
|
children: [
|
|
7227
|
-
/* @__PURE__ */ jsx100("span", { className: cn(previewClass, selected && "border-border-strong"), "aria-hidden": true, children: o.value === "system" ? /* @__PURE__ */ jsx100(
|
|
7415
|
+
/* @__PURE__ */ jsx100("span", { className: cn(previewClass, selected && "border-border-strong"), "aria-hidden": true, children: o.value === "system" ? /* @__PURE__ */ jsx100(AutoPanels, {}) : /* @__PURE__ */ jsx100(Panels, { palette: THEME_SWATCHES[o.value] }) }),
|
|
7228
7416
|
/* @__PURE__ */ jsxs67(
|
|
7229
7417
|
"span",
|
|
7230
7418
|
{
|
|
@@ -7245,7 +7433,7 @@ var Picker = React85.forwardRef(function Picker2({ value, onValueChange, classNa
|
|
|
7245
7433
|
);
|
|
7246
7434
|
}) });
|
|
7247
7435
|
});
|
|
7248
|
-
var WiredPicker =
|
|
7436
|
+
var WiredPicker = React86.forwardRef(function WiredPicker2({ onValueChange, ...props }, ref) {
|
|
7249
7437
|
const { theme, setTheme } = useTheme();
|
|
7250
7438
|
return /* @__PURE__ */ jsx100(
|
|
7251
7439
|
Picker,
|
|
@@ -7260,8 +7448,8 @@ var WiredPicker = React85.forwardRef(function WiredPicker2({ onValueChange, ...p
|
|
|
7260
7448
|
}
|
|
7261
7449
|
);
|
|
7262
7450
|
});
|
|
7263
|
-
var ThemePicker =
|
|
7264
|
-
const controlled =
|
|
7451
|
+
var ThemePicker = React86.forwardRef(function ThemePicker2({ value, onValueChange, ...props }, ref) {
|
|
7452
|
+
const controlled = React86.useRef(value !== void 0);
|
|
7265
7453
|
if (process.env.NODE_ENV !== "production" && controlled.current !== (value !== void 0)) {
|
|
7266
7454
|
console.warn(
|
|
7267
7455
|
"[ThemePicker] `value` went from " + (controlled.current ? "set to missing" : "missing to set") + " after mount. The picker stays " + (controlled.current ? "controlled" : "wired to the console theme") + " for its whole life: render it once its value is known, or leave `value` off entirely."
|
|
@@ -7273,7 +7461,7 @@ var ThemePicker = React85.forwardRef(function ThemePicker2({ value, onValueChang
|
|
|
7273
7461
|
ThemePicker.displayName = "ThemePicker";
|
|
7274
7462
|
|
|
7275
7463
|
// src/components/secret-reveal.tsx
|
|
7276
|
-
import * as
|
|
7464
|
+
import * as React87 from "react";
|
|
7277
7465
|
import { Copy as Copy2, Download } from "lucide-react";
|
|
7278
7466
|
import { jsx as jsx101, jsxs as jsxs68 } from "react/jsx-runtime";
|
|
7279
7467
|
var asText = (value) => Array.isArray(value) ? value.join("\n") : value;
|
|
@@ -7291,7 +7479,7 @@ function SecretValue({ value }) {
|
|
|
7291
7479
|
}
|
|
7292
7480
|
return /* @__PURE__ */ jsx101("code", { className: "block break-all font-mono text-sm font-medium text-text-primary", children: value });
|
|
7293
7481
|
}
|
|
7294
|
-
var SecretReveal =
|
|
7482
|
+
var SecretReveal = React87.forwardRef(
|
|
7295
7483
|
({
|
|
7296
7484
|
value,
|
|
7297
7485
|
caption,
|
|
@@ -7308,18 +7496,18 @@ var SecretReveal = React86.forwardRef(
|
|
|
7308
7496
|
className,
|
|
7309
7497
|
...props
|
|
7310
7498
|
}, ref) => {
|
|
7311
|
-
const [takenText, setTakenText] =
|
|
7312
|
-
const [refusedText, setRefusedText] =
|
|
7313
|
-
const [announcedFor, setAnnouncedFor] =
|
|
7314
|
-
const copyRef =
|
|
7315
|
-
const captionId =
|
|
7499
|
+
const [takenText, setTakenText] = React87.useState(null);
|
|
7500
|
+
const [refusedText, setRefusedText] = React87.useState(null);
|
|
7501
|
+
const [announcedFor, setAnnouncedFor] = React87.useState(null);
|
|
7502
|
+
const copyRef = React87.useRef(null);
|
|
7503
|
+
const captionId = React87.useId();
|
|
7316
7504
|
const text = asText(value);
|
|
7317
7505
|
const empty = text.length === 0;
|
|
7318
7506
|
const taken = takenText === text;
|
|
7319
7507
|
const refused = refusedText === text;
|
|
7320
|
-
|
|
7508
|
+
React87.useEffect(() => setAnnouncedFor(text), [text]);
|
|
7321
7509
|
const announced = announcedFor === text ? REVEALED : "";
|
|
7322
|
-
|
|
7510
|
+
React87.useEffect(() => {
|
|
7323
7511
|
if (autoFocus) copyRef.current?.focus();
|
|
7324
7512
|
}, [autoFocus]);
|
|
7325
7513
|
const reportTaken = () => {
|
|
@@ -7381,7 +7569,7 @@ var SecretReveal = React86.forwardRef(
|
|
|
7381
7569
|
SecretReveal.displayName = "SecretReveal";
|
|
7382
7570
|
|
|
7383
7571
|
// src/components/star-rating.tsx
|
|
7384
|
-
import * as
|
|
7572
|
+
import * as React88 from "react";
|
|
7385
7573
|
import * as RadioGroupPrimitive2 from "@radix-ui/react-radio-group";
|
|
7386
7574
|
import { Star } from "lucide-react";
|
|
7387
7575
|
import { jsx as jsx102 } from "react/jsx-runtime";
|
|
@@ -7407,7 +7595,7 @@ var StarGlyph = ({ filled, size }) => /* @__PURE__ */ jsx102(
|
|
|
7407
7595
|
)
|
|
7408
7596
|
}
|
|
7409
7597
|
);
|
|
7410
|
-
var StarRating =
|
|
7598
|
+
var StarRating = React88.forwardRef(
|
|
7411
7599
|
({
|
|
7412
7600
|
className,
|
|
7413
7601
|
value,
|
|
@@ -7422,9 +7610,9 @@ var StarRating = React87.forwardRef(
|
|
|
7422
7610
|
...props
|
|
7423
7611
|
}, ref) => {
|
|
7424
7612
|
const stars = Array.from({ length: max }, (_, index) => index + 1);
|
|
7425
|
-
const [mirror, setMirror] =
|
|
7613
|
+
const [mirror, setMirror] = React88.useState(defaultValue ?? 0);
|
|
7426
7614
|
const selected = value ?? mirror;
|
|
7427
|
-
const [preview, setPreview] =
|
|
7615
|
+
const [preview, setPreview] = React88.useState(null);
|
|
7428
7616
|
const shown = preview ?? selected;
|
|
7429
7617
|
const commit = (next) => {
|
|
7430
7618
|
setMirror(next);
|
|
@@ -7470,6 +7658,7 @@ var StarRating = React87.forwardRef(
|
|
|
7470
7658
|
if (min === 0 && star === selected) commit(0);
|
|
7471
7659
|
},
|
|
7472
7660
|
className: cn(
|
|
7661
|
+
"cursor-pointer",
|
|
7473
7662
|
// Focus is an outline held off the box, never a flush ring (`Guidelines/Look/Borders`).
|
|
7474
7663
|
"rounded-md p-0.5 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
7475
7664
|
"disabled:pointer-events-none disabled:opacity-50"
|
|
@@ -7485,7 +7674,7 @@ var StarRating = React87.forwardRef(
|
|
|
7485
7674
|
StarRating.displayName = "StarRating";
|
|
7486
7675
|
|
|
7487
7676
|
// src/components/rating-scale.tsx
|
|
7488
|
-
import * as
|
|
7677
|
+
import * as React89 from "react";
|
|
7489
7678
|
import * as RadioGroupPrimitive3 from "@radix-ui/react-radio-group";
|
|
7490
7679
|
import { jsx as jsx103, jsxs as jsxs69 } from "react/jsx-runtime";
|
|
7491
7680
|
var SLOT_BOX = {
|
|
@@ -7494,7 +7683,7 @@ var SLOT_BOX = {
|
|
|
7494
7683
|
lg: "h-11 min-w-11 px-3 text-base"
|
|
7495
7684
|
};
|
|
7496
7685
|
var defaultItemLabel2 = (value, _min, max) => `${value} out of ${max}`;
|
|
7497
|
-
var RatingScale =
|
|
7686
|
+
var RatingScale = React89.forwardRef(
|
|
7498
7687
|
({
|
|
7499
7688
|
className,
|
|
7500
7689
|
value,
|
|
@@ -7510,7 +7699,7 @@ var RatingScale = React88.forwardRef(
|
|
|
7510
7699
|
...props
|
|
7511
7700
|
}, ref) => {
|
|
7512
7701
|
const slots = Array.from({ length: Math.max(0, max - min + 1) }, (_, index) => min + index);
|
|
7513
|
-
const [mirror, setMirror] =
|
|
7702
|
+
const [mirror, setMirror] = React89.useState(defaultValue);
|
|
7514
7703
|
const selected = value ?? mirror;
|
|
7515
7704
|
const row = /* @__PURE__ */ jsx103("div", { className: cn("flex flex-wrap items-center gap-1.5", !endLabels && className), children: slots.map((slot) => {
|
|
7516
7705
|
const isSelected = slot === selected;
|
|
@@ -7529,6 +7718,7 @@ var RatingScale = React88.forwardRef(
|
|
|
7529
7718
|
"aria-label": itemLabel(slot, min, max),
|
|
7530
7719
|
className: cn(
|
|
7531
7720
|
box,
|
|
7721
|
+
"cursor-pointer",
|
|
7532
7722
|
// The hover step is the same channel the mark uses, one rung short of it, so the
|
|
7533
7723
|
// pointer never promises a mark it is not making.
|
|
7534
7724
|
"hover:border-field-border-hover hover:text-text-primary",
|
|
@@ -7797,8 +7987,10 @@ export {
|
|
|
7797
7987
|
PopoverContent,
|
|
7798
7988
|
PopoverTrigger,
|
|
7799
7989
|
Progress,
|
|
7990
|
+
QuickSearchRow,
|
|
7800
7991
|
RadioGroup2 as RadioGroup,
|
|
7801
7992
|
RadioGroupItem,
|
|
7993
|
+
RailToggle,
|
|
7802
7994
|
RatingScale,
|
|
7803
7995
|
RemovableChip,
|
|
7804
7996
|
RemoveButton,
|
|
@@ -7867,6 +8059,7 @@ export {
|
|
|
7867
8059
|
isKnownExtensionIcon,
|
|
7868
8060
|
isNotificationSettled,
|
|
7869
8061
|
navigationMenuTriggerStyle,
|
|
8062
|
+
productStatusBadge,
|
|
7870
8063
|
severityBadgeVariant,
|
|
7871
8064
|
severityLabels,
|
|
7872
8065
|
statusDotVariants,
|