@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.js CHANGED
@@ -233,7 +233,7 @@ function AdvertiserQuickFilter({
233
233
  "aria-label": caption,
234
234
  "data-testid": testIdPrefix && `${testIdPrefix}-popover`,
235
235
  children: [
236
- /* @__PURE__ */ jsx3("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ jsxs3("div", { className: "flex h-9 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5 focus-within:border-border-focus focus-within:ring-2 focus-within:ring-border-focus/30", children: [
236
+ /* @__PURE__ */ jsx3("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ jsxs3("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: [
237
237
  /* @__PURE__ */ jsx3(Search2, { size: 14, className: "shrink-0 text-text-secondary", "aria-hidden": "true" }),
238
238
  /* @__PURE__ */ jsx3(
239
239
  "input",
@@ -910,8 +910,9 @@ function NavBtn({ children, onClick, ...rest }) {
910
910
 
911
911
  // src/SearchBar.tsx
912
912
  import { useEffect as useEffect4, useId as useId2, useRef as useRef4, useState as useState4 } from "react";
913
- import { AlertCircle, Check as Check3, ChevronDown as ChevronDown3, Search as Search3 } from "lucide-react";
913
+ import { AlertCircle, Check as Check3, ChevronDown as ChevronDown3, Search as Search3, X as X2 } from "lucide-react";
914
914
  import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
915
+ var HEIGHT = { sm: "h-8", md: "h-10", lg: "h-11" };
915
916
  var DEFAULT_SEARCH_MATCH = { mode: "anyWord", wordJoin: "Or" };
916
917
  var MODE_LABEL = {
917
918
  anyWord: "Any Word",
@@ -927,6 +928,7 @@ function SearchBar({
927
928
  value,
928
929
  onChange,
929
930
  variant = "default",
931
+ size = "lg",
930
932
  matchValue,
931
933
  onMatchChange,
932
934
  className,
@@ -934,6 +936,7 @@ function SearchBar({
934
936
  }) {
935
937
  const [open, setOpen] = useState4(false);
936
938
  const ref = useRef4(null);
939
+ const input = useRef4(null);
937
940
  useEffect4(() => {
938
941
  if (!open) return;
939
942
  const onKey = (e) => e.key === "Escape" && setOpen(false);
@@ -952,7 +955,8 @@ function SearchBar({
952
955
  "div",
953
956
  {
954
957
  className: cx2(
955
- "flex h-11 min-w-[200px] flex-1 items-stretch rounded-control border border-border-strong bg-input",
958
+ "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",
959
+ HEIGHT[size],
956
960
  className
957
961
  ),
958
962
  children: [
@@ -961,16 +965,31 @@ function SearchBar({
961
965
  /* @__PURE__ */ jsx8(
962
966
  "input",
963
967
  {
968
+ ref: input,
964
969
  type: "text",
965
970
  value,
966
971
  onChange: (e) => onChange?.(e.target.value),
967
972
  placeholder,
968
973
  "aria-label": placeholder,
969
974
  "data-testid": testIdPrefix && `${testIdPrefix}-search`,
970
- className: "min-w-0 flex-1 bg-transparent text-[13px] text-text-primary outline-hidden placeholder:text-text-tertiary"
975
+ className: "min-w-0 flex-1 bg-transparent text-dense text-text-primary outline-hidden placeholder:text-text-tertiary"
971
976
  }
972
977
  )
973
978
  ] }),
979
+ value && onChange && /* @__PURE__ */ jsx8(
980
+ "button",
981
+ {
982
+ type: "button",
983
+ onClick: () => {
984
+ onChange("");
985
+ input.current?.focus();
986
+ },
987
+ "aria-label": "Clear search",
988
+ "data-testid": testIdPrefix && `${testIdPrefix}-clear`,
989
+ 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",
990
+ children: /* @__PURE__ */ jsx8(X2, { size: 14, "aria-hidden": "true" })
991
+ }
992
+ ),
974
993
  showMatch && // border-border-default, not the bare `border-border` both source
975
994
  // implementations used -- confirmed by actually compiling against
976
995
  // @mediaradar/design-tokens' real published theme.css (not assumed):
@@ -1609,7 +1628,7 @@ function NoResultsEmptyState({
1609
1628
 
1610
1629
  // src/WorkspaceSelectedCard.tsx
1611
1630
  import { useEffect as useEffect7, useRef as useRef8, useState as useState7 } from "react";
1612
- import { ChevronDown as ChevronDown6, X as X2 } from "lucide-react";
1631
+ import { ChevronDown as ChevronDown6, X as X3 } from "lucide-react";
1613
1632
  import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1614
1633
  function cx5(...parts) {
1615
1634
  return parts.filter(Boolean).join(" ");
@@ -1673,7 +1692,7 @@ function SummaryGroupItem({
1673
1692
  "aria-label": `Remove ${item.name}`,
1674
1693
  onClick: () => group.onRemove(item.id),
1675
1694
  className: "flex h-5 w-5 shrink-0 items-center justify-center rounded-control text-text-secondary hover:bg-subtle hover:text-text-danger",
1676
- children: /* @__PURE__ */ jsx14(X2, { size: 12, "aria-hidden": "true" })
1695
+ children: /* @__PURE__ */ jsx14(X3, { size: 12, "aria-hidden": "true" })
1677
1696
  }
1678
1697
  )
1679
1698
  ]
@@ -2322,7 +2341,7 @@ function SelectionPicker({
2322
2341
  }) }),
2323
2342
  source === "search" && /* @__PURE__ */ jsxs22("div", { className: "flex min-w-0 flex-col gap-3", children: [
2324
2343
  /* @__PURE__ */ jsxs22("div", { className: "flex flex-wrap items-center gap-2", children: [
2325
- /* @__PURE__ */ jsxs22("div", { className: "flex h-9 min-w-[200px] flex-1 items-center gap-2 rounded-control border border-border-strong bg-input px-3", children: [
2344
+ /* @__PURE__ */ jsxs22("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: [
2326
2345
  /* @__PURE__ */ jsx24(Search4, { size: 15, className: "text-text-secondary", "aria-hidden": "true" }),
2327
2346
  /* @__PURE__ */ jsx24(
2328
2347
  "input",
@@ -2636,7 +2655,7 @@ function FilterDropdown({
2636
2655
  onClick: () => setOpen((v) => !v),
2637
2656
  "aria-expanded": open,
2638
2657
  "data-testid": testIdPrefix && `${testIdPrefix}-filter-${filterSlug}`,
2639
- className: "inline-flex h-9 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",
2658
+ 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",
2640
2659
  children: [
2641
2660
  label,
2642
2661
  /* @__PURE__ */ jsx24(ChevronDown8, { size: 13, "aria-hidden": "true", className: cx8("transition-transform", open && "rotate-180") })
@@ -2842,7 +2861,10 @@ var buttonVariants = cva(
2842
2861
  size: {
2843
2862
  xs: "h-6 px-2 text-xs",
2844
2863
  sm: "h-8 px-3 text-sm",
2845
- md: "h-10 px-4 text-sm"
2864
+ md: "h-10 px-4 text-sm",
2865
+ // 44, the filter row's height, so a button at the end of a row of
2866
+ // filter dropdowns lines up with them. One control scale: 32 / 40 / 44.
2867
+ lg: "h-11 px-5 text-sm"
2846
2868
  },
2847
2869
  // Shape is orthogonal to size. As a fourth SIZE, `icon` could only ever
2848
2870
  // be one dimension, so an icon button never lined up with the labelled
@@ -2857,6 +2879,7 @@ var buttonVariants = cva(
2857
2879
  { size: "xs", iconOnly: true, class: "w-6" },
2858
2880
  { size: "sm", iconOnly: true, class: "w-8" },
2859
2881
  { size: "md", iconOnly: true, class: "w-10" },
2882
+ { size: "lg", iconOnly: true, class: "w-11" },
2860
2883
  // A boxed button is a target you aim at, so its label carries the weight
2861
2884
  // of one. `link` sits inline in a sentence, where semibold reads as
2862
2885
  // emphasis on the words rather than as a control.
@@ -2970,7 +2993,7 @@ function NameListModal({
2970
2993
  /* @__PURE__ */ jsx28(
2971
2994
  "div",
2972
2995
  {
2973
- className: "fixed inset-0 z-70 flex items-center justify-center bg-scrim px-4",
2996
+ className: "fixed inset-0 z-modal flex items-center justify-center bg-scrim px-4",
2974
2997
  onMouseDown: (e) => e.target === e.currentTarget && onCancel(),
2975
2998
  children: /* @__PURE__ */ jsxs26(
2976
2999
  "div",
@@ -2980,7 +3003,7 @@ function NameListModal({
2980
3003
  "aria-modal": "true",
2981
3004
  "aria-labelledby": titleId,
2982
3005
  onKeyDown: trapTab,
2983
- className: "w-full max-w-[420px] rounded-card border border-border-default bg-surface p-5 shadow-overlay",
3006
+ className: "w-full max-w-110 rounded-card border border-border-default bg-surface p-5 shadow-overlay",
2984
3007
  children: [
2985
3008
  /* @__PURE__ */ jsx28("h2", { id: titleId, className: "text-[16px] font-semibold text-text-primary", children: title }),
2986
3009
  /* @__PURE__ */ jsxs26("div", { className: "mt-4 flex flex-col gap-1.5", children: [
@@ -2993,7 +3016,7 @@ function NameListModal({
2993
3016
  value: name,
2994
3017
  onChange: (e) => setName(e.target.value),
2995
3018
  placeholder,
2996
- className: "h-10 rounded-control border border-border-strong bg-input px-3 text-sm outline-hidden focus:border-brand-primaryAction"
3019
+ 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"
2997
3020
  }
2998
3021
  )
2999
3022
  ] }),
@@ -3039,7 +3062,7 @@ function ChipContent({ caption, value, icon }) {
3039
3062
  }
3040
3063
 
3041
3064
  // src/FilterChipBar.tsx
3042
- import { CircleSlash, X as X3 } from "lucide-react";
3065
+ import { CircleSlash, X as X4 } from "lucide-react";
3043
3066
  import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
3044
3067
  function FilterChipBar({ chips, onRemove, onClearAll, parkedKeys }) {
3045
3068
  if (chips.length === 0) return null;
@@ -3085,7 +3108,7 @@ function Chip({
3085
3108
  onClick: onRemove,
3086
3109
  "aria-label": `Remove ${groupLabel}: ${label}`,
3087
3110
  className: "text-text-tertiary transition-colors hover:text-text-primary",
3088
- children: /* @__PURE__ */ jsx30(X3, { size: 12 })
3111
+ children: /* @__PURE__ */ jsx30(X4, { size: 12 })
3089
3112
  }
3090
3113
  )
3091
3114
  ]
@@ -3270,10 +3293,83 @@ function WorkspaceAvatar({ name, size = "md" }) {
3270
3293
  );
3271
3294
  }
3272
3295
 
3296
+ // src/Toast.tsx
3297
+ import { useEffect as useEffect11, useRef as useRef12, useState as useState12 } from "react";
3298
+ import { createPortal as createPortal6 } from "react-dom";
3299
+ import { AlertTriangle, Check as Check7 } from "lucide-react";
3300
+ import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
3301
+ var ICON = {
3302
+ neutral: null,
3303
+ success: /* @__PURE__ */ jsx34(Check7, { size: 15, className: "shrink-0", "aria-hidden": "true" }),
3304
+ warning: /* @__PURE__ */ jsx34(AlertTriangle, { size: 15, className: "shrink-0", "aria-hidden": "true" })
3305
+ };
3306
+ function Toast({ message, action, onClose, tone = "neutral", duration, className }) {
3307
+ const ms = duration ?? (action ? 1e4 : 5e3);
3308
+ const [paused, setPaused] = useState12(false);
3309
+ const closed = useRef12(false);
3310
+ useEffect11(() => {
3311
+ if (paused) return;
3312
+ const t = window.setTimeout(() => {
3313
+ if (closed.current) return;
3314
+ closed.current = true;
3315
+ onClose();
3316
+ }, ms);
3317
+ return () => window.clearTimeout(t);
3318
+ }, [message, ms, paused]);
3319
+ return createPortal6(
3320
+ /* @__PURE__ */ jsxs31(
3321
+ "div",
3322
+ {
3323
+ role: "status",
3324
+ "aria-live": "polite",
3325
+ onMouseEnter: () => setPaused(true),
3326
+ onMouseLeave: () => setPaused(false),
3327
+ onFocusCapture: () => setPaused(true),
3328
+ onBlurCapture: () => setPaused(false),
3329
+ className: cn(
3330
+ "fixed bottom-6 left-1/2 z-toast flex max-w-[92vw] -translate-x-1/2 items-center gap-2.5",
3331
+ "rounded-control bg-inverseSurface py-2.5 pl-4 pr-2.5 text-sm font-medium text-text-inverse shadow-overlay",
3332
+ className
3333
+ ),
3334
+ children: [
3335
+ ICON[tone] && // The inverse pair, not text-success / text-warning: those are tuned
3336
+ // for the page, and on the toast's flipped surface amber drops to 2:1.
3337
+ /* @__PURE__ */ jsx34(
3338
+ "span",
3339
+ {
3340
+ className: cn(
3341
+ "flex",
3342
+ tone === "success" ? "text-text-inverseSuccess" : "text-text-inverseWarning"
3343
+ ),
3344
+ children: ICON[tone]
3345
+ }
3346
+ ),
3347
+ /* @__PURE__ */ jsx34("span", { className: "min-w-0", children: message }),
3348
+ action && /* @__PURE__ */ jsx34(
3349
+ "button",
3350
+ {
3351
+ type: "button",
3352
+ onClick: () => {
3353
+ if (!closed.current) {
3354
+ closed.current = true;
3355
+ action.onClick();
3356
+ }
3357
+ },
3358
+ 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",
3359
+ children: action.label
3360
+ }
3361
+ )
3362
+ ]
3363
+ }
3364
+ ),
3365
+ document.body
3366
+ );
3367
+ }
3368
+
3273
3369
  // src/Tag.tsx
3274
- import { jsx as jsx34 } from "react/jsx-runtime";
3370
+ import { jsx as jsx35 } from "react/jsx-runtime";
3275
3371
  function Tag({ children, className }) {
3276
- return /* @__PURE__ */ jsx34(
3372
+ return /* @__PURE__ */ jsx35(
3277
3373
  "span",
3278
3374
  {
3279
3375
  className: cn(
@@ -3293,7 +3389,7 @@ function Tag({ children, className }) {
3293
3389
 
3294
3390
  // src/TablePagination.tsx
3295
3391
  import { ChevronDown as ChevronDown9, ChevronFirst, ChevronLast, ChevronLeft as ChevronLeft4, ChevronRight as ChevronRight5 } from "lucide-react";
3296
- import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
3392
+ import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
3297
3393
  function TablePagination({
3298
3394
  page,
3299
3395
  perPage,
@@ -3314,10 +3410,10 @@ function TablePagination({
3314
3410
  btn,
3315
3411
  "text-text-secondary hover:bg-subtle hover:text-text-primary disabled:pointer-events-none disabled:opacity-30"
3316
3412
  );
3317
- return /* @__PURE__ */ jsxs31("div", { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-2", className), "data-testid": testIdPrefix, children: [
3318
- /* @__PURE__ */ jsxs31("label", { className: "flex items-center gap-2 text-[13px] text-text-secondary", children: [
3319
- /* @__PURE__ */ jsxs31("span", { className: "relative", children: [
3320
- /* @__PURE__ */ jsx35(
3413
+ return /* @__PURE__ */ jsxs32("div", { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-2", className), "data-testid": testIdPrefix, children: [
3414
+ /* @__PURE__ */ jsxs32("label", { className: "flex items-center gap-2 text-[13px] text-text-secondary", children: [
3415
+ /* @__PURE__ */ jsxs32("span", { className: "relative", children: [
3416
+ /* @__PURE__ */ jsx36(
3321
3417
  "select",
3322
3418
  {
3323
3419
  value: perPage,
@@ -3325,10 +3421,10 @@ function TablePagination({
3325
3421
  "aria-label": "Items per page",
3326
3422
  "data-testid": testIdPrefix && `${testIdPrefix}-per-page`,
3327
3423
  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",
3328
- children: perPageOptions.map((n) => /* @__PURE__ */ jsx35("option", { value: n, children: n }, n))
3424
+ children: perPageOptions.map((n) => /* @__PURE__ */ jsx36("option", { value: n, children: n }, n))
3329
3425
  }
3330
3426
  ),
3331
- /* @__PURE__ */ jsx35(
3427
+ /* @__PURE__ */ jsx36(
3332
3428
  ChevronDown9,
3333
3429
  {
3334
3430
  size: 13,
@@ -3339,8 +3435,8 @@ function TablePagination({
3339
3435
  ] }),
3340
3436
  "items per page"
3341
3437
  ] }),
3342
- /* @__PURE__ */ jsxs31("nav", { className: "flex items-center gap-1", "aria-label": "Pagination", children: [
3343
- /* @__PURE__ */ jsx35(
3438
+ /* @__PURE__ */ jsxs32("nav", { className: "flex items-center gap-1", "aria-label": "Pagination", children: [
3439
+ /* @__PURE__ */ jsx36(
3344
3440
  "button",
3345
3441
  {
3346
3442
  type: "button",
@@ -3349,10 +3445,10 @@ function TablePagination({
3349
3445
  "aria-label": "First page",
3350
3446
  "data-testid": testIdPrefix && `${testIdPrefix}-first`,
3351
3447
  className: stepBtn,
3352
- children: /* @__PURE__ */ jsx35(ChevronFirst, { size: 16, "aria-hidden": "true" })
3448
+ children: /* @__PURE__ */ jsx36(ChevronFirst, { size: 16, "aria-hidden": "true" })
3353
3449
  }
3354
3450
  ),
3355
- /* @__PURE__ */ jsx35(
3451
+ /* @__PURE__ */ jsx36(
3356
3452
  "button",
3357
3453
  {
3358
3454
  type: "button",
@@ -3361,11 +3457,11 @@ function TablePagination({
3361
3457
  "aria-label": "Previous page",
3362
3458
  "data-testid": testIdPrefix && `${testIdPrefix}-prev`,
3363
3459
  className: stepBtn,
3364
- children: /* @__PURE__ */ jsx35(ChevronLeft4, { size: 16, "aria-hidden": "true" })
3460
+ children: /* @__PURE__ */ jsx36(ChevronLeft4, { size: 16, "aria-hidden": "true" })
3365
3461
  }
3366
3462
  ),
3367
3463
  pageWindow(current, totalPages).map(
3368
- (p) => typeof p === "string" ? /* @__PURE__ */ jsx35("span", { className: "px-1 text-[13px] text-text-tertiary", children: "\u2026" }, p) : /* @__PURE__ */ jsx35(
3464
+ (p) => typeof p === "string" ? /* @__PURE__ */ jsx36("span", { className: "px-1 text-[13px] text-text-tertiary", children: "\u2026" }, p) : /* @__PURE__ */ jsx36(
3369
3465
  "button",
3370
3466
  {
3371
3467
  type: "button",
@@ -3381,7 +3477,7 @@ function TablePagination({
3381
3477
  p
3382
3478
  )
3383
3479
  ),
3384
- /* @__PURE__ */ jsx35(
3480
+ /* @__PURE__ */ jsx36(
3385
3481
  "button",
3386
3482
  {
3387
3483
  type: "button",
@@ -3390,10 +3486,10 @@ function TablePagination({
3390
3486
  "aria-label": "Next page",
3391
3487
  "data-testid": testIdPrefix && `${testIdPrefix}-next`,
3392
3488
  className: stepBtn,
3393
- children: /* @__PURE__ */ jsx35(ChevronRight5, { size: 16, "aria-hidden": "true" })
3489
+ children: /* @__PURE__ */ jsx36(ChevronRight5, { size: 16, "aria-hidden": "true" })
3394
3490
  }
3395
3491
  ),
3396
- /* @__PURE__ */ jsx35(
3492
+ /* @__PURE__ */ jsx36(
3397
3493
  "button",
3398
3494
  {
3399
3495
  type: "button",
@@ -3402,11 +3498,11 @@ function TablePagination({
3402
3498
  "aria-label": "Last page",
3403
3499
  "data-testid": testIdPrefix && `${testIdPrefix}-last`,
3404
3500
  className: stepBtn,
3405
- children: /* @__PURE__ */ jsx35(ChevronLast, { size: 16, "aria-hidden": "true" })
3501
+ children: /* @__PURE__ */ jsx36(ChevronLast, { size: 16, "aria-hidden": "true" })
3406
3502
  }
3407
3503
  )
3408
3504
  ] }),
3409
- /* @__PURE__ */ jsxs31("span", { className: "text-[13px] text-text-tertiary tabular-nums", children: [
3505
+ /* @__PURE__ */ jsxs32("span", { className: "text-[13px] text-text-tertiary tabular-nums", children: [
3410
3506
  rangeStart.toLocaleString(),
3411
3507
  " \u2013 ",
3412
3508
  rangeEnd.toLocaleString(),
@@ -3419,9 +3515,9 @@ function TablePagination({
3419
3515
  }
3420
3516
 
3421
3517
  // src/DateRangePicker.tsx
3422
- import { useEffect as useEffect11, useMemo as useMemo4, useRef as useRef12, useState as useState12 } from "react";
3518
+ import { useEffect as useEffect12, useMemo as useMemo4, useRef as useRef13, useState as useState13 } from "react";
3423
3519
  import { ChevronDown as ChevronDown10 } from "lucide-react";
3424
- import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
3520
+ import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
3425
3521
  var MONTH_ABBR = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
3426
3522
  var QUARTER_ABBR = ["Q1", "Q2", "Q3", "Q4"];
3427
3523
  var PRESETS = ["Rolling 3 months", "Rolling 6 months", "Rolling 12 months"];
@@ -3457,7 +3553,7 @@ function spanLabel(label, today) {
3457
3553
  return `${fmtDate(s)} \u2013 ${fmtDate(e)}`;
3458
3554
  }
3459
3555
  function MiniSelect({ value, onChange, options }) {
3460
- return /* @__PURE__ */ jsx36(
3556
+ return /* @__PURE__ */ jsx37(
3461
3557
  "select",
3462
3558
  {
3463
3559
  value: String(value),
@@ -3465,8 +3561,8 @@ function MiniSelect({ value, onChange, options }) {
3465
3561
  const opt = options.find((o) => String(o.value) === e.target.value);
3466
3562
  if (opt) onChange(opt.value);
3467
3563
  },
3468
- className: "rounded-control border border-border-strong bg-input px-1.5 py-1 text-[12px] text-text-primary outline-hidden focus:border-border-focus",
3469
- children: options.map((o) => /* @__PURE__ */ jsx36("option", { value: String(o.value), children: o.label }, String(o.value)))
3564
+ 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",
3565
+ children: options.map((o) => /* @__PURE__ */ jsx37("option", { value: String(o.value), children: o.label }, String(o.value)))
3470
3566
  }
3471
3567
  );
3472
3568
  }
@@ -3483,17 +3579,17 @@ function DateRangePicker({
3483
3579
  }) {
3484
3580
  const end = useMemo4(() => today ?? startOfToday(), [today]);
3485
3581
  const yearOptions = years ?? [3, 2, 1, 0].map((n) => end.getFullYear() - n);
3486
- const [open, setOpen] = useState12(false);
3487
- const [value, setValue] = useState12(defaultValue);
3488
- const [draft, setDraft] = useState12(defaultValue);
3489
- const ref = useRef12(null);
3490
- const [fromMo, setFromMo] = useState12(end.getMonth());
3491
- const [fromYr, setFromYr] = useState12(end.getFullYear() - 1);
3492
- const [toMo, setToMo] = useState12(end.getMonth());
3493
- const [toYr, setToYr] = useState12(end.getFullYear());
3494
- const [fromQ, setFromQ] = useState12(Math.floor(end.getMonth() / 3));
3495
- const [toQ, setToQ] = useState12(Math.floor(end.getMonth() / 3));
3496
- useEffect11(() => {
3582
+ const [open, setOpen] = useState13(false);
3583
+ const [value, setValue] = useState13(defaultValue);
3584
+ const [draft, setDraft] = useState13(defaultValue);
3585
+ const ref = useRef13(null);
3586
+ const [fromMo, setFromMo] = useState13(end.getMonth());
3587
+ const [fromYr, setFromYr] = useState13(end.getFullYear() - 1);
3588
+ const [toMo, setToMo] = useState13(end.getMonth());
3589
+ const [toYr, setToYr] = useState13(end.getFullYear());
3590
+ const [fromQ, setFromQ] = useState13(Math.floor(end.getMonth() / 3));
3591
+ const [toQ, setToQ] = useState13(Math.floor(end.getMonth() / 3));
3592
+ useEffect12(() => {
3497
3593
  const [s, e] = resolveRange(value, end);
3498
3594
  onRangeChange?.(s, e);
3499
3595
  }, [value]);
@@ -3501,7 +3597,7 @@ function DateRangePicker({
3501
3597
  if (!open) setDraft(value);
3502
3598
  setOpen((o) => !o);
3503
3599
  };
3504
- useEffect11(() => {
3600
+ useEffect12(() => {
3505
3601
  if (!open) return;
3506
3602
  const onDown = (e) => {
3507
3603
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -3527,8 +3623,8 @@ function DateRangePicker({
3527
3623
  if (showFooter) setDraft(label);
3528
3624
  else commit(label);
3529
3625
  };
3530
- return /* @__PURE__ */ jsxs32("div", { className: "relative", ref, children: [
3531
- /* @__PURE__ */ jsxs32(
3626
+ return /* @__PURE__ */ jsxs33("div", { className: "relative", ref, children: [
3627
+ /* @__PURE__ */ jsxs33(
3532
3628
  "button",
3533
3629
  {
3534
3630
  type: "button",
@@ -3537,16 +3633,16 @@ function DateRangePicker({
3537
3633
  "aria-haspopup": "listbox",
3538
3634
  className: chipTriggerClass(),
3539
3635
  children: [
3540
- /* @__PURE__ */ jsxs32("span", { className: "flex flex-col gap-1 text-left leading-none", children: [
3541
- /* @__PURE__ */ jsx36("span", { className: "text-control-caption text-text-tertiary", children: spanLabel(value, end) }),
3542
- /* @__PURE__ */ jsx36("span", { className: "text-[12px] font-medium text-text-primary", children: value })
3636
+ /* @__PURE__ */ jsxs33("span", { className: "flex flex-col gap-1 text-left leading-none", children: [
3637
+ /* @__PURE__ */ jsx37("span", { className: "text-control-caption text-text-tertiary", children: spanLabel(value, end) }),
3638
+ /* @__PURE__ */ jsx37("span", { className: "text-[12px] font-medium text-text-primary", children: value })
3543
3639
  ] }),
3544
- /* @__PURE__ */ jsx36(ChevronDown10, { size: 14, "aria-hidden": "true", className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180") })
3640
+ /* @__PURE__ */ jsx37(ChevronDown10, { size: 14, "aria-hidden": "true", className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180") })
3545
3641
  ]
3546
3642
  }
3547
3643
  ),
3548
- open && /* @__PURE__ */ jsxs32("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: [
3549
- presets.map((p) => /* @__PURE__ */ jsx36(
3644
+ open && /* @__PURE__ */ jsxs33("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: [
3645
+ presets.map((p) => /* @__PURE__ */ jsx37(
3550
3646
  "button",
3551
3647
  {
3552
3648
  type: "button",
@@ -3556,26 +3652,26 @@ function DateRangePicker({
3556
3652
  },
3557
3653
  p
3558
3654
  )),
3559
- /* @__PURE__ */ jsxs32("div", { className: "mt-1 border-t border-border-default px-3 pb-2 pt-2", children: [
3560
- /* @__PURE__ */ jsx36("div", { className: "text-[13px] font-semibold text-text-primary", children: "Custom Range" }),
3561
- /* @__PURE__ */ jsxs32("div", { className: "mt-2 flex flex-col gap-2", children: [
3562
- /* @__PURE__ */ jsxs32("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3655
+ /* @__PURE__ */ jsxs33("div", { className: "mt-1 border-t border-border-default px-3 pb-2 pt-2", children: [
3656
+ /* @__PURE__ */ jsx37("div", { className: "text-[13px] font-semibold text-text-primary", children: "Custom Range" }),
3657
+ /* @__PURE__ */ jsxs33("div", { className: "mt-2 flex flex-col gap-2", children: [
3658
+ /* @__PURE__ */ jsxs33("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3563
3659
  "From",
3564
- /* @__PURE__ */ jsxs32("span", { className: "flex gap-1", children: [
3565
- granularity === "month" && /* @__PURE__ */ jsx36(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3566
- granularity === "quarter" && /* @__PURE__ */ jsx36(MiniSelect, { value: fromQ, onChange: setFromQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3567
- /* @__PURE__ */ jsx36(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3660
+ /* @__PURE__ */ jsxs33("span", { className: "flex gap-1", children: [
3661
+ granularity === "month" && /* @__PURE__ */ jsx37(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3662
+ granularity === "quarter" && /* @__PURE__ */ jsx37(MiniSelect, { value: fromQ, onChange: setFromQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3663
+ /* @__PURE__ */ jsx37(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3568
3664
  ] })
3569
3665
  ] }),
3570
- /* @__PURE__ */ jsxs32("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3666
+ /* @__PURE__ */ jsxs33("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3571
3667
  "To",
3572
- /* @__PURE__ */ jsxs32("span", { className: "flex gap-1", children: [
3573
- granularity === "month" && /* @__PURE__ */ jsx36(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3574
- granularity === "quarter" && /* @__PURE__ */ jsx36(MiniSelect, { value: toQ, onChange: setToQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3575
- /* @__PURE__ */ jsx36(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3668
+ /* @__PURE__ */ jsxs33("span", { className: "flex gap-1", children: [
3669
+ granularity === "month" && /* @__PURE__ */ jsx37(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3670
+ granularity === "quarter" && /* @__PURE__ */ jsx37(MiniSelect, { value: toQ, onChange: setToQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3671
+ /* @__PURE__ */ jsx37(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3576
3672
  ] })
3577
3673
  ] }),
3578
- /* @__PURE__ */ jsx36(
3674
+ /* @__PURE__ */ jsx37(
3579
3675
  "button",
3580
3676
  {
3581
3677
  type: "button",
@@ -3587,15 +3683,15 @@ function DateRangePicker({
3587
3683
  )
3588
3684
  ] })
3589
3685
  ] }),
3590
- showFooter && /* @__PURE__ */ jsx36(FilterDropdownFooter, { onApply: () => commit(draft) })
3686
+ showFooter && /* @__PURE__ */ jsx37(FilterDropdownFooter, { onApply: () => commit(draft) })
3591
3687
  ] })
3592
3688
  ] });
3593
3689
  }
3594
3690
 
3595
3691
  // src/MultiSelectFilter.tsx
3596
- import { useCallback as useCallback4, useEffect as useEffect12, useRef as useRef13, useState as useState13 } from "react";
3597
- import { ChevronDown as ChevronDown11, Check as Check7, Minus as Minus2, Search as Search5, X as X4 } from "lucide-react";
3598
- import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
3692
+ import { useCallback as useCallback4, useEffect as useEffect13, useRef as useRef14, useState as useState14 } from "react";
3693
+ import { ChevronDown as ChevronDown11, Check as Check8, Minus as Minus2, Search as Search5, X as X5 } from "lucide-react";
3694
+ import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
3599
3695
  function MultiSelectFilter({
3600
3696
  caption,
3601
3697
  options = [],
@@ -3619,10 +3715,10 @@ function MultiSelectFilter({
3619
3715
  }) {
3620
3716
  const groupLeaves = (g) => g.children.length ? g.children : [{ id: g.id, label: g.label }];
3621
3717
  const leafOptions = groups ? groups.flatMap(groupLeaves) : options;
3622
- const [open, setOpen] = useState13(false);
3623
- const [q, setQ] = useState13("");
3624
- const [draft, setDraft] = useState13(selected);
3625
- const ref = useRef13(null);
3718
+ const [open, setOpen] = useState14(false);
3719
+ const [q, setQ] = useState14("");
3720
+ const [draft, setDraft] = useState14(selected);
3721
+ const ref = useRef14(null);
3626
3722
  const close = useCallback4(() => {
3627
3723
  setOpen(false);
3628
3724
  setQ("");
@@ -3640,7 +3736,7 @@ function MultiSelectFilter({
3640
3736
  setOpen(false);
3641
3737
  setQ("");
3642
3738
  };
3643
- useEffect12(() => {
3739
+ useEffect13(() => {
3644
3740
  if (!open) return;
3645
3741
  const onKey = (e) => e.key === "Escape" && close();
3646
3742
  const onClick = (e) => {
@@ -3686,8 +3782,8 @@ function MultiSelectFilter({
3686
3782
  const kids = live.filter((c) => c.label.toLowerCase().includes(ql));
3687
3783
  return kids.length ? { ...g, children: kids } : null;
3688
3784
  }).filter((g) => g !== null) : [];
3689
- return /* @__PURE__ */ jsxs33("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
3690
- /* @__PURE__ */ jsxs33(
3785
+ return /* @__PURE__ */ jsxs34("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
3786
+ /* @__PURE__ */ jsxs34(
3691
3787
  "button",
3692
3788
  {
3693
3789
  type: "button",
@@ -3695,8 +3791,8 @@ function MultiSelectFilter({
3695
3791
  "aria-expanded": open,
3696
3792
  className: cn(chipTriggerClass(variant), fullWidth && "w-full justify-between"),
3697
3793
  children: [
3698
- /* @__PURE__ */ jsx37(ChipContent, { caption, value, icon }),
3699
- /* @__PURE__ */ jsx37(
3794
+ /* @__PURE__ */ jsx38(ChipContent, { caption, value, icon }),
3795
+ /* @__PURE__ */ jsx38(
3700
3796
  ChevronDown11,
3701
3797
  {
3702
3798
  size: 14,
@@ -3707,7 +3803,7 @@ function MultiSelectFilter({
3707
3803
  ]
3708
3804
  }
3709
3805
  ),
3710
- open && /* @__PURE__ */ jsxs33(
3806
+ open && /* @__PURE__ */ jsxs34(
3711
3807
  "div",
3712
3808
  {
3713
3809
  className: cn(
@@ -3718,9 +3814,9 @@ function MultiSelectFilter({
3718
3814
  role: "dialog",
3719
3815
  "aria-label": caption,
3720
3816
  children: [
3721
- searchable && /* @__PURE__ */ jsx37("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ jsxs33("div", { className: "flex h-9 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5", children: [
3722
- /* @__PURE__ */ jsx37(Search5, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
3723
- /* @__PURE__ */ jsx37(
3817
+ searchable && /* @__PURE__ */ jsx38("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ jsxs34("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: [
3818
+ /* @__PURE__ */ jsx38(Search5, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
3819
+ /* @__PURE__ */ jsx38(
3724
3820
  "input",
3725
3821
  {
3726
3822
  type: "text",
@@ -3730,37 +3826,37 @@ function MultiSelectFilter({
3730
3826
  className: "h-full flex-1 bg-transparent text-[13px] outline-hidden placeholder:text-text-tertiary"
3731
3827
  }
3732
3828
  ),
3733
- q && /* @__PURE__ */ jsx37("button", { type: "button", onClick: () => setQ(""), "aria-label": "Clear search", className: "text-text-tertiary hover:text-text-primary", children: /* @__PURE__ */ jsx37(X4, { size: 13 }) })
3829
+ q && /* @__PURE__ */ jsx38("button", { type: "button", onClick: () => setQ(""), "aria-label": "Clear search", className: "text-text-tertiary hover:text-text-primary", children: /* @__PURE__ */ jsx38(X5, { size: 13 }) })
3734
3830
  ] }) }),
3735
- /* @__PURE__ */ jsxs33("div", { className: "max-h-[280px] overflow-y-auto p-1", children: [
3831
+ /* @__PURE__ */ jsxs34("div", { className: "max-h-[280px] overflow-y-auto p-1", children: [
3736
3832
  groups ? visibleGroups.map((g) => {
3737
3833
  const state = groupState(g);
3738
- return /* @__PURE__ */ jsxs33("div", { children: [
3739
- /* @__PURE__ */ jsxs33(
3834
+ return /* @__PURE__ */ jsxs34("div", { children: [
3835
+ /* @__PURE__ */ jsxs34(
3740
3836
  "button",
3741
3837
  {
3742
3838
  type: "button",
3743
3839
  onClick: () => toggleGroup(g),
3744
3840
  className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
3745
3841
  children: [
3746
- /* @__PURE__ */ jsx37(TriCheck, { state }),
3747
- /* @__PURE__ */ jsx37("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label }),
3748
- counts && /* @__PURE__ */ jsx37(OptionCount, { n: countFor(g.id) })
3842
+ /* @__PURE__ */ jsx38(TriCheck, { state }),
3843
+ /* @__PURE__ */ jsx38("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label }),
3844
+ counts && /* @__PURE__ */ jsx38(OptionCount, { n: countFor(g.id) })
3749
3845
  ]
3750
3846
  }
3751
3847
  ),
3752
3848
  g.children.map((c) => {
3753
3849
  const checked = draft.includes(c.id);
3754
- return /* @__PURE__ */ jsxs33(
3850
+ return /* @__PURE__ */ jsxs34(
3755
3851
  "button",
3756
3852
  {
3757
3853
  type: "button",
3758
3854
  onClick: () => toggle(c.id),
3759
3855
  className: "flex w-full items-center gap-2.5 rounded-control py-2 pl-9 pr-2 text-left transition-colors hover:bg-subtle",
3760
3856
  children: [
3761
- /* @__PURE__ */ jsx37(TriCheck, { state: checked ? "all" : "none" }),
3762
- /* @__PURE__ */ jsx37("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label }),
3763
- counts && /* @__PURE__ */ jsx37(OptionCount, { n: countFor(c.id) })
3857
+ /* @__PURE__ */ jsx38(TriCheck, { state: checked ? "all" : "none" }),
3858
+ /* @__PURE__ */ jsx38("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label }),
3859
+ counts && /* @__PURE__ */ jsx38(OptionCount, { n: countFor(c.id) })
3764
3860
  ]
3765
3861
  },
3766
3862
  c.id
@@ -3769,33 +3865,33 @@ function MultiSelectFilter({
3769
3865
  ] }, g.id);
3770
3866
  }) : items.map((o) => {
3771
3867
  const checked = draft.includes(o.id);
3772
- return /* @__PURE__ */ jsxs33(
3868
+ return /* @__PURE__ */ jsxs34(
3773
3869
  "button",
3774
3870
  {
3775
3871
  type: "button",
3776
3872
  onClick: () => toggle(o.id),
3777
3873
  className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
3778
3874
  children: [
3779
- /* @__PURE__ */ jsx37(
3875
+ /* @__PURE__ */ jsx38(
3780
3876
  "span",
3781
3877
  {
3782
3878
  className: cn(
3783
3879
  "flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
3784
3880
  checked ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
3785
3881
  ),
3786
- children: checked && /* @__PURE__ */ jsx37(Check7, { size: 13, strokeWidth: 3 })
3882
+ children: checked && /* @__PURE__ */ jsx38(Check8, { size: 13, strokeWidth: 3 })
3787
3883
  }
3788
3884
  ),
3789
- /* @__PURE__ */ jsx37("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label }),
3790
- counts && /* @__PURE__ */ jsx37(OptionCount, { n: countFor(o.id) })
3885
+ /* @__PURE__ */ jsx38("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label }),
3886
+ counts && /* @__PURE__ */ jsx38(OptionCount, { n: countFor(o.id) })
3791
3887
  ]
3792
3888
  },
3793
3889
  o.id
3794
3890
  );
3795
3891
  }),
3796
- (groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ jsx37("div", { className: "py-6 text-center text-[13px] text-text-tertiary", children: "No matches." })
3892
+ (groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ jsx38("div", { className: "py-6 text-center text-[13px] text-text-tertiary", children: "No matches." })
3797
3893
  ] }),
3798
- showFooter ? /* @__PURE__ */ jsx37(FilterDropdownFooter, { onClear: () => setDraft(clearValue), onApply: apply }) : min === 0 && draft.length > 0 && /* @__PURE__ */ jsx37("div", { className: "border-t border-border-default p-2", children: /* @__PURE__ */ jsxs33(
3894
+ showFooter ? /* @__PURE__ */ jsx38(FilterDropdownFooter, { onClear: () => setDraft(clearValue), onApply: apply }) : min === 0 && draft.length > 0 && /* @__PURE__ */ jsx38("div", { className: "border-t border-border-default p-2", children: /* @__PURE__ */ jsxs34(
3799
3895
  "button",
3800
3896
  {
3801
3897
  type: "button",
@@ -3814,7 +3910,7 @@ function MultiSelectFilter({
3814
3910
  }
3815
3911
  function TriCheck({ state }) {
3816
3912
  const filled = state !== "none";
3817
- return /* @__PURE__ */ jsxs33(
3913
+ return /* @__PURE__ */ jsxs34(
3818
3914
  "span",
3819
3915
  {
3820
3916
  className: cn(
@@ -3822,14 +3918,14 @@ function TriCheck({ state }) {
3822
3918
  filled ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
3823
3919
  ),
3824
3920
  children: [
3825
- state === "all" && /* @__PURE__ */ jsx37(Check7, { size: 13, strokeWidth: 3 }),
3826
- state === "some" && /* @__PURE__ */ jsx37(Minus2, { size: 13, strokeWidth: 3 })
3921
+ state === "all" && /* @__PURE__ */ jsx38(Check8, { size: 13, strokeWidth: 3 }),
3922
+ state === "some" && /* @__PURE__ */ jsx38(Minus2, { size: 13, strokeWidth: 3 })
3827
3923
  ]
3828
3924
  }
3829
3925
  );
3830
3926
  }
3831
3927
  function OptionCount({ n }) {
3832
- return /* @__PURE__ */ jsxs33("span", { className: "shrink-0 text-[12px] tabular-nums text-text-tertiary", children: [
3928
+ return /* @__PURE__ */ jsxs34("span", { className: "shrink-0 text-[12px] tabular-nums text-text-tertiary", children: [
3833
3929
  "(",
3834
3930
  n.toLocaleString(),
3835
3931
  ")"
@@ -3837,7 +3933,7 @@ function OptionCount({ n }) {
3837
3933
  }
3838
3934
 
3839
3935
  // src/Toggle.tsx
3840
- import { jsx as jsx38 } from "react/jsx-runtime";
3936
+ import { jsx as jsx39 } from "react/jsx-runtime";
3841
3937
  var SIZES2 = {
3842
3938
  sm: { track: "h-5 w-9", knob: "h-4 w-4", on: "translate-x-[18px]" },
3843
3939
  md: { track: "h-6 w-11", knob: "h-5 w-5", on: "translate-x-[22px]" }
@@ -3845,7 +3941,7 @@ var SIZES2 = {
3845
3941
  var OFF_TRACK = "color-mix(in srgb, var(--mr-color-border-interactive) 70%, var(--mr-color-text-secondary))";
3846
3942
  function Toggle({ checked, onChange, label, size = "md", disabled, className, testIdPrefix }) {
3847
3943
  const s = SIZES2[size];
3848
- return /* @__PURE__ */ jsx38(
3944
+ return /* @__PURE__ */ jsx39(
3849
3945
  "button",
3850
3946
  {
3851
3947
  type: "button",
@@ -3863,7 +3959,7 @@ function Toggle({ checked, onChange, label, size = "md", disabled, className, te
3863
3959
  disabled && "cursor-not-allowed opacity-50",
3864
3960
  className
3865
3961
  ),
3866
- children: /* @__PURE__ */ jsx38(
3962
+ children: /* @__PURE__ */ jsx39(
3867
3963
  "span",
3868
3964
  {
3869
3965
  className: cn(
@@ -3880,20 +3976,20 @@ function Toggle({ checked, onChange, label, size = "md", disabled, className, te
3880
3976
  // src/AISpark.tsx
3881
3977
  import { useId as useId5 } from "react";
3882
3978
  import { Sparkles } from "lucide-react";
3883
- import { Fragment as Fragment5, jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
3979
+ import { Fragment as Fragment5, jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
3884
3980
  function AISpark({ size = 16, className }) {
3885
3981
  const id = useId5();
3886
- return /* @__PURE__ */ jsxs34(Fragment5, { children: [
3887
- /* @__PURE__ */ jsx39("svg", { width: "0", height: "0", "aria-hidden": "true", style: { position: "absolute" }, children: /* @__PURE__ */ jsx39("defs", { children: /* @__PURE__ */ jsxs34("linearGradient", { id, x1: "0", y1: "0", x2: "1", y2: "1", children: [
3888
- /* @__PURE__ */ jsx39("stop", { offset: "0%", stopColor: "var(--mr-color-brand-primary)" }),
3889
- /* @__PURE__ */ jsx39("stop", { offset: "100%", className: "[stop-color:#9474ff] in-data-[theme=dark]:[stop-color:#a488ff]" })
3982
+ return /* @__PURE__ */ jsxs35(Fragment5, { children: [
3983
+ /* @__PURE__ */ jsx40("svg", { width: "0", height: "0", "aria-hidden": "true", style: { position: "absolute" }, children: /* @__PURE__ */ jsx40("defs", { children: /* @__PURE__ */ jsxs35("linearGradient", { id, x1: "0", y1: "0", x2: "1", y2: "1", children: [
3984
+ /* @__PURE__ */ jsx40("stop", { offset: "0%", stopColor: "var(--mr-color-brand-primary)" }),
3985
+ /* @__PURE__ */ jsx40("stop", { offset: "100%", className: "[stop-color:#9474ff] in-data-[theme=dark]:[stop-color:#a488ff]" })
3890
3986
  ] }) }) }),
3891
- /* @__PURE__ */ jsx39(Sparkles, { size, stroke: `url(#${id})`, className, "aria-hidden": "true" })
3987
+ /* @__PURE__ */ jsx40(Sparkles, { size, stroke: `url(#${id})`, className, "aria-hidden": "true" })
3892
3988
  ] });
3893
3989
  }
3894
3990
 
3895
3991
  // src/Freshness.tsx
3896
- import { jsx as jsx40 } from "react/jsx-runtime";
3992
+ import { jsx as jsx41 } from "react/jsx-runtime";
3897
3993
  var dotColor = {
3898
3994
  fresh: "bg-status-success",
3899
3995
  recent: "bg-status-warning",
@@ -3905,7 +4001,7 @@ var srLabel = {
3905
4001
  stale: "Older than a day"
3906
4002
  };
3907
4003
  function Freshness({ level }) {
3908
- return /* @__PURE__ */ jsx40(
4004
+ return /* @__PURE__ */ jsx41(
3909
4005
  "span",
3910
4006
  {
3911
4007
  className: cn("inline-block h-1.5 w-1.5 shrink-0 rounded-full", dotColor[level]),
@@ -3916,28 +4012,306 @@ function Freshness({ level }) {
3916
4012
  }
3917
4013
 
3918
4014
  // src/SectionHeading.tsx
3919
- import { jsx as jsx41, jsxs as jsxs35 } from "react/jsx-runtime";
4015
+ import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
3920
4016
  function SectionHeading({ title, description, actions, as: Tag2 = "h2", id, className }) {
3921
- return /* @__PURE__ */ jsxs35("div", { className: cn("flex flex-wrap items-end justify-between gap-x-4 gap-y-2", className), children: [
3922
- /* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
3923
- /* @__PURE__ */ jsx41(Tag2, { id, className: "text-base font-semibold text-text-primary", children: title }),
3924
- description && /* @__PURE__ */ jsx41("p", { className: "mt-0.5 text-dense text-text-secondary", children: description })
4017
+ return /* @__PURE__ */ jsxs36("div", { className: cn("flex flex-wrap items-end justify-between gap-x-4 gap-y-2", className), children: [
4018
+ /* @__PURE__ */ jsxs36("div", { className: "min-w-0", children: [
4019
+ /* @__PURE__ */ jsx42(Tag2, { id, className: "text-base font-semibold text-text-primary", children: title }),
4020
+ description && /* @__PURE__ */ jsx42("p", { className: "mt-0.5 text-dense text-text-secondary", children: description })
3925
4021
  ] }),
3926
- actions && /* @__PURE__ */ jsx41("div", { className: "flex shrink-0 items-center gap-2", children: actions })
4022
+ actions && /* @__PURE__ */ jsx42("div", { className: "flex shrink-0 items-center gap-2", children: actions })
3927
4023
  ] });
3928
4024
  }
3929
4025
 
3930
4026
  // src/PageHeader.tsx
3931
- import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
3932
- function PageHeader({ title, description, actions, className }) {
3933
- return /* @__PURE__ */ jsxs36("header", { className: cn("flex flex-wrap items-center justify-between gap-x-6 gap-y-3", className), children: [
3934
- /* @__PURE__ */ jsxs36("div", { className: "min-w-0", children: [
3935
- /* @__PURE__ */ jsx42("h1", { className: "text-xl font-semibold tracking-tight text-text-primary", children: title }),
3936
- description && /* @__PURE__ */ jsx42("p", { className: "mt-0.5 max-w-2xl text-sm text-text-secondary", children: description })
4027
+ import { ArrowLeft } from "lucide-react";
4028
+ import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
4029
+ function PageHeader({ title, description, actions, back, className }) {
4030
+ return /* @__PURE__ */ jsxs37("header", { className: cn("flex flex-wrap items-center justify-between gap-x-6 gap-y-3", className), children: [
4031
+ /* @__PURE__ */ jsxs37("div", { className: "min-w-0", children: [
4032
+ back && /* @__PURE__ */ jsxs37(
4033
+ "a",
4034
+ {
4035
+ href: back.href ?? "#",
4036
+ onClick: back.onClick,
4037
+ 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",
4038
+ children: [
4039
+ /* @__PURE__ */ jsx43(ArrowLeft, { size: 13, "aria-hidden": "true" }),
4040
+ back.label
4041
+ ]
4042
+ }
4043
+ ),
4044
+ /* @__PURE__ */ jsx43("h1", { className: "text-xl font-semibold tracking-tight text-text-primary", children: title }),
4045
+ description && /* @__PURE__ */ jsx43("p", { className: "mt-0.5 max-w-2xl text-sm text-text-secondary", children: description })
3937
4046
  ] }),
3938
- actions && /* @__PURE__ */ jsx42("div", { className: "flex shrink-0 items-center gap-2", children: actions })
4047
+ actions && /* @__PURE__ */ jsx43("div", { className: "flex shrink-0 items-center gap-2", children: actions })
3939
4048
  ] });
3940
4049
  }
4050
+
4051
+ // src/Modal.tsx
4052
+ import { useEffect as useEffect14, useId as useId6, useRef as useRef15 } from "react";
4053
+ import { createPortal as createPortal7 } from "react-dom";
4054
+ import { X as X6 } from "lucide-react";
4055
+ import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
4056
+ var WIDTH = {
4057
+ sm: "max-w-110",
4058
+ md: "max-w-160",
4059
+ lg: "max-w-220"
4060
+ };
4061
+ var FOCUSABLE = 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
4062
+ function Modal({ open, onClose, title, description, size = "md", footer, children, className }) {
4063
+ const titleId = useId6();
4064
+ const descId = useId6();
4065
+ const panel = useRef15(null);
4066
+ const close = useRef15(onClose);
4067
+ close.current = onClose;
4068
+ useEffect14(() => {
4069
+ if (!open) return;
4070
+ const opener = document.activeElement;
4071
+ const first = panel.current?.querySelector(`[data-modal-body] :is(${FOCUSABLE})`) ?? panel.current?.querySelector(`[data-modal-footer] :is(${FOCUSABLE})`);
4072
+ (first ?? panel.current)?.focus();
4073
+ const overflow = document.body.style.overflow;
4074
+ document.body.style.overflow = "hidden";
4075
+ const onKey = (e) => {
4076
+ if (e.key === "Escape") {
4077
+ e.stopPropagation();
4078
+ close.current();
4079
+ return;
4080
+ }
4081
+ if (e.key !== "Tab" || !panel.current) return;
4082
+ const items = Array.from(panel.current.querySelectorAll(FOCUSABLE));
4083
+ if (items.length === 0) return;
4084
+ const [head, tail] = [items[0], items[items.length - 1]];
4085
+ if (e.shiftKey && document.activeElement === head) {
4086
+ e.preventDefault();
4087
+ tail.focus();
4088
+ } else if (!e.shiftKey && document.activeElement === tail) {
4089
+ e.preventDefault();
4090
+ head.focus();
4091
+ }
4092
+ };
4093
+ document.addEventListener("keydown", onKey);
4094
+ return () => {
4095
+ document.removeEventListener("keydown", onKey);
4096
+ document.body.style.overflow = overflow;
4097
+ opener?.focus?.();
4098
+ };
4099
+ }, [open]);
4100
+ if (!open || typeof document === "undefined") return null;
4101
+ return createPortal7(
4102
+ /* @__PURE__ */ jsx44(
4103
+ "div",
4104
+ {
4105
+ className: "fixed inset-0 z-modal flex items-center justify-center bg-scrim px-4 py-6",
4106
+ onMouseDown: (e) => e.target === e.currentTarget && onClose(),
4107
+ children: /* @__PURE__ */ jsxs38(
4108
+ "div",
4109
+ {
4110
+ ref: panel,
4111
+ role: "dialog",
4112
+ "aria-modal": "true",
4113
+ "aria-labelledby": titleId,
4114
+ "aria-describedby": description ? descId : void 0,
4115
+ tabIndex: -1,
4116
+ className: cn(
4117
+ "flex max-h-full w-full flex-col rounded-card border border-border-default bg-surface shadow-overlay outline-hidden",
4118
+ WIDTH[size],
4119
+ className
4120
+ ),
4121
+ children: [
4122
+ /* @__PURE__ */ jsxs38("div", { className: "flex items-start gap-3 px-5 pt-5 pb-3", children: [
4123
+ /* @__PURE__ */ jsxs38("div", { className: "min-w-0 flex-1", children: [
4124
+ /* @__PURE__ */ jsx44("h2", { id: titleId, className: "text-base font-semibold text-text-primary", children: title }),
4125
+ description && /* @__PURE__ */ jsx44("p", { id: descId, className: "mt-0.5 text-sm text-text-secondary", children: description })
4126
+ ] }),
4127
+ /* @__PURE__ */ jsx44(
4128
+ "button",
4129
+ {
4130
+ type: "button",
4131
+ onClick: onClose,
4132
+ "aria-label": "Close",
4133
+ 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",
4134
+ children: /* @__PURE__ */ jsx44(X6, { size: 16, "aria-hidden": "true" })
4135
+ }
4136
+ )
4137
+ ] }),
4138
+ children && /* @__PURE__ */ jsx44("div", { "data-modal-body": true, className: "min-h-0 flex-1 overflow-y-auto px-5 pb-5 text-sm text-text-primary", children }),
4139
+ footer && /* @__PURE__ */ jsx44("div", { "data-modal-footer": true, className: "flex items-center justify-end gap-2 border-t border-border-default px-5 py-3", children: footer })
4140
+ ]
4141
+ }
4142
+ )
4143
+ }
4144
+ ),
4145
+ document.body
4146
+ );
4147
+ }
4148
+
4149
+ // src/EmptyState.tsx
4150
+ import { jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
4151
+ function EmptyState({ icon, title, description, action, size = "sm", className }) {
4152
+ const md = size === "md";
4153
+ return /* @__PURE__ */ jsxs39(
4154
+ "div",
4155
+ {
4156
+ className: cn(
4157
+ "flex flex-col items-center text-center",
4158
+ md ? "gap-2 px-6 py-16" : "gap-1.5 px-4 py-8",
4159
+ className
4160
+ ),
4161
+ children: [
4162
+ icon && /* @__PURE__ */ jsx45(
4163
+ "span",
4164
+ {
4165
+ "aria-hidden": "true",
4166
+ className: cn(
4167
+ "flex items-center justify-center text-text-tertiary",
4168
+ md && "mb-1 size-11 rounded-full bg-subtle"
4169
+ ),
4170
+ children: icon
4171
+ }
4172
+ ),
4173
+ /* @__PURE__ */ jsx45("p", { className: cn("font-semibold text-text-primary", md ? "text-base" : "text-sm"), children: title }),
4174
+ description && /* @__PURE__ */ jsx45("p", { className: cn("max-w-sm text-text-secondary", md ? "text-sm" : "text-xs"), children: description }),
4175
+ action && /* @__PURE__ */ jsx45("div", { className: md ? "mt-3" : "mt-2", children: action })
4176
+ ]
4177
+ }
4178
+ );
4179
+ }
4180
+
4181
+ // src/Tabs.tsx
4182
+ import { useRef as useRef16 } from "react";
4183
+ import { jsx as jsx46, jsxs as jsxs40 } from "react/jsx-runtime";
4184
+ function arrowKeys(e, row) {
4185
+ if (!row || !["ArrowLeft", "ArrowRight", "Home", "End"].includes(e.key)) return;
4186
+ const items = Array.from(row.querySelectorAll("button:not([disabled])"));
4187
+ const at = items.indexOf(document.activeElement);
4188
+ const next = e.key === "Home" ? 0 : e.key === "End" ? items.length - 1 : (at + (e.key === "ArrowRight" ? 1 : -1) + items.length) % items.length;
4189
+ e.preventDefault();
4190
+ items[next]?.focus();
4191
+ items[next]?.click();
4192
+ }
4193
+ function Tabs({ items, value, onChange, idPrefix = "tabs", className, ...rest }) {
4194
+ const row = useRef16(null);
4195
+ return /* @__PURE__ */ jsx46(
4196
+ "div",
4197
+ {
4198
+ ref: row,
4199
+ role: "tablist",
4200
+ "aria-label": rest["aria-label"],
4201
+ onKeyDown: (e) => arrowKeys(e, row.current),
4202
+ className: cn("flex gap-6 border-b border-border-default", className),
4203
+ children: items.map((item) => {
4204
+ const on = item.value === value;
4205
+ return /* @__PURE__ */ jsxs40(
4206
+ "button",
4207
+ {
4208
+ type: "button",
4209
+ role: "tab",
4210
+ id: `${idPrefix}-tab-${item.value}`,
4211
+ "aria-controls": `${idPrefix}-panel-${item.value}`,
4212
+ "aria-selected": on,
4213
+ tabIndex: on ? 0 : -1,
4214
+ disabled: item.disabled,
4215
+ onClick: () => onChange(item.value),
4216
+ className: cn(
4217
+ "-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",
4218
+ on ? "border-brand-primaryAction font-semibold text-text-primary" : "border-transparent text-text-secondary hover:text-text-primary"
4219
+ ),
4220
+ children: [
4221
+ item.label,
4222
+ item.count !== void 0 && /* @__PURE__ */ jsx46("span", { className: "text-xs text-text-tertiary", children: item.count })
4223
+ ]
4224
+ },
4225
+ item.value
4226
+ );
4227
+ })
4228
+ }
4229
+ );
4230
+ }
4231
+ function SegmentedControl({
4232
+ options,
4233
+ value,
4234
+ onChange,
4235
+ size = "sm",
4236
+ className,
4237
+ ...rest
4238
+ }) {
4239
+ const row = useRef16(null);
4240
+ return /* @__PURE__ */ jsx46(
4241
+ "div",
4242
+ {
4243
+ ref: row,
4244
+ role: "radiogroup",
4245
+ "aria-label": rest["aria-label"],
4246
+ onKeyDown: (e) => arrowKeys(e, row.current),
4247
+ className: cn("inline-flex w-fit items-stretch gap-0.5 rounded-full bg-subtle p-1", size === "md" ? "h-10" : "h-8", className),
4248
+ children: options.map((o) => {
4249
+ const on = o.value === value;
4250
+ return /* @__PURE__ */ jsx46(
4251
+ "button",
4252
+ {
4253
+ type: "button",
4254
+ role: "radio",
4255
+ "aria-checked": on,
4256
+ tabIndex: on ? 0 : -1,
4257
+ onClick: () => onChange(o.value),
4258
+ className: cn(
4259
+ "rounded-full px-3 focus-visible:outline-2 focus-visible:outline-offset-1 focus-visible:outline-border-focus",
4260
+ size === "md" ? "text-sm" : "text-xs",
4261
+ on ? "bg-surface font-semibold text-text-primary shadow-raised" : "text-text-secondary hover:text-text-primary"
4262
+ ),
4263
+ children: o.label
4264
+ },
4265
+ o.value
4266
+ );
4267
+ })
4268
+ }
4269
+ );
4270
+ }
4271
+
4272
+ // src/TextField.tsx
4273
+ import { forwardRef as forwardRef3, useId as useId7 } from "react";
4274
+ import { jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
4275
+ var HEIGHT2 = { sm: "h-8", md: "h-10", lg: "h-11" };
4276
+ var TextField = forwardRef3(
4277
+ ({ label, hint, error, size = "md", icon, className, id, disabled, ...props }, ref) => {
4278
+ const auto = useId7();
4279
+ const fieldId = id ?? auto;
4280
+ const noteId = `${fieldId}-note`;
4281
+ const note = error ?? hint;
4282
+ return /* @__PURE__ */ jsxs41("div", { className: cn("flex flex-col gap-1.5", className), children: [
4283
+ label && /* @__PURE__ */ jsx47("label", { htmlFor: fieldId, className: "text-xs font-medium text-text-secondary", children: label }),
4284
+ /* @__PURE__ */ jsxs41(
4285
+ "div",
4286
+ {
4287
+ className: cn(
4288
+ "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",
4289
+ HEIGHT2[size],
4290
+ error ? "border-status-danger" : "border-border-strong",
4291
+ disabled && "opacity-50"
4292
+ ),
4293
+ children: [
4294
+ icon && /* @__PURE__ */ jsx47("span", { "aria-hidden": "true", className: "flex shrink-0 text-text-tertiary", children: icon }),
4295
+ /* @__PURE__ */ jsx47(
4296
+ "input",
4297
+ {
4298
+ ref,
4299
+ id: fieldId,
4300
+ disabled,
4301
+ "aria-invalid": error ? true : void 0,
4302
+ "aria-describedby": note ? noteId : void 0,
4303
+ className: "min-w-0 flex-1 bg-transparent text-dense text-text-primary outline-hidden placeholder:text-text-tertiary",
4304
+ ...props
4305
+ }
4306
+ )
4307
+ ]
4308
+ }
4309
+ ),
4310
+ note && /* @__PURE__ */ jsx47("p", { id: noteId, className: cn("text-xs", error ? "text-text-danger" : "text-text-tertiary"), children: note })
4311
+ ] });
4312
+ }
4313
+ );
4314
+ TextField.displayName = "TextField";
3941
4315
  export {
3942
4316
  AISpark,
3943
4317
  AdvertiserNoResults,
@@ -3955,11 +4329,13 @@ export {
3955
4329
  DateRangeFilter,
3956
4330
  DateRangePicker,
3957
4331
  Delta,
4332
+ EmptyState,
3958
4333
  FilterChipBar,
3959
4334
  FilterDropdownFooter,
3960
4335
  Freshness,
3961
4336
  InfoTip,
3962
4337
  LineChartPlaceholder,
4338
+ Modal,
3963
4339
  MultiSelectFilter,
3964
4340
  NO_RESULTS_BODY,
3965
4341
  NO_RESULTS_TITLE,
@@ -3974,6 +4350,7 @@ export {
3974
4350
  SearchBar,
3975
4351
  SectionHeading,
3976
4352
  SectionRail,
4353
+ SegmentedControl,
3977
4354
  SelectAllVisible,
3978
4355
  SelectFilter,
3979
4356
  SelectedSection,
@@ -3981,7 +4358,10 @@ export {
3981
4358
  SortButton,
3982
4359
  StackedColumnPlaceholder,
3983
4360
  TablePagination,
4361
+ Tabs,
3984
4362
  Tag,
4363
+ TextField,
4364
+ Toast,
3985
4365
  Toggle,
3986
4366
  Tooltip,
3987
4367
  WorkspaceAvatar,