ایده‌هات رو سریع‌تر از همیشه بساز

ترکیبی از سادگی، زیبایی و دقت؛ همه در قالب اجزای آماده که الهام‌بخش
شروع پروژه بعدی تو خواهند بود.

اجزای رابط کاربری
... ... ... ...

به جمع ما بپیوندید ♥️

عنوان پنجره

لطفاً پیش از ادامه، قوانین و خط‌مشی‌های زیر را مرور کنید:

  1. • استفاده مسئولانه از خدمات
  2. • رعایت حقوق سایر کاربران
  3. • پرهیز از محتوای غیرمجاز

با ادامه استفاده، موافقت خود را با این شرایط اعلام می‌کنید.

... ... ... ... ...

مورد اعتماد +60k توسعه‌دهنده

اطلاعات فروشنده تاریخ خرید مبلغ پرداختی
...
جلال بهرامی راد

۱۵ مرداد ۱۴۰۴

2,550,000 تومان موفق
...
نیکی فرهمند

۲۰ تیر ۱۴۰۴

1,700,000 تومان موفق
...
پرهام آذری

۱۴ تیر ۱۴۰۴

2,220,000 تومان نا موفق
...
رادوین فربد

۱۷ خرداد ۱۴۰۴

4,340,000 تومان موفق
...
ساینا مهرگان

۱۹ اردیبهشت ۱۴۰۴

3,740,000 تومان لغو شده
...

الگوهای آماده

دیدن همه

برای ساخت رابط‌های زیبا، تمیز و چشم‌نواز.

نورا

رایگان
برای معرفی، رزومه، نمونه کار و وبلاگ

سیگنال‌های تازه

نکته‌های فنی، ایده‌ها و تجربه‌هایی از دنیای توسعه وب؛ شما هم می‌تونید دیدگاه‌ها و دانسته‌هاتون رو با جامعه SpaceDev به اشتراک بذارید.

ج.بهرامی‌راد 3 روز پیش

گاهی لازم نیست برای تغییر یه چیز، کاربر وارد یه صفحه‌ی جدید بشه.

این ایده توی UX به Edit in Place معروفه؛ یعنی کاربر بتونه یه مقدار رو همون جایی که میبینه، ویرایش کنه.

مثلاً توی یه پنل مدیریت فروشگاه، لیست محصولات رو داریم و موجودی هر محصول هم کنار اون نمایش داده میشه.

به‌جای اینکه برای تغییر موجودی، کاربر وارد صفحه‌ی جزئیات محصول یا.. بشه، میشه با یک کلیک روی موجودی، همون‌جا اون رو به یه فیلد تبدیل کرد تا کاربر مقدار جدید رو وارد کنه.

کاربر برای یه تغییر ساده مجبور نیست صفحه رو ترک کنه، چیزی رو پیدا کنه و دوباره برگرده.

یجورایی لازم نیست برای یه کار ساده، کاربر رو از چند مرحله رد کنیم :)

ج.بهرامی‌راد 1 هفته پیش

توی TypeScript اگه بخوایم از یه Type استفاده کنیم ولی چندتا property اون رو نداشته باشیم، می‌تونیم از Omit استفاده کنیم.

مثلاً:

type User = {
  id: number
  name: string
  email: string
}

type CreateUser = Omit<User, 'id'>

اینجا CreateUser همه‌ی propertyهای User رو داره، به جز id.

یعنی به جای اینکه دوباره Type مربوط به ساخت User رو بنویسیم، از همون Type قبلی استفاده می‌کنیم و فقط چیزی که لازم نداریم رو حذف می‌کنیم.

اگه بیشتر از یه property رو هم نخواستیم، اسم propertyها رو با | از هم جدا می‌کنیم:

type CreateUser = Omit<User, 'id' | 'email'>

اینجا CreateUser فقط name رو داره.

برای Typeهایی که خیلی شبیه هم هستن، این می‌تونه جلوی کلی تکرار رو بگیره.

ج.بهرامی‌راد 2 هفته پیش

یه اصطلاح توی برنامه‌نویسی هست با عنوان Technical Debt یا بدهی فنی.

