0
# Feedback Components
1
2
@mantine/core provides comprehensive feedback and status components to communicate system state, loading conditions, and user notifications effectively. These components enhance user experience through clear visual communication.
3
4
## Alert
5
6
Alert component for displaying important messages with various severity levels.
7
8
```typescript { .api }
9
interface AlertProps {
10
/** Alert title */
11
title?: React.ReactNode;
12
/** Alert content */
13
children?: React.ReactNode;
14
/** Alert icon, displayed on the left */
15
icon?: React.ReactNode;
16
/** If true, close button will be displayed */
17
withCloseButton?: boolean;
18
/** Called when close button is clicked */
19
onClose?: () => void;
20
/** Alert variant */
21
variant?: 'light' | 'filled' | 'outline' | 'default';
22
/** Alert color theme */
23
color?: MantineColor;
24
/** Alert radius */
25
radius?: MantineRadius;
26
/** Alert size */
27
size?: MantineSize;
28
}
29
```
30
31
**Usage Example:**
32
33
```tsx
34
import { Alert } from '@mantine/core';
35
36
function AlertDemo() {
37
return (
38
<>
39
<Alert title="Information" color="blue" variant="light">
40
This is an informational alert
41
</Alert>
42
43
<Alert
44
title="Warning"
45
color="yellow"
46
variant="filled"
47
icon="⚠️"
48
withCloseButton
49
onClose={() => console.log('Alert closed')}
50
>
51
This is a warning message
52
</Alert>
53
54
<Alert title="Error" color="red" variant="outline">
55
Something went wrong
56
</Alert>
57
58
<Alert title="Success" color="green">
59
Operation completed successfully
60
</Alert>
61
</>
62
);
63
}
64
```
65
66
## Notification
67
68
Notification component for displaying temporary messages, typically used in notification systems.
69
70
```typescript { .api }
71
interface NotificationProps {
72
/** Notification title */
73
title?: React.ReactNode;
74
/** Notification message */
75
children?: React.ReactNode;
76
/** Notification icon */
77
icon?: React.ReactNode;
78
/** If true, close button will be displayed */
79
withCloseButton?: boolean;
80
/** Called when close button is clicked */
81
onClose?: () => void;
82
/** Notification variant */
83
variant?: 'light' | 'filled' | 'outline' | 'default';
84
/** Notification color theme */
85
color?: MantineColor;
86
/** Notification radius */
87
radius?: MantineRadius;
88
/** If true, notification will have border */
89
withBorder?: boolean;
90
/** Notification loading state */
91
loading?: boolean;
92
}
93
```
94
95
**Usage Example:**
96
97
```tsx
98
import { Notification } from '@mantine/core';
99
100
function NotificationDemo() {
101
return (
102
<>
103
<Notification title="Default notification">
104
This is default notification
105
</Notification>
106
107
<Notification
108
title="Success notification"
109
icon="✅"
110
color="teal"
111
onClose={() => console.log('Notification closed')}
112
>
113
Your changes have been saved
114
</Notification>
115
116
<Notification
117
loading
118
title="Uploading data"
119
withCloseButton={false}
120
>
121
Please wait until data is uploaded
122
</Notification>
123
</>
124
);
125
}
126
```
127
128
## Progress
129
130
Linear progress bar component with sections and labels support.
131
132
```typescript { .api }
133
interface ProgressProps {
134
/** Progress value (0-100) */
135
value?: number;
136
/** Progress color theme */
137
color?: MantineColor;
138
/** Progress size */
139
size?: MantineSize | number;
140
/** Progress radius */
141
radius?: MantineRadius;
142
/** If true, progress will be striped */
143
striped?: boolean;
144
/** If true, progress stripes will be animated */
145
animate?: boolean;
146
/** Progress label */
147
label?: string;
148
/** Progress sections for multi-colored progress */
149
sections?: ProgressSection[];
150
}
151
152
interface ProgressRootProps {
153
/** Progress root children */
154
children: React.ReactNode;
155
/** Progress size */
156
size?: MantineSize | number;
157
/** Progress radius */
158
radius?: MantineRadius;
159
}
160
161
interface ProgressSectionProps {
162
/** Section value (0-100) */
163
value: number;
164
/** Section color */
165
color?: MantineColor;
166
/** Section label */
167
label?: string;
168
/** If true, section will be striped */
169
striped?: boolean;
170
/** If true, section stripes will be animated */
171
animate?: boolean;
172
/** Section tooltip */
173
tooltip?: React.ReactNode;
174
}
175
176
interface ProgressLabelProps {
177
/** Label content */
178
children: React.ReactNode;
179
}
180
181
interface ProgressSection {
182
/** Section value */
183
value: number;
184
/** Section color */
185
color: MantineColor;
186
/** Section label */
187
label?: string;
188
/** Section tooltip */
189
tooltip?: React.ReactNode;
190
}
191
```
192
193
**Usage Example:**
194
195
```tsx
196
import { Progress } from '@mantine/core';
197
198
function ProgressDemo() {
199
return (
200
<>
201
{/* Simple progress */}
202
<Progress value={75} />
203
204
{/* Progress with label */}
205
<Progress value={40} label="40%" size="xl" radius="xl" />
206
207
{/* Striped and animated progress */}
208
<Progress value={65} striped animate color="lime" />
209
210
{/* Multi-section progress */}
211
<Progress
212
sections={[
213
{ value: 33, color: 'pink' },
214
{ value: 20, color: 'grape' },
215
{ value: 15, color: 'violet' },
216
]}
217
/>
218
219
{/* Compound component usage */}
220
<Progress.Root size="xl">
221
<Progress.Section value={35} color="cyan">
222
<Progress.Label>Documents</Progress.Label>
223
</Progress.Section>
224
<Progress.Section value={28} color="pink">
225
<Progress.Label>Photos</Progress.Label>
226
</Progress.Section>
227
<Progress.Section value={15} color="orange">
228
<Progress.Label>Other</Progress.Label>
229
</Progress.Section>
230
</Progress.Root>
231
</>
232
);
233
}
234
```
235
236
## RingProgress
237
238
Circular progress indicator with multiple sections support.
239
240
```typescript { .api }
241
interface RingProgressProps {
242
/** Progress sections */
243
sections: RingProgressSection[];
244
/** Ring thickness */
245
thickness?: number;
246
/** Ring size */
247
size?: number;
248
/** Ring progress label */
249
label?: React.ReactNode;
250
/** Root element props */
251
rootColor?: string;
252
/** Curve round caps */
253
roundCaps?: boolean;
254
}
255
256
interface RingProgressSection {
257
/** Section value (0-100) */
258
value: number;
259
/** Section color */
260
color: MantineColor;
261
/** Section tooltip */
262
tooltip?: React.ReactNode;
263
}
264
```
265
266
**Usage Example:**
267
268
```tsx
269
import { RingProgress, Text } from '@mantine/core';
270
271
function RingProgressDemo() {
272
return (
273
<>
274
{/* Simple ring progress */}
275
<RingProgress
276
sections={[{ value: 40, color: 'blue' }]}
277
label={
278
<Text c="blue" fw={700} ta="center" size="xl">
279
40%
280
</Text>
281
}
282
/>
283
284
{/* Multiple sections */}
285
<RingProgress
286
sections={[
287
{ value: 40, color: 'cyan' },
288
{ value: 25, color: 'orange' },
289
{ value: 15, color: 'grape' },
290
]}
291
label={
292
<div>
293
<Text ta="center" fz="lg" fw={700}>
294
Application data usage
295
</Text>
296
<Text ta="center" fz="sm" c="dimmed">
297
476 gb / 600 gb
298
</Text>
299
</div>
300
}
301
/>
302
303
{/* With tooltips */}
304
<RingProgress
305
sections={[
306
{ value: 30, color: 'pink', tooltip: 'Documents – 30 Gb' },
307
{ value: 15, color: 'grape', tooltip: 'Apps – 15 Gb' },
308
{ value: 10, color: 'violet', tooltip: 'Other – 10 Gb' },
309
]}
310
thickness={6}
311
size={180}
312
roundCaps
313
/>
314
</>
315
);
316
}
317
```
318
319
## SemiCircleProgress
320
321
Semi-circular progress indicator.
322
323
```typescript { .api }
324
interface SemiCircleProgressProps {
325
/** Progress value (0-100) */
326
value?: number;
327
/** Progress color */
328
color?: MantineColor;
329
/** Progress thickness */
330
thickness?: number;
331
/** Progress size */
332
size?: number;
333
/** Progress label */
334
label?: React.ReactNode;
335
/** If true, progress will have round caps */
336
roundCaps?: boolean;
337
/** Root color */
338
rootColor?: string;
339
}
340
```
341
342
**Usage Example:**
343
344
```tsx
345
import { SemiCircleProgress, Text } from '@mantine/core';
346
347
function SemiCircleProgressDemo() {
348
return (
349
<SemiCircleProgress
350
value={75}
351
color="teal"
352
size={200}
353
thickness={12}
354
label={
355
<Text ta="center" size="xl" fw={700}>
356
75%
357
</Text>
358
}
359
roundCaps
360
/>
361
);
362
}
363
```
364
365
## Loader
366
367
Loading spinner component with various animations and sizes.
368
369
```typescript { .api }
370
interface LoaderProps {
371
/** Loader variant/type */
372
type?: 'oval' | 'bars' | 'dots';
373
/** Loader size */
374
size?: MantineSize | number;
375
/** Loader color */
376
color?: MantineColor;
377
}
378
```
379
380
**Usage Example:**
381
382
```tsx
383
import { Loader, Stack } from '@mantine/core';
384
385
function LoaderDemo() {
386
return (
387
<Stack>
388
<Loader />
389
<Loader color="grape" />
390
<Loader size="xs" />
391
<Loader size="xl" />
392
<Loader type="bars" />
393
<Loader type="dots" />
394
</Stack>
395
);
396
}
397
```
398
399
## LoadingOverlay
400
401
Overlay component that displays loading state over content.
402
403
```typescript { .api }
404
interface LoadingOverlayProps {
405
/** If true, overlay is visible */
406
visible: boolean;
407
/** Overlay z-index */
408
zIndex?: number;
409
/** Overlay background color */
410
overlayProps?: OverlayProps;
411
/** Loader props */
412
loaderProps?: LoaderProps;
413
/** Transition props */
414
transitionProps?: TransitionProps;
415
}
416
```
417
418
**Usage Example:**
419
420
```tsx
421
import { LoadingOverlay, Button } from '@mantine/core';
422
import { useState } from 'react';
423
424
function LoadingOverlayDemo() {
425
const [visible, setVisible] = useState(false);
426
427
return (
428
<div style={{ position: 'relative', minHeight: 200 }}>
429
<LoadingOverlay
430
visible={visible}
431
zIndex={1000}
432
overlayProps={{ radius: 'sm', blur: 2 }}
433
loaderProps={{ color: 'pink', type: 'bars' }}
434
/>
435
436
<div>
437
<p>Content that will be covered by overlay</p>
438
<Button onClick={() => setVisible(v => !v)}>
439
Toggle overlay
440
</Button>
441
</div>
442
</div>
443
);
444
}
445
```
446
447
## Skeleton
448
449
Placeholder component for content that is loading.
450
451
```typescript { .api }
452
interface SkeletonProps {
453
/** Skeleton height */
454
height?: React.CSSProperties['height'];
455
/** Skeleton width */
456
width?: React.CSSProperties['width'];
457
/** If true, skeleton will be rounded */
458
circle?: boolean;
459
/** Skeleton radius */
460
radius?: MantineRadius;
461
/** If true, skeleton animation is disabled */
462
animate?: boolean;
463
/** If true, skeleton will be visible */
464
visible?: boolean;
465
/** Content to display when not loading */
466
children?: React.ReactNode;
467
}
468
```
469
470
**Usage Example:**
471
472
```tsx
473
import { Skeleton, Stack } from '@mantine/core';
474
475
function SkeletonDemo() {
476
return (
477
<Stack>
478
<Skeleton height={50} circle mb="xl" />
479
<Skeleton height={8} radius="xl" />
480
<Skeleton height={8} mt={6} radius="xl" />
481
<Skeleton height={8} mt={6} width="70%" radius="xl" />
482
</Stack>
483
);
484
}
485
486
// Conditional skeleton
487
function ConditionalSkeleton({ loading, children }) {
488
return (
489
<Skeleton visible={loading}>
490
{children}
491
</Skeleton>
492
);
493
}
494
```
495
496
## Theme Integration
497
498
Feedback components integrate with the Mantine theme system:
499
500
```tsx
501
import { MantineProvider } from '@mantine/core';
502
503
const theme = {
504
components: {
505
Alert: {
506
defaultProps: {
507
variant: 'light',
508
radius: 'md',
509
},
510
},
511
Progress: {
512
defaultProps: {
513
size: 'md',
514
radius: 'sm',
515
color: 'blue',
516
},
517
},
518
Loader: {
519
defaultProps: {
520
type: 'dots',
521
color: 'blue',
522
},
523
},
524
},
525
};
526
527
function App() {
528
return (
529
<MantineProvider theme={theme}>
530
{/* Components will use theme defaults */}
531
</MantineProvider>
532
);
533
}
534
```
535
536
## Common Usage Patterns
537
538
**Progress with States:**
539
```tsx
540
import { Progress, Text, Group } from '@mantine/core';
541
542
function ProgressWithStates({ value, status }) {
543
const getColor = () => {
544
if (value < 30) return 'red';
545
if (value < 70) return 'yellow';
546
return 'green';
547
};
548
549
return (
550
<div>
551
<Group justify="space-between" mb="xs">
552
<Text fz="sm" fw={500}>
553
Upload Progress
554
</Text>
555
<Text fz="sm" fw={500}>
556
{value}%
557
</Text>
558
</Group>
559
<Progress
560
value={value}
561
color={getColor()}
562
animate={status === 'uploading'}
563
/>
564
</div>
565
);
566
}
567
```
568
569
**Notification System:**
570
```tsx
571
import { Notification, Stack } from '@mantine/core';
572
573
function NotificationSystem({ notifications, onClose }) {
574
return (
575
<Stack>
576
{notifications.map((notification) => (
577
<Notification
578
key={notification.id}
579
title={notification.title}
580
color={notification.type}
581
onClose={() => onClose(notification.id)}
582
icon={getIconForType(notification.type)}
583
>
584
{notification.message}
585
</Notification>
586
))}
587
</Stack>
588
);
589
}
590
591
function getIconForType(type) {
592
const icons = {
593
success: '✅',
594
error: '❌',
595
warning: '⚠️',
596
info: 'ℹ️',
597
};
598
return icons[type];
599
}
600
```
601
602
**Loading States:**
603
```tsx
604
import { LoadingOverlay, Skeleton, Stack, Card } from '@mantine/core';
605
606
function LoadingStates({ isLoading, data }) {
607
if (isLoading) {
608
return (
609
<Stack>
610
<Skeleton height={50} circle mb="xl" />
611
<Skeleton height={8} radius="xl" />
612
<Skeleton height={8} mt={6} radius="xl" />
613
<Skeleton height={8} mt={6} width="70%" radius="xl" />
614
</Stack>
615
);
616
}
617
618
return (
619
<Card>
620
{/* Actual content */}
621
{data && <div>{data.content}</div>}
622
</Card>
623
);
624
}
625
```
626
627
## Accessibility Features
628
629
Feedback components include accessibility support:
630
631
- **ARIA Labels**: Proper labeling for progress indicators and alerts
632
- **Screen Reader Support**: Progress values and status changes are announced
633
- **Focus Management**: Close buttons and interactive elements are focusable
634
- **Color Contrast**: Sufficient contrast ratios for text and backgrounds
635
- **Semantic Markup**: Proper use of ARIA roles and properties