import React, { Component, AllHTMLAttributes, ReactNode, Ref } from 'react';
import jquery from 'jquery';
import { Options } from './options';
import 'owl.carousel';
const $: typeof jquery = (window as any).jQuery;
export type ComponentProps = Readonly & { children: ReactNode }>;
export type OwlCarouselProps = Options & ComponentProps;
export default class ReactOwlCarousel extends Component {
public $ele?: JQuery;
private container?: HTMLDivElement | null;
private propsWithoutOptions: ComponentProps;
private options: Options;
constructor(props: OwlCarouselProps) {
super(props);
const [options, propsWithoutOptions] = filterOptions(this.props);
this.options = options;
this.propsWithoutOptions = propsWithoutOptions;
}
public componentDidMount() {
this.$ele = $(this.container!);
this.create();
}
public componentWillReceiveProps() {
this.destory();
}
public componentDidUpdate() {
const [options, propsWithoutOptions] = filterOptions(this.props);
this.options = options;
this.propsWithoutOptions = propsWithoutOptions;
this.create();
}
public next(speed: number | number[]) {
if (!this.$ele) throw new Error('OwlCarousel is not created');
if (typeof speed === 'number') {
this.$ele.trigger('next.owl.carousel', [speed]);
}
else {
this.$ele.trigger('next.owl.carousel', speed);
}
}
public prev(speed: number | number[]) {
if (!this.$ele) throw new Error('OwlCarousel is not created');
if (typeof speed === 'number') {
this.$ele.trigger('prev.owl.carousel', [speed]);
}
else {
this.$ele.trigger('prev.owl.carousel', speed);
}
}
public to(position: number, speed: number) {
if (!this.$ele) throw new Error('OwlCarousel is not created');
if (typeof position === 'number' && typeof speed === 'number') {
this.$ele.trigger('to.owl.carousel', [position, speed]);
}
else {
this.$ele.trigger('to.owl.carousel');
}
}
public create(options?: Options) {
if (!this.$ele) throw new Error('OwlCarousel is not created');
this.$ele.owlCarousel(options || this.options);
}
public destory() {
if (!this.$ele) throw new Error('OwlCarousel is not created');
this.$ele.trigger('destroy.owl.carousel');
}
public play(timeout: number, speed: number) {
if (!this.$ele) throw new Error('OwlCarousel is not created');
if (typeof timeout === 'number' && typeof speed === 'number') {
this.$ele.trigger('play.owl.autoplay', [timeout, speed]);
}
else {
this.$ele.trigger('play.owl.autoplay');
}
}
public stop() {
if (!this.$ele) throw new Error('OwlCarousel is not created');
this.$ele.trigger('stop.owl.autoplay');
}
public render() {
const {
className,
...props,
} = this.propsWithoutOptions;
return (
);
}
private containerRef: Ref = (inst) => {
this.container = inst;
}
}
const OPTIONS = new Set([
'items',
'margin',
'loop',
'center',
'mouseDrag',
'touchDrag',
'pullDrag',
'freeDrag',
'stagePadding',
'merge',
'mergeFit',
'autoWidth',
'startPosition',
'URLhashListener',
'nav',
'rtl',
'rewind',
'navText',
'navElement',
'slideBy',
'dots',
'dotsEach',
'dotData',
'lazyLoad',
'lazyContent',
'autoplay',
'autoplayTimeout',
'autoplayHoverPause',
'smartSpeed',
'fluidSpeed',
'autoplaySpeed',
'navSpeed',
'dotsSpeed',
'dragEndSpeed',
'callbacks',
'responsive',
'responsiveRefreshRate',
'responsiveBaseElement',
'video',
'videoHeight',
'videoWidth',
'animateOut',
'animateIn',
'fallbackEasing',
'info',
'nestedItemSelector',
'itemElement',
'stageElement',
'navContainer',
'dotsContainer',
// 'CLASSES'
'refreshClass',
'loadingClass',
'loadedClass',
'rtlClass',
'dragClass',
'grabClass',
'stageClass',
'stageOuterClass',
'navContainerClass',
'navClass',
'controlsClass',
'dotClass',
'dotsClass',
'autoHeightClass',
'responsiveClass',
// 'EVENTS'
'onInitialize',
'onInitialized',
'onResize',
'onResized',
'onRefresh',
'onRefreshed',
'onDrag',
'onDragged',
'onTranslate',
'onTranslated',
'onChange',
'onChanged',
'onLoadLazy',
'onLoadedLazy',
'onStopVideo',
'onPlayVideo',
]);
interface Params { [key: string]: any; }
function filterOptions(item: Params): [Options, ComponentProps] {
const options: Params = {};
const propsWithoutOptions: Params = {};
Object.keys(item).forEach((key) => {
if (OPTIONS.has(key)) {
options[key] = item[key];
}
else {
propsWithoutOptions[key] = item[key];
}
});
return [options as Options, propsWithoutOptions as ComponentProps];
}
export * from './options';