Styled text input
Your API key is encrypted and stored securely.
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputDemoExample() {
return (
<Field>
<FieldLabel for="input-demo-api-key">API Key</FieldLabel>
<Input id="input-demo-api-key" type="password" placeholder="sk-..." />
<FieldDescription>Your API key is encrypted and stored securely.</FieldDescription>
</Field>
)
}
Installation
npx @fictjs/shadcn@latest add inputCopy the Fict shadcn component into your project.
Source
components/ui/input.tsx
src/components/ui/input.tsx
import { cn } from '@/lib/cn'
type InputProps = JSX.IntrinsicElements['input']
export function Input(props: InputProps) {
const { class: className, type = 'text', ...rest } = props
return (
<input
type={type}
class={cn(
'flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
className,
)}
{...rest}
/>
)
}
Usage
Examples
Basic
import { Input } from '@/components/ui/input'
...import { Input } from '@/components/ui/input'
export default function InputBasicExample() {
return <Input placeholder="Enter text" />
}
Field
Choose a unique username for your account.
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputFieldExample() {
return (
<Field>
<FieldLabel for="input-field-username">Username</FieldLabel>
<Input id="input-field-username" type="text" placeholder="Enter your username" />
<FieldDescription>Choose a unique username for your account.</FieldDescription>
</Field>
)
}
Fieldgroup
We'll send updates to this address.
import { Button } from '@/components/ui/button'
import { Field, FieldDescription, FieldGroup, FieldLabel } from '@/components/ui/field'
...import { Button } from '@/components/ui/button'
import { Field, FieldDescription, FieldGroup, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputFieldgroupExample() {
return (
<FieldGroup>
<Field>
<FieldLabel for="fieldgroup-name">Name</FieldLabel>
<Input id="fieldgroup-name" placeholder="Jordan Lee" />
</Field>
<Field>
<FieldLabel for="fieldgroup-email">Email</FieldLabel>
<Input id="fieldgroup-email" type="email" placeholder="name@example.com" />
<FieldDescription>We'll send updates to this address.</FieldDescription>
</Field>
<Field orientation="horizontal">
<Button type="reset" variant="outline">
Reset
</Button>
<Button type="submit">Submit</Button>
</Field>
</FieldGroup>
)
}
Disabled
This field is currently disabled.
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputDisabledExample() {
return (
<Field data-disabled>
<FieldLabel for="input-demo-disabled">Email</FieldLabel>
<Input id="input-demo-disabled" type="email" placeholder="Email" disabled />
<FieldDescription>This field is currently disabled.</FieldDescription>
</Field>
)
}
Invalid
This field contains validation errors.
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputInvalidExample() {
return (
<Field data-invalid>
<FieldLabel for="input-invalid">Invalid Input</FieldLabel>
<Input id="input-invalid" placeholder="Error" aria-invalid />
<FieldDescription>This field contains validation errors.</FieldDescription>
</Field>
)
}
File
Select a picture to upload.
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputFileExample() {
return (
<Field>
<FieldLabel for="picture">Picture</FieldLabel>
<Input id="picture" type="file" />
<FieldDescription>Select a picture to upload.</FieldDescription>
</Field>
)
}
Inline
import { Button } from '@/components/ui/button'
import { Field } from '@/components/ui/field'
...import { Button } from '@/components/ui/button'
import { Field } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputInlineExample() {
return (
<Field orientation="horizontal">
<Input type="search" placeholder="Search..." />
<Button>Search</Button>
</Field>
)
}
Grid
import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldGroup, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputGridExample() {
return (
<FieldGroup class="grid max-w-sm grid-cols-2">
<Field>
<FieldLabel for="first-name">First Name</FieldLabel>
<Input id="first-name" placeholder="Jordan" />
</Field>
<Field>
<FieldLabel for="last-name">Last Name</FieldLabel>
<Input id="last-name" placeholder="Lee" />
</Field>
</FieldGroup>
)
}
Required
This field must be filled out.
import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
...import { Field, FieldDescription, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputRequiredExample() {
return (
<Field>
<FieldLabel for="input-required">
Required Field <span class="text-destructive">*</span>
</FieldLabel>
<Input id="input-required" placeholder="This field is required" required />
<FieldDescription>This field must be filled out.</FieldDescription>
</Field>
)
}
Badge
import { Badge } from '@/components/ui/badge'
import { Field, FieldLabel } from '@/components/ui/field'
...import { Badge } from '@/components/ui/badge'
import { Field, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputBadgeExample() {
return (
<Field>
<FieldLabel for="input-badge">
Webhook URL{' '}
<Badge variant="secondary" class="ml-auto">
Beta
</Badge>
</FieldLabel>
<Input id="input-badge" type="url" placeholder="https://api.example.com/webhook" />
</Field>
)
}
Input Group
https://
import { Field, FieldLabel } from '@/components/ui/field'
import {
...import { Field, FieldLabel } from '@/components/ui/field'
import {
InputGroup,
InputGroupAddon,
InputGroupInput,
} from '@/components/ui/input-group'
export default function InputInputGroupExample() {
return (
<Field>
<FieldLabel for="input-group-url">Website URL</FieldLabel>
<InputGroup>
<InputGroupInput id="input-group-url" placeholder="example.com" />
<InputGroupAddon>https://</InputGroupAddon>
<InputGroupAddon align="inline-end">
<span aria-hidden="true">ⓘ</span>
</InputGroupAddon>
</InputGroup>
</Field>
)
}
Button Group
import { Button } from '@/components/ui/button'
import { ButtonGroup } from '@/components/ui/button-group'
...import { Button } from '@/components/ui/button'
import { ButtonGroup } from '@/components/ui/button-group'
import { Field, FieldLabel } from '@/components/ui/field'
import { Input } from '@/components/ui/input'
export default function InputButtonGroupExample() {
return (
<Field>
<FieldLabel for="input-button-group">Search</FieldLabel>
<ButtonGroup>
<Input id="input-button-group" placeholder="Type to search..." />
<Button variant="outline">Search</Button>
</ButtonGroup>
</Field>
)
}
Form
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
...import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
export default function InputFormExample() {
return (
<form class="grid w-full max-w-sm gap-4" onSubmit={event => event.preventDefault()}>
<label class="grid gap-2">
Name
<Input name="name" placeholder="Evil Rabbit" required />
</label>
<label class="grid gap-2">
Email
<Input name="email" type="email" placeholder="john@example.com" />
<small>We'll never share your email with anyone.</small>
</label>
<div class="grid grid-cols-2 gap-4">
<label class="grid gap-2">
Phone
<Input name="phone" type="tel" placeholder="+1 (555) 123-4567" />
</label>
<label class="grid gap-2">
Country
<Select defaultValue="us">
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="us">United States</SelectItem>
<SelectItem value="uk">United Kingdom</SelectItem>
<SelectItem value="ca">Canada</SelectItem>
</SelectContent>
</Select>
</label>
</div>
<label class="grid gap-2">
Address
<Input name="address" placeholder="123 Main St" />
</label>
<div class="flex gap-2">
<Button type="button" variant="outline">
Cancel
</Button>
<Button type="submit">Submit</Button>
</div>
</form>
)
}
Rtl
import { Input } from '@/components/ui/input'
...import { Input } from '@/components/ui/input'
const translations = {
ar: { dir: 'rtl', label: 'مفتاح API', description: 'مفتاح API الخاص بك مشفر ومخزن بأمان.' },
he: { dir: 'rtl', label: 'מפתח API', description: 'מפתח ה-API שלך מוצפן ונשמר בצורה מאובטחת.' },
en: {
dir: 'ltr',
label: 'API Key',
description: 'Your API key is encrypted and stored securely.',
},
} as const
export default function InputRtlExample() {
let language = $state<keyof typeof translations>('ar')
const text = () => translations[language]
return (
<div class="grid gap-4">
<select
value={language}
onChange={event => {
language = event.currentTarget.value as keyof typeof translations
}}
>
<option value="ar">Arabic (العربية)</option>
<option value="he">Hebrew (עברית)</option>
<option value="en">English</option>
</select>
<div class="grid w-80 gap-2" dir={text().dir}>
<label for="input-rtl">{text().label}</label>
<Input id="input-rtl" type="password" placeholder="sk-..." dir={text().dir} />
<p class="text-sm text-muted-foreground">{text().description}</p>
</div>
</div>
)
}