تدعم جميع مكوّنات lh-ui افتراضيًا الوضعين الفاتح والداكن . فهذه ليست سمة أُضيفت
لاحقًا، بل فرضية تصميمية لنظام الرموز.
مفتاح الوضع الداكن هو محدِّد CSS لا JS:
--lh-text-primary : # E8E0D8 ;
وطريقتان للتشغيل:
<!-- الطريقة الأولى: سمة data (موصى بها، الدلالة أوضح) -->
<!-- الطريقة الثانية: صنف (لتوافق الكود القديم / مكتبات تبديل الطرف الثالث) -->
كل ما على طبقة واجهة المستخدم (ConfigProvider في كل مكتبة أو كود العمل) فعله هو تبديل
هذه السمة / الصنف، فتتبدّل ألوان جميع المكوّنات فورًا — فمتغيرات CSS تُقيَّم في وقت
التشغيل دون أي تكلفة إعادة تصيير.
function toggleDark ( isDark : boolean ) {
document . documentElement . dataset . theme = isDark ? ' dark ' : ' light '
لا يكتب ملف الوضع الداكن إلا 118 عنصرًا ، لا مجموعة كاملة من 185. فيُتجاوز فقط
الرموز التي تحتاج إلى الانقلاب، ويُفرَض الباقي عن القيم الفاتحة.
ومبدأ التصميم هو إعادة توجيه الرموز الدلالية، لا إعادة كتابة كل مكوّن :
// ✅ الأسلوب الجيد: في الوضع الداكن تشير إلى الرموز الدلالية الداكنة
--lh-menu-item-color : var ( --lh-text-primary );
--lh-table-cell-color : var ( --lh-text-primary );
// ❌ الأسلوب السيئ: كتابة لون ملموس ثابت في الوضع الداكن
--lh-menu-item-color : rgba ( 255 , 255 , 255 , 0.85 ); // ينفصل عن text-primary، وتحتاج كل عملية ضبط لاحقة إلى تعديلين
هو الفخ الأكثر وقوعًا في الوضع الداكن، وهو سبب وجود البند السابع من
verify:styles.
الرموز التي تأخذ في var.scss قيمًا بصيغة #{$lh-foo}:
--lh-menu-item-color : #{ $lh-menu-item-color } ; // يُستبدل متغير SCSS في وقت الترجمة بقيمة فاتحة ملموسة
تُخبَز متغيرات SCSS في وقت الترجمة إلى قيم حرفية ، فتعادل:
--lh-menu-item-color : rgba ( 0 , 0 , 0 , 0.88 ); // لا ينقلب تلقائيًا في الوضع الداكن!
والنتيجة: في الوضع الداكن تبقى نصوص القوائم / الجداول / الخطوط الزمنية تأخذ قيمًا
فاتحة، فلا تظهر (أسود فوق أسود ). وقد وقع نقص كهذا فعلًا، وسجلَّت عملية تداركه في
changeset الإصدار 0.4.0.
إعادة توجيه صريحة إلى الرموز الدلالية الداكنة داخل var-dark.scss:
--lh-menu-item-color : var ( --lh-text-primary );
سلسلة fallback داخل SCSS المكوّن:
color : var ( --lh-foo , var ( --lh-bar , # 333 ));
يُقيَّم fallback الخاص بـ var() في وقت التشغيل : ما دام أي رمز في السلسلة لديه
تجاوز داكن، تتبعه السلسلة كلها وتنقلب. دون الحاجة إلى إعادة التصريح .
جدول المقارنة:
الأسلوب
وقت التقييم
السلوك في الوضع الداكن
var(--lh-foo, fallback)
وقت التشغيل
✅ ينقلب إذا كان رمز في السلسلة لديه تجاوز داكن
#{$lh-foo} (إقحام SCSS)
وقت الترجمة
❌ يُخبَز بالقيمة الفاتحة، ويحتاج إلى إعادة توجيه صريحة في var-dark
دوال SCSS مثل mix($lh-a, $lh-b)
وقت الترجمة
❌ مماثل لما سبق
من بين المسبقات الداخلية الخمس، ذات اللون الرئيسي الداكن (青花瓷 / 朱砂 / 水墨) يغوص
لونها الرئيسي في لون خلفية الصفحة في الوضع الداكن. ويتولى buildPresetDarkVars
المعالجة تلقائيًا:
قاعدة الحكم: إذا كانت نسبة تباين --lh-primary-color مقابل خلفية الصفحة الداكنة
#1A1A2E (DARK_PAGE_BG) أقل من 3 (DARK_PRIMARY_CONTRAST_THRESHOLD) يُحكَم بأنه
لون رئيسي داكن، ثم:
--lh-primary-color : color-mix ( in srgb , <قيمة حرفية> 55 % , # fff ); /* تفتيح 55% */
--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 ; /* بعد التفتيح يصبح تباين النص الأبيض غير كافٍ، فيُستبدل بالنص الأسود */
--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 );
لماذا يُعوَّض اللون الرئيسي المُفتَّح بقيمة حرفية لا var() : لأن
color-mix(in srgb, var(--lh-primary-color) 55%, #fff) يُنشئ دورة CSS ذاتية الإشارة
(تشير قيمة --lh-primary-color إلى نفسها). ولذلك تُعوَّض هذه القيمة بالقيمة
الحرفية ، بينما تستخدم البقية var() وتتبع اللون الرئيسي الحالي.
أما المسبقات ذات اللون الرئيسي الفاتح (松花绿 / 藤黄) فلا تحتاج إلى تفتيح، لكنها تحصل
مع ذلك على إعادة تعريف داكنة لـ --lh-primary-color-bg و --lh-selected-color.
النص الذي يُولِّده buildPresetStyleText يضع كتلة :root { ... } أولًا ثم كتلة
[data-theme='dark'], .dark { ... }. وعند تساوي الخصوصية يغلب الأخير ، لذلك لا
تتسرّب القيمة الفاتحة لـ --lh-selected-color المُعلَن عنها في :root للمسبقات ذات
اللون الرئيسي الفاتح إلى الوضع الداكن.
وهذا أيضًا السبب الجذري لقاعدة «يكتب <style> فقط لا style مضمَّن» — فخصوصيةstyle
المضمَّن 1,0,0,0 تطغى على كتلة متغيرات الوضع الداكن الكاملة في var-dark.scss،
فيفشل الوضع الداكن مباشرةً (لمزيد من التفاصيل انظر
النظرة العامة على السمة ).
主色与衍生语义 令牌 明色 暗色 SCSS 源 备注 --lh-primary-color #3D649E$lh-primary--lh-primary-color-hover #5078AB$lh-primary-hover--lh-primary-color-active #2B4C7C$lh-primary-active--lh-primary-color-bg color-mix(in srgb, var(--lh-primary-color) 25%, transparent)$lh-primary-light--lh-primary-color-border #2A3A4A$lh-primary-lighter--lh-color-on-primary #fff$lh-on-primary
状态 令牌 明色 暗色 SCSS 源 备注 --lh-hover-bg-color rgba(255, 255, 255, 0.08)$lh-hover-bg--lh-selected-color color-mix(in srgb, var(--lh-primary-color) 40%, #fff)—
功能色 令牌 明色 暗色 SCSS 源 备注 --lh-success-color #6FA36E$lh-success--lh-success-color-hover #82B581$lh-success-hover--lh-success-color-active #5B8C5A$lh-success-active--lh-success-color-bg #1A2A1A$lh-success-light--lh-warning-color #D4B76F$lh-warning--lh-warning-color-hover #E0C680$lh-warning-hover--lh-warning-color-active #C4A35A$lh-warning-active--lh-warning-color-bg #2A251A$lh-warning-light--lh-danger-color #C45050$lh-danger--lh-danger-color-hover #D46060$lh-danger-hover--lh-danger-color-active #B23A3A$lh-danger-active--lh-danger-color-bg #2A1A1A$lh-danger-light--lh-info-color #8F8F8F$lh-info--lh-info-color-hover #A0A0A0$lh-info-hover--lh-info-color-active #7A7A7A$lh-info-active--lh-info-color-bg #1A1A1A$lh-info-light
国风装饰色 令牌 明色 暗色 SCSS 源 备注 --lh-gold-color #D4A843$lh-gold--lh-gold-color-hover #E8C35C$lh-gold-hover--lh-gold-color-active #B8860B$lh-gold-active--lh-gold-color-bg #2A241A$lh-gold-light--lh-gold-color-border #3A2E1A$lh-gold-lighter--lh-vermilion-color #E85D4A$lh-vermilion--lh-vermilion-color-hover #FF7B6B$lh-vermilion-hover--lh-vermilion-color-active #C43A31$lh-vermilion-active--lh-vermilion-color-bg #2A1A18$lh-vermilion-light--lh-jade-color #7AAE7A$lh-jade--lh-jade-color-hover #9CC89C$lh-jade-hover--lh-jade-color-active #5B8C5A$lh-jade-active--lh-jade-color-bg #1A2A1A$lh-jade-light--lh-decoration-color rgba(212, 168, 67, 0.08)$lh-decoration-color
文本 令牌 明色 暗色 SCSS 源 备注 --lh-text-primary #E8E0D8$lh-text-primary--lh-text-regular #C8C0B8$lh-text-regular--lh-text-secondary #A09890$lh-text-secondary--lh-text-placeholder #7A7270$lh-text-placeholder--lh-text-disabled #5A5250$lh-text-disabled
边框 令牌 明色 暗色 SCSS 源 备注 --lh-border-color-base #3A3530$lh-border-color-base--lh-border-color-light #302B28$lh-border-color-light--lh-border-color-lighter #2A2520$lh-border-color-lighter--lh-border-color-extra-light #242018$lh-border-color-extra-light
圆角 令牌 明色 暗色 SCSS 源 备注 --lh-border-radius-base 沿用明色 $lh-border-radius-base--lh-border-radius-small 沿用明色 $lh-border-radius-small--lh-border-radius-round 沿用明色 $lh-border-radius-round--lh-border-radius-circle 沿用明色 $lh-border-radius-circle
背景 令牌 明色 暗色 SCSS 源 备注 --lh-bg-color #2A2520$lh-bg-color--lh-bg-color-page #1E1A16$lh-bg-color-page--lh-bg-color-disabled #242018$lh-bg-color-disabled--lh-bg-color-overlay rgba(10, 8, 6, 0.7)$lh-bg-color-overlay
阴影 令牌 明色 暗色 SCSS 源 备注 --lh-box-shadow-base 0 2px 12px 0 rgba(0, 0, 0, 0.5)$lh-box-shadow-base--lh-box-shadow-light 0 2px 4px 0 rgba(0, 0, 0, 0.4)$lh-box-shadow-light--lh-box-shadow-lighter 0 0 4px 0 rgba(0, 0, 0, 0.3)$lh-box-shadow-lighter
字体 令牌 明色 暗色 SCSS 源 备注 --lh-font-family 沿用明色 $lh-font-family--lh-font-size-extra-large 沿用明色 $lh-font-size-extra-large--lh-font-size-large 沿用明色 $lh-font-size-large--lh-font-size-medium 沿用明色 $lh-font-size-medium--lh-font-size-base 沿用明色 $lh-font-size-base--lh-font-size-small 沿用明色 $lh-font-size-small--lh-font-size-extra-small 沿用明色 $lh-font-size-extra-small--lh-font-weight-primary 沿用明色 $lh-font-weight-primary--lh-font-weight-bold 沿用明色 $lh-font-weight-bold--lh-font-line-height-primary 沿用明色 $lh-font-line-height-primary
组件级 · control 令牌 明色 暗色 SCSS 源 备注 --lh-control-height-mini 沿用明色 $lh-control-height-mini--lh-control-height-small 沿用明色 $lh-control-height-small--lh-control-height-medium 沿用明色 $lh-control-height-medium--lh-control-height-large 沿用明色 $lh-control-height-large--lh-control-height-x-large 沿用明色 $lh-control-height-x-large
间距 令牌 明色 暗色 SCSS 源 备注 --lh-spacing-xs 沿用明色 $lh-spacing-xs--lh-spacing-sm 沿用明色 $lh-spacing-sm--lh-spacing-md 沿用明色 $lh-spacing-md--lh-spacing-base 沿用明色 $lh-spacing-base--lh-spacing-lg 沿用明色 $lh-spacing-lg--lh-spacing-xl 沿用明色 $lh-spacing-xl--lh-spacing-xxl 沿用明色 $lh-spacing-xxl
层级 令牌 明色 暗色 SCSS 源 备注 --lh-z-index-normal 沿用明色 $lh-z-index-normal--lh-z-index-dropdown 沿用明色 $lh-z-index-dropdown--lh-z-index-sticky 沿用明色 $lh-z-index-sticky--lh-z-index-fixed 沿用明色 $lh-z-index-fixed--lh-z-index-modal-backdrop 沿用明色 $lh-z-index-modal-backdrop--lh-z-index-modal 沿用明色 $lh-z-index-modal--lh-z-index-popover 沿用明色 $lh-z-index-popover--lh-z-index-tooltip 沿用明色 $lh-z-index-tooltip
过渡 令牌 明色 暗色 SCSS 源 备注 --lh-transition-duration-fast 沿用明色 $lh-transition-duration-fast--lh-transition-duration-base 沿用明色 $lh-transition-duration-base--lh-transition-duration-slow 沿用明色 $lh-transition-duration-slow--lh-transition-function-ease-in-out 沿用明色 $lh-transition-function-ease-in-out
禁用态 令牌 明色 暗色 SCSS 源 备注 --lh-disabled-bg-color #242018$lh-disabled-bg-color--lh-disabled-text-color #5A5250$lh-disabled-text-color--lh-disabled-border-color #302B28$lh-disabled-border-color--lh-disabled-opacity 0.5$lh-disabled-opacity
组件级 · popover 令牌 明色 暗色 SCSS 源 备注 --lh-popover-bg-color #2A2520$lh-popover-bg-color--lh-popover-border-color #3A3530$lh-popover-border-color--lh-popover-border-radius 沿用明色 $lh-popover-border-radius--lh-popover-padding 沿用明色 $lh-popover-padding--lh-popover-title-color #E8E0D8$lh-popover-title-color--lh-popover-content-color #C8C0B8$lh-popover-content-color--lh-popover-arrow-size 沿用明色 $lh-popover-arrow-size
组件级 · popconfirm 令牌 明色 暗色 SCSS 源 备注 --lh-popconfirm-padding 沿用明色 $lh-popconfirm-padding--lh-popconfirm-icon-size 沿用明色 $lh-popconfirm-icon-size
组件级 · drawer 令牌 明色 暗色 SCSS 源 备注 --lh-drawer-bg-color #2A2520$lh-drawer-bg-color--lh-drawer-border-color #3A3530$lh-drawer-border-color--lh-drawer-header-padding 沿用明色 $lh-drawer-header-padding--lh-drawer-body-padding 沿用明色 $lh-drawer-body-padding--lh-drawer-footer-padding 沿用明色 $lh-drawer-footer-padding--lh-drawer-title-color #E8E0D8$lh-drawer-title-color--lh-drawer-close-size 沿用明色 $lh-drawer-close-size
组件级 · dropdown 令牌 明色 暗色 SCSS 源 备注 --lh-dropdown-bg-color #2A2520$lh-dropdown-bg-color--lh-dropdown-border-color #3A3530$lh-dropdown-border-color--lh-dropdown-border-radius 沿用明色 $lh-dropdown-border-radius--lh-dropdown-padding 沿用明色 $lh-dropdown-padding--lh-dropdown-item-height 沿用明色 $lh-dropdown-item-height--lh-dropdown-item-padding 沿用明色 $lh-dropdown-item-padding--lh-dropdown-item-color #C8C0B8$lh-dropdown-item-color--lh-dropdown-item-hover-bg-color var(--lh-hover-bg-color)$lh-dropdown-item-hover-bg-color--lh-dropdown-divider-color #302B28$lh-dropdown-divider-color
组件级 · message 令牌 明色 暗色 SCSS 源 备注 --lh-message-bg #2A2520$lh-message-bg-color--lh-message-border #3A3530$lh-message-border-color--lh-message-color #C8C0B8$lh-message-content-color--lh-message-shadow 沿用明色 $lh-message-shadow
组件级 · notification 令牌 明色 暗色 SCSS 源 备注 --lh-notification-bg #2A2520$lh-notification-bg-color--lh-notification-border #3A3530$lh-notification-border-color--lh-notification-title-color #E8E0D8$lh-notification-title-color--lh-notification-content-color #C8C0B8$lh-notification-content-color--lh-notification-width 沿用明色 $lh-notification-width--lh-notification-gap 沿用明色 $lh-notification-gap--lh-notification-shadow 沿用明色 $lh-notification-shadow
组件级 · loading 令牌 明色 暗色 SCSS 源 备注 --lh-loading-bg rgba(10, 8, 6, 62%)$lh-loading-bg-color--lh-loading-text-color #C8C0B8$lh-loading-text-color
组件级 · timeline 令牌 明色 暗色 SCSS 源 备注 --lh-timeline-line #302B28$lh-timeline-line--lh-timeline-dot var(--lh-info-color)$lh-timeline-dot--lh-timeline-timestamp var(--lh-text-secondary)$lh-timeline-timestamp
组件级 · collapse 令牌 明色 暗色 SCSS 源 备注 --lh-collapse-border #302B28$lh-collapse-border
组件级 · rate 令牌 明色 暗色 SCSS 源 备注 --lh-rate-active var(--lh-warning-color)$lh-rate-active
组件级 · segmented 令牌 明色 暗色 SCSS 源 备注 --lh-segmented-bg #242018$lh-segmented-bg
组件级 · calendar 令牌 明色 暗色 SCSS 源 备注 --lh-calendar-border var(--lh-border-color-lighter)$lh-calendar-border
组件级 · affix 令牌 明色 暗色 SCSS 源 备注 --lh-affix-z-index 沿用明色 $lh-affix-z-index
组件级 · backtop 令牌 明色 暗色 SCSS 源 备注 --lh-backtop-z-index 沿用明色 $lh-backtop-z-index
组件级 · menu 令牌 明色 暗色 SCSS 源 备注 --lh-menu-bg #242018$lh-menu-bg--lh-menu-padding 沿用明色 $lh-menu-padding--lh-menu-border #302B28$lh-menu-border--lh-menu-height 沿用明色 $lh-menu-height--lh-menu-collapse-width 沿用明色 $lh-menu-collapse-width--lh-menu-item-height 沿用明色 $lh-menu-item-height--lh-menu-item-padding 沿用明色 $lh-menu-item-padding--lh-menu-item-color var(--lh-text-primary)$lh-menu-item-color--lh-menu-item-hover-bg #302B28$lh-menu-item-hover-bg--lh-menu-item-active-color var(--lh-selected-color)$lh-menu-item-active-color--lh-menu-item-active-bg var(--lh-primary-color-bg)$lh-menu-item-active-bg--lh-menu-arrow-color var(--lh-text-secondary)$lh-menu-arrow-color--lh-menu-z-index 沿用明色 $lh-menu-z-index
组件级 · table 令牌 明色 暗色 SCSS 源 备注 --lh-table-bg #242018$lh-table-bg--lh-table-color var(--lh-text-regular)$lh-table-color--lh-table-header-bg #2A2420$lh-table-header-bg--lh-table-header-color var(--lh-text-primary)$lh-table-header-color--lh-table-border #302B28$lh-table-border--lh-table-row-hover-bg #2A2420$lh-table-row-hover-bg--lh-table-stripe-bg color-mix(in srgb, var(--lh-bg-color-page) 60%, transparent)$lh-table-stripe-bg--lh-table-cell-padding 沿用明色 $lh-table-cell-padding
组件级 · layout 令牌 明色 暗色 SCSS 源 备注 --lh-layout-header-height 沿用明色 $lh-layout-header-height--lh-layout-header-bg #242018$lh-layout-header-bg--lh-layout-aside-width 沿用明色 $lh-layout-aside-width--lh-layout-aside-bg #242018$lh-layout-aside-bg--lh-layout-main-bg #1C1815$lh-layout-main-bg--lh-layout-border #302B28$lh-layout-border
组件级 · row 令牌 明色 暗色 SCSS 源 备注 --lh-row-gutter 沿用明色 $lh-row-gutter
组件级 · tree 令牌 明色 暗色 SCSS 源 备注 --lh-tree-color #D8D0C8$lh-tree-color--lh-tree-padding 沿用明色 $lh-tree-padding--lh-tree-node-height 沿用明色 $lh-tree-node-height--lh-tree-node-hover-bg #2A2420$lh-tree-node-hover-bg--lh-tree-node-selected-color var(--lh-selected-color)$lh-tree-node-selected-color--lh-tree-node-selected-bg var(--lh-primary-color-bg)$lh-tree-node-selected-bg--lh-tree-arrow-color var(--lh-text-secondary)$lh-tree-arrow-color
组件级 · transfer 令牌 明色 暗色 SCSS 源 备注 --lh-transfer-panel-width 沿用明色 $lh-transfer-panel-width--lh-transfer-panel-height 沿用明色 $lh-transfer-panel-height--lh-transfer-bg #242018$lh-transfer-bg--lh-transfer-border #302B28$lh-transfer-border
组件级 · upload 令牌 明色 暗色 SCSS 源 备注 --lh-upload-bg #242018$lh-upload-bg--lh-upload-border var(--lh-border-color-base)$lh-upload-border--lh-upload-trigger-padding 沿用明色 $lh-upload-trigger-padding
组件级 · anchor 令牌 明色 暗色 SCSS 源 备注 --lh-anchor-color var(--lh-text-regular)$lh-anchor-color
组件级 · image 令牌 明色 暗色 SCSS 源 备注 --lh-image-viewer-mask rgba(0, 0, 0, 80%)—
无障碍焦点环 令牌 明色 暗色 SCSS 源 备注 --lh-focus-color #7FA6D9$lh-primary--lh-focus-ring-width 沿用明色 — --lh-focus-ring-offset 沿用明色 —
ثلاث وسائل من الأضعف إلى الأقوى:
البند السابع من pnpm verify:styles (إمكانية الوصول الداكنة) : فحص ساكن، يجد
الرموز «المخبوزة فاتحة دون تجاوز في var-dark». وهذه بوابة CI.
pnpm verify:theme (AA 4.5:1) : يقرأ مخرجات es/ ويحسب نسب تباين المسبقات في
الوضعين الفاتح والداكن. يتطلب تشغيل pnpm build أولًا. لا يُشغَّل في CI، بل يحرسه
المستخدم يدويًا.
الفحص البصري : تبديل الوضع الداكن في موقع docs / ساحات تجربة كل مكتبة ومراجعة
كل مكوّن.
قائمة مراجعة ذاتية عند إضافة رمز جديد:
تم في 0.4.0 تدارك نقص الوضع الداكن بشكل منهجي (مشكلة عدم ظهور نصوص القوائم /
الجداول / الخطوط الزمنية، انظر changeset). أما البنود المعروفة المتبقية فتُعالج مع
«مشروع رموز الارتفاع» لاحقًا.