@xwadex/fesd-next 0.3.4-7.9 → 0.3.4-8

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.
Files changed (55) hide show
  1. package/dist/components/anchors/anchors.d.ts +0 -2
  2. package/dist/components/anchors/anchors.js +7 -10
  3. package/dist/components/embla-carousels/embla-carousels-hooks.d.ts +36 -0
  4. package/dist/components/embla-carousels/embla-carousels-hooks.js +83 -0
  5. package/dist/components/embla-carousels/embla-carousels.d.ts +23 -0
  6. package/dist/components/embla-carousels/embla-carousels.js +58 -0
  7. package/dist/components/embla-carousels/index.d.ts +2 -0
  8. package/dist/components/embla-carousels/index.js +2 -0
  9. package/dist/components/emblas/embla-container.d.ts +8 -0
  10. package/dist/components/emblas/embla-container.js +12 -0
  11. package/dist/components/emblas/embla-context.d.ts +21 -0
  12. package/dist/components/emblas/embla-context.js +12 -0
  13. package/dist/components/emblas/embla.d.ts +20 -0
  14. package/dist/components/emblas/embla.js +124 -0
  15. package/dist/components/emblas/emblas-pagination.d.ts +11 -0
  16. package/dist/components/emblas/emblas-pagination.js +89 -0
  17. package/dist/components/emblas/index.d.ts +4 -0
  18. package/dist/components/emblas/index.js +4 -0
  19. package/dist/components/index.d.ts +3 -0
  20. package/dist/components/index.js +3 -0
  21. package/dist/components/scroll-containers/index.d.ts +3 -0
  22. package/dist/components/scroll-containers/index.js +3 -0
  23. package/dist/components/scroll-containers/lenis-scroll.d.ts +20 -0
  24. package/dist/components/scroll-containers/lenis-scroll.js +65 -0
  25. package/dist/components/scroll-containers/native-scroll.d.ts +6 -0
  26. package/dist/components/scroll-containers/native-scroll.js +23 -0
  27. package/dist/components/scroll-containers/scroll-containers.d.ts +25 -0
  28. package/dist/components/scroll-containers/scroll-containers.js +46 -0
  29. package/dist/components/tests/tests.js +0 -1
  30. package/dist/hooks/useAnchors.d.ts +25 -17
  31. package/dist/hooks/useAnchors.js +73 -40
  32. package/dist/hooks/useAsyncFetcher.js +0 -1
  33. package/dist/hooks/useCookies.js +24 -1
  34. package/dist/hooks/useDebounce.js +0 -1
  35. package/dist/hooks/useDebounceValue.js +0 -1
  36. package/dist/hooks/useDragResize.js +0 -1
  37. package/dist/hooks/useEffectLeave.js +0 -1
  38. package/dist/hooks/useEffectOne.js +0 -1
  39. package/dist/hooks/useHash.js +0 -1
  40. package/dist/hooks/useLocations.js +0 -1
  41. package/dist/hooks/useMounted.js +0 -1
  42. package/dist/shadcns/components/ui/button-group.d.ts +11 -0
  43. package/dist/shadcns/components/ui/button-group.js +26 -0
  44. package/dist/shadcns/components/ui/button.js +0 -1
  45. package/dist/shadcns/components/ui/field.d.ts +24 -0
  46. package/dist/shadcns/components/ui/field.js +75 -0
  47. package/dist/shadcns/components/ui/item.d.ts +23 -0
  48. package/dist/shadcns/components/ui/item.js +65 -0
  49. package/dist/shadcns/components/ui/native-select.d.ts +7 -0
  50. package/dist/shadcns/components/ui/native-select.js +13 -0
  51. package/dist/shadcns/components/ui/navigation-menu.js +0 -1
  52. package/dist/shadcns/components/ui/textarea.js +0 -1
  53. package/package.json +6 -2
  54. package/dist/hooks/useScrollContainers.d.ts +0 -27
  55. package/dist/hooks/useScrollContainers.js +0 -53
@@ -3,14 +3,12 @@ interface PropsType extends React.ComponentProps<"div"> {
3
3
  name: string;
4
4
  }
5
5
  export declare const AnchorTarget: React.FC<PropsType>;
