@itwin/itwinui-react 1.34.2 → 1.35.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/cjs/core/ButtonGroup/ButtonGroup.js +1 -0
  3. package/cjs/core/Carousel/Carousel.d.ts +68 -0
  4. package/cjs/core/Carousel/Carousel.js +130 -0
  5. package/cjs/core/Carousel/CarouselContext.d.ts +37 -0
  6. package/cjs/core/Carousel/CarouselContext.js +12 -0
  7. package/cjs/core/Carousel/CarouselDot.d.ts +13 -0
  8. package/cjs/core/Carousel/CarouselDot.js +46 -0
  9. package/cjs/core/Carousel/CarouselDotsList.d.ts +32 -0
  10. package/cjs/core/Carousel/CarouselDotsList.js +132 -0
  11. package/cjs/core/Carousel/CarouselNavigation.d.ts +15 -0
  12. package/cjs/core/Carousel/CarouselNavigation.js +88 -0
  13. package/cjs/core/Carousel/CarouselSlide.d.ts +14 -0
  14. package/cjs/core/Carousel/CarouselSlide.js +63 -0
  15. package/cjs/core/Carousel/CarouselSlider.d.ts +5 -0
  16. package/cjs/core/Carousel/CarouselSlider.js +94 -0
  17. package/cjs/core/Carousel/index.d.ts +4 -0
  18. package/cjs/core/Carousel/index.js +10 -0
  19. package/cjs/core/DatePicker/DatePicker.d.ts +5 -0
  20. package/cjs/core/DatePicker/DatePicker.js +38 -13
  21. package/cjs/core/Modal/Modal.d.ts +5 -0
  22. package/cjs/core/Modal/Modal.js +11 -9
  23. package/cjs/core/Modal/ModalContent.d.ts +14 -0
  24. package/cjs/core/Modal/ModalContent.js +46 -0
  25. package/cjs/core/Modal/index.d.ts +2 -0
  26. package/cjs/core/Modal/index.js +3 -1
  27. package/cjs/core/Table/Table.js +8 -7
  28. package/cjs/core/index.d.ts +4 -2
  29. package/cjs/core/index.js +6 -2
  30. package/cjs/core/utils/hooks/index.d.ts +1 -0
  31. package/cjs/core/utils/hooks/index.js +1 -0
  32. package/cjs/core/utils/hooks/useMediaQuery.d.ts +2 -0
  33. package/cjs/core/utils/hooks/useMediaQuery.js +46 -0
  34. package/cjs/core/utils/hooks/useTheme.d.ts +5 -0
  35. package/cjs/core/utils/hooks/useTheme.js +20 -14
  36. package/esm/core/ButtonGroup/ButtonGroup.js +1 -0
  37. package/esm/core/Carousel/Carousel.d.ts +68 -0
  38. package/esm/core/Carousel/Carousel.js +124 -0
  39. package/esm/core/Carousel/CarouselContext.d.ts +37 -0
  40. package/esm/core/Carousel/CarouselContext.js +6 -0
  41. package/esm/core/Carousel/CarouselDot.d.ts +13 -0
  42. package/esm/core/Carousel/CarouselDot.js +40 -0
  43. package/esm/core/Carousel/CarouselDotsList.d.ts +32 -0
  44. package/esm/core/Carousel/CarouselDotsList.js +126 -0
  45. package/esm/core/Carousel/CarouselNavigation.d.ts +15 -0
  46. package/esm/core/Carousel/CarouselNavigation.js +82 -0
  47. package/esm/core/Carousel/CarouselSlide.d.ts +14 -0
  48. package/esm/core/Carousel/CarouselSlide.js +57 -0
  49. package/esm/core/Carousel/CarouselSlider.d.ts +5 -0
  50. package/esm/core/Carousel/CarouselSlider.js +88 -0
  51. package/esm/core/Carousel/index.d.ts +4 -0
  52. package/esm/core/Carousel/index.js +6 -0
  53. package/esm/core/DatePicker/DatePicker.d.ts +5 -0
  54. package/esm/core/DatePicker/DatePicker.js +38 -13
  55. package/esm/core/Modal/Modal.d.ts +5 -0
  56. package/esm/core/Modal/Modal.js +11 -9
  57. package/esm/core/Modal/ModalContent.d.ts +14 -0
  58. package/esm/core/Modal/ModalContent.js +39 -0
  59. package/esm/core/Modal/index.d.ts +2 -0
  60. package/esm/core/Modal/index.js +1 -0
  61. package/esm/core/Table/Table.js +8 -7
  62. package/esm/core/index.d.ts +4 -2
  63. package/esm/core/index.js +2 -1
  64. package/esm/core/utils/hooks/index.d.ts +1 -0
  65. package/esm/core/utils/hooks/index.js +1 -0
  66. package/esm/core/utils/hooks/useMediaQuery.d.ts +2 -0
  67. package/esm/core/utils/hooks/useMediaQuery.js +39 -0
  68. package/esm/core/utils/hooks/useTheme.d.ts +5 -0
  69. package/esm/core/utils/hooks/useTheme.js +20 -14
  70. package/package.json +3 -2
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ /**
3
+ * `CarouselSlide` is used for the actual slide content. The content can be specified through `children`.
4
+ *
5
+ * It is recommended that the slide content bring its own dimensions (esp. height) and that
6
+ * the dimensions should be the same for all slides.
7
+ */
8
+ export declare const CarouselSlide: React.ForwardRefExoticComponent<{
9
+ /**
10
+ * Index of the current slide.
11
+ * Does not need to be manually specified because it will be set in parent (`CarouselSlider`).
12
+ */
13
+ index?: number | undefined;
14
+ } & Pick<React.DetailedHTMLProps<React.LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "key" | keyof React.LiHTMLAttributes<HTMLLIElement>> & React.RefAttributes<HTMLLIElement>>;
@@ -0,0 +1,57 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ /*---------------------------------------------------------------------------------------------
24
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
25
+ * See LICENSE.md in the project root for license terms and full copyright notice.
26
+ *--------------------------------------------------------------------------------------------*/
27
+ import React from 'react';
28
+ import cx from 'classnames';
29
+ import { useIntersection, useMergedRefs } from '../utils';
30
+ import { CarouselContext } from './CarouselContext';
31
+ /**
32
+ * `CarouselSlide` is used for the actual slide content. The content can be specified through `children`.
33
+ *
34
+ * It is recommended that the slide content bring its own dimensions (esp. height) and that
35
+ * the dimensions should be the same for all slides.
36
+ */
37
+ export var CarouselSlide = React.forwardRef(function (props, ref) {
38
+ var index = props.index, className = props.className, children = props.children, rest = __rest(props, ["index", "className", "children"]);
39
+ var context = React.useContext(CarouselContext);
40
+ if (!context || index == null) {
41
+ throw new Error('CarouselSlide must be used within Carousel');
42
+ }
43
+ var currentIndex = context.currentIndex, isManuallyUpdating = context.isManuallyUpdating, setCurrentIndex = context.setCurrentIndex;
44
+ var updateActiveIndexOnScroll = React.useCallback(function () {
45
+ // only update index if scroll was triggered by browser
46
+ if (!isManuallyUpdating.current && currentIndex !== index) {
47
+ setCurrentIndex(index);
48
+ }
49
+ // when manual scroll completes, reset the state of `isManuallyUpdating` so that it's ready for future actions
50
+ if (currentIndex === index) {
51
+ isManuallyUpdating.current = false;
52
+ }
53
+ }, [currentIndex, index, isManuallyUpdating, setCurrentIndex]);
54
+ var intersectionRef = useIntersection(updateActiveIndexOnScroll, { threshold: 0.5 }, false);
55
+ var refs = useMergedRefs(intersectionRef, ref);
56
+ return (React.createElement("li", __assign({ className: cx('iui-carousel-slider-item', className), role: 'tabpanel', "aria-roledescription": 'slide', ref: refs }, rest), children));
57
+ });
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ /**
3
+ * `CarouselSlider` is the scrollable list that should consist of `CarouselSlide` components.
4
+ */
5
+ export declare const CarouselSlider: React.ForwardRefExoticComponent<Pick<React.DetailedHTMLProps<React.OlHTMLAttributes<HTMLOListElement>, HTMLOListElement>, "key" | keyof React.OlHTMLAttributes<HTMLOListElement>> & React.RefAttributes<HTMLOListElement>>;
@@ -0,0 +1,88 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ /*---------------------------------------------------------------------------------------------
24
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
25
+ * See LICENSE.md in the project root for license terms and full copyright notice.
26
+ *--------------------------------------------------------------------------------------------*/
27
+ import React from 'react';
28
+ import cx from 'classnames';
29
+ import { CarouselContext } from './CarouselContext';
30
+ import { getWindow, useMergedRefs, useResizeObserver } from '../utils';
31
+ /**
32
+ * `CarouselSlider` is the scrollable list that should consist of `CarouselSlide` components.
33
+ */
34
+ export var CarouselSlider = React.forwardRef(function (props, ref) {
35
+ var children = props.children, className = props.className, rest = __rest(props, ["children", "className"]);
36
+ var context = React.useContext(CarouselContext);
37
+ if (!context) {
38
+ throw new Error('CarouselSlider must be used within Carousel');
39
+ }
40
+ var currentIndex = context.currentIndex, setSlideCount = context.setSlideCount, idPrefix = context.idPrefix, isManuallyUpdating = context.isManuallyUpdating, scrollInstantly = context.scrollInstantly;
41
+ var items = React.useMemo(function () {
42
+ var _a;
43
+ return (_a = React.Children.map(children, function (child, index) {
44
+ return React.isValidElement(child)
45
+ ? React.cloneElement(child, {
46
+ id: idPrefix + "--slide-" + index,
47
+ index: index,
48
+ })
49
+ : child;
50
+ })) !== null && _a !== void 0 ? _a : [];
51
+ }, [children, idPrefix]);
52
+ React.useLayoutEffect(function () {
53
+ setSlideCount(items.length);
54
+ }, [items.length, setSlideCount]);
55
+ var _a = React.useState(), width = _a[0], setWidth = _a[1];
56
+ var resizeRef = useResizeObserver(function (_a) {
57
+ var width = _a.width;
58
+ return setWidth(width);
59
+ })[0];
60
+ var sliderRef = React.useRef(null);
61
+ var refs = useMergedRefs(sliderRef, resizeRef, ref);
62
+ var justMounted = React.useRef(true);
63
+ var previousWidth = React.useRef();
64
+ React.useLayoutEffect(function () {
65
+ var _a, _b, _c;
66
+ var slideToShow = (_a = sliderRef.current) === null || _a === void 0 ? void 0 : _a.children.item(currentIndex);
67
+ if (!sliderRef.current ||
68
+ !slideToShow ||
69
+ (!isManuallyUpdating.current && previousWidth.current === width)) {
70
+ return;
71
+ }
72
+ // instant scroll on first mount
73
+ if (justMounted.current) {
74
+ scrollInstantly.current = true;
75
+ justMounted.current = false;
76
+ }
77
+ var motionOk = (_c = (_b = getWindow()) === null || _b === void 0 ? void 0 : _b.matchMedia('(prefers-reduced-motion: no-preference)')) === null || _c === void 0 ? void 0 : _c.matches;
78
+ sliderRef.current.scrollTo({
79
+ left: slideToShow.offsetLeft - sliderRef.current.offsetLeft,
80
+ behavior: (scrollInstantly.current || !motionOk
81
+ ? 'instant'
82
+ : 'smooth'), // scrollTo accepts 'instant' but ScrollBehavior type is wrong
83
+ });
84
+ scrollInstantly.current = false;
85
+ previousWidth.current = width;
86
+ }, [currentIndex, isManuallyUpdating, scrollInstantly, width]);
87
+ return (React.createElement("ol", __assign({ "aria-live": 'polite', className: cx('iui-carousel-slider', className), ref: refs }, rest), items));
88
+ });
@@ -0,0 +1,4 @@
1
+ export { Carousel } from './Carousel';
2
+ export type { CarouselProps } from './Carousel';
3
+ declare const _default: "./Carousel";
4
+ export default _default;
@@ -0,0 +1,6 @@
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
+ export { Carousel } from './Carousel';
6
+ export default './Carousel';
@@ -36,6 +36,11 @@ export declare type DatePickerProps = {
36
36
  * @default false
37
37
  */
38
38
  showTime?: boolean;
39
+ /**
40
+ * Show additional buttons to select year.
41
+ * @default false
42
+ */
43
+ showYearSelection?: boolean;
39
44
  } & Omit<TimePickerProps, 'date' | 'onChange' | 'setFocusHour'>;
