इनपुट समूह
खोज बार, URL फ़ील्ड और चैट कंपोज़र के इनपुट्स के लिए आइकन, बटन और kbd संकेत संलग्न करें — नियोब्रूटलिस्ट बॉर्डर और शैडोज़ के साथ।
import { Search } from "lucide-react"
import {इनपुट ग्रुप इनपुट या textarea को उसके ऐडऑन — आइकन, इनलाइन टेक्स्ट, बटन, कीबोर्ड संकेत — के साथ एक बॉर्डर वाले कंट्रोल में लपेटता है। यह इस लाइब्रेरी के Input, Textarea और Button की इन-हाउस कंपोज़िशन है, नियोब्रूटलिस्ट रेसिपी के अनुसार स्टाइल किया गया है: मोटे बॉर्डर, कठोर छायाएँ और बोल्ड टाइपोग्राफ़ी।
इसे इन स्थितियों में चुनें:
- सर्च फ़ील्ड — आगे सर्च आइकन और पीछे
⌘Kसंकेत या clear बटन। - प्रीफ़िक्स्ड और सफ़िक्स्ड इनपुट — तय
https://,@या.comटेक्स्ट ताकि उपयोगकर्ता सिर्फ़ बदलने वाला भाग टाइप करे। - चैट और प्रॉम्प्ट कंपोज़र —
block-endटूलबार बटन और send एक्शन वाला textarea।
इंस्टॉलेशन#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/input-group.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/input-group.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/input-group.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/input-group.json
निम्नलिखित कोड को अपने प्रोजेक्ट में कॉपी और पेस्ट करें.
"use client"
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
function InputGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="input-group"
role="group"
className={cn(
"group/input-group relative flex h-8 w-full min-w-0 items-center rounded border-2 bg-input shadow-sm transition-colors outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:bg-input/50 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:outline-2 has-[[data-slot=input-group-control]:focus-visible]:outline-offset-2 has-[[data-slot=input-group-control]:focus-visible]:outline-primary has-[[data-slot][aria-invalid=true]]:border-destructive has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5",
className
)}
{...props}
/>
)
}
const inputGroupAddonVariants = cva(
"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4",
{
variants: {
align: {
"inline-start":
"order-first pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem]",
"inline-end":
"order-last pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem]",
"block-start":
"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2",
"block-end":
"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2",
},
},
defaultVariants: {
align: "inline-start",
},
}
)
function InputGroupAddon({
className,
align = "inline-start",
...props
}: React.ComponentProps<"div"> & VariantProps<typeof inputGroupAddonVariants>) {
return (
<div
role="group"
data-slot="input-group-addon"
data-align={align}
className={cn(inputGroupAddonVariants({ align }), className)}
onClick={(e) => {
if ((e.target as HTMLElement).closest("button")) {
return
}
e.currentTarget.parentElement?.querySelector("input")?.focus()
}}
{...props}
/>
)
}
const inputGroupButtonVariants = cva(
"flex items-center gap-2 text-sm shadow-none",
{
variants: {
size: {
xs: "h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5",
sm: "",
"icon-xs":
"size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0",
"icon-sm": "size-8 p-0 has-[>svg]:p-0",
},
},
defaultVariants: {
size: "xs",
},
}
)
function InputGroupButton({
className,
type = "button",
variant = "ghost",
size = "xs",
...props
}: Omit<React.ComponentProps<typeof Button>, "size"> &
VariantProps<typeof inputGroupButtonVariants>) {
return (
<Button
type={type}
data-size={size}
variant={variant}
className={cn(inputGroupButtonVariants({ size }), className)}
{...props}
/>
)
}
function InputGroupText({ className, ...props }: React.ComponentProps<"span">) {
return (
<span
className={cn(
"flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4",
className
)}
{...props}
/>
)
}
function InputGroupInput({
className,
...props
}: React.ComponentProps<"input">) {
return (
<Input
data-slot="input-group-control"
className={cn(
"flex-1 rounded-none border-0 bg-transparent shadow-none outline-none focus-visible:outline-none disabled:bg-transparent aria-invalid:outline-none dark:bg-transparent dark:disabled:bg-transparent",
className
)}
{...props}
/>
)
}
function InputGroupTextarea({
className,
...props
}: React.ComponentProps<"textarea">) {
return (
<Textarea
data-slot="input-group-control"
className={cn(
"flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none outline-none focus-visible:outline-none disabled:bg-transparent aria-invalid:outline-none dark:bg-transparent dark:disabled:bg-transparent",
className
)}
{...props}
/>
)
}
export {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupText,
InputGroupInput,
InputGroupTextarea,
}
अपने प्रोजेक्ट सेटअप के अनुसार इंपोर्ट पाथ अपडेट करें.
उपयोग#
import {
InputGroup,
InputGroupAddon,
InputGroupButton,
InputGroupInput,
InputGroupText,
InputGroupTextarea,
} from "@/components/ui/input-group"<InputGroup>
<InputGroupInput placeholder="Search..." />
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
</InputGroup>कंपोज़िशन#
InputGroup बनाने के लिए निम्नलिखित कंपोज़िशन का उपयोग करें:
InputGroup
├── InputGroupInput or InputGroupTextarea
├── InputGroupAddon
├── InputGroupButton
└── InputGroupTextAlign#
इनपुट के सापेक्ष ऐडऑन को पोज़िशन करने के लिए InputGroupAddon पर align प्रॉप का उपयोग करें.
सही फ़ोकस प्रबंधन के लिए, InputGroupAddon को DOM में हमेशा
InputGroupInput या InputGroupTextarea के बाद रखा जाना चाहिए. ऐडऑन को
दृश्य रूप से पोज़िशन करने के लिए align प्रॉप का उपयोग करें.
inline-start#
ऐडऑन को इनपुट की शुरुआत में रखने के लिए align="inline-start" का उपयोग करें. यह डिफ़ॉल्ट है.
import { SearchIcon } from "lucide-react"
import {inline-end#
ऐडऑन को इनपुट के अंत में रखने के लिए align="inline-end" का उपयोग करें.
import { EyeOffIcon } from "lucide-react"
import {block-start#
ऐडऑन को इनपुट के ऊपर रखने के लिए align="block-start" का उपयोग करें.
import { CopyIcon, FileCodeIcon } from "lucide-react"
import {block-end#
ऐडऑन को इनपुट के नीचे रखने के लिए align="block-end" का उपयोग करें.
import {
Field,
FieldDescription,उदाहरण#
Icon#
import {
CheckIcon,
CreditCardIcon,Text#
import {
InputGroup,
InputGroupAddon,Button#
"use client"
import * as React from "react"Kbd#
import { SearchIcon } from "lucide-react"
import {Dropdown#
"use client"
import { ChevronDownIcon, MoreHorizontal } from "lucide-react"Spinner#
import { LoaderIcon } from "lucide-react"
import {Textarea#
import {
IconBrandJavascript,
IconCopy,Custom Input#
स्वचालित फ़ोकस स्टेट हैंडलिंग के लिए अपने कस्टम इनपुट में data-slot="input-group-control" एट्रिब्यूट जोड़ें.
यहां किसी थर्ड-पार्टी लाइब्रेरी से एक कस्टम रिसाइज़ेबल textarea का उदाहरण है.
"use client"
import TextareaAutosize from "react-textarea-autosize"RTL#
Neobrutalism में RTL सपोर्ट सक्षम करने के लिए, RTL कॉन्फ़िगरेशन गाइड देखें.
"use client"
import * as React from "react"एक्सेसिबिलिटी#
इनपुट ग्रुप के लिए कोई ARIA विजेट पैटर्न नहीं — रैपर role="group" रेंडर करता है ताकि असिस्टिव टेक ऐडऑन को कंट्रोल से जोड़े, और कीबोर्ड पहुँच नेटिव है: Tab DOM क्रम में इनपुट और किसी भी InputGroupButton तक पहुँचता है, इसलिए ऐडऑन इनपुट के बाद होने चाहिए (विज़ुअली align से रखे)। दो बातें आप पर हैं: https:// जैसा ऐडऑन टेक्स्ट विज़ुअल है, programmatic लेबल नहीं, इसलिए इनपुट को अभी भी <Label> या aria-label चाहिए; और आइकन-ओनली बटन को aria-label चाहिए — ऐडऑन पर क्लिक इनपुट फ़ोकस करता है, पर वह पॉइंटर सुविधा है, कीबोर्ड पथ नहीं।
API रेफ़रेंस#
InputGroup#
मुख्य कंपोनेंट जो इनपुट और ऐडऑन को रैप करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
<InputGroup>
<InputGroupInput />
<InputGroupAddon />
</InputGroup>InputGroupAddon#
इनपुट के साथ आइकन, टेक्स्ट, बटन या अन्य कंटेंट दिखाता है.
सही फ़ोकस नेविगेशन के लिए, InputGroupAddon कंपोनेंट को इनपुट के बाद रखा
जाना चाहिए. ऐडऑन को पोज़िशन करने के लिए align प्रॉप सेट करें.
| Prop | Type | Default |
|---|---|---|
align | "inline-start" | "inline-end" | "block-start" | "block-end" | "inline-start" |
className | string |
<InputGroupAddon align="inline-end">
<SearchIcon />
</InputGroupAddon><InputGroupInput /> के लिए, inline-start या inline-end संरेखण का उपयोग करें. <InputGroupTextarea /> के लिए, block-start या block-end संरेखण का उपयोग करें.
InputGroupAddon कंपोनेंट में कई InputGroupButton कंपोनेंट और आइकन हो सकते हैं.
<InputGroupAddon>
<InputGroupButton>Button</InputGroupButton>
<InputGroupButton>Button</InputGroupButton>
</InputGroupAddon>InputGroupButton#
इनपुट समूहों के भीतर बटन दिखाता है.
| Prop | Type | Default |
|---|---|---|
size | "xs" | "icon-xs" | "sm" | "icon-sm" | "xs" |
variant | "default" | "destructive" | "outline" | "secondary" | "ghost" | "link" | "ghost" |
className | string |
<InputGroupButton>Button</InputGroupButton>
<InputGroupButton size="icon-xs" aria-label="Copy">
<CopyIcon />
</InputGroupButton>InputGroupInput#
इनपुट समूह बनाते समय <Input /> का प्रतिस्थापन. इस कंपोनेंट में इनपुट समूह के स्टाइल पहले से लागू होते हैं और फ़ोकस स्टेट हैंडलिंग के लिए एकीकृत data-slot="input-group-control" का उपयोग करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
बाकी सभी प्रॉप्स अंतर्निहित <Input /> कंपोनेंट में पास किए जाते हैं.
<InputGroup>
<InputGroupInput placeholder="Enter text..." />
<InputGroupAddon>
<SearchIcon />
</InputGroupAddon>
</InputGroup>InputGroupTextarea#
इनपुट समूह बनाते समय <Textarea /> का प्रतिस्थापन. इस कंपोनेंट में textarea समूह के स्टाइल पहले से लागू होते हैं और फ़ोकस स्टेट हैंडलिंग के लिए एकीकृत data-slot="input-group-control" का उपयोग करता है.
| Prop | Type | Default |
|---|---|---|
className | string |
बाकी सभी प्रॉप्स अंतर्निहित <Textarea /> कंपोनेंट में पास किए जाते हैं.
<InputGroup>
<InputGroupTextarea placeholder="Enter message..." />
<InputGroupAddon align="block-end">
<InputGroupButton>Send</InputGroupButton>
</InputGroupAddon>
</InputGroup>