@itwin/itwinui-react 2.6.1 → 2.8.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 +73 -2
- package/cjs/core/Badge/Badge.d.ts +1 -1
- package/cjs/core/Badge/Badge.js +14 -15
- package/cjs/core/Carousel/Carousel.js +3 -2
- package/cjs/core/DatePicker/DatePicker.d.ts +5 -0
- package/cjs/core/DatePicker/DatePicker.js +26 -7
- package/cjs/core/Dialog/DialogMain.js +18 -23
- package/cjs/core/Slider/Thumb.js +2 -4
- package/cjs/core/Surface/Surface.d.ts +24 -2
- package/cjs/core/Surface/Surface.js +38 -2
- package/cjs/core/Surface/index.d.ts +1 -1
- package/cjs/core/Tabs/Tabs.js +3 -1
- package/cjs/core/Tile/Tile.d.ts +24 -2
- package/cjs/core/Tile/Tile.js +83 -50
- package/cjs/core/ToggleSwitch/ToggleSwitch.d.ts +11 -31
- package/cjs/core/ToggleSwitch/ToggleSwitch.js +8 -1
- package/cjs/core/index.d.ts +3 -3
- package/cjs/core/index.js +5 -1
- package/cjs/core/utils/components/Divider.d.ts +14 -0
- package/cjs/core/utils/components/Divider.js +23 -0
- package/cjs/core/utils/components/LinkAction.d.ts +30 -0
- package/cjs/core/utils/components/LinkAction.js +44 -0
- package/cjs/core/utils/components/Resizer.js +9 -9
- package/cjs/core/utils/components/VisuallyHidden.d.ts +20 -6
- package/cjs/core/utils/components/VisuallyHidden.js +10 -3
- package/cjs/core/utils/components/index.d.ts +2 -0
- package/cjs/core/utils/components/index.js +2 -0
- package/cjs/core/utils/functions/index.d.ts +1 -0
- package/cjs/core/utils/functions/index.js +1 -0
- package/cjs/core/utils/functions/supports.d.ts +4 -0
- package/cjs/core/utils/functions/supports.js +13 -0
- package/cjs/core/utils/hooks/index.d.ts +1 -0
- package/cjs/core/utils/hooks/index.js +1 -0
- package/cjs/core/utils/hooks/useDragAndDrop.js +4 -3
- package/cjs/core/utils/hooks/useIsClient.d.ts +1 -0
- package/cjs/core/utils/hooks/useIsClient.js +19 -0
- package/cjs/core/utils/hooks/useTheme.js +44 -0
- package/esm/core/Badge/Badge.d.ts +1 -1
- package/esm/core/Badge/Badge.js +14 -15
- package/esm/core/Carousel/Carousel.js +3 -2
- package/esm/core/DatePicker/DatePicker.d.ts +5 -0
- package/esm/core/DatePicker/DatePicker.js +26 -7
- package/esm/core/Dialog/DialogMain.js +19 -24
- package/esm/core/Slider/Thumb.js +2 -4
- package/esm/core/Surface/Surface.d.ts +24 -2
- package/esm/core/Surface/Surface.js +39 -3
- package/esm/core/Surface/index.d.ts +1 -1
- package/esm/core/Tabs/Tabs.js +4 -2
- package/esm/core/Tile/Tile.d.ts +24 -2
- package/esm/core/Tile/Tile.js +82 -49
- package/esm/core/ToggleSwitch/ToggleSwitch.d.ts +11 -31
- package/esm/core/ToggleSwitch/ToggleSwitch.js +8 -1
- package/esm/core/index.d.ts +3 -3
- package/esm/core/index.js +1 -1
- package/esm/core/utils/components/Divider.d.ts +14 -0
- package/esm/core/utils/components/Divider.js +17 -0
- package/esm/core/utils/components/LinkAction.d.ts +30 -0
- package/esm/core/utils/components/LinkAction.js +38 -0
- package/esm/core/utils/components/Resizer.js +9 -9
- package/esm/core/utils/components/VisuallyHidden.d.ts +20 -6
- package/esm/core/utils/components/VisuallyHidden.js +10 -3
- package/esm/core/utils/components/index.d.ts +2 -0
- package/esm/core/utils/components/index.js +2 -0
- package/esm/core/utils/functions/index.d.ts +1 -0
- package/esm/core/utils/functions/index.js +1 -0
- package/esm/core/utils/functions/supports.d.ts +4 -0
- package/esm/core/utils/functions/supports.js +9 -0
- package/esm/core/utils/hooks/index.d.ts +1 -0
- package/esm/core/utils/hooks/index.js +1 -0
- package/esm/core/utils/hooks/useDragAndDrop.js +4 -3
- package/esm/core/utils/hooks/useIsClient.d.ts +1 -0
- package/esm/core/utils/hooks/useIsClient.js +12 -0
- package/esm/core/utils/hooks/useTheme.js +21 -0
- package/package.json +2 -2
|
@@ -1,10 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
2
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
26
|
exports.useTheme = void 0;
|
|
4
27
|
/*---------------------------------------------------------------------------------------------
|
|
5
28
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
6
29
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
7
30
|
*--------------------------------------------------------------------------------------------*/
|
|
31
|
+
const React = __importStar(require("react"));
|
|
8
32
|
const functions_1 = require("../functions");
|
|
9
33
|
const useIsomorphicLayoutEffect_1 = require("./useIsomorphicLayoutEffect");
|
|
10
34
|
const useIsThemeAlreadySet_1 = require("./useIsThemeAlreadySet");
|
|
@@ -23,6 +47,7 @@ const useTheme = (theme, themeOptions) => {
|
|
|
23
47
|
var _a;
|
|
24
48
|
const ownerDocument = (_a = themeOptions === null || themeOptions === void 0 ? void 0 : themeOptions.ownerDocument) !== null && _a !== void 0 ? _a : (0, functions_1.getDocument)();
|
|
25
49
|
const isThemeAlreadySet = (0, useIsThemeAlreadySet_1.useIsThemeAlreadySet)(ownerDocument);
|
|
50
|
+
useCorrectRootFontSize();
|
|
26
51
|
(0, useIsomorphicLayoutEffect_1.useIsomorphicLayoutEffect)(() => {
|
|
27
52
|
if (!ownerDocument || isThemeAlreadySet.current) {
|
|
28
53
|
return;
|
|
@@ -81,3 +106,22 @@ const handleTheme = (theme, ownerDocument, highContrast) => {
|
|
|
81
106
|
(_b = prefersHCQuery === null || prefersHCQuery === void 0 ? void 0 : prefersHCQuery.removeEventListener) === null || _b === void 0 ? void 0 : _b.call(prefersHCQuery, 'change', changeHandler);
|
|
82
107
|
};
|
|
83
108
|
};
|
|
109
|
+
let didLogWarning = false;
|
|
110
|
+
let isDev = false;
|
|
111
|
+
// wrapping in try-catch because process might be undefined
|
|
112
|
+
try {
|
|
113
|
+
isDev = process.env.NODE_ENV !== 'production';
|
|
114
|
+
}
|
|
115
|
+
catch (_a) { }
|
|
116
|
+
/** Shows console error if the page changes the root font size */
|
|
117
|
+
const useCorrectRootFontSize = () => {
|
|
118
|
+
React.useEffect(() => {
|
|
119
|
+
if (isDev && !didLogWarning) {
|
|
120
|
+
const rootFontSize = parseInt(getComputedStyle(document.documentElement).fontSize);
|
|
121
|
+
if (rootFontSize < 16) {
|
|
122
|
+
console.error('Root font size must not be overridden. \nSee https://github.com/iTwin/iTwinUI/wiki/iTwinUI-react-v2-migration-guide#relative-font-size');
|
|
123
|
+
didLogWarning = true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}, []);
|
|
127
|
+
};
|
|
@@ -10,7 +10,7 @@ export declare type BadgeProps = {
|
|
|
10
10
|
*
|
|
11
11
|
* If not specified, a default neutral background will be used.
|
|
12
12
|
*/
|
|
13
|
-
backgroundColor?: 'primary' | 'positive' | 'negative' | 'warning' | keyof typeof SoftBackgrounds | AnyString;
|
|
13
|
+
backgroundColor?: 'primary' | 'informational' | 'positive' | 'negative' | 'warning' | keyof typeof SoftBackgrounds | AnyString;
|
|
14
14
|
/**
|
|
15
15
|
* Badge label.
|
|
16
16
|
* Always gets converted to uppercase, and truncated if too long.
|
package/esm/core/Badge/Badge.js
CHANGED
|
@@ -13,18 +13,14 @@ const getBadgeColorValue = (color) => {
|
|
|
13
13
|
if (!color) {
|
|
14
14
|
return '';
|
|
15
15
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return '#F9D7AB';
|
|
25
|
-
default:
|
|
26
|
-
return isSoftBackground(color) ? SoftBackgrounds[color] : color;
|
|
27
|
-
}
|
|
16
|
+
return isSoftBackground(color) ? SoftBackgrounds[color] : color;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Helper function that returns one of the preset badge status values.
|
|
20
|
+
*/
|
|
21
|
+
const getStatusValue = (color) => {
|
|
22
|
+
const statuses = ['positive', 'negative', 'warning', 'informational'];
|
|
23
|
+
return color && statuses.includes(color) ? color : undefined;
|
|
28
24
|
};
|
|
29
25
|
/**
|
|
30
26
|
* A colorful visual indicator for categorizing items.
|
|
@@ -36,12 +32,15 @@ const getBadgeColorValue = (color) => {
|
|
|
36
32
|
export const Badge = (props) => {
|
|
37
33
|
const { backgroundColor, style, className, children, ...rest } = props;
|
|
38
34
|
useTheme();
|
|
39
|
-
|
|
35
|
+
// choosing 'primary' status should result in data-iui-status equaling 'informational'
|
|
36
|
+
const reducedBackgroundColor = backgroundColor === 'primary' ? 'informational' : backgroundColor;
|
|
37
|
+
const statusValue = getStatusValue(reducedBackgroundColor);
|
|
38
|
+
const _style = reducedBackgroundColor && !statusValue
|
|
40
39
|
? {
|
|
41
|
-
'--iui-badge-background-color': getBadgeColorValue(
|
|
40
|
+
'--iui-badge-background-color': getBadgeColorValue(reducedBackgroundColor),
|
|
42
41
|
...style,
|
|
43
42
|
}
|
|
44
43
|
: { ...style };
|
|
45
|
-
return (React.createElement("span", { className: cx('iui-badge', className), style: _style, ...rest }, children));
|
|
44
|
+
return (React.createElement("span", { className: cx('iui-badge', className), style: _style, "data-iui-status": statusValue, ...rest }, children));
|
|
46
45
|
};
|
|
47
46
|
export default Badge;
|
|
@@ -60,8 +60,9 @@ export const Carousel = Object.assign(React.forwardRef((props, ref) => {
|
|
|
60
60
|
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
|
|
61
61
|
return;
|
|
62
62
|
}
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
const key = event.key;
|
|
64
|
+
if (key === 'ArrowLeft' || key === 'ArrowRight') {
|
|
65
|
+
setKeysPressed((old) => ({ ...old, [key]: true }));
|
|
65
66
|
}
|
|
66
67
|
};
|
|
67
68
|
const handleKeyUp = (event) => {
|
|
@@ -61,6 +61,11 @@ export declare type DatePickerProps = {
|
|
|
61
61
|
* @default false
|
|
62
62
|
*/
|
|
63
63
|
showYearSelection?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Will disable dates for which this function returns true.
|
|
66
|
+
* Disabled dates cannot be selected.
|
|
67
|
+
*/
|
|
68
|
+
isDateDisabled?: (date: Date) => boolean;
|
|
64
69
|
} & DateRangePickerProps & Omit<TimePickerProps, 'date' | 'onChange' | 'setFocusHour'>;
|
|
65
70
|
/**
|
|
66
71
|
* Date picker component
|
|
@@ -123,7 +123,7 @@ export const generateLocalizedStrings = (locale) => {
|
|
|
123
123
|
*/
|
|
124
124
|
export const DatePicker = (props) => {
|
|
125
125
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
126
|
-
const { date, onChange, localizedNames, className, style, setFocus = false, showTime = false, use12Hours = false, precision, hourStep, minuteStep, secondStep, useCombinedRenderer, combinedRenderer, hourRenderer, minuteRenderer, secondRenderer, meridiemRenderer, showYearSelection = false, enableRangeSelect = false, startDate, endDate, ...rest } = props;
|
|
126
|
+
const { date, onChange, localizedNames, className, style, setFocus = false, showTime = false, use12Hours = false, precision, hourStep, minuteStep, secondStep, useCombinedRenderer, combinedRenderer, hourRenderer, minuteRenderer, secondRenderer, meridiemRenderer, showYearSelection = false, enableRangeSelect = false, startDate, endDate, isDateDisabled, ...rest } = props;
|
|
127
127
|
useTheme();
|
|
128
128
|
const monthNames = (_a = localizedNames === null || localizedNames === void 0 ? void 0 : localizedNames.months) !== null && _a !== void 0 ? _a : defaultMonths;
|
|
129
129
|
const shortDays = (_b = localizedNames === null || localizedNames === void 0 ? void 0 : localizedNames.shortDays) !== null && _b !== void 0 ? _b : defaultShortDays;
|
|
@@ -260,6 +260,10 @@ export const DatePicker = (props) => {
|
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
};
|
|
263
|
+
const isPreviousMonthDisabled = isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(new Date(displayedYear, displayedMonthIndex, 0));
|
|
264
|
+
const isNextMonthDisabled = isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(new Date(displayedYear, displayedMonthIndex + 1, 1));
|
|
265
|
+
const isPreviousYearDisabled = isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(new Date(displayedYear - 1, 11, 31));
|
|
266
|
+
const isNextYearDisabled = isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(new Date(displayedYear + 1, 0, 1));
|
|
263
267
|
const handleCalendarKeyDown = (event) => {
|
|
264
268
|
if (!focusedDay) {
|
|
265
269
|
return;
|
|
@@ -269,6 +273,9 @@ export const DatePicker = (props) => {
|
|
|
269
273
|
case 'ArrowDown':
|
|
270
274
|
adjustedFocusedDay.setDate(focusedDay.getDate() + 7);
|
|
271
275
|
if (adjustedFocusedDay.getMonth() !== displayedMonthIndex) {
|
|
276
|
+
if (isNextMonthDisabled) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
272
279
|
handleMoveToNextMonth();
|
|
273
280
|
}
|
|
274
281
|
setFocusedDay(adjustedFocusedDay);
|
|
@@ -278,6 +285,9 @@ export const DatePicker = (props) => {
|
|
|
278
285
|
case 'ArrowUp':
|
|
279
286
|
adjustedFocusedDay.setDate(focusedDay.getDate() - 7);
|
|
280
287
|
if (adjustedFocusedDay.getMonth() !== displayedMonthIndex) {
|
|
288
|
+
if (isPreviousMonthDisabled) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
281
291
|
handleMoveToPreviousMonth();
|
|
282
292
|
}
|
|
283
293
|
setFocusedDay(adjustedFocusedDay);
|
|
@@ -287,6 +297,9 @@ export const DatePicker = (props) => {
|
|
|
287
297
|
case 'ArrowLeft':
|
|
288
298
|
adjustedFocusedDay.setDate(focusedDay.getDate() - 1);
|
|
289
299
|
if (adjustedFocusedDay.getMonth() !== displayedMonthIndex) {
|
|
300
|
+
if (isPreviousMonthDisabled) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
290
303
|
handleMoveToPreviousMonth();
|
|
291
304
|
}
|
|
292
305
|
setFocusedDay(adjustedFocusedDay);
|
|
@@ -296,6 +309,9 @@ export const DatePicker = (props) => {
|
|
|
296
309
|
case 'ArrowRight':
|
|
297
310
|
adjustedFocusedDay.setDate(focusedDay.getDate() + 1);
|
|
298
311
|
if (adjustedFocusedDay.getMonth() !== displayedMonthIndex) {
|
|
312
|
+
if (isNextMonthDisabled) {
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
299
315
|
handleMoveToNextMonth();
|
|
300
316
|
}
|
|
301
317
|
setFocusedDay(adjustedFocusedDay);
|
|
@@ -305,7 +321,9 @@ export const DatePicker = (props) => {
|
|
|
305
321
|
case 'Enter':
|
|
306
322
|
case ' ':
|
|
307
323
|
case 'Spacebar':
|
|
308
|
-
|
|
324
|
+
if (!(isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(focusedDay))) {
|
|
325
|
+
onDayClick(focusedDay);
|
|
326
|
+
}
|
|
309
327
|
event.preventDefault();
|
|
310
328
|
break;
|
|
311
329
|
}
|
|
@@ -340,23 +358,24 @@ export const DatePicker = (props) => {
|
|
|
340
358
|
return (React.createElement("div", { className: cx('iui-date-picker', className), style: style, ...rest },
|
|
341
359
|
React.createElement("div", null,
|
|
342
360
|
React.createElement("div", { className: 'iui-calendar-month-year' },
|
|
343
|
-
showYearSelection && (React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousYear, "aria-label": 'Previous year', size: 'small' },
|
|
361
|
+
showYearSelection && (React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousYear, "aria-label": 'Previous year', size: 'small', disabled: isPreviousYearDisabled },
|
|
344
362
|
React.createElement(SvgChevronLeftDouble, null))),
|
|
345
|
-
React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousMonth, "aria-label": 'Previous month', size: 'small' },
|
|
363
|
+
React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousMonth, "aria-label": 'Previous month', size: 'small', disabled: isPreviousMonthDisabled },
|
|
346
364
|
React.createElement(SvgChevronLeft, null)),
|
|
347
365
|
React.createElement("span", { "aria-live": 'polite' },
|
|
348
366
|
React.createElement("span", { className: 'iui-calendar-month', title: monthNames[displayedMonthIndex] }, monthNames[displayedMonthIndex]),
|
|
349
367
|
"\u00A0",
|
|
350
368
|
displayedYear),
|
|
351
|
-
React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextMonth, "aria-label": 'Next month', size: 'small' },
|
|
369
|
+
React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextMonth, "aria-label": 'Next month', size: 'small', disabled: isNextMonthDisabled },
|
|
352
370
|
React.createElement(SvgChevronRight, null)),
|
|
353
|
-
showYearSelection && (React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextYear, "aria-label": 'Next year', size: 'small' },
|
|
371
|
+
showYearSelection && (React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextYear, "aria-label": 'Next year', size: 'small', disabled: isNextYearDisabled },
|
|
354
372
|
React.createElement(SvgChevronRightDouble, null)))),
|
|
355
373
|
React.createElement("div", { className: 'iui-calendar-weekdays' }, shortDays.map((day, index) => (React.createElement("div", { key: day, title: longDays[index] }, day)))),
|
|
356
374
|
React.createElement("div", { onKeyDown: handleCalendarKeyDown, role: 'listbox' }, weeks.map((weekDays, weekIndex) => {
|
|
357
375
|
return (React.createElement("div", { key: `week-${displayedMonthIndex}-${weekIndex}`, className: 'iui-calendar-week' }, weekDays.map((weekDay, dayIndex) => {
|
|
358
376
|
const dateValue = weekDay.getDate();
|
|
359
|
-
|
|
377
|
+
const isDisabled = isDateDisabled === null || isDateDisabled === void 0 ? void 0 : isDateDisabled(weekDay);
|
|
378
|
+
return (React.createElement("div", { key: `day-${displayedMonthIndex}-${dayIndex}`, className: getDayClass(weekDay), onClick: () => !isDisabled && onDayClick(weekDay), role: 'option', tabIndex: isSameDay(weekDay, focusedDay) ? 0 : -1, "aria-disabled": isDisabled ? 'true' : undefined, ref: (element) => isSameDay(weekDay, focusedDay) &&
|
|
360
379
|
needFocus.current &&
|
|
361
380
|
(element === null || element === void 0 ? void 0 : element.focus()) }, dateValue));
|
|
362
381
|
})));
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import { FocusTrap, getTranslateValues,
|
|
7
|
+
import { FocusTrap, getTranslateValues, Resizer, useMergedRefs, useTheme, useIsomorphicLayoutEffect, } from '../utils';
|
|
8
8
|
import '@itwin/itwinui-css/css/dialog.css';
|
|
9
9
|
import { useDialogContext } from './DialogContext';
|
|
10
10
|
import { CSSTransition } from 'react-transition-group';
|
|
@@ -38,28 +38,7 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
38
38
|
const dialogRef = React.useRef(null);
|
|
39
39
|
const refs = useMergedRefs(dialogRef, ref);
|
|
40
40
|
const hasBeenResized = React.useRef(false);
|
|
41
|
-
// Focuses dialog when opened and brings back focus to the previously focused element when closed.
|
|
42
41
|
const previousFocusedElement = React.useRef();
|
|
43
|
-
const setFocusRef = useLatestRef(setFocus);
|
|
44
|
-
React.useEffect(() => {
|
|
45
|
-
var _a, _b, _c;
|
|
46
|
-
if (!setFocusRef.current) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
if (isOpen) {
|
|
50
|
-
previousFocusedElement.current = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.activeElement;
|
|
51
|
-
(_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.focus();
|
|
52
|
-
}
|
|
53
|
-
else {
|
|
54
|
-
(_c = previousFocusedElement.current) === null || _c === void 0 ? void 0 : _c.focus();
|
|
55
|
-
}
|
|
56
|
-
const ref = dialogRef.current;
|
|
57
|
-
return () => {
|
|
58
|
-
var _a;
|
|
59
|
-
(ref === null || ref === void 0 ? void 0 : ref.contains(document.activeElement)) &&
|
|
60
|
-
((_a = previousFocusedElement.current) === null || _a === void 0 ? void 0 : _a.focus());
|
|
61
|
-
};
|
|
62
|
-
}, [isOpen, setFocusRef]);
|
|
63
42
|
const originalBodyOverflow = React.useRef('');
|
|
64
43
|
React.useEffect(() => {
|
|
65
44
|
if (isOpen) {
|
|
@@ -130,7 +109,6 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
130
109
|
const content = (React.createElement("div", { className: cx('iui-dialog', {
|
|
131
110
|
'iui-dialog-default': styleType === 'default',
|
|
132
111
|
'iui-dialog-full-page': styleType === 'fullPage',
|
|
133
|
-
'iui-dialog-visible': isOpen,
|
|
134
112
|
'iui-dialog-draggable': isDraggable,
|
|
135
113
|
}, className), role: 'dialog', ref: refs, onKeyDown: handleKeyDown, tabIndex: -1, style: {
|
|
136
114
|
transform,
|
|
@@ -145,7 +123,24 @@ export const DialogMain = React.forwardRef((props, ref) => {
|
|
|
145
123
|
}
|
|
146
124
|
}, onResizeEnd: setResizeStyle })),
|
|
147
125
|
children));
|
|
148
|
-
return (React.createElement(CSSTransition, { in: isOpen, classNames:
|
|
126
|
+
return (React.createElement(CSSTransition, { in: isOpen, classNames: {
|
|
127
|
+
enter: 'iui-dialog-animation-enter',
|
|
128
|
+
enterActive: 'iui-dialog-animation-enter-active',
|
|
129
|
+
enterDone: 'iui-dialog-visible',
|
|
130
|
+
}, timeout: { exit: 600 },
|
|
131
|
+
// Focuses dialog when opened
|
|
132
|
+
onEntered: () => {
|
|
133
|
+
var _a, _b;
|
|
134
|
+
previousFocusedElement.current = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.activeElement;
|
|
135
|
+
setFocus && ((_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.focus({ preventScroll: true }));
|
|
136
|
+
},
|
|
137
|
+
// Brings back focus to the previously focused element when closed
|
|
138
|
+
onExit: () => {
|
|
139
|
+
var _a, _b, _c;
|
|
140
|
+
if ((_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.contains((_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.activeElement)) {
|
|
141
|
+
(_c = previousFocusedElement.current) === null || _c === void 0 ? void 0 : _c.focus();
|
|
142
|
+
}
|
|
143
|
+
}, unmountOnExit: true, nodeRef: dialogRef },
|
|
149
144
|
React.createElement(DialogDragContext.Provider, { value: { onPointerDown: handlePointerDown } },
|
|
150
145
|
trapFocus && React.createElement(FocusTrap, null, content),
|
|
151
146
|
!trapFocus && content)));
|
package/esm/core/Slider/Thumb.js
CHANGED
|
@@ -40,8 +40,6 @@ export const Thumb = (props) => {
|
|
|
40
40
|
const handlePointerDownOnThumb = React.useCallback(() => {
|
|
41
41
|
!disabled && onThumbActivated(index);
|
|
42
42
|
}, [disabled, index, onThumbActivated]);
|
|
43
|
-
const [hasFocus, setHasFocus] = React.useState(false);
|
|
44
|
-
const [isHovered, setIsHovered] = React.useState(false);
|
|
45
43
|
const adjustedValue = React.useMemo(() => {
|
|
46
44
|
if (value < sliderMin) {
|
|
47
45
|
return sliderMin;
|
|
@@ -58,11 +56,11 @@ export const Thumb = (props) => {
|
|
|
58
56
|
return (100.0 * (adjustedValue - sliderMin)) / (sliderMax - sliderMin);
|
|
59
57
|
}, [adjustedValue, sliderMax, sliderMin]);
|
|
60
58
|
const { style, className, ...rest } = thumbProps || {};
|
|
61
|
-
return (React.createElement(Tooltip, {
|
|
59
|
+
return (React.createElement(Tooltip, { placement: 'top', trigger: (tooltipProps === null || tooltipProps === void 0 ? void 0 : tooltipProps.visible) == null ? 'mouseenter click focus' : undefined, ...tooltipProps },
|
|
62
60
|
React.createElement("div", { ...rest, "data-index": index, ref: thumbRef, style: {
|
|
63
61
|
...style,
|
|
64
62
|
...(orientation === 'horizontal'
|
|
65
63
|
? { left: `${lowPercent}%` }
|
|
66
64
|
: { bottom: `${lowPercent}%` }),
|
|
67
|
-
}, className: cx('iui-slider-thumb', { 'iui-active': isActive }, className), role: 'slider', tabIndex: disabled ? undefined : 0, "aria-valuemin": minVal, "aria-valuenow": value, "aria-valuemax": maxVal, "aria-disabled": disabled, onPointerDown: handlePointerDownOnThumb, onKeyDown: (event) => handleOnKeyboardEvent(event, false), onKeyUp: (event) => handleOnKeyboardEvent(event, true)
|
|
65
|
+
}, className: cx('iui-slider-thumb', { 'iui-active': isActive }, className), role: 'slider', tabIndex: disabled ? undefined : 0, "aria-valuemin": minVal, "aria-valuenow": value, "aria-valuemax": maxVal, "aria-disabled": disabled, onPointerDown: handlePointerDownOnThumb, onKeyDown: (event) => handleOnKeyboardEvent(event, false), onKeyUp: (event) => handleOnKeyboardEvent(event, true) })));
|
|
68
66
|
};
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { CommonProps } from '../utils';
|
|
2
|
+
import { CommonProps, PolymorphicComponentProps, PolymorphicForwardRefComponent } from '../utils';
|
|
3
3
|
import '@itwin/itwinui-css/css/surface.css';
|
|
4
|
+
declare type SurfaceHeaderOwnProps = {};
|
|
5
|
+
export declare type SurfaceHeaderProps<T extends React.ElementType = 'div'> = PolymorphicComponentProps<T, SurfaceHeaderOwnProps>;
|
|
6
|
+
declare type SurfaceBodyOwnProps = {
|
|
7
|
+
/**
|
|
8
|
+
* Gives padding to the surface body
|
|
9
|
+
*/
|
|
10
|
+
isPadded?: boolean;
|
|
11
|
+
};
|
|
12
|
+
export declare type SurfaceBodyProps<T extends React.ElementType = 'div'> = PolymorphicComponentProps<T, SurfaceBodyOwnProps>;
|
|
4
13
|
export declare type SurfaceProps = {
|
|
5
14
|
/**
|
|
6
15
|
* Sets the elevation of the surface
|
|
@@ -16,6 +25,10 @@ export declare type SurfaceProps = {
|
|
|
16
25
|
* @example
|
|
17
26
|
* <Surface>Surface Content</Surface>
|
|
18
27
|
* <Surface elevation={2}>Surface Content</Surface>
|
|
28
|
+
* <Surface>
|
|
29
|
+
* <Surface.Header>Surface Header Content</Surface.Header>
|
|
30
|
+
* <Surface.Body isPadded={true}>Surface Body Content</Surface.Body>
|
|
31
|
+
* </Surface>
|
|
19
32
|
*/
|
|
20
33
|
export declare const Surface: React.ForwardRefExoticComponent<{
|
|
21
34
|
/**
|
|
@@ -26,5 +39,14 @@ export declare const Surface: React.ForwardRefExoticComponent<{
|
|
|
26
39
|
* Content in the surface.
|
|
27
40
|
*/
|
|
28
41
|
children: React.ReactNode;
|
|
29
|
-
} & Omit<CommonProps, "title"> & React.RefAttributes<HTMLDivElement
|
|
42
|
+
} & Omit<CommonProps, "title"> & React.RefAttributes<HTMLDivElement>> & {
|
|
43
|
+
/**
|
|
44
|
+
* Surface header subcomponent
|
|
45
|
+
*/
|
|
46
|
+
Header: PolymorphicForwardRefComponent<"div", SurfaceHeaderOwnProps>;
|
|
47
|
+
/**
|
|
48
|
+
* Surface body subcomponent. Additional padding can be added to the body through the 'isPadded' prop
|
|
49
|
+
*/
|
|
50
|
+
Body: PolymorphicForwardRefComponent<"div", SurfaceBodyOwnProps>;
|
|
51
|
+
};
|
|
30
52
|
export default Surface;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import { useTheme } from '../utils';
|
|
7
|
+
import { useSafeContext, useTheme, supportsHas, } from '../utils';
|
|
8
8
|
import '@itwin/itwinui-css/css/surface.css';
|
|
9
9
|
/**
|
|
10
10
|
* Helper function that returns one of the preset surface elevation values.
|
|
@@ -27,19 +27,55 @@ const getSurfaceElevationValue = (elevation) => {
|
|
|
27
27
|
return '';
|
|
28
28
|
}
|
|
29
29
|
};
|
|
30
|
+
const SurfaceHeader = React.forwardRef((props, ref) => {
|
|
31
|
+
const { as: Element = 'div', children, className, ...rest } = props;
|
|
32
|
+
const { setHasLayout } = useSafeContext(SurfaceContext);
|
|
33
|
+
React.useEffect(() => {
|
|
34
|
+
if (!supportsHas()) {
|
|
35
|
+
setHasLayout(true);
|
|
36
|
+
}
|
|
37
|
+
}, [setHasLayout]);
|
|
38
|
+
return (React.createElement(Element, { className: cx('iui-surface-header', className), ref: ref, ...rest }, children));
|
|
39
|
+
});
|
|
40
|
+
const SurfaceBody = React.forwardRef((props, ref) => {
|
|
41
|
+
const { as: Element = 'div', children, className, isPadded, ...rest } = props;
|
|
42
|
+
const { setHasLayout } = useSafeContext(SurfaceContext);
|
|
43
|
+
React.useEffect(() => {
|
|
44
|
+
if (!supportsHas()) {
|
|
45
|
+
setHasLayout(true);
|
|
46
|
+
}
|
|
47
|
+
}, [setHasLayout]);
|
|
48
|
+
return (React.createElement(Element, { className: cx('iui-surface-body', className), ref: ref, "data-iui-padded": isPadded ? 'true' : undefined, ...rest }, children));
|
|
49
|
+
});
|
|
30
50
|
/**
|
|
31
51
|
* The Surface container allows content to appear elevated through the use of a drop shadow
|
|
32
52
|
* @example
|
|
33
53
|
* <Surface>Surface Content</Surface>
|
|
34
54
|
* <Surface elevation={2}>Surface Content</Surface>
|
|
55
|
+
* <Surface>
|
|
56
|
+
* <Surface.Header>Surface Header Content</Surface.Header>
|
|
57
|
+
* <Surface.Body isPadded={true}>Surface Body Content</Surface.Body>
|
|
58
|
+
* </Surface>
|
|
35
59
|
*/
|
|
36
|
-
export const Surface = React.forwardRef((props, ref) => {
|
|
60
|
+
export const Surface = Object.assign(React.forwardRef((props, ref) => {
|
|
37
61
|
const { elevation, className, style, children, ...rest } = props;
|
|
38
62
|
useTheme();
|
|
63
|
+
const [hasLayout, setHasLayout] = React.useState(false);
|
|
39
64
|
const _style = {
|
|
40
65
|
'--iui-surface-elevation': getSurfaceElevationValue(elevation),
|
|
41
66
|
...style,
|
|
42
67
|
};
|
|
43
|
-
return (React.createElement("div", { className: cx('iui-surface', className), style: _style, ref: ref, ...rest },
|
|
68
|
+
return (React.createElement("div", { className: cx('iui-surface', className), style: _style, ref: ref, "data-iui-layout": hasLayout ? 'true' : undefined, ...rest },
|
|
69
|
+
React.createElement(SurfaceContext.Provider, { value: { setHasLayout } }, children)));
|
|
70
|
+
}), {
|
|
71
|
+
/**
|
|
72
|
+
* Surface header subcomponent
|
|
73
|
+
*/
|
|
74
|
+
Header: SurfaceHeader,
|
|
75
|
+
/**
|
|
76
|
+
* Surface body subcomponent. Additional padding can be added to the body through the 'isPadded' prop
|
|
77
|
+
*/
|
|
78
|
+
Body: SurfaceBody,
|
|
44
79
|
});
|
|
80
|
+
const SurfaceContext = React.createContext(undefined);
|
|
45
81
|
export default Surface;
|
package/esm/core/Tabs/Tabs.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import cx from 'classnames';
|
|
6
6
|
import React from 'react';
|
|
7
|
-
import { useTheme, useMergedRefs, getBoundedValue, useContainerWidth, useIsomorphicLayoutEffect, } from '../utils';
|
|
7
|
+
import { useTheme, useMergedRefs, getBoundedValue, useContainerWidth, useIsomorphicLayoutEffect, useIsClient, } from '../utils';
|
|
8
8
|
import '@itwin/itwinui-css/css/tabs.css';
|
|
9
9
|
import { Tab } from './Tab';
|
|
10
10
|
/**
|
|
@@ -44,6 +44,7 @@ export const Tabs = (props) => {
|
|
|
44
44
|
}
|
|
45
45
|
const { labels, activeIndex, onTabSelected, focusActivationMode = 'auto', type = 'default', color = 'blue', orientation = 'horizontal', tabsClassName, contentClassName, wrapperClassName, children, ...rest } = props;
|
|
46
46
|
useTheme();
|
|
47
|
+
const isClient = useIsClient();
|
|
47
48
|
const tablistRef = React.useRef(null);
|
|
48
49
|
const [tablistSizeRef, tabsWidth] = useContainerWidth(type !== 'default');
|
|
49
50
|
const refs = useMergedRefs(tablistRef, tablistSizeRef);
|
|
@@ -155,7 +156,8 @@ export const Tabs = (props) => {
|
|
|
155
156
|
return (React.createElement("div", { className: cx('iui-tabs-wrapper', `iui-${orientation}`, wrapperClassName), style: stripeProperties },
|
|
156
157
|
React.createElement("ul", { className: cx('iui-tabs', `iui-${type}`, {
|
|
157
158
|
'iui-green': color === 'green',
|
|
158
|
-
'iui-animated': type !== 'default',
|
|
159
|
+
'iui-animated': type !== 'default' && isClient,
|
|
160
|
+
'iui-not-animated': type !== 'default' && !isClient,
|
|
159
161
|
'iui-large': hasSublabel,
|
|
160
162
|
}, tabsClassName), role: 'tablist', ref: refs, onKeyDown: onKeyDown, ...rest }, labels.map((label, index) => {
|
|
161
163
|
const onClick = () => {
|
package/esm/core/Tile/Tile.d.ts
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
+
import { PolymorphicComponentProps } from '../utils';
|
|
2
3
|
import '@itwin/itwinui-css/css/tile.css';
|
|
4
|
+
declare type TileActionOwnProps = {};
|
|
5
|
+
/**
|
|
6
|
+
* Polymorphic Tile action component. Recommended to be used in a "name" of `Tile`.
|
|
7
|
+
* Renders `a` element by default.
|
|
8
|
+
* @example
|
|
9
|
+
* <Tile
|
|
10
|
+
* name={<Tile.Action href='/new-page'>Tile name<Tile.Action/>}
|
|
11
|
+
* />
|
|
12
|
+
*/
|
|
13
|
+
export declare const TileAction: (props: PolymorphicComponentProps<'a', TileActionOwnProps>) => JSX.Element;
|
|
3
14
|
export declare type TileProps = {
|
|
4
15
|
/**
|
|
5
16
|
* Name or title of the tile.
|
|
@@ -102,7 +113,8 @@ export declare type TileProps = {
|
|
|
102
113
|
* @default false
|
|
103
114
|
*/
|
|
104
115
|
isDisabled?: boolean;
|
|
105
|
-
|
|
116
|
+
onClick?: React.MouseEventHandler<HTMLElement>;
|
|
117
|
+
} & Omit<React.ComponentPropsWithoutRef<'div'>, 'onClick'>;
|
|
106
118
|
/**
|
|
107
119
|
* Tile component that displays content and actions in a card-like format.
|
|
108
120
|
* @example
|
|
@@ -120,5 +132,15 @@ export declare type TileProps = {
|
|
|
120
132
|
* isNew={false}
|
|
121
133
|
* />
|
|
122
134
|
*/
|
|
123
|
-
export declare const Tile: (props: TileProps) => JSX.Element
|
|
135
|
+
export declare const Tile: ((props: TileProps) => JSX.Element) & {
|
|
136
|
+
/**
|
|
137
|
+
* Polymorphic Tile action component. Recommended to be used in a "name" of `Tile`.
|
|
138
|
+
* Renders `a` element by default.
|
|
139
|
+
* @example
|
|
140
|
+
* <Tile
|
|
141
|
+
* name={<Tile.Action href='/new-page'>Tile name<Tile.Action/>}
|
|
142
|
+
* />
|
|
143
|
+
*/
|
|
144
|
+
Action: (props: PolymorphicComponentProps<'a', TileActionOwnProps>) => JSX.Element;
|
|
145
|
+
};
|
|
124
146
|
export default Tile;
|