دیالوگ ویرایش برچسب (LabelEditDialog)
دیالوگ کنترلشده برای ویرایش برچسبهای خوشهبندی هوشمند — با فیلد متنی، تاگل «تولیدشده توسط AI»، پیشنهادهای انتخاب سریع و اکشن حذف اختیاری.
معرفی
LabelEditDialog دیالوگ آمادهی ویرایش یک برچسب در جریانهای خوشهبندی هوشمند است و مکمل LabelChip طراحی شده: وقتی کاربر روی آیکن مداد یک چیپ کلیک میکند، این دیالوگ با مقدار فعلی باز میشود و امکان تغییر متن برچسب، تغییر پرچم «تولیدشده توسط AI» و انتخاب سریع از برچسبهای موجود را فراهم میکند. کامپوننت نسبت به ذخیرهسازی بیطرف است — نتیجه از طریق onSave به مصرفکننده تحویل داده میشود.
چه زمانی استفاده کنیم:
- ویرایش سریع نام یک برچسب خوشهبندی (مثلاً برچسبهای تولیدشده توسط AI در داشبورد تحلیل گفتوگوهای کمپین)
- تأیید یا لغو وضعیت «تولیدشده توسط AI» یک برچسب پس از بازبینی انسانی
- یکدستسازی برچسبها با انتخاب از پیشنهادهای موجود بهجای تایپ آزاد
چه زمانی استفاده نکنیم:
- ویرایش فرمهای چندفیلدی یا رکوردهای کامل — از
Dialogبا فرم سفارشی استفاده کنید - گرفتن تأیید برای یک عمل مخرب بهتنهایی — از
ConfirmDialogیاAlertDialogاستفاده کنید - افزودن یا انتخاب تگ بهصورت inline داخل فرمها — از فیلدهای انتخاب چندگزینهای استفاده کنید
استفاده
import { LabelEditDialog } from '@partodata/ui'const [open, setOpen] = React.useState(false)
const [label, setLabel] = React.useState('بازخورد بستهبندی')
const [aiGenerated, setAiGenerated] = React.useState(true)
<LabelEditDialog
open={open}
onOpenChange={setOpen}
initialValue={label}
aiGenerated={aiGenerated}
suggestions={['کمپین تخفیف فصلی', 'رونمایی محصول جدید']}
onSave={(value, ai) => {
setLabel(value)
setAiGenerated(ai)
}}
/>دیالوگ کاملاً کنترلشده است: وضعیت باز/بسته را با open و onOpenChange از بیرون مدیریت میکنید. هر بار که دیالوگ باز میشود، فرم داخلی با initialValue و aiGenerated همگام میشود؛ بنابراین همیشه مقدار فعلی رکورد را پاس بدهید.
حالتها و انواع
ترکیب با LabelChip
الگوی متداول: آیکن مداد چیپ (onEdit) دیالوگ را باز میکند و onSave نتیجه را به state یا backend مینویسد.
import { LabelChip, LabelEditDialog } from '@partodata/ui'
const [open, setOpen] = React.useState(false)
const [label, setLabel] = React.useState('گفتمان درباره برند')
const [ai, setAi] = React.useState(true)
<>
<LabelChip aiGenerated={ai} onEdit={() => setOpen(true)}>
{label}
</LabelChip>
<LabelEditDialog
open={open}
onOpenChange={setOpen}
initialValue={label}
aiGenerated={ai}
onSave={(value, aiFlag) => {
setLabel(value)
setAi(aiFlag)
}}
/>
</>با اکشن حذف
اگر onDelete را پاس بدهید، یک دکمه destructive با متن «حذف» در فوتر ظاهر میشود (در سمت آغازین فوتر، جدا از انصراف/ذخیره). با کلیک روی آن، ابتدا onDelete فراخوانی و سپس دیالوگ بسته میشود. اگر این prop را ندهید، دکمه حذف اصلاً رندر نمیشود.
<LabelEditDialog
open={open}
onOpenChange={setOpen}
initialValue="بازخورد بستهبندی"
onSave={handleSave}
onDelete={() => removeLabel(labelId)}
/>پیشنهادهای انتخاب سریع
آرایه suggestions (معمولاً سایر برچسبهای موجود در همان خوشه یا بورد) بهصورت ردیفی از LabelChipهای قابلکلیک زیر فرم نمایش داده میشود. با انتخاب هر پیشنهاد، متن آن جایگزین مقدار فیلد میشود و تاگل «تولیدشده توسط AI» خاموش میشود — چون انتخاب دستی به معنای بازبینی انسانی است.
<LabelEditDialog
open={open}
onOpenChange={setOpen}
initialValue="نظر مثبت مشتری"
suggestions={['کمپین تخفیف فصلی', 'رونمایی محصول جدید', 'همکاری برند با اینفلوئنسر']}
onSave={handleSave}
/>اعتبارسنجی داخلی دکمه ذخیره
دکمه «ذخیره» فقط زمانی فعال است که هر دو شرط برقرار باشد:
- مقدار فیلد پس از trim خالی نباشد
- مقدار یا پرچم AI نسبت به حالت اولیه تغییر کرده باشد (dirty)
مقدار ارسالی به onSave همیشه trim شده است. اعتبارسنجیهای دیگر (یکتا بودن نام، محدودیت طول، قواعد سمت سرور) بر عهده مصرفکننده است.
زبان رشتههای داخلی (locale)
عنوان، توضیح، برچسب فیلد، placeholder و متن دکمهها برای سه زبان از پیش آماده است. پیشفرض fa است.
<LabelEditDialog open={open} onOpenChange={setOpen} initialValue="Seasonal campaign" locale="en" onSave={handleSave} />راهنمای استفاده
بکنید
- همیشه مقدار فعلی رکورد را در
initialValueوaiGeneratedپاس بدهید — فرم داخلی در هر بار باز شدن با همین مقادیر همگام میشود. - دیالوگ را با آیکن مدادLabelChip(proponEdit) جفت کنید تا الگوی ویرایش برچسب در کل محصول یکدست بماند. - برچسبهای موجود در همان خوشه یا بورد را بهعنوانsuggestionsبدهید تا کاربر بهجای ساخت برچسب تکراری، از موارد موجود انتخاب کند. - اگر حذف برچسب برگشتناپذیر است، پیش از اجرای عملیات درonDeleteیک مرحله تأیید (مثلاًConfirmDialog) قرار دهید — خود دیالوگ بلافاصله بسته میشود.
نکنید
- دیالوگ را بدون مدیریت
openوonOpenChangeرندر نکنید — این کامپوننت حالت غیرکنترلشده ندارد. - به اعتبارسنجی داخلی (غیرخالی بودن و dirty بودن) بهعنوان تنها لایه اعتبارسنجی تکیه نکنید — یکتایی نام و قواعد کسبوکار را درonSaveبررسی کنید. - کلیدهای داخلی نوعFlowKeyیا شناسههای فنی را بهعنوان متن برچسب نمایش ندهید — برچسبهای خوانا و خنثی برای کاربر بنویسید. - از این دیالوگ برای ویرایش چند فیلد همزمان استفاده نکنید — دامنه آن عمداً به یک برچسب محدود است.
Props
دسترسیپذیری
- روی
Dialogدیزاینسیستم (مبتنی بر Radix Dialog) ساخته شده است: مودال با focus trap، بستن با Escape و کلیک روی overlay، و بازگشت فوکوس به عنصر آغازگر پس از بسته شدن. - عنوان و توضیح دیالوگ از طریق
DialogTitleوDialogDescriptionبهaria-labelledbyوaria-describedbyمتصل میشوند. - فیلد متنی با
Labelاستاندارد (اتصالhtmlFor/id) برچسبگذاری شده و هنگام باز شدن دیالوگ بهصورت هدفمندautoFocusمیگیرد — الگوی پذیرفتهشده برای دیالوگهایی که در پاسخ به اقدام مستقیم کاربر باز میشوند. - تاگل «تولیدشده توسط AI» یک
Checkboxاستاندارد داخل عنصرlabelاست؛ کلیک روی متن هم آن را تغییر میدهد. - پیشنهادها چیپهای قابلکلیک با
role="button"وtabIndexهستند و با کیبورد قابل انتخاباند. - ذخیره از طریق submit فرم انجام میشود؛ دکمه بستن گوشه دیالوگ نیز متن صرفاً خوانا برای screen reader دارد.
تعامل با کیبورد
Escape: بستن دیالوگ بدون ذخیره -Tab/Shift+Tab: حرکت بین عناصر داخل دیالوگ (فوکوس داخل دیالوگ محبوس است) -Enterدر فیلد متنی: ذخیره (اگر مقدار معتبر و تغییر کرده باشد) -Space: تغییر وضعیت تاگل «تولیدشده توسط AI» -EnterیاSpaceروی یک پیشنهاد: انتخاب آن پیشنهاد
کامپوننتهای مرتبط
- LabelChip — نمایش خود برچسب (با نشانگر AI، درصد اطمینان و آیکن مداد)؛ این دیالوگ مکمل آن است و معمولاً از
onEditهمان چیپ باز میشود. - Dialog — اگر فرم ویرایش سفارشی با چند فیلد یا چیدمان متفاوت نیاز دارید، بهجای این کامپوننت از
Dialogخام استفاده کنید. - ConfirmDialog — اگر حذف برچسب برگشتناپذیر است، پیش از اجرای
onDeleteیک مرحله تأیید با آن اضافه کنید. - AlertDialog — برای هشدارهای بحرانی که کاربر حتماً باید پاسخ دهد و نباید با کلیک بیرون بسته شوند.