@carbon/react 1.63.2 → 1.64.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 +1562 -1193
- package/es/components/{Slug → AILabel}/index.js +47 -35
- package/es/components/{AiSkeleton/AiSkeletonIcon.d.ts → AISkeleton/AISkeletonIcon.d.ts} +4 -4
- package/es/components/{AiSkeleton/AiSkeletonIcon.js → AISkeleton/AISkeletonIcon.js} +5 -5
- package/es/components/{AiSkeleton/AiSkeletonPlaceholder.d.ts → AISkeleton/AISkeletonPlaceholder.d.ts} +4 -4
- package/es/components/{AiSkeleton/AiSkeletonPlaceholder.js → AISkeleton/AISkeletonPlaceholder.js} +5 -5
- package/es/components/{AiSkeleton/AiSkeletonText.d.ts → AISkeleton/AISkeletonText.d.ts} +4 -4
- package/es/components/{AiSkeleton/AiSkeletonText.js → AISkeleton/AISkeletonText.js} +3 -3
- package/es/components/AISkeleton/index.d.ts +10 -0
- package/es/components/Accordion/AccordionItem.js +1 -0
- package/es/components/CheckboxGroup/CheckboxGroup.js +1 -1
- package/es/components/ComboBox/ComboBox.js +4 -4
- package/es/components/ComposedModal/ComposedModal.js +1 -1
- package/es/components/DataTable/DataTable.js +1 -1
- package/es/components/DatePicker/DatePicker.js +16 -1
- package/es/components/DatePickerInput/DatePickerInput.js +1 -1
- package/es/components/Dropdown/Dropdown.js +12 -6
- package/es/components/FluidMultiSelect/FluidMultiSelect.js +4 -2
- package/es/components/Menu/MenuItem.js +45 -63
- package/es/components/Modal/Modal.js +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.js +44 -23
- package/es/components/MultiSelect/MultiSelect.js +6 -4
- package/es/components/NumberInput/NumberInput.js +12 -4
- package/es/components/OverflowMenu/OverflowMenu.js +2 -1
- package/es/components/OverflowMenu/next/index.js +2 -1
- package/es/components/RadioButtonGroup/RadioButtonGroup.js +1 -1
- package/es/components/RadioTile/RadioTile.js +1 -1
- package/es/components/Select/Select.js +1 -1
- package/es/components/Tabs/Tabs.js +3 -3
- package/es/components/Tag/DismissibleTag.js +1 -1
- package/es/components/Tag/OperationalTag.js +1 -1
- package/es/components/Tag/SelectableTag.js +3 -1
- package/es/components/Tag/Tag.js +1 -1
- package/es/components/TextArea/TextArea.js +1 -1
- package/es/components/TextInput/PasswordInput.js +5 -0
- package/es/components/TextInput/TextInput.js +1 -1
- package/es/components/Tile/Tile.js +2 -2
- package/es/components/TreeView/TreeNode.d.ts +150 -0
- package/es/components/TreeView/TreeNode.js +22 -15
- package/es/components/TreeView/TreeView.d.ts +59 -0
- package/es/components/TreeView/TreeView.js +37 -23
- package/es/components/TreeView/index.d.ts +11 -0
- package/es/components/UIShell/SwitcherItem.d.ts +4 -0
- package/es/components/UIShell/SwitcherItem.js +7 -1
- package/es/index.d.ts +4 -2
- package/es/index.js +6 -6
- package/es/node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js +143 -0
- package/es/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs.js +39 -0
- package/lib/components/{Slug → AILabel}/index.js +49 -37
- package/lib/components/{AiSkeleton/AiSkeletonIcon.d.ts → AISkeleton/AISkeletonIcon.d.ts} +4 -4
- package/lib/components/{AiSkeleton/AiSkeletonIcon.js → AISkeleton/AISkeletonIcon.js} +5 -5
- package/lib/components/{AiSkeleton/AiSkeletonPlaceholder.d.ts → AISkeleton/AISkeletonPlaceholder.d.ts} +4 -4
- package/lib/components/{AiSkeleton/AiSkeletonPlaceholder.js → AISkeleton/AISkeletonPlaceholder.js} +5 -5
- package/lib/components/{AiSkeleton/AiSkeletonText.d.ts → AISkeleton/AISkeletonText.d.ts} +4 -4
- package/lib/components/{AiSkeleton/AiSkeletonText.js → AISkeleton/AISkeletonText.js} +3 -3
- package/lib/components/AISkeleton/index.d.ts +10 -0
- package/lib/components/Accordion/AccordionItem.js +1 -0
- package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -1
- package/lib/components/ComboBox/ComboBox.js +4 -4
- package/lib/components/ComposedModal/ComposedModal.js +1 -1
- package/lib/components/DataTable/DataTable.js +2 -2
- package/lib/components/DatePicker/DatePicker.js +15 -0
- package/lib/components/DatePickerInput/DatePickerInput.js +1 -1
- package/lib/components/Dropdown/Dropdown.js +12 -6
- package/lib/components/FluidMultiSelect/FluidMultiSelect.js +4 -2
- package/lib/components/Menu/MenuItem.js +44 -62
- package/lib/components/Modal/Modal.js +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.js +43 -22
- package/lib/components/MultiSelect/MultiSelect.js +6 -4
- package/lib/components/NumberInput/NumberInput.js +12 -4
- package/lib/components/OverflowMenu/OverflowMenu.js +2 -1
- package/lib/components/OverflowMenu/next/index.js +2 -1
- package/lib/components/RadioButtonGroup/RadioButtonGroup.js +1 -1
- package/lib/components/RadioTile/RadioTile.js +1 -1
- package/lib/components/Select/Select.js +1 -1
- package/lib/components/Tabs/Tabs.js +2 -2
- package/lib/components/Tag/DismissibleTag.js +1 -1
- package/lib/components/Tag/OperationalTag.js +1 -1
- package/lib/components/Tag/SelectableTag.js +3 -1
- package/lib/components/Tag/Tag.js +1 -1
- package/lib/components/TextArea/TextArea.js +1 -1
- package/lib/components/TextInput/PasswordInput.js +5 -0
- package/lib/components/TextInput/TextInput.js +1 -1
- package/lib/components/Tile/Tile.js +2 -2
- package/lib/components/TreeView/TreeNode.d.ts +150 -0
- package/lib/components/TreeView/TreeNode.js +24 -17
- package/lib/components/TreeView/TreeView.d.ts +59 -0
- package/lib/components/TreeView/TreeView.js +39 -25
- package/lib/components/TreeView/index.d.ts +11 -0
- package/lib/components/UIShell/SwitcherItem.d.ts +4 -0
- package/lib/components/UIShell/SwitcherItem.js +7 -1
- package/lib/index.d.ts +4 -2
- package/lib/index.js +20 -14
- package/lib/node_modules/@floating-ui/core/dist/floating-ui.core.mjs.js +148 -0
- package/lib/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs.js +47 -0
- package/package.json +5 -5
- package/scss/components/ai-label/_ai-label.scss +9 -0
- package/scss/components/ai-label/_index.scss +9 -0
- package/es/components/AiSkeleton/index.d.ts +0 -10
- package/es/components/DataTable/tools/instanceId.js +0 -20
- package/lib/components/AiSkeleton/index.d.ts +0 -10
- package/lib/components/DataTable/tools/instanceId.js +0 -24
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
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 React, { ComponentType, FunctionComponent } from 'react';
|
|
8
|
+
export type TreeNodeProps = {
|
|
9
|
+
/**
|
|
10
|
+
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
11
|
+
* The ID of the active node in the tree
|
|
12
|
+
*/
|
|
13
|
+
active?: string | number;
|
|
14
|
+
/**
|
|
15
|
+
* Specify the children of the TreeNode
|
|
16
|
+
*/
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Specify an optional className to be applied to the TreeNode
|
|
20
|
+
*/
|
|
21
|
+
className?: string;
|
|
22
|
+
/**
|
|
23
|
+
* **[Experimental]** The default expansion state of the node.
|
|
24
|
+
* *This is only supported with the `enable-treeview-controllable` feature flag!*
|
|
25
|
+
*/
|
|
26
|
+
defaultIsExpanded?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
29
|
+
* TreeNode depth to determine spacing
|
|
30
|
+
*/
|
|
31
|
+
depth?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Specify if the TreeNode is disabled
|
|
34
|
+
*/
|
|
35
|
+
disabled?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Specify the TreeNode's ID. Must be unique in the DOM and is used for props.active and props.selected
|
|
38
|
+
*/
|
|
39
|
+
id?: string;
|
|
40
|
+
/**
|
|
41
|
+
* Specify if the TreeNode is expanded (only applicable to parent nodes)
|
|
42
|
+
*/
|
|
43
|
+
isExpanded?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Rendered label for the TreeNode
|
|
46
|
+
*/
|
|
47
|
+
label: React.ReactNode;
|
|
48
|
+
/**
|
|
49
|
+
* Callback function for when the node receives or loses focus
|
|
50
|
+
*/
|
|
51
|
+
onNodeFocusEvent?: (event: React.FocusEvent<HTMLLIElement>) => void;
|
|
52
|
+
/**
|
|
53
|
+
* Callback function for when the node is selected
|
|
54
|
+
*/
|
|
55
|
+
onSelect?: (event: React.MouseEvent, node?: TreeNodeProps) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Callback function for when a parent node is expanded or collapsed
|
|
58
|
+
*/
|
|
59
|
+
onToggle?: (event: React.MouseEvent, node?: TreeNodeProps) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Callback function for when any node in the tree is selected
|
|
62
|
+
*/
|
|
63
|
+
onTreeSelect?: (event: React.MouseEvent, node?: TreeNodeProps) => void;
|
|
64
|
+
/**
|
|
65
|
+
* Optional prop to allow each node to have an associated icon.
|
|
66
|
+
* Can be a React component class
|
|
67
|
+
*/
|
|
68
|
+
renderIcon?: ComponentType | FunctionComponent;
|
|
69
|
+
/**
|
|
70
|
+
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
71
|
+
* Array containing all selected node IDs in the tree
|
|
72
|
+
*/
|
|
73
|
+
selected?: Array<string | number>;
|
|
74
|
+
/**
|
|
75
|
+
* Specify the value of the TreeNode
|
|
76
|
+
*/
|
|
77
|
+
value?: string;
|
|
78
|
+
} & Omit<React.LiHTMLAttributes<HTMLLIElement>, 'onSelect'>;
|
|
79
|
+
declare const TreeNode: React.ForwardRefExoticComponent<{
|
|
80
|
+
/**
|
|
81
|
+
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
82
|
+
* The ID of the active node in the tree
|
|
83
|
+
*/
|
|
84
|
+
active?: string | number | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Specify the children of the TreeNode
|
|
87
|
+
*/
|
|
88
|
+
children?: React.ReactNode;
|
|
89
|
+
/**
|
|
90
|
+
* Specify an optional className to be applied to the TreeNode
|
|
91
|
+
*/
|
|
92
|
+
className?: string | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* **[Experimental]** The default expansion state of the node.
|
|
95
|
+
* *This is only supported with the `enable-treeview-controllable` feature flag!*
|
|
96
|
+
*/
|
|
97
|
+
defaultIsExpanded?: boolean | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
100
|
+
* TreeNode depth to determine spacing
|
|
101
|
+
*/
|
|
102
|
+
depth?: number | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Specify if the TreeNode is disabled
|
|
105
|
+
*/
|
|
106
|
+
disabled?: boolean | undefined;
|
|
107
|
+
/**
|
|
108
|
+
* Specify the TreeNode's ID. Must be unique in the DOM and is used for props.active and props.selected
|
|
109
|
+
*/
|
|
110
|
+
id?: string | undefined;
|
|
111
|
+
/**
|
|
112
|
+
* Specify if the TreeNode is expanded (only applicable to parent nodes)
|
|
113
|
+
*/
|
|
114
|
+
isExpanded?: boolean | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Rendered label for the TreeNode
|
|
117
|
+
*/
|
|
118
|
+
label: React.ReactNode;
|
|
119
|
+
/**
|
|
120
|
+
* Callback function for when the node receives or loses focus
|
|
121
|
+
*/
|
|
122
|
+
onNodeFocusEvent?: ((event: React.FocusEvent<HTMLLIElement>) => void) | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* Callback function for when the node is selected
|
|
125
|
+
*/
|
|
126
|
+
onSelect?: ((event: React.MouseEvent, node?: TreeNodeProps) => void) | undefined;
|
|
127
|
+
/**
|
|
128
|
+
* Callback function for when a parent node is expanded or collapsed
|
|
129
|
+
*/
|
|
130
|
+
onToggle?: ((event: React.MouseEvent, node?: TreeNodeProps) => void) | undefined;
|
|
131
|
+
/**
|
|
132
|
+
* Callback function for when any node in the tree is selected
|
|
133
|
+
*/
|
|
134
|
+
onTreeSelect?: ((event: React.MouseEvent, node?: TreeNodeProps) => void) | undefined;
|
|
135
|
+
/**
|
|
136
|
+
* Optional prop to allow each node to have an associated icon.
|
|
137
|
+
* Can be a React component class
|
|
138
|
+
*/
|
|
139
|
+
renderIcon?: React.ComponentType<{}> | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
142
|
+
* Array containing all selected node IDs in the tree
|
|
143
|
+
*/
|
|
144
|
+
selected?: (string | number)[] | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Specify the value of the TreeNode
|
|
147
|
+
*/
|
|
148
|
+
value?: string | undefined;
|
|
149
|
+
} & Omit<React.LiHTMLAttributes<HTMLLIElement>, "onSelect"> & React.RefAttributes<HTMLLIElement>>;
|
|
150
|
+
export default TreeNode;
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React__default, { useRef, useState, useEffect } from 'react';
|
|
10
|
-
import PropTypes from 'prop-types';
|
|
11
9
|
import { CaretDown } from '@carbon/icons-react';
|
|
12
10
|
import cx from 'classnames';
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
11
|
+
import PropTypes from 'prop-types';
|
|
12
|
+
import React__default, { useRef, useState, useEffect } from 'react';
|
|
15
13
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
14
|
+
import { usePrefix } from '../../internal/usePrefix.js';
|
|
15
|
+
import uniqueId from '../../tools/uniqueId.js';
|
|
16
16
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
17
17
|
import { matches, match } from '../../internal/keyboard/match.js';
|
|
18
18
|
import { ArrowLeft, ArrowRight, Enter, Space } from '../../internal/keyboard/keys.js';
|
|
@@ -22,7 +22,7 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
22
22
|
active,
|
|
23
23
|
children,
|
|
24
24
|
className,
|
|
25
|
-
depth,
|
|
25
|
+
depth: propDepth,
|
|
26
26
|
disabled,
|
|
27
27
|
id: nodeId,
|
|
28
28
|
isExpanded,
|
|
@@ -33,10 +33,13 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
33
33
|
onToggle,
|
|
34
34
|
onTreeSelect,
|
|
35
35
|
renderIcon: Icon,
|
|
36
|
-
selected,
|
|
36
|
+
selected: propSelected,
|
|
37
37
|
value,
|
|
38
38
|
...rest
|
|
39
39
|
} = _ref;
|
|
40
|
+
// These are provided by the parent TreeView component
|
|
41
|
+
const depth = propDepth;
|
|
42
|
+
const selected = propSelected;
|
|
40
43
|
const enableTreeviewControllable = useFeatureFlag('enable-treeview-controllable');
|
|
41
44
|
const {
|
|
42
45
|
current: id
|
|
@@ -141,7 +144,7 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
141
144
|
* When focus is on a leaf node or a closed parent node, move focus to
|
|
142
145
|
* its parent node (unless its depth is level 1)
|
|
143
146
|
*/
|
|
144
|
-
findParentTreeNode(currentNode.current
|
|
147
|
+
findParentTreeNode(currentNode.current?.parentNode)?.focus();
|
|
145
148
|
}
|
|
146
149
|
}
|
|
147
150
|
if (children && match(event, ArrowRight)) {
|
|
@@ -150,7 +153,7 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
150
153
|
* When focus is on an expanded parent node, move focus to the first
|
|
151
154
|
* child node
|
|
152
155
|
*/
|
|
153
|
-
currentNode.current
|
|
156
|
+
(currentNode.current?.lastChild?.firstChild).focus();
|
|
154
157
|
} else {
|
|
155
158
|
if (!enableTreeviewControllable) {
|
|
156
159
|
onToggle?.(event, {
|
|
@@ -217,8 +220,8 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
217
220
|
}, [children, depth, Icon, isExpanded, enableTreeviewControllable, setExpanded]);
|
|
218
221
|
const treeNodeProps = {
|
|
219
222
|
...rest,
|
|
220
|
-
['aria-current']: isActive ||
|
|
221
|
-
['aria-selected']: disabled ?
|
|
223
|
+
['aria-current']: isActive || undefined,
|
|
224
|
+
['aria-selected']: disabled ? undefined : isSelected,
|
|
222
225
|
['aria-disabled']: disabled,
|
|
223
226
|
className: treeNodeClasses,
|
|
224
227
|
id,
|
|
@@ -226,8 +229,9 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
226
229
|
onClick: handleClick,
|
|
227
230
|
onFocus: handleFocusEvent,
|
|
228
231
|
onKeyDown: handleKeyDown,
|
|
229
|
-
|
|
230
|
-
|
|
232
|
+
role: 'treeitem',
|
|
233
|
+
// @ts-ignore
|
|
234
|
+
ref: currentNode
|
|
231
235
|
};
|
|
232
236
|
if (!children) {
|
|
233
237
|
return /*#__PURE__*/React__default.createElement("li", treeNodeProps, /*#__PURE__*/React__default.createElement("div", {
|
|
@@ -247,7 +251,9 @@ const TreeNode = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
247
251
|
className: `${prefix}--tree-node__label`,
|
|
248
252
|
ref: currentNodeLabel
|
|
249
253
|
}, /*#__PURE__*/React__default.createElement("span", {
|
|
250
|
-
className: `${prefix}--tree-parent-node__toggle
|
|
254
|
+
className: `${prefix}--tree-parent-node__toggle`
|
|
255
|
+
// @ts-ignore
|
|
256
|
+
,
|
|
251
257
|
disabled: disabled,
|
|
252
258
|
onClick: handleToggleClick
|
|
253
259
|
}, /*#__PURE__*/React__default.createElement(CaretDown, {
|
|
@@ -322,11 +328,13 @@ TreeNode.propTypes = {
|
|
|
322
328
|
* Optional prop to allow each node to have an associated icon.
|
|
323
329
|
* Can be a React component class
|
|
324
330
|
*/
|
|
331
|
+
// @ts-ignore
|
|
325
332
|
renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
326
333
|
/**
|
|
327
334
|
* **Note:** this is controlled by the parent TreeView component, do not set manually.
|
|
328
335
|
* Array containing all selected node IDs in the tree
|
|
329
336
|
*/
|
|
337
|
+
// @ts-ignore
|
|
330
338
|
selected: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number])),
|
|
331
339
|
/**
|
|
332
340
|
* Specify the value of the TreeNode
|
|
@@ -334,6 +342,5 @@ TreeNode.propTypes = {
|
|
|
334
342
|
value: PropTypes.string
|
|
335
343
|
};
|
|
336
344
|
TreeNode.displayName = 'TreeNode';
|
|
337
|
-
var TreeNode$1 = TreeNode;
|
|
338
345
|
|
|
339
|
-
export { TreeNode
|
|
346
|
+
export { TreeNode as default };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
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 React from 'react';
|
|
8
|
+
import TreeNode from './TreeNode';
|
|
9
|
+
export type TreeViewProps = {
|
|
10
|
+
/**
|
|
11
|
+
* Mark the active node in the tree, represented by its ID
|
|
12
|
+
*/
|
|
13
|
+
active?: string | number;
|
|
14
|
+
/**
|
|
15
|
+
* Specify the children of the TreeView
|
|
16
|
+
*/
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Specify an optional className to be applied to the TreeView
|
|
20
|
+
*/
|
|
21
|
+
className?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Specify whether or not the label should be hidden
|
|
24
|
+
*/
|
|
25
|
+
hideLabel?: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Provide the label text that will be read by a screen reader
|
|
28
|
+
*/
|
|
29
|
+
label: string;
|
|
30
|
+
/**
|
|
31
|
+
* **[Experimental]** Specify the selection mode of the tree.
|
|
32
|
+
* If `multiselect` is `false` then only one node can be selected at a time
|
|
33
|
+
*/
|
|
34
|
+
multiselect?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* **[Experimental]** Callback function that is called when any node is activated.
|
|
37
|
+
* *This is only supported with the `enable-treeview-controllable` feature flag!*
|
|
38
|
+
*/
|
|
39
|
+
onActivate?: (activated?: string | number) => void;
|
|
40
|
+
/**
|
|
41
|
+
* Callback function that is called when any node is selected
|
|
42
|
+
*/
|
|
43
|
+
onSelect?: (selected: Array<string | number>, payload: any) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Array representing all selected node IDs in the tree
|
|
46
|
+
*/
|
|
47
|
+
selected?: Array<string | number>;
|
|
48
|
+
/**
|
|
49
|
+
* Specify the size of the tree from a list of available sizes.
|
|
50
|
+
*/
|
|
51
|
+
size?: 'xs' | 'sm';
|
|
52
|
+
} & React.HTMLAttributes<HTMLUListElement>;
|
|
53
|
+
type TreeViewComponent = {
|
|
54
|
+
(props: TreeViewProps): JSX.Element;
|
|
55
|
+
propTypes?: any;
|
|
56
|
+
TreeNode: typeof TreeNode;
|
|
57
|
+
};
|
|
58
|
+
declare const TreeView: TreeViewComponent;
|
|
59
|
+
export default TreeView;
|
|
@@ -6,17 +6,18 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React__default, { useRef, useState, useEffect } from 'react';
|
|
10
|
-
import PropTypes from 'prop-types';
|
|
11
9
|
import cx from 'classnames';
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
10
|
+
import PropTypes from 'prop-types';
|
|
11
|
+
import React__default, { useRef, useState, useEffect } from 'react';
|
|
14
12
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
13
|
+
import { usePrefix } from '../../internal/usePrefix.js';
|
|
14
|
+
import uniqueId from '../../tools/uniqueId.js';
|
|
15
15
|
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
16
|
+
import TreeNode from './TreeNode.js';
|
|
16
17
|
import { matches, match } from '../../internal/keyboard/match.js';
|
|
17
18
|
import { ArrowUp, ArrowDown, Home, End } from '../../internal/keyboard/keys.js';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
const TreeView = _ref => {
|
|
20
21
|
let {
|
|
21
22
|
active: prespecifiedActive,
|
|
22
23
|
children,
|
|
@@ -36,6 +37,7 @@ function TreeView(_ref) {
|
|
|
36
37
|
} = useRef(rest.id || uniqueId());
|
|
37
38
|
const prefix = usePrefix();
|
|
38
39
|
const treeClasses = cx(className, `${prefix}--tree`, {
|
|
40
|
+
// @ts-ignore - will always be false according to prop types
|
|
39
41
|
[`${prefix}--tree--${size}`]: size !== 'default'
|
|
40
42
|
});
|
|
41
43
|
const treeRootRef = useRef(null);
|
|
@@ -61,9 +63,7 @@ function TreeView(_ref) {
|
|
|
61
63
|
}
|
|
62
64
|
function handleTreeSelect(event) {
|
|
63
65
|
let node = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
64
|
-
const
|
|
65
|
-
id: nodeId
|
|
66
|
-
} = node;
|
|
66
|
+
const nodeId = node.id;
|
|
67
67
|
if (multiselect && (event.metaKey || event.ctrlKey)) {
|
|
68
68
|
if (!selected.includes(nodeId)) {
|
|
69
69
|
setSelected(selected.concat(nodeId));
|
|
@@ -107,14 +107,15 @@ function TreeView(_ref) {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
let focusTarget = false;
|
|
110
|
-
const nodesWithProps = React__default.Children.map(children,
|
|
110
|
+
const nodesWithProps = React__default.Children.map(children, _node => {
|
|
111
|
+
const node = _node;
|
|
111
112
|
const sharedNodeProps = {
|
|
112
113
|
active,
|
|
113
114
|
depth: 0,
|
|
114
115
|
onNodeFocusEvent: handleFocusEvent,
|
|
115
116
|
onTreeSelect: handleTreeSelect,
|
|
116
117
|
selected,
|
|
117
|
-
tabIndex: !node.props.disabled && -1 ||
|
|
118
|
+
tabIndex: !node.props.disabled && -1 || undefined
|
|
118
119
|
};
|
|
119
120
|
if (!focusTarget && !node.props.disabled) {
|
|
120
121
|
sharedNodeProps.tabIndex = 0;
|
|
@@ -126,40 +127,47 @@ function TreeView(_ref) {
|
|
|
126
127
|
});
|
|
127
128
|
function handleKeyDown(event) {
|
|
128
129
|
event.stopPropagation();
|
|
129
|
-
if (matches(event, [ArrowUp, ArrowDown, Home, End,
|
|
130
|
+
if (matches(event, [ArrowUp, ArrowDown, Home, End,
|
|
131
|
+
// @ts-ignore - `matches` doesn't like the object syntax without missing properties
|
|
132
|
+
{
|
|
130
133
|
code: 'KeyA'
|
|
131
134
|
}])) {
|
|
132
135
|
event.preventDefault();
|
|
133
136
|
}
|
|
137
|
+
if (!treeWalker.current) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
134
140
|
treeWalker.current.currentNode = event.target;
|
|
135
|
-
let nextFocusNode;
|
|
141
|
+
let nextFocusNode = null;
|
|
136
142
|
if (match(event, ArrowUp)) {
|
|
137
143
|
nextFocusNode = treeWalker.current.previousNode();
|
|
138
144
|
}
|
|
139
145
|
if (match(event, ArrowDown)) {
|
|
140
146
|
nextFocusNode = treeWalker.current.nextNode();
|
|
141
147
|
}
|
|
148
|
+
// @ts-ignore - `matches` doesn't like the object syntax without missing properties
|
|
142
149
|
if (matches(event, [Home, End, {
|
|
143
150
|
code: 'KeyA'
|
|
144
151
|
}])) {
|
|
145
152
|
const nodeIds = [];
|
|
146
153
|
if (matches(event, [Home, End])) {
|
|
147
|
-
if (multiselect && event.shiftKey && event.ctrlKey && !treeWalker.current.currentNode.getAttribute('aria-disabled')) {
|
|
154
|
+
if (multiselect && event.shiftKey && event.ctrlKey && treeWalker.current.currentNode instanceof Element && !treeWalker.current.currentNode.getAttribute('aria-disabled')) {
|
|
148
155
|
nodeIds.push(treeWalker.current.currentNode?.id);
|
|
149
156
|
}
|
|
150
157
|
while (match(event, Home) ? treeWalker.current.previousNode() : treeWalker.current.nextNode()) {
|
|
151
158
|
nextFocusNode = treeWalker.current.currentNode;
|
|
152
|
-
if (multiselect && event.shiftKey && event.ctrlKey && !nextFocusNode.getAttribute('aria-disabled')) {
|
|
159
|
+
if (multiselect && event.shiftKey && event.ctrlKey && nextFocusNode instanceof Element && !nextFocusNode.getAttribute('aria-disabled')) {
|
|
153
160
|
nodeIds.push(nextFocusNode?.id);
|
|
154
161
|
}
|
|
155
162
|
}
|
|
156
163
|
}
|
|
164
|
+
// @ts-ignore - `matches` doesn't like the object syntax without missing properties
|
|
157
165
|
if (match(event, {
|
|
158
166
|
code: 'KeyA'
|
|
159
167
|
}) && event.ctrlKey) {
|
|
160
168
|
treeWalker.current.currentNode = treeWalker.current.root;
|
|
161
169
|
while (treeWalker.current.nextNode()) {
|
|
162
|
-
if (!treeWalker.current.currentNode.getAttribute('aria-disabled')) {
|
|
170
|
+
if (treeWalker.current.currentNode instanceof Element && !treeWalker.current.currentNode.getAttribute('aria-disabled')) {
|
|
163
171
|
nodeIds.push(treeWalker.current.currentNode?.id);
|
|
164
172
|
}
|
|
165
173
|
}
|
|
@@ -168,14 +176,19 @@ function TreeView(_ref) {
|
|
|
168
176
|
}
|
|
169
177
|
if (nextFocusNode && nextFocusNode !== event.target) {
|
|
170
178
|
resetNodeTabIndices();
|
|
171
|
-
nextFocusNode
|
|
172
|
-
|
|
179
|
+
if (nextFocusNode instanceof HTMLElement) {
|
|
180
|
+
nextFocusNode.tabIndex = 0;
|
|
181
|
+
nextFocusNode.focus();
|
|
182
|
+
}
|
|
173
183
|
}
|
|
174
184
|
rest?.onKeyDown?.(event);
|
|
175
185
|
}
|
|
176
186
|
useEffect(() => {
|
|
177
187
|
treeWalker.current = treeWalker.current ?? document.createTreeWalker(treeRootRef?.current, NodeFilter.SHOW_ELEMENT, {
|
|
178
188
|
acceptNode: function (node) {
|
|
189
|
+
if (!(node instanceof Element)) {
|
|
190
|
+
return NodeFilter.FILTER_SKIP;
|
|
191
|
+
}
|
|
179
192
|
if (node.classList.contains(`${prefix}--tree-node--disabled`)) {
|
|
180
193
|
return NodeFilter.FILTER_REJECT;
|
|
181
194
|
}
|
|
@@ -198,20 +211,20 @@ function TreeView(_ref) {
|
|
|
198
211
|
}, []);
|
|
199
212
|
useActiveAndSelectedOnMount();
|
|
200
213
|
const labelId = `${treeId}__label`;
|
|
201
|
-
const TreeLabel = () => !hideLabel
|
|
214
|
+
const TreeLabel = () => !hideLabel ? /*#__PURE__*/React__default.createElement("label", {
|
|
202
215
|
id: labelId,
|
|
203
216
|
className: `${prefix}--label`
|
|
204
|
-
}, label);
|
|
217
|
+
}, label) : null;
|
|
205
218
|
return /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement(TreeLabel, null), /*#__PURE__*/React__default.createElement("ul", _extends({}, rest, {
|
|
206
|
-
"aria-label": hideLabel ? label :
|
|
207
|
-
"aria-labelledby": !hideLabel ? labelId :
|
|
208
|
-
"aria-multiselectable": multiselect ||
|
|
219
|
+
"aria-label": hideLabel ? label : undefined,
|
|
220
|
+
"aria-labelledby": !hideLabel ? labelId : undefined,
|
|
221
|
+
"aria-multiselectable": multiselect || undefined,
|
|
209
222
|
className: treeClasses,
|
|
210
223
|
onKeyDown: handleKeyDown,
|
|
211
224
|
ref: treeRootRef,
|
|
212
225
|
role: "tree"
|
|
213
226
|
}), nodesWithProps));
|
|
214
|
-
}
|
|
227
|
+
};
|
|
215
228
|
TreeView.propTypes = {
|
|
216
229
|
/**
|
|
217
230
|
* Mark the active node in the tree, represented by its ID
|
|
@@ -256,5 +269,6 @@ TreeView.propTypes = {
|
|
|
256
269
|
*/
|
|
257
270
|
size: PropTypes.oneOf(['xs', 'sm'])
|
|
258
271
|
};
|
|
272
|
+
TreeView.TreeNode = TreeNode;
|
|
259
273
|
|
|
260
274
|
export { TreeView as default };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
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 TreeNode, { TreeNodeProps } from './TreeNode';
|
|
8
|
+
import TreeView, { TreeViewProps } from './TreeView';
|
|
9
|
+
export { TreeNode, TreeView };
|
|
10
|
+
export type { TreeViewProps, TreeNodeProps };
|
|
11
|
+
export default TreeView;
|
|
@@ -47,6 +47,10 @@ interface BaseSwitcherItemProps {
|
|
|
47
47
|
* Specify where to open the link.
|
|
48
48
|
*/
|
|
49
49
|
target?: HTMLAttributeAnchorTarget;
|
|
50
|
+
/**
|
|
51
|
+
* The rel property for the link.
|
|
52
|
+
*/
|
|
53
|
+
rel?: string;
|
|
50
54
|
}
|
|
51
55
|
interface SwitcherItemWithAriaLabel extends BaseSwitcherItemProps {
|
|
52
56
|
'aria-label': string;
|
|
@@ -29,6 +29,7 @@ const SwitcherItem = /*#__PURE__*/forwardRef(function SwitcherItem(props, forwar
|
|
|
29
29
|
onKeyDown = () => {},
|
|
30
30
|
href,
|
|
31
31
|
target,
|
|
32
|
+
rel,
|
|
32
33
|
...rest
|
|
33
34
|
} = props;
|
|
34
35
|
const prefix = usePrefix();
|
|
@@ -67,6 +68,7 @@ const SwitcherItem = /*#__PURE__*/forwardRef(function SwitcherItem(props, forwar
|
|
|
67
68
|
},
|
|
68
69
|
href: href,
|
|
69
70
|
target: target,
|
|
71
|
+
rel: rel,
|
|
70
72
|
ref: forwardRef
|
|
71
73
|
}, rest, {
|
|
72
74
|
className: linkClassName,
|
|
@@ -111,7 +113,11 @@ SwitcherItem.propTypes = {
|
|
|
111
113
|
/**
|
|
112
114
|
* Specify where to open the link.
|
|
113
115
|
*/
|
|
114
|
-
target: PropTypes.string
|
|
116
|
+
target: PropTypes.string,
|
|
117
|
+
/**
|
|
118
|
+
* The rel property for the link.
|
|
119
|
+
*/
|
|
120
|
+
rel: PropTypes.string
|
|
115
121
|
};
|
|
116
122
|
|
|
117
123
|
export { SwitcherItem as default };
|
package/es/index.d.ts
CHANGED
|
@@ -116,9 +116,11 @@ export { OverflowMenuV2 as unstable_OverflowMenuV2 } from './components/Overflow
|
|
|
116
116
|
export { PageSelector as unstable_PageSelector, Pagination as unstable_Pagination, } from './components/Pagination/experimental';
|
|
117
117
|
export * from './components/Popover';
|
|
118
118
|
export * from './components/ProgressBar';
|
|
119
|
-
export {
|
|
119
|
+
export { AILabel, AILabelContent, AILabelActions } from './components/AILabel';
|
|
120
|
+
export { AILabel as unstable__Slug, AILabelContent as unstable__SlugContent, AILabelActions as unstable__SlugActions, } from './components/AILabel';
|
|
120
121
|
export { ChatButton as unstable__ChatButton, ChatButtonSkeleton as unstable__ChatButtonSkeleton, } from './components/ChatButton';
|
|
121
|
-
export {
|
|
122
|
+
export { AISkeletonText, AISkeletonIcon, AISkeletonPlaceholder, } from './components/AISkeleton';
|
|
123
|
+
export { AISkeletonText as unstable__AiSkeletonText, AISkeletonIcon as unstable__AiSkeletonIcon, AISkeletonPlaceholder as unstable__AiSkeletonPlaceholder, } from './components/AISkeleton';
|
|
122
124
|
export * from './components/Stack';
|
|
123
125
|
export * from './components/Tooltip';
|
|
124
126
|
export { Text as unstable_Text, TextDirection as unstable_TextDirection, } from './components/Text';
|
package/es/index.js
CHANGED
|
@@ -126,6 +126,8 @@ export { Toggle } from './components/Toggle/Toggle.js';
|
|
|
126
126
|
export { default as ToggleSkeleton } from './components/Toggle/Toggle.Skeleton.js';
|
|
127
127
|
export { default as ToggleSmallSkeleton } from './components/ToggleSmall/ToggleSmall.Skeleton.js';
|
|
128
128
|
export { Toggletip, ToggletipActions, ToggletipButton, ToggletipContent, ToggletipLabel } from './components/Toggletip/index.js';
|
|
129
|
+
export { default as TreeNode } from './components/TreeView/TreeNode.js';
|
|
130
|
+
export { default as TreeView } from './components/TreeView/TreeView.js';
|
|
129
131
|
export { default as Content } from './components/UIShell/Content.js';
|
|
130
132
|
export { default as Header } from './components/UIShell/Header.js';
|
|
131
133
|
export { default as HeaderContainer } from './components/UIShell/HeaderContainer.js';
|
|
@@ -164,10 +166,10 @@ export { Layout as unstable_Layout } from './components/Layout/index.js';
|
|
|
164
166
|
export { OverflowMenuV2 as unstable_OverflowMenuV2 } from './components/OverflowMenuV2/index.js';
|
|
165
167
|
export { Popover, PopoverContent } from './components/Popover/index.js';
|
|
166
168
|
export { default as ProgressBar } from './components/ProgressBar/ProgressBar.js';
|
|
167
|
-
export {
|
|
168
|
-
export { default as unstable__AiSkeletonPlaceholder } from './components/
|
|
169
|
-
export { default as unstable__AiSkeletonIcon } from './components/
|
|
170
|
-
export { default as unstable__AiSkeletonText } from './components/
|
|
169
|
+
export { AILabel, AILabelActions, AILabelContent, AILabel as unstable__Slug, AILabelActions as unstable__SlugActions, AILabelContent as unstable__SlugContent } from './components/AILabel/index.js';
|
|
170
|
+
export { default as AISkeletonPlaceholder, default as unstable__AiSkeletonPlaceholder } from './components/AISkeleton/AISkeletonPlaceholder.js';
|
|
171
|
+
export { default as AISkeletonIcon, default as unstable__AiSkeletonIcon } from './components/AISkeleton/AISkeletonIcon.js';
|
|
172
|
+
export { default as AISkeletonText, default as unstable__AiSkeletonText } from './components/AISkeleton/AISkeletonText.js';
|
|
171
173
|
export { DefinitionTooltip } from './components/Tooltip/DefinitionTooltip.js';
|
|
172
174
|
export { Tooltip } from './components/Tooltip/Tooltip.js';
|
|
173
175
|
import './components/Text/index.js';
|
|
@@ -188,7 +190,6 @@ export { default as useContextMenu } from './components/ContextMenu/useContextMe
|
|
|
188
190
|
export { default as SliderSkeleton } from './components/Slider/Slider.Skeleton.js';
|
|
189
191
|
export { default as TextInputSkeleton } from './components/TextInput/TextInput.Skeleton.js';
|
|
190
192
|
export { default as TextInput } from './components/TextInput/TextInput.js';
|
|
191
|
-
export { default as TreeView } from './components/TreeView/TreeView.js';
|
|
192
193
|
export { default as unstable__FluidComboBox } from './components/FluidComboBox/FluidComboBox.js';
|
|
193
194
|
export { default as unstable__FluidComboBoxSkeleton } from './components/FluidComboBox/FluidComboBox.Skeleton.js';
|
|
194
195
|
export { default as unstable__FluidDatePicker } from './components/FluidDatePicker/FluidDatePicker.js';
|
|
@@ -234,4 +235,3 @@ export { default as TableToolbarSearch } from './components/DataTable/TableToolb
|
|
|
234
235
|
export { default as TableToolbarMenu } from './components/DataTable/TableToolbarMenu.js';
|
|
235
236
|
export { default as FilterableMultiSelect } from './components/MultiSelect/FilterableMultiSelect.js';
|
|
236
237
|
export { default as MultiSelect } from './components/MultiSelect/MultiSelect.js';
|
|
237
|
-
export { default as TreeNode } from './components/TreeView/TreeNode.js';
|