feat: support a custom UI theme

support a custom UI theme

Change-Id: Ic2f25fcc4620b06710c3ff1f26f84aba43881762
This commit is contained in:
zhangjingwei 2023-11-16 09:32:30 +08:00
parent f7041ca5a5
commit e018659955
32 changed files with 1043 additions and 82 deletions

View File

@ -14,7 +14,7 @@
"property-no-unknown": [ "property-no-unknown": [
true, true,
{ {
"ignoreProperties": ["/Color$/", "/Height$/"] "ignoreProperties": ["/Color$/", "/Height$/", "productsColumnWidth"]
} }
] ]
} }

View File

@ -2,6 +2,8 @@ host: 0.0.0.0
port: 8088 port: 8088
server: http://localhost server: http://localhost
theme: default
globalVariables: globalVariables:
defaultLanguage: en defaultLanguage: en
supportLanguages: # use value in i18n.js supportLanguages: # use value in i18n.js

View File

@ -0,0 +1,20 @@
const { getOptions } = require('loader-utils');
module.exports = function (source) {
const { search, change } = getOptions(this) || {}; // getOptions用于获取配置
if (!search || !change) {
return source;
}
if (source.includes(search)) {
// eslint-disable-next-line no-console
console.log(
'has-search',
search,
'in',
this.resource,
'replace to',
change
);
}
return source.replace(search, change);
};

View File

@ -0,0 +1,17 @@
const { getOptions } = require('loader-utils');
module.exports = function (source) {
const { variableFile } = getOptions(this) || {}; // getOptions用于获取配置
if (!variableFile) {
return source;
}
// 将 @import "styles/variables"; 变更为 @import "styles/variables";
const consoleReg = /~styles\/variables/g;
if (consoleReg.test(source)) {
// eslint-disable-next-line no-console
console.log(this.resourcePath, 'match ~styles/variables');
return source.replace(consoleReg, `~${variableFile}`);
}
return source;
};

26
config/theme-custom.js Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2021 99cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
module.exports = {
'primary-color': '#0C63FA',
'link-color': '#0C63FA',
'success-color': '#52C41A',
'warning-color': '#FAAD14',
'error-color': '#D40000',
'btn-default-color': '#0C63FA',
'btn-default-border': '#0C63FA',
'border-color-base': '#E8E8EA',
'border-radius-base': '2px',
'font-size-base': '12px',
};

View File

@ -7,6 +7,12 @@ const { merge, extend, has } = require('lodash');
const root = (dir) => const root = (dir) =>
`${path.resolve(__dirname, './')}/${dir}`.replace(/(\/+)/g, '/'); `${path.resolve(__dirname, './')}/${dir}`.replace(/(\/+)/g, '/');
const configRoot = (dir) =>
`${path.resolve(__dirname, '../config')}/${dir}`.replace(/(\/+)/g, '/');
const srcRoot = (dir) =>
`${path.resolve(__dirname, '../src')}/${dir}`.replace(/(\/+)/g, '/');
const loadYaml = (filePath) => { const loadYaml = (filePath) => {
try { try {
return yaml.load(fs.readFileSync(filePath), 'utf8'); return yaml.load(fs.readFileSync(filePath), 'utf8');
@ -50,15 +56,101 @@ const getObjectConfig = (key) => {
return result; return result;
}; };
const getConfig = (key) => {
// parse config yaml
const config = loadYaml(root('./config.yaml')) || {};
const tryFile = root('./local_config.yaml');
if (fs.existsSync(tryFile)) {
// merge local_config
const local_config = loadYaml(tryFile);
if (typeof local_config === 'object') {
merge(config, local_config);
}
}
return key ? config[key] : config;
};
const THEMES = {
default: {
themeFile: 'theme.js',
lessVariablesName: 'styles/variables',
globalVariables: {
menuTheme: 'dark',
skylineThemeName: 'default',
},
},
custom: {
themeFile: 'theme-custom.js',
lessVariablesName: 'styles/variables-custom',
globalVariables: {
menuTheme: 'light',
skylineThemeName: 'custom',
},
},
};
const getThemeConfig = () => {
// parse config yaml
const themeName = getConfig('theme') || 'default';
const themeInfo = THEMES[themeName] || THEMES.default;
const themeFile = configRoot(themeInfo.themeFile);
// eslint-disable-next-line no-console
console.log('themeFile', themeFile);
if (fs.existsSync(themeFile)) {
// eslint-disable-next-line import/no-dynamic-require
const config = require(themeFile);
return config;
}
// eslint-disable-next-line no-console
console.error('the theme file not exist');
return {};
};
const getCustomStyleVariables = () => {
const themeName = getConfig('theme') || 'default';
const themeInfo = THEMES[themeName] || THEMES.default;
const lessFileName = themeInfo.lessVariablesName;
const defaultLessFile = THEMES.default.lessVariablesName;
if (defaultLessFile === lessFileName) {
return false;
}
const customFile = srcRoot(`${lessFileName}.less`);
// eslint-disable-next-line no-console
console.log('customFile', customFile);
const exist = fs.existsSync(customFile) && lessFileName;
// eslint-disable-next-line no-console
console.log('exist', exist);
return exist;
};
const getGlobalVariablesForTheme = () => {
const themeName = getConfig('theme') || 'default';
const themeInfo = THEMES[themeName] || THEMES.default;
return themeInfo.globalVariables || {};
};
const getGlobalVariables = () => { const getGlobalVariables = () => {
const variables = getObjectConfig('globalVariables') || {}; const variables = getObjectConfig('globalVariables') || {};
const themeVariables = getGlobalVariablesForTheme();
const allVariables = { ...variables, ...themeVariables };
// eslint-disable-next-line no-console // eslint-disable-next-line no-console
console.log('globalVariables', variables, JSON.stringify(variables)); console.log('globalVariables', allVariables, JSON.stringify(allVariables));
return JSON.stringify(variables); return JSON.stringify(allVariables);
}; };
module.exports = { module.exports = {
getServerConfig, getServerConfig,
root, root,
getGlobalVariables, getGlobalVariables,
getThemeConfig,
getCustomStyleVariables,
}; };

View File

@ -17,7 +17,7 @@ const { normalize, resolve } = require('path');
// const path = require("path"); // const path = require("path");
// const CleanWebpackPlugin = require('clean-webpack-plugin'); // const CleanWebpackPlugin = require('clean-webpack-plugin');
const moment = require('moment'); const moment = require('moment');
const { getGlobalVariables } = require('./utils'); const { getGlobalVariables, getCustomStyleVariables } = require('./utils');
const root = (path) => resolve(__dirname, `../${path}`); const root = (path) => resolve(__dirname, `../${path}`);
const version = moment().unix(); const version = moment().unix();
@ -25,9 +25,18 @@ const version = moment().unix();
module.exports = { module.exports = {
module: { module: {
rules: [ rules: [
{
test: /\.jsx$/,
loader: resolve('config/js-string-replace-loader'),
include: [root('src/core')],
options: {
search: 'styles/variables',
change: getCustomStyleVariables(),
},
},
{ {
test: /\.jsx?$/, test: /\.jsx?$/,
include: root('node_modules'), include: [root('src'), root('node_modules')],
use: ['thread-loader', 'cache-loader'], use: ['thread-loader', 'cache-loader'],
}, },
{ {
@ -73,7 +82,10 @@ module.exports = {
}, },
}, },
], ],
include: [root('src/asset/image/cloud-logo.svg')], include: [
root('src/asset/image/cloud-logo.svg'),
root('src/asset/image/cloud-logo-white.svg'),
],
}, },
{ {
test: /\.(woff|woff2|ttf|eot|svg)$/, test: /\.(woff|woff2|ttf|eot|svg)$/,
@ -86,7 +98,10 @@ module.exports = {
}, },
}, },
], ],
exclude: [root('src/asset/image/cloud-logo.svg')], exclude: [
root('src/asset/image/cloud-logo.svg'),
root('src/asset/image/cloud-logo-white.svg'),
],
}, },
], ],
}, },

