overlapping-cards-scroll 0.1.3 → 0.1.5
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/README.md +10 -6
- package/dist/index.cjs +220 -139
- package/dist/index.js +220 -139
- package/dist/react-native-web.cjs +220 -139
- package/dist/react-native-web.js +220 -139
- package/dist/react-native.cjs +175 -90
- package/dist/react-native.js +184 -91
- package/dist/types/lib/OverlappingCardsScroll.d.ts +13 -13
- package/dist/types/lib/index.d.ts +2 -2
- package/dist/types/rn/OverlappingCardsScrollRN.native.d.ts +2 -2
- package/dist/types/rn/OverlappingCardsScrollRN.types.d.ts +10 -10
- package/dist/types/rn/OverlappingCardsScrollRN.web.d.ts +2 -2
- package/package.json +9 -2
- package/src/lib/OverlappingCardsScroll.css +13 -4
- package/src/lib/OverlappingCardsScroll.tsx +485 -382
- package/src/lib/index.ts +2 -2
- package/src/rn/OverlappingCardsScrollRN.native.tsx +404 -302
- package/src/rn/OverlappingCardsScrollRN.types.ts +78 -67
- package/src/rn/OverlappingCardsScrollRN.web.tsx +25 -23
- package/src/rn/RNWebDemo.tsx +84 -72
package/README.md
CHANGED
|
@@ -18,15 +18,19 @@ Peer dependencies:
|
|
|
18
18
|
## Web Usage
|
|
19
19
|
|
|
20
20
|
```tsx
|
|
21
|
-
import
|
|
21
|
+
import "overlapping-cards-scroll/styles.css";
|
|
22
22
|
import {
|
|
23
23
|
OverlappingCardsScroll,
|
|
24
24
|
OverlappingCardsScrollFocusTrigger,
|
|
25
|
-
} from
|
|
25
|
+
} from "overlapping-cards-scroll";
|
|
26
26
|
|
|
27
27
|
export function Example({ cards }) {
|
|
28
28
|
return (
|
|
29
|
-
<OverlappingCardsScroll
|
|
29
|
+
<OverlappingCardsScroll
|
|
30
|
+
cardHeight={280}
|
|
31
|
+
showPageDots
|
|
32
|
+
pageDotsPosition="below"
|
|
33
|
+
>
|
|
30
34
|
{cards.map((card) => (
|
|
31
35
|
<article key={card.id}>
|
|
32
36
|
<h3>{card.title}</h3>
|
|
@@ -36,7 +40,7 @@ export function Example({ cards }) {
|
|
|
36
40
|
</article>
|
|
37
41
|
))}
|
|
38
42
|
</OverlappingCardsScroll>
|
|
39
|
-
)
|
|
43
|
+
);
|
|
40
44
|
}
|
|
41
45
|
```
|
|
42
46
|
|
|
@@ -46,7 +50,7 @@ export function Example({ cards }) {
|
|
|
46
50
|
import {
|
|
47
51
|
OverlappingCardsScrollRN,
|
|
48
52
|
OverlappingCardsScrollRNFocusTrigger,
|
|
49
|
-
} from
|
|
53
|
+
} from "overlapping-cards-scroll/react-native";
|
|
50
54
|
```
|
|
51
55
|
|
|
52
56
|
`/react-native` resolves to:
|
|
@@ -62,7 +66,7 @@ You can also target explicit builds:
|
|
|
62
66
|
For web adapter usage, import package styles:
|
|
63
67
|
|
|
64
68
|
```tsx
|
|
65
|
-
import
|
|
69
|
+
import "overlapping-cards-scroll/styles.css";
|
|
66
70
|
```
|
|
67
71
|
|
|
68
72
|
## Props
|
package/dist/index.cjs
CHANGED
|
@@ -33,6 +33,7 @@ var PAGE_DOT_POSITIONS = /* @__PURE__ */ new Set(["above", "below", "overlay"]);
|
|
|
33
33
|
var normalizePageDotsPosition = (value) => PAGE_DOT_POSITIONS.has(value) ? value : "below";
|
|
34
34
|
var TAB_POSITIONS = /* @__PURE__ */ new Set(["above", "below"]);
|
|
35
35
|
var normalizeTabsPosition = (value) => TAB_POSITIONS.has(value) ? value : "above";
|
|
36
|
+
var lastKnownViewportWidth = 1;
|
|
36
37
|
function DefaultTabsContainerComponent({
|
|
37
38
|
children,
|
|
38
39
|
className,
|
|
@@ -109,7 +110,17 @@ function OverlappingCardsScrollFocusTrigger({
|
|
|
109
110
|
}
|
|
110
111
|
};
|
|
111
112
|
const buttonClassName = className ? `ocs-focus-trigger ${className}` : "ocs-focus-trigger";
|
|
112
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
113
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
114
|
+
"button",
|
|
115
|
+
{
|
|
116
|
+
type: "button",
|
|
117
|
+
className: buttonClassName,
|
|
118
|
+
disabled: !canFocus,
|
|
119
|
+
onClick: handleClick,
|
|
120
|
+
...buttonProps,
|
|
121
|
+
children
|
|
122
|
+
}
|
|
123
|
+
);
|
|
113
124
|
}
|
|
114
125
|
var resolveCardWidth = (cardWidth, viewportWidth, fallbackRatio) => {
|
|
115
126
|
if (typeof cardWidth === "number" && Number.isFinite(cardWidth) && cardWidth > 0) {
|
|
@@ -188,7 +199,7 @@ function OverlappingCardsScroll(props) {
|
|
|
188
199
|
const snapTimeoutRef = (0, import_react.useRef)(null);
|
|
189
200
|
const shouldSnapOnMouseMoveRef = (0, import_react.useRef)(false);
|
|
190
201
|
const focusTransitionTimeoutRef = (0, import_react.useRef)(null);
|
|
191
|
-
const [viewportWidth, setViewportWidth] = (0, import_react.useState)(
|
|
202
|
+
const [viewportWidth, setViewportWidth] = (0, import_react.useState)(lastKnownViewportWidth);
|
|
192
203
|
const [scrollLeft, setScrollLeft] = (0, import_react.useState)(0);
|
|
193
204
|
const [focusTransition, setFocusTransition] = (0, import_react.useState)(null);
|
|
194
205
|
const clearSnapTimeout = (0, import_react.useCallback)(() => {
|
|
@@ -208,6 +219,7 @@ function OverlappingCardsScroll(props) {
|
|
|
208
219
|
setFocusTransition(null);
|
|
209
220
|
}, [clearFocusTransitionTimeout]);
|
|
210
221
|
(0, import_react.useEffect)(() => {
|
|
222
|
+
var _a;
|
|
211
223
|
const containerElement = containerRef.current;
|
|
212
224
|
const scrollElement = scrollRef.current;
|
|
213
225
|
if (!containerElement || !scrollElement) {
|
|
@@ -216,15 +228,22 @@ function OverlappingCardsScroll(props) {
|
|
|
216
228
|
const syncScroll = () => {
|
|
217
229
|
setScrollLeft(scrollElement.scrollLeft);
|
|
218
230
|
};
|
|
231
|
+
const applyWidth = (width) => {
|
|
232
|
+
const w = Math.max(0, width);
|
|
233
|
+
if (w > 10) {
|
|
234
|
+
lastKnownViewportWidth = w;
|
|
235
|
+
setViewportWidth(w);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
219
238
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
220
|
-
var
|
|
239
|
+
var _a2, _b;
|
|
221
240
|
const entry = entries[0];
|
|
222
|
-
const width = (_b = (
|
|
223
|
-
|
|
241
|
+
const width = (_b = (_a2 = entry == null ? void 0 : entry.contentRect) == null ? void 0 : _a2.width) != null ? _b : 0;
|
|
242
|
+
applyWidth(width);
|
|
224
243
|
syncScroll();
|
|
225
244
|
});
|
|
226
245
|
resizeObserver.observe(containerElement);
|
|
227
|
-
|
|
246
|
+
applyWidth((_a = containerElement.getBoundingClientRect().width) != null ? _a : 0);
|
|
228
247
|
syncScroll();
|
|
229
248
|
scrollElement.addEventListener("scroll", syncScroll, { passive: true });
|
|
230
249
|
return () => {
|
|
@@ -233,7 +252,10 @@ function OverlappingCardsScroll(props) {
|
|
|
233
252
|
};
|
|
234
253
|
}, []);
|
|
235
254
|
(0, import_react.useEffect)(() => () => clearSnapTimeout(), [clearSnapTimeout]);
|
|
236
|
-
(0, import_react.useEffect)(
|
|
255
|
+
(0, import_react.useEffect)(
|
|
256
|
+
() => () => clearFocusTransitionTimeout(),
|
|
257
|
+
[clearFocusTransitionTimeout]
|
|
258
|
+
);
|
|
237
259
|
(0, import_react.useEffect)(() => {
|
|
238
260
|
if (snapToCardOnRelease && cardCount > 1) {
|
|
239
261
|
return;
|
|
@@ -251,7 +273,10 @@ function OverlappingCardsScroll(props) {
|
|
|
251
273
|
const layout = (0, import_react.useMemo)(() => {
|
|
252
274
|
const safeWidth = Math.max(1, viewportWidth);
|
|
253
275
|
const safeRatio = clamp(cardWidthRatio, 0.2, 0.95);
|
|
254
|
-
const width = Math.max(
|
|
276
|
+
const width = Math.max(
|
|
277
|
+
1,
|
|
278
|
+
resolveCardWidth(cardWidth, safeWidth, safeRatio)
|
|
279
|
+
);
|
|
255
280
|
if (cardCount < 2) {
|
|
256
281
|
return {
|
|
257
282
|
cardWidth: width,
|
|
@@ -275,7 +300,15 @@ function OverlappingCardsScroll(props) {
|
|
|
275
300
|
scrollRange,
|
|
276
301
|
trackWidth
|
|
277
302
|
};
|
|
278
|
-
}, [
|
|
303
|
+
}, [
|
|
304
|
+
basePeek,
|
|
305
|
+
cardCount,
|
|
306
|
+
cardWidth,
|
|
307
|
+
cardWidthRatio,
|
|
308
|
+
maxPeek,
|
|
309
|
+
minPeek,
|
|
310
|
+
viewportWidth
|
|
311
|
+
]);
|
|
279
312
|
(0, import_react.useEffect)(() => {
|
|
280
313
|
const scrollElement = scrollRef.current;
|
|
281
314
|
if (!scrollElement) {
|
|
@@ -299,7 +332,11 @@ function OverlappingCardsScroll(props) {
|
|
|
299
332
|
if (!scrollElement) {
|
|
300
333
|
return;
|
|
301
334
|
}
|
|
302
|
-
const currentScrollLeft = clamp(
|
|
335
|
+
const currentScrollLeft = clamp(
|
|
336
|
+
scrollElement.scrollLeft,
|
|
337
|
+
0,
|
|
338
|
+
layout.scrollRange
|
|
339
|
+
);
|
|
303
340
|
const nearestIndex = clamp(
|
|
304
341
|
Math.round(currentScrollLeft / layout.stepDistance),
|
|
305
342
|
0,
|
|
@@ -341,7 +378,13 @@ function OverlappingCardsScroll(props) {
|
|
|
341
378
|
snapToNearestCard({ behavior: "smooth" });
|
|
342
379
|
}, safeDelay);
|
|
343
380
|
},
|
|
344
|
-
[
|
|
381
|
+
[
|
|
382
|
+
cardCount,
|
|
383
|
+
clearSnapTimeout,
|
|
384
|
+
snapReleaseDelay,
|
|
385
|
+
snapToCardOnRelease,
|
|
386
|
+
snapToNearestCard
|
|
387
|
+
]
|
|
345
388
|
);
|
|
346
389
|
const markSnapCandidateFromScroll = (0, import_react.useCallback)(() => {
|
|
347
390
|
if (!snapToCardOnRelease || cardCount < 2) {
|
|
@@ -378,7 +421,11 @@ function OverlappingCardsScroll(props) {
|
|
|
378
421
|
shouldSnapOnMouseMoveRef.current = false;
|
|
379
422
|
cancelFocusTransition();
|
|
380
423
|
const safeIndex = clamp(Math.round(targetIndex), 0, cardCount - 1);
|
|
381
|
-
const nextScrollLeft = clamp(
|
|
424
|
+
const nextScrollLeft = clamp(
|
|
425
|
+
safeIndex * layout.stepDistance,
|
|
426
|
+
0,
|
|
427
|
+
layout.scrollRange
|
|
428
|
+
);
|
|
382
429
|
const transitionMode = (_a = options.transitionMode) != null ? _a : "swoop";
|
|
383
430
|
if (transitionMode === "swoop") {
|
|
384
431
|
const duration = Number.isFinite(options.duration) ? Math.max(0, options.duration) : focusTransitionDuration;
|
|
@@ -466,7 +513,12 @@ function OverlappingCardsScroll(props) {
|
|
|
466
513
|
applyScrollDelta(event.deltaX);
|
|
467
514
|
markSnapCandidateFromScroll();
|
|
468
515
|
},
|
|
469
|
-
[
|
|
516
|
+
[
|
|
517
|
+
cardCount,
|
|
518
|
+
cancelFocusTransition,
|
|
519
|
+
applyScrollDelta,
|
|
520
|
+
markSnapCandidateFromScroll
|
|
521
|
+
]
|
|
470
522
|
);
|
|
471
523
|
const handleTouchStart = (event) => {
|
|
472
524
|
if (cardCount < 2) {
|
|
@@ -574,143 +626,172 @@ function OverlappingCardsScroll(props) {
|
|
|
574
626
|
}
|
|
575
627
|
);
|
|
576
628
|
};
|
|
577
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
style: { marginBottom: toCssDimension(pageDotsOffset) },
|
|
584
|
-
"aria-label": "Card pages",
|
|
585
|
-
children: cards.map((_, index) => {
|
|
586
|
-
const influence = clamp(1 - Math.abs(progress - index), 0, 1);
|
|
587
|
-
const opacity = 0.25 + influence * 0.75;
|
|
588
|
-
const scale = 0.9 + influence * 0.22;
|
|
589
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
590
|
-
"button",
|
|
591
|
-
{
|
|
592
|
-
type: "button",
|
|
593
|
-
className: "ocs-page-dot",
|
|
594
|
-
"aria-label": `Go to card ${index + 1}`,
|
|
595
|
-
"aria-current": influence > 0.98 ? "page" : void 0,
|
|
596
|
-
onClick: () => focusCard(index, {
|
|
597
|
-
behavior: pageDotsBehavior,
|
|
598
|
-
transitionMode: "swoop"
|
|
599
|
-
}),
|
|
600
|
-
style: { opacity, transform: `scale(${scale})` }
|
|
601
|
-
},
|
|
602
|
-
`ocs-page-dot-above-${index}`
|
|
603
|
-
);
|
|
604
|
-
})
|
|
605
|
-
}
|
|
606
|
-
) : null,
|
|
607
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ocs-stage-frame", children: [
|
|
608
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
609
|
-
"div",
|
|
629
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
630
|
+
OverlappingCardsScrollControllerContext.Provider,
|
|
631
|
+
{
|
|
632
|
+
value: controllerContextValue,
|
|
633
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
634
|
+
"section",
|
|
610
635
|
{
|
|
611
|
-
className:
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
minHeight: toCssDimension(cardHeight)
|
|
615
|
-
},
|
|
616
|
-
onTouchStart: handleTouchStart,
|
|
617
|
-
onTouchMove: handleTouchMove,
|
|
618
|
-
onTouchEnd: handleTouchEnd,
|
|
619
|
-
onTouchCancel: handleTouchEnd,
|
|
636
|
+
className: containerClassName,
|
|
637
|
+
"aria-label": ariaLabel,
|
|
638
|
+
ref: containerRef,
|
|
620
639
|
children: [
|
|
621
|
-
|
|
622
|
-
|
|
640
|
+
resolvedTabsPosition === "above" ? renderTabs("above") : null,
|
|
641
|
+
showNavigationDots && resolvedPageDotsPosition === "above" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
642
|
+
"nav",
|
|
623
643
|
{
|
|
624
|
-
className: "ocs-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
644
|
+
className: pageDotsClassName ? `ocs-page-dots ocs-page-dots--above ${pageDotsClassName}` : "ocs-page-dots ocs-page-dots--above",
|
|
645
|
+
style: { marginBottom: toCssDimension(pageDotsOffset) },
|
|
646
|
+
"aria-label": "Card pages",
|
|
647
|
+
children: cards.map((_, index) => {
|
|
648
|
+
const influence = clamp(1 - Math.abs(progress - index), 0, 1);
|
|
649
|
+
const opacity = 0.25 + influence * 0.75;
|
|
650
|
+
const scale = 0.9 + influence * 0.22;
|
|
628
651
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
629
|
-
"
|
|
652
|
+
"button",
|
|
630
653
|
{
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
654
|
+
type: "button",
|
|
655
|
+
className: "ocs-page-dot",
|
|
656
|
+
"aria-label": `Go to card ${index + 1}`,
|
|
657
|
+
"aria-current": influence > 0.98 ? "page" : void 0,
|
|
658
|
+
onClick: () => focusCard(index, {
|
|
659
|
+
behavior: pageDotsBehavior,
|
|
660
|
+
transitionMode: "swoop"
|
|
661
|
+
}),
|
|
662
|
+
style: { opacity, transform: `scale(${scale})` }
|
|
639
663
|
},
|
|
640
|
-
|
|
664
|
+
`ocs-page-dot-above-${index}`
|
|
641
665
|
);
|
|
642
666
|
})
|
|
643
667
|
}
|
|
644
|
-
),
|
|
645
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
668
|
+
) : null,
|
|
669
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "ocs-stage-frame", children: [
|
|
670
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
671
|
+
"div",
|
|
672
|
+
{
|
|
673
|
+
className: "ocs-stage",
|
|
674
|
+
ref: stageRef,
|
|
675
|
+
style: {
|
|
676
|
+
minHeight: toCssDimension(cardHeight)
|
|
677
|
+
},
|
|
678
|
+
onTouchStart: handleTouchStart,
|
|
679
|
+
onTouchMove: handleTouchMove,
|
|
680
|
+
onTouchEnd: handleTouchEnd,
|
|
681
|
+
onTouchCancel: handleTouchEnd,
|
|
682
|
+
children: [
|
|
683
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ocs-track", children: cards.map((card, index) => {
|
|
684
|
+
var _a;
|
|
685
|
+
const cardX = resolveCardX(
|
|
686
|
+
index,
|
|
687
|
+
activeIndex,
|
|
688
|
+
transitionProgress,
|
|
689
|
+
layout
|
|
690
|
+
);
|
|
691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
692
|
+
"div",
|
|
693
|
+
{
|
|
694
|
+
className: cardContainerClassName ? `${focusTransition ? "ocs-card ocs-card--focus-transition" : "ocs-card"} ${cardContainerClassName}` : focusTransition ? "ocs-card ocs-card--focus-transition" : "ocs-card",
|
|
695
|
+
style: {
|
|
696
|
+
width: `${layout.cardWidth}px`,
|
|
697
|
+
transform: `translate3d(${cardX}px, 0, 0)`,
|
|
698
|
+
transitionDuration: focusTransition ? `${focusTransition.duration}ms` : void 0,
|
|
699
|
+
...cardContainerStyle,
|
|
700
|
+
pointerEvents: "none"
|
|
701
|
+
},
|
|
702
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
703
|
+
"div",
|
|
704
|
+
{
|
|
705
|
+
style: {
|
|
706
|
+
pointerEvents: "auto",
|
|
707
|
+
display: "flex"
|
|
708
|
+
},
|
|
709
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
710
|
+
OverlappingCardsScrollCardIndexContext.Provider,
|
|
711
|
+
{
|
|
712
|
+
value: index,
|
|
713
|
+
children: card
|
|
714
|
+
}
|
|
715
|
+
)
|
|
716
|
+
}
|
|
717
|
+
)
|
|
718
|
+
},
|
|
719
|
+
(_a = card.key) != null ? _a : `ocs-card-${index}`
|
|
720
|
+
);
|
|
721
|
+
}) }),
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "ocs-scroll-region", ref: scrollRef, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
723
|
+
"div",
|
|
724
|
+
{
|
|
725
|
+
className: "ocs-scroll-spacer",
|
|
726
|
+
style: {
|
|
727
|
+
width: `${layout.trackWidth}px`
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
) })
|
|
731
|
+
]
|
|
651
732
|
}
|
|
733
|
+
),
|
|
734
|
+
showNavigationDots && resolvedPageDotsPosition === "overlay" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
735
|
+
"nav",
|
|
736
|
+
{
|
|
737
|
+
className: pageDotsClassName ? `ocs-page-dots ocs-page-dots--overlay ${pageDotsClassName}` : "ocs-page-dots ocs-page-dots--overlay",
|
|
738
|
+
style: { bottom: toCssDimension(pageDotsOffset) },
|
|
739
|
+
"aria-label": "Card pages",
|
|
740
|
+
children: cards.map((_, index) => {
|
|
741
|
+
const influence = clamp(1 - Math.abs(progress - index), 0, 1);
|
|
742
|
+
const opacity = 0.25 + influence * 0.75;
|
|
743
|
+
const scale = 0.9 + influence * 0.22;
|
|
744
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
745
|
+
"button",
|
|
746
|
+
{
|
|
747
|
+
type: "button",
|
|
748
|
+
className: "ocs-page-dot",
|
|
749
|
+
"aria-label": `Go to card ${index + 1}`,
|
|
750
|
+
"aria-current": influence > 0.98 ? "page" : void 0,
|
|
751
|
+
onClick: () => focusCard(index, {
|
|
752
|
+
behavior: pageDotsBehavior,
|
|
753
|
+
transitionMode: "swoop"
|
|
754
|
+
}),
|
|
755
|
+
style: { opacity, transform: `scale(${scale})` }
|
|
756
|
+
},
|
|
757
|
+
`ocs-page-dot-overlay-${index}`
|
|
758
|
+
);
|
|
759
|
+
})
|
|
760
|
+
}
|
|
761
|
+
) : null
|
|
762
|
+
] }),
|
|
763
|
+
showNavigationDots && resolvedPageDotsPosition === "below" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
764
|
+
"nav",
|
|
765
|
+
{
|
|
766
|
+
className: pageDotsClassName ? `ocs-page-dots ocs-page-dots--below ${pageDotsClassName}` : "ocs-page-dots ocs-page-dots--below",
|
|
767
|
+
style: { marginTop: toCssDimension(pageDotsOffset) },
|
|
768
|
+
"aria-label": "Card pages",
|
|
769
|
+
children: cards.map((_, index) => {
|
|
770
|
+
const influence = clamp(1 - Math.abs(progress - index), 0, 1);
|
|
771
|
+
const opacity = 0.25 + influence * 0.75;
|
|
772
|
+
const scale = 0.9 + influence * 0.22;
|
|
773
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
774
|
+
"button",
|
|
775
|
+
{
|
|
776
|
+
type: "button",
|
|
777
|
+
className: "ocs-page-dot",
|
|
778
|
+
"aria-label": `Go to card ${index + 1}`,
|
|
779
|
+
"aria-current": influence > 0.98 ? "page" : void 0,
|
|
780
|
+
onClick: () => focusCard(index, {
|
|
781
|
+
behavior: pageDotsBehavior,
|
|
782
|
+
transitionMode: "swoop"
|
|
783
|
+
}),
|
|
784
|
+
style: { opacity, transform: `scale(${scale})` }
|
|
785
|
+
},
|
|
786
|
+
`ocs-page-dot-below-${index}`
|
|
787
|
+
);
|
|
788
|
+
})
|
|
652
789
|
}
|
|
653
|
-
)
|
|
790
|
+
) : null,
|
|
791
|
+
resolvedTabsPosition === "below" ? renderTabs("below") : null
|
|
654
792
|
]
|
|
655
793
|
}
|
|
656
|
-
)
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
{
|
|
660
|
-
className: pageDotsClassName ? `ocs-page-dots ocs-page-dots--overlay ${pageDotsClassName}` : "ocs-page-dots ocs-page-dots--overlay",
|
|
661
|
-
style: { bottom: toCssDimension(pageDotsOffset) },
|
|
662
|
-
"aria-label": "Card pages",
|
|
663
|
-
children: cards.map((_, index) => {
|
|
664
|
-
const influence = clamp(1 - Math.abs(progress - index), 0, 1);
|
|
665
|
-
const opacity = 0.25 + influence * 0.75;
|
|
666
|
-
const scale = 0.9 + influence * 0.22;
|
|
667
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
668
|
-
"button",
|
|
669
|
-
{
|
|
670
|
-
type: "button",
|
|
671
|
-
className: "ocs-page-dot",
|
|
672
|
-
"aria-label": `Go to card ${index + 1}`,
|
|
673
|
-
"aria-current": influence > 0.98 ? "page" : void 0,
|
|
674
|
-
onClick: () => focusCard(index, {
|
|
675
|
-
behavior: pageDotsBehavior,
|
|
676
|
-
transitionMode: "swoop"
|
|
677
|
-
}),
|
|
678
|
-
style: { opacity, transform: `scale(${scale})` }
|
|
679
|
-
},
|
|
680
|
-
`ocs-page-dot-overlay-${index}`
|
|
681
|
-
);
|
|
682
|
-
})
|
|
683
|
-
}
|
|
684
|
-
) : null
|
|
685
|
-
] }),
|
|
686
|
-
showNavigationDots && resolvedPageDotsPosition === "below" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
687
|
-
"nav",
|
|
688
|
-
{
|
|
689
|
-
className: pageDotsClassName ? `ocs-page-dots ocs-page-dots--below ${pageDotsClassName}` : "ocs-page-dots ocs-page-dots--below",
|
|
690
|
-
style: { marginTop: toCssDimension(pageDotsOffset) },
|
|
691
|
-
"aria-label": "Card pages",
|
|
692
|
-
children: cards.map((_, index) => {
|
|
693
|
-
const influence = clamp(1 - Math.abs(progress - index), 0, 1);
|
|
694
|
-
const opacity = 0.25 + influence * 0.75;
|
|
695
|
-
const scale = 0.9 + influence * 0.22;
|
|
696
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
697
|
-
"button",
|
|
698
|
-
{
|
|
699
|
-
type: "button",
|
|
700
|
-
className: "ocs-page-dot",
|
|
701
|
-
"aria-label": `Go to card ${index + 1}`,
|
|
702
|
-
"aria-current": influence > 0.98 ? "page" : void 0,
|
|
703
|
-
onClick: () => focusCard(index, {
|
|
704
|
-
behavior: pageDotsBehavior,
|
|
705
|
-
transitionMode: "swoop"
|
|
706
|
-
}),
|
|
707
|
-
style: { opacity, transform: `scale(${scale})` }
|
|
708
|
-
},
|
|
709
|
-
`ocs-page-dot-below-${index}`
|
|
710
|
-
);
|
|
711
|
-
})
|
|
712
|
-
}
|
|
713
|
-
) : null,
|
|
714
|
-
resolvedTabsPosition === "below" ? renderTabs("below") : null
|
|
715
|
-
] }) });
|
|
794
|
+
)
|
|
795
|
+
}
|
|
796
|
+
);
|
|
716
797
|
}
|