وقتی برای اینکه سریع‌تر به نتیجه برسیم، یه راه‌حل موقتی یا نه‌چندان اصولی انتخاب می‌کنیم و می‌ذاریم تمیز کردن یا بهتر کردنش رو برای بعد، در واقع داریم Technical Debt ایجاد می‌کنیم.

مثلاً یه بخشی از کد رو می‌دونیم میشه بهتر نوشت، ولی چون الان عجله داریم یا کارهایی با اولویت بالاتری وجود داره، همونطوری که هست نگهش می‌داریم و میگیم بعداً برمی‌گردیم سراغش.

این کار همیشه هم اشتباه نیست؛ گاهی یه تصمیم آگاهانه‌ست برای اینکه سریع‌تر جلو بریم. چیزی که مشکل‌ساز میشه اینه که این بدهی‌ها زیاد بشن و هیچ‌وقت براشون وقت نذاریم.

اون موقع همون کدی که قرار بود بعداً درستش کنیم می‌تونه تبدیل بشه به چیزی که توسعه و تغییر دادن پروژه رو سخت‌تر می‌کنه.

گاهی سریع‌تر جلو رفتن ارزش ایجاد کردن بدهی فنی رو داره؛ به شرطی که بعداً فراموشش نکنیم :)

ج.بهرامی‌راد 3 هفته پیش

وقتی تو ایران زندگی می‌کنی، Ctrl+C بخشی از فرایند ارسال پرامپته :)

ج.بهرامی‌راد 4 هفته پیش

برای پیاده‌سازی قابلیت چندزبانه توی Laravel می‌تونیم از پکیج laravel-translatable از Spatie استفاده کنیم.

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

اول پکیج رو نصب می‌کنیم:

composer require spatie/laravel-translatable

مثلاً فرض کنیم مدل Product داریم و می‌خوایم name و description چندزبانه باشن. توی migration، این فیلدها رو به‌صورت json تعریف می‌کنیم:

$table->json('name');
$table->json('description');

بعد توی مدل مشخص می‌کنیم که این فیلدها قابل ترجمه هستن:

use Spatie\Translatable\HasTranslations;

class Product extends Model
{
    use HasTranslations;

    public array $translatable = [
        'name',
        'description',
    ];
}

حالا مقدار name می‌تونه چیزی شبیه این باشه:

{
    "fa": "محصول جدید",
    "en": "New product"
}

و می‌تونیم ترجمه‌ها رو با خود مدل مدیریت کنیم:

$product->setTranslation('name', 'fa', 'محصول جدید');
$product->setTranslation('name', 'en', 'New product');

$product->save();

اینجوری اضافه شدن زبان جدید هم به تغییر ساختار جدول نیاز نداره؛ فقط ترجمه‌ی زبان جدید به همون JSON اضافه می‌شه.

ایده‌ی اصلی پکیج هم دقیقاً همینه: چندزبانه بودن رو داخل خود فیلد مدیریت کنیم، نه با اضافه کردن ستون برای هر زبان.

🔗 مشاهده در GitHub

ج.بهرامی‌راد 4 هفته پیش

از وقتی دسترسی تولید محتوا توی Signal رو برای همه باز کردم، باز هم فقط خودم دارم می‌نویسم 😐

بعضی وقت‌ها فکر می‌کنم دارم با خودم حرف می‌زنم 😂

شما هم هرچی دوست دارید بنویسید، راحت باشید 🌹😬

ج.بهرامی‌راد 4 هفته پیش

تقریبا تمام صفحات SpaceDev رو با Livewire ساختم و تا الان واقعاً از انتخابم راضی بودم. با اینکه SpaceDev نسبت به چیزی که اول بود بزرگ‌تر شده، هنوز موردی ندیدم که باعث بشه فکر کنم انتخاب اشتباهی کردم یا باید سراغ گزینه دیگه‌ای می‌رفتم.

توی نسخه‌های قدیمی‌تر Livewire برای داشتن navigation بدون reload میشد Turbolinks رو کنارش استفاده کرد. اون موقع همین ترکیب تجربه نسبتاً خوبی می‌داد.

اما الان با "wire:navigate" این کار خیلی راحت‌تر شده و برای جابه‌جایی بین صفحات، دیگه لازم نیست راه‌حل جداگانه‌ای کنارش داشته باشیم..

