گروه ورودی (Input Group)

افزودن آیکون‌ها، دکمه‌ها و محتوای کمکی به ورودی‌ها با پشتیبانی کامل از RTL.

نصب (Installation)

1npx @quark-lab/rad-ui add input-group

نمونه‌ها (Examples)

استفاده پایه (Basic Usage)

استفاده ساده از گروه ورودی با آیکون جستجو.

مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5} from "@/components/ui/input-group";
6import { Search } from "lucide-react";
7
8export default function BasicExample() {
9  return (
10    <div className="max-w-sm space-y-2">
11      <Label>جستجو</Label>
12      <InputGroup>
13        <InputGroupInput placeholder="جستجو..." />
14        <InputGroupAddon align="inline-end">
15          <Search className="size-4" />
16        </InputGroupAddon>
17      </InputGroup>
18    </div>
19  );
20}
21

موقعیت افزونه (Addon Alignment)

تغییر موقعیت افزونه‌ها در شروع، پایان، بالا یا پایین ورودی.

script.js
0/280
مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5  InputGroupTextarea,
6  InputGroupText,
7  InputGroupButton,
8} from "@/components/ui/input-group";
9import { Search, Mail, Copy } from "lucide-react";
10
11export default function AlignmentExample() {
12  return (
13    <div className="space-y-8">
14      {/* inline-start */}
15      <div className="max-w-sm space-y-2">
16        <Label>ایمیل (inline-start)</Label>
17        <InputGroup>
18          <InputGroupInput placeholder="ایمیل خود را وارد کنید" />
19          <InputGroupAddon align="inline-start">
20            <Mail className="size-4" />
21          </InputGroupAddon>
22        </InputGroup>
23      </div>
24
25      {/* inline-end */}
26      <div className="max-w-sm space-y-2">
27        <Label>جستجو (inline-end)</Label>
28        <InputGroup>
29          <InputGroupInput placeholder="جستجو..." />
30          <InputGroupAddon align="inline-end">
31            <Search className="size-4" />
32          </InputGroupAddon>
33        </InputGroup>
34      </div>
35
36      {/* block-start */}
37      <div className="max-w-sm space-y-2">
38        <Label>ناحیه متن (block-start)</Label>
39        <InputGroup className="flex-col">
40          <InputGroupTextarea
41            placeholder="پیام خود را بنویسید..."
42            rows={3}
43          />
44          <InputGroupAddon align="block-start">
45            <InputGroupText>script.js</InputGroupText>
46            <InputGroupButton>
47              <Copy className="size-3.5" />
48              کپی
49            </InputGroupButton>
50          </InputGroupAddon>
51        </InputGroup>
52      </div>
53
54      {/* block-end */}
55      <div className="max-w-sm space-y-2">
56        <Label>ناحیه متن (block-end)</Label>
57        <InputGroup className="flex-col">
58          <InputGroupTextarea
59            placeholder="پیام خود را بنویسید..."
60            rows={3}
61          />
62          <InputGroupAddon align="block-end">
63            <InputGroupText>
64              ۰/۲۸۰
65            </InputGroupText>
66            <InputGroupButton>ارسال</InputGroupButton>
67          </InputGroupAddon>
68        </InputGroup>
69      </div>
70    </div>
71  );
72}
73

آیکون (Icon)

افزودن آیکون‌ها به عنوان افزونه.

مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5} from "@/components/ui/input-group";
6import { Search, Mail } from "lucide-react";
7
8export default function IconExample() {
9  return (
10    <div className="max-w-sm space-y-4">
11      <div className="space-y-2">
12        <Label>جستجو</Label>
13        <InputGroup>
14          <InputGroupInput placeholder="جستجو..." />
15          <InputGroupAddon align="inline-start">
16            <Search className="size-4" />
17          </InputGroupAddon>
18        </InputGroup>
19      </div>
20      <div className="space-y-2">
21        <Label>ایمیل</Label>
22        <InputGroup>
23          <InputGroupInput placeholder="user@example.com" />
24          <InputGroupAddon align="inline-end">
25            <Mail className="size-4" />
26          </InputGroupAddon>
27        </InputGroup>
28      </div>
29    </div>
30  );
31}
32

متن (Text)

افزودن متن به عنوان پیشوند یا پسوند.

