SurfaceNew

Container component that provides surface-level styling and context for child components

Import

import { Surface } from '@heroui/react';

Usage

Default

Surface Content

This is a default surface variant. It uses bg-surface styling.

Secondary

Surface Content

This is a secondary surface variant. It uses bg-surface-secondary styling.

Tertiary

Surface Content

This is a tertiary surface variant. It uses bg-surface-tertiary styling.

Quaternary

Surface Content

This is a quaternary surface variant. It uses bg-surface-quaternary styling.

import {Surface} from "@heroui/react";

export function Variants() {
  return (
    <div className="flex flex-col gap-4">
      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">Default</p>
        <Surface className="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="default">
          <h3 className="text-foreground text-base font-semibold">Surface Content</h3>
          <p className="text-muted text-sm">
            This is a default surface variant. It uses bg-surface styling.
          </p>
        </Surface>
      </div>

      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">Secondary</p>
        <Surface className="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="secondary">
          <h3 className="text-foreground text-base font-semibold">Surface Content</h3>
          <p className="text-muted text-sm">
            This is a secondary surface variant. It uses bg-surface-secondary styling.
          </p>
        </Surface>
      </div>

      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">Tertiary</p>
        <Surface className="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="tertiary">
          <h3 className="text-foreground text-base font-semibold">Surface Content</h3>
          <p className="text-muted text-sm">
            This is a tertiary surface variant. It uses bg-surface-tertiary styling.
          </p>
        </Surface>
      </div>

      <div className="flex flex-col gap-2">
        <p className="text-muted text-sm font-medium">Quaternary</p>
        <Surface className="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="quaternary">
          <h3 className="text-foreground text-base font-semibold">Surface Content</h3>
          <p className="text-muted text-sm">
            This is a quaternary surface variant. It uses bg-surface-quaternary styling.
          </p>
        </Surface>
      </div>
    </div>
  );
}

Overview

The Surface component is a semantic container that provides different levels of visual prominence through variants. It also exposes a context that child components (like Input, TextArea, RadioGroup, and InputOTP) can use to automatically apply on-surface styling.

Variants

Surface comes in semantic variants that describe their prominence level:

  • default - Standard surface appearance (bg-surface)
  • secondary - Medium prominence (bg-surface-secondary)
  • tertiary - Higher prominence (bg-surface-tertiary)
  • quaternary - Highest prominence (bg-surface-quaternary)

Context

The Surface component provides a SurfaceContext that child components can access via useContext(SurfaceContext). Form components like Input, TextArea, RadioGroup, and InputOTP automatically detect when they're inside a Surface and apply the appropriate on-surface styling.

import { Surface, Input, TextArea } from '@heroui/react';
import { useContext } from 'react';
import { SurfaceContext } from '@heroui/react';

function MyComponent() {
  const surfaceContext = useContext(SurfaceContext);
  // Access the variant if needed
  const variant = surfaceContext.variant;
  
  return (
    <>
      <Input placeholder="This input will use on-surface styling" />
      <TextArea placeholder="This textarea will use on-surface styling" />
    </>
  );
}

function App() {
  return (
    <Surface variant="default">
      <MyComponent />
    </Surface>
  );
}

Styling

Passing Tailwind CSS classes

import { Surface } from '@heroui/react';

function CustomSurface() {
  return (
    <Surface 
      className="rounded-2xl p-8 shadow-lg" 
      variant="secondary"
    >
      <h2>Custom Styled Surface</h2>
      <p>Content goes here</p>
    </Surface>
  );
}

Customizing the component classes

To customize the Surface component classes, you can use the @layer components directive.
Learn more.

@layer components {
  .surface {
    @apply rounded-2xl border border-border;
  }
  
  .surface--secondary {
    @apply bg-gradient-to-br from-blue-50 to-purple-50;
  }
}

HeroUI follows the BEM methodology to ensure component variants and states are reusable and easy to customize.

CSS Classes

The Surface component uses these CSS classes (View source styles):

Base Classes

  • .surface - Base surface container

Variant Classes

  • .surface--default - Default surface variant (bg-surface)
  • .surface--secondary - Secondary surface variant (bg-surface-secondary)
  • .surface--tertiary - Tertiary surface variant (bg-surface-tertiary)
  • .surface--quaternary - Quaternary surface variant (bg-surface-quaternary)

API Reference

Surface Props

PropTypeDefaultDescription
variant"default" | "secondary" | "tertiary" | "quaternary""default"The visual variant of the surface
asChildbooleanfalseMerge props onto the child element
classNamestring-Additional CSS classes
childrenReactNode-The surface content

Context API

SurfaceContext

Child components can access the Surface context to get the current variant:

import { useContext } from 'react';
import { SurfaceContext } from '@heroui/react';

function MyComponent() {
  const { variant } = useContext(SurfaceContext);
  // variant will be "default" | "secondary" | "tertiary" | "quaternary" | undefined
}