@pantheon-systems/pds-toolkit-react 2.0.0-alpha.34 → 2.0.0-alpha.36

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 (59) hide show
  1. package/bin/pds-codemod.cjs +58 -0
  2. package/codemods/v1-to-v2/mappings.json +1281 -0
  3. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-value-standardization/basic.input.tsx +36 -0
  4. package/codemods/v1-to-v2/transforms/__testfixtures__/prop-value-standardization/basic.output.tsx +36 -0
  5. package/codemods/v1-to-v2/transforms/__tests__/prop-value-standardization.test.js +6 -0
  6. package/codemods/v1-to-v2/transforms/prop-value-standardization.js +112 -0
  7. package/dist/components/Table/Table.d.ts +107 -1
  8. package/dist/components/buttons/Button/Button.d.ts +15 -0
  9. package/dist/components/buttons/MenuButton/MenuButton.d.ts +20 -7
  10. package/dist/components/buttons/SegmentedButton/SegmentedButton.d.ts +6 -5
  11. package/dist/components/buttons/SplitButton/SplitButton.d.ts +1 -1
  12. package/dist/components/icons/Icon/generated-icon-data.d.ts +16 -2
  13. package/dist/components/inputs/Datepicker/Datepicker.d.ts +22 -13
  14. package/dist/css/component-css/pds-button-nav.css +1 -1
  15. package/dist/css/component-css/pds-button.css +6 -6
  16. package/dist/css/component-css/pds-datepicker.css +2 -2
  17. package/dist/css/component-css/pds-drawer.css +1 -1
  18. package/dist/css/component-css/pds-dropdown-menu.css +1 -1
  19. package/dist/css/component-css/pds-index.css +27 -23
  20. package/dist/css/component-css/pds-input-utilities.css +1 -1
  21. package/dist/css/component-css/pds-menu-button.css +1 -1
  22. package/dist/css/component-css/pds-nav-menu.css +1 -1
  23. package/dist/css/component-css/pds-navbar.css +1 -1
  24. package/dist/css/component-css/pds-pagination-mini.css +1 -1
  25. package/dist/css/component-css/pds-panel-list.css +1 -1
  26. package/dist/css/component-css/pds-panel.css +1 -1
  27. package/dist/css/component-css/pds-segmented-button.css +1 -1
  28. package/dist/css/component-css/pds-side-nav-global.css +1 -1
  29. package/dist/css/component-css/pds-side-nav.css +1 -1
  30. package/dist/css/component-css/pds-site-footer.css +1 -1
  31. package/dist/css/component-css/pds-sortable-list.css +1 -1
  32. package/dist/css/component-css/pds-split-button.css +1 -1
  33. package/dist/css/component-css/pds-status-checker.css +1 -1
  34. package/dist/css/component-css/pds-stepper.css +3 -1
  35. package/dist/css/component-css/pds-tab-menu.css +1 -1
  36. package/dist/css/component-css/pds-table-of-contents.css +1 -1
  37. package/dist/css/component-css/pds-table.css +3 -1
  38. package/dist/css/component-css/pds-tabs.css +1 -1
  39. package/dist/css/component-css/pds-tally.css +1 -1
  40. package/dist/css/component-css/pds-theme-switcher.css +1 -1
  41. package/dist/css/component-css/pds-tree-nav.css +1 -1
  42. package/dist/css/component-css/pds-user-menu.css +2 -2
  43. package/dist/css/component-css/pds-utility-button.css +1 -1
  44. package/dist/css/component-css/pds-vertical-stepper.css +1 -1
  45. package/dist/css/component-css/pds-workspace-selector.css +1 -1
  46. package/dist/css/design-tokens/variables.dark.css +43 -33
  47. package/dist/css/design-tokens/variables.light.css +33 -23
  48. package/dist/css/pds-components.css +27 -23
  49. package/dist/css/pds-core.css +2 -2
  50. package/dist/index.css +1 -1
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.js +1411 -1052
  53. package/dist/index.js.map +1 -1
  54. package/dist/libs/components/StatusDot/StatusDot.d.ts +15 -0
  55. package/dist/libs/types/layout-types.d.ts +1 -1
  56. package/dist/svg/anglesDown.svg +3 -0
  57. package/dist/svg/anglesUp.svg +3 -0
  58. package/dist/utilities/FlexContainer/FlexContainer.d.ts +2 -1
  59. package/package.json +17 -2
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import {
3
+ Spinner,
4
+ Avatar,
5
+ StatusIndicator,
6
+ Badge,
7
+ Tooltip,
8
+ } from '@pantheon-systems/pds-toolkit-react';
9
+ import { IconButton as PdsIconButton } from '@pantheon-systems/pds-toolkit-react';
10
+
11
+ // String literals — should be updated
12
+ const A = () => <Spinner size='sm' />;
13
+ const B = () => <Spinner size='md' />;
14
+ const C = () => <Spinner size='lg' />;
15
+ const D = () => <Avatar size='sm' />;
16
+ const E = () => <Avatar size='lg' />;
17
+ // StatusIndicator has a different mapping: sm→xs, md→s
18
+ const F = () => <StatusIndicator size='sm' />;
19
+ const G = () => <StatusIndicator size='md' />;
20
+ // Aliased import
21
+ const H = () => <PdsIconButton size='sm' />;
22
+
23
+ // JSX expression container — should also be updated
24
+ const I = () => <Badge size={'sm'} />;
25
+
26
+ // Already correct — should be left alone
27
+ const J = () => <Spinner size='s' />;
28
+ // Variable — cannot be transformed at compile time, leave as-is
29
+ const mySize = 'sm';
30
+ const K = () => <Spinner size={mySize} />;
31
+
32
+ // Non-PDS component — should be left alone
33
+ const L = () => <div size='sm' />;
34
+
35
+ // Tooltip uses a different prop name: triggerIconSize
36
+ const M = () => <Tooltip triggerIconSize='sm' />;
@@ -0,0 +1,36 @@
1
+ import React from 'react';
2
+ import {
3
+ Spinner,
4
+ Avatar,
5
+ StatusIndicator,
6
+ Badge,
7
+ Tooltip,
8
+ } from '@pantheon-systems/pds-toolkit-react';
9
+ import { IconButton as PdsIconButton } from '@pantheon-systems/pds-toolkit-react';
10
+
11
+ // String literals — should be updated
12
+ const A = () => <Spinner size='s' />;
13
+ const B = () => <Spinner size='m' />;
14
+ const C = () => <Spinner size='l' />;
15
+ const D = () => <Avatar size='s' />;
16
+ const E = () => <Avatar size='m' />;
17
+ // StatusIndicator has a different mapping: sm→xs, md→s
18
+ const F = () => <StatusIndicator size='xs' />;
19
+ const G = () => <StatusIndicator size='s' />;
20
+ // Aliased import
21
+ const H = () => <PdsIconButton size='s' />;
22
+
23
+ // JSX expression container — should also be updated
24
+ const I = () => <Badge size={'s'} />;
25
+
26
+ // Already correct — should be left alone
27
+ const J = () => <Spinner size='s' />;
28
+ // Variable — cannot be transformed at compile time, leave as-is
29
+ const mySize = 'sm';
30
+ const K = () => <Spinner size={mySize} />;
31
+
32
+ // Non-PDS component — should be left alone
33
+ const L = () => <div size='sm' />;
34
+
35
+ // Tooltip uses a different prop name: triggerIconSize
36
+ const M = () => <Tooltip triggerIconSize='s' />;
@@ -0,0 +1,6 @@
1
+ const { defineTest } = require('jscodeshift/src/testUtils');
2
+
3
+ const transform = 'prop-value-standardization';
4
+ const fixtures = `${__dirname}/../__testfixtures__/${transform}`;
5
+
6
+ defineTest(__dirname, transform, null, `${transform}/basic`, { parser: 'tsx' });
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Codemod: prop-value-standardization
3
+ *
4
+ * Standardizes size-related prop values across PDS v1→v2.
5
+ * Driven entirely by props.typeChanges[].migration in mappings.json.
6
+ *
7
+ * Usage:
8
+ * npx jscodeshift -t codemods/v1-to-v2/transforms/prop-value-standardization.js \
9
+ * --extensions=tsx,ts,jsx,js \
10
+ * src/
11
+ */
12
+
13
+ const path = require('path');
14
+ const mappings = require(path.join(__dirname, '../mappings.json'));
15
+
16
+ // Build lookup: { 'ComponentName.propName': { oldValue: newValue } }
17
+ // Skips entries that are notes or no-ops.
18
+ function buildMigrationLookup() {
19
+ const lookup = {};
20
+
21
+ for (const entry of mappings.props.typeChanges) {
22
+ const { component, prop, migration } = entry;
23
+ if (!migration || typeof migration !== 'object' || Array.isArray(migration))
24
+ continue;
25
+
26
+ const map = {};
27
+ for (const [from, to] of Object.entries(migration)) {
28
+ if (from === 'note') continue;
29
+ // Strip parenthetical notes e.g. "s (removed, use 's' instead)" → "s"
30
+ const cleanTo = to.split(' ')[0];
31
+ // Skip no-op entries where value is unchanged
32
+ if (cleanTo === from) continue;
33
+ map[from] = cleanTo;
34
+ }
35
+
36
+ if (Object.keys(map).length > 0) {
37
+ lookup[`${component}.${prop}`] = map;
38
+ }
39
+ }
40
+
41
+ return lookup;
42
+ }
43
+
44
+ const MIGRATION_LOOKUP = buildMigrationLookup();
45
+
46
+ module.exports = function transform(file, api) {
47
+ const j = api.jscodeshift;
48
+ const root = j(file.source);
49
+
50
+ // Map local import name → exported component name
51
+ // Handles aliased imports: import { Spinner as MySpinner } → { MySpinner: 'Spinner' }
52
+ const localToExported = new Map();
53
+
54
+ root.find(j.ImportDeclaration).forEach((nodePath) => {
55
+ if (nodePath.node.source.value !== '@pantheon-systems/pds-toolkit-react')
56
+ return;
57
+ nodePath.node.specifiers.forEach((spec) => {
58
+ if (spec.type === 'ImportSpecifier') {
59
+ localToExported.set(spec.local.name, spec.imported.name);
60
+ }
61
+ });
62
+ });
63
+
64
+ if (localToExported.size === 0) return;
65
+
66
+ let changed = false;
67
+
68
+ root.find(j.JSXOpeningElement).forEach((nodePath) => {
69
+ const nameNode = nodePath.node.name;
70
+ // Skip member expressions like <Foo.Bar />
71
+ if (nameNode.type !== 'JSXIdentifier') return;
72
+
73
+ const exportedName = localToExported.get(nameNode.name);
74
+ if (!exportedName) return;
75
+
76
+ nodePath.node.attributes.forEach((attr) => {
77
+ if (attr.type !== 'JSXAttribute' || !attr.value) return;
78
+
79
+ const propName = attr.name.name;
80
+ if (typeof propName !== 'string') return;
81
+
82
+ const map = MIGRATION_LOOKUP[`${exportedName}.${propName}`];
83
+ if (!map) return;
84
+
85
+ // size="sm"
86
+ if (attr.value.type === 'StringLiteral') {
87
+ const newValue = map[attr.value.value];
88
+ if (newValue) {
89
+ attr.value = j.stringLiteral(newValue);
90
+ changed = true;
91
+ }
92
+ return;
93
+ }
94
+
95
+ // size={"sm"}
96
+ if (
97
+ attr.value.type === 'JSXExpressionContainer' &&
98
+ attr.value.expression.type === 'StringLiteral'
99
+ ) {
100
+ const newValue = map[attr.value.expression.value];
101
+ if (newValue) {
102
+ attr.value.expression = j.stringLiteral(newValue);
103
+ changed = true;
104
+ }
105
+ }
106
+ });
107
+ });
108
+
109
+ return changed ? root.toSource() : undefined;
110
+ };
111
+
112
+ module.exports.parser = 'tsx';
@@ -1,6 +1,20 @@
1
1
  import { ComponentPropsWithoutRef, ReactNode } from 'react';
