الگوهای کاربری
کامپوننتها «چه شکلی» را پاسخ میدهند؛ الگوها «چطور کار میکند» را. هر الگو یک مسئله تکرارشونده واقعی محصول را با ترکیبی از کامپوننتها حل میکند — و در اپ مرجع همین الان در حال اجراست.
۱کلاسهای پنجره — ناوبری واکنشگرا
یک DOM، سه چیدمان ناوبری بر اساس عرض نمایشگر (کلاسهای پنجره MD3). هیچ نسخه جداگانهای برای موبایل وجود ندارد؛ فقط CSS عوض میکند.
| کلاس | عرض | ناوبری | نمای اولیه | ایجاد |
|---|---|---|---|---|
| compact | <۶۰۰ | نوار پایین ۵تایی + FAB + کشوی بیرون از صفحه | برنامه (فشرده) | فقط FAB و کلید N |
| medium | ۶۰۰–۸۳۹ | ریل آیکونی ۸۰px + FAB + کشو از دکمه منو | برنامه | FAB + ریل |
| expanded+ | ≥۸۴۰ | سایدبار دائمی ۲۶۴px (سمت راست) + دکمه ایجاد در سایدبار | ماه | دکمه سایدبار + کلید N |
بایدر
- نمای فعال و تاریخ جاری در localStorage ذخیره و بعد از بارگذاری بازیابی میشود.
- عمق لایه ناوبری: نوار پایین/ریل → کشو/سایدبار → دیالوگ — هر عمق فقط یکبار.
نبایدر
- همزمان نوار پایین و ریل؛ یا سایدبار باز و کشو روی هم.
- مخفیکردن اکشن ایجاد در هیچ کلاسی — فقط جایش عوض میشود.
۲پیشنمایش سپس ویرایش
کلیک روی هر رویداد، وظیفه یا تقویم، دیالوگ را در حالت نمایش باز میکند: همه دادهها فقطخواندنی، سریعالاسکن، بدون خطر تغییر تصادفی. کاربر با دکمه «ویرایش» به فرم میرسد. مسیر «ایجاد» مستقیم به فرم میرود — پیشنمایش برای موجودهاست.
| گام | محتوا | اکشنها |
|---|---|---|
| ۱ · کلیک | روی چیپ رویداد، ردیف وظیفه، نتیجه جستجو یا کارت تقویم | — |
| ۲ · نمایش | عنوان + تاریخ کامل جلالی (تعطیلی/جمعه قرمز) + ساعت یا «تمامروز» + تقویم با نقطه رنگ + نوع + مکان + مهمانها + یادداشت | حذف (مخرب) · ویرایش (اصلی و تنها) |
| ۳ · ویرایش | همان دیالوگ با فرم پیشپر؛ فوکوس روی عنوان | ذخیره · انصراف · حذف |
جابهجایی حالت با یک اتریبیوت روی دیالوگ — بدون بستن/بازکردن مجدد:
<div class="dialog" data-mode="view|edit"> <!-- view: سطرهای فقطخواندنی + دکمه ویرایش --> <!-- edit: فرم پیشپر + ذخیره/انصراف --> </div>
بایدر
- در حالت نمایش فقط یک دکمه اصلی («ویرایش»)؛ حذف در سمت مقابل.
- موتورهای یکسان: Enter = ویرایش، Esc = بستن، تغییر حالت بدون پرش چیدمان.
نبایدر
- باز شدن مستقیم فرم ویرایش روی کلیک ساده — تغییر تصادفی محتمل است.
- دو مرحله اضافی: نمایش → «ادامه» → فرم خالی. پیشنمایش باید کامل باشد.
۳دیالوگها، برگهها و منوها
سلسلهمراتب لایههای شناور و قواعد مشترک باز/بستهشدن.
| لایه | ابزار | چه زمانی |
|---|---|---|
| ۱ · منو | .menu | اکشنهای فرعی یک لنگر — بدون محتوای فرمی |
| ۲ · پاپآور انتخاب تاریخ | .dpop | زیر قرص تاریخ؛ Esc اول این را میبندد، بعد دیالوگ را |
| ۳ · دیالوگ/برگه | .dialog | ایجاد/نمایش/ویرایش رویداد و وظیفه، تعارضها، رزرو |
| ۴ · توست | .toast | نتیجه عمل — بدون قطعکردن جریان |
قواعد مشترک
- — اسکریم ۴۵٪ + بلور ۳px؛ کلیک روی اسکریم = بستن (بهجز وقتی فرم کثیف است: اول تأیید).
- — قفل اسکرول بدنه و محبوسکردن فوکوس در دیالوگ؛ فوکوس به عنصر محرک برمیگردد.
- — حذفِ قابلبازگردانی بهجای دیالوگ تأیید، توستِ «بازگردانی» میدهد — یک گام کمتر.
- — همزمان فقط یک لایه از هر عمق؛ باز شدن لایه جدید، قبلی را میبندد.
۴انتخاب تاریخ جلالی
پاپآور ۲۷۲px که از قرص تاریخ باز میشود — همان شبکه ماه، با رفتار کامل تقویمی.
| قاعده | جزئیات |
|---|---|
| لنگر و هاله | باز شدن پاپآور، قرصِ تاریخ را با .open روشن نگه میدارد — کاربر میداند چه چیزی دارد ویرایش میشود |
| ناوبری ماه | شورونهای RTL: «قبلی» سمت راست؛ کلیک روی عنوان = انتخاب ماه/سال سطح بالا |
| پاورقی | «امروز» همیشه؛ «پاک کردن» فقط برای تاریخهای اختیاری (موعد وظیفه) |
| کیبورد | فلشها روز به روز جابهجا میکنند؛ ماه از سرِ هفته که رد شود، ماه عوض میشود؛ Esc فقط پاپآور را میبندد |
| اعتبار | روشن/تعطیل فقط رنگ است، نه غیرفعال — هر روزی قابل انتخاب است |
۵فرمها
ترتیب استاندارد فیلدها و قواعد اعتبارسنجی — از دیالوگ رویداد تا ورود.
| قاعده | جزئیات |
|---|---|
| ترتیب فیلدها | از مهم به جزئی: عنوان ← تقویم ← نوع ← شروع/پایان ← تمامروز ← مکان ← مهمانها ← یادداشت |
| ستون واحد | فرمها همیشه تکستونه؛ فقط شروع/پایان دو قرص همعرض در یک سطر گرید ۲تایی |
| اعتبارسنجی | زنده اما بیسروصدا: خطا بعد از تعامل کاربر ظاهر میشود، نه حین تایپ اول |
| پیام خطا | علت + راهحل: «پایان نمیتواند قبل از شروع باشد» — نه «مقدار نامعتبر» |
| CTA | غیرفعال تا اعتبار کامل؛ بعد از ارسال، متن با اسپینر عوض میشود و دکمه قفل میماند |
| ارقام | ورودی عددی (تلفن، OTP) با direction:ltr + تبدیل ارقام فارسی به لاتین هنگام خواندن (J.en) |
| Enter | در فرم تکفیلدی (تلفن، جستجو) = ارسال؛ در فرم کامل = هیچ (جلوگیری از ثبت تصادفی) |
۶استیتهای داده
هر سطح داده سه استیت دارد و همه باید طراحی شوند — بارگذاری، خالی، خطا.
| استیت | نمایش | قاعده |
|---|---|---|
| بارگذاری | اسپینر وسط ناحیه؛ شبکههای بزرگ اسکلتونگونه با سلولهای سطح ۱ | کمتر از ۳۰۰ms هیچچیز نشان نده — پرش استیت نریزان |
| خالی | پیام کوتاه + اکشن ایجاد (در جای مجاز): «فعلاً کاری نیست» / «رویدادی در این روز نیست» | هر تب و نما رشته خالی مخصوص خودش را دارد؛ هیچ «—» یا باکس خالی |
| خطا | پیام + «تلاش دوباره»؛ لیستهای مهم تاریخ آخرین موفقیت را نگه میدارند | خطای شبکه دیتای قبلی را پاک نمیکند |
| همهپنهان | وقتی همه تقویمها از دید خارجاند: راهنمای برگرداندن بهجای گرید خالی | محتوا باید خودش علت خالیبودنش را بگوید |
۷همگامسازی و تعارض
همگامسازی پسزمینهای است و وقتی خوب کار میکند دیده نمیشود.
- — پیشفرض ساکت: موفقیت همگامسازی نه بنر دارد نه توست. آخرین زمان همگامسازی فقط در جایگاه کمرنگ تنظیمات.
- — تعارض = تنها استیت پرهیاهو: بنر کهربایی زیر نوار بالا → دیالوگ فهرست تعارضها با عنوان، فیلد تغییرکرده و دو تصمیم: «نگهداشتن نسخه این دستگاه» / «بازگردانی نسخه سرور».
- — تصمیم هر آیتم مستقل است؛ بعد از تصمیم آخرین آیتم، بنر بهتنهایی جمع میشود.
- — حالت آفلاین: کار بدون وقفه ادامه دارد؛ تعارضها هنگام بازگشت اتصال حل میشوند.
۸جستجو
جعبه جستجوی نوار بالا: از حالت فشرده با فوکوس باز میشود و نتایج زنده زیر خودش میآورد.
| رفتار | جزئیات |
|---|---|
| محدوده | عنوان، مکان، مهمان و یادداشت رویدادها و وظایف — از امروز به بعد و عقب |
| نتیجه | سطر با عنوان + نقطه رنگ تقویم + تاریخ کامل جلالی (تعطیلی قرمز)؛ کلیک = پرش به آن روز در نمای ماه و باز شدن پیشنمایش |
| بدون نتیجه | «چیزی برای «…» پیدا نشد» + پیشنهاد کوتاهتر کردن عبارت |
| کیبورد | / فوکوس روی جستجو · فلش بالا/پایین در نتایج · Enter انتخاب · Esc بستن |
۹حالت تاریک
حالت تاریک تعویض توکن است، نه طرح دوم: data-theme="dark" روی ریشه و همهچیز خودش درست میشود.
| قاعده | جزئیات |
|---|---|
| برند | آبی پر کنتراست پایین میآید (#8FB4FF) و متن دکمه تیره میشود — وارونگی کامل fg/bg در همان قاعده |
| تعطیلات | قرمز #D41317 در تاریک به #FF8A80 روشن میشود تا روی سطح تیره بخواند |
| رویدادها | پالت ۸رنگی با color-mix روی سطح تیره روشن میشود؛ پسزمینه چیپها همان ۱۳٪ رنگ میماند |
| سایهها | در تاریک عمیقتر و اسکریم تا ۵۸٪ — عمق باید حفظ شود |
| ماندگاری | انتخاب کاربر در tvm-theme ذخیره و بین همه صفحههای وب مشترک است |
۱۰دسترسپذیری و نوشتار رابط
نقشه کیبورد
| کلید | عمل |
|---|---|
| → / ← | ماه بعد/قبل (در RTL جهتها طبیعی تقویماند) |
| ↑ / ↓ | هفته بعد/قبل در نمای ماه |
| T | پرش به امروز |
| N | ایجاد رویداد/وظیفه (بر اساس نمای فعال) |
| / | فوکوس روی جستجو |
| Esc | بستن به ترتیب عمق: تاریخیاب ← منو ← دیالوگ |
حداقلهای غیرقابل مذاکره
- — کنتراست متن ≥ ۴٫۵:۱ در هر دو پوسته؛ هاور هرگز متن را کمکنتراستتر نمیکند.
- — :focus-visible حلقه ۲px برند روی هر عنصر قابل فوکوس — بدون حذف outline.
- — هدف لمسی ≥ ۴۴px؛ دکمههای آیکونی همیشه aria-label فارسی دارند.
- — prefers-reduced-motion همه انیمیشنها را خاموش میکند؛ پیام با حرکت جابهجا نمیشود.
- — نقشهای ARIA وضعتدار: role="checkbox/switch/dialog" + aria-checked.
نوشتار رابط
| اصل | درست | غلط |
|---|---|---|
| روشن و بدون اغراق | همگامسازی با خطا مواجه شد | اوه! یک اتفاق غیرمنتظره افتاد!! |
| اصطلاح واحد محصول | تقویم · رویداد · وظیفه · موعد | تققیم · قرار ملاقات (برای رویداد) · ددلاین |
| ارقام فارسی همهجا | ۷ شهریور · ۰۹:۳۰ | 7 شهریور · 09:30 |
| فعل دومشخص مستقیم | رویداد حذف شد — بازگردانی | عملیات حذف با موفقیت انجام گرفت |