@mediaradar/design-components 0.19.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +526 -140
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +406 -14
- package/dist/index.d.ts +406 -14
- package/dist/index.js +516 -136
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
|
-
import { ReactNode, RefObject, ButtonHTMLAttributes } from 'react';
|
|
2
|
+
import { ReactNode, RefObject, ButtonHTMLAttributes, MouseEventHandler, InputHTMLAttributes } from 'react';
|
|
3
3
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
4
4
|
import { VariantProps } from 'class-variance-authority';
|
|
5
5
|
|
|
@@ -25,6 +25,11 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
25
25
|
* portaled to the end of the page and appears only after a click, so it is
|
|
26
26
|
* aria-hidden rather than described-by.) Escape dismisses it. `label` names
|
|
27
27
|
* the button; the text describes it.
|
|
28
|
+
* @use to explain a metric, a column or a page in a sentence or two, behind
|
|
29
|
+
* the small info glyph.
|
|
30
|
+
* @use `trigger="hover"` when the explanation should also open on keyboard focus.
|
|
31
|
+
* @avoid putting anything needed to finish a task in it -- people miss it.
|
|
32
|
+
* @avoid more than two sentences; longer help belongs on the page.
|
|
28
33
|
* @usage
|
|
29
34
|
* ```tsx
|
|
30
35
|
* <InfoTip text="Trims time periods to data that has finalized across the selected media formats." />
|
|
@@ -315,6 +320,15 @@ declare function Delta({ value, suffix, arrow, period, className }: DeltaProps):
|
|
|
315
320
|
* the control, use CheckBoxBox inside your own <button role="checkbox">
|
|
316
321
|
* instead: a <button> inside a <button> is invalid markup, and a <div
|
|
317
322
|
* onClick> wrapper is not keyboard-reachable at all.
|
|
323
|
+
* @use for choosing any number of items from a list, and in filter panels
|
|
324
|
+
* where picks take effect on Apply.
|
|
325
|
+
* @use indeterminate only on a parent row whose children are partly selected.
|
|
326
|
+
* @avoid wrapping it in a clickable <div> or another <button> -- it is a
|
|
327
|
+
* button itself. When the whole row must be the control, use CheckBoxBox
|
|
328
|
+
* inside your own <button role="checkbox">.
|
|
329
|
+
* @avoid ticking and disabling a row that is already added; drop the box and
|
|
330
|
+
* say "Already added" instead.
|
|
331
|
+
* @avoid it for an on/off setting that takes effect at once -- that's Toggle.
|
|
318
332
|
* @usage
|
|
319
333
|
* ```tsx
|
|
320
334
|
* <CheckBox checked={selected} ariaLabel="Select row" onChange={toggle} />
|
|
@@ -381,6 +395,8 @@ declare function CheckBox({ checked, indeterminate, onChange, ariaLabel, disable
|
|
|
381
395
|
* ancestor owns role="checkbox", aria-checked, the accessible name and the
|
|
382
396
|
* click. Use it exactly when that ancestor is itself the control; use
|
|
383
397
|
* CheckBox when the box is the control.
|
|
398
|
+
* @use only inside a control that is already the button, to draw the box.
|
|
399
|
+
* @avoid it on its own as a checkbox -- it has no behavior; use CheckBox.
|
|
384
400
|
* @usage
|
|
385
401
|
* ```tsx
|
|
386
402
|
* <button type="button" role="checkbox" aria-checked={on} onClick={toggle}>
|
|
@@ -481,7 +497,11 @@ declare function DateRangeFilter({ caption, defaultValue, value: controlledValue
|
|
|
481
497
|
* bordered control, mirroring the legacy Creative Intel search + match-type
|
|
482
498
|
* modal (Any Word/Exact Match/Contextual/Ad Code), including the Or/And
|
|
483
499
|
* sub-choice nested under Any Word.
|
|
484
|
-
*
|
|
500
|
+
* Three heights on the one control scale -- sm 32, md 40, lg 44 (default) --
|
|
501
|
+
* so it lines up with the Buttons and dropdowns beside it. A × clears the
|
|
502
|
+
* text once something is typed.
|
|
503
|
+
* @tokens text-dense, text-badge, focus-within:outline-border-focus, focus-within:outline-2,
|
|
504
|
+
* focus-within:outline-offset-1, rounded-control, border-border-strong, bg-input, text-text-primary,
|
|
485
505
|
* text-text-tertiary, hover:bg-subtle, bg-brand-primaryAction, bg-subtle,
|
|
486
506
|
* bg-surface, border-brand-primaryAction, border-border-default,
|
|
487
507
|
* border-border-interactive, focus-visible:outline-border-focus,
|
|
@@ -498,12 +518,18 @@ declare function DateRangeFilter({ caption, defaultValue, value: controlledValue
|
|
|
498
518
|
* Or/And sub-choice under Any Word and its own click-to-toggle info tooltip.
|
|
499
519
|
* The text input carries an `aria-label` derived from `placeholder` — the
|
|
500
520
|
* wrapping `<label>` has no visible text content (just an icon and the
|
|
501
|
-
* input), so it grants the input no accessible name on its own.
|
|
521
|
+
* input), so it grants the input no accessible name on its own. The clear
|
|
522
|
+
* × shows only when there's text and `onChange` is given; it empties the
|
|
523
|
+
* field and puts focus back in it.
|
|
502
524
|
* @a11y The <input> takes its accessible name from `ariaLabel`. The match-mode
|
|
503
525
|
* popover is a radio group (role="radio" + aria-checked) and its trigger
|
|
504
526
|
* reports aria-expanded. Escape closes the popover only, leaving focus in
|
|
505
527
|
* the field -- a consumer nesting this inside another dismissible layer
|
|
506
528
|
* must sequence the two dismissals itself.
|
|
529
|
+
* @use for every search field: in a filter row (lg), a form (md), a toolbar or
|
|
530
|
+
* dropdown (sm).
|
|
531
|
+
* @use the size of the controls beside it.
|
|
532
|
+
* @avoid a hand-built search input or a borderless one -- one look everywhere.
|
|
507
533
|
* @usage
|
|
508
534
|
* ```tsx
|
|
509
535
|
* <SearchBar value={query} onChange={setQuery} />
|
|
@@ -511,6 +537,8 @@ declare function DateRangeFilter({ caption, defaultValue, value: controlledValue
|
|
|
511
537
|
* ```
|
|
512
538
|
*/
|
|
513
539
|
type SearchBarVariant = "default" | "filterable";
|
|
540
|
+
/** sm 32 in toolbars and dropdowns, md 40 in forms, lg 44 in a filter row. */
|
|
541
|
+
type SearchBarSize = "sm" | "md" | "lg";
|
|
514
542
|
type SearchMatchMode = "anyWord" | "exactMatch" | "contextual" | "adCode";
|
|
515
543
|
interface SearchMatchValue {
|
|
516
544
|
mode: SearchMatchMode;
|
|
@@ -525,6 +553,8 @@ interface SearchBarProps {
|
|
|
525
553
|
onChange?: (v: string) => void;
|
|
526
554
|
/** 'default' is a plain keyword input; 'filterable' adds the match-type dropdown. */
|
|
527
555
|
variant?: SearchBarVariant;
|
|
556
|
+
/** sm 32 in toolbars and dropdowns, md 40 in forms, lg 44 (default) in a filter row -- match the controls beside it. */
|
|
557
|
+
size?: SearchBarSize;
|
|
528
558
|
/** The 'filterable' variant's dropdown state. */
|
|
529
559
|
matchValue?: SearchMatchValue;
|
|
530
560
|
onMatchChange?: (v: SearchMatchValue) => void;
|
|
@@ -541,7 +571,7 @@ interface SearchBarProps {
|
|
|
541
571
|
*/
|
|
542
572
|
testIdPrefix?: string;
|
|
543
573
|
}
|
|
544
|
-
declare function SearchBar({ placeholder, value, onChange, variant, matchValue, onMatchChange, className, testIdPrefix, }: SearchBarProps): react.JSX.Element;
|
|
574
|
+
declare function SearchBar({ placeholder, value, onChange, variant, size, matchValue, onMatchChange, className, testIdPrefix, }: SearchBarProps): react.JSX.Element;
|
|
545
575
|
|
|
546
576
|
/**
|
|
547
577
|
* @pattern SectionRail
|
|
@@ -656,6 +686,11 @@ declare function DataScopeFilter({ value, onChange, align }: DataScopeFilterProp
|
|
|
656
686
|
* the caption. The popover is not a focus trap and does not move focus on
|
|
657
687
|
* open, so keyboard users tab into it; a consumer rendering it inside
|
|
658
688
|
* another dismissible layer has to sequence the two dismissals itself.
|
|
689
|
+
* @use for picking one value from a short list in a filter row or a form --
|
|
690
|
+
* the caption-over-value chip is the one dropdown trigger.
|
|
691
|
+
* @use the caption everywhere except tight spots where the field is obvious.
|
|
692
|
+
* @avoid a native <select> or a hand-built dropdown.
|
|
693
|
+
* @avoid it for several values at once -- that's MultiSelectFilter.
|
|
659
694
|
* @usage
|
|
660
695
|
* ```tsx
|
|
661
696
|
* <SelectFilter caption="Rank" value={rankFilter} onChange={setRankFilter} options={['All', 'VP / Director', 'Manager', 'Coordinator']} />
|
|
@@ -717,6 +752,12 @@ declare function SelectFilter({ caption, value, options, onChange, align, fullWi
|
|
|
717
752
|
* shadow on hover signals it responds to the cursor.
|
|
718
753
|
* @variant static - Set `staticCard`. Non-clickable content -- no hover
|
|
719
754
|
* treatment.
|
|
755
|
+
* @use to group related content on a surface: a stat tile, a chart, a content panel.
|
|
756
|
+
* @use `staticCard` on any card that is only read; the hover lift means the
|
|
757
|
+
* whole card is a link.
|
|
758
|
+
* @avoid setting a width on the card -- the parent grid or row decides it.
|
|
759
|
+
* @avoid a hairline rule between sections of cards; use spacing.
|
|
760
|
+
* @avoid the gradient top edge except on a workflow card that starts a task.
|
|
720
761
|
* @usage
|
|
721
762
|
* ```tsx
|
|
722
763
|
* <Card>
|
|
@@ -1384,7 +1425,7 @@ interface SelectionPickerProps<T extends PickerRow> {
|
|
|
1384
1425
|
* filtered client-side (the default), or externally-computed `results` for a
|
|
1385
1426
|
* caller whose search is server-side/async, with `loading`/`error`/
|
|
1386
1427
|
* `hasMore`/`onLoadMore` covering that mode's states.
|
|
1387
|
-
* @tokens border-border-strong, rounded-control, rounded-card, border-border-default, bg-input,
|
|
1428
|
+
* @tokens border-border-strong, rounded-control, rounded-card, border-border-default, bg-input, focus-within:outline-border-focus,
|
|
1388
1429
|
* bg-canvas, bg-surface, shadow-raised, shadow-overlay, text-text-primary,
|
|
1389
1430
|
* text-text-secondary, text-text-tertiary, text-text-link,
|
|
1390
1431
|
* text-brand-primaryAction, border-brand-primaryAction, bg-brand-primaryAction,
|
|
@@ -1506,7 +1547,7 @@ declare function PublisherBreakdownList({ rows, defaultVisibleCount, padded, vie
|
|
|
1506
1547
|
|
|
1507
1548
|
declare const buttonVariants: (props?: ({
|
|
1508
1549
|
variant?: "link" | "danger" | "primary" | "secondary" | "ghost" | "dangerGhost" | null | undefined;
|
|
1509
|
-
size?: "
|
|
1550
|
+
size?: "sm" | "md" | "lg" | "xs" | null | undefined;
|
|
1510
1551
|
iconOnly?: boolean | null | undefined;
|
|
1511
1552
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
1512
1553
|
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
@@ -1532,8 +1573,9 @@ interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement>, VariantPr
|
|
|
1532
1573
|
* @pattern Button
|
|
1533
1574
|
* @description The one control for every clickable action, from the main call
|
|
1534
1575
|
* to action on a screen down to a quiet toolbar utility. Six variants
|
|
1535
|
-
* (primary, secondary, ghost, danger, dangerGhost, link) across
|
|
1536
|
-
* (xs, sm, md), labelled or icon-only.
|
|
1576
|
+
* (primary, secondary, ghost, danger, dangerGhost, link) across four sizes
|
|
1577
|
+
* (xs 24, sm 32, md 40, lg 44), labelled or icon-only. sm, md and lg are the
|
|
1578
|
+
* one control scale TextField, SearchBar and the filter dropdowns share.
|
|
1537
1579
|
* Supports polymorphic rendering via `asChild` (Radix Slot) to apply button
|
|
1538
1580
|
* styling to a different element, e.g. a router `<Link>`. Also exports the
|
|
1539
1581
|
* raw `buttonVariants` cva function for consumers composing button styling
|
|
@@ -1654,7 +1696,7 @@ interface NameListModalProps {
|
|
|
1654
1696
|
* checkboxes under it. Shared by the Account Lists table and the list detail
|
|
1655
1697
|
* page so create/rename look identical; `fieldLabel`/`placeholder` relabel it
|
|
1656
1698
|
* for dialogs that name something other than a list.
|
|
1657
|
-
* @tokens border-border-strong, bg-scrim, rounded-card, border-border-default, bg-surface, shadow-overlay, text-text-primary, text-text-secondary, rounded-control, bg-input, focus:border-
|
|
1699
|
+
* @tokens border-border-strong, bg-scrim, rounded-card, border-border-default, bg-surface, shadow-overlay, text-text-primary, text-text-secondary, rounded-control, bg-input, focus-visible:outline-border-focus, text-dense, z-modal
|
|
1658
1700
|
* @behavior Escape closes the dialog via `onCancel`, same as clicking the
|
|
1659
1701
|
* scrim backdrop. Submit is disabled until the name is non-empty (trimmed).
|
|
1660
1702
|
* When `options` are given they render as CheckBox rows below the field, and
|
|
@@ -1888,6 +1930,96 @@ interface WorkspaceAvatarProps {
|
|
|
1888
1930
|
*/
|
|
1889
1931
|
declare function WorkspaceAvatar({ name, size }: WorkspaceAvatarProps): react.JSX.Element;
|
|
1890
1932
|
|
|
1933
|
+
type ToastTone = "neutral" | "success" | "warning";
|
|
1934
|
+
interface ToastProps {
|
|
1935
|
+
/** What happened, in a short sentence. Past tense: "12 accounts removed". */
|
|
1936
|
+
message: ReactNode;
|
|
1937
|
+
/**
|
|
1938
|
+
* One follow-up, usually Undo. Giving a toast an action extends how long it
|
|
1939
|
+
* stays, since the reader now has to notice it, read it, decide and reach.
|
|
1940
|
+
*/
|
|
1941
|
+
action?: {
|
|
1942
|
+
label: string;
|
|
1943
|
+
onClick: () => void;
|
|
1944
|
+
};
|
|
1945
|
+
/** Called when the toast has dismissed itself, or the action closed it. */
|
|
1946
|
+
onClose: () => void;
|
|
1947
|
+
/**
|
|
1948
|
+
* Carried by a leading icon, never by the surface. The surface stays the
|
|
1949
|
+
* same on every toast on purpose -- see @behavior.
|
|
1950
|
+
*/
|
|
1951
|
+
tone?: ToastTone;
|
|
1952
|
+
/**
|
|
1953
|
+
* Override the duration. The defaults are 5s, or 10s when there is an
|
|
1954
|
+
* action; both pause while hovered or focused. Set deliberately or not at
|
|
1955
|
+
* all -- a one-off number here is how the product ended up with six.
|
|
1956
|
+
*/
|
|
1957
|
+
duration?: number;
|
|
1958
|
+
className?: string;
|
|
1959
|
+
}
|
|
1960
|
+
/**
|
|
1961
|
+
* @pattern Toast
|
|
1962
|
+
* @description Transient feedback about the page or the task: "12 accounts
|
|
1963
|
+
* removed", "Export started". Floats at the bottom of the window so it never
|
|
1964
|
+
* pushes the page around, dismisses itself, and may carry one action.
|
|
1965
|
+
*
|
|
1966
|
+
* It is one of three shapes of feedback, and the shape is the first decision:
|
|
1967
|
+
* feedback about the control you just used stays ON it (a copy button's icon
|
|
1968
|
+
* becoming a tick); feedback about the page or task floats, which is this;
|
|
1969
|
+
* and feedback you have to act on before continuing stays inline where the
|
|
1970
|
+
* action is, and does not dismiss.
|
|
1971
|
+
* @props
|
|
1972
|
+
* message: ReactNode
|
|
1973
|
+
* action?: { label: string; onClick: () => void }
|
|
1974
|
+
* onClose: () => void
|
|
1975
|
+
* tone?: 'neutral' | 'success' | 'warning' (default 'neutral')
|
|
1976
|
+
* duration?: number -- ms; defaults to 5000, or 10000 with an action
|
|
1977
|
+
* @tokens bg-inverseSurface, text-text-inverse, text-text-inverseSuccess,
|
|
1978
|
+
* text-text-inverseWarning, rounded-control, shadow-overlay,
|
|
1979
|
+
* z-toast, duration-(--mr-motion-duration-interactive), ease-interactive,
|
|
1980
|
+
* focus-visible:outline-border-focus
|
|
1981
|
+
* @dependencies lucide-react
|
|
1982
|
+
* @behavior The surface is the same on every toast. Tone is a leading icon in
|
|
1983
|
+
* green or amber, not a colour wash: a toast already has the reader's attention because it
|
|
1984
|
+
* appeared, so colouring the whole surface adds nothing and makes a failure
|
|
1985
|
+
* read as an alarm. It also keeps one object rather than one per mood -- the
|
|
1986
|
+
* product had a dark pill, a light pill and a green pill doing the same job.
|
|
1987
|
+
*
|
|
1988
|
+
* Timing is tied to whether there is an action, not set per call site. 5s
|
|
1989
|
+
* reads comfortably; 10s is what an Undo needs, because the reader has to
|
|
1990
|
+
* notice the toast, read it, decide and then reach for it. Both pause on
|
|
1991
|
+
* hover and on keyboard focus, which is the real fix for the two toasts that
|
|
1992
|
+
* previously never dismissed at all -- they were held open so an Undo could
|
|
1993
|
+
* be caught, at the cost of a message that never left.
|
|
1994
|
+
* @a11y role="status" with aria-live="polite", so it is announced without
|
|
1995
|
+
* interrupting. The action is a real button inside the live region, reachable
|
|
1996
|
+
* by keyboard; focusing it pauses the timer, so a keyboard user is never
|
|
1997
|
+
* racing the dismissal. The icon is decorative -- the message carries the
|
|
1998
|
+
* meaning, since tone shown only as an icon cannot be the sole signal.
|
|
1999
|
+
* @variant neutral - Something happened. The default, and most toasts.
|
|
2000
|
+
* @variant success - A thing completed that the reader was waiting on.
|
|
2001
|
+
* @variant warning - It completed with something worth knowing. Not for failure -- a failure the reader must act on belongs inline, not in a message that leaves.
|
|
2002
|
+
* @use when reporting something that already happened, that the reader does
|
|
2003
|
+
* not have to act on.
|
|
2004
|
+
* @use with an action when the thing is reversible and reversing it is cheap
|
|
2005
|
+
* -- an Undo on a bulk delete.
|
|
2006
|
+
* @avoid when the reader must act before continuing. A toast leaves; anything
|
|
2007
|
+
* load-bearing belongs inline, next to what it is about.
|
|
2008
|
+
* @avoid when the feedback is about the control just used. A copy button's
|
|
2009
|
+
* tick belongs on the button, where the reader is already looking.
|
|
2010
|
+
* @avoid for errors that lose work. An error that leaves after ten seconds is
|
|
2011
|
+
* an error nobody can act on.
|
|
2012
|
+
* @avoid stacking several at once. Toasts queue; two at the same time means
|
|
2013
|
+
* the second is read and the first is not.
|
|
2014
|
+
* @usage
|
|
2015
|
+
* ```tsx
|
|
2016
|
+
* <Toast message="Export started" onClose={clear} />
|
|
2017
|
+
* <Toast message="12 accounts removed" action={{ label: 'Undo', onClick: undo }} onClose={clear} />
|
|
2018
|
+
* <Toast tone="success" message="Account created" onClose={clear} />
|
|
2019
|
+
* ```
|
|
2020
|
+
*/
|
|
2021
|
+
declare function Toast({ message, action, onClose, tone, duration, className }: ToastProps): react.ReactPortal;
|
|
2022
|
+
|
|
1891
2023
|
interface TagProps {
|
|
1892
2024
|
/** The tag's text, e.g. "Digital". Keep it short: the chip doesn't wrap or truncate. */
|
|
1893
2025
|
children: ReactNode;
|
|
@@ -2013,7 +2145,7 @@ interface MultiSelectGroup {
|
|
|
2013
2145
|
* button shape (two-line caption + value with a chevron) and opens a
|
|
2014
2146
|
* searchable checkbox popover. Used for the page-level Media Type /
|
|
2015
2147
|
* Advertiser filters that share state with the filter tray.
|
|
2016
|
-
* @tokens border-border-strong, 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, text-brand-onprimary
|
|
2148
|
+
* @tokens border-border-strong, 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, text-brand-onprimary, focus-within:outline-border-focus
|
|
2017
2149
|
* @dependencies lucide-react
|
|
2018
2150
|
* @behavior `variant` picks the trigger's chip stroke: `box` (default, the
|
|
2019
2151
|
* boxed two-line chip on the default border) or `inline` (same fill,
|
|
@@ -2244,6 +2376,16 @@ interface PageHeaderProps {
|
|
|
2244
2376
|
description?: ReactNode;
|
|
2245
2377
|
/** The page's main actions, right-aligned -- usually one primary Button. */
|
|
2246
2378
|
actions?: ReactNode;
|
|
2379
|
+
/**
|
|
2380
|
+
* The way back up, above the title: an arrow and the parent section's name,
|
|
2381
|
+
* "Competitive intel". Give `href`; add `onClick` to route client-side
|
|
2382
|
+
* (call `preventDefault()` and navigate).
|
|
2383
|
+
*/
|
|
2384
|
+
back?: {
|
|
2385
|
+
label: ReactNode;
|
|
2386
|
+
href?: string;
|
|
2387
|
+
onClick?: MouseEventHandler<HTMLAnchorElement>;
|
|
2388
|
+
};
|
|
2247
2389
|
className?: string;
|
|
2248
2390
|
}
|
|
2249
2391
|
/**
|
|
@@ -2257,8 +2399,11 @@ interface PageHeaderProps {
|
|
|
2257
2399
|
* title: ReactNode -- the page's name
|
|
2258
2400
|
* description?: ReactNode -- one line, about 70 characters at most, on what the user can do here
|
|
2259
2401
|
* actions?: ReactNode -- primary actions, right-aligned
|
|
2260
|
-
* @tokens text-
|
|
2402
|
+
* @tokens text-micro, uppercase, tracking-wider, text-text-tertiary,
|
|
2403
|
+
* hover:text-text-primary, focus-visible:outline-border-focus, rounded-control, text-xl, font-semibold, tracking-tight, text-text-primary, text-sm, text-text-secondary, max-w-2xl
|
|
2261
2404
|
* @use at the top of every top-level page.
|
|
2405
|
+
* @use `back` on any page one level below a section, naming the section the
|
|
2406
|
+
* arrow goes back to. This is the breadcrumb: no full path.
|
|
2262
2407
|
* @use `description` to say what the page is for, in one sentence a first-time
|
|
2263
2408
|
* user can act on ("Build your own tables from MediaRadar data...").
|
|
2264
2409
|
* @avoid putting the description to the right of the title. It competes with
|
|
@@ -2267,7 +2412,9 @@ interface PageHeaderProps {
|
|
|
2267
2412
|
* @avoid a description on every page by habit. Use one only where a first-time
|
|
2268
2413
|
* user would not know what the page is for; a pipe-separated subtitle beside
|
|
2269
2414
|
* the title is the pattern this replaces.
|
|
2270
|
-
* @
|
|
2415
|
+
* @dependencies lucide-react
|
|
2416
|
+
* @a11y Renders the page's h1. `back` is a real link, read as its label
|
|
2417
|
+
* ("Competitive intel"); the arrow is hidden from screen readers. Use `SectionHeading` (h2) for the sections below it.
|
|
2271
2418
|
* @usage
|
|
2272
2419
|
* ```tsx
|
|
2273
2420
|
* <PageHeader
|
|
@@ -2277,6 +2424,251 @@ interface PageHeaderProps {
|
|
|
2277
2424
|
* />
|
|
2278
2425
|
* ```
|
|
2279
2426
|
*/
|
|
2280
|
-
declare function PageHeader({ title, description, actions, className }: PageHeaderProps): react.JSX.Element;
|
|
2427
|
+
declare function PageHeader({ title, description, actions, back, className }: PageHeaderProps): react.JSX.Element;
|
|
2428
|
+
|
|
2429
|
+
type ModalSize = "sm" | "md" | "lg";
|
|
2430
|
+
interface ModalProps {
|
|
2431
|
+
/** Whether the dialog is showing. */
|
|
2432
|
+
open: boolean;
|
|
2433
|
+
/** Called on Escape, a click on the dimmed background, or the close button. */
|
|
2434
|
+
onClose: () => void;
|
|
2435
|
+
/** The dialog's title -- a short Title Case name, "Export options". */
|
|
2436
|
+
title: ReactNode;
|
|
2437
|
+
/** One line under the title, when the title alone doesn't say enough. */
|
|
2438
|
+
description?: ReactNode;
|
|
2439
|
+
/** sm 440 for a confirm, md 640 for a form, lg 880 for a table or a list. */
|
|
2440
|
+
size?: ModalSize;
|
|
2441
|
+
/** The buttons along the bottom, right-aligned -- primary last. */
|
|
2442
|
+
footer?: ReactNode;
|
|
2443
|
+
children?: ReactNode;
|
|
2444
|
+
className?: string;
|
|
2445
|
+
}
|
|
2446
|
+
/**
|
|
2447
|
+
* @pattern Modal
|
|
2448
|
+
* @description A dialog over a dimmed page: title, optional one-line
|
|
2449
|
+
* description, content, and a footer of buttons. Three widths -- sm 440 for a
|
|
2450
|
+
* confirm, md 640 for a form, lg 880 for a table or a list -- over the warm
|
|
2451
|
+
* scrim, which flips with dark mode.
|
|
2452
|
+
* @variant sm - 440px. A confirm: one question, two buttons.
|
|
2453
|
+
* @variant md - 640px. Default. A form.
|
|
2454
|
+
* @variant lg - 880px. A table, a long list, a preview.
|
|
2455
|
+
* @tokens bg-scrim, z-modal, rounded-card, border-border-default, bg-surface,
|
|
2456
|
+
* shadow-overlay, text-base, font-semibold, text-text-primary, text-sm,
|
|
2457
|
+
* text-text-secondary, text-text-tertiary, hover:bg-subtle,
|
|
2458
|
+
* hover:text-text-primary, rounded-control, border-t,
|
|
2459
|
+
* focus-visible:outline-border-focus
|
|
2460
|
+
* @dependencies lucide-react, react-dom
|
|
2461
|
+
* @behavior Portals to <body>. Escape, a click on the background and the ×
|
|
2462
|
+
* all call `onClose`. Focus moves to the first field (else the first footer
|
|
2463
|
+
* button) on open, Tab stays inside
|
|
2464
|
+
* it, and focus goes back to whatever opened it on close. The page behind
|
|
2465
|
+
* stops scrolling while it's open.
|
|
2466
|
+
* @a11y role="dialog" with aria-modal, named by its title and described by
|
|
2467
|
+
* `description`. The close button is labelled "Close".
|
|
2468
|
+
* @use for a task the user has to finish or cancel before going back to the
|
|
2469
|
+
* page: confirm a delete, name a list, pick export options.
|
|
2470
|
+
* @use `sm` for confirms, `md` for forms, `lg` for tables -- pick by content,
|
|
2471
|
+
* never a custom width.
|
|
2472
|
+
* @use one primary Button, last in `footer`, with a secondary "Cancel" before it.
|
|
2473
|
+
* @avoid a modal for a message that needs no answer -- use Toast.
|
|
2474
|
+
* @avoid a modal opened from another modal.
|
|
2475
|
+
* @avoid a `className` width override; if none of the three fit, raise it as
|
|
2476
|
+
* a design question.
|
|
2477
|
+
* @usage
|
|
2478
|
+
* ```tsx
|
|
2479
|
+
* <Modal
|
|
2480
|
+
* open={open}
|
|
2481
|
+
* onClose={() => setOpen(false)}
|
|
2482
|
+
* size="sm"
|
|
2483
|
+
* title="Delete this list?"
|
|
2484
|
+
* description="The 12 accounts in it stay in your workspace."
|
|
2485
|
+
* footer={<><Button variant="secondary" onClick={close}>Cancel</Button><Button variant="danger">Delete</Button></>}
|
|
2486
|
+
* />
|
|
2487
|
+
* ```
|
|
2488
|
+
*/
|
|
2489
|
+
declare function Modal({ open, onClose, title, description, size, footer, children, className }: ModalProps): react.ReactPortal | null;
|
|
2490
|
+
|
|
2491
|
+
type EmptyStateSize = "sm" | "md";
|
|
2492
|
+
interface EmptyStateProps {
|
|
2493
|
+
/** A lucide icon, about 20px -- `<SearchX size={20} />`. Optional but expected. */
|
|
2494
|
+
icon?: ReactNode;
|
|
2495
|
+
/** What's empty, in plain words -- "No brands match". */
|
|
2496
|
+
title: ReactNode;
|
|
2497
|
+
/** One line on what to do next -- "Try a shorter search or clear a filter." */
|
|
2498
|
+
description?: ReactNode;
|
|
2499
|
+
/** One way out -- a Button, usually `variant="secondary"` or `"link"`. */
|
|
2500
|
+
action?: ReactNode;
|
|
2501
|
+
/** sm inside a table, a card or a dropdown; md when it fills a page or a panel. */
|
|
2502
|
+
size?: EmptyStateSize;
|
|
2503
|
+
className?: string;
|
|
2504
|
+
}
|
|
2505
|
+
/**
|
|
2506
|
+
* @pattern EmptyState
|
|
2507
|
+
* @description What shows where content would be: an icon, a title saying
|
|
2508
|
+
* what's empty, one line on what to do next, and one action. Two sizes -- sm
|
|
2509
|
+
* inside a table, card or dropdown; md when it fills a page or a panel.
|
|
2510
|
+
* @variant sm - Default. Inside a table, a card or a dropdown.
|
|
2511
|
+
* @variant md - Fills a page or a large panel.
|
|
2512
|
+
* @tokens text-text-tertiary, text-text-primary, text-text-secondary,
|
|
2513
|
+
* font-semibold, text-sm, text-base, text-xs, bg-subtle, rounded-full
|
|
2514
|
+
* @use whenever a list, table, search or chart has nothing to show.
|
|
2515
|
+
* @use a title that names what's missing ("No brands match"), and a line that
|
|
2516
|
+
* says how to get some ("Try a shorter search or clear a filter.").
|
|
2517
|
+
* @use one action at most, the one that most likely fixes it.
|
|
2518
|
+
* @avoid "No data" or "Nothing here" -- say what's missing.
|
|
2519
|
+
* @avoid an error message in an empty state; a failed load is an error, not
|
|
2520
|
+
* an empty result.
|
|
2521
|
+
* @usage
|
|
2522
|
+
* ```tsx
|
|
2523
|
+
* <EmptyState
|
|
2524
|
+
* icon={<SearchX size={20} />}
|
|
2525
|
+
* title="No brands match"
|
|
2526
|
+
* description="Try a shorter search or clear a filter."
|
|
2527
|
+
* action={<Button variant="secondary" size="sm" onClick={clear}>Clear filters</Button>}
|
|
2528
|
+
* />
|
|
2529
|
+
* ```
|
|
2530
|
+
*/
|
|
2531
|
+
declare function EmptyState({ icon, title, description, action, size, className }: EmptyStateProps): react.JSX.Element;
|
|
2532
|
+
|
|
2533
|
+
interface TabItem<T extends string = string> {
|
|
2534
|
+
value: T;
|
|
2535
|
+
label: ReactNode;
|
|
2536
|
+
/** A count after the label -- "Contacts 12". */
|
|
2537
|
+
count?: number;
|
|
2538
|
+
disabled?: boolean;
|
|
2539
|
+
}
|
|
2540
|
+
interface TabsProps<T extends string = string> {
|
|
2541
|
+
items: TabItem<T>[];
|
|
2542
|
+
value: T;
|
|
2543
|
+
onChange: (value: T) => void;
|
|
2544
|
+
/** Names the tab list for screen readers -- "Advertiser sections". */
|
|
2545
|
+
"aria-label": string;
|
|
2546
|
+
/**
|
|
2547
|
+
* Prefix for each tab's id and its panel's id. Tab `x` gets
|
|
2548
|
+
* `${idPrefix}-tab-x` and points at `${idPrefix}-panel-x` -- give the panel
|
|
2549
|
+
* that id, role="tabpanel" and aria-labelledby the tab's id.
|
|
2550
|
+
*/
|
|
2551
|
+
idPrefix?: string;
|
|
2552
|
+
className?: string;
|
|
2553
|
+
}
|
|
2554
|
+
/**
|
|
2555
|
+
* @pattern Tabs
|
|
2556
|
+
* @description Underline tabs that switch between the sections of one page --
|
|
2557
|
+
* Overview, Creative, Contacts. The selected tab is semibold with a brand
|
|
2558
|
+
* underline; the row sits on a hairline. For switching how the same data is
|
|
2559
|
+
* shown (Spend / Share, Chart / Table), use SegmentedControl instead.
|
|
2560
|
+
* @tokens border-b, border-border-default, text-sm, text-text-secondary,
|
|
2561
|
+
* hover:text-text-primary, font-semibold, text-text-primary,
|
|
2562
|
+
* border-brand-primaryAction, text-text-tertiary, text-xs,
|
|
2563
|
+
* focus-visible:outline-border-focus, rounded-control
|
|
2564
|
+
* @behavior Controlled: `value` and `onChange`. The arrow keys, Home and End
|
|
2565
|
+
* move between tabs and select as they go; only the selected tab is in the
|
|
2566
|
+
* Tab order.
|
|
2567
|
+
* @a11y role="tablist" with an aria-label, each tab role="tab" with
|
|
2568
|
+
* aria-selected and aria-controls. Give each panel role="tabpanel" and the
|
|
2569
|
+
* ids from `idPrefix`.
|
|
2570
|
+
* @use to switch between sections of one page that hold different content.
|
|
2571
|
+
* @use short nouns for labels, 2 to 6 tabs.
|
|
2572
|
+
* @avoid tabs to switch views of the same data -- that's SegmentedControl.
|
|
2573
|
+
* @avoid tabs as page navigation; going to a different page is a link.
|
|
2574
|
+
* @usage
|
|
2575
|
+
* ```tsx
|
|
2576
|
+
* <Tabs
|
|
2577
|
+
* aria-label="Advertiser sections"
|
|
2578
|
+
* items={[{ value: "overview", label: "Overview" }, { value: "contacts", label: "Contacts", count: 12 }]}
|
|
2579
|
+
* value={tab}
|
|
2580
|
+
* onChange={setTab}
|
|
2581
|
+
* />
|
|
2582
|
+
* ```
|
|
2583
|
+
*/
|
|
2584
|
+
declare function Tabs<T extends string>({ items, value, onChange, idPrefix, className, ...rest }: TabsProps<T>): react.JSX.Element;
|
|
2585
|
+
type SegmentedControlSize = "sm" | "md";
|
|
2586
|
+
interface SegmentedOption<T extends string = string> {
|
|
2587
|
+
value: T;
|
|
2588
|
+
label: ReactNode;
|
|
2589
|
+
}
|
|
2590
|
+
interface SegmentedControlProps<T extends string = string> {
|
|
2591
|
+
options: SegmentedOption<T>[];
|
|
2592
|
+
value: T;
|
|
2593
|
+
onChange: (value: T) => void;
|
|
2594
|
+
/** Names the choice for screen readers -- "Show as". */
|
|
2595
|
+
"aria-label": string;
|
|
2596
|
+
/** sm 32 in toolbars and card headers; md 40 beside md controls. */
|
|
2597
|
+
size?: SegmentedControlSize;
|
|
2598
|
+
className?: string;
|
|
2599
|
+
}
|
|
2600
|
+
/**
|
|
2601
|
+
* @pattern SegmentedControl
|
|
2602
|
+
* @description A pill of 2 to 4 options that switches how the same data is
|
|
2603
|
+
* shown -- Spend / Share, Chart / Table, Weekly / Monthly. The selected option
|
|
2604
|
+
* is a raised white pill. Heights match the control scale: sm 32, md 40. For
|
|
2605
|
+
* switching between sections with different content, use Tabs instead.
|
|
2606
|
+
* @variant sm - 32px. Default. Toolbars and card headers.
|
|
2607
|
+
* @variant md - 40px. Next to md controls in a filter row.
|
|
2608
|
+
* @tokens rounded-full, bg-subtle, text-xs, text-sm, text-text-secondary,
|
|
2609
|
+
* hover:text-text-primary, bg-surface, font-semibold, text-text-primary,
|
|
2610
|
+
* shadow-raised, focus-visible:outline-border-focus
|
|
2611
|
+
* @behavior Controlled: `value` and `onChange`. The arrow keys, Home and End
|
|
2612
|
+
* move and select; only the selected option is in the Tab order.
|
|
2613
|
+
* @a11y role="radiogroup" with an aria-label; each option is role="radio"
|
|
2614
|
+
* with aria-checked.
|
|
2615
|
+
* @use to switch views of the same data: a measure, a chart type, a period.
|
|
2616
|
+
* @use 2 to 4 short options.
|
|
2617
|
+
* @avoid it for sections of a page with different content -- that's Tabs.
|
|
2618
|
+
* @avoid it for a filter that narrows the data -- that's a filter dropdown or chip.
|
|
2619
|
+
* @usage
|
|
2620
|
+
* ```tsx
|
|
2621
|
+
* <SegmentedControl
|
|
2622
|
+
* aria-label="Show as"
|
|
2623
|
+
* options={[{ value: "spend", label: "Spend" }, { value: "share", label: "Share" }]}
|
|
2624
|
+
* value={measure}
|
|
2625
|
+
* onChange={setMeasure}
|
|
2626
|
+
* />
|
|
2627
|
+
* ```
|
|
2628
|
+
*/
|
|
2629
|
+
declare function SegmentedControl<T extends string>({ options, value, onChange, size, className, ...rest }: SegmentedControlProps<T>): react.JSX.Element;
|
|
2630
|
+
|
|
2631
|
+
type TextFieldSize = "sm" | "md" | "lg";
|
|
2632
|
+
interface TextFieldProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "size"> {
|
|
2633
|
+
/** The visible label above the field. Leave it out only when something else on screen names the field, and pass `aria-label`. */
|
|
2634
|
+
label?: ReactNode;
|
|
2635
|
+
/** One line under the field -- a format, a limit. Replaced by `error` when there is one. */
|
|
2636
|
+
hint?: ReactNode;
|
|
2637
|
+
/** What's wrong, in a sentence. Turns the border red and is announced with the field. */
|
|
2638
|
+
error?: ReactNode;
|
|
2639
|
+
/** sm 32 in toolbars and dropdowns, md 40 in forms, lg 44 in a filter row. */
|
|
2640
|
+
size?: TextFieldSize;
|
|
2641
|
+
/** An icon inside the field on the left, about 15px. */
|
|
2642
|
+
icon?: ReactNode;
|
|
2643
|
+
}
|
|
2644
|
+
/**
|
|
2645
|
+
* @pattern TextField
|
|
2646
|
+
* @description A single-line text input with an optional label, hint and
|
|
2647
|
+
* error. Same heights as Button -- sm 32, md 40, lg 44 -- so a field and a
|
|
2648
|
+
* button side by side line up. 13px text, the strong border every control you
|
|
2649
|
+
* type into uses, and the blue focus ring.
|
|
2650
|
+
* @variant sm - 32px. Toolbars, dropdown panels, table cells.
|
|
2651
|
+
* @variant md - 40px. Default. Forms and modals.
|
|
2652
|
+
* @variant lg - 44px. A filter row, next to the filter dropdowns.
|
|
2653
|
+
* @tokens text-xs, font-medium, text-text-secondary, rounded-control, border,
|
|
2654
|
+
* border-border-strong, bg-input, text-dense, text-text-primary,
|
|
2655
|
+
* placeholder:text-text-tertiary, text-text-tertiary, border-status-danger,
|
|
2656
|
+
* text-text-danger, focus-within:outline-2, focus-within:outline-offset-1,
|
|
2657
|
+
* focus-within:outline-border-focus, opacity-50
|
|
2658
|
+
* @behavior Every native input prop passes through to the <input>; the ref
|
|
2659
|
+
* points at it too.
|
|
2660
|
+
* @a11y The label is a real <label> tied to the input. `hint` and `error` are
|
|
2661
|
+
* linked with aria-describedby, and `error` sets aria-invalid.
|
|
2662
|
+
* @use for any free-text entry: a name, an email, a number.
|
|
2663
|
+
* @use the size of the Button next to it.
|
|
2664
|
+
* @avoid it for search -- SearchBar has the icon and the clear ×.
|
|
2665
|
+
* @avoid a placeholder as the only label; it disappears on typing.
|
|
2666
|
+
* @usage
|
|
2667
|
+
* ```tsx
|
|
2668
|
+
* <TextField label="List name" value={name} onChange={(e) => setName(e.target.value)} />
|
|
2669
|
+
* <TextField size="sm" aria-label="Rows per page" />
|
|
2670
|
+
* ```
|
|
2671
|
+
*/
|
|
2672
|
+
declare const TextField: react.ForwardRefExoticComponent<TextFieldProps & react.RefAttributes<HTMLInputElement>>;
|
|
2281
2673
|
|
|
2282
|
-
export { AISpark, type AISparkProps, AdvertiserNoResults, type AdvertiserNoResultsProps, AdvertiserQuickFilter, type AdvertiserQuickFilterProps, AdvertiserSearchPrompt, type AdvertiserSearchPromptProps, Badge, type BadgeKind, type BadgeProps, type BadgeTone, BarChartPlaceholder, type BarChartPlaceholderProps, Button, type ButtonProps, Card, type CardProps, CheckBox, CheckBoxBox, type CheckBoxBoxProps, type CheckBoxProps, ChipContent, type ChipContentProps, type ChipVariant, DEFAULT_SEARCH_MATCH, DataScopeFilter, type DataScopeFilterProps, type DateGranularity, DateRangeFilter, type DateRangeFilterProps, DateRangePicker, type DateRangePickerProps, Delta, type DeltaProps, 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, PageHeader, type PageHeaderProps, 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, SectionHeading, type SectionHeadingProps, 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, ariaSortFor, buttonVariants, chipTriggerClass, cycleSort, noResultsBody, resolveRange, sortProp };
|
|
2674
|
+
export { AISpark, type AISparkProps, AdvertiserNoResults, type AdvertiserNoResultsProps, AdvertiserQuickFilter, type AdvertiserQuickFilterProps, AdvertiserSearchPrompt, type AdvertiserSearchPromptProps, Badge, type BadgeKind, type BadgeProps, type BadgeTone, BarChartPlaceholder, type BarChartPlaceholderProps, Button, type ButtonProps, Card, type CardProps, CheckBox, CheckBoxBox, type CheckBoxBoxProps, type CheckBoxProps, ChipContent, type ChipContentProps, type ChipVariant, DEFAULT_SEARCH_MATCH, DataScopeFilter, type DataScopeFilterProps, type DateGranularity, DateRangeFilter, type DateRangeFilterProps, DateRangePicker, type DateRangePickerProps, Delta, type DeltaProps, EmptyState, type EmptyStateProps, type EmptyStateSize, FilterChipBar, type FilterChipBarProps, FilterDropdownFooter, type FilterDropdownFooterProps, Freshness, type FreshnessLevel, type FreshnessProps, InfoTip, type InfoTipProps, LineChartPlaceholder, type LineChartPlaceholderProps, Modal, type ModalProps, type ModalSize, MultiSelectFilter, type MultiSelectFilterProps, type MultiSelectGroup, NO_RESULTS_BODY, NO_RESULTS_TITLE, NameListModal, type NameListModalProps, type NoResultsAction, NoResultsEmptyState, type NoResultsEmptyStateProps, PRIMARY_ACTION_CLASS, PageHeader, type PageHeaderProps, Pager, type PagerProps, type PickerColumn, type PickerFilter, type PickerRow, PieChartPlaceholder, type PieChartPlaceholderProps, type PubBreak, PublisherBreakdownList, type PublisherBreakdownListProps, QUIET_ACTION_CLASS, SearchBar, type SearchBarProps, type SearchBarSize, type SearchBarVariant, type SearchMatchMode, type SearchMatchValue, SectionHeading, type SectionHeadingProps, SectionRail, type SectionRailProps, SegmentedControl, type SegmentedControlProps, type SegmentedControlSize, type SegmentedOption, 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, type TabItem, TablePagination, type TablePaginationProps, Tabs, type TabsProps, Tag, type TagProps, TextField, type TextFieldProps, type TextFieldSize, Toast, type ToastProps, type ToastTone, Toggle, type ToggleProps, Tooltip, type TooltipProps, WorkspaceAvatar, type WorkspaceAvatarProps, WorkspaceSelectedCard, type WorkspaceSelectedCardProps, ariaSortFor, buttonVariants, chipTriggerClass, cycleSort, noResultsBody, resolveRange, sortProp };
|