UI Input
snap-cn/inputFreeComponent
A text input whose idle/hover/active/typing/invalid state is a pure function of the timeline; the focus ring, border, caret, and value reveal are keyframed presets.
Install it
npx shadcn@latest add https://snapcn.dev/r/input.jsonSource
1"use client";23import { cva } from "class-variance-authority";4import { Caret } from "@/components/snap-cn/caret";5import {6 mixOklch,7 revealedText,8 type SnapCnTheme,9 useSnapCnTheme,10} from "@/lib/snap-cn-ui";11import { cn } from "@/lib/utils";1213export type InputState =14 | "idle"15 | "hover"16 | "active"17 | "typing"18 | "blur"19 | "invalid";2021type InputSize = "sm" | "default" | "lg";2223export interface InputProps {24 state?: InputState;25 style?: InputStyle;26 placeholder?: string;27 value?: string;28 size?: InputSize;29 theme?: Partial<SnapCnTheme>;30 primary?: string;31 fullWidth?: boolean;32 className?: string;33}3435/**36 * The control, as classes.37 *38 * This is a shadcn field that happens to be driven by a frame clock, so it is39 * built the way shadcn builds one: `cva` for the size scale, `cn` for merging,40 * `data-slot` for targeting. What stays in `style` is *only* what is tweened —41 * see the note on the render below.42 */43const inputVariants = cva(44 "relative flex items-center border border-solid tracking-[-0.01em]",45 {46 variants: {47 size: {48 sm: "h-9 px-3 text-[13px]",49 default: "h-10 px-3.5 text-[15px]",50 lg: "h-12 px-4 text-[17px]",51 },52 fullWidth: { true: "w-full", false: "w-80" },53 },54 defaultVariants: { size: "default", fullWidth: false },55 },56);5758/** The placeholder overlays the value, so it needs the field's own inset. */59const placeholderVariants = cva(60 "pointer-events-none absolute whitespace-nowrap",61 {62 variants: { size: { sm: "left-3", default: "left-3.5", lg: "left-4" } },63 defaultVariants: { size: "default" },64 },65);6667/** `Caret` takes a pixel height, not a class — so this one number stays a number. */68const CARET_HEIGHT: Record<InputSize, number> = { sm: 14, default: 17, lg: 19 };6970export interface InputStyle {71 borderColor: string;72 ringColor: string;73 ringWidth: number;74 background: string;75 caretOpacity: number;76 valueReveal: number;77 placeholderOpacity: number;78}7980export interface InputStyleContext {81 idleBorder: string;82 hoverBorder: string;83 activeBorder: string;84 invalidBorder: string;85 ring: string;86 invalidRing: string;87 background: string;88 hoverBackground: string;89 foreground: string;90 mutedForeground: string;91}9293export function inputStyleContext(theme: SnapCnTheme): InputStyleContext {94 return {95 idleBorder: theme.input,96 hoverBorder: mixOklch(theme.input, theme.foreground, 0.18),97 activeBorder: theme.ring,98// … truncated
What it pulls in
npm packages
Other registry items
Files it writes
More from snap-cn
All 24 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Answer Streamanswer-stream | snap-cn | Components | Free | 2 deps | |
| UI Caretcaret | snap-cn | Components | Free | 1 dep | |
| Follower Rushfollower-rush | snap-cn | Components | Free | 2 deps | |
| Product Herohero-launch | snap-cn | Components | Free | 2 deps | |
| Karaoke Captionskaraoke-captions | snap-cn | Components | Free | 2 deps | |
| Laptop Framelaptop-frame | snap-cn | Components | Free | 1 dep | |
| Logo Assemblelogo-assemble | snap-cn | Components | Free | 1 dep | |
| Logo Flickerlogo-flicker | snap-cn | Components | Free | 1 dep |
