@itwin/itwinui-react 2.6.0 → 2.7.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 +43 -0
- 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/Slider/Thumb.js +2 -4
- package/cjs/core/Tabs/Tabs.js +3 -1
- package/cjs/core/Tile/Tile.d.ts +24 -2
- package/cjs/core/Tile/Tile.js +85 -50
- package/cjs/core/ToggleSwitch/ToggleSwitch.d.ts +11 -31
- package/cjs/core/ToggleSwitch/ToggleSwitch.js +8 -1
- package/cjs/core/index.d.ts +2 -2
- package/cjs/core/index.js +3 -1
- package/cjs/core/utils/components/LinkAction.d.ts +30 -0
- package/cjs/core/utils/components/LinkAction.js +44 -0
- package/cjs/core/utils/components/index.d.ts +1 -0
- package/cjs/core/utils/components/index.js +1 -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/useIsClient.d.ts +1 -0
- package/cjs/core/utils/hooks/useIsClient.js +19 -0
- package/cjs/core/utils/hooks/useTheme.js +5 -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/Slider/Thumb.js +2 -4
- package/esm/core/Tabs/Tabs.js +4 -2
- package/esm/core/Tile/Tile.d.ts +24 -2
- package/esm/core/Tile/Tile.js +84 -49
- package/esm/core/ToggleSwitch/ToggleSwitch.d.ts +11 -31
- package/esm/core/ToggleSwitch/ToggleSwitch.js +8 -1
- package/esm/core/index.d.ts +2 -2
- package/esm/core/index.js +1 -1
- package/esm/core/utils/components/LinkAction.d.ts +30 -0
- package/esm/core/utils/components/LinkAction.js +38 -0
- package/esm/core/utils/components/index.d.ts +1 -0
- package/esm/core/utils/components/index.js +1 -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/useIsClient.d.ts +1 -0
- package/esm/core/utils/hooks/useIsClient.js +12 -0
- package/esm/core/utils/hooks/useTheme.js +5 -0
- package/package.json +2 -2
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { PolymorphicComponentProps, PolymorphicForwardRefComponent } from '../props';
|
|
2
|
+
import '@itwin/itwinui-css/css/utils.css';
|
|
3
|
+
declare type LinkActionOwnProps = {};
|
|
4
|
+
declare type LinkBoxOwnProps = {};
|
|
5
|
+
export declare type LinkActionProps = PolymorphicComponentProps<'a', LinkActionOwnProps>;
|
|
6
|
+
export declare type LinkBoxProps = PolymorphicComponentProps<'div', LinkBoxOwnProps>;
|
|
7
|
+
/**
|
|
8
|
+
* Polymorphic link action component.
|
|
9
|
+
* It is rendered as `a` by default.
|
|
10
|
+
* @example
|
|
11
|
+
* <LinkBox>
|
|
12
|
+
* <Surface>
|
|
13
|
+
* <LinkAction href='/new-page'>Whole card is clickable</LinkAction>
|
|
14
|
+
* </Surface>
|
|
15
|
+
* </LinkBox>
|
|
16
|
+
*/
|
|
17
|
+
export declare const LinkAction: PolymorphicForwardRefComponent<"a", LinkActionOwnProps>;
|
|
18
|
+
/**
|
|
19
|
+
* Polymorphic link box component.
|
|
20
|
+
* Used to wrap around your component to use LinkAction.
|
|
21
|
+
* Rendered as `div` by default
|
|
22
|
+
* @example
|
|
23
|
+
* <LinkBox>
|
|
24
|
+
* <Surface>
|
|
25
|
+
* <LinkAction href='/new-page'>Whole card is clickable</LinkAction>
|
|
26
|
+
* </Surface>
|
|
27
|
+
* </LinkBox>
|
|
28
|
+
*/
|
|
29
|
+
export declare const LinkBox: PolymorphicForwardRefComponent<"div", LinkBoxOwnProps>;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
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.LinkBox = exports.LinkAction = 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
|
+
require("@itwin/itwinui-css/css/utils.css");
|
|
14
|
+
/**
|
|
15
|
+
* Polymorphic link action component.
|
|
16
|
+
* It is rendered as `a` by default.
|
|
17
|
+
* @example
|
|
18
|
+
* <LinkBox>
|
|
19
|
+
* <Surface>
|
|
20
|
+
* <LinkAction href='/new-page'>Whole card is clickable</LinkAction>
|
|
21
|
+
* </Surface>
|
|
22
|
+
* </LinkBox>
|
|
23
|
+
*/
|
|
24
|
+
exports.LinkAction = react_1.default.forwardRef((props, ref) => {
|
|
25
|
+
const { as: Element = 'a', className, ...rest } = props;
|
|
26
|
+
return (react_1.default.createElement(Element, { ref: ref, className: (0, classnames_1.default)('iui-link-action', className), ...rest }));
|
|
27
|
+
});
|
|
28
|
+
exports.LinkAction.displayName = 'LinkAction';
|
|
29
|
+
/**
|
|
30
|
+
* Polymorphic link box component.
|
|
31
|
+
* Used to wrap around your component to use LinkAction.
|
|
32
|
+
* Rendered as `div` by default
|
|
33
|
+
* @example
|
|
34
|
+
* <LinkBox>
|
|
35
|
+
* <Surface>
|
|
36
|
+
* <LinkAction href='/new-page'>Whole card is clickable</LinkAction>
|
|
37
|
+
* </Surface>
|
|
38
|
+
* </LinkBox>
|
|
39
|
+
*/
|
|
40
|
+
exports.LinkBox = react_1.default.forwardRef((props, ref) => {
|
|
41
|
+
const { as: Element = 'div', className, ...rest } = props;
|
|
42
|
+
return (react_1.default.createElement(Element, { ref: ref, className: (0, classnames_1.default)('iui-link-box', className), ...rest }));
|
|
43
|
+
});
|
|
44
|
+
exports.LinkBox.displayName = 'LinkBox';
|
|
@@ -30,4 +30,5 @@ __exportStar(require("./useSafeContext"), exports);
|
|
|
30
30
|
__exportStar(require("./useLatestRef"), exports);
|
|
31
31
|
__exportStar(require("./useIsomorphicLayoutEffect"), exports);
|
|
32
32
|
__exportStar(require("./useIsThemeAlreadySet"), exports);
|
|
33
|
+
__exportStar(require("./useIsClient"), exports);
|
|
33
34
|
__exportStar(require("./useId"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const useIsClient: () => boolean;
|
|
@@ -0,0 +1,19 @@
|
|
|
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.useIsClient = 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 useIsClient = () => {
|
|
13
|
+
const [isClient, setIsClient] = react_1.default.useState(false);
|
|
14
|
+
react_1.default.useEffect(() => {
|
|
15
|
+
setIsClient(true);
|
|
16
|
+
}, []);
|
|
17
|
+
return isClient;
|
|
18
|
+
};
|
|
19
|
+
exports.useIsClient = useIsClient;
|
|
@@ -27,6 +27,11 @@ const useTheme = (theme, themeOptions) => {
|
|
|
27
27
|
if (!ownerDocument || isThemeAlreadySet.current) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
|
+
// do nothing if using v1 for the main page (incremental migration)
|
|
31
|
+
if (ownerDocument.documentElement.className.includes('iui-theme-') ||
|
|
32
|
+
ownerDocument.body.classList.contains('iui-body')) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
30
35
|
ownerDocument.body.classList.toggle('iui-root', true);
|
|
31
36
|
switch (theme) {
|
|
32
37
|
case 'light':
|
|
@@ -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
|
})));
|
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
|
};
|
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;
|
package/esm/core/Tile/Tile.js
CHANGED
|
@@ -4,11 +4,31 @@
|
|
|
4
4
|
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import cx from 'classnames';
|
|
7
|
-
import { StatusIconMap, useTheme, SvgMore, SvgNew, SvgCheckmark, } from '../utils';
|
|
7
|
+
import { StatusIconMap, useTheme, SvgMore, SvgNew, SvgCheckmark, LinkAction, useSafeContext, getWindow, } from '../utils';
|
|
8
8
|
import '@itwin/itwinui-css/css/tile.css';
|
|
9
9
|
import { DropdownMenu } from '../DropdownMenu';
|
|
10
10
|
import { IconButton } from '../Buttons';
|
|
11
11
|
import { ProgressRadial } from '../ProgressIndicators';
|
|
12
|
+
const TileContext = React.createContext(undefined);
|
|
13
|
+
/**
|
|
14
|
+
* Polymorphic Tile action component. Recommended to be used in a "name" of `Tile`.
|
|
15
|
+
* Renders `a` element by default.
|
|
16
|
+
* @example
|
|
17
|
+
* <Tile
|
|
18
|
+
* name={<Tile.Action href='/new-page'>Tile name<Tile.Action/>}
|
|
19
|
+
* />
|
|
20
|
+
*/
|
|
21
|
+
export const TileAction = (props) => {
|
|
22
|
+
var _a, _b, _c;
|
|
23
|
+
const tileContext = useSafeContext(TileContext);
|
|
24
|
+
const supportsHas = (_c = (_b = (_a = getWindow()) === null || _a === void 0 ? void 0 : _a.CSS) === null || _b === void 0 ? void 0 : _b.supports) === null || _c === void 0 ? void 0 : _c.call(_b, 'selector(:has(+ *))');
|
|
25
|
+
React.useEffect(() => {
|
|
26
|
+
if (!supportsHas) {
|
|
27
|
+
tileContext.setActionable(true);
|
|
28
|
+
}
|
|
29
|
+
}, [supportsHas, tileContext]);
|
|
30
|
+
return React.createElement(LinkAction, { ...props });
|
|
31
|
+
};
|
|
12
32
|
/**
|
|
13
33
|
* Tile component that displays content and actions in a card-like format.
|
|
14
34
|
* @example
|
|
@@ -26,58 +46,73 @@ import { ProgressRadial } from '../ProgressIndicators';
|
|
|
26
46
|
* isNew={false}
|
|
27
47
|
* />
|
|
28
48
|
*/
|
|
29
|
-
export const Tile = (props) => {
|
|
30
|
-
const { className, name, description, metadata, thumbnail, buttons, leftIcon, rightIcon, badge, isNew, isSelected, moreOptions, variant = 'default', children, isActionable, status, isLoading = false, isDisabled = false, ...rest } = props;
|
|
49
|
+
export const Tile = Object.assign((props) => {
|
|
50
|
+
const { className, name, description, metadata, thumbnail, buttons, leftIcon, rightIcon, badge, isNew, isSelected, moreOptions, variant = 'default', children, isActionable: isActionableProp, status, isLoading = false, isDisabled = false, onClick, ...rest } = props;
|
|
31
51
|
useTheme();
|
|
32
52
|
const [isMenuVisible, setIsMenuVisible] = React.useState(false);
|
|
33
53
|
const showMenu = React.useCallback(() => setIsMenuVisible(true), []);
|
|
34
54
|
const hideMenu = React.useCallback(() => setIsMenuVisible(false), []);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
'
|
|
53
|
-
}),
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
55
|
+
const [localActionable, setLocalActionable] = React.useState(isActionableProp);
|
|
56
|
+
const isActionable = isActionableProp !== null && isActionableProp !== void 0 ? isActionableProp : localActionable;
|
|
57
|
+
const tileName = (React.createElement("div", { className: 'iui-tile-name' },
|
|
58
|
+
React.createElement(TitleIcon, { isLoading: isLoading, isSelected: isSelected, isNew: isNew, status: status }),
|
|
59
|
+
React.createElement("span", { className: 'iui-tile-name-label' }, isActionable && onClick ? (React.createElement(LinkAction, { as: 'button', onClick: !isDisabled ? onClick : undefined, "aria-disabled": isDisabled }, name)) : (name))));
|
|
60
|
+
return (React.createElement(TileContext.Provider, { value: { setActionable: setLocalActionable } },
|
|
61
|
+
React.createElement("div", { className: cx('iui-tile', {
|
|
62
|
+
'iui-folder': variant === 'folder',
|
|
63
|
+
'iui-new': isNew,
|
|
64
|
+
'iui-selected': isSelected,
|
|
65
|
+
'iui-actionable': isActionable,
|
|
66
|
+
[`iui-${status}`]: !!status,
|
|
67
|
+
'iui-loading': isLoading,
|
|
68
|
+
}, className), "aria-disabled": isDisabled, ...rest },
|
|
69
|
+
variant !== 'folder' ? tileName : null,
|
|
70
|
+
thumbnail && (React.createElement("div", { className: 'iui-tile-thumbnail' },
|
|
71
|
+
typeof thumbnail === 'string' ? (React.createElement("div", { className: 'iui-tile-thumbnail-picture', style: { backgroundImage: `url(${thumbnail})` } })) : thumbnail && thumbnail.type === 'img' ? (React.cloneElement(thumbnail, {
|
|
72
|
+
className: 'iui-tile-thumbnail-picture',
|
|
73
|
+
})) : React.isValidElement(thumbnail) ? (React.cloneElement(thumbnail, {
|
|
74
|
+
className: cx('iui-thumbnail-icon', thumbnail.props.className),
|
|
75
|
+
})) : (thumbnail),
|
|
76
|
+
leftIcon &&
|
|
77
|
+
React.cloneElement(leftIcon, {
|
|
78
|
+
className: 'iui-tile-thumbnail-type-indicator',
|
|
79
|
+
'data-iui-size': 'small',
|
|
80
|
+
}),
|
|
81
|
+
rightIcon &&
|
|
82
|
+
React.cloneElement(rightIcon, {
|
|
83
|
+
className: 'iui-tile-thumbnail-quick-action',
|
|
84
|
+
'data-iui-size': 'small',
|
|
85
|
+
}),
|
|
86
|
+
badge && (React.createElement("div", { className: 'iui-tile-thumbnail-badge-container' }, badge)))),
|
|
87
|
+
React.createElement("div", { className: 'iui-tile-content' },
|
|
88
|
+
variant === 'folder' ? tileName : null,
|
|
89
|
+
description != undefined && (React.createElement("div", { className: 'iui-tile-description' }, description)),
|
|
90
|
+
metadata != undefined && (React.createElement("div", { className: 'iui-tile-metadata' }, metadata)),
|
|
91
|
+
moreOptions && (React.createElement(DropdownMenu, { onShow: showMenu, onHide: hideMenu, menuItems: (close) => moreOptions.map((option) => React.cloneElement(option, {
|
|
92
|
+
onClick: (value) => {
|
|
93
|
+
var _a, _b;
|
|
94
|
+
close();
|
|
95
|
+
(_b = (_a = option.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, value);
|
|
96
|
+
},
|
|
97
|
+
})) },
|
|
98
|
+
React.createElement("div", { className: cx('iui-tile-more-options', {
|
|
99
|
+
'iui-visible': isMenuVisible,
|
|
100
|
+
}) },
|
|
101
|
+
React.createElement(IconButton, { styleType: 'borderless', size: 'small', "aria-label": 'More options' },
|
|
102
|
+
React.createElement(SvgMore, null))))),
|
|
103
|
+
children),
|
|
104
|
+
buttons && React.createElement("div", { className: 'iui-tile-buttons' }, buttons))));
|
|
105
|
+
}, {
|
|
106
|
+
/**
|
|
107
|
+
* Polymorphic Tile action component. Recommended to be used in a "name" of `Tile`.
|
|
108
|
+
* Renders `a` element by default.
|
|
109
|
+
* @example
|
|
110
|
+
* <Tile
|
|
111
|
+
* name={<Tile.Action href='/new-page'>Tile name<Tile.Action/>}
|
|
112
|
+
* />
|
|
113
|
+
*/
|
|
114
|
+
Action: TileAction,
|
|
115
|
+
});
|
|
81
116
|
const TitleIcon = ({ isLoading = false, isSelected = false, isNew = false, status, }) => {
|
|
82
117
|
const StatusIcon = !!status && StatusIconMap[status];
|
|
83
118
|
if (isLoading) {
|