@pantheon-systems/pds-toolkit-react 2.0.0-alpha.75 → 2.0.0-alpha.77

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.
Files changed (40) hide show
  1. package/dist/components/Dropdown/Dropdown.d.ts +67 -2
  2. package/dist/components/RowActionsMenu/RowActionsMenu.d.ts +46 -0
  3. package/dist/components/Table/Table.d.ts +73 -7
  4. package/dist/components/buttons/MenuButton/MenuButton.d.ts +20 -4
  5. package/dist/components/buttons/SelectButton/SelectButton.d.ts +81 -0
  6. package/dist/components/empty-states/VerticalEmptyState/VerticalEmptyState.d.ts +3 -2
  7. package/dist/components/icons/Icon/generated-icon-data.d.ts +16 -2
  8. package/dist/components/notifications/SectionMessage/SectionMessage.d.ts +7 -1
  9. package/dist/components/overlays/BottomSheet/BottomSheet.d.ts +66 -0
  10. package/dist/components/overlays/BulkActionBar/BulkActionBar.d.ts +48 -0
  11. package/dist/components/pagination/PaginationCompact/PaginationCompact.d.ts +7 -2
  12. package/dist/css/component-css/pds-bottom-sheet.css +1 -0
  13. package/dist/css/component-css/pds-bulk-action-bar.css +1 -0
  14. package/dist/css/component-css/pds-dropdown.css +3 -2
  15. package/dist/css/component-css/pds-filter-button.css +1 -1
  16. package/dist/css/component-css/pds-icon-button.css +21 -15
  17. package/dist/css/component-css/pds-index.css +33 -23
  18. package/dist/css/component-css/pds-pagination-compact.css +1 -1
  19. package/dist/css/component-css/pds-row-actions-menu.css +2 -0
  20. package/dist/css/component-css/pds-section-message.css +1 -1
  21. package/dist/css/component-css/pds-select-button.css +1 -0
  22. package/dist/css/component-css/pds-table.css +4 -2
  23. package/dist/css/component-css/pds-user-menu.css +1 -1
  24. package/dist/css/component-css/pds-utility-bar.css +1 -1
  25. package/dist/css/design-tokens/variables.dark.css +1 -18
  26. package/dist/css/design-tokens/variables.light.css +1 -18
  27. package/dist/css/layout-css/pds-sidebar-layout.css +11 -3
  28. package/dist/css/pds-components.css +33 -23
  29. package/dist/css/pds-core.css +1 -1
  30. package/dist/index.css +1 -1
  31. package/dist/index.d.ts +5 -0
  32. package/dist/index.js +2139 -1771
  33. package/dist/index.js.map +1 -1
  34. package/dist/index.source.d.ts +5 -0
  35. package/dist/layouts/SidebarLayout/SidebarLayout.d.ts +22 -3
  36. package/dist/svg/arrowDownWideShort.svg +3 -0
  37. package/dist/svg/arrowUpShortWide.svg +3 -0
  38. package/dist/utilities/auto-grid/AutoGrid.d.ts +48 -0
  39. package/dist/utilities/hooks/useDropdown/useDropdown.d.ts +11 -1
  40. package/package.json +2 -2
@@ -1,5 +1,6 @@
1
- import { ComponentPropsWithoutRef, ReactNode } from 'react';
1
+ import React, { ComponentPropsWithoutRef, ReactNode } from 'react';
2
2
  import { UseDropdownOptions } from '../../utilities/hooks/useDropdown';
3
+ import { MenuButtonProps } from '../buttons/MenuButton/MenuButton';
3
4
  import './dropdown.css';
