@itwin/itwinui-react 3.2.3 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/cjs/core/ComboBox/ComboBox.d.ts +3 -1
  3. package/cjs/core/ComboBox/ComboBox.js +3 -4
  4. package/cjs/core/ComboBox/ComboBoxInputContainer.js +1 -1
  5. package/cjs/core/Dialog/DialogContext.d.ts +1 -0
  6. package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +7 -4
  7. package/cjs/core/ExpandableBlock/ExpandableBlock.js +25 -12
  8. package/cjs/core/InputGrid/InputGrid.d.ts +7 -5
  9. package/cjs/core/InputGrid/InputGrid.js +175 -6
  10. package/cjs/core/InputGroup/InputGroup.d.ts +1 -1
  11. package/cjs/core/InputGroup/InputGroup.js +4 -13
  12. package/cjs/core/LabeledInput/LabeledInput.d.ts +1 -2
  13. package/cjs/core/LabeledInput/LabeledInput.js +11 -8
  14. package/cjs/core/LabeledSelect/LabeledSelect.d.ts +21 -1
  15. package/cjs/core/LabeledSelect/LabeledSelect.js +5 -20
  16. package/cjs/core/List/ListItem.d.ts +10 -0
  17. package/cjs/core/List/ListItem.js +14 -0
  18. package/cjs/core/Menu/MenuItem.d.ts +1 -1
  19. package/cjs/core/Modal/Modal.d.ts +3 -4
  20. package/cjs/core/Select/Select.d.ts +3 -1
  21. package/cjs/core/Select/Select.js +2 -2
  22. package/cjs/core/StatusMessage/StatusMessage.d.ts +4 -2
  23. package/cjs/core/StatusMessage/StatusMessage.js +3 -1
  24. package/cjs/core/Table/columns/selectionColumn.d.ts +1 -1
  25. package/cjs/core/Table/columns/selectionColumn.js +3 -3
  26. package/cjs/core/utils/components/InputWithIcon.d.ts +2 -0
  27. package/cjs/core/utils/components/InputWithIcon.js +11 -0
  28. package/cjs/core/utils/components/Portal.d.ts +5 -1
  29. package/cjs/core/utils/components/Portal.js +6 -2
  30. package/cjs/core/utils/components/index.d.ts +1 -0
  31. package/cjs/core/utils/components/index.js +1 -0
  32. package/esm/core/ComboBox/ComboBox.d.ts +3 -1
  33. package/esm/core/ComboBox/ComboBox.js +3 -3
  34. package/esm/core/ComboBox/ComboBoxInputContainer.js +2 -2
  35. package/esm/core/Dialog/DialogContext.d.ts +1 -0
  36. package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +7 -4
  37. package/esm/core/ExpandableBlock/ExpandableBlock.js +26 -13
  38. package/esm/core/InputGrid/InputGrid.d.ts +7 -5
  39. package/esm/core/InputGrid/InputGrid.js +176 -7
  40. package/esm/core/InputGroup/InputGroup.d.ts +1 -1
  41. package/esm/core/InputGroup/InputGroup.js +5 -14
  42. package/esm/core/LabeledInput/LabeledInput.d.ts +1 -2
  43. package/esm/core/LabeledInput/LabeledInput.js +8 -9
  44. package/esm/core/LabeledSelect/LabeledSelect.d.ts +21 -1
  45. package/esm/core/LabeledSelect/LabeledSelect.js +5 -19
  46. package/esm/core/List/ListItem.d.ts +10 -0
  47. package/esm/core/List/ListItem.js +14 -0
  48. package/esm/core/Menu/MenuItem.d.ts +1 -1
  49. package/esm/core/Modal/Modal.d.ts +3 -4
  50. package/esm/core/Select/Select.d.ts +3 -1
  51. package/esm/core/Select/Select.js +3 -3
  52. package/esm/core/StatusMessage/StatusMessage.d.ts +4 -2
  53. package/esm/core/StatusMessage/StatusMessage.js +3 -1
  54. package/esm/core/Table/columns/selectionColumn.d.ts +1 -1
  55. package/esm/core/Table/columns/selectionColumn.js +3 -3
  56. package/esm/core/utils/components/InputWithIcon.d.ts +2 -0
  57. package/esm/core/utils/components/InputWithIcon.js +8 -0
  58. package/esm/core/utils/components/Portal.d.ts +5 -1
  59. package/esm/core/utils/components/Portal.js +6 -2
  60. package/esm/core/utils/components/index.d.ts +1 -0
  61. package/esm/core/utils/components/index.js +1 -0
  62. package/package.json +3 -3
  63. package/styles.css +7 -7
