UNPKG

@web3r/flowerkit

Version:

Tree-shakable JavaScript and TypeScript utility library for frontend/browser apps: DOM, events, arrays, objects, strings, date, JSON, and network helpers (ESM/CJS, SSR-friendly).

1 lines 13.4 kB
{"version":3,"file":"index.cjs","sources":[""],"sourcesContent":["import { getWindow } from \"ssr-window\";\r\nimport { isTouchDevice } from \"../../user/isTouchDevice/index.ts\";\r\nimport { bubble } from \"../bubble/index.ts\";\r\n\r\ntype TSupportedEvents =\r\n | { type: \"pointer\"; start: \"pointerdown\"; move: \"pointermove\"; end: \"pointerup\"; cancel: \"pointercancel\"; leave: \"pointerleave\"; }\r\n | { type: \"touch\"; start: \"touchstart\"; move: \"touchmove\"; end: \"touchend\"; cancel: \"touchcancel\"; leave: \"touchleave\"; }\r\n | { type: \"mouse\"; start: \"mousedown\"; move: \"mousemove\"; end: \"mouseup\"; leave: \"mouseleave\"; };\r\n\r\nexport type TOnSwipeArgs = Parameters<typeof onSwipe>;\r\n\r\nexport type TOnSwipeReturn = ReturnType<typeof onSwipe>;\r\n\r\n/**\r\n * Adds a device-agnostic swipe detector for an element (pointer, touch, or mouse).\r\n * Dispatches a \"swipe\" `CustomEvent` or calls the provided callback.\r\n *\r\n * @template TDetail\r\n * @param {Element|Document} el Target to listen for gestures\r\n * @param {{\r\n * callback?: (detail: TDetail) => void;\r\n * minDist?: number;\r\n * maxDist?: number;\r\n * minTime?: number;\r\n * maxTime?: number;\r\n * }} [props={}] Swipe configuration\r\n * @param {boolean} [isAutoInit=true] Attach listeners immediately\r\n * @returns {{\r\n * handler: { start: (e: Event) => void; move: (e: Event) => void; end: (e: Event) => void };\r\n * addListener: () => void;\r\n * removeListener: () => void;\r\n * }}\r\n * @throws {TypeError} onSwipe: el must be an Element or Document\r\n * @throws {TypeError} onSwipe: props must be an object\r\n * @throws {TypeError} onSwipe: callback must be a function if provided\r\n * @throws {TypeError} onSwipe: minDist/maxDist/minTime/maxTime must be finite numbers if provided\r\n *\r\n * @example\r\n * onSwipe(document.getElementById(\"box\")!, { callback: ({ dir }) => console.log(dir) });\r\n */\r\nexport const onSwipe = <TDetail extends {\r\n originEvent: Event;\r\n dir: \"left\" | \"right\" | \"up\" | \"down\";\r\n dist: number;\r\n time: number;\r\n supportedEvents: TSupportedEvents;\r\n} = {\r\n originEvent: Event;\r\n dir: \"left\" | \"right\" | \"up\" | \"down\";\r\n dist: number;\r\n time: number;\r\n supportedEvents: TSupportedEvents;\r\n}>(\r\n el: Element | Document,\r\n props: {\r\n callback?: (detail: TDetail) => void;\r\n minDist?: number;\r\n maxDist?: number;\r\n minTime?: number;\r\n maxTime?: number;\r\n } = {},\r\n isAutoInit: boolean = true\r\n): { handler: { start: (e: Event) => void; move: (e: Event) => void; end: (e: Event) => void; }; addListener: () => void; removeListener: () => void; } => {\r\n if (!el || typeof (el as any).addEventListener !== \"function\") {\r\n throw new TypeError(\"onSwipe: el must be an Element or Document\");\r\n }\r\n if (props === null || typeof props !== \"object\") {\r\n throw new TypeError(\"onSwipe: props must be an object\");\r\n }\r\n const {\r\n callback, minDist, maxDist, minTime, maxTime,\r\n } = props as any;\r\n if (typeof callback !== \"undefined\" && typeof callback !== \"function\") {\r\n throw new TypeError(\"onSwipe: callback must be a function if provided\");\r\n }\r\n for (const [ k, v ] of Object.entries({\r\n minDist, maxDist, minTime, maxTime,\r\n })) {\r\n if (typeof v !== \"undefined\" && (typeof v !== \"number\" || !Number.isFinite(v))) {\r\n throw new TypeError(`onSwipe: ${k} must be a finite number if provided`);\r\n }\r\n }\r\n\r\n const settings = {\r\n minDist: 60,\r\n maxDist: 120,\r\n maxTime: 700,\r\n minTime: 50,\r\n callback: null as null | ((detail: TDetail) => void),\r\n ...props,\r\n };\r\n\r\n if (settings.maxTime < settings.minTime) {\r\n settings.maxTime = settings.minTime + 500;\r\n }\r\n\r\n if (settings.maxTime < 100 || settings.minTime < 50) {\r\n settings.maxTime = 700;\r\n settings.minTime = 50;\r\n }\r\n\r\n const eventsUnify = (e: MouseEvent | TouchEvent | PointerEvent | CustomEvent | Event) => {\r\n const te = e as TouchEvent;\r\n if (typeof te.changedTouches !== \"undefined\" && te.changedTouches && te.changedTouches.length) {\r\n return te.changedTouches[0];\r\n }\r\n return e as unknown as { pageX?: number; pageY?: number; };\r\n };\r\n\r\n const isSupport = {\r\n pointer: (\"PointerEvent\" in getWindow() || (\"msPointerEnabled\" in (getWindow().navigator as unknown as { msPointerEnabled?: unknown; }))),\r\n touch: isTouchDevice(),\r\n };\r\n\r\n const getSupportedEvents = (): TSupportedEvents => {\r\n if (isSupport.pointer) {\r\n return {\r\n type: \"pointer\",\r\n start: \"pointerdown\",\r\n move: \"pointermove\",\r\n end: \"pointerup\",\r\n cancel: \"pointercancel\",\r\n leave: \"pointerleave\",\r\n };\r\n }\r\n if (isSupport.touch) {\r\n return {\r\n type: \"touch\",\r\n start: \"touchstart\",\r\n move: \"touchmove\",\r\n end: \"touchend\",\r\n cancel: \"touchcancel\",\r\n leave: \"touchleave\",\r\n };\r\n }\r\n return {\r\n type: \"mouse\",\r\n start: \"mousedown\",\r\n move: \"mousemove\",\r\n end: \"mouseup\",\r\n leave: \"mouseleave\",\r\n };\r\n };\r\n\r\n const events = getSupportedEvents();\r\n\r\n let dir: \"none\" | \"left\" | \"right\" | \"up\" | \"down\",\r\n swipeType: \"none\" | \"left\" | \"right\" | \"up\" | \"down\",\r\n dist: number,\r\n isMouse = false,\r\n isMouseDown = false,\r\n startX = 0,\r\n distX = 0,\r\n startY = 0,\r\n distY = 0,\r\n startTime = 0;\r\n\r\n const checkStart = (e: Event): void => {\r\n const event: any = eventsUnify(e);\r\n const t = e as TouchEvent;\r\n if (isSupport.touch && typeof t.touches !== \"undefined\" && t.touches.length !== 1) {\r\n return;\r\n }\r\n dir = \"none\";\r\n swipeType = \"none\";\r\n dist = 0;\r\n const ce = e as CustomEvent<{ _pageX?: number; _pageY?: number; }>;\r\n startX = (event.pageX ?? ce?.detail?._pageX ?? 0);\r\n startY = (event.pageY ?? ce?.detail?._pageY ?? 0);\r\n startTime = Date.now();\r\n if (isMouse) {\r\n isMouseDown = true;\r\n }\r\n };\r\n\r\n const checkMove = (e: Event): void => {\r\n if (isMouse && !isMouseDown) {\r\n return;\r\n }\r\n const event: any = eventsUnify(e);\r\n const ce = e as CustomEvent<{ _pageX?: number; _pageY?: number; }>;\r\n distX = (event.pageX ?? ce?.detail?._pageX ?? 0) - startX;\r\n distY = (event.pageY ?? ce?.detail?._pageY ?? 0) - startY;\r\n if (Math.abs(distX) > Math.abs(distY)) {\r\n dir = (distX < 0) ? \"left\" : \"right\";\r\n } else {\r\n dir = (distY < 0) ? \"up\" : \"down\";\r\n }\r\n };\r\n\r\n const checkEnd = (e: Event): void => {\r\n if (isMouse && !isMouseDown) {\r\n isMouseDown = false;\r\n return;\r\n }\r\n\r\n const endTime = Date.now();\r\n const time = endTime - startTime;\r\n\r\n if (time >= settings.minTime && time <= settings.maxTime) {\r\n if (Math.abs(distX) >= settings.minDist && Math.abs(distY) <= settings.maxDist) {\r\n swipeType = dir;\r\n } else if (Math.abs(distY) >= settings.minDist && Math.abs(distX) <= settings.maxDist) {\r\n swipeType = dir;\r\n }\r\n }\r\n\r\n dist = (dir === \"left\" || dir === \"right\") ? Math.abs(distX) : Math.abs(distY);\r\n\r\n const ce = e as CustomEvent<{ _swipeType?: \"left\" | \"right\" | \"up\" | \"down\"; _pageX?: number; _pageY?: number; }>;\r\n if (ce?.detail?._swipeType) {\r\n swipeType = ce.detail._swipeType;\r\n }\r\n\r\n if (swipeType !== \"none\" && dist >= settings.minDist) {\r\n const detail = {\r\n originEvent: e,\r\n dir: swipeType as \"left\" | \"right\" | \"up\" | \"down\",\r\n dist,\r\n time,\r\n supportedEvents: events as TSupportedEvents,\r\n } as TDetail;\r\n if (typeof settings.callback === \"function\") {\r\n settings.callback(detail);\r\n } else {\r\n bubble(el as any, \"swipe\", detail, {\r\n bubbles: true,\r\n cancelable: true,\r\n });\r\n }\r\n }\r\n };\r\n\r\n const handler = {\r\n start: (e: Event): void => checkStart(e),\r\n end: (e: Event): void => checkEnd(e),\r\n move: (e: Event): void => checkMove(e),\r\n };\r\n\r\n if ((isSupport.pointer && !isSupport.touch) || events.type === \"mouse\") {\r\n isMouse = true;\r\n }\r\n\r\n const listenerCtrl = (isBind: boolean = true): void => {\r\n const action: \"addEventListener\" | \"removeEventListener\" = isBind ? \"addEventListener\" : \"removeEventListener\";\r\n (el as unknown as EventTarget)[action](events.start, handler.start as EventListener);\r\n (el as unknown as EventTarget)[action](events.move, handler.move as EventListener);\r\n (el as unknown as EventTarget)[action](events.end, handler.end as EventListener);\r\n if (isSupport.pointer && isSupport.touch) {\r\n (el as unknown as EventTarget)[action](\"lostpointercapture\", handler.end as EventListener);\r\n }\r\n };\r\n\r\n const addListener = (): void => {\r\n listenerCtrl(true);\r\n };\r\n\r\n const removeListener = (): void => {\r\n listenerCtrl(false);\r\n };\r\n\r\n if (isAutoInit) {\r\n addListener();\r\n }\r\n\r\n return {\r\n handler,\r\n addListener,\r\n removeListener,\r\n };\r\n};\r\n"],"names":["onSwipe","el","props","isAutoInit","addEventListener","TypeError","callback","minDist","maxDist","minTime","maxTime","k","v","Object","entries","Number","isFinite","settings","eventsUnify","e","te","changedTouches","length","isSupport","pointer","getWindow","navigator","touch","isTouchDevice","getSupportedEvents","type","start","move","end","cancel","leave","events","dir","swipeType","dist","isMouse","isMouseDown","startX","distX","startY","distY","startTime","checkStart","event","t","touches","ce","pageX","detail","_pageX","pageY","_pageY","Date","now","checkMove","Math","abs","checkEnd","endTime","time","_swipeType","originEvent","supportedEvents","bubble","bubbles","cancelable","handler","listenerCtrl","isBind","action","addListener","removeListener"],"mappings":"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"}