6
- export declare const AnchorContainer: React.FC<PropsType>;
7
6
  export declare const AnchorOffseter: React.FC<PropsType>;
8
7
  type TriggerProps = AnchorOptions & React.ComponentProps<"div"> & {};
9
8
  export declare const AnchorTrigger: React.FC<TriggerProps>;
10
9
  export declare const Anchors: {
11
10
  Trigger: import("react").FC<TriggerProps>;
12
11
  Target: import("react").FC<PropsType>;
13
- Container: import("react").FC<PropsType>;
14
12
  Offseter: import("react").FC<PropsType>;
15
13
  };
16
14
  export {};
@@ -1,18 +1,16 @@
1
- "use client";
2
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
+ // update: 2025.11.12
3
+ // version: 0.0.2.bate
4
+ // dev: wade
3
5
  import { useAnchors } from "../../hooks/index.js";
4
6
  import { cn } from "../../shadcns/index.js";
5
- export const AnchorTarget = ({ children, className, name }) => {
7
+ export const AnchorTarget = ({ name, ...props }) => {
6
8
  const { registerAnchors } = useAnchors();
7
- return (_jsx("div", { className: cn(className), ...registerAnchors(name), children: children }));
9
+ return (_jsx("div", { ...props, ...registerAnchors(name) }));
8
10
  };
9
- export const AnchorContainer = ({ children, className, name }) => {
10
- const { registerContainers } = useAnchors();
11
- return (_jsx("div", { className: cn(className), ...registerContainers(name), children: children }));
12
- };
13
- export const AnchorOffseter = ({ children, className, name }) => {
11
+ export const AnchorOffseter = ({ name, ...props }) => {
14
12
  const { registerOffseters } = useAnchors();
15
- return (_jsx("div", { className: cn(className), ...registerOffseters(name), children: children }));
13
+ return (_jsx("div", { ...props, ...registerOffseters(name) }));
16
14
  };
17
15
  export const AnchorTrigger = ({ children, className, ...options }) => {
18
16
  const { scrollToAnchor } = useAnchors();
@@ -21,6 +19,5 @@ export const AnchorTrigger = ({ children, className, ...options }) => {
21
19
  export const Anchors = {
22
20
  Trigger: AnchorTrigger,
23
21
  Target: AnchorTarget,
24
- Container: AnchorContainer,
25
22
  Offseter: AnchorOffseter
26
23
  };
@@ -0,0 +1,36 @@
1
+ import useEmblaCarousel from "embla-carousel-react";
2
+ import type { UseEmblaCarouselType } from "embla-carousel-react";
3
+ import type { AutoplayOptionsType } from "embla-carousel-autoplay";
4
+ import type { AutoScrollOptionsType } from "embla-carousel-auto-scroll";
5
+ import type { AutoHeightOptionsType } from "embla-carousel-auto-height";
6
+ import type { ClassNamesOptionsType } from "embla-carousel-class-names";
7
+ import type { FadeOptionsType } from "embla-carousel-fade";
8
+ type CarouselApi = UseEmblaCarouselType[1];
9
+ type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
10
+ type CarouselOptions = UseCarouselParameters[0];
11
+ export interface EmblaCarouselsHooksTypes {
12
+ options?: CarouselOptions;
13
+ autoplay?: AutoplayOptionsType | true;
14
+ autoScroll?: AutoScrollOptionsType | true;
15
+ classNames?: ClassNamesOptionsType | true;
16
+ autoHeight?: AutoHeightOptionsType | true;
17
+ fade?: FadeOptionsType | true;
18
+ wheel?: {
19
+ wheelDraggingClass?: string;
20
+ forceWheelAxis?: "x" | "y";
21
+ target?: Element;
22
+ } | true;
23
+ setApi?: (api: CarouselApi) => void;
24
+ }
25
+ export declare function emblaCarouselsHooks({ options, autoplay, autoScroll, classNames, autoHeight, fade, wheel, setApi, }: EmblaCarouselsHooksTypes): {
26
+ emblaRef: (node: HTMLElement | null) => void;
27
+ emblaApi: CarouselApi;
28
+ orientation: "x" | "y";
29
+ currentIndex: number;
30
+ isScrollPrev: boolean;
31
+ isScrollNext: boolean;
32
+ scrollPrev: () => void;
33
+ scrollNext: () => void;
34
+ onKeyDownCapture: (event: React.KeyboardEvent<HTMLDivElement>) => void;
35
+ };
36
+ export {};
@@ -0,0 +1,83 @@
1
+ // update: 2025.11.20
2
+ // version: 0.0.1.bate
3
+ // dev: wade
4
+ import { useCallback, useEffect, useEffectEvent, useMemo, useState } from "react";
5
+ import useEmblaCarousel from "embla-carousel-react";
6
+ import { WheelGesturesPlugin } from "embla-carousel-wheel-gestures";
7
+ import Autoplay from "embla-carousel-autoplay";
8
+ import AutoScroll from "embla-carousel-auto-scroll";
9
+ import AutoHeight from "embla-carousel-auto-height";
10
+ import ClassNames from "embla-carousel-class-names";
11
+ import Fade from "embla-carousel-fade";
12
+ export function emblaCarouselsHooks({ options, autoplay, autoScroll, classNames, autoHeight, fade, wheel, setApi, }) {
13
+ const orientation = options?.axis ?? "x";
14
+ const plugins = useMemo(() => ([
15
+ autoplay && Autoplay(typeof autoplay == "boolean" ? undefined : autoplay),
16
+ autoScroll && AutoScroll(typeof autoScroll == "boolean" ? undefined : autoScroll),
17
+ autoHeight && AutoHeight(typeof autoHeight == "boolean" ? undefined : autoHeight),
18
+ classNames && ClassNames(typeof classNames == "boolean" ? undefined : classNames),
19
+ fade && Fade(typeof fade == "boolean" ? undefined : fade),
20
+ wheel && WheelGesturesPlugin(typeof wheel == "boolean" ? undefined : wheel),
21
+ ].filter(plugin => plugin)), [
22
+ autoplay,
23
+ autoScroll,
24
+ classNames,
25
+ fade,
26
+ wheel,
27
+ autoHeight
28
+ ]);
29
+ const [emblaRef, emblaApi] = useEmblaCarousel(options, plugins);
30
+ const [currentIndex, setCurrentIndex] = useState(0);
31
+ const [isScrollPrev, setIsScrollPrev] = useState(false);
32
+ const [isScrollNext, setIsScrollNext] = useState(false);
33
+ const scrollPrev = useCallback(() => {
34
+ emblaApi?.scrollPrev();
35
+ }, [emblaApi]);
36
+ const scrollNext = useCallback(() => {
37
+ emblaApi?.scrollNext();
38
+ }, [emblaApi]);
39
+ const onKeyDownCapture = useCallback((event) => {
40
+ console.log("key...");
41
+ if (event.key === "ArrowLeft") {
42
+ event.preventDefault();
43
+ scrollPrev();
44
+ }
45
+ else if (event.key === "ArrowRight") {
46
+ event.preventDefault();
47
+ scrollNext();
48
+ }
49
+ }, [scrollPrev, scrollNext]);
50
+ const onSelect = useCallback((api) => {
51
+ if (!api)
52
+ return;
53
+ setCurrentIndex(api?.selectedScrollSnap());
54
+ setIsScrollPrev(api.canScrollPrev());
55
+ setIsScrollNext(api.canScrollNext());
56
+ }, []);
57
+ const initalEffect = useEffectEvent(() => {
58
+ if (!emblaApi || !setApi)
59
+ return;
60
+ setApi?.(emblaApi);
61
+ onSelect(emblaApi);
62
+ emblaApi.on("reInit", onSelect);
63
+ emblaApi.on("select", onSelect);
64
+ return () => {
65
+ emblaApi?.off("select", onSelect);
66
+ };
67
+ });
68
+ useEffect(() => {
69
+ const events = initalEffect();
70
+ return () => { events?.(); };
71
+ }, [emblaApi]);
72
+ return {
73
+ emblaRef,
74
+ emblaApi,
75
+ orientation,
76
+ currentIndex,
77
+ isScrollPrev,
78
+ isScrollNext,
79
+ scrollPrev,
80
+ scrollNext,
81
+ onKeyDownCapture
82
+ };
83
+ }
@@ -0,0 +1,23 @@
1
+ import useEmblaCarousel from "embla-carousel-react";
2
+ import type { EmblaCarouselsHooksTypes } from "./embla-carousels-hooks";
3
+ export type CarouselsContextProps = {
4
+ emblaRef: ReturnType<typeof useEmblaCarousel>[0];
5
+ emblaApi: ReturnType<typeof useEmblaCarousel>[1];
6
+ currentIndex?: number;
7
+ orientation: "x" | "y";
8
+ isScrollPrev: boolean;
9
+ isScrollNext: boolean;
10
+ scrollPrev: () => void;
11
+ scrollNext: () => void;
12
+ };
13
+ export declare const useCarouselsContext: () => CarouselsContextProps;
14
+ export interface PropsTypes extends EmblaCarouselsHooksTypes, React.ComponentProps<"div"> {
15
+ }
16
+ export declare const EmblaCarouselsRoots: React.FC<PropsTypes>;
17
+ export declare const EmblaCarouselsContents: React.FC<React.ComponentProps<"div">>;
18
+ export declare const EmblaCarouselsSlides: React.FC<React.ComponentProps<"div">>;
19
+ export declare const EmblaCarousels: {
20
+ Roots: import("react").FC<PropsTypes>;
21
+ Contents: import("react").FC<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>>;
22
+ Slides: import("react").FC<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>>;
23
+ };
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // update: 2025.11.20
3
+ // version: 0.0.1.bate
4
+ // dev: wade
5
+ import { createContext, memo, use, useMemo } from "react";
6
+ import { emblaCarouselsHooks, } from "./embla-carousels-hooks";
7
+ import { cn } from "../../shadcns/index.js";
8
+ const CarouselsContext = createContext(null);
9
+ export const useCarouselsContext = () => {
10
+ const context = use(CarouselsContext);
11
+ if (!context)
12
+ throw new Error("useCarousel must be used within a <Carousel />");
13
+ return context;
14
+ };
15
+ export const EmblaCarouselsRoots = memo(({ children, className, setApi, options, autoplay, autoScroll, classNames, autoHeight, fade, wheel, ...props }) => {
16
+ const { emblaRef, emblaApi, orientation, currentIndex, isScrollPrev, isScrollNext, scrollPrev, scrollNext, onKeyDownCapture, } = emblaCarouselsHooks({
17
+ setApi,
18
+ options,
19
+ autoplay,
20
+ autoScroll,
21
+ classNames,
22
+ autoHeight,
23
+ fade,
24
+ wheel,
25
+ });
26
+ const contextValue = useMemo(() => ({
27
+ emblaRef,
28
+ emblaApi,
29
+ orientation,
30
+ currentIndex,
31
+ isScrollPrev,
32
+ isScrollNext,
33
+ scrollPrev,
34
+ scrollNext,
35
+ }), [
36
+ emblaRef,
37
+ emblaApi,
38
+ orientation,
39
+ currentIndex,
40
+ isScrollPrev,
41
+ isScrollNext,
42
+ scrollPrev,
43
+ scrollNext,
44
+ ]);
45
+ return (_jsx(CarouselsContext, { value: contextValue, children: _jsx("div", { "data-component": "embla-carousels", onKeyDownCapture: onKeyDownCapture, className: cn("relative overflow-hidden", className), "aria-roledescription": "embla-carousels", role: "region", ...props, children: children }) }));
46
+ });
47
+ export const EmblaCarouselsContents = memo(({ className, ...props }) => {
48
+ const { emblaRef, orientation } = useCarouselsContext();
49
+ return (_jsx("div", { ref: emblaRef, className: "overflow-hidden", "data-component": "embla-carousels-contents", children: _jsx("div", { className: cn("flex", orientation === "x" ? "flex-row" : "flex-col", className), ...props }) }));
50
+ });
51
+ export const EmblaCarouselsSlides = memo(({ className, ...props }) => {
52
+ return (_jsx("div", { role: "group", "aria-roledescription": "slide", "data-component": "embla-carousels-slides", className: cn("min-w-0 shrink-0 grow-0 basis-full", className), ...props }));
53
+ });
54
+ export const EmblaCarousels = {
55
+ Roots: EmblaCarouselsRoots,
56
+ Contents: EmblaCarouselsContents,
57
+ Slides: EmblaCarouselsSlides,
58
+ };
@@ -0,0 +1,2 @@
1
+ export * from "./embla-carousels";
2
+ export * from "./embla-carousels-hooks";
@@ -0,0 +1,2 @@
1
+ export * from "./embla-carousels";
2
+ export * from "./embla-carousels-hooks";
@@ -0,0 +1,8 @@
1
+ type PropsTypes = {
2
+ className?: string;
3
+ slide?: React.FC<any>;
4
+ children?: any;
5
+ style?: any;
6
+ };
7
+ declare const EmblaContainer: React.FC<PropsTypes>;
8
+ export default EmblaContainer;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../shadcns/index.js";
3
+ import { useCarouselContext } from "./embla-context";
4
+ const EmblaContainer = ({ slide: SlideComponent, className, children, style, ...props }) => {
5
+ const { datas, emblaApi } = useCarouselContext();
6
+ const cantSlide = !emblaApi?.canScrollNext() && !emblaApi?.canScrollPrev();
7
+ return (_jsxs("div", { "data-component": "embla-container", className: cn("flex", className, cantSlide && [
8
+ "transform-[unset!important]"
9
+ ]), style: { ...style }, children: [SlideComponent && datas?.map((item, index) => (_jsx(SlideComponent, { ...item, index: index, ...props }, item?.multipurpose?.key ?? item?.id ?? index))), children] }));
10
+ };
11
+ EmblaContainer.displayName = "EmblaContainer";
12
+ export default EmblaContainer;
@@ -0,0 +1,21 @@
1
+ import type { EmblaViewportRefType } from "embla-carousel-react";
2
+ import type { EmblaCarouselType } from 'embla-carousel';
3
+ interface CarouselContextTypes {
4
+ datas: [];
5
+ emblaRef?: EmblaViewportRefType;
6
+ emblaApi?: EmblaCarouselType | null;
7
+ selectIndex: number;
8
+ scrollSnaps: number[];
9
+ nextScroll: () => void;
10
+ prevScroll: () => void;
11
+ scrollToIndex: (index: number) => void;
12
+ autoPlayReset: () => void;
13
+ autoPlayStop: () => void;
14
+ autoPlayPlay: () => void;
15
+ }
16
+ export declare const CarouselContextProvider: (props: {
17
+ children: React.ReactNode;
18
+ value: CarouselContextTypes;
19
+ }) => import("react/jsx-runtime").JSX.Element;
20
+ export declare const useCarouselContext: () => CarouselContextTypes;
21
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, use } from "react";
3
+ const CarouselContext = createContext(null);
4
+ export const CarouselContextProvider = (props) => {
5
+ return _jsx(CarouselContext, { ...props });
6
+ };
7
+ export const useCarouselContext = () => {
8
+ const context = use(CarouselContext);
9
+ if (!context)
10
+ throw new Error("useCMSData must be used inside CMSProvider");
11
+ return context;
12
+ };
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { EmblaOptionsType } from "embla-carousel";
3
+ import type { AutoplayOptionsType } from "embla-carousel-autoplay";
4
+ export interface PropsTypes extends EmblaOptionsType {
5
+ children?: React.ReactNode;
6
+ className?: string;
7
+ options?: EmblaOptionsType;
8
+ datas?: any;
9
+ autoplayEnabled?: boolean;
10
+ autoplayOptions?: AutoplayOptionsType;
11
+ setApi?: any;
12
+ setMethods?: any;
13
+ setRef?: any;
14
+ style?: any;
15
+ controls?: any;
16
+ plugins?: any;
17
+ onScrolled?: (index: number) => void;
18
+ }
19
+ declare const Embla: React.FC<PropsTypes>;
20
+ export default Embla;
@@ -0,0 +1,124 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
3
+ import useEmblaCarousel from "embla-carousel-react";
4
+ import { cn } from "../../shadcns/index.js";
5
+ import { CarouselContextProvider } from "./embla-context";
6
+ import Autoplay from "embla-carousel-autoplay";
7
+ const Embla = ({ children, className, options, datas, autoplayEnabled = true, autoplayOptions, setApi, setMethods, setRef, style, controls, onScrolled }) => {
8
+ const { loop, duration = 40 } = options || {};
9
+ const autoplaySetting = useMemo(() => {
10
+ if (!autoplayEnabled)
11
+ return;
12
+ return [Autoplay({ playOnInit: true, delay: 5000, stopOnInteraction: false, ...autoplayOptions })];
13
+ }, [autoplayEnabled, autoplayOptions]);
14
+ const [emblaRef, emblaApi] = useEmblaCarousel({ ...options, loop, duration }, autoplaySetting);
15
+ const [selectIndex, setSelectIndex] = useState(0);
16
+ const [scrollSnaps, setScrollSnaps] = useState([]);
17
+ const nextScroll = useCallback(() => {
18
+ if (!emblaApi)
19
+ return;
20
+ const { canScrollNext, scrollNext } = emblaApi;
21
+ canScrollNext() && scrollNext() && autoPlayReset();
22
+ }, [emblaApi]);
23
+ const prevScroll = useCallback(() => {
24
+ if (!emblaApi)
25
+ return;
26
+ const { canScrollPrev, scrollPrev } = emblaApi;
27
+ canScrollPrev() && scrollPrev() && autoPlayReset();
28
+ }, [emblaApi]);
29
+ const scrollToIndex = useCallback((index) => {
30
+ if (!emblaApi || typeof index !== "number")
31
+ return;
32
+ emblaApi.scrollTo(index);
33
+ }, [emblaApi]);
34
+ // 自動輪播啟動
35
+ const autoPlayReset = useCallback(() => {
36
+ if (!emblaApi)
37
+ return;
38
+ // console.log("autoplay.reset");
39
+ const autoplay = emblaApi?.plugins()?.autoplay;
40
+ autoplay && autoplay.reset();
41
+ }, [emblaApi]);
42
+ const autoPlayPlay = useCallback(() => {
43
+ if (!emblaApi)
44
+ return;
45
+ // console.log("autoplay.play");
46
+ if (!emblaApi.canScrollNext())
47
+ return; // 防呆
48
+ const autoplay = emblaApi?.plugins()?.autoplay;
49
+ autoplay && autoplay.play();
50
+ }, [emblaApi]);
51
+ // 自動輪播暫停
52
+ const autoPlayStop = useCallback(() => {
53
+ if (!emblaApi)
54
+ return;
55
+ // console.log("autoplay.stop");
56
+ const autoplay = emblaApi?.plugins()?.autoplay;
57
+ autoplay && autoplay.stop();
58
+ }, [emblaApi]);
59
+ const contextValue = useMemo(() => ({
60
+ datas,
61
+ emblaRef,
62
+ emblaApi,
63
+ selectIndex,
64
+ scrollSnaps,
65
+ nextScroll,
66
+ prevScroll,
67
+ scrollToIndex,
68
+ autoPlayReset,
69
+ autoPlayStop,
70
+ autoPlayPlay
71
+ }), [
72
+ datas,
73
+ emblaRef,
74
+ emblaApi,
75
+ selectIndex,
76
+ scrollSnaps,
77
+ nextScroll,
78
+ prevScroll,
79
+ scrollToIndex,
80
+ autoPlayReset,
81
+ autoPlayStop,
82
+ autoPlayPlay
83
+ ]);
84
+ const onInit = useCallback((emblaApi) => {
85
+ const snapList = emblaApi.scrollSnapList();
86
+ setScrollSnaps(snapList);
87
+ }, []);
88
+ const onSelectEvent = (emblaApi) => {
89
+ emblaApi.on("select", () => {
90
+ onScrolled?.(emblaApi.selectedScrollSnap());
91
+ setSelectIndex(emblaApi.selectedScrollSnap());
92
+ });
93
+ };
94
+ useEffect(() => {
95
+ if (!emblaApi)
96
+ return;
97
+ setRef?.(emblaRef);
98
+ setApi?.(emblaApi);
99
+ setMethods?.({});
100
+ onInit(emblaApi);
101
+ onSelectEvent(emblaApi);
102
+ }, [emblaApi]);
103
+ return (_jsx(CarouselContextProvider, { value: contextValue, children: _jsxs("div", { "data-component": "embla-root", className: cn("relative w-full"), children: [_jsx("div", { className: cn("overflow-hidden", "w-full", className), ref: emblaRef, style: style, children: children }), Array.isArray(controls) ? controls.map((ctrl, i) => (_jsx(React.Fragment, { children: ctrl }, i))) : controls] }) })
104
+ // <CarouselContextProvider
105
+ // value={contextValue}
106
+ // >
107
+ // <div
108
+ // data-component="embla-root"
109
+ // className={cn(
110
+ // "overflow-hidden",
111
+ // "relative",
112
+ // "w-full",
113
+ // className
114
+ // )}
115
+ // ref={emblaRef}
116
+ // style={style}
117
+ // >
118
+ // {children}
119
+ // </div>
120
+ // </CarouselContextProvider>
121
+ );
122
+ };
123
+ Embla.displayName = "Embla";
124
+ export default Embla;
@@ -0,0 +1,11 @@
1
+ type EmblaPaginationPropsTypes = {
2
+ color?: "black" | "white" | string;
3
+ align?: "start" | "center" | "end";
4
+ className?: string;
5
+ maxDots?: number;
6
+ dynamic?: boolean;
7
+ swiperNumber?: boolean;
8
+ style?: string;
9
+ };
10
+ export declare const EmblaPagination: React.FC<EmblaPaginationPropsTypes>;
11
+ export default EmblaPagination;
@@ -0,0 +1,89 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from "../../shadcns/index.js";
3
+ import { useCarouselContext } from "./embla-context";
4
+ import { useEffect, useState } from "react";
5
+ export const EmblaPagination = ({ color = "black", align, className, maxDots = 5, dynamic = true, swiperNumber = true, }) => {
6
+ const { selectIndex, scrollToIndex, scrollSnaps, autoPlayReset, emblaApi } = useCarouselContext();
7
+ // 點點計算
8
+ const total = scrollSnaps?.length ?? 0;
9
+ const active = Math.max(0, Math.min(selectIndex ?? 0, Math.max(0, total - 1)));
10
+ // 顯示數字
11
+ const paginationNumber = `${Number(active + 1) < 10 ? "0" + Number(active + 1) : Number(active + 1)}`;
12
+ const isWhite = color === "white";
13
+ // 點擊事件
14
+ const clickEvent = (index) => {
15
+ scrollToIndex(index); // 移動到當澤輪播
16
+ autoPlayReset(); // 如果有開啟自動輪播要重置輪播時間
17
+ };
18
+ // 點點是否為當前
19
+ const isSelected = (index) => {
20
+ return index === selectIndex;
21
+ };
22
+ // -- 動態點點 Start --
23
+ const [selectedIndex, setSelectedIndex] = useState(0);
24
+ const [slideCount, setSlideCount] = useState(0);
25
+ useEffect(() => {
26
+ if (!emblaApi || !dynamic)
27
+ return;
28
+ const update = () => {
29
+ setSelectedIndex(emblaApi.selectedScrollSnap());
30
+ setSlideCount(emblaApi.scrollSnapList().length);
31
+ };
32
+ emblaApi.on('select', update);
33
+ emblaApi.on('reInit', update); // 重新初始化時也更新
34
+ update();
35
+ return () => {
36
+ emblaApi.off('select', update);
37
+ emblaApi.off('reInit', update);
38
+ };
39
+ }, [emblaApi, dynamic]);
40
+ const getVisibleBullets = () => {
41
+ const total = slideCount ?? 0;
42
+ if (total === 0)
43
+ return [];
44
+ const limit = Math.max(1, Number(maxDots));
45
+ const windowSize = Math.min(total, limit);
46
+ const left = Math.floor((windowSize - 1) / 2);
47
+ const right = windowSize - left - 1;
48
+ let start = selectedIndex - left;
49
+ let end = selectedIndex + right;
50
+ if (start < 0) {
51
+ end = Math.min(end - start, total - 1);
52
+ start = 0;
53
+ }
54
+ if (end > total - 1) {
55
+ start = Math.max(0, start - (end - (total - 1)));
56
+ end = total - 1;
57
+ }
58
+ return Array.from({ length: end - start + 1 }, (_, i) => start + i);
59
+ };
60
+ const visibleRange = getVisibleBullets();
61
+ // -- 動態點點 End --
62
+ // 是否開啟動態點點決定點點跑陣列的方式
63
+ const dots = dynamic ? visibleRange : scrollSnaps?.map((_, i) => i) ?? [];
64
+ // WE - 頁碼
65
+ const swiperSnap = [
66
+ "text-[16px]",
67
+ "font-semibold",
68
+ " leading-[1.4]",
69
+ ];
70
+ const paginationColorStyle = {
71
+ "black": "#000",
72
+ "white": "#fff",
73
+ }[color] || `${color}`;
74
+ const paginationColorStyle2 = {
75
+ "--pagination-color": paginationColorStyle,
76
+ };
77
+ return (_jsxs("div", { "data-compoents": "emblas-pagination", className: cn("flex", "items-center", "gap-7.25", align === "center" && [
78
+ "justify-center",
79
+ ], className), style: paginationColorStyle2, children: [swiperNumber &&
80
+ _jsx("div", { className: cn(swiperSnap, "relative", "after:absolute", "after:top-1/2", "after:right-[-15px]", "after:-translate-y-1/2", "after:block",
81
+ // "after:bg-black",
82
+ "after:bg-(--pagination-color)", "after:w-0.5", "after:h-3.75", "after:opacity-20", isWhite && [
83
+ "after:bg-white",
84
+ ]), children: paginationNumber }), _jsx("div", { className: cn("flex", "flex-wrap", "justify-end", "items-center", "gap-y-0", "gap-x-2.5", "**:data-[component='emblas-pagination-dots']:bg-(--pagination-color)", isWhite && [
85
+ "**:data-[component='emblas-pagination-dots']:bg-white",
86
+ ]), children: dots.map((index) => (_jsx("div", { "data-component": "emblas-pagination-dots", onClick: () => clickEvent(index), className: cn("w-1.5", "h-1.5", "rounded-full", "cursor-pointer", "opacity-30", isSelected(index) && ("opacity-100")) }, index))) })] }));
87
+ };
88
+ EmblaPagination.displayName = "EmblaPagination";
89
+ export default EmblaPagination;
@@ -0,0 +1,4 @@
1
+ export * from "./embla-context";
2
+ export { default as Embla } from "./embla";
3
+ export { default as EmblaContainer } from "./embla-container";
4
+ export { default as EmblaPagination } from "./emblas-pagination";
@@ -0,0 +1,4 @@
1
+ export * from "./embla-context";
2
+ export { default as Embla } from "./embla";
3
+ export { default as EmblaContainer } from "./embla-container";
4
+ export { default as EmblaPagination } from "./emblas-pagination";
@@ -1,2 +1,5 @@
1
1
  export * from "./anchors";
2
+ export * from "./scroll-containers";
3
+ export * from "./embla-carousels";
4
+ export * from "./emblas";
2
5
  export * from "./tests";
@@ -1,2 +1,5 @@
1
1
  export * from "./anchors";
2
+ export * from "./scroll-containers";
3
+ export * from "./embla-carousels";
4
+ export * from "./emblas";
2
5
  export * from "./tests";
@@ -0,0 +1,3 @@
1
+ export * from "./native-scroll";
2
+ export * from "./lenis-scroll";
3
+ export * from "./scroll-containers";
@@ -0,0 +1,3 @@
1
+ export * from "./native-scroll";
2
+ export * from "./lenis-scroll";
3
+ export * from "./scroll-containers";
@@ -0,0 +1,20 @@
1
+ import Lenis from 'lenis';
2
+ import type { LenisOptions } from "lenis";
3
+ export interface LenisScrollProps {
4
+ root?: boolean | "asChild";
5
+ name?: string;
6
+ options?: LenisOptions;
7
+ children?: React.ReactNode;
8
+ className?: string;
9
+ }
10
+ export declare const LenisScroll: React.FC<LenisScrollProps>;
11
+ export declare const LenisRootScroll: React.FC<LenisScrollProps>;
12
+ type LenisScrollContainerProps = Omit<LenisScrollProps, "root">;
13
+ export declare const LenisContainerScroll: React.FC<LenisScrollContainerProps>;
14
+ interface LenisStores {
15
+ root?: Lenis | null;
16
+ }
17
+ export declare const useLenisStores: import("zustand").UseBoundStore<import("zustand").StoreApi<LenisStores>>;
18
+ export declare const setRootLenis: (lenis: Lenis) => void;
19
+ export declare const getRootLenis: () => LenisStores;
20
+ export {};