{"id":"l-fig-3-1","courseId":"figma-ui-design","lang":"ar","kind":"lesson","summary":"حوّل صف العادة وزر التعليم المتكرّرين في Steady إلى main components، وضع منهما instances، وطبّق overrides على ما يُسمح بتغييره في كل استخدام، وأبقِ التغييرات تتدفّق من مصدر واحد.","html":"<p>بنهاية القسم 2 صار صف العادة موجودًا في شاشة Today، ومرّتين في Habit detail (“Similar habits”)، ومرة في نتيجة بحث. ثم يتغيّر المطلوب: الصفوف تحتاج نصف قطر زوايا 16 px بدل 12. تجد ثلاث نسخ من الأربع. أما الرابعة فتُطلق بنصف القطر القديم، وينشر مستخدم دقيق الملاحظة لقطة شاشة.</p>\n<p>الـ components موجودة لكي يعيش القرار التصميمي في مكان واحد.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">الـ Main components والـ Instances</h2>\n<p>حدّد frame صف العادة واضغط <code dir=\"ltr\">Cmd+Option+K</code> (<code dir=\"ltr\">Ctrl+Alt+K</code> على Windows)، أو استخدم زر إنشاء الـ component في شريط الأدوات. يصبح الـ frame ‏<strong>main component</strong>، ويظهر بأيقونة component في لوحة الطبقات. إنه مصدر الحقيقة. انقله إلى صفحة <code dir=\"ltr\">Kit</code> التي أنشأتها في الدرس 1.1، فلا تحتوي الشاشات إلا استخداماته.</p>\n<p>كل نسخة تضعها من الآن فصاعدًا هي <strong>instance</strong>: نسخة مرتبطة. اسحب واحدة من لوحة Assets، أو انسخ الـ main component والصقه. غيّر الـ main component فتتحدّث كل الـ instances، فورًا في هذا الملف، وفي الملفات الأخرى بعد أن تنشره كمكتبة (الدرس 3.5).</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 280\" role=\"img\" aria-labelledby=\"l-fig-3-1-t1\"><defs><marker id=\"arrow-l-fig-3-1-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-fig-3-1-t1\">الـ main component ‏Habit row في صفحة Kit يرسل التحديثات إلى ثلاث instances في شاشات مختلفة. كل instance تعرض الـ override الخاص بها: اسم عادة مختلف، وstreak مخفي، وأيقونة مستبدلة.</title>\n  <rect class=\"d-box-primary\" x=\"240\" y=\"20\" width=\"200\" height=\"60\" rx=\"12\"/>\n  <text class=\"d-label-strong\" x=\"340\" y=\"46\" text-anchor=\"middle\">Habit row</text>\n  <text class=\"d-label-muted\" x=\"340\" y=\"68\" text-anchor=\"middle\">main component ‏(Kit)</text>\n  <path class=\"d-arrow\" d=\"M300 80 L120 170\" marker-end=\"url(#arrow-l-fig-3-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M340 80 L340 170\" marker-end=\"url(#arrow-l-fig-3-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M380 80 L560 170\" marker-end=\"url(#arrow-l-fig-3-1-1)\"/>\n  <rect class=\"d-box\" x=\"30\" y=\"172\" width=\"180\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"120\" y=\"196\" text-anchor=\"middle\">Instance: Today</text>\n  <text class=\"d-label-muted\" x=\"120\" y=\"216\" text-anchor=\"middle\">النص: Drink water</text>\n  <rect class=\"d-box\" x=\"250\" y=\"172\" width=\"180\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"340\" y=\"196\" text-anchor=\"middle\">Instance: Detail</text>\n  <text class=\"d-label-muted\" x=\"340\" y=\"216\" text-anchor=\"middle\">الـ streak مخفي</text>\n  <rect class=\"d-box\" x=\"470\" y=\"172\" width=\"180\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"560\" y=\"196\" text-anchor=\"middle\">Instance: Search</text>\n  <text class=\"d-label-muted\" x=\"560\" y=\"216\" text-anchor=\"middle\">أيقونة مستبدلة</text>\n  <text class=\"d-label-muted\" x=\"340\" y=\"262\" text-anchor=\"middle\">نصف قطر الزوايا والـ padding والبنية ما زالت تأتي من الـ main component</text>\n</svg><figcaption>main component واحد يغذّي كل الـ instances؛ والـ overrides تُطبَّق فوقه</figcaption></figure>\n<h2 id=\"sec-2\" tabindex=\"-1\">الـ Overrides: ما يُسمح للـ instance بتغييره</h2>\n<p>الـ instances ليست مجمّدة. يمكنك تطبيق <strong>override</strong> على المحتوى والمظهر في أي instance: تغيير النص (“Read 20 pages” إلى “Drink water”)، أو تغيير تعبئة، أو إخفاء طبقة، أو استبدال instance متداخلة بـ component آخر. هذه تعديلات يومية ولا تكسر الرابط.</p>\n<p>ما لا يمكنك تغييره في الـ instance هو <strong>بنيتها</strong>. لا يمكنك إضافة طبقة، ولا حذف واحدة، ولا إعادة ترتيب الأبناء؛ يمكنك فقط إخفاء ما هو موجود. (الاستثناء الوحيد هو الـ <em>slot</em>، أي منطقة يعلّمها صانع الـ component كمساحة مفتوحة لمحتوى حرّ، وستتعرّف إليها في الدرس التالي.) هذا الحدّ مقصود. البنية مهمّة الـ component، ولو استطاعت كل instance أن تعيد ترتيب نفسها، لما بقي هناك component.</p>\n<p>للـ overrides قاعدة مهمّة واحدة: <strong>الخاصية التي طُبّق عليها override تتوقّف عن اتّباع الـ main component</strong>. إذا غيّرت لون الـ streak في صف واحد إلى الأحمر من أجل نموذج “streak at risk”، ثم تغيّر لاحقًا لون الـ streak في الـ main component، فسيحتفظ ذلك الصف بلونه الأحمر. يحتفظ Figma بالـ override لأنه يفترض أنك قصدته. ولإعادة خاصية إلى الاتّساق، استخدم reset overrides من خيارات الـ instance في الشريط الجانبي الأيمن.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>الـ overrides كطريقة تصميم</span></p>\n<p>تغيير الـ padding والألوان وأحجام الخط instance تلو الأخرى ينتج ملفًا كل صف فيه مختلف قليلًا، وكلٌّ منها توقّف عن تلقّي التحديثات في كل ما لمسته. إذا وجدت نفسك تطبّق الـ override نفسه ثلاث مرات، فالـ component يحتاج خيارًا جديدًا (الدرس التالي)، لا مزيدًا من الـ overrides.</p>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">ابنِ الصغير ثم ضعه داخل الكبير</h2>\n<p>انظر إلى صف العادة واعثر على القطع التي تظهر في أماكن أخرى. زر التعليم يظهر أيضًا في Habit detail. وأيقونة العادة، وهي مربّع بزوايا مستديرة فيه رمز، تظهر في منتقي الأيقونات في لوحة New habit. اصنع هذه الـ components أولًا، ثم استخدم instances منها داخل الـ component ‏Habit row:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"text\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">Text</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code>Kit page\n├─ Check button          main component\n├─ Habit icon            main component\n└─ Habit row             main component\n   ├─ Habit icon         instance\n   ├─ Text stack         frame\n   │  ├─ Habit name      text\n   │  └─ Streak          text\n   └─ Check button       instance</code></pre></div>\n<p>الآن أي إصلاح لزر التعليم، مثل حلقة تركيز أوضح، يصل إلى كل صف عادة في كل شاشة وإلى الزر المستقل في Habit detail. ويبقى كل مستوى صغيرًا بما يكفي لفهمه.</p>\n<p>سمِّ الـ components كما سمّيت الطبقات: حسب الدور. يجمّع Figma الـ components في لوحة Assets حسب الأسماء المفصولة بشرطة مائلة، فيظهر <code dir=\"ltr\">Controls/Check button</code> و<code dir=\"ltr\">Controls/Chip</code> معًا تحت Controls. أبقِ البنية ضحلة؛ مستويان يكفيان عادةً لمجموعة بهذا الحجم.</p>\n<h2 id=\"sec-4\" tabindex=\"-1\">الفصل (Detach): مخرج الطوارئ</h2>\n<p>يمكنك فصل instance ‏(<code dir=\"ltr\">Cmd+Option+B</code> / <code dir=\"ltr\">Ctrl+Alt+B</code>)، فتتحوّل إلى frame عادي بلا رابط. أحيانًا يكون هذا صحيحًا: رسم تسويقي يستعير مظهر صف، أو استكشاف لمرة واحدة في صفحة <code dir=\"ltr\">Scratch</code>. أما في شاشة منتج، فالـ instance المفصولة خطأ مؤجّل. سيفوتها كل إصلاح، ولن يتذكّر أحد وجودها حتى ينشر مستخدم لقطة شاشة.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">نصيحة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>اعثر على المصدر بسرعة</span></p>\n<p>انقر بالزر الأيمن على instance واختر الانتقال إلى الـ main component الخاص بها، فيقفز Figma إلى المصدر حتى لو كان في صفحة أخرى. استخدم ذلك كلما لم تكن متأكّدًا هل تعدّل المصدر أم نسخة.</p>\n</aside>\n<p>صار صفّك component واحدًا بـ instances مرتبطة. لكن Steady يحتاج الصف بعدّة حالات: غير معلَّم، ومعلَّم، وفائت بالأمس. صنع component منفصل لكل حالة سيعيد مشكلة النسخ من جديد. الـ Variants والـ Component properties تحلّ ذلك في الدرس التالي.</p>\n","toc":[{"id":"sec-1","text":"الـ Main components والـ Instances","level":2},{"id":"sec-2","text":"الـ Overrides: ما يُسمح للـ instance بتغييره","level":2},{"id":"sec-3","text":"ابنِ الصغير ثم ضعه داخل الكبير","level":2},{"id":"sec-4","text":"الفصل (Detach): مخرج الطوارئ","level":2}],"takeaways":["الـ main component هو المصدر؛ والـ instances نسخ مرتبطة به تتحدّث حين يتغيّر.","يمكن للـ instances أن تطبّق overrides على المحتوى والمظهر، مثل النص والتعبئة والظهور والـ instances المتداخلة، لكن لا على بنية طبقاتها.","الخاصية التي طُبّق عليها override تتوقّف عن تلقّي التحديثات لتلك الخاصية وحدها، لذا طبّق أقل قدر ممكن من الـ overrides.","ابنِ الـ components الصغيرة أولًا وضعها داخل بعضها، فيصل إصلاح زر التعليم إلى كل صف يحتويه.","فصل الـ instance ‏(detach) يقطعها عن الإصلاحات المستقبلية؛ اعتبره حلًّا أخيرًا، وغالبًا علامة على أن الـ component يحتاج خيارًا جديدًا."],"further":[{"title":"Guide to components in Figma","url":"https://help.figma.com/hc/en-us/articles/360038662654-Guide-to-components-in-Figma"},{"title":"Create components to reuse in designs","url":"https://help.figma.com/hc/en-us/articles/360038663154-Create-components-to-reuse-in-designs"}],"quiz":[{"q":"<p>تغيّر نصف قطر الزوايا في الـ main component ‏Habit row من 12 إلى 16. أيّ الصفوف تتحدّث؟</p>","options":[{"text":"الصفوف التي أُنشئت بعد التغيير فقط.","why":"الـ instances روابط حيّة. الموجودة منها تتحدّث أيضًا، لا الجديدة فقط."},{"text":"كل instance لم يُطبَّق على نصف قطر زواياها override.","why":"صحيح. الـ instances تتبع الـ main component باستثناء الخصائص التي طبّقت عليها override في تلك الـ instance."},{"text":"لا شيء، حتى تضغط زر نشر في الملف نفسه.","why":"داخل الملف الواحد تصل التغييرات إلى الـ instances فورًا. النشر لمشاركتها مع ملفات أخرى عبر مكتبة."},{"text":"كل الصفوف، بما فيها المفصولة.","why":"الصفوف المفصولة frames عادية بلا رابط، فلا تتلقّى تحديثات أبدًا."}],"answer":1},{"q":"<p>يحتاج مصمّم أن يعرض صف عادة واحد سطر نص إضافيًا للـ “note”، ففصل الـ instance وأضاف النص. ما الخطوة الأفضل على المدى البعيد؟</p>","options":[{"text":"فصل كل الصفوف لتتطابق كلها.","why":"هذا يرمي نظام الـ components كله. كل إصلاح مستقبلي سيحتاج إلى تكرار يدوي."},{"text":"إبقاء النسخة المفصولة وإضافة تعليق يشرحها.","why":"التعليق لا يعيد ربطها. ستظل النسخة تنحرف مع تطوّر الـ component."},{"text":"إضافة طبقة ملاحظة اختيارية إلى الـ main component والتحكّم في ظهورها في كل instance.","why":"صحيح. حين يحتاج استخدام واحد شيئًا جديدًا، يحتاج الـ component عادةً خيارًا جديدًا، لا نسخة لمرة واحدة."},{"text":"تكرار الـ main component وتعديل النسخة المكرّرة.","why":"وجود اثنين من الـ main components شبه متطابقين يقسم كل إصلاح مستقبلي إلى اثنين."}],"answer":2},{"q":"<p>لماذا تبني زر التعليم كـ component مستقل وتضعه داخل الـ component ‏Habit row؟</p>","options":[{"text":"لأن Figma لا يسمح للـ component إلا باحتواء components أخرى.","why":"الـ components يمكن أن تحتوي أي طبقات. التداخل خيار لإعادة الاستخدام، لا قاعدة."},{"text":"لأن الـ components المتداخلة أرخص في التصدير.","why":"كلفة التصدير ليست السبب. الفائدة مصدر واحد لزر التعليم."},{"text":"لأن التداخل يخفي زر التعليم عن المطوّرين.","why":"التداخل يجعل البنية أوضح في Dev Mode، لا أخفى."},{"text":"لأن زر التعليم يظهر أيضًا في Habit detail، فيُبقي main component واحد المكانين متّسقين.","why":"صحيح. أصلح حلقة التركيز (focus ring) فيه مرة واحدة، فتتحدّث في كل صف وكل شاشة تستخدمه."}],"answer":3}],"exercise":{"kind":"choice","multiple":true,"options":["edit-text","hide-streak","swap-icon","change-fill","add-layer","reorder"],"correct":["edit-text","hide-streak","swap-icon","change-fill"],"title":"ماذا تستطيع الـ instance أن تفعل دون فصل؟","prompt":"<p>تملأ شاشة Habit detail بـ instances من الـ component ‏<strong>Habit row</strong> (يحتوي على instance من Habit icon، وكومة نصوص فيها Habit name وStreak، وinstance من Check button). لا يحتوي الـ component على slots. اختر <strong>كل</strong> تعديل يمكنك إجراؤه على instance مع إبقائها مرتبطة بالـ main component.</p>\n","hints":["الـ overrides تغيّر المحتوى والمظهر. أما البنية فتخصّ الـ main component.","الإخفاء مسموح؛ والحذف لا. استبدال instance متداخلة مسموح؛ وإضافة طبقة جديدة لا.","أربعة من الستة overrides. والاثنان اللذان يغيّران شجرة الطبقات ليسا كذلك."],"explanation":"<p>النص والظهور والتعبئة واستبدال الـ instances المتداخلة كلها <strong>overrides</strong>: تغيّر ما تعرضه الـ instance لا طريقة بنائها، فتبقى مرتبطة. أما إضافة طبقة أو إعادة ترتيب الأبناء فتغيّر <strong>البنية</strong>، ولا يتحكّم فيها إلا الـ main component (باستثناء الـ slots، وهذا الـ component لا يحتوي عليها). إذا احتاج استخدام واحد فعلًا عنصرًا إضافيًا، فأضفه إلى الـ main component كطبقة اختيارية، ثم أخفِه أو أظهره في كل instance.</p>\n","checkLabels":{},"optionText":{"edit-text":{"text":"غيّر اسم العادة إلى “Walk 8,000 steps”.","why":"صحيح. النص أكثر الـ overrides شيوعًا، ويُبقي الرابط سليمًا."},"hide-streak":{"text":"أخفِ طبقة نص Streak لعادة جديدة تمامًا.","why":"صحيح. الظهور override. الطبقة ما زالت موجودة؛ إنها مخفية فقط في هذه الـ instance."},"swap-icon":{"text":"استبدل الـ instance المتداخلة Habit icon بـ component أيقونة مختلف.","why":"صحيح. استبدال instance متداخلة override، والدرس 3.2 يشرح كيف تنتقي الخيارات المتاحة."},"change-fill":{"text":"غيّر تعبئة خلفية الصف لنموذج يعرض صفًا مميّزًا.","why":"صحيح، هذا مسموح. تذكّر أن هذا الصف لن يتبع بعد الآن تعبئة الـ main component."},"add-layer":{"text":"أضف طبقة نص جديدة “Note” تحت الـ streak.","why":"الـ instances لا يمكنها اكتساب طبقات خارج slot. أضف بدلًا من ذلك طبقة ملاحظة اختيارية إلى الـ main component."},"reorder":{"text":"انقل Check button إلى يسار الأيقونة.","why":"إعادة ترتيب الأبناء تغيّر البنية، وهذا ما لا تستطيعه الـ instances. التخطيط المناسب لليد اليسرى يكون خيارًا في الـ component."}}},"words":651,"readMinutes":4}