Socket
Socket
Sign inDemoInstall

@solid-primitives/event-listener

Package Overview
Dependencies
Maintainers
3
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@solid-primitives/event-listener - npm Package Compare versions

Comparing version 1.6.1 to 2.0.0

142

dist/index.d.ts

@@ -1,4 +0,3 @@

import { MaybeAccessor, Many } from '@solid-primitives/utils';
import { JSX, Accessor, Component } from 'solid-js';
import { Store } from 'solid-js/store';
import { MaybeAccessor, Many, Directive } from '@solid-primitives/utils';
import { JSX, Accessor } from 'solid-js';

@@ -13,3 +12,2 @@ declare type EventListenerOptions = boolean | AddEventListenerOptions;

];
declare type EventListenerMapDirectiveProps = [handlerMap: Record<string, (e: any) => void>, options?: EventListenerOptions] | Record<string, (e: any) => void>;
declare module "solid-js" {

@@ -19,3 +17,2 @@ namespace JSX {

eventListener: EventListenerDirectiveProps;
eventListenerMap: EventListenerMapDirectiveProps;
}

@@ -26,24 +23,35 @@ }

declare type EventListenerSignalReturns<Event> = [
lastEvent: Accessor<Event | undefined>,
clear: VoidFunction
];
/**
* Creates an event listener, that will be automatically disposed on cleanup.
*
* @param target - ref to HTMLElement, EventTarget or Array thereof
* @param target - ref to HTMLElement, EventTarget
* @param type - name of the handled event
* @param handler - event handler
* @param options - addEventListener options
*
* @returns Function clearing all event listeners form targets
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-listener#makeEventListener
* @example
* const clear = makeEventListener(element, 'click', e => { ... }, { passive: true })
* // remove listener (will also happen on cleanup)
* clear()
*/
declare function makeEventListener<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventType extends keyof EventMap>(target: Target, type: EventType, handler: (event: EventMap[EventType]) => void, options?: EventListenerOptions): VoidFunction;
declare function makeEventListener<EventMap extends Record<string, Event>, EventType extends keyof EventMap = keyof EventMap>(target: EventTarget, type: EventType, handler: (event: EventMap[EventType]) => void, options?: EventListenerOptions): VoidFunction;
/**
* Creates a reactive event listener, that will be automatically disposed on cleanup,
* and can take reactive arguments to attach listeners to new targets once changed.
* @param target - ref to HTMLElement, EventTarget or Array thereof
* @param type - 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/solidjs-community/solid-primitives/tree/main/packages/event-listener#createEventListener
*
* @example
* const clear = createEventListener(element, 'click', e => { ... }, { passive: true })
* const [targets, setTargets] = createSignal([element])
* createEventListener(targets, 'click', e => { ... }, { passive: true })
* setTargets([]) // <- removes listeners from previous target
* setTargets([element, button]) // <- adds listeners to new targets
*/
declare function createEventListener<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventType extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, type: MaybeAccessor<Many<EventType>>, handler: (event: EventMap[EventType]) => void, options?: EventListenerOptions): VoidFunction;
declare function createEventListener<EventMap extends Record<string, Event>, EventType extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, type: MaybeAccessor<Many<EventType>>, handler: (event: EventMap[EventType]) => void, options?: EventListenerOptions): VoidFunction;
declare function createEventListener<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventType extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, type: MaybeAccessor<Many<EventType>>, handler: (event: EventMap[EventType]) => void, options?: EventListenerOptions): void;
declare function createEventListener<EventMap extends Record<string, Event>, EventType extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, type: MaybeAccessor<Many<EventType>>, handler: (event: EventMap[EventType]) => void, options?: EventListenerOptions): void;
/**

@@ -68,4 +76,4 @@ * Provides an reactive signal of last captured event.

*/
declare function createEventSignal<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventType extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, type: MaybeAccessor<Many<EventType>>, options?: EventListenerOptions): EventListenerSignalReturns<EventMap[EventType]>;
declare function createEventSignal<EventMap extends Record<string, Event>, EventType extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, type: MaybeAccessor<Many<EventType>>, options?: EventListenerOptions): EventListenerSignalReturns<EventMap[EventType]>;
declare function createEventSignal<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, EventType extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, type: MaybeAccessor<Many<EventType>>, options?: EventListenerOptions): Accessor<EventMap[EventType]>;
declare function createEventSignal<EventMap extends Record<string, Event>, EventType extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, type: MaybeAccessor<Many<EventType>>, options?: EventListenerOptions): Accessor<EventMap[EventType]>;
/**

@@ -79,3 +87,3 @@ * Directive Usage. Creates an event listener, that will be automatically disposed on cleanup.

*/
declare function eventListener(target: Element, props: Accessor<EventListenerDirectiveProps>): void;
declare const eventListener: Directive<EventListenerDirectiveProps>;

