تخطي إلى المحتوى
Corex
كل المقالات

لوّن الأجزاء التي تملكها الآلة أصلاً

تصميم Corex طبقة لا تسأل المكوّن شيئاً. تلوّن ما يكشفه السلوك أصلاً، على أجزاء ثابتة لا تتحرك.

هناك لحظة في عمر كل مشروع Phoenix يفتح فيها أحد site.css ويضيف قاعدة. combobox يحتاج بكسل padding إضافي ليطابق تصميماً جديداً. بعد ستة أسابيع يفتح آخر نفس الملف ويضيف قاعدة مختلفة على نفس المحدد لصفحة أخرى. بعد ستة أسابيع أخرى، يفشل تدقيق تباين على شاشة لم يلمسها أحد. القواعد ما زالت هناك. لم تعد تفعل ما قصد أحد.

عشت هذه الحلقة في مشاريع كافية لأتعرف رائحتها. القطعة المشتركة (combobox، زر، حلقة تركيز) تُهاجَم من ملفات كثيرة، على أشهر، من أشخاص كثيرين، وتتحول ببطء إلى تسوية ناشئة لم يصممها أحد. قبل Corex، كان هذا الناتج الافتراضي في كل فريق انضممت إليه.

تصميم Corex هو الجزء من المكتبة الذي يجعل هذه الحلقة اختيارية. ليس الجزء الذي يملك السلوك. السلوك في آلات Zag، مربوطة بـ hooks، يعلّم data-scope وdata-part. تصميم Corex يملك المظهر، وهذا فقط. يلوّن ما تكشفه طبقة السلوك أصلاً.

هذا المنشور عن كيف يعمل هذا الفصل، ولماذا يبقى نظيفاً حتى في تطبيقات كبيرة، والقليل الذي لا يجب أن تفعله داخله.

السلوك والمظهر مشكلتان مختلفتان

الـ hook لا يقرأ site.css. لا يهتم إن كان إدخال combobox يستخدم ثيم neo أو uno. لا يعرف أي radius ضبطت. يكتب data-state="open"، يكتب aria-expanded="true"، ينقل التركيز عند ضغطة مفتاح. هذه وظيفته كلها.

CSS يأتي بعد ذلك، على صفحة تتحرك أصلاً. الحركة الصادقة، في مكتبة تأخذ السلوك بجدية، أن تترك CSS يستهدف الأجزاء التي تحافظ عليها الآلة. المكوّنات تكشف [data-scope="combobox"][data-part="input"]. التصميم يقول: هنا يذهب تنسيق الإدخال. الأسماء ثابتة عبر كل تثبيت Corex وكل صفحة في تطبيقك.

هذا العقد الهادئ تحت نظام التصميم كله. المحدد الذي تكتبه اليوم سيطابق العام القادم، حتى لو نما الـ markup بغلافات، حتى لو غيّر التصميم radius، حتى لو أضافت الآلة حالة جديدة. الأسماء لا تتحرك.

رموز، أدوات، معدّلات، في ثلاث جمل

الرموز تعرّف اللوحة والمقياس مرة. الحبر، الحدود، التباعد، radius، الطباعة، كل شيء قابل للقياس يقرأه بقية النظام.

الأدوات أسماء classes قصيرة تجمع الرموز في أنماط: ui-input كل ما يحتاجه الإدخال. ui-trigger كل ما يحتاجه المحفّز. ui-item كل ما يحتاجه صف القائمة. ui-content السطح الذي تجلس عليه اللوحة العائمة. نادراً ما تكتب هذه classes يدوياً. CSS المكوّن يستخدمها داخل قواعد @apply ويستهدف data-part الصحيح.

المعدّلات كيف تضبط نسخة واحدة دون تفريع النظام كله. تعيش على class الجذر. الزر هو button. زر accent هو button button--accent. زر كبير مستدير هو button button--accent button--lg button--rounded-lg. نظام المعدّلات له أربعة محاور (لون، حجم، radius، نوع)، وتربط مباشرة بمتغيرات CSS تحت الغطاء.

<.accordion
class="accordion accordion--accent accordion--lg accordion--rounded-lg"
id="faq"
items={@topics}
/>

إن شعرت برغبة في اختراع class جديد بجانب تلك المعدّلات، النظام يخبرك بشيء. إما أن معدّلاً موجوداً يغطي الحالة (غالباً يغطي)، أو لديك حالة فريدة حقاً والمكان الصحيح CSS تخطيط الأب، لا داخل Corex.

تغيير واحد في ui-input، حركة واحدة عبر التطبيق

هذه الملاحظة المملة التي تجعل النهج يستحق. نفس أداة ui-input تُركّب في جزء الإدخال من native-input، وcombobox، وpassword-input، وpin-input، وeditable. خمسة مكوّنات، تعريف واحد. عندما يكون تباين placeholder خاطئاً، تغيّر لون placeholder token مرة. كل إدخال في كل صفحة يلتقطه في إعادة التحميل التالية.

المحفّزات نفس القصة. الأزرار، محفّزات select، إغلاق الحوار، أسهم carousel تقرأ ui-trigger. صفوف القوائم في select وmenu وlistbox وcombobox تقرأ ui-item. اللوحات العائمة الكبيرة (محتوى popover، محتوى dialog، محتوى menu) تقرأ ui-content.

