1 | "use strict";
|
2 | "use client";
|
3 |
|
4 | var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
5 | exports.__esModule = true;
|
6 | exports.default = void 0;
|
7 | var _useEventCallback = _interopRequireDefault(require("@restart/hooks/useEventCallback"));
|
8 | var _useUpdateEffect = _interopRequireDefault(require("@restart/hooks/useUpdateEffect"));
|
9 | var _useCommittedRef = _interopRequireDefault(require("@restart/hooks/useCommittedRef"));
|
10 | var _useTimeout = _interopRequireDefault(require("@restart/hooks/useTimeout"));
|
11 | var _Anchor = _interopRequireDefault(require("@restart/ui/Anchor"));
|
12 | var _classnames = _interopRequireDefault(require("classnames"));
|
13 | var React = _interopRequireWildcard(require("react"));
|
14 | var _uncontrollable = require("uncontrollable");
|
15 | var _CarouselCaption = _interopRequireDefault(require("./CarouselCaption"));
|
16 | var _CarouselItem = _interopRequireDefault(require("./CarouselItem"));
|
17 | var _ElementChildren = require("./ElementChildren");
|
18 | var _ThemeProvider = require("./ThemeProvider");
|
19 | var _transitionEndListener = _interopRequireDefault(require("./transitionEndListener"));
|
20 | var _triggerBrowserReflow = _interopRequireDefault(require("./triggerBrowserReflow"));
|
21 | var _TransitionWrapper = _interopRequireDefault(require("./TransitionWrapper"));
|
22 | var _jsxRuntime = require("react/jsx-runtime");
|
23 | function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
24 | function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
25 | const SWIPE_THRESHOLD = 40;
|
26 | function isVisible(element) {
|
27 | if (!element || !element.style || !element.parentNode || !element.parentNode.style) {
|
28 | return false;
|
29 | }
|
30 | const elementStyle = getComputedStyle(element);
|
31 | return elementStyle.display !== 'none' && elementStyle.visibility !== 'hidden' && getComputedStyle(element.parentNode).display !== 'none';
|
32 | }
|
33 | const Carousel = React.forwardRef(({
|
34 | defaultActiveIndex = 0,
|
35 | ...uncontrolledProps
|
36 | }, ref) => {
|
37 | const {
|
38 |
|
39 | as: Component = 'div',
|
40 | bsPrefix,
|
41 | slide = true,
|
42 | fade = false,
|
43 | controls = true,
|
44 | indicators = true,
|
45 | indicatorLabels = [],
|
46 | activeIndex,
|
47 | onSelect,
|
48 | onSlide,
|
49 | onSlid,
|
50 | interval = 5000,
|
51 | keyboard = true,
|
52 | onKeyDown,
|
53 | pause = 'hover',
|
54 | onMouseOver,
|
55 | onMouseOut,
|
56 | wrap = true,
|
57 | touch = true,
|
58 | onTouchStart,
|
59 | onTouchMove,
|
60 | onTouchEnd,
|
61 | prevIcon = (0, _jsxRuntime.jsx)("span", {
|
62 | "aria-hidden": "true",
|
63 | className: "carousel-control-prev-icon"
|
64 | }),
|
65 | prevLabel = 'Previous',
|
66 | nextIcon = (0, _jsxRuntime.jsx)("span", {
|
67 | "aria-hidden": "true",
|
68 | className: "carousel-control-next-icon"
|
69 | }),
|
70 | nextLabel = 'Next',
|
71 | variant,
|
72 | className,
|
73 | children,
|
74 | ...props
|
75 | } = (0, _uncontrollable.useUncontrolled)({
|
76 | defaultActiveIndex,
|
77 | ...uncontrolledProps
|
78 | }, {
|
79 | activeIndex: 'onSelect'
|
80 | });
|
81 | const prefix = (0, _ThemeProvider.useBootstrapPrefix)(bsPrefix, 'carousel');
|
82 | const isRTL = (0, _ThemeProvider.useIsRTL)();
|
83 | const nextDirectionRef = (0, React.useRef)(null);
|
84 | const [direction, setDirection] = (0, React.useState)('next');
|
85 | const [paused, setPaused] = (0, React.useState)(false);
|
86 | const [isSliding, setIsSliding] = (0, React.useState)(false);
|
87 | const [renderedActiveIndex, setRenderedActiveIndex] = (0, React.useState)(activeIndex || 0);
|
88 | (0, React.useEffect)(() => {
|
89 | if (!isSliding && activeIndex !== renderedActiveIndex) {
|
90 | if (nextDirectionRef.current) {
|
91 | setDirection(nextDirectionRef.current);
|
92 | } else {
|
93 | setDirection((activeIndex || 0) > renderedActiveIndex ? 'next' : 'prev');
|
94 | }
|
95 | if (slide) {
|
96 | setIsSliding(true);
|
97 | }
|
98 | setRenderedActiveIndex(activeIndex || 0);
|
99 | }
|
100 | }, [activeIndex, isSliding, renderedActiveIndex, slide]);
|
101 | (0, React.useEffect)(() => {
|
102 | if (nextDirectionRef.current) {
|
103 | nextDirectionRef.current = null;
|
104 | }
|
105 | });
|
106 | let numChildren = 0;
|
107 | let activeChildInterval;
|
108 |
|
109 |
|
110 |
|
111 | (0, _ElementChildren.forEach)(children, (child, index) => {
|
112 | ++numChildren;
|
113 | if (index === activeIndex) {
|
114 | activeChildInterval = child.props.interval;
|
115 | }
|
116 | });
|
117 | const activeChildIntervalRef = (0, _useCommittedRef.default)(activeChildInterval);
|
118 | const prev = (0, React.useCallback)(event => {
|
119 | if (isSliding) {
|
120 | return;
|
121 | }
|
122 | let nextActiveIndex = renderedActiveIndex - 1;
|
123 | if (nextActiveIndex < 0) {
|
124 | if (!wrap) {
|
125 | return;
|
126 | }
|
127 | nextActiveIndex = numChildren - 1;
|
128 | }
|
129 | nextDirectionRef.current = 'prev';
|
130 | onSelect == null ? void 0 : onSelect(nextActiveIndex, event);
|
131 | }, [isSliding, renderedActiveIndex, onSelect, wrap, numChildren]);
|
132 |
|
133 |
|
134 | const next = (0, _useEventCallback.default)(event => {
|
135 | if (isSliding) {
|
136 | return;
|
137 | }
|
138 | let nextActiveIndex = renderedActiveIndex + 1;
|
139 | if (nextActiveIndex >= numChildren) {
|
140 | if (!wrap) {
|
141 | return;
|
142 | }
|
143 | nextActiveIndex = 0;
|
144 | }
|
145 | nextDirectionRef.current = 'next';
|
146 | onSelect == null ? void 0 : onSelect(nextActiveIndex, event);
|
147 | });
|
148 | const elementRef = (0, React.useRef)();
|
149 | (0, React.useImperativeHandle)(ref, () => ({
|
150 | element: elementRef.current,
|
151 | prev,
|
152 | next
|
153 | }));
|
154 |
|
155 |
|
156 | const nextWhenVisible = (0, _useEventCallback.default)(() => {
|
157 | if (!document.hidden && isVisible(elementRef.current)) {
|
158 | if (isRTL) {
|
159 | prev();
|
160 | } else {
|
161 | next();
|
162 | }
|
163 | }
|
164 | });
|
165 | const slideDirection = direction === 'next' ? 'start' : 'end';
|
166 | (0, _useUpdateEffect.default)(() => {
|
167 | if (slide) {
|
168 |
|
169 | return;
|
170 | }
|
171 | onSlide == null ? void 0 : onSlide(renderedActiveIndex, slideDirection);
|
172 | onSlid == null ? void 0 : onSlid(renderedActiveIndex, slideDirection);
|
173 | }, [renderedActiveIndex]);
|
174 | const orderClassName = `${prefix}-item-${direction}`;
|
175 | const directionalClassName = `${prefix}-item-${slideDirection}`;
|
176 | const handleEnter = (0, React.useCallback)(node => {
|
177 | (0, _triggerBrowserReflow.default)(node);
|
178 | onSlide == null ? void 0 : onSlide(renderedActiveIndex, slideDirection);
|
179 | }, [onSlide, renderedActiveIndex, slideDirection]);
|
180 | const handleEntered = (0, React.useCallback)(() => {
|
181 | setIsSliding(false);
|
182 | onSlid == null ? void 0 : onSlid(renderedActiveIndex, slideDirection);
|
183 | }, [onSlid, renderedActiveIndex, slideDirection]);
|
184 | const handleKeyDown = (0, React.useCallback)(event => {
|
185 | if (keyboard && !/input|textarea/i.test(event.target.tagName)) {
|
186 | switch (event.key) {
|
187 | case 'ArrowLeft':
|
188 | event.preventDefault();
|
189 | if (isRTL) {
|
190 | next(event);
|
191 | } else {
|
192 | prev(event);
|
193 | }
|
194 | return;
|
195 | case 'ArrowRight':
|
196 | event.preventDefault();
|
197 | if (isRTL) {
|
198 | prev(event);
|
199 | } else {
|
200 | next(event);
|
201 | }
|
202 | return;
|
203 | default:
|
204 | }
|
205 | }
|
206 | onKeyDown == null ? void 0 : onKeyDown(event);
|
207 | }, [keyboard, onKeyDown, prev, next, isRTL]);
|
208 | const handleMouseOver = (0, React.useCallback)(event => {
|
209 | if (pause === 'hover') {
|
210 | setPaused(true);
|
211 | }
|
212 | onMouseOver == null ? void 0 : onMouseOver(event);
|
213 | }, [pause, onMouseOver]);
|
214 | const handleMouseOut = (0, React.useCallback)(event => {
|
215 | setPaused(false);
|
216 | onMouseOut == null ? void 0 : onMouseOut(event);
|
217 | }, [onMouseOut]);
|
218 | const touchStartXRef = (0, React.useRef)(0);
|
219 | const touchDeltaXRef = (0, React.useRef)(0);
|
220 | const touchUnpauseTimeout = (0, _useTimeout.default)();
|
221 | const handleTouchStart = (0, React.useCallback)(event => {
|
222 | touchStartXRef.current = event.touches[0].clientX;
|
223 | touchDeltaXRef.current = 0;
|
224 | if (pause === 'hover') {
|
225 | setPaused(true);
|
226 | }
|
227 | onTouchStart == null ? void 0 : onTouchStart(event);
|
228 | }, [pause, onTouchStart]);
|
229 | const handleTouchMove = (0, React.useCallback)(event => {
|
230 | if (event.touches && event.touches.length > 1) {
|
231 | touchDeltaXRef.current = 0;
|
232 | } else {
|
233 | touchDeltaXRef.current = event.touches[0].clientX - touchStartXRef.current;
|
234 | }
|
235 | onTouchMove == null ? void 0 : onTouchMove(event);
|
236 | }, [onTouchMove]);
|
237 | const handleTouchEnd = (0, React.useCallback)(event => {
|
238 | if (touch) {
|
239 | const touchDeltaX = touchDeltaXRef.current;
|
240 | if (Math.abs(touchDeltaX) > SWIPE_THRESHOLD) {
|
241 | if (touchDeltaX > 0) {
|
242 | prev(event);
|
243 | } else {
|
244 | next(event);
|
245 | }
|
246 | }
|
247 | }
|
248 | if (pause === 'hover') {
|
249 | touchUnpauseTimeout.set(() => {
|
250 | setPaused(false);
|
251 | }, interval || undefined);
|
252 | }
|
253 | onTouchEnd == null ? void 0 : onTouchEnd(event);
|
254 | }, [touch, pause, prev, next, touchUnpauseTimeout, interval, onTouchEnd]);
|
255 | const shouldPlay = interval != null && !paused && !isSliding;
|
256 | const intervalHandleRef = (0, React.useRef)();
|
257 | (0, React.useEffect)(() => {
|
258 | var _ref, _activeChildIntervalR;
|
259 | if (!shouldPlay) {
|
260 | return undefined;
|
261 | }
|
262 | const nextFunc = isRTL ? prev : next;
|
263 | intervalHandleRef.current = window.setInterval(document.visibilityState ? nextWhenVisible : nextFunc, (_ref = (_activeChildIntervalR = activeChildIntervalRef.current) != null ? _activeChildIntervalR : interval) != null ? _ref : undefined);
|
264 | return () => {
|
265 | if (intervalHandleRef.current !== null) {
|
266 | clearInterval(intervalHandleRef.current);
|
267 | }
|
268 | };
|
269 | }, [shouldPlay, prev, next, activeChildIntervalRef, interval, nextWhenVisible, isRTL]);
|
270 | const indicatorOnClicks = (0, React.useMemo)(() => indicators && Array.from({
|
271 | length: numChildren
|
272 | }, (_, index) => event => {
|
273 | onSelect == null ? void 0 : onSelect(index, event);
|
274 | }), [indicators, numChildren, onSelect]);
|
275 | return (0, _jsxRuntime.jsxs)(Component, {
|
276 | ref: elementRef,
|
277 | ...props,
|
278 | onKeyDown: handleKeyDown,
|
279 | onMouseOver: handleMouseOver,
|
280 | onMouseOut: handleMouseOut,
|
281 | onTouchStart: handleTouchStart,
|
282 | onTouchMove: handleTouchMove,
|
283 | onTouchEnd: handleTouchEnd,
|
284 | className: (0, _classnames.default)(className, prefix, slide && 'slide', fade && `${prefix}-fade`, variant && `${prefix}-${variant}`),
|
285 | children: [indicators && (0, _jsxRuntime.jsx)("div", {
|
286 | className: `${prefix}-indicators`,
|
287 | children: (0, _ElementChildren.map)(children, (_, index) => (0, _jsxRuntime.jsx)("button", {
|
288 | type: "button",
|
289 | "data-bs-target": ""
|
290 | ,
|
291 | "aria-label": indicatorLabels != null && indicatorLabels.length ? indicatorLabels[index] : `Slide ${index + 1}`,
|
292 | className: index === renderedActiveIndex ? 'active' : undefined,
|
293 | onClick: indicatorOnClicks ? indicatorOnClicks[index] : undefined,
|
294 | "aria-current": index === renderedActiveIndex
|
295 | }, index))
|
296 | }), (0, _jsxRuntime.jsx)("div", {
|
297 | className: `${prefix}-inner`,
|
298 | children: (0, _ElementChildren.map)(children, (child, index) => {
|
299 | const isActive = index === renderedActiveIndex;
|
300 | return slide ? (0, _jsxRuntime.jsx)(_TransitionWrapper.default, {
|
301 | in: isActive,
|
302 | onEnter: isActive ? handleEnter : undefined,
|
303 | onEntered: isActive ? handleEntered : undefined,
|
304 | addEndListener: _transitionEndListener.default,
|
305 | children: (status, innerProps) => React.cloneElement(child, {
|
306 | ...innerProps,
|
307 | className: (0, _classnames.default)(child.props.className, isActive && status !== 'entered' && orderClassName, (status === 'entered' || status === 'exiting') && 'active', (status === 'entering' || status === 'exiting') && directionalClassName)
|
308 | })
|
309 | }) : React.cloneElement(child, {
|
310 | className: (0, _classnames.default)(child.props.className, isActive && 'active')
|
311 | });
|
312 | })
|
313 | }), controls && (0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
314 | children: [(wrap || activeIndex !== 0) && (0, _jsxRuntime.jsxs)(_Anchor.default, {
|
315 | className: `${prefix}-control-prev`,
|
316 | onClick: prev,
|
317 | children: [prevIcon, prevLabel && (0, _jsxRuntime.jsx)("span", {
|
318 | className: "visually-hidden",
|
319 | children: prevLabel
|
320 | })]
|
321 | }), (wrap || activeIndex !== numChildren - 1) && (0, _jsxRuntime.jsxs)(_Anchor.default, {
|
322 | className: `${prefix}-control-next`,
|
323 | onClick: next,
|
324 | children: [nextIcon, nextLabel && (0, _jsxRuntime.jsx)("span", {
|
325 | className: "visually-hidden",
|
326 | children: nextLabel
|
327 | })]
|
328 | })]
|
329 | })]
|
330 | });
|
331 | });
|
332 | Carousel.displayName = 'Carousel';
|
333 | var _default = Object.assign(Carousel, {
|
334 | Caption: _CarouselCaption.default,
|
335 | Item: _CarouselItem.default
|
336 | });
|
337 | exports.default = _default;
|
338 | module.exports = exports.default; |
\ | No newline at end of file |