Tactile Toggle
Installation
npx shadcn@latest add https://uibrik.com/r/tactile-toggle.jsonInstall the packages
npm install motionAdd the cn helper
Imports
cnfrom@/lib/utils, whichshadcn initcreates. Add it by hand without shadcn.Copy the source into your project
components/uibrik/tactile-toggle/tactile-toggle.tsx"use client"; import { useRef, useState } from "react"; import { motion, useReducedMotion } from "motion/react"; import { cn } from "@/lib/utils"; // ─── Geometry ───────────────────────────────────────────────────────────────── const TRACK_W = 44; const TRACK_H = 26; const PAD = 2; const KNOB = TRACK_H - PAD * 2; // Pointer travel before a press counts as a drag rather than a tap. const DRAG_SLOP = 3; const SPRING = { type: "spring", stiffness: 520, damping: 34, mass: 0.7 } as const; const INSTANT = { duration: 0 } as const; // Off track: a tint of the text colour, so it reads in light and dark alike. const TRACK_OFF = "color-mix(in srgb, var(--foreground) 14%, transparent)"; export type TactileToggleProps = { /** Controlled state. Leave out to let the toggle keep its own. */ checked?: boolean; /** Starting state when uncontrolled. */ defaultChecked?: boolean;
Adds the files to
components/uibrik/tactile-toggle and installs motion. With the @uibrik namespace set up: npx shadcn@latest add @uibrik/tactile-toggle.Props
TactileToggle- accent
- Type string
- "#22c55e"
- Track colour when on.
- squish
- Type number
- 6
- How far the knob stretches while pressed.
- disabled
- Type boolean
- false
- Stops the switch responding.
- checked
- Type boolean
- –
- Controlled state. Leave out to let the toggle keep its own.
- defaultChecked
- Type boolean
- false
- Starting state when uncontrolled.
- onCheckedChange
- Type (checked: boolean) => void
- –
- Called with the new state when the switch flips.
- aria-label
- Type string
- Toggle
- Accessible name, since the switch shows no text.
- className
- Type string
- –
- Classes for the switch.