優(yōu)維低代碼:Theme -u0026 Mode 頁面主題和模式(優(yōu)維 cmdb)
優(yōu)維低代碼技術(shù)專欄,是一個(gè)全新的、技術(shù)為主的專欄,由優(yōu)維技術(shù)委員會(huì)成員執(zhí)筆,基于優(yōu)維7年低代碼技術(shù)研發(fā)及運(yùn)維成果,主要介紹低代碼相關(guān)的技術(shù)原理及架構(gòu)邏輯,目的是給廣大運(yùn)維人提供一個(gè)技術(shù)交流與學(xué)習(xí)的平臺(tái)。
連載第三十一期
《高級指引:Theme & Mode 頁面主題和模式》
▽
⊙ NOTE
Brick Next 從 2.7.1 開始支持頁面主題和模式。
Brick Next 支持兩種主題:light 和 dark(默認(rèn)為 light),以及兩種模式:default 和 dashboard(默認(rèn)為 default)。
在 dark 深色主題下,頁面框架及構(gòu)件將以深色背景樣式顯示。而在 dashboard 大屏模式下,系統(tǒng)的頁面頂欄及側(cè)欄將消失,同時(shí)配合 basic-bricks.micro-view 開啟 dashboardMode: true 可以實(shí)現(xiàn)大屏效果。
目前主要在“大屏”場景下使用,注意該場景需要同時(shí)啟用深色主題和大屏模式。
# 微應(yīng)用編排:切換主題和模式
例如在 Storyboard 編排中,希望某個(gè)按鈕點(diǎn)擊后切換到“深色 大屏”場景,可以如下配置:
brick: "your-button"events: click: - action: "theme.setDarkTheme" - action: "mode.setDashboardMode"
每當(dāng)頁面初始進(jìn)入、或發(fā)生跳轉(zhuǎn)并重新渲染前,系統(tǒng)將自動(dòng)切回淺色主題和默認(rèn)模式,但系統(tǒng)開放了一個(gè)窗口期 onBeforePageLoad,以支持頁面可以設(shè)置初始化為深色主題及大屏模式。
例如假設(shè)我們希望 URL 中攜帶參數(shù) mode=dashboard 時(shí)自動(dòng)使用深色主題和大屏模式,可以如下配置:
brick: "basic-bricks.micro-view"lifeCycle: onBeforePageLoad: - if: "<% QUERY.mode === 'dashboard' %>" action: "theme.setDarkTheme" - if: "<% QUERY.mode === 'dashboard' %>" action: "mode.setDashboardMode"properties: dashboardMode: "<% QUERY.mode === 'dashboard' %>"
注意 basic-bricks.micro-view 構(gòu)件在大屏模式下會(huì)多一個(gè)退出按鈕,點(diǎn)擊后將發(fā)出 mode.dashboard.exit 事件,需要用戶自行配置退出大屏需要執(zhí)行的動(dòng)作。例如通常應(yīng)添加如下事件配置:
brick: "basic-bricks.micro-view"events: mode.dashboard.exit: - target: "_self" properties: dashboardMode: false - action: "theme.setLightTheme" - action: "mode.setDefaultMode"
不內(nèi)置退出動(dòng)作的原因是,用戶可以通過其他方式退出大屏,例如通過 history.pushQuery 跳轉(zhuǎn)重置 mode=dashboard 參數(shù)來實(shí)現(xiàn)退出大屏模式:
brick: "basic-bricks.micro-view"events: mode.dashboard.exit: - action: "history.pushQuery" args: - mode: null
⊙ IMPORTANT
不要在編排中為構(gòu)件配置固定的顏色值,而應(yīng)使用系統(tǒng)預(yù)定義的 css custom properties,具體可以參考本文下一節(jié)內(nèi)容。
# 構(gòu)件開發(fā):適配深色主題和大屏模式
系統(tǒng)通過定義一系列 CSS custom properties(又稱 CSS variables)來實(shí)現(xiàn)主題樣式的實(shí)時(shí)無縫切換,無論在編排或構(gòu)件開發(fā)時(shí)應(yīng)首先嘗試使用這些屬性。具體屬性列表可以參考這里的源碼。
系統(tǒng)當(dāng)前的主題和模式反饋在<html>元素的 data-theme 及 data-mode 屬性上,因此僅使用 css 即可完成大部分深色主題和大屏模式的適配。例如:
.your-class { color: black;}html[data-theme="dark"] .your-class { color: white;}
當(dāng)使用系統(tǒng)預(yù)定義的 CSS custom properties 時(shí),則無需額外配置 html[data-theme="dark"] 樣式:
.your-class { color: var(--text-color-default);}
有時(shí)候構(gòu)件需要在 JavaScript 中判斷當(dāng)前主題或模式,例如圖表類構(gòu)件需要根據(jù)當(dāng)前主題來生成不同的顏色列表,對此系統(tǒng)提供了 React Hooks useCurrentTheme 和 useCurrentMode 來獲取當(dāng)前的主題和模式,例如:
import { useCurrentTheme } from "@next-core/brick-kit";function YourComponent() { const theme = useCurrentTheme(); const colors = theme === "dark" ? ["red", "green"] : ["blue", "orange"]; return <YourChart colors={colors} />;}
# 適配公共 UI 規(guī)范樣式
使用 Less
Brick Next 的 UI 底層基于 Ant Design,在適配我們自己的 UI 規(guī)范相關(guān)的樣式時(shí),應(yīng)結(jié)合 Ant Design 的底層技術(shù) Less 的能力,盡量通過使用或覆蓋已有的 Less 預(yù)定義變量值來實(shí)現(xiàn)樣式更新,而不是使用固定的顏色值。例如:
// ? Good:// In `packages/custom-antd-styles/src/var.less`:@link-hover-color: #0071eb;// ? Bad:// In `packages/custom-antd-styles/src/link.less`a:hover { color: #0071eb;}
// ? Good:// In `bricks/your-brick/src/style.less`:.your-class { color: @link-hover-color;}// ? Bad:// In `bricks/your-brick/src/style.less`.your-class { color: #0071eb;}
Brick Next 的 Antd Less 變量統(tǒng)一管理在 next-core 倉庫的 packages/custom-antd-styles/src/var.less 中。
# 使用 CSS Variables
由于 Less 的處理發(fā)生在編譯階段,無法在運(yùn)行時(shí)提供切換變量的能力,因此為了實(shí)現(xiàn)運(yùn)行時(shí)深色主題的自由切換,我們還需要結(jié)合使用 CSS custom properties(又稱 CSS variables)。
對于色值一類的樣式(例如 color: #fff)通常需要為默認(rèn)主題和深色主題配置不同的色值,此時(shí),我們可以將 Antd 中對應(yīng)的 Less 變量設(shè)置為 CSS variables,并針對不同主題分別設(shè)置不同的色值。例如:
// In `packages/custom-antd-styles/src/var.less`:@text-color: var(--antd-text-color);
/* In `packages/brick-container/src/styles/variables.css`: */:root { --antd-text-color: rgba(0, 0, 0, 0.85);}html[data-theme="dark"] { --antd-text-color: #c6cfd9;}
⊙ NOTE
注意我們統(tǒng)一使用 –antd- 作為前綴加上對應(yīng)的 Antd Less 變量名作為 Antd 相關(guān)的 CSS variable name。
Brick Next 的 CSS variables 統(tǒng)一管理在 next-core 倉庫的 packages/brick-container/src/styles/variables.css 中。
# 處理 Less 編譯報(bào)錯(cuò)
由于 Antd 大量使用了色值計(jì)算(例如 darken(…) lighten(…) 等),這些計(jì)算無法兼容 CSS variable,因此有時(shí)當(dāng)我們使用 CSS variable 作為 Less 的變量值時(shí),構(gòu)建 Less 可能會(huì)報(bào)錯(cuò),對此的解決方案是使用我們自定義的 LessReplacer 插件,將這些報(bào)錯(cuò)的色值計(jì)算代碼進(jìn)行替換。
例如:
// In `packages/less-plugin-css-variables/src/LessReplacer.js`:const rawStringMap = { "darken(@item-active-bg, 2%)": "var(--antd-item-active-bg-darken-2)",};
以上配置將把 Antd Less 文件中所有的 darken(@item-active-bg, 2%) 替換為 var(–antd-item-active-bg-darken-2),注意變量命名方法為「–antd- 前綴 Antd Less 變量名 方法名 參數(shù)值」。
又例如:
// In `packages/less-plugin-css-variables/src/LessReplacer.js`:const variableMap = { "table-header-sort-active-bg": true,};
以上配置將把 Antd Less 文件中所有的 @table-header-sort-active-bg: **;(假設(shè) ** 為包含色值計(jì)算等導(dǎo)致 Less 編譯報(bào)錯(cuò)的代碼)的定義替換為 @table-header-sort-active-bg: var(–antd-table-header-sort-active-bg)。
注意這些新增的 –antd-* 需要在 packages/brick-container/src/styles/variables.css 中寫好定義。