UNPKG

solidjs-swiper

Version:
148 lines (145 loc) 4.17 kB
import { spread, insert, createComponent, use, template } from 'solid-js/web'; import { splitProps, createSignal, createEffect, onMount, For } from 'solid-js'; // src/Swiper.tsx var _tmpl$ = /* @__PURE__ */ template(`<div class="swiper-container"><div class="swiper-wrapper">`); var _tmpl$2 = /* @__PURE__ */ template(`<style> .swiper-container { position: relative; width: 100%; height: 100%; display: flex; flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: nowrap; overflow: hidden; } .swiper-wrapper { position: relative; width: 100%; height: 100%; flex-shrink: 0; display: flex; flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: nowrap; transition: transform 0ms ease-in-out; transform: translateX(-0px); } .swiper-slide { flex-shrink: 0; width: 100%; } `); var _tmpl$3 = /* @__PURE__ */ template(`<div class="swiper-slide">`); function Swiper(attrs) { const [props, rest] = splitProps(attrs, ["items", "threshold", "index", "onReady", "onChange"]); const items = () => props?.items || []; const threshold = () => props?.threshold || 80; const [activeSlide, setActiveSlide] = createSignal(props?.index || 0); const state = { active: false, start: [0, 0], end: [0, 0] }; let wrapperEl; const itemsEl = {}; const refreshActive = () => { offset = (itemsEl[0]?.clientWidth || 0) * activeSlide(); setOffset(offset, true); }; createEffect(() => setActiveSlide(props?.index || 0)); createEffect(() => { items() && refreshActive(); }); createEffect(() => { props.onChange?.(activeSlide()); }); let offset = 0; const setOffset = (value, animated = true) => { if (wrapperEl?.style) { wrapperEl.style.transform = `translateX(-${value}px)`; wrapperEl.style.transitionDuration = animated ? "250ms" : "0ms"; } }; const prev = () => { let slide = activeSlide() - 1; if (slide <= 0) { setActiveSlide(0); return false; } setActiveSlide(slide); return true; }; const next = () => { let slide = activeSlide() + 1; let maxSlide = (items()?.length || 1) - 1; if (slide >= maxSlide) { setActiveSlide(maxSlide); return false; } setActiveSlide(slide); return true; }; onMount(() => { const api = { next: () => next(), prev: () => prev() }; props?.onReady?.(api); }); const events = { onMouseDown: (event) => { event.preventDefault(); state.active = true; state.start = [event.clientX, event.clientY]; }, onMouseMove: (event) => { event.preventDefault(); if (!state.active) return; let diff = event.clientX - state.start[0]; let normalOffset = offset; setOffset(normalOffset + -diff, false); }, onMouseUp: (event) => { event.preventDefault(); if (!state.active) return; state.end = [event.clientX, event.clientY]; state.active = false; let diff = event.clientX - state.start[0]; if (diff > threshold()) { if (prev()) return true; } else if (diff < -threshold()) { if (next()) return true; } setOffset(offset); }, onMouseLeave: (event) => { events.onMouseUp(event); } }; return [(() => { const _el$ = _tmpl$(), _el$2 = _el$.firstChild; const _ref$ = wrapperEl; typeof _ref$ === "function" ? use(_ref$, _el$2) : wrapperEl = _el$2; spread(_el$2, events, false, true); insert(_el$2, createComponent(For, { get each() { return items(); }, children: (item, index) => (() => { const _el$4 = _tmpl$3(); use((el) => itemsEl[index()] = el, _el$4); insert(_el$4, () => attrs?.children?.(item, index)); return _el$4; })() })); return _el$; })(), _tmpl$2()]; } export { Swiper };