@lumx/react 3.20.1-alpha.29 → 3.20.1-alpha.30

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 (183) hide show
  1. package/_internal/Button-4b67daa8.js +98 -0
  2. package/_internal/Button-4b67daa8.js.map +1 -0
  3. package/_internal/ButtonRoot-a70baf82.js +118 -0
  4. package/_internal/ButtonRoot-a70baf82.js.map +1 -0
  5. package/_internal/Chip-70af04b4.js +144 -0
  6. package/_internal/Chip-70af04b4.js.map +1 -0
  7. package/_internal/ClickAwayProvider-1204f237.js +95 -0
  8. package/_internal/ClickAwayProvider-1204f237.js.map +1 -0
  9. package/_internal/DisabledStateContext-ea04260d.js +29 -0
  10. package/_internal/DisabledStateContext-ea04260d.js.map +1 -0
  11. package/_internal/HeadingLevelProvider-ebdcb0c7.js +61 -0
  12. package/_internal/HeadingLevelProvider-ebdcb0c7.js.map +1 -0
  13. package/_internal/IconButton-8d61f5be.js +77 -0
  14. package/_internal/IconButton-8d61f5be.js.map +1 -0
  15. package/_internal/ImageCaption-db44ec9e.js +75 -0
  16. package/_internal/ImageCaption-db44ec9e.js.map +1 -0
  17. package/_internal/List-c75646f2.js +818 -0
  18. package/_internal/List-c75646f2.js.map +1 -0
  19. package/_internal/PopoverDialog-35b2d87d.js +657 -0
  20. package/_internal/PopoverDialog-35b2d87d.js.map +1 -0
  21. package/_internal/Portal-3f86608e.js +45 -0
  22. package/_internal/Portal-3f86608e.js.map +1 -0
  23. package/_internal/RawClickable-2c2b6a89.js +52 -0
  24. package/_internal/RawClickable-2c2b6a89.js.map +1 -0
  25. package/_internal/Slides-ce641b5f.js +679 -0
  26. package/_internal/Slides-ce641b5f.js.map +1 -0
  27. package/_internal/ThemeContext-3181f000.js +14 -0
  28. package/_internal/ThemeContext-3181f000.js.map +1 -0
  29. package/_internal/Thumbnail-02bd6869.js +314 -0
  30. package/_internal/Thumbnail-02bd6869.js.map +1 -0
  31. package/_internal/components/alert-dialog-a24330ed.js +166 -0
  32. package/_internal/components/alert-dialog-a24330ed.js.map +1 -0
  33. package/_internal/components/autocomplete-70749e51.js +262 -0
  34. package/_internal/components/autocomplete-70749e51.js.map +1 -0
  35. package/_internal/components/avatar-ed9f4869.js +84 -0
  36. package/_internal/components/avatar-ed9f4869.js.map +1 -0
  37. package/_internal/components/badge-ccf47147.js +82 -0
  38. package/_internal/components/badge-ccf47147.js.map +1 -0
  39. package/_internal/components/button-9f710830.js +48 -0
  40. package/_internal/components/button-9f710830.js.map +1 -0
  41. package/_internal/components/checkbox-8ab51ef9.js +142 -0
  42. package/_internal/components/checkbox-8ab51ef9.js.map +1 -0
  43. package/_internal/components/chip-19e40755.js +103 -0
  44. package/_internal/components/chip-19e40755.js.map +1 -0
  45. package/_internal/components/comment-block-bb6a0603.js +139 -0
  46. package/_internal/components/comment-block-bb6a0603.js.map +1 -0
  47. package/_internal/components/date-picker-e4209b01.js +2 -0
  48. package/_internal/components/date-picker-e4209b01.js.map +1 -0
  49. package/_internal/components/dialog-30336ccb.js +239 -0
  50. package/_internal/components/dialog-30336ccb.js.map +1 -0
  51. package/_internal/components/divider-0e93aa3d.js +51 -0
  52. package/_internal/components/divider-0e93aa3d.js.map +1 -0
  53. package/_internal/components/drag-handle-ba2e7e67.js +52 -0
  54. package/_internal/components/drag-handle-ba2e7e67.js.map +1 -0
  55. package/_internal/components/dropdown-d18122d7.js +148 -0
  56. package/_internal/components/dropdown-d18122d7.js.map +1 -0
  57. package/_internal/components/expansion-panel-0b263437.js +169 -0
  58. package/_internal/components/expansion-panel-0b263437.js.map +1 -0
  59. package/_internal/components/flag-8f9a498a.js +60 -0
  60. package/_internal/components/flag-8f9a498a.js.map +1 -0
  61. package/_internal/components/flex-box-15be92f6.js +57 -0
  62. package/_internal/components/flex-box-15be92f6.js.map +1 -0
  63. package/_internal/components/generic-block-5d843f1e.js +128 -0
  64. package/_internal/components/generic-block-5d843f1e.js.map +1 -0
  65. package/_internal/components/grid-8c08dc4b.js +105 -0
  66. package/_internal/components/grid-8c08dc4b.js.map +1 -0
  67. package/_internal/components/grid-column-85e305e7.js +59 -0
  68. package/_internal/components/grid-column-85e305e7.js.map +1 -0
  69. package/_internal/components/heading-7bfafd7d.js +54 -0
  70. package/_internal/components/heading-7bfafd7d.js.map +1 -0
  71. package/_internal/components/icon-ee15673b.js +103 -0
  72. package/_internal/components/icon-ee15673b.js.map +1 -0
  73. package/_internal/components/image-block-3479abda.js +111 -0
  74. package/_internal/components/image-block-3479abda.js.map +1 -0
  75. package/_internal/components/image-lightbox-1d7ca133.js +758 -0
  76. package/_internal/components/image-lightbox-1d7ca133.js.map +1 -0
  77. package/_internal/components/inline-list-5ba8bb0f.js +75 -0
  78. package/_internal/components/inline-list-5ba8bb0f.js.map +1 -0
  79. package/_internal/components/input-helper-2e4e49fd.js +72 -0
  80. package/_internal/components/input-helper-2e4e49fd.js.map +1 -0
  81. package/_internal/components/input-label-30d199c3.js +60 -0
  82. package/_internal/components/input-label-30d199c3.js.map +1 -0
  83. package/_internal/components/lightbox-c5f9afd0.js +156 -0
  84. package/_internal/components/lightbox-c5f9afd0.js.map +1 -0
  85. package/_internal/components/link-43ee103e.js +73 -0
  86. package/_internal/components/link-43ee103e.js.map +1 -0
  87. package/_internal/components/link-preview-db0ee2d6.js +118 -0
  88. package/_internal/components/link-preview-db0ee2d6.js.map +1 -0
  89. package/_internal/components/list-2f256244.js +72 -0
  90. package/_internal/components/list-2f256244.js.map +1 -0
  91. package/_internal/components/message-f7674e0e.js +101 -0
  92. package/_internal/components/message-f7674e0e.js.map +1 -0
  93. package/_internal/components/mosaic-3effd0cf.js +95 -0
  94. package/_internal/components/mosaic-3effd0cf.js.map +1 -0
  95. package/_internal/components/navigation-3a5dc270.js +227 -0
  96. package/_internal/components/navigation-3a5dc270.js.map +1 -0
  97. package/_internal/components/notification-098c5600.js +146 -0
  98. package/_internal/components/notification-098c5600.js.map +1 -0
  99. package/_internal/components/popover-dfcddda4.js +3 -0
  100. package/_internal/components/popover-dfcddda4.js.map +1 -0
  101. package/_internal/components/post-block-69797e4d.js +110 -0
  102. package/_internal/components/post-block-69797e4d.js.map +1 -0
  103. package/_internal/components/progress-44bb0301.js +183 -0
  104. package/_internal/components/progress-44bb0301.js.map +1 -0
  105. package/_internal/components/progress-tracker-e0981fcc.js +309 -0
  106. package/_internal/components/progress-tracker-e0981fcc.js.map +1 -0
  107. package/_internal/components/radio-button-929c7bee.js +150 -0
  108. package/_internal/components/radio-button-929c7bee.js.map +1 -0
  109. package/_internal/components/select-64bc72a0.js +458 -0
  110. package/_internal/components/select-64bc72a0.js.map +1 -0
  111. package/_internal/components/side-navigation-c610c689.js +166 -0
  112. package/_internal/components/side-navigation-c610c689.js.map +1 -0
  113. package/_internal/components/skeleton-1ea8c82a.js +167 -0
  114. package/_internal/components/skeleton-1ea8c82a.js.map +1 -0
  115. package/_internal/components/slider-78cfaa67.js +312 -0
  116. package/_internal/components/slider-78cfaa67.js.map +1 -0
  117. package/_internal/components/slideshow-d8a943a7.js +151 -0
  118. package/_internal/components/slideshow-d8a943a7.js.map +1 -0
  119. package/_internal/components/switch-25b65051.js +122 -0
  120. package/_internal/components/switch-25b65051.js.map +1 -0
  121. package/_internal/components/table-ec20c66c.js +296 -0
  122. package/_internal/components/table-ec20c66c.js.map +1 -0
  123. package/_internal/components/tabs-89c055bd.js +299 -0
  124. package/_internal/components/tabs-89c055bd.js.map +1 -0
  125. package/_internal/components/text-d04d0f1b.js +2 -0
  126. package/_internal/components/text-d04d0f1b.js.map +1 -0
  127. package/_internal/components/text-field-8f13957e.js +361 -0
  128. package/_internal/components/text-field-8f13957e.js.map +1 -0
  129. package/_internal/components/thumbnail-1255957f.js +42 -0
  130. package/_internal/components/thumbnail-1255957f.js.map +1 -0
  131. package/_internal/components/toolbar-e7c984e6.js +62 -0
  132. package/_internal/components/toolbar-e7c984e6.js.map +1 -0
  133. package/_internal/components/tooltip-dcb43bbe.js +328 -0
  134. package/_internal/components/tooltip-dcb43bbe.js.map +1 -0
  135. package/_internal/components/uploader-7ef4db39.js +154 -0
  136. package/_internal/components/uploader-7ef4db39.js.map +1 -0
  137. package/_internal/components/user-block-24d97650.js +145 -0
  138. package/_internal/components/user-block-24d97650.js.map +1 -0
  139. package/_internal/constants-43721918.js +2170 -0
  140. package/_internal/constants-43721918.js.map +1 -0
  141. package/_internal/constants-d0e3f49e.js +24 -0
  142. package/_internal/constants-d0e3f49e.js.map +1 -0
  143. package/_internal/context-9d1336a1.js +19 -0
  144. package/_internal/context-9d1336a1.js.map +1 -0
  145. package/_internal/forwardRef-8bce732e.js +9 -0
  146. package/_internal/forwardRef-8bce732e.js.map +1 -0
  147. package/_internal/getFocusableElements-230173a8.js +13 -0
  148. package/_internal/getFocusableElements-230173a8.js.map +1 -0
  149. package/_internal/index-25c9e8c2.js +118 -0
  150. package/_internal/index-25c9e8c2.js.map +1 -0
  151. package/_internal/index-25d2a45e.js +437 -0
  152. package/_internal/index-25d2a45e.js.map +1 -0
  153. package/_internal/isComponent-b9762ff1.js +18 -0
  154. package/_internal/isComponent-b9762ff1.js.map +1 -0
  155. package/_internal/isComponentType-e806b848.js +9 -0
  156. package/_internal/isComponentType-e806b848.js.map +1 -0
  157. package/_internal/mergeRefs-f0d7d6ea.js +30 -0
  158. package/_internal/mergeRefs-f0d7d6ea.js.map +1 -0
  159. package/_internal/state-db358714.js +130 -0
  160. package/_internal/state-db358714.js.map +1 -0
  161. package/_internal/useBooleanState-2a3d237c.js +12 -0
  162. package/_internal/useBooleanState-2a3d237c.js.map +1 -0
  163. package/_internal/useCallbackOnEscape-b956a85d.js +64 -0
  164. package/_internal/useCallbackOnEscape-b956a85d.js.map +1 -0
  165. package/_internal/useDisableBodyScroll-36bd7352.js +219 -0
  166. package/_internal/useDisableBodyScroll-36bd7352.js.map +1 -0
  167. package/_internal/useDisableStateProps-69e16b7c.js +36 -0
  168. package/_internal/useDisableStateProps-69e16b7c.js.map +1 -0
  169. package/_internal/useFocusTrap-2dbae79e.js +112 -0
  170. package/_internal/useFocusTrap-2dbae79e.js.map +1 -0
  171. package/_internal/useId-3a1facc0.js +18 -0
  172. package/_internal/useId-3a1facc0.js.map +1 -0
  173. package/_internal/useRovingTabIndex-7daf0f24.js +77 -0
  174. package/_internal/useRovingTabIndex-7daf0f24.js.map +1 -0
  175. package/_internal/useTransitionVisibility-321fdbfa.js +50 -0
  176. package/_internal/useTransitionVisibility-321fdbfa.js.map +1 -0
  177. package/_internal/wrapChildrenIconWithSpaces-50d705e6.js +20 -0
  178. package/_internal/wrapChildrenIconWithSpaces-50d705e6.js.map +1 -0
  179. package/index.js +63 -14033
  180. package/index.js.map +1 -1
  181. package/package.json +3 -3
  182. package/utils/index.js +3 -158
  183. package/utils/index.js.map +1 -1
