@alcadur/react-events-hook 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,13 +2,82 @@
2
2
 
3
3
  Simple Observer pattern for React.
4
4
 
5
+ [Live Demo](https://codesandbox.io/p/sandbox/w9wqwh)
6
+
7
+ [npm package](https://www.npmjs.com/package/@alcadur/react-events-hook)
8
+
9
+ ## Installation
10
+ ```
11
+ npm i @alcadur/react-events-hook
12
+ ```
13
+
5
14
  ## What for?
6
15
  Useful for communication between components in different parts of the view.
7
16
 
8
17
  Using standard React mechanisms, it's also possible to synchronize with external events.
9
18
 
10
- ## Installation
11
- [soon]
19
+ Lets look at an example:
20
+
21
+ ![image](https://i.postimg.cc/6QTvgnz9/chrome-XWt93Ap2ma.png)
22
+
23
+ If we want to change background colors for C1, C2 and C3 from C6 we have few options:
24
+ 1. use context
25
+ 2. use global state
26
+ 3. props drilling
27
+
28
+ [![chrome-ZO2l-FT6NWj.png](https://i.postimg.cc/tggMcSL6/chrome-ZO2l-FT6NWj.png)](https://postimg.cc/BjdpLgZZ)
29
+
30
+ With events, we can avoid unnecessary boilerplate.
31
+
32
+ [![chrome-69c-Hd-SCHv-C.png](https://i.postimg.cc/tg0sSw1D/chrome-69c-Hd-SCHv-C.png)](https://postimg.cc/ZWcY0fxy)
33
+ [![chrome-M22485Lpnz.gif](https://i.postimg.cc/502bnSmm/chrome-M22485Lpnz.gif)](https://postimg.cc/SX3BK83X)
34
+
35
+
36
+ ## Docs
37
+
38
+ ### onEvent
39
+ `onEvent` is a function that subscribes to event outsite of React context.
40
+
41
+ :warning: If you want to use `onEvent` in react component without `useEvents` hook, make sure to not add a new listiner on each render.
42
+
43
+ ```ts
44
+ onEvent('eventName', (...args) => console.log('event fired with: ', args));
45
+ ````
46
+
47
+ ### useEvents
48
+ Use to subscribe to events in React components.
49
+ ```tsx
50
+ const { onEvent, emitEvent, removeEvent } = useEvents({ eventName: (...args) => console.log('event fired with: ', args) })
51
+ ```
52
+
53
+ Event name can be: `string`, `number` or `symbol`
54
+ ```ts
55
+ export const Events = {
56
+ C4_TITLE_CHANGE: Symbol(),
57
+ REMOVE_LEFT_CHILD: "remove-element",
58
+ CHANGE_COLOR: 3
59
+ } as const;
60
+ ```
61
+
62
+ You don't need to use `useEvents` hook to emit or remove events.
63
+
64
+ ### emitEvent
65
+ `emitEvent` is a function that emits single event.
66
+
67
+ ```ts
68
+ emitEvent('eventName', 'some data');
69
+ emitEvent('eventWithParams', 1, 2, 3);
70
+ ```
71
+
72
+ There no difference between directly usage of `emitEvent` and `emitEvent` returned from `useEvents` hook.
73
+
74
+ ### removeEvent
75
+ `removeEvent` is a function that removes event listener.
76
+
77
+ ```ts
78
+ const eventHandler = () => console.log('event fired');
79
+ onEvent('eventName', eventHandler);
80
+ removeEvent('eventName', eventHandler);
81
+ ```
12
82
 
13
- ## Usage
14
- [soon]
83
+ There no difference between directly usage of `removeEvent` and `removeEvent` returned from `useEvents` hook.
package/package.json CHANGED
@@ -1,48 +1,48 @@
1
- {
2
- "name": "@alcadur/react-events-hook",
3
- "version": "1.0.0",
4
- "description": "no",
5
- "keywords": [
6
- "react",
7
- "react",
8
- "hook",
9
- "react",
10
- "hooks",
11
- "events",
12
- "events",
13
- "hook"
14
- ],
15
- "homepage": "https://github.com/Alcadur/react-events-hook#readme",
16
- "bugs": {
17
- "url": "https://github.com/Alcadur/react-events-hook/issues"
18
- },
19
- "repository": {
20
- "type": "git",
21
- "url": "git+https://github.com/Alcadur/react-events-hook.git"
22
- },
23
- "license": "MIT",
24
- "author": "Alcadur",
25
- "type": "module",
26
- "main": "index.ts",
27
- "scripts": {
28
- "test": "vitest run"
29
- },
30
- "peerDependencies": {
31
- "react": "*18.0.0"
32
- },
33
- "devDependencies": {
34
- "@rollup/plugin-typescript": "^12.3.0",
35
- "@testing-library/dom": "^10.4.1",
36
- "@testing-library/jest-dom": "^6.9.1",
37
- "@testing-library/react": "^14.3.1",
38
- "@types/react": "^18.3.28",
39
- "@types/react-dom": "^18.3.7",
40
- "@vitejs/plugin-react": "^6.0.1",
41
- "jsdom": "^29.0.2",
42
- "react": "^18.3.1",
43
- "react-dom": "^18.3.1",
44
- "rollup": "^4.59.0",
45
- "typescript": "^5.9.3",
46
- "vitest": "^4.1.3"
47
- }
48
- }
1
+ {
2
+ "name": "@alcadur/react-events-hook",
3
+ "version": "1.0.2",
4
+ "description": "Helps in easy communication between React components as also with external sources",
5
+ "keywords": [
6
+ "react",
7
+ "react",
8
+ "hook",
9
+ "react",
10
+ "hooks",
11
+ "events",
12
+ "events",
13
+ "hook"
14
+ ],
15
+ "homepage": "https://github.com/Alcadur/react-events-hook#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/Alcadur/react-events-hook/issues"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/Alcadur/react-events-hook.git"
22
+ },
23
+ "license": "MIT",
24
+ "author": "Alcadur",
25
+ "type": "module",
26
+ "main": "index.ts",
27
+ "scripts": {
28
+ "test": "vitest run"
29
+ },
30
+ "peerDependencies": {
31
+ "react": "*18.0.0"
32
+ },
33
+ "devDependencies": {
34
+ "@rollup/plugin-typescript": "^12.3.0",
35
+ "@testing-library/dom": "^10.4.1",
36
+ "@testing-library/jest-dom": "^6.9.1",
37
+ "@testing-library/react": "^14.3.1",
38
+ "@types/react": "^18.3.28",
39
+ "@types/react-dom": "^18.3.7",
40
+ "@vitejs/plugin-react": "^6.0.1",
41
+ "jsdom": "^29.0.2",
42
+ "react": "^18.3.1",
43
+ "react-dom": "^18.3.1",
44
+ "rollup": "^4.59.0",
45
+ "typescript": "^5.9.3",
46
+ "vitest": "^4.1.3"
47
+ }
48
+ }
@@ -41,13 +41,20 @@ describe('useEvents', () => {
41
41
 
42
42
  it('should register events from init map', () => {
43
43
  const callback = vi.fn();
44
- renderHook(() => useEvents({ 'init-event': callback }));
44
+ const callbackSymbol = vi.fn();
45
+ const symbolEvent = Symbol('init-event');
46
+ renderHook(() => useEvents({
47
+ 'init-event': callback,
48
+ [symbolEvent]: callbackSymbol
49
+ }));
45
50
 
46
51
  const { result } = renderHook(() => useEvents());
47
52
  act(() => {
48
53
  result.current.emitEvent('init-event', 'init-data');
54
+ result.current.emitEvent(symbolEvent);
49
55
  });
50
56
 
51
57
  expect(callback).toHaveBeenCalledWith('init-data');
58
+ expect(callbackSymbol).toHaveBeenCalled()
52
59
  });
53
60
  });
@@ -7,14 +7,15 @@ export const useEvents = (eventMap: InitEventsType = {}) => {
7
7
  if (!eventMap) {
8
8
  return;
9
9
  }
10
- const eventMapEntries = Object.entries(eventMap);
11
- eventMapEntries.forEach(([event, callback]) => {
12
- onEvent(event, callback)
10
+ const events = [...Object.keys(eventMap), ...Object.getOwnPropertySymbols(eventMap)]
11
+
12
+ events.forEach( event => {
13
+ onEvent(event, eventMap[event])
13
14
  })
14
15
 
15
16
  return () => {
16
- eventMapEntries.forEach(([event, callback]) => {
17
- removeEvent(event, callback)
17
+ events.forEach((event) => {
18
+ removeEvent(event, eventMap[event])
18
19
  })
19
20
  }
20
21
  }, [eventMap])