البدء مع Lily
اختر إطار عمل، وانسخ مستودع headless أو تطبيق المثال، وابدأ بتركيب صفحاتك الخاصة. تفضّل مسارًا موجَّهًا؟ ابدأ بـ الدروس.
التثبيت
يُنشر Lily كمستودعات Git منفصلة لكل إطار عمل. وأسرع طريقة لتجربته هي نسخ مستودع headless لتقنيتك:
git clone https://github.com/LilyDesignSystem/lily-design-system-react-headless
cd lily-design-system-react-headless
pnpm install
ينطبق النمط نفسه على أطر العمل الأخرى:
@lilydesignsystem/html-headless— لا حاجة إلى تثبيت؛ انسخ ملفات.html@lilydesignsystem/svelte-headless—pnpm install@lilydesignsystem/react-headless—pnpm install@lilydesignsystem/vue-headless—pnpm install@lilydesignsystem/angular-headless—pnpm install@lilydesignsystem/nunjucks-headless—pnpm installlily-design-system-blazor-headless—dotnet build
صُمّمت مكتبات headless لتُنسخ أو تُضمَّن في المشروع — فاعتبر الشيفرة المصدرية المرجع الأصلي وانسخ ما تحتاج إليه. وتُوزَّع مساعدات التفضيلات كذلك كحزم قابلة للتثبيت مع خط بناء ونشر (npm لأطر JS، وNuGet لـ Blazor).
استخدام مكوّن headless
تأتي مكوّنات headless بـ HTML دلالي وARIA وخصائص — لكن بلا أي CSS. إليك زرًا في كل إطار عمل:
HTML
<button class="button" type="button" aria-label="Save">
Save
</button>
Svelte
<script>
import Button from "lily-design-system-svelte-headless/components/Button/Button.svelte";
</script>
<Button onclick={save}>Save</Button>
React
import Button from "lily-design-system-react-headless/components/Button";
<Button onClick={save}>Save</Button>
Vue
<script setup>
import Button from "lily-design-system-vue-headless/components/Button.vue";
</script>
<Button @click="save">Save</Button>
Angular
import { Button } from "@lilydesignsystem/angular-headless";
@Component({
imports: [Button],
template: `<lily-button (click)="save()">Save</lily-button>`,
})
Blazor
<Button OnClick="Save">Save</Button>
Nunjucks
{% from "components/button/macro.njk" import button %}
{{ button({ text: "Save", type: "button" }) }}
استخدام مثال منسّق
تتضمن تطبيقات الأمثلة CSS ومسارات وصفحات عرض كاملة. وأسرع طريقة للتجريب هي تشغيل تطبيق مثال SvelteKit أو Next أو Nuxt أو Analog أو Eleventy ومشاهدة العرض في /components.
git clone https://github.com/LilyDesignSystem/lily-design-system-svelte-sveltekit-examples
cd lily-design-system-svelte-sveltekit-examples
pnpm install
pnpm run dev
ثم افتح http://localhost:5173 وتصفّح /components.
التنسيق ورموز التصميم
يُعرض كل مكوّن بفئة واحدة بصيغة kebab-case على عنصره الجذر. فمثلًا يُنتج <Button> العنصر <button class="button">. نسّقه كما تشاء:
.button {
background: var(--my-primary);
color: #fff;
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
}
.button:hover { background: var(--my-primary-hover); }
لوحة ألوان Lily الافتراضية (المستخدمة في تطبيقات الأمثلة):
- الأساسي:
#2563eb - الخطر:
#dc2626 - التحذير:
#f59e0b - النجاح:
#16a34a - خلفية الصفحة:
#f9fafb - خلفية البطاقة:
#ffffff
هذه اقتراحات لا متطلبات. استبدلها بلوحة ألوان علامتك التجارية وسيتكيّف Lily بسرور.
سمات جاهزة
لا تريد كتابة CSS من الصفر؟ يضم Lily 45 سمة مرجعية قائمة بذاتها في الدليل themes/. كل منها ورقة أنماط واحدة تستهدف فئات الربط في Lily — اربطها ويصبح التنسيق جاهزًا:
<link rel="stylesheet" href="/assets/themes/united-kingdom-government-digital-service.css" />
تشمل المجموعة:
- القطاع العام — NHS England وNHS Scotland وNHS Wales (بنسخ للمرضى وللممارسين)، وGOV.UK GDS ونظام تصميم الويب الأمريكي.
- مستوحاة من جهات مزوِّدة — Adobe Spectrum وMozilla Protocol.
- للأغراض العامة — فاتحة وداكنة وnord وdracula وwireframe ونحو ثلاثين أخرى.
تستخدم محددات السمات :where(...)، فيفوز CSS الخاص بك دائمًا من حيث الخصوصية. اقرنها بالمساعد theme-picker أدناه للتبديل وقت التشغيل، أو اتبع درس السمات.
مساعدات التفضيلات
لكل إطار عمل فهرس مرافق *-helpers فيه ثمانية منتقيات صغيرة (وpicker-bar الذي يجمعها). وكل منها زر أيقونة headless يفتح نافذة منبثقة — قائمة خيارات أو قائمة روابط أو نموذج بحث أو (في date-time-picker) حوار انتقاء تاريخ — وليس <select> أصليًا؛ وهو آمن للعرض على الخادم ولا يأتي بأي CSS:
- theme-picker — يحمّل أوراق أنماط السمات وقت التشغيل بتبديل
<link>مُدار، ويضبطdata-themeعلى المستند، ويحفظ اختياريًا فيlocalStorage. - locale-picker — يضبط
langوdir(مع كشف تلقائي للكتابة من اليمين إلى اليسار) لتتبعهما مكتبة i18n لديك؛ ولا يترجم شيئًا بنفسه. - text-size-picker — يضبط
data-text-sizeعلى المستند؛ ويربط CSS لديك كل قيمة بحجم خط. - motion-picker — يضبط
data-motionعلى المستند، ابتداءً من إعداد تقليل الحركة لدى الزائر؛ ويقرر CSS والسكربتات لديك ما يُكبَح. - search-picker — زر أيقونة يفتح حقل بحث؛ ويؤدي الإرسال إلى صفحة بحث. يملك إجراءً لا تفضيلًا.
- link-picker — أيقونة بيت تفتح قائمة بروابط الصفحات التي يحددها تطبيقك (الرئيسية، من نحن، اتصل بنا، سياسة الخصوصية، …). يملك إجراءً لا تفضيلًا.
- share-picker — يفتح ورقة المشاركة الأصلية أو قائمة وجهات يوفّرها المستهلك، إضافةً إلى نسخ عنوان URL. يملك إجراءً لا تفضيلًا: لا يطبّق شيئًا ولا يحفظ شيئًا.
- date-time-picker — حقل نصي مع حوار انتقاء تاريخ وفق APG لتاريخ أو وقت أو كليهما. يملك قيمة نموذج لا تفضيلًا: تتحول سلسلة ISO ذهابًا وإيابًا مع
<input type="date">.
git clone https://github.com/LilyDesignSystem/lily-design-system-svelte-helpers
فهرس Svelte هو المرجع المعتمد؛ وتطابقه نسخ React وVue وAngular وHTML وNunjucks وWeb Components وBlazor عقدًا بعقد. راجع درس المساعدات.
إمكانية الوصول
تستهدف المكوّنات WCAG 2.2 AAA. وهي تتبع هذه الأنماط:
- عناصر HTML دلالية بدلًا من عناصر
<div>العامة. <label for="id">لربط التسميات بحقول الإدخال.aria-labelledby/aria-describedbyللإحالات المتبادلة.aria-invalid+aria-errormessageلحالات الخطأ.role="alert"وaria-liveللمحتوى الديناميكي.aria-pressedوaria-expandedوaria-currentللحالة.tabindexالمتنقل للشبكات.
مؤشرات التركيز يوفّرها المستهلك عن قصد — فلا يرسم Lily أبدًا حلقة تركيز افتراضية تتعارض مع تصميمك. وتحافظ تطبيقات الأمثلة على خط أساس نظيف لـ axe-core عبر مساراتها.
التدويل
كل تسمية ونص إرشادي ورسالة خطأ ونص زر هو خاصية. ولا توجد سلاسل نصية مكتوبة في الشيفرة. أدخل إطار الترجمة الذي تفضّله — Paraglide أو i18next أو vue-i18n أو react-intl أو ملفات .resx، أيًّا كان.
بالنسبة إلى التواريخ والأرقام والعملات، تقبل المكوّنات سلاسل منسّقة مسبقًا: تنسّق أنت بـ Intl.DateTimeFormat / Intl.NumberFormat / مكتبتك المفضلة وتمرّر النتيجة.
يُعلِم المساعد locale-picker مكتبة i18n لديك بالإعداد المحلي المختار بضبط lang وdir على جذر المستند.
الاختبار
يأتي كل مشروع فرعي لإطار عمل باختباراته الخاصة بحزمته المعتادة:
- HTML: WebDriverIO يعمل على متصفحات حقيقية.
- Svelte: Vitest +
@testing-library/svelte. - React: Vitest +
@testing-library/react. - Vue: Vitest +
@testing-library/vue. - Angular: Vitest + TestBed (عبر إضافة Vite الخاصة بـ Analog).
- Nunjucks: Vitest مع مساعد للعرض.
- Blazor: bUnit.
تستخدم الاختبارات المطابقات المدمجة في Vitest فقط — ولا تستخدم مطابقات jest-dom أبدًا. وهذا يُبقي مجموعات الاختبار قابلة للنقل. وتضيف تطبيقات الأمثلة مجموعات Playwright من الطرف إلى الطرف، وخطوط أساس لإمكانية الوصول بـ axe-core، ومسحًا لأحجام النوافذ المتجاوبة.
وكلاء الذكاء الاصطناعي
ينشر هذا الموقع llms.txt وllms.json في جذره — خريطة منتقاة لأهم صفحاته، لأي أداة تتبع اصطلاح llms.txt.
ويضم المستودع الأحادي المعتمد أيضًا مهارتين من مهارات Claude: lily-design-system-skill، وهي مهارة عامة تغطي مفاهيم Lily ومصطلحاته وأنماط تركيبه لكل من يبني بالنظام، وlily-design-system-maintainer-skill، وهي مهارة تقنية تغطي تخطيط الملفات المطلوبة وأدوات المستودع الأحادي لكل من يعمل عليها. وكلتاهما في جذر المستودع الأحادي المعتمد.
استكشاف الأخطاء وإصلاحها
مكوّن يُعرض لكنه يبدو بلا تنسيق
هذا هو headless يعمل كما هو مقصود — فلا يأتي أي CSS مع المكوّن. إما أن تكتب CSS لفئة المكوّن بصيغة kebab-case (الظاهرة في كل صفحة من الفهرس) أو تربط إحدى السمات الجاهزة الـ 45.
يبدو أن CSS الخاص بي لا يُطبَّق فوق السمة
ينبغي أن يُطبَّق — فمحددات السمات ملفوفة في :where(...)، وخصوصيتها صفر. وإن ظلت قاعدة ما تخسر، فتحقق من أن ورقة الأنماط لديك تُحمَّل بعد <link> السمة، وأن المحدد يطابق فعلًا فئة الربط للمكوّن.
يفشل pnpm install بخطأ في التبعيات النظيرة أو الإصدار
استخدم pnpm حديثًا (الإصدار 10 أو أحدث) وNode 22 أو أحدث. يثبّت كل مستودع إصدارات إطار عمله في package.json؛ وإن كانت سلسلة أدواتك العامة أقدم فإن pnpm env use --global lts هو أسرع حل.
قارئ الشاشة ينطق اسمًا خاطئًا لعنصر تحكم
تحقق من الخاصية label المطلوبة في المكوّن — فالمكوّنات التي لا نص ظاهرًا فيها تتطلبها، وتفوز عن قصد قيمتا aria-label / aria-labelledby المقدَّمتان من المستهلك والممرَّرتان عبر الخصائص المتبقية على الربط المدمج. وتوثّق كل صفحة من الفهرس عقد ARIA للمكوّن.
المساعد theme-picker لا يبدّل أوراق الأنماط
تأكد من أن themesUrl يشير إلى دليل يستطيع المتصفح جلبه (قدّم ملفات themes/ كأصول ثابتة) وأن معرّفات السمات في الخاصية themes تطابق أسماء الملفات. يبدّل المساعد قيمة href لعنصر <link data-lily-theme-picker> واحد مُدار — افحصه في أدوات المطوّر لترى عنوان URL المطلوب.
شيء آخر معطّل
افتح مشكلة مع إعادة إنتاج مصغّرة في المستودع المعني على github.com/LilyDesignSystem — أو راجع المجتمع والدعم.
المساهمة
Lily فتيّ ويرحب بالتعاون. وأنفع المساهمات حاليًا:
- مكوّنات جديدة (خاصةً أنماط من أنظمة تصميم راسخة).
- سمات جديدة — كل منها ورقة أنماط قائمة بذاتها، وهي أول طلب دمج محدد النطاق جيدًا.
- تنسيق أفضل للأمثلة — أظهر ما هو ممكن.
- ترجمات للسلاسل النصية في تطبيقات الأمثلة.
- تقارير أخطاء مع إعادة إنتاج مصغّرة.
- تدقيقات لإمكانية الوصول بقارئات الشاشة والتقنيات المساعدة.
افتح المشكلات وطلبات الدمج في المستودع المعني على github.com/LilyDesignSystem.
المجتمع والدعم
- الأسئلة وتقارير الأخطاء — افتح مشكلة في المستودع المعني على github.com/LilyDesignSystem.
- البريد الإلكتروني — يقرأ القائم على الصيانة joel@joelparkerhenderson.com ويرحب بالتعاون والإرشاد والملاحظات.
- المرايا — يُدفَع Lily أيضًا إلى Codeberg وGitLab، فيمكنك المشاركة من المنصة التي تفضّلها.
- السلوك — يتبع المشروع مدونة سلوك معيارية؛ كن لطيفًا وافترض حسن النية.
الأسئلة الشائعة
لماذا headless بدلًا من المنسّق جاهزًا؟
المكوّنات المنسّقة مسبقًا مريحة — إلى أن لا تطابق علامتك التجارية. أما مكوّنات headless فتتطلب جهدًا أكبر قليلًا في البداية لكنها تمنحك تحكمًا كاملًا في التصميم المرئي. وتُظهر تطبيقات الأمثلة والسمات الـ 45 طرقًا لتنسيقها؛ ويمكنك أخذها أو استبدالها بالكامل. والحجة الأطول في لماذا Lily.
لماذا هذا العدد الكبير من المكوّنات؟
يهدف Lily إلى تغطية الأنماط التي تحتاج إليها معظم التطبيقات دون أن يجبرك على بنائها من الصفر — بما في ذلك حالات أعمق كحقول المعرّفات الوطنية والسرد التحريري بالتمرير. ويستقي الفهرس من اثني عشر نظام تصميم راسخًا إضافةً إلى عمل أصيل — راجع حول المشروع.
هل يمكنني استخدام Lily مع Tailwind؟
نعم. يكشف كل مكوّن فئة جذر واحدة بصيغة kebab-case إضافةً إلى className / class يوفّره المستهلك. ضع أدوات Tailwind فوقها كما تشاء.
هل يمكنني استخدام Lily مع أطر CSS الدلالية مثل DaisyUI؟
نعم. تعمل أسماء الفئات بصيغة kebab-case على العنصر الجذر كروابط CSS دلالية. اقرن Lily بإطار دلالي تحصل على مكوّنات منسّقة مسبقًا لا تزال تحترم ARIA والتدويل.
هل توجد حزمة npm؟
تُوزَّع مساعدات التفضيلات كحزم مع خط نشر npm/NuGet. وصُمّمت مكتبات مكوّنات headless لتُنسخ أو تُضمَّن في المشروع — فالشيفرة المصدرية هي المنتَج، فتستطيع أن تقرأ وتقلّم وتملك بالضبط ما تطلقه. ويبقى النشر في السجلات لمكتبات headless على خارطة الطريق.
لماذا تراخيص متعددة؟
لدى المشاريع المختلفة احتياجات ترخيص مختلفة. فـ BSD وMIT متساهلان، ولدى Apache-2.0 منحة براءات اختراع، وتدعم خيارات GPL الترخيص بالمثل (copyleft). اختر ما يناسب وضعك.
كيف أبلغ عن خلل أو أطلب ميزة؟
افتح مشكلة في مستودع GitHub المعني، أو راسل joel@joelparkerhenderson.com.