@mediaradar/design-components 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +526 -140
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +406 -14
- package/dist/index.d.ts +406 -14
- package/dist/index.js +516 -136
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -37,11 +37,13 @@ __export(index_exports, {
|
|
|
37
37
|
DateRangeFilter: () => DateRangeFilter,
|
|
38
38
|
DateRangePicker: () => DateRangePicker,
|
|
39
39
|
Delta: () => Delta,
|
|
40
|
+
EmptyState: () => EmptyState,
|
|
40
41
|
FilterChipBar: () => FilterChipBar,
|
|
41
42
|
FilterDropdownFooter: () => FilterDropdownFooter,
|
|
42
43
|
Freshness: () => Freshness,
|
|
43
44
|
InfoTip: () => InfoTip,
|
|
44
45
|
LineChartPlaceholder: () => LineChartPlaceholder,
|
|
46
|
+
Modal: () => Modal,
|
|
45
47
|
MultiSelectFilter: () => MultiSelectFilter,
|
|
46
48
|
NO_RESULTS_BODY: () => NO_RESULTS_BODY,
|
|
47
49
|
NO_RESULTS_TITLE: () => NO_RESULTS_TITLE,
|
|
@@ -56,6 +58,7 @@ __export(index_exports, {
|
|
|
56
58
|
SearchBar: () => SearchBar,
|
|
57
59
|
SectionHeading: () => SectionHeading,
|
|
58
60
|
SectionRail: () => SectionRail,
|
|
61
|
+
SegmentedControl: () => SegmentedControl,
|
|
59
62
|
SelectAllVisible: () => SelectAllVisible,
|
|
60
63
|
SelectFilter: () => SelectFilter,
|
|
61
64
|
SelectedSection: () => SelectedSection,
|
|
@@ -63,7 +66,10 @@ __export(index_exports, {
|
|
|
63
66
|
SortButton: () => SortButton,
|
|
64
67
|
StackedColumnPlaceholder: () => StackedColumnPlaceholder,
|
|
65
68
|
TablePagination: () => TablePagination,
|
|
69
|
+
Tabs: () => Tabs,
|
|
66
70
|
Tag: () => Tag,
|
|
71
|
+
TextField: () => TextField,
|
|
72
|
+
Toast: () => Toast,
|
|
67
73
|
Toggle: () => Toggle,
|
|
68
74
|
Tooltip: () => Tooltip,
|
|
69
75
|
WorkspaceAvatar: () => WorkspaceAvatar,
|
|
@@ -311,7 +317,7 @@ function AdvertiserQuickFilter({
|
|
|
311
317
|
"aria-label": caption,
|
|
312
318
|
"data-testid": testIdPrefix && `${testIdPrefix}-popover`,
|
|
313
319
|
children: [
|
|
314
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex h-
|
|
320
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex h-8 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus", children: [
|
|
315
321
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Search, { size: 14, className: "shrink-0 text-text-secondary", "aria-hidden": "true" }),
|
|
316
322
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
317
323
|
"input",
|
|
@@ -990,6 +996,7 @@ function NavBtn({ children, onClick, ...rest }) {
|
|
|
990
996
|
var import_react4 = require("react");
|
|
991
997
|
var import_lucide_react7 = require("lucide-react");
|
|
992
998
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
999
|
+
var HEIGHT = { sm: "h-8", md: "h-10", lg: "h-11" };
|
|
993
1000
|
var DEFAULT_SEARCH_MATCH = { mode: "anyWord", wordJoin: "Or" };
|
|
994
1001
|
var MODE_LABEL = {
|
|
995
1002
|
anyWord: "Any Word",
|
|
@@ -1005,6 +1012,7 @@ function SearchBar({
|
|
|
1005
1012
|
value,
|
|
1006
1013
|
onChange,
|
|
1007
1014
|
variant = "default",
|
|
1015
|
+
size = "lg",
|
|
1008
1016
|
matchValue,
|
|
1009
1017
|
onMatchChange,
|
|
1010
1018
|
className,
|
|
@@ -1012,6 +1020,7 @@ function SearchBar({
|
|
|
1012
1020
|
}) {
|
|
1013
1021
|
const [open, setOpen] = (0, import_react4.useState)(false);
|
|
1014
1022
|
const ref = (0, import_react4.useRef)(null);
|
|
1023
|
+
const input = (0, import_react4.useRef)(null);
|
|
1015
1024
|
(0, import_react4.useEffect)(() => {
|
|
1016
1025
|
if (!open) return;
|
|
1017
1026
|
const onKey = (e) => e.key === "Escape" && setOpen(false);
|
|
@@ -1030,7 +1039,8 @@ function SearchBar({
|
|
|
1030
1039
|
"div",
|
|
1031
1040
|
{
|
|
1032
1041
|
className: cx2(
|
|
1033
|
-
"flex
|
|
1042
|
+
"flex min-w-[200px] flex-1 items-stretch rounded-control border border-border-strong bg-input focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus",
|
|
1043
|
+
HEIGHT[size],
|
|
1034
1044
|
className
|
|
1035
1045
|
),
|
|
1036
1046
|
children: [
|
|
@@ -1039,16 +1049,31 @@ function SearchBar({
|
|
|
1039
1049
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1040
1050
|
"input",
|
|
1041
1051
|
{
|
|
1052
|
+
ref: input,
|
|
1042
1053
|
type: "text",
|
|
1043
1054
|
value,
|
|
1044
1055
|
onChange: (e) => onChange?.(e.target.value),
|
|
1045
1056
|
placeholder,
|
|
1046
1057
|
"aria-label": placeholder,
|
|
1047
1058
|
"data-testid": testIdPrefix && `${testIdPrefix}-search`,
|
|
1048
|
-
className: "min-w-0 flex-1 bg-transparent text-
|
|
1059
|
+
className: "min-w-0 flex-1 bg-transparent text-dense text-text-primary outline-hidden placeholder:text-text-tertiary"
|
|
1049
1060
|
}
|
|
1050
1061
|
)
|
|
1051
1062
|
] }),
|
|
1063
|
+
value && onChange && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1064
|
+
"button",
|
|
1065
|
+
{
|
|
1066
|
+
type: "button",
|
|
1067
|
+
onClick: () => {
|
|
1068
|
+
onChange("");
|
|
1069
|
+
input.current?.focus();
|
|
1070
|
+
},
|
|
1071
|
+
"aria-label": "Clear search",
|
|
1072
|
+
"data-testid": testIdPrefix && `${testIdPrefix}-clear`,
|
|
1073
|
+
className: "mr-1.5 flex size-6 shrink-0 items-center justify-center self-center rounded-control text-text-tertiary hover:bg-subtle hover:text-text-primary focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
1074
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react7.X, { size: 14, "aria-hidden": "true" })
|
|
1075
|
+
}
|
|
1076
|
+
),
|
|
1052
1077
|
showMatch && // border-border-default, not the bare `border-border` both source
|
|
1053
1078
|
// implementations used -- confirmed by actually compiling against
|
|
1054
1079
|
// @mediaradar/design-tokens' real published theme.css (not assumed):
|
|
@@ -2400,7 +2425,7 @@ function SelectionPicker({
|
|
|
2400
2425
|
}) }),
|
|
2401
2426
|
source === "search" && /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex min-w-0 flex-col gap-3", children: [
|
|
2402
2427
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
2403
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-
|
|
2428
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { className: "flex h-8 min-w-[200px] flex-1 items-center gap-2 rounded-control border border-border-strong bg-input px-3 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus", children: [
|
|
2404
2429
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react15.Search, { size: 15, className: "text-text-secondary", "aria-hidden": "true" }),
|
|
2405
2430
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
2406
2431
|
"input",
|
|
@@ -2714,7 +2739,7 @@ function FilterDropdown({
|
|
|
2714
2739
|
onClick: () => setOpen((v) => !v),
|
|
2715
2740
|
"aria-expanded": open,
|
|
2716
2741
|
"data-testid": testIdPrefix && `${testIdPrefix}-filter-${filterSlug}`,
|
|
2717
|
-
className: "inline-flex h-
|
|
2742
|
+
className: "inline-flex h-8 items-center gap-1.5 whitespace-nowrap rounded-control border border-border-strong bg-input px-3 text-[13px] font-medium text-text-secondary transition-colors hover:bg-subtle",
|
|
2718
2743
|
children: [
|
|
2719
2744
|
label,
|
|
2720
2745
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_lucide_react15.ChevronDown, { size: 13, "aria-hidden": "true", className: cx8("transition-transform", open && "rotate-180") })
|
|
@@ -2920,7 +2945,10 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
2920
2945
|
size: {
|
|
2921
2946
|
xs: "h-6 px-2 text-xs",
|
|
2922
2947
|
sm: "h-8 px-3 text-sm",
|
|
2923
|
-
md: "h-10 px-4 text-sm"
|
|
2948
|
+
md: "h-10 px-4 text-sm",
|
|
2949
|
+
// 44, the filter row's height, so a button at the end of a row of
|
|
2950
|
+
// filter dropdowns lines up with them. One control scale: 32 / 40 / 44.
|
|
2951
|
+
lg: "h-11 px-5 text-sm"
|
|
2924
2952
|
},
|
|
2925
2953
|
// Shape is orthogonal to size. As a fourth SIZE, `icon` could only ever
|
|
2926
2954
|
// be one dimension, so an icon button never lined up with the labelled
|
|
@@ -2935,6 +2963,7 @@ var buttonVariants = (0, import_class_variance_authority.cva)(
|
|
|
2935
2963
|
{ size: "xs", iconOnly: true, class: "w-6" },
|
|
2936
2964
|
{ size: "sm", iconOnly: true, class: "w-8" },
|
|
2937
2965
|
{ size: "md", iconOnly: true, class: "w-10" },
|
|
2966
|
+
{ size: "lg", iconOnly: true, class: "w-11" },
|
|
2938
2967
|
// A boxed button is a target you aim at, so its label carries the weight
|
|
2939
2968
|
// of one. `link` sits inline in a sentence, where semibold reads as
|
|
2940
2969
|
// emphasis on the words rather than as a control.
|
|
@@ -3048,7 +3077,7 @@ function NameListModal({
|
|
|
3048
3077
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
|
|
3049
3078
|
"div",
|
|
3050
3079
|
{
|
|
3051
|
-
className: "fixed inset-0 z-
|
|
3080
|
+
className: "fixed inset-0 z-modal flex items-center justify-center bg-scrim px-4",
|
|
3052
3081
|
onMouseDown: (e) => e.target === e.currentTarget && onCancel(),
|
|
3053
3082
|
children: /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
|
|
3054
3083
|
"div",
|
|
@@ -3058,7 +3087,7 @@ function NameListModal({
|
|
|
3058
3087
|
"aria-modal": "true",
|
|
3059
3088
|
"aria-labelledby": titleId,
|
|
3060
3089
|
onKeyDown: trapTab,
|
|
3061
|
-
className: "w-full max-w-
|
|
3090
|
+
className: "w-full max-w-110 rounded-card border border-border-default bg-surface p-5 shadow-overlay",
|
|
3062
3091
|
children: [
|
|
3063
3092
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsx)("h2", { id: titleId, className: "text-[16px] font-semibold text-text-primary", children: title }),
|
|
3064
3093
|
/* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { className: "mt-4 flex flex-col gap-1.5", children: [
|
|
@@ -3071,7 +3100,7 @@ function NameListModal({
|
|
|
3071
3100
|
value: name,
|
|
3072
3101
|
onChange: (e) => setName(e.target.value),
|
|
3073
3102
|
placeholder,
|
|
3074
|
-
className: "h-10 rounded-control border border-border-strong bg-input px-3 text-
|
|
3103
|
+
className: "h-10 rounded-control border border-border-strong bg-input px-3 text-dense focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus"
|
|
3075
3104
|
}
|
|
3076
3105
|
)
|
|
3077
3106
|
] }),
|
|
@@ -3348,10 +3377,83 @@ function WorkspaceAvatar({ name, size = "md" }) {
|
|
|
3348
3377
|
);
|
|
3349
3378
|
}
|
|
3350
3379
|
|
|
3351
|
-
// src/
|
|
3380
|
+
// src/Toast.tsx
|
|
3381
|
+
var import_react15 = require("react");
|
|
3382
|
+
var import_react_dom6 = require("react-dom");
|
|
3383
|
+
var import_lucide_react20 = require("lucide-react");
|
|
3352
3384
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
3385
|
+
var ICON = {
|
|
3386
|
+
neutral: null,
|
|
3387
|
+
success: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react20.Check, { size: 15, className: "shrink-0", "aria-hidden": "true" }),
|
|
3388
|
+
warning: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_lucide_react20.AlertTriangle, { size: 15, className: "shrink-0", "aria-hidden": "true" })
|
|
3389
|
+
};
|
|
3390
|
+
function Toast({ message, action, onClose, tone = "neutral", duration, className }) {
|
|
3391
|
+
const ms = duration ?? (action ? 1e4 : 5e3);
|
|
3392
|
+
const [paused, setPaused] = (0, import_react15.useState)(false);
|
|
3393
|
+
const closed = (0, import_react15.useRef)(false);
|
|
3394
|
+
(0, import_react15.useEffect)(() => {
|
|
3395
|
+
if (paused) return;
|
|
3396
|
+
const t = window.setTimeout(() => {
|
|
3397
|
+
if (closed.current) return;
|
|
3398
|
+
closed.current = true;
|
|
3399
|
+
onClose();
|
|
3400
|
+
}, ms);
|
|
3401
|
+
return () => window.clearTimeout(t);
|
|
3402
|
+
}, [message, ms, paused]);
|
|
3403
|
+
return (0, import_react_dom6.createPortal)(
|
|
3404
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(
|
|
3405
|
+
"div",
|
|
3406
|
+
{
|
|
3407
|
+
role: "status",
|
|
3408
|
+
"aria-live": "polite",
|
|
3409
|
+
onMouseEnter: () => setPaused(true),
|
|
3410
|
+
onMouseLeave: () => setPaused(false),
|
|
3411
|
+
onFocusCapture: () => setPaused(true),
|
|
3412
|
+
onBlurCapture: () => setPaused(false),
|
|
3413
|
+
className: cn(
|
|
3414
|
+
"fixed bottom-6 left-1/2 z-toast flex max-w-[92vw] -translate-x-1/2 items-center gap-2.5",
|
|
3415
|
+
"rounded-control bg-inverseSurface py-2.5 pl-4 pr-2.5 text-sm font-medium text-text-inverse shadow-overlay",
|
|
3416
|
+
className
|
|
3417
|
+
),
|
|
3418
|
+
children: [
|
|
3419
|
+
ICON[tone] && // The inverse pair, not text-success / text-warning: those are tuned
|
|
3420
|
+
// for the page, and on the toast's flipped surface amber drops to 2:1.
|
|
3421
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3422
|
+
"span",
|
|
3423
|
+
{
|
|
3424
|
+
className: cn(
|
|
3425
|
+
"flex",
|
|
3426
|
+
tone === "success" ? "text-text-inverseSuccess" : "text-text-inverseWarning"
|
|
3427
|
+
),
|
|
3428
|
+
children: ICON[tone]
|
|
3429
|
+
}
|
|
3430
|
+
),
|
|
3431
|
+
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)("span", { className: "min-w-0", children: message }),
|
|
3432
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
3433
|
+
"button",
|
|
3434
|
+
{
|
|
3435
|
+
type: "button",
|
|
3436
|
+
onClick: () => {
|
|
3437
|
+
if (!closed.current) {
|
|
3438
|
+
closed.current = true;
|
|
3439
|
+
action.onClick();
|
|
3440
|
+
}
|
|
3441
|
+
},
|
|
3442
|
+
className: "shrink-0 rounded-control px-2.5 py-1 text-sm font-semibold text-text-inverse underline-offset-2 transition-colors duration-(--mr-motion-duration-interactive) ease-interactive hover:bg-text-inverse/15 hover:underline focus-visible:outline-solid focus-visible:outline-2 focus-visible:outline-border-focus",
|
|
3443
|
+
children: action.label
|
|
3444
|
+
}
|
|
3445
|
+
)
|
|
3446
|
+
]
|
|
3447
|
+
}
|
|
3448
|
+
),
|
|
3449
|
+
document.body
|
|
3450
|
+
);
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
// src/Tag.tsx
|
|
3454
|
+
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
3353
3455
|
function Tag({ children, className }) {
|
|
3354
|
-
return /* @__PURE__ */ (0,
|
|
3456
|
+
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
|
|
3355
3457
|
"span",
|
|
3356
3458
|
{
|
|
3357
3459
|
className: cn(
|
|
@@ -3370,8 +3472,8 @@ function Tag({ children, className }) {
|
|
|
3370
3472
|
}
|
|
3371
3473
|
|
|
3372
3474
|
// src/TablePagination.tsx
|
|
3373
|
-
var
|
|
3374
|
-
var
|
|
3475
|
+
var import_lucide_react21 = require("lucide-react");
|
|
3476
|
+
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
3375
3477
|
function TablePagination({
|
|
3376
3478
|
page,
|
|
3377
3479
|
perPage,
|
|
@@ -3392,10 +3494,10 @@ function TablePagination({
|
|
|
3392
3494
|
btn,
|
|
3393
3495
|
"text-text-secondary hover:bg-subtle hover:text-text-primary disabled:pointer-events-none disabled:opacity-30"
|
|
3394
3496
|
);
|
|
3395
|
-
return /* @__PURE__ */ (0,
|
|
3396
|
-
/* @__PURE__ */ (0,
|
|
3397
|
-
/* @__PURE__ */ (0,
|
|
3398
|
-
/* @__PURE__ */ (0,
|
|
3497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-2", className), "data-testid": testIdPrefix, children: [
|
|
3498
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("label", { className: "flex items-center gap-2 text-[13px] text-text-secondary", children: [
|
|
3499
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "relative", children: [
|
|
3500
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3399
3501
|
"select",
|
|
3400
3502
|
{
|
|
3401
3503
|
value: perPage,
|
|
@@ -3403,11 +3505,11 @@ function TablePagination({
|
|
|
3403
3505
|
"aria-label": "Items per page",
|
|
3404
3506
|
"data-testid": testIdPrefix && `${testIdPrefix}-per-page`,
|
|
3405
3507
|
className: "appearance-none rounded-control border border-border-strong bg-input py-1 pl-2.5 pr-7 text-[13px] font-medium text-text-primary focus:outline focus:outline-2 focus:outline-border-focus",
|
|
3406
|
-
children: perPageOptions.map((n) => /* @__PURE__ */ (0,
|
|
3508
|
+
children: perPageOptions.map((n) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("option", { value: n, children: n }, n))
|
|
3407
3509
|
}
|
|
3408
3510
|
),
|
|
3409
|
-
/* @__PURE__ */ (0,
|
|
3410
|
-
|
|
3511
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3512
|
+
import_lucide_react21.ChevronDown,
|
|
3411
3513
|
{
|
|
3412
3514
|
size: 13,
|
|
3413
3515
|
"aria-hidden": "true",
|
|
@@ -3417,8 +3519,8 @@ function TablePagination({
|
|
|
3417
3519
|
] }),
|
|
3418
3520
|
"items per page"
|
|
3419
3521
|
] }),
|
|
3420
|
-
/* @__PURE__ */ (0,
|
|
3421
|
-
/* @__PURE__ */ (0,
|
|
3522
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("nav", { className: "flex items-center gap-1", "aria-label": "Pagination", children: [
|
|
3523
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3422
3524
|
"button",
|
|
3423
3525
|
{
|
|
3424
3526
|
type: "button",
|
|
@@ -3427,10 +3529,10 @@ function TablePagination({
|
|
|
3427
3529
|
"aria-label": "First page",
|
|
3428
3530
|
"data-testid": testIdPrefix && `${testIdPrefix}-first`,
|
|
3429
3531
|
className: stepBtn,
|
|
3430
|
-
children: /* @__PURE__ */ (0,
|
|
3532
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react21.ChevronFirst, { size: 16, "aria-hidden": "true" })
|
|
3431
3533
|
}
|
|
3432
3534
|
),
|
|
3433
|
-
/* @__PURE__ */ (0,
|
|
3535
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3434
3536
|
"button",
|
|
3435
3537
|
{
|
|
3436
3538
|
type: "button",
|
|
@@ -3439,11 +3541,11 @@ function TablePagination({
|
|
|
3439
3541
|
"aria-label": "Previous page",
|
|
3440
3542
|
"data-testid": testIdPrefix && `${testIdPrefix}-prev`,
|
|
3441
3543
|
className: stepBtn,
|
|
3442
|
-
children: /* @__PURE__ */ (0,
|
|
3544
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react21.ChevronLeft, { size: 16, "aria-hidden": "true" })
|
|
3443
3545
|
}
|
|
3444
3546
|
),
|
|
3445
3547
|
pageWindow(current, totalPages).map(
|
|
3446
|
-
(p) => typeof p === "string" ? /* @__PURE__ */ (0,
|
|
3548
|
+
(p) => typeof p === "string" ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "px-1 text-[13px] text-text-tertiary", children: "\u2026" }, p) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3447
3549
|
"button",
|
|
3448
3550
|
{
|
|
3449
3551
|
type: "button",
|
|
@@ -3459,7 +3561,7 @@ function TablePagination({
|
|
|
3459
3561
|
p
|
|
3460
3562
|
)
|
|
3461
3563
|
),
|
|
3462
|
-
/* @__PURE__ */ (0,
|
|
3564
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3463
3565
|
"button",
|
|
3464
3566
|
{
|
|
3465
3567
|
type: "button",
|
|
@@ -3468,10 +3570,10 @@ function TablePagination({
|
|
|
3468
3570
|
"aria-label": "Next page",
|
|
3469
3571
|
"data-testid": testIdPrefix && `${testIdPrefix}-next`,
|
|
3470
3572
|
className: stepBtn,
|
|
3471
|
-
children: /* @__PURE__ */ (0,
|
|
3573
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react21.ChevronRight, { size: 16, "aria-hidden": "true" })
|
|
3472
3574
|
}
|
|
3473
3575
|
),
|
|
3474
|
-
/* @__PURE__ */ (0,
|
|
3576
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
|
|
3475
3577
|
"button",
|
|
3476
3578
|
{
|
|
3477
3579
|
type: "button",
|
|
@@ -3480,11 +3582,11 @@ function TablePagination({
|
|
|
3480
3582
|
"aria-label": "Last page",
|
|
3481
3583
|
"data-testid": testIdPrefix && `${testIdPrefix}-last`,
|
|
3482
3584
|
className: stepBtn,
|
|
3483
|
-
children: /* @__PURE__ */ (0,
|
|
3585
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_lucide_react21.ChevronLast, { size: 16, "aria-hidden": "true" })
|
|
3484
3586
|
}
|
|
3485
3587
|
)
|
|
3486
3588
|
] }),
|
|
3487
|
-
/* @__PURE__ */ (0,
|
|
3589
|
+
/* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("span", { className: "text-[13px] text-text-tertiary tabular-nums", children: [
|
|
3488
3590
|
rangeStart.toLocaleString(),
|
|
3489
3591
|
" \u2013 ",
|
|
3490
3592
|
rangeEnd.toLocaleString(),
|
|
@@ -3497,9 +3599,9 @@ function TablePagination({
|
|
|
3497
3599
|
}
|
|
3498
3600
|
|
|
3499
3601
|
// src/DateRangePicker.tsx
|
|
3500
|
-
var
|
|
3501
|
-
var
|
|
3502
|
-
var
|
|
3602
|
+
var import_react16 = require("react");
|
|
3603
|
+
var import_lucide_react22 = require("lucide-react");
|
|
3604
|
+
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
3503
3605
|
var MONTH_ABBR = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|
3504
3606
|
var QUARTER_ABBR = ["Q1", "Q2", "Q3", "Q4"];
|
|
3505
3607
|
var PRESETS = ["Rolling 3 months", "Rolling 6 months", "Rolling 12 months"];
|
|
@@ -3535,7 +3637,7 @@ function spanLabel(label, today) {
|
|
|
3535
3637
|
return `${fmtDate(s)} \u2013 ${fmtDate(e)}`;
|
|
3536
3638
|
}
|
|
3537
3639
|
function MiniSelect({ value, onChange, options }) {
|
|
3538
|
-
return /* @__PURE__ */ (0,
|
|
3640
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
3539
3641
|
"select",
|
|
3540
3642
|
{
|
|
3541
3643
|
value: String(value),
|
|
@@ -3543,8 +3645,8 @@ function MiniSelect({ value, onChange, options }) {
|
|
|
3543
3645
|
const opt = options.find((o) => String(o.value) === e.target.value);
|
|
3544
3646
|
if (opt) onChange(opt.value);
|
|
3545
3647
|
},
|
|
3546
|
-
className: "rounded-control border border-border-strong bg-input px-1.5 py-1 text-[12px] text-text-primary outline-
|
|
3547
|
-
children: options.map((o) => /* @__PURE__ */ (0,
|
|
3648
|
+
className: "rounded-control border border-border-strong bg-input px-1.5 py-1 text-[12px] text-text-primary focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus",
|
|
3649
|
+
children: options.map((o) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("option", { value: String(o.value), children: o.label }, String(o.value)))
|
|
3548
3650
|
}
|
|
3549
3651
|
);
|
|
3550
3652
|
}
|
|
@@ -3559,19 +3661,19 @@ function DateRangePicker({
|
|
|
3559
3661
|
today,
|
|
3560
3662
|
years
|
|
3561
3663
|
}) {
|
|
3562
|
-
const end = (0,
|
|
3664
|
+
const end = (0, import_react16.useMemo)(() => today ?? startOfToday(), [today]);
|
|
3563
3665
|
const yearOptions = years ?? [3, 2, 1, 0].map((n) => end.getFullYear() - n);
|
|
3564
|
-
const [open, setOpen] = (0,
|
|
3565
|
-
const [value, setValue] = (0,
|
|
3566
|
-
const [draft, setDraft] = (0,
|
|
3567
|
-
const ref = (0,
|
|
3568
|
-
const [fromMo, setFromMo] = (0,
|
|
3569
|
-
const [fromYr, setFromYr] = (0,
|
|
3570
|
-
const [toMo, setToMo] = (0,
|
|
3571
|
-
const [toYr, setToYr] = (0,
|
|
3572
|
-
const [fromQ, setFromQ] = (0,
|
|
3573
|
-
const [toQ, setToQ] = (0,
|
|
3574
|
-
(0,
|
|
3666
|
+
const [open, setOpen] = (0, import_react16.useState)(false);
|
|
3667
|
+
const [value, setValue] = (0, import_react16.useState)(defaultValue);
|
|
3668
|
+
const [draft, setDraft] = (0, import_react16.useState)(defaultValue);
|
|
3669
|
+
const ref = (0, import_react16.useRef)(null);
|
|
3670
|
+
const [fromMo, setFromMo] = (0, import_react16.useState)(end.getMonth());
|
|
3671
|
+
const [fromYr, setFromYr] = (0, import_react16.useState)(end.getFullYear() - 1);
|
|
3672
|
+
const [toMo, setToMo] = (0, import_react16.useState)(end.getMonth());
|
|
3673
|
+
const [toYr, setToYr] = (0, import_react16.useState)(end.getFullYear());
|
|
3674
|
+
const [fromQ, setFromQ] = (0, import_react16.useState)(Math.floor(end.getMonth() / 3));
|
|
3675
|
+
const [toQ, setToQ] = (0, import_react16.useState)(Math.floor(end.getMonth() / 3));
|
|
3676
|
+
(0, import_react16.useEffect)(() => {
|
|
3575
3677
|
const [s, e] = resolveRange(value, end);
|
|
3576
3678
|
onRangeChange?.(s, e);
|
|
3577
3679
|
}, [value]);
|
|
@@ -3579,7 +3681,7 @@ function DateRangePicker({
|
|
|
3579
3681
|
if (!open) setDraft(value);
|
|
3580
3682
|
setOpen((o) => !o);
|
|
3581
3683
|
};
|
|
3582
|
-
(0,
|
|
3684
|
+
(0, import_react16.useEffect)(() => {
|
|
3583
3685
|
if (!open) return;
|
|
3584
3686
|
const onDown = (e) => {
|
|
3585
3687
|
if (ref.current && !ref.current.contains(e.target)) setOpen(false);
|
|
@@ -3605,8 +3707,8 @@ function DateRangePicker({
|
|
|
3605
3707
|
if (showFooter) setDraft(label);
|
|
3606
3708
|
else commit(label);
|
|
3607
3709
|
};
|
|
3608
|
-
return /* @__PURE__ */ (0,
|
|
3609
|
-
/* @__PURE__ */ (0,
|
|
3710
|
+
return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "relative", ref, children: [
|
|
3711
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
|
|
3610
3712
|
"button",
|
|
3611
3713
|
{
|
|
3612
3714
|
type: "button",
|
|
@@ -3615,16 +3717,16 @@ function DateRangePicker({
|
|
|
3615
3717
|
"aria-haspopup": "listbox",
|
|
3616
3718
|
className: chipTriggerClass(),
|
|
3617
3719
|
children: [
|
|
3618
|
-
/* @__PURE__ */ (0,
|
|
3619
|
-
/* @__PURE__ */ (0,
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
3720
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "flex flex-col gap-1 text-left leading-none", children: [
|
|
3721
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-control-caption text-text-tertiary", children: spanLabel(value, end) }),
|
|
3722
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "text-[12px] font-medium text-text-primary", children: value })
|
|
3621
3723
|
] }),
|
|
3622
|
-
/* @__PURE__ */ (0,
|
|
3724
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_lucide_react22.ChevronDown, { size: 14, "aria-hidden": "true", className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180") })
|
|
3623
3725
|
]
|
|
3624
3726
|
}
|
|
3625
3727
|
),
|
|
3626
|
-
open && /* @__PURE__ */ (0,
|
|
3627
|
-
presets.map((p) => /* @__PURE__ */ (0,
|
|
3728
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: cn("absolute top-[calc(100%+8px)] z-30 w-[280px] overflow-hidden rounded-card border border-border-default bg-surface py-1 shadow-overlay", align === "right" ? "right-0" : "left-0"), children: [
|
|
3729
|
+
presets.map((p) => /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
3628
3730
|
"button",
|
|
3629
3731
|
{
|
|
3630
3732
|
type: "button",
|
|
@@ -3634,26 +3736,26 @@ function DateRangePicker({
|
|
|
3634
3736
|
},
|
|
3635
3737
|
p
|
|
3636
3738
|
)),
|
|
3637
|
-
/* @__PURE__ */ (0,
|
|
3638
|
-
/* @__PURE__ */ (0,
|
|
3639
|
-
/* @__PURE__ */ (0,
|
|
3640
|
-
/* @__PURE__ */ (0,
|
|
3739
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "mt-1 border-t border-border-default px-3 pb-2 pt-2", children: [
|
|
3740
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "text-[13px] font-semibold text-text-primary", children: "Custom Range" }),
|
|
3741
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "mt-2 flex flex-col gap-2", children: [
|
|
3742
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
|
|
3641
3743
|
"From",
|
|
3642
|
-
/* @__PURE__ */ (0,
|
|
3643
|
-
granularity === "month" && /* @__PURE__ */ (0,
|
|
3644
|
-
granularity === "quarter" && /* @__PURE__ */ (0,
|
|
3645
|
-
/* @__PURE__ */ (0,
|
|
3744
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "flex gap-1", children: [
|
|
3745
|
+
granularity === "month" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3746
|
+
granularity === "quarter" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MiniSelect, { value: fromQ, onChange: setFromQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
|
|
3747
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
|
|
3646
3748
|
] })
|
|
3647
3749
|
] }),
|
|
3648
|
-
/* @__PURE__ */ (0,
|
|
3750
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
|
|
3649
3751
|
"To",
|
|
3650
|
-
/* @__PURE__ */ (0,
|
|
3651
|
-
granularity === "month" && /* @__PURE__ */ (0,
|
|
3652
|
-
granularity === "quarter" && /* @__PURE__ */ (0,
|
|
3653
|
-
/* @__PURE__ */ (0,
|
|
3752
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("span", { className: "flex gap-1", children: [
|
|
3753
|
+
granularity === "month" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
|
|
3754
|
+
granularity === "quarter" && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MiniSelect, { value: toQ, onChange: setToQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
|
|
3755
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
|
|
3654
3756
|
] })
|
|
3655
3757
|
] }),
|
|
3656
|
-
/* @__PURE__ */ (0,
|
|
3758
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
3657
3759
|
"button",
|
|
3658
3760
|
{
|
|
3659
3761
|
type: "button",
|
|
@@ -3665,15 +3767,15 @@ function DateRangePicker({
|
|
|
3665
3767
|
)
|
|
3666
3768
|
] })
|
|
3667
3769
|
] }),
|
|
3668
|
-
showFooter && /* @__PURE__ */ (0,
|
|
3770
|
+
showFooter && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(FilterDropdownFooter, { onApply: () => commit(draft) })
|
|
3669
3771
|
] })
|
|
3670
3772
|
] });
|
|
3671
3773
|
}
|
|
3672
3774
|
|
|
3673
3775
|
// src/MultiSelectFilter.tsx
|
|
3674
|
-
var
|
|
3675
|
-
var
|
|
3676
|
-
var
|
|
3776
|
+
var import_react17 = require("react");
|
|
3777
|
+
var import_lucide_react23 = require("lucide-react");
|
|
3778
|
+
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
3677
3779
|
function MultiSelectFilter({
|
|
3678
3780
|
caption,
|
|
3679
3781
|
options = [],
|
|
@@ -3697,11 +3799,11 @@ function MultiSelectFilter({
|
|
|
3697
3799
|
}) {
|
|
3698
3800
|
const groupLeaves = (g) => g.children.length ? g.children : [{ id: g.id, label: g.label }];
|
|
3699
3801
|
const leafOptions = groups ? groups.flatMap(groupLeaves) : options;
|
|
3700
|
-
const [open, setOpen] = (0,
|
|
3701
|
-
const [q, setQ] = (0,
|
|
3702
|
-
const [draft, setDraft] = (0,
|
|
3703
|
-
const ref = (0,
|
|
3704
|
-
const close = (0,
|
|
3802
|
+
const [open, setOpen] = (0, import_react17.useState)(false);
|
|
3803
|
+
const [q, setQ] = (0, import_react17.useState)("");
|
|
3804
|
+
const [draft, setDraft] = (0, import_react17.useState)(selected);
|
|
3805
|
+
const ref = (0, import_react17.useRef)(null);
|
|
3806
|
+
const close = (0, import_react17.useCallback)(() => {
|
|
3705
3807
|
setOpen(false);
|
|
3706
3808
|
setQ("");
|
|
3707
3809
|
if (showFooter) return;
|
|
@@ -3718,7 +3820,7 @@ function MultiSelectFilter({
|
|
|
3718
3820
|
setOpen(false);
|
|
3719
3821
|
setQ("");
|
|
3720
3822
|
};
|
|
3721
|
-
(0,
|
|
3823
|
+
(0, import_react17.useEffect)(() => {
|
|
3722
3824
|
if (!open) return;
|
|
3723
3825
|
const onKey = (e) => e.key === "Escape" && close();
|
|
3724
3826
|
const onClick = (e) => {
|
|
@@ -3764,8 +3866,8 @@ function MultiSelectFilter({
|
|
|
3764
3866
|
const kids = live.filter((c) => c.label.toLowerCase().includes(ql));
|
|
3765
3867
|
return kids.length ? { ...g, children: kids } : null;
|
|
3766
3868
|
}).filter((g) => g !== null) : [];
|
|
3767
|
-
return /* @__PURE__ */ (0,
|
|
3768
|
-
/* @__PURE__ */ (0,
|
|
3869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
|
|
3870
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3769
3871
|
"button",
|
|
3770
3872
|
{
|
|
3771
3873
|
type: "button",
|
|
@@ -3773,9 +3875,9 @@ function MultiSelectFilter({
|
|
|
3773
3875
|
"aria-expanded": open,
|
|
3774
3876
|
className: cn(chipTriggerClass(variant), fullWidth && "w-full justify-between"),
|
|
3775
3877
|
children: [
|
|
3776
|
-
/* @__PURE__ */ (0,
|
|
3777
|
-
/* @__PURE__ */ (0,
|
|
3778
|
-
|
|
3878
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ChipContent, { caption, value, icon }),
|
|
3879
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3880
|
+
import_lucide_react23.ChevronDown,
|
|
3779
3881
|
{
|
|
3780
3882
|
size: 14,
|
|
3781
3883
|
"aria-hidden": "true",
|
|
@@ -3785,7 +3887,7 @@ function MultiSelectFilter({
|
|
|
3785
3887
|
]
|
|
3786
3888
|
}
|
|
3787
3889
|
),
|
|
3788
|
-
open && /* @__PURE__ */ (0,
|
|
3890
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3789
3891
|
"div",
|
|
3790
3892
|
{
|
|
3791
3893
|
className: cn(
|
|
@@ -3796,9 +3898,9 @@ function MultiSelectFilter({
|
|
|
3796
3898
|
role: "dialog",
|
|
3797
3899
|
"aria-label": caption,
|
|
3798
3900
|
children: [
|
|
3799
|
-
searchable && /* @__PURE__ */ (0,
|
|
3800
|
-
/* @__PURE__ */ (0,
|
|
3801
|
-
/* @__PURE__ */ (0,
|
|
3901
|
+
searchable && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex h-8 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus", children: [
|
|
3902
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react23.Search, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
|
|
3903
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3802
3904
|
"input",
|
|
3803
3905
|
{
|
|
3804
3906
|
type: "text",
|
|
@@ -3808,37 +3910,37 @@ function MultiSelectFilter({
|
|
|
3808
3910
|
className: "h-full flex-1 bg-transparent text-[13px] outline-hidden placeholder:text-text-tertiary"
|
|
3809
3911
|
}
|
|
3810
3912
|
),
|
|
3811
|
-
q && /* @__PURE__ */ (0,
|
|
3913
|
+
q && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("button", { type: "button", onClick: () => setQ(""), "aria-label": "Clear search", className: "text-text-tertiary hover:text-text-primary", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react23.X, { size: 13 }) })
|
|
3812
3914
|
] }) }),
|
|
3813
|
-
/* @__PURE__ */ (0,
|
|
3915
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "max-h-[280px] overflow-y-auto p-1", children: [
|
|
3814
3916
|
groups ? visibleGroups.map((g) => {
|
|
3815
3917
|
const state = groupState(g);
|
|
3816
|
-
return /* @__PURE__ */ (0,
|
|
3817
|
-
/* @__PURE__ */ (0,
|
|
3918
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
|
|
3919
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3818
3920
|
"button",
|
|
3819
3921
|
{
|
|
3820
3922
|
type: "button",
|
|
3821
3923
|
onClick: () => toggleGroup(g),
|
|
3822
3924
|
className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
|
|
3823
3925
|
children: [
|
|
3824
|
-
/* @__PURE__ */ (0,
|
|
3825
|
-
/* @__PURE__ */ (0,
|
|
3826
|
-
counts && /* @__PURE__ */ (0,
|
|
3926
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(TriCheck, { state }),
|
|
3927
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label }),
|
|
3928
|
+
counts && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(OptionCount, { n: countFor(g.id) })
|
|
3827
3929
|
]
|
|
3828
3930
|
}
|
|
3829
3931
|
),
|
|
3830
3932
|
g.children.map((c) => {
|
|
3831
3933
|
const checked = draft.includes(c.id);
|
|
3832
|
-
return /* @__PURE__ */ (0,
|
|
3934
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3833
3935
|
"button",
|
|
3834
3936
|
{
|
|
3835
3937
|
type: "button",
|
|
3836
3938
|
onClick: () => toggle(c.id),
|
|
3837
3939
|
className: "flex w-full items-center gap-2.5 rounded-control py-2 pl-9 pr-2 text-left transition-colors hover:bg-subtle",
|
|
3838
3940
|
children: [
|
|
3839
|
-
/* @__PURE__ */ (0,
|
|
3840
|
-
/* @__PURE__ */ (0,
|
|
3841
|
-
counts && /* @__PURE__ */ (0,
|
|
3941
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(TriCheck, { state: checked ? "all" : "none" }),
|
|
3942
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label }),
|
|
3943
|
+
counts && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(OptionCount, { n: countFor(c.id) })
|
|
3842
3944
|
]
|
|
3843
3945
|
},
|
|
3844
3946
|
c.id
|
|
@@ -3847,33 +3949,33 @@ function MultiSelectFilter({
|
|
|
3847
3949
|
] }, g.id);
|
|
3848
3950
|
}) : items.map((o) => {
|
|
3849
3951
|
const checked = draft.includes(o.id);
|
|
3850
|
-
return /* @__PURE__ */ (0,
|
|
3952
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3851
3953
|
"button",
|
|
3852
3954
|
{
|
|
3853
3955
|
type: "button",
|
|
3854
3956
|
onClick: () => toggle(o.id),
|
|
3855
3957
|
className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
|
|
3856
3958
|
children: [
|
|
3857
|
-
/* @__PURE__ */ (0,
|
|
3959
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
3858
3960
|
"span",
|
|
3859
3961
|
{
|
|
3860
3962
|
className: cn(
|
|
3861
3963
|
"flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
|
|
3862
3964
|
checked ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
|
|
3863
3965
|
),
|
|
3864
|
-
children: checked && /* @__PURE__ */ (0,
|
|
3966
|
+
children: checked && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react23.Check, { size: 13, strokeWidth: 3 })
|
|
3865
3967
|
}
|
|
3866
3968
|
),
|
|
3867
|
-
/* @__PURE__ */ (0,
|
|
3868
|
-
counts && /* @__PURE__ */ (0,
|
|
3969
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label }),
|
|
3970
|
+
counts && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(OptionCount, { n: countFor(o.id) })
|
|
3869
3971
|
]
|
|
3870
3972
|
},
|
|
3871
3973
|
o.id
|
|
3872
3974
|
);
|
|
3873
3975
|
}),
|
|
3874
|
-
(groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ (0,
|
|
3976
|
+
(groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "py-6 text-center text-[13px] text-text-tertiary", children: "No matches." })
|
|
3875
3977
|
] }),
|
|
3876
|
-
showFooter ? /* @__PURE__ */ (0,
|
|
3978
|
+
showFooter ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(FilterDropdownFooter, { onClear: () => setDraft(clearValue), onApply: apply }) : min === 0 && draft.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "border-t border-border-default p-2", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3877
3979
|
"button",
|
|
3878
3980
|
{
|
|
3879
3981
|
type: "button",
|
|
@@ -3892,7 +3994,7 @@ function MultiSelectFilter({
|
|
|
3892
3994
|
}
|
|
3893
3995
|
function TriCheck({ state }) {
|
|
3894
3996
|
const filled = state !== "none";
|
|
3895
|
-
return /* @__PURE__ */ (0,
|
|
3997
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
|
|
3896
3998
|
"span",
|
|
3897
3999
|
{
|
|
3898
4000
|
className: cn(
|
|
@@ -3900,14 +4002,14 @@ function TriCheck({ state }) {
|
|
|
3900
4002
|
filled ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
|
|
3901
4003
|
),
|
|
3902
4004
|
children: [
|
|
3903
|
-
state === "all" && /* @__PURE__ */ (0,
|
|
3904
|
-
state === "some" && /* @__PURE__ */ (0,
|
|
4005
|
+
state === "all" && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react23.Check, { size: 13, strokeWidth: 3 }),
|
|
4006
|
+
state === "some" && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react23.Minus, { size: 13, strokeWidth: 3 })
|
|
3905
4007
|
]
|
|
3906
4008
|
}
|
|
3907
4009
|
);
|
|
3908
4010
|
}
|
|
3909
4011
|
function OptionCount({ n }) {
|
|
3910
|
-
return /* @__PURE__ */ (0,
|
|
4012
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("span", { className: "shrink-0 text-[12px] tabular-nums text-text-tertiary", children: [
|
|
3911
4013
|
"(",
|
|
3912
4014
|
n.toLocaleString(),
|
|
3913
4015
|
")"
|
|
@@ -3915,7 +4017,7 @@ function OptionCount({ n }) {
|
|
|
3915
4017
|
}
|
|
3916
4018
|
|
|
3917
4019
|
// src/Toggle.tsx
|
|
3918
|
-
var
|
|
4020
|
+
var import_jsx_runtime39 = require("react/jsx-runtime");
|
|
3919
4021
|
var SIZES2 = {
|
|
3920
4022
|
sm: { track: "h-5 w-9", knob: "h-4 w-4", on: "translate-x-[18px]" },
|
|
3921
4023
|
md: { track: "h-6 w-11", knob: "h-5 w-5", on: "translate-x-[22px]" }
|
|
@@ -3923,7 +4025,7 @@ var SIZES2 = {
|
|
|
3923
4025
|
var OFF_TRACK = "color-mix(in srgb, var(--mr-color-border-interactive) 70%, var(--mr-color-text-secondary))";
|
|
3924
4026
|
function Toggle({ checked, onChange, label, size = "md", disabled, className, testIdPrefix }) {
|
|
3925
4027
|
const s = SIZES2[size];
|
|
3926
|
-
return /* @__PURE__ */ (0,
|
|
4028
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
3927
4029
|
"button",
|
|
3928
4030
|
{
|
|
3929
4031
|
type: "button",
|
|
@@ -3941,7 +4043,7 @@ function Toggle({ checked, onChange, label, size = "md", disabled, className, te
|
|
|
3941
4043
|
disabled && "cursor-not-allowed opacity-50",
|
|
3942
4044
|
className
|
|
3943
4045
|
),
|
|
3944
|
-
children: /* @__PURE__ */ (0,
|
|
4046
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
|
|
3945
4047
|
"span",
|
|
3946
4048
|
{
|
|
3947
4049
|
className: cn(
|
|
@@ -3956,22 +4058,22 @@ function Toggle({ checked, onChange, label, size = "md", disabled, className, te
|
|
|
3956
4058
|
}
|
|
3957
4059
|
|
|
3958
4060
|
// src/AISpark.tsx
|
|
3959
|
-
var
|
|
3960
|
-
var
|
|
3961
|
-
var
|
|
4061
|
+
var import_react18 = require("react");
|
|
4062
|
+
var import_lucide_react24 = require("lucide-react");
|
|
4063
|
+
var import_jsx_runtime40 = require("react/jsx-runtime");
|
|
3962
4064
|
function AISpark({ size = 16, className }) {
|
|
3963
|
-
const id = (0,
|
|
3964
|
-
return /* @__PURE__ */ (0,
|
|
3965
|
-
/* @__PURE__ */ (0,
|
|
3966
|
-
/* @__PURE__ */ (0,
|
|
3967
|
-
/* @__PURE__ */ (0,
|
|
4065
|
+
const id = (0, import_react18.useId)();
|
|
4066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
4067
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("svg", { width: "0", height: "0", "aria-hidden": "true", style: { position: "absolute" }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)("linearGradient", { id, x1: "0", y1: "0", x2: "1", y2: "1", children: [
|
|
4068
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { offset: "0%", stopColor: "var(--mr-color-brand-primary)" }),
|
|
4069
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)("stop", { offset: "100%", className: "[stop-color:#9474ff] in-data-[theme=dark]:[stop-color:#a488ff]" })
|
|
3968
4070
|
] }) }) }),
|
|
3969
|
-
/* @__PURE__ */ (0,
|
|
4071
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react24.Sparkles, { size, stroke: `url(#${id})`, className, "aria-hidden": "true" })
|
|
3970
4072
|
] });
|
|
3971
4073
|
}
|
|
3972
4074
|
|
|
3973
4075
|
// src/Freshness.tsx
|
|
3974
|
-
var
|
|
4076
|
+
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
3975
4077
|
var dotColor = {
|
|
3976
4078
|
fresh: "bg-status-success",
|
|
3977
4079
|
recent: "bg-status-warning",
|
|
@@ -3983,7 +4085,7 @@ var srLabel = {
|
|
|
3983
4085
|
stale: "Older than a day"
|
|
3984
4086
|
};
|
|
3985
4087
|
function Freshness({ level }) {
|
|
3986
|
-
return /* @__PURE__ */ (0,
|
|
4088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
3987
4089
|
"span",
|
|
3988
4090
|
{
|
|
3989
4091
|
className: cn("inline-block h-1.5 w-1.5 shrink-0 rounded-full", dotColor[level]),
|
|
@@ -3994,28 +4096,306 @@ function Freshness({ level }) {
|
|
|
3994
4096
|
}
|
|
3995
4097
|
|
|
3996
4098
|
// src/SectionHeading.tsx
|
|
3997
|
-
var
|
|
4099
|
+
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
3998
4100
|
function SectionHeading({ title, description, actions, as: Tag2 = "h2", id, className }) {
|
|
3999
|
-
return /* @__PURE__ */ (0,
|
|
4000
|
-
/* @__PURE__ */ (0,
|
|
4001
|
-
/* @__PURE__ */ (0,
|
|
4002
|
-
description && /* @__PURE__ */ (0,
|
|
4101
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: cn("flex flex-wrap items-end justify-between gap-x-4 gap-y-2", className), children: [
|
|
4102
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "min-w-0", children: [
|
|
4103
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Tag2, { id, className: "text-base font-semibold text-text-primary", children: title }),
|
|
4104
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { className: "mt-0.5 text-dense text-text-secondary", children: description })
|
|
4003
4105
|
] }),
|
|
4004
|
-
actions && /* @__PURE__ */ (0,
|
|
4106
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
4005
4107
|
] });
|
|
4006
4108
|
}
|
|
4007
4109
|
|
|
4008
4110
|
// src/PageHeader.tsx
|
|
4009
|
-
var
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
|
|
4014
|
-
|
|
4111
|
+
var import_lucide_react25 = require("lucide-react");
|
|
4112
|
+
var import_jsx_runtime43 = require("react/jsx-runtime");
|
|
4113
|
+
function PageHeader({ title, description, actions, back, className }) {
|
|
4114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("header", { className: cn("flex flex-wrap items-center justify-between gap-x-6 gap-y-3", className), children: [
|
|
4115
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsxs)("div", { className: "min-w-0", children: [
|
|
4116
|
+
back && /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
|
|
4117
|
+
"a",
|
|
4118
|
+
{
|
|
4119
|
+
href: back.href ?? "#",
|
|
4120
|
+
onClick: back.onClick,
|
|
4121
|
+
className: "mb-1.5 inline-flex items-center gap-1.5 rounded-control text-micro font-semibold uppercase tracking-wider text-text-tertiary hover:text-text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
4122
|
+
children: [
|
|
4123
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_lucide_react25.ArrowLeft, { size: 13, "aria-hidden": "true" }),
|
|
4124
|
+
back.label
|
|
4125
|
+
]
|
|
4126
|
+
}
|
|
4127
|
+
),
|
|
4128
|
+
/* @__PURE__ */ (0, import_jsx_runtime43.jsx)("h1", { className: "text-xl font-semibold tracking-tight text-text-primary", children: title }),
|
|
4129
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("p", { className: "mt-0.5 max-w-2xl text-sm text-text-secondary", children: description })
|
|
4015
4130
|
] }),
|
|
4016
|
-
actions && /* @__PURE__ */ (0,
|
|
4131
|
+
actions && /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
4017
4132
|
] });
|
|
4018
4133
|
}
|
|
4134
|
+
|
|
4135
|
+
// src/Modal.tsx
|
|
4136
|
+
var import_react19 = require("react");
|
|
4137
|
+
var import_react_dom7 = require("react-dom");
|
|
4138
|
+
var import_lucide_react26 = require("lucide-react");
|
|
4139
|
+
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
4140
|
+
var WIDTH = {
|
|
4141
|
+
sm: "max-w-110",
|
|
4142
|
+
md: "max-w-160",
|
|
4143
|
+
lg: "max-w-220"
|
|
4144
|
+
};
|
|
4145
|
+
var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
4146
|
+
function Modal({ open, onClose, title, description, size = "md", footer, children, className }) {
|
|
4147
|
+
const titleId = (0, import_react19.useId)();
|
|
4148
|
+
const descId = (0, import_react19.useId)();
|
|
4149
|
+
const panel = (0, import_react19.useRef)(null);
|
|
4150
|
+
const close = (0, import_react19.useRef)(onClose);
|
|
4151
|
+
close.current = onClose;
|
|
4152
|
+
(0, import_react19.useEffect)(() => {
|
|
4153
|
+
if (!open) return;
|
|
4154
|
+
const opener = document.activeElement;
|
|
4155
|
+
const first = panel.current?.querySelector(`[data-modal-body] :is(${FOCUSABLE})`) ?? panel.current?.querySelector(`[data-modal-footer] :is(${FOCUSABLE})`);
|
|
4156
|
+
(first ?? panel.current)?.focus();
|
|
4157
|
+
const overflow = document.body.style.overflow;
|
|
4158
|
+
document.body.style.overflow = "hidden";
|
|
4159
|
+
const onKey = (e) => {
|
|
4160
|
+
if (e.key === "Escape") {
|
|
4161
|
+
e.stopPropagation();
|
|
4162
|
+
close.current();
|
|
4163
|
+
return;
|
|
4164
|
+
}
|
|
4165
|
+
if (e.key !== "Tab" || !panel.current) return;
|
|
4166
|
+
const items = Array.from(panel.current.querySelectorAll(FOCUSABLE));
|
|
4167
|
+
if (items.length === 0) return;
|
|
4168
|
+
const [head, tail] = [items[0], items[items.length - 1]];
|
|
4169
|
+
if (e.shiftKey && document.activeElement === head) {
|
|
4170
|
+
e.preventDefault();
|
|
4171
|
+
tail.focus();
|
|
4172
|
+
} else if (!e.shiftKey && document.activeElement === tail) {
|
|
4173
|
+
e.preventDefault();
|
|
4174
|
+
head.focus();
|
|
4175
|
+
}
|
|
4176
|
+
};
|
|
4177
|
+
document.addEventListener("keydown", onKey);
|
|
4178
|
+
return () => {
|
|
4179
|
+
document.removeEventListener("keydown", onKey);
|
|
4180
|
+
document.body.style.overflow = overflow;
|
|
4181
|
+
opener?.focus?.();
|
|
4182
|
+
};
|
|
4183
|
+
}, [open]);
|
|
4184
|
+
if (!open || typeof document === "undefined") return null;
|
|
4185
|
+
return (0, import_react_dom7.createPortal)(
|
|
4186
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
4187
|
+
"div",
|
|
4188
|
+
{
|
|
4189
|
+
className: "fixed inset-0 z-modal flex items-center justify-center bg-scrim px-4 py-6",
|
|
4190
|
+
onMouseDown: (e) => e.target === e.currentTarget && onClose(),
|
|
4191
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
|
|
4192
|
+
"div",
|
|
4193
|
+
{
|
|
4194
|
+
ref: panel,
|
|
4195
|
+
role: "dialog",
|
|
4196
|
+
"aria-modal": "true",
|
|
4197
|
+
"aria-labelledby": titleId,
|
|
4198
|
+
"aria-describedby": description ? descId : void 0,
|
|
4199
|
+
tabIndex: -1,
|
|
4200
|
+
className: cn(
|
|
4201
|
+
"flex max-h-full w-full flex-col rounded-card border border-border-default bg-surface shadow-overlay outline-hidden",
|
|
4202
|
+
WIDTH[size],
|
|
4203
|
+
className
|
|
4204
|
+
),
|
|
4205
|
+
children: [
|
|
4206
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-start gap-3 px-5 pt-5 pb-3", children: [
|
|
4207
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "min-w-0 flex-1", children: [
|
|
4208
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)("h2", { id: titleId, className: "text-base font-semibold text-text-primary", children: title }),
|
|
4209
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { id: descId, className: "mt-0.5 text-sm text-text-secondary", children: description })
|
|
4210
|
+
] }),
|
|
4211
|
+
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
4212
|
+
"button",
|
|
4213
|
+
{
|
|
4214
|
+
type: "button",
|
|
4215
|
+
onClick: onClose,
|
|
4216
|
+
"aria-label": "Close",
|
|
4217
|
+
className: "-mr-1.5 -mt-1 flex size-8 shrink-0 items-center justify-center rounded-control text-text-tertiary hover:bg-subtle hover:text-text-primary focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus",
|
|
4218
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react26.X, { size: 16, "aria-hidden": "true" })
|
|
4219
|
+
}
|
|
4220
|
+
)
|
|
4221
|
+
] }),
|
|
4222
|
+
children && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { "data-modal-body": true, className: "min-h-0 flex-1 overflow-y-auto px-5 pb-5 text-sm text-text-primary", children }),
|
|
4223
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { "data-modal-footer": true, className: "flex items-center justify-end gap-2 border-t border-border-default px-5 py-3", children: footer })
|
|
4224
|
+
]
|
|
4225
|
+
}
|
|
4226
|
+
)
|
|
4227
|
+
}
|
|
4228
|
+
),
|
|
4229
|
+
document.body
|
|
4230
|
+
);
|
|
4231
|
+
}
|
|
4232
|
+
|
|
4233
|
+
// src/EmptyState.tsx
|
|
4234
|
+
var import_jsx_runtime45 = require("react/jsx-runtime");
|
|
4235
|
+
function EmptyState({ icon, title, description, action, size = "sm", className }) {
|
|
4236
|
+
const md = size === "md";
|
|
4237
|
+
return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
|
|
4238
|
+
"div",
|
|
4239
|
+
{
|
|
4240
|
+
className: cn(
|
|
4241
|
+
"flex flex-col items-center text-center",
|
|
4242
|
+
md ? "gap-2 px-6 py-16" : "gap-1.5 px-4 py-8",
|
|
4243
|
+
className
|
|
4244
|
+
),
|
|
4245
|
+
children: [
|
|
4246
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
|
|
4247
|
+
"span",
|
|
4248
|
+
{
|
|
4249
|
+
"aria-hidden": "true",
|
|
4250
|
+
className: cn(
|
|
4251
|
+
"flex items-center justify-center text-text-tertiary",
|
|
4252
|
+
md && "mb-1 size-11 rounded-full bg-subtle"
|
|
4253
|
+
),
|
|
4254
|
+
children: icon
|
|
4255
|
+
}
|
|
4256
|
+
),
|
|
4257
|
+
/* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: cn("font-semibold text-text-primary", md ? "text-base" : "text-sm"), children: title }),
|
|
4258
|
+
description && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("p", { className: cn("max-w-sm text-text-secondary", md ? "text-sm" : "text-xs"), children: description }),
|
|
4259
|
+
action && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: md ? "mt-3" : "mt-2", children: action })
|
|
4260
|
+
]
|
|
4261
|
+
}
|
|
4262
|
+
);
|
|
4263
|
+
}
|
|
4264
|
+
|
|
4265
|
+
// src/Tabs.tsx
|
|
4266
|
+
var import_react20 = require("react");
|
|
4267
|
+
var import_jsx_runtime46 = require("react/jsx-runtime");
|
|
4268
|
+
function arrowKeys(e, row) {
|
|
4269
|
+
if (!row || !["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return;
|
|
4270
|
+
const items = Array.from(row.querySelectorAll("button:not([disabled])"));
|
|
4271
|
+
const at = items.indexOf(document.activeElement);
|
|
4272
|
+
const next = e.key === "Home" ? 0 : e.key === "End" ? items.length - 1 : (at + (e.key === "ArrowRight" ? 1 : -1) + items.length) % items.length;
|
|
4273
|
+
e.preventDefault();
|
|
4274
|
+
items[next]?.focus();
|
|
4275
|
+
items[next]?.click();
|
|
4276
|
+
}
|
|
4277
|
+
function Tabs({ items, value, onChange, idPrefix = "tabs", className, ...rest }) {
|
|
4278
|
+
const row = (0, import_react20.useRef)(null);
|
|
4279
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4280
|
+
"div",
|
|
4281
|
+
{
|
|
4282
|
+
ref: row,
|
|
4283
|
+
role: "tablist",
|
|
4284
|
+
"aria-label": rest["aria-label"],
|
|
4285
|
+
onKeyDown: (e) => arrowKeys(e, row.current),
|
|
4286
|
+
className: cn("flex gap-6 border-b border-border-default", className),
|
|
4287
|
+
children: items.map((item) => {
|
|
4288
|
+
const on = item.value === value;
|
|
4289
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
|
|
4290
|
+
"button",
|
|
4291
|
+
{
|
|
4292
|
+
type: "button",
|
|
4293
|
+
role: "tab",
|
|
4294
|
+
id: `${idPrefix}-tab-${item.value}`,
|
|
4295
|
+
"aria-controls": `${idPrefix}-panel-${item.value}`,
|
|
4296
|
+
"aria-selected": on,
|
|
4297
|
+
tabIndex: on ? 0 : -1,
|
|
4298
|
+
disabled: item.disabled,
|
|
4299
|
+
onClick: () => onChange(item.value),
|
|
4300
|
+
className: cn(
|
|
4301
|
+
"-mb-px flex items-center gap-1.5 rounded-control border-b-2 pt-1 pb-2.5 text-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-border-focus disabled:opacity-50",
|
|
4302
|
+
on ? "border-brand-primaryAction font-semibold text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"
|
|
4303
|
+
),
|
|
4304
|
+
children: [
|
|
4305
|
+
item.label,
|
|
4306
|
+
item.count !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-xs text-text-tertiary", children: item.count })
|
|
4307
|
+
]
|
|
4308
|
+
},
|
|
4309
|
+
item.value
|
|
4310
|
+
);
|
|
4311
|
+
})
|
|
4312
|
+
}
|
|
4313
|
+
);
|
|
4314
|
+
}
|
|
4315
|
+
function SegmentedControl({
|
|
4316
|
+
options,
|
|
4317
|
+
value,
|
|
4318
|
+
onChange,
|
|
4319
|
+
size = "sm",
|
|
4320
|
+
className,
|
|
4321
|
+
...rest
|
|
4322
|
+
}) {
|
|
4323
|
+
const row = (0, import_react20.useRef)(null);
|
|
4324
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4325
|
+
"div",
|
|
4326
|
+
{
|
|
4327
|
+
ref: row,
|
|
4328
|
+
role: "radiogroup",
|
|
4329
|
+
"aria-label": rest["aria-label"],
|
|
4330
|
+
onKeyDown: (e) => arrowKeys(e, row.current),
|
|
4331
|
+
className: cn("inline-flex w-fit items-stretch gap-0.5 rounded-full bg-subtle p-1", size === "md" ? "h-10" : "h-8", className),
|
|
4332
|
+
children: options.map((o) => {
|
|
4333
|
+
const on = o.value === value;
|
|
4334
|
+
return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
|
|
4335
|
+
"button",
|
|
4336
|
+
{
|
|
4337
|
+
type: "button",
|
|
4338
|
+
role: "radio",
|
|
4339
|
+
"aria-checked": on,
|
|
4340
|
+
tabIndex: on ? 0 : -1,
|
|
4341
|
+
onClick: () => onChange(o.value),
|
|
4342
|
+
className: cn(
|
|
4343
|
+
"rounded-full px-3 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus",
|
|
4344
|
+
size === "md" ? "text-sm" : "text-xs",
|
|
4345
|
+
on ? "bg-surface font-semibold text-text-primary shadow-raised" : "text-text-secondary hover:text-text-primary"
|
|
4346
|
+
),
|
|
4347
|
+
children: o.label
|
|
4348
|
+
},
|
|
4349
|
+
o.value
|
|
4350
|
+
);
|
|
4351
|
+
})
|
|
4352
|
+
}
|
|
4353
|
+
);
|
|
4354
|
+
}
|
|
4355
|
+
|
|
4356
|
+
// src/TextField.tsx
|
|
4357
|
+
var import_react21 = require("react");
|
|
4358
|
+
var import_jsx_runtime47 = require("react/jsx-runtime");
|
|
4359
|
+
var HEIGHT2 = { sm: "h-8", md: "h-10", lg: "h-11" };
|
|
4360
|
+
var TextField = (0, import_react21.forwardRef)(
|
|
4361
|
+
({ label, hint, error, size = "md", icon, className, id, disabled, ...props }, ref) => {
|
|
4362
|
+
const auto = (0, import_react21.useId)();
|
|
4363
|
+
const fieldId = id ?? auto;
|
|
4364
|
+
const noteId = `${fieldId}-note`;
|
|
4365
|
+
const note = error ?? hint;
|
|
4366
|
+
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
4367
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("label", { htmlFor: fieldId, className: "text-xs font-medium text-text-secondary", children: label }),
|
|
4368
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
4369
|
+
"div",
|
|
4370
|
+
{
|
|
4371
|
+
className: cn(
|
|
4372
|
+
"flex items-center gap-2 rounded-control border bg-input px-3 focus-within:outline-2 focus-within:outline-offset-1 focus-within:outline-border-focus",
|
|
4373
|
+
HEIGHT2[size],
|
|
4374
|
+
error ? "border-status-danger" : "border-border-strong",
|
|
4375
|
+
disabled && "opacity-50"
|
|
4376
|
+
),
|
|
4377
|
+
children: [
|
|
4378
|
+
icon && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { "aria-hidden": "true", className: "flex shrink-0 text-text-tertiary", children: icon }),
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
|
|
4380
|
+
"input",
|
|
4381
|
+
{
|
|
4382
|
+
ref,
|
|
4383
|
+
id: fieldId,
|
|
4384
|
+
disabled,
|
|
4385
|
+
"aria-invalid": error ? true : void 0,
|
|
4386
|
+
"aria-describedby": note ? noteId : void 0,
|
|
4387
|
+
className: "min-w-0 flex-1 bg-transparent text-dense text-text-primary outline-hidden placeholder:text-text-tertiary",
|
|
4388
|
+
...props
|
|
4389
|
+
}
|
|
4390
|
+
)
|
|
4391
|
+
]
|
|
4392
|
+
}
|
|
4393
|
+
),
|
|
4394
|
+
note && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { id: noteId, className: cn("text-xs", error ? "text-text-danger" : "text-text-tertiary"), children: note })
|
|
4395
|
+
] });
|
|
4396
|
+
}
|
|
4397
|
+
);
|
|
4398
|
+
TextField.displayName = "TextField";
|
|
4019
4399
|
// Annotate the CommonJS export names for ESM import in node:
|
|
4020
4400
|
0 && (module.exports = {
|
|
4021
4401
|
AISpark,
|
|
@@ -4034,11 +4414,13 @@ function PageHeader({ title, description, actions, className }) {
|
|
|
4034
4414
|
DateRangeFilter,
|
|
4035
4415
|
DateRangePicker,
|
|
4036
4416
|
Delta,
|
|
4417
|
+
EmptyState,
|
|
4037
4418
|
FilterChipBar,
|
|
4038
4419
|
FilterDropdownFooter,
|
|
4039
4420
|
Freshness,
|
|
4040
4421
|
InfoTip,
|
|
4041
4422
|
LineChartPlaceholder,
|
|
4423
|
+
Modal,
|
|
4042
4424
|
MultiSelectFilter,
|
|
4043
4425
|
NO_RESULTS_BODY,
|
|
4044
4426
|
NO_RESULTS_TITLE,
|
|
@@ -4053,6 +4435,7 @@ function PageHeader({ title, description, actions, className }) {
|
|
|
4053
4435
|
SearchBar,
|
|
4054
4436
|
SectionHeading,
|
|
4055
4437
|
SectionRail,
|
|
4438
|
+
SegmentedControl,
|
|
4056
4439
|
SelectAllVisible,
|
|
4057
4440
|
SelectFilter,
|
|
4058
4441
|
SelectedSection,
|
|
@@ -4060,7 +4443,10 @@ function PageHeader({ title, description, actions, className }) {
|
|
|
4060
4443
|
SortButton,
|
|
4061
4444
|
StackedColumnPlaceholder,
|
|
4062
4445
|
TablePagination,
|
|
4446
|
+
Tabs,
|
|
4063
4447
|
Tag,
|
|
4448
|
+
TextField,
|
|
4449
|
+
Toast,
|
|
4064
4450
|
Toggle,
|
|
4065
4451
|
Tooltip,
|
|
4066
4452
|
WorkspaceAvatar,
|