@@ -4,7 +4,7 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
6
  import cx from 'classnames';
7
- import { StatusIconMap, Box } from '../utils/index.js';
7
+ import { Box } from '../utils/index.js';
8
8
  import { InputGrid } from '../InputGrid/InputGrid.js';
9
9
  import { Label } from '../Label/Label.js';
10
10
  import { StatusMessage } from '../StatusMessage/StatusMessage.js';
@@ -25,20 +25,11 @@ import { StatusMessage } from '../StatusMessage/StatusMessage.js';
25
25
  */
26
26
  export const InputGroup = React.forwardRef((props, forwardedRef) => {
27
27
  const { className, children, disabled = false, displayStyle = 'default', label, message, status, svgIcon, required = false, labelProps, messageProps, innerProps, ...rest } = props;
28
- const icon = () => {
29
- if (svgIcon) {
30
- return React.cloneElement(svgIcon, { 'aria-hidden': true });
31
- }
32
- if (status && message) {
33
- return React.cloneElement(StatusIconMap[status](), {
34
- 'aria-hidden': true,
35
- });
36
- }
37
- return undefined;
38
- };
39
- return (React.createElement(InputGrid, { ref: forwardedRef, as: 'div', labelPlacement: displayStyle, className: cx('iui-input-group-wrapper', className), ...rest },
28
+ return (React.createElement(InputGrid, { ref: forwardedRef, as: 'div', labelPlacement: displayStyle, className: cx('iui-input-group-wrapper', className), "data-iui-status": status, ...rest },
40
29
  label && (React.createElement(Label, { as: 'label', required: required, disabled: disabled, ...labelProps }, label)),
41
30
  React.createElement(Box, { as: 'div', ...innerProps, className: cx('iui-input-group', innerProps?.className) }, children),
42
- (message || status || svgIcon) && (React.createElement(StatusMessage, { startIcon: icon(), status: status, ...messageProps }, displayStyle !== 'inline' && message))));
31
+ (message || status || svgIcon) && (React.createElement(StatusMessage, { iconProps: {
32
+ 'aria-hidden': true,
33
+ }, startIcon: svgIcon, status: status, ...messageProps }, displayStyle !== 'inline' && message))));
43
34
  });
44
35
  export default InputGroup;
@@ -2,7 +2,6 @@ import * as React from 'react';
2
2
  import { Input } from '../Input/Input.js';
3
3
  import type { PolymorphicForwardRefComponent } from '../utils/index.js';
4
4
  import { InputGrid } from '../InputGrid/InputGrid.js';
5
- import { InputWithDecorations } from '../InputWithDecorations/InputWithDecorations.js';
6
5
  import { Icon } from '../Icon/Icon.js';
7
6
  export type LabeledInputProps = {
8
7
  /**
@@ -48,7 +47,7 @@ export type LabeledInputProps = {
48
47
  /**
49
48
  * Passes properties for input wrapper.
50
49
  */
51
- inputWrapperProps?: React.ComponentProps<typeof InputWithDecorations>;
50
+ inputWrapperProps?: React.ComponentPropsWithRef<'div'>;
52
51
  } & React.ComponentProps<typeof Input>;
