@mediaradar/design-components 0.18.8 → 0.19.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 +38 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +103 -2
- package/dist/index.d.ts +103 -2
- package/dist/index.js +43 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -424,6 +424,7 @@ declare function CheckBoxBox({ checked, indeterminate, disabled, className }: Ch
|
|
|
424
424
|
* @usage
|
|
425
425
|
* ```tsx
|
|
426
426
|
* <DateRangeFilter caption="Date Range" defaultValue="Rolling 6 months" onChange={setRange} />
|
|
427
|
+
* <DateRangeFilter caption="Dates" showDates shortDates placement="right" />
|
|
427
428
|
* <DateRangeFilter presetSet="creativeIntel" defaultValue="Last 7 days" onChange={setRange} />
|
|
428
429
|
* <DateRangeFilter presetSet="creativeIntel" value={preset} range={[start, end]} onChange={setPreset} onRangeChange={(s, e) => setRange({ start: s, end: e })} />
|
|
429
430
|
* ```
|
|
@@ -449,6 +450,13 @@ interface DateRangeFilterProps {
|
|
|
449
450
|
range?: [Date, Date];
|
|
450
451
|
/** Which edge of the trigger the popup aligns to. */
|
|
451
452
|
align?: "left" | "right";
|
|
453
|
+
/**
|
|
454
|
+
* Where the popup opens. 'below' (default) under the chip; 'above' over it,
|
|
455
|
+
* falling back to below when there is no room at the top of the window;
|
|
456
|
+
* 'right' beside it with bottoms aligned -- for a chip low on the page or
|
|
457
|
+
* in a narrow column, where opening below would push the popup off screen.
|
|
458
|
+
*/
|
|
459
|
+
placement?: "below" | "above" | "right";
|
|
452
460
|
/** Fired on Apply with the chip's new display value. */
|
|
453
461
|
onChange?: (value: string) => void;
|
|
454
462
|
/** Fired on Apply (and once on mount, uncontrolled only) with the resolved start/end dates -- e.g. to drive dependent table columns. */
|
|
@@ -464,7 +472,7 @@ interface DateRangeFilterProps {
|
|
|
464
472
|
/** Prefix for data-testid attributes on the trigger, popover, each preset option, and Cancel/Apply. Omit for no test-id wiring. */
|
|
465
473
|
testIdPrefix?: string;
|
|
466
474
|
}
|
|
467
|
-
declare function DateRangeFilter({ caption, defaultValue, value: controlledValue, range: controlledRange, align, onChange, onRangeChange, showDates, shortDates, icon, presetSet, testIdPrefix, }: DateRangeFilterProps): react.JSX.Element;
|
|
475
|
+
declare function DateRangeFilter({ caption, defaultValue, value: controlledValue, range: controlledRange, align, placement, onChange, onRangeChange, showDates, shortDates, icon, presetSet, testIdPrefix, }: DateRangeFilterProps): react.JSX.Element;
|
|
468
476
|
|
|
469
477
|
/**
|
|
470
478
|
* @pattern SearchBar
|
|
@@ -2178,4 +2186,97 @@ interface FreshnessProps {
|
|
|
2178
2186
|
*/
|
|
2179
2187
|
declare function Freshness({ level }: FreshnessProps): react.JSX.Element;
|
|
2180
2188
|
|
|
2181
|
-
|
|
2189
|
+
interface SectionHeadingProps {
|
|
2190
|
+
/** The section's name, in sentence case -- "Saved reports". */
|
|
2191
|
+
title: ReactNode;
|
|
2192
|
+
/** One line under the title saying what the section is or how it works. */
|
|
2193
|
+
description?: ReactNode;
|
|
2194
|
+
/** Controls that act on the whole section -- a search box, a button. Sit right, aligned to the bottom. */
|
|
2195
|
+
actions?: ReactNode;
|
|
2196
|
+
/** Heading level. Defaults to h2, the level under a page's own h1 title. */
|
|
2197
|
+
as?: "h2" | "h3";
|
|
2198
|
+
/** Id for the heading, so the section can be `aria-labelledby` it. */
|
|
2199
|
+
id?: string;
|
|
2200
|
+
className?: string;
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* @pattern SectionHeading
|
|
2204
|
+
* @description The title of a section within a page -- "Start from a template",
|
|
2205
|
+
* "Saved reports". One size everywhere (16px semibold), so every page's sections
|
|
2206
|
+
* read at the same level under the page title. Optional one-line description
|
|
2207
|
+
* under it, optional actions on the right.
|
|
2208
|
+
* @props
|
|
2209
|
+
* title: ReactNode -- the section's name, sentence case
|
|
2210
|
+
* description?: ReactNode -- one line under the title
|
|
2211
|
+
* actions?: ReactNode -- section-wide controls on the right (search, a button)
|
|
2212
|
+
* as?: 'h2' | 'h3' (default 'h2') -- heading level
|
|
2213
|
+
* id?: string -- for the section's aria-labelledby
|
|
2214
|
+
* @tokens text-base, font-semibold, text-text-primary, text-dense, text-text-secondary
|
|
2215
|
+
* @use for every titled section of a page, below the page title.
|
|
2216
|
+
* @use `description` for the one thing a reader must know before using the
|
|
2217
|
+
* section -- it sits above the content, where a long list cannot push it out
|
|
2218
|
+
* of view.
|
|
2219
|
+
* @avoid for a card's own title, or a field label inside a form. Those are
|
|
2220
|
+
* smaller and belong to the card or the field.
|
|
2221
|
+
* @avoid writing a paragraph into `description`. One line; anything longer is
|
|
2222
|
+
* help text and belongs elsewhere.
|
|
2223
|
+
* @a11y Renders a real heading (h2 by default) so screen-reader users can jump
|
|
2224
|
+
* between sections. Pass `id` and point the section's `aria-labelledby` at it.
|
|
2225
|
+
* @usage
|
|
2226
|
+
* ```tsx
|
|
2227
|
+
* <section aria-labelledby="saved-title">
|
|
2228
|
+
* <SectionHeading
|
|
2229
|
+
* id="saved-title"
|
|
2230
|
+
* title="Saved reports"
|
|
2231
|
+
* description="A saved report is its setup, with no data in it."
|
|
2232
|
+
* actions={<SearchBar placeholder="Search saved reports" value={q} onChange={setQ} />}
|
|
2233
|
+
* />
|
|
2234
|
+
* ...
|
|
2235
|
+
* </section>
|
|
2236
|
+
* ```
|
|
2237
|
+
*/
|
|
2238
|
+
declare function SectionHeading({ title, description, actions, as: Tag, id, className }: SectionHeadingProps): react.JSX.Element;
|
|
2239
|
+
|
|
2240
|
+
interface PageHeaderProps {
|
|
2241
|
+
/** The page's name -- "Report Builder". Title Case for a feature name. */
|
|
2242
|
+
title: ReactNode;
|
|
2243
|
+
/** One line under the title saying what the user can do on this page. */
|
|
2244
|
+
description?: ReactNode;
|
|
2245
|
+
/** The page's main actions, right-aligned -- usually one primary Button. */
|
|
2246
|
+
actions?: ReactNode;
|
|
2247
|
+
className?: string;
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* @pattern PageHeader
|
|
2251
|
+
* @description The top of a page: its title (the page's only h1), an optional
|
|
2252
|
+
* one-line description under it, and the page's main actions on the right.
|
|
2253
|
+
* Title 20px over a 14px description, 2px apart, so the two read as one unit;
|
|
2254
|
+
* the actions centre on the pair. Type steps down evenly from there: page
|
|
2255
|
+
* title 20, SectionHeading 16, body 14.
|
|
2256
|
+
* @props
|
|
2257
|
+
* title: ReactNode -- the page's name
|
|
2258
|
+
* description?: ReactNode -- one line, about 70 characters at most, on what the user can do here
|
|
2259
|
+
* actions?: ReactNode -- primary actions, right-aligned
|
|
2260
|
+
* @tokens text-xl, font-semibold, tracking-tight, text-text-primary, text-sm, text-text-secondary, max-w-2xl
|
|
2261
|
+
* @use at the top of every top-level page.
|
|
2262
|
+
* @use `description` to say what the page is for, in one sentence a first-time
|
|
2263
|
+
* user can act on ("Build your own tables from MediaRadar data...").
|
|
2264
|
+
* @avoid putting the description to the right of the title. It competes with
|
|
2265
|
+
* the actions and wraps unpredictably on narrow screens.
|
|
2266
|
+
* @avoid more than one primary action in `actions`.
|
|
2267
|
+
* @avoid a description on every page by habit. Use one only where a first-time
|
|
2268
|
+
* user would not know what the page is for; a pipe-separated subtitle beside
|
|
2269
|
+
* the title is the pattern this replaces.
|
|
2270
|
+
* @a11y Renders the page's h1. Use `SectionHeading` (h2) for the sections below it.
|
|
2271
|
+
* @usage
|
|
2272
|
+
* ```tsx
|
|
2273
|
+
* <PageHeader
|
|
2274
|
+
* title="Report Builder"
|
|
2275
|
+
* description="Build tables from MediaRadar data and export them whenever you need."
|
|
2276
|
+
* actions={<Button><Plus /> New report</Button>}
|
|
2277
|
+
* />
|
|
2278
|
+
* ```
|
|
2279
|
+
*/
|
|
2280
|
+
declare function PageHeader({ title, description, actions, className }: PageHeaderProps): react.JSX.Element;
|
|
2281
|
+
|
|
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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -424,6 +424,7 @@ declare function CheckBoxBox({ checked, indeterminate, disabled, className }: Ch
|
|
|
424
424
|
* @usage
|
|
425
425
|
* ```tsx
|
|
426
426
|
* <DateRangeFilter caption="Date Range" defaultValue="Rolling 6 months" onChange={setRange} />
|
|
427
|
+
* <DateRangeFilter caption="Dates" showDates shortDates placement="right" />
|
|
427
428
|
* <DateRangeFilter presetSet="creativeIntel" defaultValue="Last 7 days" onChange={setRange} />
|
|
428
429
|
* <DateRangeFilter presetSet="creativeIntel" value={preset} range={[start, end]} onChange={setPreset} onRangeChange={(s, e) => setRange({ start: s, end: e })} />
|
|
429
430
|
* ```
|
|
@@ -449,6 +450,13 @@ interface DateRangeFilterProps {
|
|
|
449
450
|
range?: [Date, Date];
|
|
450
451
|
/** Which edge of the trigger the popup aligns to. */
|
|
451
452
|
align?: "left" | "right";
|
|
453
|
+
/**
|
|
454
|
+
* Where the popup opens. 'below' (default) under the chip; 'above' over it,
|
|
455
|
+
* falling back to below when there is no room at the top of the window;
|
|
456
|
+
* 'right' beside it with bottoms aligned -- for a chip low on the page or
|
|
457
|
+
* in a narrow column, where opening below would push the popup off screen.
|
|
458
|
+
*/
|
|
459
|
+
placement?: "below" | "above" | "right";
|
|
452
460
|
/** Fired on Apply with the chip's new display value. */
|
|
453
461
|
onChange?: (value: string) => void;
|
|
454
462
|
/** Fired on Apply (and once on mount, uncontrolled only) with the resolved start/end dates -- e.g. to drive dependent table columns. */
|
|
@@ -464,7 +472,7 @@ interface DateRangeFilterProps {
|
|
|
464
472
|
/** Prefix for data-testid attributes on the trigger, popover, each preset option, and Cancel/Apply. Omit for no test-id wiring. */
|
|
465
473
|
testIdPrefix?: string;
|
|
466
474
|
}
|
|
467
|
-
declare function DateRangeFilter({ caption, defaultValue, value: controlledValue, range: controlledRange, align, onChange, onRangeChange, showDates, shortDates, icon, presetSet, testIdPrefix, }: DateRangeFilterProps): react.JSX.Element;
|
|
475
|
+
declare function DateRangeFilter({ caption, defaultValue, value: controlledValue, range: controlledRange, align, placement, onChange, onRangeChange, showDates, shortDates, icon, presetSet, testIdPrefix, }: DateRangeFilterProps): react.JSX.Element;
|
|
468
476
|
|
|
469
477
|
/**
|
|
470
478
|
* @pattern SearchBar
|
|
@@ -2178,4 +2186,97 @@ interface FreshnessProps {
|
|
|
2178
2186
|
*/
|
|
2179
2187
|
declare function Freshness({ level }: FreshnessProps): react.JSX.Element;
|
|
2180
2188
|
|
|
2181
|
-
|
|
2189
|
+
interface SectionHeadingProps {
|
|
2190
|
+
/** The section's name, in sentence case -- "Saved reports". */
|
|
2191
|
+
title: ReactNode;
|
|
2192
|
+
/** One line under the title saying what the section is or how it works. */
|
|
2193
|
+
description?: ReactNode;
|
|
2194
|
+
/** Controls that act on the whole section -- a search box, a button. Sit right, aligned to the bottom. */
|
|
2195
|
+
actions?: ReactNode;
|
|
2196
|
+
/** Heading level. Defaults to h2, the level under a page's own h1 title. */
|
|
2197
|
+
as?: "h2" | "h3";
|
|
2198
|
+
/** Id for the heading, so the section can be `aria-labelledby` it. */
|
|
2199
|
+
id?: string;
|
|
2200
|
+
className?: string;
|
|
2201
|
+
}
|
|
2202
|
+
/**
|
|
2203
|
+
* @pattern SectionHeading
|
|
2204
|
+
* @description The title of a section within a page -- "Start from a template",
|
|
2205
|
+
* "Saved reports". One size everywhere (16px semibold), so every page's sections
|
|
2206
|
+
* read at the same level under the page title. Optional one-line description
|
|
2207
|
+
* under it, optional actions on the right.
|
|
2208
|
+
* @props
|
|
2209
|
+
* title: ReactNode -- the section's name, sentence case
|
|
2210
|
+
* description?: ReactNode -- one line under the title
|
|
2211
|
+
* actions?: ReactNode -- section-wide controls on the right (search, a button)
|
|
2212
|
+
* as?: 'h2' | 'h3' (default 'h2') -- heading level
|
|
2213
|
+
* id?: string -- for the section's aria-labelledby
|
|
2214
|
+
* @tokens text-base, font-semibold, text-text-primary, text-dense, text-text-secondary
|
|
2215
|
+
* @use for every titled section of a page, below the page title.
|
|
2216
|
+
* @use `description` for the one thing a reader must know before using the
|
|
2217
|
+
* section -- it sits above the content, where a long list cannot push it out
|
|
2218
|
+
* of view.
|
|
2219
|
+
* @avoid for a card's own title, or a field label inside a form. Those are
|
|
2220
|
+
* smaller and belong to the card or the field.
|
|
2221
|
+
* @avoid writing a paragraph into `description`. One line; anything longer is
|
|
2222
|
+
* help text and belongs elsewhere.
|
|
2223
|
+
* @a11y Renders a real heading (h2 by default) so screen-reader users can jump
|
|
2224
|
+
* between sections. Pass `id` and point the section's `aria-labelledby` at it.
|
|
2225
|
+
* @usage
|
|
2226
|
+
* ```tsx
|
|
2227
|
+
* <section aria-labelledby="saved-title">
|
|
2228
|
+
* <SectionHeading
|
|
2229
|
+
* id="saved-title"
|
|
2230
|
+
* title="Saved reports"
|
|
2231
|
+
* description="A saved report is its setup, with no data in it."
|
|
2232
|
+
* actions={<SearchBar placeholder="Search saved reports" value={q} onChange={setQ} />}
|
|
2233
|
+
* />
|
|
2234
|
+
* ...
|
|
2235
|
+
* </section>
|
|
2236
|
+
* ```
|
|
2237
|
+
*/
|
|
2238
|
+
declare function SectionHeading({ title, description, actions, as: Tag, id, className }: SectionHeadingProps): react.JSX.Element;
|
|
2239
|
+
|
|
2240
|
+
interface PageHeaderProps {
|
|
2241
|
+
/** The page's name -- "Report Builder". Title Case for a feature name. */
|
|
2242
|
+
title: ReactNode;
|
|
2243
|
+
/** One line under the title saying what the user can do on this page. */
|
|
2244
|
+
description?: ReactNode;
|
|
2245
|
+
/** The page's main actions, right-aligned -- usually one primary Button. */
|
|
2246
|
+
actions?: ReactNode;
|
|
2247
|
+
className?: string;
|
|
2248
|
+
}
|
|
2249
|
+
/**
|
|
2250
|
+
* @pattern PageHeader
|
|
2251
|
+
* @description The top of a page: its title (the page's only h1), an optional
|
|
2252
|
+
* one-line description under it, and the page's main actions on the right.
|
|
2253
|
+
* Title 20px over a 14px description, 2px apart, so the two read as one unit;
|
|
2254
|
+
* the actions centre on the pair. Type steps down evenly from there: page
|
|
2255
|
+
* title 20, SectionHeading 16, body 14.
|
|
2256
|
+
* @props
|
|
2257
|
+
* title: ReactNode -- the page's name
|
|
2258
|
+
* description?: ReactNode -- one line, about 70 characters at most, on what the user can do here
|
|
2259
|
+
* actions?: ReactNode -- primary actions, right-aligned
|
|
2260
|
+
* @tokens text-xl, font-semibold, tracking-tight, text-text-primary, text-sm, text-text-secondary, max-w-2xl
|
|
2261
|
+
* @use at the top of every top-level page.
|
|
2262
|
+
* @use `description` to say what the page is for, in one sentence a first-time
|
|
2263
|
+
* user can act on ("Build your own tables from MediaRadar data...").
|
|
2264
|
+
* @avoid putting the description to the right of the title. It competes with
|
|
2265
|
+
* the actions and wraps unpredictably on narrow screens.
|
|
2266
|
+
* @avoid more than one primary action in `actions`.
|
|
2267
|
+
* @avoid a description on every page by habit. Use one only where a first-time
|
|
2268
|
+
* user would not know what the page is for; a pipe-separated subtitle beside
|
|
2269
|
+
* the title is the pattern this replaces.
|
|
2270
|
+
* @a11y Renders the page's h1. Use `SectionHeading` (h2) for the sections below it.
|
|
2271
|
+
* @usage
|
|
2272
|
+
* ```tsx
|
|
2273
|
+
* <PageHeader
|
|
2274
|
+
* title="Report Builder"
|
|
2275
|
+
* description="Build tables from MediaRadar data and export them whenever you need."
|
|
2276
|
+
* actions={<Button><Plus /> New report</Button>}
|
|
2277
|
+
* />
|
|
2278
|
+
* ```
|
|
2279
|
+
*/
|
|
2280
|
+
declare function PageHeader({ title, description, actions, className }: PageHeaderProps): react.JSX.Element;
|
|
2281
|
+
|
|
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 };
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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 });
|
|
@@ -3905,6 +3914,30 @@ function Freshness({ level }) {
|
|
|
3905
3914
|
}
|
|
3906
3915
|
);
|
|
3907
3916
|
}
|
|
3917
|
+
|
|
3918
|
+
// src/SectionHeading.tsx
|
|
3919
|
+
import { jsx as jsx41, jsxs as jsxs35 } from "react/jsx-runtime";
|
|
3920
|
+
function SectionHeading({ title, description, actions, as: Tag2 = "h2", id, className }) {
|
|
3921
|
+
return /* @__PURE__ */ jsxs35("div", { className: cn("flex flex-wrap items-end justify-between gap-x-4 gap-y-2", className), children: [
|
|
3922
|
+
/* @__PURE__ */ jsxs35("div", { className: "min-w-0", children: [
|
|
3923
|
+
/* @__PURE__ */ jsx41(Tag2, { id, className: "text-base font-semibold text-text-primary", children: title }),
|
|
3924
|
+
description && /* @__PURE__ */ jsx41("p", { className: "mt-0.5 text-dense text-text-secondary", children: description })
|
|
3925
|
+
] }),
|
|
3926
|
+
actions && /* @__PURE__ */ jsx41("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
3927
|
+
] });
|
|
3928
|
+
}
|
|
3929
|
+
|
|
3930
|
+
// src/PageHeader.tsx
|
|
3931
|
+
import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
|
|
3932
|
+
function PageHeader({ title, description, actions, className }) {
|
|
3933
|
+
return /* @__PURE__ */ jsxs36("header", { className: cn("flex flex-wrap items-center justify-between gap-x-6 gap-y-3", className), children: [
|
|
3934
|
+
/* @__PURE__ */ jsxs36("div", { className: "min-w-0", children: [
|
|
3935
|
+
/* @__PURE__ */ jsx42("h1", { className: "text-xl font-semibold tracking-tight text-text-primary", children: title }),
|
|
3936
|
+
description && /* @__PURE__ */ jsx42("p", { className: "mt-0.5 max-w-2xl text-sm text-text-secondary", children: description })
|
|
3937
|
+
] }),
|
|
3938
|
+
actions && /* @__PURE__ */ jsx42("div", { className: "flex shrink-0 items-center gap-2", children: actions })
|
|
3939
|
+
] });
|
|
3940
|
+
}
|
|
3908
3941
|
export {
|
|
3909
3942
|
AISpark,
|
|
3910
3943
|
AdvertiserNoResults,
|
|
@@ -3933,11 +3966,13 @@ export {
|
|
|
3933
3966
|
NameListModal,
|
|
3934
3967
|
NoResultsEmptyState,
|
|
3935
3968
|
PRIMARY_ACTION_CLASS,
|
|
3969
|
+
PageHeader,
|
|
3936
3970
|
Pager,
|
|
3937
3971
|
PieChartPlaceholder,
|
|
3938
3972
|
PublisherBreakdownList,
|
|
3939
3973
|
QUIET_ACTION_CLASS,
|
|
3940
3974
|
SearchBar,
|
|
3975
|
+
SectionHeading,
|
|
3941
3976
|
SectionRail,
|
|
3942
3977
|
SelectAllVisible,
|
|
3943
3978
|
SelectFilter,
|