@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
@@ -6,7 +6,7 @@ import * as React from 'react';
6
6
  import cx from 'classnames';
7
7
  import { IconButton } from '../Buttons/index.js';
8
8
  import { Input } from '../Input/index.js';
9
- import { ColorValue, InputContainer, SvgSwap, Box } from '../utils/index.js';
9
+ import { ColorValue, SvgSwap, Box } from '../utils/index.js';
10
10
  import { useColorPickerContext } from './ColorPickerContext.js';
11
11
  /**
12
12
  * `ColorInputPanel` shows input fields to enter precise color values in the specified format.
@@ -135,20 +135,43 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
135
135
  applyHsvColorChange(color.toHsvColor(), true, color);
136
136
  }
137
137
  };
138
- const hexInputField = React.createElement(
139
- InputContainer,
140
- { status: validHexInput ? undefined : 'negative' },
138
+ const hexInputField = React.createElement(Input, {
139
+ size: 'small',
140
+ maxLength: showAlpha ? 9 : 7,
141
+ minLength: 1,
142
+ placeholder: 'HEX',
143
+ value: input[0],
144
+ onChange: (event) => {
145
+ const value = event.target.value.startsWith('#')
146
+ ? event.target.value
147
+ : `#${event.target.value}`;
148
+ setInput([value]);
149
+ },
150
+ onKeyDown: (event) => {
151
+ if (event.key === 'Enter') {
152
+ event.preventDefault();
153
+ handleColorInputChange();
154
+ }
155
+ },
156
+ onBlur: (event) => {
157
+ event.preventDefault();
158
+ handleColorInputChange();
159
+ },
160
+ status: validHexInput ? undefined : 'negative',
161
+ });
162
+ const hslInputs = React.createElement(
163
+ React.Fragment,
164
+ null,
141
165
  React.createElement(Input, {
142
166
  size: 'small',
143
- maxLength: showAlpha ? 9 : 7,
144
- minLength: 1,
145
- placeholder: 'HEX',
146
- value: input[0],
167
+ type: 'number',
168
+ min: '0',
169
+ max: '359',
170
+ step: '.1',
171
+ placeholder: 'H',
172
+ value: input[0] ?? '',
147
173
  onChange: (event) => {
148
- const value = event.target.value.startsWith('#')
149
- ? event.target.value
150
- : `#${event.target.value}`;
151
- setInput([value]);
174
+ setInput([event.target.value, input[1], input[2], input[3]]);
152
175
  },
153
176
  onKeyDown: (event) => {
154
177
  if (event.key === 'Enter') {
@@ -158,97 +181,76 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
158
181
  },
159
182
  onBlur: (event) => {
160
183
  event.preventDefault();
161
- handleColorInputChange();
184
+ if (!isFocusInside(event.relatedTarget)) {
185
+ handleColorInputChange();
186
+ }
162
187
  },
188
+ status:
189
+ Number(input[0]) < 0 || Number(input[0]) > 360 ? 'negative' : undefined,
163
190
  }),
164
- );
165
- const hslInputs = React.createElement(
166
- React.Fragment,
167
- null,
168
- React.createElement(
169
- InputContainer,
170
- {
171
- status:
172
- Number(input[0]) < 0 || Number(input[0]) > 360
173
- ? 'negative'
174
- : undefined,
191
+ React.createElement(Input, {
192
+ size: 'small',
193
+ type: 'number',
194
+ min: '0',
195
+ max: '100',
196
+ step: '.1',
197
+ placeholder: 'S',
198
+ value: input[1] ?? '',
199
+ onChange: (event) => {
200
+ setInput([input[0], event.target.value, input[2], input[3]]);
175
201
  },
176
- React.createElement(Input, {
177
- size: 'small',
178
- type: 'number',
179
- min: '0',
180
- max: '359',
181
- step: '.1',
182
- placeholder: 'H',
183
- value: input[0] ?? '',
184
- onChange: (event) => {
185
- setInput([event.target.value, input[1], input[2], input[3]]);
186
- },
187
- onKeyDown: (event) => {
188
- if (event.key === 'Enter') {
189
- event.preventDefault();
190
- handleColorInputChange();
191
- }
192
- },
193
- onBlur: (event) => {
202
+ onKeyDown: (event) => {
203
+ if (event.key === 'Enter') {
194
204
  event.preventDefault();
195
- if (!isFocusInside(event.relatedTarget)) {
196
- handleColorInputChange();
197
- }
198
- },
199
- }),
200
- ),
201
- React.createElement(
202
- InputContainer,
203
- {
204
- status:
205
- Number(input[1]) < 0 || Number(input[1]) > 100
206
- ? 'negative'
207
- : undefined,
205
+ handleColorInputChange();
206
+ }
208
207
  },
209
- React.createElement(Input, {
210
- size: 'small',
211
- type: 'number',
212
- min: '0',
213
- max: '100',
214
- step: '.1',
215
- placeholder: 'S',
216
- value: input[1] ?? '',
217
- onChange: (event) => {
218
- setInput([input[0], event.target.value, input[2], input[3]]);
219
- },
220
- onKeyDown: (event) => {
221
- if (event.key === 'Enter') {
222
- event.preventDefault();
223
- handleColorInputChange();
224
- }
225
- },
226
- onBlur: (event) => {
208
+ onBlur: (event) => {
209
+ event.preventDefault();
210
+ if (!isFocusInside(event.relatedTarget)) {
211
+ handleColorInputChange();
212
+ }
213
+ },
214
+ status:
215
+ Number(input[1]) < 0 || Number(input[1]) > 100 ? 'negative' : undefined,
216
+ }),
217
+ React.createElement(Input, {
218
+ size: 'small',
219
+ type: 'number',
220
+ min: '0',
221
+ max: '100',
222
+ step: '.1',
223
+ placeholder: 'L',
224
+ value: input[2] ?? '',
225
+ onChange: (event) => {
226
+ setInput([input[0], input[1], event.target.value, input[3]]);
227
+ },
228
+ onKeyDown: (event) => {
229
+ if (event.key === 'Enter') {
227
230
  event.preventDefault();
228
- if (!isFocusInside(event.relatedTarget)) {
229
- handleColorInputChange();
230
- }
231
- },
232
- }),
233
- ),
234
- React.createElement(
235
- InputContainer,
236
- {
237
- status:
238
- Number(input[2]) < 0 || Number(input[2]) > 100
239
- ? 'negative'
240
- : undefined,
231
+ handleColorInputChange();
232
+ }
233
+ },
234
+ onBlur: (event) => {
235
+ event.preventDefault();
236
+ if (!isFocusInside(event.relatedTarget)) {
237
+ handleColorInputChange();
238
+ }
241
239
  },
240
+ status:
241
+ Number(input[2]) < 0 || Number(input[2]) > 100 ? 'negative' : undefined,
242
+ }),
243
+ showAlpha &&
242
244
  React.createElement(Input, {
243
245
  size: 'small',
244
246
  type: 'number',
245
247
  min: '0',
246
- max: '100',
247
- step: '.1',
248
- placeholder: 'L',
249
- value: input[2] ?? '',
248
+ max: '1',
249
+ step: '.01',
250
+ placeholder: 'A',
251
+ value: input[3] ?? '',
250
252
  onChange: (event) => {
251
- setInput([input[0], input[1], event.target.value, input[3]]);
253
+ setInput([input[0], input[1], input[2], event.target.value]);
252
254
  },
253
255
  onKeyDown: (event) => {
254
256
  if (event.key === 'Enter') {
@@ -262,127 +264,99 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
262
264
  handleColorInputChange();
263
265
  }
264
266
  },
267
+ status:
268
+ Number(input[3]) < 0 || Number(input[3]) > 1 ? 'negative' : undefined,
265
269
  }),
266
- ),
267
- showAlpha &&
268
- React.createElement(
269
- InputContainer,
270
- {
271
- status:
272
- Number(input[3]) < 0 || Number(input[3]) > 1
273
- ? 'negative'
274
- : undefined,
275
- },
276
- React.createElement(Input, {
277
- size: 'small',
278
- type: 'number',
279
- min: '0',
280
- max: '1',
281
- step: '.01',
282
- placeholder: 'A',
283
- value: input[3] ?? '',
284
- onChange: (event) => {
285
- setInput([input[0], input[1], input[2], event.target.value]);
286
- },
287
- onKeyDown: (event) => {
288
- if (event.key === 'Enter') {
289
- event.preventDefault();
290
- handleColorInputChange();
291
- }
292
- },
293
- onBlur: (event) => {
294
- event.preventDefault();
295
- if (!isFocusInside(event.relatedTarget)) {
296
- handleColorInputChange();
297
- }
298
- },
299
- }),
300
- ),
301
270
  );
302
271
  const rgbInputs = React.createElement(
303
272
  React.Fragment,
304
273
  null,
305
- React.createElement(
306
- InputContainer,
307
- {
308
- status:
309
- Number(input[0]) < 0 || Number(input[0]) > 255
310
- ? 'negative'
311
- : undefined,
274
+ React.createElement(Input, {
275
+ size: 'small',
276
+ type: 'number',
277
+ min: '0',
278
+ max: '255',
279
+ placeholder: 'R',
280
+ value: input[0] ?? '',
281
+ onChange: (event) => {
282
+ setInput([event.target.value, input[1], input[2], input[3]]);
312
283
  },
313
- React.createElement(Input, {
314
- size: 'small',
315
- type: 'number',
316
- min: '0',
317
- max: '255',
318
- placeholder: 'R',
319
- value: input[0] ?? '',
320
- onChange: (event) => {
321
- setInput([event.target.value, input[1], input[2], input[3]]);
322
- },
323
- onKeyDown: (event) => {
324
- if (event.key === 'Enter') {
325
- event.preventDefault();
326
- handleColorInputChange();
327
- }
328
- },
329
- onBlur: (event) => {
284
+ onKeyDown: (event) => {
285
+ if (event.key === 'Enter') {
330
286
  event.preventDefault();
331
- if (!isFocusInside(event.relatedTarget)) {
332
- handleColorInputChange();
333
- }
334
- },
335
- }),
336
- ),
337
- React.createElement(
338
- InputContainer,
339
- {
340
- status:
341
- Number(input[1]) < 0 || Number(input[1]) > 255
342
- ? 'negative'
343
- : undefined,
287
+ handleColorInputChange();
288
+ }
344
289
  },
345
- React.createElement(Input, {
346
- size: 'small',
347
- type: 'number',
348
- min: '0',
349
- max: '255',
350
- placeholder: 'G',
351
- value: input[1] ?? '',
352
- onChange: (event) => {
353
- setInput([input[0], event.target.value, input[2], input[3]]);
354
- },
355
- onKeyDown: (event) => {
356
- if (event.key === 'Enter') {
357
- event.preventDefault();
358
- handleColorInputChange();
359
- }
360
- },
361
- onBlur: (event) => {
290
+ onBlur: (event) => {
291
+ event.preventDefault();
292
+ if (!isFocusInside(event.relatedTarget)) {
293
+ handleColorInputChange();
294
+ }
295
+ },
296
+ status:
297
+ Number(input[0]) < 0 || Number(input[0]) > 255 ? 'negative' : undefined,
298
+ }),
299
+ React.createElement(Input, {
300
+ size: 'small',
301
+ type: 'number',
302
+ min: '0',
303
+ max: '255',
304
+ placeholder: 'G',
305
+ value: input[1] ?? '',
306
+ onChange: (event) => {
307
+ setInput([input[0], event.target.value, input[2], input[3]]);
308
+ },
309
+ onKeyDown: (event) => {
310
+ if (event.key === 'Enter') {
362
311
  event.preventDefault();
363
- if (!isFocusInside(event.relatedTarget)) {
364
- handleColorInputChange();
365
- }
366
- },
367
- }),
368
- ),
369
- React.createElement(
370
- InputContainer,
371
- {
372
- status:
373
- Number(input[2]) < 0 || Number(input[2]) > 255
374
- ? 'negative'
375
- : undefined,
312
+ handleColorInputChange();
313
+ }
314
+ },
315
+ onBlur: (event) => {
316
+ event.preventDefault();
317
+ if (!isFocusInside(event.relatedTarget)) {
318
+ handleColorInputChange();
319
+ }
320
+ },
321
+ status:
322
+ Number(input[1]) < 0 || Number(input[1]) > 255 ? 'negative' : undefined,
323
+ }),
324
+ React.createElement(Input, {
325
+ size: 'small',
326
+ type: 'number',
327
+ min: '0',
328
+ max: '255',
329
+ placeholder: 'B',
330
+ value: input[2] ?? '',
331
+ onChange: (event) => {
332
+ setInput([input[0], input[1], event.target.value, input[3]]);
333
+ },
334
+ onKeyDown: (event) => {
335
+ if (event.key === 'Enter') {
336
+ event.preventDefault();
337
+ handleColorInputChange();
338
+ }
376
339
  },
340
+ onBlur: (event) => {
341
+ event.preventDefault();
342
+ if (!isFocusInside(event.relatedTarget)) {
343
+ handleColorInputChange();
344
+ }
345
+ },
346
+ status:
347
+ Number(input[2]) < 0 || Number(input[2]) > 255 ? 'negative' : undefined,
348
+ }),
349
+ showAlpha &&
377
350
  React.createElement(Input, {
378
351
  size: 'small',
379
352
  type: 'number',
380
353
  min: '0',
381
- max: '255',
382
- placeholder: 'B',
383
- value: input[2] ?? '',
354
+ max: '1',
355
+ step: '.01',
356
+ placeholder: 'A',
357
+ value: input[3] ?? '',
384
358
  onChange: (event) => {
385
- setInput([input[0], input[1], event.target.value, input[3]]);
359
+ setInput([input[0], input[1], input[2], event.target.value]);
386
360
  },
387
361
  onKeyDown: (event) => {
388
362
  if (event.key === 'Enter') {
@@ -396,42 +370,9 @@ export const ColorInputPanel = React.forwardRef((props, ref) => {
396
370
  handleColorInputChange();
397
371
  }
398
372
  },
373
+ status:
374
+ Number(input[3]) < 0 || Number(input[3]) > 1 ? 'negative' : undefined,
399
375
  }),
400
- ),
401
- showAlpha &&
402
- React.createElement(
403
- InputContainer,
404
- {
405
- status:
406
- Number(input[3]) < 0 || Number(input[3]) > 1
407
- ? 'negative'
408
- : undefined,
409
- },
410
- React.createElement(Input, {
411
- size: 'small',
412
- type: 'number',
413
- min: '0',
414
- max: '1',
415
- step: '.01',
416
- placeholder: 'A',
417
- value: input[3] ?? '',
418
- onChange: (event) => {
419
- setInput([input[0], input[1], input[2], event.target.value]);
420
- },
421
- onKeyDown: (event) => {
422
- if (event.key === 'Enter') {
423
- event.preventDefault();
424
- handleColorInputChange();
425
- }
426
- },
427
- onBlur: (event) => {
428
- event.preventDefault();
429
- if (!isFocusInside(event.relatedTarget)) {
430
- handleColorInputChange();
431
- }
432
- },
433
- }),
434
- ),
435
376
  );
436
377
  return React.createElement(
437
378
  Box,
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import type { SelectOption } from '../Select/index.js';
3
3
  import type { Input } from '../Input/Input.js';
4
- import type { PopoverProps, InputContainerProps, CommonProps } from '../utils/index.js';
4
+ import type { InputContainerProps, CommonProps } from '../utils/index.js';
5
5
  type ActionType = 'added' | 'removed';
6
6
  type MultipleOnChangeProps<T> = {
7
7
  value: T;
@@ -48,7 +48,7 @@ export type ComboBoxProps<T> = {
48
48
  /**
49
49
  * Props to customize dropdown menu behavior.
50
50
  */
