react-broadcast-sync 1.5.1 → 1.8.0
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 +59 -11
- package/dist/BroadcastProvider.d.ts +2 -7
- package/dist/index.cjs.js +1 -1
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/types/types.d.ts +17 -0
- package/dist/utils/debug.d.ts +7 -1
- package/package.json +6 -1
- package/.eslintignore +0 -5
- package/.github/workflows/ci.yml +0 -61
- package/.github/workflows/release.yml +0 -39
- package/.husky/pre-commit +0 -5
- package/.nvmrc +0 -1
- package/.prettierignore +0 -4
- package/.prettierrc +0 -9
- package/.releaserc.json +0 -22
- package/CHANGELOG.md +0 -90
- package/assets/react-broadcast-sync-logo.png +0 -0
- package/commitlint.config.js +0 -3
- package/demo/react-broadcast-sync-demo/README.md +0 -130
- package/demo/react-broadcast-sync-demo/index.html +0 -14
- package/demo/react-broadcast-sync-demo/package-lock.json +0 -6379
- package/demo/react-broadcast-sync-demo/package.json +0 -42
- package/demo/react-broadcast-sync-demo/public/assets/react-broadcast-sync-demo-video.gif +0 -0
- package/demo/react-broadcast-sync-demo/public/assets/react-broadcast-sync-logo.png +0 -0
- package/demo/react-broadcast-sync-demo/src/App.tsx +0 -277
- package/demo/react-broadcast-sync-demo/src/components/Counter.tsx +0 -63
- package/demo/react-broadcast-sync-demo/src/components/TextSync.tsx +0 -61
- package/demo/react-broadcast-sync-demo/src/components/TodoList.tsx +0 -186
- package/demo/react-broadcast-sync-demo/src/hooks/useCounterBroadcast.ts +0 -96
- package/demo/react-broadcast-sync-demo/src/hooks/useTextBroadcast.ts +0 -37
- package/demo/react-broadcast-sync-demo/src/hooks/useTodoBroadcast.ts +0 -249
- package/demo/react-broadcast-sync-demo/src/main.tsx +0 -11
- package/demo/react-broadcast-sync-demo/src/theme.ts +0 -62
- package/demo/react-broadcast-sync-demo/tsconfig.json +0 -26
- package/demo/react-broadcast-sync-demo/tsconfig.node.json +0 -10
- package/demo/react-broadcast-sync-demo/vite.config.ts +0 -12
- package/eslint.config.js +0 -38
- package/jest.config.cjs +0 -9
- package/jest.setup.ts +0 -1
- package/rollup.config.mjs +0 -98
- package/src/BroadcastProvider.tsx +0 -80
- package/src/hooks/useBroadcastChannel.ts +0 -464
- package/src/index.ts +0 -9
- package/src/tests/BroadcastProvider.test.tsx +0 -163
- package/src/tests/debug.test.ts +0 -239
- package/src/tests/messageUtils.test.ts +0 -252
- package/src/tests/useBroadcastChannel.same-tab.test.tsx +0 -992
- package/src/tests/useBroadcastChannel.test.tsx +0 -1243
- package/src/types/types.ts +0 -124
- package/src/utils/debug.ts +0 -54
- package/src/utils/messageUtils.ts +0 -122
- package/tsconfig.json +0 -36
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom hook for managing counter state synchronization across browser tabs.
|
|
3
|
-
*
|
|
4
|
-
* This hook provides functionality for:
|
|
5
|
-
* 1. Synchronizing a counter value across multiple browser tabs
|
|
6
|
-
* 2. Broadcasting hover state for visual feedback
|
|
7
|
-
* 3. Maintaining consistent state across all instances
|
|
8
|
-
*
|
|
9
|
-
* @returns {Object} Counter state and handlers
|
|
10
|
-
* @property {number} count - Current counter value
|
|
11
|
-
* @property {boolean} isHovered - Whether the counter is currently hovered
|
|
12
|
-
* @property {Function} increment - Function to increment the counter
|
|
13
|
-
* @property {Function} decrement - Function to decrement the counter
|
|
14
|
-
* @property {Function} handleMouseEnter - Function to handle mouse enter event
|
|
15
|
-
* @property {Function} handleMouseLeave - Function to handle mouse leave event
|
|
16
|
-
*/
|
|
17
|
-
import { useState, useEffect, useRef } from 'react';
|
|
18
|
-
import { useBroadcastChannel } from 'react-broadcast-sync';
|
|
19
|
-
|
|
20
|
-
export const useCounterBroadcast = () => {
|
|
21
|
-
const { messages, postMessage } = useBroadcastChannel('counter', {
|
|
22
|
-
keepLatestMessage: true,
|
|
23
|
-
namespace: 'demo-app',
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const [count, setCount] = useState<number>(0);
|
|
27
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
28
|
-
const [showCheckmark, setShowCheckmark] = useState(false);
|
|
29
|
-
const lastTimestampRef = useRef<number>(0);
|
|
30
|
-
|
|
31
|
-
const syncTimeoutRef = useRef<NodeJS.Timeout>();
|
|
32
|
-
const checkmarkTimeoutRef = useRef<NodeJS.Timeout>();
|
|
33
|
-
|
|
34
|
-
// Update count when new messages arrive
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
const lastMessage = messages[messages.length - 1];
|
|
37
|
-
if (lastMessage?.message !== undefined && lastMessage.timestamp > lastTimestampRef.current) {
|
|
38
|
-
// Clear any existing timeouts
|
|
39
|
-
if (syncTimeoutRef.current) {
|
|
40
|
-
clearTimeout(syncTimeoutRef.current);
|
|
41
|
-
}
|
|
42
|
-
if (checkmarkTimeoutRef.current) {
|
|
43
|
-
clearTimeout(checkmarkTimeoutRef.current);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Reset states
|
|
47
|
-
setIsSyncing(true);
|
|
48
|
-
setShowCheckmark(false);
|
|
49
|
-
|
|
50
|
-
// Update count and timestamp
|
|
51
|
-
setCount(lastMessage.message);
|
|
52
|
-
lastTimestampRef.current = lastMessage.timestamp;
|
|
53
|
-
|
|
54
|
-
// Show checkmark after a short delay
|
|
55
|
-
syncTimeoutRef.current = setTimeout(() => {
|
|
56
|
-
setIsSyncing(false);
|
|
57
|
-
setShowCheckmark(true);
|
|
58
|
-
|
|
59
|
-
// Hide checkmark after showing it
|
|
60
|
-
checkmarkTimeoutRef.current = setTimeout(() => {
|
|
61
|
-
setShowCheckmark(false);
|
|
62
|
-
}, 1000);
|
|
63
|
-
}, 500);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Cleanup
|
|
67
|
-
return () => {
|
|
68
|
-
if (syncTimeoutRef.current) {
|
|
69
|
-
clearTimeout(syncTimeoutRef.current);
|
|
70
|
-
}
|
|
71
|
-
if (checkmarkTimeoutRef.current) {
|
|
72
|
-
clearTimeout(checkmarkTimeoutRef.current);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}, [messages]);
|
|
76
|
-
|
|
77
|
-
const increment = () => {
|
|
78
|
-
const newCount = count + 1;
|
|
79
|
-
setCount(newCount);
|
|
80
|
-
postMessage('counter', newCount);
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
const decrement = () => {
|
|
84
|
-
const newCount = count - 1;
|
|
85
|
-
setCount(newCount);
|
|
86
|
-
postMessage('counter', newCount);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
return {
|
|
90
|
-
count,
|
|
91
|
-
increment,
|
|
92
|
-
decrement,
|
|
93
|
-
isSyncing,
|
|
94
|
-
showCheckmark,
|
|
95
|
-
};
|
|
96
|
-
};
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { useState, useEffect } from 'react';
|
|
2
|
-
import { useBroadcastChannel } from 'react-broadcast-sync';
|
|
3
|
-
|
|
4
|
-
export const useTextBroadcast = () => {
|
|
5
|
-
const { messages, postMessage } = useBroadcastChannel('text', {
|
|
6
|
-
keepLatestMessage: true,
|
|
7
|
-
namespace: 'demo-app',
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const lastMessage = messages[messages.length - 1];
|
|
11
|
-
const [localText, setLocalText] = useState<string>(lastMessage ? lastMessage.message : '');
|
|
12
|
-
|
|
13
|
-
// Update local state when new messages arrive
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
if (lastMessage) {
|
|
16
|
-
setLocalText(lastMessage.message);
|
|
17
|
-
}
|
|
18
|
-
}, [lastMessage]);
|
|
19
|
-
|
|
20
|
-
// Initialize text if no messages exist
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
if (messages.length === 0) {
|
|
23
|
-
postMessage('text', '');
|
|
24
|
-
}
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
28
|
-
const newText = event.target.value;
|
|
29
|
-
setLocalText(newText); // Update local state immediately
|
|
30
|
-
postMessage('text', newText); // Broadcast to other tabs
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
return {
|
|
34
|
-
localText,
|
|
35
|
-
handleChange,
|
|
36
|
-
};
|
|
37
|
-
};
|
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom hook for managing todo list synchronization across browser tabs.
|
|
3
|
-
*
|
|
4
|
-
* This hook provides functionality for:
|
|
5
|
-
* 1. Synchronizing todo items across multiple browser tabs
|
|
6
|
-
* 2. Broadcasting hover states for visual feedback
|
|
7
|
-
* 3. Synchronizing scroll position across tabs
|
|
8
|
-
* 4. Managing todo item completion status
|
|
9
|
-
*
|
|
10
|
-
* @returns {Object} Todo list state and handlers
|
|
11
|
-
* @property {Todo[]} todos - Array of todo items
|
|
12
|
-
* @property {string} newTodo - Current input value for new todo
|
|
13
|
-
* @property {Function} setNewTodo - Function to update new todo input
|
|
14
|
-
* @property {number|null} hoveredTodoId - ID of currently hovered todo
|
|
15
|
-
* @property {boolean} isScrolling - Whether the list is currently scrolling
|
|
16
|
-
* @property {boolean} isSyncing - Whether scroll sync is in progress
|
|
17
|
-
* @property {boolean} showCheckmark - Whether to show sync completion indicator
|
|
18
|
-
* @property {React.RefObject} scrollContainerRef - Ref for the scroll container
|
|
19
|
-
* @property {Function} handleScroll - Function to handle scroll events
|
|
20
|
-
* @property {Function} addTodo - Function to add a new todo
|
|
21
|
-
* @property {Function} toggleTodo - Function to toggle todo completion
|
|
22
|
-
* @property {Function} handleTodoMouseEnter - Function to handle todo hover
|
|
23
|
-
* @property {Function} handleTodoMouseLeave - Function to handle todo unhover
|
|
24
|
-
*/
|
|
25
|
-
import { useState, useEffect, useRef } from 'react';
|
|
26
|
-
import { useBroadcastChannel } from 'react-broadcast-sync';
|
|
27
|
-
|
|
28
|
-
interface Todo {
|
|
29
|
-
id: string;
|
|
30
|
-
text: string;
|
|
31
|
-
completed: boolean;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Hook for managing todo list synchronization across browser tabs.
|
|
36
|
-
* Provides real-time todo updates, completion status tracking, and scroll position sync.
|
|
37
|
-
*
|
|
38
|
-
* @returns {Object} Todo state and handlers
|
|
39
|
-
* @property {Todo[]} todos - List of todos
|
|
40
|
-
* @property {string} newTodo - New todo input value
|
|
41
|
-
* @property {Function} handleNewTodoChange - Function to handle new todo input changes
|
|
42
|
-
* @property {Function} handleAddTodo - Function to add a new todo
|
|
43
|
-
* @property {Function} handleToggleTodo - Function to toggle todo completion
|
|
44
|
-
* @property {Function} handleDeleteTodo - Function to delete a todo
|
|
45
|
-
* @property {Function} handleScroll - Function to handle scroll position sync
|
|
46
|
-
*/
|
|
47
|
-
export const useTodoBroadcast = () => {
|
|
48
|
-
const { messages, postMessage } = useBroadcastChannel('todos', {
|
|
49
|
-
keepLatestMessage: true,
|
|
50
|
-
namespace: 'demo-app',
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Add hover state broadcast channel
|
|
54
|
-
const { messages: hoverMessages, postMessage: postHoverMessage } = useBroadcastChannel(
|
|
55
|
-
'todos-hover',
|
|
56
|
-
{
|
|
57
|
-
keepLatestMessage: true,
|
|
58
|
-
namespace: 'demo-app',
|
|
59
|
-
}
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
// Add scroll position broadcast channel
|
|
63
|
-
const { messages: scrollMessages, postMessage: postScrollMessage } = useBroadcastChannel(
|
|
64
|
-
'todos-scroll',
|
|
65
|
-
{
|
|
66
|
-
keepLatestMessage: true,
|
|
67
|
-
namespace: 'demo-app',
|
|
68
|
-
}
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
const lastMessage = messages[messages.length - 1];
|
|
72
|
-
const lastHoverMessage = hoverMessages[hoverMessages.length - 1];
|
|
73
|
-
const lastScrollMessage = scrollMessages[scrollMessages.length - 1];
|
|
74
|
-
|
|
75
|
-
const [todos, setTodos] = useState<Todo[]>(lastMessage ? lastMessage.message : []);
|
|
76
|
-
const [newTodo, setNewTodo] = useState('');
|
|
77
|
-
const [hoveredTodoId, setHoveredTodoId] = useState<string | null>(
|
|
78
|
-
lastHoverMessage ? lastHoverMessage.message : null
|
|
79
|
-
);
|
|
80
|
-
const [isScrolling, setIsScrolling] = useState(false);
|
|
81
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
82
|
-
const [showCheckmark, setShowCheckmark] = useState(false);
|
|
83
|
-
|
|
84
|
-
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
85
|
-
const scrollTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
|
86
|
-
const syncTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
|
87
|
-
const checkmarkTimeoutRef = useRef<ReturnType<typeof setTimeout>>();
|
|
88
|
-
|
|
89
|
-
// Update local state when new messages arrive
|
|
90
|
-
useEffect(() => {
|
|
91
|
-
if (lastMessage) {
|
|
92
|
-
setTodos(lastMessage.message);
|
|
93
|
-
}
|
|
94
|
-
}, [lastMessage]);
|
|
95
|
-
|
|
96
|
-
// Update hover state when new hover messages arrive
|
|
97
|
-
useEffect(() => {
|
|
98
|
-
if (lastHoverMessage) {
|
|
99
|
-
setHoveredTodoId(lastHoverMessage.message);
|
|
100
|
-
}
|
|
101
|
-
}, [lastHoverMessage]);
|
|
102
|
-
|
|
103
|
-
// Update scroll position when new scroll messages arrive
|
|
104
|
-
useEffect(() => {
|
|
105
|
-
if (lastScrollMessage && scrollContainerRef.current) {
|
|
106
|
-
// Clear any existing timeouts
|
|
107
|
-
if (syncTimeoutRef.current) {
|
|
108
|
-
clearTimeout(syncTimeoutRef.current);
|
|
109
|
-
}
|
|
110
|
-
if (checkmarkTimeoutRef.current) {
|
|
111
|
-
clearTimeout(checkmarkTimeoutRef.current);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Reset states
|
|
115
|
-
setIsSyncing(true);
|
|
116
|
-
setShowCheckmark(false);
|
|
117
|
-
setIsScrolling(false);
|
|
118
|
-
|
|
119
|
-
// Perform scroll
|
|
120
|
-
scrollContainerRef.current.scrollTo({
|
|
121
|
-
top: lastScrollMessage.message,
|
|
122
|
-
behavior: 'smooth',
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
// Listen for scroll end
|
|
126
|
-
const handleScrollEnd = () => {
|
|
127
|
-
setIsSyncing(false);
|
|
128
|
-
setShowCheckmark(true);
|
|
129
|
-
|
|
130
|
-
// Hide indicator after showing checkmark
|
|
131
|
-
checkmarkTimeoutRef.current = setTimeout(() => {
|
|
132
|
-
setShowCheckmark(false);
|
|
133
|
-
}, 1000);
|
|
134
|
-
|
|
135
|
-
// Remove the event listener
|
|
136
|
-
scrollContainerRef.current?.removeEventListener('scrollend', handleScrollEnd);
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
// Add scroll end listener
|
|
140
|
-
scrollContainerRef.current.addEventListener('scrollend', handleScrollEnd);
|
|
141
|
-
|
|
142
|
-
// Fallback timeout in case scrollend event doesn't fire
|
|
143
|
-
syncTimeoutRef.current = setTimeout(() => {
|
|
144
|
-
handleScrollEnd();
|
|
145
|
-
}, 500);
|
|
146
|
-
|
|
147
|
-
// Cleanup
|
|
148
|
-
return () => {
|
|
149
|
-
scrollContainerRef.current?.removeEventListener('scrollend', handleScrollEnd);
|
|
150
|
-
if (syncTimeoutRef.current) {
|
|
151
|
-
clearTimeout(syncTimeoutRef.current);
|
|
152
|
-
}
|
|
153
|
-
if (checkmarkTimeoutRef.current) {
|
|
154
|
-
clearTimeout(checkmarkTimeoutRef.current);
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
}, [lastScrollMessage]);
|
|
159
|
-
|
|
160
|
-
// Initialize todos if no messages exist
|
|
161
|
-
useEffect(() => {
|
|
162
|
-
if (messages.length === 0) {
|
|
163
|
-
postMessage('todos', []);
|
|
164
|
-
}
|
|
165
|
-
}, []);
|
|
166
|
-
|
|
167
|
-
const handleScrollSync = (e: React.UIEvent<HTMLDivElement>) => {
|
|
168
|
-
const newScrollPosition = e.currentTarget.scrollTop;
|
|
169
|
-
|
|
170
|
-
// Clear any existing timeouts
|
|
171
|
-
if (scrollTimeoutRef.current) {
|
|
172
|
-
clearTimeout(scrollTimeoutRef.current);
|
|
173
|
-
}
|
|
174
|
-
if (syncTimeoutRef.current) {
|
|
175
|
-
clearTimeout(syncTimeoutRef.current);
|
|
176
|
-
}
|
|
177
|
-
if (checkmarkTimeoutRef.current) {
|
|
178
|
-
clearTimeout(checkmarkTimeoutRef.current);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
// Reset states
|
|
182
|
-
setIsScrolling(true);
|
|
183
|
-
setIsSyncing(true);
|
|
184
|
-
setShowCheckmark(false);
|
|
185
|
-
|
|
186
|
-
// Debounce the scroll message to avoid too many updates
|
|
187
|
-
scrollTimeoutRef.current = setTimeout(() => {
|
|
188
|
-
postScrollMessage('todos-scroll', newScrollPosition);
|
|
189
|
-
}, 100);
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
const handleNewTodoChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
193
|
-
setNewTodo(event.target.value);
|
|
194
|
-
};
|
|
195
|
-
|
|
196
|
-
const handleAddTodo = (event: React.FormEvent) => {
|
|
197
|
-
event.preventDefault();
|
|
198
|
-
if (newTodo.trim()) {
|
|
199
|
-
const updated = [
|
|
200
|
-
...todos,
|
|
201
|
-
{ id: Date.now().toString(), text: newTodo.trim(), completed: false },
|
|
202
|
-
];
|
|
203
|
-
setTodos(updated);
|
|
204
|
-
postMessage('todos', updated);
|
|
205
|
-
setNewTodo('');
|
|
206
|
-
}
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const handleToggleTodo = (id: string) => {
|
|
210
|
-
const updated = todos.map(todo =>
|
|
211
|
-
todo.id === id ? { ...todo, completed: !todo.completed } : todo
|
|
212
|
-
);
|
|
213
|
-
setTodos(updated);
|
|
214
|
-
postMessage('todos', updated);
|
|
215
|
-
};
|
|
216
|
-
|
|
217
|
-
const handleDeleteTodo = (id: string) => {
|
|
218
|
-
const updated = todos.filter(todo => todo.id !== id);
|
|
219
|
-
setTodos(updated);
|
|
220
|
-
postMessage('todos', updated);
|
|
221
|
-
};
|
|
222
|
-
|
|
223
|
-
const handleTodoMouseEnter = (id: string) => {
|
|
224
|
-
setHoveredTodoId(id);
|
|
225
|
-
postHoverMessage('todos-hover', id);
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const handleTodoMouseLeave = () => {
|
|
229
|
-
setHoveredTodoId(null);
|
|
230
|
-
postHoverMessage('todos-hover', null);
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
return {
|
|
234
|
-
todos,
|
|
235
|
-
newTodo,
|
|
236
|
-
handleNewTodoChange,
|
|
237
|
-
handleAddTodo,
|
|
238
|
-
handleToggleTodo,
|
|
239
|
-
handleDeleteTodo,
|
|
240
|
-
handleScrollSync,
|
|
241
|
-
hoveredTodoId,
|
|
242
|
-
isScrolling,
|
|
243
|
-
isSyncing,
|
|
244
|
-
showCheckmark,
|
|
245
|
-
scrollContainerRef,
|
|
246
|
-
handleTodoMouseEnter,
|
|
247
|
-
handleTodoMouseLeave,
|
|
248
|
-
};
|
|
249
|
-
};
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom/client';
|
|
3
|
-
import App from './App';
|
|
4
|
-
import { CssBaseline } from '@mui/material';
|
|
5
|
-
|
|
6
|
-
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
7
|
-
<React.StrictMode>
|
|
8
|
-
<CssBaseline />
|
|
9
|
-
<App />
|
|
10
|
-
</React.StrictMode>
|
|
11
|
-
);
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { createTheme } from '@mui/material/styles';
|
|
2
|
-
|
|
3
|
-
export const theme = createTheme({
|
|
4
|
-
palette: {
|
|
5
|
-
primary: {
|
|
6
|
-
main: '#5EC13D',
|
|
7
|
-
dark: '#3FAD3A',
|
|
8
|
-
contrastText: '#fff',
|
|
9
|
-
},
|
|
10
|
-
secondary: {
|
|
11
|
-
main: '#3FAD3A',
|
|
12
|
-
contrastText: '#fff',
|
|
13
|
-
},
|
|
14
|
-
background: {
|
|
15
|
-
default: '#0D1117',
|
|
16
|
-
paper: '#161B22',
|
|
17
|
-
},
|
|
18
|
-
text: {
|
|
19
|
-
primary: '#fff',
|
|
20
|
-
secondary: '#bdbdbd',
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
typography: {
|
|
24
|
-
fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif',
|
|
25
|
-
h1: {
|
|
26
|
-
fontWeight: 700,
|
|
27
|
-
},
|
|
28
|
-
h2: {
|
|
29
|
-
fontWeight: 600,
|
|
30
|
-
},
|
|
31
|
-
h3: {
|
|
32
|
-
fontWeight: 600,
|
|
33
|
-
},
|
|
34
|
-
h4: {
|
|
35
|
-
fontWeight: 600,
|
|
36
|
-
},
|
|
37
|
-
h5: {
|
|
38
|
-
fontWeight: 600,
|
|
39
|
-
},
|
|
40
|
-
h6: {
|
|
41
|
-
fontWeight: 600,
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
components: {
|
|
45
|
-
MuiButton: {
|
|
46
|
-
styleOverrides: {
|
|
47
|
-
root: {
|
|
48
|
-
textTransform: 'none',
|
|
49
|
-
borderRadius: 8,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
MuiPaper: {
|
|
54
|
-
styleOverrides: {
|
|
55
|
-
root: {
|
|
56
|
-
borderRadius: 12,
|
|
57
|
-
background: '#161B22',
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
});
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2020",
|
|
4
|
-
"useDefineForClassFields": true,
|
|
5
|
-
"types": ["node"],
|
|
6
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
|
|
10
|
-
/* Bundler mode */
|
|
11
|
-
"moduleResolution": "bundler",
|
|
12
|
-
"allowImportingTsExtensions": true,
|
|
13
|
-
"resolveJsonModule": true,
|
|
14
|
-
"isolatedModules": true,
|
|
15
|
-
"noEmit": true,
|
|
16
|
-
"jsx": "react-jsx",
|
|
17
|
-
|
|
18
|
-
/* Linting */
|
|
19
|
-
"strict": true,
|
|
20
|
-
"noUnusedLocals": true,
|
|
21
|
-
"noUnusedParameters": true,
|
|
22
|
-
"noFallthroughCasesInSwitch": true
|
|
23
|
-
},
|
|
24
|
-
"include": ["src"],
|
|
25
|
-
"references": [{ "path": "./tsconfig.node.json" }]
|
|
26
|
-
}
|
package/eslint.config.js
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import eslint from '@eslint/js';
|
|
2
|
-
import tseslint from 'typescript-eslint';
|
|
3
|
-
import reactPlugin from 'eslint-plugin-react';
|
|
4
|
-
import reactHooksPlugin from 'eslint-plugin-react-hooks';
|
|
5
|
-
import prettierPlugin from 'eslint-plugin-prettier';
|
|
6
|
-
|
|
7
|
-
export default [
|
|
8
|
-
eslint.configs.recommended,
|
|
9
|
-
...tseslint.configs.recommended,
|
|
10
|
-
{
|
|
11
|
-
files: ['src/**/*.{ts,tsx}', 'demo/**/*.{ts,tsx}'],
|
|
12
|
-
plugins: {
|
|
13
|
-
react: reactPlugin,
|
|
14
|
-
'react-hooks': reactHooksPlugin,
|
|
15
|
-
prettier: prettierPlugin,
|
|
16
|
-
},
|
|
17
|
-
rules: {
|
|
18
|
-
'react/react-in-jsx-scope': 'off',
|
|
19
|
-
'react/prop-types': 'off',
|
|
20
|
-
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_' }],
|
|
21
|
-
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
|
22
|
-
'@typescript-eslint/no-explicit-any': [
|
|
23
|
-
'warn',
|
|
24
|
-
{
|
|
25
|
-
ignoreRestArgs: true,
|
|
26
|
-
fixToUnknown: false,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
'prettier/prettier': 'error',
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
files: ['**/*.test.{ts,tsx}', '**/*.d.ts'],
|
|
34
|
-
rules: {
|
|
35
|
-
'@typescript-eslint/no-explicit-any': 'off',
|
|
36
|
-
},
|
|
37
|
-
},
|
|
38
|
-
];
|
package/jest.config.cjs
DELETED
package/jest.setup.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '@testing-library/jest-dom';
|
package/rollup.config.mjs
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import babel from '@rollup/plugin-babel';
|
|
2
|
-
import resolve from '@rollup/plugin-node-resolve';
|
|
3
|
-
import commonjs from '@rollup/plugin-commonjs';
|
|
4
|
-
import typescript from '@rollup/plugin-typescript';
|
|
5
|
-
import peerDepsExternal from 'rollup-plugin-peer-deps-external';
|
|
6
|
-
import terser from '@rollup/plugin-terser';
|
|
7
|
-
|
|
8
|
-
const external = [
|
|
9
|
-
'react',
|
|
10
|
-
'react-dom',
|
|
11
|
-
'react/jsx-runtime',
|
|
12
|
-
/^react\//,
|
|
13
|
-
/^react-dom\//,
|
|
14
|
-
'typescript',
|
|
15
|
-
'tslib',
|
|
16
|
-
'@babel/runtime',
|
|
17
|
-
];
|
|
18
|
-
|
|
19
|
-
export default {
|
|
20
|
-
input: 'src/index.ts',
|
|
21
|
-
output: [
|
|
22
|
-
{
|
|
23
|
-
file: 'dist/index.esm.js',
|
|
24
|
-
format: 'es',
|
|
25
|
-
sourcemap: true,
|
|
26
|
-
globals: {
|
|
27
|
-
react: 'React',
|
|
28
|
-
'react-dom': 'ReactDOM',
|
|
29
|
-
typescript: 'ts',
|
|
30
|
-
tslib: 'tslib',
|
|
31
|
-
'@babel/runtime': 'babelRuntime',
|
|
32
|
-
},
|
|
33
|
-
exports: 'named',
|
|
34
|
-
},
|
|
35
|
-
{
|
|
36
|
-
file: 'dist/index.cjs.js',
|
|
37
|
-
format: 'cjs',
|
|
38
|
-
sourcemap: true,
|
|
39
|
-
globals: {
|
|
40
|
-
react: 'React',
|
|
41
|
-
'react-dom': 'ReactDOM',
|
|
42
|
-
typescript: 'ts',
|
|
43
|
-
tslib: 'tslib',
|
|
44
|
-
'@babel/runtime': 'babelRuntime',
|
|
45
|
-
},
|
|
46
|
-
exports: 'named',
|
|
47
|
-
},
|
|
48
|
-
],
|
|
49
|
-
plugins: [
|
|
50
|
-
peerDepsExternal({
|
|
51
|
-
includeDependencies: false,
|
|
52
|
-
}),
|
|
53
|
-
resolve({
|
|
54
|
-
mainFields: ['module', 'main'],
|
|
55
|
-
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
56
|
-
preferBuiltins: true,
|
|
57
|
-
dedupe: ['react', 'react-dom'],
|
|
58
|
-
}),
|
|
59
|
-
commonjs({
|
|
60
|
-
include: /node_modules/,
|
|
61
|
-
transformMixedEsModules: true,
|
|
62
|
-
requireReturnsDefault: 'auto',
|
|
63
|
-
}),
|
|
64
|
-
typescript({
|
|
65
|
-
tsconfig: './tsconfig.json',
|
|
66
|
-
exclude: ['**/__tests__/**', '**/*.test.ts', '**/*.test.tsx'],
|
|
67
|
-
declaration: true,
|
|
68
|
-
declarationDir: './dist',
|
|
69
|
-
emitDeclarationOnly: false,
|
|
70
|
-
sourceMap: true,
|
|
71
|
-
}),
|
|
72
|
-
babel({
|
|
73
|
-
babelHelpers: 'runtime',
|
|
74
|
-
presets: [
|
|
75
|
-
[
|
|
76
|
-
'@babel/preset-react',
|
|
77
|
-
{
|
|
78
|
-
runtime: 'automatic',
|
|
79
|
-
development: process.env.NODE_ENV === 'development',
|
|
80
|
-
},
|
|
81
|
-
],
|
|
82
|
-
],
|
|
83
|
-
plugins: [
|
|
84
|
-
[
|
|
85
|
-
'@babel/plugin-transform-runtime',
|
|
86
|
-
{
|
|
87
|
-
regenerator: true,
|
|
88
|
-
useESModules: true,
|
|
89
|
-
},
|
|
90
|
-
],
|
|
91
|
-
],
|
|
92
|
-
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
93
|
-
exclude: 'node_modules/**',
|
|
94
|
-
}),
|
|
95
|
-
terser(),
|
|
96
|
-
],
|
|
97
|
-
external,
|
|
98
|
-
};
|