@itwin/itwinui-react 2.0.2 → 2.1.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 +19 -0
- package/cjs/core/ComboBox/ComboBox.d.ts +25 -8
- package/cjs/core/ComboBox/ComboBox.js +141 -44
- package/cjs/core/ComboBox/ComboBoxDropdown.d.ts +1 -1
- package/cjs/core/ComboBox/ComboBoxDropdown.js +2 -2
- package/cjs/core/ComboBox/ComboBoxEndIcon.js +1 -1
- package/cjs/core/ComboBox/ComboBoxInput.d.ts +2 -0
- package/cjs/core/ComboBox/ComboBoxInput.js +40 -23
- package/cjs/core/ComboBox/ComboBoxMenu.js +9 -8
- package/cjs/core/ComboBox/ComboBoxMenuItem.js +1 -1
- package/cjs/core/ComboBox/ComboBoxMultipleContainer.d.ts +4 -0
- package/cjs/core/ComboBox/ComboBoxMultipleContainer.js +17 -0
- package/cjs/core/ComboBox/helpers.d.ts +20 -5
- package/cjs/core/ComboBox/helpers.js +24 -6
- package/cjs/core/Select/Select.js +2 -7
- package/cjs/core/Select/SelectTagContainer.d.ts +16 -0
- package/cjs/core/Select/SelectTagContainer.js +27 -0
- package/cjs/core/Table/Table.js +4 -2
- package/cjs/core/Table/actionHandlers/index.d.ts +1 -1
- package/cjs/core/Table/actionHandlers/index.js +2 -2
- package/cjs/core/Table/actionHandlers/selectHandler.d.ts +2 -2
- package/cjs/core/Table/actionHandlers/selectHandler.js +20 -6
- package/cjs/core/ThemeProvider/ThemeProvider.d.ts +25 -6
- package/cjs/core/ThemeProvider/ThemeProvider.js +29 -12
- package/cjs/core/utils/components/Popover.d.ts +1 -1
- package/cjs/core/utils/hooks/index.d.ts +1 -0
- package/cjs/core/utils/hooks/index.js +1 -0
- package/cjs/core/utils/hooks/useIsThemeAlreadySet.d.ts +7 -0
- package/cjs/core/utils/hooks/useIsThemeAlreadySet.js +34 -0
- package/cjs/core/utils/hooks/useTheme.js +4 -9
- package/esm/core/ComboBox/ComboBox.d.ts +25 -8
- package/esm/core/ComboBox/ComboBox.js +141 -44
- package/esm/core/ComboBox/ComboBoxDropdown.d.ts +1 -1
- package/esm/core/ComboBox/ComboBoxDropdown.js +2 -2
- package/esm/core/ComboBox/ComboBoxEndIcon.js +1 -1
- package/esm/core/ComboBox/ComboBoxInput.d.ts +2 -0
- package/esm/core/ComboBox/ComboBoxInput.js +41 -24
- package/esm/core/ComboBox/ComboBoxMenu.js +9 -8
- package/esm/core/ComboBox/ComboBoxMenuItem.js +1 -1
- package/esm/core/ComboBox/ComboBoxMultipleContainer.d.ts +4 -0
- package/esm/core/ComboBox/ComboBoxMultipleContainer.js +11 -0
- package/esm/core/ComboBox/helpers.d.ts +20 -5
- package/esm/core/ComboBox/helpers.js +24 -6
- package/esm/core/Select/Select.js +3 -8
- package/esm/core/Select/SelectTagContainer.d.ts +16 -0
- package/esm/core/Select/SelectTagContainer.js +21 -0
- package/esm/core/Table/Table.js +5 -3
- package/esm/core/Table/actionHandlers/index.d.ts +1 -1
- package/esm/core/Table/actionHandlers/index.js +1 -1
- package/esm/core/Table/actionHandlers/selectHandler.d.ts +2 -2
- package/esm/core/Table/actionHandlers/selectHandler.js +17 -3
- package/esm/core/ThemeProvider/ThemeProvider.d.ts +25 -6
- package/esm/core/ThemeProvider/ThemeProvider.js +30 -13
- package/esm/core/utils/components/Popover.d.ts +1 -1
- package/esm/core/utils/hooks/index.d.ts +1 -0
- package/esm/core/utils/hooks/index.js +1 -0
- package/esm/core/utils/hooks/useIsThemeAlreadySet.d.ts +7 -0
- package/esm/core/utils/hooks/useIsThemeAlreadySet.js +27 -0
- package/esm/core/utils/hooks/useTheme.js +4 -6
- package/package.json +10 -5
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { SelectOption } from '../Select/Select';
|
|
3
|
-
declare type ComboBoxAction =
|
|
3
|
+
declare type ComboBoxAction = {
|
|
4
|
+
type: 'multiselect';
|
|
5
|
+
value: number[];
|
|
6
|
+
} | {
|
|
7
|
+
type: 'open';
|
|
8
|
+
} | {
|
|
9
|
+
type: 'close';
|
|
10
|
+
} | {
|
|
11
|
+
type: 'select';
|
|
12
|
+
value: number;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'focus';
|
|
15
|
+
value: number | undefined;
|
|
16
|
+
};
|
|
4
17
|
export declare const comboBoxReducer: (state: {
|
|
5
18
|
isOpen: boolean;
|
|
6
|
-
|
|
19
|
+
selected: number | number[];
|
|
7
20
|
focusedIndex: number;
|
|
8
|
-
},
|
|
21
|
+
}, action: ComboBoxAction) => {
|
|
9
22
|
isOpen: boolean;
|
|
10
|
-
|
|
23
|
+
selected: number | number[];
|
|
11
24
|
focusedIndex: number;
|
|
12
25
|
};
|
|
13
26
|
export declare const ComboBoxRefsContext: React.Context<{
|
|
@@ -24,9 +37,11 @@ declare type ComboBoxStateContextProps<T = unknown> = {
|
|
|
24
37
|
minWidth: number;
|
|
25
38
|
enableVirtualization: boolean;
|
|
26
39
|
filteredOptions: SelectOption<T>[];
|
|
40
|
+
onClickHandler?: (prop: number) => void;
|
|
27
41
|
getMenuItem: (option: SelectOption<T>, filteredIndex?: number) => JSX.Element;
|
|
28
42
|
focusedIndex?: number;
|
|
43
|
+
multiple?: boolean;
|
|
29
44
|
};
|
|
30
45
|
export declare const ComboBoxStateContext: React.Context<ComboBoxStateContextProps<unknown> | undefined>;
|
|
31
|
-
export declare const ComboBoxActionContext: React.Context<((x:
|
|
46
|
+
export declare const ComboBoxActionContext: React.Context<((x: ComboBoxAction) => void) | undefined>;
|
|
32
47
|
export {};
|
|
@@ -9,9 +9,9 @@ exports.ComboBoxActionContext = exports.ComboBoxStateContext = exports.ComboBoxR
|
|
|
9
9
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
10
10
|
*--------------------------------------------------------------------------------------------*/
|
|
11
11
|
const react_1 = __importDefault(require("react"));
|
|
12
|
-
const comboBoxReducer = (state,
|
|
13
|
-
var _a;
|
|
14
|
-
switch (type) {
|
|
12
|
+
const comboBoxReducer = (state, action) => {
|
|
13
|
+
var _a, _b, _c, _d, _e;
|
|
14
|
+
switch (action.type) {
|
|
15
15
|
case 'open': {
|
|
16
16
|
return { ...state, isOpen: true };
|
|
17
17
|
}
|
|
@@ -19,14 +19,32 @@ const comboBoxReducer = (state, [type, value]) => {
|
|
|
19
19
|
return { ...state, isOpen: false };
|
|
20
20
|
}
|
|
21
21
|
case 'select': {
|
|
22
|
+
if (Array.isArray(state.selected)) {
|
|
23
|
+
return { ...state };
|
|
24
|
+
}
|
|
22
25
|
return {
|
|
23
26
|
...state,
|
|
24
|
-
|
|
25
|
-
focusedIndex: value !== null &&
|
|
27
|
+
selected: (_a = action.value) !== null && _a !== void 0 ? _a : state.selected,
|
|
28
|
+
focusedIndex: (_b = action.value) !== null && _b !== void 0 ? _b : state.focusedIndex,
|
|
26
29
|
};
|
|
27
30
|
}
|
|
31
|
+
case 'multiselect': {
|
|
32
|
+
if (!Array.isArray(state.selected)) {
|
|
33
|
+
return { ...state };
|
|
34
|
+
}
|
|
35
|
+
return { ...state, selected: action.value };
|
|
36
|
+
}
|
|
28
37
|
case 'focus': {
|
|
29
|
-
|
|
38
|
+
if (Array.isArray(state.selected)) {
|
|
39
|
+
return {
|
|
40
|
+
...state,
|
|
41
|
+
focusedIndex: (_c = action.value) !== null && _c !== void 0 ? _c : -1,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
...state,
|
|
46
|
+
focusedIndex: (_e = (_d = action.value) !== null && _d !== void 0 ? _d : state.selected) !== null && _e !== void 0 ? _e : -1,
|
|
47
|
+
};
|
|
30
48
|
}
|
|
31
49
|
default: {
|
|
32
50
|
return state;
|
|
@@ -15,6 +15,7 @@ const MenuItem_1 = require("../Menu/MenuItem");
|
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
16
|
require("@itwin/itwinui-css/css/select.css");
|
|
17
17
|
const SelectTag_1 = __importDefault(require("./SelectTag"));
|
|
18
|
+
const SelectTagContainer_1 = __importDefault(require("./SelectTagContainer"));
|
|
18
19
|
const isMultipleEnabled = (variable, multiple) => {
|
|
19
20
|
return multiple;
|
|
20
21
|
};
|
|
@@ -204,17 +205,11 @@ const MultipleSelectButton = ({ selectedItems, selectedItemsRenderer, tagRendere
|
|
|
204
205
|
}
|
|
205
206
|
return selectedItems.map((item) => tagRenderer(item));
|
|
206
207
|
}, [selectedItems, tagRenderer]);
|
|
207
|
-
const [containerRef, visibleCount] = (0, utils_1.useOverflow)(selectedItemsElements);
|
|
208
208
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
209
209
|
selectedItems &&
|
|
210
210
|
selectedItemsRenderer &&
|
|
211
211
|
selectedItemsRenderer(selectedItems),
|
|
212
212
|
selectedItems && !selectedItemsRenderer && (react_1.default.createElement("span", { className: 'iui-content' },
|
|
213
|
-
react_1.default.createElement(
|
|
214
|
-
react_1.default.createElement(react_1.default.Fragment, null,
|
|
215
|
-
visibleCount < selectedItemsElements.length
|
|
216
|
-
? selectedItemsElements.slice(0, visibleCount - 1)
|
|
217
|
-
: selectedItemsElements,
|
|
218
|
-
visibleCount < selectedItemsElements.length && (react_1.default.createElement(SelectTag_1.default, { label: `+${selectedItemsElements.length - visibleCount + 1} item(s)` }))))))));
|
|
213
|
+
react_1.default.createElement(SelectTagContainer_1.default, { tags: selectedItemsElements })))));
|
|
219
214
|
};
|
|
220
215
|
exports.default = exports.Select;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export declare type SelectTagContainerProps = {
|
|
3
|
+
/**
|
|
4
|
+
* Select tags.
|
|
5
|
+
*/
|
|
6
|
+
tags: React.ReactNode[];
|
|
7
|
+
} & Omit<React.ComponentPropsWithoutRef<'div'>, 'children'>;
|
|
8
|
+
/**
|
|
9
|
+
*/
|
|
10
|
+
export declare const SelectTagContainer: React.ForwardRefExoticComponent<{
|
|
11
|
+
/**
|
|
12
|
+
* Select tags.
|
|
13
|
+
*/
|
|
14
|
+
tags: React.ReactNode[];
|
|
15
|
+
} & Omit<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>>, "children"> & React.RefAttributes<HTMLDivElement>>;
|
|
16
|
+
export default SelectTagContainer;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SelectTagContainer = void 0;
|
|
7
|
+
/*---------------------------------------------------------------------------------------------
|
|
8
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
9
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
10
|
+
*--------------------------------------------------------------------------------------------*/
|
|
11
|
+
const react_1 = __importDefault(require("react"));
|
|
12
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
13
|
+
const utils_1 = require("../utils");
|
|
14
|
+
const SelectTag_1 = __importDefault(require("./SelectTag"));
|
|
15
|
+
/**
|
|
16
|
+
*/
|
|
17
|
+
exports.SelectTagContainer = react_1.default.forwardRef((props, ref) => {
|
|
18
|
+
const { tags, className, ...rest } = props;
|
|
19
|
+
(0, utils_1.useTheme)();
|
|
20
|
+
const [containerRef, visibleCount] = (0, utils_1.useOverflow)(tags);
|
|
21
|
+
const refs = (0, utils_1.useMergedRefs)(ref, containerRef);
|
|
22
|
+
return (react_1.default.createElement("div", { className: (0, classnames_1.default)('iui-select-tag-container', className), ref: refs, ...rest },
|
|
23
|
+
react_1.default.createElement(react_1.default.Fragment, null,
|
|
24
|
+
visibleCount < tags.length ? tags.slice(0, visibleCount - 1) : tags,
|
|
25
|
+
visibleCount < tags.length && (react_1.default.createElement(SelectTag_1.default, { label: `+${tags.length - visibleCount + 1} item(s)` })))));
|
|
26
|
+
});
|
|
27
|
+
exports.default = exports.SelectTagContainer;
|
package/cjs/core/Table/Table.js
CHANGED
|
@@ -150,7 +150,7 @@ const Table = (props) => {
|
|
|
150
150
|
case react_table_1.actions.toggleRowSelected:
|
|
151
151
|
case react_table_1.actions.toggleAllRowsSelected:
|
|
152
152
|
case react_table_1.actions.toggleAllPageRowsSelected: {
|
|
153
|
-
(0, actionHandlers_1.
|
|
153
|
+
(0, actionHandlers_1.onToggleHandler)(newState, action, instance, onSelect,
|
|
154
154
|
// If it has manual selection column, then we can't check whether row is disabled
|
|
155
155
|
hasManualSelectionColumn ? undefined : isRowDisabled);
|
|
156
156
|
break;
|
|
@@ -209,6 +209,7 @@ const Table = (props) => {
|
|
|
209
209
|
const showSortButton = (column) => data.length !== 0 && column.canSort;
|
|
210
210
|
const onRowClickHandler = react_1.default.useCallback((event, row) => {
|
|
211
211
|
const isDisabled = isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original);
|
|
212
|
+
const ctrlPressed = event.ctrlKey || event.metaKey;
|
|
212
213
|
if (!isDisabled) {
|
|
213
214
|
onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(event, row);
|
|
214
215
|
}
|
|
@@ -220,10 +221,11 @@ const Table = (props) => {
|
|
|
220
221
|
dispatch({
|
|
221
222
|
type: shiftRowSelectedAction,
|
|
222
223
|
id: row.id,
|
|
224
|
+
ctrlPressed: ctrlPressed,
|
|
223
225
|
});
|
|
224
226
|
}
|
|
225
227
|
else if (!row.isSelected &&
|
|
226
|
-
(selectionMode === 'single' || !
|
|
228
|
+
(selectionMode === 'single' || !ctrlPressed)) {
|
|
227
229
|
dispatch({
|
|
228
230
|
type: singleRowSelectedAction,
|
|
229
231
|
id: row.id,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { onExpandHandler } from './expandHandler';
|
|
2
2
|
export { onFilterHandler } from './filterHandler';
|
|
3
|
-
export {
|
|
3
|
+
export { onToggleHandler, onSingleSelectHandler, onShiftSelectHandler, } from './selectHandler';
|
|
4
4
|
export { onTableResizeStart, onTableResizeEnd } from './resizeHandler';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.onTableResizeEnd = exports.onTableResizeStart = exports.onShiftSelectHandler = exports.onSingleSelectHandler = exports.
|
|
3
|
+
exports.onTableResizeEnd = exports.onTableResizeStart = exports.onShiftSelectHandler = exports.onSingleSelectHandler = exports.onToggleHandler = exports.onFilterHandler = exports.onExpandHandler = void 0;
|
|
4
4
|
/*---------------------------------------------------------------------------------------------
|
|
5
5
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
6
6
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "onExpandHandler", { enumerable: true, get: funct
|
|
|
10
10
|
var filterHandler_1 = require("./filterHandler");
|
|
11
11
|
Object.defineProperty(exports, "onFilterHandler", { enumerable: true, get: function () { return filterHandler_1.onFilterHandler; } });
|
|
12
12
|
var selectHandler_1 = require("./selectHandler");
|
|
13
|
-
Object.defineProperty(exports, "
|
|
13
|
+
Object.defineProperty(exports, "onToggleHandler", { enumerable: true, get: function () { return selectHandler_1.onToggleHandler; } });
|
|
14
14
|
Object.defineProperty(exports, "onSingleSelectHandler", { enumerable: true, get: function () { return selectHandler_1.onSingleSelectHandler; } });
|
|
15
15
|
Object.defineProperty(exports, "onShiftSelectHandler", { enumerable: true, get: function () { return selectHandler_1.onShiftSelectHandler; } });
|
|
16
16
|
var resizeHandler_1 = require("./resizeHandler");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { ActionType, TableInstance, TableState } from 'react-table';
|
|
2
2
|
/**
|
|
3
|
-
* Handles selection when
|
|
3
|
+
* Handles selection when toggling a row (Ctrl click or checkbox click)
|
|
4
4
|
*/
|
|
5
|
-
export declare const
|
|
5
|
+
export declare const onToggleHandler: <T extends Record<string, unknown>>(newState: TableState<T>, action: ActionType, instance?: TableInstance<T> | undefined, onSelect?: ((selectedData: T[] | undefined, tableState?: TableState<T> | undefined) => void) | undefined, isRowDisabled?: ((rowData: T) => boolean) | undefined) => void;
|
|
6
6
|
/**
|
|
7
7
|
* Handles selection when clicked on a row.
|
|
8
8
|
*/
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.onShiftSelectHandler = exports.onSingleSelectHandler = exports.
|
|
3
|
+
exports.onShiftSelectHandler = exports.onSingleSelectHandler = exports.onToggleHandler = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* Handles selection
|
|
5
|
+
* Handles subrow selection and validation.
|
|
6
|
+
* - Subrow selection: Selecting a row and calling this method automatically selects all the subrows that can be selected
|
|
7
|
+
* - Validation: Ensures that any disabled/unselectable row/subrow is not selected
|
|
6
8
|
*/
|
|
7
9
|
const onSelectHandler = (newState, instance, onSelect, isRowDisabled) => {
|
|
8
10
|
if (!(instance === null || instance === void 0 ? void 0 : instance.rows.length)) {
|
|
@@ -36,7 +38,15 @@ const onSelectHandler = (newState, instance, onSelect, isRowDisabled) => {
|
|
|
36
38
|
newState.selectedRowIds = newSelectedRowIds;
|
|
37
39
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedData, newState);
|
|
38
40
|
};
|
|
39
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Handles selection when toggling a row (Ctrl click or checkbox click)
|
|
43
|
+
*/
|
|
44
|
+
const onToggleHandler = (newState, action, instance, onSelect, isRowDisabled) => {
|
|
45
|
+
onSelectHandler(newState, instance, onSelect, isRowDisabled);
|
|
46
|
+
// Toggling a row (ctrl click or checkbox click) updates the lastSelectedRowId
|
|
47
|
+
newState.lastSelectedRowId = action.id;
|
|
48
|
+
};
|
|
49
|
+
exports.onToggleHandler = onToggleHandler;
|
|
40
50
|
/**
|
|
41
51
|
* Handles selection when clicked on a row.
|
|
42
52
|
*/
|
|
@@ -55,7 +65,7 @@ const onSingleSelectHandler = (state, action, instance, onSelect, isRowDisabled)
|
|
|
55
65
|
selectedRowIds,
|
|
56
66
|
};
|
|
57
67
|
// Passing to `onSelectHandler` to handle filtered sub-rows
|
|
58
|
-
|
|
68
|
+
onSelectHandler(newState, instance, onSelect, isRowDisabled);
|
|
59
69
|
return newState;
|
|
60
70
|
};
|
|
61
71
|
exports.onSingleSelectHandler = onSingleSelectHandler;
|
|
@@ -73,7 +83,11 @@ const onShiftSelectHandler = (state, action, instance, onSelect, isRowDisabled)
|
|
|
73
83
|
startIndex = endIndex;
|
|
74
84
|
endIndex = temp;
|
|
75
85
|
}
|
|
76
|
-
|
|
86
|
+
// If ctrl + shift click, do not lose previous selection
|
|
87
|
+
// If shift click, start new selection
|
|
88
|
+
const selectedRowIds = !!action.ctrlPressed
|
|
89
|
+
? state.selectedRowIds
|
|
90
|
+
: {};
|
|
77
91
|
// 1. Select all rows between start and end
|
|
78
92
|
instance.flatRows
|
|
79
93
|
.slice(startIndex, endIndex + 1)
|
|
@@ -91,7 +105,7 @@ const onShiftSelectHandler = (state, action, instance, onSelect, isRowDisabled)
|
|
|
91
105
|
};
|
|
92
106
|
// 3.1 Deselect all selected disabled rows and their children
|
|
93
107
|
// 3.2 Convert all partially selected rows marked with tick mark to horizontal line
|
|
94
|
-
|
|
108
|
+
onSelectHandler(newState, instance, onSelect, isRowDisabled);
|
|
95
109
|
return newState;
|
|
96
110
|
};
|
|
97
111
|
exports.onShiftSelectHandler = onShiftSelectHandler;
|
|
@@ -3,7 +3,7 @@ import type { PolymorphicComponentProps, PolymorphicForwardRefComponent, ThemeOp
|
|
|
3
3
|
import '@itwin/itwinui-css/css/global.css';
|
|
4
4
|
import '@itwin/itwinui-variables/index.css';
|
|
5
5
|
export declare type ThemeProviderProps<T extends React.ElementType = 'div'> = PolymorphicComponentProps<T, ThemeProviderOwnProps>;
|
|
6
|
-
declare type
|
|
6
|
+
declare type RootProps = {
|
|
7
7
|
/**
|
|
8
8
|
* Theme to be applied. Can be 'light' or 'dark' or 'os'.
|
|
9
9
|
*
|
|
@@ -14,8 +14,21 @@ declare type ThemeProviderOwnProps = {
|
|
|
14
14
|
* @default 'light'
|
|
15
15
|
*/
|
|
16
16
|
theme?: ThemeType;
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
themeOptions?: Pick<ThemeOptions, 'highContrast'> & {
|
|
18
|
+
/**
|
|
19
|
+
* Whether or not the element should apply the recommended `background-color` on itself.
|
|
20
|
+
*
|
|
21
|
+
* When not specified, the default behavior is to apply a background-color only
|
|
22
|
+
* if it is the topmost `ThemeProvider` in the tree. Nested `ThemeProvider`s will
|
|
23
|
+
* be detected using React Context and will not apply a background-color.
|
|
24
|
+
*
|
|
25
|
+
* When set to true or false, it will override the default behavior.
|
|
26
|
+
*/
|
|
27
|
+
applyBackground?: boolean;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
declare type ThemeProviderOwnProps = Pick<RootProps, 'theme'> & ({
|
|
31
|
+
themeOptions?: RootProps['themeOptions'];
|
|
19
32
|
children: Required<React.ReactNode>;
|
|
20
33
|
} | {
|
|
21
34
|
themeOptions?: ThemeOptions;
|
|
@@ -26,10 +39,11 @@ declare type ThemeProviderOwnProps = {
|
|
|
26
39
|
* that it is wrapping around. The `theme` prop is optional and defaults to the
|
|
27
40
|
* light theme.
|
|
28
41
|
*
|
|
29
|
-
* If you want to theme the entire app, you should use this component at the root.
|
|
30
|
-
*
|
|
42
|
+
* If you want to theme the entire app, you should use this component at the root. You can also
|
|
43
|
+
* use this component to apply a different theme to only a part of the tree.
|
|
31
44
|
*
|
|
32
|
-
*
|
|
45
|
+
* By default, the topmost `ThemeProvider` in the tree will apply the recommended
|
|
46
|
+
* `background-color`. You can override this behavior using `themeOptions.applyBackground`.
|
|
33
47
|
*
|
|
34
48
|
* @example
|
|
35
49
|
* <ThemeProvider theme='os'>
|
|
@@ -40,6 +54,11 @@ declare type ThemeProviderOwnProps = {
|
|
|
40
54
|
* <ThemeProvider as='body'>
|
|
41
55
|
* <App />
|
|
42
56
|
* </ThemeProvider>
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* <ThemeProvider theme='dark' themeOptions={{ applyBackground: false }}>
|
|
60
|
+
* <App />
|
|
61
|
+
* </ThemeProvider>
|
|
43
62
|
*/
|
|
44
63
|
export declare const ThemeProvider: PolymorphicForwardRefComponent<"div", ThemeProviderOwnProps>;
|
|
45
64
|
export default ThemeProvider;
|
|
@@ -18,10 +18,11 @@ require("@itwin/itwinui-variables/index.css");
|
|
|
18
18
|
* that it is wrapping around. The `theme` prop is optional and defaults to the
|
|
19
19
|
* light theme.
|
|
20
20
|
*
|
|
21
|
-
* If you want to theme the entire app, you should use this component at the root.
|
|
22
|
-
*
|
|
21
|
+
* If you want to theme the entire app, you should use this component at the root. You can also
|
|
22
|
+
* use this component to apply a different theme to only a part of the tree.
|
|
23
23
|
*
|
|
24
|
-
*
|
|
24
|
+
* By default, the topmost `ThemeProvider` in the tree will apply the recommended
|
|
25
|
+
* `background-color`. You can override this behavior using `themeOptions.applyBackground`.
|
|
25
26
|
*
|
|
26
27
|
* @example
|
|
27
28
|
* <ThemeProvider theme='os'>
|
|
@@ -32,26 +33,42 @@ require("@itwin/itwinui-variables/index.css");
|
|
|
32
33
|
* <ThemeProvider as='body'>
|
|
33
34
|
* <App />
|
|
34
35
|
* </ThemeProvider>
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* <ThemeProvider theme='dark' themeOptions={{ applyBackground: false }}>
|
|
39
|
+
* <App />
|
|
40
|
+
* </ThemeProvider>
|
|
35
41
|
*/
|
|
36
42
|
exports.ThemeProvider = react_1.default.forwardRef((props, ref) => {
|
|
37
|
-
|
|
38
|
-
const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
|
|
43
|
+
const { theme, children, themeOptions, ...rest } = props;
|
|
39
44
|
const rootRef = react_1.default.useRef(null);
|
|
40
45
|
const mergedRefs = (0, utils_1.useMergedRefs)(rootRef, ref);
|
|
41
46
|
const hasChildren = react_1.default.Children.count(children) > 0;
|
|
42
47
|
const parentContext = react_1.default.useContext(exports.ThemeContext);
|
|
48
|
+
const contextValue = react_1.default.useMemo(() => ({ theme, themeOptions, rootRef }), [theme, themeOptions]);
|
|
49
|
+
// if no children, then fallback to this wrapper component which calls useTheme
|
|
50
|
+
if (!hasChildren) {
|
|
51
|
+
return (react_1.default.createElement(ThemeLogicWrapper, { theme: theme !== null && theme !== void 0 ? theme : parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
|
|
52
|
+
}
|
|
53
|
+
// now that we know there are children, we can render the root and provide the context value
|
|
54
|
+
return (react_1.default.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
|
|
55
|
+
react_1.default.createElement(exports.ThemeContext.Provider, { value: contextValue }, children)));
|
|
56
|
+
});
|
|
57
|
+
exports.default = exports.ThemeProvider;
|
|
58
|
+
exports.ThemeContext = react_1.default.createContext(undefined);
|
|
59
|
+
const Root = react_1.default.forwardRef((props, forwardedRef) => {
|
|
60
|
+
var _a, _b, _c;
|
|
61
|
+
const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
|
|
62
|
+
const ref = react_1.default.useRef(null);
|
|
63
|
+
const mergedRefs = (0, utils_1.useMergedRefs)(ref, forwardedRef);
|
|
43
64
|
const prefersDark = (0, utils_1.useMediaQuery)('(prefers-color-scheme: dark)');
|
|
44
65
|
const prefersHighContrast = (0, utils_1.useMediaQuery)('(prefers-contrast: more)');
|
|
45
66
|
const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
|
|
46
67
|
const shouldApplyHC = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast) !== null && _a !== void 0 ? _a : prefersHighContrast;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// otherwise just apply theme on the root using this wrapper component
|
|
51
|
-
react_1.default.createElement(ThemeLogicWrapper, { theme: theme !== null && theme !== void 0 ? theme : parentContext === null || parentContext === void 0 ? void 0 : parentContext.theme, themeOptions: themeOptions !== null && themeOptions !== void 0 ? themeOptions : parentContext === null || parentContext === void 0 ? void 0 : parentContext.themeOptions }));
|
|
68
|
+
const isThemeAlreadySet = (0, utils_1.useIsThemeAlreadySet)((_b = ref.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
|
|
69
|
+
const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : !isThemeAlreadySet.current;
|
|
70
|
+
return (react_1.default.createElement(Element, { className: (0, classnames_1.default)('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
|
|
52
71
|
});
|
|
53
|
-
exports.default = exports.ThemeProvider;
|
|
54
|
-
exports.ThemeContext = react_1.default.createContext(undefined);
|
|
55
72
|
const ThemeLogicWrapper = ({ theme, themeOptions }) => {
|
|
56
73
|
(0, utils_1.useTheme)(theme, themeOptions);
|
|
57
74
|
return react_1.default.createElement(react_1.default.Fragment, null);
|
|
@@ -26,7 +26,7 @@ export declare type PopoverProps = {
|
|
|
26
26
|
* with pre-configured props and plugins (e.g. lazy mounting, focus, etc).
|
|
27
27
|
* @private
|
|
28
28
|
*/
|
|
29
|
-
export declare const Popover: React.ForwardRefExoticComponent<Pick<PopoverProps, "disabled" | "theme" | "children" | "className" | "role" | "
|
|
29
|
+
export declare const Popover: React.ForwardRefExoticComponent<Pick<PopoverProps, "disabled" | "theme" | "children" | "className" | "role" | "offset" | "content" | "plugins" | "placement" | "trigger" | "visible" | "render" | "animateFill" | "appendTo" | "aria" | "delay" | "duration" | "followCursor" | "getReferenceClientRect" | "hideOnClick" | "ignoreAttributes" | "inlinePositioning" | "interactive" | "interactiveBorder" | "interactiveDebounce" | "moveTransition" | "popperOptions" | "showOnCreate" | "sticky" | "touch" | "triggerTarget" | "onAfterUpdate" | "onBeforeUpdate" | "onCreate" | "onDestroy" | "onHidden" | "onHide" | "onMount" | "onShow" | "onShown" | "onTrigger" | "onUntrigger" | "onClickOutside" | "allowHTML" | "animation" | "arrow" | "inertia" | "maxWidth" | "zIndex" | "singleton" | "reference"> & React.RefAttributes<unknown>>;
|
|
30
30
|
/**
|
|
31
31
|
* Plugin to hide Popover when either Esc key is pressed,
|
|
32
32
|
* or when the content inside is not tabbable and Tab key is pressed.
|
|
@@ -29,3 +29,4 @@ __exportStar(require("./useMediaQuery"), exports);
|
|
|
29
29
|
__exportStar(require("./useSafeContext"), exports);
|
|
30
30
|
__exportStar(require("./useLatestRef"), exports);
|
|
31
31
|
__exportStar(require("./useIsomorphicLayoutEffect"), exports);
|
|
32
|
+
__exportStar(require("./useIsThemeAlreadySet"), exports);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook that returns a boolean ref which is true if either:
|
|
4
|
+
* - There is a parent `ThemeProvider` in the tree, or
|
|
5
|
+
* - The <body> element has data-iui-theme attribute
|
|
6
|
+
*/
|
|
7
|
+
export declare const useIsThemeAlreadySet: (ownerDocument?: Document | undefined) => React.MutableRefObject<boolean>;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.useIsThemeAlreadySet = void 0;
|
|
7
|
+
/*---------------------------------------------------------------------------------------------
|
|
8
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
9
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
10
|
+
*--------------------------------------------------------------------------------------------*/
|
|
11
|
+
const react_1 = __importDefault(require("react"));
|
|
12
|
+
const ThemeProvider_1 = require("../../ThemeProvider/ThemeProvider");
|
|
13
|
+
const useIsomorphicLayoutEffect_1 = require("./useIsomorphicLayoutEffect");
|
|
14
|
+
const functions_1 = require("../functions");
|
|
15
|
+
/**
|
|
16
|
+
* Hook that returns a boolean ref which is true if either:
|
|
17
|
+
* - There is a parent `ThemeProvider` in the tree, or
|
|
18
|
+
* - The <body> element has data-iui-theme attribute
|
|
19
|
+
*/
|
|
20
|
+
const useIsThemeAlreadySet = (ownerDocument = (0, functions_1.getDocument)()) => {
|
|
21
|
+
const parentContext = react_1.default.useContext(ThemeProvider_1.ThemeContext);
|
|
22
|
+
const isThemeAlreadySet = react_1.default.useRef(!!parentContext || !!(ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.body.dataset.iuiTheme));
|
|
23
|
+
(0, useIsomorphicLayoutEffect_1.useIsomorphicLayoutEffect)(() => {
|
|
24
|
+
if (parentContext ||
|
|
25
|
+
(ownerDocument && !!ownerDocument.body.dataset.iuiTheme)) {
|
|
26
|
+
isThemeAlreadySet.current = true;
|
|
27
|
+
}
|
|
28
|
+
return () => {
|
|
29
|
+
isThemeAlreadySet.current = false;
|
|
30
|
+
};
|
|
31
|
+
}, [parentContext, ownerDocument]);
|
|
32
|
+
return isThemeAlreadySet;
|
|
33
|
+
};
|
|
34
|
+
exports.useIsThemeAlreadySet = useIsThemeAlreadySet;
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.useTheme = void 0;
|
|
7
4
|
/*---------------------------------------------------------------------------------------------
|
|
8
5
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
9
6
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
10
7
|
*--------------------------------------------------------------------------------------------*/
|
|
11
|
-
const react_1 = __importDefault(require("react"));
|
|
12
|
-
const ThemeProvider_1 = require("../../ThemeProvider/ThemeProvider");
|
|
13
8
|
const functions_1 = require("../functions");
|
|
14
9
|
const useIsomorphicLayoutEffect_1 = require("./useIsomorphicLayoutEffect");
|
|
10
|
+
const useIsThemeAlreadySet_1 = require("./useIsThemeAlreadySet");
|
|
15
11
|
require("@itwin/itwinui-css/css/global.css");
|
|
16
12
|
require("@itwin/itwinui-variables/index.css");
|
|
17
13
|
/**
|
|
@@ -25,11 +21,10 @@ require("@itwin/itwinui-variables/index.css");
|
|
|
25
21
|
*/
|
|
26
22
|
const useTheme = (theme, themeOptions) => {
|
|
27
23
|
var _a;
|
|
28
|
-
const themeContext = react_1.default.useContext(ThemeProvider_1.ThemeContext);
|
|
29
24
|
const ownerDocument = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.ownerDocument) !== null && _a !== void 0 ? _a : (0, functions_1.getDocument)();
|
|
25
|
+
const isThemeAlreadySet = (0, useIsThemeAlreadySet_1.useIsThemeAlreadySet)(ownerDocument);
|
|
30
26
|
(0, useIsomorphicLayoutEffect_1.useIsomorphicLayoutEffect)(() => {
|
|
31
|
-
|
|
32
|
-
if (themeContext || !ownerDocument || ownerDocument.body.dataset.iuiTheme) {
|
|
27
|
+
if (!ownerDocument || isThemeAlreadySet.current) {
|
|
33
28
|
return;
|
|
34
29
|
}
|
|
35
30
|
ownerDocument.body.classList.toggle('iui-root', true);
|
|
@@ -47,7 +42,7 @@ const useTheme = (theme, themeOptions) => {
|
|
|
47
42
|
return;
|
|
48
43
|
}
|
|
49
44
|
}
|
|
50
|
-
}, [theme,
|
|
45
|
+
}, [theme, themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast, ownerDocument]);
|
|
51
46
|
};
|
|
52
47
|
exports.useTheme = useTheme;
|
|
53
48
|
/**
|
|
@@ -3,24 +3,41 @@ import { InputProps } from '../Input';
|
|
|
3
3
|
import { SelectOption } from '../Select';
|
|
4
4
|
import { PopoverProps, CommonProps, InputContainerProps } from '../utils';
|
|
5
5
|
import 'tippy.js/animations/shift-away.css';
|
|
6
|
-
|
|
6
|
+
declare type ActionType = 'added' | 'removed';
|
|
7
|
+
declare type MultipleOnChangeProps<T> = {
|
|
8
|
+
value: T;
|
|
9
|
+
type: ActionType;
|
|
10
|
+
};
|
|
11
|
+
export declare type ComboboxMultipleTypeProps<T> = {
|
|
7
12
|
/**
|
|
8
|
-
*
|
|
13
|
+
* Enable multiple selection.
|
|
14
|
+
* @default false
|
|
9
15
|
*/
|
|
10
|
-
|
|
16
|
+
multiple?: false;
|
|
11
17
|
/**
|
|
12
18
|
* Controlled value of ComboBox.
|
|
19
|
+
* If `multiple` is enabled, it is an array of values.
|
|
13
20
|
*/
|
|
14
21
|
value?: T;
|
|
22
|
+
/**
|
|
23
|
+
* Callback fired when selected value changes.
|
|
24
|
+
*/
|
|
25
|
+
onChange?: (value: T) => void;
|
|
26
|
+
} | {
|
|
27
|
+
multiple: true;
|
|
28
|
+
value?: T[];
|
|
29
|
+
onChange?: (value: T[], event: MultipleOnChangeProps<T>) => void;
|
|
30
|
+
};
|
|
31
|
+
export declare type ComboBoxProps<T> = {
|
|
32
|
+
/**
|
|
33
|
+
* Array of options that populate the dropdown list.
|
|
34
|
+
*/
|
|
35
|
+
options: SelectOption<T>[];
|
|
15
36
|
/**
|
|
16
37
|
* Message shown below the combobox.
|
|
17
38
|
* Use `StatusMessage` component.
|
|
18
39
|
*/
|
|
19
40
|
message?: React.ReactNode;
|
|
20
|
-
/**
|
|
21
|
-
* Callback fired when selected value changes.
|
|
22
|
-
*/
|
|
23
|
-
onChange?: (value: T) => void;
|
|
24
41
|
/**
|
|
25
42
|
* Function to customize the default filtering logic.
|
|
26
43
|
*/
|
|
@@ -67,7 +84,7 @@ export declare type ComboBoxProps<T> = {
|
|
|
67
84
|
* Callback fired when dropdown menu is closed.
|
|
68
85
|
*/
|
|
69
86
|
onHide?: () => void;
|
|
70
|
-
} & Pick<InputContainerProps, 'status'> & Omit<CommonProps, 'title'>;
|
|
87
|
+
} & ComboboxMultipleTypeProps<T> & Pick<InputContainerProps, 'status'> & Omit<CommonProps, 'title'>;
|
|
71
88
|
/**
|
|
72
89
|
* ComboBox component that allows typing a value to filter the options in dropdown list.
|
|
73
90
|
* Values can be selected either using mouse clicks or using the Enter key.
|