zent
Version:
一套前端设计语言和基于React的实现
256 lines (225 loc) • 5.29 kB
Markdown
---
order: 1
zh-CN:
title: 获取主题色
triggerText: 复制所有变量
changePrompt: 切换到
en-US:
title: Get theme color
triggerText: Copy All Variables
changePrompt: Switch to
---
```jsx
import { ColorPicker, Grid, CopyButton, Button, Icon, WindowEventHandler } from 'zent';
import { ThemeSdk, ThemeScene } from '@zent/theme-sdk';
import ThemeCssVars from 'zent/theme-css-vars.json';
import { hexToRGBString } from '@zent/theme-sdk/esm/utils';
import { useState, useMemo, useCallback, useEffect } from 'react';
const { generateTheme } = ThemeSdk;
const colors = [
'#ed6a18',
'#ed9f18',
'#edd418',
'#bad415',
'#5bd415',
'#15d48e',
'#15bad4',
'#155bd4',
'#412ad4',
'#8e15d4',
'#d415ba',
'#d42f15',
];
const defaultColor = '#155bd4';
const themeIndex = {
'$primary-100': 0,
'$primary-400': 1,
'$primary-500': 2,
'$primary-600': 3,
};
const ColorType = {
hex: 'Hex',
rgb: 'Rgb',
};
const ColorScene = [
ThemeScene.DefaultHoverBackgroundColor,
ThemeScene.PrimaryHoverBackgroundColor,
ThemeScene.PrimaryBackgroundColor,
ThemeScene.PrimaryActiveBackgroundColor,
];
const getThemeCommentsVars = colors => {
return colors.filter(
({ cssVariableName }) => ThemeCssVars.vars[cssVariableName]
);
};
const transformToCss = theme => {
return theme
.map(item => `${item.cssVariableName}: ${item.color};`)
.join('\n');
};
const getSessionThemeColor = () => {
// ThemeSwitcher on top-right corner sets this variable
return window.sessionStorage.getItem('zent-theme-color') ?? defaultColor;
};
const Color = ({ colorType, setColorType }) => {
const otherType = colorType === ColorType.hex ? ColorType.rgb : ColorType.hex;
const changeColorType = useCallback(() => {
setColorType(otherType);
}, [setColorType, otherType]);
return (
<>
{colorType} Color
<Button
className="demo-theme-color-copy-switcher"
size="small"
onClick={changeColorType}
>
{i18n.changePrompt} {otherType}
</Button>
</>
);
};
const ThemeSdkComponent = () => {
const [color, setColor] = useState(getSessionThemeColor());
const theme = useMemo(() => {
return generateTheme(
{ colors: [{ baseColor: color, scene: ColorScene }] },
ThemeCssVars
);
}, [color]);
const themeComments = useMemo(() => {
return getThemeCommentsVars(theme.colors);
}, [theme]);
const themeCssStr = useMemo(() => {
return transformToCss(theme.colors);
}, [theme]);
const [colorType, setColorType] = useState(ColorType.hex);
const columns = useMemo(() => {
return [
{
title: 'CSS Variable',
name: 'cssVariableName',
bodyRender: ({ cssVariableName }) => {
return (
<div className="demo-theme-color-title">
<p className="demo-theme-color-css-variable">
{cssVariableName}
<CopyButton text={cssVariableName}>
<Icon className="demo-theme-color-copy-icon" type="order-o" />
</CopyButton>
</p>
<p className="demo-theme-color-desc">
{ThemeCssVars.vars[cssVariableName].comment}
</p>
</div>
);
},
},
{
title: <Color colorType={colorType} setColorType={setColorType} />,
name: 'color',
bodyRender: ({ color }) => {
const colorText =
colorType === ColorType.rgb ? hexToRGBString(color) : color;
return (
<div className="demo-theme-color">
<CopyButton text={colorText}>
<p
className="demo-theme-color-block"
style={{ background: color }}
></p>
</CopyButton>
<div className="demo-theme-color-name">{colorText}</div>
</div>
);
},
width: '300px',
},
];
}, [colorType]);
const onColorChange = useCallback(
baseColor => {
setColor(baseColor);
},
[]
);
const onThemeSwitch = useCallback((evt) => {
onColorChange(evt.detail);
}, []);
return (
<>
<div>
<ColorPicker
color={color}
type="simple"
onChange={onColorChange}
presetColors={colors}
/>
<span className="demo-theme-base-color">{color}</span>
<CopyButton text={themeCssStr}>
<Button type="primary" className="demo-theme-copy-btn">
{i18n.triggerText}
</Button>
</CopyButton>
</div>
<Grid
rowKey="cssVariableName"
className="demo-theme-colors"
columns={columns}
datasets={themeComments}
/>
<WindowEventHandler eventName="zent-theme-change" listener={onThemeSwitch} />
</>
);
};
ReactDOM.render(<ThemeSdkComponent />, mountNode);
```
<style>
.demo-theme-color-title {
font-size: 14px;
color: #333;
}
.demo-theme-color-css-variable {
cursor: pointer;
}
.demo-theme-color-desc {
font-size: 12px;
color: #999;
}
.demo-theme-color {
margin: 4px 8px 4px 4px;
display: flex;
align-items: center;
}
.demo-theme-color-copy-switcher {
margin-left: 16px;
}
.demo-theme-color-block {
width: 80px;
height: 30px;
margin-bottom: 4px;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
color: #000;
cursor: pointer;
}
.demo-theme-color-copy-icon {
margin-left: 4px;
}
.demo-theme-color-name {
color: #333;
text-align: center;
margin-left: 4px;
}
.demo-theme-base-color {
margin-left: 8px;
}
.demo-theme-copy-btn {
float: right;
}
.demo-theme-colors {
margin-top: 16px;
}
</style>