@watcha-authentic/react-slider 0.1.2 → 0.1.3
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.
|
@@ -19,7 +19,7 @@ const _slidercontextprovider = require("../context/slider-context-provider");
|
|
|
19
19
|
* - 드래그로 페이지 전환을 트리거하는 임계값 비율 (아이템 너비 기준)
|
|
20
20
|
*/ const CAN_SCROLL_THRESHOLD_RATIO = 0.15;
|
|
21
21
|
const DEFAULT_SCROLL_THRESHOLD = 125;
|
|
22
|
-
const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "ease", defaultIndex = 0, enableDrag = true,
|
|
22
|
+
const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "ease", defaultIndex = 0, enableDrag = true, gap = 0, itemProps, contentProps, items, visibleCount = 1, disableDraggableItems = true, wrapProps, onCreateItemView, onDraggingNow, onIndexChange, onItemKey }, ref)=>{
|
|
23
23
|
const stableOnIndexChange = (0, _reacteventcallback.useEventCallback)(onIndexChange);
|
|
24
24
|
/**
|
|
25
25
|
* - 아이템이 부족할 경우 복제하여 확장된 아이템 배열을 생성합니다.
|
|
@@ -335,63 +335,6 @@ const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "e
|
|
|
335
335
|
extendedItems,
|
|
336
336
|
getNewStatesByItems
|
|
337
337
|
]);
|
|
338
|
-
/**
|
|
339
|
-
* - 첫로드 또는 리사이즈 이벤트가 실행되면, 초기 높이와 위치를 초기화 합니다.
|
|
340
|
-
*/ (0, _react.useLayoutEffect)(()=>{
|
|
341
|
-
const handleResize = ()=>{
|
|
342
|
-
requestAnimationFrame(()=>{
|
|
343
|
-
if (!wrapRef.current) {
|
|
344
|
-
console.error("Slider 필수 요소에 접근할 수 없습니다.");
|
|
345
|
-
return;
|
|
346
|
-
}
|
|
347
|
-
// 높이, 드래그 임계값 계산
|
|
348
|
-
let estimatedHeight = 0;
|
|
349
|
-
let estimatedScrollThreshold = 0;
|
|
350
|
-
if (estimateSizeFromEveryElements) {
|
|
351
|
-
for (const [, { content }] of elementInfos.current){
|
|
352
|
-
if (content) {
|
|
353
|
-
const rect = content.getBoundingClientRect();
|
|
354
|
-
const { height } = rect;
|
|
355
|
-
if (height > estimatedHeight) {
|
|
356
|
-
estimatedHeight = height;
|
|
357
|
-
}
|
|
358
|
-
if (rect.width > estimatedScrollThreshold) {
|
|
359
|
-
estimatedScrollThreshold = rect.width * CAN_SCROLL_THRESHOLD_RATIO;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
} else {
|
|
364
|
-
const firstElementInfo = elementInfos.current.get(0);
|
|
365
|
-
const rect = firstElementInfo?.content?.getBoundingClientRect();
|
|
366
|
-
estimatedHeight = rect?.height ?? 0;
|
|
367
|
-
estimatedScrollThreshold = (rect?.width ?? DEFAULT_SCROLL_THRESHOLD) * CAN_SCROLL_THRESHOLD_RATIO;
|
|
368
|
-
}
|
|
369
|
-
wrapRef.current.style.height = `${estimatedHeight}px`;
|
|
370
|
-
canScrollThreshold.current = estimatedScrollThreshold;
|
|
371
|
-
// 아이템 위치 계산
|
|
372
|
-
setSliderInfo((prevSliderInfo)=>{
|
|
373
|
-
return {
|
|
374
|
-
...prevSliderInfo,
|
|
375
|
-
elementStates: getNewStatesByItems({
|
|
376
|
-
centerIndex: prevSliderInfo.currentIndex,
|
|
377
|
-
itemIndexs: prevSliderInfo.elementStates.map((_, index)=>index),
|
|
378
|
-
prevStates: prevSliderInfo.elementStates
|
|
379
|
-
})
|
|
380
|
-
};
|
|
381
|
-
});
|
|
382
|
-
});
|
|
383
|
-
};
|
|
384
|
-
// 초기 로드 시 높이 계산
|
|
385
|
-
handleResize();
|
|
386
|
-
window.addEventListener("resize", handleResize);
|
|
387
|
-
return ()=>{
|
|
388
|
-
window.removeEventListener("resize", handleResize);
|
|
389
|
-
};
|
|
390
|
-
}, [
|
|
391
|
-
calcElementState,
|
|
392
|
-
estimateSizeFromEveryElements,
|
|
393
|
-
getNewStatesByItems
|
|
394
|
-
]);
|
|
395
338
|
const handleSwipe = (0, _react.useCallback)(async ()=>{
|
|
396
339
|
lastSlideTriggerEvent.current = "swipe";
|
|
397
340
|
await updateStateByPageIndex({
|
|
@@ -430,6 +373,21 @@ const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "e
|
|
|
430
373
|
sliderInfo.currentIndex,
|
|
431
374
|
stableOnIndexChange
|
|
432
375
|
]);
|
|
376
|
+
/**
|
|
377
|
+
* - draggable 값을 img, a 등의 요소에 적용합니다.
|
|
378
|
+
*/ (0, _react.useLayoutEffect)(()=>{
|
|
379
|
+
if (!disableDraggableItems) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const targets = wrapRef.current?.querySelectorAll("img, a");
|
|
383
|
+
if (targets) {
|
|
384
|
+
for (const target of targets){
|
|
385
|
+
target.setAttribute("draggable", "false");
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}, [
|
|
389
|
+
disableDraggableItems
|
|
390
|
+
]);
|
|
433
391
|
const { withPointerMove } = (0, _reactmotion.usePointerMove)({
|
|
434
392
|
enabled: enableDrag,
|
|
435
393
|
target: wrapRef,
|
|
@@ -9,7 +9,7 @@ import { SliderItemContextProvider } from "../context/slider-context-provider.js
|
|
|
9
9
|
* - 드래그로 페이지 전환을 트리거하는 임계값 비율 (아이템 너비 기준)
|
|
10
10
|
*/ const CAN_SCROLL_THRESHOLD_RATIO = 0.15;
|
|
11
11
|
const DEFAULT_SCROLL_THRESHOLD = 125;
|
|
12
|
-
const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "ease", defaultIndex = 0, enableDrag = true,
|
|
12
|
+
const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "ease", defaultIndex = 0, enableDrag = true, gap = 0, itemProps, contentProps, items, visibleCount = 1, disableDraggableItems = true, wrapProps, onCreateItemView, onDraggingNow, onIndexChange, onItemKey }, ref)=>{
|
|
13
13
|
const stableOnIndexChange = useEventCallback(onIndexChange);
|
|
14
14
|
/**
|
|
15
15
|
* - 아이템이 부족할 경우 복제하여 확장된 아이템 배열을 생성합니다.
|
|
@@ -325,63 +325,6 @@ const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "e
|
|
|
325
325
|
extendedItems,
|
|
326
326
|
getNewStatesByItems
|
|
327
327
|
]);
|
|
328
|
-
/**
|
|
329
|
-
* - 첫로드 또는 리사이즈 이벤트가 실행되면, 초기 높이와 위치를 초기화 합니다.
|
|
330
|
-
*/ useLayoutEffect(()=>{
|
|
331
|
-
const handleResize = ()=>{
|
|
332
|
-
requestAnimationFrame(()=>{
|
|
333
|
-
if (!wrapRef.current) {
|
|
334
|
-
console.error("Slider 필수 요소에 접근할 수 없습니다.");
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
// 높이, 드래그 임계값 계산
|
|
338
|
-
let estimatedHeight = 0;
|
|
339
|
-
let estimatedScrollThreshold = 0;
|
|
340
|
-
if (estimateSizeFromEveryElements) {
|
|
341
|
-
for (const [, { content }] of elementInfos.current){
|
|
342
|
-
if (content) {
|
|
343
|
-
const rect = content.getBoundingClientRect();
|
|
344
|
-
const { height } = rect;
|
|
345
|
-
if (height > estimatedHeight) {
|
|
346
|
-
estimatedHeight = height;
|
|
347
|
-
}
|
|
348
|
-
if (rect.width > estimatedScrollThreshold) {
|
|
349
|
-
estimatedScrollThreshold = rect.width * CAN_SCROLL_THRESHOLD_RATIO;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
} else {
|
|
354
|
-
const firstElementInfo = elementInfos.current.get(0);
|
|
355
|
-
const rect = firstElementInfo?.content?.getBoundingClientRect();
|
|
356
|
-
estimatedHeight = rect?.height ?? 0;
|
|
357
|
-
estimatedScrollThreshold = (rect?.width ?? DEFAULT_SCROLL_THRESHOLD) * CAN_SCROLL_THRESHOLD_RATIO;
|
|
358
|
-
}
|
|
359
|
-
wrapRef.current.style.height = `${estimatedHeight}px`;
|
|
360
|
-
canScrollThreshold.current = estimatedScrollThreshold;
|
|
361
|
-
// 아이템 위치 계산
|
|
362
|
-
setSliderInfo((prevSliderInfo)=>{
|
|
363
|
-
return {
|
|
364
|
-
...prevSliderInfo,
|
|
365
|
-
elementStates: getNewStatesByItems({
|
|
366
|
-
centerIndex: prevSliderInfo.currentIndex,
|
|
367
|
-
itemIndexs: prevSliderInfo.elementStates.map((_, index)=>index),
|
|
368
|
-
prevStates: prevSliderInfo.elementStates
|
|
369
|
-
})
|
|
370
|
-
};
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
};
|
|
374
|
-
// 초기 로드 시 높이 계산
|
|
375
|
-
handleResize();
|
|
376
|
-
window.addEventListener("resize", handleResize);
|
|
377
|
-
return ()=>{
|
|
378
|
-
window.removeEventListener("resize", handleResize);
|
|
379
|
-
};
|
|
380
|
-
}, [
|
|
381
|
-
calcElementState,
|
|
382
|
-
estimateSizeFromEveryElements,
|
|
383
|
-
getNewStatesByItems
|
|
384
|
-
]);
|
|
385
328
|
const handleSwipe = useCallback(async ()=>{
|
|
386
329
|
lastSlideTriggerEvent.current = "swipe";
|
|
387
330
|
await updateStateByPageIndex({
|
|
@@ -420,6 +363,21 @@ const SliderComponent = ({ animationDuration = 500, animationTimingFunction = "e
|
|
|
420
363
|
sliderInfo.currentIndex,
|
|
421
364
|
stableOnIndexChange
|
|
422
365
|
]);
|
|
366
|
+
/**
|
|
367
|
+
* - draggable 값을 img, a 등의 요소에 적용합니다.
|
|
368
|
+
*/ useLayoutEffect(()=>{
|
|
369
|
+
if (!disableDraggableItems) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const targets = wrapRef.current?.querySelectorAll("img, a");
|
|
373
|
+
if (targets) {
|
|
374
|
+
for (const target of targets){
|
|
375
|
+
target.setAttribute("draggable", "false");
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}, [
|
|
379
|
+
disableDraggableItems
|
|
380
|
+
]);
|
|
423
381
|
const { withPointerMove } = usePointerMove({
|
|
424
382
|
enabled: enableDrag,
|
|
425
383
|
target: wrapRef,
|
package/dist/style.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.watcha-react-slider-wrap{display:
|
|
1
|
+
.watcha-react-slider-wrap{display:grid;grid-template-columns:1fr;justify-content:center;list-style:none;margin:0;padding:0;position:relative}.watcha-react-slider-item{grid-area:1/1;margin:0;padding:0}.watcha-react-slider-content{position:relative}
|
|
@@ -11,12 +11,6 @@ type SliderProps<ItemType> = {
|
|
|
11
11
|
items: Array<ItemType>;
|
|
12
12
|
onCreateItemView: (item: ItemType, index: number) => React.ReactNode;
|
|
13
13
|
onItemKey: (item: ItemType) => React.Key;
|
|
14
|
-
/**
|
|
15
|
-
* - 높이, 드래그 임계값 등의 사이즈 관련 값을 추정하는 방식을 선택 합니다. 기본값은 false 입니다.
|
|
16
|
-
* - true: 모든 자식요소로부터 추정합니다. 가장 큰 사이즈값이 선택 됩니다.
|
|
17
|
-
* - false: 첫번째 자식요소의 사이즈를 사용합니다.
|
|
18
|
-
*/
|
|
19
|
-
estimateSizeFromEveryElements?: boolean;
|
|
20
14
|
/**
|
|
21
15
|
* - item 간 거리입니다.
|
|
22
16
|
* - 기본값은 0 입니다.
|
|
@@ -53,6 +47,11 @@ type SliderProps<ItemType> = {
|
|
|
53
47
|
* - 기본값은 true 입니다.
|
|
54
48
|
*/
|
|
55
49
|
enableDrag?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* - 렌더링된 아이템의 a, img 등의 요소에 draggable 값을 제한 합니다.
|
|
52
|
+
* - 기본값은 true 입니다.
|
|
53
|
+
*/
|
|
54
|
+
disableDraggableItems?: boolean;
|
|
56
55
|
onDraggingNow?: (isDragging: boolean) => void;
|
|
57
56
|
};
|
|
58
57
|
/**
|