@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
@@ -1,11 +1,12 @@
1
1
  import * as React from 'react';
2
- import type { CommonProps, PopoverProps } from '../utils/index.js';
2
+ import { Popover } from '../utils/index.js';
3
+ import type { PolymorphicForwardRefComponent, PortalProps } from '../utils/index.js';
3
4
  export type DropdownMenuProps = {
4
5
  /**
5
6
  * List of menu items. Recommended to use MenuItem component.
6
7
  * You can pass function that takes argument `close` that closes the dropdown menu, or a list of MenuItems.
7
8
  */
8
- menuItems: (close: () => void) => JSX.Element[] | JSX.Element[] | JSX.Element;
9
+ menuItems: ((close: () => void) => JSX.Element[]) | JSX.Element[] | JSX.Element;
9
10
  /**
10
11
  * ARIA role. Role of menu. For menu use 'menu', for select use 'listbox'.
11
12
  * @default 'menu'
@@ -15,10 +16,10 @@ export type DropdownMenuProps = {
15
16
  * Child element to wrap dropdown with.
16
17
  */
17
18
  children: React.ReactNode;
18
- } & Omit<PopoverProps, 'content'> & Omit<CommonProps, 'title'>;
19
+ } & Pick<React.ComponentProps<typeof Popover>, 'visible' | 'onVisibleChange' | 'placement' | 'matchWidth'> & React.ComponentPropsWithoutRef<'ul'> & Pick<PortalProps, 'portal'>;
19
20
  /**
20
21
  * Dropdown menu component.
21
- * Uses the {@link Popover} component, which is a wrapper around [tippy.js](https://atomiks.github.io/tippyjs).
22
+ * Built on top of the {@link Popover} component.
22
23
  * @example
23
24
  * const menuItems = (close: () => void) => [
24
25
  * <MenuItem key={1} onClick={onClick(1, close)}>
@@ -35,5 +36,5 @@ export type DropdownMenuProps = {
35
36
  * <Button>Menu</Button>
36
37
  * </DropdownMenu>
37
38
  */
38
- export declare const DropdownMenu: (props: DropdownMenuProps) => React.JSX.Element;
39
+ export declare const DropdownMenu: PolymorphicForwardRefComponent<"div", DropdownMenuProps>;
39
40
  export default DropdownMenu;
@@ -3,11 +3,20 @@
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 { Popover, mergeRefs } from '../utils/index.js';
6
+ import {
7
+ Popover,
8
+ useMergedRefs,
9
+ usePopover,
10
+ Portal,
11
+ cloneElementWithRef,
12
+ useControlledState,
13
+ mergeRefs,
14
+ mergeEventHandlers,
15
+ } from '../utils/index.js';
7
16
  import { Menu } from '../Menu/index.js';
8
17
  /**
9
18
  * Dropdown menu component.
10
- * Uses the {@link Popover} component, which is a wrapper around [tippy.js](https://atomiks.github.io/tippyjs).
19
+ * Built on top of the {@link Popover} component.
11
20
  * @example
12
21
  * const menuItems = (close: () => void) => [
13
22
  * <MenuItem key={1} onClick={onClick(1, close)}>
@@ -24,74 +33,73 @@ import { Menu } from '../Menu/index.js';
24
33
  * <Button>Menu</Button>
25
34
  * </DropdownMenu>
26
35
  */
