Input
A text input component for forms and user data entry with built-in styling and accessibility features.
npx shadcn@latest add @velaui/inputpnpm dlx velaui add @velaui/inputyarn dlx shadcn@latest add @velaui/inputbunx --bun shadcn@latest add @velaui/inputveni add inputInstalls the copy of vela-ui that veni-builder serves to Venizia apps; veni-builder serves the Radix UI copy only, so this tab exists for that base alone.
npx shadcn@latest add @velaui/inputpnpm dlx velaui add @velaui/inputyarn dlx shadcn@latest add @velaui/inputbunx --bun shadcn@latest add @velaui/inputExamples
- Variants
- With label
- Disabled
- Rounded
- Start helper text
- End helper text
- Hint text
- Invalid
- Colored ring
- Characters left
Sizes
Usage
Props
| Prop | Type | Default |
|---|---|---|
size | "sm" | "md" | "lg" | "sm" |
variant | "fill" | "underline" | "outlined" | "outlined" |
Takes these and every prop of InputProps.
| Prop | Type | Default |
|---|---|---|
size | "sm" | "md" | "lg" | "sm" |
variant | "underline" | "fill" | "outlined" | "outlined" |
Takes these and every prop of InputProps.
Dependencies
- npm
class-variance-authority@0.7.1- Installs with it
- nothing else
Source
components/ui/input.tsx
/* eslint-disable react-refresh/only-export-components */
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const inputVariants = cva(
"w-full min-w-0 text-sm leading-[1.4] text-text-strong transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-text-strong placeholder:text-text-note disabled:pointer-events-none disabled:cursor-not-allowed disabled:text-text-disabled",
{
variants: {
variant: {
outlined:
"rounded-md border border-border-default bg-bg-main hover:border-border-hover hover:bg-input-hover focus-visible:border-ring-neutral-outline focus-visible:bg-input-default focus-visible:ring-3 focus-visible:ring-ring-neutral-shadow disabled:border-border-disabled disabled:bg-input-disabled aria-invalid:border-negative-middle aria-invalid:focus-visible:border-negative-middle aria-invalid:focus-visible:ring-negative-middle/25",
// Fill draws no border at rest, but hover/focus/invalid all draw a 1px
// one — reserve it as transparent so entering a state never reflows.
fill: "rounded-md border border-transparent bg-input-default hover:border-border-hover hover:bg-input-hover focus-visible:border-ring-neutral-outline focus-visible:ring-3 focus-visible:ring-ring-neutral-shadow disabled:border-transparent disabled:bg-input-disabled aria-invalid:border-negative-middle aria-invalid:focus-visible:border-negative-middle aria-invalid:focus-visible:ring-negative-middle/25",
// Underline carries no surface, no radius and no focus ring — the whole
// state vocabulary lives on the bottom border.
underline:
"rounded-none border-0 border-b border-b-border-default bg-transparent hover:border-b-border-active focus-visible:border-b-border-active disabled:border-b-border-default disabled:bg-transparent aria-invalid:border-b-negative-middle aria-invalid:focus-visible:border-b-negative-middle",
},
size: {
sm: "h-8 px-2.5 py-1.5",
md: "h-10 px-3 py-2.5",
lg: "h-12 px-4 py-3.5",
},
},
compoundVariants: [
{
variant: "underline",
size: ["sm", "md", "lg"],
className: "px-0",
},
],
defaultVariants: {
variant: "outlined",
size: "sm",
},
},
);
export type InputProps = Omit<React.ComponentProps<"input">, "size"> &
VariantProps<typeof inputVariants>;
function Input({
className,
type,
variant = "outlined",
size = "sm",
...props
}: InputProps) {
return (
<input
type={type}
data-slot="input"
data-variant={variant}
data-size={size}
className={cn(inputVariants({ variant, size }), className)}
{...props}
/>
);
}
export { Input, inputVariants };