51
- dropdownMenuProps?: PopoverProps;
51
+ dropdownMenuProps?: React.ComponentProps<'div'>;
52
52
  /**
53
53
  * Message shown when no options are available.
54
54
  * If `JSX.Element` is provided, it will be rendered as is and won't be wrapped with `MenuExtraContent`.
@@ -12,6 +12,7 @@ import {
12
12
  useLatestRef,
13
13
  useIsomorphicLayoutEffect,
14
14
  AutoclearingHiddenLiveRegion,
15
+ usePopover,
15
16
  } from '../utils/index.js';
16
17
  import {
17
18
  ComboBoxActionContext,
@@ -19,7 +20,6 @@ import {
19
20
  ComboBoxRefsContext,
20
21
  ComboBoxStateContext,
21
22
  } from './helpers.js';
22
- import { ComboBoxDropdown } from './ComboBoxDropdown.js';
23
23
  import { ComboBoxEndIcon } from './ComboBoxEndIcon.js';
24
24
  import { ComboBoxInput } from './ComboBoxInput.js';
25
25
  import { ComboBoxInputContainer } from './ComboBoxInputContainer.js';
@@ -62,8 +62,8 @@ export const ComboBox = (props) => {
62
62
  itemRenderer,
63
63
  enableVirtualization = false,
64
64
  multiple = false,
65
- onShow,
66
- onHide,
65
+ onShow: onShowProp,
66
+ onHide: onHideProp,
67
67
  ...rest
68
68
  } = props;
69
69
  // Generate a stateful random id if not specified
@@ -76,7 +76,6 @@ export const ComboBox = (props) => {
76
76
  // Refs get set in subcomponents
77
77
  const inputRef = React.useRef(null);
78
78
  const menuRef = React.useRef(null);
79
- const toggleButtonRef = React.useRef(null);
80
79
  const onChangeProp = useLatestRef(onChange);
81
80
  const optionsRef = useLatestRef(options);
82
81
  // Record to store all extra information (e.g. original indexes), where the key is the id of the option
@@ -122,6 +121,16 @@ export const ComboBox = (props) => {
122
121
  focusedIndex: -1,
123
122
  },
124
123
  );
124
+ const onShowRef = useLatestRef(onShowProp);
125
+ const onHideRef = useLatestRef(onHideProp);
126
+ const show = React.useCallback(() => {
127
+ dispatch({ type: 'open' });
128
+ onShowRef.current?.();
129
+ }, [onShowRef]);
130
+ const hide = React.useCallback(() => {
131
+ dispatch({ type: 'close' });
132
+ onHideRef.current?.();
133
+ }, [onHideRef]);
125
134
  useIsomorphicLayoutEffect(() => {
126
135
  // When the dropdown opens
127
136
  if (isOpen) {
@@ -146,13 +155,6 @@ export const ComboBox = (props) => {
146
155
  }
147
156
  }
148
157
  }, [isOpen, multiple, optionsRef, selected]);
149
- // Set min-width of menu to be same as input
150
- const [minWidth, setMinWidth] = React.useState(0);
151
- React.useEffect(() => {
152
- if (inputRef.current) {
153
- setMinWidth(inputRef.current.offsetWidth);
154
- }
155
- }, [isOpen]);
156
158
  // Update filtered options to the latest value options according to input value
157
159
  const [filteredOptions, setFilteredOptions] = React.useState(options);
158
160
  React.useEffect(() => {
@@ -179,7 +181,7 @@ export const ComboBox = (props) => {
179
181
  (event) => {
180
182
  const { value } = event.currentTarget;
181
183
  setInputValue(value);
182
- dispatch({ type: 'open' }); // reopen when typing
184
+ show(); // reopen when typing
183
185
  setFilteredOptions(
184
186
  filterFunction?.(optionsRef.current, value) ??
185
187
  optionsRef.current.filter((option) =>
@@ -191,7 +193,7 @@ export const ComboBox = (props) => {
191
193
  }
192
194
  inputProps?.onChange?.(event);
193
195
  },
194
- [filterFunction, focusedIndex, inputProps, optionsRef],
196
+ [filterFunction, focusedIndex, inputProps, optionsRef, show],
195
197
  );
196
198
  // When the value prop changes, update the selected index/indices
197
199
  React.useEffect(() => {
@@ -281,7 +283,7 @@ export const ComboBox = (props) => {
281
283
  );
282
284
  } else {
283
285
  dispatch({ type: 'select', value: __originalIndex });
284
- dispatch({ type: 'close' });
286
+ hide();
285
287
  onChangeHandler(__originalIndex);
286
288
  }
287
289
  },
@@ -292,6 +294,7 @@ export const ComboBox = (props) => {
292
294
  onChangeHandler,
293
295
  selected,
294
296
  optionsRef,
297
+ hide,
295
298
  ],
296
299
  );
297
300
  const getMenuItem = React.useCallback(
@@ -367,9 +370,16 @@ export const ComboBox = (props) => {
367
370
  ),
368
371
  [emptyStateMessage],
369
372
  );
373
+ const popover = usePopover({
374
+ visible: isOpen,
375
+ onVisibleChange: (open) => (open ? show() : hide()),
376
+ matchWidth: true,
377
+ closeOnOutsideClick: true,
378
+ trigger: { focus: true },
379
+ });
370
380
  return React.createElement(
371
381
  ComboBoxRefsContext.Provider,
372
- { value: { inputRef, menuRef, toggleButtonRef, optionsExtraInfoRef } },
382
+ { value: { inputRef, menuRef, optionsExtraInfoRef } },
373
383
  React.createElement(
374
384
  ComboBoxActionContext.Provider,
375
385
  { value: dispatch },
@@ -378,7 +388,6 @@ export const ComboBox = (props) => {
378
388
  {
379
389
  value: {
380
390
  id,
381
- minWidth,
382
391
  isOpen,
383
392
  focusedIndex,
384
393
  onClickHandler,
@@ -386,6 +395,9 @@ export const ComboBox = (props) => {
386
395
  filteredOptions,
387
396
  getMenuItem,
388
397
  multiple,
398
+ popover,
399
+ show,
400
+ hide,
389
401
  },
390
402
  },
391
403
  React.createElement(
@@ -396,6 +408,7 @@ export const ComboBox = (props) => {
396
408
  null,
397
409
  React.createElement(ComboBoxInput, {
398
410
  value: inputValue,
411
+ disabled: inputProps?.disabled,
399
412
  ...inputProps,
400
413
  onChange: handleOnInput,
401
414
  selectTags: isMultipleEnabled(selected, multiple)
@@ -420,15 +433,11 @@ export const ComboBox = (props) => {
420
433
  : null,
421
434
  ),
422
435
  React.createElement(
423
- ComboBoxDropdown,
424
- { ...dropdownMenuProps, onShow: onShow, onHide: onHide },
425
- React.createElement(
426
- ComboBoxMenu,
427
- null,
428
- filteredOptions.length > 0 && !enableVirtualization
429
- ? filteredOptions.map(getMenuItem)
430
- : emptyContent,
431
- ),
436
+ ComboBoxMenu,
437
+ { as: 'div', ...dropdownMenuProps },
438
+ filteredOptions.length > 0 && !enableVirtualization
439
+ ? filteredOptions.map(getMenuItem)
440
+ : emptyContent,
432
441
  ),
433
442
  ),
434
443
  ),