27
- export const DropdownMenu = (props) => {
36
+ export const DropdownMenu = React.forwardRef((props, forwardedRef) => {
28
37
  const {
29
38
  menuItems,
30
39
  children,
31
- className,
32
- style,
33
40
  role = 'menu',
34
- visible,
41
+ visible: visibleProp,
35
42
  placement = 'bottom-start',
36
- onShow,
37
- onHide,
38
- trigger,
39
- id,
43
+ matchWidth = false,
44
+ onVisibleChange,
45
+ portal = true,
40
46
  ...rest
41
47
  } = props;
42
- const [isVisible, setIsVisible] = React.useState(visible ?? false);
43
- React.useEffect(() => {
44
- setIsVisible(visible ?? false);
45
- }, [visible]);
46
- const open = React.useCallback(() => setIsVisible(true), []);
47
- const close = React.useCallback(() => setIsVisible(false), []);
48
+ const [visible, setVisible] = useControlledState(
49
+ false,
50
+ visibleProp,
51
+ onVisibleChange,
52
+ );
53
+ const triggerRef = React.useRef(null);
54
+ const close = React.useCallback(() => {
55
+ setVisible(false);
56
+ triggerRef.current?.focus({ preventScroll: true });
57
+ }, [setVisible]);
48
58
  const menuContent = React.useMemo(() => {
49
59
  if (typeof menuItems === 'function') {
50
60
  return menuItems(close);
51
61
  }
52
62
  return menuItems;
53
63
  }, [menuItems, close]);
54
- const targetRef = React.useRef(null);
55
- const onShowHandler = React.useCallback(
56
- (instance) => {
57
- setIsVisible(true);
58
- onShow?.(instance);
59
- },
60
- [onShow],
61
- );
62
- const onHideHandler = React.useCallback(
63
- (instance) => {
64
- setIsVisible(false);
65
- targetRef.current?.focus();
66
- onHide?.(instance);
67
- },
68
- [onHide],
69
- );
64
+ const popover = usePopover({
65
+ visible,
66
+ onVisibleChange: (open) => (open ? setVisible(true) : close()),
67
+ placement,
68
+ matchWidth,
69
+ });
70
+ const popoverRef = useMergedRefs(forwardedRef, popover.refs.setFloating);
70
71
  return React.createElement(
71
- Popover,
72
- {
73
- content: React.createElement(
74
- Menu,
75
- { className: className, style: style, role: role, id: id },
76
- menuContent,
77
- ),
78
- visible: trigger === undefined ? isVisible : undefined,
79
- onClickOutside: close,
80
- placement: placement,
81
- onShow: onShowHandler,
82
- onHide: onHideHandler,
83
- trigger: visible === undefined ? trigger : undefined,
84
- ...rest,
85
- },
86
- React.isValidElement(children)
87
- ? React.cloneElement(children, {
88
- ref: mergeRefs(targetRef, props.children.ref),
89
- onClick: (args) => {
90
- trigger === undefined && (isVisible ? close() : open());
91
- children.props.onClick?.(args);
72
+ React.Fragment,
73
+ null,
74
+ cloneElementWithRef(children, (children) => ({
75
+ ...popover.getReferenceProps(children.props),
76
+ 'aria-expanded': popover.open,
77
+ ref: mergeRefs(triggerRef, popover.refs.setReference),
78
+ })),
79
+ popover.open &&
80
+ React.createElement(
81
+ Portal,
82
+ { portal: portal },
83
+ React.createElement(
84
+ Menu,
85
+ {
86
+ ...popover.getFloatingProps({
87
+ role,
88
+ ...rest,
89
+ onKeyDown: mergeEventHandlers(props.onKeyDown, (e) => {
90
+ if (e.defaultPrevented) {
91
+ return;
92
+ }
93
+ if (e.key === 'Tab') {
94
+ close();
95
+ }
96
+ }),
97
+ }),
98
+ ref: popoverRef,
92
99
  },
93
- })
94
- : React.createElement(React.Fragment, null),
100
+ menuContent,
101
+ ),
102
+ ),
95
103
  );
96
- };
104
+ });
97
105
  export default DropdownMenu;
@@ -36,9 +36,11 @@ type ExpandableBlockOwnProps = {
36
36
  */
37
37
  disabled?: boolean;
38
38
  };
39
- type ExpandableBlockHeaderOwnProps = {
39
+ type ExpandableBlockTriggerOwnProps = {
40
40
  label?: React.ReactNode;
41
+ caption?: React.ReactNode;
41
42
  expandIcon?: React.ReactNode;
43
+ endIcon?: React.ReactNode;
42
44
  };
43
45
  type ExpandableBlockContentOwnProps = {
44
46
  innerProps?: React.ComponentPropsWithoutRef<'div'>;
@@ -46,29 +48,32 @@ type ExpandableBlockContentOwnProps = {
46
48
  /**
47
49
  * Expandable block with customizable Title, Caption, Content and EndIcon subcomponents.
48
50
  * @example
49
- * <ExpandableBlock>
50
- * <ExpandableBlock.Header>
51
+ * <ExpandableBlock.Wrapper>
52
+ * <ExpandableBlock.Trigger>
51
53
  * <ExpandableBlock.ExpandIcon/>
52
54
  * <ExpandableBlock.LabelArea>
53
55
  * <ExpandableBlock.Title/>
54
56
  * <ExpandableBlock.Caption/>
55
57
  * </ExpandableBlock.LabelArea>
56
58
  * <ExpandableBlock.EndIcon/>
57
- * </ExpandableBlock.Header>
59
+ * </ExpandableBlock.Trigger>
58
60
  * <ExpandableBlock.Content/>
59
- * </ExpandableBlock>
61
+ * </ExpandableBlock.Wrapper>
60
62
  */
61
- export declare const ExpandableBlock: PolymorphicForwardRefComponent<"div", ExpandableBlockOwnProps> & {
63
+ export declare const ExpandableBlock: PolymorphicForwardRefComponent<"div", ExpandableBlockOwnProps & {
64
+ title?: React.ReactNode;
65
+ } & Pick<ExpandableBlockTriggerOwnProps, "caption" | "endIcon">> & {
66
+ Wrapper: PolymorphicForwardRefComponent<"div", ExpandableBlockOwnProps>;
62
67
  /**
63
68
  * `Header` container that contains `ExpandIcon`, `LabelArea` and `EndIcon` subcomponents
64
69
  * @example
65
- * <ExpandableBlock.Header>
70
+ * <ExpandableBlock.Trigger>
66
71
  * <ExpandableBlock.ExpandIcon/>
67
72
  * <ExpandableBlock.LabelArea/>
68
73
  * <ExpandableBlock.EndIcon/>
69
- * </ExpandableBlock.Header>
74
+ * </ExpandableBlock.Trigger>
70
75
  */
71
- Header: PolymorphicForwardRefComponent<"button", ExpandableBlockHeaderOwnProps>;
76
+ Trigger: PolymorphicForwardRefComponent<"button", ExpandableBlockTriggerOwnProps>;
72
77
  /**
73
78
  * The expanding icon on the left of header
74
79
  */
@@ -94,24 +99,25 @@ export declare const ExpandableBlock: PolymorphicForwardRefComponent<"div", Expa
94
99
  * Svg icon displayed at the end of the main text.
95
100
  * Will override status icon if specified. Used inside `Header` subcomponent.
96
101
  * @example
97
- * <ExpandableBlock.Header>
102
+ * <ExpandableBlock.Trigger>
98
103
  * <ExpandableBlock.EndIcon> <SvgIcon/> </ExpandableBlock.EndIcon>
99
- * <ExpandableBlock.Header/>
104
+ * <ExpandableBlock.Trigger/>
100
105
  */
101
106
  EndIcon: PolymorphicForwardRefComponent<"span", Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
102
107
  ref?: ((instance: HTMLSpanElement | null) => void) | React.RefObject<HTMLSpanElement> | null | undefined;
103
- }, "fill" | "as" | "key" | "size" | keyof React.HTMLAttributes<HTMLSpanElement>> & {
108
+ }, "fill" | "as" | "key" | "size" | keyof React.HTMLAttributes<HTMLSpanElement> | "padded"> & {
104
109
  size?: "small" | "large" | "auto" | "medium" | import("../utils/types.js").AnyString | undefined;
105
110
  fill?: "default" | "informational" | "negative" | "positive" | "warning" | import("../utils/types.js").AnyString | undefined;
111
+ padded?: boolean | undefined;
106
112
  } & Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, "ref"> & {
107
113
  as?: "span" | undefined;
108
114
  }, "ref">>;
109
115
  /**
110
116
  * Content shown in the block's body when fully expanded.
111
117
  * @example
112
- * <ExpandableBlock>
118
+ * <ExpandableBlock.Wrapper>
113
119
  * <ExpandableBlock.Content> Content </ExpandableBlock.Content>
114
- * </ExpandableBlock>
120
+ * </ExpandableBlock.Wrapper>
115
121
  */
116
122
  Content: PolymorphicForwardRefComponent<"div", ExpandableBlockContentOwnProps>;
117
123
  };
@@ -17,6 +17,21 @@ import {
17
17
  const ExpandableBlockContext = React.createContext(undefined);
18
18
  ExpandableBlockContext.displayName = 'ExpandableBlockContext';
19
19
  const ExpandableBlockComponent = React.forwardRef((props, forwardedRef) => {
20
+ const { children, title, caption, endIcon, ...rest } = props;
21
+ return React.createElement(
22
+ ExpandableBlock.Wrapper,
23
+ { ...rest, ref: forwardedRef },
24
+ React.createElement(ExpandableBlock.Trigger, {
25
+ label: title,
26
+ caption: caption,
27
+ endIcon: endIcon,
28
+ }),
29
+ React.createElement(ExpandableBlock.Content, null, children),
30
+ );
31
+ });
32
+ ExpandableBlockComponent.displayName = 'ExpandableBlock';
33
+ // ----------------------------------------------------------------------------
34
+ const ExpandableBlockWrapper = React.forwardRef((props, forwardedRef) => {
20
35
  const {
21
36
  children,
22
37
  className,
@@ -60,19 +75,20 @@ const ExpandableBlockComponent = React.forwardRef((props, forwardedRef) => {
60
75
  ),
61
76
  );
62
77
  });
63
- ExpandableBlockComponent.displayName = 'ExpandableBlock';
64
- const ExpandableBlockHeader = React.forwardRef((props, forwardedRef) => {
78
+ ExpandableBlockWrapper.displayName = 'ExpandableBlock.Wrapper';
79
+ const ExpandableBlockTrigger = React.forwardRef((props, forwardedRef) => {
65
80
  const {
66
81
  className,
67
82
  children,
68
83
  label,
84
+ caption,
69
85
  onClick: onClickProp,
70
86
  expandIcon,
87
+ endIcon,
71
88
  ...rest
72
89
  } = props;
73
- const { isExpanded, setExpanded, disabled, onToggle } = useSafeContext(
74
- ExpandableBlockContext,
75
- );
90
+ const { isExpanded, setExpanded, disabled, onToggle, status } =
91
+ useSafeContext(ExpandableBlockContext);
76
92
  return React.createElement(
77
93
  ButtonBase,
78
94
  {
@@ -98,11 +114,16 @@ const ExpandableBlockHeader = React.forwardRef((props, forwardedRef) => {
98
114
  ExpandableBlock.LabelArea,
99
115
  null,
100
116
  React.createElement(ExpandableBlock.Title, null, label),
117
+ caption &&
118
+ React.createElement(ExpandableBlock.Caption, null, caption),
101
119
  ),
120
+ endIcon || status
121
+ ? React.createElement(ExpandableBlock.EndIcon, null, endIcon)
122
+ : null,
102
123
  ),
103
124
  );
104
125
  });
105
- ExpandableBlockHeader.displayName = 'ExpandableBlock.Header';
126
+ ExpandableBlockTrigger.displayName = 'ExpandableBlock.Trigger';
106
127
  // ----------------------------------------------------------------------------
107
128
  // ExpandableBlock.ExpandIcon component
108
129
  const ExpandableBlockExpandIcon = React.forwardRef((props, forwardedRef) => {
@@ -170,29 +191,30 @@ ExpandableBlockContent.displayName = 'ExpandableBlock.Content';
170
191
  /**
171
192
  * Expandable block with customizable Title, Caption, Content and EndIcon subcomponents.
172
193
  * @example
173
- * <ExpandableBlock>
174
- * <ExpandableBlock.Header>
194
+ * <ExpandableBlock.Wrapper>
195
+ * <ExpandableBlock.Trigger>
175
196
  * <ExpandableBlock.ExpandIcon/>
176
197
  * <ExpandableBlock.LabelArea>
177
198
  * <ExpandableBlock.Title/>
178
199
  * <ExpandableBlock.Caption/>
179
200
  * </ExpandableBlock.LabelArea>
180
201
  * <ExpandableBlock.EndIcon/>
181
- * </ExpandableBlock.Header>
202
+ * </ExpandableBlock.Trigger>
182
203
  * <ExpandableBlock.Content/>
183
- * </ExpandableBlock>
204
+ * </ExpandableBlock.Wrapper>
184
205
  */
185
206
  export const ExpandableBlock = Object.assign(ExpandableBlockComponent, {
207
+ Wrapper: ExpandableBlockWrapper,
186
208
  /**
187
209
  * `Header` container that contains `ExpandIcon`, `LabelArea` and `EndIcon` subcomponents
188
210
  * @example
189
- * <ExpandableBlock.Header>
211
+ * <ExpandableBlock.Trigger>
190
212
  * <ExpandableBlock.ExpandIcon/>
191
213
  * <ExpandableBlock.LabelArea/>
192
214
  * <ExpandableBlock.EndIcon/>
193
- * </ExpandableBlock.Header>
215
+ * </ExpandableBlock.Trigger>
194
216
  */
195
- Header: ExpandableBlockHeader,
217
+ Trigger: ExpandableBlockTrigger,
196
218
  /**
197
219
  * The expanding icon on the left of header
198
220
  */
@@ -218,17 +240,17 @@ export const ExpandableBlock = Object.assign(ExpandableBlockComponent, {
218
240
  * Svg icon displayed at the end of the main text.
219
241
  * Will override status icon if specified. Used inside `Header` subcomponent.
220
242
  * @example
221
- * <ExpandableBlock.Header>
243
+ * <ExpandableBlock.Trigger>
222
244
  * <ExpandableBlock.EndIcon> <SvgIcon/> </ExpandableBlock.EndIcon>
223
- * <ExpandableBlock.Header/>
245
+ * <ExpandableBlock.Trigger/>
224
246
  */
225
247
  EndIcon: ExpandableBlockEndIcon,
226
248
  /**
227
249
  * Content shown in the block's body when fully expanded.
228
250
  * @example
229
- * <ExpandableBlock>
251
+ * <ExpandableBlock.Wrapper>
230
252
  * <ExpandableBlock.Content> Content </ExpandableBlock.Content>
231
- * </ExpandableBlock>
253
+ * </ExpandableBlock.Wrapper>
232
254
  */
233
255
  Content: ExpandableBlockContent,
234
256
  });
@@ -27,8 +27,7 @@ export const HeaderDropdownButton = React.forwardRef((props, ref) => {
27
27
  {
28
28
  menuItems: menuItems,
29
29
  style: { minInlineSize: menuWidth },
30
- onShow: () => setIsMenuOpen(true),
31
- onHide: () => setIsMenuOpen(false),
30
+ onVisibleChange: (open) => setIsMenuOpen(open),
32
31
  },
33
32
  React.createElement(
34
33
  HeaderBasicButton,
@@ -46,12 +46,12 @@ export const HeaderSplitButton = React.forwardRef((props, forwardedRef) => {
46
46
  placement: menuPlacement,
47
47
  menuItems: menuItems,
48
48
  style: { minInlineSize: menuWidth },
49
- onShow: React.useCallback(() => setIsMenuOpen(true), []),
50
- onHide: React.useCallback(() => setIsMenuOpen(false), []),
49
+ onVisibleChange: (open) => setIsMenuOpen(open),
51
50
  },
52
51
  React.createElement(
53
52
  ButtonBase,
54
53
  {
54
+ 'aria-label': 'More',
55
55
  className:
56
56
  'iui-header-breadcrumb-button iui-header-breadcrumb-button-split',
57
57
  disabled: disabled,
@@ -4,6 +4,10 @@ export type InputProps = {
4
4
  * Modify size of the input.
5
5
  */
6
6
  size?: 'small' | 'large';
7
+ /**
8
+ * Status of input.
9
+ */
10
+ status?: 'positive' | 'warning' | 'negative';
7
11
  /**
8
12
  * Modify the native `size` attribute of the `<input>` element.
9
13
  * The `width` or `inline-size` property must be unset in order to use this prop.
@@ -13,13 +13,14 @@ import { useMergedRefs, Box } from '../utils/index.js';
13
13
  * <Input size='small' />
14
14
  */
15
15
  export const Input = React.forwardRef((props, ref) => {
16
- const { size, htmlSize, className, ...rest } = props;
16
+ const { size, htmlSize, status, className, ...rest } = props;
17
17
  const inputRef = React.useRef(null);
18
18
  const refs = useMergedRefs(inputRef, ref);
19
19
  return React.createElement(Box, {
20
20
  as: 'input',
21
21
  className: cx('iui-input', className),
22
22
  'data-iui-size': size,
23
+ 'data-iui-status': status,
23
24
  size: htmlSize,
24
25
  ref: refs,
25
26
  ...rest,
@@ -0,0 +1,25 @@
1
+ import type { PolymorphicForwardRefComponent } from '../utils/index.js';
2
+ type InputGridOwnProps = {
3
+ /**
4
+ * Set display style of label.
5
+ * Supported values:
6
+ * - 'default' - label appears above input.
7
+ * - 'inline' - appears in the same line as input.
8
+ * @default 'default'
9
+ */
10
+ labelPlacement?: 'default' | 'inline';
11
+ };
12
+ /**
13
+ * InputGrid component is used to display inputs (input, textarea, select)
14
+ * with label and/or status message
15
+ *
16
+ * @usage
17
+ *
18
+ * <InputGrid>
19
+ * <Label htmlFor='input-1'>This is label</Label>
20
+ * <Input id='input-1'/>
21
+ * <StatusMessage>This is message</StatusMessage>
22
+ * </InputGrid>
23
+ */
24
+ export declare const InputGrid: PolymorphicForwardRefComponent<"div", InputGridOwnProps>;
25
+ export default InputGrid;
@@ -0,0 +1,35 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import * as React from 'react';
6
+ import { Box } from '../utils/index.js';
7
+ import cx from 'classnames';
8
+ //-------------------------------------------------------------------------------
9
+ /**
10
+ * InputGrid component is used to display inputs (input, textarea, select)
11
+ * with label and/or status message
12
+ *
13
+ * @usage
14
+ *
15
+ * <InputGrid>
16
+ * <Label htmlFor='input-1'>This is label</Label>
17
+ * <Input id='input-1'/>
18
+ * <StatusMessage>This is message</StatusMessage>
19
+ * </InputGrid>
20
+ */
21
+ export const InputGrid = React.forwardRef((props, ref) => {
22
+ const { children, className, labelPlacement = undefined, ...rest } = props;
23
+ return React.createElement(
24
+ Box,
25
+ {
26
+ className: cx('iui-input-grid', className),
27
+ 'data-iui-label-placement': labelPlacement,
28
+ ref: ref,
29
+ ...rest,
30
+ },
31
+ children,
32
+ );
33
+ });
34
+ //-------------------------------------------------------------------------------
35
+ export default InputGrid;
@@ -0,0 +1,3 @@
1
+ export { InputGrid } from './InputGrid.js';
2
+ declare const _default: "./InputGrid";
3
+ export default _default;
@@ -0,0 +1,6 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ export { InputGrid } from './InputGrid.js';
6
+ export default './InputGrid';
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import type { PolymorphicForwardRefComponent } from '../utils/index.js';
3
+ import { StatusMessage } from '../StatusMessage/index.js';
3
4
  type InputGroupProps = {
4
5
  /**
5
6
  * Label of the group.
@@ -36,6 +37,18 @@ type InputGroupProps = {
36
37
  * Child inputs inside group.
37
38
  */
38
39
  children: React.ReactNode;
40
+ /**
41
+ * Passes properties for label.
42
+ */
43
+ labelProps?: React.ComponentProps<'label'>;
44
+ /**
45
+ * Passes properties for message.
46
+ */
47
+ messageProps?: Pick<React.ComponentProps<typeof StatusMessage>, 'iconProps' | 'contentProps'>;
48
+ /**
49
+ * Passes properties for inner input group element.
50
+ */
51
+ innerProps?: React.ComponentProps<'div'>;
39
52
  };
40
53
  /**
41
54
  * Group Checkbox/Radio components together
@@ -3,7 +3,11 @@
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 { StatusIconMap, InputContainer, Box } from '../utils/index.js';
6
+ import cx from 'classnames';
7
+ import { StatusIconMap, Box } from '../utils/index.js';
8
+ import { InputGrid } from '../InputGrid/index.js';
9
+ import { Label } from '../Label/index.js';
10
+ import { StatusMessage } from '../StatusMessage/index.js';
7
11
  /**
8
12
  * Group Checkbox/Radio components together
9
13
  * @example
@@ -21,6 +25,7 @@ import { StatusIconMap, InputContainer, Box } from '../utils/index.js';
21
25
  */
22
26
  export const InputGroup = React.forwardRef((props, forwardedRef) => {
23
27
  const {
28
+ className,
24
29
  children,
25
30
  disabled = false,
26
31
  displayStyle = 'default',
@@ -29,6 +34,9 @@ export const InputGroup = React.forwardRef((props, forwardedRef) => {
29
34
  status,
30
35
  svgIcon,
31
36
  required = false,
37
+ labelProps,
38
+ messageProps,
39
+ innerProps,
32
40
  ...rest
33
41
  } = props;
34
42
  const icon = () => {
@@ -43,19 +51,35 @@ export const InputGroup = React.forwardRef((props, forwardedRef) => {
43
51
  return undefined;
44
52
  };
45
53
  return React.createElement(
46
- InputContainer,
54
+ InputGrid,
47
55
  {
48
- label: label,
49
- disabled: disabled,
50
- required: required,
51
- status: status,
52
- message: message,
53
- icon: icon(),
54
- isLabelInline: displayStyle === 'inline',
55
56
  ref: forwardedRef,
57
+ as: 'div',
58
+ labelPlacement: displayStyle,
59
+ className: cx('iui-input-group-wrapper', className),
56
60
  ...rest,
57
61
  },
58
- React.createElement(Box, { className: 'iui-input-group' }, children),
62
+ label &&
63
+ React.createElement(
64
+ Label,
65
+ { as: 'label', required: required, disabled: disabled, ...labelProps },
66
+ label,
67
+ ),
68
+ React.createElement(
69
+ Box,
70
+ {
71
+ as: 'div',
72
+ ...innerProps,
73
+ className: cx('iui-input-group', innerProps?.className),
74
+ },
75
+ children,
76
+ ),
77
+ (message || status || svgIcon) &&
78
+ React.createElement(
79
+ StatusMessage,
80
+ { startIcon: icon(), status: status, ...messageProps },
81
+ displayStyle !== 'inline' && message,
82
+ ),
59
83
  );
60
84
  });
61
85
  export default InputGroup;