@carbon/react 1.47.0 → 1.48.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 +914 -839
- package/es/components/Button/Button.d.ts +1 -3
- package/es/components/Button/Button.js +9 -3
- package/es/components/ComboButton/index.js +1 -0
- package/es/components/ComposedModal/ModalHeader.js +10 -4
- package/es/components/DangerButton/DangerButton.js +2 -2
- package/es/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/es/components/DataTable/TableExpandRow.d.ts +1 -1
- package/es/components/DataTable/TableExpandRow.js +0 -1
- package/es/components/DataTable/TableHeader.d.ts +10 -1
- package/es/components/DataTable/index.d.ts +3 -2
- package/es/components/DatePicker/DatePicker.js +3 -2
- package/es/components/Dropdown/Dropdown.d.ts +3 -2
- package/es/components/Dropdown/index.d.ts +2 -2
- package/es/components/ExpandableSearch/ExpandableSearch.js +6 -3
- package/es/components/IconButton/index.d.ts +70 -0
- package/es/components/IconButton/index.js +6 -5
- package/es/components/ListBox/ListBoxMenuIcon.d.ts +3 -6
- package/es/components/ListBox/ListBoxMenuIcon.js +4 -8
- package/es/components/ListBox/index.d.ts +1 -0
- package/es/components/Menu/Menu.d.ts +59 -0
- package/es/components/Menu/Menu.js +33 -10
- package/es/components/Menu/MenuContext.d.ts +32 -0
- package/es/components/Menu/MenuItem.d.ts +119 -0
- package/es/components/Menu/MenuItem.js +17 -12
- package/es/components/Menu/index.d.ts +9 -0
- package/es/components/MenuButton/index.js +1 -0
- package/es/components/Modal/Modal.d.ts +1 -1
- package/es/components/Modal/Modal.js +10 -6
- package/es/components/OverflowMenu/next/index.js +1 -0
- package/es/components/Slug/index.js +5 -1
- package/es/components/Tooltip/Tooltip.js +1 -9
- package/es/components/TreeView/TreeNode.js +11 -3
- package/es/components/TreeView/TreeView.js +1 -1
- package/es/components/UIShell/HeaderMenu.js +1 -1
- package/es/components/UIShell/SwitcherItem.d.ts +4 -0
- package/es/components/UIShell/SwitcherItem.js +4 -0
- package/es/index.js +3 -3
- package/lib/components/Button/Button.d.ts +1 -3
- package/lib/components/Button/Button.js +9 -3
- package/lib/components/ComboButton/index.js +1 -0
- package/lib/components/ComposedModal/ModalHeader.js +10 -4
- package/lib/components/DangerButton/DangerButton.js +2 -2
- package/lib/components/DataTable/TableExpandHeader.d.ts +1 -1
- package/lib/components/DataTable/TableExpandRow.d.ts +1 -1
- package/lib/components/DataTable/TableExpandRow.js +0 -1
- package/lib/components/DataTable/TableHeader.d.ts +10 -1
- package/lib/components/DataTable/index.d.ts +3 -2
- package/lib/components/DatePicker/DatePicker.js +3 -2
- package/lib/components/Dropdown/Dropdown.d.ts +3 -2
- package/lib/components/Dropdown/index.d.ts +2 -2
- package/lib/components/ExpandableSearch/ExpandableSearch.js +5 -2
- package/lib/components/IconButton/index.d.ts +70 -0
- package/lib/components/IconButton/index.js +6 -4
- package/lib/components/ListBox/ListBoxMenuIcon.d.ts +3 -6
- package/lib/components/ListBox/ListBoxMenuIcon.js +3 -8
- package/lib/components/ListBox/index.d.ts +1 -0
- package/lib/components/Menu/Menu.d.ts +59 -0
- package/lib/components/Menu/Menu.js +33 -10
- package/lib/components/Menu/MenuContext.d.ts +32 -0
- package/lib/components/Menu/MenuItem.d.ts +119 -0
- package/lib/components/Menu/MenuItem.js +17 -12
- package/lib/components/Menu/index.d.ts +9 -0
- package/lib/components/MenuButton/index.js +1 -0
- package/lib/components/Modal/Modal.d.ts +1 -1
- package/lib/components/Modal/Modal.js +10 -6
- package/lib/components/OverflowMenu/next/index.js +1 -0
- package/lib/components/Slug/index.js +5 -1
- package/lib/components/Tooltip/Tooltip.js +0 -8
- package/lib/components/TreeView/TreeNode.js +11 -3
- package/lib/components/TreeView/TreeView.js +1 -1
- package/lib/components/UIShell/HeaderMenu.js +1 -1
- package/lib/components/UIShell/SwitcherItem.d.ts +4 -0
- package/lib/components/UIShell/SwitcherItem.js +4 -0
- package/lib/index.js +9 -8
- package/package.json +7 -7
|
@@ -348,7 +348,7 @@ const DatePicker = /*#__PURE__*/React__default["default"].forwardRef(function Da
|
|
|
348
348
|
}
|
|
349
349
|
}
|
|
350
350
|
function handleOnChange(event) {
|
|
351
|
-
if (datePickerType == 'single') {
|
|
351
|
+
if (datePickerType == 'single' && closeOnSelect) {
|
|
352
352
|
calendar.calendarContainer.classList.remove('open');
|
|
353
353
|
}
|
|
354
354
|
const {
|
|
@@ -413,7 +413,8 @@ const DatePicker = /*#__PURE__*/React__default["default"].forwardRef(function Da
|
|
|
413
413
|
end.removeEventListener('change', handleOnChange);
|
|
414
414
|
}
|
|
415
415
|
};
|
|
416
|
-
|
|
416
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
417
|
+
}, [savedOnChange, savedOnClose, savedOnOpen, readOnly, closeOnSelect, hasInput]);
|
|
417
418
|
|
|
418
419
|
// this hook allows consumers to access the flatpickr calendar
|
|
419
420
|
// instance for cases where functions like open() or close()
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import React, { ReactNode } from 'react';
|
|
8
8
|
import { UseSelectProps } from 'downshift';
|
|
9
9
|
import { ReactNodeLike } from 'prop-types';
|
|
10
|
-
import { ListBoxSize, ListBoxType } from '../ListBox';
|
|
10
|
+
import { type ListBoxMenuIconTranslationKey, ListBoxSize, ListBoxType } from '../ListBox';
|
|
11
11
|
import { ReactAttr } from '../../types/common';
|
|
12
12
|
type ExcludedAttributes = 'id' | 'onChange';
|
|
13
13
|
export interface OnChangeData<ItemType> {
|
|
@@ -123,7 +123,7 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
|
|
|
123
123
|
/**
|
|
124
124
|
* Callback function for translating ListBoxMenuIcon SVG title
|
|
125
125
|
*/
|
|
126
|
-
translateWithId?(messageId:
|
|
126
|
+
translateWithId?(messageId: ListBoxMenuIconTranslationKey, args?: Record<string, unknown>): string;
|
|
127
127
|
/**
|
|
128
128
|
* The dropdown type, `default` or `inline`
|
|
129
129
|
*/
|
|
@@ -137,6 +137,7 @@ export interface DropdownProps<ItemType> extends Omit<ReactAttr<HTMLDivElement>,
|
|
|
137
137
|
*/
|
|
138
138
|
warnText?: React.ReactNode;
|
|
139
139
|
}
|
|
140
|
+
export type DropdownTranslationKey = ListBoxMenuIconTranslationKey;
|
|
140
141
|
type DropdownComponentProps<ItemType> = React.PropsWithoutRef<React.PropsWithChildren<DropdownProps<ItemType>> & React.RefAttributes<HTMLButtonElement>>;
|
|
141
142
|
interface DropdownComponent {
|
|
142
143
|
<ItemType>(props: DropdownComponentProps<ItemType>): React.ReactElement | null;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
|
-
import Dropdown, { OnChangeData } from './Dropdown';
|
|
8
|
-
export type { OnChangeData };
|
|
7
|
+
import Dropdown, { type DropdownTranslationKey, type OnChangeData } from './Dropdown';
|
|
8
|
+
export type { DropdownTranslationKey, OnChangeData };
|
|
9
9
|
export { Dropdown };
|
|
10
10
|
export { default as DropdownSkeleton } from './Dropdown.Skeleton';
|
|
11
11
|
export default Dropdown;
|
|
@@ -40,10 +40,13 @@ function ExpandableSearch(_ref) {
|
|
|
40
40
|
const prefix = usePrefix.usePrefix();
|
|
41
41
|
function handleBlur(evt) {
|
|
42
42
|
const relatedTargetIsAllowed = evt.relatedTarget && evt.relatedTarget.classList.contains(`${prefix}--search-close`);
|
|
43
|
-
if (expanded && !relatedTargetIsAllowed && !hasContent) {
|
|
43
|
+
if (expanded && !relatedTargetIsAllowed && !hasContent && !isExpanded) {
|
|
44
44
|
setExpanded(false);
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
|
+
React.useEffect(() => {
|
|
48
|
+
setExpanded(!!isExpanded);
|
|
49
|
+
}, [isExpanded]);
|
|
47
50
|
function handleChange(evt) {
|
|
48
51
|
setHasContent(evt.target.value !== '');
|
|
49
52
|
}
|
|
@@ -56,7 +59,7 @@ function ExpandableSearch(_ref) {
|
|
|
56
59
|
evt.stopPropagation();
|
|
57
60
|
|
|
58
61
|
// escape key only clears if the input is empty, otherwise it clears the input
|
|
59
|
-
if (!evt.target?.value) {
|
|
62
|
+
if (!evt.target?.value && !isExpanded) {
|
|
60
63
|
setExpanded(false);
|
|
61
64
|
}
|
|
62
65
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
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 { ReactNodeLike } from 'prop-types';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { ButtonSize } from '../Button';
|
|
10
|
+
export declare const IconButtonKinds: readonly ["primary", "secondary", "ghost", "tertiary"];
|
|
11
|
+
export type IconButtonKind = (typeof IconButtonKinds)[number];
|
|
12
|
+
interface IconButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
13
|
+
/**
|
|
14
|
+
* Specify how the trigger should align with the tooltip
|
|
15
|
+
*/
|
|
16
|
+
align?: 'top' | 'top-left' | 'top-right' | 'bottom' | 'bottom-left' | 'bottom-right' | 'left' | 'right';
|
|
17
|
+
/**
|
|
18
|
+
* Provide an icon or asset to be rendered inside of the IconButton
|
|
19
|
+
*/
|
|
20
|
+
children?: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* Specify an optional className to be added to your Button
|
|
23
|
+
*/
|
|
24
|
+
className?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Determines whether the tooltip should close when inner content is activated (click, Enter or Space)
|
|
27
|
+
*/
|
|
28
|
+
closeOnActivation?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Specify whether the tooltip should be open when it first renders
|
|
31
|
+
*/
|
|
32
|
+
defaultOpen?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Specify whether the Button should be disabled, or not
|
|
35
|
+
*/
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Specify the duration in milliseconds to delay before displaying the tooltip
|
|
39
|
+
*/
|
|
40
|
+
enterDelayMs?: number;
|
|
41
|
+
/**
|
|
42
|
+
* Specify whether the IconButton is currently selected
|
|
43
|
+
*/
|
|
44
|
+
isSelected?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Specify the type of button to be used as the base for the IconButton
|
|
47
|
+
*/
|
|
48
|
+
kind?: IconButtonKind;
|
|
49
|
+
/**
|
|
50
|
+
* Provide the label to be rendered inside of the Tooltip. The label will use
|
|
51
|
+
* `aria-labelledby` and will fully describe the child node that is provided.
|
|
52
|
+
* This means that if you have text in the child node it will not be
|
|
53
|
+
* announced to the screen reader.
|
|
54
|
+
*/
|
|
55
|
+
label: ReactNodeLike;
|
|
56
|
+
/**
|
|
57
|
+
* Specify the duration in milliseconds to delay before hiding the tooltip
|
|
58
|
+
*/
|
|
59
|
+
leaveDelayMs?: number;
|
|
60
|
+
/**
|
|
61
|
+
* Specify the size of the Button. Defaults to `md`.
|
|
62
|
+
*/
|
|
63
|
+
size?: ButtonSize;
|
|
64
|
+
/**
|
|
65
|
+
* Specify an optional className to be added to your Tooltip wrapper
|
|
66
|
+
*/
|
|
67
|
+
wrapperClasses?: string;
|
|
68
|
+
}
|
|
69
|
+
declare const IconButton: React.ForwardRefExoticComponent<IconButtonProps & React.RefAttributes<unknown>>;
|
|
70
|
+
export { IconButton };
|
|
@@ -25,8 +25,9 @@ var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
|
|
|
25
25
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
26
26
|
var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
|
|
27
27
|
|
|
28
|
-
const
|
|
29
|
-
|
|
28
|
+
const IconButtonKinds = ['primary', 'secondary', 'ghost', 'tertiary'];
|
|
29
|
+
const IconButton = /*#__PURE__*/React__default["default"].forwardRef(function IconButton(_ref, ref) {
|
|
30
|
+
let {
|
|
30
31
|
align,
|
|
31
32
|
children,
|
|
32
33
|
className,
|
|
@@ -41,7 +42,7 @@ const IconButton = /*#__PURE__*/React__default["default"].forwardRef(function Ic
|
|
|
41
42
|
size,
|
|
42
43
|
isSelected,
|
|
43
44
|
...rest
|
|
44
|
-
} =
|
|
45
|
+
} = _ref;
|
|
45
46
|
const prefix = usePrefix.usePrefix();
|
|
46
47
|
const tooltipClasses = cx__default["default"](wrapperClasses, `${prefix}--icon-tooltip`, {
|
|
47
48
|
[`${prefix}--icon-tooltip--disabled`]: disabled
|
|
@@ -101,7 +102,7 @@ IconButton.propTypes = {
|
|
|
101
102
|
/**
|
|
102
103
|
* Specify the type of button to be used as the base for the IconButton
|
|
103
104
|
*/
|
|
104
|
-
kind: PropTypes__default["default"].oneOf(
|
|
105
|
+
kind: PropTypes__default["default"].oneOf(IconButtonKinds),
|
|
105
106
|
/**
|
|
106
107
|
* Provide the label to be rendered inside of the Tooltip. The label will use
|
|
107
108
|
* `aria-labelledby` and will fully describe the child node that is provided.
|
|
@@ -124,3 +125,4 @@ IconButton.propTypes = {
|
|
|
124
125
|
};
|
|
125
126
|
|
|
126
127
|
exports.IconButton = IconButton;
|
|
128
|
+
exports.IconButtonKinds = IconButtonKinds;
|
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
import React from 'react';
|
|
8
|
-
export
|
|
9
|
-
'close.menu': string;
|
|
10
|
-
'open.menu': string;
|
|
11
|
-
};
|
|
8
|
+
export type ListBoxMenuIconTranslationKey = 'close.menu' | 'open.menu';
|
|
12
9
|
export interface ListBoxMenuIconProps {
|
|
13
10
|
/**
|
|
14
11
|
* Specify whether the menu is currently open, which will influence the
|
|
@@ -17,10 +14,10 @@ export interface ListBoxMenuIconProps {
|
|
|
17
14
|
isOpen: boolean;
|
|
18
15
|
/**
|
|
19
16
|
* i18n hook used to provide the appropriate description for the given menu
|
|
20
|
-
* icon. This function takes in
|
|
17
|
+
* icon. This function takes in a ListBoxMenuIconTranslationKey and should
|
|
21
18
|
* return a string message for that given message id.
|
|
22
19
|
*/
|
|
23
|
-
translateWithId?(messageId:
|
|
20
|
+
translateWithId?(messageId: ListBoxMenuIconTranslationKey, args?: Record<string, unknown>): string;
|
|
24
21
|
}
|
|
25
22
|
export type ListBoxMenuIconComponent = React.FC<ListBoxMenuIconProps>;
|
|
26
23
|
/**
|
|
@@ -21,13 +21,9 @@ var cx__default = /*#__PURE__*/_interopDefaultLegacy(cx);
|
|
|
21
21
|
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
|
|
22
22
|
var PropTypes__default = /*#__PURE__*/_interopDefaultLegacy(PropTypes);
|
|
23
23
|
|
|
24
|
-
const translationIds = {
|
|
25
|
-
'close.menu': 'close.menu',
|
|
26
|
-
'open.menu': 'open.menu'
|
|
27
|
-
};
|
|
28
24
|
const defaultTranslations = {
|
|
29
|
-
|
|
30
|
-
|
|
25
|
+
'close.menu': 'Close menu',
|
|
26
|
+
'open.menu': 'Open menu'
|
|
31
27
|
};
|
|
32
28
|
const defaultTranslateWithId = id => defaultTranslations[id];
|
|
33
29
|
/**
|
|
@@ -59,11 +55,10 @@ ListBoxMenuIcon.propTypes = {
|
|
|
59
55
|
isOpen: PropTypes__default["default"].bool.isRequired,
|
|
60
56
|
/**
|
|
61
57
|
* i18n hook used to provide the appropriate description for the given menu
|
|
62
|
-
* icon. This function takes
|
|
58
|
+
* icon. This function takes a ListBoxMenuIconTranslationKey and should
|
|
63
59
|
* return a string message for that given message id.
|
|
64
60
|
*/
|
|
65
61
|
translateWithId: PropTypes__default["default"].func
|
|
66
62
|
};
|
|
67
63
|
|
|
68
64
|
exports["default"] = ListBoxMenuIcon;
|
|
69
|
-
exports.translationIds = translationIds;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 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
|
+
interface MenuProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
9
|
+
/**
|
|
10
|
+
* A collection of MenuItems to be rendered within this Menu.
|
|
11
|
+
*/
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
/**
|
|
14
|
+
* Additional CSS class names.
|
|
15
|
+
*/
|
|
16
|
+
className?: string;
|
|
17
|
+
/**
|
|
18
|
+
* A label describing the Menu.
|
|
19
|
+
*/
|
|
20
|
+
label?: string;
|
|
21
|
+
/**
|
|
22
|
+
* The mode of this menu. Defaults to full.
|
|
23
|
+
* `full` supports nesting and selectable menu items, but no icons.
|
|
24
|
+
* `basic` supports icons but no nesting or selectable menu items.
|
|
25
|
+
*
|
|
26
|
+
* **This prop is not intended for use and will be set by the respective implementation (like useContextMenu, MenuButton, and ComboButton).**
|
|
27
|
+
*/
|
|
28
|
+
mode?: 'full' | 'basic';
|
|
29
|
+
/**
|
|
30
|
+
* Provide an optional function to be called when the Menu should be closed.
|
|
31
|
+
*/
|
|
32
|
+
onClose?: () => void;
|
|
33
|
+
/**
|
|
34
|
+
* Provide an optional function to be called when the Menu is opened.
|
|
35
|
+
*/
|
|
36
|
+
onOpen?: () => void;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the Menu is open or not.
|
|
39
|
+
*/
|
|
40
|
+
open?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Specify the size of the Menu.
|
|
43
|
+
*/
|
|
44
|
+
size?: 'xs' | 'sm' | 'md' | 'lg';
|
|
45
|
+
/**
|
|
46
|
+
* Specify a DOM node where the Menu should be rendered in. Defaults to document.body.
|
|
47
|
+
*/
|
|
48
|
+
target?: any;
|
|
49
|
+
/**
|
|
50
|
+
* Specify the x position of the Menu. Either pass a single number or an array with two numbers describing your activator's boundaries ([x1, x2])
|
|
51
|
+
*/
|
|
52
|
+
x?: number | (number | null | undefined)[];
|
|
53
|
+
/**
|
|
54
|
+
* Specify the y position of the Menu. Either pass a single number or an array with two numbers describing your activator's boundaries ([y1, y2])
|
|
55
|
+
*/
|
|
56
|
+
y?: number | (number | null | undefined)[];
|
|
57
|
+
}
|
|
58
|
+
declare const Menu: React.ForwardRefExoticComponent<MenuProps & React.RefAttributes<HTMLUListElement>>;
|
|
59
|
+
export { Menu };
|
|
@@ -66,7 +66,7 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
|
|
|
66
66
|
dispatch: childDispatch
|
|
67
67
|
};
|
|
68
68
|
}, [childState, childDispatch]);
|
|
69
|
-
const menu = React.useRef();
|
|
69
|
+
const menu = React.useRef(null);
|
|
70
70
|
const ref = useMergedRefs.useMergedRefs([forwardRef, menu]);
|
|
71
71
|
const [position, setPosition] = React.useState([-1, -1]);
|
|
72
72
|
const focusableItems = childContext.state.items.filter(item => !item.disabled && item.ref.current);
|
|
@@ -154,11 +154,14 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
function handleBlur(e) {
|
|
157
|
-
if (open && onClose && isRoot && !menu.current
|
|
157
|
+
if (open && onClose && isRoot && !menu.current?.contains(e.relatedTarget)) {
|
|
158
158
|
handleClose(e);
|
|
159
159
|
}
|
|
160
160
|
}
|
|
161
161
|
function fitValue(range, axis) {
|
|
162
|
+
if (!menu.current) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
162
165
|
const {
|
|
163
166
|
width,
|
|
164
167
|
height
|
|
@@ -197,18 +200,38 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
|
|
|
197
200
|
reversedAnchor - size >= 0 ? reversedAnchor - size + offset : false,
|
|
198
201
|
// align at max (second fallback)
|
|
199
202
|
max - spacing - size];
|
|
203
|
+
|
|
204
|
+
// Previous array `options`, has at least one item that is a number (the last one - second fallback).
|
|
205
|
+
// That guarantees that the return of `find()` will always be a number
|
|
206
|
+
// and we can safely add the numeric casting `as number`.
|
|
200
207
|
const bestOption = options.find(option => option !== false);
|
|
201
208
|
return bestOption >= spacing ? bestOption : spacing;
|
|
202
209
|
}
|
|
210
|
+
function notEmpty(value) {
|
|
211
|
+
return value !== null && value !== undefined;
|
|
212
|
+
}
|
|
213
|
+
function getPosition(x) {
|
|
214
|
+
if (Array.isArray(x)) {
|
|
215
|
+
// has to be of length 2
|
|
216
|
+
const filtered = x.filter(notEmpty);
|
|
217
|
+
if (filtered.length === 2) {
|
|
218
|
+
return filtered;
|
|
219
|
+
} else {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
return [x, x];
|
|
224
|
+
}
|
|
225
|
+
}
|
|
203
226
|
function calculatePosition() {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
return [
|
|
227
|
+
const ranges = {
|
|
228
|
+
x: getPosition(x),
|
|
229
|
+
y: getPosition(y)
|
|
230
|
+
};
|
|
231
|
+
if (!ranges.x || !ranges.y) {
|
|
232
|
+
return [-1, -1];
|
|
210
233
|
}
|
|
211
|
-
return [-1, -1];
|
|
234
|
+
return [fitValue(ranges.x, 'x') ?? -1, fitValue(ranges.y, 'y') ?? -1];
|
|
212
235
|
}
|
|
213
236
|
React.useEffect(() => {
|
|
214
237
|
if (open && focusableItems.length > 0) {
|
|
@@ -222,7 +245,7 @@ const Menu = /*#__PURE__*/React__default["default"].forwardRef(function Menu(_re
|
|
|
222
245
|
} else {
|
|
223
246
|
// reset position when menu is closed in order for the --shown
|
|
224
247
|
// modifier to be applied correctly
|
|
225
|
-
setPosition(-1, -1);
|
|
248
|
+
setPosition([-1, -1]);
|
|
226
249
|
}
|
|
227
250
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
228
251
|
}, [open]);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 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
|
+
type ActionType = {
|
|
9
|
+
type: 'enableIcons' | 'registerItem';
|
|
10
|
+
payload: any;
|
|
11
|
+
};
|
|
12
|
+
type StateType = {
|
|
13
|
+
isRoot: boolean;
|
|
14
|
+
mode: 'full' | 'basic';
|
|
15
|
+
hasIcons: boolean;
|
|
16
|
+
size: 'xs' | 'sm' | 'md' | 'lg' | null;
|
|
17
|
+
items: any[];
|
|
18
|
+
requestCloseRoot: (e: Pick<React.KeyboardEvent<HTMLUListElement>, 'type'>) => void;
|
|
19
|
+
};
|
|
20
|
+
declare function menuReducer(state: StateType, action: ActionType): {
|
|
21
|
+
hasIcons: boolean;
|
|
22
|
+
isRoot: boolean;
|
|
23
|
+
mode: "full" | "basic";
|
|
24
|
+
size: "sm" | "md" | "lg" | "xs" | null;
|
|
25
|
+
items: any[];
|
|
26
|
+
requestCloseRoot: (e: Pick<React.KeyboardEvent<HTMLUListElement>, "type">) => void;
|
|
27
|
+
};
|
|
28
|
+
declare const MenuContext: React.Context<{
|
|
29
|
+
state: StateType;
|
|
30
|
+
dispatch: React.Dispatch<any>;
|
|
31
|
+
}>;
|
|
32
|
+
export { MenuContext, menuReducer };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 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
|
+
interface MenuItemProps extends React.LiHTMLAttributes<HTMLLIElement> {
|
|
9
|
+
/**
|
|
10
|
+
* Optionally provide another Menu to create a submenu. props.children can't be used to specify the content of the MenuItem itself. Use props.label instead.
|
|
11
|
+
*/
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
/**
|
|
14
|
+
* Additional CSS class names.
|
|
15
|
+
*/
|
|
16
|
+
className?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Specify whether the MenuItem is disabled or not.
|
|
19
|
+
*/
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Specify the kind of the MenuItem.
|
|
23
|
+
*/
|
|
24
|
+
kind?: 'default' | 'danger';
|
|
25
|
+
/**
|
|
26
|
+
* A required label titling the MenuItem. Will be rendered as its text content.
|
|
27
|
+
*/
|
|
28
|
+
label: string;
|
|
29
|
+
/**
|
|
30
|
+
* Provide an optional function to be called when the MenuItem is clicked.
|
|
31
|
+
*/
|
|
32
|
+
onClick?: (event: React.KeyboardEvent<HTMLLIElement> | React.MouseEvent<HTMLLIElement>) => void;
|
|
33
|
+
/**
|
|
34
|
+
* Only applicable if the parent menu is in `basic` mode. Sets the menu item's icon.
|
|
35
|
+
*/
|
|
36
|
+
renderIcon?: any;
|
|
37
|
+
/**
|
|
38
|
+
* Provide a shortcut for the action of this MenuItem. Note that the component will only render it as a hint but not actually register the shortcut.
|
|
39
|
+
*/
|
|
40
|
+
shortcut?: string;
|
|
41
|
+
}
|
|
42
|
+
declare const MenuItem: React.ForwardRefExoticComponent<MenuItemProps & React.RefAttributes<HTMLLIElement>>;
|
|
43
|
+
interface MenuItemSelectableProps {
|
|
44
|
+
/**
|
|
45
|
+
* Additional CSS class names.
|
|
46
|
+
*/
|
|
47
|
+
className?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Specify whether the option should be selected by default.
|
|
50
|
+
*/
|
|
51
|
+
defaultSelected?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* A required label titling this option.
|
|
54
|
+
*/
|
|
55
|
+
label: string;
|
|
56
|
+
/**
|
|
57
|
+
* Provide an optional function to be called when the selection state changes.
|
|
58
|
+
*/
|
|
59
|
+
onChange?: React.ChangeEventHandler<HTMLLIElement>;
|
|
60
|
+
/**
|
|
61
|
+
* Pass a bool to props.selected to control the state of this option.
|
|
62
|
+
*/
|
|
63
|
+
selected?: boolean;
|
|
64
|
+
}
|
|
65
|
+
declare const MenuItemSelectable: React.ForwardRefExoticComponent<MenuItemSelectableProps & React.RefAttributes<HTMLLIElement>>;
|
|
66
|
+
interface MenuItemGroupProps {
|
|
67
|
+
/**
|
|
68
|
+
* A collection of MenuItems to be rendered within this group.
|
|
69
|
+
*/
|
|
70
|
+
children?: React.ReactNode;
|
|
71
|
+
/**
|
|
72
|
+
* Additional CSS class names.
|
|
73
|
+
*/
|
|
74
|
+
className?: string;
|
|
75
|
+
/**
|
|
76
|
+
* A required label titling this group.
|
|
77
|
+
*/
|
|
78
|
+
label: string;
|
|
79
|
+
}
|
|
80
|
+
declare const MenuItemGroup: React.ForwardRefExoticComponent<MenuItemGroupProps & React.RefAttributes<HTMLLIElement>>;
|
|
81
|
+
interface MenuItemRadioGroupProps {
|
|
82
|
+
/**
|
|
83
|
+
* Additional CSS class names.
|
|
84
|
+
*/
|
|
85
|
+
className?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Specify the default selected item. Must match the type of props.items.
|
|
88
|
+
*/
|
|
89
|
+
defaultSelectedItem?: any;
|
|
90
|
+
/**
|
|
91
|
+
* Provide a function to convert an item to the string that will be rendered. Defaults to item.toString().
|
|
92
|
+
*/
|
|
93
|
+
itemToString?: (item: any) => string;
|
|
94
|
+
/**
|
|
95
|
+
* Provide the options for this radio group. Can be of any type, as long as you provide an appropriate props.itemToString function.
|
|
96
|
+
*/
|
|
97
|
+
items?: any[];
|
|
98
|
+
/**
|
|
99
|
+
* A required label titling this radio group.
|
|
100
|
+
*/
|
|
101
|
+
label: string;
|
|
102
|
+
/**
|
|
103
|
+
* Provide an optional function to be called when the selection changes.
|
|
104
|
+
*/
|
|
105
|
+
onChange?: React.ChangeEventHandler<HTMLLIElement>;
|
|
106
|
+
/**
|
|
107
|
+
* Provide props.selectedItem to control the state of this radio group. Must match the type of props.items.
|
|
108
|
+
*/
|
|
109
|
+
selectedItem?: any;
|
|
110
|
+
}
|
|
111
|
+
declare const MenuItemRadioGroup: React.ForwardRefExoticComponent<MenuItemRadioGroupProps & React.RefAttributes<HTMLLIElement>>;
|
|
112
|
+
interface MenuItemDividerProps {
|
|
113
|
+
/**
|
|
114
|
+
* Additional CSS class names.
|
|
115
|
+
*/
|
|
116
|
+
className?: string;
|
|
117
|
+
}
|
|
118
|
+
declare const MenuItemDivider: React.ForwardRefExoticComponent<MenuItemDividerProps & React.RefAttributes<HTMLLIElement>>;
|
|
119
|
+
export { MenuItem, MenuItemSelectable, MenuItemGroup, MenuItemRadioGroup, MenuItemDivider, };
|
|
@@ -49,7 +49,7 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
|
|
|
49
49
|
} = _ref;
|
|
50
50
|
const prefix = usePrefix.usePrefix();
|
|
51
51
|
const context = React.useContext(MenuContext.MenuContext);
|
|
52
|
-
const menuItem = React.useRef();
|
|
52
|
+
const menuItem = React.useRef(null);
|
|
53
53
|
const ref = useMergedRefs.useMergedRefs([forwardRef, menuItem]);
|
|
54
54
|
const [boundaries, setBoundaries] = React.useState({
|
|
55
55
|
x: -1,
|
|
@@ -71,6 +71,9 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
|
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
73
|
function openSubmenu() {
|
|
74
|
+
if (!menuItem.current) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
74
77
|
const {
|
|
75
78
|
x,
|
|
76
79
|
y,
|
|
@@ -115,9 +118,11 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
|
|
|
115
118
|
}, hoverIntentDelay);
|
|
116
119
|
}
|
|
117
120
|
function handleMouseLeave() {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
if (hoverIntentTimeout.current) {
|
|
122
|
+
clearTimeout(hoverIntentTimeout.current);
|
|
123
|
+
closeSubmenu();
|
|
124
|
+
menuItem.current?.focus();
|
|
125
|
+
}
|
|
121
126
|
}
|
|
122
127
|
function handleKeyDown(e) {
|
|
123
128
|
if (hasChildren && match.match(e, keys.ArrowRight)) {
|
|
@@ -167,13 +172,13 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
|
|
|
167
172
|
}, rest, {
|
|
168
173
|
ref: ref,
|
|
169
174
|
className: classNames,
|
|
170
|
-
tabIndex:
|
|
171
|
-
"aria-disabled": isDisabled
|
|
172
|
-
"aria-haspopup": hasChildren ||
|
|
173
|
-
"aria-expanded": hasChildren ? submenuOpen :
|
|
175
|
+
tabIndex: -1,
|
|
176
|
+
"aria-disabled": isDisabled,
|
|
177
|
+
"aria-haspopup": hasChildren || undefined,
|
|
178
|
+
"aria-expanded": hasChildren ? submenuOpen : undefined,
|
|
174
179
|
onClick: handleClick,
|
|
175
|
-
onMouseEnter: hasChildren ? handleMouseEnter :
|
|
176
|
-
onMouseLeave: hasChildren ? handleMouseLeave :
|
|
180
|
+
onMouseEnter: hasChildren ? handleMouseEnter : undefined,
|
|
181
|
+
onMouseLeave: hasChildren ? handleMouseLeave : undefined,
|
|
177
182
|
onKeyDown: handleKeyDown
|
|
178
183
|
}), /*#__PURE__*/React__default["default"].createElement("div", {
|
|
179
184
|
className: `${prefix}--menu-item__icon`
|
|
@@ -190,7 +195,7 @@ const MenuItem = /*#__PURE__*/React__default["default"].forwardRef(function Menu
|
|
|
190
195
|
open: submenuOpen,
|
|
191
196
|
onClose: () => {
|
|
192
197
|
closeSubmenu();
|
|
193
|
-
menuItem.current
|
|
198
|
+
menuItem.current?.focus();
|
|
194
199
|
},
|
|
195
200
|
x: boundaries.x,
|
|
196
201
|
y: boundaries.y
|
|
@@ -370,7 +375,7 @@ const MenuItemRadioGroup = /*#__PURE__*/React__default["default"].forwardRef(fun
|
|
|
370
375
|
}, /*#__PURE__*/React__default["default"].createElement("ul", _rollupPluginBabelHelpers["extends"]({}, rest, {
|
|
371
376
|
role: "group",
|
|
372
377
|
"aria-label": label
|
|
373
|
-
}), items
|
|
378
|
+
}), items?.map((item, i) => /*#__PURE__*/React__default["default"].createElement(MenuItem, {
|
|
374
379
|
key: i,
|
|
375
380
|
label: itemToString(item),
|
|
376
381
|
role: "menuitemradio",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 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 { Menu } from './Menu';
|
|
8
|
+
import { MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable } from './MenuItem';
|
|
9
|
+
export { Menu, MenuItem, MenuItemDivider, MenuItemGroup, MenuItemRadioGroup, MenuItemSelectable, };
|
|
@@ -17,6 +17,7 @@ var iconsReact = require('@carbon/icons-react');
|
|
|
17
17
|
var Button = require('../Button/Button.js');
|
|
18
18
|
require('../Button/Button.Skeleton.js');
|
|
19
19
|
var Menu = require('../Menu/Menu.js');
|
|
20
|
+
require('../Menu/MenuItem.js');
|
|
20
21
|
var useAttachedMenu = require('../../internal/useAttachedMenu.js');
|
|
21
22
|
var useId = require('../../internal/useId.js');
|
|
22
23
|
var useMergedRefs = require('../../internal/useMergedRefs.js');
|
|
@@ -11,7 +11,7 @@ import { InlineLoadingStatus } from '../InlineLoading/InlineLoading';
|
|
|
11
11
|
export declare const ModalSizes: readonly ["xs", "sm", "md", "lg"];
|
|
12
12
|
export type ModalSize = (typeof ModalSizes)[number];
|
|
13
13
|
export interface ModalSecondaryButton {
|
|
14
|
-
buttonText?: string;
|
|
14
|
+
buttonText?: string | React.ReactNode;
|
|
15
15
|
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
16
16
|
}
|
|
17
17
|
export interface ModalProps extends ReactAttr<HTMLDivElement> {
|