@itwin/itwinui-react 3.0.0-dev.7 → 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.
Files changed (215) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/cjs/core/Alert/Alert.d.ts +20 -9
  3. package/cjs/core/Alert/Alert.js +48 -10
  4. package/cjs/core/ButtonGroup/ButtonGroup.js +41 -36
  5. package/cjs/core/Buttons/DropdownButton/DropdownButton.js +7 -19
  6. package/cjs/core/Buttons/IconButton/IconButton.js +27 -44
  7. package/cjs/core/Buttons/SplitButton/SplitButton.d.ts +4 -4
  8. package/cjs/core/Buttons/SplitButton/SplitButton.js +54 -29
  9. package/cjs/core/ColorPicker/ColorInputPanel.js +172 -231
  10. package/cjs/core/ComboBox/ComboBox.d.ts +2 -2
  11. package/cjs/core/ComboBox/ComboBox.js +33 -25
  12. package/cjs/core/ComboBox/ComboBoxEndIcon.js +3 -22
  13. package/cjs/core/ComboBox/ComboBoxInput.js +29 -21
  14. package/cjs/core/ComboBox/ComboBoxMenu.d.ts +2 -2
  15. package/cjs/core/ComboBox/ComboBoxMenu.js +73 -93
  16. package/cjs/core/ComboBox/ComboBoxMenuItem.d.ts +1 -1
  17. package/cjs/core/ComboBox/ComboBoxMenuItem.js +8 -6
  18. package/cjs/core/ComboBox/helpers.d.ts +5 -3
  19. package/cjs/core/DatePicker/DatePicker.d.ts +30 -8
  20. package/cjs/core/DatePicker/DatePicker.js +40 -5
  21. package/cjs/core/Dialog/Dialog.js +10 -16
  22. package/cjs/core/Dialog/DialogContext.d.ts +3 -4
  23. package/cjs/core/DropdownMenu/DropdownMenu.d.ts +6 -5
  24. package/cjs/core/DropdownMenu/DropdownMenu.js +59 -55
  25. package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +20 -14
  26. package/cjs/core/ExpandableBlock/ExpandableBlock.js +38 -15
  27. package/cjs/core/Header/HeaderDropdownButton.js +1 -2
  28. package/cjs/core/Header/HeaderSplitButton.js +2 -2
  29. package/cjs/core/Input/Input.d.ts +4 -0
  30. package/cjs/core/Input/Input.js +2 -1
  31. package/cjs/core/InputGrid/InputGrid.d.ts +25 -0
  32. package/cjs/core/InputGrid/InputGrid.js +39 -0
  33. package/cjs/core/InputGrid/index.d.ts +3 -0
  34. package/cjs/core/InputGrid/index.js +15 -0
  35. package/cjs/core/InputGroup/InputGroup.d.ts +13 -0
  36. package/cjs/core/InputGroup/InputGroup.js +35 -9
  37. package/cjs/core/InputWithDecorations/InputWithDecorations.d.ts +39 -0
  38. package/cjs/core/InputWithDecorations/InputWithDecorations.js +81 -0
  39. package/cjs/core/InputWithDecorations/index.d.ts +3 -0
  40. package/cjs/core/InputWithDecorations/index.js +15 -0
  41. package/cjs/core/Label/Label.d.ts +5 -0
  42. package/cjs/core/Label/Label.js +2 -0
  43. package/cjs/core/LabeledInput/LabeledInput.d.ts +22 -16
  44. package/cjs/core/LabeledInput/LabeledInput.js +52 -29
  45. package/cjs/core/LabeledSelect/LabeledSelect.d.ts +17 -7
  46. package/cjs/core/LabeledSelect/LabeledSelect.js +36 -17
  47. package/cjs/core/LabeledTextarea/LabeledTextarea.d.ts +15 -5
  48. package/cjs/core/LabeledTextarea/LabeledTextarea.js +12 -45
  49. package/cjs/core/Menu/Menu.d.ts +1 -1
  50. package/cjs/core/Menu/Menu.js +2 -2
  51. package/cjs/core/Menu/MenuDivider.d.ts +2 -1
  52. package/cjs/core/Menu/MenuDivider.js +1 -1
  53. package/cjs/core/Menu/MenuItem.d.ts +1 -1
  54. package/cjs/core/Menu/MenuItem.js +78 -55
  55. package/cjs/core/Menu/MenuItemSkeleton.d.ts +1 -1
  56. package/cjs/core/Menu/MenuItemSkeleton.js +0 -1
  57. package/cjs/core/SearchBox/SearchBox.js +1 -1
  58. package/cjs/core/Select/Select.d.ts +9 -5
  59. package/cjs/core/Select/Select.js +81 -99
  60. package/cjs/core/SideNavigation/SideNavigation.js +2 -0
  61. package/cjs/core/Slider/Thumb.js +1 -0
  62. package/cjs/core/StatusMessage/StatusMessage.d.ts +12 -2
  63. package/cjs/core/StatusMessage/StatusMessage.js +23 -9
  64. package/cjs/core/Table/SubRowExpander.js +2 -0
  65. package/cjs/core/Table/columns/actionColumn.js +3 -7
  66. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.d.ts +6 -1
  67. package/cjs/core/Table/filters/DateRangeFilter/DatePickerInput.js +56 -33
  68. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.d.ts +2 -0
  69. package/cjs/core/Table/filters/DateRangeFilter/DateRangeFilter.js +2 -0
  70. package/cjs/core/Table/filters/FilterToggle.js +3 -2
  71. package/cjs/core/Textarea/Textarea.d.ts +7 -1
  72. package/cjs/core/Textarea/Textarea.js +6 -11
  73. package/cjs/core/ThemeProvider/ThemeProvider.js +1 -1
  74. package/cjs/core/Tile/Tile.d.ts +139 -15
  75. package/cjs/core/Tile/Tile.js +128 -38
  76. package/cjs/core/Toast/Toast.d.ts +12 -4
  77. package/cjs/core/Toast/Toast.js +20 -4
  78. package/cjs/core/Tooltip/Tooltip.d.ts +35 -28
  79. package/cjs/core/Tooltip/Tooltip.js +116 -117
  80. package/cjs/core/TransferList/TransferList.js +4 -12
  81. package/cjs/core/index.d.ts +3 -1
  82. package/cjs/core/index.js +28 -5
  83. package/cjs/core/utils/components/Icon.d.ts +5 -0
  84. package/cjs/core/utils/components/Icon.js +8 -1
  85. package/cjs/core/utils/components/InputContainer.d.ts +4 -5
  86. package/cjs/core/utils/components/InputContainer.js +21 -37
  87. package/cjs/core/utils/components/InputFlexContainer.d.ts +1 -0
  88. package/cjs/core/utils/components/InputFlexContainer.js +3 -1
  89. package/cjs/core/utils/components/Popover.d.ts +113 -27
  90. package/cjs/core/utils/components/Popover.js +156 -118
  91. package/cjs/core/utils/components/Portal.d.ts +27 -0
  92. package/cjs/core/utils/components/Portal.js +43 -0
  93. package/cjs/core/utils/components/index.d.ts +1 -0
  94. package/cjs/core/utils/components/index.js +1 -0
  95. package/cjs/core/utils/functions/index.d.ts +1 -0
  96. package/cjs/core/utils/functions/index.js +1 -0
  97. package/cjs/core/utils/functions/react.d.ts +8 -0
  98. package/cjs/core/utils/functions/react.js +40 -0
  99. package/cjs/core/utils/hooks/index.d.ts +1 -1
  100. package/cjs/core/utils/hooks/index.js +1 -1
  101. package/cjs/core/utils/hooks/useControlledState.d.ts +13 -0
  102. package/cjs/core/utils/hooks/useControlledState.js +39 -0
  103. package/cjs/styles.js +10 -31
  104. package/esm/core/Alert/Alert.d.ts +20 -9
  105. package/esm/core/Alert/Alert.js +49 -10
  106. package/esm/core/ButtonGroup/ButtonGroup.js +41 -36
  107. package/esm/core/Buttons/DropdownButton/DropdownButton.js +8 -24
  108. package/esm/core/Buttons/IconButton/IconButton.js +25 -40
  109. package/esm/core/Buttons/SplitButton/SplitButton.d.ts +4 -4
  110. package/esm/core/Buttons/SplitButton/SplitButton.js +61 -28
  111. package/esm/core/ColorPicker/ColorInputPanel.js +173 -232
  112. package/esm/core/ComboBox/ComboBox.d.ts +2 -2
  113. package/esm/core/ComboBox/ComboBox.js +34 -25
  114. package/esm/core/ComboBox/ComboBoxEndIcon.js +4 -25
  115. package/esm/core/ComboBox/ComboBoxInput.js +22 -21
  116. package/esm/core/ComboBox/ComboBoxMenu.d.ts +2 -2
  117. package/esm/core/ComboBox/ComboBoxMenu.js +67 -87
  118. package/esm/core/ComboBox/ComboBoxMenuItem.d.ts +1 -1
  119. package/esm/core/ComboBox/ComboBoxMenuItem.js +9 -7
  120. package/esm/core/ComboBox/helpers.d.ts +5 -3
  121. package/esm/core/DatePicker/DatePicker.d.ts +30 -8
  122. package/esm/core/DatePicker/DatePicker.js +25 -5
  123. package/esm/core/Dialog/Dialog.js +11 -23
  124. package/esm/core/Dialog/DialogContext.d.ts +3 -4
  125. package/esm/core/DropdownMenu/DropdownMenu.d.ts +6 -5
  126. package/esm/core/DropdownMenu/DropdownMenu.js +64 -56
  127. package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +20 -14
  128. package/esm/core/ExpandableBlock/ExpandableBlock.js +39 -17
  129. package/esm/core/Header/HeaderDropdownButton.js +1 -2
  130. package/esm/core/Header/HeaderSplitButton.js +2 -2
  131. package/esm/core/Input/Input.d.ts +4 -0
  132. package/esm/core/Input/Input.js +2 -1
  133. package/esm/core/InputGrid/InputGrid.d.ts +25 -0
  134. package/esm/core/InputGrid/InputGrid.js +35 -0
  135. package/esm/core/InputGrid/index.d.ts +3 -0
  136. package/esm/core/InputGrid/index.js +6 -0
  137. package/esm/core/InputGroup/InputGroup.d.ts +13 -0
  138. package/esm/core/InputGroup/InputGroup.js +34 -10
  139. package/esm/core/InputWithDecorations/InputWithDecorations.d.ts +39 -0
  140. package/esm/core/InputWithDecorations/InputWithDecorations.js +80 -0
  141. package/esm/core/InputWithDecorations/index.d.ts +3 -0
  142. package/esm/core/InputWithDecorations/index.js +6 -0
  143. package/esm/core/Label/Label.d.ts +5 -0
  144. package/esm/core/Label/Label.js +2 -0
  145. package/esm/core/LabeledInput/LabeledInput.d.ts +22 -16
  146. package/esm/core/LabeledInput/LabeledInput.js +53 -29
  147. package/esm/core/LabeledSelect/LabeledSelect.d.ts +17 -7
  148. package/esm/core/LabeledSelect/LabeledSelect.js +37 -18
  149. package/esm/core/LabeledTextarea/LabeledTextarea.d.ts +15 -5
  150. package/esm/core/LabeledTextarea/LabeledTextarea.js +14 -45
  151. package/esm/core/Menu/Menu.d.ts +1 -1
  152. package/esm/core/Menu/Menu.js +8 -3
  153. package/esm/core/Menu/MenuDivider.d.ts +2 -1
  154. package/esm/core/Menu/MenuDivider.js +1 -1
  155. package/esm/core/Menu/MenuItem.d.ts +1 -1
  156. package/esm/core/Menu/MenuItem.js +85 -52
  157. package/esm/core/Menu/MenuItemSkeleton.d.ts +1 -1
  158. package/esm/core/Menu/MenuItemSkeleton.js +0 -1
  159. package/esm/core/SearchBox/SearchBox.js +1 -1
  160. package/esm/core/Select/Select.d.ts +9 -5
  161. package/esm/core/Select/Select.js +81 -96
  162. package/esm/core/SideNavigation/SideNavigation.js +2 -0
  163. package/esm/core/Slider/Thumb.js +1 -0
  164. package/esm/core/StatusMessage/StatusMessage.d.ts +12 -2
  165. package/esm/core/StatusMessage/StatusMessage.js +23 -16
  166. package/esm/core/Table/SubRowExpander.js +2 -0
  167. package/esm/core/Table/columns/actionColumn.js +3 -7
  168. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.d.ts +6 -1
  169. package/esm/core/Table/filters/DateRangeFilter/DatePickerInput.js +56 -33
  170. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.d.ts +2 -0
  171. package/esm/core/Table/filters/DateRangeFilter/DateRangeFilter.js +2 -0
  172. package/esm/core/Table/filters/FilterToggle.js +3 -2
  173. package/esm/core/Textarea/Textarea.d.ts +7 -1
  174. package/esm/core/Textarea/Textarea.js +6 -11
  175. package/esm/core/ThemeProvider/ThemeProvider.js +4 -3
  176. package/esm/core/Tile/Tile.d.ts +139 -15
  177. package/esm/core/Tile/Tile.js +128 -38
  178. package/esm/core/Toast/Toast.d.ts +12 -4
  179. package/esm/core/Toast/Toast.js +21 -4
  180. package/esm/core/Tooltip/Tooltip.d.ts +35 -28
  181. package/esm/core/Tooltip/Tooltip.js +119 -116
  182. package/esm/core/TransferList/TransferList.js +4 -9
  183. package/esm/core/index.d.ts +3 -1
  184. package/esm/core/index.js +3 -0
  185. package/esm/core/utils/components/Icon.d.ts +5 -0
  186. package/esm/core/utils/components/Icon.js +8 -1
  187. package/esm/core/utils/components/InputContainer.d.ts +4 -5
  188. package/esm/core/utils/components/InputContainer.js +21 -32
  189. package/esm/core/utils/components/InputFlexContainer.d.ts +1 -0
  190. package/esm/core/utils/components/InputFlexContainer.js +3 -1
  191. package/esm/core/utils/components/Popover.d.ts +113 -27
  192. package/esm/core/utils/components/Popover.js +175 -118
  193. package/esm/core/utils/components/Portal.d.ts +27 -0
  194. package/esm/core/utils/components/Portal.js +36 -0
  195. package/esm/core/utils/components/index.d.ts +1 -0
  196. package/esm/core/utils/components/index.js +1 -0
  197. package/esm/core/utils/functions/index.d.ts +1 -0
  198. package/esm/core/utils/functions/index.js +1 -0
  199. package/esm/core/utils/functions/react.d.ts +8 -0
  200. package/esm/core/utils/functions/react.js +35 -0
  201. package/esm/core/utils/hooks/index.d.ts +1 -1
  202. package/esm/core/utils/hooks/index.js +1 -1
  203. package/esm/core/utils/hooks/useControlledState.d.ts +13 -0
  204. package/esm/core/utils/hooks/useControlledState.js +34 -0
  205. package/esm/styles.js +10 -31
  206. package/package.json +3 -5
  207. package/styles.css +23 -20
  208. package/cjs/core/ComboBox/ComboBoxDropdown.d.ts +0 -7
  209. package/cjs/core/ComboBox/ComboBoxDropdown.js +0 -48
  210. package/cjs/core/utils/hooks/useUncontrolledState.d.ts +0 -6
  211. package/cjs/core/utils/hooks/useUncontrolledState.js +0 -18
  212. package/esm/core/ComboBox/ComboBoxDropdown.d.ts +0 -7
  213. package/esm/core/ComboBox/ComboBoxDropdown.js +0 -42
  214. package/esm/core/utils/hooks/useUncontrolledState.d.ts +0 -6
  215. package/esm/core/utils/hooks/useUncontrolledState.js +0 -13
