Files
MediaManager/web/src/lib/components/ui/carousel/context.ts
maxDorninger b2dc7a18a6 fix formatting
2025-05-25 20:31:48 +02:00

57 lines
1.9 KiB
TypeScript

import type {EmblaCarouselSvelteType} from 'embla-carousel-svelte';
import type emblaCarouselSvelte from 'embla-carousel-svelte';
import {getContext, hasContext, setContext} from 'svelte';
import type {WithElementRef} from 'bits-ui';
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);
}