@mediaradar/design-components 0.7.0 → 0.8.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.d.cts CHANGED
@@ -1409,7 +1409,7 @@ interface PagerProps {
1409
1409
  */
1410
1410
  declare function Pager({ page, totalPages, onPage }: PagerProps): react.JSX.Element;
1411
1411
 
1412
- declare const SIZES: {
1412
+ declare const SIZES$1: {
1413
1413
  /** Matches a 15px lucide icon exactly, so a workspace name in a menu row
1414
1414
  * left-aligns with labels in icon-led rows above and below it. */
1415
1415
  readonly xs: "h-[15px] w-[15px] rounded-[4px] text-[8px] tracking-tight";
@@ -1420,7 +1420,7 @@ declare const SIZES: {
1420
1420
  interface WorkspaceAvatarProps {
1421
1421
  /** Omit for the unscoped "All data workspace". */
1422
1422
  name?: string;
1423
- size?: keyof typeof SIZES;
1423
+ size?: keyof typeof SIZES$1;
1424
1424
  }
1425
1425
  /**
1426
1426
  * @pattern WorkspaceAvatar
@@ -1437,4 +1437,234 @@ interface WorkspaceAvatarProps {
1437
1437
  */
1438
1438
  declare function WorkspaceAvatar({ name, size }: WorkspaceAvatarProps): react.JSX.Element;
1439
1439
 
1440
- export { AdvertiserNoResults, type AdvertiserNoResultsProps, AdvertiserQuickFilter, type AdvertiserQuickFilterProps, AdvertiserSearchPrompt, type AdvertiserSearchPromptProps, BarChartPlaceholder, type BarChartPlaceholderProps, Button, type ButtonProps, Card, type CardProps, CheckBox, type CheckBoxProps, ChipContent, type ChipContentProps, DEFAULT_SEARCH_MATCH, DataScopeFilter, type DataScopeFilterProps, DateRangeFilter, type DateRangeFilterProps, FilterChipBar, type FilterChipBarProps, FilterDropdownFooter, type FilterDropdownFooterProps, InfoTip, type InfoTipProps, LineChartPlaceholder, type LineChartPlaceholderProps, NO_RESULTS_BODY, NO_RESULTS_TITLE, NameListModal, type NameListModalProps, type NoResultsAction, NoResultsEmptyState, type NoResultsEmptyStateProps, PRIMARY_ACTION_CLASS, Pager, type PagerProps, type PickerColumn, type PickerFilter, type PickerRow, PieChartPlaceholder, type PieChartPlaceholderProps, type PubBreak, PublisherBreakdownList, type PublisherBreakdownListProps, QUIET_ACTION_CLASS, SearchBar, type SearchBarProps, type SearchBarVariant, type SearchMatchMode, type SearchMatchValue, SectionRail, type SectionRailProps, SelectAllVisible, type SelectAllVisibleProps, SelectFilter, type SelectFilterProps, SelectedSection, type SelectedSectionProps, SelectionPicker, type SelectionPickerAccountList, type SelectionPickerProps, SortButton, type SortButtonProps, type SortDir, type SortState, StackedColumnPlaceholder, type StackedColumnPlaceholderProps, type SummaryGroup, type SummaryGroupItemValue, Tooltip, type TooltipProps, WorkspaceAvatar, type WorkspaceAvatarProps, WorkspaceSelectedCard, type WorkspaceSelectedCardProps, buttonVariants, chipTriggerClass, cycleSort, noResultsBody, sortProp };
1440
+ interface TagProps {
1441
+ children: ReactNode;
1442
+ /** Extra classes merged onto the chip. */
1443
+ className?: string;
1444
+ }
1445
+ /**
1446
+ * @pattern Tag
1447
+ * @description Canonical descriptive tag — a neutral beige chip (e.g.
1448
+ * "Digital", a focus area, a category). Use this for every non-semantic
1449
+ * label so tags read the same everywhere. Colored/semantic badges (NEW, ±%
1450
+ * deltas, status, counts) are intentionally NOT this component.
1451
+ * @tokens bg-subtle, text-text-secondary, rounded-full
1452
+ * @usage
1453
+ * ```tsx
1454
+ * <Tag>Digital</Tag>
1455
+ * ```
1456
+ */
1457
+ declare function Tag({ children, className }: TagProps): react.JSX.Element;
1458
+
1459
+ /**
1460
+ * @pattern TablePagination
1461
+ * @description Full table-footer pagination bar: a rows-per-page select, a
1462
+ * first/prev/pages/next/last pager, and the resolved "1 – 25 of N results"
1463
+ * range. Owns no state — the host page holds `page` and `perPage` so the
1464
+ * paged slice and the bar can't disagree.
1465
+ * @tokens rounded-control, border-border-default, bg-input, text-text-primary, text-text-secondary, text-text-tertiary, bg-brand-primaryAction, text-brand-onprimary, hover:bg-subtle, hover:text-text-primary, focus:outline-border-focus
1466
+ * @behavior The current page is filled with the brand action color (matching
1467
+ * the Contacts pager). First/prev disable on page 1, next/last on the last
1468
+ * page — disabled controls stay in the layout so the row never reflows.
1469
+ * Changing the per-page count reports it and leaves the host to reset to page
1470
+ * 1. With one page of results the pager still renders, so the bar's height
1471
+ * and the range readout don't come and go as filters narrow.
1472
+ * @usage
1473
+ * ```tsx
1474
+ * <TablePagination
1475
+ * page={page}
1476
+ * perPage={perPage}
1477
+ * totalItems={matching.length}
1478
+ * onPageChange={setPage}
1479
+ * onPerPageChange={(n) => { setPerPage(n); setPage(1) }}
1480
+ * itemLabel="results"
1481
+ * />
1482
+ * ```
1483
+ */
1484
+ declare function TablePagination({ page, perPage, totalItems, onPageChange, onPerPageChange, perPageOptions, itemLabel, className, }: {
1485
+ page: number;
1486
+ perPage: number;
1487
+ totalItems: number;
1488
+ onPageChange: (page: number) => void;
1489
+ onPerPageChange: (perPage: number) => void;
1490
+ perPageOptions?: number[];
1491
+ itemLabel?: string;
1492
+ className?: string;
1493
+ }): react.JSX.Element;
1494
+ type TablePaginationProps = Parameters<typeof TablePagination>[0];
1495
+
1496
+ /** Resolve a label to its actual [start, end] span, ending at `today`. */
1497
+ declare function resolveRange(label: string, today?: Date): [Date, Date];
1498
+ declare function DateRangePicker({ defaultValue, align, presets, onChange, onRangeChange, showFooter, today, years, }: {
1499
+ defaultValue?: string;
1500
+ align?: 'left' | 'right';
1501
+ /** Rolling presets shown above Custom Range. Defaults to 3/6/12 months. */
1502
+ presets?: string[];
1503
+ onChange?: (label: string) => void;
1504
+ /** Reports the resolved start/end dates — used to drive dependent views (e.g. table columns). */
1505
+ onRangeChange?: (start: Date, end: Date) => void;
1506
+ /** Deferred mode: preset/custom-range picks stage in a draft; only the fixed
1507
+ * Apply footer commits it (no live commit on click). */
1508
+ showFooter?: boolean;
1509
+ /** End of the available data window: rolling presets resolve back from here.
1510
+ * Defaults to the current date. */
1511
+ today?: Date;
1512
+ /** Years offered in the Custom Range selects. Defaults to the last four,
1513
+ * ending with `today`'s year. */
1514
+ years?: number[];
1515
+ }): react.JSX.Element;
1516
+ type DateRangePickerProps = Parameters<typeof DateRangePicker>[0];
1517
+
1518
+ interface MultiSelectGroup {
1519
+ id: string;
1520
+ label: string;
1521
+ children: {
1522
+ id: string;
1523
+ label: string;
1524
+ }[];
1525
+ }
1526
+ /**
1527
+ * @pattern MultiSelectFilter
1528
+ * @description Quick-access multi-select chip — mirrors the DateRangeFilter
1529
+ * button shape (two-line caption + value with a chevron) and opens a
1530
+ * searchable checkbox popover. Used for the page-level Media Type /
1531
+ * Advertiser filters that share state with the filter tray.
1532
+ * @tokens rounded-control, rounded-card, border-border-default, bg-surface, shadow-overlay, text-text-primary, text-text-secondary, text-text-tertiary, text-text-link, border-border-interactive, bg-brand-primaryAction, bg-input, hover:bg-subtle, hover:text-text-primary, placeholder:text-text-tertiary
1533
+ * @dependencies lucide-react
1534
+ * @behavior Same draft/commit-on-close pattern as AdvertiserQuickFilter — the
1535
+ * draft resyncs from `selected` every time the tray opens, and (without
1536
+ * showFooter) any close path commits it, while showFooter mode requires the
1537
+ * Apply button and discards the draft on every other close. `min` enforces a
1538
+ * selection floor by silently ignoring any toggle that would drop below it —
1539
+ * there's no error state, the click just does nothing. Group parents are
1540
+ * tri-state and toggle all of their children in one action.
1541
+ * @usage
1542
+ * ```tsx
1543
+ * <MultiSelectFilter caption="Media" options={mediaOptions} selected={selected} onChange={setSelected} />
1544
+ * ```
1545
+ */
1546
+ declare function MultiSelectFilter({ caption, options, groups, selected, onChange, allLabel, searchable, searchPlaceholder, align, fullIsAll, min, icon, showFooter, clearValue, menuWidthClass, plainParent, fullWidth, }: {
1547
+ caption: string;
1548
+ options?: {
1549
+ id: string;
1550
+ label: string;
1551
+ }[];
1552
+ /** When provided, renders a nested parent → children tree (selection tracks
1553
+ * leaf ids; parents are tri-state and toggle all their children). */
1554
+ groups?: MultiSelectGroup[];
1555
+ selected: string[];
1556
+ onChange: (next: string[]) => void;
1557
+ allLabel?: string;
1558
+ searchable?: boolean;
1559
+ /** Overrides the search box's placeholder. The default derives from the
1560
+ * caption, which reads wrong once a caption is singular ("Search topic"). */
1561
+ searchPlaceholder?: string;
1562
+ align?: 'left' | 'right';
1563
+ /** Treat "all options selected" as the unfiltered "All" state in the label. */
1564
+ fullIsAll?: boolean;
1565
+ /** Minimum selections that must remain (a toggle that would drop below is ignored). */
1566
+ min?: number;
1567
+ icon?: React.ReactNode;
1568
+ /** Deferred mode: checkbox edits stage in a draft; only the fixed Apply/Clear
1569
+ * All footer commits or discards them (no live commit on close). */
1570
+ showFooter?: boolean;
1571
+ /** What "Clear all" resets the draft to — the page's default selection. */
1572
+ clearValue?: string[];
1573
+ /** Tailwind width class for the dropdown panel (default `w-60`). Widen it when
1574
+ * option labels are long and would otherwise wrap. */
1575
+ menuWidthClass?: string;
1576
+ /** Render group parents at normal weight instead of semibold. */
1577
+ plainParent?: boolean;
1578
+ /** Stretch the trigger (and, with `menuWidthClass="w-full"`, the panel) to fill
1579
+ * its container — for stacked/full-width form layouts instead of the chip bar. */
1580
+ fullWidth?: boolean;
1581
+ }): react.JSX.Element;
1582
+ type MultiSelectFilterProps = Parameters<typeof MultiSelectFilter>[0];
1583
+
1584
+ /**
1585
+ * Track, knob and travel per size. The knob leaves a 2px gutter at each end, so
1586
+ * its "on" offset is always track − knob − 2 — keep that relationship if a new
1587
+ * size is added, or the knob will sit off-centre at one end.
1588
+ */
1589
+ declare const SIZES: {
1590
+ readonly sm: {
1591
+ readonly track: "h-5 w-9";
1592
+ readonly knob: "h-4 w-4";
1593
+ readonly on: "translate-x-[18px]";
1594
+ };
1595
+ readonly md: {
1596
+ readonly track: "h-6 w-11";
1597
+ readonly knob: "h-5 w-5";
1598
+ readonly on: "translate-x-[22px]";
1599
+ };
1600
+ };
1601
+ interface ToggleProps {
1602
+ checked: boolean;
1603
+ /** Receives the value being switched TO, not the current one. */
1604
+ onChange: (next: boolean) => void;
1605
+ /** Accessible name; the visible label lives in the row around it. */
1606
+ label: string;
1607
+ size?: keyof typeof SIZES;
1608
+ disabled?: boolean;
1609
+ className?: string;
1610
+ }
1611
+ /**
1612
+ * @pattern Toggle
1613
+ * @description The app's on/off switch. Use it for a setting that takes effect
1614
+ * as a state the user keeps — "only include enriched creatives", "email me a
1615
+ * digest" — where a checkbox would read as an item being ticked off a list.
1616
+ * Rendered as a `<button role="switch">` so the on/off state is announced as a
1617
+ * switch rather than a checkbox, and so the track and knob can carry the brand
1618
+ * fill without fighting a native input's styling hooks.
1619
+ * @tokens bg-brand-primaryAction, bg-border-interactive, bg-surface, shadow-raised, outline-border-focus
1620
+ * @behavior The knob is positioned by `translate-x`, not by flex alignment, so
1621
+ * the slide animates. Off uses `bg-border-interactive` rather than a grey
1622
+ * literal, which keeps the track visible against `bg-surface` in dark mode.
1623
+ * Pair it with a label and any InfoTip in the surrounding row: this component
1624
+ * draws only the switch, so rows stay free to lay the label out however they
1625
+ * need (usually label left, switch pushed right).
1626
+ * @variant md - Settings panels and modals, where the switch is the row's subject.
1627
+ * @variant sm - Dense rows next to 13px body text, where the md track overpowers its own label.
1628
+ * @usage
1629
+ * ```tsx
1630
+ * <Toggle checked={enabled} onChange={setEnabled} label="Email news alerts" />
1631
+ * <Toggle size="sm" checked={enabled} onChange={setEnabled} label="Only include enriched creatives" />
1632
+ * ```
1633
+ */
1634
+ declare function Toggle({ checked, onChange, label, size, disabled, className }: ToggleProps): react.JSX.Element;
1635
+
1636
+ interface AISparkProps {
1637
+ size?: number;
1638
+ className?: string;
1639
+ }
1640
+ /**
1641
+ * @pattern AISpark
1642
+ * @description Assistant glyph — the lucide Sparkles icon stroked with the
1643
+ * MR orange→violet assistant gradient. Each instance scopes its own gradient
1644
+ * id, and the stops follow light/dark mode.
1645
+ * @dependencies lucide-react
1646
+ * @usage
1647
+ * ```tsx
1648
+ * <AISpark size={14} />
1649
+ * ```
1650
+ */
1651
+ declare function AISpark({ size, className }: AISparkProps): react.JSX.Element;
1652
+
1653
+ type FreshnessLevel = "fresh" | "recent" | "stale";
1654
+ interface FreshnessProps {
1655
+ level: FreshnessLevel;
1656
+ }
1657
+ /**
1658
+ * @pattern Freshness
1659
+ * @description Freshness dot — prefixed to card meta rows so a row of 4
1660
+ * timestamps stops reading as a wall of identical text. Color carries the
1661
+ * urgency signal at a glance.
1662
+ * @tokens bg-status-success, bg-status-warning, bg-text-tertiary
1663
+ * @usage
1664
+ * ```tsx
1665
+ * <Freshness level="fresh" />
1666
+ * ```
1667
+ */
1668
+ declare function Freshness({ level }: FreshnessProps): react.JSX.Element;
1669
+
1670
+ export { AISpark, type AISparkProps, AdvertiserNoResults, type AdvertiserNoResultsProps, AdvertiserQuickFilter, type AdvertiserQuickFilterProps, AdvertiserSearchPrompt, type AdvertiserSearchPromptProps, BarChartPlaceholder, type BarChartPlaceholderProps, Button, type ButtonProps, Card, type CardProps, CheckBox, type CheckBoxProps, ChipContent, type ChipContentProps, DEFAULT_SEARCH_MATCH, DataScopeFilter, type DataScopeFilterProps, DateRangeFilter, type DateRangeFilterProps, DateRangePicker, type DateRangePickerProps, FilterChipBar, type FilterChipBarProps, FilterDropdownFooter, type FilterDropdownFooterProps, Freshness, type FreshnessLevel, type FreshnessProps, InfoTip, type InfoTipProps, LineChartPlaceholder, type LineChartPlaceholderProps, MultiSelectFilter, type MultiSelectFilterProps, type MultiSelectGroup, NO_RESULTS_BODY, NO_RESULTS_TITLE, NameListModal, type NameListModalProps, type NoResultsAction, NoResultsEmptyState, type NoResultsEmptyStateProps, PRIMARY_ACTION_CLASS, Pager, type PagerProps, type PickerColumn, type PickerFilter, type PickerRow, PieChartPlaceholder, type PieChartPlaceholderProps, type PubBreak, PublisherBreakdownList, type PublisherBreakdownListProps, QUIET_ACTION_CLASS, SearchBar, type SearchBarProps, type SearchBarVariant, type SearchMatchMode, type SearchMatchValue, SectionRail, type SectionRailProps, SelectAllVisible, type SelectAllVisibleProps, SelectFilter, type SelectFilterProps, SelectedSection, type SelectedSectionProps, SelectionPicker, type SelectionPickerAccountList, type SelectionPickerProps, SortButton, type SortButtonProps, type SortDir, type SortState, StackedColumnPlaceholder, type StackedColumnPlaceholderProps, type SummaryGroup, type SummaryGroupItemValue, TablePagination, type TablePaginationProps, Tag, type TagProps, Toggle, type ToggleProps, Tooltip, type TooltipProps, WorkspaceAvatar, type WorkspaceAvatarProps, WorkspaceSelectedCard, type WorkspaceSelectedCardProps, buttonVariants, chipTriggerClass, cycleSort, noResultsBody, resolveRange, sortProp };
package/dist/index.d.ts CHANGED
@@ -1409,7 +1409,7 @@ interface PagerProps {
1409
1409
  */
1410
1410
  declare function Pager({ page, totalPages, onPage }: PagerProps): react.JSX.Element;
1411
1411
 
1412
- declare const SIZES: {
1412
+ declare const SIZES$1: {
1413
1413
  /** Matches a 15px lucide icon exactly, so a workspace name in a menu row
1414
1414
  * left-aligns with labels in icon-led rows above and below it. */
1415
1415
  readonly xs: "h-[15px] w-[15px] rounded-[4px] text-[8px] tracking-tight";
@@ -1420,7 +1420,7 @@ declare const SIZES: {
1420
1420
  interface WorkspaceAvatarProps {
1421
1421
  /** Omit for the unscoped "All data workspace". */
1422
1422
  name?: string;
1423
- size?: keyof typeof SIZES;
1423
+ size?: keyof typeof SIZES$1;
1424
1424
  }
1425
1425
  /**
1426
1426
  * @pattern WorkspaceAvatar
@@ -1437,4 +1437,234 @@ interface WorkspaceAvatarProps {
1437
1437
  */
1438
1438
  declare function WorkspaceAvatar({ name, size }: WorkspaceAvatarProps): react.JSX.Element;
1439
1439
 
1440
- export { AdvertiserNoResults, type AdvertiserNoResultsProps, AdvertiserQuickFilter, type AdvertiserQuickFilterProps, AdvertiserSearchPrompt, type AdvertiserSearchPromptProps, BarChartPlaceholder, type BarChartPlaceholderProps, Button, type ButtonProps, Card, type CardProps, CheckBox, type CheckBoxProps, ChipContent, type ChipContentProps, DEFAULT_SEARCH_MATCH, DataScopeFilter, type DataScopeFilterProps, DateRangeFilter, type DateRangeFilterProps, FilterChipBar, type FilterChipBarProps, FilterDropdownFooter, type FilterDropdownFooterProps, InfoTip, type InfoTipProps, LineChartPlaceholder, type LineChartPlaceholderProps, NO_RESULTS_BODY, NO_RESULTS_TITLE, NameListModal, type NameListModalProps, type NoResultsAction, NoResultsEmptyState, type NoResultsEmptyStateProps, PRIMARY_ACTION_CLASS, Pager, type PagerProps, type PickerColumn, type PickerFilter, type PickerRow, PieChartPlaceholder, type PieChartPlaceholderProps, type PubBreak, PublisherBreakdownList, type PublisherBreakdownListProps, QUIET_ACTION_CLASS, SearchBar, type SearchBarProps, type SearchBarVariant, type SearchMatchMode, type SearchMatchValue, SectionRail, type SectionRailProps, SelectAllVisible, type SelectAllVisibleProps, SelectFilter, type SelectFilterProps, SelectedSection, type SelectedSectionProps, SelectionPicker, type SelectionPickerAccountList, type SelectionPickerProps, SortButton, type SortButtonProps, type SortDir, type SortState, StackedColumnPlaceholder, type StackedColumnPlaceholderProps, type SummaryGroup, type SummaryGroupItemValue, Tooltip, type TooltipProps, WorkspaceAvatar, type WorkspaceAvatarProps, WorkspaceSelectedCard, type WorkspaceSelectedCardProps, buttonVariants, chipTriggerClass, cycleSort, noResultsBody, sortProp };
1440
+ interface TagProps {
1441
+ children: ReactNode;
1442
+ /** Extra classes merged onto the chip. */
1443
+ className?: string;
1444
+ }
1445
+ /**
1446
+ * @pattern Tag
1447
+ * @description Canonical descriptive tag — a neutral beige chip (e.g.
1448
+ * "Digital", a focus area, a category). Use this for every non-semantic
1449
+ * label so tags read the same everywhere. Colored/semantic badges (NEW, ±%
1450
+ * deltas, status, counts) are intentionally NOT this component.
1451
+ * @tokens bg-subtle, text-text-secondary, rounded-full
1452
+ * @usage
1453
+ * ```tsx
1454
+ * <Tag>Digital</Tag>
1455
+ * ```
1456
+ */
1457
+ declare function Tag({ children, className }: TagProps): react.JSX.Element;
1458
+
1459
+ /**
1460
+ * @pattern TablePagination
1461
+ * @description Full table-footer pagination bar: a rows-per-page select, a
1462
+ * first/prev/pages/next/last pager, and the resolved "1 – 25 of N results"
1463
+ * range. Owns no state — the host page holds `page` and `perPage` so the
1464
+ * paged slice and the bar can't disagree.
1465
+ * @tokens rounded-control, border-border-default, bg-input, text-text-primary, text-text-secondary, text-text-tertiary, bg-brand-primaryAction, text-brand-onprimary, hover:bg-subtle, hover:text-text-primary, focus:outline-border-focus
1466
+ * @behavior The current page is filled with the brand action color (matching
1467
+ * the Contacts pager). First/prev disable on page 1, next/last on the last
1468
+ * page — disabled controls stay in the layout so the row never reflows.
1469
+ * Changing the per-page count reports it and leaves the host to reset to page
1470
+ * 1. With one page of results the pager still renders, so the bar's height
1471
+ * and the range readout don't come and go as filters narrow.
1472
+ * @usage
1473
+ * ```tsx
1474
+ * <TablePagination
1475
+ * page={page}
1476
+ * perPage={perPage}
1477
+ * totalItems={matching.length}
1478
+ * onPageChange={setPage}
1479
+ * onPerPageChange={(n) => { setPerPage(n); setPage(1) }}
1480
+ * itemLabel="results"
1481
+ * />
1482
+ * ```
1483
+ */
1484
+ declare function TablePagination({ page, perPage, totalItems, onPageChange, onPerPageChange, perPageOptions, itemLabel, className, }: {
1485
+ page: number;
1486
+ perPage: number;
1487
+ totalItems: number;
1488
+ onPageChange: (page: number) => void;
1489
+ onPerPageChange: (perPage: number) => void;
1490
+ perPageOptions?: number[];
1491
+ itemLabel?: string;
1492
+ className?: string;
1493
+ }): react.JSX.Element;
1494
+ type TablePaginationProps = Parameters<typeof TablePagination>[0];
1495
+
1496
+ /** Resolve a label to its actual [start, end] span, ending at `today`. */
1497
+ declare function resolveRange(label: string, today?: Date): [Date, Date];
1498
+ declare function DateRangePicker({ defaultValue, align, presets, onChange, onRangeChange, showFooter, today, years, }: {
1499
+ defaultValue?: string;
1500
+ align?: 'left' | 'right';
1501
+ /** Rolling presets shown above Custom Range. Defaults to 3/6/12 months. */
1502
+ presets?: string[];
1503
+ onChange?: (label: string) => void;
1504
+ /** Reports the resolved start/end dates — used to drive dependent views (e.g. table columns). */
1505
+ onRangeChange?: (start: Date, end: Date) => void;
1506
+ /** Deferred mode: preset/custom-range picks stage in a draft; only the fixed
1507
+ * Apply footer commits it (no live commit on click). */
1508
+ showFooter?: boolean;
1509
+ /** End of the available data window: rolling presets resolve back from here.
1510
+ * Defaults to the current date. */
1511
+ today?: Date;
1512
+ /** Years offered in the Custom Range selects. Defaults to the last four,
1513
+ * ending with `today`'s year. */
1514
+ years?: number[];
1515
+ }): react.JSX.Element;
1516
+ type DateRangePickerProps = Parameters<typeof DateRangePicker>[0];
1517
+
1518
+ interface MultiSelectGroup {
1519
+ id: string;
1520
+ label: string;
1521
+ children: {
1522
+ id: string;
1523
+ label: string;
1524
+ }[];
1525
+ }
1526
+ /**
1527
+ * @pattern MultiSelectFilter
1528
+ * @description Quick-access multi-select chip — mirrors the DateRangeFilter
1529
+ * button shape (two-line caption + value with a chevron) and opens a
1530
+ * searchable checkbox popover. Used for the page-level Media Type /
1531
+ * Advertiser filters that share state with the filter tray.
1532
+ * @tokens rounded-control, rounded-card, border-border-default, bg-surface, shadow-overlay, text-text-primary, text-text-secondary, text-text-tertiary, text-text-link, border-border-interactive, bg-brand-primaryAction, bg-input, hover:bg-subtle, hover:text-text-primary, placeholder:text-text-tertiary
1533
+ * @dependencies lucide-react
1534
+ * @behavior Same draft/commit-on-close pattern as AdvertiserQuickFilter — the
1535
+ * draft resyncs from `selected` every time the tray opens, and (without
1536
+ * showFooter) any close path commits it, while showFooter mode requires the
1537
+ * Apply button and discards the draft on every other close. `min` enforces a
1538
+ * selection floor by silently ignoring any toggle that would drop below it —
1539
+ * there's no error state, the click just does nothing. Group parents are
1540
+ * tri-state and toggle all of their children in one action.
1541
+ * @usage
1542
+ * ```tsx
1543
+ * <MultiSelectFilter caption="Media" options={mediaOptions} selected={selected} onChange={setSelected} />
1544
+ * ```
1545
+ */
1546
+ declare function MultiSelectFilter({ caption, options, groups, selected, onChange, allLabel, searchable, searchPlaceholder, align, fullIsAll, min, icon, showFooter, clearValue, menuWidthClass, plainParent, fullWidth, }: {
1547
+ caption: string;
1548
+ options?: {
1549
+ id: string;
1550
+ label: string;
1551
+ }[];
1552
+ /** When provided, renders a nested parent → children tree (selection tracks
1553
+ * leaf ids; parents are tri-state and toggle all their children). */
1554
+ groups?: MultiSelectGroup[];
1555
+ selected: string[];
1556
+ onChange: (next: string[]) => void;
1557
+ allLabel?: string;
1558
+ searchable?: boolean;
1559
+ /** Overrides the search box's placeholder. The default derives from the
1560
+ * caption, which reads wrong once a caption is singular ("Search topic"). */
1561
+ searchPlaceholder?: string;
1562
+ align?: 'left' | 'right';
1563
+ /** Treat "all options selected" as the unfiltered "All" state in the label. */
1564
+ fullIsAll?: boolean;
1565
+ /** Minimum selections that must remain (a toggle that would drop below is ignored). */
1566
+ min?: number;
1567
+ icon?: React.ReactNode;
1568
+ /** Deferred mode: checkbox edits stage in a draft; only the fixed Apply/Clear
1569
+ * All footer commits or discards them (no live commit on close). */
1570
+ showFooter?: boolean;
1571
+ /** What "Clear all" resets the draft to — the page's default selection. */
1572
+ clearValue?: string[];
1573
+ /** Tailwind width class for the dropdown panel (default `w-60`). Widen it when
1574
+ * option labels are long and would otherwise wrap. */
1575
+ menuWidthClass?: string;
1576
+ /** Render group parents at normal weight instead of semibold. */
1577
+ plainParent?: boolean;
1578
+ /** Stretch the trigger (and, with `menuWidthClass="w-full"`, the panel) to fill
1579
+ * its container — for stacked/full-width form layouts instead of the chip bar. */
1580
+ fullWidth?: boolean;
1581
+ }): react.JSX.Element;
1582
+ type MultiSelectFilterProps = Parameters<typeof MultiSelectFilter>[0];
1583
+
1584
+ /**
1585
+ * Track, knob and travel per size. The knob leaves a 2px gutter at each end, so
1586
+ * its "on" offset is always track − knob − 2 — keep that relationship if a new
1587
+ * size is added, or the knob will sit off-centre at one end.
1588
+ */
1589
+ declare const SIZES: {
1590
+ readonly sm: {
1591
+ readonly track: "h-5 w-9";
1592
+ readonly knob: "h-4 w-4";
1593
+ readonly on: "translate-x-[18px]";
1594
+ };
1595
+ readonly md: {
1596
+ readonly track: "h-6 w-11";
1597
+ readonly knob: "h-5 w-5";
1598
+ readonly on: "translate-x-[22px]";
1599
+ };
1600
+ };
1601
+ interface ToggleProps {
1602
+ checked: boolean;
1603
+ /** Receives the value being switched TO, not the current one. */
1604
+ onChange: (next: boolean) => void;
1605
+ /** Accessible name; the visible label lives in the row around it. */
1606
+ label: string;
1607
+ size?: keyof typeof SIZES;
1608
+ disabled?: boolean;
1609
+ className?: string;
1610
+ }
1611
+ /**
1612
+ * @pattern Toggle
1613
+ * @description The app's on/off switch. Use it for a setting that takes effect
1614
+ * as a state the user keeps — "only include enriched creatives", "email me a
1615
+ * digest" — where a checkbox would read as an item being ticked off a list.
1616
+ * Rendered as a `<button role="switch">` so the on/off state is announced as a
1617
+ * switch rather than a checkbox, and so the track and knob can carry the brand
1618
+ * fill without fighting a native input's styling hooks.
1619
+ * @tokens bg-brand-primaryAction, bg-border-interactive, bg-surface, shadow-raised, outline-border-focus
1620
+ * @behavior The knob is positioned by `translate-x`, not by flex alignment, so
1621
+ * the slide animates. Off uses `bg-border-interactive` rather than a grey
1622
+ * literal, which keeps the track visible against `bg-surface` in dark mode.
1623
+ * Pair it with a label and any InfoTip in the surrounding row: this component
1624
+ * draws only the switch, so rows stay free to lay the label out however they
1625
+ * need (usually label left, switch pushed right).
1626
+ * @variant md - Settings panels and modals, where the switch is the row's subject.
1627
+ * @variant sm - Dense rows next to 13px body text, where the md track overpowers its own label.
1628
+ * @usage
1629
+ * ```tsx
1630
+ * <Toggle checked={enabled} onChange={setEnabled} label="Email news alerts" />
1631
+ * <Toggle size="sm" checked={enabled} onChange={setEnabled} label="Only include enriched creatives" />
1632
+ * ```
1633
+ */
1634
+ declare function Toggle({ checked, onChange, label, size, disabled, className }: ToggleProps): react.JSX.Element;
1635
+
1636
+ interface AISparkProps {
1637
+ size?: number;
1638
+ className?: string;
1639
+ }
1640
+ /**
1641
+ * @pattern AISpark
1642
+ * @description Assistant glyph — the lucide Sparkles icon stroked with the
1643
+ * MR orange→violet assistant gradient. Each instance scopes its own gradient
1644
+ * id, and the stops follow light/dark mode.
1645
+ * @dependencies lucide-react
1646
+ * @usage
1647
+ * ```tsx
1648
+ * <AISpark size={14} />
1649
+ * ```
1650
+ */
1651
+ declare function AISpark({ size, className }: AISparkProps): react.JSX.Element;
1652
+
1653
+ type FreshnessLevel = "fresh" | "recent" | "stale";
1654
+ interface FreshnessProps {
1655
+ level: FreshnessLevel;
1656
+ }
1657
+ /**
1658
+ * @pattern Freshness
1659
+ * @description Freshness dot — prefixed to card meta rows so a row of 4
1660
+ * timestamps stops reading as a wall of identical text. Color carries the
1661
+ * urgency signal at a glance.
1662
+ * @tokens bg-status-success, bg-status-warning, bg-text-tertiary
1663
+ * @usage
1664
+ * ```tsx
1665
+ * <Freshness level="fresh" />
1666
+ * ```
1667
+ */
1668
+ declare function Freshness({ level }: FreshnessProps): react.JSX.Element;
1669
+
1670
+ export { AISpark, type AISparkProps, AdvertiserNoResults, type AdvertiserNoResultsProps, AdvertiserQuickFilter, type AdvertiserQuickFilterProps, AdvertiserSearchPrompt, type AdvertiserSearchPromptProps, BarChartPlaceholder, type BarChartPlaceholderProps, Button, type ButtonProps, Card, type CardProps, CheckBox, type CheckBoxProps, ChipContent, type ChipContentProps, DEFAULT_SEARCH_MATCH, DataScopeFilter, type DataScopeFilterProps, DateRangeFilter, type DateRangeFilterProps, DateRangePicker, type DateRangePickerProps, FilterChipBar, type FilterChipBarProps, FilterDropdownFooter, type FilterDropdownFooterProps, Freshness, type FreshnessLevel, type FreshnessProps, InfoTip, type InfoTipProps, LineChartPlaceholder, type LineChartPlaceholderProps, MultiSelectFilter, type MultiSelectFilterProps, type MultiSelectGroup, NO_RESULTS_BODY, NO_RESULTS_TITLE, NameListModal, type NameListModalProps, type NoResultsAction, NoResultsEmptyState, type NoResultsEmptyStateProps, PRIMARY_ACTION_CLASS, Pager, type PagerProps, type PickerColumn, type PickerFilter, type PickerRow, PieChartPlaceholder, type PieChartPlaceholderProps, type PubBreak, PublisherBreakdownList, type PublisherBreakdownListProps, QUIET_ACTION_CLASS, SearchBar, type SearchBarProps, type SearchBarVariant, type SearchMatchMode, type SearchMatchValue, SectionRail, type SectionRailProps, SelectAllVisible, type SelectAllVisibleProps, SelectFilter, type SelectFilterProps, SelectedSection, type SelectedSectionProps, SelectionPicker, type SelectionPickerAccountList, type SelectionPickerProps, SortButton, type SortButtonProps, type SortDir, type SortState, StackedColumnPlaceholder, type StackedColumnPlaceholderProps, type SummaryGroup, type SummaryGroupItemValue, TablePagination, type TablePaginationProps, Tag, type TagProps, Toggle, type ToggleProps, Tooltip, type TooltipProps, WorkspaceAvatar, type WorkspaceAvatarProps, WorkspaceSelectedCard, type WorkspaceSelectedCardProps, buttonVariants, chipTriggerClass, cycleSort, noResultsBody, resolveRange, sortProp };