0
# Form Components
1
2
Comprehensive form controls including Input system, Select components, Checkbox, Radio, and specialized inputs. These components provide complete form functionality with consistent styling, validation support, and accessibility features.
3
4
## Capabilities
5
6
### Input System
7
8
The foundational input system providing consistent styling, wrapper components, and form integration across all input types.
9
10
```typescript { .api }
11
/**
12
* Base input component with label, description, error support
13
* @param props - Input component props
14
*/
15
function Input<C = 'input'>(props: InputProps<C>): JSX.Element;
16
17
interface InputProps<C = 'input'> extends BoxProps<C>, StylesApiProps<InputFactory> {
18
/** Input placeholder */
19
placeholder?: string;
20
/** Determines whether input should have error styles */
21
error?: boolean;
22
/** Input variant */
23
variant?: InputVariant;
24
/** Input size */
25
size?: MantineSize;
26
/** Left section of input */
27
leftSection?: React.ReactNode;
28
/** Width of left section */
29
leftSectionWidth?: string | number;
30
/** Props spread to left section wrapper element */
31
leftSectionProps?: Record<string, any>;
32
/** Right section of input */
33
rightSection?: React.ReactNode;
34
/** Width of right section */
35
rightSectionWidth?: string | number;
36
/** Props spread to right section wrapper element */
37
rightSectionProps?: Record<string, any>;
38
/** Determines whether input should have pointer cursor */
39
pointer?: boolean;
40
/** Determines whether input should be multiline */
41
multiline?: boolean;
42
/** Border radius from theme or number */
43
radius?: MantineRadius;
44
/** Determines whether input is disabled */
45
disabled?: boolean;
46
}
47
48
/**
49
* Input wrapper component with label, description, and error
50
* @param props - InputWrapper component props
51
*/
52
function InputWrapper(props: InputWrapperProps): JSX.Element;
53
54
interface InputWrapperProps extends BoxProps, StylesApiProps<InputWrapperFactory> {
55
/** Content */
56
children?: React.ReactNode;
57
/** Input label, displayed before input */
58
label?: React.ReactNode;
59
/** Input description, displayed after label and before input */
60
description?: React.ReactNode;
61
/** Input error, displayed after input */
62
error?: React.ReactNode;
63
/** Determines whether required asterisk should be rendered */
64
required?: boolean;
65
/** Props spread to label element */
66
labelProps?: React.ComponentPropsWithoutRef<'label'>;
67
/** Props spread to description element */
68
descriptionProps?: React.ComponentPropsWithoutRef<'div'>;
69
/** Props spread to error element */
70
errorProps?: React.ComponentPropsWithoutRef<'div'>;
71
/** Input wrapper size */
72
size?: MantineSize;
73
/** Determines whether label should have `for` attribute */
74
withAsterisk?: boolean;
75
}
76
77
/**
78
* Input compound components
79
*/
80
function InputLabel(props: InputLabelProps): JSX.Element;
81
function InputDescription(props: InputDescriptionProps): JSX.Element;
82
function InputError(props: InputErrorProps): JSX.Element;
83
function InputPlaceholder(props: InputPlaceholderProps): JSX.Element;
84
function InputClearButton(props: InputClearButtonProps): JSX.Element;
85
86
// Compound components
87
Input.Wrapper = InputWrapper;
88
Input.Label = InputLabel;
89
Input.Description = InputDescription;
90
Input.Error = InputError;
91
Input.Placeholder = InputPlaceholder;
92
93
type InputVariant = 'default' | 'filled' | 'unstyled';
94
type InputStylesNames = 'wrapper' | 'input' | 'section' | 'placeholder' | 'root';
95
```
96
97
**Basic Usage:**
98
99
```typescript
100
import { Input } from "@mantine/core";
101
102
// Basic input
103
<Input placeholder="Enter your name" />
104
105
// Input with sections
106
<Input
107
placeholder="Search"
108
leftSection={<IconSearch />}
109
rightSection={<IconX />}
110
/>
111
112
// Input wrapper with label and description
113
<Input.Wrapper
114
label="Email"
115
description="We'll never share your email"
116
error="Invalid email format"
117
required
118
>
119
<Input placeholder="your@email.com" error />
120
</Input.Wrapper>
121
```
122
123
### Text Input
124
125
Standard text input field with full Input system integration.
126
127
```typescript { .api }
128
/**
129
* Standard text input field
130
* @param props - TextInput component props
131
*/
132
function TextInput(props: TextInputProps): JSX.Element;
133
134
interface TextInputProps extends InputProps, InputWrapperProps {
135
/** Input value */
136
value?: string;
137
/** Input default value */
138
defaultValue?: string;
139
/** Called when value changes */
140
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
141
/** Input type */
142
type?: 'text' | 'email' | 'url' | 'tel' | 'search';
143
/** Maximum number of characters */
144
maxLength?: number;
145
/** Minimum number of characters */
146
minLength?: number;
147
/** Input name */
148
name?: string;
149
/** Determines whether input should be automatically completed */
150
autoComplete?: string;
151
}
152
```
153
154
**Usage Examples:**
155
156
```typescript
157
import { TextInput } from "@mantine/core";
158
159
// Basic text input
160
<TextInput
161
label="Name"
162
placeholder="Your name"
163
required
164
/>
165
166
// Controlled text input
167
const [value, setValue] = useState('');
168
<TextInput
169
label="Email"
170
value={value}
171
onChange={(event) => setValue(event.currentTarget.value)}
172
type="email"
173
/>
174
175
// Text input with validation
176
<TextInput
177
label="Username"
178
description="Username must be unique"
179
error={error}
180
leftSection={<IconUser />}
181
maxLength={20}
182
/>
183
```
184
185
### Password Input
186
187
Password input with visibility toggle functionality.
188
189
```typescript { .api }
190
/**
191
* Password input with visibility toggle
192
* @param props - PasswordInput component props
193
*/
194
function PasswordInput(props: PasswordInputProps): JSX.Element;
195
196
interface PasswordInputProps extends InputProps, InputWrapperProps {
197
/** Password value */
198
value?: string;
199
/** Default password value */
200
defaultValue?: string;
201
/** Called when value changes */
202
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
203
/** Determines whether password should be visible */
204
visible?: boolean;
205
/** Called when visibility changes */
206
onVisibilityChange?: (visible: boolean) => void;
207
/** Default visible state */
208
defaultVisible?: boolean;
209
/** Visibility toggle button props */
210
visibilityToggleButtonProps?: React.ComponentPropsWithoutRef<'button'>;
211
/** Custom visibility toggle icon */
212
visibilityToggleIcon?: (props: { reveal: boolean }) => React.ReactNode;
213
}
214
```
215
216
**Usage Examples:**
217
218
```typescript
219
import { PasswordInput } from "@mantine/core";
220
221
// Basic password input
222
<PasswordInput
223
label="Password"
224
placeholder="Your password"
225
required
226
/>
227
228
// Controlled password input
229
const [password, setPassword] = useState('');
230
const [visible, setVisible] = useState(false);
231
232
<PasswordInput
233
label="Password"
234
value={password}
235
onChange={(event) => setPassword(event.currentTarget.value)}
236
visible={visible}
237
onVisibilityChange={setVisible}
238
/>
239
```
240
241
### Number Input
242
243
Numeric input with increment/decrement controls and formatting.
244
245
```typescript { .api }
246
/**
247
* Numeric input with increment/decrement controls
248
* @param props - NumberInput component props
249
*/
250
function NumberInput(props: NumberInputProps): JSX.Element;
251
252
interface NumberInputProps extends InputProps, InputWrapperProps {
253
/** Input value */
254
value?: string | number;
255
/** Default input value */
256
defaultValue?: string | number;
257
/** Called when value changes */
258
onChange?: (value: string | number) => void;
259
/** Maximum value */
260
max?: number;
261
/** Minimum value */
262
min?: number;
263
/** Number increment/decrement on arrow key press and wheel event */
264
step?: number;
265
/** Only works if a `step` is defined. When `true`, incrementing/decrementing will snap to multiples of step value */
266
stepHoldDelay?: number;
267
/** Delay before stepping the value when control is held */
268
stepHoldInterval?: number;
269
/** Determines whether leading zeros should be removed from the value */
270
allowLeadingZeros?: boolean;
271
/** Determines whether negative values are allowed */
272
allowNegative?: boolean;
273
/** Determines whether decimal values are allowed */
274
allowDecimal?: boolean;
275
/** Characters that should trigger decimal separator */
276
decimalSeparator?: string;
277
/** Number of decimal places */
278
decimalScale?: number;
279
/** If set, fixes the number of decimal places */
280
fixedDecimalScale?: boolean;
281
/** Prefix to add before the input value */
282
prefix?: string;
283
/** Suffix to add after the input value */
284
suffix?: string;
285
/** Thousand separator character */
286
thousandSeparator?: string | boolean;
287
/** Determines whether the input should have controls */
288
hideControls?: boolean;
289
/** Props passed to increment control */
290
incrementProps?: React.ComponentPropsWithoutRef<'button'>;
291
/** Props passed to decrement control */
292
decrementProps?: React.ComponentPropsWithoutRef<'button'>;
293
/** Get input handlers to control increment/decrement outside of the component */
294
handlersRef?: React.MutableRefObject<NumberInputHandlers | undefined>;
295
}
296
297
interface NumberInputHandlers {
298
increment(): void;
299
decrement(): void;
300
}
301
```
302
303
**Usage Examples:**
304
305
```typescript
306
import { NumberInput } from "@mantine/core";
307
308
// Basic number input
309
<NumberInput
310
label="Age"
311
placeholder="Your age"
312
min={0}
313
max={120}
314
/>
315
316
// Number input with formatting
317
<NumberInput
318
label="Price"
319
prefix="$"
320
thousandSeparator=","
321
decimalScale={2}
322
fixedDecimalScale
323
/>
324
325
// Number input with custom handlers
326
const handlersRef = useRef<NumberInputHandlers>();
327
328
<NumberInput
329
label="Quantity"
330
value={quantity}
331
onChange={setQuantity}
332
min={1}
333
step={5}
334
handlersRef={handlersRef}
335
/>
336
```
337
338
### Textarea
339
340
Multi-line text input with auto-resize capability.
341
342
```typescript { .api }
343
/**
344
* Multi-line text input
345
* @param props - Textarea component props
346
*/
347
function Textarea(props: TextareaProps): JSX.Element;
348
349
interface TextareaProps extends InputProps, InputWrapperProps {
350
/** Textarea value */
351
value?: string;
352
/** Default textarea value */
353
defaultValue?: string;
354
/** Called when value changes */
355
onChange?: (event: React.ChangeEvent<HTMLTextAreaElement>) => void;
356
/** Number of visible rows */
357
rows?: number;
358
/** Maximum number of visible rows, used for auto-resize */
359
maxRows?: number;
360
/** Minimum number of visible rows, used for auto-resize */
361
minRows?: number;
362
/** Determines whether textarea should automatically resize to fit content */
363
autosize?: boolean;
364
/** Maximum number of characters */
365
maxLength?: number;
366
/** Determines whether textarea should expand to fill container */
367
resize?: 'none' | 'both' | 'horizontal' | 'vertical';
368
}
369
```
370
371
**Usage Examples:**
372
373
```typescript
374
import { Textarea } from "@mantine/core";
375
376
// Basic textarea
377
<Textarea
378
label="Comment"
379
placeholder="Your comment"
380
rows={4}
381
/>
382
383
// Auto-resizing textarea
384
<Textarea
385
label="Description"
386
placeholder="Enter description"
387
autosize
388
minRows={2}
389
maxRows={6}
390
/>
391
392
// Controlled textarea
393
const [value, setValue] = useState('');
394
<Textarea
395
label="Message"
396
value={value}
397
onChange={(event) => setValue(event.currentTarget.value)}
398
maxLength={500}
399
/>
400
```
401
402
### Select Components
403
404
Dropdown selection components including single select, multi-select, and native select.
405
406
```typescript { .api }
407
/**
408
* Single-select dropdown component
409
* @param props - Select component props
410
*/
411
function Select(props: SelectProps): JSX.Element;
412
413
interface SelectProps extends InputProps, InputWrapperProps, ComboboxLikeProps {
414
/** Select data */
415
data: ComboboxData;
416
/** Selected value */
417
value?: string | null;
418
/** Default selected value */
419
defaultValue?: string | null;
420
/** Called when value changes */
421
onChange?: (value: string | null, option: ComboboxParsedItem) => void;
422
/** Determines whether the select should be searchable */
423
searchable?: boolean;
424
/** Function to determine if option should be selectable */
425
allowDeselect?: boolean;
426
/** Determines whether the select should be clearable */
427
clearable?: boolean;
428
/** Maximum number of options displayed at a time */
429
limit?: number;
430
/** Function to filter options based on search query */
431
filter?: OptionsFilter;
432
/** Determines whether option should remain highlighted after selection */
433
withCheckIcon?: boolean;
434
/** Check icon */
435
checkIconPosition?: 'left' | 'right';
436
/** Dropdown position */
437
dropdownPosition?: 'bottom' | 'top';
438
/** Dropdown width */
439
dropdownWidth?: number | 'target';
440
}
441
442
/**
443
* Multi-select dropdown component
444
* @param props - MultiSelect component props
445
*/
446
function MultiSelect(props: MultiSelectProps): JSX.Element;
447
448
interface MultiSelectProps extends InputProps, InputWrapperProps, ComboboxLikeProps {
449
/** Select data */
450
data: ComboboxData;
451
/** Selected values */
452
value?: string[];
453
/** Default selected values */
454
defaultValue?: string[];
455
/** Called when value changes */
456
onChange?: (value: string[], options: ComboboxParsedItem[]) => void;
457
/** Determines whether the select should be searchable */
458
searchable?: boolean;
459
/** Determines whether the select should be clearable */
460
clearable?: boolean;
461
/** Maximum number of selected values */
462
maxValues?: number;
463
/** Determines whether duplicate values are allowed */
464
allowDuplicates?: boolean;
465
/** Hide selected options from the list */
466
hidePickedOptions?: boolean;
467
}
468
469
/**
470
* Native HTML select element
471
* @param props - NativeSelect component props
472
*/
473
function NativeSelect(props: NativeSelectProps): JSX.Element;
474
475
interface NativeSelectProps extends InputProps, InputWrapperProps {
476
/** Select data */
477
data: (string | { value: string; label: string; disabled?: boolean })[];
478
/** Selected value */
479
value?: string;
480
/** Default selected value */
481
defaultValue?: string;
482
/** Called when value changes */
483
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
484
}
485
```
486
487
**Usage Examples:**
488
489
```typescript
490
import { Select, MultiSelect, NativeSelect } from "@mantine/core";
491
492
// Basic select
493
<Select
494
label="Country"
495
placeholder="Pick a country"
496
data={['United States', 'Canada', 'Mexico', 'United Kingdom']}
497
/>
498
499
// Select with objects
500
<Select
501
label="Framework"
502
data={[
503
{ value: 'react', label: 'React' },
504
{ value: 'vue', label: 'Vue.js' },
505
{ value: 'angular', label: 'Angular' }
506
]}
507
value={framework}
508
onChange={setFramework}
509
/>
510
511
// Searchable select
512
<Select
513
label="Technology"
514
placeholder="Search technologies"
515
data={technologies}
516
searchable
517
clearable
518
/>
519
520
// Multi-select
521
<MultiSelect
522
label="Languages"
523
placeholder="Pick languages you know"
524
data={['JavaScript', 'TypeScript', 'Python', 'Java', 'C++', 'Rust']}
525
value={selectedLanguages}
526
onChange={setSelectedLanguages}
527
maxValues={3}
528
/>
529
530
// Native select
531
<NativeSelect
532
label="Size"
533
data={['XS', 'S', 'M', 'L', 'XL']}
534
value={size}
535
onChange={(event) => setSize(event.currentTarget.value)}
536
/>
537
```
538
539
### Checkbox Components
540
541
Checkbox controls with group functionality and card variants.
542
543
```typescript { .api }
544
/**
545
* Checkbox input component
546
* @param props - Checkbox component props
547
*/
548
function Checkbox(props: CheckboxProps): JSX.Element;
549
550
interface CheckboxProps extends InputProps, InputWrapperProps {
551
/** Checkbox checked state */
552
checked?: boolean;
553
/** Default checked state */
554
defaultChecked?: boolean;
555
/** Called when checked state changes */
556
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
557
/** Checkbox value */
558
value?: string;
559
/** Determines whether checkbox is indeterminate */
560
indeterminate?: boolean;
561
/** Checkbox label */
562
label?: React.ReactNode;
563
/** Icon displayed when checkbox is checked */
564
icon?: React.FC<CheckboxIconProps>;
565
/** Icon displayed when checkbox is indeterminate */
566
indeterminateIcon?: React.FC<CheckboxIconProps>;
567
/** Checkbox color */
568
color?: MantineColor;
569
/** Checkbox radius */
570
radius?: MantineRadius;
571
/** Determines whether checkbox label should have pointer cursor */
572
labelPosition?: 'left' | 'right';
573
}
574
575
/**
576
* Checkbox group component
577
* @param props - CheckboxGroup component props
578
*/
579
function CheckboxGroup(props: CheckboxGroupProps): JSX.Element;
580
581
interface CheckboxGroupProps extends InputWrapperProps {
582
/** Selected values */
583
value?: string[];
584
/** Default selected values */
585
defaultValue?: string[];
586
/** Called when value changes */
587
onChange?: (value: string[]) => void;
588
/** Checkbox group name */
589
name?: string;
590
/** Checkboxes */
591
children: React.ReactNode;
592
}
593
594
/**
595
* Checkbox card component
596
* @param props - CheckboxCard component props
597
*/
598
function CheckboxCard(props: CheckboxCardProps): JSX.Element;
599
600
interface CheckboxCardProps extends CheckboxProps {
601
/** Card content */
602
children?: React.ReactNode;
603
/** Determines whether card should have border when checked */
604
withBorder?: boolean;
605
}
606
607
/**
608
* Checkbox indicator component
609
* @param props - CheckboxIndicator component props
610
*/
611
function CheckboxIndicator(props: CheckboxIndicatorProps): JSX.Element;
612
613
// Compound components
614
Checkbox.Group = CheckboxGroup;
615
Checkbox.Indicator = CheckboxIndicator;
616
Checkbox.Card = CheckboxCard;
617
```
618
619
**Usage Examples:**
620
621
```typescript
622
import { Checkbox } from "@mantine/core";
623
624
// Basic checkbox
625
<Checkbox
626
label="I agree to the terms of service"
627
checked={agreed}
628
onChange={(event) => setAgreed(event.currentTarget.checked)}
629
/>
630
631
// Checkbox group
632
<Checkbox.Group
633
label="Select your favorite frameworks"
634
value={frameworks}
635
onChange={setFrameworks}
636
>
637
<Group mt="xs">
638
<Checkbox value="react" label="React" />
639
<Checkbox value="vue" label="Vue" />
640
<Checkbox value="angular" label="Angular" />
641
</Group>
642
</Checkbox.Group>
643
644
// Checkbox cards
645
<Checkbox.Group value={selectedCards} onChange={setSelectedCards}>
646
<Group>
647
<Checkbox.Card value="card1" withBorder>
648
<Text fw={500}>Card Option 1</Text>
649
<Text size="sm" c="dimmed">Description for option 1</Text>
650
</Checkbox.Card>
651
<Checkbox.Card value="card2" withBorder>
652
<Text fw={500}>Card Option 2</Text>
653
<Text size="sm" c="dimmed">Description for option 2</Text>
654
</Checkbox.Card>
655
</Group>
656
</Checkbox.Group>
657
```
658
659
### Radio Components
660
661
Radio button controls with group functionality and card variants.
662
663
```typescript { .api }
664
/**
665
* Radio button component
666
* @param props - Radio component props
667
*/
668
function Radio(props: RadioProps): JSX.Element;
669
670
interface RadioProps extends InputProps, InputWrapperProps {
671
/** Radio checked state */
672
checked?: boolean;
673
/** Default checked state */
674
defaultChecked?: boolean;
675
/** Called when checked state changes */
676
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
677
/** Radio value */
678
value?: string;
679
/** Radio label */
680
label?: React.ReactNode;
681
/** Icon displayed when radio is checked */
682
icon?: React.FC<RadioIconProps>;
683
/** Radio color */
684
color?: MantineColor;
685
/** Determines whether radio label should have pointer cursor */
686
labelPosition?: 'left' | 'right';
687
}
688
689
/**
690
* Radio group component
691
* @param props - RadioGroup component props
692
*/
693
function RadioGroup(props: RadioGroupProps): JSX.Element;
694
695
interface RadioGroupProps extends InputWrapperProps {
696
/** Selected value */
697
value?: string;
698
/** Default selected value */
699
defaultValue?: string;
700
/** Called when value changes */
701
onChange?: (value: string) => void;
702
/** Radio group name */
703
name?: string;
704
/** Radio buttons */
705
children: React.ReactNode;
706
}
707
708
/**
709
* Radio card component
710
* @param props - RadioCard component props
711
*/
712
function RadioCard(props: RadioCardProps): JSX.Element;
713
714
interface RadioCardProps extends RadioProps {
715
/** Card content */
716
children?: React.ReactNode;
717
/** Determines whether card should have border when checked */
718
withBorder?: boolean;
719
}
720
721
// Compound components
722
Radio.Group = RadioGroup;
723
Radio.Indicator = RadioIndicator;
724
Radio.Card = RadioCard;
725
```
726
727
**Usage Examples:**
728
729
```typescript
730
import { Radio } from "@mantine/core";
731
732
// Radio group
733
<Radio.Group
734
label="Select your favorite framework"
735
value={framework}
736
onChange={setFramework}
737
>
738
<Group mt="xs">
739
<Radio value="react" label="React" />
740
<Radio value="vue" label="Vue" />
741
<Radio value="angular" label="Angular" />
742
</Group>
743
</Radio.Group>
744
745
// Radio cards
746
<Radio.Group value={selectedPlan} onChange={setSelectedPlan}>
747
<Group>
748
<Radio.Card value="basic" withBorder>
749
<Text fw={500}>Basic Plan</Text>
750
<Text size="sm" c="dimmed">$9/month</Text>
751
</Radio.Card>
752
<Radio.Card value="premium" withBorder>
753
<Text fw={500}>Premium Plan</Text>
754
<Text size="sm" c="dimmed">$19/month</Text>
755
</Radio.Card>
756
</Group>
757
</Radio.Group>
758
```
759
760
### Switch Component
761
762
Toggle switch component for binary choices.
763
764
```typescript { .api }
765
/**
766
* Toggle switch component
767
* @param props - Switch component props
768
*/
769
function Switch(props: SwitchProps): JSX.Element;
770
771
interface SwitchProps extends InputProps, InputWrapperProps {
772
/** Switch checked state */
773
checked?: boolean;
774
/** Default checked state */
775
defaultChecked?: boolean;
776
/** Called when checked state changes */
777
onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
778
/** Switch label */
779
label?: React.ReactNode;
780
/** Label displayed on the thumb when switch is on */
781
onLabel?: React.ReactNode;
782
/** Label displayed on the thumb when switch is off */
783
offLabel?: React.ReactNode;
784
/** Switch color */
785
color?: MantineColor;
786
/** Determines whether switch label should have pointer cursor */
787
labelPosition?: 'left' | 'right';
788
/** Thumb icon when switch is on */
789
thumbIcon?: React.ReactNode;
790
}
791
792
/**
793
* Switch group component
794
* @param props - SwitchGroup component props
795
*/
796
function SwitchGroup(props: SwitchGroupProps): JSX.Element;
797
798
// Compound components
799
Switch.Group = SwitchGroup;
800
```
801
802
**Usage Examples:**
803
804
```typescript
805
import { Switch } from "@mantine/core";
806
807
// Basic switch
808
<Switch
809
label="Enable notifications"
810
checked={notifications}
811
onChange={(event) => setNotifications(event.currentTarget.checked)}
812
/>
813
814
// Switch with labels
815
<Switch
816
label="Dark mode"
817
onLabel="ON"
818
offLabel="OFF"
819
checked={darkMode}
820
onChange={(event) => setDarkMode(event.currentTarget.checked)}
821
/>
822
```
823
824
### Slider Components
825
826
Range slider components for numeric value selection.
827
828
```typescript { .api }
829
/**
830
* Single value slider component
831
* @param props - Slider component props
832
*/
833
function Slider(props: SliderProps): JSX.Element;
834
835
interface SliderProps extends InputWrapperProps, StylesApiProps<SliderFactory> {
836
/** Slider value */
837
value?: number;
838
/** Default slider value */
839
defaultValue?: number;
840
/** Called when value changes */
841
onChange?: (value: number) => void;
842
/** Called when dragging ends */
843
onChangeEnd?: (value: number) => void;
844
/** Minimum value */
845
min?: number;
846
/** Maximum value */
847
max?: number;
848
/** Step for value increment/decrement */
849
step?: number;
850
/** Number of decimal places for value */
851
precision?: number;
852
/** Determines whether thumb label should be displayed */
853
showLabelOnHover?: boolean;
854
/** Content displayed in thumb label */
855
label?: React.ReactNode | ((value: number) => React.ReactNode);
856
/** Marks displayed on the track */
857
marks?: { value: number; label?: React.ReactNode }[];
858
/** Slider color */
859
color?: MantineColor;
860
/** Slider radius */
861
radius?: MantineRadius;
862
/** Slider size */
863
size?: MantineSize;
864
/** Determines whether slider is disabled */
865
disabled?: boolean;
866
/** Thumb icon */
867
thumbIcon?: React.ReactNode;
868
/** Determines whether slider should be inverted */
869
inverted?: boolean;
870
}
871
872
/**
873
* Range slider component for selecting a range of values
874
* @param props - RangeSlider component props
875
*/
876
function RangeSlider(props: RangeSliderProps): JSX.Element;
877
878
interface RangeSliderProps extends Omit<SliderProps, 'value' | 'defaultValue' | 'onChange' | 'onChangeEnd'> {
879
/** Range value */
880
value?: RangeSliderValue;
881
/** Default range value */
882
defaultValue?: RangeSliderValue;
883
/** Called when value changes */
884
onChange?: (value: RangeSliderValue) => void;
885
/** Called when dragging ends */
886
onChangeEnd?: (value: RangeSliderValue) => void;
887
/** Minimum range between values */
888
minRange?: number;
889
/** Maximum range between values */
890
maxRange?: number;
891
}
892
893
type RangeSliderValue = [number, number];
894
```
895
896
**Usage Examples:**
897
898
```typescript
899
import { Slider, RangeSlider } from "@mantine/core";
900
901
// Basic slider
902
<Slider
903
label="Volume"
904
value={volume}
905
onChange={setVolume}
906
min={0}
907
max={100}
908
step={5}
909
marks={[
910
{ value: 0, label: '0%' },
911
{ value: 50, label: '50%' },
912
{ value: 100, label: '100%' }
913
]}
914
/>
915
916
// Range slider
917
<RangeSlider
918
label="Price range"
919
value={priceRange}
920
onChange={setPriceRange}
921
min={0}
922
max={1000}
923
step={10}
924
minRange={50}
925
/>
926
```
927
928
### Combobox System
929
930
Advanced combobox system providing the foundation for complex selection components.
931
932
```typescript { .api }
933
/**
934
* Flexible combobox component for building custom selection inputs
935
* @param props - Combobox component props
936
*/
937
function Combobox(props: ComboboxProps): JSX.Element;
938
939
interface ComboboxProps extends BoxProps, StylesApiProps<ComboboxFactory> {
940
/** Combobox store */
941
store: ComboboxStore;
942
/** Determines whether dropdown should be rendered within Portal */
943
withinPortal?: boolean;
944
/** Dropdown position relative to target */
945
position?: FloatingPosition;
946
/** Dropdown z-index */
947
zIndex?: number;
948
/** Props passed down to Transition component */
949
transitionProps?: TransitionProps;
950
/** Dropdown shadow from theme or custom value */
951
shadow?: MantineShadow;
952
/** Determines whether focus should be trapped within dropdown */
953
trapFocus?: boolean;
954
/** Called when dropdown closes */
955
onClose?: () => void;
956
/** Called when dropdown opens */
957
onOpen?: () => void;
958
/** Combobox content */
959
children?: React.ReactNode;
960
}
961
962
/**
963
* Hook to manage combobox state
964
* @param options - Combobox configuration options
965
* @returns Combobox store
966
*/
967
function useCombobox(options?: UseComboboxOptions): ComboboxStore;
968
969
interface UseComboboxOptions {
970
/** Determines whether dropdown should be opened by default */
971
defaultOpened?: boolean;
972
/** Called when dropdown opens */
973
onDropdownOpen?: () => void;
974
/** Called when dropdown closes */
975
onDropdownClose?: () => void;
976
}
977
978
/**
979
* Combobox compound components
980
*/
981
function ComboboxTarget(props: ComboboxTargetProps): JSX.Element;
982
function ComboboxDropdown(props: ComboboxDropdownProps): JSX.Element;
983
function ComboboxOptions(props: ComboboxOptionsProps): JSX.Element;
984
function ComboboxOption(props: ComboboxOptionProps): JSX.Element;
985
function ComboboxGroup(props: ComboboxGroupProps): JSX.Element;
986
function ComboboxSearch(props: ComboboxSearchProps): JSX.Element;
987
function ComboboxEmpty(props: ComboboxEmptyProps): JSX.Element;
988
function ComboboxHeader(props: ComboboxHeaderProps): JSX.Element;
989
function ComboboxFooter(props: ComboboxFooterProps): JSX.Element;
990
function ComboboxClearButton(props: ComboboxClearButtonProps): JSX.Element;
991
992
// Compound components
993
Combobox.Target = ComboboxTarget;
994
Combobox.Dropdown = ComboboxDropdown;
995
Combobox.Options = ComboboxOptions;
996
Combobox.Option = ComboboxOption;
997
Combobox.Group = ComboboxGroup;
998
Combobox.Search = ComboboxSearch;
999
Combobox.Empty = ComboboxEmpty;
1000
Combobox.Header = ComboboxHeader;
1001
Combobox.Footer = ComboboxFooter;
1002
Combobox.ClearButton = ComboboxClearButton;
1003
```
1004
1005
**Advanced Usage:**
1006
1007
```typescript
1008
import { Combobox, Input, InputBase, useCombobox } from "@mantine/core";
1009
1010
function CustomSelect() {
1011
const combobox = useCombobox({
1012
onDropdownClose: () => combobox.resetSelectedOption(),
1013
});
1014
1015
const [value, setValue] = useState<string | null>(null);
1016
const [search, setSearch] = useState('');
1017
1018
const options = groceries
1019
.filter(item => item.toLowerCase().includes(search.toLowerCase().trim()))
1020
.map(item => (
1021
<Combobox.Option value={item} key={item}>
1022
{item}
1023
</Combobox.Option>
1024
));
1025
1026
return (
1027
<Combobox
1028
store={combobox}
1029
onOptionSubmit={(val) => {
1030
setValue(val);
1031
setSearch(val);
1032
combobox.closeDropdown();
1033
}}
1034
>
1035
<Combobox.Target>
1036
<InputBase
1037
component="button"
1038
type="button"
1039
pointer
1040
rightSection={<Combobox.Chevron />}
1041
onClick={() => combobox.toggleDropdown()}
1042
>
1043
{value || <Input.Placeholder>Pick value</Input.Placeholder>}
1044
</InputBase>
1045
</Combobox.Target>
1046
1047
<Combobox.Dropdown>
1048
<Combobox.Search
1049
value={search}
1050
onChange={(event) => setSearch(event.currentTarget.value)}
1051
placeholder="Search groceries"
1052
/>
1053
<Combobox.Options>
1054
{options.length > 0 ? options : <Combobox.Empty>Nothing found</Combobox.Empty>}
1055
</Combobox.Options>
1056
</Combobox.Dropdown>
1057
</Combobox>
1058
);
1059
}
1060
```
1061
1062
### File Input
1063
1064
File selection input with drag and drop support.
1065
1066
```typescript { .api }
1067
/**
1068
* File upload input component
1069
* @param props - FileInput component props
1070
*/
1071
function FileInput(props: FileInputProps): JSX.Element;
1072
1073
interface FileInputProps extends InputProps, InputWrapperProps {
1074
/** Selected file */
1075
value?: File | null;
1076
/** Default selected file */
1077
defaultValue?: File | null;
1078
/** Called when file is selected */
1079
onChange?: (file: File | null) => void;
1080
/** File input accept attribute */
1081
accept?: string;
1082
/** Determines whether multiple files can be selected */
1083
multiple?: boolean;
1084
/** Capture attribute for mobile file inputs */
1085
capture?: boolean | 'user' | 'environment';
1086
/** Function to get display value from file */
1087
valueComponent?: React.FC<{ value: File }>;
1088
}
1089
```
1090
1091
**Usage Examples:**
1092
1093
```typescript
1094
import { FileInput } from "@mantine/core";
1095
1096
// Basic file input
1097
<FileInput
1098
label="Upload resume"
1099
placeholder="Choose file"
1100
accept="application/pdf"
1101
value={file}
1102
onChange={setFile}
1103
/>
1104
1105
// Multiple file input
1106
<FileInput
1107
label="Upload images"
1108
placeholder="Choose files"
1109
accept="image/*"
1110
multiple
1111
value={files}
1112
onChange={setFiles}
1113
/>
1114
```