# iOS Capsule Button

> iOS capsule button with filled, tinted, gray and plain styles in three sizes and a custom tint.

- Author: Atelier UI
- License: MIT
- Page: https://chromotion.dev/en/components/ios-capsule-button
- Site: Atelier UI (https://chromotion.dev)

## Install

```bash
npx shadcn@latest add https://chromotion.dev/r/ios-capsule-button.json
```

Stack: React + TypeScript + Tailwind CSS v4, shadcn/ui conventions. `cn` comes from `@/lib/utils`.

## Dependencies

No extra dependencies.

## Usage

```tsx title="components/ios-capsule-button-demo.tsx"
import { IOSCapsuleButton } from "@/components/ios-capsule-button"

export default function IOSCapsuleButtonDemo() {
  return (
    <div className="flex w-full max-w-md flex-col items-center gap-3 rounded-2xl bg-neutral-100 p-10 dark:bg-neutral-900">
      <IOSCapsuleButton className="w-full">Continue</IOSCapsuleButton>
      <IOSCapsuleButton variant="tinted" className="w-full">
        Add to Library
      </IOSCapsuleButton>
      <IOSCapsuleButton variant="gray" className="w-full">
        Not Now
      </IOSCapsuleButton>
      <div className="flex items-center gap-2">
        <IOSCapsuleButton size="small" tint="#34c759" style={{ color: "#0a0a0a" }}>
          Done
        </IOSCapsuleButton>
        <IOSCapsuleButton size="small" variant="tinted" tint="#ff9500">
          Edit
        </IOSCapsuleButton>
        <IOSCapsuleButton size="small" variant="plain" tint="#ff3b30">
          Delete
        </IOSCapsuleButton>
      </div>
    </div>
  )
}
```

## Source

```tsx title="components/ios-capsule-button.tsx"
import * as React from "react"

import { cn } from "@/lib/utils"

const sizes = {
  large: "h-[50px] px-7 text-[17px]",
  medium: "h-11 px-6 text-[17px]",
  small: "h-8 px-4 text-[15px]",
} as const

export interface IOSCapsuleButtonProps extends React.ComponentProps<"button"> {
  variant?: "filled" | "tinted" | "gray" | "plain"
  size?: keyof typeof sizes
  /** Any CSS color; defaults to the system blue */
  tint?: string
}

export function IOSCapsuleButton({
  variant = "filled",
  size = "large",
  tint,
  className,
  style,
  ...props
}: IOSCapsuleButtonProps) {
  const variantStyle: React.CSSProperties = !tint
    ? {}
    : variant === "filled"
      ? { backgroundColor: tint, color: "#fff" }
      : variant === "tinted"
        ? { color: tint, backgroundColor: `color-mix(in oklab, ${tint} 15%, transparent)` }
        : { color: tint }

  return (
    <button
      type="button"
      style={{ ...variantStyle, ...style }}
      className={cn(
        "inline-flex items-center justify-center gap-2 rounded-full font-semibold tracking-[-0.01em] select-none",
        "transition-[transform,opacity] duration-150 active:scale-[0.96] active:opacity-70",
        "focus-visible:ring-[3px] focus-visible:ring-[#007aff]/40 focus-visible:outline-none",
        "disabled:pointer-events-none disabled:opacity-40",
        sizes[size],
        !tint && variant === "filled" && "bg-[#0064d2] text-white",
        !tint && variant === "tinted" && "bg-[#007aff]/15 text-[#0064d2] dark:text-[#6cb2ff]",
        !tint && (variant === "gray" || variant === "plain") && "text-[#0064d2] dark:text-[#6cb2ff]",
        variant === "gray" && "bg-[#7878801f] dark:bg-[#7878805c]",
        variant === "plain" && "font-normal",
        className
      )}
      {...props}
    />
  )
}
```
