@abpjs/theme-shared 0.7.6

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.
Files changed (36) hide show
  1. package/LICENSE +165 -0
  2. package/README.md +568 -0
  3. package/dist/components/confirmation/Confirmation.d.ts +27 -0
  4. package/dist/components/confirmation/index.d.ts +1 -0
  5. package/dist/components/index.d.ts +4 -0
  6. package/dist/components/modal/Modal.d.ts +114 -0
  7. package/dist/components/modal/index.d.ts +1 -0
  8. package/dist/components/toast/Toast.d.ts +43 -0
  9. package/dist/components/toast/index.d.ts +1 -0
  10. package/dist/components/ui/Alert.d.ts +50 -0
  11. package/dist/components/ui/Button.d.ts +70 -0
  12. package/dist/components/ui/Checkbox.d.ts +64 -0
  13. package/dist/components/ui/FormField.d.ts +50 -0
  14. package/dist/components/ui/color-mode.d.ts +19 -0
  15. package/dist/components/ui/index.d.ts +16 -0
  16. package/dist/components/ui/provider.d.ts +2 -0
  17. package/dist/components/ui/toaster.d.ts +3 -0
  18. package/dist/components/ui/tooltip.d.ts +11 -0
  19. package/dist/contexts/confirmation.context.d.ts +100 -0
  20. package/dist/contexts/index.d.ts +2 -0
  21. package/dist/contexts/toaster.context.d.ts +91 -0
  22. package/dist/handlers/error.handler.d.ts +110 -0
  23. package/dist/handlers/index.d.ts +1 -0
  24. package/dist/hooks/index.d.ts +3 -0
  25. package/dist/index.d.ts +17 -0
  26. package/dist/index.js +1305 -0
  27. package/dist/index.mjs +1281 -0
  28. package/dist/models/confirmation.d.ts +21 -0
  29. package/dist/models/index.d.ts +2 -0
  30. package/dist/models/toaster.d.ts +48 -0
  31. package/dist/providers/ThemeSharedProvider.d.ts +135 -0
  32. package/dist/providers/index.d.ts +1 -0
  33. package/dist/theme/index.d.ts +42 -0
  34. package/dist/utils/index.d.ts +1 -0
  35. package/dist/utils/styles.d.ts +14 -0
  36. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,568 @@
