@thewhateverapp/tile-sdk 0.13.1 → 0.13.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.
|
@@ -86,6 +86,10 @@ export interface SlideshowProps {
|
|
|
86
86
|
showDots?: boolean;
|
|
87
87
|
/** Show navigation arrows (default: true) */
|
|
88
88
|
showArrows?: boolean;
|
|
89
|
+
/** Enable swipe gestures on touch devices (default: true) */
|
|
90
|
+
swipeable?: boolean;
|
|
91
|
+
/** Image fit mode: 'cover' fills container (may crop), 'contain' shows full image (may letterbox) */
|
|
92
|
+
objectFit?: 'cover' | 'contain';
|
|
89
93
|
/** Children rendered as overlay */
|
|
90
94
|
children?: ReactNode;
|
|
91
95
|
/** Additional class names */
|
|
@@ -106,7 +110,7 @@ export interface SlideshowProps {
|
|
|
106
110
|
* </Slideshow>
|
|
107
111
|
* ```
|
|
108
112
|
*/
|
|
109
|
-
export declare function Slideshow({ images, intervalMs, autoAdvance, transition, transitionDuration, showDots, showArrows, children, className, imageClassName, }: SlideshowProps): React.JSX.Element;
|
|
113
|
+
export declare function Slideshow({ images, intervalMs, autoAdvance, transition, transitionDuration, showDots, showArrows, swipeable, objectFit, children, className, imageClassName, }: SlideshowProps): React.JSX.Element;
|
|
110
114
|
/**
|
|
111
115
|
* Hook to access slideshow state and controls from within Slideshow children.
|
|
112
116
|
* Also aliased as useSlideshow for consistency with VideoPlayer.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/Slideshow.tsx"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/react/overlay/Slideshow.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import React, { createContext, useContext, useEffect, useState, useCallback, } from 'react';
|
|
2
|
+
import React, { createContext, useContext, useEffect, useRef, useState, useCallback, } from 'react';
|
|
3
3
|
/**
|
|
4
4
|
* SlideshowSingleton - Manages slideshow state across route changes.
|
|
5
5
|
*
|
|
@@ -186,8 +186,10 @@ const SlideshowContext = createContext(null);
|
|
|
186
186
|
* </Slideshow>
|
|
187
187
|
* ```
|
|
188
188
|
*/
|
|
189
|
-
export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, transition = 'fade', transitionDuration = 500, showDots = true, showArrows = true, children, className = '', imageClassName = '', }) {
|
|
189
|
+
export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, transition = 'fade', transitionDuration = 500, showDots = true, showArrows = true, swipeable = true, objectFit = 'cover', children, className = '', imageClassName = '', }) {
|
|
190
190
|
const [state, setState] = useState(() => getSlideshowSingleton().getState());
|
|
191
|
+
const containerRef = useRef(null);
|
|
192
|
+
const touchStartRef = useRef(null);
|
|
191
193
|
// Initialize and subscribe to singleton
|
|
192
194
|
useEffect(() => {
|
|
193
195
|
const singleton = getSlideshowSingleton();
|
|
@@ -201,6 +203,49 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
|
|
|
201
203
|
const unsubscribe = singleton.onStateChange(setState);
|
|
202
204
|
return unsubscribe;
|
|
203
205
|
}, [images, intervalMs, autoAdvance, transitionDuration]);
|
|
206
|
+
// Control functions bound to singleton
|
|
207
|
+
const singleton = getSlideshowSingleton();
|
|
208
|
+
const controls = {
|
|
209
|
+
next: useCallback(() => singleton.next(), []),
|
|
210
|
+
prev: useCallback(() => singleton.prev(), []),
|
|
211
|
+
goTo: useCallback((index) => singleton.goTo(index), []),
|
|
212
|
+
pause: useCallback(() => singleton.pause(), []),
|
|
213
|
+
resume: useCallback(() => singleton.resume(), []),
|
|
214
|
+
toggle: useCallback(() => singleton.toggle(), []),
|
|
215
|
+
};
|
|
216
|
+
// Touch/swipe handlers
|
|
217
|
+
const handleTouchStart = useCallback((e) => {
|
|
218
|
+
if (!swipeable || state.totalSlides <= 1)
|
|
219
|
+
return;
|
|
220
|
+
const touch = e.touches[0];
|
|
221
|
+
touchStartRef.current = {
|
|
222
|
+
x: touch.clientX,
|
|
223
|
+
y: touch.clientY,
|
|
224
|
+
time: Date.now(),
|
|
225
|
+
};
|
|
226
|
+
}, [swipeable, state.totalSlides]);
|
|
227
|
+
const handleTouchEnd = useCallback((e) => {
|
|
228
|
+
if (!swipeable || !touchStartRef.current || state.isTransitioning)
|
|
229
|
+
return;
|
|
230
|
+
const touch = e.changedTouches[0];
|
|
231
|
+
const deltaX = touch.clientX - touchStartRef.current.x;
|
|
232
|
+
const deltaY = touch.clientY - touchStartRef.current.y;
|
|
233
|
+
const deltaTime = Date.now() - touchStartRef.current.time;
|
|
234
|
+
// Minimum swipe distance (50px) and max time (300ms for quick swipe, or slower with more distance)
|
|
235
|
+
const minSwipeDistance = 50;
|
|
236
|
+
const isHorizontalSwipe = Math.abs(deltaX) > Math.abs(deltaY);
|
|
237
|
+
const isValidSwipe = Math.abs(deltaX) > minSwipeDistance && isHorizontalSwipe;
|
|
238
|
+
const isQuickSwipe = deltaTime < 300 || Math.abs(deltaX) > 100;
|
|
239
|
+
if (isValidSwipe && isQuickSwipe) {
|
|
240
|
+
if (deltaX > 0) {
|
|
241
|
+
controls.prev();
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
controls.next();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
touchStartRef.current = null;
|
|
248
|
+
}, [swipeable, state.isTransitioning, controls]);
|
|
204
249
|
// Get transition styles
|
|
205
250
|
const getTransitionStyles = (index) => {
|
|
206
251
|
const isActive = index === state.currentIndex;
|
|
@@ -229,16 +274,6 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
|
|
|
229
274
|
};
|
|
230
275
|
}
|
|
231
276
|
};
|
|
232
|
-
// Control functions bound to singleton
|
|
233
|
-
const singleton = getSlideshowSingleton();
|
|
234
|
-
const controls = {
|
|
235
|
-
next: useCallback(() => singleton.next(), []),
|
|
236
|
-
prev: useCallback(() => singleton.prev(), []),
|
|
237
|
-
goTo: useCallback((index) => singleton.goTo(index), []),
|
|
238
|
-
pause: useCallback(() => singleton.pause(), []),
|
|
239
|
-
resume: useCallback(() => singleton.resume(), []),
|
|
240
|
-
toggle: useCallback(() => singleton.toggle(), []),
|
|
241
|
-
};
|
|
242
277
|
const contextValue = {
|
|
243
278
|
state,
|
|
244
279
|
controls,
|
|
@@ -248,9 +283,9 @@ export function Slideshow({ images, intervalMs = 5000, autoAdvance = true, trans
|
|
|
248
283
|
React.createElement("p", { className: "text-white/60" }, "No images")));
|
|
249
284
|
}
|
|
250
285
|
return (React.createElement(SlideshowContext.Provider, { value: contextValue },
|
|
251
|
-
React.createElement("div", { className: `relative w-full h-full bg-black overflow-hidden ${className}
|
|
252
|
-
React.createElement("div", { className: "relative w-full h-full" }, images.map((image, index) => (React.createElement("div", { key: `${image.url}-${index}`, style: getTransitionStyles(index), className: imageClassName },
|
|
253
|
-
React.createElement("img", { src: image.url, alt: image.alt || `Slide ${index + 1}`, className:
|
|
286
|
+
React.createElement("div", { ref: containerRef, className: `relative w-full h-full bg-black overflow-hidden ${className}`, onTouchStart: handleTouchStart, onTouchEnd: handleTouchEnd },
|
|
287
|
+
React.createElement("div", { className: "relative w-full h-full" }, images.map((image, index) => (React.createElement("div", { key: `${image.url}-${index}`, style: getTransitionStyles(index), className: `flex items-center justify-center ${imageClassName}` },
|
|
288
|
+
React.createElement("img", { src: image.url, alt: image.alt || `Slide ${index + 1}`, className: `w-full h-full ${objectFit === 'cover' ? 'object-cover' : 'object-contain'}`, style: { objectPosition: 'center' }, loading: index === 0 ? 'eager' : 'lazy', draggable: false }))))),
|
|
254
289
|
showArrows && state.totalSlides > 1 && (React.createElement(React.Fragment, null,
|
|
255
290
|
React.createElement("button", { onClick: controls.prev, disabled: state.isTransitioning, className: "absolute left-2 top-1/2 -translate-y-1/2 p-2 bg-black/40 hover:bg-black/60 rounded-full text-white transition-colors disabled:opacity-50", "aria-label": "Previous slide" },
|
|
256
291
|
React.createElement("svg", { className: "w-5 h-5", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" },
|