@@ -85,3 +93,2 @@ declare type EventHandlersMap<EventMap> = {

};
declare type EventListenerStoreReturns<E> = [lastEvents: Store<Partial<E>>, clear: VoidFunction];
/**

@@ -94,4 +101,2 @@ * A helpful primitive that listens to a map of events. Handle them by individual callbacks.

*
* @returns Function clearing all event listeners form targets
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

@@ -101,3 +106,3 @@ * @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-listener#createEventListenerMap

* @example
* const clear = createEventListenerMap(element, {
* createEventListenerMap(element, {
* mousemove: mouseHandler,

@@ -108,46 +113,11 @@ * mouseenter: e => {},

*/
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?: EventListenerOptions): VoidFunction;
declare function createEventListenerMap<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, HandlersMap extends Partial<EventHandlersMap<EventMap>>>(target: MaybeAccessor<Many<Target>>, handlersMap: HandlersMap, options?: EventListenerOptions): VoidFunction;
/**
* 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 omitted)*
* @param eventNames names of events you want to listen to, e.g. `"mousemove", "touchend", "click"`
*
* @returns reactive store with the latest captured events & clear function
*
* @see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-listener#createEventStore
*
* @example
* const [lastEvents, clear] = 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[]): EventListenerStoreReturns<Pick<EventMap, UsedEvents>>;
declare function createEventStore<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, UsedEvents extends keyof EventMap>(target: MaybeAccessor<Many<Target>>, options: EventListenerOptions, ...eventNames: UsedEvents[]): EventListenerStoreReturns<Pick<EventMap, UsedEvents>>;
declare function createEventStore<EventMap extends Record<string, Event>, UsedEvents extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, ...eventNames: UsedEvents[]): EventListenerStoreReturns<Pick<EventMap, UsedEvents>>;
declare function createEventStore<EventMap extends Record<string, Event>, UsedEvents extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, options: EventListenerOptions, ...eventNames: UsedEvents[]): EventListenerStoreReturns<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 function createEventListenerMap<EventMap extends Record<string, Event>, UsedEvents extends keyof EventMap = keyof EventMap>(target: MaybeAccessor<Many<EventTarget>>, handlersMap: Partial<Pick<EventHandlersMap<EventMap>, UsedEvents>>, options?: EventListenerOptions): void;
declare function createEventListenerMap<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>, HandlersMap extends Partial<EventHandlersMap<EventMap>>>(target: MaybeAccessor<Many<Target>>, handlersMap: HandlersMap, options?: EventListenerOptions): void;
declare type EventAttributes<T> = {
[K in keyof JSX.DOMAttributes<T>]: `${K}` extends `on${string}` ? JSX.DOMAttributes<T>[K] : never;
declare type WindowEventProps = {
[K in keyof WindowEventMap as `on${Capitalize<K>}` | `on${K}`]?: (event: WindowEventMap[K]) => void;
};
declare type DocumentEventProps = {
[K in keyof DocumentEventMap as `on${Capitalize<K>}` | `on${K}`]?: (event: DocumentEventMap[K]) => void;
};
/**

@@ -161,3 +131,3 @@ * Listen to the `window` DOM Events, using a component.

*/
declare const WindowEventListener: Component<EventAttributes<null>>;
declare function WindowEventListener(props: WindowEventProps): undefined;
/**

@@ -171,28 +141,22 @@ * Listen to the `document` DOM Events, using a component.

*/
declare const DocumentEventListener: Component<EventAttributes<null>>;
declare function DocumentEventListener(props: DocumentEventProps): undefined;
declare type EventListenerBus<EventMap extends Record<string, any>> = Readonly<{
[K in `on${keyof EventMap extends string ? keyof EventMap : never}`]: (handler: (event: EventMap[K extends `on${infer T}` ? T : never]) => void) => VoidFunction;
} & {
on: <T extends keyof EventMap>(type: MaybeAccessor<Many<T>>, handler: (event: EventMap[T]) => void) => VoidFunction;
}>;
declare type EventListenerStackOn<EventMap extends Record<string, any>> = {
<T extends keyof EventMap>(type: T, handler: (event: EventMap[T]) => void, options?: EventListenerOptions): VoidFunction;
};
/**
* Dynamically add and remove event listeners to an event target. The listeners will be automatically removed on cleanup.
* @param target the event target, could be a `window`, `document`, `HTMLElement` or `MediaQueryList`. *Defaults to `window`*
* @param options event listener options, such as `passive` or `capture`
* @returns a Proxy object, which lets you create event listeners by calling appropriate property
* @see https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-listener#createEventListenerBus
* Creates a stack of event listeners, that will be automatically disposed on cleanup.
* @param target - ref to HTMLElement, EventTarget
* @param options - addEventListener options
* @returns Function clearing all event listeners form targets
* @example
* const bus = createEventListenerBus(document.body);
* bus.onpointerenter(e => {...});
* // listeners return a function that removes them
* const clear = bus.onpointermove(e => {...});
* clear();
* // or pass event type as an argument
* const unsub = bus.on('click', e => {...})
* const [listen, clear] = makeEventListenerStack(target, { passive: true });
* listen("mousemove", handleMouse);
* listen("dragover", handleMouse);
* // remove listener (will also happen on cleanup)
* clear()
*/
declare function createEventListenerBus(target?: undefined, options?: EventListenerOptions): EventListenerBus<WindowEventMap>;
declare function createEventListenerBus<Target extends TargetWithEventMap>(target: MaybeAccessor<Many<Target>>, options?: EventListenerOptions): EventListenerBus<EventMapOf<Target>>;
declare function createEventListenerBus<EventMap extends Record<string, Event>>(target?: MaybeAccessor<Many<EventTarget>>, options?: EventListenerOptions): EventListenerBus<EventMap>;
declare function makeEventListenerStack<Target extends TargetWithEventMap, EventMap extends EventMapOf<Target>>(target: Target, options?: EventListenerOptions): [listen: EventListenerStackOn<EventMap>, clear: VoidFunction];
declare function makeEventListenerStack<EventMap extends Record<string, Event>>(target: EventTarget, options?: EventListenerOptions): [listen: EventListenerStackOn<EventMap>, clear: VoidFunction];
export { DocumentEventListener, E, EventHandlersMap, EventListenerBus, EventListenerDirectiveProps, EventListenerMapDirectiveProps, EventListenerOptions, EventListenerSignalReturns, EventListenerStoreReturns, EventMapOf, TargetWithEventMap, WindowEventListener, createEventListener, createEventListenerBus, createEventListenerMap, createEventSignal, createEventStore, eventListener, eventListenerMap };
export { DocumentEventListener, DocumentEventProps, E, EventHandlersMap, EventListenerDirectiveProps, EventListenerOptions, EventListenerStackOn, EventMapOf, TargetWithEventMap, WindowEventListener, WindowEventProps, createEventListener, createEventListenerMap, createEventSignal, eventListener, makeEventListener, makeEventListenerStack };
// src/eventListener.ts
import {
createCallbackStack,
noop,
isServer,
access,
asArray
} from "@solid-primitives/utils";
import { isServer, access, asArray } from "@solid-primitives/utils";
import { createEffect, onCleanup, createRenderEffect, createSignal } from "solid-js";
function makeEventListener(target, type, handler, options) {
target.addEventListener(type, handler, options);
return onCleanup(target.removeEventListener.bind(target, type, handler, options));
}
function createEventListener(targets, type, handler, options) {
if (isServer)
return noop;
const cleanup = createCallbackStack();
return;
const attachListeners = () => {
cleanup.execute();
asArray(access(type)).forEach((type2) => {
asArray(access(targets)).forEach((el) => {
if (!el)
return;
el.addEventListener(type2, handler, options);
cleanup.push(() => el.removeEventListener(type2, handler, options));
});
asArray(access(targets)).forEach((el) => {
if (el)
asArray(access(type)).forEach((type2) => makeEventListener(el, type2, handler, options));
});

@@ -29,111 +21,56 @@ };

createRenderEffect(attachListeners);
onCleanup(cleanup.execute);
return cleanup.execute;
}
function createEventSignal(target, type, options) {
const [lastEvent, setLastEvent] = createSignal();
const clear = createEventListener(target, type, setLastEvent, options);
return [lastEvent, clear];
createEventListener(target, type, setLastEvent, options);
return lastEvent;
}
function eventListener(target, props) {
const toCleanup = createCallbackStack();
var eventListener = (target, props) => {
createEffect(() => {
toCleanup.execute();
const [type, handler, options] = props();
target.addEventListener(type, handler, options);
toCleanup.push(() => target.removeEventListener(type, handler, options));
makeEventListener(target, type, handler, options);
});
onCleanup(toCleanup.execute);
}
};
// src/eventListenerMap.ts
import {
createCallbackStack as createCallbackStack2,
forEachEntry,
access as access2
} from "@solid-primitives/utils";
import { createEffect as createEffect2, createSignal as createSignal2, onCleanup as onCleanup2 } from "solid-js";
import { forEachEntry } from "@solid-primitives/utils";
function createEventListenerMap(targets, handlersMap, options) {
const { push, execute } = createCallbackStack2();
forEachEntry(access2(handlersMap), (eventName, handler) => {
push(createEventListener(targets, eventName, (e) => handler == null ? void 0 : handler(e), options));
forEachEntry(handlersMap, (eventName, handler) => {
if (handler)
createEventListener(targets, eventName, handler, options);
});
return execute;
}
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 = {};
const { push, execute } = createCallbackStack2();
names.forEach((type) => {
const [accessor, setter] = createSignal2();
Object.defineProperty(store, type, { get: accessor, set: setter, enumerable: true });
push(createEventListener(targets, type, setter, options));
});
return [store, execute];
}
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;
forEachEntry(handlersMap, (type, handler) => {
target.addEventListener(type, handler, options);
toCleanup.push(() => target.removeEventListener(type, handler, options));
});
});
onCleanup2(toCleanup.execute);
}
// src/components.ts
import { isClient } 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);
import { isClient, keys } from "@solid-primitives/utils";
var attachPropListeners = (target, props) => {
keys(props).forEach((attr) => {
if (attr.startsWith("on") && typeof props[attr] === "function")
makeEventListener(target, attr.substring(2).toLowerCase(), props[attr]);
});
};
var WindowEventListener = (props) => {
function WindowEventListener(props) {
if (isClient)
forEachEventAttr(props, (type, attr) => {
createEventListener(window, type, (e) => props[attr](e));
});
attachPropListeners(window, props);
return void 0;
};
var DocumentEventListener = (props) => {
}
function DocumentEventListener(props) {
if (isClient)
forEachEventAttr(props, (eventName, attr) => {
createEventListener(document, eventName, (e) => props[attr](e));
});
attachPropListeners(document, props);
return void 0;
};
}
// src/bus.ts
import { createProxy, isClient as isClient2 } from "@solid-primitives/utils";
import { runWithSubRoot } from "@solid-primitives/rootless";
import { getOwner } from "solid-js";
function createEventListenerBus(target = isClient2 ? window : [], options = {}) {
const owner = getOwner();
const addListener = (type, handler) => runWithSubRoot(() => {
createEventListener(target, type, handler, options);
}, owner, getOwner());
return createProxy({
get: (key) => (...args) => args.length === 2 ? addListener(...args) : addListener(key.substring(2), args[0])
});
// src/eventListenerStack.ts
import { createCallbackStack } from "@solid-primitives/utils";
import { onCleanup as onCleanup2 } from "solid-js";
function makeEventListenerStack(target, options) {
const { push, execute } = createCallbackStack();
return [
(type, handler, overwriteOptions) => {
const clear = makeEventListener(target, type, handler, overwriteOptions != null ? overwriteOptions : options);
push(clear);
return clear;
},
onCleanup2(execute)
];
}

@@ -144,8 +81,7 @@ export {

createEventListener,
createEventListenerBus,
createEventListenerMap,
createEventSignal,
createEventStore,
eventListener,
eventListenerMap
makeEventListener,
makeEventListenerStack
};
{
"name": "@solid-primitives/event-listener",
"version": "1.6.1",
"description": "Primitive to manage creating event listeners.",
"version": "2.0.0",
"description": "SolidJS Primitives to manage creating event listeners.",
"author": "David Di Biase <dave.dibiase@gmail.com>",
"contributors": [
"Damian Tarnawski <gthetarnav@gmail.com>"
],
"license": "MIT",

@@ -19,4 +22,2 @@ "homepage": "https://github.com/solidjs-community/solid-primitives/tree/main/packages/event-listener",

"createEventListenerMap",
"createEventStore",
"createEventListenerBus",
"WindowEventListener",

@@ -37,6 +38,7 @@ "DocumentEventListener"

"scripts": {
"start": "vite -r ./dev/ -c ./dev/vite.config.ts",
"start": "vite serve dev --host",
"dev": "yarn start",
"build": "tsup",
"test": "uvu -r solid-register",
"watch-test": "watchlist src test -- npm test"
"test:watch": "watchlist src test -- npm test"
},

@@ -51,10 +53,10 @@ "keywords": [

"jsdom": "^19.0.0",
"prettier": "^2.5.0",
"solid-register": "^0.1.5",
"prettier": "^2.6.2",
"solid-register": "^0.2.3",
"tslib": "^2.3.1",
"tsup": "^5.10.0",
"unocss": "0.24.3",
"uvu": "^0.5.2",
"vite": "2.8.1",
"vite-plugin-solid": "2.2.5",
"tsup": "^5.12.6",
"unocss": "0.31.12",
"uvu": "^0.5.3",
"vite": "2.9.5",
"vite-plugin-solid": "2.2.6",
"watchlist": "^0.3.1"

@@ -66,5 +68,4 @@ },

"dependencies": {
"@solid-primitives/rootless": "^0.1.0",
"@solid-primitives/utils": "^1.2.0"
}
}

@@ -14,9 +14,17 @@ <p>

- [`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.
##### Non-reactive primitives:
- [`makeEventListener`](#makeEventListener) - Non-reactive primitive for adding event listeners that get's removed onCleanup.
- [`makeEventListenerStack`](#makeEventListenerStack) - Creates a stack of event listeners, that will be automatically disposed on cleanup.
##### Reactive primitives:
- [`createEventListener`](#createEventListener) - Reactive version of [`makeEventListener`](#makeEventListener), that takes signal arguments to apply new listeners once changed.
- [`createEventSignal`](#createEventListener) - Like [`createEventListener`](#createEventListener), but captured events are stored in a returned signal.
- [`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.
- [`createEventListenerBus`](#createEventListenerBus) - Dynamically add and remove event listeners to an event target by calling appropriate property.
##### Component global listeners:
- [`WindowEventListener`](#WindowEventListener) - Listen to the `window` DOM Events, using a component.
- [`DocumentEventListener`](#DocumentEventListener) - The same as [`WindowEventListener`](#WindowEventListener), but listens to `document` events.
- [`DocumentEventListener`](#DocumentEventListener) - Listen to the `document` DOM Events, using a component.

@@ -31,12 +39,14 @@ ## Installation

## `createEventListener`
## `makeEventListener`
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.
Can be used to listen to DOM or Custom Events on window, document, or any EventTarget.
Event listener is automatically removed on root cleanup. The clear() function is also returned for calling it early.
### How to use it
```ts
import { createEventListener } from "@solid-primitives/event-listener";
```tsx
import { makeEventListener } from "@solid-primitives/event-listener";
const clear = createEventListener(
const clear = makeEventListener(
document.getElementById("myButton"),

@@ -51,13 +61,69 @@ "mousemove",

// when listening to element refs, call it inside onMount
let ref!: HTMLDivElement
onMount(() => {
makeEventListener(ref, "click", e => {...}, { passive: true });
});
<div ref={ref} />;
```
#### Custom events
```ts
// you can provide your own event map type as well:
// fill both type generics for the best type support
makeEventListener<{ myCustomEvent: MyEvent; other: Event }, "myCustomEvent">(
window,
"myCustomEvent",
() => console.log("yup!")
);
// just don't use interfaces as EventMaps! (write them using `type` keyword)
```
## `makeEventListenerStack`
Creates a stack of event listeners, that will be automatically disposed on cleanup.
### How to use it
```ts
import { makeEventListenerStack } from "@solid-primitives/event-listener";
const [listen, clear] = makeEventListenerStack(target, { passive: true });
listen("mousemove", handleMouse);
listen("dragover", handleMouse);
// remove listener (will also happen on cleanup)
clear();
```
## `createEventListener`
Reactive version of [`makeEventListener`](#makeEventListener), that can take signal `target` and `type` arguments to apply new listeners once changed.
### How to use it
```tsx
import { createEventListener } from "@solid-primitives/event-listener";
createEventListener(
document.getElementById("myButton"),
"mousemove",
e => console.log("x:", e.pageX, "y:", e.pageY),
{ passive: true }
);
// target element and event name can be reactive signals
const [ref, setRef] = createSignal<HTMLElement>();
const [name, setName] = createSignal("mousemove");
createEventListener(ref, name, e => {}, { passive: true });
const [type, setType] = createSignal("mousemove");
createEventListener(ref, type, e => {...});
// also runs in createEffect so refs are already bound
// (but variable refs need to be wrapped in functions)
// when using ref as a target, pass it in a function – function will be executed after mount
// or wrap the whole primitive in onMount
let ref;
createEventListener(() => ref, "mousemove", e => {});
return <div ref={ref}/>;
<div ref={ref} />;
```

@@ -78,2 +144,27 @@

#### Removing event listeners manually
Since version `@2.0.0` `createEventListener` and other reactive primitives aren't returning a `clear()` function, because of it's flawed behavior [described in this issue](https://github.com/solidjs-community/solid-primitives/issues/103).
Although there are still ways to remove attached event listeners:
1. Changing reactive `target` or `type` arguments to an empty array.
```ts
const [type, setType] = createSignal<"click" | []>("click");
createEventListener(window, type, e => {...});
// remove listener:
setType([]);
```
2. Wrapping usage of `createEventListener` primitive in Solid's `createRoot` or `createBranch` | `createDisposable` from ["@solid-primitives/rootless"](https://github.com/solidjs-community/solid-primitives/tree/main/packages/rootless#createDisposable).
```ts
import { createDisposable } from "@solid-primitives/rootless";
const clear = createDisposable(() => createEventListener(element, "click", e => {...}));
// remove listener:
clear();
```
#### Listening to multiple events

@@ -111,3 +202,3 @@

// all arguments can be reactive signals
const [lastEvent, clear] = createEventSignal(el, "mousemove", { passive: true });
const lastEvent = createEventSignal(el, "mousemove", { passive: true });

@@ -117,5 +208,2 @@ createEffect(() => {

});
// to clear all the event listeners
clear();
```

@@ -132,3 +220,3 @@

const clear = createEventListenerMap(element, {
createEventListenerMap(element, {
mousemove: mouseHandler,

@@ -139,5 +227,2 @@ mouseenter: e => {},

// to clear all the event listeners
clear();
// both target can be reactive:

@@ -169,133 +254,2 @@ const [target, setTarget] = createSignal(document.getElementById("abc"));

### 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>;
```
## `createEventStore`
Similar to [`createEventListenerMap`](#createEventListenerMap), but provides a reactive store with the latest captured events.
### How to use it
```ts
const [lastEvents, clear] = createEventStore(el, "mousemove", "touchend", "click");
createEffect(() => {
console.log(lastEvents?.mousemove.x);
});
// to clear all the event listeners
clear()
// both target and options args can be reactive:
const [target, setTarget] = createSignal(document.getElementById("abc"));
const [lastEvents] = createEventStore(target, "mousemove", "touchmove");
// createEventStore can be used to listen to custom events
// fill both type generics for the best type support
const [lastEvents] = createEventStore<
{
myEvent: MyEvent;
custom: Event;
unused: Event;
},
"myEvent" | "custom"
>(target, "myEvent", "custom");
// DON'T DO THIS:
const [{ mousemove }] = createEventStore(target, "mousemove", ...);
// the store cannot be destructured
```
## `createEventListenerBus`
###### Added in `@1.5.0`
Dynamically add and remove event listeners to an event target by calling appropriate property. The listeners will be automatically removed on cleanup.
### How to use it
#### Import
```ts
import { createEventListenerBus } from "@solid-primitives/event-listener";
```
#### Basic usage
`createEventListenerBus` takes two arguments:
- `target` - the event target, could be a `window`, `document`, `HTMLElement` or `MediaQueryList`. _Defaults to `window`_
- `options` - event listener options, such as `passive` or `capture`
```ts
const bus = createEventListenerBus(document.body);
bus.onpointerenter(e => {...});
// listeners return a function that removes them
const clear = bus.onpointermove(e => {...});
clear();
```
#### Reactive target
Target argument could be an **array**, and a **reactive signal**.
```ts
const [target, setTarget] = createSignal([document.body]);
const bus = createEventListenerBus(target);
setTarget(p => [...p, window]); // will change the targets of all active listeners.
```
#### generic on()
Using `bus.on(type, handler)` gives you more options in passing event type.
```ts
bus.on("click", e => {});
bus.on(["mousemove", "mousedown"], e => {});
const [types, setTypes] = createsignal(["focus", "blur"]);
bus.on(types, e => {});
```
#### Custom Events
The `createEventListenerBus` can be used to listen to Custom Events.
```ts
const bus = createEventListenerBus<{
foo: SomeEvent;
bar: MyEvent;
}>();
bus.onfoo(e => {});
bus.onbar(e => {});
```
#### Reactive Roots
The EventListenerBus is designed in a way to let you add event listeners outside of reactive roots/ in different root then the one primitive was used in.
```ts
const bus = createRoot(dispose => {
return createEventListenerBus();
});
// listeners can be added outside of the original root setup function.
createRoot(dispose => {
bus.onclick(e => {});
});
```
## `WindowEventListener`

@@ -383,2 +337,12 @@

2.0.0
[PR#113](https://github.com/solidjs-community/solid-primitives/pull/113)
Remove `createEventListenerBus`, `createEventListenerStore` & `eventListenerMap`
Add `makeEventListener` and `makeEventListenerStack`
Remove clear() functions from reactive primitives.
</details>

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc