Pallas UI
DocsComponents
Core Concepts
    • Introduction
    • Getting Started
    • Theming
    • Color Tokens
    • Spacing & Sizing
    • Layout Guide
    • AspectRatio
    • Box
    • Flex
    • Grid
    • Shapes
Previews
    • Accordion
    • Alert
    • Avatar
    • Badge
    • Breadcrumb
    • Button
    • Carousel
    • Checkbox
    • Combobox
    • Command
    • Date Picker
    • Form
    • Input
    • Input OTP
    • Label
    • MenuBar
    • Modal
    • Popover
    • Progress
    • Radio Group
    • Segmented
    • Select
    • Separator
    • Sheet
    • Sidebar
    • Skeleton
    • Slider
    • Spinner
    • Steps
    • Switch
    • Tabs
    • Textarea
    • Toast
    • Tooltip
    • Typography
  1. Components
  2. Button

Button

Displays a button or a component that looks like a button.

Installation

Install the following dependencies

npm install @radix-ui/react-slot

Copy and paste the following code into your project

import { Slot } from '@radix-ui/react-slot'
import { css, cx } from '@styled-system/css'
import { styled } from '@styled-system/jsx'
import { type ButtonVariantProps, button, icon, spinner } from '@styled-system/recipes'
import type { SystemStyleObject } from '@styled-system/types'
import React, { cloneElement, isValidElement } from 'react'
 
export type ButtonProps = ButtonVariantProps & //exported for toast
  React.ButtonHTMLAttributes<HTMLButtonElement> & {
    isLoading?: boolean
    icon?: React.ReactElement<{ className?: string }>
    iconPosition?: 'start' | 'end'
    css?: SystemStyleObject
    asChild?: boolean
  }
 
const Spinner = styled('div', spinner)
 
// Map button sizes to icon recipe sizes
const buttonToIconSize = {
  sm: 'sm',
  md: 'md',
  lg: 'lg',
  icon: 'md',
} as const
 
export const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
  (
    {
      children,
      className,
      isLoading,
      disabled,
      icon: iconProp,
      iconPosition = 'start',
      variant,
      size,
      shape,
      width,
      css: cssProp,
      asChild = false,
      ...props
    },
    ref,
  ) => {
    const Comp = asChild ? Slot : 'button'
 
    // Apply icon recipe styles to the icon
    const iconElement =
      iconProp && isValidElement(iconProp)
        ? cloneElement(iconProp, {
            className: cx(
              icon({ size: buttonToIconSize[size as keyof typeof buttonToIconSize] }),
              css({ flexShrink: 0 }),
              iconProp.props.className,
            ),
          })
        : iconProp
 
    return (
      <Comp
        ref={ref}
        disabled={disabled || isLoading}
        className={cx(button({ variant, size, width, shape }), cssProp && css(cssProp), className)}
        {...props}
      >
        <span data-slot="button-content-wrapper">
          {iconPosition === 'start' &&
            (isLoading ? <Spinner size="sm" variant="thin" /> : iconElement)}
          {children}
          {iconPosition === 'end' &&
            (isLoading ? <Spinner size="sm" variant="thin" /> : iconElement)}
        </span>
      </Comp>
    )
  },
)
 
Button.displayName = 'Button'

Update the import paths to match your project setup

Usage

import { Button } from '@/components/ui/button/button'
<Button variant="default" size="default">
  Button
</Button>

Properties

PropertyTypeDefaultDescriptionOptions
variantstringprimaryVisual style of the buttonprimary, outlined, dashed, default, text, link
sizestringmdSize of the buttonsm, md, lg, icon
shapestringdefaultShape of the buttondefault, rounded, circle
widthstring-Width variantfull
isLoadingbooleanfalseShows loading spinnertrue, false
iconReactElement-Button icon element-
iconPositionstringstartPosition of the iconstart, end
disabledbooleanfalseDisables the buttontrue, false
classNamestring-Custom CSS classes-
cssSystemStyleObject-Inline Panda CSS styles-
asChildbooleanfalseRender as a different elementtrue, false

The button component also accepts all standard HTML button attributes as props.

Examples

Default

Outline

Dashed

Link

Text

With Icon

Icon Position

Loading State

Shapes

The shape prop allows you to modify the button's border radius:

  • default - Standard corners
  • rounded - Fully rounded corners
  • circle - Perfect circle (best used with size="icon")

Built with ❤️ by the carbonteq team. The source code is available on GitHub.

© 2025 Pallas UI. All rights reserved.