53
52
  /**
54
53
  * Basic labeled input component
@@ -4,12 +4,12 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
6
  import { Input } from '../Input/Input.js';
7
- import { StatusIconMap, useId } from '../utils/index.js';
7
+ import { InputWithIcon, StatusIconMap } from '../utils/index.js';
8
8
  import { InputGrid } from '../InputGrid/InputGrid.js';
9
- import { InputWithDecorations } from '../InputWithDecorations/InputWithDecorations.js';
10
9
  import { StatusMessage } from '../StatusMessage/StatusMessage.js';
11
10
  import { Label } from '../Label/Label.js';
12
11
  import { Icon } from '../Icon/Icon.js';
12
+ import cx from 'classnames';
13
13
  /**
14
14
  * Basic labeled input component
15
15
  * @example
@@ -19,15 +19,14 @@ import { Icon } from '../Icon/Icon.js';
19
19
  * <LabeledInput status='negative' label='Negative' />
20
20
  */
21
21
  export const LabeledInput = React.forwardRef((props, ref) => {
22
- const uid = useId();
23
- const { disabled = false, label, message, status, svgIcon, wrapperProps, labelProps, messageContentProps, iconProps, inputWrapperProps, displayStyle = 'default', required = false, id = uid, ...rest } = props;
22
+ const { disabled = false, label, message, status, svgIcon, wrapperProps, labelProps, messageContentProps, iconProps, inputWrapperProps, displayStyle = 'default', required = false, ...rest } = props;
24
23
  const icon = svgIcon ?? (status && StatusIconMap[status]());
25
24
  const shouldShowIcon = svgIcon !== null && (svgIcon || (status && !message));
26
- return (React.createElement(InputGrid, { labelPlacement: displayStyle, ...wrapperProps },
27
- label && (React.createElement(Label, { as: 'label', required: required, disabled: disabled, htmlFor: id, ...labelProps }, label)),
28
- React.createElement(InputWithDecorations, { status: status, isDisabled: disabled, ...inputWrapperProps },
29
- React.createElement(InputWithDecorations.Input, { disabled: disabled, required: required, id: id, ref: ref, ...rest }),
30
- shouldShowIcon && (React.createElement(Icon, { fill: !svgIcon ? status : undefined, padded: true, ...iconProps }, icon))),
25
+ return (React.createElement(InputGrid, { labelPlacement: displayStyle, "data-iui-status": status, ...wrapperProps },
26
+ label && (React.createElement(Label, { as: 'label', required: required, disabled: disabled, ...labelProps }, label)),
27
+ React.createElement(InputWithIcon, { ...inputWrapperProps },
28
+ React.createElement(Input, { disabled: disabled, required: required, ref: ref, ...rest }),
29
+ shouldShowIcon && (React.createElement(Icon, { fill: status, ...iconProps, className: cx('iui-end-icon', iconProps?.className) }, icon))),
31
30
  typeof message === 'string' ? (React.createElement(StatusMessage, { status: status, iconProps: iconProps, contentProps: messageContentProps }, message)) : (message)));
32
31
  });
33
32
  export default LabeledInput;
@@ -10,6 +10,22 @@ export type LabeledSelectProps<T> = {
10
10
  label?: React.ReactNode;
11
11
  /**
12
12
  * Message below the select. Does not apply to 'inline' select.
13
+ *
14
+ * @example
15
+ * <caption>strings</caption>
16
+ * <LabeledSelect message='Positive Message' … />
17
+ *
18
+ * @example
19
+ * <caption>Using StatusMessage for complete customization (e.g. icon)</caption>
20
+ * <LabeledSelect
21
+ * status="positive"
22
+ * message={
23
+ * <StatusMessage status="positive" startIcon={<SvgStar />}>
24
+ * Help message
25
+ * </StatusMessage>
26
+ * }
27
+ * …
28
+ * />
13
29
  */
14
30
  message?: React.ReactNode;
15
31
  /**
@@ -18,6 +34,8 @@ export type LabeledSelectProps<T> = {
18
34
  */
19
35
  status?: 'positive' | 'warning' | 'negative';
20
36
  /**
37
+ * @deprecated Pass a `<StatusMessage startIcon={svgIcon} />` to the `message` prop instead.
38
+ *
21
39
  * Custom svg icon. Will override status icon if specified.
22
40
  */
23
41
  svgIcon?: JSX.Element;
@@ -76,5 +94,7 @@ export type LabeledSelectProps<T> = {
76
94
  * svgIcon={<SvgCamera />}
77
95
  * />
78
96
  */
79
- export declare const LabeledSelect: React.ForwardRefExoticComponent<LabeledSelectProps<unknown> & React.RefAttributes<HTMLElement>>;
97
+ export declare const LabeledSelect: <T>(props: LabeledSelectProps<T> & {
98
+ ref?: React.ForwardedRef<HTMLElement> | undefined;
99
+ }) => JSX.Element;
80
100
  export default LabeledSelect;
@@ -4,7 +4,6 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import * as React from 'react';
6
6
  import { Select } from '../Select/Select.js';
7
- import { StatusIconMap, useId } from '../utils/index.js';
8
7
  import { StatusMessage } from '../StatusMessage/StatusMessage.js';
9
8
  import { InputGrid } from '../InputGrid/InputGrid.js';
10
9
  import { Label } from '../Label/Label.js';
@@ -43,23 +42,10 @@ import { Icon } from '../Icon/Icon.js';
43
42
  * />
44
43
  */
45
44
  export const LabeledSelect = React.forwardRef((props, forwardedRef) => {
46
- const { className, disabled = false, label, message, status, svgIcon, displayStyle = 'default', style, required = false, triggerProps, wrapperProps, labelProps, messageContentProps, messageIconProps, ...rest } = props;
47
- const labelId = `${useId()}-label`;
48
- const icon = () => {
49
- if (svgIcon) {
50
- return React.createElement(Icon, null, svgIcon);
51
- }
52
- if (status && message) {
53
- return StatusIconMap[status]();
54
- }
55
- return undefined;
56
- };
57
- return (React.createElement(InputGrid, { labelPlacement: displayStyle, ...wrapperProps },
58
- label && (React.createElement(Label, { as: 'div', required: required, disabled: disabled, id: labelId, ...labelProps }, label)),
59
- React.createElement(Select, { disabled: disabled, className: className, style: style, status: status, ...rest, ref: forwardedRef, triggerProps: {
60
- 'aria-labelledby': labelId,
61
- ...triggerProps,
62
- } }),
63
- typeof message === 'string' ? (React.createElement(StatusMessage, { status: status, startIcon: displayStyle === 'default' ? icon() : undefined, iconProps: messageIconProps, contentProps: messageContentProps }, message)) : (message)));
45
+ const { className, disabled = false, label, message, status, svgIcon, displayStyle = 'default', style, required = false, wrapperProps, labelProps, messageContentProps, messageIconProps, ...rest } = props;
46
+ return (React.createElement(InputGrid, { labelPlacement: displayStyle, "data-iui-status": status, ...wrapperProps },
47
+ label && (React.createElement(Label, { as: 'div', required: required, disabled: disabled, ...labelProps }, label)),
48
+ React.createElement(Select, { disabled: disabled, className: className, style: style, ...rest, ref: forwardedRef }),
49
+ typeof message === 'string' ? (React.createElement(StatusMessage, { status: status, startIcon: svgIcon, iconProps: messageIconProps, contentProps: messageContentProps }, message)) : (message)));
64
50
  });
65
51
  export default LabeledSelect;
@@ -68,4 +68,14 @@ export declare const ListItem: PolymorphicForwardRefComponent<"li", ListItemOwnP
68
68
  * </ListItem>
69
69
  */
70
70
  Description: PolymorphicForwardRefComponent<NonNullable<keyof JSX.IntrinsicElements>, {}>;
71
+ /**
72
+ * Wrapper over [LinkAction](https://itwinui.bentley.com/docs/linkaction) which allows rendering a link inside a ListItem.
73
+ * This ensures that clicking anywhere on the ListItem will trigger the link.
74
+ *
75
+ * @example
76
+ * <ListItem>
77
+ * <ListItem.Action href='https://example.com'>Example link</ListItem.Action>
78
+ * </ListItem>
79
+ */
80
+ Action: PolymorphicForwardRefComponent<"a", {}>;
71
81
  };
@@ -5,6 +5,7 @@
5
5
  import * as React from 'react';
6
6
  import cx from 'classnames';
7
7
  import { polymorphic, Box } from '../utils/index.js';
8
+ import { LinkAction } from '../LinkAction/LinkAction.js';
8
9
  const ListItemComponent = React.forwardRef((props, ref) => {
9
10
  const { size = 'default', disabled = false, active = false, actionable = false, focused = false, className, ...rest } = props;
10
11
  return (React.createElement(Box, { as: 'li', className: cx('iui-list-item', className), "data-iui-active": active ? 'true' : undefined, "data-iui-disabled": disabled ? 'true' : undefined, "data-iui-size": size === 'large' ? 'large' : undefined, "data-iui-actionable": actionable ? 'true' : undefined, "data-iui-focused": focused ? 'true' : undefined, ref: ref, ...rest }));
@@ -20,6 +21,9 @@ ListItemContent.displayName = 'ListItem.Content';
20
21
  const ListItemDescription = polymorphic('iui-list-item-description');
21
22
  ListItemDescription.displayName = 'ListItem.Description';
22
23
  // ----------------------------------------------------------------------------
24
+ const ListItemAction = LinkAction;
25
+ ListItemAction.displayName = 'ListItem.Action';
26
+ // ----------------------------------------------------------------------------
23
27
  // Exported compound component
24
28
  /**
25
29
  * A generic ListItem component that can be used simply for displaying data, or as a base
@@ -61,4 +65,14 @@ export const ListItem = Object.assign(ListItemComponent, {
61
65
  * </ListItem>
62
66
  */
63
67
  Description: ListItemDescription,
68
+ /**
69
+ * Wrapper over [LinkAction](https://itwinui.bentley.com/docs/linkaction) which allows rendering a link inside a ListItem.
70
+ * This ensures that clicking anywhere on the ListItem will trigger the link.
71
+ *
72
+ * @example
73
+ * <ListItem>
74
+ * <ListItem.Action href='https://example.com'>Example link</ListItem.Action>
75
+ * </ListItem>
76
+ */
77
+ Action: ListItemAction,
64
78
  });
@@ -43,7 +43,7 @@ export type MenuItemProps = {
43
43
  */
44
44
  endIcon?: JSX.Element;
45
45
  /**
46
- * @deprecated Use endIcon
46
+ * @deprecated Use endIcon.
47
47
  * SVG icon component shown on the right.
48
48
  */
49
49
  badge?: JSX.Element;
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import type { PolymorphicForwardRefComponent } from '../utils/index.js';
2
+ import type { PolymorphicForwardRefComponent, PortalProps } from '../utils/index.js';
3
3
  import type { DialogMainProps } from '../Dialog/DialogMain.js';
4
4
  type ModalProps = {
5
5
  /**
@@ -33,12 +33,11 @@ type ModalProps = {
33
33
  * If true, the dialog will be portaled into a <div> inside the nearest `ThemeProvider`.
34
34
  *
35
35
  * Can be set to an object with a `to` property to portal into a specific element.
36
+ * If `to`/`to()` === `null`/`undefined`, the default behavior will be used (i.e. as if `portal` is not passed).
36
37
  *
37
38
  * @default true
38
39
  */
39
- portal?: boolean | {
40
- to: HTMLElement;
41
- };
40
+ portal?: PortalProps['portal'];
42
41
  /**
43
42
  * Content of the modal.
44
43
  */
@@ -168,5 +168,7 @@ export type SelectProps<T> = {
168
168
  * )}
169
169
  * />
170
170
  */
171
- export declare const Select: React.ForwardRefExoticComponent<SelectProps<unknown> & React.RefAttributes<HTMLElement>>;
171
+ export declare const Select: <T>(props: SelectProps<T> & {
172
+ ref?: React.ForwardedRef<HTMLElement> | undefined;
173
+ }) => JSX.Element;
172
174
  export default Select;
@@ -6,7 +6,7 @@ import * as React from 'react';
6
6
  import cx from 'classnames';
7
7
  import { Menu } from '../Menu/Menu.js';
8
8
  import { MenuItem } from '../Menu/MenuItem.js';
9
- import { SvgCaretDownSmall, useId, AutoclearingHiddenLiveRegion, Box, Portal, useMergedRefs, SvgCheckmark, useLatestRef, } from '../utils/index.js';
9
+ import { SvgCaretDownSmall, useId, AutoclearingHiddenLiveRegion, Box, Portal, useMergedRefs, SvgCheckmark, useLatestRef, InputWithIcon, } from '../utils/index.js';
10
10
  import { SelectTag } from './SelectTag.js';
11
11
  import { SelectTagContainer } from './SelectTagContainer.js';
12
12
  import { Icon } from '../Icon/Icon.js';
@@ -69,7 +69,7 @@ const isSingleOnChange = (onChange, multiple) => {
69
69
  */
70
70
  export const Select = React.forwardRef((props, forwardedRef) => {
71
71
  const uid = useId();
72
- const { options, value: valueProp, onChange: onChangeProp, placeholder, disabled = false, size, itemRenderer, selectedItemRenderer, className, style, menuClassName, menuStyle, multiple = false, triggerProps, status, popoverProps, ...rest } = props;
72
+ const { options, value: valueProp, onChange: onChangeProp, placeholder, disabled = false, size, itemRenderer, selectedItemRenderer, menuClassName, menuStyle, multiple = false, triggerProps, status, popoverProps, ...rest } = props;
73
73
  const [isOpen, setIsOpen] = React.useState(false);
74
74
  const [liveRegionSelection, setLiveRegionSelection] = React.useState('');
75
75
  const [uncontrolledValue, setUncontrolledValue] = React.useState();
@@ -160,7 +160,7 @@ export const Select = React.forwardRef((props, forwardedRef) => {
160
160
  onVisibleChange: (open) => (open ? show() : hide()),
161
161
  });
162
162
  return (React.createElement(React.Fragment, null,
163
- React.createElement(Box, { className: cx('iui-input-with-icon', className), style: style, ...rest, ref: useMergedRefs(popover.refs.setPositionReference, forwardedRef) },
163
+ React.createElement(InputWithIcon, { ...rest, ref: useMergedRefs(popover.refs.setPositionReference, forwardedRef) },
164
164
  React.createElement(Box, { ...popover.getReferenceProps(), tabIndex: 0, role: 'combobox', "data-iui-size": size, "data-iui-status": status, "aria-disabled": disabled, "aria-autocomplete": 'none', "aria-expanded": isOpen, "aria-haspopup": 'listbox', "aria-controls": `${uid}-menu`, ...triggerProps, ref: useMergedRefs(selectRef, triggerProps?.ref, popover.refs.setReference), className: cx('iui-select-button', {
165
165
  'iui-placeholder': (!selectedItems || selectedItems.length === 0) &&
166
166
  !!placeholder,
@@ -4,9 +4,11 @@ import { Icon } from '../Icon/Icon.js';
4
4
  type StatusMessageProps = {
5
5
  /**
6
6
  * Custom icon to be displayed at the beginning.
7
- * It will default to the `status` icon, if it's set.
7
+ *
8
+ * - It will default to the `status` icon, if `status` is set.
9
+ * - If `startIcon` is set to `null`, no icon will be displayed, even if `status` is set.
8
10
  */
9
- startIcon?: JSX.Element;
11
+ startIcon?: JSX.Element | null;
10
12
  /**
11
13
  * Message content.
12
14
  */
@@ -15,8 +15,10 @@ import { Icon } from '../Icon/Icon.js';
15
15
  export const StatusMessage = React.forwardRef((props, ref) => {
16
16
  const { children, startIcon: userStartIcon, status, className, iconProps, contentProps, ...rest } = props;
17
17
  const icon = userStartIcon ?? (status && StatusIconMap[status]());
18
+ // If user passes null, we don't want to show the icon
19
+ const shouldShowIcon = userStartIcon !== null && !!icon;
18
20
  return (React.createElement(Box, { className: cx('iui-status-message', className), "data-iui-status": status, ref: ref, ...rest },
19
- !!icon ? (React.createElement(Icon, { "aria-hidden": true, ...iconProps }, icon)) : null,
21
+ shouldShowIcon ? (React.createElement(Icon, { "aria-hidden": true, ...iconProps }, icon)) : null,
20
22
  React.createElement(Box, { ...contentProps }, children)));
21
23
  });
22
24
  export default StatusMessage;
@@ -27,7 +27,7 @@ export declare const SelectionColumn: <T extends Record<string, unknown>>(props?
27
27
  maxWidth: number;
28
28
  columnClassName: string;
29
29
  cellClassName: string;
30
- Header: ({ getToggleAllRowsSelectedProps, toggleAllRowsSelected, rows, initialRows, state, }: HeaderProps<T>) => React.JSX.Element;
30
+ Header: ({ getToggleAllRowsSelectedProps, toggleAllRowsSelected, rows, preFilteredFlatRows, state, }: HeaderProps<T>) => React.JSX.Element;
31
31
  Cell: ({ row }: CellProps<T>) => React.JSX.Element;
32
32
  cellRenderer: (props: CellRendererProps<T>) => React.JSX.Element;
33
33
  };
@@ -31,9 +31,9 @@ export const SelectionColumn = (props = {}) => {
31
31
  maxWidth: densityWidth,
32
32
  columnClassName: 'iui-slot',
33
33
  cellClassName: 'iui-slot',
34
- Header: ({ getToggleAllRowsSelectedProps, toggleAllRowsSelected, rows, initialRows, state, }) => {
35
- const disabled = rows.every((row) => isDisabled?.(row.original));
36
- const checked = initialRows.every((row) => state.selectedRowIds[row.id] || isDisabled?.(row.original));
34
+ Header: ({ getToggleAllRowsSelectedProps, toggleAllRowsSelected, rows, preFilteredFlatRows, state, }) => {
35
+ const disabled = preFilteredFlatRows.every((row) => isDisabled?.(row.original));
36
+ const checked = preFilteredFlatRows.every((row) => state.selectedRowIds[row.id] || isDisabled?.(row.original));
37
37
  const indeterminate = !checked && Object.keys(state.selectedRowIds).length > 0;
38
38
  return (React.createElement(Checkbox, { ...getToggleAllRowsSelectedProps(), style: {}, title: '' // Removes default title that comes from react-table
39
39
  , checked: checked && !disabled, indeterminate: indeterminate, disabled: disabled, onChange: () => toggleAllRowsSelected(!rows.some((row) => row.isSelected)) }));
@@ -0,0 +1,2 @@
1
+ /** @private */
2
+ export declare const InputWithIcon: import("../props.js").PolymorphicForwardRefComponent<"div", {}>;
@@ -0,0 +1,8 @@
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 { polymorphic } from '../functions/polymorphic.js';
6
+ /** @private */
7
+ export const InputWithIcon = polymorphic.div('iui-input-with-icon');
8
+ InputWithIcon.displayName = 'InputWithIcon';
@@ -9,10 +9,12 @@ export type PortalProps = {
9
9
  *
10
10
  * Otherwise, it will portal to the element passed to `to`.
11
11
  *
12
+ * If `to`/`to()` === `null`/`undefined`, the default behavior will be used (i.e. as if `portal` is not passed).
13
+ *
12
14
  * @default true
13
15
  */
14
16
  portal?: boolean | {
15
- to: HTMLElement | (() => HTMLElement);
17
+ to: HTMLElement | null | undefined | (() => HTMLElement | null | undefined);
16
18
  };
17
19
  };
18
20
  /**
@@ -21,6 +23,8 @@ export type PortalProps = {
21
23
  * - if `portal` is set to true, renders into nearest ThemeContext.portalContainer
22
24
  * - if `portal` is set to false, renders as-is without portal
23
25
  * - otherwise renders into `portal.to` (can be an element or a function)
26
+ * - If `to`/`to()` === `null`/`undefined`, the default behavior will be used (i.e. as if `portal` is not passed).
27
+ * - E.g. `portal={{ to: () => document.querySelector('.may-not-exist') }}`.
24
28
  *
25
29
  * @private
26
30
  */
@@ -14,6 +14,8 @@ import { useIsClient } from '../hooks/useIsClient.js';
14
14
  * - if `portal` is set to true, renders into nearest ThemeContext.portalContainer
15
15
  * - if `portal` is set to false, renders as-is without portal
16
16
  * - otherwise renders into `portal.to` (can be an element or a function)
17
+ * - If `to`/`to()` === `null`/`undefined`, the default behavior will be used (i.e. as if `portal` is not passed).
18
+ * - E.g. `portal={{ to: () => document.querySelector('.may-not-exist') }}`.
17
19
  *
18
20
  * @private
19
21
  */
@@ -29,8 +31,10 @@ export const Portal = (props) => {
29
31
  // ----------------------------------------------------------------------------
30
32
  const usePortalTo = (portal) => {
31
33
  const themeInfo = React.useContext(ThemeContext);
34
+ const defaultPortalTo = themeInfo?.portalContainer ?? getDocument()?.body;
32
35
  if (typeof portal === 'boolean') {
33
- return portal ? themeInfo?.portalContainer ?? getDocument()?.body : null;
36
+ return portal ? defaultPortalTo : null;
34
37
  }
35
- return typeof portal.to === 'function' ? portal.to() : portal.to;
38
+ const portalTo = typeof portal.to === 'function' ? portal.to() : portal.to;
39
+ return portalTo ?? defaultPortalTo;
36
40
  };
@@ -2,6 +2,7 @@ export * from './Resizer.js';
2
2
  export * from './FocusTrap.js';
3
3
  export * from './InputContainer.js';
4
4
  export * from './InputFlexContainer.js';
5
+ export * from './InputWithIcon.js';
5
6
  export * from './WithCSSTransition.js';
6
7
  export * from './MiddleTextTruncation.js';
7
8
  export * from './VirtualScroll.js';
@@ -6,6 +6,7 @@ export * from './Resizer.js';
6
6
  export * from './FocusTrap.js';
7
7
  export * from './InputContainer.js';
8
8
  export * from './InputFlexContainer.js';
9
+ export * from './InputWithIcon.js';
9
10
  export * from './WithCSSTransition.js';
10
11
  export * from './MiddleTextTruncation.js';
11
12
  export * from './VirtualScroll.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itwin/itwinui-react",
3
- "version": "3.2.3",
3
+ "version": "3.3.0",
4
4
  "author": "Bentley Systems",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -85,7 +85,7 @@
85
85
  "tslib": "^2.6.0"
86
86
  },
87
87
  "devDependencies": {
88
- "@itwin/itwinui-css": "^2.1.0",
88
+ "@itwin/itwinui-css": "^2.2.0",
89
89
  "@itwin/itwinui-variables": "3.0.0",
90
90
  "@swc/cli": "^0.1.62",
91
91
  "@swc/core": "^1.3.68",
@@ -112,7 +112,7 @@
112
112
  "ts-jest": "^29.0.0",
113
113
  "ts-node": "^10.0.0",
114
114
  "typescript": "~5.1.6",
115
- "vite": "^4.5.1"
115
+ "vite": "^5.0.12"
116
116
  },
117
117
  "peerDependencies": {
118
118
  "react": ">= 17.0.0 < 19.0.0",