@carbon/react 1.68.0 → 1.69.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 +871 -871
- package/README.md +3 -3
- package/es/components/Accordion/AccordionItem.js +0 -1
- package/es/components/Button/Button.js +6 -0
- package/es/components/Checkbox/Checkbox.js +1 -1
- package/es/components/CheckboxGroup/CheckboxGroup.js +1 -2
- package/es/components/CheckboxGroup/index.d.ts +10 -0
- package/es/components/ComboBox/ComboBox.js +13 -18
- package/es/components/ComboButton/index.js +10 -3
- package/es/components/DataTable/TableCell.d.ts +1 -4
- package/es/components/DataTable/TableCell.js +3 -2
- package/es/components/Disclosure/index.d.ts +18 -0
- package/es/components/Dropdown/Dropdown.js +11 -9
- package/es/components/FileUploader/FileUploader.d.ts +8 -92
- package/es/components/FileUploader/FileUploader.js +116 -137
- package/es/components/Grid/CSSGrid.js +8 -1
- package/es/components/Grid/Grid.js +4 -0
- package/es/components/IdPrefix/index.d.ts +26 -0
- package/es/components/ListBox/next/ListBoxSelection.d.ts +9 -1
- package/es/components/ListBox/next/ListBoxSelection.js +12 -5
- package/es/components/Menu/MenuItem.js +1 -4
- package/es/components/MenuButton/index.d.ts +4 -0
- package/es/components/MenuButton/index.js +19 -5
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +4 -0
- package/es/components/MultiSelect/FilterableMultiSelect.js +32 -6
- package/es/components/MultiSelect/MultiSelect.js +11 -9
- package/es/components/OverflowMenu/next/index.d.ts +4 -0
- package/es/components/OverflowMenu/next/index.js +19 -9
- package/es/components/PaginationNav/PaginationNav.js +1 -1
- package/es/components/Popover/index.js +18 -14
- package/es/components/Portal/index.d.ts +25 -0
- package/es/components/Slider/Slider.js +2 -2
- package/es/components/Tabs/Tabs.js +46 -20
- package/es/components/Tag/DismissibleTag.js +2 -2
- package/es/components/Tag/OperationalTag.d.ts +2 -10
- package/es/components/Tag/OperationalTag.js +2 -14
- package/es/components/Tag/SelectableTag.d.ts +18 -10
- package/es/components/Tag/SelectableTag.js +22 -28
- package/es/components/Toggle/Toggle.js +2 -0
- package/es/components/ToggleSmall/ToggleSmall.Skeleton.d.ts +49 -0
- package/es/components/ToggleSmall/index.d.ts +7 -0
- package/es/components/TreeView/TreeNode.js +4 -2
- package/es/components/TreeView/TreeView.js +4 -4
- package/es/components/UIShell/SideNavMenuItem.d.ts +4 -3
- package/es/components/UIShell/SideNavMenuItem.js +1 -4
- package/es/index.js +1 -1
- package/es/internal/useIdPrefix.d.ts +9 -0
- package/lib/components/Accordion/AccordionItem.js +0 -1
- package/lib/components/Button/Button.js +6 -0
- package/lib/components/Checkbox/Checkbox.js +1 -1
- package/lib/components/CheckboxGroup/CheckboxGroup.js +1 -2
- package/lib/components/CheckboxGroup/index.d.ts +10 -0
- package/lib/components/ComboBox/ComboBox.js +18 -23
- package/lib/components/ComboButton/index.js +12 -5
- package/lib/components/DataTable/TableCell.d.ts +1 -4
- package/lib/components/DataTable/TableCell.js +3 -2
- package/lib/components/Disclosure/index.d.ts +18 -0
- package/lib/components/Dropdown/Dropdown.js +18 -16
- package/lib/components/FileUploader/FileUploader.d.ts +8 -92
- package/lib/components/FileUploader/FileUploader.js +113 -134
- package/lib/components/Grid/CSSGrid.js +8 -1
- package/lib/components/Grid/Grid.js +4 -0
- package/lib/components/IdPrefix/index.d.ts +26 -0
- package/lib/components/ListBox/next/ListBoxSelection.d.ts +9 -1
- package/lib/components/ListBox/next/ListBoxSelection.js +12 -5
- package/lib/components/Menu/MenuItem.js +1 -4
- package/lib/components/MenuButton/index.d.ts +4 -0
- package/lib/components/MenuButton/index.js +19 -5
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +4 -0
- package/lib/components/MultiSelect/FilterableMultiSelect.js +32 -6
- package/lib/components/MultiSelect/MultiSelect.js +18 -16
- package/lib/components/OverflowMenu/next/index.d.ts +4 -0
- package/lib/components/OverflowMenu/next/index.js +21 -11
- package/lib/components/PaginationNav/PaginationNav.js +1 -1
- package/lib/components/Popover/index.js +18 -14
- package/lib/components/Portal/index.d.ts +25 -0
- package/lib/components/Slider/Slider.js +2 -2
- package/lib/components/Tabs/Tabs.js +46 -20
- package/lib/components/Tag/DismissibleTag.js +2 -2
- package/lib/components/Tag/OperationalTag.d.ts +2 -10
- package/lib/components/Tag/OperationalTag.js +2 -14
- package/lib/components/Tag/SelectableTag.d.ts +18 -10
- package/lib/components/Tag/SelectableTag.js +22 -28
- package/lib/components/Toggle/Toggle.js +2 -0
- package/lib/components/ToggleSmall/ToggleSmall.Skeleton.d.ts +49 -0
- package/lib/components/ToggleSmall/index.d.ts +7 -0
- package/lib/components/TreeView/TreeNode.js +4 -2
- package/lib/components/TreeView/TreeView.js +4 -4
- package/lib/components/UIShell/SideNavMenuItem.d.ts +4 -3
- package/lib/components/UIShell/SideNavMenuItem.js +1 -4
- package/lib/index.js +2 -2
- package/lib/internal/useIdPrefix.d.ts +9 -0
- package/package.json +10 -9
- package/telemetry.yml +809 -809
|
@@ -5,157 +5,137 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
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__default from 'react';
|
|
11
|
+
import React__default, { useState } from 'react';
|
|
12
12
|
import Filename from './Filename.js';
|
|
13
13
|
import FileUploaderButton from './FileUploaderButton.js';
|
|
14
14
|
import { ButtonKinds } from '../../prop-types/types.js';
|
|
15
|
-
import {
|
|
15
|
+
import { usePrefix } from '../../internal/usePrefix.js';
|
|
16
16
|
import '../Text/index.js';
|
|
17
|
+
import { useId } from '../../internal/useId.js';
|
|
17
18
|
import { Text } from '../Text/Text.js';
|
|
18
19
|
import { matches } from '../../internal/keyboard/match.js';
|
|
19
20
|
import { Enter, Space } from '../../internal/keyboard/keys.js';
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
22
|
+
const FileUploader = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
23
|
+
let {
|
|
24
|
+
accept,
|
|
25
|
+
buttonKind,
|
|
26
|
+
buttonLabel,
|
|
27
|
+
className,
|
|
28
|
+
disabled,
|
|
29
|
+
filenameStatus,
|
|
30
|
+
iconDescription,
|
|
31
|
+
labelDescription,
|
|
32
|
+
labelTitle,
|
|
33
|
+
multiple,
|
|
34
|
+
name,
|
|
35
|
+
onChange,
|
|
36
|
+
onClick,
|
|
37
|
+
onDelete,
|
|
38
|
+
size,
|
|
39
|
+
...other
|
|
40
|
+
} = _ref;
|
|
41
|
+
const fileUploaderInstanceId = useId('file-uploader');
|
|
42
|
+
const [state, updateState] = useState({
|
|
43
|
+
fileNames: []
|
|
44
|
+
});
|
|
45
|
+
const nodes = [];
|
|
46
|
+
const prefix = usePrefix();
|
|
47
|
+
const handleChange = evt => {
|
|
48
|
+
evt.stopPropagation();
|
|
49
|
+
const filenames = Array.prototype.map.call(evt.target.files, file => file.name);
|
|
50
|
+
updateState(prevState => ({
|
|
51
|
+
fileNames: multiple ? [...new Set([...prevState.fileNames, ...filenames])] : filenames
|
|
52
|
+
}));
|
|
53
|
+
if (onChange) {
|
|
54
|
+
onChange(evt);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const handleClick = (evt, _ref2) => {
|
|
58
|
+
let {
|
|
59
|
+
index,
|
|
60
|
+
filenameStatus
|
|
61
|
+
} = _ref2;
|
|
62
|
+
if (filenameStatus === 'edit') {
|
|
30
63
|
evt.stopPropagation();
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
|
|
64
|
+
const filteredArray = state.fileNames.filter(filename => filename !== nodes[index]?.innerText?.trim());
|
|
65
|
+
updateState({
|
|
66
|
+
fileNames: filteredArray
|
|
34
67
|
});
|
|
35
|
-
if (
|
|
36
|
-
|
|
68
|
+
if (onDelete) {
|
|
69
|
+
onDelete(evt);
|
|
70
|
+
uploaderButton.current?.focus?.();
|
|
37
71
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
onClick?.(evt);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const uploaderButton = /*#__PURE__*/React__default.createRef();
|
|
76
|
+
const classes = cx({
|
|
77
|
+
[`${prefix}--form-item`]: true,
|
|
78
|
+
[className]: className
|
|
79
|
+
});
|
|
80
|
+
const getHelperLabelClasses = baseClass => cx(baseClass, {
|
|
81
|
+
[`${prefix}--label-description--disabled`]: disabled
|
|
82
|
+
});
|
|
83
|
+
const selectedFileClasses = cx(`${prefix}--file__selected-file`, {
|
|
84
|
+
[`${prefix}--file__selected-file--md`]: size === 'field' || size === 'md',
|
|
85
|
+
[`${prefix}--file__selected-file--sm`]: size === 'small' || size === 'sm'
|
|
86
|
+
});
|
|
87
|
+
return /*#__PURE__*/React__default.createElement("div", _extends({
|
|
88
|
+
className: classes
|
|
89
|
+
}, other), !labelTitle ? null : /*#__PURE__*/React__default.createElement(Text, {
|
|
90
|
+
as: "h3",
|
|
91
|
+
className: getHelperLabelClasses(`${prefix}--file--label`)
|
|
92
|
+
}, labelTitle), /*#__PURE__*/React__default.createElement(Text, {
|
|
93
|
+
as: "p",
|
|
94
|
+
className: getHelperLabelClasses(`${prefix}--label-description`),
|
|
95
|
+
id: fileUploaderInstanceId
|
|
96
|
+
}, labelDescription), /*#__PURE__*/React__default.createElement(FileUploaderButton, {
|
|
97
|
+
innerRef: uploaderButton,
|
|
98
|
+
disabled: disabled,
|
|
99
|
+
labelText: buttonLabel,
|
|
100
|
+
multiple: multiple,
|
|
101
|
+
buttonKind: buttonKind,
|
|
102
|
+
onChange: handleChange,
|
|
103
|
+
disableLabelChanges: true,
|
|
104
|
+
accept: accept,
|
|
105
|
+
name: name,
|
|
106
|
+
size: size,
|
|
107
|
+
"aria-describedby": fileUploaderInstanceId
|
|
108
|
+
}), /*#__PURE__*/React__default.createElement("div", {
|
|
109
|
+
className: `${prefix}--file-container`
|
|
110
|
+
}, state.fileNames.length === 0 ? null : state.fileNames.map((name, index) => /*#__PURE__*/React__default.createElement("span", _extends({
|
|
111
|
+
key: index,
|
|
112
|
+
className: selectedFileClasses,
|
|
113
|
+
ref: node => nodes[index] = node // eslint-disable-line
|
|
114
|
+
}, other), /*#__PURE__*/React__default.createElement(Text, {
|
|
115
|
+
as: "p",
|
|
116
|
+
className: `${prefix}--file-filename`,
|
|
117
|
+
id: name
|
|
118
|
+
}, name), /*#__PURE__*/React__default.createElement("span", {
|
|
119
|
+
className: `${prefix}--file__state-container`
|
|
120
|
+
}, /*#__PURE__*/React__default.createElement(Filename, {
|
|
121
|
+
name: name,
|
|
122
|
+
iconDescription: iconDescription,
|
|
123
|
+
status: filenameStatus,
|
|
124
|
+
onKeyDown: evt => {
|
|
125
|
+
if (matches(evt, [Enter, Space])) {
|
|
126
|
+
handleClick(evt, {
|
|
127
|
+
index,
|
|
128
|
+
filenameStatus
|
|
49
129
|
});
|
|
50
|
-
if (this.props.onDelete) {
|
|
51
|
-
this.props.onDelete(evt);
|
|
52
|
-
this.uploaderButton.current?.focus?.();
|
|
53
|
-
}
|
|
54
|
-
this.props.onClick?.(evt);
|
|
55
130
|
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this.setState({
|
|
60
|
-
filenames: []
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
static getDerivedStateFromProps(_ref2, state) {
|
|
65
|
-
let {
|
|
131
|
+
},
|
|
132
|
+
onClick: evt => handleClick(evt, {
|
|
133
|
+
index,
|
|
66
134
|
filenameStatus
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
return prevFilenameStatus === filenameStatus ? null : {
|
|
72
|
-
filenameStatus,
|
|
73
|
-
prevFilenameStatus: filenameStatus
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
render() {
|
|
77
|
-
const {
|
|
78
|
-
iconDescription,
|
|
79
|
-
buttonLabel = '',
|
|
80
|
-
buttonKind = 'primary',
|
|
81
|
-
disabled = false,
|
|
82
|
-
filenameStatus = 'uploading',
|
|
83
|
-
labelDescription,
|
|
84
|
-
labelTitle,
|
|
85
|
-
className,
|
|
86
|
-
multiple = false,
|
|
87
|
-
accept = [],
|
|
88
|
-
name,
|
|
89
|
-
size = 'md',
|
|
90
|
-
onDelete,
|
|
91
|
-
// eslint-disable-line
|
|
92
|
-
...other
|
|
93
|
-
} = this.props;
|
|
94
|
-
const prefix = this.context;
|
|
95
|
-
const classes = cx({
|
|
96
|
-
[`${prefix}--form-item`]: true,
|
|
97
|
-
[className]: className
|
|
98
|
-
});
|
|
99
|
-
const getHelperLabelClasses = baseClass => cx(baseClass, {
|
|
100
|
-
[`${prefix}--label-description--disabled`]: disabled
|
|
101
|
-
});
|
|
102
|
-
const selectedFileClasses = cx(`${prefix}--file__selected-file`, {
|
|
103
|
-
[`${prefix}--file__selected-file--md`]: size === 'field' || size === 'md',
|
|
104
|
-
[`${prefix}--file__selected-file--sm`]: size === 'small' || size === 'sm'
|
|
105
|
-
});
|
|
106
|
-
return /*#__PURE__*/React__default.createElement("div", _extends({
|
|
107
|
-
className: classes
|
|
108
|
-
}, other), !labelTitle ? null : /*#__PURE__*/React__default.createElement(Text, {
|
|
109
|
-
as: "h3",
|
|
110
|
-
className: getHelperLabelClasses(`${prefix}--file--label`)
|
|
111
|
-
}, labelTitle), /*#__PURE__*/React__default.createElement(Text, {
|
|
112
|
-
as: "p",
|
|
113
|
-
className: getHelperLabelClasses(`${prefix}--label-description`),
|
|
114
|
-
id: "description"
|
|
115
|
-
}, labelDescription), /*#__PURE__*/React__default.createElement(FileUploaderButton, {
|
|
116
|
-
innerRef: this.uploaderButton,
|
|
117
|
-
disabled: disabled,
|
|
118
|
-
labelText: buttonLabel,
|
|
119
|
-
multiple: multiple,
|
|
120
|
-
buttonKind: buttonKind,
|
|
121
|
-
onChange: this.handleChange,
|
|
122
|
-
disableLabelChanges: true,
|
|
123
|
-
accept: accept,
|
|
124
|
-
name: name,
|
|
125
|
-
size: size,
|
|
126
|
-
"aria-describedby": "description"
|
|
127
|
-
}), /*#__PURE__*/React__default.createElement("div", {
|
|
128
|
-
className: `${prefix}--file-container`
|
|
129
|
-
}, this.state.filenames.length === 0 ? null : this.state.filenames.map((name, index) => /*#__PURE__*/React__default.createElement("span", _extends({
|
|
130
|
-
key: index,
|
|
131
|
-
className: selectedFileClasses,
|
|
132
|
-
ref: node => this.nodes[index] = node // eslint-disable-line
|
|
133
|
-
}, other), /*#__PURE__*/React__default.createElement(Text, {
|
|
134
|
-
as: "p",
|
|
135
|
-
className: `${prefix}--file-filename`,
|
|
136
|
-
id: name
|
|
137
|
-
}, name), /*#__PURE__*/React__default.createElement("span", {
|
|
138
|
-
className: `${prefix}--file__state-container`
|
|
139
|
-
}, /*#__PURE__*/React__default.createElement(Filename, {
|
|
140
|
-
name: name,
|
|
141
|
-
iconDescription: iconDescription,
|
|
142
|
-
status: filenameStatus,
|
|
143
|
-
onKeyDown: evt => {
|
|
144
|
-
if (matches(evt, [Enter, Space])) {
|
|
145
|
-
this.handleClick(evt, {
|
|
146
|
-
index,
|
|
147
|
-
filenameStatus
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
onClick: evt => this.handleClick(evt, {
|
|
152
|
-
index,
|
|
153
|
-
filenameStatus
|
|
154
|
-
})
|
|
155
|
-
}))))));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
_defineProperty(FileUploader, "propTypes", {
|
|
135
|
+
})
|
|
136
|
+
}))))));
|
|
137
|
+
});
|
|
138
|
+
FileUploader.propTypes = {
|
|
159
139
|
/**
|
|
160
140
|
* Specify the types of files that this input should be able to receive
|
|
161
141
|
*/
|
|
@@ -221,7 +201,6 @@ _defineProperty(FileUploader, "propTypes", {
|
|
|
221
201
|
* sizes.
|
|
222
202
|
*/
|
|
223
203
|
size: PropTypes.oneOf(['sm', 'md', 'lg'])
|
|
224
|
-
}
|
|
225
|
-
_defineProperty(FileUploader, "contextType", PrefixContext);
|
|
204
|
+
};
|
|
226
205
|
|
|
227
206
|
export { FileUploader as default };
|
|
@@ -14,6 +14,7 @@ import { useGridSettings, GridSettings } from './GridContext.js';
|
|
|
14
14
|
|
|
15
15
|
function CSSGrid(_ref) {
|
|
16
16
|
let {
|
|
17
|
+
align,
|
|
17
18
|
as: BaseComponent = 'div',
|
|
18
19
|
children,
|
|
19
20
|
className: customClassName,
|
|
@@ -46,7 +47,9 @@ function CSSGrid(_ref) {
|
|
|
46
47
|
[`${prefix}--css-grid`]: true,
|
|
47
48
|
[`${prefix}--css-grid--condensed`]: mode === 'condensed',
|
|
48
49
|
[`${prefix}--css-grid--narrow`]: mode === 'narrow',
|
|
49
|
-
[`${prefix}--css-grid--full-width`]: fullWidth
|
|
50
|
+
[`${prefix}--css-grid--full-width`]: fullWidth,
|
|
51
|
+
[`${prefix}--css-grid--start`]: align === 'start',
|
|
52
|
+
[`${prefix}--css-grid--end`]: align === 'end'
|
|
50
53
|
});
|
|
51
54
|
|
|
52
55
|
// cast as any to let TypeScript allow passing in attributes to base component
|
|
@@ -59,6 +62,10 @@ function CSSGrid(_ref) {
|
|
|
59
62
|
}, rest), children));
|
|
60
63
|
}
|
|
61
64
|
CSSGrid.propTypes = {
|
|
65
|
+
/**
|
|
66
|
+
* Specify grid aligment. Default is center
|
|
67
|
+
*/
|
|
68
|
+
align: PropTypes.oneOf(['start', 'center', 'end']),
|
|
62
69
|
/**
|
|
63
70
|
* Provide a custom element to render instead of the default <div>
|
|
64
71
|
*/
|
|
@@ -19,6 +19,10 @@ function Grid(props) {
|
|
|
19
19
|
return /*#__PURE__*/React__default.createElement(FlexGridComponent, props);
|
|
20
20
|
}
|
|
21
21
|
Grid.propTypes = {
|
|
22
|
+
/**
|
|
23
|
+
* Specify grid aligment. Default is center
|
|
24
|
+
*/
|
|
25
|
+
align: PropTypes.oneOf(['start', 'center', 'end']),
|
|
22
26
|
/**
|
|
23
27
|
* Provide a custom element to render instead of the default <div>
|
|
24
28
|
*/
|
|
@@ -0,0 +1,26 @@
|
|
|
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 PropTypes from 'prop-types';
|
|
8
|
+
import { PropsWithChildren, ReactNode } from 'react';
|
|
9
|
+
type IdPrefixProps = {
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
/**
|
|
12
|
+
* The value used to prefix the auto-generated id placed on some DOM elements
|
|
13
|
+
*/
|
|
14
|
+
prefix?: string;
|
|
15
|
+
};
|
|
16
|
+
declare function IdPrefix({ children, prefix }: PropsWithChildren<IdPrefixProps>): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
declare namespace IdPrefix {
|
|
18
|
+
var propTypes: {
|
|
19
|
+
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
20
|
+
/**
|
|
21
|
+
* The value used to prefix the auto-generated id placed on some DOM elements
|
|
22
|
+
*/
|
|
23
|
+
prefix: PropTypes.Requireable<string>;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export { IdPrefix };
|
|
@@ -37,6 +37,10 @@ export interface ListBoxSelectionProps {
|
|
|
37
37
|
* Specify whether or not the clear selection element should be disabled
|
|
38
38
|
*/
|
|
39
39
|
disabled?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Whether or not the listbox is readonly
|
|
42
|
+
*/
|
|
43
|
+
readOnly?: boolean;
|
|
40
44
|
/**
|
|
41
45
|
* Specify an optional `onClearSelection` handler that is called when the underlying
|
|
42
46
|
* element is cleared
|
|
@@ -58,7 +62,7 @@ export interface ListBoxSelectionProps {
|
|
|
58
62
|
*/
|
|
59
63
|
onMouseUp?: React.MouseEventHandler<HTMLButtonElement>;
|
|
60
64
|
}
|
|
61
|
-
declare function ListBoxSelection({ clearSelection, selectionCount, translateWithId: t, disabled, onClearSelection, ...rest }: ListBoxSelectionProps): import("react/jsx-runtime").JSX.Element;
|
|
65
|
+
declare function ListBoxSelection({ clearSelection, selectionCount, translateWithId: t, disabled, readOnly, onClearSelection, ...rest }: ListBoxSelectionProps): import("react/jsx-runtime").JSX.Element;
|
|
62
66
|
declare namespace ListBoxSelection {
|
|
63
67
|
var propTypes: {
|
|
64
68
|
/**
|
|
@@ -70,6 +74,10 @@ declare namespace ListBoxSelection {
|
|
|
70
74
|
* Specify whether or not the clear selection element should be disabled
|
|
71
75
|
*/
|
|
72
76
|
disabled: PropTypes.Requireable<boolean>;
|
|
77
|
+
/**
|
|
78
|
+
* Whether or not the listbox is readonly
|
|
79
|
+
*/
|
|
80
|
+
readOnly: PropTypes.Requireable<boolean>;
|
|
73
81
|
/**
|
|
74
82
|
* Specify an optional `onClearSelection` handler that is called when the underlying
|
|
75
83
|
* element is cleared
|
|
@@ -26,6 +26,7 @@ function ListBoxSelection(_ref) {
|
|
|
26
26
|
selectionCount,
|
|
27
27
|
translateWithId: t = defaultTranslateWithId,
|
|
28
28
|
disabled,
|
|
29
|
+
readOnly,
|
|
29
30
|
onClearSelection,
|
|
30
31
|
...rest
|
|
31
32
|
} = _ref;
|
|
@@ -40,7 +41,7 @@ function ListBoxSelection(_ref) {
|
|
|
40
41
|
});
|
|
41
42
|
function onClick(event) {
|
|
42
43
|
event.stopPropagation();
|
|
43
|
-
if (disabled) {
|
|
44
|
+
if (disabled || readOnly) {
|
|
44
45
|
return;
|
|
45
46
|
}
|
|
46
47
|
clearSelection(event);
|
|
@@ -57,21 +58,23 @@ function ListBoxSelection(_ref) {
|
|
|
57
58
|
}, selectionCount), /*#__PURE__*/React__default.createElement("button", {
|
|
58
59
|
"aria-label": description,
|
|
59
60
|
className: `${prefix}--tag__close-icon`,
|
|
60
|
-
disabled: disabled,
|
|
61
|
+
disabled: disabled || readOnly,
|
|
61
62
|
onClick: onClick,
|
|
62
63
|
tabIndex: -1,
|
|
63
64
|
title: description,
|
|
64
|
-
type: "button"
|
|
65
|
+
type: "button",
|
|
66
|
+
"aria-disabled": readOnly ? true : undefined
|
|
65
67
|
}, _Close || (_Close = /*#__PURE__*/React__default.createElement(Close, null))));
|
|
66
68
|
}
|
|
67
69
|
return /*#__PURE__*/React__default.createElement("button", _extends({}, rest, {
|
|
68
70
|
"aria-label": description,
|
|
69
71
|
className: className,
|
|
70
|
-
disabled: disabled,
|
|
72
|
+
disabled: disabled || readOnly,
|
|
71
73
|
onClick: onClick,
|
|
72
74
|
tabIndex: -1,
|
|
73
75
|
title: description,
|
|
74
|
-
type: "button"
|
|
76
|
+
type: "button",
|
|
77
|
+
"aria-disabled": readOnly ? true : undefined
|
|
75
78
|
}), _Close2 || (_Close2 = /*#__PURE__*/React__default.createElement(Close, null)));
|
|
76
79
|
}
|
|
77
80
|
ListBoxSelection.propTypes = {
|
|
@@ -84,6 +87,10 @@ ListBoxSelection.propTypes = {
|
|
|
84
87
|
* Specify whether or not the clear selection element should be disabled
|
|
85
88
|
*/
|
|
86
89
|
disabled: PropTypes.bool,
|
|
90
|
+
/**
|
|
91
|
+
* Whether or not the listbox is readonly
|
|
92
|
+
*/
|
|
93
|
+
readOnly: PropTypes.bool,
|
|
87
94
|
/**
|
|
88
95
|
* Specify an optional `onClearSelection` handler that is called when the underlying
|
|
89
96
|
* element is cleared
|
|
@@ -347,9 +347,6 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
|
|
|
347
347
|
});
|
|
348
348
|
function handleClick(item, e) {
|
|
349
349
|
setSelection(item);
|
|
350
|
-
if (onChange) {
|
|
351
|
-
onChange(e);
|
|
352
|
-
}
|
|
353
350
|
}
|
|
354
351
|
useEffect(() => {
|
|
355
352
|
if (!context.state.hasIcons) {
|
|
@@ -374,7 +371,7 @@ const MenuItemRadioGroup = /*#__PURE__*/forwardRef(function MenuItemRadioGroup(_
|
|
|
374
371
|
"aria-checked": item === selection,
|
|
375
372
|
renderIcon: item === selection ? Checkmark : undefined,
|
|
376
373
|
onClick: e => {
|
|
377
|
-
handleClick(item
|
|
374
|
+
handleClick(item);
|
|
378
375
|
}
|
|
379
376
|
}))));
|
|
380
377
|
});
|
|
@@ -39,6 +39,10 @@ export interface MenuButtonProps extends ComponentProps<'div'> {
|
|
|
39
39
|
* Specify the tabIndex of the button.
|
|
40
40
|
*/
|
|
41
41
|
tabIndex?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
|
|
44
|
+
*/
|
|
45
|
+
menuTarget?: Element;
|
|
42
46
|
}
|
|
43
47
|
declare const MenuButton: React.ForwardRefExoticComponent<Omit<MenuButtonProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
44
48
|
export { MenuButton };
|
|
@@ -18,6 +18,7 @@ import { useAttachedMenu } from '../../internal/useAttachedMenu.js';
|
|
|
18
18
|
import { useId } from '../../internal/useId.js';
|
|
19
19
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
20
20
|
import { flip, size, useFloating, autoUpdate } from '@floating-ui/react';
|
|
21
|
+
import { useFeatureFlag } from '../FeatureFlags/index.js';
|
|
21
22
|
import mergeRefs from '../../tools/mergeRefs.js';
|
|
22
23
|
|
|
23
24
|
const validButtonKinds = ['primary', 'tertiary', 'ghost'];
|
|
@@ -32,14 +33,21 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
|
|
|
32
33
|
size: size$1 = 'lg',
|
|
33
34
|
menuAlignment = 'bottom',
|
|
34
35
|
tabIndex = 0,
|
|
36
|
+
menuTarget,
|
|
35
37
|
...rest
|
|
36
38
|
} = _ref;
|
|
39
|
+
// feature flag utilized to separate out only the dynamic styles from @floating-ui
|
|
40
|
+
// flag is turned on when collision detection (ie. flip, hide) logic is not desired
|
|
41
|
+
const enableOnlyFloatingStyles = useFeatureFlag('enable-v12-dynamic-floating-styles');
|
|
37
42
|
const id = useId('MenuButton');
|
|
38
43
|
const prefix = usePrefix();
|
|
39
44
|
const triggerRef = useRef(null);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
let middlewares = [];
|
|
46
|
+
if (!enableOnlyFloatingStyles) {
|
|
47
|
+
middlewares = [flip({
|
|
48
|
+
crossAxis: false
|
|
49
|
+
})];
|
|
50
|
+
}
|
|
43
51
|
if (menuAlignment === 'bottom' || menuAlignment === 'top') {
|
|
44
52
|
middlewares.push(size({
|
|
45
53
|
apply(_ref2) {
|
|
@@ -121,7 +129,8 @@ const MenuButton = /*#__PURE__*/forwardRef(function MenuButton(_ref, forwardRef)
|
|
|
121
129
|
mode: "basic",
|
|
122
130
|
size: size$1,
|
|
123
131
|
open: open,
|
|
124
|
-
onClose: handleClose
|
|
132
|
+
onClose: handleClose,
|
|
133
|
+
target: menuTarget
|
|
125
134
|
}, children));
|
|
126
135
|
});
|
|
127
136
|
MenuButton.propTypes = {
|
|
@@ -160,7 +169,12 @@ MenuButton.propTypes = {
|
|
|
160
169
|
* Specify the tabIndex of the button.
|
|
161
170
|
*/
|
|
162
171
|
// @ts-ignore-next-line -- avoid spurious (?) TS2322 error
|
|
163
|
-
tabIndex: PropTypes.number
|
|
172
|
+
tabIndex: PropTypes.number,
|
|
173
|
+
/**
|
|
174
|
+
* Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
|
|
175
|
+
*/
|
|
176
|
+
|
|
177
|
+
menuTarget: PropTypes.instanceOf(typeof Element !== 'undefined' ? Element : Object)
|
|
164
178
|
};
|
|
165
179
|
|
|
166
180
|
export { MenuButton };
|
|
@@ -143,6 +143,10 @@ export interface FilterableMultiSelectProps<ItemType> extends MultiSelectSorting
|
|
|
143
143
|
* what this field is for
|
|
144
144
|
*/
|
|
145
145
|
placeholder?: string;
|
|
146
|
+
/**
|
|
147
|
+
* Whether or not the filterable multiselect is readonly
|
|
148
|
+
*/
|
|
149
|
+
readOnly?: boolean;
|
|
146
150
|
/**
|
|
147
151
|
* Specify feedback (mode) of the selection.
|
|
148
152
|
* `top`: selected item jumps to top
|
|
@@ -90,6 +90,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
90
90
|
onChange,
|
|
91
91
|
onMenuChange,
|
|
92
92
|
placeholder,
|
|
93
|
+
readOnly,
|
|
93
94
|
titleText,
|
|
94
95
|
type,
|
|
95
96
|
selectionFeedback = 'top-after-reopen',
|
|
@@ -232,9 +233,11 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
232
233
|
}
|
|
233
234
|
};
|
|
234
235
|
function handleMenuChange(forceIsOpen) {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
if (!readOnly) {
|
|
237
|
+
const nextIsOpen = forceIsOpen ?? !isOpen;
|
|
238
|
+
setIsOpen(nextIsOpen);
|
|
239
|
+
validateHighlightFocus();
|
|
240
|
+
}
|
|
238
241
|
}
|
|
239
242
|
useEffect(() => {
|
|
240
243
|
onMenuChange?.(isOpen);
|
|
@@ -423,7 +426,8 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
423
426
|
[`${prefix}--multi-select--open`]: isOpen,
|
|
424
427
|
[`${prefix}--multi-select--inline`]: inline,
|
|
425
428
|
[`${prefix}--multi-select--selected`]: controlledSelectedItems?.length > 0,
|
|
426
|
-
[`${prefix}--multi-select--filterable--input-focused`]: inputFocused
|
|
429
|
+
[`${prefix}--multi-select--filterable--input-focused`]: inputFocused,
|
|
430
|
+
[`${prefix}--multi-select--readonly`]: readOnly
|
|
427
431
|
});
|
|
428
432
|
const labelProps = getLabelProps();
|
|
429
433
|
const buttonProps = getToggleButtonProps({
|
|
@@ -510,6 +514,24 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
510
514
|
setIsFocused(evt?.type === 'focus' ? true : false);
|
|
511
515
|
}
|
|
512
516
|
};
|
|
517
|
+
const mergedRef = mergeRefs(textInput, inputProps.ref);
|
|
518
|
+
const readOnlyEventHandlers = readOnly ? {
|
|
519
|
+
onClick: evt => {
|
|
520
|
+
// NOTE: does not prevent click
|
|
521
|
+
evt.preventDefault();
|
|
522
|
+
// focus on the element as per readonly input behavior
|
|
523
|
+
if (mergedRef.current !== undefined) {
|
|
524
|
+
mergedRef.current.focus();
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
onKeyDown: evt => {
|
|
528
|
+
const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
|
|
529
|
+
// This prevents the select from opening for the above keys
|
|
530
|
+
if (selectAccessKeys.includes(evt.key)) {
|
|
531
|
+
evt.preventDefault();
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
} : {};
|
|
513
535
|
const clearSelectionContent = controlledSelectedItems.length > 0 ? /*#__PURE__*/React__default.createElement("span", {
|
|
514
536
|
className: `${prefix}--visually-hidden`
|
|
515
537
|
}, clearSelectionDescription, " ", controlledSelectedItems.length, ",", clearSelectionText) : /*#__PURE__*/React__default.createElement("span", {
|
|
@@ -533,12 +555,13 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
533
555
|
invalidText: invalidText,
|
|
534
556
|
warn: warn,
|
|
535
557
|
warnText: warnText,
|
|
536
|
-
isOpen: isOpen,
|
|
558
|
+
isOpen: !readOnly && isOpen,
|
|
537
559
|
size: size$1
|
|
538
560
|
}, /*#__PURE__*/React__default.createElement("div", {
|
|
539
561
|
className: `${prefix}--list-box__field`,
|
|
540
562
|
ref: autoAlign ? refs.setReference : null
|
|
541
563
|
}, controlledSelectedItems.length > 0 && /*#__PURE__*/React__default.createElement(ListBoxSelection, {
|
|
564
|
+
readOnly: readOnly,
|
|
542
565
|
clearSelection: () => {
|
|
543
566
|
clearSelection();
|
|
544
567
|
if (textInput.current) {
|
|
@@ -551,7 +574,9 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
551
574
|
}), /*#__PURE__*/React__default.createElement("input", _extends({
|
|
552
575
|
className: inputClasses
|
|
553
576
|
}, inputProps, {
|
|
554
|
-
ref:
|
|
577
|
+
ref: mergedRef
|
|
578
|
+
}, readOnlyEventHandlers, {
|
|
579
|
+
readOnly: readOnly
|
|
555
580
|
})), invalid && /*#__PURE__*/React__default.createElement(WarningFilled, {
|
|
556
581
|
className: `${prefix}--list-box__invalid-icon`
|
|
557
582
|
}), showWarning && /*#__PURE__*/React__default.createElement(WarningAltFilled, {
|
|
@@ -560,6 +585,7 @@ const FilterableMultiSelect = /*#__PURE__*/React__default.forwardRef(function Fi
|
|
|
560
585
|
clearSelection: clearInputValue,
|
|
561
586
|
disabled: disabled,
|
|
562
587
|
translateWithId: translateWithId,
|
|
588
|
+
readOnly: readOnly,
|
|
563
589
|
onMouseUp: event => {
|
|
564
590
|
// If we do not stop this event from propagating,
|
|
565
591
|
// it seems like Downshift takes our event and
|