Button
دکمه یا عنصری شبیه به دکمه برای آغاز یک عمل؛ با ده حالت بصری، پنج رنگ معنایی، شش اندازه و کنترل جداگانهٔ شعاع گوشه.
کد، دستور نصب و مرجع API این صفحه با فریمورک انتخابی عوض میشود.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
نصب
با CLI اختصاصی dig-ui کامپوننت را از رجیستری دیگ نصب کنید؛ وابستگیها و فایلها خودکار اضافه میشوند.
pnpm dlx dig-ui@latest add https://design-system-tau-green.vercel.app/r/button.jsonnpx dig-ui@latest add https://design-system-tau-green.vercel.app/r/button.jsonyarn dlx dig-ui@latest add https://design-system-tau-green.vercel.app/r/button.jsonbunx --bun dig-ui@latest add https://design-system-tau-green.vercel.app/r/button.jsonVue هنوز CLI اختصاصی دیگ ندارد. فایل رجیستری برای ابزارهای خودتان در دسترس است، ولی برای نصب از تب «دستی» استفاده کنید.
curl -O https://design-system-tau-green.vercel.app/r/vue/button.jsonSvelte هنوز CLI اختصاصی دیگ ندارد. فایل رجیستری برای ابزارهای خودتان در دسترس است، ولی برای نصب از تب «دستی» استفاده کنید.
curl -O https://design-system-tau-green.vercel.app/r/svelte/button.jsonAngular هنوز CLI اختصاصی دیگ ندارد. فایل رجیستری برای ابزارهای خودتان در دسترس است، ولی برای نصب از تب «دستی» استفاده کنید.
curl -O https://design-system-tau-green.vercel.app/r/angular/button.jsonاستفاده
import { Button } from "@/components/ui/button"
<Button variant="outline" size="lg">دکمه</Button><script setup lang="ts">
import Button from "@/components/ui/Button.vue"
</script>
<template>
<Button variant="outline" size="lg">دکمه</Button>
</template><script lang="ts">
import Button from "$lib/components/ui/button.svelte";
</script>
<Button variant="outline" size="lg">دکمه</Button>import { Component } from "@angular/core"
import { DigButton } from "@/components/ui/button"
@Component({
selector: "app-demo",
standalone: true,
imports: [DigButton],
template: `<button digButton variant="outline" size="lg">دکمه</button>`,
})
export class DemoComponent {}ترکیب اجزا
در هر چهار فریمورک، کلاسهای Tailwind و توکنهای رنگ کاملاً یکساناند؛ فقط شیوهٔ اتصال فرق میکند.
- ریاکت و ویو از یک کامپوننت با پراپ
asChild/asاستفاده میکنند. - اسولت با دادن
hrefبهجای button یک anchor میسازد. - انگولار بهجای کامپوننت یک دایرکتیو روی تگ بومی میگذارد تا فرمها و رویدادها دستنخورده بمانند.
رنگ هم با دو متغیر CSS منتقل میشود (--btn و --btn-foreground)، پس محور رنگ و محور حالت مستقل از هم میمانند و افزودن یک رنگ تازه فقط یک سطر است.
تنها تفاوت رفتاری در انگولار است: چون دایرکتیو نباید ویژگی disabled تگ میزبان را بازنویسی کند، loading آنجا بهجای disabled از aria-disabled و متوقفکردن کلیک استفاده میکند.
دسترسپذیری
- از عنصر بومی button استفاده میکند؛ با Enter و Space فعال میشود و حلقهٔ فوکوس مرئی دارد.
- برای دکمههای فقط آیکونی حتماً aria-label بنویسید.
- پراپ loading خودش aria-busy و غیرفعالسازی را انجام میدهد؛ متن دکمه را هم عوض کنید تا صفحهخوان بفهمد چه چیزی در حال انجام است.
- رنگهای success و warning در تم روشن یک پله تیرهاند تا هم زیر متن سفید و هم روی زمینهٔ روشن از AA رد شوند؛ در حالتهای نرم مثل flat کنتراست حدود ۴ است، پس برای متنهای ریز از حالتهای توپر استفاده کنید.
- وقتی دکمه در واقع لینک است (asChild در ریاکت، as-child در ویو، href در اسولت، یا سلکتور a[digButton] در انگولار) نقش واقعی link حفظ میشود؛ رفتار صفحهکلید لینک است نه دکمه.
مرجع API
Button
تمام ویژگیهای استاندارد button نیز پشتیبانی میشود (onClick، type، disabled و…).
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| variant | "default" | "secondary" | "destructive" | "outline" | "bordered" | "ghost" | "flat" | "faded" | "shadow" | "link" | "default" | حالت بصری دکمه. |
| size | "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | "default" | اندازهٔ دکمه؛ سه اندازهٔ icon برای دکمهٔ مربعی فقط آیکونی. |
| color | "default" | "primary" | "success" | "warning" | "destructive" | "default" | رنگ معنایی، مستقل از حالت. default یعنی همان ظاهر خنثای دیگ. |
| radius | "none" | "sm" | "md" | "lg" | "full" | — | شعاع گوشه؛ اگر ندهید شعاع پیشفرض اندازه بهکار میرود. |
| fullWidth | boolean | false | دکمه تمام عرض ظرفش را میگیرد. |
| loading | boolean | false | اسپینر نشان میدهد، دکمه را غیرفعال میکند و aria-busy میگذارد. |
| asChild | boolean | false | بهجای رندر تگ button، استایلها را روی فرزند مستقیم اعمال میکند (مناسب Link). |
Button.vue
روی Primitive از Reka UI سوار است، پس همهٔ ویژگیهای تگ مقصد بهصورت fallthrough منتقل میشوند.
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| variant | "default" | "secondary" | "destructive" | "outline" | "bordered" | "ghost" | "flat" | "faded" | "shadow" | "link" | "default" | حالت بصری دکمه. |
| size | "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | "default" | اندازهٔ دکمه؛ سه اندازهٔ icon برای دکمهٔ مربعی فقط آیکونی. |
| color | "default" | "primary" | "success" | "warning" | "destructive" | "default" | رنگ معنایی، مستقل از حالت. default یعنی همان ظاهر خنثای دیگ. |
| radius | "none" | "sm" | "md" | "lg" | "full" | — | شعاع گوشه؛ اگر ندهید شعاع پیشفرض اندازه بهکار میرود. |
| full-width | boolean | false | دکمه تمام عرض ظرفش را میگیرد (نام پراپ در اسکریپت fullWidth است). |
| loading | boolean | false | اسپینر نشان میدهد، دکمه را غیرفعال میکند و aria-busy میگذارد. |
| as | string | Component | "button" | تگ یا کامپوننتی که رندر میشود؛ مثلاً as="a" برای لینک. |
| as-child | boolean | false | معادل asChild در ریاکت: استایلها روی فرزند اسلات مینشینند (مناسب RouterLink). |
| class | HTMLAttributes['class'] | — | با cn ادغام میشود، پس کلاسهای شما بر واریانت اولویت دارند. |
DigButton
دایرکتیو standalone با سلکتور button[digButton], a[digButton]. چون تگ بومی حفظ میشود، type، form، (click) و رفتار صفحهکلید همان چیزی است که مرورگر میدهد.
| ویژگی | نوع | پیشفرض | توضیح |
|---|---|---|---|
| variant | "default" | "secondary" | "destructive" | "outline" | "bordered" | "ghost" | "flat" | "faded" | "shadow" | "link" | "default" | حالت بصری دکمه (signal input). |
| size | "default" | "sm" | "lg" | "icon" | "icon-sm" | "icon-lg" | "default" | اندازهٔ دکمه؛ سه اندازهٔ icon برای دکمهٔ مربعی فقط آیکونی. |
| color | "default" | "primary" | "success" | "warning" | "destructive" | "default" | رنگ معنایی، مستقل از حالت (signal input). default یعنی همان ظاهر خنثای دیگ. |
| radius | "none" | "sm" | "md" | "lg" | "full" | — | شعاع گوشه؛ اگر ندهید شعاع پیشفرض اندازه بهکار میرود. |
| fullWidth | boolean | false | دکمه تمام عرض ظرفش را میگیرد؛ با booleanAttribute، پس fullWidth تنها هم کافی است. |
| loading | boolean | false | اسپینر نشان میدهد، disabled و aria-busy را روی تگ بومی میگذارد. |
| class | string | "" | کلاسهای شما با cn به کلاسهای واریانت اضافه و در تعارضها برنده میشوند. |
نمونهها
Variants
ده حالت بصری برای سطحهای مختلف اهمیت: default برای عمل اصلی، secondary و outline برای عملهای فرعی، bordered برای حاشیهٔ پررنگ بدون پسزمینه، flat و faded برای سطحهای ملایم، shadow برای دکمهٔ شناور، ghost برای نوار ابزار، destructive برای عملهای مخرب و link برای پیوندهای متنی.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Colors
رنگ محور جداگانهای از حالت است: حالت تصمیم میگیرد رنگ کجا بنشیند (پسزمینه، حاشیه یا متن) و رنگ تصمیم میگیرد کدام توکن معنایی استفاده شود. پیشفرض یعنی «همان ظاهر خنثای دیگ».
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Variant and Color
هر رنگ روی هر حالت مینشیند؛ لازم نیست برای هر ترکیب واریانت جدا بسازید.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Sizes
سه اندازهٔ متنی و سه اندازهٔ مربعی مخصوص آیکون که ارتفاعشان دقیقاً با اندازهٔ متنی همنام خودشان برابر است، تا کنار هم در یک نوار ابزار همتراز بنشینند.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Radius
شعاع گوشه محور مستقلی است و بر شعاع پیشفرضِ اندازه اولویت دارد؛ برای دکمههای قرصشکل radius=full بدهید.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
With Icon
آیکون را کنار متن قرار دهید؛ فاصلهگذاری و اندازهٔ آیکون خودکار تنظیم میشود و در چیدمان راستبهچپ جای درست مینشیند.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Loading
پراپ loading همزمان اسپینر را نشان میدهد، دکمه را غیرفعال میکند و aria-busy میگذارد. اسپینر یک شبهعنصر CSS است، پس در هر چهار فریمورک بدون آیکون اضافه یکسان کار میکند. اگر اسپینر دلخواه میخواهید، بهجای loading همان الگوی قدیمی با آیکون را بهکار ببرید.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
As Link
هر فریمورک راه خودش را دارد، ولی نتیجه یکی است: استایل دکمه روی یک anchor واقعی مینشیند، بدون تودرتویی نامعتبر button داخل a.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Disabled
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
Full Width
برای فرمهای موبایل، بهجای کلاس دستی w-full از پراپ fullWidth استفاده کنید.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Vue دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Svelte دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
پیشنمایش با نسخهٔ ریاکت رندر شده است؛ پورت Angular دقیقاً همین کلاسهای Tailwind را دارد، پس خروجی بصری یکسان است.
کدام نمونه برای کدام موقعیت
| نمونه | کجا به کار میآید |
|---|---|
| Variants | ده حالت بصری برای سطحهای مختلف اهمیت: default برای عمل اصلی، secondary و outline برای عملهای فرعی، bordered برای حاشیهٔ پررنگ بدون پسزمینه، flat و faded برای سطحهای ملایم، shadow برای دکمهٔ شناور، ghost برای نوار ابزار، destructive برای عملهای مخرب و link برای پیوندهای متنی. |
| Colors | رنگ محور جداگانهای از حالت است: حالت تصمیم میگیرد رنگ کجا بنشیند (پسزمینه، حاشیه یا متن) و رنگ تصمیم میگیرد کدام توکن معنایی استفاده شود |
| Variant and Color | هر رنگ روی هر حالت مینشیند؛ لازم نیست برای هر ترکیب واریانت جدا بسازید. |
| Sizes | سه اندازهٔ متنی و سه اندازهٔ مربعی مخصوص آیکون که ارتفاعشان دقیقاً با اندازهٔ متنی همنام خودشان برابر است، تا کنار هم در یک نوار ابزار همتراز بنشینند. |
| Radius | شعاع گوشه محور مستقلی است و بر شعاع پیشفرضِ اندازه اولویت دارد؛ برای دکمههای قرصشکل radius=full بدهید. |
| With Icon | آیکون را کنار متن قرار دهید؛ فاصلهگذاری و اندازهٔ آیکون خودکار تنظیم میشود و در چیدمان راستبهچپ جای درست مینشیند. |
| Loading | پراپ loading همزمان اسپینر را نشان میدهد، دکمه را غیرفعال میکند و aria-busy میگذارد |
| As Link | هر فریمورک راه خودش را دارد، ولی نتیجه یکی است: استایل دکمه روی یک anchor واقعی مینشیند، بدون تودرتویی نامعتبر button داخل a. |
| Disabled | دکمهای که تا برطرفشدن یک شرط (مثل تکمیل فرم) نباید قابل کلیک باشد |
| Full Width | برای فرمهای موبایل، بهجای کلاس دستی w-full از پراپ fullWidth استفاده کنید. |
دستورالعمل استفاده
برچسب دکمه
انجام بده
لیبل باید فعل و نتیجهٔ عمل را مشخص کند تا کاربر بدون فکرکردن بداند با کلیک چه میشود.
انجام نده
لیبل مبهم مثل «کلیک کنید» یا «باشه» به کاربر نمیگوید نتیجهٔ این عمل چیست.
یک عمل اصلی در هر صفحه
انجام بده
فقط یک دکمهٔ پررنگ (default یا shadow) برای مهمترین عمل؛ بقیه با outline یا ghost کنار میروند.
انجام نده
دو دکمهٔ پررنگ کنار هم چشم را دو قسمت میکند و مشخص نیست کدام عمل اولویت دارد.
رنگ مخرب فقط برای عملیات مخرب
انجام بده
رنگ destructive را فقط برای عملی بگذارید که واقعاً غیرقابلبازگشت است، مثل حذف.
انجام نده
استفاده از رنگ مخرب برای یک عمل بیخطر مثل انصراف، کاربر را نگران چیزی میکند که خطری ندارد.