@solid-primitives/event-listener
Advanced tools
Comparing version 1.2.6 to 1.3.2
@@ -1,80 +0,147 @@ | ||
import { Accessor, JSX } from "solid-js"; | ||
import { MaybeAccessor, Many } from '@solid-primitives/utils'; | ||
import { JSX, Accessor, Component } from 'solid-js'; | ||
import { Store } from 'solid-js/store'; | ||
declare type EventMapOf<T> = T extends Window | ||
? WindowEventMap | ||
: T extends Document | ||
? DocumentEventMap | ||
: T extends HTMLElement | ||
? HTMLElementEventMap | ||
: T extends MediaQueryList | ||
? MediaQueryListEventMap | ||
: {}; | ||
declare type EventMapOfMultiple<T> = T extends EventTarget | ||
? EventMapOf<T> | ||
: T extends EventTarget[] | ||
? EventMapOf<T[number]> | ||
: never; | ||
declare type EventListenerProps< | ||
T extends EventTarget | EventTarget[], | ||
E extends Record<string, Event> = {} | ||
> = [ | ||
name: [{}, {}] extends [EventMapOfMultiple<T>, E] | ||
? string | ||
: string & (keyof EventMapOfMultiple<T> | keyof E), | ||
handler: EventListenerOrEventListenerObject | null, | ||
options?: AddEventListenerOptions | ||
declare type TargetWithEventMap = Window | Document | HTMLElement | MediaQueryList; | ||
declare type EventMapOf<Target> = Target extends Window ? WindowEventMap : Target extends Document ? DocumentEventMap : Target extends HTMLElement ? HTMLElementEventMap : Target extends MediaQueryList ? MediaQueryListEventMap : never; | ||
declare type EventListenerDirectiveProps = [ | ||
name: string, | ||
handler: (e: any) => void, | ||
options?: AddEventListenerOptions | boolean | ||
]; | ||
declare type CreateEventListenerReturn = [ | ||
add: (el: EventTarget) => void, | ||
remove: (el: EventTarget) => void | ||
]; | ||
declare type EventListenerMapDirectiveProps = [handlerMap: Record<string, (e: any) => void>, options?: AddEventListenerOptions | boolean] | Record<string, (e: any) => void>; | ||
declare module "solid-js" { | ||
namespace JSX { | ||
interface Directives { | ||
createEventListener: ( | ||
ref: HTMLElement, | ||
props: Accessor<EventListenerProps<HTMLElement, {}>> | ||
) => [add: (target: EventTarget) => void, remove: (target: EventTarget) => void]; | ||
namespace JSX { | ||
interface Directives { | ||
eventListener: EventListenerDirectiveProps; | ||
eventListenerMap: EventListenerMapDirectiveProps; | ||
} | ||
} | ||
} | ||
} | ||
declare type E = JSX.Element; | ||
declare type CreateEventListenerFn = < | ||
EventMap extends Record<string, Event>, | ||
Target extends EventTarget | EventTarget[] | ||
>( | ||
target: Target, | ||
...props: [Accessor<EventListenerProps<Target, EventMap>>] | EventListenerProps<Target, EventMap> | ||
) => CreateEventListenerReturn; | ||
/** | ||
* Creates an event listener helper primitive. | ||
* Creates an event listener, that will be automatically disposed on cleanup. | ||
* | ||
* @param target - ref to HTMLElement, EventTarget or Array thereof | ||
* @param nameOrProps - name of the event or Accessor with the event props ([name, handler, options?]) | ||
* @param handler - if nameOrProps contains a name, you can specify the handler here | ||
* @param options - if nameOrProps contains a name, you can specify event listener options | ||
* @param eventName - name of the handled event | ||
* @param handler - event handler | ||
* @param options - addEventListener options | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener | ||
* @see https://github.com/davedbase/solid-primitives/tree/main/packages/event-listener#createEventListener | ||
* | ||
* @example | ||
* ```tsx | ||
* const [add, remove] = createEventListener( | ||
* document.getElementById("mybutton"), | ||
* "mouseDown", | ||
* () => console.log("Click") | ||
* ); | ||
* // or as a directive | ||
* <MyButton use:createEventListener={() => ['click', () => console.log("Click")]}>Click!</MyButton> | ||
* // you can provide your own event map type: | ||
* createEventListener<{ myCustomEvent: Event }, Window>(window, 'myCustomEvent', () => console.log("yup!")); | ||
* ``` | ||
* createEventListener(element, 'click', e => { ... }, { passive: true }) | ||
*/ | ||
declare const createEventListener: CreateEventListenerFn; | ||
declare function createEventListener<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventName extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, eventName: MaybeAccessor<EventName>, handler: (event: EventMap[EventName]) => void, options?: MaybeAccessor<boolean | AddEventListenerOptions>): void; | ||
declare function createEventListener<EventMap extends Record<string, Event>, EventName extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, eventName: MaybeAccessor<EventName>, handler: (event: EventMap[EventName]) => void, options?: MaybeAccessor<boolean | AddEventListenerOptions>): void; | ||
/** | ||
* Provides an reactive signal of last captured event. | ||
* | ||
* @param target - ref to HTMLElement, EventTarget or Array thereof | ||
* @param eventName - name of the handled event | ||
* @param options - addEventListener options | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener | ||
* @see https://github.com/davedbase/solid-primitives/tree/main/packages/event-listener#createEventSignal | ||
* | ||
* @example | ||
* const lastEvent = createEventSignal(el, 'click', { passive: true }) | ||
*/ | ||
declare function createEventSignal<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventName extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, eventName: MaybeAccessor<EventName>, options?: MaybeAccessor<boolean | AddEventListenerOptions>): Accessor<EventMap[EventName] | undefined>; | ||
declare function createEventSignal<EventMap extends Record<string, Event>, EventName extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, eventName: MaybeAccessor<EventName>, options?: MaybeAccessor<boolean | AddEventListenerOptions>): Accessor<EventMap[EventName] | undefined>; | ||
/** | ||
* Directive Usage. Creates an event listener, that will be automatically disposed on cleanup. | ||
* | ||
* @param props [eventName, eventHandler, options] | ||
* | ||
* @example | ||
* <button use:eventListener={["click", () => {...}]}>Click me!</button> | ||
*/ | ||
declare function eventListener(target: Element, props: Accessor<EventListenerDirectiveProps>): void; | ||
export { | ||
CreateEventListenerReturn, | ||
E, | ||
EventListenerProps, | ||
EventMapOf, | ||
EventMapOfMultiple, | ||
createEventListener, | ||
createEventListener as default | ||
declare type EventHandlersMap<EventMap> = { | ||
[EventName in keyof EventMap]: (event: EventMap[EventName]) => void; | ||
}; | ||
/** | ||
* A helpful primitive that listens to a map of events. Handle them by individual callbacks. | ||
* | ||
* @param target accessor or variable of multiple or single event targets | ||
* @param handlersMap e.g. `{ mousemove: e => {}, click: e => {} }` | ||
* @param options e.g. `{ passive: true }` | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener | ||
* @see https://github.com/davedbase/solid-primitives/tree/main/packages/event-listener#createEventListenerMap | ||
* | ||
* @example | ||
* createEventListenerMap(element, { | ||
* mousemove: mouseHandler, | ||
* mouseenter: e => {}, | ||
* touchend: touchHandler | ||
* }); | ||
*/ | ||
declare function createEventListenerMap<EventMap extends Record<string, Event>, UsedEvents extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, handlersMap: Partial<Pick<EventHandlersMap<EventMap>, UsedEvents>>, options?: MaybeAccessor<boolean | AddEventListenerOptions>): void; | ||
declare function createEventListenerMap<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, HandlersMap extends Partial<EventHandlersMap<EventMap>>>(target: MaybeAccessor<Many<Target>>, handlersMap: HandlersMap, options?: MaybeAccessor<boolean | AddEventListenerOptions>): void; | ||
/** | ||
* A helpful primitive that listens to target events and provides a reactive store with the latest captured events. | ||
* | ||
* @param target accessor or variable of multiple or single event targets | ||
* @param options e.g. `{ passive: true }` *(can be omited)* | ||
* @param eventNames names of events you want to listen to, e.g. `"mousemove", "touchend", "click"` | ||
* | ||
* @returns reactive store with the latest captured events | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener | ||
* @see https://github.com/davedbase/solid-primitives/tree/main/packages/event-listener#createEventStore | ||
* | ||
* @example | ||
* const lastEvents = createEventStore(el, "mousemove", "touchend", "click"); | ||
* | ||
* createEffect(() => { | ||
* console.log(lastEvents.mousemove.x) | ||
* }) | ||
*/ | ||
declare function createEventStore<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, UsedEvents extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, ...eventNames: UsedEvents[]): Store<Partial<Pick<EventMap, UsedEvents>>>; | ||
declare function createEventStore<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, UsedEvents extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, options: MaybeAccessor<boolean | AddEventListenerOptions>, ...eventNames: UsedEvents[]): Store<Partial<Pick<EventMap, UsedEvents>>>; | ||
declare function createEventStore<EventMap extends Record<string, Event>, UsedEvents extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, ...eventNames: UsedEvents[]): Store<Partial<Pick<EventMap, UsedEvents>>>; | ||
declare function createEventStore<EventMap extends Record<string, Event>, UsedEvents extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, options: MaybeAccessor<boolean | AddEventListenerOptions>, ...eventNames: UsedEvents[]): Store<Partial<Pick<EventMap, UsedEvents>>>; | ||
/** | ||
* Directive Usage. A helpful primitive that listens to provided events. Handle them by callbacks. | ||
* | ||
* @param props [handlerMap, options] | handlerMap | ||
* - **handlerMap**: e.g. `{ mousemove: e => {}, click: e => {} }` | ||
* - **options** e.g. `{ passive: true }` | ||
* | ||
* @example | ||
* <div use:eventListenerMap={{ | ||
* mousemove: e => {}, | ||
* click: clickHandler, | ||
* touchstart: () => {} | ||
* }}></div> | ||
*/ | ||
declare function eventListenerMap(target: Element, getProps: Accessor<EventListenerMapDirectiveProps>): void; | ||
declare type EventAttributes<T> = { | ||
[K in keyof JSX.DOMAttributes<T>]: `${K}` extends `on${string}` ? JSX.DOMAttributes<T>[K] : never; | ||
}; | ||
/** | ||
* Listen to the `window` DOM Events, using a component. | ||
* | ||
* @see https://github.com/davedbase/solid-primitives/tree/main/packages/event-listener#WindowEventListener | ||
* | ||
* @example | ||
* <WindowEventListener onMouseMove={e => console.log(e.x, e.y)} /> | ||
*/ | ||
declare const WindowEventListener: Component<EventAttributes<null>>; | ||
/** | ||
* Listen to the `document` DOM Events, using a component. | ||
* | ||
* @see https://github.com/davedbase/solid-primitives/tree/main/packages/event-listener#DocumentEventListener | ||
* | ||
* @example | ||
* <DocumentEventListener onMouseMove={e => console.log(e.x, e.y)} /> | ||
*/ | ||
declare const DocumentEventListener: Component<EventAttributes<null>>; | ||
export { DocumentEventListener, E, EventHandlersMap, EventListenerDirectiveProps, EventListenerMapDirectiveProps, EventMapOf, TargetWithEventMap, WindowEventListener, createEventListener, createEventListenerMap, createEventSignal, createEventStore, eventListener, eventListenerMap }; |
@@ -1,33 +0,122 @@ | ||
// src/index.ts | ||
// src/eventListener.ts | ||
import { | ||
access, | ||
createCallbackStack, | ||
isClient, | ||
forEach | ||
} from "@solid-primitives/utils"; | ||
import { createSignal } from "solid-js"; | ||
import { createEffect, onCleanup } from "solid-js"; | ||
var createEventListener = (target, ...propsArray) => { | ||
const targets = Array.isArray(target) ? target : [target]; | ||
const props = typeof propsArray[0] === "function" ? propsArray[0] : () => propsArray; | ||
const add = target2 => { | ||
targets.includes(target2) || targets.push(target2); | ||
const [name, handler, options] = props(); | ||
if (name && handler !== void 0) { | ||
target2.addEventListener.apply(target2, props()); | ||
} | ||
}; | ||
const remove = target2 => { | ||
targets.forEach((t, index) => t === target2 && targets.splice(index, 1)); | ||
target2.removeEventListener.apply(target2, props()); | ||
}; | ||
targets.forEach(add); | ||
createEffect(previousProps => { | ||
const currentProps = props(); | ||
if (previousProps !== currentProps) { | ||
previousProps && | ||
targets.forEach(target2 => target2.removeEventListener.apply(target2, previousProps)); | ||
targets.forEach(add); | ||
} | ||
return currentProps; | ||
}, props()); | ||
onCleanup(() => { | ||
targets.forEach(remove); | ||
function createEventListener(targets, eventName, handler, options) { | ||
if (!isClient) | ||
return; | ||
const toCleanup = createCallbackStack(); | ||
createEffect(() => { | ||
toCleanup.execute(); | ||
const _eventName = access(eventName); | ||
const _options = access(options); | ||
forEach(targets, (el) => { | ||
if (!el) | ||
return; | ||
el.addEventListener(_eventName, handler, _options); | ||
toCleanup.push(() => el.removeEventListener(_eventName, handler, _options)); | ||
}); | ||
}); | ||
return [add, remove]; | ||
onCleanup(toCleanup.execute); | ||
} | ||
function createEventSignal(target, eventName, options) { | ||
const [lastEvent, setLastEvent] = createSignal(); | ||
createEventListener(target, eventName, setLastEvent, options); | ||
return lastEvent; | ||
} | ||
function eventListener(target, props) { | ||
const toCleanup = createCallbackStack(); | ||
createEffect(() => { | ||
toCleanup.execute(); | ||
const [eventName, handler, options] = props(); | ||
target.addEventListener(eventName, handler, options); | ||
toCleanup.push(() => target.removeEventListener(eventName, handler, options)); | ||
}); | ||
onCleanup(toCleanup.execute); | ||
} | ||
// src/eventListenerMap.ts | ||
import { entries, createCallbackStack as createCallbackStack2 } from "@solid-primitives/utils"; | ||
import { createEffect as createEffect2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js"; | ||
function createEventListenerMap(targets, handlersMap, options) { | ||
entries(handlersMap).forEach(([eventName, handler]) => { | ||
createEventListener(targets, eventName, (e) => handler == null ? void 0 : handler(e), options); | ||
}); | ||
} | ||
function createEventStore(targets, ...rest) { | ||
let options = void 0; | ||
let names; | ||
if (typeof rest[0] === "string") | ||
names = rest; | ||
else { | ||
const [_options, ..._events] = rest; | ||
options = _options; | ||
names = _events; | ||
} | ||
const store = {}; | ||
names.forEach((eventName) => { | ||
const [accessor, setter] = createSignal2(); | ||
Object.defineProperty(store, eventName, { get: accessor, set: setter, enumerable: true }); | ||
createEventListener(targets, eventName, setter, options); | ||
}); | ||
return store; | ||
} | ||
function eventListenerMap(target, getProps) { | ||
const toCleanup = createCallbackStack2(); | ||
createEffect2(() => { | ||
toCleanup.execute(); | ||
let handlersMap; | ||
let options; | ||
const props = getProps(); | ||
if (Array.isArray(props)) { | ||
handlersMap = props[0]; | ||
options = props[1]; | ||
} else | ||
handlersMap = props; | ||
entries(handlersMap).forEach(([eventName, handler]) => { | ||
target.addEventListener(eventName, handler, options); | ||
toCleanup.push(() => target.removeEventListener(eventName, handler, options)); | ||
}); | ||
}); | ||
onCleanup2(toCleanup.execute); | ||
} | ||
// src/components.ts | ||
import { isClient as isClient2 } from "@solid-primitives/utils"; | ||
var forEachEventAttr = (props, fn) => { | ||
Object.keys(props).forEach((attr) => { | ||
if (!attr.startsWith("on")) | ||
return; | ||
const eventName = attr.substring(2).toLowerCase(); | ||
fn(eventName, attr); | ||
}); | ||
}; | ||
var src_default = createEventListener; | ||
export { createEventListener, src_default as default }; | ||
var WindowEventListener = (props) => { | ||
if (isClient2) | ||
forEachEventAttr(props, (eventName, attr) => { | ||
createEventListener(window, eventName, (e) => props[attr](e)); | ||
}); | ||
return void 0; | ||
}; | ||
var DocumentEventListener = (props) => { | ||
if (isClient2) | ||
forEachEventAttr(props, (eventName, attr) => { | ||
createEventListener(document, eventName, (e) => props[attr](e)); | ||
}); | ||
return void 0; | ||
}; | ||
export { | ||
DocumentEventListener, | ||
WindowEventListener, | ||
createEventListener, | ||
createEventListenerMap, | ||
createEventSignal, | ||
createEventStore, | ||
eventListener, | ||
eventListenerMap | ||
}; |
{ | ||
"name": "@solid-primitives/event-listener", | ||
"version": "1.2.6", | ||
"version": "1.3.2", | ||
"description": "Primitive to manage creating event listeners.", | ||
@@ -16,20 +16,21 @@ "author": "David Di Biase <dave.dibiase@gmail.com>", | ||
"list": [ | ||
"createEventListener" | ||
"createEventListener", | ||
"GlobalEventListener" | ||
], | ||
"category": "Browser APIs" | ||
}, | ||
"private": false, | ||
"sideEffects": false, | ||
"type": "module", | ||
"main": "dist/index.cjs", | ||
"module": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
"files": [ | ||
"dist" | ||
], | ||
"private": false, | ||
"sideEffects": false, | ||
"type": "module", | ||
"main": "./dist/index.cjs", | ||
"module": "./dist/index.js", | ||
"types": "./dist/index.d.ts", | ||
"scripts": { | ||
"prebuild": "npm run clean", | ||
"clean": "rimraf dist/", | ||
"start": "vite -r ./dev/ -c ./dev/vite.config.ts", | ||
"build": "tsup", | ||
"test": "uvu -r solid-register" | ||
"test": "uvu -r solid-register", | ||
"watch-test": "watchlist src test -- npm test" | ||
}, | ||
@@ -43,13 +44,19 @@ "keywords": [ | ||
"devDependencies": { | ||
"jsdom": "^18.1.1", | ||
"jsdom": "^19.0.0", | ||
"prettier": "^2.5.0", | ||
"solid-register": "^0.1.1", | ||
"solid-register": "0.0.18", | ||
"tslib": "^2.3.1", | ||
"tsup": "^5.10.1", | ||
"typescript": "^4.5.2", | ||
"uvu": "^0.5.2" | ||
"tsup": "^5.10.0", | ||
"unocss": "^0.12.4", | ||
"uvu": "^0.5.2", | ||
"vite": "2.6.14", | ||
"vite-plugin-solid": "2.1.2", | ||
"watchlist": "^0.3.1" | ||
}, | ||
"peerDependencies": { | ||
"solid-js": "^1.2.5" | ||
}, | ||
"dependencies": { | ||
"@solid-primitives/utils": "^0.0.255" | ||
} | ||
} |
247
README.md
@@ -9,2 +9,9 @@ # @solid-primitives/event-listener | ||
- [`createEventListener`](#createEventListener) - Very basic and straightforward primitive that handles multiple elements according to a single event binding. | ||
- [`createEventSignal`](#createEventListener) - Like `createEventListener`, but events are handled with the returned signal, instead of with a callback. | ||
- [`createEventListenerMap`](#createEventListenerMap) - A helpful primitive that listens to a map of events. Handle them by individual callbacks. | ||
- [`createEventStore`](#createEventStore) - Similar to `createEventListenerMap`, but provides a reactive store with the latest captured events. | ||
- [`WindowEventListener`](#WindowEventListener) - Listen to the `window` DOM Events, using a component. | ||
- [`DocumentEventListener`](#DocumentEventListener) - The same as [`WindowEventListener`](#WindowEventListener), but listens to `document` events. | ||
## Installation | ||
@@ -18,25 +25,240 @@ | ||
## How to use it | ||
## `createEventListener` | ||
### createEventListener | ||
Can be used to listen to DOM or Custom Events on window, document, list of HTML elements or any EventTarget. The target prop can be reactive. | ||
A very straightforward primitive that handles multiple elements according to a single event binding. | ||
### How to use it | ||
```ts | ||
const [add, remove] = createEventListener(document.getElementById("mybutton"), "mouseDown", () => | ||
console.log("Click") | ||
import { createEventListener } from "@solid-primitives/event-listener"; | ||
createEventListener( | ||
document.getElementById("mybutton"), | ||
"mousemove", | ||
e => console.log("x:", e.pageX, "y:", e.pageY), | ||
{ passive: true } | ||
); | ||
``` | ||
### Directive | ||
// target element, event name and options can be reactive signals | ||
const [ref, setRef] = createSignal<HTMLElement>(); | ||
const [name, setName] = createSignal("mousemove"); | ||
const [options, setOptions] = createSignal({ passive: true }); | ||
createEventListener(ref, name, e => {}, options); | ||
```ts | ||
<MyButton use:createEventListener={() => ["click", () => console.log("Click")]}>Click!</MyButton>; | ||
// you can provide your own event map type as well: | ||
createEventListener<{ myCustomEvent: Event }>(window, "myCustomEvent", () => console.log("yup!")); | ||
// just don't use interfaces as EventMaps! | ||
``` | ||
### Directive Usage | ||
props passed to the directive are also reactive, so you can change handlers on the fly. | ||
```tsx | ||
import { eventListener } from "@solid-primitives/event-listener"; | ||
// avoids tree-shaking the directive: | ||
eventListener; | ||
<button use:eventListener={["click", () => console.log("Click")]}>Click!</button>; | ||
``` | ||
### Types | ||
```ts | ||
function createEventListener< | ||
EventMap extends Record<string, Event>, | ||
EventName extends keyof EventMap | ||
>( | ||
target: MaybeAccessor<Many<EventTarget>>, | ||
eventName: MaybeAccessor<EventName>, | ||
handler: (event: EventMap[EventName]) => void, | ||
options?: MaybeAccessor<boolean | AddEventListenerOptions> | ||
): void; | ||
// Directive | ||
function eventListener( | ||
target: Element, | ||
props: Accessor<EventListenerDirectiveProps> | ||
): EventListenerReturn; | ||
type EventListenerDirectiveProps = [ | ||
name: string, | ||
handler: (e: any) => void, | ||
options?: AddEventListenerOptions | boolean | ||
]; | ||
``` | ||
## `createEventSignal` | ||
Like [`createEventListener`](#createEventListener), but events are handled with the returned signal, instead of with a callback. | ||
### How to use it | ||
```ts | ||
import { createEventSignal } from "@solid-primitives/event-listener"; | ||
// all arguments can be reactive signals | ||
const lastEvent = createEventSignal(el, "mousemove", { passive: true }); | ||
createEffect(() => { | ||
console.log(lastEvent()?.x, lastEvent()?.y); | ||
}); | ||
``` | ||
## `createEventListenerMap` | ||
A helpful primitive that listens to a map of events. Handle them by individual callbacks. | ||
### How to use it | ||
```ts | ||
import { createEventListenerMap } from "@solid-primitives/event-listener"; | ||
createEventListenerMap(element, { | ||
mousemove: mouseHandler, | ||
mouseenter: e => {}, | ||
touchend: touchHandler | ||
}); | ||
// both target and options args can be reactive: | ||
const [target, setTarget] = createSignal(document.getElementById("abc")); | ||
const [options, setOptions] = createSignal({ passive: true }); | ||
createEventListenerMap( | ||
target, | ||
{ | ||
mousemove: e => {}, | ||
touchstart: e => {} | ||
}, | ||
options | ||
); | ||
// createEventListenerMap can be used to listen to custom events | ||
createEventListenerMap< | ||
{ | ||
myEvent: MyEvent; | ||
custom: Event; | ||
other: Event; | ||
}, | ||
"myEvent" | "custom" | ||
>(target, { | ||
myEvent: e => {}, | ||
custom: e => {} | ||
}); | ||
``` | ||
### Directive usage | ||
```tsx | ||
import { eventListenerMap } from "@solid-primitives/event-listener"; | ||
// prevent tree-shaking: | ||
eventListenerMap; | ||
<div | ||
use:eventListenerMap={{ | ||
mousemove: e => {}, | ||
click: clickHandler, | ||
touchstart: () => {}, | ||
myCustomEvent: e => {} | ||
}} | ||
></div>; | ||
``` | ||
### Types | ||
```ts | ||
function createEventListenerMap< | ||
EventMap extends Record<string, Event>, | ||
UsedEvents extends keyof EventMap = keyof EventMap | ||
>( | ||
target: MaybeAccessor<Many<EventTarget>>, | ||
handlersMap: EventHandlersMap, | ||
options?: MaybeAccessor<boolean | AddEventListenerOptions> | ||
): void; | ||
``` | ||
## `createEventStore` | ||
Similar to [`createEventListenerMap`](#createEventListenerMap), but provides a reactive store with the latest captured events. | ||
### How to use it | ||
```ts | ||
const lastEvents = createEventStore(el, "mousemove", "touchend", "click"); | ||
createEffect(() => { | ||
console.log(lastEvents?.mousemove.x); | ||
}); | ||
// both target and options args can be reactive: | ||
const [target, setTarget] = createSignal(document.getElementById("abc")); | ||
const [options, setOptions] = createSignal({ passive: true }); | ||
const lastEvents = createEventStore(target, options, "mousemove", "touchmove"); | ||
// createEventStore can be used to listen to custom events | ||
const lastEvents = createEventStore< | ||
{ | ||
myEvent: MyEvent; | ||
custom: Event; | ||
}, | ||
"myEvent" | "custom" | ||
>(target, "myEvent", "custom"); | ||
// DON'T DO THIS: | ||
const { mousemove } = createEventStore(target, "mousemove", ...); | ||
// the store cannot be destructured | ||
``` | ||
### types | ||
```ts | ||
function createEventStore< | ||
EventMap extends Record<string, Event>, | ||
UsedEvents extends keyof EventMap = keyof EventMap | ||
>( | ||
target: MaybeAccessor<Many<EventTarget>>, | ||
...eventNames: UsedEvents[] | ||
): Store<Partial<Pick<EventMap, UsedEvents>>>; | ||
// with options: | ||
function createEventStore< | ||
EventMap extends Record<string, Event>, | ||
UsedEvents extends keyof EventMap = keyof EventMap | ||
>( | ||
target: MaybeAccessor<Many<EventTarget>>, | ||
options: MaybeAccessor<boolean | AddEventListenerOptions>, | ||
...eventNames: UsedEvents[] | ||
): Store<Partial<Pick<EventMap, UsedEvents>>>; | ||
``` | ||
## `WindowEventListener` | ||
Listen to the `window` DOM Events, using a component. | ||
You can use it with any Solid's Control-Flow components, e.g. `<Show/>` or `<Switch/>`. | ||
The event handler prop is reactive, so you can use it with signals. | ||
### How to use it | ||
```tsx | ||
import { WindowEventListener } from "@solid-primitives/event-listener"; | ||
<WindowEventListener onMouseMove={e => console.log(e.x, e.y)} />; | ||
``` | ||
## `DocumentEventListener` | ||
The same as [`WindowEventListener`](#WindowEventListener), but listens to `document` events. | ||
### How to use it | ||
```tsx | ||
import { DocumentEventListener } from "@solid-primitives/event-listener"; | ||
<DocumentEventListener onMouseMove={e => console.log(e.x, e.y)} />; | ||
``` | ||
## Demo | ||
You may view a working example here: https://codesandbox.io/s/solid-primitives-event-listener-8mm77 | ||
You may view a working example here: https://codesandbox.io/s/solid-primitives-event-listener-elti5 | ||
@@ -68,2 +290,7 @@ ## Changelog | ||
1.3.0 | ||
**(minor breaking changes to type generics and returned functions)** | ||
Primitive rewritten to provide better types and more reliable usage. Added more primitives. | ||
</details> |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
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
28754
421
294
2
10
+ Added@solid-primitives/utils@0.0.255(transitive)