@carbon/react 1.43.0-rc.0 → 1.44.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 +1161 -1001
- package/es/components/ComboBox/ComboBox.js +12 -0
- package/es/components/ComboButton/index.js +2 -1
- package/es/components/ComposedModal/ComposedModal.d.ts +3 -3
- package/es/components/ComposedModal/ComposedModal.js +3 -3
- package/es/components/ContextMenu/useContextMenu.js +2 -1
- package/es/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
- package/es/components/Dropdown/Dropdown.js +4 -1
- package/es/components/Link/Link.d.ts +5 -0
- package/es/components/Link/Link.js +9 -2
- package/es/components/Menu/Menu.js +14 -0
- package/es/components/Menu/MenuContext.js +1 -0
- package/es/components/Menu/MenuItem.js +19 -4
- package/es/components/MenuButton/index.js +3 -1
- package/es/components/Slug/index.js +1 -1
- package/es/components/UIShell/SideNav.js +1 -1
- package/es/components/UIShell/Switcher.d.ts +38 -0
- package/es/components/UIShell/Switcher.js +14 -13
- package/es/components/UIShell/SwitcherDivider.d.ts +9 -0
- package/es/components/UIShell/SwitcherDivider.js +4 -5
- package/es/components/UIShell/SwitcherItem.d.ts +49 -0
- package/es/components/UIShell/SwitcherItem.js +13 -17
- package/es/prop-types/tools/getDisplayName.js +34 -0
- package/lib/components/ComboBox/ComboBox.js +12 -0
- package/lib/components/ComboButton/index.js +2 -1
- package/lib/components/ComposedModal/ComposedModal.d.ts +3 -3
- package/lib/components/ComposedModal/ComposedModal.js +3 -3
- package/lib/components/ContextMenu/useContextMenu.js +2 -1
- package/lib/components/DataTableSkeleton/DataTableSkeleton.js +1 -1
- package/lib/components/Dropdown/Dropdown.js +4 -1
- package/lib/components/Link/Link.d.ts +5 -0
- package/lib/components/Link/Link.js +9 -2
- package/lib/components/Menu/Menu.js +14 -0
- package/lib/components/Menu/MenuContext.js +1 -0
- package/lib/components/Menu/MenuItem.js +19 -4
- package/lib/components/MenuButton/index.js +3 -1
- package/lib/components/Slug/index.js +1 -1
- package/lib/components/UIShell/SideNav.js +1 -1
- package/lib/components/UIShell/Switcher.d.ts +38 -0
- package/lib/components/UIShell/Switcher.js +13 -12
- package/lib/components/UIShell/SwitcherDivider.d.ts +9 -0
- package/lib/components/UIShell/SwitcherDivider.js +4 -5
- package/lib/components/UIShell/SwitcherItem.d.ts +49 -0
- package/lib/components/UIShell/SwitcherItem.js +12 -16
- package/lib/prop-types/tools/getDisplayName.js +38 -0
- package/package.json +3 -3
|
@@ -351,6 +351,18 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
351
351
|
if (match(event, End) && event.code !== 'Numpad1') {
|
|
352
352
|
event.target.setSelectionRange(event.target.value.length, event.target.value.length);
|
|
353
353
|
}
|
|
354
|
+
if (event.altKey && event.key == 'ArrowDown') {
|
|
355
|
+
event.preventDownshiftDefault = true;
|
|
356
|
+
if (!isOpen) {
|
|
357
|
+
toggleMenu();
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (event.altKey && event.key == 'ArrowUp') {
|
|
361
|
+
event.preventDownshiftDefault = true;
|
|
362
|
+
if (isOpen) {
|
|
363
|
+
toggleMenu();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
354
366
|
}
|
|
355
367
|
});
|
|
356
368
|
const handleFocus = evt => {
|
|
@@ -68,7 +68,7 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
function handleOpen() {
|
|
71
|
-
menuRef.current.style.
|
|
71
|
+
menuRef.current.style.inlineSize = `${width}px`;
|
|
72
72
|
}
|
|
73
73
|
const containerClasses = cx(`${prefix}--combo-button__container`, `${prefix}--combo-button__container--${size}`, {
|
|
74
74
|
[`${prefix}--combo-button__container--open`]: open
|
|
@@ -100,6 +100,7 @@ const ComboButton = /*#__PURE__*/React__default.forwardRef(function ComboButton(
|
|
|
100
100
|
ref: menuRef,
|
|
101
101
|
id: id,
|
|
102
102
|
label: t('carbon.combo-button.additional-actions'),
|
|
103
|
+
mode: "basic",
|
|
103
104
|
size: size,
|
|
104
105
|
open: open,
|
|
105
106
|
onClose: handleClose,
|
|
@@ -4,7 +4,7 @@ export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
4
4
|
children?: ReactNode;
|
|
5
5
|
/**
|
|
6
6
|
* Provide whether the modal content has a form element.
|
|
7
|
-
* If `true` is used here, non-form child content should have `
|
|
7
|
+
* If `true` is used here, non-form child content should have `cds--modal-content__regular-content` class.
|
|
8
8
|
*/
|
|
9
9
|
hasForm?: boolean;
|
|
10
10
|
/**
|
|
@@ -15,11 +15,11 @@ export interface ModalBodyProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
15
15
|
export declare const ModalBody: React.ForwardRefExoticComponent<ModalBodyProps & React.RefAttributes<HTMLDivElement>>;
|
|
16
16
|
export interface ComposedModalProps extends HTMLAttributes<HTMLDivElement> {
|
|
17
17
|
/**
|
|
18
|
-
* Specify the aria-label for
|
|
18
|
+
* Specify the aria-label for cds--modal-container
|
|
19
19
|
*/
|
|
20
20
|
'aria-label'?: string;
|
|
21
21
|
/**
|
|
22
|
-
* Specify the aria-labelledby for
|
|
22
|
+
* Specify the aria-labelledby for cds--modal-container
|
|
23
23
|
*/
|
|
24
24
|
'aria-labelledby'?: string;
|
|
25
25
|
/**
|
|
@@ -56,7 +56,7 @@ ModalBody.propTypes = {
|
|
|
56
56
|
className: PropTypes.string,
|
|
57
57
|
/**
|
|
58
58
|
* Provide whether the modal content has a form element.
|
|
59
|
-
* If `true` is used here, non-form child content should have `
|
|
59
|
+
* If `true` is used here, non-form child content should have `cds--modal-content__regular-content` class.
|
|
60
60
|
*/
|
|
61
61
|
hasForm: PropTypes.bool,
|
|
62
62
|
/**
|
|
@@ -231,11 +231,11 @@ const ComposedModal = /*#__PURE__*/React__default.forwardRef(function ComposedMo
|
|
|
231
231
|
});
|
|
232
232
|
ComposedModal.propTypes = {
|
|
233
233
|
/**
|
|
234
|
-
* Specify the aria-label for
|
|
234
|
+
* Specify the aria-label for cds--modal-container
|
|
235
235
|
*/
|
|
236
236
|
['aria-label']: PropTypes.string,
|
|
237
237
|
/**
|
|
238
|
-
* Specify the aria-labelledby for
|
|
238
|
+
* Specify the aria-labelledby for cds--modal-container
|
|
239
239
|
*/
|
|
240
240
|
['aria-labelledby']: PropTypes.string,
|
|
241
241
|
/**
|
|
@@ -63,7 +63,7 @@ const DataTableSkeleton = _ref => {
|
|
|
63
63
|
}, rest), /*#__PURE__*/React__default.createElement("thead", null, /*#__PURE__*/React__default.createElement("tr", null, columnsArray.map(i => /*#__PURE__*/React__default.createElement("th", {
|
|
64
64
|
key: i
|
|
65
65
|
}, headers ? /*#__PURE__*/React__default.createElement("div", {
|
|
66
|
-
className: "
|
|
66
|
+
className: "cds--table-header-label"
|
|
67
67
|
}, headers[i]?.header) : _span2 || (_span2 = /*#__PURE__*/React__default.createElement("span", null)))))), /*#__PURE__*/React__default.createElement("tbody", null, rows)));
|
|
68
68
|
};
|
|
69
69
|
DataTableSkeleton.propTypes = {
|
|
@@ -277,6 +277,9 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
277
277
|
item,
|
|
278
278
|
index
|
|
279
279
|
});
|
|
280
|
+
if (item !== null && typeof item === 'object' && Object.prototype.hasOwnProperty.call(item, 'id')) {
|
|
281
|
+
itemProps.id = item['id'];
|
|
282
|
+
}
|
|
280
283
|
const title = isObject && 'text' in item && itemToElement ? item.text : itemToString(item);
|
|
281
284
|
return /*#__PURE__*/React__default.createElement(ListBox.MenuItem, _extends({
|
|
282
285
|
key: itemProps.id,
|
|
@@ -304,7 +307,7 @@ Dropdown.propTypes = {
|
|
|
304
307
|
*/
|
|
305
308
|
ariaLabel: deprecate(PropTypes.string, 'This prop syntax has been deprecated. Please use the new `aria-label`.'),
|
|
306
309
|
/**
|
|
307
|
-
* Provide a custom className to be applied on the
|
|
310
|
+
* Provide a custom className to be applied on the cds--dropdown node
|
|
308
311
|
*/
|
|
309
312
|
className: PropTypes.string,
|
|
310
313
|
/**
|
|
@@ -6,6 +6,11 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import React, { AnchorHTMLAttributes, AriaAttributes, ComponentType, HTMLAttributeAnchorTarget } from 'react';
|
|
8
8
|
export interface LinkProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
|
|
9
|
+
/**
|
|
10
|
+
* Provide a custom element or component to render the top-level node for the
|
|
11
|
+
* component.
|
|
12
|
+
*/
|
|
13
|
+
as?: string | undefined;
|
|
9
14
|
/**
|
|
10
15
|
* @description Indicates the element that represents the
|
|
11
16
|
* current item within a container or set of related
|
|
@@ -13,6 +13,7 @@ import { usePrefix } from '../../internal/usePrefix.js';
|
|
|
13
13
|
|
|
14
14
|
const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
|
|
15
15
|
let {
|
|
16
|
+
as: BaseComponent,
|
|
16
17
|
children,
|
|
17
18
|
className: customClassName,
|
|
18
19
|
href,
|
|
@@ -33,7 +34,7 @@ const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
|
|
|
33
34
|
});
|
|
34
35
|
const rel = target === '_blank' ? 'noopener' : undefined;
|
|
35
36
|
const linkProps = {
|
|
36
|
-
className,
|
|
37
|
+
className: BaseComponent ? undefined : className,
|
|
37
38
|
rel,
|
|
38
39
|
target
|
|
39
40
|
};
|
|
@@ -46,7 +47,8 @@ const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
|
|
|
46
47
|
linkProps.role = 'link';
|
|
47
48
|
linkProps['aria-disabled'] = true;
|
|
48
49
|
}
|
|
49
|
-
|
|
50
|
+
const BaseComponentAsAny = BaseComponent ?? 'a';
|
|
51
|
+
return /*#__PURE__*/React__default.createElement(BaseComponentAsAny, _extends({
|
|
50
52
|
ref: ref
|
|
51
53
|
}, linkProps, rest), children, !inline && Icon && /*#__PURE__*/React__default.createElement("div", {
|
|
52
54
|
className: `${prefix}--link__icon`
|
|
@@ -54,6 +56,11 @@ const Link = /*#__PURE__*/React__default.forwardRef(function Link(_ref, ref) {
|
|
|
54
56
|
});
|
|
55
57
|
Link.displayName = 'Link';
|
|
56
58
|
Link.propTypes = {
|
|
59
|
+
/**
|
|
60
|
+
* Provide a custom element or component to render the top-level node for the
|
|
61
|
+
* component.
|
|
62
|
+
*/
|
|
63
|
+
as: PropTypes.string,
|
|
57
64
|
/**
|
|
58
65
|
* Provide the content for the Link
|
|
59
66
|
*/
|
|
@@ -12,6 +12,7 @@ import React__default, { useRef, useContext, useReducer, useMemo, useState, useE
|
|
|
12
12
|
import { createPortal } from 'react-dom';
|
|
13
13
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
14
14
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
15
|
+
import { warning } from '../../internal/warning.js';
|
|
15
16
|
import { MenuContext, menuReducer } from './MenuContext.js';
|
|
16
17
|
import { useLayoutDirection } from '../LayoutDirection/useLayoutDirection.js';
|
|
17
18
|
import { match } from '../../internal/keyboard/match.js';
|
|
@@ -24,6 +25,7 @@ const Menu = /*#__PURE__*/React__default.forwardRef(function Menu(_ref, forwardR
|
|
|
24
25
|
children,
|
|
25
26
|
className,
|
|
26
27
|
label,
|
|
28
|
+
mode = 'full',
|
|
27
29
|
onClose,
|
|
28
30
|
onOpen,
|
|
29
31
|
open,
|
|
@@ -37,10 +39,14 @@ const Menu = /*#__PURE__*/React__default.forwardRef(function Menu(_ref, forwardR
|
|
|
37
39
|
const focusReturn = useRef(null);
|
|
38
40
|
const context = useContext(MenuContext);
|
|
39
41
|
const isRoot = context.state.isRoot;
|
|
42
|
+
if (context.state.mode === 'basic' && !isRoot) {
|
|
43
|
+
process.env.NODE_ENV !== "production" ? warning(false, 'Nested menus are not supported when the menu is in "basic" mode.') : void 0;
|
|
44
|
+
}
|
|
40
45
|
const menuSize = isRoot ? size : context.state.size;
|
|
41
46
|
const [childState, childDispatch] = useReducer(menuReducer, {
|
|
42
47
|
...context.state,
|
|
43
48
|
isRoot: false,
|
|
49
|
+
mode,
|
|
44
50
|
size,
|
|
45
51
|
requestCloseRoot: isRoot ? handleClose : context.state.requestCloseRoot
|
|
46
52
|
});
|
|
@@ -245,6 +251,14 @@ Menu.propTypes = {
|
|
|
245
251
|
* A label describing the Menu.
|
|
246
252
|
*/
|
|
247
253
|
label: PropTypes.string,
|
|
254
|
+
/**
|
|
255
|
+
* The mode of this menu. Defaults to full.
|
|
256
|
+
* `full` supports nesting and selectable menu items, but no icons.
|
|
257
|
+
* `basic` supports icons but no nesting or selectable menu items.
|
|
258
|
+
*
|
|
259
|
+
* **This prop is not intended for use and will be set by the respective implementation (like useContextMenu, MenuButton, and ComboButton).**
|
|
260
|
+
*/
|
|
261
|
+
mode: PropTypes.oneOf(['full', 'basic']),
|
|
248
262
|
/**
|
|
249
263
|
* Provide an optional function to be called when the Menu should be closed.
|
|
250
264
|
*/
|
|
@@ -13,6 +13,7 @@ import { CaretLeft, CaretRight, Checkmark } from '@carbon/icons-react';
|
|
|
13
13
|
import { useControllableState } from '../../internal/useControllableState.js';
|
|
14
14
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
15
15
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
16
|
+
import { warning } from '../../internal/warning.js';
|
|
16
17
|
import { Menu } from './Menu.js';
|
|
17
18
|
import { MenuContext } from './MenuContext.js';
|
|
18
19
|
import '../Text/index.js';
|
|
@@ -143,6 +144,14 @@ const MenuItem = /*#__PURE__*/React__default.forwardRef(function MenuItem(_ref,
|
|
|
143
144
|
setRtl(false);
|
|
144
145
|
}
|
|
145
146
|
}, [direction]);
|
|
147
|
+
const iconsAllowed = context.state.mode === 'basic' || rest.role === 'menuitemcheckbox' || rest.role === 'menuitemradio';
|
|
148
|
+
useEffect(() => {
|
|
149
|
+
if (iconsAllowed && IconElement && !context.state.hasIcons) {
|
|
150
|
+
context.dispatch({
|
|
151
|
+
type: 'enableIcons'
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}, [iconsAllowed, IconElement, context.state.hasIcons, context]);
|
|
146
155
|
return /*#__PURE__*/React__default.createElement("li", _extends({
|
|
147
156
|
role: "menuitem"
|
|
148
157
|
}, rest, {
|
|
@@ -158,7 +167,7 @@ const MenuItem = /*#__PURE__*/React__default.forwardRef(function MenuItem(_ref,
|
|
|
158
167
|
onKeyDown: handleKeyDown
|
|
159
168
|
}), /*#__PURE__*/React__default.createElement("div", {
|
|
160
169
|
className: `${prefix}--menu-item__icon`
|
|
161
|
-
}, IconElement && /*#__PURE__*/React__default.createElement(IconElement, null)), /*#__PURE__*/React__default.createElement(Text, {
|
|
170
|
+
}, iconsAllowed && IconElement && /*#__PURE__*/React__default.createElement(IconElement, null)), /*#__PURE__*/React__default.createElement(Text, {
|
|
162
171
|
as: "div",
|
|
163
172
|
className: `${prefix}--menu-item__label`
|
|
164
173
|
}, label), shortcut && !hasChildren && /*#__PURE__*/React__default.createElement("div", {
|
|
@@ -202,7 +211,7 @@ MenuItem.propTypes = {
|
|
|
202
211
|
*/
|
|
203
212
|
onClick: PropTypes.func,
|
|
204
213
|
/**
|
|
205
|
-
*
|
|
214
|
+
* Only applicable if the parent menu is in `basic` mode. Sets the menu item's icon.
|
|
206
215
|
*/
|
|
207
216
|
renderIcon: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
|
|
208
217
|
/**
|
|
@@ -221,6 +230,9 @@ const MenuItemSelectable = /*#__PURE__*/React__default.forwardRef(function MenuI
|
|
|
221
230
|
} = _ref2;
|
|
222
231
|
const prefix = usePrefix();
|
|
223
232
|
const context = useContext(MenuContext);
|
|
233
|
+
if (context.state.mode === 'basic') {
|
|
234
|
+
process.env.NODE_ENV !== "production" ? warning(false, 'MenuItemSelectable is not supported when the menu is in "basic" mode.') : void 0;
|
|
235
|
+
}
|
|
224
236
|
const [checked, setChecked] = useControllableState({
|
|
225
237
|
value: selected,
|
|
226
238
|
onChange,
|
|
@@ -246,7 +258,7 @@ const MenuItemSelectable = /*#__PURE__*/React__default.forwardRef(function MenuI
|
|
|
246
258
|
className: classNames,
|
|
247
259
|
role: "menuitemcheckbox",
|
|
248
260
|
"aria-checked": checked,
|
|
249
|
-
renderIcon: checked
|
|
261
|
+
renderIcon: checked ? Checkmark : undefined,
|
|
250
262
|
onClick: handleClick
|
|
251
263
|
}));
|
|
252
264
|
});
|
|
@@ -318,6 +330,9 @@ const MenuItemRadioGroup = /*#__PURE__*/React__default.forwardRef(function MenuI
|
|
|
318
330
|
} = _ref4;
|
|
319
331
|
const prefix = usePrefix();
|
|
320
332
|
const context = useContext(MenuContext);
|
|
333
|
+
if (context.state.mode === 'basic') {
|
|
334
|
+
process.env.NODE_ENV !== "production" ? warning(false, 'MenuItemRadioGroup is not supported when the menu is in "basic" mode.') : void 0;
|
|
335
|
+
}
|
|
321
336
|
const [selection, setSelection] = useControllableState({
|
|
322
337
|
value: selectedItem,
|
|
323
338
|
onChange,
|
|
@@ -349,7 +364,7 @@ const MenuItemRadioGroup = /*#__PURE__*/React__default.forwardRef(function MenuI
|
|
|
349
364
|
label: itemToString(item),
|
|
350
365
|
role: "menuitemradio",
|
|
351
366
|
"aria-checked": item === selection,
|
|
352
|
-
renderIcon: item === selection
|
|
367
|
+
renderIcon: item === selection ? Checkmark : undefined,
|
|
353
368
|
onClick: e => {
|
|
354
369
|
handleClick(item, e);
|
|
355
370
|
}
|
|
@@ -57,6 +57,7 @@ const MenuButton = /*#__PURE__*/React__default.forwardRef(function MenuButton(_r
|
|
|
57
57
|
function handleOpen() {
|
|
58
58
|
menuRef.current.style.inlineSize = `${width}px`;
|
|
59
59
|
}
|
|
60
|
+
const containerClasses = cx(`${prefix}--menu-button__container`, className);
|
|
60
61
|
const triggerClasses = cx(`${prefix}--menu-button__trigger`, {
|
|
61
62
|
[`${prefix}--menu-button__trigger--open`]: open
|
|
62
63
|
});
|
|
@@ -64,7 +65,7 @@ const MenuButton = /*#__PURE__*/React__default.forwardRef(function MenuButton(_r
|
|
|
64
65
|
return /*#__PURE__*/React__default.createElement("div", _extends({}, rest, {
|
|
65
66
|
ref: ref,
|
|
66
67
|
"aria-owns": open ? id : null,
|
|
67
|
-
className:
|
|
68
|
+
className: containerClasses
|
|
68
69
|
}), /*#__PURE__*/React__default.createElement(Button, {
|
|
69
70
|
className: triggerClasses,
|
|
70
71
|
size: size,
|
|
@@ -80,6 +81,7 @@ const MenuButton = /*#__PURE__*/React__default.forwardRef(function MenuButton(_r
|
|
|
80
81
|
ref: menuRef,
|
|
81
82
|
id: id,
|
|
82
83
|
label: label,
|
|
84
|
+
mode: "basic",
|
|
83
85
|
size: size,
|
|
84
86
|
open: open,
|
|
85
87
|
onClose: handleClose,
|
|
@@ -103,7 +103,7 @@ const Slug = /*#__PURE__*/React__default.forwardRef(function Slug(_ref3, ref) {
|
|
|
103
103
|
onRevertClick(evt);
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
const ariaLabel = `${aiText} - ${slugLabel}`;
|
|
106
|
+
const ariaLabel = !aiTextLabel ? `${aiText} - ${slugLabel}` : `${aiText} - ${aiTextLabel}`;
|
|
107
107
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
108
108
|
className: slugClasses,
|
|
109
109
|
ref: ref,
|
|
@@ -170,7 +170,7 @@ function SideNavRenderFunction(_ref, ref) {
|
|
|
170
170
|
tabIndex: -1,
|
|
171
171
|
ref: navRef,
|
|
172
172
|
className: `${prefix}--side-nav__navigation ${className}`,
|
|
173
|
-
inert: !isRail
|
|
173
|
+
inert: !isRail ? expanded || isLg ? undefined : -1 : undefined
|
|
174
174
|
}, accessibilityLabel, eventHandlers, other), childrenToRender));
|
|
175
175
|
}
|
|
176
176
|
const SideNav = /*#__PURE__*/React__default.forwardRef(SideNavRenderFunction);
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
/**
|
|
8
|
+
* Copyright IBM Corp. 2016, 2023
|
|
9
|
+
*
|
|
10
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
11
|
+
* LICENSE file in the root directory of this source tree.
|
|
12
|
+
*/
|
|
13
|
+
import React, { ReactNode } from 'react';
|
|
14
|
+
interface BaseSwitcherProps {
|
|
15
|
+
/**
|
|
16
|
+
* expects to receive <SwitcherItem />
|
|
17
|
+
*/
|
|
18
|
+
children: ReactNode;
|
|
19
|
+
/**
|
|
20
|
+
* Optionally provide a custom class to apply to the underlying `<ul>` node
|
|
21
|
+
*/
|
|
22
|
+
className?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Specify whether the panel is expanded
|
|
25
|
+
*/
|
|
26
|
+
expanded?: boolean;
|
|
27
|
+
}
|
|
28
|
+
interface SwitcherWithAriaLabel extends BaseSwitcherProps {
|
|
29
|
+
'aria-label': string;
|
|
30
|
+
'aria-labelledby'?: never;
|
|
31
|
+
}
|
|
32
|
+
interface SwitcherWithAriaLabelledBy extends BaseSwitcherProps {
|
|
33
|
+
'aria-label'?: never;
|
|
34
|
+
'aria-labelledby': string;
|
|
35
|
+
}
|
|
36
|
+
type SwitcherProps = SwitcherWithAriaLabel | SwitcherWithAriaLabelledBy;
|
|
37
|
+
declare const Switcher: React.ForwardRefExoticComponent<SwitcherProps & React.RefAttributes<HTMLUListElement>>;
|
|
38
|
+
export default Switcher;
|
|
@@ -6,14 +6,15 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React__default, { useRef } from 'react';
|
|
9
|
+
import React__default, { forwardRef, useRef } from 'react';
|
|
10
10
|
import cx from 'classnames';
|
|
11
|
-
import PropTypes from 'prop-types';
|
|
12
|
-
import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
|
|
13
11
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
14
12
|
import { useMergedRefs } from '../../internal/useMergedRefs.js';
|
|
13
|
+
import PropTypes from 'prop-types';
|
|
14
|
+
import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
|
|
15
|
+
import getDisplayName from '../../prop-types/tools/getDisplayName.js';
|
|
15
16
|
|
|
16
|
-
const Switcher = /*#__PURE__*/
|
|
17
|
+
const Switcher = /*#__PURE__*/forwardRef(function Switcher(props, forwardRef) {
|
|
17
18
|
const switcherRef = useRef(null);
|
|
18
19
|
const ref = useMergedRefs([switcherRef, forwardRef]);
|
|
19
20
|
const prefix = usePrefix();
|
|
@@ -29,7 +30,7 @@ const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props,
|
|
|
29
30
|
'aria-labelledby': ariaLabelledBy
|
|
30
31
|
};
|
|
31
32
|
const className = cx(`${prefix}--switcher`, {
|
|
32
|
-
[customClassName]: !!customClassName
|
|
33
|
+
[customClassName || '']: !!customClassName
|
|
33
34
|
});
|
|
34
35
|
const handleSwitcherItemFocus = _ref => {
|
|
35
36
|
let {
|
|
@@ -54,13 +55,14 @@ const Switcher = /*#__PURE__*/React__default.forwardRef(function Switcher(props,
|
|
|
54
55
|
return enabledIndices[nextIndex];
|
|
55
56
|
}
|
|
56
57
|
})();
|
|
57
|
-
const switcherItem = switcherRef.current
|
|
58
|
-
switcherItem
|
|
58
|
+
const switcherItem = switcherRef.current?.children[nextValidIndex]?.children[0];
|
|
59
|
+
if (switcherItem) {
|
|
60
|
+
switcherItem.focus();
|
|
61
|
+
}
|
|
59
62
|
};
|
|
60
|
-
const childrenWithProps = React__default.Children.
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
if (child.type?.displayName === 'SwitcherItem') {
|
|
63
|
+
const childrenWithProps = React__default.Children.map(children, (child, index) => {
|
|
64
|
+
// only setup click handlers if onChange event is passed
|
|
65
|
+
if ( /*#__PURE__*/React__default.isValidElement(child) && child.type && getDisplayName(child.type) === 'Switcher') {
|
|
64
66
|
return /*#__PURE__*/React__default.cloneElement(child, {
|
|
65
67
|
handleSwitcherItemFocus,
|
|
66
68
|
index,
|
|
@@ -98,6 +100,5 @@ Switcher.propTypes = {
|
|
|
98
100
|
*/
|
|
99
101
|
expanded: PropTypes.bool
|
|
100
102
|
};
|
|
101
|
-
var Switcher$1 = Switcher;
|
|
102
103
|
|
|
103
|
-
export { Switcher
|
|
104
|
+
export { Switcher as default };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface SwitcherDividerProps {
|
|
3
|
+
/**
|
|
4
|
+
* Optionally provide a custom class to apply to the underlying `<li>` node
|
|
5
|
+
*/
|
|
6
|
+
className?: string;
|
|
7
|
+
}
|
|
8
|
+
declare const SwitcherDivider: React.FC<SwitcherDividerProps>;
|
|
9
|
+
export default SwitcherDivider;
|
|
@@ -17,11 +17,11 @@ const SwitcherDivider = _ref => {
|
|
|
17
17
|
...other
|
|
18
18
|
} = _ref;
|
|
19
19
|
const prefix = usePrefix();
|
|
20
|
-
const
|
|
21
|
-
[customClassName]: !!customClassName
|
|
20
|
+
const classNames = cx(`${prefix}--switcher__item--divider`, {
|
|
21
|
+
[customClassName || '']: !!customClassName
|
|
22
22
|
});
|
|
23
23
|
return /*#__PURE__*/React__default.createElement("hr", _extends({}, other, {
|
|
24
|
-
className:
|
|
24
|
+
className: classNames
|
|
25
25
|
}));
|
|
26
26
|
};
|
|
27
27
|
SwitcherDivider.propTypes = {
|
|
@@ -30,6 +30,5 @@ SwitcherDivider.propTypes = {
|
|
|
30
30
|
*/
|
|
31
31
|
className: PropTypes.string
|
|
32
32
|
};
|
|
33
|
-
var SwitcherDivider$1 = SwitcherDivider;
|
|
34
33
|
|
|
35
|
-
export { SwitcherDivider
|
|
34
|
+
export { SwitcherDivider as default };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface BaseSwitcherItemProps {
|
|
3
|
+
/**
|
|
4
|
+
* Specify the text content for the link
|
|
5
|
+
*/
|
|
6
|
+
children: React.ReactNode;
|
|
7
|
+
/**
|
|
8
|
+
* Optionally provide a custom class to apply to the underlying `<li>` node
|
|
9
|
+
*/
|
|
10
|
+
className?: string;
|
|
11
|
+
/**
|
|
12
|
+
* event handlers
|
|
13
|
+
*/
|
|
14
|
+
handleSwitcherItemFocus?: (event: {
|
|
15
|
+
currentIndex: number;
|
|
16
|
+
direction: number;
|
|
17
|
+
}) => void;
|
|
18
|
+
/**
|
|
19
|
+
* Specify the index of the SwitcherItem
|
|
20
|
+
*/
|
|
21
|
+
index?: number;
|
|
22
|
+
/**
|
|
23
|
+
* event handlers
|
|
24
|
+
*/
|
|
25
|
+
onKeyDown?: (event: KeyboardEvent) => void;
|
|
26
|
+
/**
|
|
27
|
+
* Specify the tab index of the Link
|
|
28
|
+
*/
|
|
29
|
+
tabIndex?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Specify whether the panel is expanded
|
|
32
|
+
*/
|
|
33
|
+
expanded?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Specify whether the panel is selected
|
|
36
|
+
*/
|
|
37
|
+
isSelected?: boolean;
|
|
38
|
+
}
|
|
39
|
+
interface SwitcherItemWithAriaLabel extends BaseSwitcherItemProps {
|
|
40
|
+
'aria-label': string;
|
|
41
|
+
'aria-labelledby'?: never;
|
|
42
|
+
}
|
|
43
|
+
interface SwitcherItemWithAriaLabelledBy extends BaseSwitcherItemProps {
|
|
44
|
+
'aria-label'?: never;
|
|
45
|
+
'aria-labelledby': string;
|
|
46
|
+
}
|
|
47
|
+
type SwitcherItemProps = SwitcherItemWithAriaLabel | SwitcherItemWithAriaLabelledBy;
|
|
48
|
+
declare const SwitcherItem: React.ForwardRefExoticComponent<SwitcherItemProps & React.RefAttributes<React.ElementType<any>>>;
|
|
49
|
+
export default SwitcherItem;
|
|
@@ -6,17 +6,17 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
9
|
-
import React__default from 'react';
|
|
9
|
+
import React__default, { forwardRef } from 'react';
|
|
10
10
|
import cx from 'classnames';
|
|
11
11
|
import PropTypes from 'prop-types';
|
|
12
|
-
import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
|
|
13
12
|
import Link from './Link.js';
|
|
14
13
|
import { usePrefix } from '../../internal/usePrefix.js';
|
|
14
|
+
import { AriaLabelPropType } from '../../prop-types/AriaPropTypes.js';
|
|
15
15
|
import { match } from '../../internal/keyboard/match.js';
|
|
16
16
|
import { ArrowDown, ArrowUp } from '../../internal/keyboard/keys.js';
|
|
17
17
|
|
|
18
|
-
const SwitcherItem = /*#__PURE__*/
|
|
19
|
-
|
|
18
|
+
const SwitcherItem = /*#__PURE__*/forwardRef(function SwitcherItem(props, forwardRef) {
|
|
19
|
+
const {
|
|
20
20
|
'aria-label': ariaLabel,
|
|
21
21
|
'aria-labelledby': ariaLabelledBy,
|
|
22
22
|
className: customClassName,
|
|
@@ -28,10 +28,10 @@ const SwitcherItem = /*#__PURE__*/React__default.forwardRef(function SwitcherIte
|
|
|
28
28
|
handleSwitcherItemFocus,
|
|
29
29
|
onKeyDown = () => {},
|
|
30
30
|
...rest
|
|
31
|
-
} =
|
|
31
|
+
} = props;
|
|
32
32
|
const prefix = usePrefix();
|
|
33
|
-
const
|
|
34
|
-
[customClassName]: !!customClassName
|
|
33
|
+
const classNames = cx(`${prefix}--switcher__item`, {
|
|
34
|
+
[customClassName || '']: !!customClassName
|
|
35
35
|
});
|
|
36
36
|
const accessibilityLabel = {
|
|
37
37
|
'aria-label': ariaLabel,
|
|
@@ -44,36 +44,33 @@ const SwitcherItem = /*#__PURE__*/React__default.forwardRef(function SwitcherIte
|
|
|
44
44
|
if (match(evt, ArrowDown)) {
|
|
45
45
|
evt.preventDefault();
|
|
46
46
|
handleSwitcherItemFocus?.({
|
|
47
|
-
currentIndex: index,
|
|
47
|
+
currentIndex: index || -1,
|
|
48
48
|
direction: 1
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
if (match(evt, ArrowUp)) {
|
|
52
52
|
evt.preventDefault();
|
|
53
53
|
handleSwitcherItemFocus?.({
|
|
54
|
-
currentIndex: index,
|
|
54
|
+
currentIndex: index || -1,
|
|
55
55
|
direction: -1
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
return /*#__PURE__*/React__default.createElement("li", {
|
|
60
|
-
className:
|
|
60
|
+
className: classNames
|
|
61
61
|
}, /*#__PURE__*/React__default.createElement(Link, _extends({
|
|
62
62
|
onKeyDown: evt => {
|
|
63
63
|
setTabFocus(evt);
|
|
64
64
|
onKeyDown(evt);
|
|
65
|
-
}
|
|
65
|
+
},
|
|
66
|
+
ref: forwardRef
|
|
66
67
|
}, rest, {
|
|
67
|
-
ref: ref,
|
|
68
68
|
className: linkClassName,
|
|
69
69
|
tabIndex: tabIndex
|
|
70
70
|
}, accessibilityLabel), children));
|
|
71
71
|
});
|
|
72
72
|
SwitcherItem.displayName = 'SwitcherItem';
|
|
73
73
|
SwitcherItem.propTypes = {
|
|
74
|
-
/**
|
|
75
|
-
* Required props for accessibility label on the underlying menuitem
|
|
76
|
-
*/
|
|
77
74
|
...AriaLabelPropType,
|
|
78
75
|
/**
|
|
79
76
|
* Specify the text content for the link
|
|
@@ -100,6 +97,5 @@ SwitcherItem.propTypes = {
|
|
|
100
97
|
*/
|
|
101
98
|
tabIndex: PropTypes.number
|
|
102
99
|
};
|
|
103
|
-
var SwitcherItem$1 = SwitcherItem;
|
|
104
100
|
|
|
105
|
-
export { SwitcherItem
|
|
101
|
+
export { SwitcherItem as default };
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
|
|
8
|
+
const cachedDisplayNames = new WeakMap();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `getDisplayName` is a utility function for getting a name from a given
|
|
12
|
+
* component type. It supports names from React elements, Stateless Functional
|
|
13
|
+
* Components, and Class-based Components
|
|
14
|
+
*/
|
|
15
|
+
const getDisplayName = type => {
|
|
16
|
+
if (typeof type === 'string') {
|
|
17
|
+
return type;
|
|
18
|
+
}
|
|
19
|
+
if (cachedDisplayNames.has(type)) {
|
|
20
|
+
return cachedDisplayNames.get(type);
|
|
21
|
+
}
|
|
22
|
+
let displayName;
|
|
23
|
+
if (typeof type.displayName === 'string') {
|
|
24
|
+
displayName = type.displayName;
|
|
25
|
+
}
|
|
26
|
+
if (!displayName) {
|
|
27
|
+
displayName = type.name || 'Unknown';
|
|
28
|
+
}
|
|
29
|
+
cachedDisplayNames.set(type, displayName);
|
|
30
|
+
return displayName;
|
|
31
|
+
};
|
|
32
|
+
var getDisplayName$1 = getDisplayName;
|
|
33
|
+
|
|
34
|
+
export { getDisplayName$1 as default };
|