40
45
  /**
41
46
  * Date picker component
@@ -26,6 +26,8 @@ var __rest = (this && this.__rest) || function (s, e) {
26
26
  *--------------------------------------------------------------------------------------------*/
27
27
  import SvgChevronLeft from '@itwin/itwinui-icons-react/cjs/icons/ChevronLeft';
28
28
  import SvgChevronRight from '@itwin/itwinui-icons-react/cjs/icons/ChevronRight';
29
+ import SvgChevronLeftDouble from '@itwin/itwinui-icons-react/cjs/icons/ChevronLeftDouble';
30
+ import SvgChevronRightDouble from '@itwin/itwinui-icons-react/cjs/icons/ChevronRightDouble';
29
31
  import cx from 'classnames';
30
32
  import React from 'react';
31
33
  import { useTheme } from '../utils';
@@ -120,15 +122,15 @@ export var generateLocalizedStrings = function (locale) {
120
122
  */
121
123
  export var DatePicker = function (props) {
122
124
  var _a, _b, _c;
123
- var date = props.date, onChange = props.onChange, localizedNames = props.localizedNames, className = props.className, style = props.style, _d = props.setFocus, setFocus = _d === void 0 ? false : _d, _e = props.showTime, showTime = _e === void 0 ? false : _e, _f = props.use12Hours, use12Hours = _f === void 0 ? false : _f, precision = props.precision, hourStep = props.hourStep, minuteStep = props.minuteStep, secondStep = props.secondStep, rest = __rest(props, ["date", "onChange", "localizedNames", "className", "style", "setFocus", "showTime", "use12Hours", "precision", "hourStep", "minuteStep", "secondStep"]);
125
+ var date = props.date, onChange = props.onChange, localizedNames = props.localizedNames, className = props.className, style = props.style, _d = props.setFocus, setFocus = _d === void 0 ? false : _d, _e = props.showTime, showTime = _e === void 0 ? false : _e, _f = props.use12Hours, use12Hours = _f === void 0 ? false : _f, precision = props.precision, hourStep = props.hourStep, minuteStep = props.minuteStep, secondStep = props.secondStep, _g = props.showYearSelection, showYearSelection = _g === void 0 ? false : _g, rest = __rest(props, ["date", "onChange", "localizedNames", "className", "style", "setFocus", "showTime", "use12Hours", "precision", "hourStep", "minuteStep", "secondStep", "showYearSelection"]);
124
126
  useTheme();
125
127
  var monthNames = (_a = localizedNames === null || localizedNames === void 0 ? void 0 : localizedNames.months) !== null && _a !== void 0 ? _a : defaultMonths;
126
128
  var shortDays = (_b = localizedNames === null || localizedNames === void 0 ? void 0 : localizedNames.shortDays) !== null && _b !== void 0 ? _b : defaultShortDays;
127
129
  var longDays = (_c = localizedNames === null || localizedNames === void 0 ? void 0 : localizedNames.days) !== null && _c !== void 0 ? _c : defaultLongDays;
128
- var _g = React.useState(date), selectedDay = _g[0], setSelectedDay = _g[1];
129
- var _h = React.useState(selectedDay !== null && selectedDay !== void 0 ? selectedDay : new Date()), focusedDay = _h[0], setFocusedDay = _h[1];
130
- var _j = React.useState(selectedDay ? selectedDay.getMonth() : new Date().getMonth()), displayedMonthIndex = _j[0], setDisplayedMonthIndex = _j[1];
131
- var _k = React.useState(selectedDay ? selectedDay.getFullYear() : new Date().getFullYear()), displayedYear = _k[0], setDisplayedYear = _k[1];
130
+ var _h = React.useState(date), selectedDay = _h[0], setSelectedDay = _h[1];
131
+ var _j = React.useState(selectedDay !== null && selectedDay !== void 0 ? selectedDay : new Date()), focusedDay = _j[0], setFocusedDay = _j[1];
132
+ var _k = React.useState(selectedDay ? selectedDay.getMonth() : new Date().getMonth()), displayedMonthIndex = _k[0], setDisplayedMonthIndex = _k[1];
133
+ var _l = React.useState(selectedDay ? selectedDay.getFullYear() : new Date().getFullYear()), displayedYear = _l[0], setDisplayedYear = _l[1];
132
134
  // Used to focus days only when days are changed
133
135
  // e.g. without this, when changing months day would be focused
134
136
  var needFocus = React.useRef(setFocus);
@@ -174,6 +176,16 @@ export var DatePicker = function (props) {
174
176
  var newDate = new Date(newYear, newMonth, currentDate.getDate(), currentDate.getHours(), currentDate.getMinutes(), currentDate.getSeconds());
175
177
  return newDate;
176
178
  };
179
+ var handleMoveToPreviousYear = function () {
180
+ var newYear = displayedYear - 1;
181
+ setMonthAndYear(displayedMonthIndex, newYear);
182
+ setFocusedDay(getNewFocusedDate(newYear, displayedMonthIndex));
183
+ };
184
+ var handleMoveToNextYear = function () {
185
+ var newYear = displayedYear + 1;
186
+ setMonthAndYear(displayedMonthIndex, newYear);
187
+ setFocusedDay(getNewFocusedDate(newYear, displayedMonthIndex));
188
+ };
177
189
  var handleMoveToPreviousMonth = function () {
178
190
  var newMonth = displayedMonthIndex !== 0 ? displayedMonthIndex - 1 : 11;
179
191
  var newYear = displayedMonthIndex !== 0 ? displayedYear : displayedYear - 1;
@@ -246,26 +258,39 @@ export var DatePicker = function (props) {
246
258
  break;
247
259
  }
248
260
  };
261
+ var getDayClass = function (day) {
262
+ if (day.getMonth() !== displayedMonthIndex) {
263
+ return 'iui-calendar-day-outside-month';
264
+ }
265
+ var dayClass = 'iui-calendar-day';
266
+ if (isSameDay(day, selectedDay)) {
267
+ dayClass += '-selected';
268
+ }
269
+ if (isSameDay(day, new Date())) {
270
+ dayClass += '-today';
271
+ }
272
+ return dayClass;
273
+ };
249
274
  return (React.createElement("div", __assign({ className: cx('iui-date-picker', className), style: style }, rest),
250
275
  React.createElement("div", null,
251
276
  React.createElement("div", { className: 'iui-calendar-month-year' },
252
- React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousMonth, "aria-label": 'Previous month' },
277
+ showYearSelection && (React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousYear, "aria-label": 'Previous year', size: 'small' },
278
+ React.createElement(SvgChevronLeftDouble, null))),
279
+ React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToPreviousMonth, "aria-label": 'Previous month', size: 'small' },
253
280
  React.createElement(SvgChevronLeft, null)),
254
281
  React.createElement("span", { "aria-live": 'polite' },
255
282
  React.createElement("span", { className: 'iui-calendar-month', title: monthNames[displayedMonthIndex] }, monthNames[displayedMonthIndex]),
256
283
  "\u00A0",
257
284
  displayedYear),
258
- React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextMonth, "aria-label": 'Next month' },
259
- React.createElement(SvgChevronRight, null))),
285
+ React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextMonth, "aria-label": 'Next month', size: 'small' },
286
+ React.createElement(SvgChevronRight, null)),
287
+ showYearSelection && (React.createElement(IconButton, { styleType: 'borderless', onClick: handleMoveToNextYear, "aria-label": 'Next year', size: 'small' },
288
+ React.createElement(SvgChevronRightDouble, null)))),
260
289
  React.createElement("div", { className: 'iui-calendar-weekdays' }, shortDays.map(function (day, index) { return (React.createElement("div", { key: day, title: longDays[index] }, day)); })),
