@itwin/itwinui-react 3.4.2 → 3.6.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 +46 -0
- package/cjs/core/Carousel/Carousel.d.ts +4 -4
- package/cjs/core/Carousel/CarouselNavigation.d.ts +4 -4
- package/cjs/core/Dialog/Dialog.js +19 -17
- package/cjs/core/Dialog/DialogContext.d.ts +4 -0
- package/cjs/core/Dialog/DialogMain.js +1 -1
- package/cjs/core/Dialog/DialogTitleBar.js +1 -1
- package/cjs/core/InputGroup/InputGroup.d.ts +4 -0
- package/cjs/core/InputGroup/InputGroup.js +20 -4
- package/cjs/core/InputWithDecorations/InputWithDecorations.d.ts +18 -62
- package/cjs/core/InputWithDecorations/InputWithDecorations.js +21 -6
- package/cjs/core/LabeledSelect/LabeledSelect.d.ts +376 -4
- package/cjs/core/LabeledSelect/LabeledSelect.js +1 -1
- package/cjs/core/Popover/Popover.d.ts +6 -3
- package/cjs/core/ProgressIndicators/ProgressLinear.js +6 -1
- package/cjs/core/ProgressIndicators/ProgressRadial.js +8 -3
- package/cjs/core/SearchBox/SearchBox.js +4 -6
- package/cjs/core/Select/Select.d.ts +197 -102
- package/cjs/core/Select/Select.js +72 -19
- package/cjs/core/Table/Table.js +2 -1
- package/cjs/core/Tabs/Tabs.js +19 -3
- package/cjs/core/Tile/Tile.d.ts +2 -2
- package/cjs/core/ToggleSwitch/ToggleSwitch.d.ts +4 -2
- package/cjs/core/ToggleSwitch/ToggleSwitch.js +5 -11
- package/cjs/core/Typography/Anchor.d.ts +21 -1
- package/cjs/core/Typography/Anchor.js +38 -3
- package/cjs/core/VisuallyHidden/VisuallyHidden.js +19 -3
- package/cjs/core/utils/components/InputFlexContainer.d.ts +25 -0
- package/cjs/core/utils/components/InputFlexContainer.js +19 -1
- package/cjs/core/utils/components/LineClamp.d.ts +5 -0
- package/cjs/core/utils/components/LineClamp.js +49 -0
- package/cjs/core/utils/components/ShadowRoot.d.ts +2 -1
- package/cjs/core/utils/components/ShadowRoot.js +19 -4
- package/cjs/core/utils/components/index.d.ts +1 -0
- package/cjs/core/utils/components/index.js +1 -0
- package/cjs/core/utils/functions/polymorphic.d.ts +5 -3
- package/cjs/core/utils/functions/polymorphic.js +20 -5
- package/cjs/core/utils/icons/Svg.js +5 -1
- package/cjs/core/utils/icons/SvgStatusError.js +1 -1
- package/esm/core/Carousel/Carousel.d.ts +4 -4
- package/esm/core/Carousel/CarouselNavigation.d.ts +4 -4
- package/esm/core/Dialog/Dialog.js +19 -17
- package/esm/core/Dialog/DialogContext.d.ts +4 -0
- package/esm/core/Dialog/DialogMain.js +1 -1
- package/esm/core/Dialog/DialogTitleBar.js +1 -1
- package/esm/core/InputGroup/InputGroup.d.ts +4 -0
- package/esm/core/InputGroup/InputGroup.js +20 -4
- package/esm/core/InputWithDecorations/InputWithDecorations.d.ts +18 -62
- package/esm/core/InputWithDecorations/InputWithDecorations.js +22 -7
- package/esm/core/LabeledSelect/LabeledSelect.d.ts +376 -4
- package/esm/core/LabeledSelect/LabeledSelect.js +1 -1
- package/esm/core/Popover/Popover.d.ts +6 -3
- package/esm/core/ProgressIndicators/ProgressLinear.js +7 -2
- package/esm/core/ProgressIndicators/ProgressRadial.js +9 -4
- package/esm/core/SearchBox/SearchBox.js +5 -7
- package/esm/core/Select/Select.d.ts +197 -102
- package/esm/core/Select/Select.js +73 -20
- package/esm/core/Table/Table.js +2 -1
- package/esm/core/Tabs/Tabs.js +19 -3
- package/esm/core/Tile/Tile.d.ts +2 -2
- package/esm/core/ToggleSwitch/ToggleSwitch.d.ts +4 -2
- package/esm/core/ToggleSwitch/ToggleSwitch.js +6 -12
- package/esm/core/Typography/Anchor.d.ts +21 -1
- package/esm/core/Typography/Anchor.js +11 -2
- package/esm/core/VisuallyHidden/VisuallyHidden.js +19 -3
- package/esm/core/utils/components/InputFlexContainer.d.ts +25 -0
- package/esm/core/utils/components/InputFlexContainer.js +18 -0
- package/esm/core/utils/components/LineClamp.d.ts +5 -0
- package/esm/core/utils/components/LineClamp.js +23 -0
- package/esm/core/utils/components/ShadowRoot.d.ts +2 -1
- package/esm/core/utils/components/ShadowRoot.js +19 -4
- package/esm/core/utils/components/index.d.ts +1 -0
- package/esm/core/utils/components/index.js +1 -0
- package/esm/core/utils/functions/polymorphic.d.ts +5 -3
- package/esm/core/utils/functions/polymorphic.js +20 -5
- package/esm/core/utils/icons/Svg.js +5 -1
- package/esm/core/utils/icons/SvgStatusError.js +1 -1
- package/package.json +27 -27
- package/styles.css +39 -38
|
@@ -1,54 +1,193 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import type { CommonProps } from '../utils/index.js';
|
|
3
3
|
import { usePopover } from '../Popover/Popover.js';
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Select component to select value from options.
|
|
6
|
+
* Generic type is used for value. It prevents you from mistakenly using other types in `options`, `value` and `onChange`.
|
|
7
|
+
* @example
|
|
8
|
+
* <caption>Basic select.</caption>
|
|
9
|
+
* <Select
|
|
10
|
+
* options={[
|
|
11
|
+
* { value: '1', label: 'Option 1' },
|
|
12
|
+
* { value: '2', label: 'Option 2' },
|
|
13
|
+
* { value: '3', label: 'Option 3' },
|
|
14
|
+
* ]}
|
|
15
|
+
* />
|
|
16
|
+
* @example
|
|
17
|
+
* <caption>Native select.</caption>
|
|
18
|
+
* <Select
|
|
19
|
+
* native
|
|
20
|
+
* options={[
|
|
21
|
+
* { value: '1', label: 'Option 1' },
|
|
22
|
+
* { value: '2', label: 'Option 2' },
|
|
23
|
+
* { value: '3', label: 'Option 3' },
|
|
24
|
+
* ]}
|
|
25
|
+
* />
|
|
26
|
+
* @example
|
|
27
|
+
* <caption>Disabled select with placeholder.</caption>
|
|
28
|
+
* <Select
|
|
29
|
+
* disabled={true}
|
|
30
|
+
* placeholder='Placeholder text'
|
|
31
|
+
* options={[{ value: 1, label: 'Option 1' }, { value: 2, label: 'Option 2' }, { value: 3, label: 'Option 3' }]}
|
|
32
|
+
* />
|
|
33
|
+
* @example
|
|
34
|
+
* <caption>Select with selected value and change handler.</caption>
|
|
35
|
+
* <Select
|
|
36
|
+
* value={selectedValue}
|
|
37
|
+
* onChange={(value) => setSelectedValue(value)}
|
|
38
|
+
* options={[{ value: 1, label: 'Option 1' }, { value: 2, label: 'Option 2' }, { value: 3, label: 'Option 3' }]}
|
|
39
|
+
* />
|
|
40
|
+
* @example
|
|
41
|
+
* <caption>Select using custom renderers for menu items and selected value.</caption>
|
|
42
|
+
* <Select
|
|
43
|
+
* options={[
|
|
44
|
+
* { value: 'yellow', label: 'Yellow' },
|
|
45
|
+
* { value: 'green', label: 'Green' },
|
|
46
|
+
* { value: 'red', label: 'Red' },
|
|
47
|
+
* ]}
|
|
48
|
+
* value={selectedValue}
|
|
49
|
+
* placeholder='Placeholder text'
|
|
50
|
+
* itemRenderer={(option, itemProps) => (
|
|
51
|
+
* <MenuItem
|
|
52
|
+
* style={{ color: option.value }}
|
|
53
|
+
* isSelected={itemProps.isSelected}
|
|
54
|
+
* onClick={() => {
|
|
55
|
+
* setSelectedValue(option.value);
|
|
56
|
+
* itemProps.close();
|
|
57
|
+
* }}
|
|
58
|
+
* role='option'
|
|
59
|
+
* ref={(el) => itemProps.isSelected && el?.scrollIntoView()}
|
|
60
|
+
* >
|
|
61
|
+
* {option.label}
|
|
62
|
+
* </MenuItem>
|
|
63
|
+
* )}
|
|
64
|
+
* selectedItemRenderer={(option) => (
|
|
65
|
+
* <span style={{ backgroundColor: option.value }}>{option.label}</span>
|
|
66
|
+
* )}
|
|
67
|
+
* />
|
|
68
|
+
*/
|
|
69
|
+
export declare const Select: <T>(props: SelectProps<T> & {
|
|
70
|
+
ref?: React.ForwardedRef<HTMLElement> | undefined;
|
|
71
|
+
}) => JSX.Element;
|
|
72
|
+
export type SelectProps<T> = Omit<React.ComponentPropsWithoutRef<'div'>, 'onChange' | 'placeholder' | 'value' | 'defaultValue'> & (({
|
|
5
73
|
/**
|
|
6
|
-
*
|
|
74
|
+
* If true, the native `<select>` element will be rendered.
|
|
75
|
+
*
|
|
76
|
+
* Extra props, such as `name` can be passed to the `<select>` using `triggerProps`.
|
|
77
|
+
*
|
|
78
|
+
* @default false
|
|
7
79
|
*/
|
|
8
|
-
|
|
80
|
+
native: true;
|
|
81
|
+
} & NativeSelectProps) | ({
|
|
82
|
+
native?: false;
|
|
83
|
+
} & CustomSelectProps<T> & {
|
|
9
84
|
/**
|
|
10
|
-
*
|
|
85
|
+
* styleType is only supported for `<Select native>`.
|
|
11
86
|
*/
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
|
|
87
|
+
styleType?: never;
|
|
88
|
+
}));
|
|
89
|
+
type NativeSelectProps = SelectCommonProps & {
|
|
15
90
|
/**
|
|
16
|
-
*
|
|
91
|
+
* Selected option value.
|
|
92
|
+
*
|
|
93
|
+
* Must be a string, because it is passed as an attribute to the native <select>.
|
|
94
|
+
*
|
|
95
|
+
* Alternatively, pass `null` to reset the value.
|
|
17
96
|
*/
|
|
18
|
-
|
|
97
|
+
value?: string | null;
|
|
19
98
|
/**
|
|
20
|
-
*
|
|
99
|
+
* Callback invoked when the selected value changes.
|
|
21
100
|
*/
|
|
22
|
-
|
|
101
|
+
onChange?: (value: string, event: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
23
102
|
/**
|
|
24
|
-
*
|
|
25
|
-
* Use 'large' when any of the select options have `sublabel`.
|
|
103
|
+
* Array of options that populates the select menu.
|
|
26
104
|
*
|
|
27
|
-
*
|
|
105
|
+
* The `value` property of each option must be a string.
|
|
28
106
|
*/
|
|
29
|
-
|
|
107
|
+
options: Array<{
|
|
108
|
+
label: string;
|
|
109
|
+
value: string;
|
|
110
|
+
disabled?: boolean;
|
|
111
|
+
}>;
|
|
30
112
|
/**
|
|
31
|
-
*
|
|
113
|
+
* Default value that is selected on initial render. This is useful when you don't want to
|
|
114
|
+
* maintain your own state but still want to control the initial value.
|
|
115
|
+
*
|
|
116
|
+
* If not passed, the first option (or placeholder) will be automatically selected.
|
|
32
117
|
*/
|
|
33
|
-
|
|
118
|
+
defaultValue?: string;
|
|
34
119
|
/**
|
|
35
|
-
*
|
|
36
|
-
* SVG icon component shown on the left.
|
|
120
|
+
* Props to pass to the select element.
|
|
37
121
|
*/
|
|
38
|
-
|
|
122
|
+
triggerProps?: Omit<React.ComponentPropsWithRef<'select'>, 'size'>;
|
|
123
|
+
required?: boolean;
|
|
124
|
+
multiple?: never;
|
|
125
|
+
} & NativeSelectStyleTypeProps;
|
|
126
|
+
type NativeSelectStyleTypeProps = {
|
|
39
127
|
/**
|
|
40
|
-
*
|
|
128
|
+
* Style of the select.
|
|
129
|
+
* Use 'borderless' to hide outline.
|
|
130
|
+
* @default 'default'
|
|
41
131
|
*/
|
|
42
|
-
|
|
132
|
+
styleType?: 'default';
|
|
43
133
|
/**
|
|
44
|
-
*
|
|
134
|
+
* Placeholder for when no item is selected.
|
|
135
|
+
*
|
|
136
|
+
* Will be rendered as a disabled option at the top of the list, and automatically
|
|
137
|
+
* selected when no `value` or `defaultValue` is provided.
|
|
138
|
+
*
|
|
139
|
+
* Not allowed when `styleType` is `borderless`.
|
|
140
|
+
*/
|
|
141
|
+
placeholder?: string;
|
|
142
|
+
} | {
|
|
143
|
+
styleType: 'borderless';
|
|
144
|
+
placeholder?: never;
|
|
145
|
+
};
|
|
146
|
+
type SelectCommonProps = {
|
|
147
|
+
/**
|
|
148
|
+
* Disables select.
|
|
149
|
+
* @default false
|
|
45
150
|
*/
|
|
46
151
|
disabled?: boolean;
|
|
47
152
|
/**
|
|
48
|
-
*
|
|
153
|
+
* Modify size of select.
|
|
49
154
|
*/
|
|
50
|
-
|
|
51
|
-
|
|
155
|
+
size?: 'small' | 'large';
|
|
156
|
+
/**
|
|
157
|
+
* Status of select.
|
|
158
|
+
*/
|
|
159
|
+
status?: 'positive' | 'warning' | 'negative';
|
|
160
|
+
};
|
|
161
|
+
export type CustomSelectProps<T> = SelectCommonProps & {
|
|
162
|
+
/**
|
|
163
|
+
* Placeholder when no item is selected.
|
|
164
|
+
*/
|
|
165
|
+
placeholder?: React.ReactNode;
|
|
166
|
+
/**
|
|
167
|
+
* Array of options that populates the select menu.
|
|
168
|
+
*/
|
|
169
|
+
options: SelectOption<T>[];
|
|
170
|
+
/**
|
|
171
|
+
* Custom renderer for an item in the dropdown list. `MenuItem` item props are going to be populated if not provided.
|
|
172
|
+
*/
|
|
173
|
+
itemRenderer?: (option: SelectOption<T>, itemProps: ItemRendererProps) => JSX.Element;
|
|
174
|
+
/**
|
|
175
|
+
* Custom class for menu.
|
|
176
|
+
*/
|
|
177
|
+
menuClassName?: string;
|
|
178
|
+
/**
|
|
179
|
+
* Custom style for menu.
|
|
180
|
+
*/
|
|
181
|
+
menuStyle?: React.CSSProperties;
|
|
182
|
+
/**
|
|
183
|
+
* Props to customize Popover behavior.
|
|
184
|
+
*/
|
|
185
|
+
popoverProps?: Pick<Parameters<typeof usePopover>[0], 'visible' | 'onVisibleChange' | 'placement' | 'matchWidth' | 'closeOnOutsideClick'>;
|
|
186
|
+
/**
|
|
187
|
+
* Props to pass to the select button (trigger) element.
|
|
188
|
+
*/
|
|
189
|
+
triggerProps?: React.ComponentPropsWithRef<'div'>;
|
|
190
|
+
} & SelectMultipleTypeProps<T> & Omit<React.ComponentPropsWithoutRef<'div'>, 'size' | 'disabled' | 'placeholder' | 'onChange'>;
|
|
52
191
|
export type SelectValueChangeEvent = 'added' | 'removed';
|
|
53
192
|
export type SelectMultipleTypeProps<T> = {
|
|
54
193
|
/**
|
|
@@ -64,8 +203,10 @@ export type SelectMultipleTypeProps<T> = {
|
|
|
64
203
|
/**
|
|
65
204
|
* Selected option value.
|
|
66
205
|
* If `multiple` is enabled, it is an array of values.
|
|
206
|
+
*
|
|
207
|
+
* Pass `null` to reset the value.
|
|
67
208
|
*/
|
|
68
|
-
value?: T;
|
|
209
|
+
value?: T | null;
|
|
69
210
|
/**
|
|
70
211
|
* Callback function handling change event on select.
|
|
71
212
|
*/
|
|
@@ -76,98 +217,52 @@ export type SelectMultipleTypeProps<T> = {
|
|
|
76
217
|
value?: T[];
|
|
77
218
|
onChange?: (value: T, event: SelectValueChangeEvent) => void;
|
|
78
219
|
};
|
|
79
|
-
export type
|
|
220
|
+
export type ItemRendererProps = {
|
|
80
221
|
/**
|
|
81
|
-
*
|
|
222
|
+
* Close handler that closes the dropdown.
|
|
82
223
|
*/
|
|
83
|
-
|
|
224
|
+
close: () => void;
|
|
84
225
|
/**
|
|
85
|
-
*
|
|
226
|
+
* Indicates whether an item is selected.
|
|
86
227
|
*/
|
|
87
|
-
|
|
228
|
+
isSelected: boolean;
|
|
229
|
+
};
|
|
230
|
+
export type SelectOption<T> = {
|
|
88
231
|
/**
|
|
89
|
-
*
|
|
90
|
-
* @default false
|
|
232
|
+
* Label of the item used in dropdown list and when selected.
|
|
91
233
|
*/
|
|
92
|
-
|
|
234
|
+
label: string;
|
|
93
235
|
/**
|
|
94
|
-
*
|
|
236
|
+
* Sublabel of the item shown below the label.
|
|
95
237
|
*/
|
|
96
|
-
|
|
238
|
+
sublabel?: React.ReactNode;
|
|
97
239
|
/**
|
|
98
|
-
*
|
|
240
|
+
* Modify height of the item.
|
|
241
|
+
* Use 'large' when any of the select options have `sublabel`.
|
|
242
|
+
*
|
|
243
|
+
* Defaults to 'large' if `sublabel` provided, otherwise 'default'.
|
|
99
244
|
*/
|
|
100
|
-
|
|
245
|
+
size?: 'default' | 'large';
|
|
101
246
|
/**
|
|
102
|
-
*
|
|
247
|
+
* Value of the item.
|
|
103
248
|
*/
|
|
104
|
-
|
|
249
|
+
value: T;
|
|
105
250
|
/**
|
|
106
|
-
*
|
|
251
|
+
* @deprecated Use startIcon
|
|
252
|
+
* SVG icon component shown on the left.
|
|
107
253
|
*/
|
|
108
|
-
|
|
254
|
+
icon?: JSX.Element;
|
|
109
255
|
/**
|
|
110
|
-
*
|
|
256
|
+
* SVG icon component shown on the left.
|
|
111
257
|
*/
|
|
112
|
-
|
|
258
|
+
startIcon?: JSX.Element;
|
|
113
259
|
/**
|
|
114
|
-
*
|
|
260
|
+
* Item is disabled.
|
|
115
261
|
*/
|
|
116
|
-
|
|
262
|
+
disabled?: boolean;
|
|
117
263
|
/**
|
|
118
|
-
*
|
|
264
|
+
* Any other props.
|
|
119
265
|
*/
|
|
120
|
-
|
|
121
|
-
} &
|
|
122
|
-
|
|
123
|
-
* Select component to select value from options.
|
|
124
|
-
* Generic type is used for value. It prevents you from mistakenly using other types in `options`, `value` and `onChange`.
|
|
125
|
-
* @example
|
|
126
|
-
* <caption>Basic select.</caption>
|
|
127
|
-
* <Select<number> options={[{ value: 1, label: 'Option 1' }, { value: 2, label: 'Option 2' }, { value: 3, label: 'Option 3' }]} />
|
|
128
|
-
* @example
|
|
129
|
-
* <caption>Disabled select with placeholder.</caption>
|
|
130
|
-
* <Select
|
|
131
|
-
* disabled={true}
|
|
132
|
-
* placeholder='Placeholder text'
|
|
133
|
-
* options={[{ value: 1, label: 'Option 1' }, { value: 2, label: 'Option 2' }, { value: 3, label: 'Option 3' }]}
|
|
134
|
-
* />
|
|
135
|
-
* @example
|
|
136
|
-
* <caption>Select with selected value and change handler.</caption>
|
|
137
|
-
* <Select<number>
|
|
138
|
-
* value={selectedValue}
|
|
139
|
-
* onChange={(value) => setSelectedValue(value)}
|
|
140
|
-
* options={[{ value: 1, label: 'Option 1' }, { value: 2, label: 'Option 2' }, { value: 3, label: 'Option 3' }]}
|
|
141
|
-
* />
|
|
142
|
-
* @example
|
|
143
|
-
* <caption>Select using custom renderers for menu items and selected value.</caption>
|
|
144
|
-
* <Select<string>
|
|
145
|
-
* options={[
|
|
146
|
-
* { value: 'yellow', label: 'Yellow' },
|
|
147
|
-
* { value: 'green', label: 'Green' },
|
|
148
|
-
* { value: 'red', label: 'Red' },
|
|
149
|
-
* ]}
|
|
150
|
-
* value={selectedValue}
|
|
151
|
-
* placeholder='Placeholder text'
|
|
152
|
-
* itemRenderer={(option, itemProps) => (
|
|
153
|
-
* <MenuItem
|
|
154
|
-
* style={{ color: option.value }}
|
|
155
|
-
* isSelected={itemProps.isSelected}
|
|
156
|
-
* onClick={() => {
|
|
157
|
-
* setSelectedValue(option.value);
|
|
158
|
-
* itemProps.close();
|
|
159
|
-
* }}
|
|
160
|
-
* role='option'
|
|
161
|
-
* ref={(el) => itemProps.isSelected && el?.scrollIntoView()}
|
|
162
|
-
* >
|
|
163
|
-
* {option.label}
|
|
164
|
-
* </MenuItem>
|
|
165
|
-
* )}
|
|
166
|
-
* selectedItemRenderer={(option) => (
|
|
167
|
-
* <span style={{ backgroundColor: option.value }}>{option.label}</span>
|
|
168
|
-
* )}
|
|
169
|
-
* />
|
|
170
|
-
*/
|
|
171
|
-
export declare const Select: <T>(props: SelectProps<T> & {
|
|
172
|
-
ref?: React.ForwardedRef<HTMLElement> | undefined;
|
|
173
|
-
}) => JSX.Element;
|
|
266
|
+
[key: string]: unknown;
|
|
267
|
+
} & CommonProps;
|
|
268
|
+
export {};
|
|
@@ -40,19 +40,29 @@ const SelectTag_js_1 = require("./SelectTag.js");
|
|
|
40
40
|
const SelectTagContainer_js_1 = require("./SelectTagContainer.js");
|
|
41
41
|
const Icon_js_1 = require("../Icon/Icon.js");
|
|
42
42
|
const Popover_js_1 = require("../Popover/Popover.js");
|
|
43
|
-
|
|
44
|
-
return multiple;
|
|
45
|
-
};
|
|
46
|
-
// Type guard for multiple did not work
|
|
47
|
-
const isSingleOnChange = (onChange, multiple) => {
|
|
48
|
-
return !multiple;
|
|
49
|
-
};
|
|
43
|
+
// ----------------------------------------------------------------------------
|
|
50
44
|
/**
|
|
51
45
|
* Select component to select value from options.
|
|
52
46
|
* Generic type is used for value. It prevents you from mistakenly using other types in `options`, `value` and `onChange`.
|
|
53
47
|
* @example
|
|
54
48
|
* <caption>Basic select.</caption>
|
|
55
|
-
* <Select
|
|
49
|
+
* <Select
|
|
50
|
+
* options={[
|
|
51
|
+
* { value: '1', label: 'Option 1' },
|
|
52
|
+
* { value: '2', label: 'Option 2' },
|
|
53
|
+
* { value: '3', label: 'Option 3' },
|
|
54
|
+
* ]}
|
|
55
|
+
* />
|
|
56
|
+
* @example
|
|
57
|
+
* <caption>Native select.</caption>
|
|
58
|
+
* <Select
|
|
59
|
+
* native
|
|
60
|
+
* options={[
|
|
61
|
+
* { value: '1', label: 'Option 1' },
|
|
62
|
+
* { value: '2', label: 'Option 2' },
|
|
63
|
+
* { value: '3', label: 'Option 3' },
|
|
64
|
+
* ]}
|
|
65
|
+
* />
|
|
56
66
|
* @example
|
|
57
67
|
* <caption>Disabled select with placeholder.</caption>
|
|
58
68
|
* <Select
|
|
@@ -62,14 +72,14 @@ const isSingleOnChange = (onChange, multiple) => {
|
|
|
62
72
|
* />
|
|
63
73
|
* @example
|
|
64
74
|
* <caption>Select with selected value and change handler.</caption>
|
|
65
|
-
* <Select
|
|
75
|
+
* <Select
|
|
66
76
|
* value={selectedValue}
|
|
67
77
|
* onChange={(value) => setSelectedValue(value)}
|
|
68
78
|
* options={[{ value: 1, label: 'Option 1' }, { value: 2, label: 'Option 2' }, { value: 3, label: 'Option 3' }]}
|
|
69
79
|
* />
|
|
70
80
|
* @example
|
|
71
81
|
* <caption>Select using custom renderers for menu items and selected value.</caption>
|
|
72
|
-
* <Select
|
|
82
|
+
* <Select
|
|
73
83
|
* options={[
|
|
74
84
|
* { value: 'yellow', label: 'Yellow' },
|
|
75
85
|
* { value: 'green', label: 'Green' },
|
|
@@ -97,12 +107,38 @@ const isSingleOnChange = (onChange, multiple) => {
|
|
|
97
107
|
* />
|
|
98
108
|
*/
|
|
99
109
|
exports.Select = React.forwardRef((props, forwardedRef) => {
|
|
110
|
+
const { native, ...rest } = props;
|
|
111
|
+
const Component = native ? NativeSelect : CustomSelect;
|
|
112
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
return React.createElement(Component, { ...rest, ref: forwardedRef });
|
|
115
|
+
});
|
|
116
|
+
// ----------------------------------------------------------------------------
|
|
117
|
+
const NativeSelect = React.forwardRef((props, forwardedRef) => {
|
|
118
|
+
const { triggerProps, options, disabled, placeholder, defaultValue: defaultValueProp = placeholder !== undefined ? '' : undefined, value: valueProp, onChange: onChangeProp, size, status, styleType, required, ...rest } = props;
|
|
119
|
+
return (React.createElement(index_js_1.InputWithIcon, { ...rest, ref: forwardedRef },
|
|
120
|
+
React.createElement(SelectButton, { as: 'select', size: size, status: status, styleType: styleType, disabled: disabled, defaultValue: valueProp === undefined ? defaultValueProp : undefined, value: valueProp === null ? '' : valueProp, required: required, ...triggerProps, onKeyDown: (0, index_js_1.mergeEventHandlers)(triggerProps?.onKeyDown, (event) => {
|
|
121
|
+
// Firefox does not open the menu on Enter, so we need to do it manually.
|
|
122
|
+
if (event.key === 'Enter') {
|
|
123
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
124
|
+
// @ts-ignore
|
|
125
|
+
event.currentTarget.showPicker?.();
|
|
126
|
+
}
|
|
127
|
+
}), onChange: (0, index_js_1.mergeEventHandlers)(triggerProps?.onChange, (event) => {
|
|
128
|
+
onChangeProp?.(event.currentTarget.value, event);
|
|
129
|
+
}) },
|
|
130
|
+
styleType !== 'borderless' && placeholder !== undefined ? (React.createElement("option", { value: '', disabled: true }, placeholder)) : null,
|
|
131
|
+
options.map((option) => (React.createElement("option", { key: option.value, ...option }, option.label)))),
|
|
132
|
+
React.createElement(SelectEndIcon, { disabled: disabled })));
|
|
133
|
+
});
|
|
134
|
+
// ----------------------------------------------------------------------------
|
|
135
|
+
const CustomSelect = React.forwardRef((props, forwardedRef) => {
|
|
100
136
|
const uid = (0, index_js_1.useId)();
|
|
101
137
|
const { options, value: valueProp, onChange: onChangeProp, placeholder, disabled = false, size, itemRenderer, selectedItemRenderer, menuClassName, menuStyle, multiple = false, triggerProps, status, popoverProps, ...rest } = props;
|
|
102
138
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
103
139
|
const [liveRegionSelection, setLiveRegionSelection] = React.useState('');
|
|
104
140
|
const [uncontrolledValue, setUncontrolledValue] = React.useState();
|
|
105
|
-
const value = valueProp
|
|
141
|
+
const value = valueProp !== undefined ? valueProp : uncontrolledValue;
|
|
106
142
|
const onChangeRef = (0, index_js_1.useLatestRef)(onChangeProp);
|
|
107
143
|
const selectRef = React.useRef(null);
|
|
108
144
|
const show = React.useCallback(() => {
|
|
@@ -190,18 +226,13 @@ exports.Select = React.forwardRef((props, forwardedRef) => {
|
|
|
190
226
|
});
|
|
191
227
|
return (React.createElement(React.Fragment, null,
|
|
192
228
|
React.createElement(index_js_1.InputWithIcon, { ...rest, ref: (0, index_js_1.useMergedRefs)(popover.refs.setPositionReference, forwardedRef) },
|
|
193
|
-
React.createElement(
|
|
194
|
-
'iui-placeholder': (!selectedItems || selectedItems.length === 0) &&
|
|
195
|
-
!!placeholder,
|
|
229
|
+
React.createElement(SelectButton, { ...popover.getReferenceProps(), tabIndex: 0, role: 'combobox', size: size, status: status, "aria-disabled": disabled ? 'true' : undefined, "aria-autocomplete": 'none', "aria-expanded": isOpen, "aria-haspopup": 'listbox', "aria-controls": `${uid}-menu`, ...triggerProps, ref: (0, index_js_1.useMergedRefs)(selectRef, triggerProps?.ref, popover.refs.setReference), className: (0, classnames_1.default)({
|
|
230
|
+
'iui-placeholder': (!selectedItems || selectedItems.length === 0) && !!placeholder,
|
|
196
231
|
'iui-disabled': disabled,
|
|
197
232
|
}, triggerProps?.className) },
|
|
198
233
|
(!selectedItems || selectedItems.length === 0) && (React.createElement(index_js_1.Box, { as: 'span', className: 'iui-content' }, placeholder)),
|
|
199
234
|
isMultipleEnabled(selectedItems, multiple) ? (React.createElement(MultipleSelectButton, { selectedItems: selectedItems, selectedItemsRenderer: selectedItemRenderer, tagRenderer: tagRenderer })) : (React.createElement(SingleSelectButton, { selectedItem: selectedItems, selectedItemRenderer: selectedItemRenderer }))),
|
|
200
|
-
React.createElement(
|
|
201
|
-
'iui-disabled': disabled,
|
|
202
|
-
'iui-open': isOpen,
|
|
203
|
-
}) },
|
|
204
|
-
React.createElement(index_js_1.SvgCaretDownSmall, null)),
|
|
235
|
+
React.createElement(SelectEndIcon, { disabled: disabled, isOpen: isOpen }),
|
|
205
236
|
multiple ? (React.createElement(index_js_1.AutoclearingHiddenLiveRegion, { text: liveRegionSelection })) : null),
|
|
206
237
|
popover.open && (React.createElement(index_js_1.Portal, null,
|
|
207
238
|
React.createElement(Menu_js_1.Menu, { role: 'listbox', className: menuClassName, id: `${uid}-menu`, key: `${uid}-menu`, ...popover.getFloatingProps({
|
|
@@ -213,6 +244,27 @@ exports.Select = React.forwardRef((props, forwardedRef) => {
|
|
|
213
244
|
},
|
|
214
245
|
}), ref: popover.refs.setFloating }, menuItems)))));
|
|
215
246
|
});
|
|
247
|
+
// ----------------------------------------------------------------------------
|
|
248
|
+
// Type guards
|
|
249
|
+
const isMultipleEnabled = (variable, multiple) => {
|
|
250
|
+
return multiple;
|
|
251
|
+
};
|
|
252
|
+
// Type guard for multiple did not work
|
|
253
|
+
const isSingleOnChange = (onChange, multiple) => {
|
|
254
|
+
return !multiple;
|
|
255
|
+
};
|
|
256
|
+
// ----------------------------------------------------------------------------
|
|
257
|
+
const SelectButton = React.forwardRef((props, forwardedRef) => {
|
|
258
|
+
const { size, status, styleType = 'default', ...rest } = props;
|
|
259
|
+
return (React.createElement(index_js_1.Box, { "data-iui-size": size, "data-iui-status": status, "data-iui-variant": styleType !== 'default' ? styleType : undefined, ...rest, ref: forwardedRef, className: (0, classnames_1.default)('iui-select-button', props.className) }));
|
|
260
|
+
});
|
|
261
|
+
// ----------------------------------------------------------------------------
|
|
262
|
+
const SelectEndIcon = React.forwardRef((props, forwardedRef) => {
|
|
263
|
+
const { disabled, isOpen, ...rest } = props;
|
|
264
|
+
return (React.createElement(Icon_js_1.Icon, { "aria-hidden": true, ...rest, ref: forwardedRef, className: (0, classnames_1.default)('iui-end-icon', { 'iui-disabled': disabled, 'iui-open': isOpen }, props.className) },
|
|
265
|
+
React.createElement(index_js_1.SvgCaretDownSmall, null)));
|
|
266
|
+
});
|
|
267
|
+
// ----------------------------------------------------------------------------
|
|
216
268
|
const SingleSelectButton = ({ selectedItem, selectedItemRenderer, }) => {
|
|
217
269
|
const startIcon = selectedItem?.startIcon ?? selectedItem?.icon;
|
|
218
270
|
return (React.createElement(React.Fragment, null,
|
|
@@ -223,6 +275,7 @@ const SingleSelectButton = ({ selectedItem, selectedItemRenderer, }) => {
|
|
|
223
275
|
startIcon && (React.createElement(index_js_1.Box, { as: 'span', className: 'iui-icon', "aria-hidden": true }, startIcon)),
|
|
224
276
|
React.createElement(index_js_1.Box, { as: 'span', className: 'iui-content' }, selectedItem.label)))));
|
|
225
277
|
};
|
|
278
|
+
// ----------------------------------------------------------------------------
|
|
226
279
|
const MultipleSelectButton = ({ selectedItems, selectedItemsRenderer, tagRenderer, }) => {
|
|
227
280
|
const selectedItemsElements = React.useMemo(() => {
|
|
228
281
|
if (!selectedItems) {
|
package/cjs/core/Table/Table.js
CHANGED
|
@@ -290,7 +290,8 @@ const Table = (props) => {
|
|
|
290
290
|
// This is to avoid the old columnOrder from affecting the new columns' columnOrder
|
|
291
291
|
React.useEffect(() => {
|
|
292
292
|
// Check if columns have changed (by value)
|
|
293
|
-
if (
|
|
293
|
+
if (lastPassedColumns.current.length > 0 &&
|
|
294
|
+
JSON.stringify(lastPassedColumns.current) !== JSON.stringify(columns)) {
|
|
294
295
|
instance.setColumnOrder([]);
|
|
295
296
|
}
|
|
296
297
|
lastPassedColumns.current = columns;
|
package/cjs/core/Tabs/Tabs.js
CHANGED
|
@@ -71,13 +71,14 @@ const TabList = React.forwardRef((props, ref) => {
|
|
|
71
71
|
}, className), role: 'tablist', ref: refs, ...rest },
|
|
72
72
|
React.createElement(TabListContext.Provider, { value: {
|
|
73
73
|
tabsWidth,
|
|
74
|
+
tablistRef,
|
|
74
75
|
} }, children)));
|
|
75
76
|
});
|
|
76
77
|
TabList.displayName = 'Tabs.TabList';
|
|
77
78
|
const Tab = React.forwardRef((props, forwardedRef) => {
|
|
78
79
|
const { className, children, value, label, ...rest } = props;
|
|
79
80
|
const { orientation, activeValue, setActiveValue, type, setStripeProperties, idPrefix, focusActivationMode, } = (0, index_js_1.useSafeContext)(TabsContext);
|
|
80
|
-
const { tabsWidth } = (0, index_js_1.useSafeContext)(TabListContext);
|
|
81
|
+
const { tabsWidth, tablistRef } = (0, index_js_1.useSafeContext)(TabListContext);
|
|
81
82
|
const tabRef = React.useRef();
|
|
82
83
|
const isActive = activeValue === value;
|
|
83
84
|
const isActiveRef = (0, index_js_1.useLatestRef)(isActive);
|
|
@@ -94,13 +95,27 @@ const Tab = React.forwardRef((props, forwardedRef) => {
|
|
|
94
95
|
(0, index_js_1.useLayoutEffect)(() => {
|
|
95
96
|
const updateStripe = () => {
|
|
96
97
|
const currentTabRect = tabRef.current?.getBoundingClientRect();
|
|
98
|
+
const tabslistRect = tablistRef.current?.getBoundingClientRect();
|
|
99
|
+
// Using getBoundingClientRect() to get decimal granularity.
|
|
100
|
+
// Not using offsetLeft/offsetTop because they round to the nearest integer.
|
|
101
|
+
// Even minor inaccuracies in the stripe position can cause unexpected scroll/scrollbar.
|
|
102
|
+
// See: https://github.com/iTwin/iTwinUI/issues/1870
|
|
103
|
+
const tabsStripePosition = currentTabRect != null && tabslistRect != null
|
|
104
|
+
? {
|
|
105
|
+
horizontal: currentTabRect.x - tabslistRect.x,
|
|
106
|
+
vertical: currentTabRect.y - tabslistRect.y,
|
|
107
|
+
}
|
|
108
|
+
: {
|
|
109
|
+
horizontal: 0,
|
|
110
|
+
vertical: 0,
|
|
111
|
+
};
|
|
97
112
|
setStripeProperties({
|
|
98
113
|
'--iui-tabs-stripe-size': orientation === 'horizontal'
|
|
99
114
|
? `${currentTabRect?.width}px`
|
|
100
115
|
: `${currentTabRect?.height}px`,
|
|
101
116
|
'--iui-tabs-stripe-position': orientation === 'horizontal'
|
|
102
|
-
? `${
|
|
103
|
-
: `${
|
|
117
|
+
? `${tabsStripePosition.horizontal}px`
|
|
118
|
+
: `${tabsStripePosition.vertical}px`,
|
|
104
119
|
});
|
|
105
120
|
};
|
|
106
121
|
if (type !== 'default' && isActive) {
|
|
@@ -112,6 +127,7 @@ const Tab = React.forwardRef((props, forwardedRef) => {
|
|
|
112
127
|
isActive,
|
|
113
128
|
tabsWidth,
|
|
114
129
|
setStripeProperties,
|
|
130
|
+
tablistRef,
|
|
115
131
|
]);
|
|
116
132
|
const onKeyDown = (event) => {
|
|
117
133
|
if (event.altKey) {
|
package/cjs/core/Tile/Tile.d.ts
CHANGED
|
@@ -255,7 +255,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
|
|
|
255
255
|
labelProps?: Omit<Omit<Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
256
256
|
ref?: ((instance: HTMLDivElement | null) => void) | React.RefObject<HTMLDivElement> | null | undefined;
|
|
257
257
|
}, "as" | "children" | "content" | "portal" | keyof {
|
|
258
|
-
placement?: import("@floating-ui/
|
|
258
|
+
placement?: import("@floating-ui/core").Placement | undefined;
|
|
259
259
|
visible?: boolean | undefined;
|
|
260
260
|
onVisibleChange?: ((visible: boolean) => void) | undefined;
|
|
261
261
|
autoUpdateOptions?: {
|
|
@@ -284,7 +284,7 @@ export declare const Tile: PolymorphicForwardRefComponent<"div", TileLegacyProps
|
|
|
284
284
|
content: React.ReactNode;
|
|
285
285
|
children?: React.ReactNode;
|
|
286
286
|
} & import("../utils/index.js").PortalProps & {
|
|
287
|
-
placement?: import("@floating-ui/
|
|
287
|
+
placement?: import("@floating-ui/core").Placement | undefined;
|
|
288
288
|
visible?: boolean | undefined;
|
|
289
289
|
onVisibleChange?: ((visible: boolean) => void) | undefined;
|
|
290
290
|
autoUpdateOptions?: {
|
|
@@ -17,9 +17,11 @@ type ToggleSwitchProps = {
|
|
|
17
17
|
*/
|
|
18
18
|
size?: 'default';
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Custom icon inside the toggle switch. Shown only when toggle is checked and size is not small.
|
|
21
|
+
*
|
|
22
|
+
* Will override the default checkmark icon.
|
|
21
23
|
*/
|
|
22
|
-
icon?: JSX.Element;
|
|
24
|
+
icon?: JSX.Element | null;
|
|
23
25
|
} | {
|
|
24
26
|
size: 'small';
|
|
25
27
|
icon?: never;
|
|
@@ -53,21 +53,15 @@ const index_js_1 = require("../utils/index.js");
|
|
|
53
53
|
* <ToggleSwitch label='With icon toggle' icon={<svg viewBox='0 0 16 16'><path d='M1 1v14h14V1H1zm13 1.7v10.6L8.7 8 14 2.7zM8 7.3L2.7 2h10.6L8 7.3zm-.7.7L2 13.3V2.7L7.3 8zm.7.7l5.3 5.3H2.7L8 8.7z' /></svg>} />
|
|
54
54
|
*/
|
|
55
55
|
exports.ToggleSwitch = React.forwardRef((props, ref) => {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
props = { ...props };
|
|
60
|
-
delete props.icon;
|
|
61
|
-
}
|
|
62
|
-
const { disabled = false, labelPosition = 'right', label, className, style, size = 'default', ...rest } = props;
|
|
63
|
-
const inputElementRef = React.useRef(null);
|
|
64
|
-
const refs = (0, index_js_1.useMergedRefs)(inputElementRef, ref);
|
|
56
|
+
const { disabled = false, labelPosition = 'right', label, className, style, size = 'default', icon: iconProp, ...rest } = props;
|
|
57
|
+
// Disallow custom icon for small size, but keep the default checkmark when prop is not passed.
|
|
58
|
+
const shouldShowIcon = iconProp === undefined || (iconProp !== null && size !== 'small');
|
|
65
59
|
return (React.createElement(index_js_1.Box, { as: label ? 'label' : 'div', className: (0, classnames_1.default)('iui-toggle-switch-wrapper', {
|
|
66
60
|
'iui-disabled': disabled,
|
|
67
61
|
'iui-label-on-right': label && labelPosition === 'right',
|
|
68
62
|
'iui-label-on-left': label && labelPosition === 'left',
|
|
69
63
|
}, className), "data-iui-size": size, style: style },
|
|
70
|
-
React.createElement(index_js_1.Box, { as: 'input', className: 'iui-toggle-switch', type: 'checkbox', role: 'switch', disabled: disabled, ref:
|
|
71
|
-
|
|
64
|
+
React.createElement(index_js_1.Box, { as: 'input', className: 'iui-toggle-switch', type: 'checkbox', role: 'switch', disabled: disabled, ref: ref, ...rest }),
|
|
65
|
+
shouldShowIcon && (React.createElement(index_js_1.Box, { as: 'span', className: 'iui-toggle-switch-icon', "aria-hidden": true }, iconProp || React.createElement(index_js_1.SvgCheckmark, null))),
|
|
72
66
|
label && (React.createElement(index_js_1.Box, { as: 'span', className: 'iui-toggle-switch-label' }, label))));
|
|
73
67
|
});
|