Toggle field components

FREE

Free and open-source React toggle field components built for modern applications and websites. These toggle fields are built using React Aria and styled with Tailwind CSS.

Installation

You can add this Toggle component using our CLI or manually:

npx untitledui@latest add toggle

Toggle examples

Below are examples and variations of this toggle component:

API reference

Toggle

Import Toggle from @/components/base/toggle/toggle. Renders React Aria’s Switch — all of its props are supported.

Toggle props
PropTypeDefaultDescription
size
"sm""md"
"sm"Controls the toggle dimensions, the gap between it and the text, and the label and hint typography.
labelstring—Text rendered beside the toggle. It sits inside the switch's label element, so it also acts as the accessible name and flips the toggle when clicked.
hintReactNode—Supporting text rendered under the label. Clicks on it are stopped so reading the hint does not flip the toggle.
slimboolean—Renders the compact toggle variant, with a shorter track and a bordered knob that overlaps its edges.
Props from React Aria (37)
Toggle inherited props
PropTypeDefaultDescription
onClick((e: MouseEvent<FocusableElement>) => void)—Not recommended – use onPress instead. onClick is an alias for onPress provided for compatibility with other libraries. onPress provides additional event details for non-mouse interactions.
onPress((e: PressEvent) => void)—Handler that is called when the press is released over the target.
onPressChange((isPressed: boolean) => void)—Handler that is called when the press state changes.
onPressEnd((e: PressEvent) => void)—Handler that is called when a press interaction ends, either over the target or when the pointer leaves the target.
onPressStart((e: PressEvent) => void)—Handler that is called when a press interaction starts.
onPressUp((e: PressEvent) => void)—Handler that is called when a press is released over the target, regardless of whether it started on the target or not.
onHoverChange((isHovering: boolean) => void)—Handler that is called when the hover state changes.
onHoverEnd((e: HoverEvent) => void)—Handler that is called when a hover interaction ends.
onHoverStart((e: HoverEvent) => void)—Handler that is called when a hover interaction starts.
onBlur((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element loses focus.
onFocus((e: FocusEvent<Element, Element>) => void)—Handler that is called when the element receives focus.
onFocusChange((isFocused: boolean) => void)—Handler that is called when the element's focus status changes.
autoFocusboolean—Whether the element should receive focus on render.
excludeFromTabOrderboolean—Whether to exclude the element from the sequential tab order. If true, the element will not be focusable via the keyboard by tabbing. This should be avoided except in rare scenarios where an alternative means of accessing the element or its functionality via the keyboard is available.
onKeyDown((e: KeyboardEvent) => void)—Handler that is called when a key is pressed.
onKeyUp((e: KeyboardEvent) => void)—Handler that is called when a key is released.
formstring—The <form> element to associate the input with. The value of this attribute must be the id of a <form> in the same document.
namestring—The name of the input element, used when submitting an HTML form.
defaultSelectedboolean—Whether the element should be selected (uncontrolled).
idstring—The element's unique identifier.
inputRefRef<HTMLInputElement | null>—A ref for the HTML input element.
isDisabledboolean—Whether the input is disabled.
isReadOnlyboolean—Whether the input can be selected but not changed by the user.
isSelectedboolean—Whether the element should be selected (controlled).
onChange((isSelected: boolean) => void)—Handler that is called when the element's selection state changes.
valuestring—The value of the input element, used when submitting an HTML form.
styleStyleOrFunction<SwitchRenderProps>—The inline style for the element. A function may be provided to compute the style based on component state.
childrenChildrenOrFunction<SwitchRenderProps>—The children of the component. A function may be provided to alter the children based on component state.
slotstring | null—A slot name for the component. Slots allow the component to receive props from a parent component. An explicit null value indicates that the local props completely override all props received from a parent.
classNameClassNameOrFunction<SwitchRenderProps>—The CSS className for the element. A function may be provided to compute the class based on component state.
renderDOMRenderFunction<"label", SwitchRenderProps>—Overrides the default DOM element with a custom render function. This allows rendering existing components with built-in styles and behaviors such as router links, animation libraries, and pre-styled components.Requirements:
  • You must render the expected element type (e.g. if <button> is expected, you cannot render an <a>).
  • Only a single root DOM element can be rendered (no fragments).
  • You must pass through props and ref to the underlying DOM element, merging with your own prop as appropriate.
aria-describedbystring—Identifies the element (or elements) that describes the object.
aria-detailsstring—Identifies the element (or elements) that provide a detailed, extended description for the object.
aria-labelstring—Defines a string value that labels the current element.
aria-labelledbystring—Identifies the element (or elements) that labels the current element.
aria-errormessagestring—Identifies the element that provides an error message for the object.
aria-controlsstring—Identifies the element (or elements) whose contents or presence are controlled by the current element.

Also accepts the global HTML attributes (dir, lang, hidden, inert, translate), all standard React DOM event handlers.

ToggleBase

Import ToggleBase from @/components/base/toggle/toggle. Renders a <div> element.

ToggleBase props
PropTypeDefaultDescription
size
"sm""md"
"sm"Controls the track and knob dimensions, and how far the knob slides when selected.
slimboolean—Renders the compact variant: an unpadded track with a bordered knob that overlaps its edges instead of sitting inside them.
classNamestring—Additional classes merged onto the track element.
isHoveredboolean—Whether to darken the track while selected, for the hover appearance. Normally passed down by Toggle from React Aria's render state rather than set by hand.
isFocusVisibleboolean—Whether to draw the keyboard focus ring around the track. Normally passed down by Toggle rather than set by hand.
isSelectedboolean—Whether to render the on appearance: brand-filled track with the knob slid to the right. Normally passed down by Toggle rather than set by hand.
isDisabledboolean—Whether to render the dimmed, not-allowed appearance. Normally passed down by Toggle rather than set by hand.

FAQs

Please refer to our frequently asked questions page for more.

Use isSelected with onChange for a controlled toggle; onChange receives the new boolean value. For an uncontrolled toggle, set the initial state with defaultSelected.

Toggles support "sm" and "md" through the size prop. The default is "sm". The size changes the switch dimensions and the size of the label and hint text.

Set slim to true for a slimmer variant. The thumb is the same height as the track and has a border, instead of sitting inside the track with padding.

Pass label for the main text and hint for supporting text below it. The component is a React Aria Switch, so clicking the label also toggles it.

Pass an aria-label that describes the setting, for example aria-label="Enable notifications", since there is no visible text to name the switch.

Yes. React Aria's Switch renders a visually hidden checkbox input, so pass name (and optionally value) to include it in form submissions. Use isDisabled to disable it, which shows the toggle at 50% opacity.

Yes, ToggleBase is exported separately and renders only the track and thumb. It isn't interactive, so pass the state yourself with props like isSelected, isHovered, isFocusVisible and isDisabled.