फ़ील्ड
सेटिंग्स पैनलों, चेकआउट फ़ॉर्मों और साइनअप फ़्लो के लिए लेबल, नियंत्रण, सहायता पाठ और त्रुटि स्लॉट — नियोब्रूटलिस्ट फ़ॉर्म ट्रीटमेंट के साथ।
import { Button } from "@/components/ui/button"
import { Checkbox } from "@/components/ui/checkbox"
import {फ़ील्ड लेबल, कंट्रोल, हेल्पर टेक्स्ट और एरर मैसेज को एक संरेखित ब्लॉक में लपेटता है, और FieldGroup तथा FieldSet से समूहित सेक्शन तक बढ़ता है। नीचे कोई प्रिमिटिव नहीं — सादा fieldset, legend और role="group" सेमेंटिक्स, Label और Separator के साथ, नियोब्रूटलिस्ट रेसिपी: लेजेंड और लेबल पर बोल्ड हेडिंग टाइप; लपेटे कंट्रोल मोटे बॉर्डर और कठोर छायाएँ लाते हैं।
इसे इन स्थितियों में चुनें:
- सेटिंग्स पेज —
FieldSetलेजेंड और ग्रुपों के बीचFieldSeparatorसे प्रोफ़ाइल, नोटिफ़िकेशन, बिलिंग स्टैक करें। - चेकआउट और साइनअप फ़ॉर्म — इनपुट, सेलेक्ट और स्विच पर लेबल, विवरण और एरर अलाइनमेंट एक जैसा रखें।
- चॉइस कार्ड — प्लान पिकर और प्रेफ़रेंस पैनल के लिए रेडियो, चेकबॉक्स या स्विच को चुनने योग्य
FieldLabelकार्ड में लपेटें।
इंस्टॉलेशन#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/field.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/field.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/field.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/field.json
निम्नलिखित कोड को अपने प्रोजेक्ट में कॉपी और पेस्ट करें.
"use client"
import { useMemo } from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { Label } from "@/components/ui/label"
import { Separator } from "@/components/ui/separator"
function FieldSet({ className, ...props }: React.ComponentProps<"fieldset">) {
return (
<fieldset
data-slot="field-set"
className={cn(
"flex flex-col gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3",
className
)}
{...props}
/>
)
}
function FieldLegend({
className,
variant = "legend",
...props
}: React.ComponentProps<"legend"> & { variant?: "legend" | "label" }) {
return (
<legend
data-slot="field-legend"
data-variant={variant}
className={cn(
"mb-1.5 font-head font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base",
className
)}
{...props}
/>
)
}
function FieldGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="field-group"
className={cn(
"group/field-group @container/field-group flex w-full flex-col gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4",
className
)}
{...props}
/>
)
}
const fieldVariants = cva(
"group/field flex w-full gap-2 data-[invalid=true]:text-destructive",
{
variants: {
orientation: {
vertical: "flex-col *:w-full [&>.sr-only]:w-auto",
horizontal:
"flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
responsive:
"flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px",
},
},
defaultVariants: {
orientation: "vertical",
},
}
)
function Field({
className,
orientation = "vertical",
...props
}: React.ComponentProps<"div"> & VariantProps<typeof fieldVariants>) {
return (
<div
role="group"
data-slot="field"
data-orientation={orientation}
className={cn(fieldVariants({ orientation }), className)}
{...props}
/>
)
}
function FieldContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="field-content"
className={cn(
"group/field-content flex flex-1 flex-col gap-0.5 leading-snug",
className
)}
{...props}
/>
)
}
function FieldLabel({
className,
...props
}: React.ComponentProps<typeof Label>) {
return (
<Label
data-slot="field-label"
className={cn(
"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded has-[>[data-slot=field]]:border-2 *:data-[slot=field]:p-2.5 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10",
"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col",
className
)}
{...props}
/>
)
}
function FieldTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="field-label"
className={cn(
"flex w-fit items-center gap-2 text-sm font-head font-medium group-data-[disabled=true]/field:opacity-50",
className
)}
{...props}
/>
)
}
function FieldDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<p
data-slot="field-description"
className={cn(
"text-left text-sm leading-normal font-normal text-muted-foreground group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5",
"last:mt-0 nth-last-2:-mt-1",
"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
)}
{...props}
/>
)
}
function FieldSeparator({
children,
className,
...props
}: React.ComponentProps<"div"> & {
children?: React.ReactNode
}) {
return (
<div
data-slot="field-separator"
data-content={!!children}
className={cn(
"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2",
className
)}
{...props}
>
<Separator className="absolute inset-0 top-1/2" />
{children && (
<span
className="relative mx-auto block w-fit bg-background px-2 text-muted-foreground"
data-slot="field-separator-content"
>
{children}
</span>
)}
</div>
)
}
function FieldError({
className,
children,
errors,
...props
}: React.ComponentProps<"div"> & {
errors?: Array<{ message?: string } | undefined>
}) {
const content = useMemo(() => {
if (children) {
return children
}
if (!errors?.length) {
return null
}
const uniqueErrors = [
...new Map(errors.map((error) => [error?.message, error])).values(),
]
if (uniqueErrors?.length == 1) {
return uniqueErrors[0]?.message
}
return (
<ul className="ml-4 flex list-disc flex-col gap-1">
{uniqueErrors.map(
(error, index) =>
error?.message && <li key={index}>{error.message}</li>
)}
</ul>
)
}, [children, errors])
if (!content) {
return null
}
return (
<div
role="alert"
data-slot="field-error"
className={cn("text-sm font-normal text-destructive", className)}
{...props}
>
{content}
</div>
)
}
export {
Field,
FieldLabel,
FieldDescription,
FieldError,
FieldGroup,
FieldLegend,
FieldSeparator,
FieldSet,
FieldContent,
FieldTitle,
}
अपने प्रोजेक्ट सेटअप के अनुसार इंपोर्ट पाथ अपडेट करें.
उपयोग#
import {
Field,
FieldContent,
FieldDescription,
FieldError,
FieldGroup,
FieldLabel,
FieldLegend,
FieldSeparator,
FieldSet,
FieldTitle,
} from "@/components/ui/field"<FieldSet>
<FieldLegend>Profile</FieldLegend>
<FieldDescription>This appears on invoices and emails.</FieldDescription>
<FieldGroup>
<Field>
<FieldLabel htmlFor="name">Full name</FieldLabel>
<Input id="name" autoComplete="off" placeholder="Evil Rabbit" />
<FieldDescription>This appears on invoices and emails.</FieldDescription>
</Field>
<Field>
<FieldLabel htmlFor="username">Username</FieldLabel>
<Input id="username" autoComplete="off" aria-invalid />
<FieldError>Choose another username.</FieldError>
</Field>
<Field orientation="horizontal">
<Switch id="newsletter" />
<FieldLabel htmlFor="newsletter">Subscribe to the newsletter</FieldLabel>
</Field>
</FieldGroup>
</FieldSet>कंपोज़िशन#
Field#
लेबल, हेल्पर टेक्स्ट और वैलिडेशन के साथ एक अकेला कंट्रोल.
Field
├── FieldLabel
├── Input / Textarea / Switch / Select
├── FieldDescription
└── FieldErrorFieldGroup#
एक ही समूह में संबंधित फ़ील्ड. जरूरत पड़ने पर सेक्शन के बीच FieldSeparator का उपयोग करें.
FieldGroup
├── Field
│ ├── FieldLabel
│ ├── Input / Textarea / Switch / Select
│ ├── FieldDescription
│ └── FieldError
├── FieldSeparator
└── Field
├── FieldLabel
└── Input / Textarea / Switch / SelectFieldSet#
एक लेजेंड और विवरण के साथ सिमेंटिक समूह, जिसमें आमतौर पर एक FieldGroup होता है.
FieldSet
├── FieldLegend
├── FieldDescription
└── FieldGroup
├── Field
│ ├── FieldLabel
│ ├── Input / Textarea / Switch / Select
│ ├── FieldDescription
│ └── FieldError
└── Field
├── FieldLabel
└── Input / Textarea / Switch / Selectएनाटॉमी#
Field फ़ैमिली सुलभ फ़ॉर्म बनाने के लिए डिज़ाइन की गई है. एक सामान्य फ़ील्ड इस तरह संरचित होता है:
<Field>
<FieldLabel htmlFor="input-id">Label</FieldLabel>
{/* Input, Select, Switch, etc. */}
<FieldDescription>Optional helper text.</FieldDescription>
<FieldError>Validation message.</FieldError>
</Field>Fieldएक अकेले फ़ील्ड का मुख्य रैपर है.FieldContentएक flex कॉलम है जो लेबल और विवरण को समूहबद्ध करता है. अगर आपके पास कोई विवरण नहीं है तो इसकी जरूरत नहीं है.- संबंधित फ़ील्ड को
FieldGroupसे रैप करें, और सिमेंटिक समूह के लिएFieldLegendके साथFieldSetका उपयोग करें.
फ़ॉर्म#
Field कंपोनेंट के साथ और React Hook Form, Tanstack Form, या Formisch के साथ फ़ॉर्म बनाने के लिए Form डॉक्युमेंटेशन देखें.
उदाहरण#
Input#
import {
Field,
FieldDescription,Textarea#
import {
Field,
FieldDescription,Select#
import {
Field,
FieldDescription,Slider#
"use client"
import * as React from "react"Fieldset#
import {
Field,
FieldDescription,Checkbox#
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,Radio#
import {
Field,
FieldDescription,Switch#
import { Field, FieldLabel } from "@/components/ui/field"
import { Switch } from "@/components/ui/switch"
Choice Card#
चयन योग्य फ़ील्ड समूह बनाने के लिए Field कंपोनेंट्स को FieldLabel के अंदर रैप करें. यह RadioItem, Checkbox और Switch कंपोनेंट्स के साथ काम करता है.
import {
Field,
FieldContent,Field Group#
FieldGroup के साथ Field कंपोनेंट्स को स्टैक करें. उन्हें अलग करने के लिए FieldSeparator जोड़ें.
import { Checkbox } from "@/components/ui/checkbox"
import {
Field,RTL#
Neobrutalism में RTL सपोर्ट सक्षम करने के लिए, RTL कॉन्फ़िगरेशन गाइड देखें.
"use client"
import * as React from "react"रिस्पॉन्सिव लेआउट#
- वर्टिकल फ़ील्ड: डिफ़ॉल्ट ओरिएंटेशन लेबल, कंट्रोल और हेल्पर टेक्स्ट को एक के ऊपर एक स्टैक करता है—मोबाइल-फ़र्स्ट लेआउट के लिए आदर्श.
- हॉरिज़ॉन्टल फ़ील्ड: लेबल और कंट्रोल को अगल-बगल संरेखित करने के लिए
Fieldपरorientation="horizontal"सेट करें. विवरण को संरेखित रखने के लिए इसेFieldContentके साथ जोड़ें. - रिस्पॉन्सिव फ़ील्ड: कंटेनर-अवेयर पैरेंट के अंदर स्वचालित कॉलम लेआउट के लिए
orientation="responsive"सेट करें. विशिष्ट ब्रेकपॉइंट्स पर ओरिएंटेशन बदलने के लिएFieldGroupपर@container/field-groupक्लासेस लागू करें.
import { Button } from "@/components/ui/button"
import {
Field,वैलिडेशन और एरर#
- पूरे ब्लॉक को एरर स्टेट में बदलने के लिए
Fieldपरdata-invalidजोड़ें. - सहायक तकनीकों के लिए इनपुट पर ही
aria-invalidजोड़ें. - एरर संदेशों को फ़ील्ड के साथ संरेखित रखने के लिए
FieldErrorको कंट्रोल के तुरंत बाद याFieldContentके अंदर रेंडर करें.
<Field data-invalid>
<FieldLabel htmlFor="email">Email</FieldLabel>
<Input id="email" type="email" aria-invalid />
<FieldError>Enter a valid email address.</FieldError>
</Field>एक्सेसिबिलिटी#
FieldSetऔरFieldLegendकीबोर्ड और सहायक तकनीक उपयोगकर्ताओं के लिए संबंधित कंट्रोल्स को समूहबद्ध रखते हैं.Field,role="group"आउटपुट करता है, इसलिए नेस्टेड कंट्रोल्स संयोजित होने परFieldLabelऔरFieldLegendसे लेबलिंग प्राप्त करते हैं.FieldSeparatorका उपयोग संयम से करें ताकि स्क्रीन रीडर्स को स्पष्ट सेक्शन सीमाएं मिलें.
एक्सेसिबिलिटी#
फ़ील्ड परिवार सेमेंटिक्स-पहले है: FieldSet और FieldLegend नेटिव fieldset/legend रेंडर करते हैं, Field role="group" रेंडर करता है, और FieldError role="alert" रेंडर करता है ताकि वैलिडेशन संदेश दिखते ही घोषित हों।
- हर
FieldLabelको कंट्रोल सेhtmlFor/idसे जोड़ें — लेबल पर क्लिक फ़ोकस/टॉगल करता है और स्क्रीन रीडर संबंध घोषित करते हैं। - अमान्य इनपुट पर कंट्रोल पर ही
aria-invalidसेट करें;Fieldपरdata-invalidसिर्फ़ एरर स्टाइल चलाता है। - कीबोर्ड व्यवहार अंदर के कंट्रोल का है — रैपर अपना कोई फ़ोकस स्टॉप या की बाइंडिंग नहीं जोड़ते।
API रेफ़रेंस#
FieldSet#
एक कंटेनर जो स्पेसिंग प्रीसेट के साथ एक सिमेंटिक fieldset रेंडर करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
<FieldSet>
<FieldLegend>Delivery</FieldLegend>
<FieldGroup>{/* Fields */}</FieldGroup>
</FieldSet>FieldLegend#
FieldSet के लिए लेजेंड एलिमेंट. लेबल आकार के साथ संरेखित करने के लिए label वैरिएंट पर स्विच करें.
| Prop | Type | Default |
|---|---|---|
variant | "legend" | "label" | "legend" |
className | string |
<FieldLegend variant="label">Notification Preferences</FieldLegend>FieldLegend के दो वैरिएंट हैं: legend और label. label वैरिएंट लेबल का आकार और संरेखण लागू करता है. नेस्टेड FieldSet होने पर उपयोगी.
FieldGroup#
लेआउट रैपर जो Field कंपोनेंट्स को स्टैक करता है और रिस्पॉन्सिव ओरिएंटेशन के लिए container queries सक्षम करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
<FieldGroup className="@container/field-group flex flex-col gap-6">
<Field>{/* ... */}</Field>
<Field>{/* ... */}</Field>
</FieldGroup>Field#
एक अकेले फ़ील्ड का मुख्य रैपर. ओरिएंटेशन कंट्रोल, अमान्य स्टेट स्टाइलिंग और स्पेसिंग प्रदान करता है.
| Prop | Type | Default |
|---|---|---|
orientation | "vertical" | "horizontal" | "responsive" | "vertical" |
className | string | |
data-invalid | boolean |
<Field orientation="horizontal">
<FieldLabel htmlFor="remember">Remember me</FieldLabel>
<Switch id="remember" />
</Field>FieldContent#
flex कॉलम जो कंट्रोल और विवरणों को समूहबद्ध करता है जब लेबल कंट्रोल के बगल में होता है. अगर आपके पास कोई विवरण नहीं है तो इसकी जरूरत नहीं है.
| Prop | Type | Default |
|---|---|---|
className | string |
<Field>
<Checkbox id="notifications" />
<FieldContent>
<FieldLabel htmlFor="notifications">Notifications</FieldLabel>
<FieldDescription>Email, SMS, and push options.</FieldDescription>
</FieldContent>
</Field>FieldLabel#
लेबल जो सीधे इनपुट और नेस्टेड Field चिल्ड्रन दोनों के लिए स्टाइल किया गया है.
| Prop | Type | Default |
|---|---|---|
className | string | |
asChild | boolean | false |
<FieldLabel htmlFor="email">Email</FieldLabel>FieldTitle#
FieldContent के अंदर लेबल स्टाइलिंग के साथ एक टाइटल रेंडर करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
<FieldContent>
<FieldTitle>Enable Touch ID</FieldTitle>
<FieldDescription>Unlock your device faster.</FieldDescription>
</FieldContent>FieldDescription#
हेल्पर टेक्स्ट स्लॉट जो हॉरिज़ॉन्टल लेआउट में लंबी लाइनों को स्वचालित रूप से संतुलित करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
<FieldDescription>We never share your email with anyone.</FieldDescription>FieldSeparator#
FieldGroup के अंदर सेक्शन अलग करने के लिए विज़ुअल डिवाइडर. वैकल्पिक इनलाइन कंटेंट स्वीकार करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
<FieldSeparator>Or continue with</FieldSeparator>FieldError#
सुलभ एरर कंटेनर जो चिल्ड्रन या एक errors array (उदाहरण के लिए, react-hook-form से) स्वीकार करता है.
| Prop | Type | Default |
|---|---|---|
errors | Array<{ message?: string } | undefined> | |
className | string |
<FieldError errors={errors.username} />जब errors array में कई संदेश होते हैं, तो कंपोनेंट स्वचालित रूप से एक सूची रेंडर करता है.
FieldError, Standard Schema लागू करने वाले किसी भी वैलिडेटर द्वारा उत्पन्न issues भी स्वीकार करता है, जिसमें Zod, Valibot और ArkType शामिल हैं. विभिन्न लाइब्रेरीज़ में एकीकृत एरर सूची रेंडर करने के लिए स्कीमा परिणाम से issues array सीधे पास करें.