Skip to content

Commit 20ee2e3

Browse files
committed
fix(context): Add DataViewContext
1 parent 7dd3591 commit 20ee2e3

File tree

3 files changed

+74
-0
lines changed

3 files changed

+74
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import React, {
2+
PropsWithChildren,
3+
createContext,
4+
useCallback,
5+
useState
6+
} from "react";
7+
8+
export const EventTypes = {
9+
rowClick: 'rowClick'
10+
} as const;
11+
12+
export type DataViewEvent = typeof EventTypes[keyof typeof EventTypes];
13+
14+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
15+
type Callback = (...args: any[]) => void;
16+
interface Subscriptions { [id: string]: Callback }
17+
type ContextType = { [event in DataViewEvent]: Subscriptions };
18+
type Subscribe = (event: DataViewEvent, callback: Callback) => () => void;
19+
20+
export const DataViewContext = createContext<{
21+
subscribe: Subscribe;
22+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
23+
trigger: (event: DataViewEvent, ...payload: any[]) => void;
24+
}>({
25+
subscribe: () => () => null,
26+
trigger: () => null
27+
});
28+
29+
export const DataViewProvider = ({ children }: PropsWithChildren) => {
30+
const [ subscriptions, setSubscriptions ] = useState<ContextType>({
31+
[EventTypes.rowClick]: {}
32+
});
33+
34+
const subscribe: Subscribe = (event, callback) => {
35+
const id = crypto.randomUUID();
36+
37+
// set new subscription
38+
setSubscriptions((prevSubscriptions) => ({
39+
...prevSubscriptions,
40+
[event]: { ...prevSubscriptions[event], [id]: callback }
41+
}));
42+
43+
// return unsubscribe function
44+
return () => {
45+
setSubscriptions((prevSubscriptions) => {
46+
const updatedSubscriptions = { ...prevSubscriptions };
47+
delete updatedSubscriptions[event][id];
48+
return updatedSubscriptions;
49+
});
50+
};
51+
};
52+
53+
const trigger = useCallback(
54+
(event: DataViewEvent, ...payload: unknown[]) => {
55+
Object.values(subscriptions[event]).forEach((callback) => {
56+
callback(...payload);
57+
});
58+
},
59+
[ subscriptions ]
60+
);
61+
62+
return (
63+
<DataViewContext.Provider value={{ subscribe, trigger }}>
64+
{children}
65+
</DataViewContext.Provider>
66+
);
67+
};
68+
69+
export default DataViewContext;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default } from './DataViewContext';
2+
export * from './DataViewContext';

packages/module/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,8 @@ export * from './Hooks';
44
export { default as DataViewToolbar } from './DataViewToolbar';
55
export * from './DataViewToolbar';
66

7+
export { default as DataViewContext } from './DataViewContext';
8+
export * from './DataViewContext';
9+
710
export { default as DataView } from './DataView';
811
export * from './DataView';

0 commit comments

Comments
 (0)