Glin UI
Signature / Molecule

Glass Toggle

Toggle switch with liquid fill animation and frosted glass surface.

Installation$

Install from
pnpm dlx @glinui/cli@latest add glass-toggle

Prefer the package?

Usage$

GlassToggle is a "use client" component. It works in both controlled (checked) and uncontrolled (defaultChecked) modes.

Examples$

State matrix$

Statesmmdlg
Off
On
Disabled off
Disabled on
import { GlassToggle } from "@glinui/ui"
export function Demo() {
return (
<div className="grid grid-cols-3 gap-4">
{(["sm", "md", "lg"] as const).map((size) => (
<div key={size} className="flex flex-col items-center gap-3">
<GlassToggle aria-label="Off" size={size} />
<GlassToggle aria-label="On" size={size} defaultChecked />
<GlassToggle aria-label="Disabled" size={size} disabled />
<GlassToggle aria-label="Disabled on" size={size} disabled defaultChecked />
</div>
))}
</div>
)
}

With icons$

import { GlassToggle } from "@glinui/ui"
import { Moon, Sun } from "@phosphor-icons/react"
export function Demo() {
return (
<>
<GlassToggle aria-label="Theme" size="lg" defaultChecked onIcon={<Moon weight="fill" />} offIcon={<Sun weight="fill" />} />
<GlassToggle aria-label="Labels" size="lg" showLabels defaultChecked />
</>
)
}

With label and description$

Join known networks automatically.

Banners, sounds and badges.

Turns off all radios.

import { GlassToggle } from "@glinui/ui"
export function Demo() {
return (
<>
<GlassToggle label="Wi-Fi" description="Join known networks automatically." defaultChecked />
<GlassToggle label="Notifications" description="Banners, sounds and badges." />
</>
)
}

Loading$

import { useState } from "react"
import { GlassToggle } from "@glinui/ui"
export function Demo() {
const [on, setOn] = useState(false)
const [busy, setBusy] = useState(false)
return (
<GlassToggle
aria-label="Save on toggle"
checked={on}
loading={busy}
onCheckedChange={(next) => {
setBusy(true)
setTimeout(() => { setOn(next); setBusy(false) }, 1200)
}}
/>
)
}

Controlled$

checked: false
import { useState } from "react"
import { GlassToggle } from "@glinui/ui"
export function Demo() {
const [on, setOn] = useState(false)
return (
<>
<GlassToggle aria-label="Controlled" checked={on} onCheckedChange={setOn} />
<output>checked: {String(on)}</output>
</>
)
}

Form$

Wi-Fi
Alerts
Airplane
(submit the form)
import { GlassToggle } from "@glinui/ui"
export function Demo() {
return (
<form onSubmit={(e) => {
e.preventDefault()
console.log(Object.fromEntries(new FormData(e.currentTarget)))
}}>
<GlassToggle aria-label="Wi-Fi" name="wifi" defaultChecked />
<GlassToggle aria-label="Alerts" name="alerts" value="yes" />
<button type="submit">Submit</button>
</form>
)
}

Glass on photo backdrop$

The glass track is translucent, so it reads best over color. The liquid fill wipes in from the inline start.

"use client"
import { GlassToggle } from "@glinui/ui"
export function GlassOnPhoto() {
return (
<div className="bg-[url('/photo.jpg')] p-8">
<GlassToggle defaultChecked />
</div>
)
}

Custom Color$

activeColor sets a CSS custom property on the element (no inline style attribute).

"use client"
import { GlassToggle } from "@glinui/ui"
export function GlassToggleColorDemo() {
return (
<div className="flex items-center justify-center gap-6 p-8">
<GlassToggle defaultChecked activeColor="#22c55e" />
<GlassToggle defaultChecked activeColor="#6366f1" />
<GlassToggle defaultChecked activeColor="#f43f5e" />
</div>
)
}

Accessibility$

  • Renders with role="switch" and aria-checked.
  • Supports keyboard activation (Space) and a visible focus ring.
  • Native form participation through name, value, required and form.
  • loading sets aria-busy and makes the toggle inert.
  • 44px minimum hit area at every size; thumb moves toward the inline end in RTL.
  • Disabled state reduces opacity and blocks interaction.

Reduced Motion$

When prefers-reduced-motion: reduce is active, or data-glin-motion is none or subtle, the thumb and fill change state instantly with no sliding transform.

API Reference$

PropTypeDefaultDescription

Source$

import { GlassToggle } from "@glinui/ui"
packages/ui/src/components/glass-toggle.tsx

Generated API Snapshot

Beta

Auto-extracted from TypeScript source in packages/ui/src/components/glass-toggle.tsx. This section is in beta and may lag behind hand-curated docs. Regenerate with pnpm --filter @glinui/docs api:generate.

Generated: 2026-10-08T01:41:21.546Z · Full index: /docs/api-metadata

Primary Props Type

GlassToggleProps

No explicit component-only fields were extracted. This component primarily inherits native or composed props.

GlassToggleProps

No explicit fields extracted for this props type.