@mediaradar/design-components 0.18.8 → 0.20.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
@@ -583,7 +583,7 @@ function CheckBoxBox({ checked, indeterminate, disabled, className }) {
583
583
  }
584
584
 
585
585
  // src/DateRangeFilter.tsx
586
- import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
586
+ import { useEffect as useEffect3, useLayoutEffect, useMemo as useMemo2, useRef as useRef3, useState as useState3 } from "react";
587
587
  import { ChevronDown as ChevronDown2, ChevronLeft, ChevronRight } from "lucide-react";
588
588
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
589
589
  var DEFAULT_SHORTCUTS = [
@@ -707,6 +707,7 @@ function DateRangeFilter({
707
707
  value: controlledValue,
708
708
  range: controlledRange,
709
709
  align = "left",
710
+ placement = "below",
710
711
  onChange,
711
712
  onRangeChange,
712
713
  showDates = false,
@@ -791,6 +792,13 @@ function DateRangeFilter({
791
792
  onRangeChange?.(s, e);
792
793
  setOpen(false);
793
794
  };
795
+ const popRef = useRef3(null);
796
+ const [flipBelow, setFlipBelow] = useState3(false);
797
+ useLayoutEffect(() => {
798
+ if (!open || placement !== "above" || !ref.current || !popRef.current) return;
799
+ setFlipBelow(ref.current.getBoundingClientRect().top < popRef.current.offsetHeight + 16);
800
+ }, [open, placement]);
801
+ const above = placement === "above" && !flipBelow;
794
802
  return /* @__PURE__ */ jsxs6("div", { className: "relative", ref, children: [
795
803
  /* @__PURE__ */ jsxs6(
796
804
  "button",
@@ -814,7 +822,8 @@ function DateRangeFilter({
814
822
  "div",
815
823
  {
816
824
  "data-testid": testIdPrefix && `${testIdPrefix}-popover`,
817
- className: `absolute top-[calc(100%+8px)] z-30 flex overflow-hidden rounded-card border border-border-default bg-surface shadow-overlay ${align === "right" ? "right-0" : "left-0"}`,
825
+ ref: popRef,
826
+ className: `absolute z-30 flex overflow-hidden rounded-card border border-border-default bg-surface shadow-overlay ${placement === "right" ? "bottom-0 left-full ml-2" : `${above ? "bottom-full mb-2" : "top-[calc(100%+8px)]"} ${align === "right" ? "right-0" : "left-0"}`}`,
818
827
  role: "dialog",
819
828
  "aria-label": "Select date range",
820
829
  children: [
@@ -1375,7 +1384,7 @@ function Option({
1375
1384
  }
1376
1385
 
1377
1386
  // src/SelectFilter.tsx
1378
- import { useCallback as useCallback2, useEffect as useEffect6, useLayoutEffect, useRef as useRef7, useState as useState6 } from "react";
1387
+ import { useCallback as useCallback2, useEffect as useEffect6, useLayoutEffect as useLayoutEffect2, useRef as useRef7, useState as useState6 } from "react";
1379
1388
  import { createPortal as createPortal2 } from "react-dom";
1380
1389
  import { Check as Check5, ChevronDown as ChevronDown5 } from "lucide-react";
1381
1390
  import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
@@ -1405,7 +1414,7 @@ function SelectFilter({
1405
1414
  const r = ref.current.getBoundingClientRect();
1406
1415
  setPos({ top: r.bottom + 8, left: align === "right" ? r.right - r.width : r.left, width: r.width });
1407
1416
  }, [align]);
1408
- useLayoutEffect(() => {
1417
+ useLayoutEffect2(() => {
1409
1418
  if (!open) return;
1410
1419
  reposition();
1411
1420
  }, [open, reposition]);
@@ -1878,7 +1887,7 @@ function StackedColumnPlaceholder({
1878
1887
  }
1879
1888
 
1880
1889
  // src/Tooltip.tsx
1881
- import { useEffect as useEffect8, useId as useId3, useLayoutEffect as useLayoutEffect2, useRef as useRef9, useState as useState8 } from "react";
1890
+ import { useEffect as useEffect8, useId as useId3, useLayoutEffect as useLayoutEffect3, useRef as useRef9, useState as useState8 } from "react";
1882
1891
  import { createPortal as createPortal3 } from "react-dom";
1883
1892
  import { jsx as jsx20, jsxs as jsxs18 } from "react/jsx-runtime";
1884
1893
  function cx6(...parts) {
@@ -2044,7 +2053,7 @@ function Tooltip({
2044
2053
  window.addEventListener("keydown", onKey);
2045
2054
  return () => window.removeEventListener("keydown", onKey);
2046
2055
  }, [anchor]);
2047
- useLayoutEffect2(() => {
2056
+ useLayoutEffect3(() => {
2048
2057
  if (!anchor) return;
2049
2058
  const el = boxRef.current;
2050
2059
  if (!el) return;
@@ -2185,7 +2194,7 @@ function SelectedSection({ count, open, onToggle, children, testIdPrefix }) {
2185
2194
  }
2186
2195
 
2187
2196
  // src/SelectionPicker.tsx
2188
- import { useCallback as useCallback3, useEffect as useEffect9, useLayoutEffect as useLayoutEffect3, useMemo as useMemo3, useRef as useRef10, useState as useState9 } from "react";
2197
+ import { useCallback as useCallback3, useEffect as useEffect9, useLayoutEffect as useLayoutEffect4, useMemo as useMemo3, useRef as useRef10, useState as useState9 } from "react";
2189
2198
  import { createPortal as createPortal4 } from "react-dom";
2190
2199
  import { Search as Search4, Plus, Info as Info2, ChevronRight as ChevronRight3, ChevronDown as ChevronDown8, Check as Check6, List, Loader2 } from "lucide-react";
2191
2200
  import { Fragment as Fragment4, jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
@@ -2590,7 +2599,7 @@ function FilterDropdown({
2590
2599
  const [pos, setPos] = useState9(null);
2591
2600
  const searchable = filter.options.length > 8;
2592
2601
  const shownOptions = searchable && q.trim() ? filter.options.filter((o) => o.toLowerCase().includes(q.trim().toLowerCase())) : filter.options;
2593
- useLayoutEffect3(() => {
2602
+ useLayoutEffect4(() => {
2594
2603
  if (!open || !btnRef.current) return;
2595
2604
  const r = btnRef.current.getBoundingClientRect();
2596
2605
  setPos({ top: r.bottom + 6, left: r.left });
@@ -3261,10 +3270,83 @@ function WorkspaceAvatar({ name, size = "md" }) {
3261
3270
  );
3262
3271
  }
3263
3272
 
3273
+ // src/Toast.tsx
3274
+ import { useEffect as useEffect11, useRef as useRef12, useState as useState12 } from "react";
3275
+ import { createPortal as createPortal6 } from "react-dom";
3276
+ import { AlertTriangle, Check as Check7 } from "lucide-react";
3277
+ import { jsx as jsx34, jsxs as jsxs31 } from "react/jsx-runtime";
3278
+ var ICON = {
3279
+ neutral: null,
3280
+ success: /* @__PURE__ */ jsx34(Check7, { size: 15, className: "shrink-0", "aria-hidden": "true" }),
3281
+ warning: /* @__PURE__ */ jsx34(AlertTriangle, { size: 15, className: "shrink-0", "aria-hidden": "true" })
3282
+ };
3283
+ function Toast({ message, action, onClose, tone = "neutral", duration, className }) {
3284
+ const ms = duration ?? (action ? 1e4 : 5e3);
3285
+ const [paused, setPaused] = useState12(false);
3286
+ const closed = useRef12(false);
3287
+ useEffect11(() => {
3288
+ if (paused) return;
3289
+ const t = window.setTimeout(() => {
3290
+ if (closed.current) return;
3291
+ closed.current = true;
3292
+ onClose();
3293
+ }, ms);
3294
+ return () => window.clearTimeout(t);
3295
+ }, [message, ms, paused]);
3296
+ return createPortal6(
3297
+ /* @__PURE__ */ jsxs31(
3298
+ "div",
3299
+ {
3300
+ role: "status",
3301
+ "aria-live": "polite",
3302
+ onMouseEnter: () => setPaused(true),
3303
+ onMouseLeave: () => setPaused(false),
3304
+ onFocusCapture: () => setPaused(true),
3305
+ onBlurCapture: () => setPaused(false),
3306
+ className: cn(
3307
+ "fixed bottom-6 left-1/2 z-toast flex max-w-[92vw] -translate-x-1/2 items-center gap-2.5",
3308
+ "rounded-control bg-inverseSurface py-2.5 pl-4 pr-2.5 text-sm font-medium text-text-inverse shadow-overlay",
3309
+ className
3310
+ ),
3311
+ children: [
3312
+ ICON[tone] && // The inverse pair, not text-success / text-warning: those are tuned
3313
+ // for the page, and on the toast's flipped surface amber drops to 2:1.
3314
+ /* @__PURE__ */ jsx34(
3315
+ "span",
3316
+ {
3317
+ className: cn(
3318
+ "flex",
3319
+ tone === "success" ? "text-text-inverseSuccess" : "text-text-inverseWarning"
3320
+ ),
3321
+ children: ICON[tone]
3322
+ }
3323
+ ),
3324
+ /* @__PURE__ */ jsx34("span", { className: "min-w-0", children: message }),
3325
+ action && /* @__PURE__ */ jsx34(
3326
+ "button",
3327
+ {
3328
+ type: "button",
3329
+ onClick: () => {
3330
+ if (!closed.current) {
3331
+ closed.current = true;
3332
+ action.onClick();
3333
+ }
3334
+ },
3335
+ 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",
3336
+ children: action.label
3337
+ }
3338
+ )
3339
+ ]
3340
+ }
3341
+ ),
3342
+ document.body
3343
+ );
3344
+ }
3345
+
3264
3346
  // src/Tag.tsx
3265
- import { jsx as jsx34 } from "react/jsx-runtime";
3347
+ import { jsx as jsx35 } from "react/jsx-runtime";
3266
3348
  function Tag({ children, className }) {
3267
- return /* @__PURE__ */ jsx34(
3349
+ return /* @__PURE__ */ jsx35(
3268
3350
  "span",
3269
3351
  {
3270
3352
  className: cn(
@@ -3284,7 +3366,7 @@ function Tag({ children, className }) {
3284
3366
 
3285
3367
  // src/TablePagination.tsx
3286
3368
  import { ChevronDown as ChevronDown9, ChevronFirst, ChevronLast, ChevronLeft as ChevronLeft4, ChevronRight as ChevronRight5 } from "lucide-react";
3287
- import { jsx as jsx35, jsxs as jsxs31 } from "react/jsx-runtime";
3369
+ import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
3288
3370
  function TablePagination({
3289
3371
  page,
3290
3372
  perPage,
@@ -3305,10 +3387,10 @@ function TablePagination({
3305
3387
  btn,
3306
3388
  "text-text-secondary hover:bg-subtle hover:text-text-primary disabled:pointer-events-none disabled:opacity-30"
3307
3389
  );
3308
- return /* @__PURE__ */ jsxs31("div", { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-2", className), "data-testid": testIdPrefix, children: [
3309
- /* @__PURE__ */ jsxs31("label", { className: "flex items-center gap-2 text-[13px] text-text-secondary", children: [
3310
- /* @__PURE__ */ jsxs31("span", { className: "relative", children: [
3311
- /* @__PURE__ */ jsx35(
3390
+ return /* @__PURE__ */ jsxs32("div", { className: cn("flex flex-wrap items-center justify-between gap-x-4 gap-y-2", className), "data-testid": testIdPrefix, children: [
3391
+ /* @__PURE__ */ jsxs32("label", { className: "flex items-center gap-2 text-[13px] text-text-secondary", children: [
3392
+ /* @__PURE__ */ jsxs32("span", { className: "relative", children: [
3393
+ /* @__PURE__ */ jsx36(
3312
3394
  "select",
3313
3395
  {
3314
3396
  value: perPage,
@@ -3316,10 +3398,10 @@ function TablePagination({
3316
3398
  "aria-label": "Items per page",
3317
3399
  "data-testid": testIdPrefix && `${testIdPrefix}-per-page`,
3318
3400
  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",
3319
- children: perPageOptions.map((n) => /* @__PURE__ */ jsx35("option", { value: n, children: n }, n))
3401
+ children: perPageOptions.map((n) => /* @__PURE__ */ jsx36("option", { value: n, children: n }, n))
3320
3402
  }
3321
3403
  ),
3322
- /* @__PURE__ */ jsx35(
3404
+ /* @__PURE__ */ jsx36(
3323
3405
  ChevronDown9,
3324
3406
  {
3325
3407
  size: 13,
@@ -3330,8 +3412,8 @@ function TablePagination({
3330
3412
  ] }),
3331
3413
  "items per page"
3332
3414
  ] }),
3333
- /* @__PURE__ */ jsxs31("nav", { className: "flex items-center gap-1", "aria-label": "Pagination", children: [
3334
- /* @__PURE__ */ jsx35(
3415
+ /* @__PURE__ */ jsxs32("nav", { className: "flex items-center gap-1", "aria-label": "Pagination", children: [
3416
+ /* @__PURE__ */ jsx36(
3335
3417
  "button",
3336
3418
  {
3337
3419
  type: "button",
@@ -3340,10 +3422,10 @@ function TablePagination({
3340
3422
  "aria-label": "First page",
3341
3423
  "data-testid": testIdPrefix && `${testIdPrefix}-first`,
3342
3424
  className: stepBtn,
3343
- children: /* @__PURE__ */ jsx35(ChevronFirst, { size: 16, "aria-hidden": "true" })
3425
+ children: /* @__PURE__ */ jsx36(ChevronFirst, { size: 16, "aria-hidden": "true" })
3344
3426
  }
3345
3427
  ),
3346
- /* @__PURE__ */ jsx35(
3428
+ /* @__PURE__ */ jsx36(
3347
3429
  "button",
3348
3430
  {
3349
3431
  type: "button",
@@ -3352,11 +3434,11 @@ function TablePagination({
3352
3434
  "aria-label": "Previous page",
3353
3435
  "data-testid": testIdPrefix && `${testIdPrefix}-prev`,
3354
3436
  className: stepBtn,
3355
- children: /* @__PURE__ */ jsx35(ChevronLeft4, { size: 16, "aria-hidden": "true" })
3437
+ children: /* @__PURE__ */ jsx36(ChevronLeft4, { size: 16, "aria-hidden": "true" })
3356
3438
  }
3357
3439
  ),
3358
3440
  pageWindow(current, totalPages).map(
3359
- (p) => typeof p === "string" ? /* @__PURE__ */ jsx35("span", { className: "px-1 text-[13px] text-text-tertiary", children: "\u2026" }, p) : /* @__PURE__ */ jsx35(
3441
+ (p) => typeof p === "string" ? /* @__PURE__ */ jsx36("span", { className: "px-1 text-[13px] text-text-tertiary", children: "\u2026" }, p) : /* @__PURE__ */ jsx36(
3360
3442
  "button",
3361
3443
  {
3362
3444
  type: "button",
@@ -3372,7 +3454,7 @@ function TablePagination({
3372
3454
  p
3373
3455
  )
3374
3456
  ),
3375
- /* @__PURE__ */ jsx35(
3457
+ /* @__PURE__ */ jsx36(
3376
3458
  "button",
3377
3459
  {
3378
3460
  type: "button",
@@ -3381,10 +3463,10 @@ function TablePagination({
3381
3463
  "aria-label": "Next page",
3382
3464
  "data-testid": testIdPrefix && `${testIdPrefix}-next`,
3383
3465
  className: stepBtn,
3384
- children: /* @__PURE__ */ jsx35(ChevronRight5, { size: 16, "aria-hidden": "true" })
3466
+ children: /* @__PURE__ */ jsx36(ChevronRight5, { size: 16, "aria-hidden": "true" })
3385
3467
  }
3386
3468
  ),
3387
- /* @__PURE__ */ jsx35(
3469
+ /* @__PURE__ */ jsx36(
3388
3470
  "button",
3389
3471
  {
3390
3472
  type: "button",
@@ -3393,11 +3475,11 @@ function TablePagination({
3393
3475
  "aria-label": "Last page",
3394
3476
  "data-testid": testIdPrefix && `${testIdPrefix}-last`,
3395
3477
  className: stepBtn,
3396
- children: /* @__PURE__ */ jsx35(ChevronLast, { size: 16, "aria-hidden": "true" })
3478
+ children: /* @__PURE__ */ jsx36(ChevronLast, { size: 16, "aria-hidden": "true" })
3397
3479
  }
3398
3480
  )
3399
3481
  ] }),
3400
- /* @__PURE__ */ jsxs31("span", { className: "text-[13px] text-text-tertiary tabular-nums", children: [
3482
+ /* @__PURE__ */ jsxs32("span", { className: "text-[13px] text-text-tertiary tabular-nums", children: [
3401
3483
  rangeStart.toLocaleString(),
3402
3484
  " \u2013 ",
3403
3485
  rangeEnd.toLocaleString(),
@@ -3410,9 +3492,9 @@ function TablePagination({
3410
3492
  }
3411
3493
 
3412
3494
  // src/DateRangePicker.tsx
3413
- import { useEffect as useEffect11, useMemo as useMemo4, useRef as useRef12, useState as useState12 } from "react";
3495
+ import { useEffect as useEffect12, useMemo as useMemo4, useRef as useRef13, useState as useState13 } from "react";
3414
3496
  import { ChevronDown as ChevronDown10 } from "lucide-react";
3415
- import { jsx as jsx36, jsxs as jsxs32 } from "react/jsx-runtime";
3497
+ import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
3416
3498
  var MONTH_ABBR = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
3417
3499
  var QUARTER_ABBR = ["Q1", "Q2", "Q3", "Q4"];
3418
3500
  var PRESETS = ["Rolling 3 months", "Rolling 6 months", "Rolling 12 months"];
@@ -3448,7 +3530,7 @@ function spanLabel(label, today) {
3448
3530
  return `${fmtDate(s)} \u2013 ${fmtDate(e)}`;
3449
3531
  }
3450
3532
  function MiniSelect({ value, onChange, options }) {
3451
- return /* @__PURE__ */ jsx36(
3533
+ return /* @__PURE__ */ jsx37(
3452
3534
  "select",
3453
3535
  {
3454
3536
  value: String(value),
@@ -3457,7 +3539,7 @@ function MiniSelect({ value, onChange, options }) {
3457
3539
  if (opt) onChange(opt.value);
3458
3540
  },
3459
3541
  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",
3460
- children: options.map((o) => /* @__PURE__ */ jsx36("option", { value: String(o.value), children: o.label }, String(o.value)))
3542
+ children: options.map((o) => /* @__PURE__ */ jsx37("option", { value: String(o.value), children: o.label }, String(o.value)))
3461
3543
  }
3462
3544
  );
3463
3545
  }
@@ -3474,17 +3556,17 @@ function DateRangePicker({
3474
3556
  }) {
3475
3557
  const end = useMemo4(() => today ?? startOfToday(), [today]);
3476
3558
  const yearOptions = years ?? [3, 2, 1, 0].map((n) => end.getFullYear() - n);
3477
- const [open, setOpen] = useState12(false);
3478
- const [value, setValue] = useState12(defaultValue);
3479
- const [draft, setDraft] = useState12(defaultValue);
3480
- const ref = useRef12(null);
3481
- const [fromMo, setFromMo] = useState12(end.getMonth());
3482
- const [fromYr, setFromYr] = useState12(end.getFullYear() - 1);
3483
- const [toMo, setToMo] = useState12(end.getMonth());
3484
- const [toYr, setToYr] = useState12(end.getFullYear());
3485
- const [fromQ, setFromQ] = useState12(Math.floor(end.getMonth() / 3));
3486
- const [toQ, setToQ] = useState12(Math.floor(end.getMonth() / 3));
3487
- useEffect11(() => {
3559
+ const [open, setOpen] = useState13(false);
3560
+ const [value, setValue] = useState13(defaultValue);
3561
+ const [draft, setDraft] = useState13(defaultValue);
3562
+ const ref = useRef13(null);
3563
+ const [fromMo, setFromMo] = useState13(end.getMonth());
3564
+ const [fromYr, setFromYr] = useState13(end.getFullYear() - 1);
3565
+ const [toMo, setToMo] = useState13(end.getMonth());
3566
+ const [toYr, setToYr] = useState13(end.getFullYear());
3567
+ const [fromQ, setFromQ] = useState13(Math.floor(end.getMonth() / 3));
3568
+ const [toQ, setToQ] = useState13(Math.floor(end.getMonth() / 3));
3569
+ useEffect12(() => {
3488
3570
  const [s, e] = resolveRange(value, end);
3489
3571
  onRangeChange?.(s, e);
3490
3572
  }, [value]);
@@ -3492,7 +3574,7 @@ function DateRangePicker({
3492
3574
  if (!open) setDraft(value);
3493
3575
  setOpen((o) => !o);
3494
3576
  };
3495
- useEffect11(() => {
3577
+ useEffect12(() => {
3496
3578
  if (!open) return;
3497
3579
  const onDown = (e) => {
3498
3580
  if (ref.current && !ref.current.contains(e.target)) setOpen(false);
@@ -3518,8 +3600,8 @@ function DateRangePicker({
3518
3600
  if (showFooter) setDraft(label);
3519
3601
  else commit(label);
3520
3602
  };
3521
- return /* @__PURE__ */ jsxs32("div", { className: "relative", ref, children: [
3522
- /* @__PURE__ */ jsxs32(
3603
+ return /* @__PURE__ */ jsxs33("div", { className: "relative", ref, children: [
3604
+ /* @__PURE__ */ jsxs33(
3523
3605
  "button",
3524
3606
  {
3525
3607
  type: "button",
@@ -3528,16 +3610,16 @@ function DateRangePicker({
3528
3610
  "aria-haspopup": "listbox",
3529
3611
  className: chipTriggerClass(),
3530
3612
  children: [
3531
- /* @__PURE__ */ jsxs32("span", { className: "flex flex-col gap-1 text-left leading-none", children: [
3532
- /* @__PURE__ */ jsx36("span", { className: "text-control-caption text-text-tertiary", children: spanLabel(value, end) }),
3533
- /* @__PURE__ */ jsx36("span", { className: "text-[12px] font-medium text-text-primary", children: value })
3613
+ /* @__PURE__ */ jsxs33("span", { className: "flex flex-col gap-1 text-left leading-none", children: [
3614
+ /* @__PURE__ */ jsx37("span", { className: "text-control-caption text-text-tertiary", children: spanLabel(value, end) }),
3615
+ /* @__PURE__ */ jsx37("span", { className: "text-[12px] font-medium text-text-primary", children: value })
3534
3616
  ] }),
3535
- /* @__PURE__ */ jsx36(ChevronDown10, { size: 14, "aria-hidden": "true", className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180") })
3617
+ /* @__PURE__ */ jsx37(ChevronDown10, { size: 14, "aria-hidden": "true", className: cn("shrink-0 text-text-secondary transition-transform", open && "rotate-180") })
3536
3618
  ]
3537
3619
  }
3538
3620
  ),
3539
- 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: [
3540
- presets.map((p) => /* @__PURE__ */ jsx36(
3621
+ 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: [
3622
+ presets.map((p) => /* @__PURE__ */ jsx37(
3541
3623
  "button",
3542
3624
  {
3543
3625
  type: "button",
@@ -3547,26 +3629,26 @@ function DateRangePicker({
3547
3629
  },
3548
3630
  p
3549
3631
  )),
3550
- /* @__PURE__ */ jsxs32("div", { className: "mt-1 border-t border-border-default px-3 pb-2 pt-2", children: [
3551
- /* @__PURE__ */ jsx36("div", { className: "text-[13px] font-semibold text-text-primary", children: "Custom Range" }),
3552
- /* @__PURE__ */ jsxs32("div", { className: "mt-2 flex flex-col gap-2", children: [
3553
- /* @__PURE__ */ jsxs32("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3632
+ /* @__PURE__ */ jsxs33("div", { className: "mt-1 border-t border-border-default px-3 pb-2 pt-2", children: [
3633
+ /* @__PURE__ */ jsx37("div", { className: "text-[13px] font-semibold text-text-primary", children: "Custom Range" }),
3634
+ /* @__PURE__ */ jsxs33("div", { className: "mt-2 flex flex-col gap-2", children: [
3635
+ /* @__PURE__ */ jsxs33("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3554
3636
  "From",
3555
- /* @__PURE__ */ jsxs32("span", { className: "flex gap-1", children: [
3556
- granularity === "month" && /* @__PURE__ */ jsx36(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3557
- granularity === "quarter" && /* @__PURE__ */ jsx36(MiniSelect, { value: fromQ, onChange: setFromQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3558
- /* @__PURE__ */ jsx36(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3637
+ /* @__PURE__ */ jsxs33("span", { className: "flex gap-1", children: [
3638
+ granularity === "month" && /* @__PURE__ */ jsx37(MiniSelect, { value: fromMo, onChange: setFromMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3639
+ granularity === "quarter" && /* @__PURE__ */ jsx37(MiniSelect, { value: fromQ, onChange: setFromQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3640
+ /* @__PURE__ */ jsx37(MiniSelect, { value: fromYr, onChange: setFromYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3559
3641
  ] })
3560
3642
  ] }),
3561
- /* @__PURE__ */ jsxs32("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3643
+ /* @__PURE__ */ jsxs33("label", { className: "flex items-center justify-between gap-2 text-[12px] text-text-secondary", children: [
3562
3644
  "To",
3563
- /* @__PURE__ */ jsxs32("span", { className: "flex gap-1", children: [
3564
- granularity === "month" && /* @__PURE__ */ jsx36(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3565
- granularity === "quarter" && /* @__PURE__ */ jsx36(MiniSelect, { value: toQ, onChange: setToQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3566
- /* @__PURE__ */ jsx36(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3645
+ /* @__PURE__ */ jsxs33("span", { className: "flex gap-1", children: [
3646
+ granularity === "month" && /* @__PURE__ */ jsx37(MiniSelect, { value: toMo, onChange: setToMo, options: MONTH_ABBR.map((mm, i) => ({ label: mm, value: i })) }),
3647
+ granularity === "quarter" && /* @__PURE__ */ jsx37(MiniSelect, { value: toQ, onChange: setToQ, options: QUARTER_ABBR.map((qq, i) => ({ label: qq, value: i })) }),
3648
+ /* @__PURE__ */ jsx37(MiniSelect, { value: toYr, onChange: setToYr, options: yearOptions.map((y) => ({ label: String(y), value: y })) })
3567
3649
  ] })
3568
3650
  ] }),
3569
- /* @__PURE__ */ jsx36(
3651
+ /* @__PURE__ */ jsx37(
3570
3652
  "button",
3571
3653
  {
3572
3654
  type: "button",
@@ -3578,15 +3660,15 @@ function DateRangePicker({
3578
3660
  )
3579
3661
  ] })
3580
3662
  ] }),
3581
- showFooter && /* @__PURE__ */ jsx36(FilterDropdownFooter, { onApply: () => commit(draft) })
3663
+ showFooter && /* @__PURE__ */ jsx37(FilterDropdownFooter, { onApply: () => commit(draft) })
3582
3664
  ] })
3583
3665
  ] });
3584
3666
  }
3585
3667
 
3586
3668
  // src/MultiSelectFilter.tsx
3587
- import { useCallback as useCallback4, useEffect as useEffect12, useRef as useRef13, useState as useState13 } from "react";
3588
- import { ChevronDown as ChevronDown11, Check as Check7, Minus as Minus2, Search as Search5, X as X4 } from "lucide-react";
3589
- import { jsx as jsx37, jsxs as jsxs33 } from "react/jsx-runtime";
3669
+ import { useCallback as useCallback4, useEffect as useEffect13, useRef as useRef14, useState as useState14 } from "react";
3670
+ import { ChevronDown as ChevronDown11, Check as Check8, Minus as Minus2, Search as Search5, X as X4 } from "lucide-react";
3671
+ import { jsx as jsx38, jsxs as jsxs34 } from "react/jsx-runtime";
3590
3672
  function MultiSelectFilter({
3591
3673
  caption,
3592
3674
  options = [],
@@ -3610,10 +3692,10 @@ function MultiSelectFilter({
3610
3692
  }) {
3611
3693
  const groupLeaves = (g) => g.children.length ? g.children : [{ id: g.id, label: g.label }];
3612
3694
  const leafOptions = groups ? groups.flatMap(groupLeaves) : options;
3613
- const [open, setOpen] = useState13(false);
3614
- const [q, setQ] = useState13("");
3615
- const [draft, setDraft] = useState13(selected);
3616
- const ref = useRef13(null);
3695
+ const [open, setOpen] = useState14(false);
3696
+ const [q, setQ] = useState14("");
3697
+ const [draft, setDraft] = useState14(selected);
3698
+ const ref = useRef14(null);
3617
3699
  const close = useCallback4(() => {
3618
3700
  setOpen(false);
3619
3701
  setQ("");
@@ -3631,7 +3713,7 @@ function MultiSelectFilter({
3631
3713
  setOpen(false);
3632
3714
  setQ("");
3633
3715
  };
3634
- useEffect12(() => {
3716
+ useEffect13(() => {
3635
3717
  if (!open) return;
3636
3718
  const onKey = (e) => e.key === "Escape" && close();
3637
3719
  const onClick = (e) => {
@@ -3677,8 +3759,8 @@ function MultiSelectFilter({
3677
3759
  const kids = live.filter((c) => c.label.toLowerCase().includes(ql));
3678
3760
  return kids.length ? { ...g, children: kids } : null;
3679
3761
  }).filter((g) => g !== null) : [];
3680
- return /* @__PURE__ */ jsxs33("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
3681
- /* @__PURE__ */ jsxs33(
3762
+ return /* @__PURE__ */ jsxs34("div", { className: cn("relative", fullWidth && "w-full"), ref, children: [
3763
+ /* @__PURE__ */ jsxs34(
3682
3764
  "button",
3683
3765
  {
3684
3766
  type: "button",
@@ -3686,8 +3768,8 @@ function MultiSelectFilter({
3686
3768
  "aria-expanded": open,
3687
3769
  className: cn(chipTriggerClass(variant), fullWidth && "w-full justify-between"),
3688
3770
  children: [
3689
- /* @__PURE__ */ jsx37(ChipContent, { caption, value, icon }),
3690
- /* @__PURE__ */ jsx37(
3771
+ /* @__PURE__ */ jsx38(ChipContent, { caption, value, icon }),
3772
+ /* @__PURE__ */ jsx38(
3691
3773
  ChevronDown11,
3692
3774
  {
3693
3775
  size: 14,
@@ -3698,7 +3780,7 @@ function MultiSelectFilter({
3698
3780
  ]
3699
3781
  }
3700
3782
  ),
3701
- open && /* @__PURE__ */ jsxs33(
3783
+ open && /* @__PURE__ */ jsxs34(
3702
3784
  "div",
3703
3785
  {
3704
3786
  className: cn(
@@ -3709,9 +3791,9 @@ function MultiSelectFilter({
3709
3791
  role: "dialog",
3710
3792
  "aria-label": caption,
3711
3793
  children: [
3712
- 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: [
3713
- /* @__PURE__ */ jsx37(Search5, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
3714
- /* @__PURE__ */ jsx37(
3794
+ searchable && /* @__PURE__ */ jsx38("div", { className: "border-b border-border-default p-2", children: /* @__PURE__ */ jsxs34("div", { className: "flex h-9 items-center gap-2 rounded-control border border-border-strong bg-input px-2.5", children: [
3795
+ /* @__PURE__ */ jsx38(Search5, { size: 14, className: "text-text-secondary", "aria-hidden": "true" }),
3796
+ /* @__PURE__ */ jsx38(
3715
3797
  "input",
3716
3798
  {
3717
3799
  type: "text",
@@ -3721,37 +3803,37 @@ function MultiSelectFilter({
3721
3803
  className: "h-full flex-1 bg-transparent text-[13px] outline-hidden placeholder:text-text-tertiary"
3722
3804
  }
3723
3805
  ),
3724
- 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 }) })
3806
+ q && /* @__PURE__ */ jsx38("button", { type: "button", onClick: () => setQ(""), "aria-label": "Clear search", className: "text-text-tertiary hover:text-text-primary", children: /* @__PURE__ */ jsx38(X4, { size: 13 }) })
3725
3807
  ] }) }),
3726
- /* @__PURE__ */ jsxs33("div", { className: "max-h-[280px] overflow-y-auto p-1", children: [
3808
+ /* @__PURE__ */ jsxs34("div", { className: "max-h-[280px] overflow-y-auto p-1", children: [
3727
3809
  groups ? visibleGroups.map((g) => {
3728
3810
  const state = groupState(g);
3729
- return /* @__PURE__ */ jsxs33("div", { children: [
3730
- /* @__PURE__ */ jsxs33(
3811
+ return /* @__PURE__ */ jsxs34("div", { children: [
3812
+ /* @__PURE__ */ jsxs34(
3731
3813
  "button",
3732
3814
  {
3733
3815
  type: "button",
3734
3816
  onClick: () => toggleGroup(g),
3735
3817
  className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
3736
3818
  children: [
3737
- /* @__PURE__ */ jsx37(TriCheck, { state }),
3738
- /* @__PURE__ */ jsx37("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label }),
3739
- counts && /* @__PURE__ */ jsx37(OptionCount, { n: countFor(g.id) })
3819
+ /* @__PURE__ */ jsx38(TriCheck, { state }),
3820
+ /* @__PURE__ */ jsx38("span", { className: cn("flex-1 text-[14px] text-text-primary", !plainParent && "font-semibold"), children: g.label }),
3821
+ counts && /* @__PURE__ */ jsx38(OptionCount, { n: countFor(g.id) })
3740
3822
  ]
3741
3823
  }
3742
3824
  ),
3743
3825
  g.children.map((c) => {
3744
3826
  const checked = draft.includes(c.id);
3745
- return /* @__PURE__ */ jsxs33(
3827
+ return /* @__PURE__ */ jsxs34(
3746
3828
  "button",
3747
3829
  {
3748
3830
  type: "button",
3749
3831
  onClick: () => toggle(c.id),
3750
3832
  className: "flex w-full items-center gap-2.5 rounded-control py-2 pl-9 pr-2 text-left transition-colors hover:bg-subtle",
3751
3833
  children: [
3752
- /* @__PURE__ */ jsx37(TriCheck, { state: checked ? "all" : "none" }),
3753
- /* @__PURE__ */ jsx37("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label }),
3754
- counts && /* @__PURE__ */ jsx37(OptionCount, { n: countFor(c.id) })
3834
+ /* @__PURE__ */ jsx38(TriCheck, { state: checked ? "all" : "none" }),
3835
+ /* @__PURE__ */ jsx38("span", { className: "flex-1 text-[14px] text-text-primary", children: c.label }),
3836
+ counts && /* @__PURE__ */ jsx38(OptionCount, { n: countFor(c.id) })
3755
3837
  ]
3756
3838
  },
3757
3839
  c.id
@@ -3760,33 +3842,33 @@ function MultiSelectFilter({
3760
3842
  ] }, g.id);
3761
3843
  }) : items.map((o) => {
3762
3844
  const checked = draft.includes(o.id);
3763
- return /* @__PURE__ */ jsxs33(
3845
+ return /* @__PURE__ */ jsxs34(
3764
3846
  "button",
3765
3847
  {
3766
3848
  type: "button",
3767
3849
  onClick: () => toggle(o.id),
3768
3850
  className: "flex w-full items-center gap-2.5 rounded-control px-2 py-2 text-left transition-colors hover:bg-subtle",
3769
3851
  children: [
3770
- /* @__PURE__ */ jsx37(
3852
+ /* @__PURE__ */ jsx38(
3771
3853
  "span",
3772
3854
  {
3773
3855
  className: cn(
3774
3856
  "flex h-[18px] w-[18px] shrink-0 items-center justify-center rounded-[5px] border transition-colors",
3775
3857
  checked ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
3776
3858
  ),
3777
- children: checked && /* @__PURE__ */ jsx37(Check7, { size: 13, strokeWidth: 3 })
3859
+ children: checked && /* @__PURE__ */ jsx38(Check8, { size: 13, strokeWidth: 3 })
3778
3860
  }
3779
3861
  ),
3780
- /* @__PURE__ */ jsx37("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label }),
3781
- counts && /* @__PURE__ */ jsx37(OptionCount, { n: countFor(o.id) })
3862
+ /* @__PURE__ */ jsx38("span", { className: "flex-1 text-[14px] text-text-primary", children: o.label }),
3863
+ counts && /* @__PURE__ */ jsx38(OptionCount, { n: countFor(o.id) })
3782
3864
  ]
3783
3865
  },
3784
3866
  o.id
3785
3867
  );
3786
3868
  }),
3787
- (groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ jsx37("div", { className: "py-6 text-center text-[13px] text-text-tertiary", children: "No matches." })
3869
+ (groups && !visibleGroups.length || !groups && !items.length) && /* @__PURE__ */ jsx38("div", { className: "py-6 text-center text-[13px] text-text-tertiary", children: "No matches." })
3788
3870
  ] }),
3789
- 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(
3871
+ 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(
3790
3872
  "button",
3791
3873
  {
3792
3874
  type: "button",
@@ -3805,7 +3887,7 @@ function MultiSelectFilter({
3805
3887
  }
3806
3888
  function TriCheck({ state }) {
3807
3889
  const filled = state !== "none";
3808
- return /* @__PURE__ */ jsxs33(
3890
+ return /* @__PURE__ */ jsxs34(
3809
3891
  "span",
3810
3892
  {
3811
3893
  className: cn(
@@ -3813,14 +3895,14 @@ function TriCheck({ state }) {
3813
3895
  filled ? "border-transparent bg-brand-primaryAction text-brand-onprimary" : "border-border-interactive bg-input"
3814
3896
  ),
3815
3897
  children: [
3816
- state === "all" && /* @__PURE__ */ jsx37(Check7, { size: 13, strokeWidth: 3 }),
3817
- state === "some" && /* @__PURE__ */ jsx37(Minus2, { size: 13, strokeWidth: 3 })
3898
+ state === "all" && /* @__PURE__ */ jsx38(Check8, { size: 13, strokeWidth: 3 }),
3899
+ state === "some" && /* @__PURE__ */ jsx38(Minus2, { size: 13, strokeWidth: 3 })
3818
3900
  ]
3819
3901
  }
3820
3902
  );
3821
3903
  }
3822
3904
  function OptionCount({ n }) {
3823
- return /* @__PURE__ */ jsxs33("span", { className: "shrink-0 text-[12px] tabular-nums text-text-tertiary", children: [
3905
+ return /* @__PURE__ */ jsxs34("span", { className: "shrink-0 text-[12px] tabular-nums text-text-tertiary", children: [
3824
3906
  "(",
3825
3907
  n.toLocaleString(),
3826
3908
  ")"
@@ -3828,7 +3910,7 @@ function OptionCount({ n }) {
3828
3910
  }
3829
3911
 
3830
3912
  // src/Toggle.tsx
3831
- import { jsx as jsx38 } from "react/jsx-runtime";
3913
+ import { jsx as jsx39 } from "react/jsx-runtime";
3832
3914
  var SIZES2 = {
3833
3915
  sm: { track: "h-5 w-9", knob: "h-4 w-4", on: "translate-x-[18px]" },
3834
3916
  md: { track: "h-6 w-11", knob: "h-5 w-5", on: "translate-x-[22px]" }
@@ -3836,7 +3918,7 @@ var SIZES2 = {
3836
3918
  var OFF_TRACK = "color-mix(in srgb, var(--mr-color-border-interactive) 70%, var(--mr-color-text-secondary))";
3837
3919
  function Toggle({ checked, onChange, label, size = "md", disabled, className, testIdPrefix }) {
3838
3920
  const s = SIZES2[size];
3839
- return /* @__PURE__ */ jsx38(
3921
+ return /* @__PURE__ */ jsx39(
3840
3922
  "button",
3841
3923
  {
3842
3924
  type: "button",
@@ -3854,7 +3936,7 @@ function Toggle({ checked, onChange, label, size = "md", disabled, className, te
3854
3936
  disabled && "cursor-not-allowed opacity-50",
3855
3937
  className
3856
3938
  ),
3857
- children: /* @__PURE__ */ jsx38(
3939
+ children: /* @__PURE__ */ jsx39(
3858
3940
  "span",
3859
3941
  {
3860
3942
  className: cn(
@@ -3871,20 +3953,20 @@ function Toggle({ checked, onChange, label, size = "md", disabled, className, te
3871
3953
  // src/AISpark.tsx
3872
3954
  import { useId as useId5 } from "react";
3873
3955
  import { Sparkles } from "lucide-react";
3874
- import { Fragment as Fragment5, jsx as jsx39, jsxs as jsxs34 } from "react/jsx-runtime";
3956
+ import { Fragment as Fragment5, jsx as jsx40, jsxs as jsxs35 } from "react/jsx-runtime";
3875
3957
  function AISpark({ size = 16, className }) {
3876
3958
  const id = useId5();
3877
- return /* @__PURE__ */ jsxs34(Fragment5, { children: [
3878
- /* @__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: [
3879
- /* @__PURE__ */ jsx39("stop", { offset: "0%", stopColor: "var(--mr-color-brand-primary)" }),
3880
- /* @__PURE__ */ jsx39("stop", { offset: "100%", className: "[stop-color:#9474ff] in-data-[theme=dark]:[stop-color:#a488ff]" })
3959
+ return /* @__PURE__ */ jsxs35(Fragment5, { children: [
3960
+ /* @__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: [
3961
+ /* @__PURE__ */ jsx40("stop", { offset: "0%", stopColor: "var(--mr-color-brand-primary)" }),
3962
+ /* @__PURE__ */ jsx40("stop", { offset: "100%", className: "[stop-color:#9474ff] in-data-[theme=dark]:[stop-color:#a488ff]" })
3881
3963
  ] }) }) }),
3882
- /* @__PURE__ */ jsx39(Sparkles, { size, stroke: `url(#${id})`, className, "aria-hidden": "true" })
3964
+ /* @__PURE__ */ jsx40(Sparkles, { size, stroke: `url(#${id})`, className, "aria-hidden": "true" })
3883
3965
  ] });
3884
3966
  }
3885
3967
 
3886
3968
  // src/Freshness.tsx
3887
- import { jsx as jsx40 } from "react/jsx-runtime";
3969
+ import { jsx as jsx41 } from "react/jsx-runtime";
3888
3970
  var dotColor = {
3889
3971
  fresh: "bg-status-success",
3890
3972
  recent: "bg-status-warning",
@@ -3896,7 +3978,7 @@ var srLabel = {
3896
3978
  stale: "Older than a day"
3897
3979
  };
3898
3980
  function Freshness({ level }) {
3899
- return /* @__PURE__ */ jsx40(
3981
+ return /* @__PURE__ */ jsx41(
3900
3982
  "span",
3901
3983
  {
3902
3984
  className: cn("inline-block h-1.5 w-1.5 shrink-0 rounded-full", dotColor[level]),
@@ -3905,6 +3987,30 @@ function Freshness({ level }) {
3905
3987
  }
3906
3988
  );
3907
3989
  }
3990
+
3991
+ // src/SectionHeading.tsx
3992
+ import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
3993
+ function SectionHeading({ title, description, actions, as: Tag2 = "h2", id, className }) {
3994
+ return /* @__PURE__ */ jsxs36("div", { className: cn("flex flex-wrap items-end justify-between gap-x-4 gap-y-2", className), children: [
3995
+ /* @__PURE__ */ jsxs36("div", { className: "min-w-0", children: [
3996
+ /* @__PURE__ */ jsx42(Tag2, { id, className: "text-base font-semibold text-text-primary", children: title }),
3997
+ description && /* @__PURE__ */ jsx42("p", { className: "mt-0.5 text-dense text-text-secondary", children: description })
3998
+ ] }),
3999
+ actions && /* @__PURE__ */ jsx42("div", { className: "flex shrink-0 items-center gap-2", children: actions })
4000
+ ] });
4001
+ }
4002
+
4003
+ // src/PageHeader.tsx
4004
+ import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
4005
+ function PageHeader({ title, description, actions, className }) {
4006
+ return /* @__PURE__ */ jsxs37("header", { className: cn("flex flex-wrap items-center justify-between gap-x-6 gap-y-3", className), children: [
4007
+ /* @__PURE__ */ jsxs37("div", { className: "min-w-0", children: [
4008
+ /* @__PURE__ */ jsx43("h1", { className: "text-xl font-semibold tracking-tight text-text-primary", children: title }),
4009
+ description && /* @__PURE__ */ jsx43("p", { className: "mt-0.5 max-w-2xl text-sm text-text-secondary", children: description })
4010
+ ] }),
4011
+ actions && /* @__PURE__ */ jsx43("div", { className: "flex shrink-0 items-center gap-2", children: actions })
4012
+ ] });
4013
+ }
3908
4014
  export {
3909
4015
  AISpark,
3910
4016
  AdvertiserNoResults,
@@ -3933,11 +4039,13 @@ export {
3933
4039
  NameListModal,
3934
4040
  NoResultsEmptyState,
3935
4041
  PRIMARY_ACTION_CLASS,
4042
+ PageHeader,
3936
4043
  Pager,
3937
4044
  PieChartPlaceholder,
3938
4045
  PublisherBreakdownList,
3939
4046
  QUIET_ACTION_CLASS,
3940
4047
  SearchBar,
4048
+ SectionHeading,
3941
4049
  SectionRail,
3942
4050
  SelectAllVisible,
3943
4051
  SelectFilter,
@@ -3947,6 +4055,7 @@ export {
3947
4055
  StackedColumnPlaceholder,
3948
4056
  TablePagination,
3949
4057
  Tag,
4058
+ Toast,
3950
4059
  Toggle,
3951
4060
  Tooltip,
3952
4061
  WorkspaceAvatar,