Skip to content

Surface

The background a part of a page stands on.

Solidtype_heroui.Surface is a <div> with the classes HeroUI’s own surfaceVariants gives. Kobalte has no surface, and a surface has no behaviour: it gives what is inside it its variant, by Surface.Context, so a part can choose the colours that stand out on it.

Surface Content

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

surface_usage.mlx
module Surface = Solidtype_heroui.Surface
let make () =
<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>

A surface’s variant says how prominent it is:

  • `default, the standard surface, bg-surface
  • `secondary, of medium prominence, bg-surface-secondary
  • `tertiary, of higher prominence, bg-surface-tertiary
  • `transparent, with no background

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.

surface_variants.mlx
module Surface = Solidtype_heroui.Surface
let make () =
<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>

A part inside a surface reads its variant, a function it calls to follow it as it changes, or None on no surface:

let surface = Surface.Context.use () in
let on_surface () =
match surface with Some variant -> variant () | None -> `default

HeroUI’s With Form Components example needs Input and TextArea, which are not ported yet.

class_ is added after HeroUI’s classes.

Billing overview

View invoices and payment methods in one place.

surface_tailwind.mlx
module Surface = Solidtype_heroui.Surface
let make () =
<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>

HeroUI’s classes are global, so a stylesheet restyles every surface, as with HeroUI in React:

@layer components {
.surface {
@apply rounded-2xl border border-border;
}
.surface--secondary {
@apply bg-gradient-to-br from-blue-50 to-purple-50;
}
}
  • .surface, and its variants .surface--default, .surface--secondary, .surface--tertiary, .surface--transparent

Each prop beside the name HeroUI’s React component gives it.

React solidtype Type Default Description
variant variant [ `default | `secondary | `tertiary | `transparent ] `default How prominent it is
className class_ string Added after HeroUI’s classes
children children elements Its content
SurfaceContext Surface.Context (unit -> variant) option The variant a part inside it reads

Original HeroUI documentation: Surface.

The same HeroUI Surface twice, under the same props: in solidtype on the left, in React on the right. Below them, every attribute of the two elements: a marked row is one they disagree on.

solidtype — OCaml, on Solid and Kobalte
Surface Content
React — TypeScript, on React Aria
attributesolidtypeReact