@solid-primitives/event-listener
Advanced tools
Comparing version 1.1.4 to 1.2.3
@@ -0,15 +1,42 @@ | ||
import { Accessor } from "solid-js"; | ||
import type { JSX } from "solid-js"; | ||
export declare type EventListenerProps<E extends Record<string, Event> = {}> = [ | ||
name: (keyof WindowEventMap | keyof E) & string, | ||
handler: EventListenerOrEventListenerObject | null, | ||
options?: AddEventListenerOptions | ||
]; | ||
declare module "solid-js" { | ||
namespace JSX { | ||
interface Directives { | ||
createEventListener: (ref: HTMLElement, props: Accessor<EventListenerProps<{}>>) => [ | ||
add: (target: EventTarget) => void, | ||
remove: (target: EventTarget) => void | ||
]; | ||
} | ||
} | ||
} | ||
export declare type E = JSX.Element; | ||
/** | ||
* Creates an event listener helper primitive. | ||
* | ||
* @param eventName - Event name to bind to | ||
* @param handler - Function handler to trigger | ||
* @param element - HTML element to bind the event to | ||
* @param options - *useCapture* boolean or an object that specifies characteristics about the event listener. | ||
* @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 | ||
* | ||
* @example | ||
* ```ts | ||
* createEventListener("mouseDown", () => console.log("Click"), document.getElementById("mybutton")) | ||
* ```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, 'myCustomEvent', () => console.log("yup!")); | ||
* ``` | ||
*/ | ||
declare const createEventListener: <T extends HTMLElement, E extends keyof WindowEventMap>(eventName: E, handler: (event: WindowEventMap[E]) => void, targets?: Window | T | T[], options?: boolean | AddEventListenerOptions | undefined) => readonly [add: (el: Window | T) => void, remove: (el: Window | T) => void]; | ||
export declare function createEventListener<E extends Record<string, Event> = {}>(ref: EventTarget | EventTarget[], props: Accessor<EventListenerProps<E>>): readonly [add: (el: EventTarget) => void, remove: (el: EventTarget) => void]; | ||
export declare function createEventListener<E extends Record<string, Event> = {}>(target: EventTarget | EventTarget[], eventName: keyof E & string, handler: EventListenerOrEventListenerObject | null, options?: EventListenerOptions): readonly [add: (el: EventTarget) => void, remove: (el: EventTarget) => void]; | ||
export default createEventListener; |
@@ -1,24 +0,29 @@ | ||
import { onMount, onCleanup } from "solid-js"; | ||
/** | ||
* Creates an event listener helper primitive. | ||
* | ||
* @param eventName - Event name to bind to | ||
* @param handler - Function handler to trigger | ||
* @param element - HTML element to bind the event to | ||
* @param options - *useCapture* boolean or an object that specifies characteristics about the event listener. | ||
* | ||
* @example | ||
* ```ts | ||
* createEventListener("mouseDown", () => console.log("Click"), document.getElementById("mybutton")) | ||
* ``` | ||
*/ | ||
const createEventListener = (eventName, handler, targets = window, options) => { | ||
const add = (target) => target.addEventListener && | ||
target.addEventListener(eventName, handler, options); | ||
const remove = (target) => target.removeEventListener && | ||
target.removeEventListener(eventName, handler, options); | ||
onMount(() => (Array.isArray(targets) ? targets.forEach(add) : add(targets))); | ||
onCleanup(() => (Array.isArray(targets) ? targets.forEach(remove) : remove(targets))); | ||
import { createEffect, onCleanup } from "solid-js"; | ||
export function createEventListener(target, nameOrProps, handler, options) { | ||
const targets = Array.isArray(target) ? target : [target]; | ||
const props = typeof nameOrProps === 'function' ? nameOrProps : () => [nameOrProps ?? '', handler ?? null, options]; | ||
const add = (target) => { | ||
targets.includes(target) || targets.push(target); | ||
target.addEventListener.apply(target, props()); | ||
}; | ||
const remove = (target) => { | ||
targets.forEach((t, index) => t === target && targets.splice(index, 1)); | ||
target.removeEventListener.apply(target, props()); | ||
}; | ||
// we need to directly add the event, otherwise we cannot dispatch it before the next effect runs | ||
targets.forEach(add); | ||
createEffect((previousProps) => { | ||
const currentProps = props(); | ||
if (previousProps !== currentProps) { | ||
previousProps && targets.forEach((target) => target.removeEventListener.apply(target, previousProps)); | ||
targets.forEach(add); | ||
} | ||
return currentProps; | ||
}, props()); | ||
onCleanup(() => { | ||
targets.forEach(remove); | ||
}); | ||
return [add, remove]; | ||
}; | ||
} | ||
; | ||
export default createEventListener; |
{ | ||
"name": "@solid-primitives/event-listener", | ||
"version": "1.1.4", | ||
"version": "1.2.3", | ||
"description": "Primitive to manage creating event listeners.", | ||
@@ -19,3 +19,4 @@ "author": "David Di Biase <dave.dibiase@gmail.com>", | ||
"clean": "rimraf dist/", | ||
"build": "tsc" | ||
"build": "tsc", | ||
"test": "jest" | ||
}, | ||
@@ -29,16 +30,39 @@ "keywords": [ | ||
"devDependencies": { | ||
"@types/jest": "^26.0.10", | ||
"@babel/preset-env": "7.15.6", | ||
"@types/jest": "27.0.1", | ||
"babel-preset-solid": "1.1.5", | ||
"jest": "27.0.1", | ||
"prettier": "^2.0.5", | ||
"solid-testing-library": "^0.2.0", | ||
"ts-jest": "27.0.5", | ||
"tslib": "^2.0.1", | ||
"typescript": "^4.0.2" | ||
"typescript": "^4.4.3" | ||
}, | ||
"dependencies": { | ||
"solid-js": "^1.1.6" | ||
}, | ||
"peerDependencies": { | ||
"solid-js": "^1.0.7" | ||
"solid-js": "^1.1.6" | ||
}, | ||
"jest": { | ||
"preset": "ts-jest", | ||
"globals": { | ||
"ts-jest": { | ||
"tsconfig": "tsconfig.json", | ||
"babelConfig": { | ||
"presets": [ | ||
"babel-preset-solid", | ||
"@babel/preset-env" | ||
] | ||
} | ||
} | ||
}, | ||
"setupFiles": [ | ||
"./test/setup.ts" | ||
] | ||
], | ||
"testEnvironment": "jsdom", | ||
"moduleNameMapper": { | ||
"solid-js/web": "<rootDir>/node_modules/solid-js/web/dist/web.cjs", | ||
"solid-js": "<rootDir>/node_modules/solid-js/dist/solid.cjs" | ||
} | ||
} | ||
} |
@@ -11,6 +11,11 @@ # @solid-primitives/event-listener | ||
```ts | ||
const [listener] = createEventListener("mouseDown", () => console.log("Click"), document.getElementById("mybutton")) | ||
<button use:listener>Click me</button> | ||
``` | ||
```ts | ||
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, "myCustomEvent", () => console.log("yup!")); | ||
``` | ||
@@ -30,2 +35,10 @@ ## Demo | ||
1.1.4 | ||
Released a version with type mostly cleaned up. | ||
1.2.3 | ||
Switched to a more idiomatic pattern: Warning: incompatible with the previous version! | ||
</details> |
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
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
7123
72
43
2
8
+ Addedsolid-js@^1.1.6