@lumx/react 3.9.4-alpha.0 → 3.9.4-alpha.2
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/index.js +86 -72
- package/index.js.map +1 -1
- package/package.json +3 -3
- package/src/components/slideshow/Slides.tsx +8 -2
- package/src/components/slideshow/constants.ts +4 -0
- package/src/components/slideshow/useSlideFocusManagement.tsx +64 -67
- package/src/components/slideshow/useSlideshowControls.ts +13 -1
package/index.js
CHANGED
|
@@ -11806,6 +11806,8 @@ const PAGINATION_ITEMS_MAX = 5;
|
|
|
11806
11806
|
* Size of a pagination item. Used to translate wrapper.
|
|
11807
11807
|
*/
|
|
11808
11808
|
const PAGINATION_ITEM_SIZE = 12;
|
|
11809
|
+
const NEXT_SLIDE_EVENT = 'lumx-next-slide-event';
|
|
11810
|
+
const PREV_SLIDE_EVENT = 'lumx-prev-slide-event';
|
|
11809
11811
|
|
|
11810
11812
|
const DEFAULT_OPTIONS = {
|
|
11811
11813
|
activeIndex: 0,
|
|
@@ -11901,6 +11903,17 @@ const useSlideshowControls = _ref => {
|
|
|
11901
11903
|
goTo(-1, loopBack, true);
|
|
11902
11904
|
}, [goTo, stopAutoPlay]);
|
|
11903
11905
|
|
|
11906
|
+
// Listen to custom next/prev slide events
|
|
11907
|
+
useEffect(() => {
|
|
11908
|
+
if (!element) return undefined;
|
|
11909
|
+
element.addEventListener(NEXT_SLIDE_EVENT, onNextClick);
|
|
11910
|
+
element.addEventListener(PREV_SLIDE_EVENT, onPreviousClick);
|
|
11911
|
+
return () => {
|
|
11912
|
+
element.removeEventListener(NEXT_SLIDE_EVENT, onNextClick);
|
|
11913
|
+
element.removeEventListener(PREV_SLIDE_EVENT, onPreviousClick);
|
|
11914
|
+
};
|
|
11915
|
+
}, [element, onNextClick, onPreviousClick]);
|
|
11916
|
+
|
|
11904
11917
|
// If the activeIndex props changes, update the current slide
|
|
11905
11918
|
useEffect(() => {
|
|
11906
11919
|
setActiveIndex(activeIndex);
|
|
@@ -12125,11 +12138,11 @@ function useKeyNavigate(element, onNext, onPrevious) {
|
|
|
12125
12138
|
}
|
|
12126
12139
|
|
|
12127
12140
|
/**
|
|
12128
|
-
*
|
|
12141
|
+
* Data attribute set on elements whose focus was blocked.
|
|
12129
12142
|
* This is to easily find elements that have been tempered with,
|
|
12130
12143
|
* and not elements whose focus was already initially blocked.
|
|
12131
|
-
|
|
12132
|
-
const
|
|
12144
|
+
*/
|
|
12145
|
+
const BLOCKED_FOCUS = 'data-focus-blocked';
|
|
12133
12146
|
|
|
12134
12147
|
/**
|
|
12135
12148
|
* Manage how slides must behave when visible or not.
|
|
@@ -12141,91 +12154,88 @@ const useSlideFocusManagement = _ref => {
|
|
|
12141
12154
|
slidesRef
|
|
12142
12155
|
} = _ref;
|
|
12143
12156
|
const [slide, setSlide] = React__default.useState(null);
|
|
12144
|
-
|
|
12145
|
-
|
|
12157
|
+
const [focusableElementSet, setFocusableElementSet] = React__default.useState();
|
|
12158
|
+
React__default.useEffect(() => {
|
|
12146
12159
|
if (!slide) {
|
|
12147
12160
|
return undefined;
|
|
12148
12161
|
}
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
slide.removeAttribute('inert');
|
|
12157
|
-
slide.setAttribute('aria-hidden', 'false');
|
|
12158
|
-
// Find elements we have blocked focus on
|
|
12159
|
-
// (won't be necessary once "inert" gets sufficient browser support)
|
|
12160
|
-
focusableElements = Array.from(slide.querySelectorAll(`.${BLOCKED_FOCUS_CLASSNAME}`));
|
|
12161
|
-
for (const focusableElement of focusableElements) {
|
|
12162
|
-
focusableElement.removeAttribute('tabindex');
|
|
12163
|
-
focusableElement.classList.remove(BLOCKED_FOCUS_CLASSNAME);
|
|
12162
|
+
// Update the slide's focusable element list (including the blocked elements)
|
|
12163
|
+
const updateFocusableElements = () => setFocusableElementSet(function () {
|
|
12164
|
+
let set = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Set();
|
|
12165
|
+
// TODO: remove when `inert` gets sufficient browser support
|
|
12166
|
+
const focusedBlocked = Array.from(slide.querySelectorAll(`[${BLOCKED_FOCUS}]`));
|
|
12167
|
+
for (const element of focusedBlocked) {
|
|
12168
|
+
set.add(element);
|
|
12164
12169
|
}
|
|
12165
|
-
|
|
12170
|
+
for (const element of getFocusableElements(slide)) {
|
|
12171
|
+
set.add(element);
|
|
12172
|
+
}
|
|
12173
|
+
return set;
|
|
12174
|
+
});
|
|
12166
12175
|
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12176
|
+
// Observe changes in the content of the slide
|
|
12177
|
+
const observer = new MutationObserver(mutationsList => {
|
|
12178
|
+
if (mutationsList.some(mutation => mutation.type === 'childList')) {
|
|
12179
|
+
updateFocusableElements();
|
|
12180
|
+
}
|
|
12181
|
+
});
|
|
12182
|
+
updateFocusableElements();
|
|
12183
|
+
observer.observe(slide, {
|
|
12184
|
+
attributes: true,
|
|
12185
|
+
childList: true,
|
|
12186
|
+
subtree: true
|
|
12187
|
+
});
|
|
12188
|
+
return observer.disconnect();
|
|
12189
|
+
}, [slide]);
|
|
12190
|
+
useEffect(() => {
|
|
12191
|
+
if (!slide || !focusableElementSet) {
|
|
12192
|
+
return;
|
|
12193
|
+
}
|
|
12194
|
+
const focusableElements = Array.from(focusableElementSet);
|
|
12195
|
+
if (!isSlideDisplayed) {
|
|
12196
|
+
/* Block slide */
|
|
12171
12197
|
slide.setAttribute('inert', '');
|
|
12172
12198
|
slide.setAttribute('aria-hidden', 'true');
|
|
12173
|
-
|
|
12199
|
+
|
|
12200
|
+
// TODO: remove when `inert` gets sufficient browser support
|
|
12174
12201
|
for (const focusableElement of focusableElements) {
|
|
12175
12202
|
focusableElement.setAttribute('tabindex', '-1');
|
|
12176
|
-
focusableElement.
|
|
12203
|
+
focusableElement.setAttribute(BLOCKED_FOCUS, '');
|
|
12177
12204
|
}
|
|
12178
|
-
}
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
blockSlide();
|
|
12184
|
-
}
|
|
12185
|
-
};
|
|
12205
|
+
} else {
|
|
12206
|
+
var _slidesRef$current;
|
|
12207
|
+
/* Un-block slide */
|
|
12208
|
+
slide.removeAttribute('inert');
|
|
12209
|
+
slide.removeAttribute('aria-hidden');
|
|
12186
12210
|
|
|
12187
|
-
|
|
12188
|
-
|
|
12189
|
-
|
|
12190
|
-
|
|
12191
|
-
if (mutation.type === 'childList') {
|
|
12192
|
-
handleDisplay();
|
|
12193
|
-
}
|
|
12211
|
+
// TODO: remove when `inert` gets sufficient browser support
|
|
12212
|
+
for (const focusableElement of focusableElements) {
|
|
12213
|
+
focusableElement.removeAttribute('tabindex');
|
|
12214
|
+
focusableElement.removeAttribute(BLOCKED_FOCUS);
|
|
12194
12215
|
}
|
|
12195
|
-
});
|
|
12196
|
-
handleDisplay();
|
|
12197
12216
|
|
|
12198
|
-
|
|
12199
|
-
|
|
12200
|
-
|
|
12201
|
-
|
|
12217
|
+
// Change focus on slide displayed
|
|
12218
|
+
const isUserActivated = (slidesRef === null || slidesRef === void 0 ? void 0 : (_slidesRef$current = slidesRef.current) === null || _slidesRef$current === void 0 ? void 0 : _slidesRef$current.dataset.lumxUserActivated) === 'true';
|
|
12219
|
+
if (isUserActivated) {
|
|
12220
|
+
var _elementToFocus;
|
|
12221
|
+
let elementToFocus = slide;
|
|
12202
12222
|
|
|
12203
|
-
|
|
12204
|
-
|
|
12205
|
-
|
|
12206
|
-
|
|
12207
|
-
|
|
12223
|
+
// We have exactly one focusable element => focus it
|
|
12224
|
+
if (focusableElementSet.size === 1) {
|
|
12225
|
+
// eslint-disable-next-line prefer-destructuring
|
|
12226
|
+
elementToFocus = focusableElements[0];
|
|
12227
|
+
}
|
|
12208
12228
|
|
|
12209
|
-
|
|
12210
|
-
|
|
12211
|
-
|
|
12229
|
+
// We have not focusable element => focus the pagination item
|
|
12230
|
+
if (focusableElementSet.size === 0) {
|
|
12231
|
+
elementToFocus = document.querySelector(`[aria-controls="${slide === null || slide === void 0 ? void 0 : slide.id}"]`);
|
|
12232
|
+
}
|
|
12233
|
+
(_elementToFocus = elementToFocus) === null || _elementToFocus === void 0 ? void 0 : _elementToFocus.focus({
|
|
12234
|
+
preventScroll: true
|
|
12235
|
+
});
|
|
12212
12236
|
}
|
|
12213
|
-
(_elementToFocus = elementToFocus) === null || _elementToFocus === void 0 ? void 0 : _elementToFocus.focus({
|
|
12214
|
-
preventScroll: true
|
|
12215
|
-
});
|
|
12216
|
-
}
|
|
12217
|
-
|
|
12218
|
-
/** If slide is hidden, start observing for elements to block focus */
|
|
12219
|
-
if (!isSlideDisplayed) {
|
|
12220
|
-
observer.observe(slide, {
|
|
12221
|
-
attributes: true,
|
|
12222
|
-
childList: true,
|
|
12223
|
-
subtree: true
|
|
12224
|
-
});
|
|
12225
|
-
return () => observer.disconnect();
|
|
12226
12237
|
}
|
|
12227
|
-
|
|
12228
|
-
}, [isSlideDisplayed, slide, slidesRef]);
|
|
12238
|
+
}, [focusableElementSet, isSlideDisplayed, slide, slidesRef]);
|
|
12229
12239
|
return setSlide;
|
|
12230
12240
|
};
|
|
12231
12241
|
|
|
@@ -12527,6 +12537,10 @@ const Slides = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
12527
12537
|
return groupBy && groupBy > 1 ? chunk(childrenArray, groupBy) : childrenArray;
|
|
12528
12538
|
}, [children, groupBy]);
|
|
12529
12539
|
const slidesRef = React__default.useRef(null);
|
|
12540
|
+
const slide = slidesRef.current;
|
|
12541
|
+
const onNextSlide = React__default.useCallback(() => slide === null || slide === void 0 ? void 0 : slide.dispatchEvent(new CustomEvent(NEXT_SLIDE_EVENT)), [slide]);
|
|
12542
|
+
const onPrevSlide = React__default.useCallback(() => slide === null || slide === void 0 ? void 0 : slide.dispatchEvent(new CustomEvent(NEXT_SLIDE_EVENT)), [slide]);
|
|
12543
|
+
useKeyNavigate(slide, onNextSlide, onPrevSlide);
|
|
12530
12544
|
return /*#__PURE__*/React__default.createElement("section", _extends({
|
|
12531
12545
|
id: id,
|
|
12532
12546
|
ref: useMergeRefs(slidesRef, ref)
|
|
@@ -12551,7 +12565,7 @@ const Slides = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
12551
12565
|
}, groups.map((group, index) => /*#__PURE__*/React__default.createElement(SlideshowItemGroup, {
|
|
12552
12566
|
key: index,
|
|
12553
12567
|
id: slidesId && buildSlideShowGroupId(slidesId, index),
|
|
12554
|
-
label: slideGroupLabel ? slideGroupLabel(index + 1, groups.length)
|
|
12568
|
+
label: slideGroupLabel === null || slideGroupLabel === void 0 ? void 0 : slideGroupLabel(index + 1, groups.length),
|
|
12555
12569
|
isDisplayed: index >= startIndexVisible && index < endIndexVisible,
|
|
12556
12570
|
slidesRef: slidesRef
|
|
12557
12571
|
}, group)))), afterSlides);
|