@itwin/itwinui-react 1.32.0-dev.0 → 1.32.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 +16 -0
- package/cjs/core/Checkbox/Checkbox.d.ts +13 -0
- package/cjs/core/Checkbox/Checkbox.js +15 -22
- package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
- package/cjs/core/ComboBox/ComboBox.d.ts +11 -0
- package/cjs/core/ComboBox/ComboBox.js +52 -19
- package/cjs/core/ExpandableBlock/ExpandableBlock.d.ts +6 -0
- package/cjs/core/ExpandableBlock/ExpandableBlock.js +3 -2
- package/cjs/core/Menu/Menu.js +3 -3
- package/cjs/core/Radio/Radio.d.ts +13 -0
- package/cjs/core/Radio/Radio.js +7 -8
- package/cjs/core/Tree/Tree.d.ts +123 -0
- package/cjs/core/Tree/Tree.js +177 -0
- package/cjs/core/Tree/TreeContext.d.ts +25 -0
- package/cjs/core/Tree/TreeContext.js +20 -0
- package/cjs/core/Tree/TreeNode.d.ts +87 -0
- package/cjs/core/Tree/TreeNode.js +169 -0
- package/cjs/core/Tree/TreeNodeExpander.d.ts +8 -0
- package/cjs/core/Tree/TreeNodeExpander.js +46 -0
- package/cjs/core/Tree/index.d.ts +6 -0
- package/cjs/core/Tree/index.js +13 -0
- package/cjs/core/index.d.ts +2 -0
- package/cjs/core/index.js +5 -1
- package/cjs/core/utils/functions/focusable.js +6 -2
- package/esm/core/Checkbox/Checkbox.d.ts +13 -0
- package/esm/core/Checkbox/Checkbox.js +15 -22
- package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
- package/esm/core/ComboBox/ComboBox.d.ts +11 -0
- package/esm/core/ComboBox/ComboBox.js +53 -20
- package/esm/core/ExpandableBlock/ExpandableBlock.d.ts +6 -0
- package/esm/core/ExpandableBlock/ExpandableBlock.js +3 -2
- package/esm/core/Menu/Menu.js +3 -3
- package/esm/core/Radio/Radio.d.ts +13 -0
- package/esm/core/Radio/Radio.js +7 -8
- package/esm/core/Tree/Tree.d.ts +123 -0
- package/esm/core/Tree/Tree.js +170 -0
- package/esm/core/Tree/TreeContext.d.ts +25 -0
- package/esm/core/Tree/TreeContext.js +13 -0
- package/esm/core/Tree/TreeNode.d.ts +87 -0
- package/esm/core/Tree/TreeNode.js +162 -0
- package/esm/core/Tree/TreeNodeExpander.d.ts +8 -0
- package/esm/core/Tree/TreeNodeExpander.js +39 -0
- package/esm/core/Tree/index.d.ts +6 -0
- package/esm/core/Tree/index.js +7 -0
- package/esm/core/index.d.ts +2 -0
- package/esm/core/index.js +1 -0
- package/esm/core/utils/functions/focusable.js +6 -2
- package/package.json +2 -2
|
@@ -32,6 +32,7 @@ import '@itwin/itwinui-css/css/inputs.css';
|
|
|
32
32
|
/**
|
|
33
33
|
* Simple input checkbox
|
|
34
34
|
* @example
|
|
35
|
+
* <Checkbox />
|
|
35
36
|
* <Checkbox label='Basic Checkbox' />
|
|
36
37
|
* <Checkbox label='Disabled Checkbox' disabled />
|
|
37
38
|
* <Checkbox label='Checked' checked />
|
|
@@ -41,8 +42,8 @@ import '@itwin/itwinui-css/css/inputs.css';
|
|
|
41
42
|
* <Checkbox label='Visibility Checkbox' variant='eyeball' />
|
|
42
43
|
*/
|
|
43
44
|
export var Checkbox = React.forwardRef(function (props, ref) {
|
|
44
|
-
var _a;
|
|
45
|
-
var className = props.className,
|
|
45
|
+
var _a, _b;
|
|
46
|
+
var className = props.className, _c = props.disabled, disabled = _c === void 0 ? false : _c, _d = props.indeterminate, indeterminate = _d === void 0 ? false : _d, label = props.label, status = props.status, _e = props.variant, variant = _e === void 0 ? 'default' : _e, setFocus = props.setFocus, _f = props.isLoading, isLoading = _f === void 0 ? false : _f, style = props.style, checkmarkClassName = props.checkmarkClassName, checkmarkStyle = props.checkmarkStyle, rest = __rest(props, ["className", "disabled", "indeterminate", "label", "status", "variant", "setFocus", "isLoading", "style", "checkmarkClassName", "checkmarkStyle"]);
|
|
46
47
|
useTheme();
|
|
47
48
|
var inputElementRef = React.useRef(null);
|
|
48
49
|
var refs = useMergedRefs(inputElementRef, ref);
|
|
@@ -59,27 +60,19 @@ export var Checkbox = React.forwardRef(function (props, ref) {
|
|
|
59
60
|
: inputElementRef.current.checked;
|
|
60
61
|
}
|
|
61
62
|
});
|
|
62
|
-
var
|
|
63
|
-
React.createElement("
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
React.createElement(
|
|
68
|
-
|
|
69
|
-
React.createElement("path", { d: 'm8 0a1 1 0 0 0 -1 1v2.07135a8.91637 8.91637 0 0 0 -7 4.92865 8.91637 8.91637 0 0 0 7 4.92865v2.07135a1 1 0 0 0 2 0v-14a1 1 0 0 0 -1-1zm-1.5 4.9a1.55426 1.55426 0 0 1 .5.087v2.81451a1.40746 1.40746 0 0 1 -.5.09849 1.538 1.538 0 0 1 -1.5-1.5 1.53794 1.53794 0 0 1 1.5-1.5zm-2.3 5.4a6.97279 6.97279 0 0 1 -2.5-2.3 6.89429 6.89429 0 0 1 2.4-2.4c.1 0 .1-.1.2-.1a3.194 3.194 0 0 0 -.3 1.4 4.0047 4.0047 0 0 0 3 3.857v.65289a6.37491 6.37491 0 0 1 -2.8-1.10989z' })),
|
|
70
|
-
React.createElement("path", { className: 'iui-uncheck', d: 'm1.70671 12.879 11.17218-11.17219 1.4142 1.4142-11.17218 11.17218zm.99329-1.679 1.1-1.1a5.06317 5.06317 0 0 1 -2-2.1 7.48268 7.48268 0 0 1 6.2-3.5 4.86877 4.86877 0 0 1 1.2.1l1.3-1.3a10.07431 10.07431 0 0 0 -2.5-.3 8.84129 8.84129 0 0 0 -8 5 8.42455 8.42455 0 0 0 2.7 3.2zm10.7-6.4-1.1 1.1a7.08625 7.08625 0 0 1 2 2.1 7.50323 7.50323 0 0 1 -6.2 3.5 8.31665 8.31665 0 0 1 -1.3-.2l-1.3 1.3a8.909 8.909 0 0 0 6.4-.5 9.04344 9.04344 0 0 0 4.1-4.1 9.168 9.168 0 0 0 -2.6-3.2z' })));
|
|
71
|
-
return (React.createElement("label", { className: cx('iui-checkbox', (_a = {
|
|
63
|
+
var checkbox = (React.createElement(React.Fragment, null,
|
|
64
|
+
React.createElement("input", __assign({ className: cx('iui-checkbox', {
|
|
65
|
+
'iui-checkbox-visibility': variant === 'eyeball',
|
|
66
|
+
'iui-loading': isLoading,
|
|
67
|
+
}, className && (_a = {}, _a[className] = !label, _a), checkmarkClassName), style: __assign(__assign({}, (!label && style)), checkmarkStyle), disabled: disabled || isLoading, type: 'checkbox', ref: refs }, rest)),
|
|
68
|
+
isLoading && React.createElement(ProgressRadial, { size: 'x-small', indeterminate: true })));
|
|
69
|
+
return !label ? (checkbox) : (React.createElement("label", { className: cx('iui-checkbox-wrapper', (_b = {
|
|
72
70
|
'iui-disabled': disabled
|
|
73
71
|
},
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
React.createElement("
|
|
79
|
-
React.createElement("span", { className: cx('iui-checkbox-checkmark', checkmarkClassName), style: checkmarkStyle },
|
|
80
|
-
isLoading && React.createElement(ProgressRadial, { indeterminate: true }),
|
|
81
|
-
!isLoading &&
|
|
82
|
-
(variant === 'default' ? defaultCheckbox : visibilityCheckbox)),
|
|
83
|
-
label && React.createElement("span", { className: 'iui-label' }, label)));
|
|
72
|
+
_b["iui-" + status] = !!status,
|
|
73
|
+
_b['iui-loading'] = isLoading,
|
|
74
|
+
_b), className), style: style },
|
|
75
|
+
checkbox,
|
|
76
|
+
label && React.createElement("span", { className: 'iui-checkbox-label' }, label)));
|
|
84
77
|
});
|
|
85
78
|
export default Checkbox;
|
|
@@ -17,5 +17,5 @@ export declare type ColorSwatchProps = {
|
|
|
17
17
|
* <ColorSwatch color='#23450b' onClick={onClick}/>
|
|
18
18
|
* <ColorSwatch color={{ r: 255, g: 255, b: 0 }} onClick={onClick}/>
|
|
19
19
|
*/
|
|
20
|
-
export declare const ColorSwatch: React.ForwardRefExoticComponent<Pick<ColorSwatchProps, "dir" | "slot" | "style" | "title" | "id" | "role" | "children" | "className" | "accessKey" | "draggable" | "hidden" | "lang" | "translate" | "prefix" | "contentEditable" | "inputMode" | "tabIndex" | "onFocus" | "color" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-
|
|
20
|
+
export declare const ColorSwatch: React.ForwardRefExoticComponent<Pick<ColorSwatchProps, "dir" | "slot" | "style" | "title" | "id" | "aria-disabled" | "role" | "children" | "className" | "accessKey" | "draggable" | "hidden" | "lang" | "translate" | "prefix" | "contentEditable" | "inputMode" | "tabIndex" | "onFocus" | "color" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-details" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerEnterCapture" | "onPointerLeave" | "onPointerLeaveCapture" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "contextMenu" | "placeholder" | "spellCheck" | "radioGroup" | "about" | "datatype" | "inlist" | "property" | "resource" | "typeof" | "vocab" | "autoCapitalize" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "is" | "isActive"> & React.RefAttributes<HTMLDivElement>>;
|
|
21
21
|
export default ColorSwatch;
|
|
@@ -33,6 +33,17 @@ export declare type ComboBoxProps<T> = {
|
|
|
33
33
|
* @default 'No options found'
|
|
34
34
|
*/
|
|
35
35
|
emptyStateMessage?: string;
|
|
36
|
+
/**
|
|
37
|
+
* A custom item renderer can be specified to control the rendering.
|
|
38
|
+
* This function should ideally return a customized version of `MenuItem`,
|
|
39
|
+
* otherwise you will need to make sure to provide styling for the `isFocused` state.
|
|
40
|
+
*/
|
|
41
|
+
itemRenderer?: (option: SelectOption<T>, states: {
|
|
42
|
+
isSelected: boolean;
|
|
43
|
+
isFocused: boolean;
|
|
44
|
+
id: string;
|
|
45
|
+
index: number;
|
|
46
|
+
}) => JSX.Element;
|
|
36
47
|
} & Pick<InputContainerProps, 'status'> & Omit<CommonProps, 'title'>;
|
|
37
48
|
/**
|
|
38
49
|
* ComboBox component that allows typing a value to filter the options in dropdown list.
|
|
@@ -29,7 +29,7 @@ import cx from 'classnames';
|
|
|
29
29
|
import { Input } from '../Input';
|
|
30
30
|
import { Menu, MenuExtraContent, MenuItem } from '../Menu';
|
|
31
31
|
import { Text } from '../Typography';
|
|
32
|
-
import { InputContainer, useTheme, Popover, getFocusableElements, getRandomValue, } from '../utils';
|
|
32
|
+
import { InputContainer, useTheme, Popover, getFocusableElements, getRandomValue, mergeRefs, } from '../utils';
|
|
33
33
|
import SvgCaretDownSmall from '@itwin/itwinui-icons-react/cjs/icons/CaretDownSmall';
|
|
34
34
|
import 'tippy.js/animations/shift-away.css';
|
|
35
35
|
/**
|
|
@@ -46,7 +46,7 @@ import 'tippy.js/animations/shift-away.css';
|
|
|
46
46
|
* />
|
|
47
47
|
*/
|
|
48
48
|
export var ComboBox = function (props) {
|
|
49
|
-
var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "emptyStateMessage"]);
|
|
49
|
+
var options = props.options, value = props.value, onChange = props.onChange, filterFunction = props.filterFunction, className = props.className, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _a = props.emptyStateMessage, emptyStateMessage = _a === void 0 ? 'No options found' : _a, itemRenderer = props.itemRenderer, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "className", "inputProps", "dropdownMenuProps", "emptyStateMessage", "itemRenderer"]);
|
|
50
50
|
// Generate a stateful random id if not specified
|
|
51
51
|
var id = React.useState(function () {
|
|
52
52
|
var _a, _b;
|
|
@@ -61,16 +61,31 @@ export var ComboBox = function (props) {
|
|
|
61
61
|
return value === options[index].value;
|
|
62
62
|
});
|
|
63
63
|
}, [options, id]);
|
|
64
|
+
var userOnChange = React.useRef(onChange);
|
|
64
65
|
var memoizedItems = React.useMemo(function () {
|
|
65
|
-
return options.map(function (
|
|
66
|
-
var label =
|
|
67
|
-
|
|
66
|
+
return options.map(function (option, index) {
|
|
67
|
+
var label = option.label, value = option.value, rest = __rest(option, ["label", "value"]);
|
|
68
|
+
var additionalProps = {
|
|
69
|
+
value: value,
|
|
70
|
+
role: 'option',
|
|
71
|
+
onClick: function () {
|
|
72
|
+
var _a;
|
|
68
73
|
setSelectedValue(value);
|
|
69
|
-
|
|
74
|
+
(_a = userOnChange.current) === null || _a === void 0 ? void 0 : _a.call(userOnChange, value);
|
|
70
75
|
setIsOpen(false);
|
|
71
|
-
}
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
if (itemRenderer) {
|
|
79
|
+
return React.cloneElement(itemRenderer(option, {
|
|
80
|
+
id: getOptionId(index),
|
|
81
|
+
index: index,
|
|
82
|
+
isSelected: false,
|
|
83
|
+
isFocused: false,
|
|
84
|
+
}), additionalProps);
|
|
85
|
+
}
|
|
86
|
+
return (React.createElement(MenuItem, __assign({ id: getOptionId(index), key: getOptionId(index) }, additionalProps, rest), label));
|
|
72
87
|
});
|
|
73
|
-
}, [options, getOptionId,
|
|
88
|
+
}, [options, getOptionId, itemRenderer]);
|
|
74
89
|
var inputRef = React.useRef(null);
|
|
75
90
|
var menuRef = React.useRef(null);
|
|
76
91
|
var toggleButtonRef = React.useRef(null);
|
|
@@ -149,6 +164,7 @@ export var ComboBox = function (props) {
|
|
|
149
164
|
});
|
|
150
165
|
}, [inputValue, options, selectedValue, isOpen, filterFunction]);
|
|
151
166
|
var onKeyDown = React.useCallback(function (event) {
|
|
167
|
+
var _a;
|
|
152
168
|
var focusableOptions = getFocusableElements(menuRef.current);
|
|
153
169
|
var focusedIndexInFilteredList = focusableOptions.findIndex(function (_a) {
|
|
154
170
|
var _b;
|
|
@@ -182,7 +198,7 @@ export var ComboBox = function (props) {
|
|
|
182
198
|
case 'Enter':
|
|
183
199
|
if (isOpen) {
|
|
184
200
|
setSelectedValue(options[focusedIndex].value);
|
|
185
|
-
|
|
201
|
+
(_a = userOnChange.current) === null || _a === void 0 ? void 0 : _a.call(userOnChange, options[focusedIndex].value);
|
|
186
202
|
}
|
|
187
203
|
setIsOpen(function (open) { return !open; });
|
|
188
204
|
event.preventDefault();
|
|
@@ -202,26 +218,41 @@ export var ComboBox = function (props) {
|
|
|
202
218
|
}
|
|
203
219
|
break;
|
|
204
220
|
}
|
|
205
|
-
}, [focusedIndex, isOpen, options, getOptionId
|
|
221
|
+
}, [focusedIndex, isOpen, options, getOptionId]);
|
|
206
222
|
var menuItems = React.useMemo(function () {
|
|
207
223
|
if (filteredOptions.length === 0) {
|
|
208
|
-
return
|
|
209
|
-
React.createElement(
|
|
224
|
+
return [
|
|
225
|
+
React.createElement(MenuExtraContent, { key: 0 },
|
|
226
|
+
React.createElement(Text, { isMuted: true }, emptyStateMessage)),
|
|
227
|
+
];
|
|
210
228
|
}
|
|
211
229
|
return filteredOptions.map(function (option) {
|
|
230
|
+
var _a;
|
|
212
231
|
var index = options.findIndex(function (_a) {
|
|
213
232
|
var value = _a.value;
|
|
214
233
|
return option.value === value;
|
|
215
234
|
});
|
|
216
235
|
if (index < 0) {
|
|
217
|
-
return;
|
|
236
|
+
return React.createElement(React.Fragment, null);
|
|
218
237
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
238
|
+
var id = getOptionId(index);
|
|
239
|
+
var isSelected = selectedValue === option.value;
|
|
240
|
+
var isFocused = focusedIndex === index;
|
|
241
|
+
var focusScrollRef = function (el) {
|
|
242
|
+
return isFocused && (el === null || el === void 0 ? void 0 : el.scrollIntoView({ block: 'nearest' }));
|
|
243
|
+
};
|
|
244
|
+
if (isSelected || isFocused) {
|
|
245
|
+
var item = (_a = itemRenderer === null || itemRenderer === void 0 ? void 0 : itemRenderer(option, { index: index, id: id, isSelected: isSelected, isFocused: isFocused })) !== null && _a !== void 0 ? _a : React.cloneElement(memoizedItems[index], { isSelected: isSelected });
|
|
246
|
+
return React.cloneElement(item, {
|
|
247
|
+
className: cx({ 'iui-focused': isFocused }, item.props.className),
|
|
248
|
+
ref: mergeRefs(focusScrollRef, item.props.ref),
|
|
249
|
+
value: option.value,
|
|
250
|
+
role: 'option',
|
|
251
|
+
onClick: function () {
|
|
252
|
+
var _a;
|
|
253
|
+
setSelectedValue(option.value);
|
|
254
|
+
(_a = userOnChange.current) === null || _a === void 0 ? void 0 : _a.call(userOnChange, option.value);
|
|
255
|
+
setIsOpen(false);
|
|
225
256
|
},
|
|
226
257
|
});
|
|
227
258
|
}
|
|
@@ -231,8 +262,10 @@ export var ComboBox = function (props) {
|
|
|
231
262
|
filteredOptions,
|
|
232
263
|
emptyStateMessage,
|
|
233
264
|
options,
|
|
234
|
-
|
|
265
|
+
getOptionId,
|
|
235
266
|
selectedValue,
|
|
267
|
+
focusedIndex,
|
|
268
|
+
itemRenderer,
|
|
236
269
|
memoizedItems,
|
|
237
270
|
]);
|
|
238
271
|
return (React.createElement(InputContainer, __assign({ className: className, isIconInline: true }, rest, { id: id }),
|
|
@@ -38,6 +38,12 @@ export declare type ExpandableBlockProps = {
|
|
|
38
38
|
* @default 'default'
|
|
39
39
|
*/
|
|
40
40
|
size?: 'default' | 'small';
|
|
41
|
+
/**
|
|
42
|
+
* Style of the ExpandableBlock.
|
|
43
|
+
* Use 'borderless' to hide outline.
|
|
44
|
+
* @default 'default'
|
|
45
|
+
*/
|
|
46
|
+
styleType?: 'default' | 'borderless';
|
|
41
47
|
} & Omit<CommonProps, 'title'>;
|
|
42
48
|
/**
|
|
43
49
|
* Container that allows content to be hidden behind a brief title and a caption.
|
|
@@ -40,10 +40,10 @@ import '@itwin/itwinui-css/css/expandable-block.css';
|
|
|
40
40
|
*/
|
|
41
41
|
export var ExpandableBlock = function (props) {
|
|
42
42
|
var _a;
|
|
43
|
-
var caption = props.caption, children = props.children, className = props.className, title = props.title, onToggle = props.onToggle, style = props.style, _b = props.isExpanded, isExpanded = _b === void 0 ? false : _b, endIcon = props.endIcon, status = props.status, _c = props.size, size = _c === void 0 ? 'default' : _c, rest = __rest(props, ["caption", "children", "className", "title", "onToggle", "style", "isExpanded", "endIcon", "status", "size"]);
|
|
43
|
+
var caption = props.caption, children = props.children, className = props.className, title = props.title, onToggle = props.onToggle, style = props.style, _b = props.isExpanded, isExpanded = _b === void 0 ? false : _b, endIcon = props.endIcon, status = props.status, _c = props.size, size = _c === void 0 ? 'default' : _c, _d = props.styleType, styleType = _d === void 0 ? 'default' : _d, rest = __rest(props, ["caption", "children", "className", "title", "onToggle", "style", "isExpanded", "endIcon", "status", "size", "styleType"]);
|
|
44
44
|
useTheme();
|
|
45
45
|
var icon = endIcon !== null && endIcon !== void 0 ? endIcon : (status && StatusIconMap[status]());
|
|
46
|
-
var
|
|
46
|
+
var _e = React.useState(isExpanded), expanded = _e[0], setExpanded = _e[1];
|
|
47
47
|
React.useEffect(function () {
|
|
48
48
|
setExpanded(isExpanded);
|
|
49
49
|
}, [isExpanded]);
|
|
@@ -62,6 +62,7 @@ export var ExpandableBlock = function (props) {
|
|
|
62
62
|
'iui-with-caption': !!caption,
|
|
63
63
|
'iui-expanded': expanded,
|
|
64
64
|
'iui-small': size === 'small',
|
|
65
|
+
'iui-borderless': styleType === 'borderless',
|
|
65
66
|
}, className), style: style }, rest),
|
|
66
67
|
React.createElement("div", { "aria-expanded": expanded, className: 'iui-header', tabIndex: 0, onClick: handleToggle, onKeyDown: onKeyDown },
|
|
67
68
|
React.createElement(SvgChevronRight, { className: 'iui-icon', "aria-hidden": true }),
|
package/esm/core/Menu/Menu.js
CHANGED
|
@@ -37,6 +37,9 @@ export var Menu = React.forwardRef(function (props, ref) {
|
|
|
37
37
|
var _c = React.useState(), focusedIndex = _c[0], setFocusedIndex = _c[1];
|
|
38
38
|
var menuRef = React.useRef(null);
|
|
39
39
|
var refs = useMergedRefs(menuRef, ref);
|
|
40
|
+
React.useEffect(function () {
|
|
41
|
+
setFocusedIndex(null);
|
|
42
|
+
}, [children]);
|
|
40
43
|
React.useEffect(function () {
|
|
41
44
|
var _a;
|
|
42
45
|
var items = getFocusableElements(menuRef.current);
|
|
@@ -49,9 +52,6 @@ export var Menu = React.forwardRef(function (props, ref) {
|
|
|
49
52
|
setFocusedIndex(selectedIndex > -1 ? selectedIndex : 0);
|
|
50
53
|
}
|
|
51
54
|
}, [setFocus, focusedIndex]);
|
|
52
|
-
React.useEffect(function () {
|
|
53
|
-
setFocusedIndex(null);
|
|
54
|
-
}, [children]);
|
|
55
55
|
var onKeyDown = function (event) {
|
|
56
56
|
var items = getFocusableElements(menuRef.current);
|
|
57
57
|
if (!(items === null || items === void 0 ? void 0 : items.length)) {
|
|
@@ -11,10 +11,16 @@ export declare type RadioProps = {
|
|
|
11
11
|
status?: 'positive' | 'warning' | 'negative';
|
|
12
12
|
/**
|
|
13
13
|
* Custom CSS class name for the checkmark element.
|
|
14
|
+
*
|
|
15
|
+
* @deprecated As of 1.32.0, this is applied on the actual radio `<input>` element.
|
|
16
|
+
* The checkmark has been moved into a pseudo-element.
|
|
14
17
|
*/
|
|
15
18
|
checkmarkClassName?: string;
|
|
16
19
|
/**
|
|
17
20
|
* Custom CSS Style for the checkmark element.
|
|
21
|
+
*
|
|
22
|
+
* @deprecated As of 1.32.0, this is applied on the actual radio `<input>` element.
|
|
23
|
+
* The checkmark has been moved into a pseudo-element.
|
|
18
24
|
*/
|
|
19
25
|
checkmarkStyle?: React.CSSProperties;
|
|
20
26
|
/**
|
|
@@ -26,6 +32,7 @@ export declare type RadioProps = {
|
|
|
26
32
|
/**
|
|
27
33
|
* Basic radio input component
|
|
28
34
|
* @example
|
|
35
|
+
* <Radio />
|
|
29
36
|
* <Radio label='Radio' />
|
|
30
37
|
* <Radio disabled={true} label='Radio' />
|
|
31
38
|
* <Radio status='positive' label='Positive' />
|
|
@@ -43,10 +50,16 @@ export declare const Radio: React.ForwardRefExoticComponent<{
|
|
|
43
50
|
status?: "positive" | "warning" | "negative" | undefined;
|
|
44
51
|
/**
|
|
45
52
|
* Custom CSS class name for the checkmark element.
|
|
53
|
+
*
|
|
54
|
+
* @deprecated As of 1.32.0, this is applied on the actual radio `<input>` element.
|
|
55
|
+
* The checkmark has been moved into a pseudo-element.
|
|
46
56
|
*/
|
|
47
57
|
checkmarkClassName?: string | undefined;
|
|
48
58
|
/**
|
|
49
59
|
* Custom CSS Style for the checkmark element.
|
|
60
|
+
*
|
|
61
|
+
* @deprecated As of 1.32.0, this is applied on the actual radio `<input>` element.
|
|
62
|
+
* The checkmark has been moved into a pseudo-element.
|
|
50
63
|
*/
|
|
51
64
|
checkmarkStyle?: React.CSSProperties | undefined;
|
|
52
65
|
/**
|
package/esm/core/Radio/Radio.js
CHANGED
|
@@ -31,6 +31,7 @@ import '@itwin/itwinui-css/css/inputs.css';
|
|
|
31
31
|
/**
|
|
32
32
|
* Basic radio input component
|
|
33
33
|
* @example
|
|
34
|
+
* <Radio />
|
|
34
35
|
* <Radio label='Radio' />
|
|
35
36
|
* <Radio disabled={true} label='Radio' />
|
|
36
37
|
* <Radio status='positive' label='Positive' />
|
|
@@ -38,8 +39,8 @@ import '@itwin/itwinui-css/css/inputs.css';
|
|
|
38
39
|
* <Radio status='negative' label='Negative' />
|
|
39
40
|
*/
|
|
40
41
|
export var Radio = React.forwardRef(function (props, ref) {
|
|
41
|
-
var _a;
|
|
42
|
-
var className = props.className,
|
|
42
|
+
var _a, _b;
|
|
43
|
+
var className = props.className, _c = props.disabled, disabled = _c === void 0 ? false : _c, label = props.label, status = props.status, style = props.style, checkmarkClassName = props.checkmarkClassName, checkmarkStyle = props.checkmarkStyle, _d = props.setFocus, setFocus = _d === void 0 ? false : _d, rest = __rest(props, ["className", "disabled", "label", "status", "style", "checkmarkClassName", "checkmarkStyle", "setFocus"]);
|
|
43
44
|
useTheme();
|
|
44
45
|
var inputElementRef = React.useRef(null);
|
|
45
46
|
var refs = useMergedRefs(inputElementRef, ref);
|
|
@@ -48,11 +49,9 @@ export var Radio = React.forwardRef(function (props, ref) {
|
|
|
48
49
|
inputElementRef.current.focus();
|
|
49
50
|
}
|
|
50
51
|
}, [setFocus]);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
React.createElement("circle", { cx: '8', cy: '8', r: '4' }))),
|
|
56
|
-
label && React.createElement("span", { className: 'iui-label' }, label)));
|
|
52
|
+
var radio = (React.createElement("input", __assign({ className: cx('iui-radio', className && (_a = {}, _a[className] = !label, _a), checkmarkClassName), style: __assign(__assign({}, (!label && style)), checkmarkStyle), disabled: disabled, type: 'radio', ref: refs }, rest)));
|
|
53
|
+
return !label ? (radio) : (React.createElement("label", { className: cx('iui-radio-wrapper', (_b = { 'iui-disabled': disabled }, _b["iui-" + status] = !!status, _b), className), style: style },
|
|
54
|
+
radio,
|
|
55
|
+
label && React.createElement("span", { className: 'iui-radio-label' }, label)));
|
|
57
56
|
});
|
|
58
57
|
export default Radio;
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { CommonProps } from '../utils';
|
|
3
|
+
import '@itwin/itwinui-css/css/tree.css';
|
|
4
|
+
export declare type NodeData<T> = {
|
|
5
|
+
/**
|
|
6
|
+
* Array of the child nodes contained in the node.
|
|
7
|
+
*/
|
|
8
|
+
subNodes?: Array<T>;
|
|
9
|
+
/**
|
|
10
|
+
* Unique id of the node.
|
|
11
|
+
*/
|
|
12
|
+
nodeId: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom type used to map type `T` to `NodeData`
|
|
15
|
+
*/
|
|
16
|
+
node: T;
|
|
17
|
+
/**
|
|
18
|
+
* Flag whether the node is expanded.
|
|
19
|
+
*/
|
|
20
|
+
isExpanded?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Flag whether the node is disabled.
|
|
23
|
+
*/
|
|
24
|
+
isDisabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Flag whether the node is selected.
|
|
27
|
+
*/
|
|
28
|
+
isSelected?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Flag whether the node has sub-nodes.
|
|
31
|
+
* Used to determine if node should be expandable.
|
|
32
|
+
*/
|
|
33
|
+
hasSubNodes: boolean;
|
|
34
|
+
};
|
|
35
|
+
export declare type NodeRenderProps<T> = Omit<NodeData<T>, 'subNodes'>;
|
|
36
|
+
export declare type TreeProps<T> = {
|
|
37
|
+
/**
|
|
38
|
+
* Render function that should return the node element.
|
|
39
|
+
* Recommended to use `TreeNode` component.
|
|
40
|
+
* Must be memoized.
|
|
41
|
+
* @example
|
|
42
|
+
* const nodeRenderer = React.useCallback(({ node, ...rest }: NodeRenderProps<DataType>) => (
|
|
43
|
+
* <TreeNode
|
|
44
|
+
* label={node.label}
|
|
45
|
+
* onNodeExpanded={onNodeExpanded}
|
|
46
|
+
* {...rest}
|
|
47
|
+
* />
|
|
48
|
+
* ), [onNodeExpanded])
|
|
49
|
+
*/
|
|
50
|
+
nodeRenderer: (props: NodeRenderProps<T>) => JSX.Element;
|
|
51
|
+
/**
|
|
52
|
+
* Array of custom data used for `TreeNodes` inside `Tree`.
|
|
53
|
+
*/
|
|
54
|
+
data: T[];
|
|
55
|
+
/**
|
|
56
|
+
* Function that maps your `data` entry to `NodeData` that has all info about the node state.
|
|
57
|
+
* It will be used to render a tree node in `nodeRenderer`.
|
|
58
|
+
* Must be memoized.
|
|
59
|
+
* @example
|
|
60
|
+
* const getNode = React.useCallback((node: DemoData): NodeData<DemoData> => {
|
|
61
|
+
* return {
|
|
62
|
+
* subNodes: node.subItems,
|
|
63
|
+
* nodeId: node.id,
|
|
64
|
+
* node,
|
|
65
|
+
* isExpanded: expandedNodes[node.id],
|
|
66
|
+
* hasSubNodes: node.subItems.length > 0,
|
|
67
|
+
* };
|
|
68
|
+
* }, [expandedNodes]);
|
|
69
|
+
*/
|
|
70
|
+
getNode: (node: T) => NodeData<T>;
|
|
71
|
+
} & Omit<CommonProps, 'title'>;
|
|
72
|
+
/**
|
|
73
|
+
* Tree component used to display a hierarchical structure of `TreeNodes`.
|
|
74
|
+
* User should control state of expanded, selected and disabled nodes using `getNode` prop.
|
|
75
|
+
* @example
|
|
76
|
+
type DemoData = {
|
|
77
|
+
id: string;
|
|
78
|
+
label: string;
|
|
79
|
+
subItems: DemoData[];
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const data: Array<DemoData> = [
|
|
83
|
+
{
|
|
84
|
+
id: 'Node-1',
|
|
85
|
+
label: 'Facility 1',
|
|
86
|
+
subItems: [{ id: 'Node-1-1', label: 'Unit 1', subItems: [] }],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: 'Node-2',
|
|
90
|
+
label: 'Facility 2',
|
|
91
|
+
subItems: [{ id: 'Node-2-1', label: 'Unit 2', subItems: [] }],
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
|
|
95
|
+
const [expandedNodes, setExpandedNodes] = React.useState<Record<string, boolean>>({});
|
|
96
|
+
const onNodeExpanded = React.useCallback((nodeId: string, isExpanded: boolean) => {
|
|
97
|
+
setExpandedNodes((oldExpanded) => ({ ...oldExpanded, [nodeId]: isExpanded }));
|
|
98
|
+
}, []);
|
|
99
|
+
|
|
100
|
+
const getNode = React.useCallback((node: DemoData): NodeData<DemoData> => {
|
|
101
|
+
return {
|
|
102
|
+
subNodes: node.subItems,
|
|
103
|
+
nodeId: node.id,
|
|
104
|
+
node,
|
|
105
|
+
isExpanded: expandedNodes[node.id],
|
|
106
|
+
hasSubNodes: node.subItems.length > 0,
|
|
107
|
+
};
|
|
108
|
+
}, [expandedNodes]);
|
|
109
|
+
|
|
110
|
+
<Tree<DemoData>
|
|
111
|
+
data={data}
|
|
112
|
+
getNode={getNode}
|
|
113
|
+
nodeRenderer={React.useCallback(({ node, ...rest }) => (
|
|
114
|
+
<TreeNode
|
|
115
|
+
label={node.label}
|
|
116
|
+
onNodeExpanded={onNodeExpanded}
|
|
117
|
+
{...rest}
|
|
118
|
+
/>
|
|
119
|
+
), [onNodeExpanded])}
|
|
120
|
+
/>
|
|
121
|
+
*/
|
|
122
|
+
export declare const Tree: <T>(props: TreeProps<T>) => JSX.Element;
|
|
123
|
+
export default Tree;
|