هناك لحظة، أول مرة تغيّر token وترى التطبيق كله يتحرك معاً، يتوقف الجاذب الأكاديمي. نظام التصميم يتوقف عن كونه مجلد ملفات ويصبح كائناً واحداً يمكنك ضبطه.

التباين رقم، ليس إحساساً

الأربع ثيمات (neo، uno، duo، leo) تأتي بملفات token فاتحة وداكنة لكل. ثمانية أسطح من مجموعة واحدة من الأدوات والمكوّنات، مع ضمان حقيقي تحتها.

اللوحات تُولَّد عبر Adobe Leonardo API بأهداف تباين صريحة. الحبر الأساسي على خلفية الصفحة يصل 7.0:1. الحبر الخافت على خلفية الصفحة فوق 4.5:1. الحدود، accent، كل لون مسماً في النظام له رقم، لا عين.

هذا ما يجعل تبديل data-theme أو data-mode على <html> ممكناً والتطبيق كله يبقى مقروءاً.

<html lang="en" data-theme="neo" data-mode="light">
 <body class="typo layout">
 {@inner_content}
 </body>
</html>

أنت لا تطلب من اللوحة أن تكون جميلة في وضعين. تطلب أن تجتاز تدقيقاً في وضعين، وخط الأنابيب يقوم بالعمل.

إن فشلت تسمية في تدقيق، الجواب غالباً تبديل ثيم، أو وضع، أو معدّل (button--accent مقابل button--muted)، قبل أي override. الرموز هي المصدر. الـ overrides هي العرض.

site.css رفيع

الإعداد صغير بما يكفي لفقرة. شغّل mix corex.design مرة. الملفات تحت assets/corex/. في app.css، استورد قاعدة Corex، ملفات الثيم التي تريد إظهارها، الطباعة، التخطيط، وملفاً لكل مكوّن ترسمه. وجّه Tailwind للمجلد المنسوخ. ضع data-theme وdata-mode على <html>. ضع class="typo layout" على <body>. هذه القصة كلها.

@import "../corex/main.css";
@import "../corex/theme/neo.css";
@import "../corex/components/typo.css";
@import "../corex/components/layout.css";
@import "../corex/components/accordion.css";
@import "../corex/components/combobox.css";
@import "../corex/components/button.css";

إن كان app.css ما زال يحمّل daisyUI من phx.new الافتراضي، أزله. نظاما token يتقاتلان على نفس أسماء الأدوات هو الطريقة الأكثر موثوقية لجعل الاثنين غير سعداء.

أشياء لا يجب أن تفعلها

قصير لأن القائمة قصيرة.

لا تضف محدداً جديداً في site.css يتجاوز داخل Corex. المحددات في CSS المكوّن تطابق جزءك أصلاً. إضافة موازية تعني تعريفين، سياقين، سببين لسلوك غريب في التغيير التالي.

لا تكرّر أنماط التركيز لكل LiveView. أنماط التركيز في نظام التصميم. تعمل أصلاً. إعادة تنفيذها لكل صفحة كيف تبدأ حلقات التركيز بالاختلاف على شاشات متجاورة.

لا تمرّر class على heroicon داخل مكوّن Corex. المكوّن الأب ينسّق الأيقونات في slots أصلاً. إضافة class تقاتله.

لا تخترع اسم class بجانب معدّل. إما المعدّل موجود (استخدمه)، أو يجب أن يوجد (افتح issue)، أو الصفحة تحتاج class تخطيط خارج المكوّن (اكتبه في CSS خاص بك، ليس على data-part).

ماذا يعيش أين، عندما تنسى

من السهل وضع المشكلة في المكان الخطأ في الشهر الأول. مرجع سريع عندما أنسى.

إن كان radius خاطئاً في كل مكان، فهو token. إن كان radius صحيحاً لكن على بطاقة واحدة، فهو معدّل (--rounded-lg).

إن قفز التركيز لمكان غريب، فهذه الآلة، ليس الطلاء. اقرأ في عقلان.

إن فشلت تسمية في التباين، فهو ثيم أو وضع أو accent دلالي.

إن بدا الـ markup خاطئاً، فهذا التشريح، ليس التصميم.

إن ومضت سمات hover أو open ثم اختفت، patch والآلة يتجادلان. انظر JS.ignore_attributes في منشور عقلان.

الفكرة

التصميم الطبقة الوحيدة التي يمكن أن تتغيّر بينما السلوك ثابت. الإعداد الصحيح يجعل ذلك التغيير رخيصاً. تعديل token ينتشر في كل مكان. تبديل معدّل يضبط نسخة واحدة. تبديل ثيم يعيد تلوين التطبيق كله، بتباين مضمون برقم فُحص قبل أن تفتح الملف.

عندما تكون الرموز صحيحة، تتصرف الأدوات. عندما تتصرف الأدوات، ترث المكوّنات. عندما ترث المكوّنات، تضبط المعدّلات. ولا شيء في site.css يحتاج أن يعرف ما يعنيه [data-scope="combobox"] فعلاً.


بعد وضع الطلاء، بحث combobox المغذّى من الخادم هو النمط الذي يثبت أن لغة التصميم تبقى عندما البيانات أكبر من أن تدخل المتصفح. التشريح ما تؤلفه. عقلان من يملك الحالة في وقت التشغيل. التصميم ما يراه المستخدمون بينما كل ذلك يعمل تحته.