⌘K
(opens in new tab)
Liquidify
Documentation
Getting started
Concepts
Liquid GlassProvidersThemingCompositionControlled stateFormsAccessibilityBrowser supportFidelity notesSSR and React Server Components
Guides
Packages
Design tokens
Examples
AI resourcesDocumentation versions
Community

Composition

Compose Liquidify with native elements, refs, and compound component APIs.

Liquidify components prefer a semantic native root. Pass the documented native props, use the forwarded ref for focus or measurement, and keep application layout outside the component.

asChild is opt-in

asChild is not a universal prop. A component exposes it only when its implementation merges behavior and accessibility onto a single child safely. Today, Button is the primary slottable control:

import { Button } from "@liquidify/react"

export function DocumentationLink() {
  return (
    <Button asChild variant="glass">
      <a href="/docs">Read the documentation</a>
    </Button>
  )
}

In this mode the child owns its element semantics. Supply exactly one element child and verify keyboard behavior after composition. Unsupported components reject asChild at the type level instead of ignoring it.

Refs

Refs point to the rendered native root, or to the merged child when a supported component uses asChild.

import { useRef } from "react"
import { Button } from "@liquidify/react"

export function FocusExample() {
  const buttonRef = useRef<HTMLButtonElement>(null)
  return <Button ref={buttonRef}>Continue</Button>
}

Label typography with labelProps

A component that renders its own text routes that text through the internal Text primitive. When you need to retype a label — a different variant, weight, or colour — pass labelProps rather than wrapping the label in your own styled node. It is a closed, token-backed set of typography axes (variant, weight, color, tint, tracking, transform, italic, lineHeight, wrap) spread last into that Text, so your value wins over the component's computed default without restructuring its anatomy.

import { Toggle } from "@liquidify/react"

export function EmphasisedLabel() {
  return (
    <Toggle labelProps={{ variant: "headline", color: "secondary" }} defaultChecked>
      Wi-Fi
    </Toggle>
  )
}

When you instead pass an already-styled Text, Icon, or element as the label, the component passes it through untouched — it never double-wraps a non-primitive child.

The onPress convention

Action controls report activation through onPress, a no-argument callback that fires once per intended activation regardless of whether the user clicked, tapped, or pressed a key. It is the SwiftUI action: analogue and is distinct from stateful controls, which report a value through onChange (Toggle a boolean, Slider a number, TextField and Picker a string).

import { Button } from "@liquidify/react"

export function SaveAction({ onSave }: { onSave: () => void }) {
  return (
    <Button variant="borderedProminent" onPress={onSave}>
      Save
    </Button>
  )
}

Because Button renders a native <button type="button">, use onPress to run the action directly rather than relying on native form submission.

Compound components

Some APIs expose a root plus named parts or structured item data. Follow each component page's anatomy instead of flattening roles into decorative elements. Stable item identifiers are part of behavioral correctness for menus, actions, tabs, and other collections.

ThemingControlled state