🌴Ocean UI
Base components

Button

A flexible button component that supports multiple variants, sizes, and states. Built with Ark UI factory for accessibility and styled using Ocean UI design tokens.

@ark-ui/react/factory

Example

How to install and use

1

Complete the manual installation setup

If you haven't already completed the first 4 steps of the manual installation guide, please do so before continuing to install these components.

2

Create a button.tsx file and paste the following code into it.

/components/ui/button.tsx

import { cva, type VariantProps } from "class-variance-authority";
import { ark } from "@ark-ui/react/factory";
import type { ComponentProps } from "react";

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

const buttonVariants = cva(
  "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-semibold transition-all outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-5 [&_svg]:shrink-0",
  {
    variants: {
      variant: {
        primary:
          "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
        secondary:
          "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
        tertiary: "text-muted-foreground hover:bg-muted hover:text-foreground",
        outline:
          "border border-border bg-transparent text-foreground hover:bg-muted",
        ghost: "text-foreground hover:bg-muted",
        destructive:
          "bg-destructive text-white shadow-xs hover:bg-destructive/90",
        link: "text-primary underline-offset-4 hover:underline",
      },
      size: {
        sm: "h-8 px-3 py-2 has-[>svg]:px-2.5",
        md: "h-9 px-3.5 py-2.5 has-[>svg]:px-3",
        lg: "h-10 px-4 py-2.5 has-[>svg]:px-3.5",
        xl: "h-11 px-4.5 py-3 has-[>svg]:px-4",
      },
    },
    defaultVariants: {
      variant: "primary",
      size: "md",
    },
  }
);

export interface ButtonProps
  extends ComponentProps<typeof ark.button>,
    VariantProps<typeof buttonVariants> {}

function Button({
  variant,
  size,
  className,
  ...props
}: ButtonProps) {
  return (
    <ark.button
      type="button"
      data-slot="button"
      className={cn(buttonVariants({ variant, size, className }))}
      {...props}
    />
  );
}

export { Button, buttonVariants };
3

Finally, Choose any example you like and add it to your project.
For instance, create a new file at components/shared/{example-component-name}.tsx, paste the example code into that file, and then import and use the component wherever you need it in your application.

The Button component uses Ark UI's factory function (ark.button) for built-in accessibility. It's styled with Tailwind CSS using Ocean UI design tokens from tokens.css.

Overview

The Button component is a fundamental UI element for triggering actions. It supports multiple visual styles, sizes, loading states, and icon placement. Built on top of Ark UI's factory function, it provides native button accessibility out of the box.

Variants

The Button component supports seven visual variants:

  • primary: Main action button with brand color background
  • secondary: Secondary action with subtle background and border
  • tertiary: Tertiary action with tertiary text color and hover background
  • outline: Outlined button with transparent background
  • ghost: Minimal button with no background, only text
  • destructive: For destructive actions (delete, remove)
  • link: Text button styled as a link

Sizes

The Button component supports four sizes:

  • sm: Small button (height: 32px)
  • md: Medium button (height: 36px) - default
  • lg: Large button (height: 40px)
  • xl: Extra large button (height: 44px)

Features

  • Icons: Support for leading and trailing icons
  • Loading State: Built-in loading spinner with optional loading text
  • Disabled State: Proper disabled styling and behavior
  • Accessibility: Full keyboard navigation and ARIA support via Ark UI
  • Customizable: All styles can be overridden via className prop

Select Examples

Primary

Primary variant buttons are used for main actions. They feature a brand color background and are the most prominent buttons in the interface.

Secondary

Secondary variant buttons are used for secondary actions. They have a subtle background and border, providing a less prominent alternative to primary buttons.

Tertiary

Tertiary variant buttons use tertiary text colors and show a background on hover. They're useful for less prominent actions that still need to be visible.

Outline

Outline variant buttons have a transparent background with a border. They're useful for actions that need to be visible but less prominent than primary or secondary buttons.

Ghost

Ghost variant buttons have no background and minimal styling. They're ideal for subtle actions or when you want the button to blend into the interface.

Destructive

Destructive variant buttons are used for dangerous or irreversible actions like deleting or removing content. They use error colors to indicate the severity of the action.

Primary

Outline

Tertiary

Link variant buttons are styled as text links with underline on hover. They're useful for navigation or less prominent actions.

Icon Leading

Buttons with leading icons display icons before the text. This pattern is useful for emphasizing the action type and improving visual scanning.

Primary

Outline

Ghost

Icon Trailing

Buttons with trailing icons display icons after the text. This pattern is useful for indicating direction, navigation, or additional context.

Primary

Outline

Ghost

Icon Only

Icon-only buttons contain only an icon without text. They're useful for compact interfaces, toolbars, or when space is limited. Always include an aria-label for accessibility.

Primary

Outline

Ghost

Disabled

Disabled buttons are non-interactive and visually indicate that an action is currently unavailable. They maintain their visual style but appear faded and cannot be clicked.

Secondary

Outline

Ghost

Shapes

Buttons can have different border radius styles. Use rounded-none for rectangular buttons, rounded-full for pill-shaped buttons, or keep the default rounded-lg for slightly rounded corners.

Loading

Buttons support loading states with a spinner. You can show the loading spinner alone or keep the text visible while loading.

On this page