feat(color): remove built-in theme and get palette from tvision color (#392)

* feat(color): remove built-in theme and get all palette from tvision color

* feat: sync color to charts

* chore: move color utils to utils dir

* fix: dynamic theme color init

* feat: card with default nobordered
This commit is contained in:
yuyang 2023-01-10 15:41:24 +08:00 committed by GitHub
parent 02ea472748
commit 61abcdd28e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 147 additions and 508 deletions

View File

@ -30,7 +30,7 @@
"qs": "^6.10.5",
"tdesign-icons-vue-next": "^0.1.7",
"tdesign-vue-next": "^1.0.0",
"tvision-color": "^1.3.1",
"tvision-color": "^1.5.0",
"vue": "^3.2.31",
"vue-clipboard3": "^2.0.0",
"vue-router": "~4.1.5"

View File

@ -3,10 +3,7 @@
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { getBrandColor } from '@/config/color';
import { useSettingStore } from '@/store';
const store = useSettingStore();
import { DEFAULT_COLOR_OPTIONS } from '@/config/color';
const panelColor =
'conic-gradient(from 90deg at 50% 50%, #FF0000 -19.41deg, #FF0000 18.76deg, #FF8A00 59.32deg, #FFE600 99.87deg, #14FF00 141.65deg, #00A3FF 177.72deg, #0500FF 220.23deg, #AD00FF 260.13deg, #FF00C7 300.69deg, #FF0000 340.59deg, #FF0000 378.76deg)';
@ -19,17 +16,17 @@ const props = defineProps({
const style = computed(() => {
const { value } = props;
const { colorList } = store;
return {
background: value !== 'dynamic' ? getBrandColor(value, colorList)['--td-brand-color'] : panelColor,
background: DEFAULT_COLOR_OPTIONS.indexOf(value) > -1 ? value : panelColor,
};
});
</script>
<style lang="less" scoped>
.color-container {
width: 24px;
height: 24px;
border-radius: 50%;
border-radius: var(--td-radius-circle);
display: inline-block;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<t-card theme="poster2">
<t-card theme="poster2" :bordered="false">
<template #avatar>
<t-avatar size="56px">
<template #icon>

View File

@ -1,138 +1,7 @@
/* eslint-disable indent */
import { Color } from 'tvision-color';
export type TColorToken = Record<string, string>;
export type TColorSeries = Record<string, TColorToken>;
export const defaultLightColor = [
'#0052d9',
'#0594fa',
'#00a870',
'#ebb105',
'#ed7b2f',
'#e34d59',
'#ed49b4',
'#834ec2',
];
export const defaultDarkColor = [
'#4582e6',
'#29a4fb',
'#03a56f',
'#ca8d03',
'#ed7b2f',
'#ea7b84',
'#f172c5',
'#ab87d5',
];
export const COLOR_TOKEN: TColorSeries = {
DEFAULT: {
'--td-brand-color': '#0052d9',
'--td-brand-color-1': '#f2f3ff',
'--td-brand-color-2': '#d9e1ff',
'--td-brand-color-3': '#b5c7ff',
'--td-brand-color-4': '#8eabff',
'--td-brand-color-5': '#618dff',
'--td-brand-color-6': '#366ef4',
'--td-brand-color-7': '#0052d9',
'--td-brand-color-8': '#003cab',
'--td-brand-color-9': '#002a7c',
'--td-brand-color-10': '#001a57',
},
CYAN: {
'--td-brand-color': '#0594FA',
'--td-brand-color-1': '#d7eefe',
'--td-brand-color-2': '#aeddfd',
'--td-brand-color-3': '#84cafd',
'--td-brand-color-4': '#58b8fc',
'--td-brand-color-5': '#29a4fb',
'--td-brand-color-6': '#0594FA',
'--td-brand-color-7': '#29a4fb',
'--td-brand-color-8': '#0594FA',
'--td-brand-color-9': '#0378df',
'--td-brand-color-10': '#01409b',
},
GREEN: {
'--td-brand-color': '#00A870',
'--td-brand-color-1': '#8dffd9',
'--td-brand-color-2': '#00f2a2',
'--td-brand-color-3': '#00dc92',
'--td-brand-color-4': '#00c583',
'--td-brand-color-5': '#00A870',
'--td-brand-color-6': '#009a5d',
'--td-brand-color-7': '#00c583',
'--td-brand-color-8': '#00A870',
'--td-brand-color-9': '#009a5d',
'--td-brand-color-10': '#004a14',
},
ORANGE: {
'--td-brand-color': '#ED7B2F',
'--td-brand-color-1': '#fce5d7',
'--td-brand-color-2': '#f8cdaf',
'--td-brand-color-3': '#f4b285',
'--td-brand-color-4': '#f19659',
'--td-brand-color-5': '#ED7B2F',
'--td-brand-color-6': '#e75510',
'--td-brand-color-7': '#f19659',
'--td-brand-color-8': '#ED7B2F',
'--td-brand-color-9': '#e75510',
'--td-brand-color-10': '#7f0a02',
},
RED: {
'--td-brand-color': '#E34D59',
'--td-brand-color-1': '#fbe5e7',
'--td-brand-color-2': '#f7ccd0',
'--td-brand-color-3': '#f3b2b8',
'--td-brand-color-4': '#ef989f',
'--td-brand-color-5': '#ea7b84',
'--td-brand-color-6': '#E34D59',
'--td-brand-color-7': '#ea7b84',
'--td-brand-color-8': '#E34D59',
'--td-brand-color-9': '#e42c3a',
'--td-brand-color-10': '#8d0309',
},
PINK: {
'--td-brand-color': '#ED49B4',
'--td-brand-color-1': '#fce5f4',
'--td-brand-color-2': '#facae9',
'--td-brand-color-3': '#f7aede',
'--td-brand-color-4': '#f491d2',
'--td-brand-color-5': '#f172c5',
'--td-brand-color-6': '#ED49B4',
'--td-brand-color-7': '#f172c5',
'--td-brand-color-8': '#ED49B4',
'--td-brand-color-9': '#e80f9d',
'--td-brand-color-10': '#8f025e',
},
PURPLE: {
'--td-brand-color': '#834EC2',
'--td-brand-color-1': '#eee6f7',
'--td-brand-color-2': '#ddceee',
'--td-brand-color-3': '#ccb6e6',
'--td-brand-color-4': '#bb9edc',
'--td-brand-color-5': '#ab87d5',
'--td-brand-color-6': '#9a6fce',
'--td-brand-color-7': '#9a6fce',
'--td-brand-color-8': '#834EC2',
'--td-brand-color-9': '#783ac3',
'--td-brand-color-10': '#4c1397',
},
YELLOW: {
'--td-brand-color': '#EBB105',
'--td-brand-color-1': '#fde9ab',
'--td-brand-color-2': '#fbd152',
'--td-brand-color-3': '#EBB105',
'--td-brand-color-4': '#dda204',
'--td-brand-color-5': '#ca8d03',
'--td-brand-color-6': '#b67803',
'--td-brand-color-7': '#fbd152',
'--td-brand-color-8': '#EBB105',
'--td-brand-color-9': '#dda204',
'--td-brand-color-10': '#603100',
},
};
// TODO: 中性色暂时固定 待tvision-color生成带色彩倾向的中性色
export const LIGHT_CHART_COLORS = {
textColor: 'rgba(0, 0, 0, 0.9)',
placeholderColor: 'rgba(0, 0, 0, 0.35)',
@ -149,70 +18,13 @@ export const DARK_CHART_COLORS = {
export type TChartColor = typeof LIGHT_CHART_COLORS;
function toUnderline(name: string): string {
return name.replace(/([A-Z])/g, '_$1').toUpperCase();
}
export function getBrandColor(type: string, colorList: TColorSeries): TColorToken {
const name = /^#[A-F\d]{6}$/i.test(type) ? type : toUnderline(type);
return colorList[name || 'DEFAULT'];
}
export function getColorList(colorArray: Array<TColorToken>): Array<string> {
const pureColorList = [];
colorArray.map((colorToken) => Object.keys(colorToken).map((key) => pureColorList.push(colorToken[key])));
return pureColorList;
}
export function generateColorMap(theme: string, colorPalette: Array<string>, mode: 'light' | 'dark') {
const isDarkMode = mode === 'dark';
let brandColorIdx = colorPalette.indexOf(theme);
if (isDarkMode) {
// eslint-disable-next-line no-use-before-define
colorPalette.reverse().map((color) => {
const [h, s, l] = Color.colorTransform(color, 'hex', 'hsl');
return Color.colorTransform([h, Number(s) - 4, l], 'hsl', 'hex');
});
brandColorIdx = 5;
colorPalette[0] = `${colorPalette[brandColorIdx]}20`;
}
const colorMap = {
'--td-brand-color': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-1': colorPalette[0], // light
'--td-brand-color-2': colorPalette[1], // focus
'--td-brand-color-3': colorPalette[2], // disabled
'--td-brand-color-4': colorPalette[3],
'--td-brand-color-5': colorPalette[4],
'--td-brand-color-6': colorPalette[5],
'--td-brand-color-7': brandColorIdx > 0 ? colorPalette[brandColorIdx - 1] : theme, // hover
'--td-brand-color-8': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-9': brandColorIdx > 8 ? theme : colorPalette[brandColorIdx + 1], // click
'--td-brand-color-10': colorPalette[9],
};
return colorMap;
}
export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: 'light' | 'dark') {
const isDarkMode = mode === 'dark';
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
const styleSheet = document.createElement('style');
styleSheet.type = 'text/css';
styleSheet.innerText = `${root}{
--td-brand-color: ${colorMap['--td-brand-color']};
--td-brand-color-1: ${colorMap['--td-brand-color-1']};
--td-brand-color-2: ${colorMap['--td-brand-color-2']};
--td-brand-color-3: ${colorMap['--td-brand-color-3']};
--td-brand-color-4: ${colorMap['--td-brand-color-4']};
--td-brand-color-5: ${colorMap['--td-brand-color-5']};
--td-brand-color-6: ${colorMap['--td-brand-color-6']};
--td-brand-color-7: ${colorMap['--td-brand-color-7']};
--td-brand-color-8: ${colorMap['--td-brand-color-8']};
--td-brand-color-9: ${colorMap['--td-brand-color-9']};
--td-brand-color-10: ${colorMap['--td-brand-color-10']};
}`;
document.head.appendChild(styleSheet);
}
export const DEFAULT_COLOR_OPTIONS = [
'#0052D9',
'#0594FA',
'#00A870',
'#EBB105',
'#ED7B2F',
'#E34D59',
'#ED49B4',
'#834EC2',
];

View File

@ -10,6 +10,5 @@ export default {
isHeaderFixed: true,
isUseTabsRouter: false,
showHeader: true,
backgroundTheme: 'blueGrey',
brandTheme: 'default',
brandTheme: '#0052D9',
};

View File

@ -23,11 +23,7 @@
</t-radio-group>
<div class="setting-group-title">主题色</div>
<t-radio-group v-model="formData.brandTheme">
<div
v-for="(item, index) in COLOR_OPTIONS.slice(0, COLOR_OPTIONS.length - 1)"
:key="index"
class="setting-layout-drawer"
>
<div v-for="(item, index) in DEFAULT_COLOR_OPTIONS" :key="index" class="setting-layout-drawer">
<t-radio-button :key="index" :value="item" class="setting-layout-color-group">
<color-container :value="item" />
</t-radio-button>
@ -50,11 +46,8 @@
:swatch-colors="[]"
/>
</template>
<t-radio-button
:value="COLOR_OPTIONS[COLOR_OPTIONS.length - 1]"
class="setting-layout-color-group dynamic-color-btn"
>
<color-container :value="COLOR_OPTIONS[COLOR_OPTIONS.length - 1]" />
<t-radio-button :value="dynamicColor" class="setting-layout-color-group dynamic-color-btn">
<color-container :value="dynamicColor" />
</t-radio-button>
</t-popup>
</div>
@ -110,7 +103,8 @@ import Thumbnail from '@/components/thumbnail/index.vue';
import ColorContainer from '@/components/color/index.vue';
import STYLE_CONFIG from '@/config/style';
import { insertThemeStylesheet, generateColorMap } from '@/config/color';
import { DEFAULT_COLOR_OPTIONS } from '@/config/color';
import { insertThemeStylesheet, generateColorMap } from '@/utils/color';
import SettingDarkIcon from '@/assets/assets-setting-dark.svg';
import SettingLightIcon from '@/assets/assets-setting-light.svg';
@ -119,12 +113,13 @@ import SettingAutoIcon from '@/assets/assets-setting-auto.svg';
const settingStore = useSettingStore();
const LAYOUT_OPTION = ['side', 'top', 'mix'];
const COLOR_OPTIONS = ['default', 'cyan', 'green', 'yellow', 'orange', 'red', 'pink', 'purple', 'dynamic'];
const MODE_OPTIONS = [
{ type: 'light', text: '明亮' },
{ type: 'dark', text: '暗黑' },
{ type: 'auto', text: '跟随系统' },
];
const initStyleConfig = () => {
const styleConfig = STYLE_CONFIG;
for (const key in styleConfig) {
@ -136,6 +131,10 @@ const initStyleConfig = () => {
return styleConfig;
};
const dynamicColor = computed(() => {
const isDynamic = DEFAULT_COLOR_OPTIONS.indexOf(formData.value.brandTheme) === -1;
return isDynamic ? formData.value.brandTheme : '';
});
const formData = ref({ ...initStyleConfig() });
const isColoPickerDisplay = ref(false);
@ -151,14 +150,17 @@ const showSettingPanel = computed({
});
const changeColor = (hex: string) => {
const newPalette = Color.getPaletteByGradation({
const { colors: newPalette, primary: brandColorIndex } = Color.getColorGradations({
colors: [hex],
step: 10,
remainInput: false, //
})[0];
const { mode } = settingStore;
const colorMap = generateColorMap(hex, newPalette, mode as 'light' | 'dark');
const colorMap = generateColorMap(hex, newPalette, mode as 'light' | 'dark', brandColorIndex);
settingStore.addColor({ [hex]: colorMap });
formData.value.brandTheme = hex;
settingStore.updateConfig({ ...formData.value, brandTheme: hex });
insertThemeStylesheet(hex, colorMap, mode as 'light' | 'dark');
};
@ -209,7 +211,7 @@ const getThumbnailUrl = (name: string): string => {
};
watchEffect(() => {
settingStore.updateConfig(formData.value);
if (formData.value.brandTheme) settingStore.updateConfig(formData.value);
});
</script>
<style lang="less" scoped>

View File

@ -1,7 +1,7 @@
<template>
<t-row :gutter="16" class="row-container">
<t-col :xs="12" :xl="9">
<t-card title="统计数据" :subtitle="`(万元)${currentMonth}`" class="dashboard-chart-card">
<t-card title="统计数据" :subtitle="`(万元)${currentMonth}`" class="dashboard-chart-card" :bordered="false">
<template #option>
<div class="dashboard-chart-title-container">
<t-date-range-picker
@ -22,7 +22,7 @@
</t-card>
</t-col>
<t-col :xs="12" :xl="3">
<t-card title="销售渠道" :subtitle="currentMonth" class="dashboard-chart-card">
<t-card title="销售渠道" :subtitle="currentMonth" class="dashboard-chart-card" :bordered="false">
<div
id="countContainer"
ref="countContainer"

View File

@ -1,5 +1,5 @@
<template>
<t-card>
<t-card :bordered="false">
<t-row>
<t-col :xs="12" :xl="9">
<t-card

View File

@ -1,7 +1,7 @@
<template>
<t-row :gutter="16" class="row-container">
<t-col :xs="12" :xl="6">
<t-card title="销售订单排名" class="dashboard-rank-card">
<t-card title="销售订单排名" class="dashboard-rank-card" :bordered="false">
<template #actions>
<t-radio-group default-value="dateVal">
<t-radio-button value="dateVal">本周</t-radio-button>
@ -26,7 +26,7 @@
</t-card>
</t-col>
<t-col :xs="12" :xl="6">
<t-card title="销售订单排名" class="dashboard-rank-card">
<t-card title="销售订单排名" class="dashboard-rank-card" :bordered="false">
<template #actions>
<t-radio-group default-value="dateVal">
<t-radio-button value="dateVal">本周</t-radio-button>

View File

@ -3,6 +3,7 @@
<t-col v-for="(item, index) in PANE_LIST" :key="item.title" :xs="6" :xl="3">
<t-card
:title="item.title"
:bordered="false"
:style="{ height: '168px' }"
:class="{ 'dashboard-item': true, 'dashboard-item--main-color': index == 0 }"
>

View File

@ -1,6 +1,6 @@
<template>
<div class="dashboard-panel-detail">
<t-card title="本月采购申请情况" class="dashboard-detail-card">
<t-card title="本月采购申请情况" class="dashboard-detail-card" :bordered="false">
<t-row :gutter="[16, 16]">
<t-col v-for="(item, index) in PANE_LIST_DATA" :key="index" :xs="6" :xl="3">
<t-card class="dashboard-list-card" :description="item.title">
@ -18,7 +18,7 @@
</t-card>
<t-row :gutter="[16, 16]" class="row-margin">
<t-col :xs="12" :xl="9">
<t-card class="dashboard-detail-card" title="采购商品申请趋势" subtitle="(件)">
<t-card class="dashboard-detail-card" title="采购商品申请趋势" subtitle="(件)" :bordered="false">
<template #actions>
<t-date-range-picker
class="card-date-picker-container"
@ -41,7 +41,7 @@
/>
</t-col>
</t-row>
<t-card :class="['dashboard-detail-card', 'row-margin']" title="采购商品满意度分布">
<t-card :class="['dashboard-detail-card', 'row-margin']" title="采购商品满意度分布" :bordered="false">
<template #actions>
<t-date-range-picker
class="card-date-picker-container"

View File

@ -1,6 +1,6 @@
<template>
<div class="detail-advanced">
<t-card title="基本信息">
<t-card title="基本信息" :bordered="false">
<div class="info-block">
<div v-for="(item, index) in BASE_INFO_DATA" :key="index" class="info-item">
<h1>{{ item.name }}</h1>
@ -18,7 +18,7 @@
</t-card>
<!-- 发票进度 -->
<t-card title="发票进度" class="container-base-margin-top">
<t-card title="发票进度" class="container-base-margin-top" :bordered="false">
<t-row justify="space-between">
<t-steps :current="updateCurrent">
<t-step-item title="申请提交" content="已于12月21日提交" />
@ -30,7 +30,7 @@
</t-card>
<!-- 产品目录 -->
<t-card title="产品目录" class="container-base-margin-top">
<t-card title="产品目录" class="container-base-margin-top" :bordered="false">
<template #option>
<t-radio-group default-value="dateVal">
<t-radio-button value="dateVal"> 季度 </t-radio-button>
@ -53,7 +53,7 @@
</t-card>
<!-- 产品采购明细 -->
<t-card title="产品采购明细" class="container-base-margin-top">
<t-card title="产品采购明细" class="container-base-margin-top" :bordered="false">
<t-table
:columns="columns"
:data="data"

View File

@ -1,6 +1,6 @@
<template>
<div class="detail-base">
<t-card title="基本信息">
<t-card title="基本信息" :bordered="false">
<div class="info-block">
<div v-for="(item, index) in BASE_INFO_DATA" :key="index" class="info-item">
<h1>{{ item.name }}</h1>
@ -17,7 +17,7 @@
</div>
</t-card>
<t-card title="变更记录" class="container-base-margin-top">
<t-card title="变更记录" class="container-base-margin-top" :bordered="false">
<t-steps class="detail-base-info-steps" layout="vertical" theme="dot" :current="1">
<t-step-item title="上传合同附件" content="这里是提示文字" />
<t-step-item title="修改合同金额" content="这里是提示文字" />

View File

@ -2,14 +2,14 @@
<div class="detail-deploy">
<t-row :gutter="16">
<t-col :lg="6" :xs="12">
<t-card title="部署趋势">
<t-card title="部署趋势" :bordered="false">
<div class="deploy-panel-left">
<div id="monitorContainer" style="width: 100%; height: 265px" />
</div>
</t-card>
</t-col>
<t-col :lg="6" :xs="12">
<t-card title="告警情况">
<t-card title="告警情况" :bordered="false">
<template #option>
<t-radio-group default-value="dateVal" @change="onAlertChange">
<t-radio-button value="dateVal"> 本周 </t-radio-button>
@ -22,7 +22,7 @@
</t-row>
<!-- 项目列表 -->
<t-card title="项目列表" class="container-base-margin-top">
<t-card title="项目列表" class="container-base-margin-top" :bordered="false">
<t-table
:columns="columns"
:data="data"

View File

@ -1,6 +1,6 @@
<template>
<div>
<t-card class="list-card-container">
<t-card class="list-card-container" :bordered="false">
<t-row justify="space-between">
<div class="left-operation-container">
<t-button @click="handleSetupContract"> 新建合同 </t-button>

View File

@ -9,7 +9,7 @@
<img src="@/assets/assets-tencent-logo.png" class="logo" />
</div>
<t-card class="user-info-list" title="个人信息">
<t-card class="user-info-list" title="个人信息" :bordered="false">
<template #actions>
<t-button theme="default" shape="square" variant="text">
<t-icon name="edit" size="18" />
@ -27,7 +27,7 @@
</t-row>
</t-card>
<t-card class="content-container">
<t-card class="content-container" :bordered="false">
<t-tabs value="second">
<t-tab-panel value="first" label="内容列表">
<p>内容列表</p>
@ -54,13 +54,13 @@
</t-col>
<t-col :flex="1">
<t-card class="user-intro">
<t-card class="user-intro" :bordered="false">
<t-avatar size="90px">T</t-avatar>
<div class="name">My Account</div>
<div class="position">XXG 港澳业务拓展组员工 直客销售</div>
</t-card>
<t-card title="团队成员" class="user-team">
<t-card title="团队成员" class="user-team" :bordered="false">
<template #actions>
<t-button theme="default" shape="square" variant="text">
<t-icon name="edit" size="18" />
@ -73,7 +73,7 @@
</t-list>
</t-card>
<t-card title="服务产品" class="product-container">
<t-card title="服务产品" class="product-container" :bordered="false">
<template #actions>
<t-button theme="default" shape="square" variant="text">
<t-icon name="edit" size="18" />

View File

@ -1,13 +1,15 @@
import { defineStore } from 'pinia';
import { Color } from 'tvision-color';
import keys from 'lodash/keys';
import { COLOR_TOKEN, LIGHT_CHART_COLORS, DARK_CHART_COLORS, TColorSeries } from '@/config/color';
import { LIGHT_CHART_COLORS, DARK_CHART_COLORS, TColorSeries } from '@/config/color';
import { insertThemeStylesheet, generateColorMap } from '@/utils/color';
import STYLE_CONFIG from '@/config/style';
import { store } from '@/store';
const state = {
...STYLE_CONFIG,
showSettingPanel: false,
colorList: COLOR_TOKEN,
colorList: {},
chartColors: LIGHT_CHART_COLORS,
};
@ -49,6 +51,16 @@ export const useSettingStore = defineStore('setting', {
this.chartColors = isDarkMode ? DARK_CHART_COLORS : LIGHT_CHART_COLORS;
},
changeBrandTheme(brandTheme: string) {
const { colors: newPalette, primary: brandColorIndex } = Color.getColorGradations({
colors: [brandTheme],
step: 10,
remainInput: false, // 是否保留输入 不保留会矫正不合适的主题色
})[0];
const { mode } = this;
const colorMap = generateColorMap(brandTheme, newPalette, mode as 'light' | 'dark', brandColorIndex);
insertThemeStylesheet(brandTheme, colorMap, mode as 'light' | 'dark');
document.documentElement.setAttribute('theme-color', brandTheme);
},
addColor(payload: TColorSeries) {

View File

@ -1,3 +1,3 @@
@import './font-family.less';
@import './theme/index.less';
@import './reset.less';

View File

@ -1,27 +0,0 @@
:root[theme-color='cyan'] {
--td-brand-color: #0594fa;
--td-brand-color-1: #d7eefe;
--td-brand-color-2: #aeddfd;
--td-brand-color-3: #84cafd;
--td-brand-color-4: #58b8fc;
--td-brand-color-5: #29a4fb;
--td-brand-color-6: #0594fa;
--td-brand-color-7: #29a4fb;
--td-brand-color-8: #0594fa;
--td-brand-color-9: #0378df;
--td-brand-color-10: #01409b;
}
:root[theme-color='cyan'][theme-mode='dark'] {
--td-brand-color: #29a4fb;
--td-brand-color-1: #01409b;
--td-brand-color-2: #0152b3;
--td-brand-color-3: #0264ca;
--td-brand-color-4: #0378df;
--td-brand-color-5: #0594fa;
--td-brand-color-6: #29a4fb;
--td-brand-color-7: #0594fa;
--td-brand-color-8: #29a4fb;
--td-brand-color-9: #58b8fc;
--td-brand-color-10: #d7eefe;
}

View File

@ -1,26 +0,0 @@
:root,
:root[theme-mode='light'] {
--td-brand-color-1: #f2f3ff;
--td-brand-color-2: #d9e1ff;
--td-brand-color-3: #b5c7ff;
--td-brand-color-4: #8eabff;
--td-brand-color-5: #618dff;
--td-brand-color-6: #366ef4;
--td-brand-color-7: #0052d9;
--td-brand-color-8: #003cab;
--td-brand-color-9: #002a7c;
--td-brand-color-10: #001a57;
}
:root[theme-mode='dark'] {
--td-brand-color-1: #1b2f51;
--td-brand-color-2: #173463;
--td-brand-color-3: #143975;
--td-brand-color-4: #103d88;
--td-brand-color-5: #0d429a;
--td-brand-color-6: #054bbe;
--td-brand-color-7: #2667d4;
--td-brand-color-8: #4582e6;
--td-brand-color-9: #699ef5;
--td-brand-color-10: #96bbf8;
}

View File

@ -1,26 +0,0 @@
:root[theme-color='green'] {
--td-brand-color-1: #e8f8f2;
--td-brand-color-2: #bcebdc;
--td-brand-color-3: #85dbbe;
--td-brand-color-4: #48c79c;
--td-brand-color-5: #00a870;
--td-brand-color-6: #078d5c;
--td-brand-color-7: #067945;
--td-brand-color-8: #00a870;
--td-brand-color-9: #044f2a;
--td-brand-color-10: #033017;
}
:root[theme-color='green'][theme-mode='dark'] {
--td-brand-color: #03a56f;
--td-brand-color-1: #024b15;
--td-brand-color-2: #03965c;
--td-brand-color-3: #03a56f;
--td-brand-color-4: #04c383;
--td-brand-color-5: #03965c;
--td-brand-color-6: #03a56f;
--td-brand-color-7: #04c383;
--td-brand-color-8: #03a56f;
--td-brand-color-9: #05eb9f;
--td-brand-color-10: #91fdd9;
}

View File

@ -1,15 +0,0 @@
@import './default.less';
@import './cyan.less';
@import './green.less';
@import './orange.less';
@import './pink.less';
@import './purple.less';
@import './red.less';
@import './yellow.less';

View File

@ -1,28 +0,0 @@
:root[theme-color='orange'] {
--td-brand-color: #ed7b2f;
--td-brand-color-1: #fce5d7;
--td-brand-color-2: #f8cdaf;
--td-brand-color-3: #f4b285;
--td-brand-color-4: #f19659;
--td-brand-color-5: #ed7b2f;
--td-brand-color-6: #e75510;
--td-brand-color-7: #f19659;
--td-brand-color-8: #ed7b2f;
--td-brand-color-9: #e75510;
--td-brand-color-10: #7f0a02;
--td-brand-color: #ed7b2f;
}
:root[theme-color='orange'][theme-mode='dark'] {
--td-brand-color: #ed7b2f;
--td-brand-color-1: #692204;
--td-brand-color-2: #873105;
--td-brand-color-3: #a24006;
--td-brand-color-4: #c25110;
--td-brand-color-5: #d66724;
--td-brand-color-6: #ed8139;
--td-brand-color-7: #ff9852;
--td-brand-color-8: #ed7b2f;
--td-brand-color-9: #ed7b2f;
--td-brand-color-10: #fce5d7;
}

View File

@ -1,27 +0,0 @@
:root[theme-color='pink'] {
--td-brand-color: #ed49b4;
--td-brand-color-1: #fce5f4;
--td-brand-color-2: #facae9;
--td-brand-color-3: #f7aede;
--td-brand-color-4: #f491d2;
--td-brand-color-5: #f172c5;
--td-brand-color-6: #ed49b4;
--td-brand-color-7: #f172c5;
--td-brand-color-8: #ed49b4;
--td-brand-color-9: #e80f9d;
--td-brand-color-10: #8f025e;
}
:root[theme-color='pink'][theme-mode='dark'] {
--td-brand-color: #ff70cf;
--td-brand-color-1: #5b374f;
--td-brand-color-2: #9b066d;
--td-brand-color-3: #bc088a;
--td-brand-color-4: #d435a0;
--td-brand-color-5: #ed53b7;
--td-brand-color-6: #ff70cf;
--td-brand-color-7: #ff99e4;
--td-brand-color-8: #ff70cf;
--td-brand-color-9: #ffdbfd;
--td-brand-color-10: #fff2ff;
}

View File

@ -1,27 +0,0 @@
:root[theme-color='purple'] {
--td-brand-color: #834ec2;
--td-brand-color-1: #eee6f7;
--td-brand-color-2: #ddceee;
--td-brand-color-3: #ccb6e6;
--td-brand-color-4: #bb9edc;
--td-brand-color-5: #ab87d5;
--td-brand-color-6: #9a6fce;
--td-brand-color-7: #9a6fce;
--td-brand-color-8: #834ec2;
--td-brand-color-9: #783ac3;
--td-brand-color-10: #4c1397;
}
:root[theme-color='purple'][theme-mode='dark'] {
--td-brand-color: #ab87d5;
--td-brand-color-1: #4c1397;
--td-brand-color-2: #6325b0;
--td-brand-color-3: #783ac3;
--td-brand-color-4: #834ec2;
--td-brand-color-5: #9a6fce;
--td-brand-color-6: #ab87d5;
--td-brand-color-7: #ab87d5;
--td-brand-color-8: #ab87d5;
--td-brand-color-9: #ccb6e6;
--td-brand-color-10: #eee6f7;
}

View File

@ -1,27 +0,0 @@
:root[theme-color='red'] {
---td-brand-color: #e34d59;
--td-brand-color-1: #fbe5e7;
--td-brand-color-2: #f7ccd0;
--td-brand-color-3: #f3b2b8;
--td-brand-color-4: #ef989f;
--td-brand-color-5: #ea7b84;
--td-brand-color-6: #e34d59;
--td-brand-color-7: #ea7b84;
--td-brand-color-8: #e34d59;
--td-brand-color-9: #e42c3a;
--td-brand-color-10: #8d0309;
}
:root[theme-color='red'][theme-mode='dark'] {
--td-brand-color: #fb6e77;
--td-brand-color-1: #4f3335;
--td-brand-color-2: #960627;
--td-brand-color-3: #b01c37;
--td-brand-color-4: #c9384a;
--td-brand-color-5: #e35661;
--td-brand-color-6: #fb6e77;
--td-brand-color-7: #ff9195;
--td-brand-color-8: #fb6e77;
--td-brand-color-9: #ffd6d8;
--td-brand-color-10: #fff2f2;
}

View File

@ -1,27 +0,0 @@
:root[theme-color='yellow'] {
--td-brand-color: #ebb105;
--td-brand-color-1: #fde9ab;
--td-brand-color-2: #fbd152;
--td-brand-color-3: #ebb105;
--td-brand-color-4: #dda204;
--td-brand-color-5: #ca8d03;
--td-brand-color-6: #b67803;
--td-brand-color-7: #fbd152;
--td-brand-color-8: #ebb105;
--td-brand-color-9: #dda204;
--td-brand-color-10: #603100;
}
:root[theme-color='yellow'][theme-mode='dark'] {
--td-brand-color: #ca8d03;
--td-brand-color-1: #603100;
--td-brand-color-2: #764101;
--td-brand-color-3: #8c5201;
--td-brand-color-4: #a16502;
--td-brand-color-5: #b67803;
--td-brand-color-6: #ca8d03;
--td-brand-color-7: #764101;
--td-brand-color-8: #ca8d03;
--td-brand-color-9: #a16502;
--td-brand-color-10: #fde9ab;
}

View File

@ -1,7 +1,7 @@
import { Color } from 'tvision-color';
import * as echarts from 'echarts/core';
import { getBrandColor, defaultLightColor, defaultDarkColor } from '@/config/color';
import { getSettingStore } from '@/store';
import trim from 'lodash/trim';
import { TColorToken } from '@/config/color';
/**
*
@ -10,37 +10,20 @@ import { getSettingStore } from '@/store';
* @param {string} theme
* @returns {}
*/
export function getColorFromTheme(theme: string): Array<string> {
const settingStore = getSettingStore();
const { colorList, mode } = settingStore;
const isDarkMode = mode === 'dark';
let themeColorList;
const themeColor = getBrandColor(theme, colorList);
if (!/^#[A-F\d]{6}$/i.test(theme)) {
theme = themeColor?.['--td-brand-color'] || '#0052D9';
const themIdx = defaultLightColor.indexOf(theme.toLocaleLowerCase());
const defaultGradients = !isDarkMode ? defaultLightColor : defaultDarkColor;
const spliceThemeList = defaultGradients.slice(0, themIdx);
themeColorList = defaultGradients.slice(themIdx, defaultGradients.length).concat(spliceThemeList);
} else {
theme = themeColor?.['--td-brand-color'];
themeColorList = Color.getRandomPalette({
color: theme,
colorGamut: 'bright',
number: 8,
});
}
export function getColorFromTheme(): Array<string> {
const theme = trim(getComputedStyle(document.documentElement).getPropertyValue('--td-brand-color'));
const themeColorList = Color.getRandomPalette({
color: theme,
colorGamut: 'bright',
number: 8,
});
return themeColorList;
}
/** 图表颜色 */
export function getChartListColor(): Array<string> {
const settingStore = getSettingStore();
const { brandTheme } = settingStore;
const res = getColorFromTheme(brandTheme);
const res = getColorFromTheme();
return res;
}
@ -70,3 +53,66 @@ export function changeChartsTheme(chartsList: echarts.EChartsType[]): void {
}
}
}
/**
*
*/
export function generateColorMap(
theme: string,
colorPalette: Array<string>,
mode: 'light' | 'dark',
brandColorIdx: number,
) {
const isDarkMode = mode === 'dark';
if (isDarkMode) {
// eslint-disable-next-line no-use-before-define
colorPalette.reverse().map((color) => {
const [h, s, l] = Color.colorTransform(color, 'hex', 'hsl');
return Color.colorTransform([h, Number(s) - 4, l], 'hsl', 'hex');
});
brandColorIdx = 5;
colorPalette[0] = `${colorPalette[brandColorIdx]}20`;
}
const colorMap = {
'--td-brand-color': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-1': colorPalette[0], // light
'--td-brand-color-2': colorPalette[1], // focus
'--td-brand-color-3': colorPalette[2], // disabled
'--td-brand-color-4': colorPalette[3],
'--td-brand-color-5': colorPalette[4],
'--td-brand-color-6': colorPalette[5],
'--td-brand-color-7': brandColorIdx > 0 ? colorPalette[brandColorIdx - 1] : theme, // hover
'--td-brand-color-8': colorPalette[brandColorIdx], // 主题色
'--td-brand-color-9': brandColorIdx > 8 ? theme : colorPalette[brandColorIdx + 1], // click
'--td-brand-color-10': colorPalette[9],
};
return colorMap;
}
/**
*
*/
export function insertThemeStylesheet(theme: string, colorMap: TColorToken, mode: 'light' | 'dark') {
const isDarkMode = mode === 'dark';
const root = !isDarkMode ? `:root[theme-color='${theme}']` : `:root[theme-color='${theme}'][theme-mode='dark']`;
const styleSheet = document.createElement('style');
styleSheet.type = 'text/css';
styleSheet.innerText = `${root}{
--td-brand-color: ${colorMap['--td-brand-color']};
--td-brand-color-1: ${colorMap['--td-brand-color-1']};
--td-brand-color-2: ${colorMap['--td-brand-color-2']};
--td-brand-color-3: ${colorMap['--td-brand-color-3']};
--td-brand-color-4: ${colorMap['--td-brand-color-4']};
--td-brand-color-5: ${colorMap['--td-brand-color-5']};
--td-brand-color-6: ${colorMap['--td-brand-color-6']};
--td-brand-color-7: ${colorMap['--td-brand-color-7']};
--td-brand-color-8: ${colorMap['--td-brand-color-8']};
--td-brand-color-9: ${colorMap['--td-brand-color-9']};
--td-brand-color-10: ${colorMap['--td-brand-color-10']};
}`;
document.head.appendChild(styleSheet);
}