Button
Use buttons to trigger actions throughout your interface. Buttons are promises of what happens next.View source →Use buttons to trigger actions throughout your interface. Buttons are promises of what happens next. Design them to build user confidence and guide decision-making naturally.
This is an enhanced version of the Button component from Radix Themes. For the original API reference, see the Radix Themes Button documentation.
Playground
Installation
shellUsage
tsxProps
Variants
Use the variant prop to set button style.
Classic
Elevated style with subtle shadow for maximum visual impact and primary actions.
tsxSolid
Filled background for primary actions and important CTAs.
tsxSoft
Subtle background for secondary actions and content-heavy interfaces.
tsxOutline
Bordered style for secondary actions and form controls.
tsxSurface
Elevated surface for content-heavy UIs and card-based layouts.
tsxGhost
Minimal style for utility actions and inline text integration.
tsxSizes
Set size for button density: 1 (24px), 2 (32px), 3 (40px), 4 (48px). Use 3 or 4 for mobile touch targets. Supports responsive objects like { initial: '1', sm: '2', md: '3', lg: '4' }.
Size 1
For toolbars and dense interfaces.
tsxSize 2
For standard interface contexts.
tsxSize 3
For important actions and mobile touch targets.
tsxSize 4
For hero sections and maximum impact.
tsxColors
Use the color prop with semantic colors to communicate the action's intent to users. Use highContrast for maximum visibility, especially on complex or translucent backgrounds.
tsxMaterial
Use the material prop to set button appearance. Choose solid for opaque backgrounds, or translucent for depth and separation over images or dynamic backgrounds. Avoid outline and ghost variants with translucent material, as they may lack contrast.
Theme
Buttons automatically inherit the theme's material setting. Wrap your interface in a Theme component to control material globally:
tsxCustom
Override the theme's material for a button when you need a specific effect. Translucent effects only show over backgrounds—use highContrast for readability.
tsxStates
Loading
Set loading to true to replace all content with a centered spinner and disable the button automatically. No need to set disabled manually.
tsxFor a more sophisticated loading pattern where text remains visible, wrap your icon in a Spinner component:
tsxDisabled
Set the disabled prop to true to prevent interaction when an action is unavailable, such as during form validation or when authentication is required.
tsxInteractive
Buttons handle focus for keyboard navigation. For complex patterns, use data-state for custom visuals.
tsxLayout
Full Width
Set the fullWidth prop to true to make the button fill its container. This is useful for mobile layouts and form submissions.
tsxFlush
Use the flush prop with the ghost variant to remove padding, making the button blend with text while staying interactive.
tsxMargin
Use margin props for spacing around buttons. All margin props are responsive and accept design tokens or CSS values.
tsxTooltips
Use the tooltip prop to add context to button actions, especially for icon buttons or unclear actions. Tooltips appear on hover and focus for accessibility. Always provide a tooltip for icon-only buttons.
tsxIcons
Place icons directly inside buttons; they'll be sized automatically based on the button's size.
tsxFor icon-only buttons, use the IconButton component for proper accessibility and touch targets.
tsxPolymorphism
As
Use the as prop to render buttons as different HTML elements while maintaining button styling. This is useful for navigation links, routing integration, or custom interactive elements that need button appearance.
tsxAsChild
Use the asChild prop to merge button props with a child element using the Radix Slot pattern. This is ideal for composition with routing libraries like Next.js Link or React Router, as it applies button styling without creating an additional wrapper element.
tsxResponsive
Use responsive objects with the size prop to adapt button sizing across different breakpoints. The component uses a mobile-first approach where each breakpoint applies styles at its minimum width and above.
tsxForm
Use standard HTML form attributes to integrate buttons with forms. The component supports all form attributes for comprehensive form integration, including loading states for async operations and validation-based disabled states.
tsxButton also supports customizable tooltip props for content, position, timing, and behavior. Additionally, all margin props (m, mx, my, mt, mr, mb, ml) are supported with responsive values.
Accessibility
Kookie UI's Button extends Radix's accessibility foundation with enhanced loading states and built-in tooltip support.
Enhanced Loading States
Loading states automatically apply comprehensive ARIA attributes:
aria-busy="true"- announces processing statearia-disabled="true"- prevents interactionaria-describedby- links to loading announcementaria-label- dynamically includes "(loading)" status
Loading announcements include: "[Button text] is loading, please wait..."
Keyboard Navigation
- Full keyboard support with Enter and Space keys
- Visible focus indicators for all variants
- Enhanced focus management for Windows High Contrast mode
Screen Readers
- Semantic button elements with proper roles
- Loading state announcements
- Tooltip associations via
aria-describedby - Disabled state announcements
Enhancements
Kookie UI extends Radix Themes Button with practical improvements:
Built-in Tooltip Support
Native tooltip prop eliminates need for wrapper components. Tooltips automatically provide accessibility through aria-describedby associations and support positioning via tooltipSide and tooltipAlign props.
Override Styles
Advanced overrideStyles prop enables per-state style customization using design tokens. Define styles for normal, hover, active, pressed, open, disabled, and focus states without writing CSS.
Enhanced Loading State
Loading state replaces all button content with a centered spinner and disables interaction. Screen readers announce loading context with proper aria-busy and aria-disabled attributes. For patterns where text should remain visible during loading, wrap icons in the Spinner component instead.
Flush Mode
flush prop removes padding for seamless text integration, especially with ghost variant. Creates inline button behavior while maintaining interactive touch targets.
Changelog
Added
- Enhanced loading state accessibility with
aria-busy,aria-disabled, andaria-describedbyattributes - Built-in tooltip support through
tooltip,tooltipSide,tooltipAlignprops - New
materialprop for solid/translucent theme contexts flushprop for seamless text integration with ghost variants- Full margin prop system with responsive support
- Enhanced form integration with complete HTML form attribute support
- RTL (Right-to-Left) layout support for international applications
- Windows High Contrast mode support via
forced-colorsmedia query - Enhanced reduced motion support for users with vestibular disorders
- Improved loading state announcements with contextual button text
- Tooltip accessibility integration with proper
aria-describedbyassociations
Changed
- Improved 3D shadow system for classic variant with better depth perception
- Enhanced active state feedback with subtle padding adjustments
- Better contrast relationships in both light and dark themes
- Comprehensive transition token system with duration and easing tokens
- Automatic reduced motion support via
prefers-reduced-motion
Deprecated
panelBackgroundprop in favor ofmaterialprop
Fixed
- Better color saturation and brightness in high contrast mode
- Enhanced focus indicators for improved accessibility
- Consistent contrast ratios across all variants and states
- Full TypeScript support for polymorphic
asprop with better type inference - Loading state accessibility with proper button text context in announcements
- Focus management with enhanced forced-colors support for Windows High Contrast
- Spinner animations now respect
prefers-reduced-motionuser preference - Tooltip associations properly linked to buttons via unique IDs