4
5
  export interface DropdownProps extends UseDropdownOptions {
5
6
  /**
@@ -19,12 +20,19 @@ export interface DropdownProps extends UseDropdownOptions {
19
20
  }
20
21
  /**
21
22
  * Root Dropdown component. Provides dropdown context to sub-components.
23
+ *
24
+ * Wraps the actual implementation in a Floating UI tree boundary: when
25
+ * nested inside another floating panel, it joins that panel's tree so
26
+ * outside-clicks and Escape inside this dropdown resolve to this (innermost)
27
+ * dropdown without wrongly dismissing the parent. When not nested, it
28
+ * provides its own single-node tree — no consumer opt-in needed.
22
29
  */
23
30
  export declare const Dropdown: {
24
- ({ children, className, inline, ...options }: DropdownProps): import("react/jsx-runtime").JSX.Element;
31
+ (props: DropdownProps): import("react/jsx-runtime").JSX.Element;
25
32
  Trigger: ({ children, className, showTriggerIcon, ...props }: DropdownTriggerProps) => import("react/jsx-runtime").JSX.Element;
26
33
  Panel: ({ children, className, ...props }: DropdownPanelProps) => import("react/jsx-runtime").JSX.Element;
27
34
  Item: ({ children, className, closeOnSelect, description, disabled, icon, index, isActive, isCritical, onClick, onKeyDown, trailingIcon, ...props }: DropdownItemProps) => import("react/jsx-runtime").JSX.Element;
35
+ ActionItem: ({ children, className, closeOnSelect, description, disabled, icon, index, isActive, linkContent, menuAriaLabel, menuItems, onClick, onKeyDown, ...props }: DropdownActionItemProps) => import("react/jsx-runtime").JSX.Element;
28
36
  CheckboxItem: ({ checked, children, className, description, disabled, indeterminate, index, onCheckedChange, onClick, onKeyDown, ...props }: DropdownCheckboxItemProps) => import("react/jsx-runtime").JSX.Element;
29
37
  Heading: ({ children, className, ...props }: DropdownHeadingProps) => import("react/jsx-runtime").JSX.Element;
30
38
  Separator: ({ className, ...props }: DropdownSeparatorProps) => import("react/jsx-runtime").JSX.Element;
@@ -99,6 +107,63 @@ export interface DropdownItemProps extends ComponentPropsWithoutRef<'li'> {
99
107
  */
100
108
  trailingIcon?: ReactNode;
101
109
  }
110
+ export interface DropdownActionItemProps extends Omit<ComponentPropsWithoutRef<'li'>, 'onClick'> {
111
+ /**
112
+ * Item content — label text. Rendered inside `linkContent` when provided.
113
+ */
114
+ children?: ReactNode;
115
+ /**
116
+ * Additional class names.
117
+ */
118
+ className?: string;
119
+ /**
120
+ * Close the dropdown when the row is selected (default: true).
121
+ */
122
+ closeOnSelect?: boolean;
123
+ /**
124
+ * Secondary text displayed below the label.
125
+ */
126
+ description?: ReactNode;
127
+ /**
128
+ * Disabled state. Disables row selection only — the trailing kebab menu
129
+ * stays available.
130
+ */
131
+ disabled?: boolean;
132
+ /**
133
+ * Leading content — PDSIcon name, or custom ReactNode (Avatar, etc.).
134
+ */
135
+ icon?: ReactNode;
136
+ /**
137
+ * Index of this item in the list (required for keyboard navigation).
138
+ */
139
+ index: number;
140
+ /**
141
+ * Selected or current state.
142
+ */
143
+ isActive?: boolean;
144
+ /**
145
+ * Link element to navigate to on selection (e.g. `<a href='...'>` or a
146
+ * router `Link`). Takes precedence over `onClick` when both are given —
147
+ * pass whichever matches how selecting this row should behave.
148
+ */
149
+ linkContent?: ReactNode;
150
+ /**
151
+ * Contextual label for the row's kebab menu, e.g. `Actions for ${item.title}`.
152
+ * Supplied per-row by the consumer — required, since a plain "Actions"
153
+ * label isn't distinguishable between rows for screen reader users.
154
+ */
155
+ menuAriaLabel: string;
156
+ /**
157
+ * Menu items for the kebab's menu — passed straight through to the
158
+ * underlying `MenuButton`.
159
+ */
160
+ menuItems: MenuButtonProps['menuItems'];
161
+ /**
162
+ * Callback fired when the row is selected. Ignored when `linkContent` is
163
+ * given — the link's own navigation is the selection behavior.
164
+ */
165
+ onClick?: (event: React.SyntheticEvent<HTMLElement>) => void;
166
+ }
102
167
  export interface DropdownCheckboxItemProps extends Omit<ComponentPropsWithoutRef<'li'>, 'onChange'> {
103
168
  /**
104
169
  * Checked state of the item.
@@ -0,0 +1,46 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import { MenuButton } from '../buttons/MenuButton/MenuButton';
3
+ import './row-actions-menu.css';
4
+ /**
5
+ * Prop types for RowActionsMenu
6
+ */
7
+ export interface RowActionsMenuProps extends ComponentPropsWithoutRef<'div'> {
8
+ /**
9
+ * Arbitrary leading row content.
10
+ */
11
+ children: ReactNode;
12
+ /**
13
+ * Additional class names
14
+ */
15
+ className?: string;
16
+ /**
17
+ * Contextual label for the row's kebab menu, e.g. `Actions for ${item.title}`.
18
+ * Supplied per-row by the consumer — required, since a plain "Actions"
19
+ * label isn't distinguishable between rows for screen reader users.
20
+ */
21
+ menuAriaLabel: string;
22
+ /**
23
+ * Menu items for the kebab's menu — passed straight through to the
24
+ * underlying `MenuButton`. Use `isCritical`/`criticalLabel` on an item
25
+ * for a destructive action (e.g. "Remove").
26
+ */
27
+ menuItems: ComponentPropsWithoutRef<typeof MenuButton>['menuItems'];
28
+ /**
29
+ * Where this row is being used, for the hover/active fill style. `dropdown`
30
+ * (default) is an inset rounded pill, matching a floating menu's own items
31
+ * (e.g. nested inside `Dropdown`). `panel` fills edge-to-edge with square
32
+ * corners, matching a flush list inside a panel/widget (e.g. `WidgetPanel`).
33
+ */
34
+ variant?: 'dropdown' | 'panel';
35
+ }
36
+ /**
37
+ * RowActionsMenu UI component.
38
+ *
39
+ * A generic row primitive: arbitrary leading content plus a trailing kebab
40
+ * button that's visually revealed on hover and keyboard focus, opening a
41
+ * `MenuButton` actions menu. Not specific to any one consumer — meant to be
42
+ * reused anywhere a list needs a per-row actions menu (e.g. bookmarks,
43
+ * recent sites). Safe to nest inside another floating panel (e.g. a
44
+ * `Dropdown`) — see `MenuButton`/`Dropdown`'s Floating UI tree handling.
45
+ */
46
+ export declare const RowActionsMenu: ({ children, className, menuAriaLabel, menuItems, variant, ...props }: RowActionsMenuProps) => import("react/jsx-runtime").JSX.Element;
@@ -3,20 +3,50 @@ import { PaginationCompactProps } from '../pagination/PaginationCompact/Paginati
3
3
  import './table.css';
4
4
  export type SortOrder = 'asc' | 'desc';
5
5
  export type DetailPanelContext = {
6
- /** Whether there is a next row to navigate to. */
6
+ /**
7
+ * 1-based position of the inspected row among `totalCount`. Reflects the
8
+ * sorted (but not paginated) row order — the same set Prev/Next step
9
+ * through, which continues across page boundaries rather than stopping
10
+ * at the current page.
11
+ */
12
+ currentIndex: number;
13
+ /**
14
+ * Whether calling `onNext` would go anywhere. Prev/Next loop — Next from
15
+ * the last row wraps to the first — so this is only false when there's a
16
+ * single row (nowhere to navigate to at all).
17
+ */
7
18
  hasNext: boolean;
8
- /** Whether there is a previous row to navigate to. */
19
+ /**
20
+ * Whether calling `onPrev` would go anywhere. Prev/Next loop — Prev from
21
+ * the first row wraps to the last — so this is only false when there's a
22
+ * single row (nowhere to navigate to at all).
23
+ */
9
24
  hasPrev: boolean;
10
25
  /** Close the detail panel. */
11
26
  onClose: () => void;
12
- /** Navigate to the next row. */
27
+ /** Navigate to the next row, looping from the last back to the first. */
13
28
  onNext: () => void;
14
- /** Navigate to the previous row. */
29
+ /** Navigate to the previous row, looping from the first back to the last. */
15
30
  onPrev: () => void;
16
31
  /** Stable ID of the currently inspected row. */
17
32
  rowId: string;
33
+ /**
34
+ * Total number of rows `currentIndex` counts among — the same sorted,
35
+ * unpaginated set Prev/Next step through.
36
+ */
37
+ totalCount: number;
18
38
  };
19
39
  export interface TableColumn {
40
+ /**
41
+ * When true, this column's cell content is shown on the compact card
42
+ * rendered at mobile widths, in addition to the full detail view. The
43
+ * first card-visible column reads as the card's title; any further ones
44
+ * render as a secondary line. Columns without this flag are omitted from
45
+ * the card front but still appear in the full detail view (the row's
46
+ * `renderDetailPanel` content, or the auto-generated one — see
47
+ * `hasMobileDetailSheet`). Has no effect above the mobile breakpoint.
48
+ */
49
+ cardVisible?: boolean;
20
50
  /** Content to display in the header cell. */
21
51
  header: ReactNode;
22
52
  /** Stable identifier used for rendering cell content from rowData. */
@@ -64,7 +94,9 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
64
94
  detailPanelNav?: boolean;
65
95
  /**
66
96
  * Optional title displayed in the detail panel header, to the left of the
67
- * close button.
97
+ * close button. Also titles the mobile detail sheet — including when it's
98
+ * showing the auto-generated column list (no `renderDetailPanel`
99
+ * provided), a case with no desktop panel of its own to title.
68
100
  */
69
101
  detailPanelTitle?: ReactNode;
70
102
  /**
@@ -92,6 +124,14 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
92
124
  * independently of and below the pagination footer when both are present.
93
125
  */
94
126
  footer?: ReactNode;
127
+ /**
128
+ * Returns the position counter text shown between the Prev/Next buttons
129
+ * in the built-in detail panel/mobile sheet footer. Defaults to
130
+ * `(current, total) => \`${current} of ${total}\``. Override for
131
+ * translation. Has no effect when `renderDetailPanelFooter` is provided —
132
+ * use the context's `currentIndex`/`totalCount` there instead.
133
+ */
134
+ getDetailPanelPositionLabel?: (current: number, total: number) => string;
95
135
  /**
96
136
  * Returns the accessible label for each option in the rows-per-page selector.
97
137
  * Defaults to `(size) => \`Show ${size} rows per page\``.
@@ -134,6 +174,30 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
134
174
  * Override for translation.
135
175
  */
136
176
  getSortLabel?: (columnHeader: string) => string;
177
+ /**
178
+ * When `true`, the table renders as a list of tappable cards at the
179
+ * mobile breakpoint instead of a `<table>`. Defaults to `false` — an
180
+ * existing table keeps its desktop `<table>` layout (horizontally
181
+ * scrollable) at every breakpoint until explicitly opted in, so
182
+ * upgrading the package never silently changes how a table already in
183
+ * use looks or behaves. Opt in per table, tuning `cardVisible` on its
184
+ * columns as you go. When `false` (or unset), none of the
185
+ * mobile-specific behavior applies: `cardVisible` has no effect, and row
186
+ * detail (if any) still uses the desktop side panel, not a sheet.
187
+ */
188
+ hasMobileCards?: boolean;
189
+ /**
190
+ * When `true` (default), tapping a card at the mobile breakpoint opens a
191
+ * bottom sheet with that row's detail — `renderDetailPanel`'s content when
192
+ * provided, or an auto-generated label/value list of every column when
193
+ * not (so data omitted from the compact card, via `cardVisible`, is never
194
+ * completely inaccessible). Set to `false` to suppress the mobile sheet
195
+ * entirely — appropriate for a table with too few columns to make one
196
+ * useful. Has no effect when a row is inspectable only via `onRowInspect`
197
+ * with no `renderDetailPanel` — that case already has nothing to show in
198
+ * a sheet and keeps calling `onRowInspect` directly, matching desktop.
199
+ */
200
+ hasMobileDetailSheet?: boolean;
137
201
  /**
138
202
  * ID of the currently inspected row. When provided, that row receives a
139
203
  * highlighted background. Use the same ID space as `getRowId`. Only
@@ -246,7 +310,9 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
246
310
  /**
247
311
  * When true, renders the table inside a Panel with no padding. Automatically
248
312
  * applies first-column spacing and removes the last row's bottom border so
249
- * it doesn't double up against the footer border.
313
+ * it doesn't double up against the footer border. Has no effect at the
314
+ * mobile breakpoint (see `hasMobileCards`) — cards sit flush against the
315
+ * page background instead of inside a Panel.
250
316
  */
251
317
  panel?: boolean;
252
318
  /**
@@ -297,4 +363,4 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
297
363
  */
298
364
  totalItemCount?: number;
299
365
  }
300
- export declare const Table: ({ className, closeDetailPanelLabel, columns, currentPage, defaultSortKey, defaultSortOrder, detailPanelNav, detailPanelTitle, detailPanelWidth, emptyState, emptyStateHeading, emptyStateMessage, footer, getPageSizeLabel, getRowClassName, getRowId, getRowSelectDisabledReason, getSelectRowLabel, getSortLabel, inspectedRowId, isLoading, isRowSelectable, itemsPerPage, loadingRowCount, maxHeight, minHeight, nextDetailPanelRowLabel, onDetailPanelNext, onDetailPanelPrev, onPageChange, onPageSizeChange, onRowInspect, onRowSelectionChange, onSort, pageSizeOptions, pageSizeSelectLabel, paginationLabels, panel, prevDetailPanelRowLabel, renderDetailPanel, renderDetailPanelFooter, rowData, selectAllLabel, selectedRows, sortKey, sortOrder, totalItemCount, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
366
+ export declare const Table: ({ className, closeDetailPanelLabel, columns, currentPage, defaultSortKey, defaultSortOrder, detailPanelNav, detailPanelTitle, detailPanelWidth, emptyState, emptyStateHeading, emptyStateMessage, footer, getDetailPanelPositionLabel, getPageSizeLabel, getRowClassName, getRowId, getRowSelectDisabledReason, getSelectRowLabel, getSortLabel, hasMobileCards, hasMobileDetailSheet, inspectedRowId, isLoading, isRowSelectable, itemsPerPage, loadingRowCount, maxHeight, minHeight, nextDetailPanelRowLabel, onDetailPanelNext, onDetailPanelPrev, onPageChange, onPageSizeChange, onRowInspect, onRowSelectionChange, onSort, pageSizeOptions, pageSizeSelectLabel, paginationLabels, panel, prevDetailPanelRowLabel, renderDetailPanel, renderDetailPanelFooter, rowData, selectAllLabel, selectedRows, sortKey, sortOrder, totalItemCount, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
@@ -57,6 +57,14 @@ export interface MenuButtonProps extends ComponentPropsWithRef<'span'> {
57
57
  * Optional callback function for when the button is clicked or activated by the keyboard.
58
58
  */
59
59
  onClick?: () => void;
60
+ /**
61
+ * Optional callback fired whenever the menu's open state changes. Use
62
+ * this to manage focus deliberately when this MenuButton is nested
63
+ * inside another floating panel — e.g. return focus to the row that
64
+ * owns this menu when it closes, rather than leaving it to Floating UI's
65
+ * default (which can otherwise leave focus on an ancestor panel).
66
+ */
67
+ onOpenChange?: (isOpen: boolean) => void;
60
68
  /**
61
69
  * Which size of button to render.
62
70
  */
@@ -84,12 +92,20 @@ export interface MenuButtonProps extends ComponentPropsWithRef<'span'> {
84
92
  * Which variant of button to render. Not available in `iconOnly` mode.
85
93
  * `navbar` is visually identical to `subtle` except it has no background
86
94
  * at rest — only on hover/expanded — for triggers that sit directly on a
87
- * nav/toolbar surface rather than a plain page background.
95
+ * nav/toolbar surface rather than a plain page background. `reverse-secondary`
96
+ * is for triggers on a dark/reverse surface — passed straight through to
97
+ * the underlying `Button`, which already supports it.
88
98
  */
89
- variant?: Extract<ButtonVariant, 'primary' | 'secondary' | 'subtle'> | 'navbar';
99
+ variant?: Extract<ButtonVariant, 'primary' | 'secondary' | 'subtle' | 'reverse-secondary'> | 'navbar';
90
100
  }
91
101
  /**
92
- * MenuButton UI component
102
+ * MenuButton UI component.
103
+ *
104
+ * Wraps the actual implementation in a Floating UI tree boundary: when
105
+ * nested inside another floating panel (e.g. a `Dropdown`'s panel), it joins
106
+ * that panel's tree so outside-clicks and Escape inside this menu resolve to
107
+ * this (innermost) menu without wrongly dismissing the parent. When not
108
+ * nested, it provides its own single-node tree — no consumer opt-in needed.
93
109
  */
94
- export declare const MenuButton: ({ className, disabled, iconName, iconOnly, id, isMobileAccordion, isSplitButton, label, menuItems, onClick, size, statusDot, tally, testId, undefinedLabel, variant, ...props }: MenuButtonProps) => import("react/jsx-runtime").JSX.Element;
110
+ export declare const MenuButton: (props: MenuButtonProps) => import("react/jsx-runtime").JSX.Element;
95
111
  export {};
@@ -0,0 +1,81 @@
1
+ import './select-button.css';
2
+ /**
3
+ * A single option the SelectButton can choose between.
4
+ */
5
+ export interface SelectButtonOption {
6
+ /**
7
+ * Whether this option is disabled.
8
+ */
9
+ disabled?: boolean;
10
+ /**
11
+ * Visible label for the option.
12
+ */
13
+ label: string;
14
+ /**
15
+ * Unique value used for selection.
16
+ */
17
+ value: string;
18
+ }
19
+ /**
20
+ * Prop types for SelectButton
21
+ */
22
+ export interface SelectButtonProps {
23
+ /**
24
+ * Additional class names.
25
+ */
26
+ className?: string;
27
+ /**
28
+ * Disable the entire control.
29
+ */
30
+ disabled?: boolean;
31
+ /**
32
+ * id applied to the trigger button.
33
+ */
34
+ id?: string;
35
+ /**
36
+ * The dimension name shown in the trigger (e.g. "Sort").
37
+ */
38
+ keyLabel: string;
39
+ /**
40
+ * Show the in-menu search input once the number of options reaches this
41
+ * threshold. Defaults to `8`. Set to `0` to always show it.
42
+ */
43
+ minFilterItems?: number;
44
+ /**
45
+ * Text shown when the search finds no matching options.
46
+ */
47
+ noResultsText?: string;
48
+ /**
49
+ * Called with the next value whenever the selection changes.
50
+ */
51
+ onChange: (value: string) => void;
52
+ /**
53
+ * Options the user can choose between.
54
+ */
55
+ options: SelectButtonOption[];
56
+ /**
57
+ * Accessible label for the search input.
58
+ */
59
+ searchLabel?: string;
60
+ /**
61
+ * Placeholder for the search input.
62
+ */
63
+ searchPlaceholder?: string;
64
+ /**
65
+ * The currently selected value (controlled). Exactly one option is always
66
+ * selected — there is no "cleared" state.
67
+ */
68
+ value: string;
69
+ }
70
+ /**
71
+ * SelectButton — a trigger + menu for choosing exactly one value out of a
72
+ * small fixed set, for controls where a value is always active (e.g. sort
73
+ * field, group-by, time range, page size). Composes the same `Dropdown` +
74
+ * radio-item-with-checkmark pattern as `FilterButton`, but without
75
+ * `FilterButton`'s optional/clearable semantics — there is no empty state and
76
+ * no clear affordance, because unlike a filter, this kind of control can
77
+ * never have "nothing" selected.
78
+ *
79
+ * Selection is controlled: pass `value` and handle `onChange`.
80
+ */
81
+ export declare const SelectButton: ({ className, disabled, id, keyLabel, minFilterItems, noResultsText, onChange, options, searchLabel, searchPlaceholder, value, }: SelectButtonProps) => import("react/jsx-runtime").JSX.Element;
@@ -24,10 +24,11 @@ export interface VerticalEmptyStateProps extends ComponentPropsWithoutRef<'div'>
24
24
  headingLevel?: HeadingLevel;
25
25
  /**
26
26
  * PDS illustration image to display above the heading.
27
- * Should be a link to an SVG file, either from Brandfolder or local.
27
+ * Can be a string (a link to an SVG file, either from Brandfolder or
28
+ * local) or a React node (e.g. a Spinner, for in-progress empty states).
28
29
  * See full documentation for details.
29
30
  */
30
- image?: string;
31
+ image?: string | ReactNode;
31
32
  /**
32
33
  * Height of the image (CSS value like '200px', '50%', etc.)
33
34
  */
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * Generated by: npm run generate:icon-data
5
5
  * Source: icon-registry.ts + Font Awesome packages + custom-icons.tsx
6
- * Generated: 2026-08-25T01:31:01.546Z
6
+ * Generated: 2026-08-27T19:48:12.899Z
7
7
  */
8
8
  import { customIcons } from './custom-icons';
9
9
  export { customIcons };
@@ -71,6 +71,13 @@ export declare const iconData: {
71
71
  readonly svgPathData: "M360 512c13.3 0 24-10.7 24-24s-10.7-24-24-24L24 464c-13.3 0-24 10.7-24 24s10.7 24 24 24l336 0zM175 377c9.4 9.4 24.6 9.4 33.9 0L345 241c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-95 95 0-278.1c0-13.3-10.7-24-24-24s-24 10.7-24 24l0 278.1-95-95c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9L175 377z";
72
72
  readonly width: 384;
73
73
  };
74
+ readonly arrowDownWideShort: {
75
+ readonly aliases: readonly ["sort descending", "sort z to a"];
76
+ readonly categories: readonly ["arrows", "data"];
77
+ readonly height: 512;
78
+ readonly svgPathData: "M249 369L145 473c-9.4 9.4-24.6 9.4-33.9 0L7 369c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l63 63 0-342.1c0-13.3 10.7-24 24-24s24 10.7 24 24l0 342.1 63-63c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9zm63 111c-13.3 0-24-10.7-24-24s10.7-24 24-24l48 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-48 0zm0-128c-13.3 0-24-10.7-24-24s10.7-24 24-24l112 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-112 0zm0-128c-13.3 0-24-10.7-24-24s10.7-24 24-24l176 0c13.3 0 24 10.7 24 24s-10.7 24-24 24l-176 0zm0-128c-13.3 0-24-10.7-24-24s10.7-24 24-24l240 0c13.3 0 24 10.7 24 24s-10.7 24-24 24L312 96z";
79
+ readonly width: 576;
80
+ };
74
81
  readonly arrowLeft: {
75
82
  readonly aliases: readonly ["back", "previous"];
76
83
  readonly categories: readonly ["arrows", "navigation"];
@@ -92,6 +99,13 @@ export declare const iconData: {
92
99
  readonly svgPathData: "M463 473c9.4 9.4 24.6 9.4 33.9 0l72-72c9.4-9.4 9.4-24.6 0-33.9s-24.6-9.4-33.9 0l-31 31 0-270.1c0-53-43-96-96-96L280 32c-13.3 0-24 10.7-24 24s10.7 24 24 24l128 0c26.5 0 48 21.5 48 48l0 270.1-31-31c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l72 72zM113 39c-9.4-9.4-24.6-9.4-33.9 0L7 111c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l31-31 0 270.1c0 53 43 96 96 96l128 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-128 0c-26.5 0-48-21.5-48-48l0-270.1 31 31c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L113 39z";
93
100
  readonly width: 576;
94
101
  };
102
+ readonly arrowUpShortWide: {
103
+ readonly aliases: readonly ["sort ascending", "sort a to z"];
104
+ readonly categories: readonly ["arrows", "data"];
105
+ readonly height: 512;
106
+ readonly svgPathData: "M145 39c-9.4-9.4-24.6-9.4-33.9 0L7 143c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l63-63 0 342.1c0 13.3 10.7 24 24 24s24-10.7 24-24l0-342.1 63 63c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L145 39zm167 9c-13.3 0-24 10.7-24 24s10.7 24 24 24l48 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-48 0zm0 128c-13.3 0-24 10.7-24 24s10.7 24 24 24l112 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-112 0zm0 128c-13.3 0-24 10.7-24 24s10.7 24 24 24l176 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-176 0zm0 128c-13.3 0-24 10.7-24 24s10.7 24 24 24l240 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-240 0z";
107
+ readonly width: 576;
108
+ };
95
109
  readonly asterisk: {
96
110
  readonly aliases: readonly ["required", "star"];
97
111
  readonly categories: readonly ["objects"];
@@ -1619,7 +1633,7 @@ export declare const iconData: {
1619
1633
  readonly width: 576;
1620
1634
  };
1621
1635
  };
1622
- export declare const iconList: readonly ["angleDown", "angleLeft", "angleRight", "anglesDown", "anglesLeft", "anglesRight", "anglesUp", "angleUp", "arrowDownToLine", "arrowLeft", "arrowRight", "arrowsRetweet", "asterisk", "banBug", "bars", "barsFilter", "barsStaggered", "bell", "billboard", "bitbucket", "bluesky", "bolt", "boltPantheon", "boltSolid", "book", "bookmark", "bookmarkSolid", "books", "box", "bracketRight", "bracketsSquare", "brainCircuit", "broomWide", "building", "buildings", "bullhorn", "calendarDays", "caretDown", "caretLeft", "caretRight", "caretUp", "ccAmex", "ccApplePay", "ccDiscover", "ccGeneric", "ccMC", "ccPaypal", "ccVisa", "chartLine", "chartNetwork", "chartSimple", "check", "circle", "circleCheck", "circleExclamation", "circleExclamationSolid", "circleHalfStroke", "circleInfo", "circleInfoSolid", "circleMinus", "circleNotch", "circlePlus", "circleQuestion", "circleQuestionSolid", "circleUser", "circleXmark", "claude", "clock", "cloud", "cloudArrowDown", "cloudArrowUp", "cloudPlus", "code", "codeBranch", "codeMerge", "collapseToCenter", "command", "comment", "compress", "copy", "desktop", "diagramVenn", "diamondExclamation", "diamonds4", "discourse", "display", "dollarSign", "download", "drupal", "ellipsis", "ellipsisVertical", "emptySet", "envelope", "envelopeOpen", "exclamation", "expand", "expandFromCenter", "externalLink", "eye", "eyeSlash", "facebook", "file", "fileCheck", "fileContract", "fileCSV", "fileDiff", "fileExport", "fileImport", "fileLines", "filePDF", "fileZip", "floppyDisk", "folder", "folderTree", "gear", "gem", "github", "gitlab", "globe", "graduationCap", "grid", "grid2", "gripDots", "gripDotsVertical", "heart", "heartSolid", "house", "idCard", "image", "inputText", "instagram", "keySkeleton", "landmark", "laptop", "laptopCode", "leaf", "lifeRing", "link", "linkedin", "listCheck", "locationCrosshairs", "lock", "lockOpen", "magnifyingGlass", "medal", "memo", "messages", "minus", "moon", "move", "nextJs", "octagonExclamation", "openai", "paperclip", "paperPlane", "pause", "pen", "penField", "penPaintbrush", "phone", "play", "plus", "question", "quotesLeft", "quotesRight", "rectangleList", "reply", "robot", "rocketLaunch", "rotate", "rotateClock", "rotateLeft", "rotateRight", "rss", "save", "server", "shareNodes", "shield", "shieldQuartered", "shovel", "sidebar", "siren", "sirenOn", "sitemap", "slack", "slashForward", "slider", "slidersSimple", "snowflake", "sparkles", "squareCheck", "squareCode", "squareDashed", "squareMinus", "squarePen", "squareQuestion", "squareTerminal", "star", "starSolid", "sun", "sunBright", "table", "tableColumns", "tableRows", "terminal", "text", "threads", "thumbsDown", "thumbsUp", "trash", "triangleExclamation", "twitter", "unlink", "upload", "user", "userAstronaut", "userGear", "userPlus", "users", "userSolid", "video", "wavePulse", "windowRestore", "wordpress", "wreathLaurel", "wrench", "xmark", "xmarkLarge", "xTwitter", "youtube"];
1636
+ export declare const iconList: readonly ["angleDown", "angleLeft", "angleRight", "anglesDown", "anglesLeft", "anglesRight", "anglesUp", "angleUp", "arrowDownToLine", "arrowDownWideShort", "arrowLeft", "arrowRight", "arrowsRetweet", "arrowUpShortWide", "asterisk", "banBug", "bars", "barsFilter", "barsStaggered", "bell", "billboard", "bitbucket", "bluesky", "bolt", "boltPantheon", "boltSolid", "book", "bookmark", "bookmarkSolid", "books", "box", "bracketRight", "bracketsSquare", "brainCircuit", "broomWide", "building", "buildings", "bullhorn", "calendarDays", "caretDown", "caretLeft", "caretRight", "caretUp", "ccAmex", "ccApplePay", "ccDiscover", "ccGeneric", "ccMC", "ccPaypal", "ccVisa", "chartLine", "chartNetwork", "chartSimple", "check", "circle", "circleCheck", "circleExclamation", "circleExclamationSolid", "circleHalfStroke", "circleInfo", "circleInfoSolid", "circleMinus", "circleNotch", "circlePlus", "circleQuestion", "circleQuestionSolid", "circleUser", "circleXmark", "claude", "clock", "cloud", "cloudArrowDown", "cloudArrowUp", "cloudPlus", "code", "codeBranch", "codeMerge", "collapseToCenter", "command", "comment", "compress", "copy", "desktop", "diagramVenn", "diamondExclamation", "diamonds4", "discourse", "display", "dollarSign", "download", "drupal", "ellipsis", "ellipsisVertical", "emptySet", "envelope", "envelopeOpen", "exclamation", "expand", "expandFromCenter", "externalLink", "eye", "eyeSlash", "facebook", "file", "fileCheck", "fileContract", "fileCSV", "fileDiff", "fileExport", "fileImport", "fileLines", "filePDF", "fileZip", "floppyDisk", "folder", "folderTree", "gear", "gem", "github", "gitlab", "globe", "graduationCap", "grid", "grid2", "gripDots", "gripDotsVertical", "heart", "heartSolid", "house", "idCard", "image", "inputText", "instagram", "keySkeleton", "landmark", "laptop", "laptopCode", "leaf", "lifeRing", "link", "linkedin", "listCheck", "locationCrosshairs", "lock", "lockOpen", "magnifyingGlass", "medal", "memo", "messages", "minus", "moon", "move", "nextJs", "octagonExclamation", "openai", "paperclip", "paperPlane", "pause", "pen", "penField", "penPaintbrush", "phone", "play", "plus", "question", "quotesLeft", "quotesRight", "rectangleList", "reply", "robot", "rocketLaunch", "rotate", "rotateClock", "rotateLeft", "rotateRight", "rss", "save", "server", "shareNodes", "shield", "shieldQuartered", "shovel", "sidebar", "siren", "sirenOn", "sitemap", "slack", "slashForward", "slider", "slidersSimple", "snowflake", "sparkles", "squareCheck", "squareCode", "squareDashed", "squareMinus", "squarePen", "squareQuestion", "squareTerminal", "star", "starSolid", "sun", "sunBright", "table", "tableColumns", "tableRows", "terminal", "text", "threads", "thumbsDown", "thumbsUp", "trash", "triangleExclamation", "twitter", "unlink", "upload", "user", "userAstronaut", "userGear", "userPlus", "users", "userSolid", "video", "wavePulse", "windowRestore", "wordpress", "wreathLaurel", "wrench", "xmark", "xmarkLarge", "xTwitter", "youtube"];
1623
1637
  export type PDSIconName = (typeof iconList)[number];
1624
1638
  export declare const categoryList: readonly ["actions", "arrows", "brands", "communication", "custom", "data", "development", "documents", "financial", "media", "navigation", "objects", "security", "status", "users"];
1625
1639
  export type IconCategory = (typeof categoryList)[number];
@@ -40,6 +40,12 @@ export interface SectionMessageProps extends ComponentPropsWithoutRef<'div'> {
40
40
  * Callback function when message is dismissed.
41
41
  */
42
42
  onDismiss?: (event: MouseEvent<HTMLButtonElement>, id: string) => void;
43
+ /**
44
+ * Props for an optional secondary action, rendered before `ctaButton` so the
45
+ * more prominent action sits on the outside. Can include any Button props
46
+ * except for size. Defaults to the `link` variant.
47
+ */
48
+ secondaryCta?: ComponentPropsWithoutRef<typeof Button>;
43
49
  /**
44
50
  * Message title.
45
51
  */
@@ -56,5 +62,5 @@ export interface SectionMessageProps extends ComponentPropsWithoutRef<'div'> {
56
62
  /**
57
63
  * SectionMessage UI component
58
64
  */
59
- export declare const SectionMessage: ({ className, ctaButton, ctaIcon, dismissLabel, id, isDismissible, message, onDismiss, title, type, typeLabels, ...props }: SectionMessageProps) => import("react/jsx-runtime").JSX.Element;
65
+ export declare const SectionMessage: ({ className, ctaButton, ctaIcon, dismissLabel, id, isDismissible, message, onDismiss, secondaryCta, title, type, typeLabels, ...props }: SectionMessageProps) => import("react/jsx-runtime").JSX.Element;
60
66
  export {};
@@ -0,0 +1,66 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import './bottom-sheet.css';
3
+ export interface BottomSheetProps extends Omit<ComponentPropsWithoutRef<'div'>, 'title'> {
4
+ /**
5
+ * Aria label that describes the sheet. Falls back to `title` if not provided.
6
+ */
7
+ ariaLabel?: string;
8
+ /**
9
+ * Main content for the sheet. Pass a `slot="footer"` child for footer content
10
+ * (e.g. Prev/Next navigation), same pattern as `Drawer`.
11
+ */
12
+ children?: ReactNode;
13
+ /**
14
+ * Additional class names
15
+ */
16
+ className?: string;
17
+ /**
18
+ * Text for the close button's aria-label attribute. Defaults to `'Close'`.
19
+ */
20
+ closeButtonLabel?: string;
21
+ /**
22
+ * If true, clicking the scrim will not close the sheet.
23
+ */
24
+ disableOutsideClick?: boolean;
25
+ /**
26
+ * Height while expanded (dragged past the expand threshold, or the grabber
27
+ * tapped/activated once). Accepts any valid CSS value. Defaults to `'96dvh'`.
28
+ * Pass `null` to disable expansion entirely — the sheet can then only be
29
+ * dragged smaller (toward dismissal), never past its default `height`.
30
+ */
31
+ expandedHeight?: string | null;
32
+ /**
33
+ * Indicates if the built-in close button will be shown.
34
+ */
35
+ hasCloseButton?: boolean;
36
+ /**
37
+ * Default (collapsed) height. Accepts any valid CSS value. Defaults to `'62dvh'`.
38
+ */
39
+ height?: string;
40
+ /**
41
+ * Is the sheet open?
42
+ */
43
+ isOpen?: boolean;
44
+ /**
45
+ * Accessible label for the drag handle. Dragging resizes the sheet, but
46
+ * that's a pointer-only enhancement — for keyboard/screen reader users,
47
+ * activating this handle (Enter/Space) closes the sheet outright, the
48
+ * same as dragging it down past the dismiss threshold. Defaults to
49
+ * `'Close sheet'`.
50
+ */
51
+ resizeLabel?: string;
52
+ /**
53
+ * Function to set the sheet's open state.
54
+ */
55
+ setIsOpen?: (isOpen: boolean) => void;
56
+ /**
57
+ * Title for the sheet. Accepts a string or ReactNode. Leave empty for no title.
58
+ */
59
+ title?: ReactNode;
60
+ }
61
+ /**
62
+ * BottomSheet UI component. A mobile-oriented overlay that slides up from the
63
+ * bottom of the viewport, with a draggable handle to resize between a default
64
+ * and an expanded height, or drag down past a threshold to dismiss.
65
+ */
66
+ export declare const BottomSheet: ({ ariaLabel, children, className, closeButtonLabel, disableOutsideClick, expandedHeight, hasCloseButton, height, isOpen: isOpenProp, resizeLabel, setIsOpen: setIsOpenProp, title, ...props }: BottomSheetProps) => any;
@@ -0,0 +1,48 @@
1
+ import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
+ import './bulk-action-bar.css';
3
+ /**
4
+ * Prop types for BulkActionBar
5
+ */
6
+ export interface BulkActionBarProps extends ComponentPropsWithoutRef<'div'> {
7
+ /**
8
+ * Action content (e.g. `MenuButton`s) rendered between the count and the
9
+ * clear button. Not opinionated about what it contains — this component
10
+ * only owns the count, the clear button, and the surrounding chrome.
11
+ * Since the bar always renders on a reverse (dark) surface, content
12
+ * should use variants suited to that — e.g. `MenuButton`'s
13
+ * `reverse-secondary`, `IconButton`'s `reverse`.
14
+ */
15
+ children?: ReactNode;
16
+ /**
17
+ * Additional class names
18
+ */
19
+ className?: string;
20
+ /**
21
+ * Accessible label for the built-in clear button. Defaults to `'Clear
22
+ * selection'`. Override for translation.
23
+ */
24
+ clearLabel?: string;
25
+ /**
26
+ * Number of items currently selected.
27
+ */
28
+ count: number;
29
+ /**
30
+ * Returns the visible count label. Defaults to `(count) => \`${count} selected\``.
31
+ * Override for translation, or to describe what's selected (e.g. "3 sites selected").
32
+ */
33
+ getCountLabel?: (count: number) => string;
34
+ /**
35
+ * Called when the clear button is activated. Typically clears the
36
+ * selection; whether that also exits any "select mode" the consumer has
37
+ * is up to them — this component has no opinion on that state.
38
+ */
39
+ onClear: () => void;
40
+ }
41
+ /**
42
+ * BulkActionBar UI component — a floating bar that surfaces a selection
43
+ * count and bulk actions once at least one item is selected. Pinned to the
44
+ * bottom of the viewport, content scrolls behind it. Mounting/unmounting
45
+ * based on selection state is the consumer's responsibility; this component
46
+ * always renders what it's given.
47
+ */
48
+ export declare const BulkActionBar: ({ children, className, clearLabel, count, getCountLabel, onClear, ...props }: BulkActionBarProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { ComponentPropsWithoutRef } from 'react';
2
2
  import { HeadingLevelCommon } from '../../../libs/types/custom-types';
3
3
  import './pagination-compact.css';
4
- export type PaginationCompactPageControlType = 'dropdown' | 'input';
4
+ export type PaginationCompactPageControlType = 'dropdown' | 'input' | 'static';
5
5
  /**
6
6
  * Prop types for PaginationCompact
7
7
  */
@@ -48,7 +48,12 @@ export interface PaginationCompactProps extends ComponentPropsWithoutRef<'nav'>
48
48
  */
49
49
  onPageChange?: (page: number) => void;
50
50
  /**
51
- * Which control to use for jumping to a page: a dropdown select or a typed number input. Defaults to `'dropdown'`.
51
+ * Which control to use for jumping to a page: a dropdown select or a typed
52
+ * number input. `'static'` renders the current page as plain text instead
53
+ * — no direct jump-to-page at all, just Prev/Next — for contexts where
54
+ * that control isn't worth the space (e.g. a mobile card list, where
55
+ * search/filter is the more realistic way to narrow a large result set
56
+ * down, not paging through it one page at a time). Defaults to `'dropdown'`.
52
57
  */
53
58
  pageControlType?: PaginationCompactPageControlType;
54
59
  /**
@@ -0,0 +1 @@
1
+ @layer pds-v1, pds-v2;@layer pds-v2{.pds-bottom-sheet__wrapper{inset:0;position:fixed;z-index:var(--pds-z-index-modal)}.pds-bottom-sheet__scrim{background-color:var(--pds-color-overlay-subtle);inset:0;opacity:0;position:fixed;transition:opacity .3s ease}.pds-bottom-sheet__scrim--visible{opacity:1}.pds-bottom-sheet{background-color:var(--pds-color-surface-default);border-radius:var(--pds-border-radius-panel) var(--pds-border-radius-panel) 0 0;bottom:0;box-shadow:var(--pds-elevation-overlay);display:flex;flex-direction:column;height:var(--pds-bottom-sheet-height,62dvh);left:0;max-height:96dvh;overflow:hidden;position:fixed;right:0;transform:translateY(105%);transition:height .2s var(--pds-animation-timing-function-default),transform .3s var(--pds-animation-timing-function-default)}.pds-bottom-sheet--open{transform:translateY(0)}.pds-bottom-sheet--expanded{height:var(--pds-bottom-sheet-expanded-height,96dvh)}.pds-bottom-sheet--dragging{transition:none}.pds-bottom-sheet__header{border-block-end:1px solid var(--pds-color-border-default);flex-shrink:0;padding:var(--pds-spacing-s) var(--pds-spacing-l) var(--pds-spacing-m);position:relative}.pds-bottom-sheet__grabber{background:transparent;border:0;cursor:grab;inset:0;position:absolute;touch-action:none;-webkit-user-select:none;user-select:none}.pds-bottom-sheet__grabber:active{cursor:grabbing}.pds-bottom-sheet__grabber:focus{outline:none}.pds-bottom-sheet__grabber-bar{background-color:var(--pds-color-border-default);border-radius:var(--pds-border-radius-button);display:block;height:.3125rem;margin-block-end:var(--pds-spacing-2xs);margin-inline:auto;width:2.75rem}.pds-bottom-sheet__grabber:focus-visible~.pds-bottom-sheet__grabber-bar{outline:2px solid var(--pds-color-interactive-foreground-current);outline-offset:2px}.pds-bottom-sheet__title-row{align-items:center;display:flex;gap:var(--pds-spacing-s);justify-content:flex-end}.pds-bottom-sheet__title{flex:1;font-family:var(--pds-typography-ff-compact);font-size:var(--pds-typography-size-l);font-weight:var(--pds-typography-fw-semibold);line-height:var(--pds-typography-lh-s)}.pds-bottom-sheet__close-button{position:relative}.pds-bottom-sheet__content{flex:1;overflow-y:auto;padding:var(--pds-spacing-m) var(--pds-spacing-l) var(--pds-spacing-l)}.pds-bottom-sheet__footer{align-items:center;border-top:1px solid var(--pds-color-border-default);display:flex;flex-shrink:0;justify-content:space-between;padding:var(--pds-spacing-m) var(--pds-spacing-l)}.pds-bottom-sheet__footer>*{width:100%}}
@@ -0,0 +1 @@
1
+ @layer pds-v1, pds-v2;@layer pds-v2{.pds-bulk-action-bar{align-items:center;background-color:var(--pds-color-surface-reverse);border:var(--pds-border-width-default) solid var(--pds-color-surface-reverse);border-radius:var(--pds-border-radius-card);bottom:var(--pds-spacing-m);box-shadow:var(--pds-elevation-overlay);display:flex;flex-wrap:wrap;gap:var(--pds-spacing-s);left:50%;padding:var(--pds-spacing-s) var(--pds-spacing-m);position:fixed;transform:translateX(-50%);width:calc(100% - var(--pds-spacing-xl));z-index:10}.pds-bulk-action-bar__count{color:var(--pds-color-foreground-reverse);flex-shrink:0;font-size:var(--pds-typography-size-s)}.pds-bulk-action-bar__actions{display:flex;flex-wrap:wrap;gap:var(--pds-spacing-s);margin-inline-start:auto}}