View File

@ -21,10 +21,15 @@ const HtmlWebPackPlugin = require('html-webpack-plugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const common = require('./webpack.common'); const common = require('./webpack.common');
const theme = require('./theme');
const server = require('./server.dev'); const server = require('./server.dev');
const { getThemeConfig, getCustomStyleVariables } = require('./utils');
const theme = getThemeConfig();
console.log('theme', theme);
const root = (path) => resolve(__dirname, `../${path}`); const root = (path) => resolve(__dirname, `../${path}`);
const { host, port, proxy } = server; const { host, port, proxy } = server;
@ -129,7 +134,12 @@ module.exports = (env) => {
options: { options: {
importLoaders: true, importLoaders: true,
javascriptEnabled: true, javascriptEnabled: true,
modifyVars: theme, },
},
{
loader: resolve('config/less-replace-loader'),
options: {
variableFile: getCustomStyleVariables(),
}, },
}, },
], ],

View File

@ -21,7 +21,10 @@ const autoprefixer = require('autoprefixer');
const CleanWebpackPlugin = require('clean-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin');
const common = require('./webpack.common'); const common = require('./webpack.common');
const theme = require('./theme');
const { getThemeConfig, getCustomStyleVariables } = require('./utils');
const theme = getThemeConfig();
const root = (path) => resolve(__dirname, `../${path}`); const root = (path) => resolve(__dirname, `../${path}`);
@ -102,7 +105,12 @@ module.exports = (env) => {
options: { options: {
importLoaders: true, importLoaders: true,
javascriptEnabled: true, javascriptEnabled: true,
modifyVars: theme, },
},
{
loader: resolve('config/less-replace-loader'),
options: {
variableFile: getCustomStyleVariables(),
}, },
}, },
], ],

View File

@ -22,7 +22,10 @@ const CleanWebpackPlugin = require('clean-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin'); const TerserPlugin = require('terser-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin'); const CompressionWebpackPlugin = require('compression-webpack-plugin');
const common = require('./webpack.common'); const common = require('./webpack.common');
const theme = require('./theme');
const { getThemeConfig, getCustomStyleVariables } = require('./utils');
const theme = getThemeConfig();
const root = (path) => resolve(__dirname, `../${path}`); const root = (path) => resolve(__dirname, `../${path}`);
@ -91,7 +94,12 @@ module.exports = (env) => {
options: { options: {
importLoaders: true, importLoaders: true,
javascriptEnabled: true, javascriptEnabled: true,
modifyVars: theme, },
},
{
loader: resolve('config/less-replace-loader'),
options: {
variableFile: getCustomStyleVariables(),
}, },
}, },
], ],

View File