https://
@company.com
تومان
مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5  InputGroupText,
6} from "@/components/ui/input-group";
7
8export default function TextExample() {
9  return (
10    <div className="max-w-sm space-y-4">
11      <div className="space-y-2">
12        <Label>آدرس وب‌سایت</Label>
13        <InputGroup>
14          <InputGroupInput placeholder="example.com" />
15          <InputGroupAddon align="inline-start">
16            <InputGroupText>https://</InputGroupText>
17          </InputGroupAddon>
18        </InputGroup>
19      </div>
20      <div className="space-y-2">
21        <Label>ایمیل شرکت</Label>
22        <InputGroup>
23          <InputGroupInput placeholder="نام کاربری" />
24          <InputGroupAddon align="inline-end">
25            <InputGroupText>@company.com</InputGroupText>
26          </InputGroupAddon>
27        </InputGroup>
28      </div>
29      <div className="space-y-2">
30        <Label>قیمت</Label>
31        <InputGroup>
32          <InputGroupInput placeholder="0" type="number" />
33          <InputGroupAddon align="inline-start">
34            <InputGroupText>تومان</InputGroupText>
35          </InputGroupAddon>
36        </InputGroup>
37      </div>
38    </div>
39  );
40}
41

دکمه (Button)

افزودن دکمه‌های تعاملی به ورودی.

https://
مشاهده کد
1import { useState } from "react";
2import {
3  InputGroup,
4  InputGroupAddon,
5  InputGroupInput,
6  InputGroupText,
7  InputGroupButton,
8} from "@/components/ui/input-group";
9import { Search, Eye, EyeOff } from "lucide-react";
10
11export default function ButtonExample() {
12  const [showPassword, setShowPassword] = useState(false);
13
14  return (
15    <div className="max-w-sm space-y-4">
16      <div className="space-y-2">
17        <Label>جستجوی وب‌سایت</Label>
18        <InputGroup>
19          <InputGroupInput placeholder="جستجو..." />
20          <InputGroupAddon align="inline-start">
21            <InputGroupText>https://</InputGroupText>
22          </InputGroupAddon>
23          <InputGroupAddon align="inline-end">
24            <InputGroupButton>
25              <Search className="size-3.5" />
26              جستجو
27            </InputGroupButton>
28          </InputGroupAddon>
29        </InputGroup>
30      </div>
31      <div className="space-y-2">
32        <Label>رمز عبور</Label>
33        <InputGroup>
34          <InputGroupInput
35            type={showPassword ? "text" : "password"}
36            placeholder="رمز عبور"
37          />
38          <InputGroupAddon align="inline-end">
39            <InputGroupButton
40              size="icon-xs"
41              aria-label={showPassword ? "مخفی کردن" : "نمایش"}
42              onClick={() => setShowPassword(!showPassword)}
43            >
44              {showPassword ? (
45                <EyeOff className="size-3.5" />
46              ) : (
47                <Eye className="size-3.5" />
48              )}
49            </InputGroupButton>
50          </InputGroupAddon>
51        </InputGroup>
52      </div>
53    </div>
54  );
55}
56

میانبر صفحه‌کلید (Kbd)

نمایش میانبر صفحه‌کلید در ورودی.

⌘K
مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5} from "@/components/ui/input-group";
6import { Kbd } from "@/components/ui/kbd";
7
8export default function KbdExample() {
9  return (
10    <div className="max-w-sm space-y-2">
11      <Label>جستجوی سریع</Label>
12      <InputGroup>
13        <InputGroupInput placeholder="جستجو..." />
14        <InputGroupAddon align="inline-end">
15          <Kbd>⌘K</Kbd>
16        </InputGroupAddon>
17      </InputGroup>
18    </div>
19  );
20}
21

بارگذاری (Loading)

نمایش وضعیت بارگذاری با اسپینر.

ذخیره...
مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5  InputGroupText,
6} from "@/components/ui/input-group";
7import { Loader2 } from "lucide-react";
8
9export default function LoadingExample() {
10  return (
11    <div className="max-w-sm space-y-2">
12      <Label>در حال ذخیره</Label>
13      <InputGroup>
14        <InputGroupInput placeholder="در حال ذخیره..." disabled />
15        <InputGroupAddon align="inline-end">
16          <Loader2 className="size-4 animate-spin" />
17          <InputGroupText>ذخیره...</InputGroupText>
18        </InputGroupAddon>
19      </InputGroup>
20    </div>
21  );
22}
23

ناحیه متن (Textarea)

استفاده از گروه ورودی با ناحیه متن.

۰/۲۸۰
مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupTextarea,
5  InputGroupText,
6  InputGroupButton,
7} from "@/components/ui/input-group";
8
9export default function TextareaExample() {
10  return (
11    <div className="max-w-sm space-y-2">
12      <Label>پیام</Label>
13      <InputGroup className="flex-col">
14        <InputGroupTextarea
15          placeholder="پیام خود را بنویسید..."
16          rows={4}
17        />
18        <InputGroupAddon align="block-end">
19          <InputGroupText>۰/۲۸۰</InputGroupText>
20          <InputGroupButton>ارسال</InputGroupButton>
21        </InputGroupAddon>
22      </InputGroup>
23    </div>
24  );
25}
26