1
+ # @abpjs/theme-shared
2
+
3
+ > Shared UI components and services for ABP Framework in React
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@abpjs/theme-shared.svg)](https://www.npmjs.com/package/@abpjs/theme-shared)
6
+ [![documentation](https://img.shields.io/badge/docs-abpjs.io-blue.svg)](https://docs.abpjs.io/docs/packages/theme-shared/overview)
7
+ [![License: LGPL-3.0](https://img.shields.io/badge/License-LGPL--3.0-blue.svg)](https://www.gnu.org/licenses/lgpl-3.0)
8
+
9
+ ## Overview
10
+
11
+ `@abpjs/theme-shared` provides essential shared UI components and services for ABP-based React applications. It includes toast notifications, confirmation dialogs, modal management, and global error handling - the building blocks that other ABP theme packages depend on.
12
+
13
+ This package is a React translation of the original `@abp/ng.theme.shared` Angular package, offering the same powerful UI utilities with modern React patterns.
14
+
15
+ ## Features
16
+
17
+ - **Toast Notifications** - Global notification system with multiple types
18
+ - **Confirmation Dialogs** - Promise-based confirmation modals
19
+ - **Modal Management** - Centralized modal service
20
+ - **Error Handling** - Global error handler with user-friendly messages
21
+ - **Theme Configuration** - Chakra UI v3 theme customization with `createSystem`
22
+ - **Color Mode** - Built-in light/dark theme support (opt-in)
23
+ - **Utility Functions** - Common UI utilities and helpers
24
+ - **TypeScript** - Full type safety with comprehensive definitions
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ # Using npm
30
+ npm install @abpjs/theme-shared
31
+
32
+ # Using yarn
33
+ yarn add @abpjs/theme-shared
34
+
35
+ # Using pnpm
36
+ pnpm add @abpjs/theme-shared
37
+ ```
38
+
39
+ ### Required Dependencies
40
+
41
+ This package requires the following peer dependencies:
42
+
43
+ ```bash
44
+ npm install @abpjs/core @chakra-ui/react @emotion/react lucide-react
45
+ ```
46
+
47
+ > **Note:** Chakra UI v3 no longer requires `@emotion/styled` or `framer-motion` as peer dependencies.
48
+
49
+ ## Quick Start
50
+
51
+ ### 1. Setup the Theme Provider
52
+
53
+ Wrap your application with the ThemeSharedProvider:
54
+
55
+ ```tsx
56
+ import { ThemeSharedProvider } from '@abpjs/theme-shared';
57
+ import { CoreProvider } from '@abpjs/core';
58
+
59
+ function App() {
60
+ return (
61
+ <CoreProvider environment={environment}>
62
+ <ThemeSharedProvider>
63
+ <YourApp />
64
+ </ThemeSharedProvider>
65
+ </CoreProvider>
66
+ );
67
+ }
68
+ ```
69
+
70
+ > **Note:** `ThemeSharedProvider` includes Chakra's provider internally, so you don't need to wrap with `ChakraProvider` separately.
71
+
72
+ ### 2. Show Toast Notifications
73
+
74
+ ```tsx
75
+ import { useToaster } from '@abpjs/theme-shared';
76
+
77
+ function MyComponent() {
78
+ const toaster = useToaster();
79
+
80
+ const handleSuccess = () => {
81
+ toaster.success('Operation completed successfully!', 'Success');
82
+ };
83
+
84
+ const handleError = () => {
85
+ toaster.error('Something went wrong!', 'Error');
86
+ };
87
+
88
+ const handleWarning = () => {
89
+ toaster.warn('Please review your input.', 'Warning');
90
+ };
91
+
92
+ const handleInfo = () => {
93
+ toaster.info('Did you know? You can customize this.', 'Info');
94
+ };
95
+
96
+ return (
97
+ <div>
98
+ <button onClick={handleSuccess}>Success</button>
99
+ <button onClick={handleError}>Error</button>
100
+ <button onClick={handleWarning}>Warning</button>
101
+ <button onClick={handleInfo}>Info</button>
102
+ </div>
103
+ );
104
+ }
105
+ ```
106
+
107
+ ### 3. Show Confirmation Dialogs
108
+
109
+ ```tsx
110
+ import { useConfirmation, Toaster } from '@abpjs/theme-shared';
111
+
112
+ function DeleteButton({ onDelete }) {
113
+ const confirmation = useConfirmation();
114
+
115
+ const handleClick = async () => {
116
+ const status = await confirmation.warn(
117
+ 'Are you sure you want to delete this item? This action cannot be undone.',
118
+ 'Delete Item',
119
+ {
120
+ yesCopy: 'Delete',
121
+ cancelCopy: 'Cancel',
122
+ }
123
+ );
124
+
125
+ if (status === Toaster.Status.confirm) {
126
+ onDelete();
127
+ }
128
+ };
129
+
130
+ return <button onClick={handleClick}>Delete</button>;
131
+ }
132
+ ```
133
+
134
+ ## Components
135
+
136
+ ### Toast / ToastContainer
137
+
138
+ Toast notification component and container.
139
+
140
+ ```tsx
141
+ import { ToastContainer } from '@abpjs/theme-shared';
142
+
143
+ // The ToastContainer is usually placed at the root level
144
+ // ThemeSharedProvider includes it by default when renderToasts={true}
145
+ function App() {
146
+ return (
147
+ <ThemeSharedProvider renderToasts={true}>
148
+ <YourApp />
149
+ </ThemeSharedProvider>
150
+ );
151
+ }
152
+ ```
153
+
154
+ ### ConfirmationDialog
155
+
156
+ Confirmation dialog component.
157
+
158
+ ```tsx
159
+ import { ConfirmationDialog } from '@abpjs/theme-shared';
160
+
161
+ // Usually managed by the provider, but can be used directly
162
+ // ThemeSharedProvider includes it by default when renderConfirmation={true}
163
+ ```
164
+
165
+ ### Modal
166
+
167
+ Generic modal component for custom dialogs. Uses Chakra UI v3 Dialog internally.
168
+
169
+ ```tsx
170
+ import { Modal } from '@abpjs/theme-shared';
171
+
172
+ function CustomModal({ isOpen, onClose }) {
173
+ return (
174
+ <Modal
175
+ visible={isOpen}
176
+ onVisibleChange={(open) => !open && onClose()}
177
+ header="Custom Modal"
178
+ size="md"
179
+ footer={
180
+ <>
181
+ <Button variant="ghost" onClick={onClose}>Cancel</Button>
182
+ <Button colorPalette="blue">Save</Button>
183
+ </>
184
+ }
185
+ >
186
+ <p>Your modal content here</p>
187
+ </Modal>
188
+ );
189
+ }
190
+ ```
191
+
192
+ **Props:**
193
+
194
+ | Prop | Type | Default | Description |
195
+ |------|------|---------|-------------|
196
+ | `visible` | `boolean` | - | Controls modal visibility |
197
+ | `onVisibleChange` | `(visible: boolean) => void` | - | Callback when visibility changes |
198
+ | `header` | `ReactNode` | - | Modal header content |
199
+ | `footer` | `ReactNode` | - | Modal footer content |
200
+ | `size` | `'sm' \| 'md' \| 'lg' \| 'xl' \| 'full'` | `'md'` | Modal size |
201
+ | `centered` | `boolean` | `true` | Center modal vertically |
202
+ | `closeOnOverlayClick` | `boolean` | `true` | Close when clicking outside |
203
+ | `closeOnEscape` | `boolean` | `true` | Close on Escape key |
204
+ | `showCloseButton` | `boolean` | `true` | Show close button in header |
205
+ | `scrollBehavior` | `'inside' \| 'outside'` | `'inside'` | Scroll behavior for content |
206
+ | `children` | `ReactNode` | - | Modal content |
207
+
208
+ ## Hooks
209
+
210
+ ### useToaster
211
+
212
+ Hook for showing toast notifications.
213
+
214
+ ```tsx
215
+ import { useToaster } from '@abpjs/theme-shared';
216
+
217
+ function MyComponent() {
218
+ const toaster = useToaster();
219
+
220
+ // Success toast
221
+ toaster.success('Saved successfully!', 'Success');
222
+
223
+ // Error toast
224
+ toaster.error('Failed to save.', 'Error');
225
+
226
+ // Warning toast
227
+ toaster.warn('Please check your input.', 'Warning');
228
+
229
+ // Info toast
230
+ toaster.info('New updates available.', 'Info');
231
+
232
+ // With options
233
+ toaster.success('Custom message', 'Title', {
234
+ life: 5000, // Duration in ms
235
+ sticky: false, // If true, won't auto-dismiss
236
+ closable: true, // Show close button
237
+ });
238
+ }
239
+ ```
240
+
241
+ **Toaster Methods:**
242
+
243
+ | Method | Description |
244
+ |--------|-------------|
245
+ | `success(message, title?, options?)` | Show success notification |
246
+ | `error(message, title?, options?)` | Show error notification |
247
+ | `warn(message, title?, options?)` | Show warning notification |
248
+ | `info(message, title?, options?)` | Show info notification |
249
+ | `clear()` | Clear all notifications |
250
+ | `remove(id)` | Remove specific notification |
251
+
252
+ ### useConfirmation
253
+
254
+ Hook for showing confirmation dialogs.
255
+
256
+ ```tsx
257
+ import { useConfirmation, Toaster } from '@abpjs/theme-shared';
258
+
259
+ function MyComponent() {
260
+ const confirmation = useConfirmation();
261
+
262
+ const handleDelete = async () => {
263
+ const status = await confirmation.warn(
264
+ 'Are you sure?',
265
+ 'Delete',
266
+ {
267
+ yesCopy: 'Yes, Delete',
268
+ cancelCopy: 'No, Keep',
269
+ }
270
+ );
271
+
272
+ if (status === Toaster.Status.confirm) {
273
+ // User confirmed
274
+ performDelete();
275
+ }
276
+ };
277
+
278
+ // Different severity methods
279
+ const showInfo = () => confirmation.info('Info message', 'Info');
280
+ const showSuccess = () => confirmation.success('Success!', 'Success');
281
+ const showError = () => confirmation.error('Error occurred', 'Error');
282
+ }
283
+ ```
284
+
285
+ **Confirmation Options:**
286
+
287
+ ```typescript
288
+ interface ConfirmationOptions {
289
+ yesCopy?: string; // Default: 'Yes' (localized)
290
+ cancelCopy?: string; // Default: 'Cancel' (localized)
291
+ hideYesBtn?: boolean; // Hide confirm button
292
+ hideCancelBtn?: boolean; // Hide cancel button
293
+ }
294
+ ```
295
+
296
+ ## Theme Configuration
297
+
298
+ ### Custom Theme with Chakra v3
299
+
300
+ Customize the theme using `defineConfig`:
301
+
302
+ ```tsx
303
+ import { ThemeSharedProvider, defineConfig } from '@abpjs/theme-shared';
304
+
305
+ const customTheme = defineConfig({
306
+ theme: {
307
+ tokens: {
308
+ colors: {
309
+ brand: {
310
+ 50: { value: '#e3f2fd' },
311
+ 100: { value: '#bbdefb' },
312
+ 500: { value: '#2196f3' },
313
+ 600: { value: '#1e88e5' },
314
+ // ... more shades
315
+ },
316
+ },
317
+ },
318
+ semanticTokens: {
319
+ colors: {
320
+ brand: {
321
+ solid: { value: '{colors.brand.500}' },
322
+ contrast: { value: 'white' },
323
+ fg: { value: '{colors.brand.700}' },
324
+ },
325
+ },
326
+ },
327
+ },
328
+ });
329
+
330
+ function App() {
331
+ return (
332
+ <ThemeSharedProvider themeOverrides={customTheme}>
333
+ <YourApp />
334
+ </ThemeSharedProvider>
335
+ );
336
+ }
337
+ ```
338
+
339
+ ### Color Mode (Dark/Light Theme)
340
+
341
+ Enable color mode support:
342
+
343
+ ```tsx
344
+ import { ThemeSharedProvider } from '@abpjs/theme-shared';
345
+
346
+ function App() {
347
+ return (
348
+ <ThemeSharedProvider
349
+ enableColorMode={true}
350
+ defaultColorMode="light" // 'light' | 'dark' | 'system'
351
+ >
352
+ <YourApp />
353
+ </ThemeSharedProvider>
354
+ );
355
+ }
356
+ ```
357
+
358
+ Use color mode in components:
359
+
360
+ ```tsx
361
+ import { useColorMode, ColorModeButton } from '@abpjs/theme-shared';
362
+
363
+ function Header() {
364
+ const { colorMode, toggleColorMode } = useColorMode();
365
+
366
+ return (
367
+ <header>
368
+ <span>Current mode: {colorMode}</span>
369
+ <ColorModeButton /> {/* Pre-built toggle button */}
370
+ </header>
371
+ );
372
+ }
373
+ ```
374
+
375
+ ## ThemeSharedProvider Props
376
+
377
+ | Prop | Type | Default | Description |
378
+ |------|------|---------|-------------|
379
+ | `children` | `ReactNode` | - | Child components |
380
+ | `renderToasts` | `boolean` | `true` | Render ToastContainer |
381
+ | `renderConfirmation` | `boolean` | `true` | Render ConfirmationDialog |
382
+ | `themeOverrides` | `ThemeOverride` | - | Custom theme configuration |
383
+ | `toastPosition` | `string` | `'bottom-right'` | Toast position |
384
+ | `enableColorMode` | `boolean` | `false` | Enable dark/light mode |
385
+ | `defaultColorMode` | `'light' \| 'dark' \| 'system'` | `'light'` | Default color mode |
386
+
387
+ ## Data Models
388
+
389
+ ### Toaster Types
390
+
391
+ ```typescript
392
+ namespace Toaster {
393
+ interface Toast {
394
+ id: string;
395
+ message: string;
396
+ title?: string;
397
+ severity: 'info' | 'success' | 'warn' | 'error';
398
+ life?: number;
399
+ sticky?: boolean;
400
+ closable?: boolean;
401
+ messageLocalizationParams?: string[];
402
+ titleLocalizationParams?: string[];
403
+ }
404
+
405
+ enum Status {
406
+ confirm = 'confirm',
407
+ reject = 'reject',
408
+ dismiss = 'dismiss',
409
+ }
410
+ }
411
+ ```
412
+
413
+ ## Complete Example
414
+
415
+ Full integration example:
416
+
417
+ ```tsx
418
+ import { BrowserRouter } from 'react-router-dom';
419
+ import { CoreProvider } from '@abpjs/core';
420
+ import {
421
+ ThemeSharedProvider,
422
+ useToaster,
423
+ useConfirmation,
424
+ Toaster,
425
+ defineConfig,
426
+ } from '@abpjs/theme-shared';
427
+
428
+ const environment = {
429
+ // Your ABP configuration
430
+ };
431
+
432
+ // Optional: Custom theme
433
+ const customTheme = defineConfig({
434
+ theme: {
435
+ tokens: {
436
+ colors: {
437
+ brand: {
438
+ 500: { value: '#6366f1' }, // Custom primary color
439
+ },
440
+ },
441
+ },
442
+ },
443
+ });
444
+
445
+ // Main App
446
+ function App() {
447
+ return (
448
+ <CoreProvider environment={environment}>
449
+ <ThemeSharedProvider
450
+ themeOverrides={customTheme}
451
+ enableColorMode={true}
452
+ >
453
+ <BrowserRouter>
454
+ <AppContent />
455
+ </BrowserRouter>
456
+ </ThemeSharedProvider>
457
+ </CoreProvider>
458
+ );
459
+ }
460
+
461
+ // Example usage in a component
462
+ function UserActions({ user }) {
463
+ const toaster = useToaster();
464
+ const confirmation = useConfirmation();
465
+
466
+ const handleSave = async () => {
467
+ try {
468
+ await saveUser(user);
469
+ toaster.success('User saved successfully!', 'Success');
470
+ } catch (error) {
471
+ toaster.error(error.message, 'Error');
472
+ }
473
+ };
474
+
475
+ const handleDelete = async () => {
476
+ const status = await confirmation.warn(
477
+ `Are you sure you want to delete ${user.name}?`,
478
+ 'Delete User',
479
+ { yesCopy: 'Delete' }
480
+ );
481
+
482
+ if (status === Toaster.Status.confirm) {
483
+ try {
484
+ await deleteUser(user.id);
485
+ toaster.success('User deleted!', 'Success');
486
+ } catch (error) {
487
+ toaster.error(error.message, 'Error');
488
+ }
489
+ }
490
+ };
491
+
492
+ return (
493
+ <div>
494
+ <button onClick={handleSave}>Save</button>
495
+ <button onClick={handleDelete}>Delete</button>
496
+ </div>
497
+ );
498
+ }
499
+
500
+ export default App;
501
+ ```
502
+
503
+ ## Migration from Chakra UI v2
504
+
505
+ If you're upgrading from a previous version that used Chakra UI v2:
506
+
507
+ ### Key Changes
508
+
509
+ 1. **No separate ChakraProvider** - `ThemeSharedProvider` now includes it
510
+ 2. **Theme configuration** - Use `defineConfig()` instead of `extendTheme()`
511
+ 3. **Modal API** - Use `visible`/`onVisibleChange` instead of `isOpen`/`onClose`
512
+ 4. **Color tokens** - Use `{ value: '#color' }` format in theme tokens
513
+ 5. **Boolean props** - `isDisabled` → `disabled`, `isLoading` → `loading`
514
+ 6. **Color scheme** - `colorScheme` → `colorPalette`
515
+ 7. **Icons** - Use `lucide-react` instead of `@chakra-ui/icons`
516
+
517
+ ### Example Migration
518
+
519
+ ```tsx
520
+ // Before (Chakra v2)
521
+ <Modal isOpen={isOpen} onClose={onClose} isCentered>
522
+ <ModalOverlay />
523
+ <ModalContent>
524
+ <ModalHeader>Title</ModalHeader>
525
+ <ModalBody>Content</ModalBody>
526
+ </ModalContent>
527
+ </Modal>
528
+
529
+ // After (Chakra v3 via @abpjs/theme-shared)
530
+ <Modal
531
+ visible={isOpen}
532
+ onVisibleChange={(open) => !open && onClose()}
533
+ header="Title"
534
+ centered
535
+ >
536
+ Content
537
+ </Modal>
538
+ ```
539
+
540
+ ## Documentation
541
+
542
+ For comprehensive documentation, visit [docs.abpjs.io](https://docs.abpjs.io):
543
+
544
+ - **[Package Documentation](https://docs.abpjs.io/docs/packages/theme-shared/overview)** - Full API reference and examples
545
+ - **[Toaster](https://docs.abpjs.io/docs/packages/theme-shared/toaster)** - Toast notifications guide
546
+ - **[Confirmation](https://docs.abpjs.io/docs/packages/theme-shared/confirmation)** - Confirmation dialogs guide
547
+ - **[Getting Started](https://docs.abpjs.io/docs/getting-started/installation)** - Installation and setup guide
548
+ - **[All Packages](https://docs.abpjs.io/docs/)** - Browse all ABP React packages
549
+
550
+ ## Related Packages
551
+
552
+ - [@abpjs/core](https://www.npmjs.com/package/@abpjs/core) - Core infrastructure (required)
553
+ - [@abpjs/theme-basic](https://www.npmjs.com/package/@abpjs/theme-basic) - Layout components
554
+ - [@abpjs/account](https://www.npmjs.com/package/@abpjs/account) - Account management
555
+ - [@abpjs/permission-management](https://www.npmjs.com/package/@abpjs/permission-management) - Permission management
556
+ - [@abpjs/tenant-management](https://www.npmjs.com/package/@abpjs/tenant-management) - Tenant administration
557
+
558
+ ## Contributing
559
+
560
+ This package is part of the [ABP React](https://github.com/abpjs/abp-react) monorepo. Contributions are welcome!
561
+
562
+ ## License
563
+
564
+ LGPL-3.0 - See [LICENSE](https://github.com/abpjs/abp-react/blob/main/LICENSE) for details.
565
+
566
+ ---
567
+
568
+ **[View Full Documentation](https://docs.abpjs.io/docs/packages/theme-shared/overview)** | **[Report Issues](https://github.com/abpjs/abp-react/issues)** | **[View Source](https://github.com/abpjs/abp-react/tree/main/packages/theme-shared)**
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ export interface ConfirmationDialogProps {
3
+ /** Custom class name for the dialog content */
4
+ className?: string;
5
+ }
6
+ /**
7
+ * ConfirmationDialog - Renders the confirmation dialog.
8
+ *
9
+ * This is the React equivalent of Angular's ConfirmationComponent.
10
+ * Place this component once in your app to display confirmations.
11
+ *
12
+ * In Chakra v3, we use Dialog with role="alertdialog" instead of AlertDialog.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * function App() {
17
+ * return (
18
+ * <ThemeSharedProvider>
19
+ * <MainContent />
20
+ * <ConfirmationDialog />
21
+ * </ThemeSharedProvider>
22
+ * );
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function ConfirmationDialog({ className }: ConfirmationDialogProps): React.ReactElement | null;
27
+ export default ConfirmationDialog;
@@ -0,0 +1 @@
1
+ export * from './Confirmation';
@@ -0,0 +1,4 @@
1
+ export * from './toast';
2
+ export * from './confirmation';
3
+ export * from './modal';
4
+ export * from './ui';