@itwin/itwinui-react 2.0.4 → 2.1.1
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 +15 -2
- 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/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/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
|
@@ -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,21 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import cx from 'classnames';
|
|
7
|
+
import { useTheme, useOverflow, useMergedRefs } from '../utils';
|
|
8
|
+
import SelectTag from './SelectTag';
|
|
9
|
+
/**
|
|
10
|
+
*/
|
|
11
|
+
export const SelectTagContainer = React.forwardRef((props, ref) => {
|
|
12
|
+
const { tags, className, ...rest } = props;
|
|
13
|
+
useTheme();
|
|
14
|
+
const [containerRef, visibleCount] = useOverflow(tags);
|
|
15
|
+
const refs = useMergedRefs(ref, containerRef);
|
|
16
|
+
return (React.createElement("div", { className: cx('iui-select-tag-container', className), ref: refs, ...rest },
|
|
17
|
+
React.createElement(React.Fragment, null,
|
|
18
|
+
visibleCount < tags.length ? tags.slice(0, visibleCount - 1) : tags,
|
|
19
|
+
visibleCount < tags.length && (React.createElement(SelectTag, { label: `+${tags.length - visibleCount + 1} item(s)` })))));
|
|
20
|
+
});
|
|
21
|
+
export default SelectTagContainer;
|
package/esm/core/Table/Table.js
CHANGED
|
@@ -13,7 +13,7 @@ import { TableRowMemoized } from './TableRowMemoized';
|
|
|
13
13
|
import { FilterToggle } from './filters';
|
|
14
14
|
import { customFilterFunctions } from './filters/customFilterFunctions';
|
|
15
15
|
import { useExpanderCell, useSelectionCell, useSubRowFiltering, useSubRowSelection, useResizeColumns, useColumnDragAndDrop, useScrollToRow, useStickyColumns, } from './hooks';
|
|
16
|
-
import { onExpandHandler, onFilterHandler,
|
|
16
|
+
import { onExpandHandler, onFilterHandler, onToggleHandler, onShiftSelectHandler, onSingleSelectHandler, onTableResizeEnd, onTableResizeStart, } from './actionHandlers';
|
|
17
17
|
import VirtualScroll from '../utils/components/VirtualScroll';
|
|
18
18
|
import { SELECTION_CELL_ID } from './columns';
|
|
19
19
|
const singleRowSelectedAction = 'singleRowSelected';
|
|
@@ -144,7 +144,7 @@ export const Table = (props) => {
|
|
|
144
144
|
case TableActions.toggleRowSelected:
|
|
145
145
|
case TableActions.toggleAllRowsSelected:
|
|
146
146
|
case TableActions.toggleAllPageRowsSelected: {
|
|
147
|
-
|
|
147
|
+
onToggleHandler(newState, action, instance, onSelect,
|
|
148
148
|
// If it has manual selection column, then we can't check whether row is disabled
|
|
149
149
|
hasManualSelectionColumn ? undefined : isRowDisabled);
|
|
150
150
|
break;
|
|
@@ -203,6 +203,7 @@ export const Table = (props) => {
|
|
|
203
203
|
const showSortButton = (column) => data.length !== 0 && column.canSort;
|
|
204
204
|
const onRowClickHandler = React.useCallback((event, row) => {
|
|
205
205
|
const isDisabled = isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original);
|
|
206
|
+
const ctrlPressed = event.ctrlKey || event.metaKey;
|
|
206
207
|
if (!isDisabled) {
|
|
207
208
|
onRowClick === null || onRowClick === void 0 ? void 0 : onRowClick(event, row);
|
|
208
209
|
}
|
|
@@ -214,10 +215,11 @@ export const Table = (props) => {
|
|
|
214
215
|
dispatch({
|
|
215
216
|
type: shiftRowSelectedAction,
|
|
216
217
|
id: row.id,
|
|
218
|
+
ctrlPressed: ctrlPressed,
|
|
217
219
|
});
|
|
218
220
|
}
|
|
219
221
|
else if (!row.isSelected &&
|
|
220
|
-
(selectionMode === 'single' || !
|
|
222
|
+
(selectionMode === 'single' || !ctrlPressed)) {
|
|
221
223
|
dispatch({
|
|
222
224
|
type: singleRowSelectedAction,
|
|
223
225
|
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';
|
|
@@ -4,5 +4,5 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
export { onExpandHandler } from './expandHandler';
|
|
6
6
|
export { onFilterHandler } from './filterHandler';
|
|
7
|
-
export {
|
|
7
|
+
export { onToggleHandler, onSingleSelectHandler, onShiftSelectHandler, } from './selectHandler';
|
|
8
8
|
export { onTableResizeStart, onTableResizeEnd } from './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,7 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Handles selection
|
|
2
|
+
* Handles subrow selection and validation.
|
|
3
|
+
* - Subrow selection: Selecting a row and calling this method automatically selects all the subrows that can be selected
|
|
4
|
+
* - Validation: Ensures that any disabled/unselectable row/subrow is not selected
|
|
3
5
|
*/
|
|
4
|
-
|
|
6
|
+
const onSelectHandler = (newState, instance, onSelect, isRowDisabled) => {
|
|
5
7
|
if (!(instance === null || instance === void 0 ? void 0 : instance.rows.length)) {
|
|
6
8
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect([], newState);
|
|
7
9
|
return;
|
|
@@ -33,6 +35,14 @@ export const onSelectHandler = (newState, instance, onSelect, isRowDisabled) =>
|
|
|
33
35
|
newState.selectedRowIds = newSelectedRowIds;
|
|
34
36
|
onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedData, newState);
|
|
35
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* Handles selection when toggling a row (Ctrl click or checkbox click)
|
|
40
|
+
*/
|
|
41
|
+
export const onToggleHandler = (newState, action, instance, onSelect, isRowDisabled) => {
|
|
42
|
+
onSelectHandler(newState, instance, onSelect, isRowDisabled);
|
|
43
|
+
// Toggling a row (ctrl click or checkbox click) updates the lastSelectedRowId
|
|
44
|
+
newState.lastSelectedRowId = action.id;
|
|
45
|
+
};
|
|
36
46
|
/**
|
|
37
47
|
* Handles selection when clicked on a row.
|
|
38
48
|
*/
|
|
@@ -68,7 +78,11 @@ export const onShiftSelectHandler = (state, action, instance, onSelect, isRowDis
|
|
|
68
78
|
startIndex = endIndex;
|
|
69
79
|
endIndex = temp;
|
|
70
80
|
}
|
|
71
|
-
|
|
81
|
+
// If ctrl + shift click, do not lose previous selection
|
|
82
|
+
// If shift click, start new selection
|
|
83
|
+
const selectedRowIds = !!action.ctrlPressed
|
|
84
|
+
? state.selectedRowIds
|
|
85
|
+
: {};
|
|
72
86
|
// 1. Select all rows between start and end
|
|
73
87
|
instance.flatRows
|
|
74
88
|
.slice(startIndex, endIndex + 1)
|
|
@@ -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;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import { useTheme, useMediaQuery, useMergedRefs } from '../utils';
|
|
7
|
+
import { useTheme, useMediaQuery, useMergedRefs, useIsThemeAlreadySet, } from '../utils';
|
|
8
8
|
import '@itwin/itwinui-css/css/global.css';
|
|
9
9
|
import '@itwin/itwinui-variables/index.css';
|
|
10
10
|
/**
|
|
@@ -12,10 +12,11 @@ import '@itwin/itwinui-variables/index.css';
|
|
|
12
12
|
* that it is wrapping around. The `theme` prop is optional and defaults to the
|
|
13
13
|
* light theme.
|
|
14
14
|
*
|
|
15
|
-
* If you want to theme the entire app, you should use this component at the root.
|
|
16
|
-
*
|
|
15
|
+
* If you want to theme the entire app, you should use this component at the root. You can also
|
|
16
|
+
* use this component to apply a different theme to only a part of the tree.
|
|
17
17
|
*
|
|
18
|
-
*
|
|
18
|
+
* By default, the topmost `ThemeProvider` in the tree will apply the recommended
|
|
19
|
+
* `background-color`. You can override this behavior using `themeOptions.applyBackground`.
|
|
19
20
|
*
|
|
20
21
|
* @example
|
|
21
22
|
* <ThemeProvider theme='os'>
|
|
@@ -26,26 +27,42 @@ import '@itwin/itwinui-variables/index.css';
|
|
|
26
27
|
* <ThemeProvider as='body'>
|
|
27
28
|
* <App />
|
|
28
29
|
* </ThemeProvider>
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* <ThemeProvider theme='dark' themeOptions={{ applyBackground: false }}>
|
|
33
|
+
* <App />
|
|
34
|
+
* </ThemeProvider>
|
|
29
35
|
*/
|
|
30
36
|
export const ThemeProvider = React.forwardRef((props, ref) => {
|
|
31
|
-
|
|
32
|
-
const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
|
|
37
|
+
const { theme, children, themeOptions, ...rest } = props;
|
|
33
38
|
const rootRef = React.useRef(null);
|
|
34
39
|
const mergedRefs = useMergedRefs(rootRef, ref);
|
|
35
40
|
const hasChildren = React.Children.count(children) > 0;
|
|
36
41
|
const parentContext = React.useContext(ThemeContext);
|
|
42
|
+
const contextValue = React.useMemo(() => ({ theme, themeOptions, rootRef }), [theme, themeOptions]);
|
|
43
|
+
// if no children, then fallback to this wrapper component which calls useTheme
|
|
44
|
+
if (!hasChildren) {
|
|
45
|
+
return (React.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 }));
|
|
46
|
+
}
|
|
47
|
+
// now that we know there are children, we can render the root and provide the context value
|
|
48
|
+
return (React.createElement(Root, { theme: theme, themeOptions: themeOptions, ref: mergedRefs, ...rest },
|
|
49
|
+
React.createElement(ThemeContext.Provider, { value: contextValue }, children)));
|
|
50
|
+
});
|
|
51
|
+
export default ThemeProvider;
|
|
52
|
+
export const ThemeContext = React.createContext(undefined);
|
|
53
|
+
const Root = React.forwardRef((props, forwardedRef) => {
|
|
54
|
+
var _a, _b, _c;
|
|
55
|
+
const { theme, children, themeOptions, as: Element = 'div', className, ...rest } = props;
|
|
56
|
+
const ref = React.useRef(null);
|
|
57
|
+
const mergedRefs = useMergedRefs(ref, forwardedRef);
|
|
37
58
|
const prefersDark = useMediaQuery('(prefers-color-scheme: dark)');
|
|
38
59
|
const prefersHighContrast = useMediaQuery('(prefers-contrast: more)');
|
|
39
60
|
const shouldApplyDark = theme === 'dark' || (theme === 'os' && prefersDark);
|
|
40
61
|
const shouldApplyHC = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast) !== null && _a !== void 0 ? _a : prefersHighContrast;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// otherwise just apply theme on the root using this wrapper component
|
|
45
|
-
React.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 }));
|
|
62
|
+
const isThemeAlreadySet = useIsThemeAlreadySet((_b = ref.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
|
|
63
|
+
const shouldApplyBackground = (_c = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.applyBackground) !== null && _c !== void 0 ? _c : !isThemeAlreadySet.current;
|
|
64
|
+
return (React.createElement(Element, { className: cx('iui-root', { 'iui-root-background': shouldApplyBackground }, className), "data-iui-theme": shouldApplyDark ? 'dark' : 'light', "data-iui-contrast": shouldApplyHC ? 'high' : 'default', ref: mergedRefs, ...rest }, children));
|
|
46
65
|
});
|
|
47
|
-
export default ThemeProvider;
|
|
48
|
-
export const ThemeContext = React.createContext(undefined);
|
|
49
66
|
const ThemeLogicWrapper = ({ theme, themeOptions }) => {
|
|
50
67
|
useTheme(theme, themeOptions);
|
|
51
68
|
return React.createElement(React.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.
|
|
@@ -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,27 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { ThemeContext } from '../../ThemeProvider/ThemeProvider';
|
|
7
|
+
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
|
|
8
|
+
import { getDocument } from '../functions';
|
|
9
|
+
/**
|
|
10
|
+
* Hook that returns a boolean ref which is true if either:
|
|
11
|
+
* - There is a parent `ThemeProvider` in the tree, or
|
|
12
|
+
* - The <body> element has data-iui-theme attribute
|
|
13
|
+
*/
|
|
14
|
+
export const useIsThemeAlreadySet = (ownerDocument = getDocument()) => {
|
|
15
|
+
const parentContext = React.useContext(ThemeContext);
|
|
16
|
+
const isThemeAlreadySet = React.useRef(!!parentContext || !!(ownerDocument === null || ownerDocument === void 0 ? void 0 : ownerDocument.body.dataset.iuiTheme));
|
|
17
|
+
useIsomorphicLayoutEffect(() => {
|
|
18
|
+
if (parentContext ||
|
|
19
|
+
(ownerDocument && !!ownerDocument.body.dataset.iuiTheme)) {
|
|
20
|
+
isThemeAlreadySet.current = true;
|
|
21
|
+
}
|
|
22
|
+
return () => {
|
|
23
|
+
isThemeAlreadySet.current = false;
|
|
24
|
+
};
|
|
25
|
+
}, [parentContext, ownerDocument]);
|
|
26
|
+
return isThemeAlreadySet;
|
|
27
|
+
};
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
3
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
|
-
import React from 'react';
|
|
6
|
-
import { ThemeContext } from '../../ThemeProvider/ThemeProvider';
|
|
7
5
|
import { getDocument, getWindow } from '../functions';
|
|
8
6
|
import { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect';
|
|
7
|
+
import { useIsThemeAlreadySet } from './useIsThemeAlreadySet';
|
|
9
8
|
import '@itwin/itwinui-css/css/global.css';
|
|
10
9
|
import '@itwin/itwinui-variables/index.css';
|
|
11
10
|
/**
|
|
@@ -19,11 +18,10 @@ import '@itwin/itwinui-variables/index.css';
|
|
|
19
18
|
*/
|
|
20
19
|
export const useTheme = (theme, themeOptions) => {
|
|
21
20
|
var _a;
|
|
22
|
-
const themeContext = React.useContext(ThemeContext);
|
|
23
21
|
const ownerDocument = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.ownerDocument) !== null && _a !== void 0 ? _a : getDocument();
|
|
22
|
+
const isThemeAlreadySet = useIsThemeAlreadySet(ownerDocument);
|
|
24
23
|
useIsomorphicLayoutEffect(() => {
|
|
25
|
-
|
|
26
|
-
if (themeContext || !ownerDocument || ownerDocument.body.dataset.iuiTheme) {
|
|
24
|
+
if (!ownerDocument || isThemeAlreadySet.current) {
|
|
27
25
|
return;
|
|
28
26
|
}
|
|
29
27
|
ownerDocument.body.classList.toggle('iui-root', true);
|
|
@@ -41,7 +39,7 @@ export const useTheme = (theme, themeOptions) => {
|
|
|
41
39
|
return;
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
}, [theme,
|
|
42
|
+
}, [theme, themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.highContrast, ownerDocument]);
|
|
45
43
|
};
|
|
46
44
|
/**
|
|
47
45
|
* Helper function to apply the specified theme, or detect the OS theme.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/itwinui-react",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"author": "Bentley Systems",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "cjs/index.js",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
],
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "yarn clean:build && tsc -p tsconfig.cjs.json && tsc -p tsconfig.esm.json",
|
|
50
|
-
"build:watch": "
|
|
51
|
-
"clean:build": "
|
|
50
|
+
"build:watch": "concurrently \"tsc -p tsconfig.cjs.json --watch\" \"tsc -p tsconfig.esm.json --watch\"",
|
|
51
|
+
"clean:build": "rimraf esm && rimraf cjs",
|
|
52
52
|
"clean:coverage": "rimraf coverage",
|
|
53
53
|
"clean": "rimraf .turbo && yarn clean:coverage && yarn clean:build && rimraf node_modules",
|
|
54
54
|
"test": "jest",
|
|
@@ -56,11 +56,14 @@
|
|
|
56
56
|
"format": "prettier --config .prettierrc **/*.{tsx,ts,js} --ignore-path .gitignore --write",
|
|
57
57
|
"lint": "eslint \"**/*.{js,ts,tsx}\" --max-warnings=0",
|
|
58
58
|
"lint:fix": "yarn lint --fix && node ../configs/copyrightLinter.js --fix \"*/**/*.{js,ts,tsx}\"",
|
|
59
|
-
"dev": "yarn build:
|
|
59
|
+
"dev": "yarn clean:build && concurrently \"yarn dev:esm\" \"yarn dev:cjs\" \"yarn dev:types\"",
|
|
60
|
+
"dev:esm": "swc src -d esm --watch",
|
|
61
|
+
"dev:cjs": "swc src -d cjs --watch -C module.type=commonjs",
|
|
62
|
+
"dev:types": "concurrently \"tsc -p tsconfig.cjs.json --emitDeclarationOnly --watch --preserveWatchOutput\" \"tsc -p tsconfig.esm.json --emitDeclarationOnly --watch --preserveWatchOutput\"",
|
|
60
63
|
"createComponent": "node ../../scripts/createComponent.js"
|
|
61
64
|
},
|
|
62
65
|
"dependencies": {
|
|
63
|
-
"@itwin/itwinui-css": "^1.
|
|
66
|
+
"@itwin/itwinui-css": "^1.2.0",
|
|
64
67
|
"@itwin/itwinui-illustrations-react": "^2.0.0",
|
|
65
68
|
"@itwin/itwinui-variables": "^1.0.0",
|
|
66
69
|
"@tippyjs/react": "^4.2.6",
|
|
@@ -72,6 +75,8 @@
|
|
|
72
75
|
},
|
|
73
76
|
"devDependencies": {
|
|
74
77
|
"@babel/core": "^7.12.10",
|
|
78
|
+
"@swc/cli": "^0.1.57",
|
|
79
|
+
"@swc/core": "^1.3.21",
|
|
75
80
|
"@testing-library/jest-dom": "^5.16.4",
|
|
76
81
|
"@testing-library/react": "^13.2.0",
|
|
77
82
|
"@testing-library/user-event": "^14.1.1",
|