# Form Controls
Every Shoelace component makes use of a [shadow DOM](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM) to encapsulate markup, styles, and behavior. One caveat of this approach is that native `
```
```jsx react
import { SlButton, SlCheckbox, SlInput, SlMenuItem, SlSelect, SlTextarea } from '@shoelace-style/shoelace/dist/react';
const App = () => {
function handleSubmit(event) {
event.preventDefault();
alert('All fields are valid!');
}
return (
);
};
```
### Input Patterns
To restrict a value to a specific [pattern](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern), use the `pattern` attribute. This example only allows the letters A-Z, so the form will not submit if a number or symbol is entered. This only works with `` elements.
```html preview
```
```jsx react
import { SlButton, SlInput } from '@shoelace-style/shoelace/dist/react';
const App = () => {
function handleSubmit(event) {
event.preventDefault();
alert('All fields are valid!');
}
return (
);
};
```
### Input Types
Some input types will automatically trigger constraints, such as `email` and `url`.
```html preview
```
```jsx react
import { SlButton, SlInput } from '@shoelace-style/shoelace/dist/react';
const App = () => {
function handleSubmit(event) {
event.preventDefault();
alert('All fields are valid!');
}
return (
);
};
```
### Custom Validation
To create a custom validation error, pass a non-empty string to the `setCustomValidity()` method. This will override any existing validation constraints. The form will not be submitted when a custom validity is set and the browser will show a validation error when the containing form is submitted. To make the input valid again, call `setCustomValidity()` again with an empty string.
```html preview
```
```jsx react
import { useRef, useState } from 'react';
import { SlButton, SlInput } from '@shoelace-style/shoelace/dist/react';
const App = () => {
const input = useRef(null);
const [value, setValue] = useState('');
function handleInput(event) {
setValue(event.target.value);
if (event.target.value === 'shoelace') {
input.current.setCustomValidity('');
} else {
input.current.setCustomValidity("Hey, you're supposed to type 'shoelace' before submitting this!");
}
}
function handleSubmit(event) {
event.preventDefault();
alert('All fields are valid!');
}
return (
);
};
```
?> Custom validation can be applied to any form control that supports the `setCustomValidity()` method. It is not limited to inputs and textareas.
### Custom Validation Styles
The `invalid` attribute reflects the form control's validity, so you can style invalid fields using the `[invalid]` selector. The example below demonstrates how you can give erroneous fields a different appearance. Type something other than "shoelace" to demonstrate this.
```html preview
Please enter "shoelace" to continue
```
```jsx react
import { SlInput } from '@shoelace-style/shoelace/dist/react';
const css = `
.custom-input[invalid]:not([disabled])::part(label),
.custom-input[invalid]:not([disabled])::part(help-text) {
color: var(--sl-color-danger-600);
}
.custom-input[invalid]:not([disabled])::part(base) {
border-color: var(--sl-color-danger-500);
}
.custom-input[invalid]:focus-within::part(base) {
box-shadow: 0 0 0 var(--sl-focus-ring-width) var(--sl-color-danger-500);
}
`;
const App = () => (
<>
Please enter "shoelace" to continue
>
);
```
### Third-party Validation
To opt out of the browser's built-in validation and use your own, add the `novalidate` attribute to the form. This will ignore all constraints and prevent the browser from showing its own warnings when form controls are invalid.
Remember that the `invalid` attribute on form controls reflects validity as defined by the [Constraint Validation API](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation). You can set it initially, but the `invalid` attribute will update as the user interacts with the form control. As such, you should not rely on it to set invalid styles using a custom validation library.
Instead, toggle a class and target it in your stylesheet as shown below.
```html
```