@ -0,0 +1,11 @@
---
features:
- |
Support a custom UI theme
* Support theme setting in the config.yaml file, optional values: default, custom.
The default value represents the old theme, the custom value represents the new theme,
and the color is light.
* When you want to use the customized new theme, you can set `theme: custom` in config.yaml
or local_config.yaml.

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="167px" height="50px" viewBox="0 0 167 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>logo- user</title>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="logo--user" fill-rule="nonzero">
<g id="logo" transform="translate(-0.000000, 3.000000)">
<g id="编组" transform="translate(29.000000, 20.000000) scale(-1, 1) rotate(-180.000000) translate(-29.000000, -20.000000) translate(0.000000, 0.000000)">
<path d="M51.2031251,24.3636366 C51.2031251,24.2727276 48.3484375,18.8181821 44.9046875,12.2272729 L38.5609375,0.227272729 L36.521875,0.0909090918 C35.3890625,1.01030295e-14 34.4375,0.0454545459 34.4375,0.181818183 C34.4375,0.318181822 36.884375,5.0454546 39.875,10.6818183 C42.865625,16.318182 45.7203126,21.7272729 46.2187501,22.7272729 C47.0796875,24.4545457 47.2609376,24.5454548 49.1640626,24.5454548 C50.2968751,24.5454548 51.2031251,24.4545457 51.2031251,24.3636366 Z" id="路径" fill="#03A9F4"></path>
<path d="M53.83125,19.2272729 L54.6921876,17.5 L49.8890625,8.77272735 L45.0859375,0.0454545459 L42.9109375,0 L40.7359376,0 L42.4578125,3.09090912 C43.409375,4.77272731 45.9921875,9.5 48.2578126,13.5454547 C50.478125,17.5909092 52.471875,20.9090911 52.6531251,20.9090911 C52.834375,20.9090911 53.378125,20.1363638 53.83125,19.2272729 Z" id="路径" fill="#03A9F4"></path>
<path d="M54.7375001,5.86363642 L51.475,0 L49.5265625,0 C48.4390625,0 47.578125,0.0909090918 47.578125,0.227272729 C47.578125,0.363636368 49.4359375,3.8636364 51.7015626,8 L55.8703125,15.5 L56.9125,13.6363637 L58,11.7272729 L54.7375001,5.86363642 Z" id="路径" fill="#03AAF6"></path>
<g id="编组-27" transform="translate(0.000000, 1.363636)" fill="#FFFFFF">
<path d="M32.1718751,0 L33.2593751,2.18181821 C33.8174342,3.30143545 36.4089075,8.05187619 39.1459306,12.9934129 L39.603125,13.818182 C42.503125,19.0454547 44.859375,23.5 44.859375,23.7272729 C44.859375,23.9545457 43.0921875,27.4090912 40.9171875,31.3636367 L40.9171875,31.3636367 L36.9296875,38.636364 L20.1640625,38.636364 L16.1765625,31.3636367 L12.1890625,24.0909093 L6.52500001,24.0909093 L3.2625,18.2272728 C1.45,15 -7.97167064e-24,12.2272729 -7.97167064e-24,12.0909092 C-7.97167064e-24,11.7272729 4.3046875,3.95454549 5.70937501,1.72727275 L5.70937501,1.72727275 L6.796875,0 L32.1718751,0 Z M29.815625,4.09090913 L8.70000001,4.09090913 L6.52500001,8.09090913 L4.3953125,12.0454547 L6.47968751,15.9090911 L8.56406251,19.7727275 L11.509375,19.9090911 L14.4546875,20.0454547 L18.396875,27.2727276 L22.384375,34.5454549 L34.7093751,34.5454549 L37.51875,29.4090912 C39.059375,26.5454548 40.328125,24.0000002 40.328125,23.7272729 C40.328125,23.4545457 37.971875,18.9545457 35.071875,13.6818183 L35.071875,13.6818183 L29.815625,4.09090913 Z" id="形状结合"></path>
</g>
</g>
</g>
<text id="Cloud" fill="#FFFFFF" font-family="PingFangSC-Regular, PingFang SC" font-size="36" font-weight="normal">
<tspan x="69" y="38">Cloud</tspan>
</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -145,12 +145,12 @@ export class AvatarDropdown extends React.Component {
<Button <Button
type="link" type="link"
onClick={this.handleLogout} onClick={this.handleLogout}
className={`${styles.logout} ${styles['no-padding-top']}`} className={`${styles['menu-btn']} ${styles.logout} ${styles['no-padding-top']}`}
> >
{t('Sign Out')} {t('Sign Out')}
</Button> </Button>
</Menu.Item> </Menu.Item>
<Menu.Divider /> <Menu.Divider className={styles['menu-divider']} />
{this.renderLanguageMenuItem()} {this.renderLanguageMenuItem()}
<Menu.Item key="password" className={styles['menu-item']}> <Menu.Item key="password" className={styles['menu-item']}>
<ItemActionButtons <ItemActionButtons

View File

@ -15,6 +15,7 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import cloudLogo from 'asset/image/cloud-logo.svg'; import cloudLogo from 'asset/image/cloud-logo.svg';
import cloudLogoWhite from 'asset/image/cloud-logo-white.svg';
import { getPath } from 'utils/route-map'; import { getPath } from 'utils/route-map';
import classnames from 'classnames'; import classnames from 'classnames';
import GlobalNav from '../GlobalNav'; import GlobalNav from '../GlobalNav';
@ -35,10 +36,14 @@ export default function HeaderContent(props) {
const renderLogo = () => { const renderLogo = () => {
const homeUrl = getRoutePath('overview'); const homeUrl = getRoutePath('overview');
const logoSrc =
GLOBAL_VARIABLES.skylineThemeName === 'default'
? cloudLogo
: cloudLogoWhite;
return ( return (
<div className={classnames(styles.logo)}> <div className={classnames(styles.logo)}>
<Link to={homeUrl}> <Link to={homeUrl}>
<img src={cloudLogo} alt="logo" className={styles['logo-image']} /> <img src={logoSrc} alt="logo" className={styles['logo-image']} />
</Link> </Link>
</div> </div>
); );

View File

@ -1,29 +1,40 @@
@import '~styles/variables'; @import '~styles/variables';
.menu { .menu {
color: @avatar-dropdown-text-color;
background-color: @avatar-dropdown-background-color;
:global(.anticon) { :global(.anticon) {
margin-right: 8px; margin-right: 8px;
} }
:global(.ant-dropdown-menu-item) { :global {
min-width: 245px; .ant-dropdown-menu-item {
min-width: 245px;
color: @avatar-dropdown-text-color;
&:hover {
color: @avatar-dropdown-hover-text-color;
background-color: @avatar-dropdown-hover-background-color;
}
}
} }
.no-hover { .no-hover {
overflow: hidden; overflow: hidden;
&:hover { &:hover {
background-color: #fff; background-color: @avatar-dropdown-hover-background-color;
} }
} }
.name-item { .name-item {
padding: 0 12px; padding: 0 12px;
font-weight: bold;
line-height: 40px; line-height: 40px;
.user-label { .user-label {
margin-right: 8px; margin-right: 8px;
font-weight: 'bold';
} }
span { span {
@ -33,6 +44,24 @@
.menu-item { .menu-item {
line-height: 30px; line-height: 30px;
:global {
.ant-btn {
color: @avatar-dropdown-button-color;
}
.ant-btn-link[disabled] {
color: @avatar-dropdown-button-disabled-color;
}
}
}
.menu-btn {
color: @avatar-dropdown-button-color;
}
.menu-divider {
background-color: @avatar-dropdown-divider-color;
} }
} }
@ -110,15 +139,15 @@
height: 100%; height: 100%;
padding-left: 0; padding-left: 0;
overflow: hidden; overflow: hidden;
color: @title-color; color: @layout-text-color;
background-color: #fff; background-color: @layout-header-color;
box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 9%); box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 9%);
} }
.avatar { .avatar {
width: 30px; width: 30px;
height: 30px; height: 30px;
color: #bfbfbf; color: @avatar-color;
border: none; border: none;
box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 9%); box-shadow: 0 2px 20px 0 rgba(0, 0, 0, 9%);
} }
@ -162,7 +191,11 @@
.single-link { .single-link {
margin-right: 5px; margin-right: 5px;
color: @primary-color; color: @layout-link-color;
&:hover {
color: @layout-link-color;
}
} }
.token { .token {
@ -178,12 +211,12 @@
.logo { .logo {
float: left; float: left;
width: 190px; width: @layout-header-logo-wrapper-width;
height: @header-height; height: @header-height;
line-height: @header-height; line-height: @header-height;
text-align: center; text-align: center;
img { img {
height: 30px; height: @layout-header-logo-image-height;
} }
} }

View File

@ -48,6 +48,10 @@ export default class Left extends React.Component {
render() { render() {
const { items } = this.props; const { items } = this.props;
return <div id="global-nav-left">{items.map(this.renderItem)}</div>; return (
<div id="global-nav-left" className={styles.left}>
{items.map(this.renderItem)}
</div>
);
} }
} }

View File

@ -1,18 +1,23 @@
@import '~styles/variables';
// .left {}
.item { .item {
padding: 12px 24px; padding: 12px 24px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background-color: rgba(0, 0, 0, 5%); background-color: @products-drawer-hover-background-1;
} }
} }
.item-label { .item-label {
display: block; display: block;
width: 100%; width: 100%;
color: #000; color: @products-title-color;
font-size: 13px;
&:hover { &:hover {
color: #000; color: @products-title-color;
} }
} }

View File

@ -15,13 +15,12 @@
import React from 'react'; import React from 'react';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Input } from 'antd'; import { Input } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { navItemPropType } from '../common'; import { navItemPropType } from '../common';
import styles from './index.less'; import styles from './index.less';
const { Search } = Input;
export default class Right extends React.Component { export default class Right extends React.Component {
static propTypes = { static propTypes = {
items: PropTypes.oneOfType([ items: PropTypes.oneOfType([
@ -113,11 +112,11 @@ export default class Right extends React.Component {
renderSearch() { renderSearch() {
return ( return (
<div className={styles.search}> <div className={styles.search}>
<Search <Input
prefix={<SearchOutlined />}
placeholder={t('Search')} placeholder={t('Search')}
allowClear allowClear
onChange={this.onInputChange} onChange={this.onInputChange}
onSearch={this.onSearch}
/> />
</div> </div>
); );

View File

@ -1,3 +1,5 @@
@import '~styles/variables';
.right { .right {
columns: 200px 3; columns: 200px 3;
column-gap: 12px; column-gap: 12px;
@ -13,7 +15,7 @@
box-sizing: border-box; box-sizing: border-box;
height: 32px; height: 32px;
margin-bottom: 4px; margin-bottom: 4px;
color: #000; color: @products-title-color;
font-weight: 600; font-weight: 600;
font-size: 14px; font-size: 14px;
line-height: 22px; line-height: 22px;
@ -33,17 +35,53 @@
} }
&:hover { &:hover {
background-color: rgba(0, 0, 0, 5%); color: @products-drawer-sub-title-hover-color;
background-color: @products-drawer-sub-title-hover-background;
.link-name {
color: @products-drawer-sub-title-hover-color;
}
} }
.link-name { .link-name {
color: #000; color: @products-sub-title-color;
} }
} }
.search { .search {
width: 90%; width: 60%;
margin-top: -8px; margin-top: -8px;
margin-bottom: 16px; margin-bottom: 16px;
margin-left: 0; margin-left: 0;
:global {
.ant-input-affix-wrapper {
background-color: @products-drawer-search-background;
border: @products-drawer-search-border;
border-color: @products-drawer-search-border-color;
box-shadow: none;
}
.anticon-search {
color: @products-drawer-search-icon !important;
}
.ant-input {
color: @products-drawer-search-input-color;
background-color: @products-drawer-search-background;
&:hover {
border: @products-drawer-search-hover-border-color;
}
}
.ant-input-affix-wrapper:not(.ant-input-affix-wrapper-disabled):hover {
border-color: @products-drawer-search-hover-border-color;
}
.ant-input-clear-icon,
.ant-input-clear-icon:active {
color: @products-drawer-search-input-color;
}
}
} }

View File

@ -64,6 +64,10 @@ export class GlobalNav extends React.Component {
height: `calc(100% - ${globalCSS.headerHeight})`, height: `calc(100% - ${globalCSS.headerHeight})`,
}; };
const productsColumnWidth = Number(
globalCSS.productsColumnWidth.replace('px', '')
);
return ( return (
<> <>
<div className={styles['global-nav-icon']} onClick={this.onToggleOpen}> <div className={styles['global-nav-icon']} onClick={this.onToggleOpen}>
@ -75,30 +79,32 @@ export class GlobalNav extends React.Component {
</div> </div>
<Drawer <Drawer
title={t('Service List')} title={t('Service List')}
className={styles['drawer-left']}
placement="left" placement="left"
closable={false} closable={false}
onClose={this.onClose} onClose={this.onClose}
visible={visible} visible={visible}
style={drawerStyle} style={drawerStyle}
bodyStyle={{ padding: 0 }} bodyStyle={{ padding: 0 }}
width="240" width={productsColumnWidth}
destroyOnClose destroyOnClose
> >
<Left items={navItems} onClose={this.onClose} /> <Left items={navItems} onClose={this.onClose} />
</Drawer> </Drawer>
<Drawer <Drawer
title={null} title={null}
className={styles['drawer-right']}
placement="left" placement="left"
closable closable
onClose={this.onClose} onClose={this.onClose}
visible={visible} visible={visible}
style={{ style={{
...drawerStyle, ...drawerStyle,
left: visible ? '240px' : 0, left: visible ? globalCSS.productsColumnWidth : 0,
}} }}
bodyStyle={{ padding: 0 }} bodyStyle={{ padding: 0 }}
mask mask
width="1020" width={productsColumnWidth * 4}
maskStyle={{ backgroundColor: 'transparent' }} maskStyle={{ backgroundColor: 'transparent' }}
closeIcon={<CloseOutlined style={{ fontSize: '20px' }} />} closeIcon={<CloseOutlined style={{ fontSize: '20px' }} />}
> >

View File

@ -9,8 +9,12 @@
font-size: 16px; font-size: 16px;
line-height: @header-height; line-height: @header-height;
text-align: center; text-align: center;
background-color: @primary-color; background-color: @products-icon-background;
cursor: pointer; cursor: pointer;
&:hover {
background-color: @products-icon-hover-background;
}
} }
.global-nav-icon-icon { .global-nav-icon-icon {
@ -20,3 +24,33 @@
.main { .main {
padding: 32px 32px 0; padding: 32px 32px 0;
} }
.drawer-left {
:global {
.ant-drawer-header {
background-color: @products-drawer-background-1;
.ant-drawer-title {
color: @products-header-title-color;
}
border-bottom-color: @products-drawer-divider-color-1;
}
.ant-drawer-body {
background-color: @products-drawer-background-2;
}
}
}
.drawer-right {
:global {
.ant-drawer-body {
background-color: @products-drawer-background-1;
}
.ant-drawer-close {
color: @products-drawer-close-icon;
}
}
}

View File

@ -565,7 +565,8 @@ class MagicInput extends PureComponent {
className={classnames( className={classnames(
'magic-input-wrapper', 'magic-input-wrapper',
styles['magic-input-wrapper'], styles['magic-input-wrapper'],
isFocus ? styles['magic-input-wrapper-active'] : '' isFocus ? styles['magic-input-wrapper-active'] : '',
isFocus ? 'magic-input-wrapper-active' : ''
)} )}
> >
<Col>{this.renderTags()}</Col> <Col>{this.renderTags()}</Col>

View File

@ -11,8 +11,8 @@
width: 100%; width: 100%;
min-width: 200px; min-width: 200px;
padding: 3px 0 3px 8px; padding: 3px 0 3px 8px;
background-color: #fff; background-color: @table-header-search-input-background;
border: 1px solid rgb(217, 217, 217); border: 1px solid @table-header-search-input-border-color;
border-radius: @border-radius; border-radius: @border-radius;
:global { :global {
@ -22,7 +22,7 @@
margin-bottom: 1px; margin-bottom: 1px;
padding: 0 4px; padding: 0 4px;
color: #fff; color: #fff;
font-size: 10px; font-size: @table-header-search-input-font-size;
line-height: 24px; line-height: 24px;
background-color: @primary-color; background-color: @primary-color;
border: none; border: none;
@ -69,7 +69,7 @@
} }
input::placeholder { input::placeholder {
font-size: 10px; font-size: @table-header-search-input-font-size;
} }
.ant-menu-vertical > .ant-menu-item { .ant-menu-vertical > .ant-menu-item {
@ -80,7 +80,7 @@
.ant-menu-vertical .ant-menu-item { .ant-menu-vertical .ant-menu-item {
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
font-size: 10px; font-size: @table-header-search-input-font-size;
} }
} }
} }
@ -101,7 +101,7 @@
} }
.key { .key {
font-size: 10px; font-size: @table-header-search-input-font-size;
line-height: 24px; line-height: 24px;
:global { :global {
@ -156,6 +156,7 @@
.close-btn { .close-btn {
height: 28px !important; height: 28px !important;
padding: 0; padding: 0;
background-color: @table-header-default-button-background;
border: none; border: none;
} }
} }

View File

@ -81,6 +81,35 @@
.ant-btn[disabled] { .ant-btn[disabled] {
box-shadow: 0 2px 0 rgba(0, 0, 0, 4.5%); box-shadow: 0 2px 0 rgba(0, 0, 0, 4.5%);
} }
.ant-btn-default {
color: @table-header-default-button-color;
background-color: @table-header-default-button-background;
border-color: @table-header-default-button-border;
}
.ant-btn-default:hover {
color: @primary-color;
border-color: @primary-color;
}
.ant-btn-dangerous {
color: @table-header-danger-button-color;
}
.ant-btn-dangerous:hover {
color: @error-color;
border-color: @error-color;
}
.ant-btn[disabled],
.ant-btn[disabled]:hover,
.ant-btn[disabled]:focus,
.ant-btn[disabled]:active {
color: @table-header-disable-button-color !important;
background: @table-header-disable-button-background !important;
border-color: @table-header-disable-button-border !important;
}
} }
} }

View File

@ -283,7 +283,11 @@ export default class SimpleTable extends React.Component {
const dataSource = this.getDataSource(); const dataSource = this.getDataSource();
return ( return (
<Table <Table
className={classnames(styles['sl-simple-table'], className)} className={classnames(
styles['sl-simple-table'],
'sl-simple-table',
className
)}
columns={currentColumns} columns={currentColumns}
dataSource={dataSource} dataSource={dataSource}
loading={isLoading} loading={isLoading}

View File

@ -136,7 +136,13 @@ export class LayoutMenu extends Component {
if (item.level > 1) { if (item.level > 1) {
return null; return null;
} }
if (!item.children || item.children.length === 0 || item.level) { const { showChildren = true } = item;
if (
!showChildren ||
!item.children ||
item.children.length === 0 ||
item.level
) {
return ( return (
<Menu.Item <Menu.Item
key={item.key} key={item.key}
@ -145,7 +151,13 @@ export class LayoutMenu extends Component {
> >
{/* <Menu.Item key={item.key} className={styles['menu-item-no-child']}> */} {/* <Menu.Item key={item.key} className={styles['menu-item-no-child']}> */}
{item.icon} {item.icon}
<span className={styles['menu-item-title']}> <span
className={
item.level === 0 || (item.level === 1 && !showChildren)
? styles['menu-item-title']
: styles['sub-menu-item-title']
}
>
{item.name.length >= this.maxTitleLength ? ( {item.name.length >= this.maxTitleLength ? (
<Tooltip title={item.name} placement="right"> <Tooltip title={item.name} placement="right">
{item.name} {item.name}
@ -224,7 +236,7 @@ export class LayoutMenu extends Component {
const newSelectedKeys = this.getSelectedKeysForMenu(selectedKeys); const newSelectedKeys = this.getSelectedKeysForMenu(selectedKeys);
return ( return (
<Menu <Menu
theme="dark" theme={GLOBAL_VARIABLES.menuTheme}
mode="inline" mode="inline"
className={collapsed ? styles['menu-collapsed'] : styles.menu} className={collapsed ? styles['menu-collapsed'] : styles.menu}
defaultSelectedKeys={newSelectedKeys} defaultSelectedKeys={newSelectedKeys}

View File

@ -59,15 +59,17 @@
line-height: 75px; line-height: 75px;
background-color: @sider-background; background-color: @sider-background;
border-width: 32px; border-width: 32px;
border-radius: 4px 0 0 4px; border-radius: @border-radius 0 0 @border-radius;
} }
} }
} }
.menu { .menu,
.menu-collapsed {
max-height: calc(100vh - 64px); max-height: calc(100vh - 64px);
padding-right: 14px; padding-right: @sider-menu-padding;
padding-left: 14px; padding-left: @sider-menu-padding;
overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
&::-webkit-scrollbar { &::-webkit-scrollbar {
@ -104,9 +106,35 @@
line-height: 44px; line-height: 44px;
} }
& .ant-menu-item-selected { .ant-menu-item-selected,
background-color: @primary-color; .ant-menu-item-active {
border-radius: @border-radius; color: @sider-menu-item-selected-text-color !important;
border-radius: @sider-menu-item-selected-border-radius;
}
.ant-menu-item-selected {
background-color: @sider-menu-item-selected-background !important;
}
.ant-menu-sub.ant-menu-inline {
background-color: @sider-sub-menu-background !important;
}
.ant-menu-item-selected::after {
border-right: @sider-menu-item-selected-after-border-right !important;
}
.ant-menu-submenu-active,
.ant-menu-submenu-selected,
.ant-menu-submenu-title:hover,
.ant-menu-submenu:hover
> .ant-menu-submenu-title
> .ant-menu-submenu-arrow {
color: @sider-menu-item-selected-text-color !important;
}
.ant-menu-submenu-title:active {
background-color: @sider-menu-item-selected-background;
} }
} }
} }
@ -135,8 +163,8 @@
:global { :global {
.ant-menu-sub.ant-menu-inline { .ant-menu-sub.ant-menu-inline {
padding-right: 5px; padding-right: @sider-sub-menu-item-padding-left;
padding-left: 5px; padding-left: @sider-sub-menu-item-padding-left;
} }
.ant-menu-item > span::before { .ant-menu-item > span::before {
@ -146,17 +174,38 @@
left: 30px; left: 30px;
width: 5px; width: 5px;
height: 5px; height: 5px;
background-color: rgba(255, 255, 255, 65%); background-color: @sider-sub-menu-item-dot-color;
border-radius: 50%; border-radius: 50%;
content: ''; content: '';
} }
.ant-menu-item-selected > span::before { .ant-menu-item {
background-color: #fff !important; margin-top: @sider-sub-menu-item-margin-top !important;
margin-bottom: @sider-sub-menu-item-margin-bottom !important;
}
.ant-menu-item-selected {
background-color: @sider-sub-menu-item-selected-background !important;
}
.ant-menu-item-selected:hover {
background-color: @sider-sub-menu-item-selected-background !important;
} }
.ant-menu-item-active > span::before { .ant-menu-item-active > span::before {
background-color: @primary-color; background-color: @sider-menu-item-hover-dot-color !important;
}
.ant-menu-item-active {
background-color: @sider-sub-menu-item-hover-background !important;
}
.ant-menu-item-selected > span::before {
background-color: @sider-menu-item-selected-dot-color !important;
}
.ant-menu-item-selected::after {
border-right: @sider-menu-item-selected-after-border-right !important;
} }
.ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal) .ant-menu-dark.ant-menu-dark:not(.ant-menu-horizontal)
@ -173,6 +222,7 @@
background-color: #fff; background-color: #fff;
.breadcrumb-item { .breadcrumb-item {
font-size: @breadcrumb-item-font-size;
line-height: @breadcrumb-height; line-height: @breadcrumb-height;
} }
@ -225,7 +275,7 @@
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: -1; z-index: -1;
background: rgba(0, 0, 0, 35%); background: @sider-trigger-background-color;
border-right: none; border-right: none;
border-radius: 0 4px 4px 0; border-radius: 0 4px 4px 0;
transform: scaleX(2.2) perspective(50px) rotateY(50deg); transform: scaleX(2.2) perspective(50px) rotateY(50deg);
@ -251,10 +301,12 @@
bottom: 0; bottom: 0;
left: 0; left: 0;
z-index: 1; z-index: 1;
width: 230px; width: @sider-width;
padding-top: 10px; padding-top: @sider-menu-padding-top;
background-color: @sider-background; background-color: @sider-background;
border-right: @sider-border-right;
transition: all 0.2s; transition: all 0.2s;
// border-right: 1px solid #e5e6eb;
} }
.base-layout-sider-collapsed { .base-layout-sider-collapsed {
@ -276,7 +328,7 @@
position: absolute; position: absolute;
top: @header-height; top: @header-height;
right: 0; right: 0;
left: 230px; left: @sider-width;
height: calc(100vh - @header-height); height: calc(100vh - @header-height);
} }
@ -285,12 +337,12 @@
} }
.base-layout-sider-hover { .base-layout-sider-hover {
width: 230px; width: @sider-width;
transition: all 0.2s; transition: all 0.2s;
.menu-collapsed { .menu-collapsed {
padding-right: 14px; padding-right: @sider-menu-padding;
padding-left: 14px; padding-left: @sider-menu-padding;
.menu-item-collapsed { .menu-item-collapsed {
padding-left: 48px !important; padding-left: 48px !important;
@ -324,7 +376,7 @@
} }
.menu-item-title { .menu-item-title {
font-size: @size-normal; font-size: @sider-menu-title-font-size;
span { span {
display: inline-block; display: inline-block;
@ -334,3 +386,8 @@
text-overflow: ellipsis; text-overflow: ellipsis;
} }
} }
.sub-menu-item-title {
color: @sider-sub-menu-title-color;
font-size: @sider-sub-menu-title-font-size;
}

View File

@ -1,8 +1,9 @@
@import '~antd/lib/style/themes/default.less'; @import '~antd/lib/style/themes/default.less';
@import '~styles/variables';
.container { .container {
height: 100%; height: 100%;
padding: 44px; padding: @overview-padding;
overflow: auto; overflow: auto;
:global { :global {

View File

@ -3,7 +3,7 @@
.container { .container {
height: 100%; height: 100%;
padding: 44px; padding: @overview-padding;
overflow: auto; overflow: auto;
.main-icon { .main-icon {

View File

@ -163,7 +163,8 @@
} }
} }
.sl-table { .sl-table,
.sl-simple-table {
.ant-table-thead > tr > th { .ant-table-thead > tr > th {
background: rgba(0, 104, 255, 2%); background: rgba(0, 104, 255, 2%);
} }
@ -172,12 +173,9 @@
background: rgba(0, 104, 255, 10%); background: rgba(0, 104, 255, 10%);
} }
.ant-table-tbody > tr.ant-table-row-selected > td,
.ant-table-tbody > tr.ant-table-row:hover > td { .ant-table-tbody > tr.ant-table-row:hover > td {
background: #f2f7ff; background-color: @table-row-selected-background;
}
.ant-table-tbody > tr.ant-table-row-selected > td {
background: #f2f7ff;
} }
td.ant-table-column-sort { td.ant-table-column-sort {
@ -195,6 +193,11 @@
.ant-table-thead > tr > th.ant-table-selection-column:first-child { .ant-table-thead > tr > th.ant-table-selection-column:first-child {
padding-left: 8px; padding-left: 8px;
} }
.ant-checkbox-inner {
width: @table-checkbox-size;
height: @table-checkbox-size;
}
} }
.tip { .tip {
@ -218,4 +221,14 @@
.inline-block { .inline-block {
display: inline-block; display: inline-block;
} }
.sl-form {
.magic-input-wrapper {
border-color: @form-item-magic-input-wrapper-border-color;
}
.magic-input-wrapper-active {
border-color: @primary-color;
}
}
} }

View File

@ -0,0 +1,386 @@
/* init */
@blue-1: #0c63fa;
@blue-2: rgba(0, 104, 255, 65%);
@blue-3: rgba(89, 157, 255, 35%);
@blue-4: #005ade;
@blue-5: rgba(25, 128, 255, 10%);
@blue-6: #e8f2ff;
@primary-color: @blue-1;
@info-color: @blue-2;
@hover-color: @blue-4;
@heading-color: rgba(0, 0, 0, 65%);
@green-1: #57e39b;
@green-2: rgba(87, 227, 155, 65%);
@green-3: rgba(87, 227, 155, 35%);
@success-color: @green-1;
@yellow-1: #fedf40;
@yellow-2: rgba(254, 223, 64, 65%);
@yellow-3: rgba(254, 223, 64, 35%);
@warn-color: @yellow-1;
@warn-light-color: #f6b23d;
@warn-dark-color: #fa8c16;
@red-1: #eb354d;
@red-2: rgba(235, 53, 77, 65%);
@red-3: rgba(235, 53, 77, 35%);
@error-color: @red-1;
@danger-color: #c4233e;
@danger-color-hover: #f76070;
@red: @red-color03;
@gray-1: #d2d2d2;
@gray-2: #f2f2f2;
@gray-3: #fafafa;
@gray-4: #f0f1f7;
@gray-5: #f2f3f8;
@dark-text-title: rgba(0, 0, 0, 100%);
@dark-text-title-second: rgba(0, 0, 0, 85%);
@color-text-body: rgba(0, 0, 0, 65%);
@color-text-caption: rgba(0, 0, 0, 45%);
@color-text-disable: rgba(0, 0, 0, 25%);
@color-text-default: rgb(29, 33, 41);
@color-text-title: rgba(0, 0, 0, 85%);
@size-header-1: 38px;
@size-header-2: 30px;
@size-header-3: 24px;
@size-header-4: 16px;
@size-display: 20px;
@size-body: 14px;
@size-caption: 12px;
@dark-color01: #79879c;
@dark-color02: #6b7b95;
@dark-color03: #5f708a;
@dark-color04: #4a5974;
@dark-color05: #404e68;
@dark-color06: #36435c;
@dark-color07: #124191;
@dark-color08: #181d28;
@dark-color09: rgba(0, 0, 0, 30%);
@dark-color10: rgba(0, 0, 0, 50%);
@dark-color11: #241f20;
@dark-color12: #1d2129;
@dark-color13: #272e3b;
@light-color01: #f9fbfd;
@light-color02: #eff4f9;
@light-color03: #e3e9ef;
@light-color04: #d8dee5;
@light-color05: #d1d7df;
@light-color06: #ccd3db;
@light-color07: #c1c9d1;
@light-color08: #abb4be;
@green-color01: #c4e6d4;
@green-color02: #a2d8bb;
@green-color03: #1890ff;
@green-color04: #479e88;
@green-color05: #3b747a;
@blue-color01: #c7deef;
@blue-color02: #7eb8dc;
@blue-color03: #329dce;
@blue-color04: #3385b0;
@blue-color05: #326e93;
@red-color01: #fae7e5;
@red-color02: #ea8573;
@red-color03: #ca2621;
@red-color04: #ab2f29;
@red-color05: #8c3231;
@yellow-color01: #ffe1be;
@yellow-color02: #ffc781;
@yellow-color03: #f5a623;
@yellow-color04: #e0992c;
@yellow-color05: #8d663e;
@yellow-color06: #faad14;
@yellow-color07: #fff3dc;
@white: #fff;
@black: #000;
@blue-color: #124191;
/* specific color */
@dark: @dark-color07;
@dark-grey: @dark-color03;
@grey: @dark-color01;
@lightest: @light-color01;
@light: @light-color02;
@green: @green-color03;
@blue: @blue-color03;
@yellow: @yellow-color03;
@yellow-dark: @yellow-color04;
@red: @red-color03;
@red-dark: @red-color04;
@primary: @green-color03;
@sub: @blue-color03;
@warning: @yellow-color03;
@danger: @red-color03;
@title-color: @dark-text-title;
@second-title-color: @dark-color03;
@text-color: @primary-color;
@second-text-color: @dark-color01;
@third-text-color: @dark-color04;
@placeholder-color: @dark-color03;
@input-color: @dark-color07;
@input-bg: #f2f3f8;
@head-color: @dark-color07;
@title-color: @dark-text-title;
@second-title-color: @dark-color03;
@text-color: @primary-color;
@second-text-color: @dark-color01;
@third-text-color: @dark-color04;
@placeholder-color: @dark-color03;
@input-color: @dark-color07;
@input-bg: #f2f3f8;
@head-color: @dark-color07;
@background-color: #f0f2f5;
@icon-color: @dark-color07;
@text-color-secondary: rgba(134, 144, 156);
/* border */
@border-color: @light-color06;
@border-hover-color: @dark-color01;
@second-border-color: @light-color02;
@border-focus-color: @green-color03;
@border-radius: 2px;
@border-color-base: rgba(0, 0, 0, 15%);
/* input */
@input-border-color: @light-color08;
@input-hover-color: @dark-color01;
@input-focus-color: @green-color03;
@input-error-color: @red-color03;
@input-border-radius: @border-radius;
/* background */
@bg-color: @light-color02;
@body-bg-color: @light-color02;
@th-bg-color: @light-color01;
@card-bg-color: @white;
@dashboard-bg-color: @gray-5;
/* button */
@btn-default-bg: @light-color02;
@btn-default-border: @light-color06;
@btn-default-hover-bg: @light-color03;
@btn-default-hover-border: @light-color07;
@btn-default-active-bg: @light-color08;
@btn-default-active-border: @light-color07;
@btn-primary-bg: @dark-color07;
@btn-primary-hover-bg: @dark-color07;
@btn-control-bg: @dark-color07;
@btn-control-hover-bg: @dark-color07;
@btn-danger-bg: @red-color03;
@btn-danger-active-bg: @red-color04;
@btn-flat-hover-bg: @light-color03;
@btn-flat-active-bg: @light-color04;
@text-hover: @dark-color07;
@table-expanded-row-bg: #fdfeff;
@table-row-hover-bg: #f5f8f9;
@select-option-hover-bg: #f5f7f8;
/* shadow */
@base-shadow: 0 4px 8px 0 rgba(36, 46, 66, 6%);
@title-shadow: 0 2px 4px rgba(72, 91, 127, 40%);
@head-shadow: 0 4px 8px rgba(36, 46, 66, 10%);
@btn-text-shadow: 0 2px 4px rgba(36, 46, 66, 10%);
@btn-default-shadow: none;
@btn-default-active-shadow: inset 0 4px 8px 0 rgba(36, 46, 66, 12%);
@btn-primary-shadow: none;
@btn-primary-active-shadow: inset 0 4px 8px 0 rgba(35, 45, 65, 24%);
@btn-control-shadow: 0 8px 16px 0 rgba(35, 45, 65, 28%);
@btn-danger-shadow: 0 8px 16px 0 rgba(202, 38, 33, 28%);
@card-shadow: 0 4px 8px 0 rgba(36, 46, 66, 6%);
@card-hover-shadow: 0 6px 16px 0 rgba(33, 43, 54, 20%);
@card-selector-shadow: 0 8px 16px 0 rgba(36, 46, 66, 8%);
@tr-shadow: inset 0 2px 4px 0 rgba(72, 91, 127, 20%);
@box-shadow-base: 0 0 8px 0 rgba(0, 0, 0, 15%);
/* font */
@font-family: system-ui, -apple-system, blinkmacsystemfont, segoe ui, roboto,
'PingFang SC', 'Microsoft YaHei', 'Alibaba PuHuiTi', 'Dosis', 'Helvetica Neue',
helvetica, arial, sans-serif;
@font-family-id: @font-family;
@font-family-code: 'PT Mono', monaco, menlo, consolas, 'Courier New', monospace;
@size-small: 12px;
@size-normal: 14px;
@size-medium: 16px;
@size-mid-large: 24px;
@size-large: 28px;
@body-size: @size-small;
@font-bold: 600;
@font-normal: 400;
@font-thin: 300;
/* animation */
@trans-speed: 0.3s;
/* size */
@nav-width: 260px;
@narrow-nav-width: 240px;
@header-height: 50px;
@body-padding-left: 16px;
@body-padding-right: 16px;
@body-padding: 16px;
@breadcrumb-height: 50px;
@footer-height: 75px;
@menu-width: @sider-width;
@icon-status-info: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNLTMtM2gyNHYyNEgtM3oiLz48cGF0aCBmaWxsPSIjMjE5MUNBIiBkPSJNOSAxOEE5IDkgMCAxIDEgOSAwYTkgOSAwIDAgMSAwIDE4ek05IDUuNjgxYTEuMzEyIDEuMzEyIDAgMSAwIDAtMi42MjMgMS4zMTIgMS4zMTIgMCAwIDAgMCAyLjYyM3pNOCA3LjUxNlYxNWgyVjcuNTE2SDh6Ii8+PC9nPjwvc3ZnPg==');
@icon-status-success: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNLTMtM2gyNHYyNEgtM3oiLz48cGF0aCBmaWxsPSIjMDBBQTcyIiBkPSJNOSAxOEE5IDkgMCAxIDEgOSAwYTkgOSAwIDAgMSAwIDE4em0tMi4xMTUtNi45NEw0LjQ5NCA4LjY3bC0xLjQxNSAxLjQxNCAzLjgwNiAzLjgwNiA3LjU0OC03LjU0OC0xLjQxNC0xLjQxNC02LjEzNCA2LjEzNHoiLz48L2c+PC9zdmc+');
@icon-status-warning: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIxOCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNLTItM2gyNHYyNEgtMnoiLz48cGF0aCBmaWxsPSIjRjVDNDE0IiBkPSJNMTAgMGwxMCAxNy4zMkgwTDEwIDB6bTAgMTYuMDAxYTEgMSAwIDEgMCAwLTIgMSAxIDAgMCAwIDAgMnpNOSA2bC4yIDdoMS42bC4yLTdIOXoiLz48L2c+PC9zdmc+');
@icon-status-error: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNLTMtM2gyNHYyNEgtM3oiLz48cGF0aCBmaWxsPSIjQ0EyNjIxIiBkPSJNMTIuNzI4IDBMMTggNS4yNzJ2Ny40NTZMMTIuNzI4IDE4SDUuMjcyTDAgMTIuNzI4VjUuMjcyTDUuMjcyIDBoNy40NTZ6bS0yLjMxNCA5bDMuNDY2LTMuNDY2LTEuNDE0LTEuNDE0TDkgNy41ODYgNS41MzYgNC4xMjIgNC4xMjIgNS41MzYgNy41ODYgOSA0LjEyIDEyLjQ2NmwxLjQxNCAxLjQxNEw5IDEwLjQxNGwzLjQ2NCAzLjQ2NCAxLjQxNC0xLjQxNEwxMC40MTQgOXoiLz48cGF0aCBmaWxsPSIjRkZGIiBkPSJNMTAuNDE0IDlsMy40NjQgMy40NjQtMS40MTQgMS40MTRMOSAxMC40MTQgNS41MzQgMTMuODggNC4xMiAxMi40NjYgNy41ODYgOSA0LjEyMiA1LjUzNmwxLjQxNC0xLjQxNEw5IDcuNTg2bDMuNDY2LTMuNDY2IDEuNDE0IDEuNDE0eiIvPjwvZz48L3N2Zz4=');
/* sider */
@sider-background: #fff;
@sider-open-background: #222121;
@sider-collapsed-width: 50px;
@sider-menu-padding: 0;
@sider-menu-padding-top: 0;
@sider-border-right: 1px solid #e5e6eb;
@sider-width: 192px;
@sider-menu-item-selected-background: #f6f7fb;
@sider-sub-menu-item-margin-top: 0;
@sider-sub-menu-item-margin-bottom: 0;
@sider-sub-menu-item-selected-background: #f6f7fb;
@sider-sub-menu-item-hover-background: #f6f7fb;
@sider-menu-item-selected-border-radius: 0;
@sider-menu-item-selected-text-color: #1d2129;
@sider-menu-item-hover-dot-color: #c9cdd4;
@sider-menu-item-selected-dot-color: @primary-color;
@sider-menu-item-selected-after-border-right: 0;
@sider-sub-menu-background: #fff;
@sider-sub-menu-item-padding-left: 0;
@sider-sub-menu-item-dot-color: #c9cdd4;
@sider-trigger-background-color: rgba(0, 0, 0, 15%);
@sider-menu-title-font-size: 14px;
@sider-sub-menu-title-font-size: 13px;
@sider-sub-menu-title-color: #4e5969;
@box-shadow01: 0 2px 10px 0 rgba(1, 32, 87, 50%);
//layout
@layout-header-color: @dark-color12;
@layout-text-color: @white;
@layout-link-color: @white;
@layout-header-menu-background-color: @layout-header-color;
@layout-header-menu-text-color: @white;
@layout-header-menu-text-hover-color: @white;
@layout-header-menu-search-background: #282e39;
@layout-header-menu-search-text-color: @white;
@layout-header-menu-search-icon: #86909c;
@layout-header-menu-region-hover: #e8f2ff;
@layout-header-color-hover: @dark-color09;
@layout-selected-color: #111418;
@layout-header-logo-wrapper-width: 141px;
@layout-header-logo-image-height: 20px;
.layout-header-menu-search-border {
border: none;
}
//products
@products-icon-background: #272e3b;
@products-icon-hover-background: @primary-color;
@products-header-title-color: #fff;
@products-title-color: #c9cdd4;
@products-sub-title-color: #86909c;
@products-icon-fill-color: #c9cdd4;
@products-drawer-background-1: #101319;
@products-drawer-hover-background-1: #101319;
@products-drawer-divider-color-1: #101319;
@products-drawer-sub-title-hover-background: hsla(0deg, 0%, 100%, 10%);
@products-drawer-sub-title-hover-color: #fff;
@products-drawer-background-2: #1b1e24;
@products-drawer-header-title: #fff;
@products-drawer-left-icon: #0053ec;
@products-drawer-close-icon: #fff;
@products-drawer-search-icon: #838383;
@products-drawer-search-box-shadow: 0 0 0 2px rgba(12, 99, 250, 20%);
@products-drawer-search-placeholder-color: #86909c;
@products-drawer-search-border-color: #e9e9e9;
@products-drawer-search-border: none;
@products-drawer-search-hover-border-color: #e9e9e9;
@products-drawer-search-background: #1d2129;
@products-drawer-search-input-color: @white;
@products-column-width: @sider-width;
// breadcrumb
@breadcrumb-item-font-size: 14px;
// overview padding
@overview-padding: 16px;
// table
// @table-header-default-button-background: @background-color;
// @table-header-search-input-background: @background-color;
// @table-header-search-input-border-color: @primary-color;
@table-header-default-button-background: #fff;
@table-header-default-button-border: #fff;
@table-header-default-button-color: #1d2129;
@table-header-search-input-background: #fff;
@table-header-search-input-border-color: #fff;
@table-header-search-input-font-size: 12px;
@table-header-danger-button-color: @error-color;
@table-header-disable-button-color: #c9cdd4;
@table-header-disable-button-border: #fff;
@table-header-disable-button-background: #fff;
@table-row-selected-background: #f1f2f6;
@table-checkbox-size: 12px;
//form
@form-item-label-color: @dark-color13;
@form-item-magic-input-wrapper-border-color: #d9d9d9;
//avatar-dropdown
@avatar-color: #1d2129;
@avatar-dropdown-background-color: @dark-color12;
@avatar-dropdown-text-color: @white;
@avatar-dropdown-button-color: @white;
@avatar-dropdown-property-text-color: #86909c;
@avatar-dropdown-copy-icon-color: @white;
@avatar-dropdown-hover-background-color: @dark-color09;
@avatar-dropdown-hover-text-color: @white;
@avatar-dropdown-button-disabled-color: #86909c;
@avatar-dropdown-divider-color: rgba(134, 144, 156, 20%);
.vertical-center {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
/* login */
@login-error: #a43a39;
@money-color: #f50;
:export {
primaryColor: @primary-color;
successColor: @success-color;
warnColor: @warn-color;
warnDarkColor: @warn-dark-color;
warnLightColor: @warn-light-color;
errorColor: @error-color;
dangerColor: @danger-color;
moneyColor: @money-color;
infoColor: @info-color;
headerHeight: @header-height;
productsColumnWidth: @products-column-width;
}

View File

@ -31,6 +31,8 @@
@gray-2: #f2f2f2; @gray-2: #f2f2f2;
@gray-3: #fafafa; @gray-3: #fafafa;
@dark-text-title: rgba(0, 0, 0, 100%);
@dark-text-title-second: rgba(0, 0, 0, 85%);
@color-text-title: rgba(0, 0, 0, 85%); @color-text-title: rgba(0, 0, 0, 85%);
@color-text-body: rgba(0, 0, 0, 65%); @color-text-body: rgba(0, 0, 0, 65%);
@color-text-caption: rgba(0, 0, 0, 45%); @color-text-caption: rgba(0, 0, 0, 45%);
@ -129,12 +131,112 @@
@sider-background: #26262b; @sider-background: #26262b;
@sider-open-background: #222121; @sider-open-background: #222121;
@sider-collapsed-width: 40px; @sider-collapsed-width: 40px;
@sider-menu-padding: 14px;
@sider-menu-padding-top: 10px;
@sider-border-right: none;
@sider-width: 230px;
// @sider-menu-item-selected-background: #26262b;
@sider-menu-item-selected-background: @primary-color;
@sider-sub-menu-item-margin-top: 4px;
@sider-sub-menu-item-margin-bottom: 8px;
@sider-sub-menu-item-selected-background: @primary-color;
@sider-sub-menu-item-hover-background: transparent;
@sider-menu-item-selected-border-radius: @border-radius;
@sider-menu-item-selected-text-color: #fff;
@sider-menu-item-selected-after-border-right: 3px solid #0c63fa;
@sider-menu-item-hover-dot-color: @primary-color;
@sider-menu-item-selected-dot-color: #fff;
@sider-sub-menu-background: #222121;
@sider-sub-menu-item-padding-left: 5px;
@sider-sub-menu-item-dot-color: rgba(255, 255, 255, 65%);
@sider-trigger-background-color: rgba(0, 0, 0, 35%);
@sider-menu-title-font-size: 14px;
@sider-sub-menu-title-font-size: 14px;
@sider-sub-menu-title-color: rgba(255, 255, 255, 65%);
/* login */ /* login */
@login-error: #a43a39; @login-error: #a43a39;
@money-color: #f50; @money-color: #f50;
//layout
@layout-header-color: @white;
@layout-text-color: @title-color;
@layout-link-color: @primary-color;
@layout-header-menu-background-color: @layout-header-color;
@layout-header-menu-text-color: @white;
@layout-header-menu-text-hover-color: @white;
@layout-header-menu-search-background: #282e39;
@layout-header-menu-search-text-color: @white;
@layout-header-menu-search-icon: #86909c;
@layout-header-menu-region-hover: #e8f2ff;
@layout-header-color-hover: @primary-color;
@layout-selected-color: #111418;
@layout-header-logo-wrapper-width: 190px;
@layout-header-logo-image-height: 30px;
//form
@form-item-label-color: rgba(0, 0, 0, 85%);
@form-item-magic-input-wrapper-border-color: #d9d9d9;
//avatar-dropdown
@avatar-color: #bfbfbf;
@avatar-dropdown-background-color: #fff;
@avatar-dropdown-text-color: @color-text-title;
@avatar-dropdown-button-color: @primary-color;
@avatar-dropdown-property-text-color: #86909c;
@avatar-dropdown-copy-icon-color: @white;
@avatar-dropdown-hover-background-color: #fff;
@avatar-dropdown-hover-text-color: @color-text-title;
@avatar-dropdown-button-disabled-color: @color-text-title;
@avatar-dropdown-divider-color: #fff;
//products
@products-icon-background: @primary-color;
@products-icon-hover-background: @primary-color;
@products-header-title-color: @color-text-title;
@products-title-color: #000;
@products-sub-title-color: #000;
@products-icon-fill-color: #c9cdd4;
@products-drawer-background-1: #fff;
@products-drawer-divider-color-1: #f0f0f0;
@products-drawer-hover-background-1: rgba(0, 0, 0, 5%);
@products-drawer-sub-title-hover-background: rgba(0, 0, 0, 5%);
@products-drawer-sub-title-hover-color: #000;
@products-drawer-background-2: #fff;
@products-drawer-header-title: #fff;
@products-drawer-left-icon: #0053ec;
@products-drawer-close-icon: rgba(0, 0, 0, 45%);
@products-drawer-search-icon: rgba(0, 0, 0, 45%);
@products-drawer-search-box-shadow: 0 0 0 2px rgba(12, 99, 250, 20%);
@products-drawer-search-placeholder-color: #86909c;
@products-drawer-search-border-color: #d9d9d9;
@products-drawer-search-border: 1px solid #d9d9d9;
@products-drawer-search-hover-border-color: @primary-color;
@products-drawer-search-background: #fff;
@products-drawer-search-input-color: rgba(0, 0, 0, 85%);
@products-column-width: @sider-width;
// breadcrumb
@breadcrumb-item-font-size: 12px;
// overview padding
@overview-padding: 44px;
// table
@table-header-default-button-background: #fff;
@table-header-default-button-border: @primary-color;
@table-header-default-button-color: @primary-color;
@table-header-search-input-background: #fff;
@table-header-search-input-border-color: #d9d9d9;
@table-header-search-input-font-size: 10px;
@table-header-danger-button-color: @error-color;
@table-header-disable-button-color: rgba(0, 0, 0, 25%);
@table-header-disable-button-border: #d9d9d9;
@table-header-disable-button-background: #f5f5f5;
@table-row-selected-background: #f2f7ff;
@table-checkbox-size: 14px;
:export { :export {
primaryColor: @primary-color; primaryColor: @primary-color;
successColor: @success-color; successColor: @success-color;
@ -146,4 +248,5 @@
moneyColor: @money-color; moneyColor: @money-color;
infoColor: @info-color; infoColor: @info-color;
headerHeight: @header-height; headerHeight: @header-height;
productsColumnWidth: @products-column-width;
} }