@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.
- package/CHANGELOG.md +27 -0
- package/cjs/core/ComboBox/ComboBox.d.ts +3 -1
- package/cjs/core/ComboBox/ComboBox.js +3 -4
- package/cjs/core/ComboBox/ComboBoxInputContainer.js +1 -1
- package/cjs/core/Dialog/DialogContext.d.ts +1 -0
- package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +7 -4
- package/cjs/core/ExpandableBlock/ExpandableBlock.js +25 -12
- package/cjs/core/InputGrid/InputGrid.d.ts +7 -5
- package/cjs/core/InputGrid/InputGrid.js +175 -6
- package/cjs/core/InputGroup/InputGroup.d.ts +1 -1
- package/cjs/core/InputGroup/InputGroup.js +4 -13
- package/cjs/core/LabeledInput/LabeledInput.d.ts +1 -2
- package/cjs/core/LabeledInput/LabeledInput.js +11 -8
- package/cjs/core/LabeledSelect/LabeledSelect.d.ts +21 -1
- package/cjs/core/LabeledSelect/LabeledSelect.js +5 -20
- package/cjs/core/List/ListItem.d.ts +10 -0
- package/cjs/core/List/ListItem.js +14 -0
- package/cjs/core/Menu/MenuItem.d.ts +1 -1
- package/cjs/core/Modal/Modal.d.ts +3 -4
- package/cjs/core/Select/Select.d.ts +3 -1
- package/cjs/core/Select/Select.js +2 -2
- package/cjs/core/StatusMessage/StatusMessage.d.ts +4 -2
- package/cjs/core/StatusMessage/StatusMessage.js +3 -1
- package/cjs/core/Table/columns/selectionColumn.d.ts +1 -1
- package/cjs/core/Table/columns/selectionColumn.js +3 -3
- package/cjs/core/utils/components/InputWithIcon.d.ts +2 -0
- package/cjs/core/utils/components/InputWithIcon.js +11 -0
- package/cjs/core/utils/components/Portal.d.ts +5 -1
- package/cjs/core/utils/components/Portal.js +6 -2
- package/cjs/core/utils/components/index.d.ts +1 -0
- package/cjs/core/utils/components/index.js +1 -0
- package/esm/core/ComboBox/ComboBox.d.ts +3 -1
- package/esm/core/ComboBox/ComboBox.js +3 -3
- package/esm/core/ComboBox/ComboBoxInputContainer.js +2 -2
- package/esm/core/Dialog/DialogContext.d.ts +1 -0
- package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +7 -4
- package/esm/core/ExpandableBlock/ExpandableBlock.js +26 -13
- package/esm/core/InputGrid/InputGrid.d.ts +7 -5
- package/esm/core/InputGrid/InputGrid.js +176 -7
- package/esm/core/InputGroup/InputGroup.d.ts +1 -1
- package/esm/core/InputGroup/InputGroup.js +5 -14
- package/esm/core/LabeledInput/LabeledInput.d.ts +1 -2
- package/esm/core/LabeledInput/LabeledInput.js +8 -9
- package/esm/core/LabeledSelect/LabeledSelect.d.ts +21 -1
- package/esm/core/LabeledSelect/LabeledSelect.js +5 -19
- package/esm/core/List/ListItem.d.ts +10 -0
- package/esm/core/List/ListItem.js +14 -0
- package/esm/core/Menu/MenuItem.d.ts +1 -1
- package/esm/core/Modal/Modal.d.ts +3 -4
- package/esm/core/Select/Select.d.ts +3 -1
- package/esm/core/Select/Select.js +3 -3
- package/esm/core/StatusMessage/StatusMessage.d.ts +4 -2
- package/esm/core/StatusMessage/StatusMessage.js +3 -1
- package/esm/core/Table/columns/selectionColumn.d.ts +1 -1
- package/esm/core/Table/columns/selectionColumn.js +3 -3
- package/esm/core/utils/components/InputWithIcon.d.ts +2 -0
- package/esm/core/utils/components/InputWithIcon.js +8 -0
- package/esm/core/utils/components/Portal.d.ts +5 -1
- package/esm/core/utils/components/Portal.js +6 -2
- package/esm/core/utils/components/index.d.ts +1 -0
- package/esm/core/utils/components/index.js +1 -0
- package/package.json +3 -3
- 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 {
|
|
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
|
-
|
|
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, {
|
|
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.
|
|
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 {
|
|
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
|
|
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,
|
|
28
|
-
React.createElement(
|
|
29
|
-
React.createElement(
|
|
30
|
-
shouldShowIcon && (React.createElement(Icon, { fill:
|
|
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:
|
|
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,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
});
|
|
@@ -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?:
|
|
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:
|
|
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,
|
|
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(
|
|
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
|
-
*
|
|
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
|
-
|
|
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,
|
|
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,
|
|
35
|
-
const disabled =
|
|
36
|
-
const checked =
|
|
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,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 ?
|
|
36
|
+
return portal ? defaultPortalTo : null;
|
|
34
37
|
}
|
|
35
|
-
|
|
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.
|
|
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.
|
|
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": "^
|
|
115
|
+
"vite": "^5.0.12"
|
|
116
116
|
},
|
|
117
117
|
"peerDependencies": {
|
|
118
118
|
"react": ">= 17.0.0 < 19.0.0",
|