@carbon/react 1.89.0 → 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 +922 -881
- package/README.md +2 -2
- package/es/components/ComposedModal/ComposedModal.js +14 -3
- package/es/components/DataTable/DataTable.d.ts +3 -8
- 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/Modal/Modal.js +12 -6
- package/es/components/NumberInput/NumberInput.js +11 -6
- package/es/components/Popover/index.js +6 -2
- package/es/components/Tag/DismissibleTag.d.ts +5 -0
- package/es/components/Tag/DismissibleTag.js +6 -1
- package/es/components/Toggletip/index.js +19 -8
- package/es/components/TreeView/TreeNode.d.ts +28 -0
- package/es/components/TreeView/TreeNode.js +6 -5
- package/lib/components/ComposedModal/ComposedModal.js +14 -3
- package/lib/components/DataTable/DataTable.d.ts +3 -8
- 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/Modal/Modal.js +12 -6
- package/lib/components/NumberInput/NumberInput.js +10 -5
- package/lib/components/Popover/index.js +6 -2
- package/lib/components/Tag/DismissibleTag.d.ts +5 -0
- package/lib/components/Tag/DismissibleTag.js +6 -1
- package/lib/components/Toggletip/index.js +18 -7
- package/lib/components/TreeView/TreeNode.d.ts +28 -0
- package/lib/components/TreeView/TreeNode.js +6 -5
- package/package.json +9 -9
- package/telemetry.yml +14 -0
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
9
|
import cx from 'classnames';
|
|
10
10
|
import PropTypes from 'prop-types';
|
|
11
|
-
import React, { useContext, useRef, useState } from 'react';
|
|
11
|
+
import React, { useContext, useRef, useState, useEffect } from 'react';
|
|
12
12
|
import { Popover, PopoverContent } from '../Popover/index.js';
|
|
13
13
|
import { Escape } from '../../internal/keyboard/keys.js';
|
|
14
14
|
import { match } from '../../internal/keyboard/match.js';
|
|
@@ -127,13 +127,24 @@ function Toggletip({
|
|
|
127
127
|
actions.close();
|
|
128
128
|
}
|
|
129
129
|
});
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (!ref.current) return;
|
|
132
|
+
const targetDocument = ref.current.ownerDocument || document;
|
|
133
|
+
const eventType = 'PointerEvent' in window ? 'pointerdown' : 'mousedown';
|
|
134
|
+
const handleOutsideClick = event => {
|
|
135
|
+
const node = event.target;
|
|
136
|
+
if (open && node && !ref.current.contains(node)) {
|
|
137
|
+
setOpen(false);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
const options = {
|
|
141
|
+
capture: true
|
|
142
|
+
};
|
|
143
|
+
targetDocument.addEventListener(eventType, handleOutsideClick, options);
|
|
144
|
+
return () => {
|
|
145
|
+
targetDocument.removeEventListener(eventType, handleOutsideClick, options);
|
|
146
|
+
};
|
|
147
|
+
}, [open]);
|
|
137
148
|
return /*#__PURE__*/React.createElement(ToggletipContext.Provider, {
|
|
138
149
|
value: value
|
|
139
150
|
}, /*#__PURE__*/React.createElement(Popover, _extends({
|
|
@@ -11,6 +11,9 @@ export type TreeNodeProps = {
|
|
|
11
11
|
/**
|
|
12
12
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
13
13
|
* The ID of the active node in the tree
|
|
14
|
+
*
|
|
15
|
+
* @deprecated The `active` prop for `TreeNode` has
|
|
16
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
14
17
|
*/
|
|
15
18
|
active?: string | number;
|
|
16
19
|
/**
|
|
@@ -29,6 +32,9 @@ export type TreeNodeProps = {
|
|
|
29
32
|
/**
|
|
30
33
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
31
34
|
* TreeNode depth to determine spacing
|
|
35
|
+
*
|
|
36
|
+
* @deprecated The `depth` prop for `TreeNode` has
|
|
37
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
32
38
|
*/
|
|
33
39
|
depth?: number;
|
|
34
40
|
/**
|
|
@@ -49,6 +55,9 @@ export type TreeNodeProps = {
|
|
|
49
55
|
label: React.ReactNode;
|
|
50
56
|
/**
|
|
51
57
|
* Callback function for when the node receives or loses focus
|
|
58
|
+
*
|
|
59
|
+
* @deprecated The `onNodeFocusEvent` prop for `TreeNode` has
|
|
60
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
52
61
|
*/
|
|
53
62
|
onNodeFocusEvent?: (event: React.FocusEvent<HTMLElement>) => void;
|
|
54
63
|
/**
|
|
@@ -61,6 +70,9 @@ export type TreeNodeProps = {
|
|
|
61
70
|
onToggle?: UncontrolledOnToggle | ControlledOnToggle;
|
|
62
71
|
/**
|
|
63
72
|
* Callback function for when any node in the tree is selected
|
|
73
|
+
*
|
|
74
|
+
* @deprecated The `onTreeSelect` prop for `TreeNode` has
|
|
75
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
64
76
|
*/
|
|
65
77
|
onTreeSelect?: (event: React.MouseEvent | React.KeyboardEvent, node: Pick<TreeNodeProps, 'id' | 'label' | 'value'>) => void;
|
|
66
78
|
/**
|
|
@@ -70,6 +82,8 @@ export type TreeNodeProps = {
|
|
|
70
82
|
/**
|
|
71
83
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
72
84
|
* Array containing all selected node IDs in the tree
|
|
85
|
+
* @deprecated The `selected` prop for `TreeNode` has
|
|
86
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
73
87
|
*/
|
|
74
88
|
selected?: Array<string | number>;
|
|
75
89
|
/**
|
|
@@ -97,6 +111,9 @@ declare const TreeNode: React.ForwardRefExoticComponent<{
|
|
|
97
111
|
/**
|
|
98
112
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
99
113
|
* The ID of the active node in the tree
|
|
114
|
+
*
|
|
115
|
+
* @deprecated The `active` prop for `TreeNode` has
|
|
116
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
100
117
|
*/
|
|
101
118
|
active?: string | number;
|
|
102
119
|
/**
|
|
@@ -115,6 +132,9 @@ declare const TreeNode: React.ForwardRefExoticComponent<{
|
|
|
115
132
|
/**
|
|
116
133
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
117
134
|
* TreeNode depth to determine spacing
|
|
135
|
+
*
|
|
136
|
+
* @deprecated The `depth` prop for `TreeNode` has
|
|
137
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
118
138
|
*/
|
|
119
139
|
depth?: number;
|
|
120
140
|
/**
|
|
@@ -135,6 +155,9 @@ declare const TreeNode: React.ForwardRefExoticComponent<{
|
|
|
135
155
|
label: React.ReactNode;
|
|
136
156
|
/**
|
|
137
157
|
* Callback function for when the node receives or loses focus
|
|
158
|
+
*
|
|
159
|
+
* @deprecated The `onNodeFocusEvent` prop for `TreeNode` has
|
|
160
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
138
161
|
*/
|
|
139
162
|
onNodeFocusEvent?: (event: React.FocusEvent<HTMLElement>) => void;
|
|
140
163
|
/**
|
|
@@ -147,6 +170,9 @@ declare const TreeNode: React.ForwardRefExoticComponent<{
|
|
|
147
170
|
onToggle?: UncontrolledOnToggle | ControlledOnToggle;
|
|
148
171
|
/**
|
|
149
172
|
* Callback function for when any node in the tree is selected
|
|
173
|
+
*
|
|
174
|
+
* @deprecated The `onTreeSelect` prop for `TreeNode` has
|
|
175
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
150
176
|
*/
|
|
151
177
|
onTreeSelect?: (event: React.MouseEvent | React.KeyboardEvent, node: Pick<TreeNodeProps, "id" | "label" | "value">) => void;
|
|
152
178
|
/**
|
|
@@ -156,6 +182,8 @@ declare const TreeNode: React.ForwardRefExoticComponent<{
|
|
|
156
182
|
/**
|
|
157
183
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
158
184
|
* Array containing all selected node IDs in the tree
|
|
185
|
+
* @deprecated The `selected` prop for `TreeNode` has
|
|
186
|
+
* been deprecated after the introduction of context. It will be removed in the next major release.
|
|
159
187
|
*/
|
|
160
188
|
selected?: Array<string | number>;
|
|
161
189
|
/**
|
|
@@ -12,6 +12,7 @@ import PropTypes from 'prop-types';
|
|
|
12
12
|
import React, { useContext, useRef, useState, useEffect, useCallback } from 'react';
|
|
13
13
|
import { ArrowLeft, ArrowRight, Enter, Space } from '../../internal/keyboard/keys.js';
|
|
14
14
|
import { matches, match } from '../../internal/keyboard/match.js';
|
|
15
|
+
import { deprecate } from '../../prop-types/deprecate.js';
|
|
15
16
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
16
17
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
17
18
|
import { useId } from '../../internal/useId.js';
|
|
@@ -413,7 +414,7 @@ TreeNode.propTypes = {
|
|
|
413
414
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
414
415
|
* The ID of the active node in the tree
|
|
415
416
|
*/
|
|
416
|
-
active: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
417
|
+
active: deprecate(PropTypes.oneOfType([PropTypes.string, PropTypes.number]), 'The `active` prop for `TreeNode` is no longer needed and has ' + 'been deprecated. It will be removed in the next major release.'),
|
|
417
418
|
/**
|
|
418
419
|
* Specify the children of the TreeNode
|
|
419
420
|
*/
|
|
@@ -431,7 +432,7 @@ TreeNode.propTypes = {
|
|
|
431
432
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
432
433
|
* TreeNode depth to determine spacing
|
|
433
434
|
*/
|
|
434
|
-
depth: PropTypes.number,
|
|
435
|
+
depth: deprecate(PropTypes.number, 'The `depth` prop for `TreeNode` is no longer needed and has ' + 'been deprecated. It will be removed in the next major release.'),
|
|
435
436
|
/**
|
|
436
437
|
* Specify if the TreeNode is disabled
|
|
437
438
|
*/
|
|
@@ -451,7 +452,7 @@ TreeNode.propTypes = {
|
|
|
451
452
|
/**
|
|
452
453
|
* Callback function for when the node receives or loses focus
|
|
453
454
|
*/
|
|
454
|
-
onNodeFocusEvent: PropTypes.func,
|
|
455
|
+
onNodeFocusEvent: deprecate(PropTypes.func, 'The `onNodeFocusEvent` prop for `TreeNode` is no longer needed and has ' + 'been deprecated. It will be removed in the next major release.'),
|
|
455
456
|
/**
|
|
456
457
|
* Callback function for when the node is selected
|
|
457
458
|
*/
|
|
@@ -463,7 +464,7 @@ TreeNode.propTypes = {
|
|
|
463
464
|
/**
|
|
464
465
|
* Callback function for when any node in the tree is selected
|
|
465
466
|
*/
|
|
466
|
-
onTreeSelect: PropTypes.func,
|
|
467
|
+
onTreeSelect: deprecate(PropTypes.func, 'The `onTreeSelect` prop for `TreeNode` is no longer needed and has ' + 'been deprecated. It will be removed in the next major release.'),
|
|
467
468
|
/**
|
|
468
469
|
* A component used to render an icon.
|
|
469
470
|
*/
|
|
@@ -474,7 +475,7 @@ TreeNode.propTypes = {
|
|
|
474
475
|
* Array containing all selected node IDs in the tree
|
|
475
476
|
*/
|
|
476
477
|
// @ts-ignore
|
|
477
|
-
selected: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
|
|
478
|
+
selected: deprecate(PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])), 'The `selected` prop for `TreeNode` is no longer needed and has ' + 'been deprecated. It will be removed in the next major release.'),
|
|
478
479
|
/**
|
|
479
480
|
* Specify the value of the TreeNode
|
|
480
481
|
*/
|
|
@@ -170,9 +170,14 @@ const ComposedModal = /*#__PURE__*/React.forwardRef(function ComposedModal({
|
|
|
170
170
|
} = evt;
|
|
171
171
|
const mouseDownTarget = onMouseDownTarget.current;
|
|
172
172
|
evt.stopPropagation();
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
const shouldCloseOnOutsideClick =
|
|
174
|
+
// Passive modals can close on clicks outside the modal when
|
|
175
|
+
// preventCloseOnClickOutside is undefined or explicitly set to false.
|
|
176
|
+
isPassive && !preventCloseOnClickOutside ||
|
|
177
|
+
// Non-passive modals have to explicitly opt-in for close on outside
|
|
178
|
+
// behavior by explicitly setting preventCloseOnClickOutside to false,
|
|
179
|
+
// rather than just leaving it undefined.
|
|
180
|
+
!isPassive && preventCloseOnClickOutside === false;
|
|
176
181
|
if (shouldCloseOnOutsideClick && target instanceof Node && !wrapFocus.elementOrParentIsFloatingMenu(target, selectorsFloatingMenus) && innerModal.current && !innerModal.current.contains(target) && !innerModal.current.contains(mouseDownTarget)) {
|
|
177
182
|
closeModal(evt);
|
|
178
183
|
}
|
|
@@ -256,6 +261,12 @@ const ComposedModal = /*#__PURE__*/React.forwardRef(function ComposedModal({
|
|
|
256
261
|
return child;
|
|
257
262
|
}
|
|
258
263
|
});
|
|
264
|
+
|
|
265
|
+
// Modals without a footer are considered passive and carry limitations as
|
|
266
|
+
// outlined in the design spec.
|
|
267
|
+
const containsModalFooter = React.Children.toArray(childrenWithProps).some(child => utils.isComponentElement(child, ModalFooter.ModalFooter));
|
|
268
|
+
const isPassive = !containsModalFooter;
|
|
269
|
+
process.env.NODE_ENV !== "production" ? warning.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;
|
|
259
270
|
React.useEffect(() => {
|
|
260
271
|
if (!open) return;
|
|
261
272
|
const handleEscapeKey = event => {
|
|
@@ -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: {
|
|
@@ -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
|
*/
|
|
@@ -21,6 +21,8 @@ var TableDecoratorRow = require('./TableDecoratorRow.js');
|
|
|
21
21
|
var index = require('../AILabel/index.js');
|
|
22
22
|
var utils = require('../../internal/utils.js');
|
|
23
23
|
|
|
24
|
+
/** Props shared between `TableRow` and `TableExpandRow`. */
|
|
25
|
+
|
|
24
26
|
const TableExpandRow = /*#__PURE__*/React.forwardRef(({
|
|
25
27
|
['aria-controls']: ariaControls,
|
|
26
28
|
['aria-label']: ariaLabel,
|
|
@@ -89,13 +91,13 @@ TableExpandRow.propTypes = {
|
|
|
89
91
|
* Space separated list of one or more ID values referencing the TableExpandedRow(s) being controlled by the TableExpandRow
|
|
90
92
|
* TODO: make this required in v12
|
|
91
93
|
*/
|
|
92
|
-
|
|
94
|
+
'aria-controls': PropTypes.string,
|
|
93
95
|
/**
|
|
94
96
|
* Specify the string read by a voice reader when the expand trigger is
|
|
95
97
|
* focused
|
|
96
98
|
*/
|
|
97
99
|
/**@ts-ignore*/
|
|
98
|
-
|
|
100
|
+
'aria-label': PropTypes.string,
|
|
99
101
|
/**
|
|
100
102
|
* Deprecated, please use `aria-label` instead.
|
|
101
103
|
* 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;
|
|
@@ -14,12 +14,11 @@ var cx = require('classnames');
|
|
|
14
14
|
var PropTypes = require('prop-types');
|
|
15
15
|
var React = require('react');
|
|
16
16
|
var iconsReact = require('@carbon/icons-react');
|
|
17
|
-
require('./state/sorting.js');
|
|
18
17
|
var useId = require('../../internal/useId.js');
|
|
19
18
|
var usePrefix = require('../../internal/usePrefix.js');
|
|
19
|
+
var sortStates = require('./state/sortStates.js');
|
|
20
20
|
var index = require('../AILabel/index.js');
|
|
21
21
|
var utils = require('../../internal/utils.js');
|
|
22
|
-
var sortStates = require('./state/sortStates.js');
|
|
23
22
|
|
|
24
23
|
const defaultScope = 'col';
|
|
25
24
|
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;
|
|
@@ -19,28 +19,10 @@ var TableDecoratorRow = require('./TableDecoratorRow.js');
|
|
|
19
19
|
var index = require('../AILabel/index.js');
|
|
20
20
|
var utils = require('../../internal/utils.js');
|
|
21
21
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
let rowHasAILabel;
|
|
25
|
-
if (props?.children) {
|
|
26
|
-
// TODO: Why is this loop a `map`? It's not returning anything. Ideally,
|
|
27
|
-
// it seems that it should be a `some`. Maybe I'm missing something?
|
|
28
|
-
React.Children.toArray(props.children).map(child => {
|
|
29
|
-
if (utils.isComponentElement(child, TableSlugRow.default)) {
|
|
30
|
-
if (child.props.slug) {
|
|
31
|
-
rowHasAILabel = true;
|
|
32
|
-
}
|
|
33
|
-
} else if (utils.isComponentElement(child, TableDecoratorRow.default) && utils.isComponentElement(child.props.decorator, index.AILabel)) {
|
|
34
|
-
rowHasAILabel = true;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
22
|
+
const frFn = React.forwardRef;
|
|
23
|
+
const TableRow = frFn((props, ref) => {
|
|
38
24
|
// Remove unnecessary props if provided to this component, these are
|
|
39
25
|
// only useful in `TableExpandRow`
|
|
40
|
-
const className = cx(props.className, {
|
|
41
|
-
[`${prefix}--data-table--selected`]: props.isSelected,
|
|
42
|
-
[`${prefix}--data-table--slug-row ${prefix}--data-table--ai-label-row`]: rowHasAILabel
|
|
43
|
-
});
|
|
44
26
|
const {
|
|
45
27
|
ariaLabel,
|
|
46
28
|
'aria-label': ariaLabelAlt,
|
|
@@ -50,6 +32,17 @@ const TableRow = /*#__PURE__*/React.forwardRef((props, ref) => {
|
|
|
50
32
|
isSelected,
|
|
51
33
|
...cleanProps
|
|
52
34
|
} = props;
|
|
35
|
+
const prefix = usePrefix.usePrefix();
|
|
36
|
+
const rowHasAILabel = React.Children.toArray(props.children).some(child => {
|
|
37
|
+
if (utils.isComponentElement(child, TableSlugRow.default)) {
|
|
38
|
+
return !!child.props.slug;
|
|
39
|
+
}
|
|
40
|
+
return utils.isComponentElement(child, TableDecoratorRow.default) && utils.isComponentElement(child.props.decorator, index.AILabel);
|
|
41
|
+
});
|
|
42
|
+
const className = cx(props.className, {
|
|
43
|
+
[`${prefix}--data-table--selected`]: isSelected,
|
|
44
|
+
[`${prefix}--data-table--slug-row ${prefix}--data-table--ai-label-row`]: rowHasAILabel
|
|
45
|
+
});
|
|
53
46
|
if (className) {
|
|
54
47
|
cleanProps.className = className;
|
|
55
48
|
}
|
|
@@ -65,7 +58,27 @@ TableRow.propTypes = {
|
|
|
65
58
|
/**
|
|
66
59
|
* Specify if the row is selected
|
|
67
60
|
*/
|
|
68
|
-
isSelected: PropTypes.bool
|
|
61
|
+
isSelected: PropTypes.bool,
|
|
62
|
+
/**
|
|
63
|
+
* Non-standard alias for `aria-label`.
|
|
64
|
+
*/
|
|
65
|
+
ariaLabel: PropTypes.string,
|
|
66
|
+
/**
|
|
67
|
+
* Accessible label for the row element.
|
|
68
|
+
*/
|
|
69
|
+
'aria-label': PropTypes.string,
|
|
70
|
+
/**
|
|
71
|
+
* Associates this row with the id of the corresponding expanded row content.
|
|
72
|
+
*/
|
|
73
|
+
'aria-controls': PropTypes.string,
|
|
74
|
+
/**
|
|
75
|
+
* Handler called when the row’s expand toggle is clicked.
|
|
76
|
+
*/
|
|
77
|
+
onExpand: PropTypes.func,
|
|
78
|
+
/**
|
|
79
|
+
* Flag indicating whether the row is currently expanded.
|
|
80
|
+
*/
|
|
81
|
+
isExpanded: PropTypes.bool
|
|
69
82
|
};
|
|
70
83
|
|
|
71
84
|
exports.default = TableRow;
|
|
@@ -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 {};
|
|
@@ -10,37 +10,39 @@
|
|
|
10
10
|
var sortStates = require('./sortStates.js');
|
|
11
11
|
var sorting = require('../tools/sorting.js');
|
|
12
12
|
|
|
13
|
-
// Our initialSortState should be `NONE`, unless a consumer has specified a
|
|
14
|
-
// different initialSortState
|
|
15
13
|
const initialSortState = sortStates.sortStates.NONE;
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
|
-
*
|
|
19
|
-
* information:
|
|
16
|
+
* Gets the next sort direction for a header.
|
|
20
17
|
*
|
|
21
|
-
* @param
|
|
22
|
-
* @param
|
|
23
|
-
* @param
|
|
24
|
-
* @returns {string}
|
|
18
|
+
* @param prevHeader - Key of the previously sorted header.
|
|
19
|
+
* @param currentHeader - Key of the currently selected header.
|
|
20
|
+
* @param prevState - Previous sort direction.
|
|
25
21
|
*/
|
|
26
|
-
const getNextSortDirection = (prevHeader,
|
|
27
|
-
//
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
const getNextSortDirection = (prevHeader, currentHeader, prevState) => {
|
|
23
|
+
// Cycle for sorting the same header: NONE -> ASC -> DESC -> NONE.
|
|
24
|
+
if (prevHeader === currentHeader) {
|
|
25
|
+
switch (prevState) {
|
|
26
|
+
case sortStates.sortStates.NONE:
|
|
27
|
+
return sortStates.sortStates.ASC;
|
|
28
|
+
case sortStates.sortStates.ASC:
|
|
29
|
+
return sortStates.sortStates.DESC;
|
|
30
|
+
case sortStates.sortStates.DESC:
|
|
31
|
+
return sortStates.sortStates.NONE;
|
|
34
32
|
}
|
|
35
|
-
if (prevState === 'ASC') {
|
|
36
|
-
return sortStates.sortStates.DESC;
|
|
37
|
-
}
|
|
38
|
-
return sortStates.sortStates.NONE;
|
|
39
33
|
}
|
|
40
|
-
|
|
41
|
-
//
|
|
34
|
+
|
|
35
|
+
// Sorting a new header starts at ascending order.
|
|
42
36
|
return sortStates.sortStates.ASC;
|
|
43
37
|
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Gets the next sort state.
|
|
41
|
+
*
|
|
42
|
+
* @param props - Component props.
|
|
43
|
+
* @param state - Current table state.
|
|
44
|
+
* @param key - Header key to sort by.
|
|
45
|
+
*/
|
|
44
46
|
const getNextSortState = (props, state, {
|
|
45
47
|
key
|
|
46
48
|
}) => {
|
|
@@ -48,38 +50,26 @@ const getNextSortState = (props, state, {
|
|
|
48
50
|
sortDirection,
|
|
49
51
|
sortHeaderKey
|
|
50
52
|
} = state;
|
|
51
|
-
const nextSortDirection = getNextSortDirection(key, sortHeaderKey, sortDirection);
|
|
53
|
+
const nextSortDirection = getNextSortDirection(key, sortHeaderKey ?? '', sortDirection);
|
|
52
54
|
return getSortedState(props, state, key, nextSortDirection);
|
|
53
55
|
};
|
|
54
56
|
|
|
55
57
|
/**
|
|
56
|
-
*
|
|
57
|
-
* header key and sortDirection
|
|
58
|
+
* Gets a sort state update.
|
|
58
59
|
*
|
|
59
|
-
* @param
|
|
60
|
-
* @param
|
|
61
|
-
* @param
|
|
62
|
-
*
|
|
63
|
-
* @param {object} state
|
|
64
|
-
* @param {Array<string>} state.rowIds Array of row ids
|
|
65
|
-
* @param {object} state.cellsById Lookup object for cells by id
|
|
66
|
-
* @param {Array<string>} state.initialRowOrder Initial row order for the
|
|
67
|
-
* current set of rows
|
|
68
|
-
* @param {string} key The key for the given header we are serving the
|
|
69
|
-
* sorted state for
|
|
70
|
-
* @param {string} sortDirection The sortState that we want to order by
|
|
71
|
-
* @returns {object}
|
|
60
|
+
* @param props - Component props.
|
|
61
|
+
* @param state - Current state of the table.
|
|
62
|
+
* @param key - Header key to sort by.
|
|
63
|
+
* @param sortDirection - Sort direction to apply.
|
|
72
64
|
*/
|
|
73
|
-
const getSortedState = (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
sortRow
|
|
82
|
-
} = props;
|
|
65
|
+
const getSortedState = ({
|
|
66
|
+
locale,
|
|
67
|
+
sortRow
|
|
68
|
+
}, {
|
|
69
|
+
rowIds,
|
|
70
|
+
cellsById,
|
|
71
|
+
initialRowOrder
|
|
72
|
+
}, key, sortDirection) => {
|
|
83
73
|
const nextRowIds = sortDirection !== sortStates.sortStates.NONE ? sorting.sortRows({
|
|
84
74
|
rowIds,
|
|
85
75
|
cellsById,
|
|
@@ -90,12 +80,11 @@ const getSortedState = (props, state, key, sortDirection) => {
|
|
|
90
80
|
}) : initialRowOrder;
|
|
91
81
|
return {
|
|
92
82
|
sortHeaderKey: key,
|
|
93
|
-
sortDirection
|
|
83
|
+
sortDirection,
|
|
94
84
|
rowIds: nextRowIds
|
|
95
85
|
};
|
|
96
86
|
};
|
|
97
87
|
|
|
98
|
-
exports.sortStates = sortStates.sortStates;
|
|
99
88
|
exports.getNextSortDirection = getNextSortDirection;
|
|
100
89
|
exports.getNextSortState = getNextSortState;
|
|
101
90
|
exports.getSortedState = getSortedState;
|