@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.
- package/LICENSE +165 -0
- package/README.md +568 -0
- package/dist/components/confirmation/Confirmation.d.ts +27 -0
- package/dist/components/confirmation/index.d.ts +1 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/modal/Modal.d.ts +114 -0
- package/dist/components/modal/index.d.ts +1 -0
- package/dist/components/toast/Toast.d.ts +43 -0
- package/dist/components/toast/index.d.ts +1 -0
- package/dist/components/ui/Alert.d.ts +50 -0
- package/dist/components/ui/Button.d.ts +70 -0
- package/dist/components/ui/Checkbox.d.ts +64 -0
- package/dist/components/ui/FormField.d.ts +50 -0
- package/dist/components/ui/color-mode.d.ts +19 -0
- package/dist/components/ui/index.d.ts +16 -0
- package/dist/components/ui/provider.d.ts +2 -0
- package/dist/components/ui/toaster.d.ts +3 -0
- package/dist/components/ui/tooltip.d.ts +11 -0
- package/dist/contexts/confirmation.context.d.ts +100 -0
- package/dist/contexts/index.d.ts +2 -0
- package/dist/contexts/toaster.context.d.ts +91 -0
- package/dist/handlers/error.handler.d.ts +110 -0
- package/dist/handlers/index.d.ts +1 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1305 -0
- package/dist/index.mjs +1281 -0
- package/dist/models/confirmation.d.ts +21 -0
- package/dist/models/index.d.ts +2 -0
- package/dist/models/toaster.d.ts +48 -0
- package/dist/providers/ThemeSharedProvider.d.ts +135 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/theme/index.d.ts +42 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/styles.d.ts +14 -0
- 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
|
+
[](https://www.npmjs.com/package/@abpjs/theme-shared)
|
|
6
|
+
[](https://docs.abpjs.io/docs/packages/theme-shared/overview)
|
|
7
|
+
[](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';
|