261
290
  React.createElement("div", { onKeyDown: handleCalendarKeyDown, role: 'listbox' }, weeks.map(function (weekDays, weekIndex) {
262
291
  return (React.createElement("div", { key: "week-" + displayedMonthIndex + "-" + weekIndex, className: 'iui-calendar-week' }, weekDays.map(function (weekDay, dayIndex) {
263
292
  var dateValue = weekDay.getDate();
264
- return (React.createElement("div", { key: "day-" + displayedMonthIndex + "-" + dayIndex, className: cx('iui-calendar-day', {
265
- 'iui-outside-month': weekDay.getMonth() !== displayedMonthIndex,
266
- 'iui-today': isSameDay(weekDay, new Date()),
267
- 'iui-selected': isSameDay(weekDay, selectedDay),
268
- }), onClick: function () { return onDayClick(weekDay); }, role: 'option', tabIndex: isSameDay(weekDay, focusedDay) ? 0 : -1, ref: function (element) {
293
+ return (React.createElement("div", { key: "day-" + displayedMonthIndex + "-" + dayIndex, className: getDayClass(weekDay), onClick: function () { return onDayClick(weekDay); }, role: 'option', tabIndex: isSameDay(weekDay, focusedDay) ? 0 : -1, ref: function (element) {
269
294
  return isSameDay(weekDay, focusedDay) &&
270
295
  needFocus.current &&
271
296
  (element === null || element === void 0 ? void 0 : element.focus());
@@ -45,6 +45,11 @@ export declare type ModalProps = {
45
45
  * @default document
46
46
  */
47
47
  ownerDocument?: Document;
48
+ /**
49
+ * Type of the modal.
50
+ * @default 'default'
51
+ */
52
+ styleType?: 'default' | 'fullPage';
48
53
  /**
49
54
  * Content of the modal.
50
55
  */
@@ -31,6 +31,7 @@ import SvgClose from '@itwin/itwinui-icons-react/cjs/icons/Close';
31
31
  import { useTheme, getContainer, getDocument, FocusTrap, } from '../utils';
32
32
  import '@itwin/itwinui-css/css/modal.css';
33
33
  import { IconButton } from '../Buttons/IconButton';
34
+ import { CSSTransition } from 'react-transition-group';
34
35
  /**
35
36
  * Modal component which can wrap any content.
36
37
  * @example
@@ -53,7 +54,7 @@ import { IconButton } from '../Buttons/IconButton';
53
54
  * </Modal>
54
55
  */
55
56
  export var Modal = function (props) {
56
- var _a = props.isOpen, isOpen = _a === void 0 ? false : _a, _b = props.isDismissible, isDismissible = _b === void 0 ? true : _b, _c = props.closeOnEsc, closeOnEsc = _c === void 0 ? true : _c, _d = props.closeOnExternalClick, closeOnExternalClick = _d === void 0 ? true : _d, onClose = props.onClose, title = props.title, onKeyDown = props.onKeyDown, id = props.id, className = props.className, style = props.style, children = props.children, _e = props.modalRootId, modalRootId = _e === void 0 ? 'iui-react-portal-container' : _e, _f = props.ownerDocument, ownerDocument = _f === void 0 ? getDocument() : _f, rest = __rest(props, ["isOpen", "isDismissible", "closeOnEsc", "closeOnExternalClick", "onClose", "title", "onKeyDown", "id", "className", "style", "children", "modalRootId", "ownerDocument"]);
57
+ var _a = props.isOpen, isOpen = _a === void 0 ? false : _a, _b = props.isDismissible, isDismissible = _b === void 0 ? true : _b, _c = props.closeOnEsc, closeOnEsc = _c === void 0 ? true : _c, _d = props.closeOnExternalClick, closeOnExternalClick = _d === void 0 ? true : _d, onClose = props.onClose, title = props.title, onKeyDown = props.onKeyDown, id = props.id, className = props.className, style = props.style, children = props.children, _e = props.styleType, styleType = _e === void 0 ? 'default' : _e, _f = props.modalRootId, modalRootId = _f === void 0 ? 'iui-react-portal-container' : _f, _g = props.ownerDocument, ownerDocument = _g === void 0 ? getDocument() : _g, rest = __rest(props, ["isOpen", "isDismissible", "closeOnEsc", "closeOnExternalClick", "onClose", "title", "onKeyDown", "id", "className", "style", "children", "styleType", "modalRootId", "ownerDocument"]);
57
58
  useTheme();
58
59
  var container = getContainer(modalRootId, ownerDocument);
59
60
  var overlayRef = React.useRef(null);
@@ -111,13 +112,14 @@ export var Modal = function (props) {
111
112
  onClose(event);
112
113
  }
113
114
  };
114
- return !!container ? (ReactDOM.createPortal(isOpen && (React.createElement(FocusTrap, null,
115
- React.createElement("div", __assign({ className: cx('iui-modal', 'iui-modal-visible', className), tabIndex: -1, onKeyDown: handleKeyDown, ref: overlayRef, onMouseDown: handleMouseDown }, rest),
116
- React.createElement("div", { className: 'iui-modal-dialog', id: id, style: style, role: 'dialog', "aria-modal": 'true' },
117
- React.createElement("div", { className: 'iui-title-bar' },
118
- React.createElement("div", { className: 'iui-title' }, title),
119
- isDismissible && (React.createElement(IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
120
- React.createElement(SvgClose, null)))),
121
- children)))), container)) : (React.createElement(React.Fragment, null));
115
+ return !!container ? (ReactDOM.createPortal(React.createElement(CSSTransition, { in: isOpen, classNames: 'iui-modal-animation', timeout: { exit: 600 }, unmountOnExit: true },
116
+ React.createElement(FocusTrap, null,
117
+ React.createElement("div", __assign({ className: cx('iui-modal', { 'iui-modal-full-page': styleType === 'fullPage' }, { 'iui-modal-visible': isOpen }, className), tabIndex: -1, onKeyDown: handleKeyDown, ref: overlayRef, onMouseDown: handleMouseDown }, rest),
118
+ React.createElement("div", { className: 'iui-modal-dialog', id: id, style: style, role: 'dialog', "aria-modal": 'true' },
119
+ React.createElement("div", { className: 'iui-title-bar' },
120
+ React.createElement("div", { className: 'iui-title' }, title),
121
+ isDismissible && (React.createElement(IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
122
+ React.createElement(SvgClose, null)))),
123
+ children)))), container)) : (React.createElement(React.Fragment, null));
122
124
  };
123
125
  export default Modal;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import { CommonProps } from '../utils';
3
+ import '@itwin/itwinui-css/css/modal.css';
4
+ export declare type ModalContentProps = {
5
+ /**
6
+ * Main content in the `Modal`.
7
+ */
8
+ children: React.ReactNode;
9
+ } & Omit<CommonProps, 'title'>;
10
+ /**
11
+ * Container for content in `Modal`.
12
+ */
13
+ export declare const ModalContent: (props: ModalContentProps) => JSX.Element;
14
+ export default ModalContent;
@@ -0,0 +1,39 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ var __rest = (this && this.__rest) || function (s, e) {
13
+ var t = {};
14
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
15
+ t[p] = s[p];
16
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
17
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
18
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
19
+ t[p[i]] = s[p[i]];
20
+ }
21
+ return t;
22
+ };
23
+ /*---------------------------------------------------------------------------------------------
24
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
25
+ * See LICENSE.md in the project root for license terms and full copyright notice.
26
+ *--------------------------------------------------------------------------------------------*/
27
+ import React from 'react';
28
+ import cx from 'classnames';
29
+ import { useTheme } from '../utils';
30
+ import '@itwin/itwinui-css/css/modal.css';
31
+ /**
32
+ * Container for content in `Modal`.
33
+ */
34
+ export var ModalContent = function (props) {
35
+ var children = props.children, className = props.className, rest = __rest(props, ["children", "className"]);
36
+ useTheme();
37
+ return (React.createElement("div", __assign({ className: cx('iui-modal-content', className) }, rest), children));
38
+ };
39
+ export default ModalContent;
@@ -2,5 +2,7 @@ export { Modal } from './Modal';
2
2
  export type { ModalProps } from './Modal';
3
3
  export { ModalButtonBar } from './ModalButtonBar';
4
4
  export type { ModalButtonBarProps } from './ModalButtonBar';
5
+ export { ModalContent } from './ModalContent';
6
+ export type { ModalContentProps } from './ModalContent';
5
7
  declare const _default: "./Modal";
6
8
  export default _default;
@@ -4,4 +4,5 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  export { Modal } from './Modal';
6
6
  export { ModalButtonBar } from './ModalButtonBar';
7
+ export { ModalContent } from './ModalContent';
7
8
  export default './Modal';
@@ -228,11 +228,12 @@ export var Table = function (props) {
228
228
  });
229
229
  var headerRef = React.useRef(null);
230
230
  var bodyRef = React.useRef(null);
231
- var getPreparedRow = React.useCallback(function (row) {
231
+ var getPreparedRow = React.useCallback(function (index) {
232
+ var row = page[index];
232
233
  prepareRow(row);
233
- return (React.createElement(TableRowMemoized, { row: row, rowProps: rowProps, isLast: row.index === data.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell }));
234
+ return (React.createElement(TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell }));
234
235
  }, [
235
- data.length,
236
+ page,
236
237
  expanderCell,
237
238
  hasAnySubRows,
238
239
  instance,
@@ -244,7 +245,7 @@ export var Table = function (props) {
244
245
  state,
245
246
  subComponent,
246
247
  ]);
247
- var virtualizedItemRenderer = React.useCallback(function (index) { return getPreparedRow(page[index]); }, [getPreparedRow, page]);
248
+ var virtualizedItemRenderer = React.useCallback(function (index) { return getPreparedRow(index); }, [getPreparedRow]);
248
249
  return (React.createElement(React.Fragment, null,
249
250
  React.createElement("div", __assign({ ref: function (element) {
250
251
  setOwnerDocument(element === null || element === void 0 ? void 0 : element.ownerDocument);
@@ -268,8 +269,8 @@ export var Table = function (props) {
268
269
  }
269
270
  } }),
270
271
  column.render('Header'),
271
- !isLoading && (data.length != 0 || areFiltersSet) && (React.createElement(FilterToggle, { column: column, ownerDocument: ownerDocument })),
272
- !isLoading && data.length != 0 && column.canSort && (React.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (React.createElement(SvgSortUp, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (React.createElement(SvgSortDown, { className: 'iui-icon iui-sort', "aria-hidden": true })))),
272
+ (data.length !== 0 || areFiltersSet) && (React.createElement(FilterToggle, { column: column, ownerDocument: ownerDocument })),
273
+ data.length !== 0 && column.canSort && (React.createElement("div", { className: 'iui-cell-end-icon' }, column.isSorted && column.isSortedDesc ? (React.createElement(SvgSortUp, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (React.createElement(SvgSortDown, { className: 'iui-icon iui-sort', "aria-hidden": true })))),
273
274
  isResizable &&
274
275
  column.isResizerVisible &&
275
276
  index !== headerGroup.headers.length - 1 && (React.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
@@ -287,7 +288,7 @@ export var Table = function (props) {
287
288
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
288
289
  }
289
290
  }, tabIndex: -1 }),
290
- data.length !== 0 && (React.createElement(React.Fragment, null, enableVirtualization ? (React.createElement(VirtualScroll, { itemsLength: page.length, itemRenderer: virtualizedItemRenderer })) : (page.map(function (row) { return getPreparedRow(row); })))),
291
+ data.length !== 0 && (React.createElement(React.Fragment, null, enableVirtualization ? (React.createElement(VirtualScroll, { itemsLength: page.length, itemRenderer: virtualizedItemRenderer })) : (page.map(function (_, index) { return getPreparedRow(index); })))),
291
292
  isLoading && data.length === 0 && (React.createElement("div", { className: 'iui-table-empty' },
292
293
  React.createElement(ProgressRadial, { indeterminate: true }))),
293
294
  isLoading && data.length !== 0 && (React.createElement("div", { className: 'iui-row' },
@@ -8,6 +8,8 @@ export { Button, DropdownButton, IconButton, IdeasButton, SplitButton, } from '.
8
8
  export type { ButtonProps, DropdownButtonProps, IconButtonProps, IdeasButtonProps, SplitButtonProps, } from './Buttons';
9
9
  export { ButtonGroup } from './ButtonGroup';
10
10
  export type { ButtonGroupProps } from './ButtonGroup';
11
+ export { Carousel } from './Carousel';
12
+ export type { CarouselProps } from './Carousel';
11
13
  export { Checkbox } from './Checkbox';
12
14
  export type { CheckboxProps } from './Checkbox';
13
15
  export { ColorPicker, ColorSwatch, ColorBuilder, ColorInputPanel, ColorPalette, } from './ColorPicker';
@@ -48,8 +50,8 @@ export { LabeledTextarea } from './LabeledTextarea';
48
50
  export type { LabeledTextareaProps } from './LabeledTextarea';
49
51
  export { Menu, MenuItem, MenuDivider, MenuExtraContent } from './Menu';
50
52
  export type { MenuProps, MenuItemProps, MenuDividerProps, MenuExtraContentProps, } from './Menu';
51
- export { Modal, ModalButtonBar } from './Modal';
52
- export type { ModalProps, ModalButtonBarProps } from './Modal';
53
+ export { Modal, ModalButtonBar, ModalContent } from './Modal';
54
+ export type { ModalProps, ModalButtonBarProps, ModalContentProps, } from './Modal';
53
55
  export { ProgressLinear, ProgressRadial } from './ProgressIndicators';
54
56
  export type { ProgressLinearProps, ProgressRadialProps, } from './ProgressIndicators';
55
57
  export { Radio } from './Radio';
package/esm/core/index.js CHANGED
@@ -7,6 +7,7 @@ export { Badge } from './Badge';
7
7
  export { Breadcrumbs } from './Breadcrumbs';
8
8
  export { Button, DropdownButton, IconButton, IdeasButton, SplitButton, } from './Buttons';
9
9
  export { ButtonGroup } from './ButtonGroup';
10
+ export { Carousel } from './Carousel';
10
11
  export { Checkbox } from './Checkbox';
11
12
  export { ColorPicker, ColorSwatch, ColorBuilder, ColorInputPanel, ColorPalette, } from './ColorPicker';
12
13
  export { ComboBox } from './ComboBox';
@@ -27,7 +28,7 @@ export { InputGroup } from './InputGroup';
27
28
  export { LabeledSelect } from './LabeledSelect';
28
29
  export { LabeledTextarea } from './LabeledTextarea';
29
30
  export { Menu, MenuItem, MenuDivider, MenuExtraContent } from './Menu';
30
- export { Modal, ModalButtonBar } from './Modal';
31
+ export { Modal, ModalButtonBar, ModalContent } from './Modal';
31
32
  export { ProgressLinear, ProgressRadial } from './ProgressIndicators';
32
33
  export { Radio } from './Radio';
33
34
  export { RadioTile, RadioTileGroup } from './RadioTiles';
@@ -5,3 +5,4 @@ export * from './useResizeObserver';
5
5
  export * from './useContainerWidth';
6
6
  export * from './useTheme';
7
7
  export * from './useIntersection';
8
+ export * from './useMediaQuery';
@@ -9,3 +9,4 @@ export * from './useResizeObserver';
9
9
  export * from './useContainerWidth';
10
10
  export * from './useTheme';
11
11
  export * from './useIntersection';
12
+ export * from './useMediaQuery';
@@ -0,0 +1,2 @@
1
+ export declare const useMediaQuery: (queryString: string) => boolean;
2
+ export default useMediaQuery;
@@ -0,0 +1,39 @@
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 { getWindow } from '../functions';
7
+ export var useMediaQuery = function (queryString) {
8
+ var _a = React.useState(), matches = _a[0], setMatches = _a[1];
9
+ React.useLayoutEffect(function () {
10
+ var _a, _b, _c;
11
+ var mediaQueryList = (_b = (_a = getWindow()) === null || _a === void 0 ? void 0 : _a.matchMedia) === null || _b === void 0 ? void 0 : _b.call(_a, queryString);
12
+ var handleChange = function (_a) {
13
+ var matches = _a.matches;
14
+ return setMatches(matches);
15
+ };
16
+ if (mediaQueryList != undefined) {
17
+ setMatches(mediaQueryList.matches);
18
+ try {
19
+ mediaQueryList.addEventListener('change', handleChange);
20
+ }
21
+ catch (_d) {
22
+ // Safari 13 fallback
23
+ (_c = mediaQueryList.addListener) === null || _c === void 0 ? void 0 : _c.call(mediaQueryList, handleChange);
24
+ }
25
+ }
26
+ return function () {
27
+ var _a;
28
+ try {
29
+ mediaQueryList === null || mediaQueryList === void 0 ? void 0 : mediaQueryList.removeEventListener('change', handleChange);
30
+ }
31
+ catch (_b) {
32
+ // Safari 13 fallback
33
+ (_a = mediaQueryList === null || mediaQueryList === void 0 ? void 0 : mediaQueryList.removeListener) === null || _a === void 0 ? void 0 : _a.call(mediaQueryList, handleChange);
34
+ }
35
+ };
36
+ }, [queryString]);
37
+ return !!matches;
38
+ };
39
+ export default useMediaQuery;
@@ -6,6 +6,11 @@ export declare type ThemeOptions = {
6
6
  * @default document
7
7
  */
8
8
  ownerDocument?: Document;
9
+ /**
10
+ * Whether to apply high-contrast versions of light and dark themes.
11
+ * Will default to user preference if browser supports it.
12
+ */
13
+ highContrast?: boolean;
9
14
  };
10
15
  export declare type ThemeType = 'light' | 'dark' | 'os';
11
16
  /**