56 lines
1.8 KiB
TypeScript
56 lines
1.8 KiB
TypeScript
import type { WithElementRef } from "@/lib/utils.js";
|
|
import type { EmblaCarouselSvelteType } from "embla-carousel-svelte";
|
|
import type emblaCarouselSvelte from "embla-carousel-svelte";
|
|
import { getContext, hasContext, setContext } from "svelte";
|
|
import type { HTMLAttributes } from "svelte/elements";
|
|
|
|
export type CarouselAPI =
|
|
NonNullable<NonNullable<EmblaCarouselSvelteType["$$_attributes"]>["on:emblaInit"]> extends (
|
|
evt: CustomEvent<infer CarouselAPI>
|
|
) => void
|
|
? CarouselAPI
|
|
: never;
|
|
|
|
type EmblaCarouselConfig = NonNullable<Parameters<typeof emblaCarouselSvelte>[1]>;
|
|
|
|
export type CarouselOptions = EmblaCarouselConfig["options"];
|
|
export type CarouselPlugins = EmblaCarouselConfig["plugins"];
|
|
|
|
////
|
|
|
|
export type CarouselProps = {
|
|
opts?: CarouselOptions;
|
|
plugins?: CarouselPlugins;
|
|
setApi?: (api: CarouselAPI | undefined) => void;
|
|
orientation?: "horizontal" | "vertical";
|
|
} & WithElementRef<HTMLAttributes<HTMLDivElement>>;
|
|
|
|
const EMBLA_CAROUSEL_CONTEXT = Symbol("EMBLA_CAROUSEL_CONTEXT");
|
|
|
|
export type EmblaContext = {
|
|
api: CarouselAPI | undefined;
|
|
orientation: "horizontal" | "vertical";
|
|
scrollNext: () => void;
|
|
scrollPrev: () => void;
|
|
canScrollNext: boolean;
|
|
canScrollPrev: boolean;
|
|
handleKeyDown: (e: KeyboardEvent) => void;
|
|
options: CarouselOptions;
|
|
plugins: CarouselPlugins;
|
|
onInit: (e: CustomEvent<CarouselAPI>) => void;
|
|
scrollTo: (index: number, jump?: boolean) => void;
|
|
scrollSnaps: number[];
|
|
selectedIndex: number;
|
|
};
|
|
|
|
export function setEmblaContext(config: EmblaContext): EmblaContext {
|
|
setContext(EMBLA_CAROUSEL_CONTEXT, config);
|
|
return config;
|
|
}
|
|
|
|
export function getEmblaContext(name = "This component") {
|
|
if (!hasContext(EMBLA_CAROUSEL_CONTEXT)) {
|
|
throw new Error(`${name} must be used within a <Carousel.Root> component`);
|
|
}
|
|
return getContext<ReturnType<typeof setEmblaContext>>(EMBLA_CAROUSEL_CONTEXT);
|
|
}
|