Surface

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

Usage

import { Surface } from '@hareui/vue'

Surface Content

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

<script setup lang="ts">import { Surface } from '@hareui/vue'</script><template>  <Surface class="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="default">    <h3 class="text-base font-semibold text-foreground">Surface Content</h3>    <p class="text-sm text-muted">      This is a default surface variant. It uses bg-surface styling.    </p>  </Surface></template>

Examples

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)

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.

Transparent

Surface Content

This is a transparent surface variant. It has no background, suitable for overlays and cards with custom backgrounds.

<script setup lang="ts">import { Surface } from '@hareui/vue'</script><template>  <div class="flex flex-col gap-4">    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">Default</p>      <Surface class="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="default">        <h3 class="text-base font-semibold text-foreground">Surface Content</h3>        <p class="text-sm text-muted">          This is a default surface variant. It uses bg-surface styling.        </p>      </Surface>    </div>    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">Secondary</p>      <Surface class="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="secondary">        <h3 class="text-base font-semibold text-foreground">Surface Content</h3>        <p class="text-sm text-muted">          This is a secondary surface variant. It uses bg-surface-secondary styling.        </p>      </Surface>    </div>    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">Tertiary</p>      <Surface class="flex min-w-[320px] flex-col gap-3 rounded-3xl p-6" variant="tertiary">        <h3 class="text-base font-semibold text-foreground">Surface Content</h3>        <p class="text-sm text-muted">          This is a tertiary surface variant. It uses bg-surface-tertiary styling.        </p>      </Surface>    </div>    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">Transparent</p>      <Surface class="flex min-w-[320px] flex-col gap-3 rounded-3xl border p-6" variant="transparent">        <h3 class="text-base font-semibold text-foreground">Surface Content</h3>        <p class="text-sm text-muted">          This is a transparent surface variant. It has no background, suitable for overlays and          cards with custom backgrounds.        </p>      </Surface>    </div>  </div></template>

With Form Components

When using form components inside a Surface, use the variant="secondary" prop on them to apply the lower-emphasis variant suitable for surface backgrounds.

<script setup lang="ts">import { Input, Surface, TextArea } from '@hareui/vue'</script><template>  <Surface class="flex min-w-[320px] flex-col gap-4 rounded-3xl p-6" variant="default">    <Input placeholder="Input with secondary variant" variant="secondary" />    <TextArea placeholder="TextArea with secondary variant" variant="secondary" />  </Surface></template>

Customization

Tailwind CSS

Billing overview

View invoices and payment methods in one place.

<script setup lang="ts">import { Surface } from '@hareui/vue'</script><template>  <Surface    class="w-full max-w-sm rounded-xl border border-accent/15 bg-linear-to-br from-accent/8 via-surface to-surface-secondary p-4"    variant="default"  >    <h3 class="text-sm font-semibold text-foreground">Billing overview</h3>    <p class="text-sm text-muted">View invoices and payment methods in one place.</p>  </Surface></template>

Global theme override

Override the surface theme app-wide with createHareUI:

app.use(createHareUI({
  ui: {
    surface: {
      slots: { base: 'rounded-2xl border border-border' },
      variants: {
        variant: { secondary: { base: 'bg-gradient-to-br from-blue-50 to-purple-50' } },
      },
    },
  },
}))

Styling Reference

Each rendered element carries the same data-slot string as HeroUI, so selectors translate 1:1.

ui keydata-slotDescription
basesurfaceBase surface container

HeroUI's .surface--* modifier classes correspond to the variant prop (HareUI renders utilities, not BEM classes, so style through class, ui or createHareUI): transparent, default, secondary, tertiary.

API Reference

Props

PropTypeDefaultDescription
asAsTag | Component"div"The element or component to render as.
variant"default" | "transparent" | "secondary" | "tertiary""default"The visual variant of the surface.
uiComponentSlots<{ slots: { base: string; }; variants: { variant: { transparent: { base: string; }; default: { base: string; }; secondary: { base: string; }; tertiary: { base: string; }; }; }; defaultVariants: { variant: string; }; }>-Per-slot class overrides.

Slots

SlotPropsDescription
defaultanyThe surface content.

Context API

surfaceContextKey

Child components can inject the Surface context to read the current variant:

import { inject } from 'vue'
import { surfaceContextKey } from '@hareui/vue'

const ctx = inject(surfaceContextKey)
// ctx?.variant.value is a Ref<'transparent' | 'default' | 'secondary' | 'tertiary'>

On this page

No Headings