Button

Usage

import { Button } from '@jamie/ui/button'
 
export function ButtonDemo() {
  return <Button>Join Meeting</Button>
}

Variants

All six button variants: default, outline, secondary, ghost, destructive, and link.

import { Button } from '@jamie/ui/button'
 
export function ButtonVariantsDemo() {
  return (
    <div className="flex flex-wrap justify-center gap-3">
      <Button variant="default">Default</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="destructive">Destructive</Button>
      <Button variant="link">Link</Button>
    </div>
  )
}

Sizes

Buttons come in seven text sizes: xs, sm, default, medium, lg, xl, and 2xl.

Default

DefaultHoverSelectedExtra SmallSmallDefaultMediumLargeExtra Large2X Large
import { Fragment } from 'react'
import { Button } from '@jamie/ui/button'
 
const sizes = [
  { label: 'Extra Small', value: 'xs' },
  { label: 'Small', value: 'sm' },
  { label: 'Default', value: 'default' },
  { label: 'Medium', value: 'medium' },
  { label: 'Large', value: 'lg' },
  { label: 'Extra Large', value: 'xl' },
  { label: '2X Large', value: '2xl' },
] as const
 
const hoverClass = 'bg-primary-container-low'
const selectedClass = 'bg-primary-container-high'
 
export function ButtonSizesDemo() {
  return (
    <div className="inline-grid grid-cols-[auto_auto_auto_auto] items-center justify-items-start gap-x-6 gap-y-3">
      <div />
      <span className="text-xs font-medium text-muted-foreground">Default</span>
      <span className="text-xs font-medium text-muted-foreground">Hover</span>
      <span className="text-xs font-medium text-muted-foreground">Selected</span>
 
      {sizes.map(({ label, value }) => (
        <Fragment key={value}>
          <span className="text-xs font-medium text-muted-foreground whitespace-nowrap">
            {label}
          </span>
          <Button size={value}>
            Button
          </Button>
          <Button size={value} className={hoverClass}>
            Button
          </Button>
          <Button size={value} className={selectedClass}>
            Button
          </Button>
        </Fragment>
      ))}
    </div>
  )
}

Outline

DefaultHoverSelectedExtra SmallSmallDefaultMediumLargeExtra Large2X Large
import { Fragment } from 'react'
import { Button } from '@jamie/ui/button'
 
const sizes = [
  { label: 'Extra Small', value: 'xs' },
  { label: 'Small', value: 'sm' },
  { label: 'Default', value: 'default' },
  { label: 'Medium', value: 'medium' },
  { label: 'Large', value: 'lg' },
  { label: 'Extra Large', value: 'xl' },
  { label: '2X Large', value: '2xl' },
] as const
 
const hoverClass = 'bg-surface-container-high dark:bg-outline/50'
const selectedClass = 'bg-surface-container-highest dark:bg-outline/70'
 
export function ButtonSizesOutlineDemo() {
  return (
    <div className="inline-grid grid-cols-[auto_auto_auto_auto] items-center justify-items-start gap-x-6 gap-y-3">
      <div />
      <span className="text-xs font-medium text-muted-foreground">Default</span>
      <span className="text-xs font-medium text-muted-foreground">Hover</span>
      <span className="text-xs font-medium text-muted-foreground">Selected</span>
 
      {sizes.map(({ label, value }) => (
        <Fragment key={value}>
          <span className="text-xs font-medium text-muted-foreground whitespace-nowrap">
            {label}
          </span>
          <Button variant="outline" size={value}>
            Button
          </Button>
          <Button variant="outline" size={value} className={hoverClass}>
            Button
          </Button>
          <Button variant="outline" size={value} className={selectedClass}>
            Button
          </Button>
        </Fragment>
      ))}
    </div>
  )
}

With Icon

Use data-icon="inline-start" or data-icon="inline-end" on an icon element for proper spacing.

import { Button } from '@jamie/ui/button'
import { ArrowRightIcon, DownloadIcon, ExternalLinkIcon, MailIcon } from 'lucide-react'
 
export function ButtonWithIconDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Button>
        <MailIcon data-icon="inline-start" />
        Send Recap
      </Button>
      <Button variant="outline">
        View Transcript
        <ArrowRightIcon data-icon="inline-end" />
      </Button>
      <Button variant="secondary">
        <DownloadIcon data-icon="inline-start" />
        Export
      </Button>
      <Button variant="ghost">
        Open Link
        <ExternalLinkIcon data-icon="inline-end" />
      </Button>
    </div>
  )
}

Icon Only

Icon-only buttons in four sizes: icon-xs, icon-sm, icon, and icon-lg.

import { Button } from '@jamie/ui/button'
import { MicIcon, PlayIcon, PlusIcon, SettingsIcon } from 'lucide-react'
 
export function ButtonIconDemo() {
  return (
    <div className="flex flex-wrap items-end gap-4">
      <Button variant="outline" size="icon-xs">
        <PlusIcon />
      </Button>
      <Button variant="outline" size="icon-sm">
        <MicIcon />
      </Button>
      <Button variant="outline" size="icon">
        <SettingsIcon />
      </Button>
      <Button variant="outline" size="icon-lg">
        <PlayIcon />
      </Button>
    </div>
  )
}