نظرة عامة على نظام السمة
نظام السمة في lh-ui ذا مصدرين، ويجب توضيح هذه النقطة أولًا:
| المصدر | المحتوى | طريقة الاستهلاك |
|---|---|---|
styles/theme/common/var.scss + var-dark.scss |
خصائص CSS المخصصة (--lh-*) |
var(--lh-*) في SCSS المكوّنات، تُقيَّم في وقت التشغيل |
styles/theme/common/variables.scss |
متغيرات SCSS ($lh-*) |
تُخبَز في وقت الترجمة إلى قيم ملموسة، وتُستخدم في الحسابات (دوال الألوان، تركيب الظلال، إلخ) |
src/theme/themes/index.ts |
تخطيط vars لخمس مسبقات |
حقن JS في وقت التشغيل في <style> (ConfigProvider / ThemeStudio) |
لا تعترف المكوّنات إلا بمتغيرات CSS. وغاية وجود نظام السمة في جانب JS هي: حقن مجموعة من رموز التصميم في وقت التشغيل داخل شجرة فرعية من DOM، كي تبدِّل المكوّنات مظهرها دون إعادة الترجمة.
المساران
Section titled “المساران”1. مسبقات السمة (جاهزة للاستخدام مباشرةً)
Section titled “1. مسبقات السمة (جاهزة للاستخدام مباشرةً)”خمس مسبقات إعداد مدمجة: 青花瓷 (الخزف الأزرق) / 松花绿 (أخضر الصنوبر) / 朱砂 (الزنجفر) /
水墨 (رسم الحبر) / 藤黄 (أصفر عشبي). وتستخدم طبقة واجهة المستخدم buildPresetStyleText(vars)
لتوليد نص <style> وكتابته في DOM.
import { LH_THEME_PRESETS, buildPresetStyleText, LH_PRESET_THEME_STYLE_ID } from '@lh-ui/share/theme'
const preset = LH_THEME_PRESETS[0] // 青花瓷 (الخزف الأزرق)const styleText = buildPresetStyleText(preset.vars) // يُجمَّع في نص CSS// → يُحقن في <style id="lh-preset-theme">لمزيد من التفاصيل انظر مسبقات السمة.
2. التخصيص في وقت التشغيل (themeVars)
Section titled “2. التخصيص في وقت التشغيل (themeVars)”يستقبل ConfigProvider خاصية themeVars بمفاتيح مختصرة (تُضاف إليها بادئة --lh-
تلقائيًا):
<lh-config-provider :theme-vars="{ 'primary-color': '#1677ff' }"> <App /></lh-config-provider>لمزيد من التفاصيل انظر التخصيص في وقت التشغيل.
خمس بدائيع وقت التشغيل
Section titled “خمس بدائيع وقت التشغيل”يُصدِّر src/theme/index.ts (والتنفيذ في src/theme/themes/index.ts):
| البدائية | التوقيع | الاستخدام |
|---|---|---|
LH_THEME_PRESETS |
LhThemePreset[] |
مصفوفة جميع المسبقات، يمر عليها docs و ConfigProvider |
registerTheme(preset) |
(preset: LhThemePreset) => void |
تسجيل مسبقة أو الكتابة فوقها (الكتابة فوق الاسم نفسه، ويمكن أيضًا الكتابة فوق المسبقات الداخلية) |
getThemePreset(name) |
(name: LhThemePresetName) => LhThemePreset | undefined |
جلب المسبقة بالاسم |
getThemeVars(name) |
(name: LhThemePresetName) => LhThemeVars | undefined |
جلب vars الخاصة بها بالاسم (يُعيد undefined إذا لم تكن مُسجَّلة) |
buildPresetStyleText(vars) |
(vars: Record<string, string>) => string |
تجميع vars في نص <style> قابل للحقن |
وهنالك بدائيع حساب التباين (يستخدمها verify:theme و ThemeStudio):
| البدائية | التوقيع | الاستخدام |
|---|---|---|
getRelativeLuminance(color) |
(color: string | undefined) => number | undefined |
السطوع النسبي وفق WCAG (يُعيد undefined لغير hex) |
getContrastRatio(a, b) |
(a, b: string | undefined) => number | undefined |
نسبة التباين وفق WCAG (1~21) |
buildPresetDarkVars(vars) |
(vars: Record<string, string>) => Record<string, string> |
اشتقاق متغيرات الكتلة الداكنة من vars المسبقة |
LH_PRESET_THEME_STYLE_ID |
'lh-preset-theme' |
المعرّف الثابت لعنصر الحقن |
الأنواع
Section titled “الأنواع”export type LhThemePresetName = | 'cerblue' | 'songhua' | 'zhusha' | 'shuimo' | 'golden' | (string & {}) // ← أسماء مخصصة مفتوحة، مع الإبقاء على الإكمال التلقائي للحرفيات
export interface LhThemePreset { name: LhThemePresetName label: string // الاسم الصيني labelEn: string // الاسم الإنجليزي description: string // وصف السمة vars: Record<string, string> // تخطيط متغيرات CSS}
export type LhThemeVars = Record<string, string>إن (string & {}) في نهاية LhThemePresetName حيلة في TS: تُبقي الإكمال التلقائي للحرفيات
الخمس الأولى، وتسمح في الوقت نفسه بتمرير أي سلسلة عبر registerTheme({ name: 'my-brand', ... }).
وتُعيد الأسماء غير المُسجَّلة undefined في getThemePreset / getThemeVars.
قيد الحقن: كتابة <style> فقط، لا style مضمَّن
Section titled “قيد الحقن: كتابة <style> فقط، لا style مضمَّن”هذا أهم قيد في نظام السمة، وقد واجهنا مرة فخًا فيه:
// ✅ صحيح: كتابة عنصر <style>، الخصوصية 0,1,0const el = document.createElement('style')el.id = LH_PRESET_THEME_STYLE_IDel.textContent = buildPresetStyleText(vars)document.head.appendChild(el)
// ❌ خطأ: كتابة style مضمَّن (inline) على documentElement، الخصوصية 1,0,0,0Object.assign(document.documentElement.style, vars)لماذا: تخصص style المضمَّنة درجة خصوصية أعلى من أي ورقة أنماط، فتطغى على إعلانات
الوضع الداكن الكاملة داخل var-dark.scss ([data-theme='dark'], .dark { --lh-*: ... })،
مما يُفسد ألوان الوضع الداكن — إذ تُسحَق المتغيرات الداكنة بقيم فاتحة مضمَّنة.
بنية النص التي يُولِّدها buildPresetStyleText:
:root { --lh-primary-color: #2B4C7C; /* ...vars المسبقة كاملة */}
[data-theme='dark'],.dark { --lh-primary-color-bg: color-mix(in srgb, var(--lh-primary-color) 25%, transparent); --lh-selected-color: color-mix(in srgb, var(--lh-primary-color) 40%, #fff); /* تفتيح إضافي للون الرئيسي في المسبقات الداكنة */}تأتي الكتلة الداكنة بعد كتلة :root ولديها الخصوصية نفسها، فيغلِّبها المتصفح —
وبالتالي لا تتسرّب القيمة الفاتحة لـ --lh-selected-color المُعلَن عنها في :root
للمسبقات ذات اللون الرئيسي الفاتح إلى الوضع الداكن. ويُشتق محتوى الكتلة الداكنة من
buildPresetDarkVars.
اشتقاق الوضع الداكن في buildPresetDarkVars
Section titled “اشتقاق الوضع الداكن في buildPresetDarkVars”ثلاث قواعد:
-
إعادة تعريف متغيرين دون قيد (بالإشارة عبر
var()، تُقيَّمان على العنصر المُطبَّق عليه، وتتبعان اللون الرئيسي الحالي):--lh-primary-color-bg: color-mix(in srgb, var(--lh-primary-color) 25%, transparent)--lh-selected-color: color-mix(in srgb, var(--lh-primary-color) 40%, #fff)
-
تفتيح اللون الرئيسي الداكن: إذا كانت نسبة تباين
--lh-primary-colorمقابل خلفية الصفحة الداكنة#1A1A2E(DARK_PAGE_BG) أقل من 3 (DARK_PRIMARY_CONTRAST_THRESHOLD)، يُحكَم بأنه لون رئيسي داكن ويُضاف تفتيحه:--lh-primary-color: color-mix(in srgb, <قيمة حرفية> 55%, #fff)—— يعوَّض بالقيمة الحرفية مباشرةً، لأنcolor-mix(var(--lh-primary-color) …)يُنشئ دورة CSS ذاتية الإشارة--lh-primary-color-hover: color-mix(in srgb, var(--lh-primary-color) 70%, #fff)--lh-primary-color-active: color-mix(in srgb, var(--lh-primary-color) 85%, #000)--lh-color-on-primary: #101410(INK_ON_LIGHTENED_PRIMARY) —— فبعد التفتيح يصبح تباين النص الأبيض أقل من 3:1، فيُستبدل بالنص الأسود (الحبر)
-
يحسب التباين عبر
getContrastRatio(getRelativeLuminance(primary), getRelativeLuminance(DARK_PAGE_BG)). وتُعيد القيم غير hex (بما فيها القيم الديناميكية التي تحويvar()) القيمةundefined، فتُعامَل على أنها «لا يمكن الحكم عليها» — ولهذا يجب أن يكون اللون الرئيسي في vars المسبقة قيمة hex حرفية.
المزامنة المزدوجة المصدر
Section titled “المزامنة المزدوجة المصدر”عند تغيير اللون الرئيسي لسمة داخلية، يجب تعديل المصدرين معًا:
vars['--lh-primary-color']للمسبقة داخلsrc/theme/themes/index.ts(لحقن JS في وقت التشغيل)$lh-primary-colorفيstyles/theme/common/variables.scss(لحسابات SCSS في المكوّنات)
ويوجد اختبار ارتجاع للاتساق في tests/unit/theme.spec.ts، يُمسك أي عدم مزامنة عند تشغيل
pnpm test.
ما لا تستطيع السمة فعله
Section titled “ما لا تستطيع السمة فعله”- لا تستطيع تغيير ارتفاع عناصر التحكم: فرموز الارتفاع
--lh-control-height-*لم تُنشأ بعد (تتفاوت ارتفاعات عناصر التحكم، وهو مُسجَّل في «مشروع رموز الارتفاع» بانتظار changeset لاحق). - لا تستطيع تغيير بنية المكوّن: فالسمة تبدِّل قيم الرموز فقط، وتبقى التخطيط وبنية DOM كما هي.
- الزخارف نظام مستقل: انظر الزخارف الصينية.
معاينة المسبقات
Section titled “معاينة المسبقات”cerblue · Ceramic Blue青花瓷釉下彩,清雅素净
--lh-primary-color#2B4C7C--lh-primary-color-hover#3D649E--lh-primary-color-active#1F3A5F--lh-primary-color-bg#E8EDF3--lh-primary-color-border#D4DCE8
songhua · Pine Green竹林修竹,生机勃勃
--lh-primary-color#5B8C5A--lh-primary-color-hover#7BB079--lh-primary-color-active#4F8F4C--lh-primary-color-bg#E8F5E8--lh-primary-color-border#D0E8CF--lh-color-on-primary#101410--lh-selected-color#456F44
zhusha · Vermilion传统印章朱砂红,喜庆庄重
--lh-primary-color#B23A3A--lh-primary-color-hover#C45050--lh-primary-color-active#9A3030--lh-primary-color-bg#FDF0F0--lh-primary-color-border#F0D8D8
shuimo · Ink Wash水墨丹青,素雅极简
--lh-primary-color#2C2C2C--lh-primary-color-hover#5A5A5A--lh-primary-color-active#1A1A1A--lh-primary-color-bg#F5F5F5--lh-primary-color-border#E0E0E0
golden · Golden Autumn深秋枫黄,温暖金黄
--lh-primary-color#B8860B--lh-primary-color-hover#D4A843--lh-primary-color-active#A87F0A--lh-primary-color-bg#FBF6EA--lh-primary-color-border#F0E8D0--lh-color-on-primary#1E1A16--lh-selected-color#82600A
وثائق ذات صلة
Section titled “وثائق ذات صلة”- مسبقات السمة —— شرح المسبقات الداخلية الخمس
- رموز التصميم —— الجدول الكامل: 185 فاتحًا + 118 داكنًا
- التخصيص في وقت التشغيل —— themeVars / componentTheme / patternComponents
- الوضع الداكن —— الآلية وفخ الخبز في وقت الترجمة
- الزخارف الصينية —— 6 زخارف مدمجة
Copyright © 2024-2026 FengMo WenXue