@@ -0,0 +1,679 @@
1
+ import classNames from 'classnames';
2
+ import { getRootClassName, handleBasicClasses } from '@lumx/core/js/utils/className';
3
+ import { f as forwardRef } from './forwardRef-8bce732e.js';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+ import React__default, { useRef, useEffect, useState, useCallback, useMemo, Children } from 'react';
6
+ import { mdiChevronLeft } from '@lumx/icons/esm/chevron-left';
7
+ import { mdiChevronRight } from '@lumx/icons/esm/chevron-right';
8
+ import { mdiPlayCircleOutline } from '@lumx/icons/esm/play-circle-outline';
9
+ import { mdiPauseCircleOutline } from '@lumx/icons/esm/pause-circle-outline';
10
+ import { W as WINDOW } from './constants-d0e3f49e.js';
11
+ import { u as useId } from './useId-3a1facc0.js';
12
+ import { u as useRovingTabIndex } from './useRovingTabIndex-7daf0f24.js';
13
+ import { u as useTheme } from './ThemeContext-3181f000.js';
14
+ import { range } from '@lumx/core/js/utils/collection/range';
15
+ import { detectHorizontalSwipe } from '@lumx/core/js/utils';
16
+ import { Theme, Emphasis } from '@lumx/core/js/constants';
17
+ import { I as IconButton } from './IconButton-8d61f5be.js';
18
+ import { chunk } from '@lumx/core/js/utils/collection/chunk';
19
+ import { m as mergeRefs } from './mergeRefs-f0d7d6ea.js';
20
+ import { g as getFocusableElements } from './getFocusableElements-230173a8.js';
21
+
22
+ /**
23
+ * Making setInterval Declarative with React Hooks.
24
+ * Credits: https://overreacted.io/making-setinterval-declarative-with-react-hooks/
25
+ *
26
+ * @param callback Function called by setInterval.
27
+ * @param delay Delay for setInterval.
28
+ */
29
+ function useInterval(callback, delay) {
30
+ const savedCallback = useRef();
31
+ useEffect(() => {
32
+ savedCallback.current = callback;
33
+ });
34
+ useEffect(() => {
35
+ if (delay === null) return undefined;
36
+ function tick() {
37
+ savedCallback.current?.();
38
+ }
39
+ const id = setInterval(tick, delay);
40
+ return () => clearInterval(id);
41
+ }, [delay]);
42
+ }
43
+
44
+ /**
45
+ * Autoplay default interval in ms.
46
+ */
47
+ const AUTOPLAY_DEFAULT_INTERVAL = 5000;
48
+
49
+ /**
50
+ * Full width size in percent.
51
+ */
52
+ const FULL_WIDTH_PERCENT = 100;
53
+
54
+ /**
55
+ * Edge from the active index.
56
+ */
57
+ const EDGE_FROM_ACTIVE_INDEX = 2;
58
+
59
+ /**
60
+ * Max number of pagination items.
61
+ */
62
+ const PAGINATION_ITEMS_MAX = 5;
63
+
64
+ /**
65
+ * Size of a pagination item. Used to translate wrapper.
66
+ */
67
+ const PAGINATION_ITEM_SIZE = 12;
68
+
69
+ const DEFAULT_OPTIONS = {
70
+ activeIndex: 0,
71
+ groupBy: 1,
72
+ interval: AUTOPLAY_DEFAULT_INTERVAL
73
+ };
74
+ const useSlideshowControls = ({
75
+ activeIndex = DEFAULT_OPTIONS.activeIndex,
76
+ groupBy = DEFAULT_OPTIONS.groupBy,
77
+ interval = DEFAULT_OPTIONS.interval,
78
+ autoPlay,
79
+ defaultActiveIndex,
80
+ onChange,
81
+ itemsCount,
82
+ id,
83
+ slidesId
84
+ }) => {
85
+ const [currentIndex, setCurrentIndex] = useState(activeIndex);
86
+ // Use state instead of a ref to make the slideshow controls update directly when the element is set.
87
+ const [element, setElement] = useState(null);
88
+
89
+ // Number of slides when using groupBy prop.
90
+ const slidesCount = Math.ceil(itemsCount / Math.min(groupBy, itemsCount));
91
+
92
+ // Change current index to display next slide.
93
+ const goToNextSlide = useCallback((loopback = true) => {
94
+ setCurrentIndex(index => {
95
+ if (loopback && index === slidesCount - 1) {
96
+ // Loopback to the start.
97
+ return 0;
98
+ }
99
+ if (index < slidesCount - 1) {
100
+ // Next slide.
101
+ return index + 1;
102
+ }
103
+ return index;
104
+ });
105
+ }, [slidesCount, setCurrentIndex]);
106
+
107
+ // Change current index to display previous slide.
108
+ const goToPreviousSlide = useCallback((loopback = true) => {
109
+ setCurrentIndex(index => {
110
+ if (loopback && index === 0) {
111
+ // Loopback to the end.
112
+ return slidesCount - 1;
113
+ }
114
+ if (index > 0) {
115
+ // Previous slide.
116
+ return index - 1;
117
+ }
118
+ return index;
119
+ });
120
+ }, [slidesCount, setCurrentIndex]);
121
+
122
+ // Auto play
123
+ const [isAutoPlaying, setIsAutoPlaying] = useState(Boolean(autoPlay));
124
+ const [isForcePaused, setIsForcePaused] = useState(false);
125
+ const isSlideshowAutoPlaying = isForcePaused ? false : isAutoPlaying;
126
+ // Start
127
+ useInterval(goToNextSlide, isSlideshowAutoPlaying && slidesCount > 1 ? interval : null);
128
+
129
+ // Reset current index if it become invalid.
130
+ useEffect(() => {
131
+ if (currentIndex > slidesCount - 1) {
132
+ setCurrentIndex(defaultActiveIndex);
133
+ }
134
+ }, [currentIndex, slidesCount, defaultActiveIndex]);
135
+ const startAutoPlay = () => {
136
+ setIsAutoPlaying(Boolean(autoPlay));
137
+ };
138
+ const stopAutoPlay = () => {
139
+ setIsAutoPlaying(false);
140
+ };
141
+
142
+ // Handle click on a bullet to go to a specific slide.
143
+ const onPaginationClick = useCallback(index => {
144
+ stopAutoPlay();
145
+ setIsForcePaused(true);
146
+ if (index >= 0 && index < slidesCount) {
147
+ setCurrentIndex(index);
148
+ }
149
+ }, [slidesCount, setCurrentIndex]);
150
+
151
+ // Handle click or keyboard event to go to next slide.
152
+ const onNextClick = useCallback((loopback = true) => {
153
+ stopAutoPlay();
154
+ setIsForcePaused(true);
155
+ goToNextSlide(loopback);
156
+ }, [goToNextSlide]);
157
+
158
+ // Handle click or keyboard event to go to previous slide.
159
+ const onPreviousClick = useCallback((loopback = true) => {
160
+ stopAutoPlay();
161
+ setIsForcePaused(true);
162
+ goToPreviousSlide(loopback);
163
+ }, [goToPreviousSlide]);
164
+
165
+ // If the activeIndex props changes, update the current slide
166
+ useEffect(() => {
167
+ setCurrentIndex(activeIndex);
168
+ }, [activeIndex]);
169
+
170
+ // If the slide changes, with autoplay for example, trigger "onChange"
171
+ useEffect(() => {
172
+ if (!onChange) return;
173
+ onChange(currentIndex);
174
+ }, [currentIndex, onChange]);
175
+ const generatedSlideshowId = useId();
176
+ const slideshowId = id || generatedSlideshowId;
177
+ const generatedSlidesId = useId();
178
+ const slideshowSlidesId = slidesId || generatedSlidesId;
179
+ const toggleAutoPlay = () => {
180
+ if (isSlideshowAutoPlaying) {
181
+ stopAutoPlay();
182
+ } else {
183
+ startAutoPlay();
184
+ }
185
+ };
186
+ const toggleForcePause = () => {
187
+ const shouldBePaused = !isForcePaused;
188
+ setIsForcePaused(shouldBePaused);
189
+ if (!shouldBePaused) {
190
+ startAutoPlay();
191
+ } else {
192
+ stopAutoPlay();
193
+ }
194
+ };
195
+
196
+ // Start index and end index of visible slides.
197
+ const startIndexVisible = currentIndex * groupBy;
198
+ const endIndexVisible = startIndexVisible + groupBy;
199
+ return {
200
+ startIndexVisible,
201
+ endIndexVisible,
202
+ setSlideshow: setElement,
203
+ slideshow: element,
204
+ slideshowId,
205
+ slideshowSlidesId,
206
+ onPreviousClick,
207
+ onNextClick,
208
+ onPaginationClick,
209
+ isAutoPlaying: isSlideshowAutoPlaying,
210
+ toggleAutoPlay,
211
+ activeIndex: currentIndex,
212
+ slidesCount,
213
+ setActiveIndex: setCurrentIndex,
214
+ startAutoPlay,
215
+ stopAutoPlay,
216
+ isForcePaused,
217
+ toggleForcePause
218
+ };
219
+ };
220
+
221
+ /**
222
+ * Classname set on elements whose focus was blocked.
223
+ * This is to easily find elements that have been tempered with,
224
+ * and not elements whose focus was already initially blocked.
225
+ * */
226
+ const BLOCKED_FOCUS_CLASSNAME = 'focus-blocked';
227
+
228
+ /**
229
+ * Manage how slides must behave when visible or not.
230
+ * When not visible, they should be hidden from screen readers and not focusable.
231
+ */
232
+ const useSlideFocusManagement = ({
233
+ isSlideDisplayed,
234
+ slideRef
235
+ }) => {
236
+ useEffect(() => {
237
+ const element = slideRef?.current;
238
+ if (!element) {
239
+ return undefined;
240
+ }
241
+
242
+ /**
243
+ * Display given slide to screen readers and, if focus was blocked, restore focus on elements.
244
+ */
245
+ const enableSlide = () => {
246
+ // Hide from screen readers
247
+ element.setAttribute('aria-hidden', 'false');
248
+ // Find elements we have blocked focus on
249
+ element.querySelectorAll(`.${BLOCKED_FOCUS_CLASSNAME}`).forEach(focusableElement => {
250
+ focusableElement.removeAttribute('tabindex');
251
+ focusableElement.classList.remove(BLOCKED_FOCUS_CLASSNAME);
252
+ });
253
+ };
254
+
255
+ /**
256
+ * Hide given slide from screen readers and block focus on all focusable elements within.
257
+ */
258
+ const blockSlide = () => {
259
+ element.setAttribute('aria-hidden', 'true');
260
+ getFocusableElements(element).forEach(focusableElement => {
261
+ focusableElement.setAttribute('tabindex', '-1');
262
+ focusableElement.classList.add(BLOCKED_FOCUS_CLASSNAME);
263
+ });
264
+ };
265
+ const handleDisplay = () => {
266
+ if (!element) {
267
+ return;
268
+ }
269
+ if (isSlideDisplayed) {
270
+ enableSlide();
271
+ } else {
272
+ blockSlide();
273
+ }
274
+ };
275
+
276
+ // Callback function to execute when mutations are observed
277
+ const callback = mutationsList => {
278
+ if (element) {
279
+ for (const mutation of mutationsList) {
280
+ if (mutation.type === 'childList') {
281
+ handleDisplay();
282
+ }
283
+ }
284
+ }
285
+ };
286
+
287
+ // Create an observer instance linked to the callback function
288
+ const observer = new MutationObserver(callback);
289
+ if (element) {
290
+ handleDisplay();
291
+
292
+ /** If slide is hidden, start observing for elements to block focus */
293
+ if (!isSlideDisplayed) {
294
+ observer.observe(element, {
295
+ attributes: true,
296
+ childList: true,
297
+ subtree: true
298
+ });
299
+ }
300
+ }
301
+ return () => {
302
+ if (!isSlideDisplayed) {
303
+ observer.disconnect();
304
+ }
305
+ };
306
+ }, [isSlideDisplayed, slideRef]);
307
+ };
308
+
309
+ /**
310
+ * Component display name.
311
+ */
312
+ const COMPONENT_NAME$3 = 'SlideshowItemGroup';
313
+
314
+ /**
315
+ * Component default class name and class prefix.
316
+ */
317
+ const CLASSNAME$3 = getRootClassName(COMPONENT_NAME$3);
318
+ const buildSlideShowGroupId = (slidesId, index) => `${slidesId}-slide-${index}`;
319
+
320
+ /**
321
+ * SlideshowItemGroup component.
322
+ *
323
+ * @param props Component props.
324
+ * @param ref Component ref.
325
+ * @return React element.
326
+ */
327
+ const SlideshowItemGroup = forwardRef((props, ref) => {
328
+ const {
329
+ className,
330
+ children,
331
+ role = 'group',
332
+ label,
333
+ isDisplayed,
334
+ ...forwardedProps
335
+ } = props;
336
+ const groupRef = React__default.useRef(null);
337
+ useSlideFocusManagement({
338
+ isSlideDisplayed: isDisplayed,
339
+ slideRef: groupRef
340
+ });
341
+ return /*#__PURE__*/jsx("div", {
342
+ ref: mergeRefs(groupRef, ref),
343
+ role: role,
344
+ className: classNames(className, CLASSNAME$3),
345
+ "aria-roledescription": "slide",
346
+ "aria-label": label,
347
+ ...forwardedProps,
348
+ children: children
349
+ });
350
+ });
351
+ SlideshowItemGroup.displayName = COMPONENT_NAME$3;
352
+ SlideshowItemGroup.className = CLASSNAME$3;
353
+
354
+ /**
355
+ * Component display name.
356
+ */
357
+ const COMPONENT_NAME$2 = 'SlideshowItem';
358
+
359
+ /**
360
+ * Component default class name and class prefix.
361
+ */
362
+ const CLASSNAME$2 = getRootClassName(COMPONENT_NAME$2);
363
+
364
+ /**
365
+ * SlideshowItem component.
366
+ *
367
+ * @param props Component props.
368
+ * @param ref Component ref.
369
+ * @return React element.
370
+ */
371
+ const SlideshowItem = forwardRef((props, ref) => {
372
+ const {
373
+ className,
374
+ children,
375
+ ...forwardedProps
376
+ } = props;
377
+ return /*#__PURE__*/jsx("div", {
378
+ ref: ref,
379
+ className: classNames(className, CLASSNAME$2),
380
+ ...forwardedProps,
381
+ children: children
382
+ });
383
+ });
384
+ SlideshowItem.displayName = COMPONENT_NAME$2;
385
+ SlideshowItem.className = CLASSNAME$2;
386
+
387
+ const isTouchDevice = () => 'ontouchstart' in window;
388
+
389
+ /**
390
+ * Listen swipe to navigate left and right.
391
+ */
392
+ function useSwipeNavigate(element, onNext, onPrevious) {
393
+ useEffect(() => {
394
+ if (!element || !isTouchDevice()) return undefined;
395
+ return detectHorizontalSwipe(element, swipe => {
396
+ const callback = swipe === 'right' ? onPrevious : onNext;
397
+ callback?.();
398
+ });
399
+ }, [onPrevious, onNext, element]);
400
+ }
401
+
402
+ /**
403
+ * Calculate the currently visible pagination "bullet" range.
404
+ */
405
+ function usePaginationVisibleRange(activeIndex, slideCount) {
406
+ const previousVisibleRangeRef = useRef();
407
+ return useMemo(() => {
408
+ const lastSlide = slideCount - 1;
409
+ const {
410
+ current: previousVisibleRange
411
+ } = previousVisibleRangeRef;
412
+ let newVisibleRange;
413
+ if (activeIndex === previousVisibleRange?.max && activeIndex < lastSlide) {
414
+ newVisibleRange = {
415
+ min: previousVisibleRange.min + 1,
416
+ max: previousVisibleRange.max + 1
417
+ };
418
+ } else if (activeIndex === previousVisibleRange?.min && activeIndex > 0) {
419
+ newVisibleRange = {
420
+ min: previousVisibleRange.min - 1,
421
+ max: previousVisibleRange.max - 1
422
+ };
423
+ } else {
424
+ const deltaItems = PAGINATION_ITEMS_MAX - 1;
425
+ let min = activeIndex - EDGE_FROM_ACTIVE_INDEX;
426
+ let max = activeIndex + EDGE_FROM_ACTIVE_INDEX;
427
+ if (activeIndex > lastSlide - EDGE_FROM_ACTIVE_INDEX) {
428
+ min = lastSlide - deltaItems;
429
+ max = lastSlide;
430
+ } else if (activeIndex < deltaItems) {
431
+ min = 0;
432
+ max = deltaItems;
433
+ }
434
+ newVisibleRange = {
435
+ min,
436
+ max
437
+ };
438
+ }
439
+ previousVisibleRangeRef.current = newVisibleRange;
440
+ return newVisibleRange;
441
+ }, [activeIndex, slideCount]);
442
+ }
443
+
444
+ /**
445
+ * Component display name.
446
+ */
447
+ const COMPONENT_NAME$1 = 'SlideshowControls';
448
+
449
+ /**
450
+ * Component default class name and class prefix.
451
+ */
452
+ const CLASSNAME$1 = getRootClassName(COMPONENT_NAME$1);
453
+
454
+ /**
455
+ * Component default props.
456
+ */
457
+ const DEFAULT_PROPS = {
458
+ activeIndex: 0
459
+ };
460
+
461
+ /**
462
+ * SlideshowControls component.
463
+ *
464
+ * @param props Component props.
465
+ * @param ref Component ref.
466
+ * @return React element.
467
+ */
468
+ const InternalSlideshowControls = forwardRef((props, ref) => {
469
+ const defaultTheme = useTheme() || Theme.light;
470
+ const {
471
+ activeIndex = DEFAULT_PROPS.activeIndex,
472
+ className,
473
+ nextButtonProps,
474
+ onNextClick,
475
+ onPaginationClick,
476
+ onPreviousClick,
477
+ parentRef,
478
+ previousButtonProps,
479
+ paginationProps,
480
+ slidesCount,
481
+ theme = defaultTheme,
482
+ isAutoPlaying = false,
483
+ playButtonProps,
484
+ paginationItemLabel,
485
+ paginationItemProps,
486
+ ...forwardedProps
487
+ } = props;
488
+ let parent;
489
+ if (WINDOW) {
490
+ // Checking window object to avoid errors in SSR.
491
+ parent = parentRef instanceof HTMLElement ? parentRef : parentRef?.current;
492
+ }
493
+ const paginationRef = React__default.useRef(null);
494
+ // Listen to touch swipe navigate left & right.
495
+ useSwipeNavigate(parent,
496
+ // Go next without loopback.
497
+ useCallback(() => onNextClick?.(false), [onNextClick]),
498
+ // Go previous without loopback.
499
+ useCallback(() => onPreviousClick?.(false), [onPreviousClick]));
500
+
501
+ /**
502
+ * Add roving tab index pattern to pagination items and activate slide on focus.
503
+ */
504
+ useRovingTabIndex({
505
+ parentRef: paginationRef,
506
+ elementSelector: 'button',
507
+ keepTabIndex: true,
508
+ onElementFocus: element => {
509
+ element.click();
510
+ }
511
+ });
512
+
513
+ // Pagination "bullet" range.
514
+ const visibleRange = usePaginationVisibleRange(activeIndex, slidesCount);
515
+
516
+ // Inline style of wrapper element.
517
+ const wrapperStyle = {
518
+ transform: `translateX(-${PAGINATION_ITEM_SIZE * visibleRange.min}px)`
519
+ };
520
+ return /*#__PURE__*/jsxs("div", {
521
+ ref: ref,
522
+ ...forwardedProps,
523
+ className: classNames(className, handleBasicClasses({
524
+ prefix: CLASSNAME$1,
525
+ theme
526
+ }), {
527
+ [`${CLASSNAME$1}--has-infinite-pagination`]: slidesCount > PAGINATION_ITEMS_MAX
528
+ }),
529
+ children: [/*#__PURE__*/jsx(IconButton, {
530
+ ...previousButtonProps,
531
+ icon: mdiChevronLeft,
532
+ className: `${CLASSNAME$1}__navigation`,
533
+ color: theme === Theme.dark ? 'light' : 'dark',
534
+ emphasis: Emphasis.low,
535
+ onClick: onPreviousClick
536
+ }), /*#__PURE__*/jsx("div", {
537
+ ref: paginationRef,
538
+ className: `${CLASSNAME$1}__pagination`,
539
+ children: /*#__PURE__*/jsx("div", {
540
+ className: `${CLASSNAME$1}__pagination-items`,
541
+ style: wrapperStyle,
542
+ role: "tablist",
543
+ ...paginationProps,
544
+ children: useMemo(() => range(slidesCount).map(index => {
545
+ const isOnEdge = index !== 0 && index !== slidesCount - 1 && (index === visibleRange.min || index === visibleRange.max);
546
+ const isActive = activeIndex === index;
547
+ const isOutRange = index < visibleRange.min || index > visibleRange.max;
548
+ const {
549
+ className: itemClassName = undefined,
550
+ label = undefined,
551
+ ...itemProps
552
+ } = paginationItemProps ? paginationItemProps(index) : {};
553
+ const ariaLabel = label || paginationItemLabel?.(index) || `${index + 1} / ${slidesCount}`;
554
+ return /*#__PURE__*/jsx("button", {
555
+ className: classNames(handleBasicClasses({
556
+ prefix: `${CLASSNAME$1}__pagination-item`,
557
+ isActive,
558
+ isOnEdge,
559
+ isOutRange
560
+ }), itemClassName),
561
+ type: "button",
562
+ tabIndex: isActive ? undefined : -1,
563
+ role: "tab",
564
+ "aria-selected": isActive,
565
+ onClick: () => onPaginationClick?.(index),
566
+ "aria-label": ariaLabel,
567
+ ...itemProps
568
+ }, index);
569
+ }), [slidesCount, visibleRange.min, visibleRange.max, activeIndex, paginationItemProps, paginationItemLabel, onPaginationClick])
570
+ })
571
+ }), playButtonProps ? /*#__PURE__*/jsx(IconButton, {
572
+ ...playButtonProps,
573
+ icon: isAutoPlaying ? mdiPauseCircleOutline : mdiPlayCircleOutline,
574
+ className: `${CLASSNAME$1}__play`,
575
+ color: theme === Theme.dark ? 'light' : 'dark',
576
+ emphasis: Emphasis.low
577
+ }) : null, /*#__PURE__*/jsx(IconButton, {
578
+ ...nextButtonProps,
579
+ icon: mdiChevronRight,
580
+ className: `${CLASSNAME$1}__navigation`,
581
+ color: theme === Theme.dark ? 'light' : 'dark',
582
+ emphasis: Emphasis.low,
583
+ onClick: onNextClick
584
+ })]
585
+ });
586
+ });
587
+ InternalSlideshowControls.displayName = COMPONENT_NAME$1;
588
+ InternalSlideshowControls.className = CLASSNAME$1;
589
+ InternalSlideshowControls.defaultProps = DEFAULT_PROPS;
590
+ const SlideshowControls = Object.assign(InternalSlideshowControls, {
591
+ useSlideshowControls,
592
+ useSlideshowControlsDefaultOptions: DEFAULT_OPTIONS
593
+ });
594
+
595
+ /**
596
+ * Component display name.
597
+ */
598
+ const COMPONENT_NAME = 'Slideshow';
599
+
600
+ /**
601
+ * Component default class name and class prefix.
602
+ */
603
+ const CLASSNAME = getRootClassName(COMPONENT_NAME);
604
+
605
+ /**
606
+ * Slides component.
607
+ *
608
+ * @param props Component props.
609
+ * @param ref Component ref.
610
+ * @return React element.
611
+ */
612
+ const Slides = forwardRef((props, ref) => {
613
+ const defaultTheme = useTheme();
614
+ const {
615
+ activeIndex,
616
+ id,
617
+ className,
618
+ theme = defaultTheme,
619
+ fillHeight,
620
+ groupBy,
621
+ isAutoPlaying,
622
+ toggleAutoPlay,
623
+ slidesId,
624
+ children,
625
+ afterSlides,
626
+ hasControls,
627
+ slideGroupLabel,
628
+ ...forwardedProps
629
+ } = props;
630
+ const wrapperRef = React__default.useRef(null);
631
+ const startIndexVisible = activeIndex;
632
+ const endIndexVisible = startIndexVisible + 1;
633
+
634
+ // Inline style of wrapper element.
635
+ const wrapperStyle = {
636
+ transform: `translateX(-${FULL_WIDTH_PERCENT * activeIndex}%)`
637
+ };
638
+ const groups = React__default.useMemo(() => {
639
+ const childrenArray = Children.toArray(children);
640
+ return groupBy && groupBy > 1 ? chunk(childrenArray, groupBy) : childrenArray;
641
+ }, [children, groupBy]);
642
+ return /*#__PURE__*/jsxs("section", {
643
+ id: id,
644
+ ref: ref,
645
+ ...forwardedProps,
646
+ className: classNames(className, handleBasicClasses({
647
+ prefix: CLASSNAME,
648
+ theme
649
+ }), {
650
+ [`${CLASSNAME}--fill-height`]: fillHeight,
651
+ [`${CLASSNAME}--group-by-${groupBy}`]: Boolean(groupBy)
652
+ }),
653
+ "aria-roledescription": "carousel",
654
+ children: [/*#__PURE__*/jsx("div", {
655
+ id: slidesId,
656
+ className: `${CLASSNAME}__slides`,
657
+ onMouseEnter: toggleAutoPlay,
658
+ onMouseLeave: toggleAutoPlay,
659
+ "aria-live": isAutoPlaying ? 'off' : 'polite',
660
+ children: /*#__PURE__*/jsx("div", {
661
+ ref: wrapperRef,
662
+ className: `${CLASSNAME}__wrapper`,
663
+ style: wrapperStyle,
664
+ children: groups.map((group, index) => /*#__PURE__*/jsx(SlideshowItemGroup, {
665
+ id: slidesId && buildSlideShowGroupId(slidesId, index),
666
+ role: hasControls ? 'tabpanel' : 'group',
667
+ label: slideGroupLabel ? slideGroupLabel(index + 1, groups.length) : undefined,
668
+ isDisplayed: index >= startIndexVisible && index < endIndexVisible,
669
+ children: group
670
+ }, index))
671
+ })
672
+ }), afterSlides]
673
+ });
674
+ });
675
+ Slides.displayName = COMPONENT_NAME;
676
+ Slides.className = CLASSNAME;
677
+
678
+ export { DEFAULT_OPTIONS as D, SlideshowItem as S, SlideshowControls as a, Slides as b, buildSlideShowGroupId as c };
679
+ //# sourceMappingURL=Slides-ce641b5f.js.map