# 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 Error Messages
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
Due to the many ways form controls are used, Shoelace doesn't provide out of the box validation styles for form controls as part of its default theme. Instead, the following attributes will be applied to reflect a control's validity as users interact with it. You can use them to create custom styles for any of the validation states you're interested in.
- `data-required` - the form control is required
- `data-optional` - the form control is optional
- `data-invalid` - the form control is currently invalid
- `data-valid` - the form control is currently valid
- `data-user-invalid` - the form control is currently invalid and the user has interacted with it
- `data-user-valid` - the form control is currently valid and the user has interacted with it
These attributes map to the browser's built-in pseudo classes for validation: [`:required`](https://developer.mozilla.org/en-US/docs/Web/CSS/:required), [`:optional`](https://developer.mozilla.org/en-US/docs/Web/CSS/:optional), [`:invalid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:invalid), [`:valid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:valid), and the proposed [`:user-invalid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:user-invalid) and [`:user-valid`](https://developer.mozilla.org/en-US/docs/Web/CSS/:user-valid).
?> In the future, data attributes will be replaced with custom pseudo classes such as `:--valid` and `:--invalid`. Shoelace is using data attributes as a workaround until browsers support custom states through [`ElementInternals.states`](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/states).
### Styling Invalid Form Controls
You can target validity using any of the aforementioned data attributes, but it's usually preferable to target `data-user-invalid` and `data-user-valid` since they get applied only after a user interaction such as typing or submitting. This prevents empty form controls from appearing invalid immediately, which often results in a poor user experience.
This example demonstrates custom validation styles using `data-user-invalid` and `data-user-valid`. Try Typing in the fields to see how validity changes with user input.
```html preview
```