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 key | data-slot | Description |
|---|---|---|
base | surface | Base 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
| Prop | Type | Default | Description |
|---|---|---|---|
as | AsTag | Component | "div" | The element or component to render as. |
variant | "default" | "transparent" | "secondary" | "tertiary" | "default" | The visual variant of the surface. |
ui | ComponentSlots<{ 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
| Slot | Props | Description |
|---|---|---|
default | any | The 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'>