@@ -4,43 +4,22 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import cx from 'classnames';
6
6
  import * as React from 'react';
7
- import {
8
- useSafeContext,
9
- useMergedRefs,
10
- SvgCaretDownSmall,
11
- mergeEventHandlers,
12
- Box,
13
- } from '../utils/index.js';
14
- import { ComboBoxActionContext, ComboBoxRefsContext } from './helpers.js';
7
+ import { SvgCaretDownSmall, Icon } from '../utils/index.js';
15
8
  export const ComboBoxEndIcon = React.forwardRef((props, forwardedRef) => {
16
- const {
17
- className,
18
- children,
19
- onClick: onClickProp,
20
- disabled,
21
- isOpen,
22
- ...rest
23
- } = props;
24
- const dispatch = useSafeContext(ComboBoxActionContext);
25
- const { toggleButtonRef } = useSafeContext(ComboBoxRefsContext);
26
- const refs = useMergedRefs(toggleButtonRef, forwardedRef);
9
+ const { className, children, disabled, isOpen, ...rest } = props;
27
10
  return React.createElement(
28
- Box,
11
+ Icon,
29
12
  {
30
13
  as: 'span',
31
- ref: refs,
14
+ ref: forwardedRef,
32
15
  className: cx(
33
16
  'iui-end-icon',
34
17
  {
35
- 'iui-actionable': !disabled,
36
18
  'iui-disabled': disabled,
37
19
  'iui-open': isOpen,
38
20
  },
39
21
  className,
40
22
  ),
41
- onClick: mergeEventHandlers(onClickProp, () => {
42
- dispatch({ type: isOpen ? 'close' : 'open' });
43
- }),
44
23
  ...rest,
45
24
  },
46
25
  children ?? React.createElement(SvgCaretDownSmall, { 'aria-hidden': true }),
@@ -19,9 +19,9 @@ import {
19
19
  export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
20
20
  const {
21
21
  onKeyDown: onKeyDownProp,
22
- onFocus: onFocusProp,
23
22
  onClick: onClickProp,
24
23
  selectTags,
24
+ size,
25
25
  ...rest
26
26
  } = props;
27
27
  const {
@@ -31,11 +31,14 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
31
31
  enableVirtualization,
32
32
  multiple,
33
33
  onClickHandler,
34
+ popover,
35
+ show,
36
+ hide,
34
37
  } = useSafeContext(ComboBoxStateContext);
35
38
  const dispatch = useSafeContext(ComboBoxActionContext);
36
39
  const { inputRef, menuRef, optionsExtraInfoRef } =
37
40
  useSafeContext(ComboBoxRefsContext);
38
- const refs = useMergedRefs(inputRef, forwardedRef);
41
+ const refs = useMergedRefs(inputRef, popover.refs.setReference, forwardedRef);
39
42
  const focusedIndexRef = React.useRef(focusedIndex ?? -1);
40
43
  React.useEffect(() => {
41
44
  focusedIndexRef.current = focusedIndex ?? -1;
@@ -47,7 +50,6 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
47
50
  };
48
51
  const handleKeyDown = React.useCallback(
49
52
  (event) => {
50
- onKeyDownProp?.(event);
51
53
  const length = Object.keys(optionsExtraInfoRef.current).length ?? 0;
52
54
  if (event.altKey) {
53
55
  return;
@@ -56,7 +58,7 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
56
58
  case 'ArrowDown': {
57
59
  event.preventDefault();
58
60
  if (!isOpen) {
59
- return dispatch({ type: 'open' });
61
+ return show();
60
62
  }
61
63
  if (length === 0) {
62
64
  return;
@@ -98,7 +100,7 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
98
100
  case 'ArrowUp': {
99
101
  event.preventDefault();
100
102
  if (!isOpen) {
101
- return dispatch({ type: 'open' });
103
+ return show();
102
104
  }
103
105
  if (length === 0) {
104
106
  return;
@@ -142,17 +144,17 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
142
144
  onClickHandler?.(focusedIndexRef.current);
143
145
  }
144
146
  } else {
145
- dispatch({ type: 'open' });
147
+ show();
146
148
  }
147
149
  break;
148
150
  }
149
151
  case 'Escape': {
150
152
  event.preventDefault();
151
- dispatch({ type: 'close' });
153
+ hide();
152
154
  break;
153
155
  }
154
156
  case 'Tab':
155
- dispatch({ type: 'close' });
157
+ hide();
156
158
  break;
157
159
  }
158
160
  },
@@ -162,31 +164,26 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
162
164
  isOpen,
163
165
  menuRef,
164
166
  onClickHandler,
165
- onKeyDownProp,
166
167
  optionsExtraInfoRef,
168
+ show,
169
+ hide,
167
170
  ],
168
171
  );
169
- const handleFocus = React.useCallback(
170
- (event) => {
171
- dispatch({ type: 'open' });
172
- onFocusProp?.(event);
173
- },
174
- [dispatch, onFocusProp],
175
- );
176
172
  const handleClick = React.useCallback(() => {
177
173
  if (!isOpen) {
178
- dispatch({ type: 'open' });
174
+ show();
175
+ } else {
176
+ hide();
179
177
  }
180
- }, [dispatch, isOpen]);
178
+ }, [hide, isOpen, show]);
181
179
  const [tagContainerWidthRef, tagContainerWidth] = useContainerWidth();
182
180
  return React.createElement(
183
181
  React.Fragment,
184
182
  null,
185
183
  React.createElement(Input, {
186
184
  ref: refs,
187
- onKeyDown: handleKeyDown,
188
185
  onClick: mergeEventHandlers(onClickProp, handleClick),
189
- onFocus: handleFocus,
186
+ 'aria-expanded': isOpen,
190
187
  'aria-activedescendant':
191
188
  isOpen && focusedIndex != undefined && focusedIndex > -1
192
189
  ? getIdFromIndex(focusedIndex)
@@ -199,7 +196,11 @@ export const ComboBoxInput = React.forwardRef((props, forwardedRef) => {
199
196
  autoCorrect: 'off',
200
197
  style: multiple ? { paddingInlineStart: tagContainerWidth + 18 } : {},
201
198
  'aria-describedby': multiple ? `${id}-selected-live` : undefined,
202
- ...rest,
199
+ size: size,
200
+ ...popover.getReferenceProps({
201
+ onKeyDown: mergeEventHandlers(onKeyDownProp, handleKeyDown),
202
+ ...rest,
203
+ }),
203
204
  }),
204
205
  multiple && selectTags
205
206
  ? React.createElement(ComboBoxMultipleContainer, {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { Menu } from '../Menu/index.js';
3
3
  import type { PolymorphicForwardRefComponent } from '../utils/index.js';
4
- type ComboBoxMenuProps = Omit<React.ComponentPropsWithoutRef<typeof Menu>, 'onClick'> & React.ComponentPropsWithoutRef<'ul'>;
5
- export declare const ComboBoxMenu: PolymorphicForwardRefComponent<"ul", ComboBoxMenuProps>;
4
+ type ComboBoxMenuProps = Omit<React.ComponentPropsWithoutRef<typeof Menu>, 'onClick'> & React.ComponentPropsWithoutRef<'div'>;
5
+ export declare const ComboBoxMenu: PolymorphicForwardRefComponent<"div", ComboBoxMenuProps>;
6
6
  export {};
@@ -5,109 +5,89 @@
5
5
  import cx from 'classnames';
6
6
  import * as React from 'react';
7
7
  import { Menu } from '../Menu/index.js';
8
- import { Surface } from '../Surface/index.js';
9
8
  import {
10
9
  useSafeContext,
11
10
  useMergedRefs,
12
11
  useVirtualization,
13
- mergeRefs,
14
- getWindow,
12
+ Portal,
13
+ Box,
15
14
  } from '../utils/index.js';
16
15
  import { ComboBoxStateContext, ComboBoxRefsContext } from './helpers.js';
17
- const isOverflowOverlaySupported = () =>
18
- getWindow()?.CSS?.supports?.('overflow: overlay');
19
- const VirtualizedComboBoxMenu = React.forwardRef(
20
- ({ children, className, style, ...rest }, forwardedRef) => {
21
- const { minWidth, id, filteredOptions, getMenuItem, focusedIndex } =
22
- useSafeContext(ComboBoxStateContext);
23
- const { menuRef } = useSafeContext(ComboBoxRefsContext);
24
- const virtualItemRenderer = React.useCallback(
25
- (index) =>
26
- filteredOptions.length > 0
27
- ? getMenuItem(filteredOptions[index], index)
28
- : children, // Here is expected empty state content
29
- [filteredOptions, getMenuItem, children],
16
+ const VirtualizedComboBoxMenu = (props) => {
17
+ const { children, ...rest } = props;
18
+ const { filteredOptions, getMenuItem, focusedIndex } =
19
+ useSafeContext(ComboBoxStateContext);
20
+ const { menuRef } = useSafeContext(ComboBoxRefsContext);
21
+ const virtualItemRenderer = React.useCallback(
22
+ (index) =>
23
+ filteredOptions.length > 0
24
+ ? getMenuItem(filteredOptions[index], index)
25
+ : children, // Here is expected empty state content
26
+ [filteredOptions, getMenuItem, children],
27
+ );
28
+ const focusedVisibleIndex = React.useMemo(() => {
29
+ const currentElement = menuRef.current?.querySelector(
30
+ `[data-iui-index="${focusedIndex}"]`,
30
31
  );
31
- const focusedVisibleIndex = React.useMemo(() => {
32
- const currentElement = menuRef.current?.querySelector(
33
- `[data-iui-index="${focusedIndex}"]`,
34
- );
35
- if (!currentElement) {
36
- return focusedIndex;
37
- }
38
- return Number(
39
- currentElement.getAttribute('data-iui-filtered-index') ?? focusedIndex,
40
- );
41
- }, [focusedIndex, menuRef]);
42
- const { outerProps, innerProps, visibleChildren } = useVirtualization({
43
- // 'Fool' VirtualScroll by passing length 1
44
- // whenever there is no elements, to show empty state message
45
- itemsLength: filteredOptions.length || 1,
46
- itemRenderer: virtualItemRenderer,
47
- scrollToIndex: focusedVisibleIndex,
48
- });
49
- const surfaceStyles = {
50
- minInlineSize: minWidth,
51
- // set as constant because we don't want it shifting when items are unmounted
52
- maxInlineSize: minWidth,
53
- // max-height must be on the outermost element for virtual scroll
54
- maxBlockSize: 'calc((var(--iui-component-height) - 1px) * 8.5)',
55
- overflowY: isOverflowOverlaySupported() ? 'overlay' : 'auto',
56
- ...style,
57
- };
58
- return React.createElement(
59
- Surface,
60
- { style: surfaceStyles },
61
- React.createElement(
62
- 'div',
63
- { ...outerProps },
64
- React.createElement(
65
- Menu,
66
- {
67
- id: `${id}-list`,
68
- setFocus: false,
69
- role: 'listbox',
70
- ref: mergeRefs(menuRef, innerProps.ref, forwardedRef),
71
- className: className,
72
- style: innerProps.style,
73
- ...rest,
74
- },
75
- visibleChildren,
76
- ),
77
- ),
32
+ if (!currentElement) {
33
+ return focusedIndex;
34
+ }
35
+ return Number(
36
+ currentElement.getAttribute('data-iui-filtered-index') ?? focusedIndex,
78
37
  );
79
- },
80
- );
38
+ }, [focusedIndex, menuRef]);
39
+ const { outerProps, innerProps, visibleChildren } = useVirtualization({
40
+ // 'Fool' VirtualScroll by passing length 1
41
+ // whenever there is no elements, to show empty state message
42
+ itemsLength: filteredOptions.length || 1,
43
+ itemRenderer: virtualItemRenderer,
44
+ scrollToIndex: focusedVisibleIndex,
45
+ });
46
+ return React.createElement(
47
+ Box,
48
+ { as: 'div', ...outerProps, ...rest },
49
+ React.createElement(
50
+ 'div',
51
+ { ...innerProps, ref: innerProps.ref },
52
+ visibleChildren,
53
+ ),
54
+ );
55
+ };
81
56
  export const ComboBoxMenu = React.forwardRef((props, forwardedRef) => {
82
- const { className, style, ...rest } = props;
83
- const { minWidth, id, enableVirtualization } =
57
+ const { className, children, style, ...rest } = props;
58
+ const { id, enableVirtualization, popover } =
84
59
  useSafeContext(ComboBoxStateContext);
85
60
  const { menuRef } = useSafeContext(ComboBoxRefsContext);
86
- const refs = useMergedRefs(menuRef, forwardedRef);
87
- const styles = React.useMemo(
88
- () => ({
89
- minInlineSize: minWidth,
90
- maxInlineSize: `min(${minWidth * 2}px, 90vw)`,
91
- }),
92
- [minWidth],
93
- );
94
- return React.createElement(
95
- React.Fragment,
96
- null,
97
- !enableVirtualization
98
- ? React.createElement(Menu, {
61
+ const refs = useMergedRefs(popover.refs.setFloating, forwardedRef, menuRef);
62
+ return (
63
+ popover.open &&
64
+ React.createElement(
65
+ Portal,
66
+ { portal: true },
67
+ React.createElement(
68
+ Menu,
69
+ {
99
70
  id: `${id}-list`,
100
- style: { ...styles, ...style },
101
71
  setFocus: false,
102
72
  role: 'listbox',
103
73
  ref: refs,
104
74
  className: cx('iui-scroll', className),
105
- ...rest,
106
- })
107
- : React.createElement(VirtualizedComboBoxMenu, {
108
- ref: forwardedRef,
109
- ...props,
110
- }),
75
+ ...popover.getFloatingProps({
76
+ style: !enableVirtualization
77
+ ? style
78
+ : {
79
+ // set as constant because we don't want it shifting when items are unmounted
80
+ maxInlineSize: 0,
81
+ ...style,
82
+ },
83
+ ...rest,
84
+ }),
85
+ },
86
+ !enableVirtualization
87
+ ? children
88
+ : React.createElement(VirtualizedComboBoxMenu, null, children),
89
+ ),
90
+ )
111
91
  );
112
92
  });
113
93
  ComboBoxMenu.displayName = 'ComboBoxMenu';
@@ -4,5 +4,5 @@ import type { PolymorphicForwardRefComponent } from '../utils/index.js';
4
4
  type ComboBoxMenuItemProps = MenuItemProps & {
5
5
  index: number;
6
6
  };
7
- export declare const ComboBoxMenuItem: React.MemoExoticComponent<PolymorphicForwardRefComponent<"li", ComboBoxMenuItemProps>>;
7
+ export declare const ComboBoxMenuItem: React.MemoExoticComponent<PolymorphicForwardRefComponent<"div", ComboBoxMenuItemProps>>;
8
8
  export {};
@@ -3,7 +3,7 @@
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 { useSafeContext, useMergedRefs } from '../utils/index.js';
6
+ import { useSafeContext, useMergedRefs, SvgCheckmark } from '../utils/index.js';
7
7
  import { ComboBoxStateContext } from './helpers.js';
8
8
  import { ListItem } from '../List/ListItem.js';
9
9
  export const ComboBoxMenuItem = React.memo(
@@ -33,6 +33,7 @@ export const ComboBoxMenuItem = React.memo(
33
33
  return React.createElement(
34
34
  ListItem,
35
35
  {
36
+ as: 'div',
36
37
  actionable: true,
37
38
  size: size,
38
39
  active: isSelected,
@@ -59,12 +60,13 @@ export const ComboBoxMenuItem = React.memo(
59
60
  children,
60
61
  sublabel && React.createElement(ListItem.Description, null, sublabel),
61
62
  ),
62
- endIcon &&
63
- React.createElement(
64
- ListItem.Icon,
65
- { as: 'span', 'aria-hidden': true },
66
- endIcon,
67
- ),
63
+ endIcon ||
64
+ (isSelected &&
65
+ React.createElement(
66
+ ListItem.Icon,
67
+ { as: 'span', 'aria-hidden': true },
68
+ endIcon ?? React.createElement(SvgCheckmark, null),
69
+ )),
68
70
  );
69
71
  }),
70
72
  );
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { SelectOption } from '../Select/Select.js';
3
+ import type { usePopover } from '../utils/index.js';
3
4
  type ComboBoxAction = {
4
5
  type: 'multiselect';
5
6
  value: number[];
@@ -25,8 +26,7 @@ export declare const comboBoxReducer: (state: {
25
26
  };
26
27
  export declare const ComboBoxRefsContext: React.Context<{
27
28
  inputRef: React.RefObject<HTMLInputElement>;
28
- menuRef: React.RefObject<HTMLUListElement>;
29
- toggleButtonRef: React.RefObject<HTMLSpanElement>;
29
+ menuRef: React.RefObject<HTMLElement>;
30
30
  optionsExtraInfoRef: React.MutableRefObject<Record<string, {
31
31
  __originalIndex: number;
32
32
  }>>;
@@ -34,13 +34,15 @@ export declare const ComboBoxRefsContext: React.Context<{
34
34
  type ComboBoxStateContextProps<T = unknown> = {
35
35
  isOpen: boolean;
36
36
  id: string;
37
- minWidth: number;
38
37
  enableVirtualization: boolean;
39
38
  filteredOptions: SelectOption<T>[];
40
39
  onClickHandler?: (prop: number) => void;
41
40
  getMenuItem: (option: SelectOption<T>, filteredIndex?: number) => JSX.Element;
42
41
  focusedIndex?: number;
43
42
  multiple?: boolean;
43
+ popover: ReturnType<typeof usePopover>;
44
+ show: () => void;
45
+ hide: () => void;
44
46
  };
45
47
  export declare const ComboBoxStateContext: React.Context<ComboBoxStateContextProps<unknown> | undefined>;
46
48
  export declare const ComboBoxActionContext: React.Context<((x: ComboBoxAction) => void) | undefined>;
@@ -1,14 +1,14 @@
1
+ import * as React from 'react';
1
2
  import type { PolymorphicForwardRefComponent } from '../utils/index.js';
2
3
  import type { TimePickerProps } from '../TimePicker/TimePicker.js';
4
+ export type DatePickerLocalizedNames = {
5
+ [key in 'months' | 'shortDays' | 'days']: string[];
6
+ };
3
7
  /**
4
8
  * Generate localized months and days strings using `Intl.DateTimeFormat` for passed locale to use in DatePicker component.
5
9
  * If locale is not passed, browser locale will be used.
6
10
  */
7
- export declare const generateLocalizedStrings: (locale?: string) => {
8
- months: string[];
9
- shortDays: string[];
10
- days: string[];
11
- };
11
+ export declare const generateLocalizedStrings: (locale?: string) => DatePickerLocalizedNames;
12
12
  export type DateRangePickerProps = {
13
13
  /**
14
14
  * Enable date range support.
@@ -42,9 +42,7 @@ type DatePickerProps = {
42
42
  * Pass localized week days (start from sunday) and months.
43
43
  * Use helper function `generateLocalizedStrings` to generate strings using `Intl.DateTimeFormat`.
44
44
  */
45
- localizedNames?: {
46
- [key in 'months' | 'shortDays' | 'days']: string[];
47
- };
45
+ localizedNames?: DatePickerLocalizedNames;
48
46
  /**
49
47
  * Set focus on selected day or today.
50
48
  * @default false
@@ -60,6 +58,30 @@ type DatePickerProps = {
60
58
  * @default false
61
59
  */
62
60
  showYearSelection?: boolean;
61
+ /**
62
+ * Allows props to be passed for calendar month year, referring to the div that wraps around the month/year and the next/previous buttons.
63
+ */
64
+ monthYearProps?: React.ComponentProps<'div'>;
65
+ /**
66
+ * Allows props to be passed for only month, referring to span that wraps around the month title.
67
+ */
68
+ monthProps?: React.ComponentProps<'span'>;
69
+ /**
70
+ * Allows props to be passed for week days, referring to div that wraps around the week day title.
71
+ */
72
+ weekDayProps?: React.ComponentProps<'div'>;
73
+ /**
74
+ * Allows props to be passed for individual day , referring to div element the wraps around single day number.
75
+ */
76
+ dayProps?: React.ComponentProps<'div'>;
77
+ /**
78
+ * Allows props to be passed for calendar, referring to div that is used for listbox for wraping days and weeks.
79
+ */
80
+ calendarProps?: React.ComponentProps<'div'>;
81
+ /**
82
+ * Allows props to be passed for weeks, referring to div that wraps around weeks.
83
+ */
84
+ weekProps?: React.ComponentProps<'div'>;
63
85
  /**
64
86
  * Will disable dates for which this function returns true.
65
87
  * Disabled dates cannot be selected.
@@ -142,6 +142,12 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
142
142
  enableRangeSelect = false,
143
143
  startDate,
144
144
  endDate,
145
+ monthYearProps,
146
+ calendarProps,
147
+ monthProps,
148
+ weekDayProps,
149
+ dayProps,
150
+ weekProps,
145
151
  isDateDisabled,
146
152
  ...rest
147
153
  } = props;
@@ -419,7 +425,11 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
419
425
  null,
420
426
  React.createElement(
421
427
  Box,
422
- { className: 'iui-calendar-month-year' },
428
+ {
429
+ as: 'div',
430
+ ...monthYearProps,
431
+ className: cx('iui-calendar-month-year', monthYearProps?.className),
432
+ },
423
433
  showYearSelection &&
424
434
  React.createElement(
425
435
  IconButton,
@@ -448,9 +458,10 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
448
458
  Box,
449
459
  {
450
460
  as: 'span',
451
- className: 'iui-calendar-month',
452
461
  id: dateTableId,
453
462
  title: monthNames[displayedMonthIndex],
463
+ ...monthProps,
464
+ className: cx('iui-calendar-month', monthProps?.className),
454
465
  },
455
466
  monthNames[displayedMonthIndex],
456
467
  ),
@@ -481,7 +492,11 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
481
492
  ),
482
493
  React.createElement(
483
494
  Box,
484
- { className: 'iui-calendar-weekdays' },
495
+ {
496
+ as: 'div',
497
+ ...weekDayProps,
498
+ className: cx('iui-calendar-weekdays', weekDayProps?.className),
499
+ },
485
500
  shortDays.map((day, index) =>
486
501
  React.createElement('div', { key: day, title: longDays[index] }, day),
487
502
  ),
@@ -492,13 +507,16 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
492
507
  onKeyDown: handleCalendarKeyDown,
493
508
  role: 'listbox',
494
509
  'aria-labelledby': dateTableId,
510
+ ...calendarProps,
495
511
  },
496
512
  weeks.map((weekDays, weekIndex) => {
497
513
  return React.createElement(
498
514
  Box,
499
515
  {
516
+ as: 'div',
500
517
  key: `week-${displayedMonthIndex}-${weekIndex}`,
501
- className: 'iui-calendar-week',
518
+ ...weekProps,
519
+ className: cx('iui-calendar-week', weekProps?.className),
502
520
  },
503
521
  weekDays.map((weekDay, dayIndex) => {
504
522
  const dateValue = weekDay.getDate();
@@ -506,8 +524,8 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
506
524
  return React.createElement(
507
525
  Box,
508
526
  {
527
+ as: 'div',
509
528
  key: `day-${displayedMonthIndex}-${dayIndex}`,
510
- className: getDayClass(weekDay),
511
529
  onClick: () => !isDisabled && onDayClick(weekDay),
512
530
  role: 'option',
513
531
  tabIndex: isSameDay(weekDay, focusedDay) ? 0 : -1,
@@ -516,6 +534,8 @@ export const DatePicker = React.forwardRef((props, forwardedRef) => {
516
534
  isSameDay(weekDay, focusedDay) &&
517
535
  needFocus.current &&
518
536
  element?.focus(),
537
+ ...dayProps,
538
+ className: cx(getDayClass(weekDay), dayProps?.className),
519
539
  },
520
540
  dateValue,
521
541
  );
@@ -3,7 +3,6 @@
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 * as ReactDOM from 'react-dom';
7
6
  import cx from 'classnames';
8
7
  import { DialogTitleBar } from './DialogTitleBar.js';
9
8
  import { DialogContent } from './DialogContent.js';
@@ -11,13 +10,7 @@ import { DialogBackdrop } from './DialogBackdrop.js';
11
10
  import { DialogContext } from './DialogContext.js';
12
11
  import { DialogButtonBar } from './DialogButtonBar.js';
13
12
  import { DialogMain } from './DialogMain.js';
14
- import {
15
- useMergedRefs,
16
- Box,
17
- useGlobals,
18
- getDocument,
19
- useIsClient,
20
- } from '../utils/index.js';
13
+ import { useMergedRefs, Box, Portal } from '../utils/index.js';
21
14
  const DialogComponent = React.forwardRef((props, ref) => {
22
15
  const {
23
16
  trapFocus = false,
@@ -37,20 +30,6 @@ const DialogComponent = React.forwardRef((props, ref) => {
37
30
  ...rest
38
31
  } = props;
39
32
  const dialogRootRef = React.useRef(null);
40
- const context = useGlobals();
41
- const isClient = useIsClient();
42
- const portalTo =
43
- typeof portal !== 'boolean'
44
- ? portal.to
45
- : portal
46
- ? context?.portalContainer || getDocument()?.body
47
- : null;
48
- const dialog = React.createElement(Box, {
49
- className: cx('iui-dialog-wrapper', className),
50
- 'data-iui-relative': relativeTo === 'container',
51
- ref: useMergedRefs(ref, dialogRootRef),
52
- ...rest,
53
- });
54
33
  return React.createElement(
55
34
  DialogContext.Provider,
56
35
  {
@@ -70,7 +49,16 @@ const DialogComponent = React.forwardRef((props, ref) => {
70
49
  placement,
71
50
  },
72
51
  },
73
- portalTo && isClient ? ReactDOM.createPortal(dialog, portalTo) : dialog,
52
+ React.createElement(
53
+ Portal,
54
+ { portal: portal },
55
+ React.createElement(Box, {
56
+ className: cx('iui-dialog-wrapper', className),
57
+ 'data-iui-relative': relativeTo === 'container',
58
+ ref: useMergedRefs(ref, dialogRootRef),
59
+ ...rest,
60
+ }),
61
+ ),
74
62
  );
75
63
  });
76
64
  /**
@@ -1,4 +1,5 @@
1
1
  import * as React from 'react';
2
+ import type { PortalProps } from '../utils/index.js';
2
3
  export type DialogContextProps = {
3
4
  /**
4
5
  * Flag whether dialog should be shown.
@@ -67,11 +68,9 @@ export type DialogContextProps = {
67
68
  *
68
69
  * Can be set to an object with a `to` property to portal into a specific element.
69
70
  *
70
- * @default false
71
+ * Defaults to false if using `Dialog` and true if using `Modal`.
71
72
  */
72
- portal?: boolean | {
73
- to: HTMLElement;
74
- };
73
+ portal?: PortalProps['portal'];
75
74
  /**
76
75
  * Dialog root ref. For internal use.
77
76
  */