@carbon/react 1.89.0-rc.1 → 1.90.0-rc.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/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +1152 -849
- package/README.md +2 -2
- package/es/components/ComposedModal/ComposedModal.js +16 -5
- package/es/components/DataTable/DataTable.d.ts +3 -8
- package/es/components/DataTable/DataTable.js +10 -3
- package/es/components/DataTable/TableExpandRow.d.ts +33 -5
- package/es/components/DataTable/TableExpandRow.js +4 -2
- package/es/components/DataTable/TableHeader.d.ts +1 -2
- package/es/components/DataTable/TableHeader.js +1 -2
- package/es/components/DataTable/TableRow.d.ts +3 -6
- package/es/components/DataTable/TableRow.js +35 -22
- package/es/components/DataTable/state/sorting.d.ts +55 -14
- package/es/components/DataTable/state/sorting.js +40 -50
- package/es/components/DataTable/tools/sorting.js +4 -0
- package/es/components/Dialog/Dialog.d.ts +245 -0
- package/es/components/Dialog/Dialog.js +593 -0
- package/es/components/Dialog/index.d.ts +3 -251
- package/es/components/Dialog/index.js +1 -609
- package/es/components/FeatureFlags/index.d.ts +3 -1
- package/es/components/FeatureFlags/index.js +5 -2
- package/es/components/FileUploader/FileUploader.d.ts +28 -6
- package/es/components/FileUploader/FileUploader.js +152 -38
- package/es/components/Menu/MenuItem.js +2 -1
- package/es/components/Modal/Modal.js +14 -8
- package/es/components/NumberInput/NumberInput.js +11 -6
- package/es/components/Popover/index.js +6 -2
- package/es/components/StructuredList/StructuredList.js +4 -2
- package/es/components/Tag/DismissibleTag.d.ts +5 -0
- package/es/components/Tag/DismissibleTag.js +6 -1
- package/es/components/Toggletip/index.js +20 -8
- package/es/components/TreeView/TreeNode.d.ts +28 -0
- package/es/components/TreeView/TreeNode.js +6 -5
- package/es/index.d.ts +2 -1
- package/es/index.js +2 -0
- package/lib/components/ComposedModal/ComposedModal.js +16 -5
- package/lib/components/DataTable/DataTable.d.ts +3 -8
- package/lib/components/DataTable/DataTable.js +10 -3
- package/lib/components/DataTable/TableExpandRow.d.ts +33 -5
- package/lib/components/DataTable/TableExpandRow.js +4 -2
- package/lib/components/DataTable/TableHeader.d.ts +1 -2
- package/lib/components/DataTable/TableHeader.js +1 -2
- package/lib/components/DataTable/TableRow.d.ts +3 -6
- package/lib/components/DataTable/TableRow.js +34 -21
- package/lib/components/DataTable/state/sorting.d.ts +55 -14
- package/lib/components/DataTable/state/sorting.js +39 -50
- package/lib/components/DataTable/tools/sorting.js +4 -0
- package/lib/components/Dialog/Dialog.d.ts +245 -0
- package/lib/components/Dialog/Dialog.js +602 -0
- package/lib/components/Dialog/index.d.ts +3 -251
- package/lib/components/Dialog/index.js +9 -614
- package/lib/components/FeatureFlags/index.d.ts +3 -1
- package/lib/components/FeatureFlags/index.js +5 -2
- package/lib/components/FileUploader/FileUploader.d.ts +28 -6
- package/lib/components/FileUploader/FileUploader.js +151 -37
- package/lib/components/Menu/MenuItem.js +2 -1
- package/lib/components/Modal/Modal.js +21 -15
- package/lib/components/NumberInput/NumberInput.js +10 -5
- package/lib/components/Popover/index.js +6 -2
- package/lib/components/StructuredList/StructuredList.js +4 -2
- package/lib/components/Tag/DismissibleTag.d.ts +5 -0
- package/lib/components/Tag/DismissibleTag.js +6 -1
- package/lib/components/Toggletip/index.js +19 -7
- package/lib/components/TreeView/TreeNode.d.ts +28 -0
- package/lib/components/TreeView/TreeNode.js +6 -5
- package/lib/index.d.ts +2 -1
- package/lib/index.js +60 -58
- package/package.json +15 -15
- package/telemetry.yml +16 -0
package/README.md
CHANGED
|
@@ -114,14 +114,14 @@ function MyComponent() {
|
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
For a full list of icons available, checkout our
|
|
117
|
-
[website](https://
|
|
117
|
+
[website](https://carbondesignsystem.com/elements/icons/library/).
|
|
118
118
|
|
|
119
119
|
## 📖 API Documentation
|
|
120
120
|
|
|
121
121
|
If you're looking for `@carbon/react` API documentation, check out:
|
|
122
122
|
|
|
123
123
|
- [Storybook](https://react.carbondesignsystem.com/)
|
|
124
|
-
- [Icon Library](https://
|
|
124
|
+
- [Icon Library](https://carbondesignsystem.com/elements/icons/library/)
|
|
125
125
|
|
|
126
126
|
## 🙌 Contributing
|
|
127
127
|
|
|
@@ -24,7 +24,7 @@ import { match } from '../../internal/keyboard/match.js';
|
|
|
24
24
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
25
25
|
import { composeEventHandlers } from '../../tools/events.js';
|
|
26
26
|
import { deprecate } from '../../prop-types/deprecate.js';
|
|
27
|
-
import {
|
|
27
|
+
import { Dialog } from '../Dialog/Dialog.js';
|
|
28
28
|
import { warning } from '../../internal/warning.js';
|
|
29
29
|
import { AILabel } from '../AILabel/index.js';
|
|
30
30
|
import { isComponentElement } from '../../internal/utils.js';
|
|
@@ -166,9 +166,14 @@ const ComposedModal = /*#__PURE__*/React.forwardRef(function ComposedModal({
|
|
|
166
166
|
} = evt;
|
|
167
167
|
const mouseDownTarget = onMouseDownTarget.current;
|
|
168
168
|
evt.stopPropagation();
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
const shouldCloseOnOutsideClick =
|
|
170
|
+
// Passive modals can close on clicks outside the modal when
|
|
171
|
+
// preventCloseOnClickOutside is undefined or explicitly set to false.
|
|
172
|
+
isPassive && !preventCloseOnClickOutside ||
|
|
173
|
+
// Non-passive modals have to explicitly opt-in for close on outside
|
|
174
|
+
// behavior by explicitly setting preventCloseOnClickOutside to false,
|
|
175
|
+
// rather than just leaving it undefined.
|
|
176
|
+
!isPassive && preventCloseOnClickOutside === false;
|
|
172
177
|
if (shouldCloseOnOutsideClick && target instanceof Node && !elementOrParentIsFloatingMenu(target, selectorsFloatingMenus) && innerModal.current && !innerModal.current.contains(target) && !innerModal.current.contains(mouseDownTarget)) {
|
|
173
178
|
closeModal(evt);
|
|
174
179
|
}
|
|
@@ -252,6 +257,12 @@ const ComposedModal = /*#__PURE__*/React.forwardRef(function ComposedModal({
|
|
|
252
257
|
return child;
|
|
253
258
|
}
|
|
254
259
|
});
|
|
260
|
+
|
|
261
|
+
// Modals without a footer are considered passive and carry limitations as
|
|
262
|
+
// outlined in the design spec.
|
|
263
|
+
const containsModalFooter = Children.toArray(childrenWithProps).some(child => isComponentElement(child, ModalFooter));
|
|
264
|
+
const isPassive = !containsModalFooter;
|
|
265
|
+
process.env.NODE_ENV !== "production" ? warning(!(!isPassive && preventCloseOnClickOutside === false), '`<ComposedModal>` prop `preventCloseOnClickOutside` should not be ' + '`false` when `<ModalFooter>` is present. Transactional, non-passive ' + 'Modals should not be dissmissable by clicking outside. ' + 'See: https://carbondesignsystem.com/components/modal/usage/#transactional-modal') : void 0;
|
|
255
266
|
useEffect(() => {
|
|
256
267
|
if (!open) return;
|
|
257
268
|
const handleEscapeKey = event => {
|
|
@@ -304,7 +315,7 @@ const ComposedModal = /*#__PURE__*/React.forwardRef(function ComposedModal({
|
|
|
304
315
|
const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/cloneElement(candidate, {
|
|
305
316
|
size: 'sm'
|
|
306
317
|
}) : null;
|
|
307
|
-
const modalBody = enableDialogElement ? /*#__PURE__*/React.createElement(
|
|
318
|
+
const modalBody = enableDialogElement ? /*#__PURE__*/React.createElement(Dialog, {
|
|
308
319
|
open: open,
|
|
309
320
|
focusAfterCloseRef: launcherButtonRef,
|
|
310
321
|
modal: true,
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
import React, { type ChangeEvent, type MouseEvent, type ReactElement, type ReactNode } from 'react';
|
|
9
|
+
import { type SortRowFn } from './state/sorting';
|
|
9
10
|
import type { DataTableSortState } from './state/sortStates';
|
|
10
11
|
import { TranslateWithId } from '../../types/common';
|
|
11
12
|
declare const translationKeys: {
|
|
@@ -181,13 +182,7 @@ export interface DataTableProps<RowType, ColTypes extends any[]> extends Transla
|
|
|
181
182
|
render?: (renderProps: DataTableRenderProps<RowType, ColTypes>) => ReactElement;
|
|
182
183
|
rows: Omit<DataTableRow<ColTypes>, 'cells'>[];
|
|
183
184
|
size?: DataTableSize;
|
|
184
|
-
sortRow?:
|
|
185
|
-
sortDirection: DataTableSortState;
|
|
186
|
-
sortStates: Record<DataTableSortState, DataTableSortState>;
|
|
187
|
-
locale: string;
|
|
188
|
-
key: string;
|
|
189
|
-
compare: (a: number | string, b: number | string, locale?: string) => number;
|
|
190
|
-
}) => number;
|
|
185
|
+
sortRow?: SortRowFn;
|
|
191
186
|
stickyHeader?: boolean;
|
|
192
187
|
useStaticWidth?: boolean;
|
|
193
188
|
useZebraStyles?: boolean;
|
|
@@ -286,7 +281,7 @@ export declare const DataTable: {
|
|
|
286
281
|
};
|
|
287
282
|
TableHead: (props: React.HTMLAttributes<"thead">) => React.ReactElement<any>;
|
|
288
283
|
TableHeader: React.ForwardRefExoticComponent<import("./TableHeader").TableHeaderProps & React.RefAttributes<HTMLTableCellElement>>;
|
|
289
|
-
TableRow: React.ForwardRefExoticComponent<import("./TableRow").TableRowProps & React.RefAttributes<
|
|
284
|
+
TableRow: React.ForwardRefExoticComponent<import("./TableRow").TableRowProps & React.RefAttributes<HTMLTableRowElement>>;
|
|
290
285
|
TableSelectAll: {
|
|
291
286
|
({ ariaLabel: deprecatedAriaLabel, ["aria-label"]: ariaLabel, checked, id, indeterminate, name, onSelect, disabled, className, }: import("./TableSelectAll").TableSelectAllProps): import("react/jsx-runtime").JSX.Element;
|
|
292
287
|
propTypes: {
|
|
@@ -549,9 +549,16 @@ const DataTable = props => {
|
|
|
549
549
|
* @param headerKey - The field for the header that we are sorting by.
|
|
550
550
|
*/
|
|
551
551
|
const handleSortBy = headerKey => () => {
|
|
552
|
-
setState(prev =>
|
|
553
|
-
|
|
554
|
-
|
|
552
|
+
setState(prev => {
|
|
553
|
+
const sortState = getNextSortState(props, prev, {
|
|
554
|
+
key: headerKey
|
|
555
|
+
});
|
|
556
|
+
return {
|
|
557
|
+
...prev,
|
|
558
|
+
// Preserve ALL existing state
|
|
559
|
+
...sortState // Then apply only the sorting changes
|
|
560
|
+
};
|
|
561
|
+
});
|
|
555
562
|
};
|
|
556
563
|
|
|
557
564
|
/**
|
|
@@ -4,13 +4,41 @@
|
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import React, { type MouseEventHandler, type PropsWithChildren } from 'react';
|
|
8
|
-
|
|
9
|
-
export interface
|
|
7
|
+
import React, { type HTMLAttributes, type MouseEventHandler, type PropsWithChildren } from 'react';
|
|
8
|
+
/** Props shared between `TableRow` and `TableExpandRow`. */
|
|
9
|
+
export interface TableRowExpandInteropProps {
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated Use `aria-label` instead.
|
|
12
|
+
*/
|
|
13
|
+
ariaLabel?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Specify the string read by a voice reader when the expand trigger is
|
|
16
|
+
* focused
|
|
17
|
+
*/
|
|
18
|
+
'aria-label'?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Space separated list of one or more ID values referencing the TableExpandedRow(s) being controlled by the TableExpandRow
|
|
21
|
+
*/
|
|
22
|
+
'aria-controls'?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Specify whether this row is expanded or not. This helps coordinate data
|
|
25
|
+
* attributes so that `TableExpandRow` and `TableExpandedRow` work together
|
|
26
|
+
*/
|
|
27
|
+
isExpanded?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Hook for when a listener initiates a request to expand the given row
|
|
30
|
+
*/
|
|
31
|
+
onExpand?: MouseEventHandler<HTMLButtonElement>;
|
|
32
|
+
/**
|
|
33
|
+
* Specify if the row is selected.
|
|
34
|
+
*/
|
|
35
|
+
isSelected?: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface TableExpandRowProps extends PropsWithChildren<Omit<HTMLAttributes<HTMLTableRowElement>, 'onClick'>>, Omit<TableRowExpandInteropProps, 'aria-label' | 'onExpand'> {
|
|
10
38
|
/**
|
|
11
39
|
* Space separated list of one or more ID values referencing the TableExpandedRow(s) being controlled by the TableExpandRow
|
|
12
40
|
*/
|
|
13
|
-
|
|
41
|
+
'aria-controls'?: string;
|
|
14
42
|
/**
|
|
15
43
|
* @deprecated This prop has been deprecated and will be
|
|
16
44
|
* removed in the next major release of Carbon. Use the
|
|
@@ -21,7 +49,7 @@ export interface TableExpandRowProps extends PropsWithChildren<TableRowProps> {
|
|
|
21
49
|
* Specify the string read by a voice reader when the expand trigger is
|
|
22
50
|
* focused
|
|
23
51
|
*/
|
|
24
|
-
|
|
52
|
+
'aria-label': string;
|
|
25
53
|
/**
|
|
26
54
|
* The id of the matching th node in the table head. Addresses a11y concerns outlined here: https://www.ibm.com/able/guidelines/ci162/info_and_relationships.html and https://www.w3.org/TR/WCAG20-TECHS/H43
|
|
27
55
|
*/
|
|
@@ -17,6 +17,8 @@ import TableDecoratorRow from './TableDecoratorRow.js';
|
|
|
17
17
|
import { AILabel } from '../AILabel/index.js';
|
|
18
18
|
import { isComponentElement } from '../../internal/utils.js';
|
|
19
19
|
|
|
20
|
+
/** Props shared between `TableRow` and `TableExpandRow`. */
|
|
21
|
+
|
|
20
22
|
const TableExpandRow = /*#__PURE__*/React.forwardRef(({
|
|
21
23
|
['aria-controls']: ariaControls,
|
|
22
24
|
['aria-label']: ariaLabel,
|
|
@@ -85,13 +87,13 @@ TableExpandRow.propTypes = {
|
|
|
85
87
|
* Space separated list of one or more ID values referencing the TableExpandedRow(s) being controlled by the TableExpandRow
|
|
86
88
|
* TODO: make this required in v12
|
|
87
89
|
*/
|
|
88
|
-
|
|
90
|
+
'aria-controls': PropTypes.string,
|
|
89
91
|
/**
|
|
90
92
|
* Specify the string read by a voice reader when the expand trigger is
|
|
91
93
|
* focused
|
|
92
94
|
*/
|
|
93
95
|
/**@ts-ignore*/
|
|
94
|
-
|
|
96
|
+
'aria-label': PropTypes.string,
|
|
95
97
|
/**
|
|
96
98
|
* Deprecated, please use `aria-label` instead.
|
|
97
99
|
* Specify the string read by a voice reader when the expand trigger is
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React, { type HTMLAttributes, type MouseEventHandler, type ReactNode } from 'react';
|
|
8
|
-
import { sortStates } from './state/sorting';
|
|
9
8
|
import { TranslateWithId } from '../../types/common';
|
|
10
|
-
import { DataTableSortState } from './state/sortStates';
|
|
9
|
+
import { sortStates, type DataTableSortState } from './state/sortStates';
|
|
11
10
|
export type TableHeaderTranslationKey = 'carbon.table.header.icon.description';
|
|
12
11
|
export interface TableHeaderTranslationArgs {
|
|
13
12
|
header: ReactNode;
|
|
@@ -10,12 +10,11 @@ import cx from 'classnames';
|
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import React, { useRef, cloneElement } from 'react';
|
|
12
12
|
import { ArrowUp, ArrowsVertical } from '@carbon/icons-react';
|
|
13
|
-
import './state/sorting.js';
|
|
14
13
|
import { useId } from '../../internal/useId.js';
|
|
15
14
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
15
|
+
import { sortStates } from './state/sortStates.js';
|
|
16
16
|
import { AILabel } from '../AILabel/index.js';
|
|
17
17
|
import { isComponentElement } from '../../internal/utils.js';
|
|
18
|
-
import { sortStates } from './state/sortStates.js';
|
|
19
18
|
|
|
20
19
|
const defaultScope = 'col';
|
|
21
20
|
const translationKeys = {
|
|
@@ -5,15 +5,12 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React, { type HTMLAttributes } from 'react';
|
|
8
|
-
|
|
8
|
+
import type { TableRowExpandInteropProps } from './TableExpandRow';
|
|
9
|
+
export interface TableRowProps extends HTMLAttributes<HTMLTableRowElement>, TableRowExpandInteropProps {
|
|
9
10
|
/**
|
|
10
11
|
* Specify an optional className to be applied to the container node
|
|
11
12
|
*/
|
|
12
13
|
className?: string;
|
|
13
|
-
/**
|
|
14
|
-
* Specify if the row is selected
|
|
15
|
-
*/
|
|
16
|
-
isSelected?: boolean;
|
|
17
14
|
}
|
|
18
|
-
declare const TableRow: React.ForwardRefExoticComponent<TableRowProps & React.RefAttributes<
|
|
15
|
+
declare const TableRow: React.ForwardRefExoticComponent<TableRowProps & React.RefAttributes<HTMLTableRowElement>>;
|
|
19
16
|
export default TableRow;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React, { Children } from 'react';
|
|
9
|
+
import React, { forwardRef, Children } from 'react';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
11
|
import cx from 'classnames';
|
|
12
12
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
@@ -15,28 +15,10 @@ import TableDecoratorRow from './TableDecoratorRow.js';
|
|
|
15
15
|
import { AILabel } from '../AILabel/index.js';
|
|
16
16
|
import { isComponentElement } from '../../internal/utils.js';
|
|
17
17
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
let rowHasAILabel;
|
|
21
|
-
if (props?.children) {
|
|
22
|
-
// TODO: Why is this loop a `map`? It's not returning anything. Ideally,
|
|
23
|
-
// it seems that it should be a `some`. Maybe I'm missing something?
|
|
24
|
-
Children.toArray(props.children).map(child => {
|
|
25
|
-
if (isComponentElement(child, TableSlugRow)) {
|
|
26
|
-
if (child.props.slug) {
|
|
27
|
-
rowHasAILabel = true;
|
|
28
|
-
}
|
|
29
|
-
} else if (isComponentElement(child, TableDecoratorRow) && isComponentElement(child.props.decorator, AILabel)) {
|
|
30
|
-
rowHasAILabel = true;
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
}
|
|
18
|
+
const frFn = forwardRef;
|
|
19
|
+
const TableRow = frFn((props, ref) => {
|
|
34
20
|
// Remove unnecessary props if provided to this component, these are
|
|
35
21
|
// only useful in `TableExpandRow`
|
|
36
|
-
const className = cx(props.className, {
|
|
37
|
-
[`${prefix}--data-table--selected`]: props.isSelected,
|
|
38
|
-
[`${prefix}--data-table--slug-row ${prefix}--data-table--ai-label-row`]: rowHasAILabel
|
|
39
|
-
});
|
|
40
22
|
const {
|
|
41
23
|
ariaLabel,
|
|
42
24
|
'aria-label': ariaLabelAlt,
|
|
@@ -46,6 +28,17 @@ const TableRow = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
46
28
|
isSelected,
|
|
47
29
|
...cleanProps
|
|
48
30
|
} = props;
|
|
31
|
+
const prefix = usePrefix();
|
|
32
|
+
const rowHasAILabel = Children.toArray(props.children).some(child => {
|
|
33
|
+
if (isComponentElement(child, TableSlugRow)) {
|
|
34
|
+
return !!child.props.slug;
|
|
35
|
+
}
|
|
36
|
+
return isComponentElement(child, TableDecoratorRow) && isComponentElement(child.props.decorator, AILabel);
|
|
37
|
+
});
|
|
38
|
+
const className = cx(props.className, {
|
|
39
|
+
[`${prefix}--data-table--selected`]: isSelected,
|
|
40
|
+
[`${prefix}--data-table--slug-row ${prefix}--data-table--ai-label-row`]: rowHasAILabel
|
|
41
|
+
});
|
|
49
42
|
if (className) {
|
|
50
43
|
cleanProps.className = className;
|
|
51
44
|
}
|
|
@@ -61,7 +54,27 @@ TableRow.propTypes = {
|
|
|
61
54
|
/**
|
|
62
55
|
* Specify if the row is selected
|
|
63
56
|
*/
|
|
64
|
-
isSelected: PropTypes.bool
|
|
57
|
+
isSelected: PropTypes.bool,
|
|
58
|
+
/**
|
|
59
|
+
* Non-standard alias for `aria-label`.
|
|
60
|
+
*/
|
|
61
|
+
ariaLabel: PropTypes.string,
|
|
62
|
+
/**
|
|
63
|
+
* Accessible label for the row element.
|
|
64
|
+
*/
|
|
65
|
+
'aria-label': PropTypes.string,
|
|
66
|
+
/**
|
|
67
|
+
* Associates this row with the id of the corresponding expanded row content.
|
|
68
|
+
*/
|
|
69
|
+
'aria-controls': PropTypes.string,
|
|
70
|
+
/**
|
|
71
|
+
* Handler called when the row’s expand toggle is clicked.
|
|
72
|
+
*/
|
|
73
|
+
onExpand: PropTypes.func,
|
|
74
|
+
/**
|
|
75
|
+
* Flag indicating whether the row is currently expanded.
|
|
76
|
+
*/
|
|
77
|
+
isExpanded: PropTypes.bool
|
|
65
78
|
};
|
|
66
79
|
|
|
67
80
|
export { TableRow as default };
|
|
@@ -1,15 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2025
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import { type DataTableSortState } from './sortStates';
|
|
8
|
+
import type { DataTableCell } from '../DataTable';
|
|
9
|
+
export interface SortRowParams {
|
|
10
|
+
key: string;
|
|
11
|
+
sortDirection: DataTableSortState;
|
|
12
|
+
sortStates: Record<DataTableSortState, DataTableSortState>;
|
|
8
13
|
locale: string;
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
compare: (a: string | number, b: string | number, locale?: string) => number;
|
|
15
|
+
}
|
|
16
|
+
export type SortRowFn = (cellA: any, cellB: any, options: SortRowParams) => number;
|
|
17
|
+
interface Props {
|
|
18
|
+
locale?: string;
|
|
19
|
+
sortRow?: SortRowFn;
|
|
20
|
+
}
|
|
21
|
+
interface State<ColTypes extends any[]> {
|
|
22
|
+
rowIds: string[];
|
|
23
|
+
cellsById: Record<string, DataTableCell<ColTypes[number]>>;
|
|
24
|
+
initialRowOrder: string[];
|
|
25
|
+
sortHeaderKey: string | null;
|
|
26
|
+
sortDirection: DataTableSortState;
|
|
27
|
+
}
|
|
28
|
+
export declare const initialSortState: DataTableSortState;
|
|
29
|
+
/**
|
|
30
|
+
* Gets the next sort direction for a header.
|
|
31
|
+
*
|
|
32
|
+
* @param prevHeader - Key of the previously sorted header.
|
|
33
|
+
* @param currentHeader - Key of the currently selected header.
|
|
34
|
+
* @param prevState - Previous sort direction.
|
|
35
|
+
*/
|
|
36
|
+
export declare const getNextSortDirection: (prevHeader: string, currentHeader: string, prevState: DataTableSortState) => DataTableSortState;
|
|
37
|
+
/**
|
|
38
|
+
* Gets the next sort state.
|
|
39
|
+
*
|
|
40
|
+
* @param props - Component props.
|
|
41
|
+
* @param state - Current table state.
|
|
42
|
+
* @param key - Header key to sort by.
|
|
43
|
+
*/
|
|
44
|
+
export declare const getNextSortState: <ColTypes extends any[]>(props: Props, state: State<ColTypes>, { key }: {
|
|
45
|
+
key: string;
|
|
46
|
+
}) => Pick<State<ColTypes>, "sortHeaderKey" | "sortDirection" | "rowIds">;
|
|
47
|
+
/**
|
|
48
|
+
* Gets a sort state update.
|
|
49
|
+
*
|
|
50
|
+
* @param props - Component props.
|
|
51
|
+
* @param state - Current state of the table.
|
|
52
|
+
* @param key - Header key to sort by.
|
|
53
|
+
* @param sortDirection - Sort direction to apply.
|
|
54
|
+
*/
|
|
55
|
+
export declare const getSortedState: <ColTypes extends any[]>({ locale, sortRow }: Props, { rowIds, cellsById, initialRowOrder }: State<ColTypes>, key: string, sortDirection: DataTableSortState) => Pick<State<ColTypes>, "rowIds" | "sortDirection" | "sortHeaderKey">;
|
|
56
|
+
export {};
|
|
@@ -8,37 +8,39 @@
|
|
|
8
8
|
import { sortStates } from './sortStates.js';
|
|
9
9
|
import { sortRows } from '../tools/sorting.js';
|
|
10
10
|
|
|
11
|
-
// Our initialSortState should be `NONE`, unless a consumer has specified a
|
|
12
|
-
// different initialSortState
|
|
13
11
|
const initialSortState = sortStates.NONE;
|
|
14
12
|
|
|
15
13
|
/**
|
|
16
|
-
*
|
|
17
|
-
* information:
|
|
14
|
+
* Gets the next sort direction for a header.
|
|
18
15
|
*
|
|
19
|
-
* @param
|
|
20
|
-
* @param
|
|
21
|
-
* @param
|
|
22
|
-
* @returns {string}
|
|
16
|
+
* @param prevHeader - Key of the previously sorted header.
|
|
17
|
+
* @param currentHeader - Key of the currently selected header.
|
|
18
|
+
* @param prevState - Previous sort direction.
|
|
23
19
|
*/
|
|
24
|
-
const getNextSortDirection = (prevHeader,
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
20
|
+
const getNextSortDirection = (prevHeader, currentHeader, prevState) => {
|
|
21
|
+
// Cycle for sorting the same header: NONE -> ASC -> DESC -> NONE.
|
|
22
|
+
if (prevHeader === currentHeader) {
|
|
23
|
+
switch (prevState) {
|
|
24
|
+
case sortStates.NONE:
|
|
25
|
+
return sortStates.ASC;
|
|
26
|
+
case sortStates.ASC:
|
|
27
|
+
return sortStates.DESC;
|
|
28
|
+
case sortStates.DESC:
|
|
29
|
+
return sortStates.NONE;
|
|
32
30
|
}
|
|
33
|
-
if (prevState === 'ASC') {
|
|
34
|
-
return sortStates.DESC;
|
|
35
|
-
}
|
|
36
|
-
return sortStates.NONE;
|
|
37
31
|
}
|
|
38
|
-
|
|
39
|
-
//
|
|
32
|
+
|
|
33
|
+
// Sorting a new header starts at ascending order.
|
|
40
34
|
return sortStates.ASC;
|
|
41
35
|
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Gets the next sort state.
|
|
39
|
+
*
|
|
40
|
+
* @param props - Component props.
|
|
41
|
+
* @param state - Current table state.
|
|
42
|
+
* @param key - Header key to sort by.
|
|
43
|
+
*/
|
|
42
44
|
const getNextSortState = (props, state, {
|
|
43
45
|
key
|
|
44
46
|
}) => {
|
|
@@ -46,38 +48,26 @@ const getNextSortState = (props, state, {
|
|
|
46
48
|
sortDirection,
|
|
47
49
|
sortHeaderKey
|
|
48
50
|
} = state;
|
|
49
|
-
const nextSortDirection = getNextSortDirection(key, sortHeaderKey, sortDirection);
|
|
51
|
+
const nextSortDirection = getNextSortDirection(key, sortHeaderKey ?? '', sortDirection);
|
|
50
52
|
return getSortedState(props, state, key, nextSortDirection);
|
|
51
53
|
};
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
*
|
|
55
|
-
* header key and sortDirection
|
|
56
|
+
* Gets a sort state update.
|
|
56
57
|
*
|
|
57
|
-
* @param
|
|
58
|
-
* @param
|
|
59
|
-
* @param
|
|
60
|
-
*
|
|
61
|
-
* @param {object} state
|
|
62
|
-
* @param {Array<string>} state.rowIds Array of row ids
|
|
63
|
-
* @param {object} state.cellsById Lookup object for cells by id
|
|
64
|
-
* @param {Array<string>} state.initialRowOrder Initial row order for the
|
|
65
|
-
* current set of rows
|
|
66
|
-
* @param {string} key The key for the given header we are serving the
|
|
67
|
-
* sorted state for
|
|
68
|
-
* @param {string} sortDirection The sortState that we want to order by
|
|
69
|
-
* @returns {object}
|
|
58
|
+
* @param props - Component props.
|
|
59
|
+
* @param state - Current state of the table.
|
|
60
|
+
* @param key - Header key to sort by.
|
|
61
|
+
* @param sortDirection - Sort direction to apply.
|
|
70
62
|
*/
|
|
71
|
-
const getSortedState = (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
sortRow
|
|
80
|
-
} = props;
|
|
63
|
+
const getSortedState = ({
|
|
64
|
+
locale,
|
|
65
|
+
sortRow
|
|
66
|
+
}, {
|
|
67
|
+
rowIds,
|
|
68
|
+
cellsById,
|
|
69
|
+
initialRowOrder
|
|
70
|
+
}, key, sortDirection) => {
|
|
81
71
|
const nextRowIds = sortDirection !== sortStates.NONE ? sortRows({
|
|
82
72
|
rowIds,
|
|
83
73
|
cellsById,
|
|
@@ -88,9 +78,9 @@ const getSortedState = (props, state, key, sortDirection) => {
|
|
|
88
78
|
}) : initialRowOrder;
|
|
89
79
|
return {
|
|
90
80
|
sortHeaderKey: key,
|
|
91
|
-
sortDirection
|
|
81
|
+
sortDirection,
|
|
92
82
|
rowIds: nextRowIds
|
|
93
83
|
};
|
|
94
84
|
};
|
|
95
85
|
|
|
96
|
-
export { getNextSortDirection, getNextSortState, getSortedState, initialSortState
|
|
86
|
+
export { getNextSortDirection, getNextSortState, getSortedState, initialSortState };
|
|
@@ -42,6 +42,10 @@ const compareStrings = (a, b, locale = 'en') => {
|
|
|
42
42
|
numeric: isNumeric
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
|
+
|
|
46
|
+
// TODO: Should `SortRowParams` in
|
|
47
|
+
// packages/react/src/components/DataTable/state/sorting.ts be used here?
|
|
48
|
+
|
|
45
49
|
/**
|
|
46
50
|
* Sorts table rows based on the provided column key and direction.
|
|
47
51
|
*/
|