Skip to content

Commit 7d0da7c

Browse files
committedDec 8, 2021
finishing updates
- return clear function form event-listener primitives - update readme - update mouse and active-element to last event-listener changes

21 files changed

+177
-138
lines changed
 

‎packages/active-element/README.md

+14-8
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,20 @@ A reactive `document.activeElement`. Check which element is currently focused.
2424
```ts
2525
import { createActiveElement } from "@solid-primitives/active-element";
2626

27-
const [activeEl, { stop, start }] = createActiveElement();
28-
// "stop" and "start" are for adding and removing event listeners
27+
const [activeEl, clear] = createActiveElement();
28+
29+
createEffect(() => {
30+
console.log(activeEl());
31+
});
32+
33+
// clear all event listeners
34+
clear();
2935
```
3036

3137
### Types
3238

3339
```ts
34-
function createActiveElement(): [
35-
getter: Accessor<null | Element>,
36-
actions: { stop: Fn; start: Fn }
37-
];
40+
function createActiveElement(): [getter: Accessor<null | Element>, clear: ClearListeners];
3841
```
3942

4043
## `createIsElementActive`
@@ -46,14 +49,17 @@ Pass in an element, and see if it's focused.
4649
```ts
4750
import { createIsElementActive } from "@solid-primitives/active-element";
4851

49-
const [isFocused, { stop, start }] = createIsElementActive(() => el);
52+
const [isFocused, clear] = createIsElementActive(() => el);
5053
// "stop" and "start" are for adding and removing event listeners
5154

5255
// you can also use signals for ref
5356
const [ref, setRef] = createSignal<Element>();
5457
const [isFocused] = createIsElementActive(ref);
5558
// this way if the element changes,
5659
// the "isFocused" will start checking the new element
60+
61+
// clear all event listeners
62+
clear();
5763
```
5864

5965
### As Directive
@@ -73,7 +79,7 @@ const [active, setActive] = createSignal(false)
7379
```ts
7480
function createIsElementActive(
7581
target: MaybeAccessor<Element>
76-
): [getter: Accessor<boolean>, actions: { stop: Fn; start: Fn }];
82+
): [getter: Accessor<boolean>, clear: ClearListeners];
7783

7884
type IsElementActiveProps = (isActive: boolean) => void;
7985
```

‎packages/active-element/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"solid-js": "^1.2.5"
6363
},
6464
"dependencies": {
65-
"@solid-primitives/event-listener": "^1.3.0",
66-
"@solid-primitives/utils": "^0.0.250"
65+
"@solid-primitives/event-listener": "^1.3.2",
66+
"@solid-primitives/utils": "^0.0.255"
6767
}
6868
}

‎packages/active-element/src/common.ts

-12
This file was deleted.

‎packages/active-element/src/index.ts

+7-17
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1+
import { ClearListeners, createEventListenerMap } from "@solid-primitives/event-listener";
12
import { access, Fn, MaybeAccessor, createCallbackStack } from "@solid-primitives/utils";
23
import { Accessor, createComputed, createEffect, createSignal, JSX } from "solid-js";
3-
import { addListener } from "./common";
44

