@atomico/hooks
Advanced tools
Comparing version 3.16.0 to 3.16.1
{ | ||
"name": "@atomico/hooks", | ||
"description": "Series of utilities in hooks format to extend the operation of Atomico", | ||
"version": "3.16.0", | ||
"version": "3.16.1", | ||
"type": "module", | ||
@@ -43,6 +43,5 @@ "workspaces": [ | ||
"./use-css-light-dom": "./src/use-css-light-dom/use-css-light-dom.js", | ||
"./use-current-value": "./src/use-current-value/use-current-value.js", | ||
"./use-debounce-state": "./src/use-debounce-state/use-debounce-state.js", | ||
"./use-disabled": "./src/use-disabled/use-disabled.js", | ||
"./use-drag": "./src/use-drag/use-drag.js", | ||
"./use-force-render": "./src/use-force-render/use-force-render.js", | ||
"./use-form": "./src/use-form/use-form.js", | ||
@@ -72,2 +71,8 @@ "./use-internals": "./src/use-internals/use-internals.js", | ||
], | ||
"use-current-value": [ | ||
"./types/use-current-value/use-current-value.d.ts" | ||
], | ||
"use-listener": [ | ||
"./types/use-listener/use-listener.d.ts" | ||
], | ||
"use-click-coordinates": [ | ||
@@ -100,11 +105,2 @@ "./types/use-click-coordinates/use-click-coordinates.d.ts" | ||
], | ||
"use-drag": [ | ||
"./types/use-drag/use-drag.d.ts" | ||
], | ||
"use-force-render": [ | ||
"./types/use-force-render/use-force-render.d.ts" | ||
], | ||
"use-listener": [ | ||
"./types/use-listener/use-listener.d.ts" | ||
], | ||
"use-form": [ | ||
@@ -111,0 +107,0 @@ "./types/use-form/use-form.d.ts" |
import { useEffect } from "atomico"; | ||
import { useCurrentValue } from "../use-current-value/use-current-value"; | ||
import { addListener } from "../use-listener/use-listener"; | ||
/** | ||
* | ||
* @typedef {{x:number,y:number,offset:{x:number,y:number}}} Coordinates | ||
*/ | ||
/** | ||
* | ||
* @param {PointerEvent & TouchEvent} event | ||
* @returns {Coordinates|null} | ||
*/ | ||
export function getCoordinates(event) { | ||
if (event.isTrusted) { | ||
let x, y, offset; | ||
if (/touch/.test(event.type)) { | ||
let touch = event.touches[0]; | ||
if (!touch) return; | ||
x = touch.clientX; | ||
y = touch.clientY; | ||
} else { | ||
x = event.clientX; | ||
y = event.clientY; | ||
} | ||
if (/touch/.test(event.type)) { | ||
const rect = current.getBoundingClientRect(); | ||
let touch = event.touches[0]; | ||
offset = { | ||
x: touch.pageX - rect.left, | ||
y: touch.pageY - rect.top, | ||
}; | ||
} else { | ||
offset = { | ||
x: event.offsetX, | ||
y: event.offsetY, | ||
}; | ||
} | ||
return { offset, x, y }; | ||
} | ||
} | ||
/** | ||
* | ||
* @param {import("atomico").Ref} ref | ||
@@ -48,2 +10,4 @@ * @param {(coordinates:Coordinates)=>void} callback | ||
export function useClickCoordinates(ref, callback) { | ||
const value = useCurrentValue(callback); | ||
useEffect(() => { | ||
@@ -56,13 +20,54 @@ const { current } = ref; | ||
const coordinates = getCoordinates(event); | ||
coordinates && callback(coordinates); | ||
coordinates && value.current(coordinates); | ||
}; | ||
current.addEventListener("click", handler, true); | ||
current.addEventListener("touchstart", handler, true); | ||
const removeClick = addListener(current, "click", handler, true); | ||
const removeTouchstart = addListener(current, "touchstart", handler, true); | ||
return () => { | ||
current.removeEventListener("click", handler); | ||
current.removeEventListener("touchstart", handler); | ||
removeClick(); | ||
removeTouchstart(); | ||
}; | ||
}, [ref]); | ||
} | ||
/** | ||
* | ||
* @param {PointerEvent & TouchEvent} event | ||
* @returns {Coordinates|null} | ||
*/ | ||
export function getCoordinates(event) { | ||
if (!event.isTrusted) return; | ||
let x, y, offset; | ||
if (/touch/.test(event.type)) { | ||
let [touch] = event.touches; | ||
if (!touch) return; | ||
x = touch.clientX; | ||
y = touch.clientY; | ||
const rect = event.currentTarget.getBoundingClientRect(); | ||
offset = { | ||
x: touch.pageX - rect.left, | ||
y: touch.pageY - rect.top, | ||
}; | ||
} else { | ||
x = event.clientX; | ||
y = event.clientY; | ||
offset = { | ||
x: event.offsetX, | ||
y: event.offsetY, | ||
}; | ||
} | ||
return { offset, x, y }; | ||
} | ||
/** | ||
* | ||
* @typedef {{x:number,y:number,offset:{x:number,y:number}}} Coordinates | ||
*/ |
@@ -1,3 +0,3 @@ | ||
import { useLayoutEffect, useRef } from "atomico"; | ||
import { useLayoutEffect } from "atomico"; | ||
import { useCurrentValue } from "../use-current-value/use-current-value"; | ||
/** | ||
@@ -12,11 +12,21 @@ * @template {string} T | ||
export function useListener(ref, name, handler, options) { | ||
const scope = useRef(); | ||
scope.current = handler; | ||
const value = useCurrentValue(handler); | ||
useLayoutEffect(() => { | ||
const { current } = ref; | ||
if (!current) return; | ||
let handler = (event) => scope.current(event); | ||
current.addEventListener(name, handler, options); | ||
return () => current.removeEventListener(current, handler); | ||
return addListener(current, name, (event) => value.current(event), options); | ||
}, [name, !!handler]); | ||
} | ||
/** | ||
* Associate an event and return a callback to remove said event | ||
* @param {Element} current | ||
* @param {string} name | ||
* @param {(ev:any)=>any} handler | ||
* @param {boolean|AddEventListenerOptions} options | ||
* @returns {()=>void} | ||
*/ | ||
export function addListener(current, name, handler, options) { | ||
current.addEventListener(name, handler, options); | ||
return () => current.removeEventListener(name, handler); | ||
} |
import { useEffect, useState } from "atomico"; | ||
import { useCurrentValue } from "../use-current-value/use-current-value"; | ||
/** | ||
@@ -15,5 +16,8 @@ * create an instance of MutationObserver for the given reference | ||
export function useMutationObserver(ref, observe, config) { | ||
const value = useCurrentValue(observe); | ||
useEffect(() => { | ||
if (!ref.current) return; | ||
const observer = new MutationObserver(observe); | ||
const observer = new MutationObserver((mutations) => | ||
value.current(mutations) | ||
); | ||
observer.observe(ref.current, config); | ||
@@ -20,0 +24,0 @@ return () => observer.disconnect(); |
@@ -1,2 +0,3 @@ | ||
import { useEffect, useRef, useState } from "atomico"; | ||
import { useEffect, useState } from "atomico"; | ||
import { useCurrentValue } from "../use-current-value/use-current-value"; | ||
@@ -25,4 +26,3 @@ const listenersId = Symbol(); | ||
export function useResizeObserver(ref, callback) { | ||
const refCallback = useRef(); | ||
refCallback.current = callback; | ||
const value = useCurrentValue(callback); | ||
useEffect(() => { | ||
@@ -34,3 +34,4 @@ const { current } = ref; | ||
*/ | ||
const listener = (rect) => refCallback.current(rect); | ||
const listener = (rect) => value.current(rect); | ||
if (!current[listenersId]) { | ||
@@ -40,3 +41,5 @@ resizeObserver.observe(current); | ||
} | ||
current[listenersId].add(listener); | ||
return () => { | ||
@@ -43,0 +46,0 @@ current[listenersId].delete(listener); |
@@ -5,2 +5,3 @@ import { useState, useEffect } from "atomico"; | ||
export { redirect, getPath } from "./src/history.js"; | ||
import { addListener } from "../use-listener/use-listener"; | ||
@@ -97,4 +98,3 @@ /**@type {InternalState} */ | ||
}; | ||
current.addEventListener("click", handler); | ||
return () => current.removeEventListener("click", handler); | ||
return addListener(current, "click", handler); | ||
}, [ref]); | ||
@@ -101,0 +101,0 @@ } |
import { useState, useEffect, Mark } from "atomico"; | ||
import { addListener } from "../use-listener/use-listener"; | ||
/** | ||
@@ -23,4 +24,3 @@ * | ||
// listener and unlistener | ||
current.addEventListener(type, handler); | ||
return () => current.removeEventListener(type, handler); | ||
return addListener(current, "slotchange", handler); | ||
}, []); | ||
@@ -27,0 +27,0 @@ |
/** | ||
* | ||
* @typedef {{x:number,y:number,offset:{x:number,y:number}}} Coordinates | ||
* @param {import("atomico").Ref} ref | ||
* @param {(coordinates:Coordinates)=>void} callback | ||
*/ | ||
export function useClickCoordinates(ref: import("atomico").Ref, callback: (coordinates: Coordinates) => void): void; | ||
/** | ||
@@ -11,8 +13,2 @@ * | ||
export function getCoordinates(event: PointerEvent & TouchEvent): Coordinates | null; | ||
/** | ||
* | ||
* @param {import("atomico").Ref} ref | ||
* @param {(coordinates:Coordinates)=>void} callback | ||
*/ | ||
export function useClickCoordinates(ref: import("atomico").Ref, callback: (coordinates: Coordinates) => void): void; | ||
export type Coordinates = { | ||
@@ -19,0 +15,0 @@ x: number; |
@@ -10,1 +10,10 @@ /** | ||
export function useListener<T extends string, R extends import("atomico").Ref<HTMLElement>>(ref: R, name: T, handler: (ev: any) => any, options?: boolean | AddEventListenerOptions | undefined): void; | ||
/** | ||
* Associate an event and return a callback to remove said event | ||
* @param {Element} current | ||
* @param {string} name | ||
* @param {(ev:any)=>any} handler | ||
* @param {boolean|AddEventListenerOptions} options | ||
* @returns {()=>void} | ||
*/ | ||
export function addListener(current: Element, name: string, handler: (ev: any) => any, options: boolean | AddEventListenerOptions): () => void; |
60273
73
1789