شاید یه روزی برسه که Livewire دیگه برای نیازهای SpaceDev کافی نباشه و مجبور بشم مسیر دیگه‌ای رو انتخاب کنم؛ ولی فعلاً که راضی‌ام :)

ج.بهرامی‌راد 4 هفته پیش

یکی از نکته‌هایی که توی طراحی مینیمال باید بهش توجه کنیم، اینه که مینیمال بودن به معنی خالی کردن صفحه از المان‌ها نیست.

فضای خالی، رنگ‌های محدود و حذف چیزهای اضافی می‌تونن ظاهر یک UI رو ساده‌تر کنن، اما قرار نیست فقط برای مینیمال‌تر شدن، هر چیزی رو از صفحه حذف کنیم.

گاهی یک دکمه، یک خط جداکننده یا حتی یک متن کوتاه، همون چیزیه که باعث میشه کاربر راحت‌تر صفحه رو بفهمه.

مینیمال یعنی ساده‌تر کردن UI، نه خالی‌تر کردنش.

minimal ≠ empty

ج.بهرامی‌راد 1 ماه پیش

توی لاراول، متد undot() برای تبدیل کلیدهای دارای . به یک ساختار تو‌در‌تو در Collection استفاده می‌شه.

فرض کنید تنظیمات یک کاربر رو به این شکل داریم:

$settings = collect([
    'notifications.email' => true,
    'notifications.sms' => false,
    'appearance.theme' => 'dark',
]);

اگه بخوایم این داده‌ها به یک آرایه‌ی تو‌در‌تو تبدیل بشن:

$settings = $settings->undot();

نتیجه:

[
    'notifications' => [
        'email' => true,
        'sms' => false,
    ],
    'appearance' => [
        'theme' => 'dark',
    ],
]

با undot() می‌تونیم کلیدهای دارای . رو به ساختار تو‌در‌تو تبدیل کنیم، بدون اینکه خودمون این ساختار رو بسازیم.

ج.بهرامی‌راد 1 ماه پیش

CANVAS

هر چیزی که تصور می‌کنی، می‌توانی بسازی

الهام بگیر، کد را بررسی کن و ایده‌های خودت را بساز؛ از مینی‌اپ‌ها و صفحات فرود گرفته تا رابط‌های کاربری و پیاده‌سازی چالش‌های واقعی.

spacedev.ir/canvas

کیت‌های رابط کاربری

دیدن همه

مجموعه‌ای از رابط های کاربری آماده برای شروع سریع طراحی و استفاده مستقیم در پروژه‌ها.

دانیا

برای طراحی وب‌سایت‌های آموزشی

رابط کاربری برنامه

چیدمان فرم‌ها، جدول‌ها، مودال‌ها — هرچیزی که برای ساخت اپلیکیشن‌های وب زیبا و ریسپانسیو نیاز دارید.

اجزای پایه

...

دکمه

3 کامپوننت

...

تصویر نمایه

3 کامپوننت

...

فهرست کشویی

1 کامپوننت

...

نشانک

2 کامپوننت

...

پنجره‌های محاوره‌ای

1 کامپوننت

چیدمان‌های داده‌ای

...

جدول

1 کامپوننت

...

نمای شبکه‌ای

1 کامپوننت

...

جریان فعالیتها

-

فرم ها

...

فیلدهای ورودی

2 کامپوننت

...

فیلد انتخاب

-

...

انتخاب چندگانه

1 کامپوننت

...

گزینه‌های انتخابی

1 کامپوننت

...

فیلد چندخطی

2 کامپوننت

...

روشن/خاموش

1 کامپوننت

...

فرم ورود

1 کامپوننت

ساختار صفحات

...

چیدمان‌ با نوار کناری

1 کامپوننت

...

چینش عمودی

-

الگوهای صفحه

...

چت

1 کامپوننت

...

صفحه فرود

1 کامپوننت

بازاریابی

بخش‌های شاخص، معرفی ویژگی‌ها و فرم‌های عضویت در خبرنامه و همه‌چیزی که برای ساخت وب‌سایت‌های بازاریابی زیبا نیاز داری.

اجزای صفحه

...

دعوت به اقدام

2 کامپوننت

تازه‌ترین نوشته‌ها

دیدن همه

تجربه‌ها، دیدگاه‌ها و نکات الهام‌بخشی که با شما به اشتراک می‌گذاریم.