2
2
  import './table.css';
3
3
  export type SortOrder = 'asc' | 'desc';
4
+ export type DetailPanelContext = {
5
+ /** Whether there is a next row to navigate to. */
6
+ hasNext: boolean;
7
+ /** Whether there is a previous row to navigate to. */
8
+ hasPrev: boolean;
9
+ /** Close the detail panel. */
10
+ onClose: () => void;
11
+ /** Navigate to the next row. */
12
+ onNext: () => void;
13
+ /** Navigate to the previous row. */
14
+ onPrev: () => void;
15
+ /** Stable ID of the currently inspected row. */
16
+ rowId: string;
17
+ };
4
18
  export interface TableColumn {
5
19
  /** Content to display in the header cell. */
6
20
  header: ReactNode;
@@ -17,6 +31,11 @@ export interface TableColumn {
17
31
  export interface TableProps extends ComponentPropsWithoutRef<'table'> {
18
32
  /** Additional class names */
19
33
  className?: string;
34
+ /**
35
+ * Accessible label for the detail panel close button.
36
+ * Defaults to `'Close detail panel'`. Override for translation.
37
+ */
38
+ closeDetailPanelLabel?: string;
20
39
  /** Column definitions. Each column requires a stable `id`. */
21
40
  columns: TableColumn[];
22
41
  /**
@@ -35,6 +54,23 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
35
54
  * Only applies in uncontrolled sort mode.
36
55
  */
37
56
  defaultSortOrder?: SortOrder;
57
+ /**
58
+ * When `true` (default), renders built-in prev/next navigation buttons in
59
+ * the detail panel footer. Set to `false` to hide the footer entirely.
60
+ * Has no effect when `renderDetailPanelFooter` is provided — the custom
61
+ * footer always takes precedence.
62
+ */
63
+ detailPanelNav?: boolean;
64
+ /**
65
+ * Optional title displayed in the detail panel header, to the left of the
66
+ * close button.
67
+ */
68
+ detailPanelTitle?: ReactNode;
69
+ /**
70
+ * Custom width for the detail panel. Accepts any valid CSS value (e.g. `'20rem'`, `'400px'`).
71
+ * Defaults to `'20rem'`.
72
+ */
73
+ detailPanelWidth?: string;
38
74
  /**
39
75
  * Custom empty state rendered when `rowData` is empty and `isLoading` is false.
40
76
  * When provided, takes precedence over `emptyStateHeading` and `emptyStateMessage`.
@@ -49,12 +85,24 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
49
85
  * Optional message displayed below the heading in the default empty state.
50
86
  */
51
87
  emptyStateMessage?: string;
88
+ /**
89
+ * Optional content rendered below the table, outside the scroll area.
90
+ * Use for status bars, custom controls, or other table-level UI. Renders
91
+ * independently of and below the pagination footer when both are present.
92
+ */
93
+ footer?: ReactNode;
52
94
  /**
53
95
  * Returns the accessible label for each option in the rows-per-page selector.
54
96
  * Defaults to `(size) => \`Show ${size} rows per page\``.
55
97
  * Override for translation.
56
98
  */
57
99
  getPageSizeLabel?: (size: number) => string;
100
+ /**
101
+ * Returns an additional CSS class name to apply to a row's `<tr>` element.
102
+ * Use for per-row status coloring or other conditional styling.
103
+ * Receives the row data object and its stable row ID (from `getRowId`).
104
+ */
105
+ getRowClassName?: (row: Record<string, ReactNode>, rowId: string) => string | null | undefined;
58
106
  /**
59
107
  * Derives a stable string ID from a row object for selection tracking.
60
108
  * Defaults to the row's array index. Provide this when using pagination
@@ -75,6 +123,12 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
75
123
  * Override for translation.
76
124
  */
77
125
  getSortLabel?: (columnHeader: string) => string;
126
+ /**
127
+ * ID of the currently inspected row. When provided, that row receives a
128
+ * highlighted background. Use the same ID space as `getRowId`. Only
129
+ * meaningful when `onRowInspect` or `renderDetailPanel` is also provided.
130
+ */
131
+ inspectedRowId?: string;
78
132
  /**
79
133
  * When true, renders skeleton rows instead of data. Use while data is loading.
80
134
  */
@@ -89,6 +143,21 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
89
143
  * Number of skeleton rows to render when `isLoading` is true. Defaults to 5.
90
144
  */
91
145
  loadingRowCount?: number;
146
+ /**
147
+ * Accessible label for the detail panel "next row" button.
148
+ * Defaults to `'Next row'`. Override for translation.
149
+ */
150
+ nextDetailPanelRowLabel?: string;
151
+ /**
152
+ * Called after the detail panel navigates to the next row. Use for side
153
+ * effects (fetching data, analytics) — the built-in navigation still runs.
154
+ */
155
+ onDetailPanelNext?: (row: Record<string, ReactNode>, rowId: string) => void;
156
+ /**
157
+ * Called after the detail panel navigates to the previous row. Use for side
158
+ * effects (fetching data, analytics) — the built-in navigation still runs.
159
+ */
160
+ onDetailPanelPrev?: (row: Record<string, ReactNode>, rowId: string) => void;
92
161
  /**
93
162
  * Callback fired when the user navigates to a new page. Receives the new
94
163
  * 1-based page number. Providing this prop enables controlled pagination mode.
@@ -100,6 +169,12 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
100
169
  * In uncontrolled mode the Table manages page size internally.
101
170
  */
102
171
  onPageSizeChange?: (size: number) => void;
172
+ /**
173
+ * Callback fired when a row is clicked for inspection. Providing this prop
174
+ * makes rows clickable and enables the row detail drawer pattern.
175
+ * Receives the row data object and its stable row ID (from `getRowId`).
176
+ */
177
+ onRowInspect?: (row: Record<string, ReactNode>, rowId: string) => void;
103
178
  /**
104
179
  * Callback fired when row selection changes. Providing this prop enables
105
180
  * the checkbox column. Receives the full array of currently selected row IDs.
@@ -114,11 +189,42 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
114
189
  * internally and expects the parent to pass pre-sorted data.
115
190
  */
116
191
  onSort?: (key: string, order: SortOrder) => void;
192
+ /**
193
+ * Render prop for the detail panel content. When provided, clicking a row
194
+ * slides in an inline detail panel alongside the table. Receives the row
195
+ * data and a context object with navigation callbacks and state.
196
+ * See the [Row detail panel](/docs/components-table--row-detail-panel) story.
197
+ */
117
198
  /**
118
199
  * Available page size options rendered in the rows-per-page selector.
119
200
  * When provided, the selector is shown to the left of the pagination controls.
120
201
  */
121
202
  pageSizeOptions?: number[];
203
+ /**
204
+ * When true, renders the table inside a Panel with no padding. Automatically
205
+ * applies first-column spacing and removes the last row's bottom border so
206
+ * it doesn't double up against the footer border.
207
+ */
208
+ panel?: boolean;
209
+ /**
210
+ * Accessible label for the detail panel "previous row" button.
211
+ * Defaults to `'Previous row'`. Override for translation.
212
+ */
213
+ prevDetailPanelRowLabel?: string;
214
+ /**
215
+ * Render prop for the detail panel content. When provided, clicking a row
216
+ * slides in an inline detail panel alongside the table. Receives the row
217
+ * data and a context object with navigation callbacks and state.
218
+ * See the [Row detail panel](/docs/components-table--row-detail-panel) story.
219
+ */
220
+ renderDetailPanel?: (row: Record<string, ReactNode>, context: DetailPanelContext) => ReactNode;
221
+ /**
222
+ * Optional content rendered at the bottom of the detail panel, outside the
223
+ * scrollable content area. Use for navigation controls, action buttons, or
224
+ * other panel-level UI. The consumer is responsible for all styling including
225
+ * any separator between content and footer.
226
+ */
227
+ renderDetailPanelFooter?: (row: Record<string, ReactNode>, context: DetailPanelContext) => ReactNode;
122
228
  /**
123
229
  * Row data as an array of records keyed by column id.
124
230
  * In controlled pagination mode, pass only the current page's rows.
@@ -148,4 +254,4 @@ export interface TableProps extends ComponentPropsWithoutRef<'table'> {
148
254
  */
149
255
  totalItemCount?: number;
150
256
  }
151
- export declare const Table: ({ className, columns, currentPage, defaultSortKey, defaultSortOrder, emptyState, emptyStateHeading, emptyStateMessage, getPageSizeLabel, getRowId, getSelectRowLabel, getSortLabel, isLoading, itemsPerPage, loadingRowCount, onPageChange, onPageSizeChange, onRowSelectionChange, onSort, pageSizeOptions, rowData, selectAllLabel, selectedRows, sortKey, sortOrder, totalItemCount, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
257
+ export declare const Table: ({ className, closeDetailPanelLabel, columns, currentPage, defaultSortKey, defaultSortOrder, detailPanelNav, detailPanelTitle, detailPanelWidth, emptyState, emptyStateHeading, emptyStateMessage, footer, getPageSizeLabel, getRowClassName, getRowId, getSelectRowLabel, getSortLabel, inspectedRowId, isLoading, itemsPerPage, loadingRowCount, nextDetailPanelRowLabel, onDetailPanelNext, onDetailPanelPrev, onPageChange, onPageSizeChange, onRowInspect, onRowSelectionChange, onSort, pageSizeOptions, panel, prevDetailPanelRowLabel, renderDetailPanel, renderDetailPanelFooter, rowData, selectAllLabel, selectedRows, sortKey, sortOrder, totalItemCount, ...props }: TableProps) => import("react/jsx-runtime").JSX.Element;
@@ -1,5 +1,7 @@
1
1
  import React, { ComponentPropsWithoutRef, MouseEvent, ReactNode } from 'react';
2
+ import { StatusDotType } from '../../../libs/components/StatusDot/StatusDot';
2
3
  import { ButtonDisplayType, ButtonSize, ButtonType, ButtonVariant } from '../../../libs/types/custom-types';
4
+ import { TallyProps } from '../../badges/Tally/Tally';
3
5
  import { PDSIcon } from '../../icons/Icon/Icon';
4
6
  import './button.css';
5
7
  interface ButtonProps extends ComponentPropsWithoutRef<'button'> {
@@ -56,6 +58,19 @@ interface ButtonProps extends ComponentPropsWithoutRef<'button'> {
56
58
  * @default 's'
57
59
  */
58
60
  size?: ButtonSize;
61
+ /**
62
+ * A status dot displayed in the left icon slot. Mutually exclusive with `iconName` when `displayType` is `icon-start`.
63
+ * Only valid on `primary`, `secondary`, and `subtle` variants.
64
+ */
65
+ statusDot?: StatusDotType;
66
+ /**
67
+ * A tally badge displayed in the right icon slot. Mutually exclusive with `iconName` when `displayType` is `icon-end`.
68
+ * Only valid on `primary`, `secondary`, `subtle`, and `highlight` variants.
69
+ */
70
+ tally?: {
71
+ label: TallyProps['label'];
72
+ type: TallyProps['type'];
73
+ };
59
74
  /**
60
75
  * Text for an optional tooltip to be displayed when the button is `disabled`, `isLoading`, or `isWorking`.
61
76
  */
@@ -1,5 +1,7 @@
1
1
  import { ComponentPropsWithRef, ReactNode } from 'react';
2
+ import { StatusDotType } from '../../../libs/components/StatusDot/StatusDot';
2
3
  import { ButtonVariant, HeadingItemType, LinkItemType, MenuItemType, NodeItemType, SeparatorItemType } from '../../../libs/types/custom-types';
4
+ import { TallyProps } from '../../badges/Tally/Tally';
3
5
  import { PDSIcon } from '../../icons/Icon/Icon';
4
6
  import '@components/Dropdown/dropdown.css';
5
7
  import './menu-button.css';
@@ -17,13 +19,13 @@ export interface MenuButtonProps extends ComponentPropsWithRef<'span'> {
17
19
  */
18
20
  disabled?: boolean;
19
21
  /**
20
- * How the button is displayed.
22
+ * Icon name for icon-only mode.
21
23
  */
22
- displayType?: 'icon-end' | 'icon-only';
24
+ iconName?: PDSIcon;
23
25
  /**
24
- * Icon name for icon-only buttons.
26
+ * Render as an icon-only button (no label, no angle-down). Not compatible with `tally` or `statusDot`.
25
27
  */
26
- iconName?: PDSIcon;
28
+ iconOnly?: boolean;
27
29
  /**
28
30
  * ID value for this component.
29
31
  */
@@ -52,6 +54,17 @@ export interface MenuButtonProps extends ComponentPropsWithRef<'span'> {
52
54
  * Which size of button to render.
53
55
  */
54
56
  size?: MenuButtonSize;
57
+ /**
58
+ * A status dot displayed in the left icon slot. Not available in `iconOnly` mode.
59
+ */
60
+ statusDot?: StatusDotType;
61
+ /**
62
+ * A tally badge displayed between the label and the angle-down icon. Not available in `iconOnly` mode.
63
+ */
64
+ tally?: {
65
+ label: TallyProps['label'];
66
+ type: TallyProps['type'];
67
+ };
55
68
  /**
56
69
  * Optional `data-testid` value for this component.
57
70
  */
@@ -61,12 +74,12 @@ export interface MenuButtonProps extends ComponentPropsWithRef<'span'> {
61
74
  */
62
75
  undefinedLabel?: string;
63
76
  /**
64
- * Which variant of button to render only valid for icon-end (default) display type.
77
+ * Which variant of button to render. Not available in `iconOnly` mode.
65
78
  */
66
- variant?: Extract<ButtonVariant, 'primary' | 'secondary' | 'subtle'>;
79
+ variant?: Extract<ButtonVariant, 'primary' | 'secondary' | 'subtle' | 'highlight'>;
67
80
  }
68
81
  /**
69
82
  * MenuButton UI component
70
83
  */
71
- export declare const MenuButton: ({ className, disabled, displayType, iconName, id, isSplitButton, label, menuItems, menuPosition, onClick, size, testId, undefinedLabel, variant, ...props }: MenuButtonProps) => import("react/jsx-runtime").JSX.Element;
84
+ export declare const MenuButton: ({ className, disabled, iconName, iconOnly, id, isSplitButton, label, menuItems, menuPosition, onClick, size, statusDot, tally, testId, undefinedLabel, variant, ...props }: MenuButtonProps) => import("react/jsx-runtime").JSX.Element;
72
85
  export {};
@@ -19,7 +19,7 @@ interface OptionType {
19
19
  */
20
20
  export interface SegmentedButtonProps {
21
21
  /**
22
- * Additional class names
22
+ * Additional class names.
23
23
  */
24
24
  className?: string;
25
25
  /**
@@ -27,7 +27,7 @@ export interface SegmentedButtonProps {
27
27
  */
28
28
  defaultValue?: string;
29
29
  /**
30
- * Is the SegmentedButton disabled?
30
+ * Disables all options in the SegmentedButton.
31
31
  */
32
32
  disabled?: boolean;
33
33
  /**
@@ -39,11 +39,12 @@ export interface SegmentedButtonProps {
39
39
  */
40
40
  label: string;
41
41
  /**
42
- * Callback function that will return the updated value from the instance when it changes.
42
+ * Callback fired when the selected option changes.
43
43
  */
44
44
  onChange?: (value: string) => void;
45
45
  /**
46
- * Array of button options — must be between 2 and 6 options.
46
+ * Array of button options — must be between 2 and 6 options. Each option
47
+ * may include an optional icon displayed before the label.
47
48
  */
48
49
  options: OptionType[];
49
50
  /**
@@ -51,7 +52,7 @@ export interface SegmentedButtonProps {
51
52
  */
52
53
  size?: 's' | 'm';
53
54
  /**
54
- * Value of the Segmented Button. Used to set the value of the field when controlled. Cannot be used in conjunction with the `defaultValue` prop.
55
+ * Controlled value. Cannot be used together with `defaultValue`.
55
56
  */
56
57
  value?: string;
57
58
  }
@@ -33,7 +33,7 @@ interface SplitButtonProps extends ComponentPropsWithoutRef<'span'> {
33
33
  /**
34
34
  * Which variant of button to render
35
35
  */
36
- variant?: Extract<ButtonVariant, 'primary' | 'secondary'>;
36
+ variant?: Extract<ButtonVariant, 'primary' | 'secondary' | 'highlight'>;
37
37
  }
38
38
  /**
39
39
  * A component used to render a button with a primary action and a menu of additional options
@@ -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-05-28T21:43:58.268Z
6
+ * Generated: 2026-07-02T02:04:49.319Z
7
7
  */
8
8
  import { customIcons } from './custom-icons';
9
9
  export { customIcons };
@@ -29,6 +29,13 @@ export declare const iconData: {
29
29
  readonly svgPathData: "M241.5 239c9.4 9.4 9.4 24.6 0 33.9L81.5 433c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9l143-143-143-143c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l160 160z";
30
30
  readonly width: 256;
31
31
  };
32
+ readonly anglesDown: {
33
+ readonly aliases: readonly ["chevrons down", "double down", "scroll to bottom"];
34
+ readonly categories: readonly ["arrows"];
35
+ readonly height: 512;
36
+ readonly svgPathData: "M369.5 113l-160 160c-9.4 9.4-24.6 9.4-33.9 0L15.5 113c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l143 143 143-143c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9zm0 192l-160 160c-9.4 9.4-24.6 9.4-33.9 0L15.5 305c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l143 143 143-143c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9z";
37
+ readonly width: 384;
38
+ };
32
39
  readonly anglesLeft: {
33
40
  readonly aliases: readonly ["chevrons left", "double left"];
34
41
  readonly categories: readonly ["arrows"];
@@ -43,6 +50,13 @@ export declare const iconData: {
43
50
  readonly svgPathData: "M81.5 433l160-160c9.4-9.4 9.4-24.6 0-33.9L81.5 79c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l143 143-143 143c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0zm192 0l160-160c9.4-9.4 9.4-24.6 0-33.9L273.5 79c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l143 143-143 143c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0z";
44
51
  readonly width: 448;
45
52
  };
53
+ readonly anglesUp: {
54
+ readonly aliases: readonly ["chevrons up", "double up", "scroll to top"];
55
+ readonly categories: readonly ["arrows"];
56
+ readonly height: 512;
57
+ readonly svgPathData: "M209.5 47c-9.4-9.4-24.6-9.4-33.9 0L15.5 207c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l143-143 143 143c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9L209.5 47zm160 352l-160-160c-9.4-9.4-24.6-9.4-33.9 0L15.5 399c-9.4 9.4-9.4 24.6 0 33.9s24.6 9.4 33.9 0l143-143 143 143c9.4 9.4 24.6 9.4 33.9 0s9.4-24.6 0-33.9z";
58
+ readonly width: 384;
59
+ };
46
60
  readonly angleUp: {
47
61
  readonly aliases: readonly ["chevron up"];
48
62
  readonly categories: readonly ["arrows"];
@@ -1493,7 +1507,7 @@ export declare const iconData: {
1493
1507
  readonly width: 576;
1494
1508
  };
1495
1509
  };
1496
- export declare const iconList: readonly ["angleDown", "angleLeft", "angleRight", "anglesLeft", "anglesRight", "angleUp", "arrowDownLeftAndArrowUpRightToCenter", "arrowDownToLine", "arrowLeft", "arrowRight", "arrowsRetweet", "arrowsUpDownLeftRight", "asterisk", "banBug", "bars", "barsFilter", "barsStaggered", "bell", "billboard", "bitbucket", "bluesky", "bolt", "boltPantheon", "boltSolid", "book", "books", "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", "circleInfo", "circleInfoSolid", "circleMinus", "circleNotch", "circlePlus", "circleQuestion", "circleQuestionSolid", "circleUser", "circleXmark", "cloud", "cloudArrowDown", "cloudArrowUp", "cloudPlus", "code", "codeBranch", "codeMerge", "command", "comment", "compress", "copy", "desktop", "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", "folder", "folderTree", "gear", "gem", "github", "gitlab", "globe", "graduationCap", "grid", "gripDots", "gripDotsVertical", "heart", "heartSolid", "house", "idCard", "image", "inputText", "instagram", "keySkeleton", "landmark", "laptop", "laptopCode", "leaf", "lifeRing", "linkedin", "linkSimple", "linkSimpleSlash", "listCheck", "locationCrosshairs", "lock", "lockOpen", "magnifyingGlass", "medal", "memo", "messages", "minus", "moon", "nextJs", "paperclip", "paperPlane", "pause", "pen", "penField", "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", "slidersSimple", "snowflake", "sparkles", "squareCheck", "squareCode", "squareMinus", "squarePen", "squareQuestion", "squareTerminal", "star", "starSolid", "sun", "sunBright", "table", "tableRows", "terminal", "text", "threads", "thumbsDown", "thumbsUp", "trash", "triangleExclamation", "twitter", "upload", "user", "userAstronaut", "userGear", "userPlus", "users", "video", "wavePulse", "windowRestore", "wordpress", "wreathLaurel", "wrench", "xmark", "xmarkLarge", "xTwitter", "youtube"];
1510
+ export declare const iconList: readonly ["angleDown", "angleLeft", "angleRight", "anglesDown", "anglesLeft", "anglesRight", "anglesUp", "angleUp", "arrowDownLeftAndArrowUpRightToCenter", "arrowDownToLine", "arrowLeft", "arrowRight", "arrowsRetweet", "arrowsUpDownLeftRight", "asterisk", "banBug", "bars", "barsFilter", "barsStaggered", "bell", "billboard", "bitbucket", "bluesky", "bolt", "boltPantheon", "boltSolid", "book", "books", "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", "circleInfo", "circleInfoSolid", "circleMinus", "circleNotch", "circlePlus", "circleQuestion", "circleQuestionSolid", "circleUser", "circleXmark", "cloud", "cloudArrowDown", "cloudArrowUp", "cloudPlus", "code", "codeBranch", "codeMerge", "command", "comment", "compress", "copy", "desktop", "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", "folder", "folderTree", "gear", "gem", "github", "gitlab", "globe", "graduationCap", "grid", "gripDots", "gripDotsVertical", "heart", "heartSolid", "house", "idCard", "image", "inputText", "instagram", "keySkeleton", "landmark", "laptop", "laptopCode", "leaf", "lifeRing", "linkedin", "linkSimple", "linkSimpleSlash", "listCheck", "locationCrosshairs", "lock", "lockOpen", "magnifyingGlass", "medal", "memo", "messages", "minus", "moon", "nextJs", "paperclip", "paperPlane", "pause", "pen", "penField", "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", "slidersSimple", "snowflake", "sparkles", "squareCheck", "squareCode", "squareMinus", "squarePen", "squareQuestion", "squareTerminal", "star", "starSolid", "sun", "sunBright", "table", "tableRows", "terminal", "text", "threads", "thumbsDown", "thumbsUp", "trash", "triangleExclamation", "twitter", "upload", "user", "userAstronaut", "userGear", "userPlus", "users", "video", "wavePulse", "windowRestore", "wordpress", "wreathLaurel", "wrench", "xmark", "xmarkLarge", "xTwitter", "youtube"];
1497
1511
  export type PDSIconName = (typeof iconList)[number];
1498
1512
  export declare const categoryList: readonly ["actions", "arrows", "brands", "communication", "custom", "data", "development", "documents", "financial", "media", "navigation", "objects", "security", "status", "users"];
1499
1513
  export type IconCategory = (typeof categoryList)[number];
@@ -1,16 +1,21 @@
1
- import { HTMLAttributes } from 'react';
1
+ import { HTMLAttributes, ReactNode } from 'react';
2
2
  import { Locale } from 'date-fns';
3
3
  import { DateRange } from 'react-day-picker';
4
+ import { ValidationStatus } from '../../../libs/types/input-types';
4
5
  import 'react-day-picker/dist/style.css';
5
6
  import './datepicker.css';
6
- type PresetType = 'today' | 'current-week' | 'current-month' | 'last-week' | 'last-month';
7
+ export type PresetType = 'today' | 'current-week' | 'current-month' | 'last-week' | 'last-month';
7
8
  export interface CustomPresetConfig {
8
- active?: boolean;
9
9
  custom?: () => DateRange;
10
10
  days?: number;
11
11
  label: string;
12
12
  type?: PresetType;
13
13
  }
14
+ /**
15
+ * Converts a preset config to a DateRange. Use this alongside an external
16
+ * SegmentedButton, Select, or other control to compose preset date pickers.
17
+ */
18
+ export declare const getPresetDateRange: (preset: CustomPresetConfig) => DateRange;
14
19
  export interface DatepickerTranslationStrings {
15
20
  clearButton?: string;
16
21
  doneButton?: string;
@@ -21,6 +26,7 @@ export interface DatepickerTranslationStrings {
21
26
  selectedDateRange?: string;
22
27
  selectedStartDate?: string;
23
28
  to?: string;
29
+ todayButton?: string;
24
30
  }
25
31
  /**
26
32
  * Prop types for Datepicker.
@@ -61,6 +67,10 @@ export interface DatepickerProps extends DatepickerHTMLProps {
61
67
  * Maximum selectable date.
62
68
  */
63
69
  maxDate?: Date;
70
+ /**
71
+ * Helper text displayed below the input.
72
+ */
73
+ message?: string | ReactNode;
64
74
  /**
65
75
  * Minimum selectable date.
66
76
  */
@@ -69,19 +79,10 @@ export interface DatepickerProps extends DatepickerHTMLProps {
69
79
  * onChange handler
70
80
  */
71
81
  onChange?: (value: DateRange | Date | undefined) => void;
72
- /**
73
- * Callback fired once on mount when an active preset is applied.
74
- * Only fires if no initial value is provided and a preset has active: true.
75
- */
76
- onInitialize?: (value: DateRange | Date | undefined) => void;
77
82
  /**
78
83
  * Placeholder text for the trigger button.
79
84
  */
80
85
  placeholder?: string;
81
- /**
82
- * Optional preset date ranges (only available when hasDateRange is true).
83
- */
84
- presets?: CustomPresetConfig[];
85
86
  /**
86
87
  * Is this field required?
87
88
  */
@@ -98,6 +99,14 @@ export interface DatepickerProps extends DatepickerHTMLProps {
98
99
  * Translation strings for labels.
99
100
  */
100
101
  translationStrings?: DatepickerTranslationStrings;
102
+ /**
103
+ * Validation message that takes priority over `message` when set.
104
+ */
105
+ validationMessage?: string;
106
+ /**
107
+ * Validation status. Controls error/success styling and message display.
108
+ */
109
+ validationStatus?: ValidationStatus;
101
110
  /**
102
111
  * Selected date or date range.
103
112
  */
@@ -106,5 +115,5 @@ export interface DatepickerProps extends DatepickerHTMLProps {
106
115
  /**
107
116
  * Datepicker UI component.
108
117
  */
109
- export declare const Datepicker: ({ className, disabled, hasDateRange, id, inputWidth, label, locale, maxDate, minDate, onChange, onInitialize, placeholder, presets, required, showLabel, tooltipText, translationStrings, value, ...props }: DatepickerProps) => import("react/jsx-runtime").JSX.Element;
118
+ export declare const Datepicker: ({ className, disabled, hasDateRange, id, inputWidth, label, locale, maxDate, message, minDate, onChange, placeholder, required, showLabel, tooltipText, translationStrings: translationStringsProp, validationMessage, validationStatus, value, ...props }: DatepickerProps) => import("react/jsx-runtime").JSX.Element;
110
119
  export {};