--- title: Button description: Trigger actions or navigate with styled buttons. --- import ButtonReference from '/snippets/ui/generated/input/button.mdx'; Use `Button` for an action. Supply its visible label as children, and give icon-only buttons an `aria-label`. For recurring design defaults, use [MainButton](/ui/components/input/main-button) or [LightButton](/ui/components/input/light-button) from `twenty-ui/components`. Both share Button's native props, refs, state, and rendering behavior. ## State ownership `Button` triggers an action and does not manage a selected value, so it has no controlled or uncontrolled selection mode. Its native `value` prop supplies form data, not selection state. Your application owns `loading`, `disabled`, and `soon`, which default to `false`. Clicking a button does not change these props or automatically show loading while an asynchronous handler runs. Pass the current application state explicitly. ```tsx import { useState } from 'react'; import { Button } from 'twenty-ui/primitives/input'; type SaveRecordProps = { onSave: () => Promise }; export const SaveRecord = ({ onSave }: SaveRecordProps) => { const [loading, setLoading] = useState(false); const [hasError, setHasError] = useState(false); const handleSave = async () => { setLoading(true); setHasError(false); try { await onSave(); } catch { setHasError(true); } finally { setLoading(false); } }; return ( <> {hasError &&

Unable to save the record. Try again.

} ); }; ``` The application starts and clears loading around the save operation. The button prevents activation while loading and becomes available again when the operation finishes, including after an error. `MainButton` and `LightButton` use the same state model. ## Appearance ```tsx import { Button } from 'twenty-ui/primitives/input'; import { IconPlus } from 'twenty-ui/icon'; export const CreateRecord = () => ( ); ``` Choose `solid`, `outline`, `soft`, or `ghost` independently of the `neutral`, `accent`, `danger`, or `success` color. Sizes are `sm` and `md`; the defaults are `outline`, `neutral`, and `md`. `fullWidth` fills the available width. `startIcon` and `endIcon` accept elements and are decorative. `elevated` adds a shadow. `hotkeys` displays keyboard hints on larger screens; bind the shortcuts in your application. `disabled`, `loading`, and `soon` prevent activation. Loading keeps the label accessible and preserves the button's width while showing a spinner. Customize the upcoming-feature label with `soonLabel`. ## Links and forms ```tsx import { Button } from 'twenty-ui/primitives/input'; export const DocumentationLink = () => ( ); ``` `href` renders an anchor with link semantics. The caller can supply its own `render` element or router link. Set `href` and preserve an anchor for navigation; without `href`, preserve a native button. Button derives its semantics without public `nativeButton` or `role` flags. Disabled links cannot activate. Buttons default to `type="button"`. Set `type="submit"` or `type="reset"` explicitly for forms. Native props, event handlers, refs, and Base UI's `render` prop pass through to the root. ## Props