Forms
Form control styles, layout options, and custom components.
Supported input types
import FormLabel from 'react-bootstrap/FormLabel'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
import FormRange from 'react-bootstrap/FormRange'
export default function FormsInputTypesDemo() {
return (
<>
{/* Text input */}
<div className="mb-3">
<FormLabel htmlFor="text-input">Text</FormLabel>
<FormControl type="text" id="text-input" defaultValue="Artisanal kale" />
</div>
{/* Search input */}
<div className="mb-3">
<FormLabel htmlFor="search-input">Search</FormLabel>
<FormControl type="search" id="search-input" defaultValue="How do I shoot web" />
</div>
{/* Email input */}
<div className="mb-3">
<FormLabel htmlFor="email-input">Email</FormLabel>
<FormControl type="email" id="email-input" defaultValue="email@example.com" />
</div>
{/* URL input */}
<div className="mb-3">
<FormLabel htmlFor="url-input">URL</FormLabel>
<FormControl type="url" id="url-input" defaultValue="https://getbootstrap.com" />
</div>
{/* Phone input */}
<div className="mb-3">
<FormLabel htmlFor="tel-input">Phone</FormLabel>
<FormControl type="tel" id="tel-input" defaultValue="1-(770)-334-2518" />
</div>
{/* Password input */}
<div className="mb-3">
<FormLabel htmlFor="pass-input">Password</FormLabel>
<FormControl type="password" id="pass-input" defaultValue="mypasswordexample" />
</div>
{/* Textarea */}
<div className="mb-3">
<FormLabel htmlFor="textarea-input">Textarea</FormLabel>
<FormControl as="textarea" id="textarea-input" rows={5} defaultValue="Hello World!" />
</div>
{/* Select */}
<div className="mb-3">
<FormLabel htmlFor="select-input">Select</FormLabel>
<FormSelect id="select-input" defaultValue="" aria-label="Default select example">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
</div>
{/* Multiselect */}
<div className="mb-3">
<FormLabel htmlFor="multiselect-input">Multiselect</FormLabel>
<FormSelect id="multiselect-input" multiple defaultValue={['1']} aria-label="Multiple select example">
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
<option value="4">Option item 4</option>
<option value="5">Option item 5</option>
<option value="6">Option item 6</option>
</FormSelect>
</div>
{/* File input */}
<div className="mb-3">
<FormLabel htmlFor="file-input">File</FormLabel>
<FormControl type="file" id="file-input" />
</div>
{/* Number input */}
<div className="mb-3">
<FormLabel htmlFor="number-input">Number</FormLabel>
<FormControl type="number" id="number-input" defaultValue={37} />
</div>
{/* Datalist */}
<div className="mb-3">
<FormLabel htmlFor="datalist-input">Datalist</FormLabel>
<FormControl type="text" list="datalist-options" id="datalist-input" placeholder="Type to search..." />
<datalist id="datalist-options">
<option value="San Francisco"></option>
<option value="New York"></option>
<option value="Seattle"></option>
<option value="Los Angeles"></option>
<option value="Chicago"></option>
</datalist>
</div>
{/* Range input */}
<div className="mb-3">
<FormLabel htmlFor="range-input">Range</FormLabel>
<FormRange />
</div>
{/* Color input */}
<div className="mb-3">
<FormLabel htmlFor="color-input">Color</FormLabel>
<FormControl type="color" className="form-control-color" id="color-input" defaultValue="#ffa14a" />
</div>
</>
)
}
Floating labels
import FloatingLabel from 'react-bootstrap/FloatingLabel'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
export default function FormsFloatingLabelsDemo() {
return (
<>
{/* Text input */}
<FloatingLabel controlId="fl-text" label="Your name" className="mb-3">
<FormControl type="text" placeholder="Your name" />
</FloatingLabel>
{/* Select */}
<FloatingLabel controlId="fl-select" label="Your country" className="mb-3">
<FormSelect aria-label="Floating label select">
<option value="Argentina">Argentina</option>
<option value="Belgium">Belgium</option>
<option value="France">France</option>
<option value="Germany">Germany</option>
<option value="Japan">Japan</option>
<option value="Spain">Spain</option>
<option value="USA">USA</option>
</FormSelect>
</FloatingLabel>
{/* Textarea */}
<FloatingLabel controlId="fl-textarea" label="Your message">
<FormControl as="textarea" placeholder="Your message" style={{ height: 120 }} />
</FloatingLabel>
</>
)
}
Custom select
Learn more about this component in Select box section.
import FloatingLabel from 'react-bootstrap/FloatingLabel'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
export default function FormsCustomSelectDemo() {
return (
<>
{/* Basic example of custom select */}
<FormLabel>Basic example</FormLabel>
<SelectBox
choices={[
{ value: 'Argentina', label: 'Argentina' },
{ value: 'Belgium', label: 'Belgium' },
{ value: 'Denmark', label: 'Denmark' },
{ value: 'France', label: 'France' },
{ value: 'Germany', label: 'Germany' },
{ value: 'Japan', label: 'Japan' },
{ value: 'Switzerland', label: 'Switzerland' },
]}
placeholder="Select country..."
className="mb-3"
aria-label="Basic select example"
/>
{/* Added search functionality */}
<FormLabel>Search example</FormLabel>
<SelectBox
choices={[
{ value: 'Argentina', label: 'Argentina' },
{ value: 'Belgium', label: 'Belgium' },
{ value: 'Denmark', label: 'Denmark' },
{ value: 'France', label: 'France' },
{ value: 'Germany', label: 'Germany' },
{ value: 'Japan', label: 'Japan' },
{ value: 'Switzerland', label: 'Switzerland' },
{ value: 'United Kingdom', label: 'United Kingdom' },
{ value: 'United States', label: 'United States' },
]}
searchEnabled
placeholder="Select country..."
aria-label="Select with search"
/>
</>
)
}
Password visibility toggle
import FormLabel from 'react-bootstrap/FormLabel'
import PasswordInput from '@/components/forms/password-input'
export default function FormsPasswordToggleInputDemo() {
return (
<>
<FormLabel htmlFor="pass-visibility">Password</FormLabel>
<PasswordInput id="pass-visibility" defaultValue="hidden@password" />
</>
)
}
Checkboxes
import FormCheck from 'react-bootstrap/FormCheck'
export default function FormsCheckboxesDemo() {
return (
<>
{/* Stacked checkboxes */}
{[
{ id: 'ex-check-1', label: 'Check this checkbox' },
{ id: 'ex-check-2', label: 'Uncheck this checkbox', checked: true },
{ id: 'ex-check-3', label: 'Disabled checkbox', disabled: true },
{ id: 'ex-check-4', label: 'Disabled checked', checked: true, disabled: true },
].map(({ id, label, checked, disabled }) => (
<FormCheck key={id} id={id} label={label} defaultChecked={checked} disabled={disabled} />
))}
{/* Inline checkboxes */}
<div className="pt-3">
{[
{ id: 'ex-check-5', label: 'Check this checkbox' },
{ id: 'ex-check-6', label: 'Uncheck this checkbox', checked: true },
{ id: 'ex-check-7', label: 'Disabled checkbox', disabled: true },
{ id: 'ex-check-8', label: 'Disabled checked', checked: true, disabled: true },
].map(({ id, label, checked, disabled }) => (
<FormCheck key={id} inline id={id} label={label} defaultChecked={checked} disabled={disabled} />
))}
</div>
</>
)
}
Radio buttons
import FormCheck from 'react-bootstrap/FormCheck'
export default function FormsRadiosDemo() {
return (
<>
{/* Stacked radio buttons */}
{[
{ id: 'ex-radio-1', label: 'Toggle this radio' },
{ id: 'ex-radio-2', label: 'Toggle this radio', checked: true },
{ id: 'ex-radio-3', label: 'Disabled radio', disabled: true },
{ id: 'ex-radio-4', label: 'Disabled checked', checked: true, disabled: true },
].map(({ id, label, checked, disabled }) => (
<FormCheck
key={id}
type="radio"
id={id}
name={`${!disabled ? 'radio' : ''}`}
label={label}
defaultChecked={checked}
disabled={disabled}
/>
))}
{/* Inline radio buttons */}
<div className="pt-3">
{[
{ id: 'ex-radio-5', label: 'Toggle this radio' },
{ id: 'ex-radio-6', label: 'Toggle this radio', checked: true },
{ id: 'ex-radio-7', label: 'Disabled radio', disabled: true },
{ id: 'ex-radio-8', label: 'Disabled checked', checked: true, disabled: true },
].map(({ id, label, checked, disabled }) => (
<FormCheck
key={id}
type="radio"
inline
id={id}
name={`${!disabled ? 'inline-radio' : ''}`}
label={label}
defaultChecked={checked}
disabled={disabled}
/>
))}
</div>
</>
)
}
Switches
import FormCheck from 'react-bootstrap/FormCheck'
export default function FormsSwitchesDemo() {
return (
<>
{[
{ id: 'ex-switch-1', label: 'Default switch checkbox' },
{ id: 'ex-switch-2', label: 'Checked switch checkbox', checked: true },
{ id: 'ex-switch-3', label: 'Disabled switch checkbox', disabled: true },
{ id: 'ex-switch-4', label: 'Disabled checked switch checkbox', checked: true, disabled: true },
].map(({ id, label, checked, disabled }) => (
<FormCheck key={id} type="switch" id={id} label={label} defaultChecked={checked} disabled={disabled} />
))}
</>
)
}
Button toggles (Color, size options)
'use client'
import { useState } from 'react'
import Image from 'next/image'
import Stack from 'react-bootstrap/Stack'
import FormLabel from 'react-bootstrap/FormLabel'
import ToggleButton from 'react-bootstrap/ToggleButton'
export default function FormsButtonsTogglesDemo() {
const [sizeValue, setSizeValue] = useState('XL')
const [modelValue, setModelValue] = useState('64 GB')
const [colorValue, setColorValue] = useState('Gray blue')
const [colorImageValue, setColorImageValue] = useState('Viridian')
return (
<>
{/* Size options made of <ToggleButton> */}
<FormLabel className="pb-1 mb-2">Sizes</FormLabel>
<Stack direction="horizontal" gap={2} className="flex-wrap mb-4">
{['XL', 'L', 'M', 'S', 'XS'].map((size, index) => (
<ToggleButton
key={index}
type="radio"
id={`size-${index}`}
variant="outline-secondary btn-icon"
size="sm"
name="size-options"
value={size}
checked={sizeValue === size}
onChange={(e) => setSizeValue(e.currentTarget.value)}
disabled={size === 'S' && true}
>
{size}
</ToggleButton>
))}
</Stack>
{/* Model options made of <ToggleButton> */}
<FormLabel className="pb-1 mb-2">Model</FormLabel>
<Stack direction="horizontal" gap={2} className="flex-wrap mb-4">
{['64 GB', '128 GB', '256 GB', '512 GB'].map((model, index) => (
<ToggleButton
key={index}
type="radio"
id={`model-${index}`}
variant="outline-secondary"
size="sm"
name="model-options"
value={model}
checked={modelValue === model}
onChange={(e) => setModelValue(e.currentTarget.value)}
disabled={model === '512 GB' && true}
>
{model}
</ToggleButton>
))}
</Stack>
{/* Color options made of <ToggleButton> with binded label */}
<FormLabel className="pb-1 mb-2">
Color: <span className="text-body fw-normal">{colorValue}</span>
</FormLabel>
<Stack direction="horizontal" gap={2} className="flex-wrap mb-4">
{[
{ colorName: 'Gray blue', colorHex: '#5a7aa1' },
{ colorName: 'Pink', colorHex: '#ee7976' },
{ colorName: 'Light blue', colorHex: '#9acbf1' },
{ colorName: 'Green', colorHex: '#8cd1ab' },
].map(({ colorName, colorHex }, index) => (
<ToggleButton
key={index}
type="radio"
id={`color-${index}`}
variant="color fs-xl"
name="color-options"
value={colorName}
checked={colorValue === colorName}
onChange={(e) => setColorValue(e.currentTarget.value)}
style={{ color: colorHex }}
>
<span className="visually-hidden">{colorName}</span>
</ToggleButton>
))}
</Stack>
{/* Color options made of <ToggleButton> with binded label */}
<FormLabel className="pb-1 mb-2">
Color: <span className="text-body fw-normal">{colorImageValue}</span>
</FormLabel>
<Stack direction="horizontal" gap={2} className="flex-wrap">
{[
{ image: '/img/shop/furniture/product/colors/color01.png', color: 'Viridian' },
{ image: '/img/shop/furniture/product/colors/color02.png', color: 'Green' },
{ image: '/img/shop/furniture/product/colors/color03.png', color: 'Blue' },
].map(({ image, color }, index) => (
<ToggleButton
key={index}
type="radio"
id={`color-image-${index}`}
variant="image p-0"
name="color-image-options"
value={color}
checked={colorImageValue === color}
onChange={(e) => setColorImageValue(e.currentTarget.value)}
>
<Image src={image} width={56} height={56} alt={color} />
<span className="visually-hidden">{color}</span>
</ToggleButton>
))}
</Stack>
</>
)
}
Count input (+/-)
The CountInput is a custom Cartzilla component.
Available props:
value={number}
- The current value of the input. Use this to control the component externally via state.defaultValue={number}
- The initial value of the input for uncontrolled usage.min={number}
- The minimum value allowed for the input. Default is0
.max={number}
- The maximum value allowed for the input. Default isInfinity
.size={"sm" | "lg"}
- Controls the size of the input and buttons. Use"sm"
for small or"lg"
for large sizes.disabled={boolean}
- Disables the input and buttons when set totrue
.onChange={(value) => void}
- Callback triggered whenever the input value changes (increment, decrement, or external update).onIncrement={(value) => void}
- Callback triggered when the increment button is clicked. Receives the updated value.onDecrement={(value) => void}
- Callback triggered when the decrement button is clicked. Receives the updated value.
'use client'
import { useState } from 'react'
import Stack from 'react-bootstrap/Stack'
import CountInput from '@/components/forms/count-input'
export default function FormsCountInputDemo() {
const [count, setCount] = useState(1)
return (
<Stack gap={3} className="align-items-start">
{/* Small stateless count input */}
<CountInput size="sm" defaultValue={1} aria-label="Count input" />
{/* Controlled (with state) count input with min/max values and callbacks */}
<CountInput
value={count}
min={1}
max={5}
// incrementBtnLabel="Increment quantity" // Optionally change increment button aria-label
// decrementBtnLabel="Decrement quantity" // Optionally change decrement button aria-label
onChange={(value) => {
console.log('Changed to:', value)
setCount(value)
}}
onIncrement={(value) => {
console.log('Incremented to:', value)
setCount(value)
}}
onDecrement={(value) => {
console.log('Decremented to:', value)
setCount(value)
}}
aria-label="Count input"
/>
{/* Large stateless count input */}
<CountInput size="lg" defaultValue={1} aria-label="Count input" />
{/* Disabled count input */}
<CountInput defaultValue={1} disabled aria-label="Disabled count input" />
</Stack>
)
}
Range slider
The RangeSlider is powered by the Radix UI Slider component.
Available props:
value={number[]}
- The current values of the slider thumbs. This prop controls the slider externally via state.defaultValue={number[]}
- The initial values of the slider thumbs for uncontrolled usage.min={number}
- The minimum value allowed on the slider. This prop is required.max={number}
- The maximum value allowed on the slider. This prop is required.step={number}
- The increment between values when the slider is moved. Default is1
.minStepsBetweenThumbs={number}
- Specifies the minimum number of steps required between slider thumbs.onValueChange={(values: number[]) => void}
- Callback triggered whenever the slider values change. Receives the updated array of values.orientation={"horizontal" | "vertical"}
- The orientation of the slider. Defaults to"horizontal"
.tooltips={boolean}
- Whether to show tooltips on the slider thumbs. Default istrue
.tooltipPrefix={string}
- Optional prefix text displayed in tooltips.tooltipSuffix={string}
- Optional suffix text displayed in tooltips.pips={boolean}
- Whether to display a scale (pips) on the slider. Default isfalse
.dir={"ltr" | "rtl"}
- Specifies the text direction for the slider. Default is"ltr"
.
'use client'
import { useState } from 'react'
import FormLabel from 'react-bootstrap/FormLabel'
import FormControl from 'react-bootstrap/FormControl'
import Stack from 'react-bootstrap/Stack'
import RangeSlider from '@/components/forms/range-slider'
export default function FormsRangeSliderDemo() {
const [values, setValues] = useState([250, 680])
const handleInputChange = (index: number, value: string) => {
const numericValue = Math.max(0, Math.min(1000, Number(value)))
const updatedValues = [...values]
updatedValues[index] = numericValue
setValues(updatedValues)
}
return (
<>
{/* Two handles + slider with scale (pips) + bind inputs */}
<FormLabel id="range-slider-label">Price range</FormLabel>
<RangeSlider
min={0}
max={1000}
step={1}
pips
value={values}
onValueChange={setValues}
minStepsBetweenThumbs={1}
tooltipPrefix="$"
aria-labelledby="range-slider-label"
/>
<Stack direction="horizontal" gap={2}>
<div className="position-relative w-50">
<i className="ci-dollar-sign position-absolute top-50 start-0 translate-middle-y ms-3"/>
<FormControl
type="number"
min={0}
max={values[1] - 1}
value={values[0]}
onChange={(e) => handleInputChange(0, e.target.value)}
className="form-icon-start"
/>
</div>
<i className="ci-minus text-body-emphasis mx-2"/>
<div className="position-relative w-50">
<i className="ci-dollar-sign position-absolute top-50 start-0 translate-middle-y ms-3"/>
<FormControl
type="number"
min={values[0] + 1}
max={1000}
value={values[1]}
onChange={(e) => handleInputChange(1, e.target.value)}
className="form-icon-start"
/>
</div>
</Stack>
{/* Slider with one handle + no bind inputs */}
<RangeSlider
min={0}
max={1000}
step={1}
defaultValue={[450]}
minStepsBetweenThumbs={1}
tooltipPrefix="$"
/>
</>
)
}
Shapes
import Stack from 'react-bootstrap/Stack'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
export default function FormsShapesDemo() {
return (
<Stack direction="horizontal" gap={4} className="flex-wrap flex-sm-nowrap">
{/* Text inputs */}
<Stack gap={3} className="w-100">
<FormControl type="text" placeholder="Rounded input" />
<FormControl type="text" className="rounded-pill" placeholder="Pill input" />
<FormControl type="text" className="rounded-0" placeholder="Square input" />
</Stack>
{/* Selects */}
<Stack gap={3} className="w-100">
<FormSelect defaultValue="" aria-label="Rounded select">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
<FormSelect defaultValue="" aria-label="Pill select">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
<FormSelect defaultValue="" aria-label="RounSquareded select">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
</Stack>
</Stack>
)
}
Sizes
import Stack from 'react-bootstrap/Stack'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
export default function FormsSizesDemo() {
return (
<Stack direction="horizontal" gap={4} className="flex-wrap flex-sm-nowrap">
{/* Text inputs */}
<Stack gap={3} className="w-100">
<FormControl type="text" placeholder="Rounded input" />
<FormControl type="text" className="rounded-pill" placeholder="Pill input" />
<FormControl type="text" className="rounded-0" placeholder="Square input" />
</Stack>
{/* Selects */}
<Stack gap={3} className="w-100">
<FormSelect defaultValue="" aria-label="Rounded select">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
<FormSelect defaultValue="" aria-label="Pill select">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
<FormSelect defaultValue="" aria-label="RounSquareded select">
<option value="" disabled>Choose option...</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
</Stack>
</Stack>
)
}
Readonly & disabled
import Stack from 'react-bootstrap/Stack'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
export default function FormsDisabledDemo() {
return (
<Stack gap={3}>
<FormControl type="text" defaultValue="Readonly input" readOnly />
<FormControl type="text" plaintext className="fs-sm" defaultValue="Plain text input" readOnly />
<FormControl type="text" defaultValue="Disabled input" disabled />
<FormSelect defaultValue="" aria-label="Disabled select" disabled>
<option value="" disabled>Disabled select</option>
<option value="1">Option item 1</option>
<option value="2">Option item 2</option>
<option value="3">Option item 3</option>
</FormSelect>
</Stack>
)
}
Inline form
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import FormLabel from 'react-bootstrap/FormLabel'
import FormControl from 'react-bootstrap/FormControl'
import FormSelect from 'react-bootstrap/FormSelect'
import FormCheck from 'react-bootstrap/FormCheck'
import Button from 'react-bootstrap/Button'
export default function FormsInlineDemo() {
return (
<Row as="form" sm="auto" className="g-3 align-items-center">
<Col xs={12}>
<FormLabel htmlFor="inline-form-input" className="visually-hidden">
Full name
</FormLabel>
<FormControl type="text" id="inline-form-input" placeholder="Full name" />
</Col>
<Col xs={12}>
<FormLabel htmlFor="inline-form-select" className="visually-hidden">
Preference
</FormLabel>
<FormSelect id="inline-form-select" defaultValue="choose">
<option value="choose" disabled>
Choose...
</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</FormSelect>
</Col>
<Col xs={12}>
<FormCheck id="inline-form-check" label="Remember me" />
</Col>
<Col xs={12}>
<Button type="submit">Submit</Button>
</Col>
</Row>
)
}
Help text
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces, special characters, or emoji.
import FormLabel from 'react-bootstrap/FormLabel'
import FormControl from 'react-bootstrap/FormControl'
import FormText from 'react-bootstrap/FormText'
export default function FormsHelpTextDemo() {
return (
<>
<FormLabel htmlFor="inputPassword">Password</FormLabel>
<FormControl
type="password"
id="inputPassword"
placeholder="Your password..."
aria-labelledby="passwordHelpBlock"
/>
<FormText as="div" id="passwordHelpBlock">
Your password must be 8-20 characters long, contain letters and numbers, and must not contain spaces,
special characters, or emoji.
</FormText>
</>
)
}
Validation: status text
'use client'
import { useState, type FormEvent } from 'react'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
export default function FormsValidationTextDemo() {
const [validated, setValidated] = useState(false)
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
const form = event.currentTarget
if (form.checkValidity() === false) {
event.preventDefault()
event.stopPropagation()
}
setValidated(true)
}
return (
<Form noValidate validated={validated} onSubmit={handleSubmit}>
<Row>
<Col md={4} className="mb-3">
<Form.Label htmlFor="validationText01">First name</Form.Label>
<Form.Control type="text" id="validationText01" placeholder="First name" defaultValue="John" required />
<Form.Control.Feedback type="invalid">Please enter your first name.</Form.Control.Feedback>
<Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback>
</Col>
<Col md={4} className="mb-3">
<Form.Label htmlFor="validationText02">Last name</Form.Label>
<Form.Control type="text" id="validationText02" placeholder="Last name" defaultValue="Doe" required />
<Form.Control.Feedback type="invalid">Please enter your last name.</Form.Control.Feedback>
<Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback>
</Col>
<Col md={4} className="mb-3">
<Form.Label htmlFor="validationText03">Username</Form.Label>
<Form.Control type="text" id="validationText03" placeholder="Username" required />
<Form.Control.Feedback type="invalid">Please choose a username.</Form.Control.Feedback>
<Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback>
</Col>
</Row>
<Row>
<Col md={6} className="mb-3">
<Form.Label htmlFor="validationText04">City</Form.Label>
<Form.Select id="validationText04" defaultValue="" required>
<option value="" disabled>
Choose city...
</option>
<option value="Dallas">Dallas</option>
<option value="Houston">Houston</option>
<option value="Los Angeles">Los Angeles</option>
<option value="Miami">Miami</option>
<option value="New York">New York</option>
</Form.Select>
<Form.Control.Feedback type="invalid">Please provide a valid city.</Form.Control.Feedback>
<Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback>
</Col>
<Col md={3} className="mb-3">
<Form.Label htmlFor="validationText05">State</Form.Label>
<Form.Select id="validationText05" defaultValue="" required>
<option value="" disabled>
Choose state...
</option>
<option value="Arizona">Arizona</option>
<option value="Colorado">Colorado</option>
<option value="Florida">Florida</option>
<option value="Indiana">Indiana</option>
<option value="Kentucky">Kentucky</option>
<option value="Texas">Texas</option>
</Form.Select>
<Form.Control.Feedback type="invalid">Please provide a valid State.</Form.Control.Feedback>
<Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback>
</Col>
<Col md={3} className="mb-3">
<Form.Label htmlFor="validationText06">Zip</Form.Label>
<Form.Control type="text" id="validationText06" placeholder="Zip" required />
<Form.Control.Feedback type="invalid">Please provide a valid zip.</Form.Control.Feedback>
<Form.Control.Feedback type="valid">Looks good!</Form.Control.Feedback>
</Col>
</Row>
<Form.Check
id="validationText07"
label="Agree to terms and conditions"
feedback="You must agree before submitting."
feedbackType="invalid"
required
className="mb-3"
/>
<Button type="submit">Submit form</Button>
</Form>
)
}
Validation: status tooltips
'use client'
import { useState, type FormEvent } from 'react'
import Row from 'react-bootstrap/Row'
import Col from 'react-bootstrap/Col'
import Form from 'react-bootstrap/Form'
import Button from 'react-bootstrap/Button'
export default function FormsValidationTooltipsDemo() {
const [validated, setValidated] = useState(false)
const handleSubmit = (event: FormEvent<HTMLFormElement>) => {
const form = event.currentTarget
if (form.checkValidity() === false) {
event.preventDefault()
event.stopPropagation()
}
setValidated(true)
}
return (
<Form noValidate validated={validated} onSubmit={handleSubmit}>
<Row>
<Col md={4} className="position-relative mb-4">
<Form.Label htmlFor="validationTooltip01">First name</Form.Label>
<Form.Control
type="text"
id="validationTooltip01"
placeholder="First name"
defaultValue="John"
required
/>
<Form.Control.Feedback tooltip type="invalid">
Please enter your first name.
</Form.Control.Feedback>
<Form.Control.Feedback tooltip type="valid">
Looks good!
</Form.Control.Feedback>
</Col>
<Col md={4} className="position-relative mb-4">
<Form.Label htmlFor="validationTooltip02">Last name</Form.Label>
<Form.Control type="text" id="validationTooltip02" placeholder="Last name" defaultValue="Doe" required />
<Form.Control.Feedback tooltip type="invalid">
Please enter your last name.
</Form.Control.Feedback>
<Form.Control.Feedback tooltip type="valid">
Looks good!
</Form.Control.Feedback>
</Col>
<Col md={4} className="position-relative mb-4">
<Form.Label htmlFor="validationTooltip03">Username</Form.Label>
<Form.Control type="text" id="validationTooltip03" placeholder="Username" required />
<Form.Control.Feedback tooltip type="invalid">
Please choose a username.
</Form.Control.Feedback>
<Form.Control.Feedback tooltip type="valid">
Looks good!
</Form.Control.Feedback>
</Col>
</Row>
<Row>
<Col md={6} className="position-relative mb-4">
<Form.Label htmlFor="validationTooltip04">City</Form.Label>
<Form.Select id="validationTooltip04" defaultValue="" required>
<option value="" disabled>
Choose city...
</option>
<option value="Dallas">Dallas</option>
<option value="Houston">Houston</option>
<option value="Los Angeles">Los Angeles</option>
<option value="Miami">Miami</option>
<option value="New York">New York</option>
</Form.Select>
<Form.Control.Feedback tooltip type="invalid">
Please provide a valid city.
</Form.Control.Feedback>
<Form.Control.Feedback tooltip type="valid">
Looks good!
</Form.Control.Feedback>
</Col>
<Col md={3} className="position-relative mb-4">
<Form.Label htmlFor="validationTooltip05">State</Form.Label>
<Form.Select id="validationTooltip05" defaultValue="" required>
<option value="" disabled>
Choose state...
</option>
<option value="Arizona">Arizona</option>
<option value="Colorado">Colorado</option>
<option value="Florida">Florida</option>
<option value="Indiana">Indiana</option>
<option value="Kentucky">Kentucky</option>
<option value="Texas">Texas</option>
</Form.Select>
<Form.Control.Feedback tooltip type="invalid">
Please provide a valid State.
</Form.Control.Feedback>
<Form.Control.Feedback tooltip type="valid">
Looks good!
</Form.Control.Feedback>
</Col>
<Col md={3} className="position-relative mb-4">
<Form.Label htmlFor="validationTooltip06">Zip</Form.Label>
<Form.Control type="text" id="validationTooltip06" placeholder="Zip" required />
<Form.Control.Feedback tooltip type="invalid">
Please provide a valid zip.
</Form.Control.Feedback>
<Form.Control.Feedback tooltip type="valid">
Looks good!
</Form.Control.Feedback>
</Col>
</Row>
<Form.Check
id="validationTooltip07"
label="Agree to terms and conditions"
feedback="You must agree before submitting."
feedbackType="invalid"
feedbackTooltip
required
className="position-relative mb-4"
/>
<Button type="submit">Submit form</Button>
</Form>
)
}