نمونه کاربردی (Practical Example)

فرم کامل (Form)

ترکیب چندین گروه ورودی در یک فرم.

@company.com
https://
حداکثر ۵۰۰ کاراکتر
مشاهده کد
1import {
2  InputGroup,
3  InputGroupAddon,
4  InputGroupInput,
5  InputGroupText,
6  InputGroupButton,
7  InputGroupTextarea,
8} from "@/components/ui/input-group";
9import { Button } from "@/components/ui/button";
10import { Globe, Copy } from "lucide-react";
11
12export default function PracticalExample() {
13  return (
14    <form className="max-w-md space-y-4">
15      <div className="space-y-2">
16        <Label>نام کامل</Label>
17        <InputGroup>
18          <InputGroupInput placeholder="نام و نام خانوادگی" />
19          <InputGroupAddon align="inline-start">
20            <Globe className="size-4" />
21          </InputGroupAddon>
22        </InputGroup>
23      </div>
24      <div className="space-y-2">
25        <Label>ایمیل</Label>
26        <InputGroup>
27          <InputGroupInput placeholder="user" />
28          <InputGroupAddon align="inline-end">
29            <InputGroupText>@company.com</InputGroupText>
30          </InputGroupAddon>
31        </InputGroup>
32      </div>
33      <div className="space-y-2">
34        <Label>آدرس وب‌سایت</Label>
35        <InputGroup>
36          <InputGroupInput placeholder="example.com" />
37          <InputGroupAddon align="inline-start">
38            <InputGroupText>https://</InputGroupText>
39          </InputGroupAddon>
40        </InputGroup>
41      </div>
42      <div className="space-y-2">
43        <Label>توضیحات</Label>
44        <InputGroup className="flex-col">
45          <InputGroupTextarea
46            placeholder="توضیحات را بنویسید..."
47            rows={3}
48          />
49          <InputGroupAddon align="block-end">
50            <InputGroupText className="flex-1">
51              حداکثر ۵۰۰ کاراکتر
52            </InputGroupText>
53            <InputGroupButton>
54              <Copy className="size-3.5" />
55              کپی
56            </InputGroupButton>
57          </InputGroupAddon>
58        </InputGroup>
59      </div>
60      <div className="flex justify-end gap-3 pt-2">
61        <Button variant="outline" type="button">
62          لغو
63        </Button>
64        <Button type="submit">ذخیره</Button>
65      </div>
66    </form>
67  );
68}
69

پشتیبانی RTL

کامپوننت گروه ورودی به طور کامل از جهت‌گیری راست‌چین پشتیبانی می‌کند. از ویژگی‌های منطقی CSS برای تعیین موقعیت افزونه‌ها استفاده می‌شود.

  • inline-start و inline-end بر اساس جهت سند تنظیم می‌شوند
  • فاصله‌گذاری از ps- و pe- (ویژگی‌های منطقی) استفاده می‌کند
  • گوشه‌های گرد از rounded-s-md و rounded-e-md استفاده می‌کنند

مرجع API (API Reference)

InputGroup

کامپوننت اصلی که ورودی‌ها و افزونه‌ها را در بر می‌گیرد.

پراپ (Prop)نوع (Type)پیش‌فرض (Default)توضیحات (Description)
classNamestring-کلاس‌های CSS سفارشی

InputGroupAddon

نمایش آیکون‌ها، متن، دکمه‌ها یا محتوای دیگر در کنار ورودی.

پراپ (Prop)نوع (Type)پیش‌فرض (Default)توضیحات (Description)
align"inline-start" | "inline-end" | "block-start" | "block-end""inline-start"موقعیت افزونه نسبت به ورودی
classNamestring-کلاس‌های CSS سفارشی

InputGroupButton

نمایش دکمه‌ها در گروه ورودی.

پراپ (Prop)نوع (Type)پیش‌فرض (Default)توضیحات (Description)
size"xs" | "sm" | "icon-xs" | "icon-sm""xs"اندازه دکمه
variant"default" | "destructive" | "outline" | "ghost" | "link""ghost"نوع ظاهری دکمه
classNamestring-کلاس‌های CSS سفارشی

InputGroupInput

جایگزین Input برای استفاده در گروه ورودی.

پراپ (Prop)نوع (Type)پیش‌فرض (Default)توضیحات (Description)
classNamestring-کلاس‌های CSS سفارشی
...propsInputHTMLAttributes-تمام ویژگی‌های استاندارد HTML input

InputGroupTextarea

جایگزین Textarea برای استفاده در گروه ورودی.

پراپ (Prop)نوع (Type)پیش‌فرض (Default)توضیحات (Description)
classNamestring-کلاس‌های CSS سفارشی
...propsTextareaHTMLAttributes-تمام ویژگی‌های استاندارد HTML textarea