@edusight/notification-widget 1.0.18 โ 1.0.28
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/CHANGELOG.md +6 -0
- package/README.md +764 -52
- package/dist/components-BJ465mfK.js +1534 -0
- package/dist/components-BJ465mfK.js.map +1 -0
- package/dist/components-ytSNU0U3.cjs +72 -0
- package/dist/components-ytSNU0U3.cjs.map +1 -0
- package/dist/hooks-CACL0Qzv.cjs +2 -0
- package/dist/hooks-CACL0Qzv.cjs.map +1 -0
- package/dist/hooks-DQflK_dw.js +160 -0
- package/dist/hooks-DQflK_dw.js.map +1 -0
- package/dist/index.cjs.js +2 -46
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.css +1 -0
- package/dist/index.d.ts +245 -19
- package/dist/index.esm.js +679 -5027
- package/dist/index.esm.js.map +1 -1
- package/package.json +33 -22
- package/dist/components/EmptyState.d.ts +0 -7
- package/dist/components/EmptyState.d.ts.map +0 -1
- package/dist/components/NotificationBell.d.ts +0 -8
- package/dist/components/NotificationBell.d.ts.map +0 -1
- package/dist/components/NotificationCenter.d.ts +0 -19
- package/dist/components/NotificationCenter.d.ts.map +0 -1
- package/dist/components/NotificationGroup.d.ts +0 -13
- package/dist/components/NotificationGroup.d.ts.map +0 -1
- package/dist/components/NotificationItem.d.ts +0 -10
- package/dist/components/NotificationItem.d.ts.map +0 -1
- package/dist/components/NotificationList.d.ts +0 -16
- package/dist/components/NotificationList.d.ts.map +0 -1
- package/dist/components/Preferences.d.ts +0 -10
- package/dist/components/Preferences.d.ts.map +0 -1
- package/dist/hooks/useNotificationCenter.d.ts +0 -23
- package/dist/hooks/useNotificationCenter.d.ts.map +0 -1
- package/dist/hooks/useNotifications.d.ts +0 -22
- package/dist/hooks/useNotifications.d.ts.map +0 -1
- package/dist/hooks/useWebSocket.d.ts +0 -21
- package/dist/hooks/useWebSocket.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/interfaces/notification-client.interface.d.ts +0 -3
- package/dist/interfaces/notification-client.interface.d.ts.map +0 -1
- package/dist/notification-widget.css +0 -1
- package/dist/services/notification-service.d.ts +0 -9
- package/dist/services/notification-service.d.ts.map +0 -1
- package/dist/services/websocket-service.d.ts +0 -36
- package/dist/services/websocket-service.d.ts.map +0 -1
- package/dist/theme/notification-theme.d.ts +0 -3
- package/dist/theme/notification-theme.d.ts.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
# EduSight Notification Widget
|
|
2
2
|
|
|
3
|
-
React notification center widget with
|
|
3
|
+
A modern, accessible React notification center widget built with clean architecture principles, featuring real-time updates, comprehensive notification management, and SDK dependency injection.
|
|
4
|
+
|
|
5
|
+
## โจ Version 3.0.0 Features
|
|
6
|
+
|
|
7
|
+
- ๐๏ธ **Refactored Architecture** - Clean architecture with dependency injection and separation of concerns
|
|
8
|
+
- ๐ **SDK Integration** - Direct integration with @edusight/notification-sdk using dependency injection pattern
|
|
9
|
+
- ๐ **Performance Optimized** - Code splitting, memoization, and optimized bundle size (<25KB gzipped)
|
|
10
|
+
- โฟ **Enhanced Accessibility** - WCAG 2.1 AA compliance with improved keyboard navigation
|
|
11
|
+
- ๐ **Dynamic Theming** - Runtime theme switching with dark mode support
|
|
12
|
+
- ๐ฑ **Responsive Design** - Mobile-first approach with responsive breakpoints
|
|
13
|
+
- ๐ก๏ธ **Error Boundaries** - Comprehensive error handling with fallback components
|
|
14
|
+
- ๐ **Real-time Sync** - WebSocket integration with fallback polling and cross-tab synchronization
|
|
15
|
+
- ๐งช **Comprehensive Testing** - Unit, integration, and accessibility tests with >90% coverage
|
|
16
|
+
|
|
17
|
+
## Features
|
|
18
|
+
|
|
19
|
+
- ๐ **Real-time Updates** - WebSocket integration with automatic reconnection and fallback polling
|
|
20
|
+
- ๐ฑ **Responsive Design** - Works seamlessly on desktop, tablet, and mobile
|
|
21
|
+
- โ
**Full CRUD Operations** - Mark as read/unread, archive, delete with optimistic updates
|
|
22
|
+
- ๐จ **Customizable UI** - Dynamic theme support with CSS variables
|
|
23
|
+
- ๐ **SDK Integration** - Direct integration with @edusight/notification-sdk using dependency injection
|
|
24
|
+
- โฟ **Accessibility** - Full WCAG 2.1 compliance with keyboard navigation
|
|
25
|
+
- ๐ **Performance** - Lazy loading, memoization, and optimized re-renders
|
|
26
|
+
- ๐ **Multi-tenant** - Built-in tenant and environment scoping
|
|
27
|
+
- ๐ก๏ธ **Error Boundaries** - Component-level error boundaries with fallback UI
|
|
28
|
+
- โ๏ธ **Live Preferences** - Real-time preference management with debounced saving
|
|
29
|
+
- ๐ **Cross-tab Sync** - Synchronization across multiple browser tabs
|
|
30
|
+
- ๐ฏ **Clean Architecture** - Separation of concerns with dependency injection pattern
|
|
4
31
|
|
|
5
32
|
## Installation
|
|
6
33
|
|
|
@@ -8,73 +35,758 @@ React notification center widget with Material UI styling.
|
|
|
8
35
|
npm install @edusight/notification-widget
|
|
9
36
|
```
|
|
10
37
|
|
|
11
|
-
|
|
38
|
+
### Peer Dependencies
|
|
39
|
+
|
|
40
|
+
The widget requires React 18+ as a peer dependency:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install react@^18.2.0 react-dom@^18.2.0
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Styles
|
|
47
|
+
|
|
48
|
+
Import the widget styles in your application:
|
|
12
49
|
|
|
13
50
|
```tsx
|
|
14
|
-
import
|
|
15
|
-
|
|
51
|
+
import '@edusight/notification-widget/styles';
|
|
52
|
+
// or
|
|
53
|
+
import '@edusight/notification-widget/styles.css';
|
|
54
|
+
```
|
|
16
55
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
56
|
+
## Quick Start
|
|
57
|
+
|
|
58
|
+
### Basic Setup with NotificationWidget
|
|
59
|
+
|
|
60
|
+
The main component that provides a complete notification center experience:
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { NotificationWidget } from '@edusight/notification-widget';
|
|
64
|
+
import '@edusight/notification-widget/styles';
|
|
25
65
|
|
|
26
66
|
function App() {
|
|
27
67
|
return (
|
|
28
|
-
<
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
68
|
+
<NotificationWidget
|
|
69
|
+
sdkConfig={{
|
|
70
|
+
apiKey: 'your-api-key',
|
|
71
|
+
baseUrl: 'https://api.example.com',
|
|
72
|
+
subscriberId: 'user-123',
|
|
73
|
+
tenantId: 'your-tenant',
|
|
74
|
+
environmentId: 'production',
|
|
75
|
+
environment: 'production',
|
|
76
|
+
}}
|
|
77
|
+
position="right"
|
|
78
|
+
size="medium"
|
|
79
|
+
theme="light"
|
|
80
|
+
onError={(error) => console.error('Widget error:', error)}
|
|
35
81
|
/>
|
|
36
82
|
);
|
|
37
83
|
}
|
|
38
84
|
```
|
|
39
85
|
|
|
40
|
-
|
|
86
|
+
### Development Setup
|
|
41
87
|
|
|
42
|
-
|
|
88
|
+
For development, you can use the playground environment:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd playground
|
|
92
|
+
npm install
|
|
93
|
+
npm run dev
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The playground provides a complete testing environment with:
|
|
97
|
+
- Mock data for offline development
|
|
98
|
+
- Real-time WebSocket simulation
|
|
99
|
+
- All widget features and configurations
|
|
100
|
+
- Debug logging and status monitoring
|
|
101
|
+
|
|
102
|
+
## Core Concepts
|
|
103
|
+
|
|
104
|
+
### NotificationWidget
|
|
105
|
+
|
|
106
|
+
The main widget component that provides a complete notification center with SDK dependency injection:
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { NotificationWidget } from '@edusight/notification-widget';
|
|
110
|
+
|
|
111
|
+
<NotificationWidget
|
|
112
|
+
sdkConfig={{
|
|
113
|
+
apiKey: 'your-api-key',
|
|
114
|
+
baseUrl: 'https://api.example.com',
|
|
115
|
+
subscriberId: 'user-123',
|
|
116
|
+
websocketUrl: 'wss://api.example.com',
|
|
117
|
+
environment: 'production',
|
|
118
|
+
}}
|
|
119
|
+
position="right"
|
|
120
|
+
size="medium"
|
|
121
|
+
theme="light"
|
|
122
|
+
className="custom-widget-class"
|
|
123
|
+
onError={(error) => console.error('Widget error:', error)}
|
|
124
|
+
/>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Props:**
|
|
128
|
+
- `sdkConfig`: `SDKConfiguration` - SDK configuration for dependency injection
|
|
129
|
+
- `position`: `'left' | 'right'` - Popover position relative to bell (default: 'right')
|
|
130
|
+
- `size`: `'small' | 'medium' | 'large'` - Widget size (default: 'medium')
|
|
131
|
+
- `theme`: `'light' | 'dark'` - Theme mode (default: 'light')
|
|
132
|
+
- `className`: `string` - Additional CSS classes
|
|
133
|
+
- `onError`: `(error: Error) => void` - Error handler callback
|
|
134
|
+
|
|
135
|
+
### SDK Configuration
|
|
136
|
+
|
|
137
|
+
The widget uses dependency injection to integrate with the EduSight Notification SDK:
|
|
43
138
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
139
|
+
```typescript
|
|
140
|
+
interface SDKConfiguration {
|
|
141
|
+
apiKey: string; // API key for authentication
|
|
142
|
+
baseUrl: string; // Base URL for the notification service
|
|
143
|
+
subscriberId: string; // Subscriber ID for the current user
|
|
144
|
+
tenantId: string; // Tenant ID for multi-tenant support
|
|
145
|
+
environmentId: string; // Environment ID for environment scoping
|
|
146
|
+
environment: 'development' | 'staging' | 'production'; // Environment setting
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Note:** WebSocket URL is automatically derived from `baseUrl` by the SDK. The SDK converts HTTP URLs to WebSocket URLs automatically (http โ ws, https โ wss).
|
|
151
|
+
|
|
152
|
+
### useSDK Hook
|
|
153
|
+
|
|
154
|
+
Access the SDK instance from within the widget context:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import { useSDK } from '@edusight/notification-widget';
|
|
158
|
+
|
|
159
|
+
function CustomComponent() {
|
|
160
|
+
const { client, isInitialized, error } = useSDK();
|
|
161
|
+
|
|
162
|
+
if (!isInitialized) return <div>Loading...</div>;
|
|
163
|
+
if (error) return <div>Error: {error.message}</div>;
|
|
164
|
+
|
|
165
|
+
// Use the SDK client for custom operations
|
|
166
|
+
const handleCustomAction = async () => {
|
|
167
|
+
await client.notifications.markAsRead('notification-id');
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
return <button onClick={handleCustomAction}>Custom Action</button>;
|
|
171
|
+
}
|
|
172
|
+
```
|
|
52
173
|
|
|
53
174
|
## Components
|
|
54
175
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
75
|
-
-
|
|
76
|
-
-
|
|
77
|
-
-
|
|
176
|
+
### NotificationWidget
|
|
177
|
+
|
|
178
|
+
Main notification center component with complete functionality:
|
|
179
|
+
|
|
180
|
+
```tsx
|
|
181
|
+
import { NotificationWidget } from '@edusight/notification-widget';
|
|
182
|
+
|
|
183
|
+
<NotificationWidget
|
|
184
|
+
sdkConfig={sdkConfig}
|
|
185
|
+
position="right"
|
|
186
|
+
size="medium"
|
|
187
|
+
theme="light"
|
|
188
|
+
onError={handleError}
|
|
189
|
+
/>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Features:
|
|
193
|
+
- Bell icon with unread count badge
|
|
194
|
+
- Popover with notification list
|
|
195
|
+
- Real-time WebSocket updates with fallback polling
|
|
196
|
+
- Live preferences management
|
|
197
|
+
- Error boundaries with fallback UI
|
|
198
|
+
- Cross-tab synchronization
|
|
199
|
+
- Optimistic updates
|
|
200
|
+
|
|
201
|
+
### BellComponent
|
|
202
|
+
|
|
203
|
+
Notification bell icon with unread badge (used internally by NotificationWidget):
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import { BellComponent } from '@edusight/notification-widget';
|
|
207
|
+
|
|
208
|
+
<BellComponent
|
|
209
|
+
unreadCount={5}
|
|
210
|
+
onClick={handleClick}
|
|
211
|
+
size="medium"
|
|
212
|
+
disabled={false}
|
|
213
|
+
/>
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### InboxPopover
|
|
217
|
+
|
|
218
|
+
Notification popover content (used internally by NotificationWidget):
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { InboxPopover } from '@edusight/notification-widget';
|
|
222
|
+
|
|
223
|
+
<InboxPopover
|
|
224
|
+
isOpen={true}
|
|
225
|
+
onClose={handleClose}
|
|
226
|
+
position="right"
|
|
227
|
+
currentView="notifications"
|
|
228
|
+
onViewChange={handleViewChange}
|
|
229
|
+
notifications={notifications}
|
|
230
|
+
onNotificationAction={handleAction}
|
|
231
|
+
preferences={preferences}
|
|
232
|
+
onPreferenceChange={handlePreferenceChange}
|
|
233
|
+
/>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### NotificationItem
|
|
237
|
+
|
|
238
|
+
Individual notification item component:
|
|
239
|
+
|
|
240
|
+
```tsx
|
|
241
|
+
import { NotificationItem } from '@edusight/notification-widget';
|
|
242
|
+
|
|
243
|
+
<NotificationItem
|
|
244
|
+
notification={notification}
|
|
245
|
+
onAction={handleAction}
|
|
246
|
+
isSelected={false}
|
|
247
|
+
onSelect={handleSelect}
|
|
248
|
+
/>
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
### PreferencesView
|
|
252
|
+
|
|
253
|
+
Notification preference management component:
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
import { PreferencesView } from '@edusight/notification-widget';
|
|
257
|
+
|
|
258
|
+
<PreferencesView
|
|
259
|
+
preferences={preferences}
|
|
260
|
+
onChange={handleChange}
|
|
261
|
+
isLoading={false}
|
|
262
|
+
/>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### Error Boundaries
|
|
266
|
+
|
|
267
|
+
The widget includes comprehensive error boundaries:
|
|
268
|
+
|
|
269
|
+
```tsx
|
|
270
|
+
import {
|
|
271
|
+
NotificationWidgetErrorBoundary,
|
|
272
|
+
ComponentErrorBoundary
|
|
273
|
+
} from '@edusight/notification-widget';
|
|
274
|
+
|
|
275
|
+
// Main widget error boundary
|
|
276
|
+
<NotificationWidgetErrorBoundary onError={handleError}>
|
|
277
|
+
<YourComponent />
|
|
278
|
+
</NotificationWidgetErrorBoundary>
|
|
279
|
+
|
|
280
|
+
// Component-level error boundary
|
|
281
|
+
<ComponentErrorBoundary componentName="CustomComponent">
|
|
282
|
+
<CustomComponent />
|
|
283
|
+
</ComponentErrorBoundary>
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## Hooks
|
|
287
|
+
|
|
288
|
+
### useLivePreferences
|
|
289
|
+
|
|
290
|
+
Manage notification preferences with real-time saving:
|
|
291
|
+
|
|
292
|
+
```tsx
|
|
293
|
+
import { useLivePreferences } from '@edusight/notification-widget';
|
|
294
|
+
|
|
295
|
+
const {
|
|
296
|
+
updatePreference,
|
|
297
|
+
isSaving,
|
|
298
|
+
error
|
|
299
|
+
} = useLivePreferences({
|
|
300
|
+
preferences: currentPreferences,
|
|
301
|
+
onPreferencesChange: handleChange,
|
|
302
|
+
onError: handleError,
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
// Update a preference (automatically debounced and saved)
|
|
306
|
+
updatePreference('channels.email', true);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### useSDK
|
|
310
|
+
|
|
311
|
+
Access the SDK instance within the widget context:
|
|
312
|
+
|
|
313
|
+
```tsx
|
|
314
|
+
import { useSDK } from '@edusight/notification-widget';
|
|
315
|
+
|
|
316
|
+
const { client, isInitialized, error } = useSDK();
|
|
317
|
+
|
|
318
|
+
if (!isInitialized) return <div>Loading...</div>;
|
|
319
|
+
|
|
320
|
+
// Use SDK methods directly
|
|
321
|
+
const markAsRead = async (id: string) => {
|
|
322
|
+
await client.notifications.markAsRead(id);
|
|
323
|
+
};
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
### Custom Hooks Integration
|
|
327
|
+
|
|
328
|
+
The widget is designed to work with custom hooks that use the SDK:
|
|
329
|
+
|
|
330
|
+
```tsx
|
|
331
|
+
// Custom hook using the SDK
|
|
332
|
+
function useCustomNotifications() {
|
|
333
|
+
const { client } = useSDK();
|
|
334
|
+
const [notifications, setNotifications] = useState([]);
|
|
335
|
+
|
|
336
|
+
useEffect(() => {
|
|
337
|
+
if (client) {
|
|
338
|
+
client.notifications.list().then(setNotifications);
|
|
339
|
+
}
|
|
340
|
+
}, [client]);
|
|
341
|
+
|
|
342
|
+
return notifications;
|
|
343
|
+
}
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Configuration
|
|
347
|
+
|
|
348
|
+
### SDKConfiguration
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
interface SDKConfiguration {
|
|
352
|
+
apiKey: string; // API key for authentication
|
|
353
|
+
baseUrl: string; // Base URL for the notification service
|
|
354
|
+
subscriberId: string; // Subscriber ID for the current user
|
|
355
|
+
tenantId: string; // Tenant ID for multi-tenant support
|
|
356
|
+
environmentId: string; // Environment ID for environment scoping
|
|
357
|
+
environment: 'development' | 'staging' | 'production'; // Environment setting
|
|
358
|
+
}
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
### NotificationWidgetProps
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
interface NotificationWidgetProps {
|
|
365
|
+
sdkConfig: SDKConfiguration; // SDK configuration for dependency injection
|
|
366
|
+
position?: 'left' | 'right'; // Popover position (default: 'right')
|
|
367
|
+
size?: 'small' | 'medium' | 'large'; // Widget size (default: 'medium')
|
|
368
|
+
theme?: 'light' | 'dark'; // Theme mode (default: 'light')
|
|
369
|
+
className?: string; // Additional CSS classes
|
|
370
|
+
onError?: (error: Error) => void; // Error handler callback
|
|
371
|
+
}
|
|
372
|
+
```
|
|
373
|
+
|
|
374
|
+
### Widget State Management
|
|
375
|
+
|
|
376
|
+
The widget uses a reducer pattern for state management:
|
|
377
|
+
|
|
378
|
+
```typescript
|
|
379
|
+
interface WidgetState {
|
|
380
|
+
notifications: Notification[]; // Current notifications
|
|
381
|
+
unreadCount: number; // Unread notification count
|
|
382
|
+
preferences: NotificationPreferences; // User preferences
|
|
383
|
+
ui: {
|
|
384
|
+
isOpen: boolean; // Popover open state
|
|
385
|
+
currentView: 'notifications' | 'preferences'; // Current view
|
|
386
|
+
selectedNotifications: string[]; // Selected notification IDs
|
|
387
|
+
isLoading: boolean; // Loading state
|
|
388
|
+
error: Error | null; // Error state
|
|
389
|
+
};
|
|
390
|
+
websocket: {
|
|
391
|
+
connected: boolean; // WebSocket connection status
|
|
392
|
+
reconnecting: boolean; // Reconnection state
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
## Styling & Theming
|
|
398
|
+
|
|
399
|
+
### Tailwind CSS Integration
|
|
400
|
+
|
|
401
|
+
The widget is built with Tailwind CSS and follows clean design principles. All components use Tailwind utility classes for consistent styling.
|
|
402
|
+
|
|
403
|
+
### Theme Support
|
|
404
|
+
|
|
405
|
+
The widget supports light and dark themes:
|
|
406
|
+
|
|
407
|
+
```tsx
|
|
408
|
+
// Light theme (default)
|
|
409
|
+
<NotificationWidget theme="light" sdkConfig={config} />
|
|
410
|
+
|
|
411
|
+
// Dark theme
|
|
412
|
+
<NotificationWidget theme="dark" sdkConfig={config} />
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
### Custom Styling
|
|
416
|
+
|
|
417
|
+
Override widget styles using CSS classes:
|
|
418
|
+
|
|
419
|
+
```tsx
|
|
420
|
+
<NotificationWidget
|
|
421
|
+
className="custom-notification-widget"
|
|
422
|
+
sdkConfig={config}
|
|
423
|
+
/>
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
```css
|
|
427
|
+
.custom-notification-widget {
|
|
428
|
+
/* Custom styles for the widget container */
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
.custom-notification-widget .notification-bell {
|
|
432
|
+
/* Custom styles for the bell component */
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.custom-notification-widget .notification-popover {
|
|
436
|
+
/* Custom styles for the popover */
|
|
437
|
+
}
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
### CSS Variables
|
|
441
|
+
|
|
442
|
+
The widget uses CSS variables for theming:
|
|
443
|
+
|
|
444
|
+
```css
|
|
445
|
+
:root {
|
|
446
|
+
--notification-primary: #3b82f6;
|
|
447
|
+
--notification-primary-hover: #2563eb;
|
|
448
|
+
--notification-background: #ffffff;
|
|
449
|
+
--notification-text: #1f2937;
|
|
450
|
+
--notification-border: #e5e7eb;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
[data-theme='dark'] {
|
|
454
|
+
--notification-primary: #60a5fa;
|
|
455
|
+
--notification-primary-hover: #3b82f6;
|
|
456
|
+
--notification-background: #1f2937;
|
|
457
|
+
--notification-text: #f9fafb;
|
|
458
|
+
--notification-border: #374151;
|
|
459
|
+
}
|
|
460
|
+
```
|
|
461
|
+
|
|
462
|
+
## Performance Optimizations
|
|
463
|
+
|
|
464
|
+
### Architecture Benefits
|
|
465
|
+
|
|
466
|
+
The refactored architecture provides several performance benefits:
|
|
467
|
+
|
|
468
|
+
- **Dependency Injection**: SDK is initialized once and reused across components
|
|
469
|
+
- **Error Boundaries**: Component-level error isolation prevents cascading failures
|
|
470
|
+
- **Optimistic Updates**: UI updates immediately while API calls happen in background
|
|
471
|
+
- **Debounced Preferences**: Preference changes are debounced to reduce API calls
|
|
472
|
+
- **Fallback Polling**: Automatic fallback to polling when WebSocket fails
|
|
473
|
+
|
|
474
|
+
### Code Splitting
|
|
475
|
+
|
|
476
|
+
The widget includes optimized code splitting:
|
|
477
|
+
|
|
478
|
+
```tsx
|
|
479
|
+
// Main widget bundle: ~17KB gzipped
|
|
480
|
+
import { NotificationWidget } from '@edusight/notification-widget';
|
|
481
|
+
|
|
482
|
+
// Components are automatically code-split
|
|
483
|
+
// - Bell component: Loaded immediately
|
|
484
|
+
// - Popover content: Loaded on first open
|
|
485
|
+
// - Preferences view: Loaded when accessed
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### Memory Management
|
|
489
|
+
|
|
490
|
+
The widget includes proper cleanup:
|
|
491
|
+
|
|
492
|
+
- WebSocket connections are properly closed
|
|
493
|
+
- Event listeners are removed on unmount
|
|
494
|
+
- Timers and intervals are cleared
|
|
495
|
+
- Component state is reset on errors
|
|
496
|
+
|
|
497
|
+
### Bundle Size
|
|
498
|
+
|
|
499
|
+
Optimized bundle sizes:
|
|
500
|
+
|
|
501
|
+
- Main widget: ~17KB gzipped
|
|
502
|
+
- SDK integration: ~5KB additional
|
|
503
|
+
- Styles: ~25KB (includes Tailwind utilities)
|
|
504
|
+
- Total: ~47KB gzipped (complete package)
|
|
505
|
+
|
|
506
|
+
## Accessibility
|
|
507
|
+
|
|
508
|
+
The widget includes:
|
|
509
|
+
|
|
510
|
+
- โ
WCAG 2.1 Level AA compliance
|
|
511
|
+
- โ
Keyboard navigation (Tab, Enter, Escape)
|
|
512
|
+
- โ
ARIA labels and roles
|
|
513
|
+
- โ
Screen reader support
|
|
514
|
+
- โ
High contrast mode support
|
|
515
|
+
- โ
Focus management
|
|
516
|
+
|
|
517
|
+
Use the `AccessibilityProvider` for custom accessibility options:
|
|
518
|
+
|
|
519
|
+
```tsx
|
|
520
|
+
import { AccessibilityProvider } from '@edusight/notification-widget';
|
|
521
|
+
|
|
522
|
+
<AccessibilityProvider options={{ highContrast: true }}>
|
|
523
|
+
<YourApp />
|
|
524
|
+
</AccessibilityProvider>
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
## Playground Development Environment
|
|
528
|
+
|
|
529
|
+
A comprehensive development environment is included for testing and debugging:
|
|
530
|
+
|
|
531
|
+
```bash
|
|
532
|
+
cd playground
|
|
533
|
+
npm install
|
|
534
|
+
npm run dev
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
The playground demonstrates:
|
|
538
|
+
|
|
539
|
+
- Complete NotificationWidget integration
|
|
540
|
+
- SDK dependency injection pattern
|
|
541
|
+
- Real-time WebSocket simulation
|
|
542
|
+
- All notification operations (CRUD)
|
|
543
|
+
- Live preferences management
|
|
544
|
+
- Error boundary testing
|
|
545
|
+
- Cross-tab synchronization
|
|
546
|
+
- Responsive design testing
|
|
547
|
+
- Debug logging and monitoring
|
|
548
|
+
|
|
549
|
+
### Playground Features
|
|
550
|
+
|
|
551
|
+
- **Configuration Panel**: Test different SDK configurations
|
|
552
|
+
- **Debug Console**: Real-time logging and status monitoring
|
|
553
|
+
- **Connection Status**: API and WebSocket connection indicators
|
|
554
|
+
- **Feature Testing**: All widget features in one place
|
|
555
|
+
- **Error Simulation**: Test error boundaries and fallbacks
|
|
556
|
+
|
|
557
|
+
See the playground README for detailed development documentation.
|
|
558
|
+
|
|
559
|
+
## Build Status
|
|
560
|
+
|
|
561
|
+
| Component | Status | Bundle Size | Features |
|
|
562
|
+
|-----------|--------|-------------|----------|
|
|
563
|
+
| Widget | โ
Success | ~17 KB (gzipped) | Complete notification center |
|
|
564
|
+
| SDK Integration | โ
Success | ~5 KB (gzipped) | Dependency injection |
|
|
565
|
+
| Styles | โ
Success | ~25 KB (gzipped) | Tailwind utilities |
|
|
566
|
+
| Playground | โ
Success | ~330 KB (gzipped) | Development environment |
|
|
567
|
+
|
|
568
|
+
## Development
|
|
569
|
+
|
|
570
|
+
### Build
|
|
571
|
+
|
|
572
|
+
```bash
|
|
573
|
+
npm run build
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Generates:
|
|
577
|
+
- `dist/index.esm.js` - ES modules build
|
|
578
|
+
- `dist/index.cjs.js` - CommonJS build
|
|
579
|
+
- `dist/index.d.ts` - TypeScript declarations
|
|
580
|
+
- `dist/index.css` - Compiled styles
|
|
581
|
+
|
|
582
|
+
### Test
|
|
583
|
+
|
|
584
|
+
```bash
|
|
585
|
+
npm test # Run all tests
|
|
586
|
+
npm run test:watch # Watch mode
|
|
587
|
+
npm run test:coverage # Coverage report
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Test coverage: >90% across all components and hooks
|
|
591
|
+
|
|
592
|
+
### Lint
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
npm run lint # Check for issues
|
|
596
|
+
npm run lint:fix # Fix auto-fixable issues
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### Type Check
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
npm run type-check # TypeScript type checking
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## Integration Workflow
|
|
606
|
+
|
|
607
|
+
1. **Install the widget**: `npm install @edusight/notification-widget`
|
|
608
|
+
2. **Import styles**: `import '@edusight/notification-widget/styles'`
|
|
609
|
+
3. **Configure SDK**: Set up your SDK configuration object
|
|
610
|
+
4. **Add NotificationWidget**: Place the widget component in your app
|
|
611
|
+
5. **Handle errors**: Implement error handling for production use
|
|
612
|
+
6. **Test with playground**: Use the included playground for development
|
|
613
|
+
|
|
614
|
+
### Example Integration
|
|
615
|
+
|
|
616
|
+
```tsx
|
|
617
|
+
import React from 'react';
|
|
618
|
+
import { NotificationWidget } from '@edusight/notification-widget';
|
|
619
|
+
import '@edusight/notification-widget/styles';
|
|
620
|
+
|
|
621
|
+
function App() {
|
|
622
|
+
const sdkConfig = {
|
|
623
|
+
apiKey: process.env.REACT_APP_NOTIFICATION_API_KEY!,
|
|
624
|
+
baseUrl: process.env.REACT_APP_NOTIFICATION_API_URL!,
|
|
625
|
+
subscriberId: getCurrentUserId(),
|
|
626
|
+
tenantId: getCurrentTenantId(),
|
|
627
|
+
environmentId: getCurrentEnvironmentId(),
|
|
628
|
+
environment: process.env.NODE_ENV as 'development' | 'staging' | 'production',
|
|
629
|
+
};
|
|
630
|
+
|
|
631
|
+
const handleError = (error: Error) => {
|
|
632
|
+
console.error('Notification widget error:', error);
|
|
633
|
+
// Send to error tracking service
|
|
634
|
+
errorTracker.captureException(error);
|
|
635
|
+
};
|
|
636
|
+
|
|
637
|
+
return (
|
|
638
|
+
<div className="app">
|
|
639
|
+
<header className="app-header">
|
|
640
|
+
<h1>My Application</h1>
|
|
641
|
+
<NotificationWidget
|
|
642
|
+
sdkConfig={sdkConfig}
|
|
643
|
+
position="right"
|
|
644
|
+
size="medium"
|
|
645
|
+
theme="light"
|
|
646
|
+
onError={handleError}
|
|
647
|
+
/>
|
|
648
|
+
</header>
|
|
649
|
+
<main>
|
|
650
|
+
{/* Your app content */}
|
|
651
|
+
</main>
|
|
652
|
+
</div>
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
export default App;
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
## Troubleshooting
|
|
660
|
+
|
|
661
|
+
### "useSDK must be used within a NotificationWidget"
|
|
662
|
+
|
|
663
|
+
Ensure your component is used within the NotificationWidget context:
|
|
664
|
+
|
|
665
|
+
```tsx
|
|
666
|
+
// โ Wrong - useSDK outside widget context
|
|
667
|
+
function MyComponent() {
|
|
668
|
+
const { client } = useSDK(); // This will throw an error
|
|
669
|
+
return <div>...</div>;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
// โ
Correct - Custom component within widget
|
|
673
|
+
<NotificationWidget sdkConfig={config}>
|
|
674
|
+
{/* Custom components can use useSDK here */}
|
|
675
|
+
</NotificationWidget>
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### SDK Configuration Issues
|
|
679
|
+
|
|
680
|
+
1. **Check required fields**: Ensure all required SDK config fields are provided
|
|
681
|
+
2. **Verify URLs**: Check that `baseUrl` and `websocketUrl` are correct
|
|
682
|
+
3. **Environment mismatch**: Ensure `environment` matches your deployment
|
|
683
|
+
4. **API key validation**: Verify the API key is valid and has proper permissions
|
|
684
|
+
|
|
685
|
+
### WebSocket Connection Issues
|
|
686
|
+
|
|
687
|
+
1. **URL format**: Ensure WebSocket URL uses `ws://` or `wss://` protocol
|
|
688
|
+
2. **CORS settings**: Check CORS configuration on the backend
|
|
689
|
+
3. **Firewall/proxy**: Verify WebSocket connections aren't blocked
|
|
690
|
+
4. **Fallback polling**: The widget automatically falls back to polling if WebSocket fails
|
|
691
|
+
|
|
692
|
+
### Performance Issues
|
|
693
|
+
|
|
694
|
+
1. **Bundle size**: Check if you're importing the entire widget when you only need parts
|
|
695
|
+
2. **Re-renders**: Use React DevTools to identify unnecessary re-renders
|
|
696
|
+
3. **Memory leaks**: Ensure proper cleanup of event listeners and timers
|
|
697
|
+
4. **Error boundaries**: Check if error boundaries are catching and handling errors properly
|
|
698
|
+
|
|
699
|
+
### Styling Issues
|
|
700
|
+
|
|
701
|
+
1. **CSS conflicts**: Ensure your CSS doesn't conflict with widget styles
|
|
702
|
+
2. **Tailwind purging**: Make sure Tailwind isn't purging widget classes
|
|
703
|
+
3. **Theme application**: Verify theme prop is being applied correctly
|
|
704
|
+
4. **Custom classes**: Check that custom className prop is being used
|
|
705
|
+
|
|
706
|
+
## API Reference
|
|
707
|
+
|
|
708
|
+
### Exported Components
|
|
709
|
+
|
|
710
|
+
```typescript
|
|
711
|
+
export {
|
|
712
|
+
NotificationWidget, // Main widget component
|
|
713
|
+
BellComponent, // Bell icon with badge
|
|
714
|
+
InboxPopover, // Popover content
|
|
715
|
+
NotificationItem, // Individual notification
|
|
716
|
+
PreferencesView, // Preferences management
|
|
717
|
+
NotificationWidgetErrorBoundary, // Main error boundary
|
|
718
|
+
ComponentErrorBoundary, // Component-level error boundary
|
|
719
|
+
};
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### Exported Hooks
|
|
723
|
+
|
|
724
|
+
```typescript
|
|
725
|
+
export {
|
|
726
|
+
useSDK, // Access SDK instance
|
|
727
|
+
useLivePreferences, // Live preferences management
|
|
728
|
+
};
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Exported Types
|
|
732
|
+
|
|
733
|
+
```typescript
|
|
734
|
+
export type {
|
|
735
|
+
NotificationWidgetProps, // Main widget props
|
|
736
|
+
SDKConfiguration, // SDK config interface
|
|
737
|
+
WidgetState, // Widget state interface
|
|
738
|
+
WidgetAction, // State action types
|
|
739
|
+
Notification, // Core notification type
|
|
740
|
+
NotificationPreferences, // Preferences interface
|
|
741
|
+
WidgetError, // Error interface
|
|
742
|
+
};
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
### Re-exported SDK Types
|
|
746
|
+
|
|
747
|
+
```typescript
|
|
748
|
+
export type {
|
|
749
|
+
Notification as SDKNotification,
|
|
750
|
+
NotificationFilters,
|
|
751
|
+
} from '@edusight/notification-sdk';
|
|
752
|
+
```
|
|
753
|
+
|
|
754
|
+
## Architecture
|
|
755
|
+
|
|
756
|
+
### Clean Architecture Principles
|
|
757
|
+
|
|
758
|
+
The widget follows clean architecture principles:
|
|
759
|
+
|
|
760
|
+
1. **Separation of Concerns**: UI, business logic, and data access are separated
|
|
761
|
+
2. **Dependency Injection**: SDK is injected rather than directly imported
|
|
762
|
+
3. **Error Boundaries**: Component-level error isolation
|
|
763
|
+
4. **State Management**: Centralized state with reducer pattern
|
|
764
|
+
5. **Event Handling**: Proper event cleanup and memory management
|
|
765
|
+
|
|
766
|
+
### Component Hierarchy
|
|
767
|
+
|
|
768
|
+
```
|
|
769
|
+
NotificationWidget
|
|
770
|
+
โโโ SDKProvider (Dependency Injection)
|
|
771
|
+
โโโ NotificationWidgetErrorBoundary
|
|
772
|
+
โโโ NotificationWidgetInternal
|
|
773
|
+
โโโ ComponentErrorBoundary (BellComponent)
|
|
774
|
+
โ โโโ BellComponent
|
|
775
|
+
โโโ ComponentErrorBoundary (InboxPopover)
|
|
776
|
+
โโโ InboxPopover
|
|
777
|
+
โโโ NotificationsList
|
|
778
|
+
โ โโโ NotificationItem[]
|
|
779
|
+
โโโ PreferencesView
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### State Flow
|
|
783
|
+
|
|
784
|
+
1. **SDK Initialization**: SDKProvider initializes and provides SDK instance
|
|
785
|
+
2. **State Management**: useReducer manages widget state centrally
|
|
786
|
+
3. **Real-time Updates**: WebSocket events update state via reducer actions
|
|
787
|
+
4. **Optimistic Updates**: UI updates immediately, API calls happen async
|
|
788
|
+
5. **Error Handling**: Errors are caught by boundaries and handled gracefully
|
|
789
|
+
|
|
78
790
|
## License
|
|
79
791
|
|
|
80
792
|
MIT
|