@itwin/itwinui-react 3.0.0-dev.8 → 3.0.0-dev.9
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/CHANGELOG.md +12 -0
- package/cjs/core/Buttons/DropdownButton/DropdownButton.js +7 -19
- package/cjs/core/Buttons/SplitButton/SplitButton.d.ts +4 -4
- package/cjs/core/Buttons/SplitButton/SplitButton.js +53 -31
- package/cjs/core/ComboBox/ComboBox.d.ts +2 -2
- package/cjs/core/ComboBox/ComboBox.js +32 -24
- package/cjs/core/ComboBox/ComboBoxInput.js +29 -21
- package/cjs/core/ComboBox/ComboBoxMenu.js +73 -93
- package/cjs/core/ComboBox/helpers.d.ts +4 -1
- package/cjs/core/DropdownMenu/DropdownMenu.d.ts +6 -5
- package/cjs/core/DropdownMenu/DropdownMenu.js +59 -55
- package/cjs/core/Header/HeaderDropdownButton.js +1 -2
- package/cjs/core/Header/HeaderSplitButton.js +1 -2
- package/cjs/core/Menu/Menu.js +1 -1
- package/cjs/core/Menu/MenuItem.js +77 -55
- package/cjs/core/Select/Select.d.ts +5 -5
- package/cjs/core/Select/Select.js +74 -93
- package/cjs/core/Table/columns/actionColumn.js +3 -7
- package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.js +36 -41
- package/cjs/core/Table/filters/FilterToggle.js +3 -2
- package/cjs/core/Tile/Tile.js +21 -22
- package/cjs/core/index.d.ts +1 -1
- package/cjs/core/index.js +8 -1
- package/cjs/core/utils/components/InputContainer.d.ts +4 -4
- package/cjs/core/utils/components/InputContainer.js +7 -3
- package/cjs/core/utils/components/Popover.d.ts +113 -27
- package/cjs/core/utils/components/Popover.js +156 -118
- package/cjs/styles.js +2 -5
- package/esm/core/Buttons/DropdownButton/DropdownButton.js +8 -24
- package/esm/core/Buttons/SplitButton/SplitButton.d.ts +4 -4
- package/esm/core/Buttons/SplitButton/SplitButton.js +53 -28
- package/esm/core/ComboBox/ComboBox.d.ts +2 -2
- package/esm/core/ComboBox/ComboBox.js +33 -24
- package/esm/core/ComboBox/ComboBoxInput.js +22 -21
- package/esm/core/ComboBox/ComboBoxMenu.js +67 -87
- package/esm/core/ComboBox/helpers.d.ts +4 -1
- package/esm/core/DropdownMenu/DropdownMenu.d.ts +6 -5
- package/esm/core/DropdownMenu/DropdownMenu.js +64 -56
- package/esm/core/Header/HeaderDropdownButton.js +1 -2
- package/esm/core/Header/HeaderSplitButton.js +1 -2
- package/esm/core/Menu/Menu.js +7 -2
- package/esm/core/Menu/MenuItem.js +84 -52
- package/esm/core/Select/Select.d.ts +5 -5
- package/esm/core/Select/Select.js +74 -90
- package/esm/core/Table/columns/actionColumn.js +3 -7
- package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.js +36 -41
- package/esm/core/Table/filters/FilterToggle.js +3 -2
- package/esm/core/Tile/Tile.js +21 -22
- package/esm/core/index.d.ts +1 -1
- package/esm/core/index.js +1 -0
- package/esm/core/utils/components/InputContainer.d.ts +4 -4
- package/esm/core/utils/components/InputContainer.js +7 -2
- package/esm/core/utils/components/Popover.d.ts +113 -27
- package/esm/core/utils/components/Popover.js +175 -118
- package/esm/styles.js +2 -5
- package/package.json +2 -4
- package/styles.css +3 -3
- package/cjs/core/ComboBox/ComboBoxDropdown.d.ts +0 -7
- package/cjs/core/ComboBox/ComboBoxDropdown.js +0 -43
- package/esm/core/ComboBox/ComboBoxDropdown.d.ts +0 -7
- package/esm/core/ComboBox/ComboBoxDropdown.js +0 -37
package/esm/core/Menu/Menu.js
CHANGED
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
useMergedRefs,
|
|
9
|
+
getFocusableElements,
|
|
10
|
+
Box,
|
|
11
|
+
mergeEventHandlers,
|
|
12
|
+
} from '../utils/index.js';
|
|
8
13
|
/**
|
|
9
14
|
* Basic menu component. Can be used for select or dropdown components.
|
|
10
15
|
*/
|
|
@@ -63,9 +68,9 @@ export const Menu = React.forwardRef((props, ref) => {
|
|
|
63
68
|
as: 'div',
|
|
64
69
|
className: cx('iui-menu', className),
|
|
65
70
|
role: 'menu',
|
|
66
|
-
onKeyDown: onKeyDown,
|
|
67
71
|
ref: refs,
|
|
68
72
|
...rest,
|
|
73
|
+
onKeyDown: mergeEventHandlers(props.onKeyDown, onKeyDown),
|
|
69
74
|
});
|
|
70
75
|
});
|
|
71
76
|
export default Menu;
|
|
@@ -3,17 +3,27 @@
|
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import * as React from 'react';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
SvgCaretRightSmall,
|
|
8
|
+
usePopover,
|
|
9
|
+
Portal,
|
|
10
|
+
useMergedRefs,
|
|
11
|
+
useId,
|
|
12
|
+
} from '../utils/index.js';
|
|
7
13
|
import { Menu } from './Menu.js';
|
|
8
14
|
import { ListItem } from '../List/ListItem.js';
|
|
15
|
+
import { flushSync } from 'react-dom';
|
|
9
16
|
/**
|
|
10
17
|
* Context used to provide menu item ref to sub-menu items.
|
|
11
18
|
*/
|
|
12
|
-
const MenuItemContext = React.createContext({
|
|
19
|
+
const MenuItemContext = React.createContext({
|
|
20
|
+
ref: undefined,
|
|
21
|
+
setIsNestedSubmenuVisible: () => {},
|
|
22
|
+
});
|
|
13
23
|
/**
|
|
14
24
|
* Basic menu item component. Should be used inside `Menu` component for each item.
|
|
15
25
|
*/
|
|
16
|
-
export const MenuItem = React.forwardRef((props,
|
|
26
|
+
export const MenuItem = React.forwardRef((props, forwardedRef) => {
|
|
17
27
|
const {
|
|
18
28
|
children,
|
|
19
29
|
isSelected,
|
|
@@ -22,21 +32,33 @@ export const MenuItem = React.forwardRef((props, ref) => {
|
|
|
22
32
|
onClick,
|
|
23
33
|
sublabel,
|
|
24
34
|
size = !!sublabel ? 'large' : 'default',
|
|
25
|
-
startIcon: startIconProp,
|
|
26
35
|
icon,
|
|
27
|
-
|
|
36
|
+
startIcon = icon,
|
|
28
37
|
badge,
|
|
38
|
+
endIcon = badge,
|
|
29
39
|
role = 'menuitem',
|
|
30
40
|
subMenuItems = [],
|
|
31
41
|
...rest
|
|
32
42
|
} = props;
|
|
33
43
|
const menuItemRef = React.useRef(null);
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const subMenuRef = React.useRef(null);
|
|
44
|
+
const [focusOnSubmenu, setFocusOnSubmenu] = React.useState(false);
|
|
45
|
+
const submenuId = useId();
|
|
37
46
|
const [isSubmenuVisible, setIsSubmenuVisible] = React.useState(false);
|
|
38
|
-
const
|
|
39
|
-
|
|
47
|
+
const [isNestedSubmenuVisible, setIsNestedSubmenuVisible] =
|
|
48
|
+
React.useState(false);
|
|
49
|
+
const parent = React.useContext(MenuItemContext);
|
|
50
|
+
const onVisibleChange = (open) => {
|
|
51
|
+
setIsSubmenuVisible(open);
|
|
52
|
+
// we don't want parent to close when mouse goes into a nested submenu,
|
|
53
|
+
// so we need to let the parent know whether the submenu is still open.
|
|
54
|
+
parent.setIsNestedSubmenuVisible(open);
|
|
55
|
+
};
|
|
56
|
+
const popover = usePopover({
|
|
57
|
+
visible: isSubmenuVisible || isNestedSubmenuVisible,
|
|
58
|
+
onVisibleChange,
|
|
59
|
+
placement: 'right-start',
|
|
60
|
+
trigger: { hover: true, focus: true },
|
|
61
|
+
});
|
|
40
62
|
const onKeyDown = (event) => {
|
|
41
63
|
if (event.altKey) {
|
|
42
64
|
return;
|
|
@@ -52,22 +74,37 @@ export const MenuItem = React.forwardRef((props, ref) => {
|
|
|
52
74
|
case 'ArrowRight': {
|
|
53
75
|
if (subMenuItems.length > 0) {
|
|
54
76
|
setIsSubmenuVisible(true);
|
|
77
|
+
// flush and reset state so we are ready to focus again next time
|
|
78
|
+
flushSync(() => setFocusOnSubmenu(true));
|
|
79
|
+
setFocusOnSubmenu(false);
|
|
55
80
|
event.preventDefault();
|
|
56
81
|
event.stopPropagation();
|
|
57
82
|
}
|
|
58
83
|
break;
|
|
59
84
|
}
|
|
60
85
|
case 'ArrowLeft': {
|
|
61
|
-
|
|
86
|
+
if (parent.ref) {
|
|
87
|
+
parent.ref.current?.focus();
|
|
88
|
+
parent.setIsNestedSubmenuVisible(false);
|
|
89
|
+
}
|
|
62
90
|
event.stopPropagation();
|
|
63
91
|
event.preventDefault();
|
|
64
92
|
break;
|
|
65
93
|
}
|
|
94
|
+
case 'Escape': {
|
|
95
|
+
// focus might get lost if submenu closes so move it back to parent
|
|
96
|
+
parent.ref?.current?.focus();
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
66
99
|
default:
|
|
67
100
|
break;
|
|
68
101
|
}
|
|
69
102
|
};
|
|
70
|
-
const
|
|
103
|
+
const handlers = {
|
|
104
|
+
onClick: () => !disabled && onClick?.(value),
|
|
105
|
+
onKeyDown,
|
|
106
|
+
};
|
|
107
|
+
return React.createElement(
|
|
71
108
|
ListItem,
|
|
72
109
|
{
|
|
73
110
|
as: 'div',
|
|
@@ -75,24 +112,21 @@ export const MenuItem = React.forwardRef((props, ref) => {
|
|
|
75
112
|
size: size,
|
|
76
113
|
active: isSelected,
|
|
77
114
|
disabled: disabled,
|
|
78
|
-
|
|
79
|
-
|
|
115
|
+
ref: useMergedRefs(
|
|
116
|
+
menuItemRef,
|
|
117
|
+
forwardedRef,
|
|
118
|
+
subMenuItems.length > 0 ? popover.refs.setReference : null,
|
|
119
|
+
),
|
|
80
120
|
role: role,
|
|
81
121
|
tabIndex: disabled || role === 'presentation' ? undefined : -1,
|
|
82
122
|
'aria-selected': isSelected,
|
|
83
|
-
'aria-haspopup': subMenuItems.length > 0,
|
|
123
|
+
'aria-haspopup': subMenuItems.length > 0 ? 'true' : undefined,
|
|
124
|
+
'aria-controls': subMenuItems.length > 0 ? submenuId : undefined,
|
|
125
|
+
'aria-expanded': subMenuItems.length > 0 ? popover.open : undefined,
|
|
84
126
|
'aria-disabled': disabled,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (
|
|
89
|
-
!(e.relatedTarget instanceof Node) ||
|
|
90
|
-
!subMenuRef.current?.contains(e.relatedTarget)
|
|
91
|
-
) {
|
|
92
|
-
setIsSubmenuVisible(false);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
...rest,
|
|
127
|
+
...(subMenuItems.length === 0
|
|
128
|
+
? { ...handlers, ...rest }
|
|
129
|
+
: popover.getReferenceProps({ ...handlers, ...rest })),
|
|
96
130
|
},
|
|
97
131
|
startIcon &&
|
|
98
132
|
React.createElement(
|
|
@@ -119,34 +153,32 @@ export const MenuItem = React.forwardRef((props, ref) => {
|
|
|
119
153
|
{ as: 'span', 'aria-hidden': true },
|
|
120
154
|
endIcon,
|
|
121
155
|
),
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
{ value: { ref: menuItemRef } },
|
|
156
|
+
subMenuItems.length > 0 &&
|
|
157
|
+
popover.open &&
|
|
158
|
+
React.createElement(
|
|
159
|
+
Portal,
|
|
160
|
+
null,
|
|
128
161
|
React.createElement(
|
|
129
|
-
|
|
130
|
-
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
setIsSubmenuVisible(false);
|
|
162
|
+
MenuItemContext.Provider,
|
|
163
|
+
{ value: { ref: menuItemRef, setIsNestedSubmenuVisible } },
|
|
164
|
+
React.createElement(
|
|
165
|
+
Menu,
|
|
166
|
+
{
|
|
167
|
+
setFocus: focusOnSubmenu,
|
|
168
|
+
ref: popover.refs.setFloating,
|
|
169
|
+
...popover.getFloatingProps({
|
|
170
|
+
id: submenuId,
|
|
171
|
+
onPointerMove: () => {
|
|
172
|
+
// pointer might move into a nested submenu and set isSubmenuVisible to false,
|
|
173
|
+
// so we need to flip it back to true when pointer re-enters this submenu.
|
|
174
|
+
setIsSubmenuVisible(true);
|
|
143
175
|
},
|
|
144
|
-
},
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
listItem,
|
|
176
|
+
}),
|
|
177
|
+
},
|
|
178
|
+
subMenuItems,
|
|
179
|
+
),
|
|
149
180
|
),
|
|
150
|
-
)
|
|
181
|
+
),
|
|
182
|
+
);
|
|
151
183
|
});
|
|
152
184
|
export default MenuItem;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { usePopover } from '../utils/index.js';
|
|
3
|
+
import type { CommonProps } from '../utils/index.js';
|
|
3
4
|
export type ItemRendererProps = {
|
|
4
5
|
/**
|
|
5
6
|
* Close handler that closes the dropdown.
|
|
@@ -110,15 +111,14 @@ export type SelectProps<T> = {
|
|
|
110
111
|
*/
|
|
111
112
|
menuStyle?: React.CSSProperties;
|
|
112
113
|
/**
|
|
113
|
-
* Props to customize
|
|
114
|
-
* @see [tippy.js props](https://atomiks.github.io/tippyjs/v6/all-props/)
|
|
114
|
+
* Props to customize Popover behavior.
|
|
115
115
|
*/
|
|
116
|
-
popoverProps?:
|
|
116
|
+
popoverProps?: Pick<Parameters<typeof usePopover>[0], 'visible' | 'onVisibleChange' | 'placement' | 'matchWidth' | 'closeOnOutsideClick'>;
|
|
117
117
|
/**
|
|
118
118
|
* Props to pass to the select button (trigger) element.
|
|
119
119
|
*/
|
|
120
120
|
triggerProps?: React.ComponentPropsWithoutRef<'div'>;
|
|
121
|
-
} & SelectMultipleTypeProps<T> &
|
|
121
|
+
} & SelectMultipleTypeProps<T> & Omit<React.ComponentPropsWithoutRef<'div'>, 'size' | 'disabled' | 'placeholder' | 'onChange'>;
|
|
122
122
|
/**
|
|
123
123
|
* Select component to select value from options.
|
|
124
124
|
* Generic type is used for value. It prevents you from mistakenly using other types in `options`, `value` and `onChange`.
|
|
@@ -7,10 +7,12 @@ import cx from 'classnames';
|
|
|
7
7
|
import { Menu, MenuItem } from '../Menu/index.js';
|
|
8
8
|
import {
|
|
9
9
|
SvgCaretDownSmall,
|
|
10
|
-
Popover,
|
|
11
10
|
useId,
|
|
12
11
|
AutoclearingHiddenLiveRegion,
|
|
13
12
|
Box,
|
|
13
|
+
usePopover,
|
|
14
|
+
Portal,
|
|
15
|
+
useMergedRefs,
|
|
14
16
|
SvgCheckmark,
|
|
15
17
|
Icon,
|
|
16
18
|
} from '../utils/index.js';
|
|
@@ -87,55 +89,27 @@ export const Select = (props) => {
|
|
|
87
89
|
style,
|
|
88
90
|
menuClassName,
|
|
89
91
|
menuStyle,
|
|
90
|
-
onShow,
|
|
91
|
-
onHide,
|
|
92
|
-
popoverProps,
|
|
93
92
|
multiple = false,
|
|
94
93
|
triggerProps,
|
|
95
94
|
status,
|
|
95
|
+
popoverProps,
|
|
96
96
|
...rest
|
|
97
97
|
} = props;
|
|
98
|
-
const [
|
|
99
|
-
const isOpen = popoverProps?.visible ?? isOpenState;
|
|
100
|
-
const [minWidth, setMinWidth] = React.useState(0);
|
|
98
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
101
99
|
const [liveRegionSelection, setLiveRegionSelection] = React.useState('');
|
|
102
100
|
const selectRef = React.useRef(null);
|
|
103
|
-
const
|
|
104
|
-
(
|
|
105
|
-
setIsOpen(true);
|
|
106
|
-
onShow?.(instance);
|
|
107
|
-
},
|
|
108
|
-
[onShow],
|
|
109
|
-
);
|
|
110
|
-
const onHideHandler = React.useCallback(
|
|
111
|
-
(instance) => {
|
|
112
|
-
setIsOpen(false);
|
|
113
|
-
selectRef.current?.focus({ preventScroll: true }); // move focus back to select button
|
|
114
|
-
onHide?.(instance);
|
|
115
|
-
},
|
|
116
|
-
[onHide],
|
|
117
|
-
);
|
|
118
|
-
React.useEffect(() => {
|
|
119
|
-
if (selectRef.current) {
|
|
120
|
-
setMinWidth(selectRef.current.offsetWidth);
|
|
121
|
-
}
|
|
122
|
-
}, [isOpen]);
|
|
123
|
-
const onKeyDown = (event) => {
|
|
124
|
-
if (event.altKey) {
|
|
101
|
+
const show = React.useCallback(() => {
|
|
102
|
+
if (disabled) {
|
|
125
103
|
return;
|
|
126
104
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
default:
|
|
136
|
-
break;
|
|
137
|
-
}
|
|
138
|
-
};
|
|
105
|
+
setIsOpen(true);
|
|
106
|
+
popoverProps?.onVisibleChange?.(true);
|
|
107
|
+
}, [disabled, popoverProps]);
|
|
108
|
+
const hide = React.useCallback(() => {
|
|
109
|
+
setIsOpen(false);
|
|
110
|
+
selectRef.current?.focus({ preventScroll: true }); // move focus back to select button
|
|
111
|
+
popoverProps?.onVisibleChange?.(false);
|
|
112
|
+
}, [popoverProps]);
|
|
139
113
|
const menuItems = React.useMemo(() => {
|
|
140
114
|
return options.map((option, index) => {
|
|
141
115
|
const isSelected = isMultipleEnabled(value, multiple)
|
|
@@ -159,7 +133,7 @@ export const Select = (props) => {
|
|
|
159
133
|
}
|
|
160
134
|
if (isSingleOnChange(onChange, multiple)) {
|
|
161
135
|
onChange?.(option.value);
|
|
162
|
-
|
|
136
|
+
hide();
|
|
163
137
|
} else {
|
|
164
138
|
onChange?.(option.value, isSelected ? 'removed' : 'added');
|
|
165
139
|
}
|
|
@@ -188,7 +162,7 @@ export const Select = (props) => {
|
|
|
188
162
|
...menuItem.props,
|
|
189
163
|
});
|
|
190
164
|
});
|
|
191
|
-
}, [itemRenderer, multiple, onChange, options, value]);
|
|
165
|
+
}, [hide, itemRenderer, multiple, onChange, options, value]);
|
|
192
166
|
const selectedItems = React.useMemo(() => {
|
|
193
167
|
if (value == null) {
|
|
194
168
|
return undefined;
|
|
@@ -203,53 +177,39 @@ export const Select = (props) => {
|
|
|
203
177
|
label: item.label,
|
|
204
178
|
});
|
|
205
179
|
}, []);
|
|
180
|
+
const popover = usePopover({
|
|
181
|
+
visible: isOpen,
|
|
182
|
+
matchWidth: true,
|
|
183
|
+
closeOnOutsideClick: true,
|
|
184
|
+
...popoverProps,
|
|
185
|
+
onVisibleChange: (open) => (open ? show() : hide()),
|
|
186
|
+
});
|
|
206
187
|
return React.createElement(
|
|
207
|
-
|
|
208
|
-
|
|
188
|
+
React.Fragment,
|
|
189
|
+
null,
|
|
209
190
|
React.createElement(
|
|
210
|
-
|
|
191
|
+
Box,
|
|
211
192
|
{
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
className: cx('iui-scroll', menuClassName),
|
|
217
|
-
style: {
|
|
218
|
-
minInlineSize: minWidth,
|
|
219
|
-
maxInlineSize: `min(${minWidth * 2}px, 90vw)`,
|
|
220
|
-
...menuStyle,
|
|
221
|
-
},
|
|
222
|
-
id: `${uid}-menu`,
|
|
223
|
-
key: `${uid}-menu`,
|
|
224
|
-
},
|
|
225
|
-
menuItems,
|
|
226
|
-
),
|
|
227
|
-
placement: 'bottom-start',
|
|
228
|
-
aria: { content: null },
|
|
229
|
-
onShow: onShowHandler,
|
|
230
|
-
onHide: onHideHandler,
|
|
231
|
-
...popoverProps,
|
|
232
|
-
visible: isOpen,
|
|
233
|
-
onClickOutside: () => {
|
|
234
|
-
setIsOpen(false);
|
|
235
|
-
},
|
|
193
|
+
className: cx('iui-input-with-icon', className),
|
|
194
|
+
style: style,
|
|
195
|
+
...rest,
|
|
196
|
+
ref: popover.refs.setPositionReference,
|
|
236
197
|
},
|
|
237
198
|
React.createElement(
|
|
238
199
|
Box,
|
|
239
200
|
{
|
|
201
|
+
...popover.getReferenceProps(),
|
|
240
202
|
tabIndex: 0,
|
|
241
203
|
role: 'combobox',
|
|
242
|
-
ref: selectRef,
|
|
243
204
|
'data-iui-size': size,
|
|
244
205
|
'data-iui-status': status,
|
|
245
|
-
onClick: () => !disabled && setIsOpen((o) => !o),
|
|
246
|
-
onKeyDown: (e) => !disabled && onKeyDown(e),
|
|
247
206
|
'aria-disabled': disabled,
|
|
248
207
|
'aria-autocomplete': 'none',
|
|
249
208
|
'aria-expanded': isOpen,
|
|
250
209
|
'aria-haspopup': 'listbox',
|
|
251
210
|
'aria-controls': `${uid}-menu`,
|
|
252
211
|
...triggerProps,
|
|
212
|
+
ref: useMergedRefs(selectRef, popover.refs.setReference),
|
|
253
213
|
className: cx(
|
|
254
214
|
'iui-select-button',
|
|
255
215
|
{
|
|
@@ -277,24 +237,48 @@ export const Select = (props) => {
|
|
|
277
237
|
selectedItemRenderer: selectedItemRenderer,
|
|
278
238
|
}),
|
|
279
239
|
),
|
|
240
|
+
React.createElement(
|
|
241
|
+
Icon,
|
|
242
|
+
{
|
|
243
|
+
as: 'span',
|
|
244
|
+
'aria-hidden': true,
|
|
245
|
+
className: cx('iui-end-icon', {
|
|
246
|
+
'iui-disabled': disabled,
|
|
247
|
+
'iui-open': isOpen,
|
|
248
|
+
}),
|
|
249
|
+
},
|
|
250
|
+
React.createElement(SvgCaretDownSmall, null),
|
|
251
|
+
),
|
|
252
|
+
multiple
|
|
253
|
+
? React.createElement(AutoclearingHiddenLiveRegion, {
|
|
254
|
+
text: liveRegionSelection,
|
|
255
|
+
})
|
|
256
|
+
: null,
|
|
280
257
|
),
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
258
|
+
popover.open &&
|
|
259
|
+
React.createElement(
|
|
260
|
+
Portal,
|
|
261
|
+
null,
|
|
262
|
+
React.createElement(
|
|
263
|
+
Menu,
|
|
264
|
+
{
|
|
265
|
+
role: 'listbox',
|
|
266
|
+
className: cx('iui-scroll', menuClassName),
|
|
267
|
+
id: `${uid}-menu`,
|
|
268
|
+
key: `${uid}-menu`,
|
|
269
|
+
...popover.getFloatingProps({
|
|
270
|
+
style: menuStyle,
|
|
271
|
+
onKeyDown: ({ key }) => {
|
|
272
|
+
if (key === 'Tab') {
|
|
273
|
+
hide();
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
}),
|
|
277
|
+
ref: popover.refs.setFloating,
|
|
278
|
+
},
|
|
279
|
+
menuItems,
|
|
280
|
+
),
|
|
281
|
+
),
|
|
298
282
|
);
|
|
299
283
|
};
|
|
300
284
|
const SingleSelectButton = ({ selectedItem, selectedItemRenderer }) => {
|
|
@@ -105,13 +105,9 @@ export const ActionColumn = ({ columnManager = false } = {}) => {
|
|
|
105
105
|
{
|
|
106
106
|
...dropdownMenuProps,
|
|
107
107
|
menuItems: headerCheckBoxes,
|
|
108
|
-
|
|
109
|
-
setIsOpen(
|
|
110
|
-
dropdownMenuProps
|
|
111
|
-
},
|
|
112
|
-
onShow: (i) => {
|
|
113
|
-
setIsOpen(true);
|
|
114
|
-
dropdownMenuProps.onShow?.(i);
|
|
108
|
+
onVisibleChange: (open) => {
|
|
109
|
+
setIsOpen(open);
|
|
110
|
+
dropdownMenuProps?.onVisibleChange?.(open);
|
|
115
111
|
},
|
|
116
112
|
className: cx('iui-scroll', dropdownMenuProps.className),
|
|
117
113
|
},
|
|
@@ -66,54 +66,49 @@ const DatePickerInput = React.forwardRef((props, forwardedRef) => {
|
|
|
66
66
|
[onChange, parseInput],
|
|
67
67
|
);
|
|
68
68
|
return React.createElement(
|
|
69
|
-
|
|
70
|
-
{
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
visible: isVisible,
|
|
80
|
-
onClickOutside: (_, e) => {
|
|
81
|
-
if (!buttonRef.current?.contains(e.target)) {
|
|
82
|
-
close();
|
|
83
|
-
}
|
|
69
|
+
InputGrid,
|
|
70
|
+
{ labelPlacement: 'inline', ...wrapperProps },
|
|
71
|
+
React.createElement(
|
|
72
|
+
Label,
|
|
73
|
+
{
|
|
74
|
+
as: 'label',
|
|
75
|
+
required: required,
|
|
76
|
+
disabled: disabled,
|
|
77
|
+
htmlFor: id,
|
|
78
|
+
...labelProps,
|
|
84
79
|
},
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
label,
|
|
81
|
+
),
|
|
87
82
|
React.createElement(
|
|
88
|
-
|
|
89
|
-
{
|
|
83
|
+
InputWithDecorations,
|
|
84
|
+
{ ...inputWrapperProps },
|
|
85
|
+
React.createElement(InputWithDecorations.Input, {
|
|
86
|
+
id: id,
|
|
87
|
+
value: inputValue,
|
|
88
|
+
onChange: onInputChange,
|
|
89
|
+
required: required,
|
|
90
|
+
disabled: disabled,
|
|
91
|
+
ref: forwardedRef,
|
|
92
|
+
...rest,
|
|
93
|
+
}),
|
|
90
94
|
React.createElement(
|
|
91
|
-
|
|
95
|
+
Popover,
|
|
92
96
|
{
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
content: React.createElement(DatePicker, {
|
|
98
|
+
date: date,
|
|
99
|
+
onChange: onDateSelected,
|
|
100
|
+
setFocus: true,
|
|
101
|
+
isDateDisabled: isDateDisabled,
|
|
102
|
+
localizedNames: localizedNames,
|
|
103
|
+
}),
|
|
104
|
+
placement: 'bottom-end',
|
|
105
|
+
visible: isVisible,
|
|
106
|
+
onVisibleChange: setIsVisible,
|
|
107
|
+
closeOnOutsideClick: true,
|
|
98
108
|
},
|
|
99
|
-
label,
|
|
100
|
-
),
|
|
101
|
-
React.createElement(
|
|
102
|
-
InputWithDecorations,
|
|
103
|
-
{ ...inputWrapperProps },
|
|
104
|
-
React.createElement(InputWithDecorations.Input, {
|
|
105
|
-
id: id,
|
|
106
|
-
value: inputValue,
|
|
107
|
-
onChange: onInputChange,
|
|
108
|
-
onClick: close,
|
|
109
|
-
required: required,
|
|
110
|
-
disabled: disabled,
|
|
111
|
-
ref: forwardedRef,
|
|
112
|
-
...rest,
|
|
113
|
-
}),
|
|
114
109
|
React.createElement(
|
|
115
110
|
InputWithDecorations.Button,
|
|
116
|
-
{
|
|
111
|
+
{ 'aria-label': 'Date picker', ref: buttonRef },
|
|
117
112
|
React.createElement(SvgCalendar, null),
|
|
118
113
|
),
|
|
119
114
|
),
|
|
@@ -43,7 +43,8 @@ export const FilterToggle = (props) => {
|
|
|
43
43
|
content: column.render('Filter', { close, setFilter, clearFilter }),
|
|
44
44
|
placement: 'bottom-start',
|
|
45
45
|
visible: isVisible,
|
|
46
|
-
|
|
46
|
+
onVisibleChange: setIsVisible,
|
|
47
|
+
closeOnOutsideClick: true,
|
|
47
48
|
},
|
|
48
49
|
React.createElement(
|
|
49
50
|
IconButton,
|
|
@@ -51,8 +52,8 @@ export const FilterToggle = (props) => {
|
|
|
51
52
|
styleType: 'borderless',
|
|
52
53
|
isActive: isVisible || isColumnFiltered,
|
|
53
54
|
className: cx('iui-table-filter-button', className),
|
|
55
|
+
'aria-label': 'Filter',
|
|
54
56
|
onClick: (e) => {
|
|
55
|
-
setIsVisible((v) => !v);
|
|
56
57
|
// Prevents from triggering sort
|
|
57
58
|
e.stopPropagation();
|
|
58
59
|
},
|
package/esm/core/Tile/Tile.js
CHANGED
|
@@ -212,32 +212,31 @@ const TileMoreOptions = React.forwardRef((props, forwardedRef) => {
|
|
|
212
212
|
const { className, children = [], buttonProps, ...rest } = props;
|
|
213
213
|
const [isMenuVisible, setIsMenuVisible] = React.useState(false);
|
|
214
214
|
return React.createElement(
|
|
215
|
-
|
|
215
|
+
Box,
|
|
216
216
|
{
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
}),
|
|
227
|
-
),
|
|
217
|
+
className: cx(
|
|
218
|
+
'iui-tile-more-options',
|
|
219
|
+
{
|
|
220
|
+
'iui-visible': isMenuVisible,
|
|
221
|
+
},
|
|
222
|
+
className,
|
|
223
|
+
),
|
|
224
|
+
ref: forwardedRef,
|
|
225
|
+
...rest,
|
|
228
226
|
},
|
|
229
227
|
React.createElement(
|
|
230
|
-
|
|
228
|
+
DropdownMenu,
|
|
231
229
|
{
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
230
|
+
onVisibleChange: setIsMenuVisible,
|
|
231
|
+
menuItems: (close) =>
|
|
232
|
+
children?.map((option) =>
|
|
233
|
+
React.cloneElement(option, {
|
|
234
|
+
onClick: (value) => {
|
|
235
|
+
close();
|
|
236
|
+
option.props.onClick?.(value);
|
|
237
|
+
},
|
|
238
|
+
}),
|
|
239
|
+
),
|
|
241
240
|
},
|
|
242
241
|
React.createElement(
|
|
243
242
|
IconButton,
|