{"id":"l-ds-4-1","courseId":"design-systems","lang":"ar","kind":"lesson","summary":"اعكس طبقات الـ tokens في مجموعات Figma variables وmodes الخاصة بها، وانشرها عبر المكتبات، وشغّل عملية مزامنة واحدة حتى لا تختلف ملفات التصميم والكود أبدًا على قيمة.","html":"<p>طوال ثمانية أشهر بعد إطلاق الـ tokens، كان لدى Northwind حقيقتان. ملف JSON في المستودع يقول إن أزرق الإجراء هو <code dir=\"ltr\">#1f5ae0</code>، ومكتبة Figma تقول <code dir=\"ltr\">#2160e8</code>، لأن مصمّمًا عدّله قليلًا من أجل تصميم لحملة ثم نشره. كان المهندسون يبنون من لوحة الفحص، فأطلق الموقع التسويقي أزرق وأطلق التطبيق أزرق آخر. الـ tokens لا تحلّ مشكلة الاتّساق إلا إذا قرأت ملفات التصميم والكود من القرارات نفسها.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">ربط الطبقات بـ Figma variables</h2>\n<p>متغيّرات Figma (Figma variables) تحمل قيمًا قابلة لإعادة الاستخدام مثل الألوان والأرقام، مجمّعة في <strong>collections</strong>. ويمكن أن يكون للـ collection عدّة <strong>modes</strong>، يعطي كلٌّ منها كل متغيّر في المجموعة قيمة مختلفة. ويمكن أيضًا لمتغيّر أن يكون اسمًا مستعارًا لمتغيّر آخر. وهذا يكفي لعكس معمارية الـ tokens تقريبًا واحدًا لواحد:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"جدول قابل للتمرير\" tabindex=\"0\"><table><thead>\n<tr>\n<th>مفهوم الـ token</th>\n<th>في Figma</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>طبقة الـ primitives</td>\n<td>collection باسم “Primitives” بـ mode واحد</td>\n</tr>\n<tr>\n<td>الطبقة الدلالية</td>\n<td>collection باسم “Semantic” بـ modes هي Light وDark</td>\n</tr>\n<tr>\n<td>الكثافة</td>\n<td>collection باسم “Density” بـ modes هي Comfortable وCompact</td>\n</tr>\n<tr>\n<td>العلامة</td>\n<td>collection ممتدّة لكل علامة (Enterprise)، أو collection باسم Brand فيها mode لكل علامة</td>\n</tr>\n<tr>\n<td>الاسم المستعار <code dir=\"ltr\">{color.blue.600}</code></td>\n<td>متغيّر يشير إلى <code dir=\"ltr\">blue/600</code></td>\n</tr>\n</tbody>\n</table></div><p>أسماء المتغيّرات تستخدم الشرطات المائلة لتشكيل المجموعات، فيظهر <code dir=\"ltr\">color/action/bg</code> كمسار مجموعة في المنتقي، ويقابل الـ token المسمّى <code dir=\"ltr\">color.action.bg</code>. وتختار الإطارات (frames) في Figma الـ modes كما تفعل الـ attribute selectors في CSS: يمكن للإطار أن يحدّد mode صراحة، وكل ما بداخله مضبوط على Auto يرث ذلك الـ mode، فيعمل إطار واجهة رئيسية داكن على صفحة فاتحة تمامًا مثل <code dir=\"ltr\">data-theme=&quot;dark&quot;</code> على قسم.</p>\n<p>وللعلامات، تسمح لك <strong>المجموعات الممتدّة (extended collections)</strong> في Figma، المتاحة على خطة Enterprise، بإنشاء collection لـ Tidewater ترث من المجموعة الدلالية لـ Northwind وتخصّص متغيّرات العلامة وحدها. والتحديثات على المتغيّرات التي لم تخصّصها Tidewater تمرّ تلقائيًا. وعلى الخطط الأخرى، تحقّق لك collection منفصلة باسم Brand بـ mode لكل علامة معظم الطريق.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">اجعل المتغيّر الصحيح هو الأسهل</h2>\n<p>إعدادان أهمّ من أي نظام تسمية. الأول: <strong>أخفِ الـ primitives من النشر</strong>. تستطيع المجموعة الدلالية أن تشير إليها، لكن المصمّمين في ملفات المنتجات لا يرون إلا المتغيّرات الدلالية، وهذه بالضبط القاعدة التي تتبعها المكوّنات في الكود. والثاني: أعطِ كل متغيّر منشور <strong>صيغة كود (code syntax)</strong>: فيعرض Dev Mode حينها <code dir=\"ltr\">var(--nw-color-action-bg)</code> بدل قيمة hex، فيكون ما اختاره المصمّم هو حرفيًا ما يكتبه المهندس. وتحديد النطاق (scoping) يساعد أيضًا: اقصر متغيّرات الألوان على الخصائص المقصودة لها، حتى لا يظهر لون نص في منتقي التعبئة.</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>مصدران للحقيقة</span></p>\n<p>إن قبلت مكتبة Figma وملف JSON كلاهما التعديل المباشر، فسيتباعدان؛ المسألة مسألة وقت فقط. اختر مصدر حقيقة واحدًا للقيم، واجعل الآخر مرآة لا تتغيّر إلا عبر عملية المزامنة. اختارت Northwind ملف JSON في المستودع، لأن الإصدارات والمراجعة وفحوص التباين والإطلاقات كانت تعيش هناك أصلًا. والفرق التي يقودها التصميم تختار أحيانًا Figma مصدرًا؛ وكلا الخيارين ينجح ما دام الجانب الآخر لا يُعدَّل يدويًا أبدًا.</p>\n</aside>\n<h2 id=\"sec-3\" tabindex=\"-1\">حلقة المزامنة</h2>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 230\" role=\"img\" aria-labelledby=\"l-ds-4-1-t1\"><defs><marker id=\"arrow-l-ds-4-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-ds-4-1-t1\">حلقة: مصمّم يقترح تغييرًا في branch على Figma، ويصدّر JSON إلى pull request، فيفحص الـ CI ويبني، ثم يُنشر الإصدار، ثم يُستورد ملف JSON الخاص بالإصدار إلى مكتبة Figma.</title>\n  <rect class=\"d-box-accent\" x=\"20\" y=\"30\" width=\"150\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"95\" y=\"55\" text-anchor=\"middle\">branch في Figma</text>\n  <text class=\"d-label-muted\" x=\"95\" y=\"74\" text-anchor=\"middle\">اقتراح</text>\n  <rect class=\"d-box-primary\" x=\"265\" y=\"30\" width=\"150\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"340\" y=\"55\" text-anchor=\"middle\">Pull request</text>\n  <text class=\"d-label-muted\" x=\"340\" y=\"74\" text-anchor=\"middle\">JSON الـ tokens</text>\n  <rect class=\"d-box\" x=\"510\" y=\"30\" width=\"150\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"585\" y=\"55\" text-anchor=\"middle\">فحوص الـ CI</text>\n  <text class=\"d-label-muted\" x=\"585\" y=\"74\" text-anchor=\"middle\">بناء المخرجات</text>\n  <rect class=\"d-box-success\" x=\"510\" y=\"150\" width=\"150\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"585\" y=\"183\" text-anchor=\"middle\">الإصدار</text>\n  <rect class=\"d-box-accent\" x=\"20\" y=\"150\" width=\"150\" height=\"56\" rx=\"10\"/>\n  <text class=\"d-label\" x=\"95\" y=\"175\" text-anchor=\"middle\">مكتبة Figma</text>\n  <text class=\"d-label-muted\" x=\"95\" y=\"194\" text-anchor=\"middle\">استيراد ونشر</text>\n  <path class=\"d-arrow\" d=\"M170 58 L261 58\" marker-end=\"url(#arrow-l-ds-4-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M415 58 L506 58\" marker-end=\"url(#arrow-l-ds-4-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M585 86 L585 146\" marker-end=\"url(#arrow-l-ds-4-1-1)\"/>\n  <path class=\"d-arrow\" d=\"M510 178 L174 178\" marker-end=\"url(#arrow-l-ds-4-1-1)\"/>\n  <text class=\"d-label-muted\" x=\"340\" y=\"168\" text-anchor=\"middle\">JSON الإصدار</text>\n</svg><figcaption>مصدر حقيقة واحد، وFigma مرآة متزامنة</figcaption></figure>\n<p>ما زال المصمّمون يصمّمون في Figma؛ لكنهم فقط لا ينشرون قيم الـ tokens مباشرة. يبدأ التغيير في <strong>branch</strong> من ملف المكتبة (الـ branching متاح على خطتي Organization وEnterprise في Figma)، حيث يستطيع المصمّم تجربته في تصاميم حقيقية. وحين يجهز، تُصدَّر الـ modes المتغيّرة كـ JSON: إذ يستطيع Figma تصدير modes المجموعة واستيرادها بصيغة DTCG. ويصبح التصدير pull request على مستودع الـ tokens، حيث يشغّل الـ CI الفحوص من القسم 2، ويراجعه مصمّم ومهندس من النواة. وبعد الإصدار، يُستورد ملف JSON الخاص بالإصدار إلى ملف المكتبة الرئيسي ويُنشر تحديث المكتبة.</p>\n<p>بعض الفرق تؤتمت الخطوة الأخيرة بـ plugin أو بـ REST API الخاص بـ Figma. أما Northwind فتفعلها يدويًا مرة في كل إصدار؛ تستغرق عشر دقائق، ونظرة بشرية إلى لوحة المتغيّرات التقطت مرتين استيرادًا خاطئًا.</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>حين تنشر مكتبة، يتلقّى العاملون في الملفات التي تستخدمها إشعارًا ويختارون متى يقبلون التحديثات. عامل ذلك كرفع إصدار حزمة: انشر مع إصدار الكود، والصق الـ changelog نفسه في وصف النشر حتى يرى المصمّمون ما الذي تغيّر ولماذا.</p>\n</aside>\n<p>الحلقة نفسها تعمل مع المكوّنات، إذ يربط Code Connect مكوّنات Figma بالكود الخاص بها في Dev Mode. في التمرين ترتّب خطوات تغيير token. وبعدها تعطي هذه الإصدارات أرقامًا تخبر الفرق بما سيفعله التحديث بها.</p>\n","toc":[{"id":"sec-1","text":"ربط الطبقات بـ Figma variables","level":2},{"id":"sec-2","text":"اجعل المتغيّر الصحيح هو الأسهل","level":2},{"id":"sec-3","text":"حلقة المزامنة","level":2}],"takeaways":["اربط طبقات الـ tokens بمجموعات المتغيّرات (collections) في Figma، واربط الـ themes والعلامات والكثافة بالـ modes أو بالمجموعات الممتدّة.","اختر مصدر حقيقة واحدًا لقيم الـ tokens، واجعل الجانب الآخر مرآة تُحدَّث بعملية محدّدة، لا يدويًا أبدًا.","أعطِ المتغيّرات الدلالية صيغة كود (code syntax) وأخفِ الـ primitives من النشر، حتى يختار المصمّمون الأسماء نفسها التي يكتبها المهندسون.","تحديثات المكتبة إصدارات أيضًا؛ يقبلها المصمّمون في ملفاتهم كما يرفع المهندسون إصدار حزمة."],"further":[{"title":"Guide to variables in Figma","url":"https://help.figma.com/hc/en-us/articles/15339657135383-Guide-to-variables-in-Figma"},{"title":"Modes for variables (Figma)","url":"https://help.figma.com/hc/en-us/articles/15343816063383-Modes-for-variables"},{"title":"Extend a variable collection (Figma)","url":"https://help.figma.com/hc/en-us/articles/36346281624471-Extend-a-variable-collection"},{"title":"Guide to libraries in Figma","url":"https://help.figma.com/hc/en-us/articles/360041051154-Guide-to-libraries-in-Figma"}],"quiz":[{"q":"<p>يستطيع مصمّمو Northwind اختيار أي primitive مثل <code dir=\"ltr\">blue/600</code> من المكتبة، وما زالت التصاميم تستخدم الـ primitives حيث مكان الـ semantic tokens. ما أفضل إصلاح؟</p>","options":[{"text":"حذف مجموعة الـ primitives من Figma.","why":"المتغيّرات الدلالية أسماء مستعارة للـ primitives، فيجب أن تبقى الـ primitives موجودة في الملف."},{"text":"الطلب من المصمّمين في اجتماع أن يتوقّفوا عن استخدام الـ primitives.","why":"التذكيرات تتلاشى؛ يجب أن تجعل المكتبة الاختيار الصحيح هو الأسهل."},{"text":"إعادة تسمية الـ primitives ببادئة «لا تستخدم».","why":"تزحم كل اسم وتتركها مع ذلك في المنتقي."},{"text":"إخفاء متغيّرات الـ primitives من النشر، حتى لا تظهر في الملفات المستهلكة إلا المتغيّرات الدلالية.","why":"صحيح. تبقى الـ primitives متاحة للإشارة إليها داخل المكتبة، بينما لا يرى المصمّمون إلا الأسماء التي يجب أن يستخدموها."}],"answer":3},{"q":"<p>غيّر مصمّم <code dir=\"ltr\">color/action/bg</code> في Figma الأسبوع الماضي، وغيّر مهندس الـ token نفسه في JSON أمس، إلى قيمة مختلفة. أيّ فشل في العملية يكشفه هذا؟</p>","options":[{"text":"مصدران للحقيقة يقبل كلاهما التعديل المباشر.","why":"صحيح. مع مصدر واحد ومرآة، كان أحد التعديلين سيصبح اقتراحًا مقدَّمًا إلى المصدر بدل تغيير منافس."},{"text":"متغيّرات Figma لا تدعم الألوان القادمة من الكود.","why":"متغيّرات Figma تحمل الألوان جيدًا؛ المشكلة في مَن يُسمح له بتغييرها، وأين."},{"text":"كان على المهندس أن ينتظر مراجعة التصميم التالية.","why":"التوقيت لا يحلّ المشكلة؛ فبدون مصدر واحد يمكن لأي تعديلين أن يتعارضا."}],"answer":0},{"q":"<p>كيف يجب أن تمثّل Northwind علامتيها في Figma على خطة Enterprise؟</p>","options":[{"text":"نسخ المكتبة كاملة لـ Tidewater وصيانة النسختين يدويًا.","why":"المكتبات المنسوخة تتباعد، وهذه هي المشكلة التي وُجد النظام لحلّها."},{"text":"وضع ألوان العلامة مباشرة على كل مكوّن كتخصيصات (overrides).","why":"التخصيصات على المكوّنات تتجاوز المتغيّرات، فيتوقّف عمل الـ themes والربط بالكود."},{"text":"توسيع المجموعة الدلالية لـ Tidewater وتخصيص متغيّرات العلامة وحدها.","why":"صحيح. المجموعة الممتدّة ترث كل ما لا تخصّصه، فتصل التغييرات المشتركة إلى العلامتين معًا."},{"text":"تخزين ألوان العلامة كأنماط نصّ (text styles).","why":"أنماط النص تصف الطباعة لا الألوان، ولا ترتبط بالـ modes ولا بالـ tokens."}],"answer":2}],"exercise":{"kind":"order","items":["propose","export","ci","review","release","sync"],"title":"أطلق تغيير token من Figma إلى الكود وبالعكس","prompt":"<p>يريد مصمّم في Northwind أن يجعل <code dir=\"ltr\">color/text/subtle</code> أغمق لأنه يفشل في التباين في الـ theme الداكن لعلامة Tidewater. ملف JSON في مستودع الـ tokens هو مصدر الحقيقة، ومكتبة Figma مرآة. رتّب خطوات التغيير.</p>\n","hints":["لا شيء يصل إلى مكتبة Figma المنشورة قبل أن يصدر من المستودع.","الفحوص تعمل على الـ pull request، قبل أن يوافق عليه البشر."],"explanation":"<p>يجرّب المصمّم في branch، فلا يتغيّر شيء منشور بعد. ويدخل JSON المُصدَّر إلى مصدر الحقيقة عبر pull request، حيث يتحقّق الـ CI من الأسماء والمراجع والتباين ويبني كل المنصّات. ويراجع البشر وأمامهم هذا الدليل، ثم يُنشر إصدار جديد مع changelog، وعندها فقط يُستورد ملف JSON الخاص بالإصدار إلى المكتبة الرئيسية ويُنشر، فيعكس Figma بالضبط ما أُطلق.</p>\n","checkLabels":{},"itemText":{"propose":"يجرّب المصمّم القيمة الأغمق في branch من ملف مكتبة Figma","export":"تصدير الـ modes المتغيّرة كـ JSON بصيغة DTCG وفتح pull request في مستودع الـ tokens","ci":"يشغّل الـ CI فحوص التسمية والمراجع والتباين ويبني CSS وSwift وKotlin","review":"يراجع مصمّم ومهندس من النواة الـ pull request والفروقات البصرية فيه","release":"الدمج ونشر إصدار جديد من الـ tokens مع إدخال في الـ changelog","sync":"استيراد ملف JSON الخاص بالإصدار إلى متغيّرات المكتبة الرئيسية ونشر تحديث المكتبة"}},"words":645,"readMinutes":4}