Skip to content

Commit

Permalink
feat: add css var prefix support of arco theme
Browse files Browse the repository at this point in the history
  • Loading branch information
zamhown committed Jan 29, 2024
1 parent d9127d1 commit 2552be1
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 119 deletions.
194 changes: 100 additions & 94 deletions packages/vchart-arco-theme/src/common/token-map.ts
Original file line number Diff line number Diff line change
@@ -1,103 +1,109 @@
import type { DataSchemeTokenMap, PaletteTokenMap } from '@visactor/vchart-theme-utils/esm/interface';

export const paletteTokenMap: PaletteTokenMap = {
/** 背景色 */
backgroundColor: '--color-bg-1',
/** 图表边框色 */
borderColor: '--color-border',
/** 鼠标 hover 项背景颜色 */
hoverBackgroundColor: '--color-secondary-hover',
/** 滑块类组件背景条填充颜色 */
sliderRailColor: '--color-fill-3',
/** 滑块类组件滑块填充颜色 */
sliderHandleColor: '--color-bg-2',
/** 滑块类组件已选范围填充颜色 */
sliderTrackColor: '--primary-6',
/** 浮层背景区域颜色 */
popupBackgroundColor: '--color-bg-popup',
export const getPaletteTokenMap = (prefix?: string): PaletteTokenMap => {
const prefixStr = prefix ? `${prefix}${prefix[prefix.length - 1] === '-' ? '' : '-'}` : '';
return {
/** 背景色 */
backgroundColor: `--${prefixStr}color-bg-1`,
/** 图表边框色 */
borderColor: `--${prefixStr}color-border`,
/** 鼠标 hover 项背景颜色 */
hoverBackgroundColor: `--${prefixStr}color-secondary-hover`,
/** 滑块类组件背景条填充颜色 */
sliderRailColor: `--${prefixStr}color-fill-3`,
/** 滑块类组件滑块填充颜色 */
sliderHandleColor: `--${prefixStr}color-bg-2`,
/** 滑块类组件已选范围填充颜色 */
sliderTrackColor: '--primary-6',
/** 浮层背景区域颜色 */
popupBackgroundColor: `--${prefixStr}color-bg-popup`,

/** 主要字色 */
primaryFontColor: '--color-text-1',
/** 次要字色 */
secondaryFontColor: '--color-text-2',
/** 第三字色 */
tertiaryFontColor: '--color-text-3',
/** 轴标签字色 */
axisLabelFontColor: '--color-text-3',
/** 禁用字色 */
disableFontColor: '--color-text-4',
/** 轴高亮标记字色 */
axisMarkerFontColor: '--color-bg-1',
/** 主要字色 */
primaryFontColor: `--${prefixStr}color-text-1`,
/** 次要字色 */
secondaryFontColor: `--${prefixStr}color-text-2`,
/** 第三字色 */
tertiaryFontColor: `--${prefixStr}color-text-3`,
/** 轴标签字色 */
axisLabelFontColor: `--${prefixStr}color-text-3`,
/** 禁用字色 */
disableFontColor: `--${prefixStr}color-text-4`,
/** 轴高亮标记字色 */
axisMarkerFontColor: `--${prefixStr}color-bg-1`,

/** 轴网格线颜色 */
axisGridColor: '--color-border',
/** 轴线颜色 */
axisDomainColor: '--color-neutral-3',
/** 缩略轴滑块描边颜色 */
dataZoomHandlerStrokeColor: '--color-neutral-5',
/** 缩略轴图表区域颜色 */
dataZoomChartColor: '--color-fill-4',
/** 轴网格线颜色 */
axisGridColor: `--${prefixStr}color-border`,
/** 轴线颜色 */
axisDomainColor: `--${prefixStr}color-neutral-3`,
/** 缩略轴滑块描边颜色 */
dataZoomHandlerStrokeColor: `--${prefixStr}color-neutral-5`,
/** 缩略轴图表区域颜色 */
dataZoomChartColor: `--${prefixStr}color-fill-4`,

/** 播放器控制器填充颜色 */
playerControllerColor: '--primary-6',
/** 播放器控制器填充颜色 */
playerControllerColor: '--primary-6',

/** 轴高亮标记背景色 */
axisMarkerBackgroundColor: '--color-text-1',
/** 标注标签背景颜色 */
markLabelBackgroundColor: '--color-border',
/** 标注线颜色 */
markLineStrokeColor: '--color-text-2',
/** 轴高亮标记背景色 */
axisMarkerBackgroundColor: `--${prefixStr}color-text-1`,
/** 标注标签背景颜色 */
markLabelBackgroundColor: `--${prefixStr}color-border`,
/** 标注线颜色 */
markLineStrokeColor: `--${prefixStr}color-text-2`,

/** 危险色 */
dangerColor: '--danger-6',
/** 警告色 */
warningColor: '--warning-6',
/** 成功色 */
successColor: '--success-6',
/** 信息色 */
infoColor: '--arcoblue-6'
/** 危险色 */
dangerColor: '--danger-6',
/** 警告色 */
warningColor: '--warning-6',
/** 成功色 */
successColor: '--success-6',
/** 信息色 */
infoColor: '--arcoblue-6'
};
};

export const dataSchemeTokenMap: DataSchemeTokenMap = [
// 第一档颜色(数据项 <= 10)
{
maxDomainLength: 10,
scheme: [
'--color-data-1',
'--color-data-3',
'--color-data-5',
'--color-data-7',
'--color-data-9',
'--color-data-11',
'--color-data-13',
'--color-data-15',
'--color-data-17',
'--color-data-19'
]
},
// 第二档颜色(数据项 > 10)
{
scheme: [
'--color-data-1',
'--color-data-2',
'--color-data-3',
'--color-data-4',
'--color-data-5',
'--color-data-6',
'--color-data-7',
'--color-data-8',
'--color-data-9',
'--color-data-10',
'--color-data-11',
'--color-data-12',
'--color-data-13',
'--color-data-14',
'--color-data-15',
'--color-data-16',
'--color-data-17',
'--color-data-18',
'--color-data-19',
'--color-data-20'
]
}
];
export const getDataSchemeTokenMap = (prefix?: string): DataSchemeTokenMap => {
const prefixStr = prefix ? `${prefix}${prefix[prefix.length - 1] === '-' ? '' : '-'}` : '';
return [
// 第一档颜色(数据项 <= 10)
{
maxDomainLength: 10,
scheme: [
`--${prefixStr}color-data-1`,
`--${prefixStr}color-data-3`,
`--${prefixStr}color-data-5`,
`--${prefixStr}color-data-7`,
`--${prefixStr}color-data-9`,
`--${prefixStr}color-data-11`,
`--${prefixStr}color-data-13`,
`--${prefixStr}color-data-15`,
`--${prefixStr}color-data-17`,
`--${prefixStr}color-data-19`
]
},
// 第二档颜色(数据项 > 10)
{
scheme: [
`--${prefixStr}color-data-1`,
`--${prefixStr}color-data-2`,
`--${prefixStr}color-data-3`,
`--${prefixStr}color-data-4`,
`--${prefixStr}color-data-5`,
`--${prefixStr}color-data-6`,
`--${prefixStr}color-data-7`,
`--${prefixStr}color-data-8`,
`--${prefixStr}color-data-9`,
`--${prefixStr}color-data-10`,
`--${prefixStr}color-data-11`,
`--${prefixStr}color-data-12`,
`--${prefixStr}color-data-13`,
`--${prefixStr}color-data-14`,
`--${prefixStr}color-data-15`,
`--${prefixStr}color-data-16`,
`--${prefixStr}color-data-17`,
`--${prefixStr}color-data-18`,
`--${prefixStr}color-data-19`,
`--${prefixStr}color-data-20`
]
}
];
};
12 changes: 8 additions & 4 deletions packages/vchart-arco-theme/src/generator.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import type { IColorSchemeStruct, ITheme, IThemeColorScheme, ProgressiveDataScheme } from '@visactor/vchart';
import { arcoDesignDark } from './dark';
import { arcoDesignLight } from './light';
import { dataSchemeTokenMap, paletteTokenMap } from './common/token-map';
import { getDataSchemeTokenMap, getPaletteTokenMap } from './common/token-map';
import { generateDataScheme, generatePalette } from '@visactor/vchart-theme-utils';

const baseThemeMap = {
light: arcoDesignLight,
dark: arcoDesignDark
};

export const generateVChartArcoTheme = (mode: 'light' | 'dark', chartContainer?: HTMLElement): ITheme => {
export const generateVChartArcoTheme = (
mode: 'light' | 'dark',
prefix?: string,
chartContainer?: HTMLElement
): ITheme => {
const baseTheme = baseThemeMap[mode];
const { dataScheme, palette } = baseTheme.colorScheme.default as IColorSchemeStruct;
const colorScheme: IThemeColorScheme = {
default: {
dataScheme: generateDataScheme(
mode,
dataSchemeTokenMap,
getDataSchemeTokenMap(prefix),
dataScheme as ProgressiveDataScheme<string>,
chartContainer
),
palette: generatePalette(mode, paletteTokenMap, palette, chartContainer)
palette: generatePalette(mode, getPaletteTokenMap(prefix), palette, chartContainer)
}
};
return {
Expand Down
26 changes: 16 additions & 10 deletions packages/vchart-arco-theme/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ITheme } from '@visactor/vchart';
// eslint-disable-next-line no-duplicate-imports
import VChart from '@visactor/vchart';
import { ThemeManager } from '@visactor/vchart';
import type { IInitVChartArcoThemeOption } from './interface';
import { generateThemeName, getCurrentMode, observeAttribute } from './util';
import { generateVChartArcoTheme } from './generator';
Expand All @@ -11,27 +11,33 @@ export * from './light';
export * from './dark';

export const initVChartArcoTheme = (options?: IInitVChartArcoThemeOption) => {
const { defaultMode, isWatchingMode = true } = options ?? {};
const { defaultMode, isWatchingMode = true, prefix, themeManager = ThemeManager } = options ?? {};

switchVChartArcoTheme(false, defaultMode);
switchVChartArcoTheme(themeManager, prefix, false, defaultMode);

if (isWatchingMode) {
observeAttribute(document.body, 'arco-theme', () => switchVChartArcoTheme());
observeAttribute(document.body, 'arco-theme', () => switchVChartArcoTheme(themeManager, prefix));
}
};

export const switchVChartArcoTheme = (force?: boolean, mode?: 'light' | 'dark', theme?: ITheme) => {
export const switchVChartArcoTheme = (
themeManager: typeof ThemeManager,
prefix?: string,
force?: boolean,
mode?: 'light' | 'dark',
theme?: ITheme
) => {
if (!mode) {
mode = getCurrentMode();
}
const themeName = generateThemeName(mode);
if (!force && VChart.ThemeManager.getCurrentTheme() === themeName) {
if (!force && themeManager.getCurrentTheme() === themeName) {
return;
} else if (force) {
VChart.ThemeManager.removeTheme(themeName);
themeManager.removeTheme(themeName);
}
if (!VChart.ThemeManager.themeExist(themeName)) {
VChart.ThemeManager.registerTheme(themeName, theme ?? generateVChartArcoTheme(mode));
if (!themeManager.themeExist(themeName)) {
themeManager.registerTheme(themeName, theme ?? generateVChartArcoTheme(mode, prefix));
}
VChart.ThemeManager.setCurrentTheme(themeName);
themeManager.setCurrentTheme(themeName);
};
6 changes: 6 additions & 0 deletions packages/vchart-arco-theme/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import type { ThemeManager } from '@visactor/vchart';

export interface IInitVChartArcoThemeOption {
/** 初始亮暗色模式 */
defaultMode?: 'light' | 'dark';
/** 是否监听亮暗色模式自动更改图表主题 */
isWatchingMode?: boolean;
/** 指定 ThemeManager,一般不用指定,如果遇到多版本 vchart 共存时需要指定 */
themeManager?: typeof ThemeManager;
/** arco css 变量前缀,例如:原始变量名为`--color-data-1`,配置为`"arco"`后变为`--arco-color-data-1` */
prefix?: string;
}
32 changes: 21 additions & 11 deletions packages/vchart-semi-theme/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { ITheme } from '@visactor/vchart';
// eslint-disable-next-line no-duplicate-imports
import VChart from '@visactor/vchart';
import { ThemeManager } from '@visactor/vchart';
import type { IInitVChartSemiThemeOption } from './interface';
import { generateThemeName, getCurrentMode, observeAttribute, observeThemeSwitch } from './util';
import { generateVChartSemiTheme } from './generator';
Expand All @@ -12,12 +12,17 @@ export * from './light';
export * from './dark';

export const initVChartSemiTheme = (options?: IInitVChartSemiThemeOption) => {
const { defaultMode, isWatchingMode = true, isWatchingThemeSwitch = false } = options ?? {};
const {
defaultMode,
isWatchingMode = true,
isWatchingThemeSwitch = false,
themeManager = ThemeManager
} = options ?? {};

switchVChartSemiTheme(false, defaultMode);
switchVChartSemiTheme(themeManager, false, defaultMode);

if (isWatchingMode) {
observeAttribute(document.body, THEME_MODE_ATTRIBUTE, () => switchVChartSemiTheme());
observeAttribute(document.body, THEME_MODE_ATTRIBUTE, () => switchVChartSemiTheme(themeManager));
}
if (isWatchingThemeSwitch) {
observeThemeSwitch(() => {
Expand All @@ -28,7 +33,7 @@ export const initVChartSemiTheme = (options?: IInitVChartSemiThemeOption) => {
const timer = setInterval(() => {
const theme = generateVChartSemiTheme(mode);
if (times > 50 || cacheColorScheme !== JSON.stringify(theme.colorScheme)) {
switchVChartSemiTheme(true, mode, theme);
switchVChartSemiTheme(themeManager, true, mode, theme);
clearInterval(timer);
}
times++;
Expand All @@ -37,18 +42,23 @@ export const initVChartSemiTheme = (options?: IInitVChartSemiThemeOption) => {
}
};

export const switchVChartSemiTheme = (force?: boolean, mode?: 'light' | 'dark', theme?: ITheme) => {
export const switchVChartSemiTheme = (
themeManager: typeof ThemeManager,
force?: boolean,
mode?: 'light' | 'dark',
theme?: ITheme
) => {
if (!mode) {
mode = getCurrentMode();
}
const themeName = generateThemeName(mode);
if (!force && VChart.ThemeManager.getCurrentTheme() === themeName) {
if (!force && themeManager.getCurrentTheme() === themeName) {
return;
} else if (force) {
VChart.ThemeManager.removeTheme(themeName);
themeManager.removeTheme(themeName);
}
if (!VChart.ThemeManager.themeExist(themeName)) {
VChart.ThemeManager.registerTheme(themeName, theme ?? generateVChartSemiTheme(mode));
if (!themeManager.themeExist(themeName)) {
themeManager.registerTheme(themeName, theme ?? generateVChartSemiTheme(mode));
}
VChart.ThemeManager.setCurrentTheme(themeName);
themeManager.setCurrentTheme(themeName);
};
4 changes: 4 additions & 0 deletions packages/vchart-semi-theme/src/interface.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import type { ThemeManager } from '@visactor/vchart';

export interface IInitVChartSemiThemeOption {
/** 初始亮暗色模式 */
defaultMode?: 'light' | 'dark';
/** 是否监听亮暗色模式自动更改图表主题 */
isWatchingMode?: boolean;
/** 是否监听主题变化自动更改图表主题(适用于 semi 官方主题切换接口:https://semi.design/dsm/install_switcher)*/
isWatchingThemeSwitch?: boolean;
/** 指定 ThemeManager,一般不用指定,如果遇到多版本 vchart 共存时需要指定 */
themeManager?: typeof ThemeManager;
}

0 comments on commit 2552be1

Please sign in to comment.