55
export type IsElementActiveProps = (isActive: boolean) => void;
66
declare module "solid-js" {
@@ -20,10 +20,7 @@ export type E = JSX.Element;
2020
* @example
2121
* const [activeEl, { stop, start }] = createActiveElement()
2222
*/
23-
export function createActiveElement(): [
24-
getter: Accessor<null | Element>,
25-
actions: { stop: Fn; start: Fn }
26-
] {
23+
export function createActiveElement(): [getter: Accessor<null | Element>, clear: ClearListeners] {
2724
const [active, setActive] = createSignal<Element | null>(null);
2825
const handleChange = () => setActive(window.document.activeElement);
2926

@@ -32,19 +29,12 @@ export function createActiveElement(): [
3229
toCleanup.execute();
3330
handleChange();
3431
toCleanup.push(
35-
addListener(window, "blur", handleChange),
36-
addListener(window, "focus", handleChange)
32+
createEventListenerMap(window, { blur: handleChange, focus: handleChange }, true)
3733
);
3834
};
3935
start();
4036

41-
return [
42-
active,
43-
{
44-
stop: toCleanup.execute,
45-
start
46-
}
47-
];
37+
return [active, toCleanup.execute];
4838
}
4939

5040
/**
@@ -56,7 +46,7 @@ export function createActiveElement(): [
5646
*/
5747
export function createIsElementActive(
5848
target: MaybeAccessor<Element>
59-
): [getter: Accessor<boolean>, actions: { stop: Fn; start: Fn }] {
49+
): [getter: Accessor<boolean>, clear: ClearListeners] {
6050
const [isActive, setIsActive] = createSignal(false);
6151
const handleFocus = () => setIsActive(true);
6252
const handleBlur = () => setIsActive(false);
@@ -67,15 +57,15 @@ export function createIsElementActive(
6757
const el = access(target);
6858
if (!el) return setIsActive(false);
6959
setIsActive(window.document.activeElement === el);
70-
toCleanup.push(addListener(el, "blur", handleBlur), addListener(el, "focus", handleFocus));
60+
toCleanup.push(createEventListenerMap(el, { blur: handleBlur, focus: handleFocus }, true));
7161
};
7262

7363
const el = access(target);
7464
setIsActive(!!el && window.document.activeElement === el);
7565

7666
createEffect(start);
7767

78-
return [isActive, { stop: toCleanup.execute, start }];
68+
return [isActive, toCleanup.execute];
7969
}
8070

8171
/**

‎packages/active-element/test/index.test.ts

+3-6
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ const cae = suite("createActiveElement");
77

88
cae("returns correct values", () =>
99
createRoot(dispose => {
10-
const [activeEl, { stop, start }] = createActiveElement();
10+
const [activeEl, stop] = createActiveElement();
1111

1212
assert.type(activeEl, "function");
1313
assert.ok(
1414
() => activeEl() === null || activeEl() === document.body,
1515
"no element should be active"
1616
);
1717
assert.type(stop, "function");
18-
assert.type(start, "function");
1918

2019
dispose();
2120
})
@@ -28,12 +27,11 @@ const iea = suite("createIsElementActive");
2827
iea("returns correct values", () =>
2928
createRoot(dispose => {
3029
const el = document.createElement("div");
31-
const [isFocused, { stop, start }] = createIsElementActive(el);
30+
const [isFocused, stop] = createIsElementActive(el);
3231

3332
assert.type(isFocused, "function");
3433
assert.is(isFocused(), false);
3534
assert.type(stop, "function");
36-
assert.type(start, "function");
3735

3836
dispose();
3937
})
@@ -42,12 +40,11 @@ iea("returns correct values", () =>
4240
iea("target can be an accessor", () =>
4341
createRoot(dispose => {
4442
const el = document.createElement("div");
45-
const [isFocused, { stop, start }] = createIsElementActive(() => el);
43+
const [isFocused, stop] = createIsElementActive(() => el);
4644

4745
assert.type(isFocused, "function");
4846
assert.is(isFocused(), false);
4947
assert.type(stop, "function");
50-
assert.type(start, "function");
5148

5249
dispose();
5350
})

‎packages/event-listener/README.md

+46-14
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![size](https://img.shields.io/bundlephobia/minzip/@solid-primitives/event-listener?style=for-the-badge)](https://bundlephobia.com/package/@solid-primitives/event-listener)
55
[![size](https://img.shields.io/npm/v/@solid-primitives/event-listener?style=for-the-badge)](https://www.npmjs.com/package/@solid-primitives/event-listener)
66

7-
A helpful event listener primitive that binds window and any element supplied.
7+
A set of primitives that help with listening to DOM and Custom Events.
88

99
- [`createEventListener`](#createEventListener) - Very basic and straightforward primitive that handles multiple elements according to a single event binding.
1010
- [`createEventSignal`](#createEventListener) - Like `createEventListener`, but events are handled with the returned signal, instead of with a callback.
@@ -30,13 +30,16 @@ Can be used to listen to DOM or Custom Events on window, document, list of HTML
3030
```ts
3131
import { createEventListener } from "@solid-primitives/event-listener";
3232

33-
createEventListener(
34-
document.getElementById("mybutton"),
33+
const clear = createEventListener(
34+
document.getElementById("myButton"),
3535
"mousemove",
3636
e => console.log("x:", e.pageX, "y:", e.pageY),
3737
{ passive: true }
3838
);
3939

40+
// to clear all of the event listeners
41+
clear();
42+
4043
// target element, event name and options can be reactive signals
4144
const [ref, setRef] = createSignal<HTMLElement>();
4245
const [name, setName] = createSignal("mousemove");
@@ -71,7 +74,7 @@ function createEventListener<
7174
eventName: MaybeAccessor<EventName>,
7275
handler: (event: EventMap[EventName]) => void,
7376
options?: MaybeAccessor<boolean | AddEventListenerOptions>
74-
): void;
77+
): ClearListeners;
7578

7679
// Directive
7780
function eventListener(
@@ -96,11 +99,32 @@ Like [`createEventListener`](#createEventListener), but events are handled with
9699
import { createEventSignal } from "@solid-primitives/event-listener";
97100

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

101104
createEffect(() => {
102105
console.log(lastEvent()?.x, lastEvent()?.y);
103106
});
107+
108+
// to clear all the event listeners
109+
clear();
110+
```
111+
112+
### Types
113+
114+
```ts
115+
function createEventSignal<
116+
EventMap extends Record<string, Event>,
117+
EventName extends keyof EventMap = keyof EventMap
118+
>(
119+
target: MaybeAccessor<Many<EventTarget>>,
120+
eventName: MaybeAccessor<EventName>,
121+
options?: MaybeAccessor<boolean | AddEventListenerOptions>
122+
): EventListenerSignalReturns<EventMap[EventName]>;
123+
124+
type EventListenerSignalReturns<Event> = [
125+
lastEvent: Accessor<Event | undefined>,
126+
clear: ClearListeners
127+
];
104128
```
105129

106130
## `createEventListenerMap`
@@ -112,12 +136,15 @@ A helpful primitive that listens to a map of events. Handle them by individual c
112136
```ts
113137
import { createEventListenerMap } from "@solid-primitives/event-listener";
114138

115-
createEventListenerMap(element, {
139+
const clear = createEventListenerMap(element, {
116140
mousemove: mouseHandler,
117141
mouseenter: e => {},
118142
touchend: touchHandler
119143
});
120144

145+
// to clear all the event listeners
146+
clear();
147+
121148
// both target and options args can be reactive:
122149
const [target, setTarget] = createSignal(document.getElementById("abc"));
123150
const [options, setOptions] = createSignal({ passive: true });
@@ -171,7 +198,7 @@ function createEventListenerMap<
171198
target: MaybeAccessor<Many<EventTarget>>,
172199
handlersMap: EventHandlersMap,
173200
options?: MaybeAccessor<boolean | AddEventListenerOptions>
174-
): void;
201+
): ClearListeners;
175202
```
176203

177204
## `createEventStore`
@@ -181,19 +208,22 @@ Similar to [`createEventListenerMap`](#createEventListenerMap), but provides a r
181208
### How to use it
182209

183210
```ts
184-
const lastEvents = createEventStore(el, "mousemove", "touchend", "click");
211+
const [lastEvents, clear] = createEventStore(el, "mousemove", "touchend", "click");
185212

186213
createEffect(() => {
187214
console.log(lastEvents?.mousemove.x);
188215
});
189216

217+
// to clear all the event listeners
218+
clear()
219+
190220
// both target and options args can be reactive:
191221
const [target, setTarget] = createSignal(document.getElementById("abc"));
192222
const [options, setOptions] = createSignal({ passive: true });
193-
const lastEvents = createEventStore(target, options, "mousemove", "touchmove");
223+
const [lastEvents] = createEventStore(target, options, "mousemove", "touchmove");
194224

195225
// createEventStore can be used to listen to custom events
196-
const lastEvents = createEventStore<
226+
const [lastEvents] = createEventStore<
197227
{
198228
myEvent: MyEvent;
199229
custom: Event;
@@ -202,7 +232,7 @@ const lastEvents = createEventStore<
202232
>(target, "myEvent", "custom");
203233

204234
// DON'T DO THIS:
205-
const { mousemove } = createEventStore(target, "mousemove", ...);
235+
const [{ mousemove }] = createEventStore(target, "mousemove", ...);
206236
// the store cannot be destructured
207237
```
208238

@@ -215,7 +245,7 @@ function createEventStore<
215245
>(
216246
target: MaybeAccessor<Many<EventTarget>>,
217247
...eventNames: UsedEvents[]
218-
): Store<Partial<Pick<EventMap, UsedEvents>>>;
248+
): EventListnenerStoreReturns<Pick<EventMap, UsedEvents>>;
219249

220250
// with options:
221251
function createEventStore<
@@ -225,7 +255,9 @@ function createEventStore<
225255
target: MaybeAccessor<Many<EventTarget>>,
226256
options: MaybeAccessor<boolean | AddEventListenerOptions>,
227257
...eventNames: UsedEvents[]
228-
): Store<Partial<Pick<EventMap, UsedEvents>>>;
258+
): EventListnenerStoreReturns<Pick<EventMap, UsedEvents>>;
259+
260+
type EventListnenerStoreReturns<E> = [lastEvents: Store<Partial<E>>, clear: ClearListeners];
229261
```
230262

231263
## `WindowEventListener`
@@ -288,6 +320,6 @@ Migrated to new build process.
288320
1.3.0
289321

290322
**(minor breaking changes to type generics and returned functions)**
291-
Primitive rewritten to provide better types and more reliable usage. Added more primitives.
323+
Primitive rewritten to provide better types and more reliable usage. Added a lot more primitives.
292324

293325
</details>

‎packages/event-listener/dev/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ const List: Component = () => {
4646
const [items, setItems] = createSignal<HTMLDivElement[]>([]);
4747

4848
// new event listeners are automatically added to the new items
49-
const lastEvent = createEventSignal(items, "click");
49+
const [lastEvent] = createEventSignal(items, "click");
5050

5151
return (
5252
<div class="flex flex-col items-center space-y-6">

‎packages/event-listener/package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
"stage": 3,
1515
"list": [
1616
"createEventListener",
17-
"GlobalEventListener"
17+
"createEventSignal",
18+
"createEventListenerMap",
19+
"createEventStore",
20+
"WindowEventListener",
21+
"DocumentEventListener"
1822
],
1923
"category": "Browser APIs"
2024
},
@@ -55,6 +59,6 @@
5559
"solid-js": "^1.2.5"
5660
},
5761
"dependencies": {
58-
"@solid-primitives/utils": "^0.0.250"
62+
"@solid-primitives/utils": "^0.0.255"
5963
}
6064
}

0 commit comments

Comments
 (0)
Please sign in to comment.