@solid-primitives/mouse
Advanced tools
Comparing version
@@ -1,135 +0,3 @@ | ||
import { Position, MaybeAccessor } from '@solid-primitives/utils'; | ||
import { Accessor } from 'solid-js'; | ||
type MouseSourceType = "mouse" | "touch" | null; | ||
type MousePosition = Position & { | ||
sourceType: MouseSourceType; | ||
}; | ||
type MousePositionInside = MousePosition & { | ||
isInside: boolean; | ||
}; | ||
interface PositionRelativeToElement extends Position { | ||
top: number; | ||
left: number; | ||
width: number; | ||
height: number; | ||
isInside: boolean; | ||
} | ||
interface UseTouchOptions { | ||
/** | ||
* Listen to touch events. If enabled, position will be updated on `touchstart` event. | ||
* @default true | ||
*/ | ||
touch?: boolean; | ||
} | ||
interface FollowTouchOptions { | ||
/** | ||
* If enabled, position will be updated on `touchmove` event. | ||
* @default true | ||
*/ | ||
followTouch?: boolean; | ||
} | ||
/** | ||
* Attaches event listeners to provided targat, listeneing for changes to the mouse/touch position. | ||
* @param target | ||
* ```ts | ||
* SVGSVGElement | HTMLElement | Window | Document | ||
* ``` | ||
* @param callback function fired on every position change | ||
* @param options {@link UseTouchOptions} & {@link FollowTouchOptions} | ||
* @returns function removing all event listeners | ||
*/ | ||
declare function makeMousePositionListener(target: (SVGSVGElement | HTMLElement | Window | Document) | undefined, callback: (position: MousePosition) => void, options?: UseTouchOptions & FollowTouchOptions): VoidFunction; | ||
/** | ||
* Attaches event listeners to provided targat, listening for mouse/touch entering/leaving the element. | ||
* @param target | ||
* ```ts | ||
* SVGSVGElement | HTMLElement | Window | Document | ||
* ``` | ||
* @param callback function fired on mouse leaving or entering the element | ||
* @param options {@link UseTouchOptions} | ||
* @returns function removing all event listeners | ||
*/ | ||
declare function makeMouseInsideListener(target: (SVGSVGElement | HTMLElement | Window | Document) | undefined, callback: (isInside: boolean) => void, options?: UseTouchOptions): VoidFunction; | ||
/** | ||
* Turn position relative to the page, into position relative to an element. | ||
*/ | ||
declare const getPositionToElement: (pageX: number, pageY: number, el: Element) => PositionRelativeToElement; | ||
/** | ||
* Turn position relative to the page, into position relative to an element. Clamped to the element bounds. | ||
*/ | ||
declare const getPositionInElement: (pageX: number, pageY: number, el: Element) => PositionRelativeToElement; | ||
/** | ||
* Turn position relative to the page, into position relative to the screen. | ||
*/ | ||
declare const getPositionToScreen: (pageX: number, pageY: number) => Position; | ||
interface MousePositionOptions extends UseTouchOptions, FollowTouchOptions { | ||
/** | ||
* Initial values | ||
* @default { x: 0, y: 0, isInside: false, sourceType: null } | ||
*/ | ||
initialValue?: Partial<MousePositionInside>; | ||
} | ||
interface PositionToElementOptions extends UseTouchOptions, FollowTouchOptions { | ||
/** | ||
* Initial value | ||
* @default { x: 0, y: 0, top: 0, left: 0, width: 0, height: 0, isInside: false } | ||
*/ | ||
initialValue?: Partial<PositionRelativeToElement>; | ||
} | ||
/** | ||
* Attaches event listeners to {@link target} element to provide a reactive object of current mouse position on the page. | ||
* @param target (Defaults to `window`) element to attach the listeners to – can be a reactive function | ||
* @param options {@link MousePositionOptions} | ||
* @returns reactive object of current mouse position on the page | ||
* ```ts | ||
* { x: number, y: number, sourceType: MouseSourceType, isInside: boolean } | ||
* ``` | ||
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/mouse#createmouseposition | ||
* @example | ||
* const [el, setEl] = createSignal(ref) | ||
* const pos = createMousePosition(el, { touch: false }) | ||
* createEffect(() => { | ||
* console.log(pos.x, pos.y) | ||
* }) | ||
*/ | ||
declare function createMousePosition(target?: MaybeAccessor<SVGSVGElement | HTMLElement | Window | Document>, options?: MousePositionOptions): MousePositionInside; | ||
/** | ||
* Attaches event listeners to `window` to provide a reactive object of current mouse position on the page. | ||
* | ||
* This is a [singleton root primitive](https://github.com/solidjs-community/solid-primitives/tree/main/packages/rootless#createSingletonRoot). | ||
* @returns reactive object of current mouse position on the page | ||
* ```ts | ||
* { x: number, y: number, sourceType: MouseSourceType, isInside: boolean } | ||
* ``` | ||
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/mouse#useMousePosition | ||
* @example | ||
* const pos = useMousePosition() | ||
* createEffect(() => { | ||
* console.log(pos.x, pos.y) | ||
* }) | ||
*/ | ||
declare const useMousePosition: () => MousePositionInside; | ||
/** | ||
* Provides an autoupdating position relative to an element based on provided page position. | ||
* | ||
* @param element target `Element` used in calculations | ||
* @param pos reactive function returning page position *(relative to the page not window)* | ||
* @param options {@link PositionToElementOptions} | ||
* @returns Autoupdating position relative to top-left of the target + current bounds of the element. | ||
* | ||
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/mouse#createPositionToElement | ||
* | ||
* @example | ||
* const [el, setEl] = createSignal(ref) | ||
* const pos = useMousePosition() | ||
* const relative = createPositionToElement(el, () => pos) | ||
* createEffect(() => { | ||
* console.log(relative.x, relative.y) | ||
* }) | ||
*/ | ||
declare function createPositionToElement(element: Element | Accessor<Element | undefined>, pos: Accessor<Position>, options?: PositionToElementOptions): PositionRelativeToElement; | ||
export { type FollowTouchOptions, type MousePosition, type MousePositionInside, type MousePositionOptions, type MouseSourceType, type PositionRelativeToElement, type PositionToElementOptions, type UseTouchOptions, createMousePosition, createPositionToElement, getPositionInElement, getPositionToElement, getPositionToScreen, makeMouseInsideListener, makeMousePositionListener, useMousePosition }; | ||
export * from "./types.js"; | ||
export { makeMousePositionListener, makeMouseInsideListener, getPositionToElement, getPositionToScreen, getPositionInElement, } from "./common.js"; | ||
export * from "./primitives.js"; |
@@ -1,133 +0,3 @@ | ||
import { makeEventListenerStack } from '@solid-primitives/event-listener'; | ||
import { noop, clamp, asAccessor } from '@solid-primitives/utils'; | ||
import { isServer } from 'solid-js/web'; | ||
import { createHydratableSingletonRoot } from '@solid-primitives/rootless'; | ||
import { createStaticStore, createDerivedStaticStore } from '@solid-primitives/static-store'; | ||
import { createEffect, sharedConfig, createSignal, onMount } from 'solid-js'; | ||
// src/common.ts | ||
var PASSIVE = { passive: true }; | ||
var DEFAULT_MOUSE_POSITION = { | ||
x: 0, | ||
y: 0, | ||
isInside: false, | ||
sourceType: null | ||
}; | ||
var DEFAULT_RELATIVE_ELEMENT_POSITION = { | ||
x: 0, | ||
y: 0, | ||
top: 0, | ||
left: 0, | ||
width: 0, | ||
height: 0, | ||
isInside: true | ||
}; | ||
function makeMousePositionListener(target = window, callback, options = {}) { | ||
if (isServer) { | ||
return noop; | ||
} | ||
const { touch = true, followTouch = true } = options; | ||
const [listen, clear] = makeEventListenerStack(target, PASSIVE); | ||
const handleMouse = (e) => callback({ x: e.pageX, y: e.pageY, sourceType: "mouse" }); | ||
listen("mousemove", handleMouse); | ||
listen("dragover", handleMouse); | ||
if (touch) { | ||
const handleTouch = (e) => { | ||
if (e.touches.length) | ||
callback({ x: e.touches[0].clientX, y: e.touches[0].clientY, sourceType: "touch" }); | ||
}; | ||
listen("touchstart", handleTouch); | ||
if (followTouch) listen("touchmove", handleTouch); | ||
} | ||
return clear; | ||
} | ||
function makeMouseInsideListener(target = window, callback, options = {}) { | ||
if (isServer) { | ||
return noop; | ||
} | ||
const { touch = true } = options; | ||
const [listen, clear] = makeEventListenerStack(target, PASSIVE); | ||
let mouseIn = false; | ||
let touchIn = !touch; | ||
function handleChange(isInside) { | ||
this === "mouse" ? mouseIn = isInside : touchIn = isInside; | ||
callback(mouseIn || touchIn); | ||
} | ||
listen("mouseover", handleChange.bind("mouse", true)); | ||
listen("mouseout", handleChange.bind("mouse", false)); | ||
listen("mousemove", handleChange.bind("mouse", true), { passive: true, once: true }); | ||
if (touch) { | ||
listen("touchstart", handleChange.bind("touch", true)); | ||
listen("touchend", handleChange.bind("touch", false)); | ||
} | ||
return clear; | ||
} | ||
var getPositionToElement = (pageX, pageY, el) => { | ||
if (isServer) { | ||
return DEFAULT_RELATIVE_ELEMENT_POSITION; | ||
} | ||
const bounds = el.getBoundingClientRect(), top = bounds.top + window.scrollY, left = bounds.left + window.scrollX, x = pageX - left, y = pageY - top, { width, height } = bounds; | ||
return { | ||
x, | ||
y, | ||
top, | ||
left, | ||
width, | ||
height, | ||
isInside: x >= 0 && y >= 0 && x <= width && y <= height | ||
}; | ||
}; | ||
var getPositionInElement = (pageX, pageY, el) => { | ||
if (isServer) { | ||
return DEFAULT_RELATIVE_ELEMENT_POSITION; | ||
} | ||
const relative = getPositionToElement(pageX, pageY, el); | ||
return { | ||
...relative, | ||
x: clamp(relative.x, 0, relative.width), | ||
y: clamp(relative.y, 0, relative.height) | ||
}; | ||
}; | ||
var getPositionToScreen = isServer ? () => DEFAULT_MOUSE_POSITION : (pageX, pageY) => ({ | ||
x: pageX - window.scrollX, | ||
y: pageY - window.screenY | ||
}); | ||
function createMousePosition(target, options = {}) { | ||
const fallback = { | ||
...DEFAULT_MOUSE_POSITION, | ||
...options.initialValue | ||
}; | ||
if (isServer) { | ||
return fallback; | ||
} | ||
const [state, setState] = createStaticStore(fallback); | ||
const attachListeners = (el) => { | ||
makeMousePositionListener(el, setState, options); | ||
makeMouseInsideListener(el, setState.bind(void 0, "isInside"), options); | ||
}; | ||
if (typeof target !== "function") attachListeners(target); | ||
else createEffect(() => attachListeners(target())); | ||
return state; | ||
} | ||
var useMousePosition = /* @__PURE__ */ createHydratableSingletonRoot( | ||
createMousePosition.bind(void 0, void 0, void 0) | ||
); | ||
function createPositionToElement(element, pos, options = {}) { | ||
const fallback = { | ||
...DEFAULT_RELATIVE_ELEMENT_POSITION, | ||
...options.initialValue | ||
}; | ||
if (isServer) { | ||
return fallback; | ||
} | ||
const isFn = typeof element === "function", isHydrating = sharedConfig.context, getEl = asAccessor(element), [shouldFallback, setShouldFallback] = createSignal(!!isHydrating, { equals: false }); | ||
if (isHydrating || isFn) onMount(() => setShouldFallback(false)); | ||
return createDerivedStaticStore(() => { | ||
let el; | ||
if (shouldFallback() || !(el = getEl())) return fallback; | ||
const { x, y } = pos(); | ||
return getPositionToElement(x, y, el); | ||
}); | ||
} | ||
export { createMousePosition, createPositionToElement, getPositionInElement, getPositionToElement, getPositionToScreen, makeMouseInsideListener, makeMousePositionListener, useMousePosition }; | ||
export * from "./types.js"; | ||
export { makeMousePositionListener, makeMouseInsideListener, getPositionToElement, getPositionToScreen, getPositionInElement, } from "./common.js"; | ||
export * from "./primitives.js"; |
{ | ||
"name": "@solid-primitives/mouse", | ||
"version": "2.0.21", | ||
"version": "2.1.0", | ||
"description": "A collection of Solid Primitives, that capture current mouse cursor position, and help to deal with common related usecases.", | ||
@@ -24,3 +24,2 @@ "author": "Damian Tarnawski <gthetarnav@gmail.com>", | ||
"type": "module", | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.js", | ||
@@ -34,6 +33,2 @@ "types": "./dist/index.d.ts", | ||
"default": "./dist/index.js" | ||
}, | ||
"require": { | ||
"types": "./dist/index.d.cts", | ||
"default": "./dist/index.cjs" | ||
} | ||
@@ -53,9 +48,9 @@ }, | ||
"solid-js": "^1.8.7", | ||
"@solid-primitives/raf": "^2.2.0" | ||
"@solid-primitives/raf": "^2.3.0" | ||
}, | ||
"dependencies": { | ||
"@solid-primitives/event-listener": "^2.3.3", | ||
"@solid-primitives/rootless": "^1.4.5", | ||
"@solid-primitives/static-store": "^0.0.9", | ||
"@solid-primitives/utils": "^6.2.3" | ||
"@solid-primitives/event-listener": "^2.4.0", | ||
"@solid-primitives/static-store": "^0.1.0", | ||
"@solid-primitives/utils": "^6.3.0", | ||
"@solid-primitives/rootless": "^1.5.0" | ||
}, | ||
@@ -62,0 +57,0 @@ "peerDependencies": { |
@@ -7,3 +7,2 @@ <p> | ||
[](https://turborepo.org/) | ||
[](https://bundlephobia.com/package/@solid-primitives/mouse) | ||
@@ -10,0 +9,0 @@ [](https://www.npmjs.com/package/@solid-primitives/mouse) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
11
57.14%23548
-21.44%363
-8.79%188
-0.53%1
Infinity%+ Added
- Removed