chore: init theme (#14508)

* chore: init theme

* chore: update faas config
pull/14528/head
iamkun 2019-02-28 16:00:59 +08:00 committed by Zhi Cun
parent 2604c6192f
commit febdd3bbb4
63 changed files with 5552 additions and 805 deletions

View File

@ -172,6 +172,9 @@ const webpackConfig = {
]), ]),
new ProgressBarPlugin(), new ProgressBarPlugin(),
new VueLoaderPlugin(), new VueLoaderPlugin(),
new webpack.DefinePlugin({
'process.env.FAAS_ENV': JSON.stringify(process.env.FAAS_ENV)
}),
new webpack.LoaderOptionsPlugin({ new webpack.LoaderOptionsPlugin({
vue: { vue: {
compilerOptions: { compilerOptions: {

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

18
examples/color.js Normal file
View File

@ -0,0 +1,18 @@
export const tintColor = (c, tint) => {
const color = c.replace('#', '');
let red = parseInt(color.slice(0, 2), 16);
let green = parseInt(color.slice(2, 4), 16);
let blue = parseInt(color.slice(4, 6), 16);
if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',');
} else {
red += Math.round(tint * (255 - red));
green += Math.round(tint * (255 - green));
blue += Math.round(tint * (255 - blue));
red = red.toString(16);
green = green.toString(16);
blue = blue.toString(16);
return `#${ red }${ green }${ blue }`;
}
};

View File

@ -17,6 +17,7 @@
.container { .container {
height: 100%; height: 100%;
box-sizing: border-box; box-sizing: border-box;
border-bottom: 1px solid #DCDFE6;
} }
.nav-lang-spe { .nav-lang-spe {
@ -122,23 +123,24 @@
a { a {
text-decoration: none; text-decoration: none;
color: #888; color: #1989FA;
opacity: 0.5;
display: block; display: block;
padding: 0 22px; padding: 0 22px;
&.active, &.active,
&:hover { &:hover {
color: #333; opacity: 1;
} }
&.active::after { &.active::after {
content: ''; content: '';
display: inline-block; display: inline-block;
position: absolute; position: absolute;
bottom: 15px; bottom: 0;
left: calc(50% - 7px); left: calc(50% - 15px);
width: 14px; width: 30px;
height: 4px; height: 2px;
background: #409EFF; background: #409EFF;
} }
} }
@ -356,7 +358,8 @@
<!--theme picker--> <!--theme picker-->
<li class="nav-item nav-theme-switch" v-show="isComponentPage"> <li class="nav-item nav-theme-switch" v-show="isComponentPage">
<theme-picker></theme-picker> <theme-configurator :key="lang" v-if="showThemeConfigurator"></theme-configurator>
<theme-picker v-else></theme-picker>
</li> </li>
</ul> </ul>
</div> </div>
@ -365,9 +368,12 @@
</template> </template>
<script> <script>
import ThemePicker from './theme-picker.vue'; import ThemePicker from './theme-picker.vue';
import ThemeConfigurator from './theme-configurator';
import AlgoliaSearch from './search.vue'; import AlgoliaSearch from './search.vue';
import compoLang from '../i18n/component.json'; import compoLang from '../i18n/component.json';
import Element from 'main/index.js'; import Element from 'main/index.js';
import bus from '../bus';
const { version } = Element; const { version } = Element;
export default { export default {
@ -389,6 +395,7 @@
components: { components: {
ThemePicker, ThemePicker,
ThemeConfigurator,
AlgoliaSearch AlgoliaSearch
}, },
@ -404,6 +411,10 @@
}, },
isComponentPage() { isComponentPage() {
return /^component/.test(this.$route.name); return /^component/.test(this.$route.name);
},
showThemeConfigurator() {
const host = location.hostname;
return host.match('localhost') || host.match('elenet');
} }
}, },
@ -441,6 +452,17 @@
}; };
xhr.open('GET', '/versions.json'); xhr.open('GET', '/versions.json');
xhr.send(); xhr.send();
let primaryLast = '#409EFF';
bus.$on('user-theme-config-update', (val) => {
let primaryColor = val.global['$--color-primary'];
if (!primaryColor) primaryColor = '#409EFF';
const base64svg = 'data:image/svg+xml;base64,';
const imgSet = document.querySelectorAll('h1 img');
imgSet.forEach((img) => {
img.src = `${base64svg}${window.btoa(window.atob(img.src.replace(base64svg, '')).replace(primaryLast, primaryColor))}`;
});
primaryLast = primaryColor;
});
} }
}; };
</script> </script>

View File

@ -0,0 +1,55 @@
<script>
const ORIGINAL_THEME = '#409EFF';
import { get as ajaxGet } from './utils/ajax';
import { updateDomHeadStyle } from './utils/utils.js';
export default {
data() {
return {
docs: '', // content of docs css
theme: ORIGINAL_THEME
};
},
methods: {
updateDocStyle(e) {
const val = e.global['$--color-primary'] || ORIGINAL_THEME;
const oldVal = this.theme;
const getHandler = (variable, id) => {
return () => {
let newStyle = this.updateStyle(this[variable], ORIGINAL_THEME, val);
updateDomHeadStyle(id, newStyle);
};
};
const docsHandler = getHandler('docs', 'docs-style');
if (!this.docs) {
const links = [].filter.call(document.querySelectorAll('link'), link => {
return /docs\..+\.css/.test(link.href || '');
});
links[0] && this.getCSSString(links[0].href, docsHandler, 'docs');
} else {
docsHandler();
}
const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => {
const text = style.innerText;
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text);
});
styles.forEach(style => {
const { innerText } = style;
if (typeof innerText !== 'string') return;
style.innerText = this.updateStyle(innerText, oldVal, val);
});
this.theme = val;
},
updateStyle(style, oldColor, newColor) {
return style.replace(new RegExp(oldColor, 'ig'), newColor);
},
getCSSString(url, callback, variable) {
ajaxGet(url).then((res) => {
this[variable] = res;
callback();
});
}
}
};
</script>

View File

@ -0,0 +1,76 @@
<template>
<div class="action-area">
<div class="action-area-main">
<div class="action-button">
<el-button type="warning" @click.stop="onReset">{{getActionDisplayName("reset-theme")}}</el-button>
</div>
<div class="action-button">
<el-button
type="primary"
:loading=downloading
@click.stop="onDownload">
{{getActionDisplayName("download-theme")}}
</el-button>
</div>
</div>
</div>
</template>
<style>
.action-area {
width: 24%;
max-width: 400px;
position: fixed;
right: 0;
bottom: 0;
padding-right: 1%;
}
@media (min-width: 1600px) {
.action-area {
padding-right: calc((100% - 1600px) / 2);
}
}
.action-area-main {
opacity: .95;
background: #F5F7FA;
height: 70px;
bottom: 0;
width: 97%;
box-sizing: border-box;
margin: 0 .5% 0 5%;
}
.action-button {
width: 50%;
text-align: center;
display: inline-block;
padding-top: 15px;
}
</style>
<script>
import { getActionDisplayName } from './utils/utils.js';
export default {
data() {
return {
downloading: false
};
},
methods: {
onReset() {
this.$parent.onReset();
},
getActionDisplayName(key) {
return getActionDisplayName(key);
},
onDownload() {
this.downloading = true;
this.$parent.onDownload()
.then()
.catch((err) => {
this.$parent.onError(err);
})
.then(() => {
this.downloading = false;
});
}
}
};
</script>

View File

@ -0,0 +1,86 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<theme-input
v-if="isGlobal"
:val="value"
@change="onChange"
></theme-input>
<el-select
v-if="!isGlobal"
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
import Mixin from './mixin';
import Input from './input';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
data() {
return {
options: [],
value: ''
};
},
components: {
themeInput: Input
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
const golbalV = this.golbalValue.border;
if (golbalV) {
Object.keys(golbalV).forEach((font) => {
if (font.includes('border-radius')) {
const size = golbalV[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@ -0,0 +1,155 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
<el-button
class="plus-button"
size="mini"
round
icon="el-icon-plus"
@click.stop="onAddShadow"
>
</el-button>
</div>
<div class="config-content" v-for="(each, key) in valueArr" :key="key">
<div class="content-10">
<color-picker
size="mini"
class="colorPicker"
v-model="each.color"
@change="val => onInputChange(val, key, 'color')"
show-alpha
></color-picker>
<span class="content-tip">Color</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.offsetX"
@change="val => onInputChange(Number(val), key, 'offsetX')"
>
</theme-input>
<span class="content-tip">X-px</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.offsetY"
@change="val => onInputChange(Number(val), key, 'offsetY')"
>
</theme-input>
<span class="content-tip">Y-px</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.spreadRadius"
@change="val => onInputChange(Number(val), key, 'spreadRadius')"
>
</theme-input>
<span class="content-tip">Spread</span>
</div>
<div class="content-20">
<theme-input
size="mini"
:val="each.blurRadius"
@change="val => onInputChange(Number(val), key, 'blurRadius')"
>
</theme-input>
<span class="content-tip">Blur</span>
</div>
<div class="content-10">
<el-button
size="mini"
round
icon="el-icon-minus"
@click.stop="val => onMinusShadow(key)"
></el-button>
</div>
</div>
</section>
</template>
<style scoped>
.plus-button {
position: absolute;
left: 90%;
}
.colorPicker {
margin-left: 0;
}
.content-20 .el-input__suffix-inner span{
line-height: 28px;
}
.content-20 {
padding: 0 3px;
}
.content-10 {
vertical-align: top;
}
.content-tip {
color: #909399;
font-size: 12px;
}
.config-content {
padding: 5px 0;
}
/* Element buton style override */
.el-button--mini.is-round {
padding: 3px 3px;
}
</style>
<script>
import Mixin from './mixin';
import Input from './input';
import { parse as parseShaodw, stringify as stringifyShaodw } from '../utils/boxShadow.js';
import ColorPicker from './color-picker';
export default {
components: {
ColorPicker,
themeInput: Input
},
data() {
return {
valueArr: []
};
},
mixins: [Mixin],
methods: {
onAddShadow() {
this.valueArr.push({
offsetX: 0,
offsetY: 0,
spreadRadius: 0,
blurRadius: 0,
color: 'rgba(0,0,0,0)',
inset: false
});
},
onMinusShadow(index) {
this.valueArr.splice(index, 1);
this.onShadowChange();
},
onInputChange(e, index, key) {
const arr = this.valueArr[index];
arr[key] = e;
this.valueArr.splice(index, 1, arr);
this.onShadowChange();
},
onShadowChange() {
this.onChange(
stringifyShaodw(this.valueArr)
);
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.valueArr = parseShaodw(value);
}
}
}
};
</script>

View File

@ -0,0 +1,8 @@
import ColorPicker from './src/main';
/* istanbul ignore next */
ColorPicker.install = function(Vue) {
Vue.component(ColorPicker.name, ColorPicker);
};
export default ColorPicker;

View File

@ -0,0 +1,316 @@
const hsv2hsl = function(hue, sat, val) {
return [
hue,
(sat * val / ((hue = (2 - sat) * val) < 1 ? hue : 2 - hue)) || 0,
hue / 2
];
};
// Need to handle 1.0 as 100%, since once it is a number, there is no difference between it and 1
// <http://stackoverflow.com/questions/7422072/javascript-how-to-detect-number-as-a-decimal-including-1-0>
const isOnePointZero = function(n) {
return typeof n === 'string' && n.indexOf('.') !== -1 && parseFloat(n) === 1;
};
const isPercentage = function(n) {
return typeof n === 'string' && n.indexOf('%') !== -1;
};
// Take input from [0, n] and return it as [0, 1]
const bound01 = function(value, max) {
if (isOnePointZero(value)) value = '100%';
const processPercent = isPercentage(value);
value = Math.min(max, Math.max(0, parseFloat(value)));
// Automatically convert percentage into number
if (processPercent) {
value = parseInt(value * max, 10) / 100;
}
// Handle floating point rounding errors
if ((Math.abs(value - max) < 0.000001)) {
return 1;
}
// Convert into [0, 1] range if it isn't already
return (value % max) / parseFloat(max);
};
const INT_HEX_MAP = { 10: 'A', 11: 'B', 12: 'C', 13: 'D', 14: 'E', 15: 'F' };
const toHex = function({ r, g, b }) {
const hexOne = function(value) {
value = Math.min(Math.round(value), 255);
const high = Math.floor(value / 16);
const low = value % 16;
return '' + (INT_HEX_MAP[high] || high) + (INT_HEX_MAP[low] || low);
};
if (isNaN(r) || isNaN(g) || isNaN(b)) return '';
return '#' + hexOne(r) + hexOne(g) + hexOne(b);
};
const HEX_INT_MAP = { A: 10, B: 11, C: 12, D: 13, E: 14, F: 15 };
const parseHexChannel = function(hex) {
if (hex.length === 2) {
return (HEX_INT_MAP[hex[0].toUpperCase()] || +hex[0]) * 16 + (HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1]);
}
return HEX_INT_MAP[hex[1].toUpperCase()] || +hex[1];
};
const hsl2hsv = function(hue, sat, light) {
sat = sat / 100;
light = light / 100;
let smin = sat;
const lmin = Math.max(light, 0.01);
let sv;
let v;
light *= 2;
sat *= (light <= 1) ? light : 2 - light;
smin *= lmin <= 1 ? lmin : 2 - lmin;
v = (light + sat) / 2;
sv = light === 0 ? (2 * smin) / (lmin + smin) : (2 * sat) / (light + sat);
return {
h: hue,
s: sv * 100,
v: v * 100
};
};
// `rgbToHsv`
// Converts an RGB color value to HSV
// *Assumes:* r, g, and b are contained in the set [0, 255] or [0, 1]
// *Returns:* { h, s, v } in [0,1]
const rgb2hsv = function(r, g, b) {
r = bound01(r, 255);
g = bound01(g, 255);
b = bound01(b, 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
let h, s;
let v = max;
const d = max - min;
s = max === 0 ? 0 : d / max;
if (max === min) {
h = 0; // achromatic
} else {
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return { h: h * 360, s: s * 100, v: v * 100 };
};
// `hsvToRgb`
// Converts an HSV color value to RGB.
// *Assumes:* h is contained in [0, 1] or [0, 360] and s and v are contained in [0, 1] or [0, 100]
// *Returns:* { r, g, b } in the set [0, 255]
const hsv2rgb = function(h, s, v) {
h = bound01(h, 360) * 6;
s = bound01(s, 100);
v = bound01(v, 100);
const i = Math.floor(h);
const f = h - i;
const p = v * (1 - s);
const q = v * (1 - f * s);
const t = v * (1 - (1 - f) * s);
const mod = i % 6;
const r = [v, q, p, p, t, v][mod];
const g = [t, v, v, q, p, p][mod];
const b = [p, p, t, v, v, q][mod];
return {
r: Math.round(r * 255),
g: Math.round(g * 255),
b: Math.round(b * 255)
};
};
export default class Color {
constructor(options) {
this._hue = 0;
this._saturation = 100;
this._value = 100;
this._alpha = 100;
this.enableAlpha = false;
this.format = 'hex';
this.value = '';
options = options || {};
for (let option in options) {
if (options.hasOwnProperty(option)) {
this[option] = options[option];
}
}
this.doOnChange();
}
set(prop, value) {
if (arguments.length === 1 && typeof prop === 'object') {
for (let p in prop) {
if (prop.hasOwnProperty(p)) {
this.set(p, prop[p]);
}
}
return;
}
this['_' + prop] = value;
this.doOnChange();
}
get(prop) {
return this['_' + prop];
}
toRgb() {
return hsv2rgb(this._hue, this._saturation, this._value);
}
fromString(value) {
if (!value) {
this._hue = 0;
this._saturation = 100;
this._value = 100;
this.doOnChange();
return;
}
const fromHSV = (h, s, v) => {
this._hue = Math.max(0, Math.min(360, h));
this._saturation = Math.max(0, Math.min(100, s));
this._value = Math.max(0, Math.min(100, v));
this.doOnChange();
};
if (value.indexOf('hsl') !== -1) {
const parts = value.replace(/hsla|hsl|\(|\)/gm, '')
.split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
if (parts.length === 4) {
this._alpha = Math.floor(parseFloat(parts[3]) * 100);
} else if (parts.length === 3) {
this._alpha = 100;
}
if (parts.length >= 3) {
const { h, s, v } = hsl2hsv(parts[0], parts[1], parts[2]);
fromHSV(h, s, v);
}
} else if (value.indexOf('hsv') !== -1) {
const parts = value.replace(/hsva|hsv|\(|\)/gm, '')
.split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
if (parts.length === 4) {
this._alpha = Math.floor(parseFloat(parts[3]) * 100);
} else if (parts.length === 3) {
this._alpha = 100;
}
if (parts.length >= 3) {
fromHSV(parts[0], parts[1], parts[2]);
}
} else if (value.indexOf('rgb') !== -1) {
const parts = value.replace(/rgba|rgb|\(|\)/gm, '')
.split(/\s|,/g).filter((val) => val !== '').map((val, index) => index > 2 ? parseFloat(val) : parseInt(val, 10));
if (parts.length === 4) {
this._alpha = Math.floor(parseFloat(parts[3]) * 100);
} else if (parts.length === 3) {
this._alpha = 100;
}
if (parts.length >= 3) {
const { h, s, v } = rgb2hsv(parts[0], parts[1], parts[2]);
fromHSV(h, s, v);
}
} else if (value.indexOf('#') !== -1) {
const hex = value.replace('#', '').trim();
let r, g, b;
if (hex.length === 3) {
r = parseHexChannel(hex[0] + hex[0]);
g = parseHexChannel(hex[1] + hex[1]);
b = parseHexChannel(hex[2] + hex[2]);
} else if (hex.length === 6 || hex.length === 8) {
r = parseHexChannel(hex.substring(0, 2));
g = parseHexChannel(hex.substring(2, 4));
b = parseHexChannel(hex.substring(4, 6));
}
if (hex.length === 8) {
this._alpha = Math.floor(parseHexChannel(hex.substring(6)) / 255 * 100);
} else if (hex.length === 3 || hex.length === 6) {
this._alpha = 100;
}
const { h, s, v } = rgb2hsv(r, g, b);
fromHSV(h, s, v);
}
}
compare(color) {
return Math.abs(color._hue - this._hue) < 2 &&
Math.abs(color._saturation - this._saturation) < 1 &&
Math.abs(color._value - this._value) < 1 &&
Math.abs(color._alpha - this._alpha) < 1;
}
doOnChange() {
const { _hue, _saturation, _value, _alpha, format } = this;
if (this.enableAlpha) {
switch (format) {
case 'hsl':
const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100);
this.value = `hsla(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%, ${ _alpha / 100})`;
break;
case 'hsv':
this.value = `hsva(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%, ${ _alpha / 100})`;
break;
default:
const { r, g, b } = hsv2rgb(_hue, _saturation, _value);
this.value = `rgba(${r}, ${g}, ${b}, ${ _alpha / 100 })`;
}
} else {
switch (format) {
case 'hsl':
const hsl = hsv2hsl(_hue, _saturation / 100, _value / 100);
this.value = `hsl(${ _hue }, ${ Math.round(hsl[1] * 100) }%, ${ Math.round(hsl[2] * 100) }%)`;
break;
case 'hsv':
this.value = `hsv(${ _hue }, ${ Math.round(_saturation) }%, ${ Math.round(_value) }%)`;
break;
case 'rgb':
const { r, g, b } = hsv2rgb(_hue, _saturation, _value);
this.value = `rgb(${r}, ${g}, ${b})`;
break;
default:
this.value = toHex(hsv2rgb(_hue, _saturation, _value));
}
}
}
};

View File

@ -0,0 +1,132 @@
<template>
<div class="el-color-alpha-slider" :class="{ 'is-vertical': vertical }">
<div class="el-color-alpha-slider__bar"
@click="handleClick"
ref="bar"
:style="{
background: background
}">
</div>
<div class="el-color-alpha-slider__thumb"
ref="thumb"
:style="{
left: thumbLeft + 'px',
top: thumbTop + 'px'
}">
</div>
</div>
</template>
<script>
import draggable from '../draggable';
export default {
name: 'el-color-alpha-slider',
props: {
color: {
required: true
},
vertical: Boolean
},
watch: {
'color._alpha'() {
this.update();
},
'color.value'() {
this.update();
}
},
methods: {
handleClick(event) {
const thumb = this.$refs.thumb;
const target = event.target;
if (target !== thumb) {
this.handleDrag(event);
}
},
handleDrag(event) {
const rect = this.$el.getBoundingClientRect();
const { thumb } = this.$refs;
if (!this.vertical) {
let left = event.clientX - rect.left;
left = Math.max(thumb.offsetWidth / 2, left);
left = Math.min(left, rect.width - thumb.offsetWidth / 2);
this.color.set('alpha', Math.round((left - thumb.offsetWidth / 2) / (rect.width - thumb.offsetWidth) * 100));
} else {
let top = event.clientY - rect.top;
top = Math.max(thumb.offsetHeight / 2, top);
top = Math.min(top, rect.height - thumb.offsetHeight / 2);
this.color.set('alpha', Math.round((top - thumb.offsetHeight / 2) / (rect.height - thumb.offsetHeight) * 100));
}
},
getThumbLeft() {
if (this.vertical) return 0;
const el = this.$el;
const alpha = this.color._alpha;
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(alpha * (el.offsetWidth - thumb.offsetWidth / 2) / 100);
},
getThumbTop() {
if (!this.vertical) return 0;
const el = this.$el;
const alpha = this.color._alpha;
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(alpha * (el.offsetHeight - thumb.offsetHeight / 2) / 100);
},
getBackground() {
if (this.color && this.color.value) {
const { r, g, b } = this.color.toRgb();
return `linear-gradient(to right, rgba(${r}, ${g}, ${b}, 0) 0%, rgba(${r}, ${g}, ${b}, 1) 100%)`;
}
return null;
},
update() {
this.thumbLeft = this.getThumbLeft();
this.thumbTop = this.getThumbTop();
this.background = this.getBackground();
}
},
data() {
return {
thumbLeft: 0,
thumbTop: 0,
background: null
};
},
mounted() {
const { bar, thumb } = this.$refs;
const dragConfig = {
drag: (event) => {
this.handleDrag(event);
},
end: (event) => {
this.handleDrag(event);
}
};
draggable(bar, dragConfig);
draggable(thumb, dragConfig);
this.update();
}
};
</script>

View File

@ -0,0 +1,113 @@
<template>
<div class="el-color-predefine color-list-container">
<div class="el-color-predefine__colors color-list">
<div class="color-list-item"
:class="{selected: item.selected, 'is-alpha': item._alpha < 100}"
v-for="(item, index) in rgbaColors"
:key="colors[index].variable"
@click="handleSelect(index)">
<span class="color-list-item-ball" :style="{'background-color': item.value}">
</span>
<div class="color-list-item-label">
{{item.info.label}}
</div>
<div class="color-list-item-value">
{{item.info.value}}
</div>
</div>
</div>
</div>
</template>
<style>
.color-list-container {
border-top: 1px solid #EBEEF5;
margin-top: 15px;
padding-top: 10px;
width: 100%;
}
.color-list {
max-height: 138px;
overflow: auto;
}
.color-list-item {
height: 24px;
width: 100%;
cursor: pointer;
margin: 2px 0;
}
.color-list-item:hover {
background: #efefef;
}
.color-list-item-ball {
height: 20px;
width: 20px;
margin-top: 2px;
margin-left: 5px;
border-radius: 100%;
display: inline-block;
}
.color-list-item-label {
margin-left: 15px;
font-size: 13px;
line-height: 24px;
display: inline-block;
vertical-align: super;
width: 30%;
}
.color-list-item-value {
margin-left: 15px;
font-size: 13px;
line-height: 24px;
display: inline-block;
vertical-align: super;
}
</style>
<script>
import Color from '../color';
export default {
props: {
colors: { type: Array, required: true },
color: { required: true }
},
data() {
return {
rgbaColors: this.parseColors(this.colors, this.color)
};
},
methods: {
handleSelect(index) {
this.color.fromString(this.colors[index].value);
this.$emit('select', this.colors[index]);
},
parseColors(colors, color) {
return colors.map(value => {
const c = new Color();
c.enableAlpha = true;
c.format = 'rgba';
c.fromString(value.value);
c.info = value;
c.selected = c.value === color.value;
return c;
});
}
},
watch: {
'$parent.currentColor'(val) {
const color = new Color();
color.fromString(val);
this.rgbaColors.forEach(item => {
item.selected = color.compare(item);
});
},
colors(newVal) {
this.rgbaColors = this.parseColors(newVal, this.color);
},
color(newVal) {
this.rgbaColors = this.parseColors(this.colors, newVal);
}
}
};
</script>

View File

@ -0,0 +1,123 @@
<template>
<div class="el-color-hue-slider" :class="{ 'is-vertical': vertical }">
<div class="el-color-hue-slider__bar" @click="handleClick" ref="bar"></div>
<div class="el-color-hue-slider__thumb"
:style="{
left: thumbLeft + 'px',
top: thumbTop + 'px'
}"
ref="thumb">
</div>
</div>
</template>
<script>
import draggable from '../draggable';
export default {
name: 'el-color-hue-slider',
props: {
color: {
required: true
},
vertical: Boolean
},
data() {
return {
thumbLeft: 0,
thumbTop: 0
};
},
computed: {
hueValue() {
const hue = this.color.get('hue');
return hue;
}
},
watch: {
hueValue() {
this.update();
}
},
methods: {
handleClick(event) {
const thumb = this.$refs.thumb;
const target = event.target;
if (target !== thumb) {
this.handleDrag(event);
}
},
handleDrag(event) {
const rect = this.$el.getBoundingClientRect();
const { thumb } = this.$refs;
let hue;
if (!this.vertical) {
let left = event.clientX - rect.left;
left = Math.min(left, rect.width - thumb.offsetWidth / 2);
left = Math.max(thumb.offsetWidth / 2, left);
hue = Math.round((left - thumb.offsetWidth / 2) / (rect.width - thumb.offsetWidth) * 360);
} else {
let top = event.clientY - rect.top;
top = Math.min(top, rect.height - thumb.offsetHeight / 2);
top = Math.max(thumb.offsetHeight / 2, top);
hue = Math.round((top - thumb.offsetHeight / 2) / (rect.height - thumb.offsetHeight) * 360);
}
this.color.set('hue', hue);
},
getThumbLeft() {
if (this.vertical) return 0;
const el = this.$el;
const hue = this.color.get('hue');
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(hue * (el.offsetWidth - thumb.offsetWidth / 2) / 360);
},
getThumbTop() {
if (!this.vertical) return 0;
const el = this.$el;
const hue = this.color.get('hue');
if (!el) return 0;
const thumb = this.$refs.thumb;
return Math.round(hue * (el.offsetHeight - thumb.offsetHeight / 2) / 360);
},
update() {
this.thumbLeft = this.getThumbLeft();
this.thumbTop = this.getThumbTop();
}
},
mounted() {
const { bar, thumb } = this.$refs;
const dragConfig = {
drag: (event) => {
this.handleDrag(event);
},
end: (event) => {
this.handleDrag(event);
}
};
draggable(bar, dragConfig);
draggable(thumb, dragConfig);
this.update();
}
};
</script>

View File

@ -0,0 +1,134 @@
<template>
<transition name="el-zoom-in-top" @after-leave="doDestroy">
<div
class="el-color-dropdown"
v-show="showPopper">
<div class="el-color-dropdown__main-wrapper">
<hue-slider ref="hue" :color="color" vertical style="float: right;"></hue-slider>
<sv-panel ref="sl" :color="color"></sv-panel>
</div>
<alpha-slider v-if="showAlpha" ref="alpha" :color="color"></alpha-slider>
<predefine v-if="predefine" :color="color" :colors="predefine"></predefine>
<div class="el-color-dropdown__btns">
<span class="el-color-dropdown__value">
<el-input
v-model="customInput"
@keyup.native.enter="handleConfirm"
@blur="handleConfirm"
:validate-event="false"
size="mini">
</el-input>
</span>
<!-- <el-button
size="mini"
type="text"
class="el-color-dropdown__link-btn"
@click="$emit('clear')">
{{ t('el.colorpicker.clear') }}
</el-button> -->
<el-button
plain
size="mini"
class="el-color-dropdown__btn"
@click="confirmValue">
{{ t('el.colorpicker.confirm') }}
</el-button>
</div>
<color-list
v-if="colorList && colorList.length > 0"
:color="color"
:colors="colorList"
@select=onColorListSelect
></color-list>
</div>
</transition>
</template>
<script>
import SvPanel from './sv-panel';
import HueSlider from './hue-slider';
import AlphaSlider from './alpha-slider';
import Predefine from './predefine';
import ColorList from './color-list';
import Popper from 'element-ui/src/utils/vue-popper';
import Locale from 'element-ui/src/mixins/locale';
import ElInput from 'element-ui/packages/input';
import ElButton from 'element-ui/packages/button';
export default {
name: 'el-color-picker-dropdown',
mixins: [Popper, Locale],
components: {
SvPanel,
HueSlider,
AlphaSlider,
ElInput,
ElButton,
Predefine,
ColorList
},
props: {
color: {
required: true
},
showAlpha: Boolean,
predefine: Array,
colorList: Array
},
data() {
return {
customInput: ''
};
},
computed: {
currentColor() {
const parent = this.$parent;
return !parent.value && !parent.showPanelColor ? '' : parent.color.value;
}
},
methods: {
confirmValue() {
this.$emit('pick');
},
onColorListSelect(e) {
this.$emit('pick', e);
},
handleConfirm() {
this.color.fromString(this.customInput);
}
},
mounted() {
this.$parent.popperElm = this.popperElm = this.$el;
this.referenceElm = this.$parent.$el;
},
watch: {
showPopper(val) {
if (val === true) {
this.$nextTick(() => {
const { sl, hue, alpha } = this.$refs;
sl && sl.update();
hue && hue.update();
alpha && alpha.update();
});
}
},
currentColor: {
immediate: true,
handler(val) {
this.customInput = val;
}
}
}
};
</script>

View File

@ -0,0 +1,61 @@
<template>
<div class="el-color-predefine">
<div class="el-color-predefine__colors">
<div class="el-color-predefine__color-selector"
:class="{selected: item.selected, 'is-alpha': item._alpha < 100}"
v-for="(item, index) in rgbaColors"
:key="colors[index]"
@click="handleSelect(index)">
<div :style="{'background-color': item.value}">
</div>
</div>
</div>
</div>
</template>
<script>
import Color from '../color';
export default {
props: {
colors: { type: Array, required: true },
color: { required: true }
},
data() {
return {
rgbaColors: this.parseColors(this.colors, this.color)
};
},
methods: {
handleSelect(index) {
this.color.fromString(this.colors[index]);
},
parseColors(colors, color) {
return colors.map(value => {
const c = new Color();
c.enableAlpha = true;
c.format = 'rgba';
c.fromString(value);
c.selected = c.value === color.value;
return c;
});
}
},
watch: {
'$parent.currentColor'(val) {
const color = new Color();
color.fromString(val);
this.rgbaColors.forEach(item => {
item.selected = color.compare(item);
});
},
colors(newVal) {
this.rgbaColors = this.parseColors(newVal, this.color);
},
color(newVal) {
this.rgbaColors = this.parseColors(this.colors, newVal);
}
}
};
</script>

View File

@ -0,0 +1,100 @@
<template>
<div class="el-color-svpanel"
:style="{
backgroundColor: background
}">
<div class="el-color-svpanel__white"></div>
<div class="el-color-svpanel__black"></div>
<div class="el-color-svpanel__cursor"
:style="{
top: cursorTop + 'px',
left: cursorLeft + 'px'
}">
<div></div>
</div>
</div>
</template>
<script>
import draggable from '../draggable';
export default {
name: 'el-sl-panel',
props: {
color: {
required: true
}
},
computed: {
colorValue() {
const hue = this.color.get('hue');
const value = this.color.get('value');
return { hue, value };
}
},
watch: {
colorValue() {
this.update();
}
},
methods: {
update() {
const saturation = this.color.get('saturation');
const value = this.color.get('value');
const el = this.$el;
let { clientWidth: width, clientHeight: height } = el;
this.cursorLeft = saturation * width / 100;
this.cursorTop = (100 - value) * height / 100;
this.background = 'hsl(' + this.color.get('hue') + ', 100%, 50%)';
},
handleDrag(event) {
const el = this.$el;
const rect = el.getBoundingClientRect();
let left = event.clientX - rect.left;
let top = event.clientY - rect.top;
left = Math.max(0, left);
left = Math.min(left, rect.width);
top = Math.max(0, top);
top = Math.min(top, rect.height);
this.cursorLeft = left;
this.cursorTop = top;
this.color.set({
saturation: left / rect.width * 100,
value: 100 - top / rect.height * 100
});
}
},
mounted() {
draggable(this.$el, {
drag: (event) => {
this.handleDrag(event);
},
end: (event) => {
this.handleDrag(event);
}
});
this.update();
},
data() {
return {
cursorTop: 0,
cursorLeft: 0,
background: 'hsl(0, 100%, 50%)'
};
}
};
</script>

View File

@ -0,0 +1,36 @@
import Vue from 'vue';
let isDragging = false;
export default function(element, options) {
if (Vue.prototype.$isServer) return;
const moveFn = function(event) {
if (options.drag) {
options.drag(event);
}
};
const upFn = function(event) {
document.removeEventListener('mousemove', moveFn);
document.removeEventListener('mouseup', upFn);
document.onselectstart = null;
document.ondragstart = null;
isDragging = false;
if (options.end) {
options.end(event);
}
};
element.addEventListener('mousedown', function(event) {
if (isDragging) return;
document.onselectstart = function() { return false; };
document.ondragstart = function() { return false; };
document.addEventListener('mousemove', moveFn);
document.addEventListener('mouseup', upFn);
isDragging = true;
if (options.start) {
options.start(event);
}
});
}

View File

@ -0,0 +1,190 @@
<template>
<div
:class="[
'el-color-picker',
colorDisabled ? 'is-disabled' : '',
colorSize ? `el-color-picker--${ colorSize }` : ''
]"
v-clickoutside="hide">
<div class="el-color-picker__mask" v-if="colorDisabled"></div>
<div class="el-color-picker__trigger" @click="handleTrigger">
<span class="el-color-picker__color" :class="{ 'is-alpha': showAlpha }">
<span class="el-color-picker__color-inner"
:style="{
backgroundColor: displayedColor
}"></span>
<span class="el-color-picker__empty el-icon-close" v-if="!value && !showPanelColor"></span>
</span>
<span class="el-color-picker__icon el-icon-arrow-down" v-show="value || showPanelColor"></span>
</div>
<picker-dropdown
ref="dropdown"
:class="['el-color-picker__panel', popperClass || '']"
v-model="showPicker"
@pick="confirmValue"
@clear="clearValue"
:color="color"
:show-alpha="showAlpha"
:predefine="predefine"
:colorList="colorList">
</picker-dropdown>
</div>
</template>
<script>
import Color from './color';
import PickerDropdown from './components/picker-dropdown.vue';
import Clickoutside from 'element-ui/src/utils/clickoutside';
import Emitter from 'element-ui/src/mixins/emitter';
export default {
name: 'ElColorPicker',
mixins: [Emitter],
props: {
value: String,
showAlpha: Boolean,
colorFormat: String,
disabled: Boolean,
size: String,
popperClass: String,
predefine: Array,
colorList: Array
},
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
directives: { Clickoutside },
computed: {
displayedColor() {
if (!this.value && !this.showPanelColor) {
return 'transparent';
}
return this.displayedRgb(this.color, this.showAlpha);
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
colorSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
colorDisabled() {
return this.disabled || (this.elForm || {}).disabled;
}
},
watch: {
value(val) {
if (!val) {
this.showPanelColor = false;
} else if (val && val !== this.color.value) {
this.color.fromString(val);
}
},
color: {
deep: true,
handler() {
this.showPanelColor = true;
}
},
displayedColor(val) {
if (!this.showPicker) return;
const currentValueColor = new Color({
enableAlpha: this.showAlpha,
format: this.colorFormat
});
currentValueColor.fromString(this.value);
const currentValueColorRgb = this.displayedRgb(currentValueColor, this.showAlpha);
if (val !== currentValueColorRgb) {
this.$emit('active-change', val);
}
}
},
methods: {
handleTrigger() {
if (this.colorDisabled) return;
this.showPicker = !this.showPicker;
},
confirmValue(selection) {
const value = selection || this.color.value;
this.$emit('input', value);
this.$emit('change', value);
this.dispatch('ElFormItem', 'el.form.change', value);
this.showPicker = false;
},
clearValue() {
this.$emit('input', null);
this.$emit('change', null);
if (this.value !== null) {
this.dispatch('ElFormItem', 'el.form.change', null);
}
this.showPanelColor = false;
this.showPicker = false;
this.resetColor();
},
hide() {
this.showPicker = false;
this.resetColor();
},
resetColor() {
this.$nextTick(_ => {
if (this.value) {
this.color.fromString(this.value);
} else {
this.showPanelColor = false;
}
});
},
displayedRgb(color, showAlpha) {
if (!(color instanceof Color)) {
throw Error('color should be instance of Color Class');
}
const { r, g, b } = color.toRgb();
return showAlpha
? `rgba(${ r }, ${ g }, ${ b }, ${ color.get('alpha') / 100 })`
: `rgb(${ r }, ${ g }, ${ b })`;
}
},
mounted() {
const value = this.value;
if (value) {
this.color.fromString(value);
}
this.popperElm = this.$refs.dropdown.$el;
},
data() {
const color = new Color({
enableAlpha: this.showAlpha,
format: this.colorFormat
});
return {
color,
showPicker: false,
showPanelColor: false
};
},
components: {
PickerDropdown
}
};
</script>

View File

@ -0,0 +1,89 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<div class="content-80">
<el-input
:value=displayValue
readonly
slot="reference"
@click.native="onInputClick"
></el-input>
</div>
<div class="content-20">
<color-picker
ref="colorPicker"
class="colorPicker"
v-model="pickerColor"
@change=onPickerChange
:colorList="golbalColorList"
></color-picker>
</div>
</div>
</section>
</template>
<style>
input {
cursor: pointer;
}
.colorPicker {
margin-left: 10px;
vertical-align: bottom;
}
</style>
<script>
import Mixin from './mixin';
import { getStyleDisplayValue, getStyleDisplayName } from '../utils/utils.js';
import ColorPicker from './color-picker';
export default {
components: {
ColorPicker
},
data() {
return {
pickerColor: ''
};
},
mixins: [Mixin],
watch: {
displayValue: {
immediate: true,
handler(value) {
if (value.startsWith('#')) {
this.pickerColor = value;
}
}
}
},
computed: {
golbalColor() {
return this.golbalValue.color;
},
displayValue() {
return getStyleDisplayValue(this.mergedValue, this.golbalColor);
},
golbalColorList() {
return this.isGlobal ? [] : Object.keys(this.golbalColor).map((c) => (
{
label: getStyleDisplayName(this.golbalColor[c]),
value: this.golbalColor[c].value,
variable: c
}
));
}
},
methods: {
onInputClick() {
this.$refs.colorPicker && this.$refs.colorPicker.handleTrigger();
},
onPickerChange(e) {
this.onChange(e.variable || e);
}
}
};
</script>

View File

@ -0,0 +1,101 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
const defaultFontLineHeight = [
'1',
'1.3',
'1.5',
'1.7',
'12px',
'16px',
'20px',
'24px',
'28px'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontLineHeight.forEach((size) => {
this.options.push({
value: size,
label: size
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-line-height')) {
const size = golbalTypography[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@ -0,0 +1,101 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
const defaultFontSize = [
'12px',
'13px',
'14px',
'16px',
'18px',
'20px',
'28px',
'36px',
'48px'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontSize.forEach((size) => {
this.options.push({
value: size,
label: size
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-size')) {
const size = golbalTypography[font];
this.options.push({
value: size.key,
label: getStyleDisplayName(size)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@ -0,0 +1,106 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<el-select
v-model="value"
class="select"
@change="onSelectChange"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</section>
</template>
<style>
.select {
width: 100%;
}
</style>
<script>
const defaultFontWeight = [
'normal',
'bold',
'bolder',
'lighter',
'100',
'200',
'300',
'400',
'500',
'600',
'700',
'800',
'900',
'inherit'
];
import Mixin from './mixin';
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
componentName: {
type: String
},
golbalValue: {
type: Object
}
},
data() {
return {
options: [],
value: ''
};
},
mixins: [Mixin],
computed: {
isGlobalInputValue() {
return this.config.value.startsWith('$');
}
},
methods: {
onSelectChange(e) {
this.onChange(e);
},
initSelectOption() {
this.options = [];
defaultFontWeight.forEach((weight) => {
this.options.push({
value: weight,
label: weight
});
});
const golbalTypography = this.golbalValue.typography;
if (this.isGlobalInputValue && golbalTypography) {
Object.keys(golbalTypography).forEach((font) => {
if (font.includes('font-weight')) {
const weight = golbalTypography[font];
this.options.push({
value: weight.key,
label: getStyleDisplayName(weight)
});
}
});
}
}
},
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.initSelectOption();
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@ -0,0 +1,45 @@
<template>
<el-input
@keyup.enter.native="onUpdate"
v-model="value"
@blur="onUpdate"
v-bind="$attrs"
>
<template slot="suffix">
<slot name="suffix"></slot>
</template>
</el-input>
</template>
<script>
export default {
props: ['val', 'onChange'],
data() {
return {
value: '',
oldValue: ''
};
},
methods: {
onUpdate(e) {
const { value } = e.target;
if (value !== this.oldValue) {
this.oldValue = value;
this.$emit('change', value);
}
}
},
watch: {
val: {
immediate: true,
handler(value) {
this.value = value;
if (!this.oldValue) {
this.oldValue = value;
}
}
}
}
};
</script>

View File

@ -0,0 +1,75 @@
<style>
.config {
padding: 5px 0;
}
.config-label {
color: #606266;;
font-size: 14px;
padding-bottom: 5px;
position: relative;
}
.config-content {
}
.content-80 {
box-sizing: border-box;
display: inline-block;
width: 80%;
}
.content-20 {
box-sizing: border-box;
display: inline-block;
width: 20%;
vertical-align: bottom;
}
.content-10 {
box-sizing: border-box;
display: inline-block;
width: 10%;
vertical-align: bottom;
}
.content-15 {
box-sizing: border-box;
display: inline-block;
width: 15%;
vertical-align: bottom;
}
</style>
<script>
import { getStyleDisplayName } from '../utils/utils.js';
export default {
props: {
config: {
type: Object
},
userConfig: {
type: Object
},
golbalValue: {
type: Object
},
componentName: {
type: String
}
},
computed: {
mergedValue() {
return this.userConfig[this.config.key] || this.config.value;
},
displayName() {
return getStyleDisplayName(this.config, this.componentName);
},
isGlobal() {
return !this.config.value.startsWith('$');
}
},
methods: {
onChange(value) {
this.$emit('onChange', {
key: this.config.key,
value
});
}
}
};
</script>

View File

@ -0,0 +1,38 @@
<template>
<section class="config" :key="displayName">
<div class="config-label">
{{displayName}}
</div>
<div class="config-content">
<theme-input
:val="value"
@change="onChange"
></theme-input>
</div>
</section>
</template>
<script>
import Input from './input';
import Mixin from './mixin';
export default {
components: {
themeInput: Input
},
data() {
return {
value: ''
};
},
mixins: [Mixin],
watch: {
'mergedValue': {
immediate: true,
handler(value) {
this.value = this.mergedValue;
}
}
}
};
</script>

View File

@ -0,0 +1,232 @@
<template>
<div>
<el-button
round
type="primary"
size="mini"
@click.stop="showConfigurator"
>{{getActionDisplayName("theme-editor")}}</el-button>
<transition name="fade">
<div v-show="visible" class="configurator" ref="configurator">
<div
class="main-configurator"
ref="mainConfigurator"
>
<div v-if="currentConfig">
<main-panel
:currentConfig="currentConfig"
:defaultConfig="defaultConfig"
:userConfig="userConfig"
:globalValue="globalValue"
@onChange="userConfigChange"
></main-panel>
</div>
<div v-if="init && !currentConfig" class="no-config">
<img src="../../assets/images/theme-no-config.png" alt>
<span>{{getActionDisplayName("no-config")}}</span>
</div>
<download-area></download-area>
</div>
</div>
</transition>
</div>
</template>
<style>
.configurator {
height: 100%;
width: 24%;
max-width: 400px;
position: fixed;
overflow-y: auto;
top: 79px;
right: 0;
bottom: 0;
background: #fff;
color: #666;
line-height: 24px;
padding-right: 1%;
}
.configurator .main-configurator {
height: 100%;
overflow: auto;
background: #F5F7FA;
border: 1px solid #EBEEF5;
box-shadow: 0 2px 10px 0 rgba(0,0,0,0.06);
border-radius: 8px;
width: 97%;
box-sizing: border-box;
margin: 0 .5% 0 5%;
}
.no-config {
margin-top: 130px;
text-align: center;
img {
width: 50%;
display: block;
margin: 0 auto;
}
span {
margin-top: 10px;
display: block;
color: #909399;
font-size: 14px;
}
}
.fade-enter,.fade-leave-to {
transform:translateX(100%);
}
.fade-enter-active ,.fade-leave-active {
transition:all 0.3s ease;
}
@media (min-width: 1600px) {
.configurator {
padding-right: calc((100% - 1600px) / 2);
}
}
</style>
<script>
import bus from '../../bus';
import { getVars, updateVars } from './utils/api.js';
import mainPanel from './main';
import {
filterConfigType,
filterGlobalValue,
updateDomHeadStyle,
getActionDisplayName
} from './utils/utils.js';
import DocStyle from './docStyle';
import Loading from './loading';
import DownloadArea from './download';
export default {
components: {
mainPanel,
DownloadArea
},
data() {
return {
init: false,
visible: false,
defaultConfig: null,
currentConfig: null,
userConfig: {
global: {},
local: {}
},
lastApply: 0
};
},
mixins: [DocStyle, Loading],
computed: {
globalValue() {
return filterGlobalValue(this.defaultConfig, this.userConfig);
}
},
methods: {
getActionDisplayName(key) {
return getActionDisplayName(key);
},
showConfigurator() {
this.visible = !this.visible;
bus.$emit('user-theme-config-visible', this.visible);
window.userThemeConfigVisible = Boolean(this.visible);
if (this.init) return;
this.$nextTick(() => {
const loading = this.$loading({
target: this.$refs.configurator
});
let defaultConfig;
getVars()
.then((res) => {
defaultConfig = res;
})
.catch((err) => {
this.onError(err);
})
.then(() => {
setTimeout(() => {
if (defaultConfig) {
this.defaultConfig = defaultConfig;
this.filterCurrentConfig();
this.init = true;
}
loading.close();
}, 300); // action after transition
});
});
},
filterCurrentConfig() {
this.currentConfig = this.defaultConfig.find((config) => {
return config.name === this.$route.path.split('/').pop().toLowerCase();
});
},
userConfigChange(e) {
this.$set(this.userConfig[filterConfigType(this.currentConfig.name)], e.key, e.value);
this.onAction();
},
applyStyle(res, time) {
if (time < this.lastApply) return;
this.updateDocs();
updateDomHeadStyle('chalk-style', res);
this.lastApply = time;
},
onDownload() {
return updateVars(Object.assign({}, this.userConfig, {download: true}), (xhr) => {
xhr.responseType = 'blob';
});
},
onReset() {
this.userConfig = {
global: {},
local: {}
};
this.onAction();
},
onAction() {
this.triggerComponentLoading(true);
const time = +new Date();
updateVars(this.userConfig)
.then((res) => {
this.applyStyle(res, time);
})
.catch((err) => {
this.onError(err);
})
.then(() => {
this.triggerComponentLoading(false);
});
},
onError(err) {
let message;
try {
message = JSON.parse(err).message;
} catch (e) {
message = err;
}
this.$message.error(message);
},
triggerComponentLoading(val) {
bus.$emit('user-theme-config-loading', val);
},
updateDocs() {
window.userThemeConfig = JSON.parse(JSON.stringify(this.userConfig));
bus.$emit('user-theme-config-update', this.userConfig);
this.updateDocStyle(this.userConfig);
}
},
watch: {
'$route.path'() {
this.defaultConfig && this.filterCurrentConfig();
if (!this.$refs.mainConfigurator) return;
this.$nextTick(() => {
this.$refs.mainConfigurator.scrollTop = 0;
});
}
}
};
</script>

View File

@ -0,0 +1,35 @@
<style>
.loadingClass {
z-index: 0!important;
.el-loading-spinner {
top: 0%;
margin-top: 30%;
}
}
</style>
<script>
import bus from '../../bus.js';
import './progress.js';
export default {
data() {
return {
count: 0
};
},
created() {
bus.$on('user-theme-config-loading', val => {
if (val) {
this.count++;
if (this.count > 1) return;
this.$bar.start();
} else {
this.count--;
if (this.count) return;
this.$bar.finish();
}
});
}
};
</script>

View File

@ -0,0 +1,124 @@
<template>
<div class="main">
<!-- <span>{{configName}}</span> -->
<div v-for="(config, key) in configByOrder" :key="key">
<span
v-if="showCategory(config.category, key + 1)"
class="category-name"
>
{{getCategoryDisplayName(config.category)}}
</span>
<component
:is="editorComponent(config.type)"
:componentName=configName
:config=config
:userConfig=userConfigByType
:golbalValue=globalValue
@onChange=onChange
>
</component>
</div>
</div>
</template>
<style>
.main {
margin-bottom: 140px;
padding: 10px;
}
.category-name {
color: #C0C4CC;
font-size: 18px;
display: block;
margin: 8px 0 4px 0;
}
</style>
<script>
import ColorEditor from './editor/color';
import fontWeightEditor from './editor/fontWeight';
import fontSizeEditor from './editor/fontSize';
import fontLineHeightEditor from './editor/fontLineHeight';
import borderRadiusEditor from './editor/borderRadius';
import boxShadowEditor from './editor/boxShadow';
import simpleTextEditor from './editor/simpleText';
import { filterConfigType, getCategoryDisplayName } from './utils/utils.js';
export default {
components: {
ColorEditor,
fontSizeEditor,
fontLineHeightEditor,
simpleTextEditor,
borderRadiusEditor,
boxShadowEditor,
fontWeightEditor
},
props: {
defaultConfig: {
type: Array
},
currentConfig: {
type: Object
},
userConfig: {
type: Object
},
globalValue: {
type: Object
}
},
computed: {
configName() {
return this.currentConfig.name;
},
userConfigByType() {
return this.userConfig[filterConfigType(this.configName)];
},
configByOrder() {
return this.currentConfig.config.sort((a, b) => (a.order - b.order));
}
},
methods: {
getCategoryDisplayName(key) {
return getCategoryDisplayName(key);
},
editorComponent(type) {
switch (type) {
case 'color':
return ColorEditor;
case 'fontWeight':
return fontWeightEditor;
case 'fontSize':
return fontSizeEditor;
case 'fontLineHeight':
return fontLineHeightEditor;
case 'borderRadius':
return borderRadiusEditor;
case 'boxShadow':
return boxShadowEditor;
default:
return simpleTextEditor;
}
},
onChange(e) {
this.$emit('onChange', e);
},
showCategory(name, key) {
if (!name) {
return false;
}
if (!this.categoryDisplay[name] || this.categoryDisplay[name] === key) {
this.categoryDisplay[name] = key;
return true;
}
return false;
}
},
data() {
return {
categoryDisplay: {}
};
}
};
</script>

View File

@ -0,0 +1,6 @@
import Vue from 'vue';
import ProgressBar from './progress.vue';
Vue.prototype.$bar = new Vue(ProgressBar).$mount();
document.body.appendChild(Vue.prototype.$bar.$el);

View File

@ -0,0 +1,108 @@
<template>
<div class="progress" :style="{
'width': percent+'%',
'height': height,
'background-color': canSuccess? successColor() : failedColor(),
'opacity': show ? 1 : 0
}"></div>
</template>
<script>
/* eslint-disable */
export default {
data () {
return {
percent: 0,
show: false,
canSuccess: true,
duration: 3000,
height: '2px'
}
},
methods: {
successColor() {
return this.userSelectColor()['$--color-primary'] || '#409EFF';
},
failedColor() {
return this.userSelectColor()['$--color-danger'] || '#F56C6C';
},
userSelectColor() {
return window.userThemeConfig && window.userThemeConfig.global || {}
},
start () {
this.show = true
this.canSuccess = true
if (this._timer) {
clearInterval(this._timer)
this.percent = 0
}
// Code from Nuxt.js!
this._cut = 10000 / Math.floor(this.duration)
this._timer = setInterval(() => {
this.increase(this._cut * Math.random())
if (this.percent >= 90) {
this.percent = 90;
}
}, 100)
return this
},
set (num) {
this.show = true
this.canSuccess = true
this.percent = Math.floor(num)
return this
},
get () {
return Math.floor(this.percent)
},
increase (num) {
this.percent = this.percent + Math.floor(num)
return this
},
decrease (num) {
this.percent = this.percent - Math.floor(num)
return this
},
finish () {
this.percent = 100
this.hide()
return this
},
pause () {
clearInterval(this._timer)
return this
},
hide () {
clearInterval(this._timer)
this._timer = null
setTimeout(() => {
this.show = false
this.$nextTick(() => {
setTimeout(() => {
this.percent = 0
}, 200)
})
}, 500)
return this
},
fail () {
this.canSuccess = false
return this
}
}
}
</script>
<style scoped>
.progress {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
height: 2px;
width: 0%;
transition: width 0.2s, opacity 0.4s;
opacity: 1;
z-index: 999999;
}
</style>

View File

@ -0,0 +1,65 @@
const defaultError = 'Server Error 500';
const defaultTimeout = 'Request Timeout';
const xhr = (method, url, data = null, cb) => {
return new window.Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
const doReject = (xhr) => {
reject(xhr.response || xhr.statusText || defaultError);
};
xhr.open(method, url);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.timeout = 10000;
if (cb) cb(xhr);
xhr.onload = () => {
if (xhr.readyState === 4) {
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
let response = xhr.response;
const type = xhr.getResponseHeader('Content-Type');
if (type.indexOf('zip') > -1) {
let filename = 'style.zip';
const disposition = xhr.getResponseHeader('content-disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) {
filename = matches[1].replace(/['"]/g, '');
}
}
var blob = new Blob([response], { type });
var zipUrl = URL.createObjectURL(blob);
var link = document.createElement('a');
link.href = zipUrl;
link.download = filename;
link.click();
resolve(response);
return;
}
try {
response = JSON.parse(xhr.response);
} catch (e) {}
resolve(response);
} else {
doReject(xhr);
}
} else {
doReject(xhr);
}
};
xhr.onerror = () => {
doReject(xhr);
};
xhr.ontimeout = () => {
xhr.abort();
reject(defaultTimeout);
};
xhr.send(JSON.stringify(data));
});
};
export const post = (url, data, cb) => {
return xhr('POST', url, data, cb);
};
export const get = (url) => {
return xhr('GET', url);
};

View File

@ -0,0 +1,20 @@
import Element from 'main/index.js';
import { post, get } from './ajax';
const { version } = Element;
const hostList = {
local: 'http://localhost:3008/',
alpha: 'https://ssr.alpha.elenet.me/element-theme-server/',
production: 'https://ssr.elenet.me/element-theme-server/'
};
const host = hostList[process.env.FAAS_ENV] || hostList.production;
export const getVars = () => {
return get(`${host}getVariable?version=${version}`);
};
export const updateVars = (data, cb) => {
return post(`${host}updateVariable?version=${version}`, data, cb);
};

View File

@ -0,0 +1,59 @@
const VALUES_REG = /,(?![^\(]*\))/;
const PARTS_REG = /\s(?![^(]*\))/;
const LENGTH_REG = /^[0-9]+[a-zA-Z%]+?$/;
const parseValue = str => {
const parts = str.split(PARTS_REG);
const inset = parts.includes('inset');
const last = parts.slice(-1)[0];
const color = !isLength(last) ? last : undefined;
const nums = parts
.filter(n => n !== 'inset')
.filter(n => n !== color)
.map(toNum);
const [ offsetX, offsetY, blurRadius, spreadRadius ] = nums;
return {
inset,
offsetX,
offsetY,
blurRadius,
spreadRadius,
color
};
};
const stringifyValue = obj => {
const {
inset,
offsetX = 0,
offsetY = 0,
blurRadius = 0,
spreadRadius,
color
} = obj || {};
return [
(inset ? 'inset' : null),
offsetX,
offsetY,
blurRadius,
spreadRadius,
color
].filter(v => v !== null && v !== undefined)
.map(toPx)
.map(s => ('' + s).trim())
.join(' ');
};
const isLength = v => v === '0' || LENGTH_REG.test(v);
const toNum = v => {
if (!/px$/.test(v) && v !== '0') return v;
const n = parseFloat(v);
return !isNaN(n) ? n : v;
};
const toPx = n => typeof n === 'number' && n !== 0 ? (n + 'px') : n;
export const parse = str => str.split(VALUES_REG).map(s => s.trim()).map(parseValue);
export const stringify = arr => arr.map(stringifyValue).join(', ');

View File

@ -0,0 +1,80 @@
import deepmerge from 'deepmerge';
import constant from '../../../i18n/theme-editor.json';
export const filterConfigType = (name) => {
switch (name) {
case 'color':
case 'typography':
case 'border':
return 'global';
default:
return 'local';
}
};
export const filterGlobalValue = (defaultConfig, userConfig) => {
const valueObject = {};
const globalArr = ['color', 'typography', 'border'];
globalArr.forEach((global) => {
const configObj = {};
defaultConfig
.find(config => (config.name === global))
.config.forEach(c => (configObj[c.key] = deepmerge({}, c)));
valueObject[global] = configObj;
Object.keys(configObj).forEach((c) => {
if (userConfig.global[c]) {
configObj[c].value = userConfig.global[c];
}
});
});
return valueObject;
};
export const getStyleDisplayValue = (displayValue, global) => {
if (displayValue.startsWith('$')) {
return global[displayValue].value;
}
return displayValue;
};
const getLang = () => {
return location.hash.replace('#', '').split('/')[1] || 'zh-CN';
};
const getNameFromI18N = (name) => {
const lang = getLang();
return constant.filter(config => config.lang === lang)[0][name];
};
export const getStyleDisplayName = (config, componentName) => {
const displayNameMap = getNameFromI18N('display-name');
if (config.name !== '[]') {
const langIndex = {'zh-CN': '0', 'es': 2, 'fr-FR': 3}[getLang()] || 1;
const nameArr = config.name.replace(/\[?\]?/g, '').split(',');
return nameArr[langIndex] || nameArr[1];
}
let displayName = config.key.replace(`$--${componentName}-`, '').replace();
Object.keys(displayNameMap).forEach((name) => {
displayName = displayName.replace(name, displayNameMap[name]);
});
displayName = displayName.replace(/-/g, ' ');
return displayName.trim();
};
export const getActionDisplayName = (key) => {
return getNameFromI18N('action')[key] || key;
};
export const getCategoryDisplayName = (key) => {
return getNameFromI18N('category')[key] || key;
};
export const updateDomHeadStyle = (id, styleContent) => {
let styleTag = document.getElementById(id);
if (!styleTag) {
styleTag = document.createElement('style');
styleTag.setAttribute('id', id);
document.head.appendChild(styleTag);
}
styleTag.innerText = styleContent.replace(/@font-face{[^}]+}/, '');
};

View File

@ -0,0 +1,181 @@
<script>
import bus from '../../bus';
const varMap = {
'$--box-shadow-light': 'boxShadowLight',
'$--box-shadow-base': 'boxShadowBase',
'$--border-radius-base': 'borderRadiusBase',
'$--border-radius-small': 'borderRadiusSmall'
};
const original = {
boxShadowLight: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
boxShadowBase: '0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)',
borderRadiusBase: '4px',
borderRadiusSmall: '2px'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
boxShadowLight: '',
boxShadowBase: '',
borderRadiusBase: '',
borderRadiusSmall: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(varMap).forEach((c) => {
if (value[c]) {
this[varMap[c]] = value[c]
} else {
this[varMap[c]] = original[varMap[c]]
}
});
}
}
}
}
</script>
<style>
.demo-border .text {
width: 15%;
}
.demo-border .line {
width: 70%;
}
.demo-border .line div{
width: 100%;
height: 0;
border: 1px solid #EEE;
}
.demo-border .line .dashed{
border: 2px dashed #EEE;
}
.demo-shadow {
height: 100px;
width: 50%;
border: 1px solid #eee;
}
.demo-shadow-text {
line-height: 50px;
color: #666;
font-size: 14px;
}
.demo-radius .title{
color: #666;
font-size: 18px;
margin: 10px 0;
}
.demo-radius .value{
color: #333;
font-size: 16px;
margin: 10px 0;
}
.demo-radius .radius {
height: 60px;
width: 70%;
border: 1px solid #D7DAE2;
border-radius: 0;
margin-top: 20px;
}
.demo-radius .radius-30 {
border-radius: 30px;
}
</style>
## Border
We standardize the borders that can be used in buttons, cards, pop-ups and other components.
### Border
There are few border styles to choose.
<table class="demo-border">
<tbody>
<tr>
<td class="text">Name</td>
<td class="text">Thickness</td>
<td class="line">Demo</td>
</tr>
<tr>
<td class="text">Solid</td>
<td class="text">1px</td>
<td class="line">
<div></div>
</td>
</tr>
<tr>
<td class="text">Dashed</td>
<td class="text">2px</td>
<td class="line">
<div class="dashed"></div>
</td>
</tr>
</tbody>
</table>
### Radius
There are few radius styles to choose.
<el-row :gutter="12" class="demo-radius">
<el-col :span="6" :xs="{span: 12}">
<div class="title">No Radius</div>
<div class="value">border-radius: 0px</div>
<div class="radius"></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Small Radius</div>
<div class="value">border-radius: {{borderRadiusSmall}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusSmall }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Large Radius</div>
<div class="value">border-radius: {{borderRadiusBase}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusBase }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Round Radius</div>
<div class="value">border-radius: 30px</div>
<div class="radius radius-30"></div>
</el-col>
</el-row>
### Shadow
There are few shaodw styles to choose.
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowBase }"
></div>
<span class="demo-shadow-text">Basic Shaodw box-shadow: {{boxShadowBase}}</span>
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowLight }"
></div>
<span class="demo-shadow-text">Light Shadow box-shadow: {{boxShadowLight}}</span>

View File

@ -1,9 +1,101 @@
<script>
import bus from '../../bus';
import { tintColor } from '../../color.js';
const varMap = {
'primary': '$--color-primary',
'success': '$--color-success',
'warning': '$--color-warning',
'danger': '$--color-danger',
'info': '$--color-info',
'white': '$--color-white',
'black': '$--color-black',
'textPrimary': '$--color-text-primary',
'textRegular': '$--color-text-regular',
'textSecondary': '$--color-text-secondary',
'textPlaceholder': '$--color-text-placeholder',
'borderBase': '$--border-color-base',
'borderLight': '$--border-color-light',
'borderLighter': '$--border-color-lighter',
'borderExtraLight': '$--border-color-extra-light'
};
const original = {
primary: '#409EFF',
success: '#67C23A',
warning: '#E6A23C',
danger: '#F56C6C',
info: '#909399',
white: '#FFFFFF',
black: '#000000',
textPrimary: '#303133',
textRegular: '#606266',
textSecondary: '#909399',
textPlaceholder: '#C0C4CC',
borderBase: '#DCDFE6',
borderLight: '#E4E7ED',
borderLighter: '#EBEEF5',
borderExtraLight: '#F2F6FC'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
primary: '',
success: '',
warning: '',
danger: '',
info: '',
white: '',
black: '',
textPrimary: '',
textRegular: '',
textSecondary: '',
textPlaceholder: '',
borderBase: '',
borderLight: '',
borderLighter: '',
borderExtraLight: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(original).forEach((o) => {
if (value[varMap[o]]) {
this[o] = value[varMap[o]]
} else {
this[o] = original[o]
}
});
}
}
},
}
</script>
<style> <style>
.demo-color-box { .demo-color-box {
position: relative;
border-radius: 4px; border-radius: 4px;
padding: 20px; padding: 20px;
margin: 5px 0; margin: 5px 0;
height: 74px; height: 114px;
box-sizing: border-box; box-sizing: border-box;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
@ -14,6 +106,12 @@
line-height: 24px; line-height: 24px;
} }
} }
.demo-color-box-other {
height: 74px;
margin: 10px 0!important;
border-radius: 4px 4px 4px 4px!important;
padding: 15px 20px;
}
.demo-color-box-group { .demo-color-box-group {
.demo-color-box { .demo-color-box {
border-radius: 0; border-radius: 0;
@ -26,55 +124,48 @@
border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;
} }
} }
.bg-blue { .bg-color-sub {
background-color: #409EFF; width: 100%;
height: 40px;
left: 0;
bottom: 0;
position: absolute;
border-radius: 0 0 4px 4px;
} }
.bg-blue-sub-item {
.bg-success { width: 11.1111111%;
background-color: #13CE66; height: 100%;
display: inline-block;
} }
.bg-warning { .bg-blue-sub-item:first-child {
background-color: #f7ba2a; border-radius: 0 0 0 4px;
} }
.bg-danger { .bg-success-sub-item {
background-color: #ff4949; width: 50%;
height: 100%;
display: inline-block;
} }
.bg-info { .bg-success-sub-item:first-child {
background-color: #909399; border-radius: 0 0 0 4px;
} }
.bg-success-sub-item:last-child {
.bg-text-primary { border-radius: 0 0 4px 0;
background-color: #303133;
} }
.bg-text-regular { .bg-transparent {
background-color: #606266; border: 1px solid #FCC3C3;
color: #303133;
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 98 L100 0 L100 1 L1 98' fill='%23FCC3C3' /></svg>");
background-repeat:no-repeat;
background-position:center center;
background-size: 100% 100%, auto;
} }
.bg-text-secondary { .demo-color-box-lite {
background-color: #909399;
}
.bg-text-placeholder {
background-color: #c0c4cc;
}
.bg-border-base {
background-color: #dcdfe6;
}
.bg-border-light {
background-color: #e4e7ed;
}
.bg-border-lighter {
background-color: #ebeef5;
}
.bg-border-extra-light {
background-color: #f2f6fc;
}
[class*=" bg-border-"] {
color: #303133; color: #303133;
} }
</style> </style>
## Color ## Color
Element uses a specific set of palettes to specify colors to provide a consistent look and feel for the products you build. Element uses a specific set of palettes to specify colors to provide a consistent look and feel for the products you build.
### Main Color ### Main Color
@ -82,8 +173,24 @@ Element uses a specific set of palettes to specify colors to provide a consisten
The main color of Element is bright and friendly blue. The main color of Element is bright and friendly blue.
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="10" :xs="{span: 12}">
<div class="demo-color-box bg-blue">Blue<div class="value">#409EFF</div></div> <div
class="demo-color-box"
:style="{ background: primary }"
>
Brand Color<div class="value">#409EFF</div>
<div
class="bg-color-sub"
:style="{ background: tintColor(primary, 0.9) }"
>
<div
class="bg-blue-sub-item"
v-for="(item, key) in Array(8)"
:key="key"
:style="{ background: tintColor(primary, (key + 1) / 10) }"
>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -93,16 +200,72 @@ Besides the main color, you need to use different scene colors in different scen
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-success">Success<div class="value">#67C23A</div></div> <div class="demo-color-box"
:style="{ background: success }"
>Success<div class="value">#67C23A</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(success, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-warning">Warning<div class="value">#E6A23C</div></div> <div class="demo-color-box"
:style="{ background: warning }"
>Warning<div class="value">#E6A23C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(warning, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-danger">Danger<div class="value">#F56C6C</div></div> <div class="demo-color-box"
:style="{ background: danger }"
>Danger<div class="value">#F56C6C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(danger, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-info">Info<div class="value">#909399</div></div> <div class="demo-color-box"
:style="{ background: info }"
>Info<div class="value">#909399</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(info, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -113,18 +276,48 @@ Neutral colors are for text, background and border colors. You can use different
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-text-primary">Primary Text<div class="value">#303133</div></div> <div class="demo-color-box demo-color-box-other"
<div class="demo-color-box bg-text-regular">Regular Text<div class="value">#606266</div></div> :style="{ background: textPrimary }"
<div class="demo-color-box bg-text-secondary">Secondary Text<div class="value">#909399</div></div> >Primary Text<div class="value">{{textPrimary}}</div></div>
<div class="demo-color-box bg-text-placeholder">Placeholder Text<div class="value">#C0C4CC</div></div> <div class="demo-color-box demo-color-box-other"
:style="{ background: textRegular }"
>
Regular Text<div class="value">{{textRegular}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textSecondary }"
>Secondary Text<div class="value">{{textSecondary}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textPlaceholder }"
>Placeholder Text<div class="value">{{textPlaceholder}}</div></div>
</div> </div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-border-base">Base Border<div class="value">#DCDFE6</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
<div class="demo-color-box bg-border-light">Light Border<div class="value">#E4E7ED</div></div> :style="{ background: borderBase }"
<div class="demo-color-box bg-border-lighter">Lighter Border<div class="value">#EBEEF5</div></div> >Base Border<div class="value">{{borderBase}}</div></div>
<div class="demo-color-box bg-border-extra-light">Extra Light Border<div class="value">#F2F6FC</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLight }"
>Light Border<div class="value">{{borderLight}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLighter }"
>Lighter Border<div class="value">{{borderLighter}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderExtraLight }"
>Extra Light Border<div class="value">{{borderExtraLight}}</div></div>
</div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group">
<div
class="demo-color-box demo-color-box-other"
:style="{ background: black }"
>Basic Black<div class="value">{{black}}</div></div>
<div
class="demo-color-box demo-color-box-other"
:style="{ background: white, color: '#303133', border: '1px solid #eee' }"
>Basic White<div class="value">{{white}}</div></div>
<div class="demo-color-box demo-color-box-other bg-transparent">Transparent<div class="value">Transparent</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -1,74 +1,96 @@
<style> <script>
.demo-typo-box { import bus from '../../bus';
height: 200px; const varMap = [
width: 200px; '$--font-size-extra-large',
position: relative; '$--font-size-large',
border: 1px solid #eaeefb; '$--font-size-medium',
font-size: 40px; '$--font-size-base',
color: #1f2d3d; '$--font-size-small',
text-align: center; '$--font-size-extra-small'
line-height: 162px; ];
padding-bottom: 36px; const original = {
box-sizing: border-box; 'font_size_extra_large': '20px',
display: inline-block; 'font_size_large': '18px',
margin-right: 17px; 'font_size_medium': '16px',
border-radius: 4px; 'font_size_base': '14px',
'font_size_small': '13px',
.name { 'font_size_extra_small': '12px'
position: absolute;
bottom: 0;
width: 100%;
height: 35px;
border-top: 1px solid #eaeefb;
font-size: 14px;
color: #8492a6;
line-height: 35px;
text-align: left;
text-indent: 10px;
font-family: 'Helvetica Neue';
}
} }
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
'font_size_extra_large': '',
'font_size_large': '',
'font_size_medium': '',
'font_size_base': '',
'font_size_small': '',
'font_size_extra_small': ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
varMap.forEach((v) => {
const key = v.replace('$--', '').replace(/-/g, '_')
if (value[v]) {
this[key] = value[v]
} else {
this[key] = original[key]
}
});
}
}
},
}
</script>
<style>
.demo-typo-size { .demo-typo-size {
.h1 {
font-size: 20px;
}
.h2 {
font-size: 18px;
}
.h3 {
font-size: 16px;
}
.text-regular {
font-size: 14px;
}
.text-small {
font-size: 13px;
}
.text-smaller {
font-size: 12px;
}
.color-dark-light { .color-dark-light {
color: #99a9bf; color: #99a9bf;
} }
} }
.typo-PingFang { .demo-term-box img{
font-family: 'PingFang SC'; width: 24%;
margin: 0 4% 20px 0;
} }
.typo-Hiragino {
font-family: 'Hiragino Sans GB'; .lineH-left {
display: inline-block;
height: 80px
} }
.typo-Microsoft { .lineH-right {
font-family: 'Microsoft YaHei'; display: inline-block;
list-style: none;
padding: 0 0 0 90px;
margin: 0;
vertical-align: top;
} }
/* 英文 */ .lineH-right li{
.typo-Helvetica-Neue { font-size: 13px;
font-family: 'Helvetica Neue'; color: #666;
height: 20px;
line-height: 20px;
} }
.typo-Helvetica { .lineH-right li span{
font-family: 'Helvetica'; padding-left: 40px;
}
.typo-Arial {
font-family: 'Arial';
} }
</style> </style>
@ -76,34 +98,81 @@
We create a font convention to ensure the best presentation across different platforms. We create a font convention to ensure the best presentation across different platforms.
### Chinese Font ### Font
<div class="demo-term-box">
<div class="demo-typo-box typo-PingFang"> <img src="../../assets/images/term-pingfang.png" alt="">
和畅惠风 <img src="../../assets/images/term-hiragino.png" alt="">
<div class="name">PingFang SC</div> <img src="../../assets/images/term-microsoft.png" alt="">
</div> <img src="../../assets/images/term-sf.png" alt="">
<div class="demo-typo-box typo-Hiragino"> <img src="../../assets/images/term-helvetica.png" alt="">
和畅惠风 <img src="../../assets/images/term-arial.png" alt="">
<div class="name">Hiragino Sans GB</div>
</div>
<div class="demo-typo-box typo-Microsoft">
和畅惠风
<div class="name">Microsoft YaHei</div>
</div> </div>
### English / Numberic Font ### Font Convention
<div class="demo-typo-box typo-Helvetica-neue"> <table class="demo-typo-size">
RGag <tbody>
<div class="name">Helvetica Neue</div> <tr
</div> >
<div class="demo-typo-box typo-Helvetica"> <td>Level</td>
RGag <td>Font Size</td>
<div class="name">Helvetica</div> <td class="color-dark-light">Demo</td>
</div> </tr>
<div class="demo-typo-box typo-Arial"> <tr
RGag :style="{ fontSize: font_size_extra_small }"
<div class="name">Arial</div> >
<td>Supplementary text</td>
<td class="color-dark-light">{{font_size_extra_small}} Extra Small</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_small }"
>
<td>Body (small)</td>
<td class="color-dark-light">{{font_size_small}} Small</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_base }"
>
<td>Body</td>
<td class="color-dark-light">{{font_size_base}} Base</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_medium }"
>
<td >Small Title</td>
<td class="color-dark-light">{{font_size_medium}} Medium</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_large }"
>
<td>Title</td>
<td class="color-dark-light">{{font_size_large}} large</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_extra_large }"
>
<td>Main Title</td>
<td class="color-dark-light">{{font_size_extra_large}} Extra large</td>
<td>Build with Element</td>
</tr>
</tbody>
</table>
### Font Line Height
<div>
<img class="lineH-left" src="~examples/assets/images/typography.png" />
<ul class="lineH-right">
<li>line-height:1 <span>No line height</span></li>
<li>line-height:1.3 <span>Compact</span></li>
<li>line-height:1.5 <span>Regular</span></li>
<li>line-height:1.7 <span>Loose</span></li>
</ul>
</div> </div>
### Font-family ### Font-family
@ -111,41 +180,3 @@ We create a font convention to ensure the best presentation across different pla
```css ```css
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
``` ```
### Font Convention
<table class="demo-typo-size">
<tbody>
<tr>
<td class="h1">Main Title</td>
<td class="h1">Build with Element</td>
<td class="color-dark-light">20px Extra large</td>
</tr>
<tr>
<td class="h2">Title</td>
<td class="h2">Build with Element</td>
<td class="color-dark-light">18px large</td>
</tr>
<tr>
<td class="h3">Small Title</td>
<td class="h3">Build with Element</td>
<td class="color-dark-light">16px Medium</td>
</tr>
<tr>
<td class="text-regular">Body</td>
<td class="text-regular">Build with Element</td>
<td class="color-dark-light">14px Small</td>
</tr>
<tr>
<td class="text-small">Body (small)</td>
<td class="text-small">Build with Element</td>
<td class="color-dark-light">13px Extra Small</td>
</tr>
<tr>
<td class="text-smaller">Supplementary text</td>
<td class="text-smaller">Build with Element</td>
<td class="color-dark-light">12px Extra Extra Small</td>
</tr>
</tbody>
</table>

181
examples/docs/es/border.md Normal file
View File

@ -0,0 +1,181 @@
<script>
import bus from '../../bus';
const varMap = {
'$--box-shadow-light': 'boxShadowLight',
'$--box-shadow-base': 'boxShadowBase',
'$--border-radius-base': 'borderRadiusBase',
'$--border-radius-small': 'borderRadiusSmall'
};
const original = {
boxShadowLight: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
boxShadowBase: '0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)',
borderRadiusBase: '4px',
borderRadiusSmall: '2px'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
boxShadowLight: '',
boxShadowBase: '',
borderRadiusBase: '',
borderRadiusSmall: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(varMap).forEach((c) => {
if (value[c]) {
this[varMap[c]] = value[c]
} else {
this[varMap[c]] = original[varMap[c]]
}
});
}
}
}
}
</script>
<style>
.demo-border .text {
width: 15%;
}
.demo-border .line {
width: 70%;
}
.demo-border .line div{
width: 100%;
height: 0;
border: 1px solid #EEE;
}
.demo-border .line .dashed{
border: 2px dashed #EEE;
}
.demo-shadow {
height: 100px;
width: 50%;
border: 1px solid #eee;
}
.demo-shadow-text {
line-height: 50px;
color: #666;
font-size: 14px;
}
.demo-radius .title{
color: #666;
font-size: 18px;
margin: 10px 0;
}
.demo-radius .value{
color: #333;
font-size: 16px;
margin: 10px 0;
}
.demo-radius .radius {
height: 60px;
width: 70%;
border: 1px solid #D7DAE2;
border-radius: 0;
margin-top: 20px;
}
.demo-radius .radius-30 {
border-radius: 30px;
}
</style>
## Border
We standardize the borders that can be used in buttons, cards, pop-ups and other components.
### Border
There are few border styles to choose.
<table class="demo-border">
<tbody>
<tr>
<td class="text">Name</td>
<td class="text">Thickness</td>
<td class="line">Demo</td>
</tr>
<tr>
<td class="text">Solid</td>
<td class="text">1px</td>
<td class="line">
<div></div>
</td>
</tr>
<tr>
<td class="text">Dashed</td>
<td class="text">2px</td>
<td class="line">
<div class="dashed"></div>
</td>
</tr>
</tbody>
</table>
### Radius
There are few radius styles to choose.
<el-row :gutter="12" class="demo-radius">
<el-col :span="6" :xs="{span: 12}">
<div class="title">No Radius</div>
<div class="value">border-radius: 0px</div>
<div class="radius"></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Small Radius</div>
<div class="value">border-radius: {{borderRadiusSmall}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusSmall }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Large Radius</div>
<div class="value">border-radius: {{borderRadiusBase}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusBase }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Round Radius</div>
<div class="value">border-radius: 30px</div>
<div class="radius radius-30"></div>
</el-col>
</el-row>
### Shadow
There are few shaodw styles to choose.
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowBase }"
></div>
<span class="demo-shadow-text">Basic Shaodw box-shadow: {{boxShadowBase}}</span>
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowLight }"
></div>
<span class="demo-shadow-text">Light Shadow box-shadow: {{boxShadowLight}}</span>

View File

@ -1,19 +1,117 @@
<script>
import bus from '../../bus';
import { tintColor } from '../../color.js';
const varMap = {
'primary': '$--color-primary',
'success': '$--color-success',
'warning': '$--color-warning',
'danger': '$--color-danger',
'info': '$--color-info',
'white': '$--color-white',
'black': '$--color-black',
'textPrimary': '$--color-text-primary',
'textRegular': '$--color-text-regular',
'textSecondary': '$--color-text-secondary',
'textPlaceholder': '$--color-text-placeholder',
'borderBase': '$--border-color-base',
'borderLight': '$--border-color-light',
'borderLighter': '$--border-color-lighter',
'borderExtraLight': '$--border-color-extra-light'
};
const original = {
primary: '#409EFF',
success: '#67C23A',
warning: '#E6A23C',
danger: '#F56C6C',
info: '#909399',
white: '#FFFFFF',
black: '#000000',
textPrimary: '#303133',
textRegular: '#606266',
textSecondary: '#909399',
textPlaceholder: '#C0C4CC',
borderBase: '#DCDFE6',
borderLight: '#E4E7ED',
borderLighter: '#EBEEF5',
borderExtraLight: '#F2F6FC'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
primary: '',
success: '',
warning: '',
danger: '',
info: '',
white: '',
black: '',
textPrimary: '',
textRegular: '',
textSecondary: '',
textPlaceholder: '',
borderBase: '',
borderLight: '',
borderLighter: '',
borderExtraLight: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(original).forEach((o) => {
if (value[varMap[o]]) {
this[o] = value[varMap[o]]
} else {
this[o] = original[o]
}
});
}
}
},
}
</script>
<style> <style>
.demo-color-box { .demo-color-box {
position: relative;
border-radius: 4px; border-radius: 4px;
padding: 20px; padding: 20px;
margin: 5px 0; margin: 5px 0;
height: 74px; height: 114px;
box-sizing: border-box; box-sizing: border-box;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
& .value { & .value {
font-size: 12px; font-size: 12px;
opacity: 0.69; opacity: 0.69;
line-height: 24px; line-height: 24px;
} }
} }
.demo-color-box-other {
height: 74px;
margin: 10px 0!important;
border-radius: 4px 4px 4px 4px!important;
padding: 15px 20px;
}
.demo-color-box-group { .demo-color-box-group {
.demo-color-box { .demo-color-box {
border-radius: 0; border-radius: 0;
@ -26,50 +124,42 @@
border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;
} }
} }
.bg-blue { .bg-color-sub {
background-color: #409EFF; width: 100%;
height: 40px;
left: 0;
bottom: 0;
position: absolute;
border-radius: 0 0 4px 4px;
} }
.bg-blue-sub-item {
.bg-success { width: 11.1111111%;
background-color: #13CE66; height: 100%;
display: inline-block;
} }
.bg-warning { .bg-blue-sub-item:first-child {
background-color: #f7ba2a; border-radius: 0 0 0 4px;
} }
.bg-danger { .bg-success-sub-item {
background-color: #ff4949; width: 50%;
height: 100%;
display: inline-block;
} }
.bg-info { .bg-success-sub-item:first-child {
background-color: #909399; border-radius: 0 0 0 4px;
} }
.bg-success-sub-item:last-child {
.bg-text-primary { border-radius: 0 0 4px 0;
background-color: #303133;
} }
.bg-text-regular { .bg-transparent {
background-color: #606266; border: 1px solid #FCC3C3;
color: #303133;
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 98 L100 0 L100 1 L1 98' fill='%23FCC3C3' /></svg>");
background-repeat:no-repeat;
background-position:center center;
background-size: 100% 100%, auto;
} }
.bg-text-secondary { .demo-color-box-lite {
background-color: #909399;
}
.bg-text-placeholder {
background-color: #c0c4cc;
}
.bg-border-base {
background-color: #dcdfe6;
}
.bg-border-light {
background-color: #e4e7ed;
}
.bg-border-lighter {
background-color: #ebeef5;
}
.bg-border-extra-light {
background-color: #f2f6fc;
}
[class*=" bg-border-"] {
color: #303133; color: #303133;
} }
</style> </style>
@ -82,8 +172,24 @@ Element utiliza un conjunto de paletas para especificar colores, y así, proporc
El color principal de Element es el azul brillante y amigable. El color principal de Element es el azul brillante y amigable.
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="10" :xs="{span: 12}">
<div class="demo-color-box bg-blue">Azul<div class="value">#409EFF</div></div> <div
class="demo-color-box"
:style="{ background: primary }"
>
Brand Color<div class="value">#409EFF</div>
<div
class="bg-color-sub"
:style="{ background: tintColor(primary, 0.9) }"
>
<div
class="bg-blue-sub-item"
v-for="(item, key) in Array(8)"
:key="key"
:style="{ background: tintColor(primary, (key + 1) / 10) }"
>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -93,16 +199,72 @@ Además del color principal, se necesitan utilizar distintos colores para difere
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-success">Éxito<div class="value">#67C23A</div></div> <div class="demo-color-box"
:style="{ background: success }"
>Success<div class="value">#67C23A</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(success, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-warning">Precaución<div class="value">#E6A23C</div></div> <div class="demo-color-box"
:style="{ background: warning }"
>Warning<div class="value">#E6A23C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(warning, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-danger">Peligro<div class="value">#F56C6C</div></div> <div class="demo-color-box"
:style="{ background: danger }"
>Danger<div class="value">#F56C6C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(danger, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-info">Info<div class="value">#909399</div></div> <div class="demo-color-box"
:style="{ background: info }"
>Info<div class="value">#909399</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(info, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -113,18 +275,48 @@ Los colores neutrales son para texto, fondos y bordes. Puede usar diferentes col
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-text-primary">Texto primario<div class="value">#303133</div></div> <div class="demo-color-box demo-color-box-other"
<div class="demo-color-box bg-text-regular">Texto regular<div class="value">#606266</div></div> :style="{ background: textPrimary }"
<div class="demo-color-box bg-text-secondary">Texto secundario<div class="value">#909399</div></div> >Texto primario<div class="value">{{textPrimary}}</div></div>
<div class="demo-color-box bg-text-placeholder">Texto de placeholder<div class="value">#C0C4CC</div></div> <div class="demo-color-box demo-color-box-other"
:style="{ background: textRegular }"
>
Texto regular<div class="value">{{textRegular}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textSecondary }"
>Texto secundario<div class="value">{{textSecondary}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textPlaceholder }"
>Texto de placeholder<div class="value">{{textPlaceholder}}</div></div>
</div> </div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-border-base">Borde base<div class="value">#DCDFE6</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
<div class="demo-color-box bg-border-light">Borde ligero<div class="value">#E4E7ED</div></div> :style="{ background: borderBase }"
<div class="demo-color-box bg-border-lighter">Borde claro<div class="value">#EBEEF5</div></div> >Borde base<div class="value">{{borderBase}}</div></div>
<div class="demo-color-box bg-border-extra-light">Borde extra claro<div class="value">#F2F6FC</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLight }"
>Borde ligero<div class="value">{{borderLight}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLighter }"
>Borde claro<div class="value">{{borderLighter}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderExtraLight }"
>Borde extra claro<div class="value">{{borderExtraLight}}</div></div>
</div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group">
<div
class="demo-color-box demo-color-box-other"
:style="{ background: black }"
>Basic Black<div class="value">{{black}}</div></div>
<div
class="demo-color-box demo-color-box-other"
:style="{ background: white, color: '#303133', border: '1px solid #eee' }"
>Basic White<div class="value">{{white}}</div></div>
<div class="demo-color-box demo-color-box-other bg-transparent">Transparent<div class="value">Transparent</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -1,74 +1,96 @@
<style> <script>
.demo-typo-box { import bus from '../../bus';
height: 200px; const varMap = [
width: 200px; '$--font-size-extra-large',
position: relative; '$--font-size-large',
border: 1px solid #eaeefb; '$--font-size-medium',
font-size: 40px; '$--font-size-base',
color: #1f2d3d; '$--font-size-small',
text-align: center; '$--font-size-extra-small'
line-height: 162px; ];
padding-bottom: 36px; const original = {
box-sizing: border-box; 'font_size_extra_large': '20px',
display: inline-block; 'font_size_large': '18px',
margin-right: 17px; 'font_size_medium': '16px',
border-radius: 4px; 'font_size_base': '14px',
'font_size_small': '13px',
.name { 'font_size_extra_small': '12px'
position: absolute;
bottom: 0;
width: 100%;
height: 35px;
border-top: 1px solid #eaeefb;
font-size: 14px;
color: #8492a6;
line-height: 35px;
text-align: left;
text-indent: 10px;
font-family: 'Helvetica Neue';
}
} }
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
'font_size_extra_large': '',
'font_size_large': '',
'font_size_medium': '',
'font_size_base': '',
'font_size_small': '',
'font_size_extra_small': ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
varMap.forEach((v) => {
const key = v.replace('$--', '').replace(/-/g, '_')
if (value[v]) {
this[key] = value[v]
} else {
this[key] = original[key]
}
});
}
}
},
}
</script>
<style>
.demo-typo-size { .demo-typo-size {
.h1 {
font-size: 20px;
}
.h2 {
font-size: 18px;
}
.h3 {
font-size: 16px;
}
.text-regular {
font-size: 14px;
}
.text-small {
font-size: 13px;
}
.text-smaller {
font-size: 12px;
}
.color-dark-light { .color-dark-light {
color: #99a9bf; color: #99a9bf;
} }
} }
.typo-PingFang { .demo-term-box img{
font-family: 'PingFang SC'; width: 24%;
margin: 0 4% 20px 0;
} }
.typo-Hiragino {
font-family: 'Hiragino Sans GB'; .lineH-left {
display: inline-block;
height: 80px
} }
.typo-Microsoft { .lineH-right {
font-family: 'Microsoft YaHei'; display: inline-block;
list-style: none;
padding: 0 0 0 90px;
margin: 0;
vertical-align: top;
} }
/* 英文 */ .lineH-right li{
.typo-Helvetica-Neue { font-size: 13px;
font-family: 'Helvetica Neue'; color: #666;
height: 20px;
line-height: 20px;
} }
.typo-Helvetica { .lineH-right li span{
font-family: 'Helvetica'; padding-left: 40px;
}
.typo-Arial {
font-family: 'Arial';
} }
</style> </style>
@ -76,34 +98,81 @@
Creamos una convención de fuentes para asegurar la mejor presentación en diferentes plataformas. Creamos una convención de fuentes para asegurar la mejor presentación en diferentes plataformas.
### Fuente en chino ### Fuente
<div class="demo-term-box">
<div class="demo-typo-box typo-PingFang"> <img src="../../assets/images/term-pingfang.png" alt="">
和畅惠风 <img src="../../assets/images/term-hiragino.png" alt="">
<div class="name">PingFang SC</div> <img src="../../assets/images/term-microsoft.png" alt="">
</div> <img src="../../assets/images/term-sf.png" alt="">
<div class="demo-typo-box typo-Hiragino"> <img src="../../assets/images/term-helvetica.png" alt="">
和畅惠风 <img src="../../assets/images/term-arial.png" alt="">
<div class="name">Hiragino Sans GB</div>
</div>
<div class="demo-typo-box typo-Microsoft">
和畅惠风
<div class="name">Microsoft YaHei</div>
</div> </div>
### Inglés / Fuente Numérica ### Convención de fuentes
<div class="demo-typo-box typo-Helvetica-neue"> <table class="demo-typo-size">
RGag <tbody>
<div class="name">Helvetica Neue</div> <tr
</div> >
<div class="demo-typo-box typo-Helvetica"> <td>Level</td>
RGag <td>Font Size</td>
<div class="name">Helvetica</div> <td class="color-dark-light">Demo</td>
</div> </tr>
<div class="demo-typo-box typo-Arial"> <tr
RGag :style="{ fontSize: font_size_extra_small }"
<div class="name">Arial</div> >
<td>Supplementary text</td>
<td class="color-dark-light">{{font_size_extra_small}} Extra Small</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_small }"
>
<td>Body (small)</td>
<td class="color-dark-light">{{font_size_small}} Small</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_base }"
>
<td>Body</td>
<td class="color-dark-light">{{font_size_base}} Base</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_medium }"
>
<td >Small Title</td>
<td class="color-dark-light">{{font_size_medium}} Medium</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_large }"
>
<td>Title</td>
<td class="color-dark-light">{{font_size_large}} large</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_extra_large }"
>
<td>Main Title</td>
<td class="color-dark-light">{{font_size_extra_large}} Extra large</td>
<td>Build with Element</td>
</tr>
</tbody>
</table>
### Font Line Height
<div>
<img class="lineH-left" src="~examples/assets/images/typography.png" />
<ul class="lineH-right">
<li>line-height:1 <span>No line height</span></li>
<li>line-height:1.3 <span>Compact</span></li>
<li>line-height:1.5 <span>Regular</span></li>
<li>line-height:1.7 <span>Loose</span></li>
</ul>
</div> </div>
### Font-family ### Font-family
@ -111,41 +180,3 @@ Creamos una convención de fuentes para asegurar la mejor presentación en difer
```css ```css
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
``` ```
### Convención de fuentes
<table class="demo-typo-size">
<tbody>
<tr>
<td class="h1">Main Title</td>
<td class="h1">Build with Element</td>
<td class="color-dark-light">20px Extra large</td>
</tr>
<tr>
<td class="h2">Title</td>
<td class="h2">Build with Element</td>
<td class="color-dark-light">18px large</td>
</tr>
<tr>
<td class="h3">Small Title</td>
<td class="h3">Build with Element</td>
<td class="color-dark-light">16px Medium</td>
</tr>
<tr>
<td class="text-regular">Body</td>
<td class="text-regular">Build with Element</td>
<td class="color-dark-light">14px Small</td>
</tr>
<tr>
<td class="text-small">Body (small)</td>
<td class="text-small">Build with Element</td>
<td class="color-dark-light">13px Extra Small</td>
</tr>
<tr>
<td class="text-smaller">Supplementary text</td>
<td class="text-smaller">Build with Element</td>
<td class="color-dark-light">12px Extra Extra Small</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,181 @@
<script>
import bus from '../../bus';
const varMap = {
'$--box-shadow-light': 'boxShadowLight',
'$--box-shadow-base': 'boxShadowBase',
'$--border-radius-base': 'borderRadiusBase',
'$--border-radius-small': 'borderRadiusSmall'
};
const original = {
boxShadowLight: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
boxShadowBase: '0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)',
borderRadiusBase: '4px',
borderRadiusSmall: '2px'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
boxShadowLight: '',
boxShadowBase: '',
borderRadiusBase: '',
borderRadiusSmall: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(varMap).forEach((c) => {
if (value[c]) {
this[varMap[c]] = value[c]
} else {
this[varMap[c]] = original[varMap[c]]
}
});
}
}
}
}
</script>
<style>
.demo-border .text {
width: 15%;
}
.demo-border .line {
width: 70%;
}
.demo-border .line div{
width: 100%;
height: 0;
border: 1px solid #EEE;
}
.demo-border .line .dashed{
border: 2px dashed #EEE;
}
.demo-shadow {
height: 100px;
width: 50%;
border: 1px solid #eee;
}
.demo-shadow-text {
line-height: 50px;
color: #666;
font-size: 14px;
}
.demo-radius .title{
color: #666;
font-size: 18px;
margin: 10px 0;
}
.demo-radius .value{
color: #333;
font-size: 16px;
margin: 10px 0;
}
.demo-radius .radius {
height: 60px;
width: 70%;
border: 1px solid #D7DAE2;
border-radius: 0;
margin-top: 20px;
}
.demo-radius .radius-30 {
border-radius: 30px;
}
</style>
## Border
We standardize the borders that can be used in buttons, cards, pop-ups and other components.
### Border
There are few border styles to choose.
<table class="demo-border">
<tbody>
<tr>
<td class="text">Name</td>
<td class="text">Thickness</td>
<td class="line">Demo</td>
</tr>
<tr>
<td class="text">Solid</td>
<td class="text">1px</td>
<td class="line">
<div></div>
</td>
</tr>
<tr>
<td class="text">Dashed</td>
<td class="text">2px</td>
<td class="line">
<div class="dashed"></div>
</td>
</tr>
</tbody>
</table>
### Radius
There are few radius styles to choose.
<el-row :gutter="12" class="demo-radius">
<el-col :span="6" :xs="{span: 12}">
<div class="title">No Radius</div>
<div class="value">border-radius: 0px</div>
<div class="radius"></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Small Radius</div>
<div class="value">border-radius: {{borderRadiusSmall}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusSmall }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Large Radius</div>
<div class="value">border-radius: {{borderRadiusBase}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusBase }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">Round Radius</div>
<div class="value">border-radius: 30px</div>
<div class="radius radius-30"></div>
</el-col>
</el-row>
### Shadow
There are few shaodw styles to choose.
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowBase }"
></div>
<span class="demo-shadow-text">Basic Shaodw box-shadow: {{boxShadowBase}}</span>
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowLight }"
></div>
<span class="demo-shadow-text">Light Shadow box-shadow: {{boxShadowLight}}</span>

View File

@ -1,9 +1,101 @@
<script>
import bus from '../../bus';
import { tintColor } from '../../color.js';
const varMap = {
'primary': '$--color-primary',
'success': '$--color-success',
'warning': '$--color-warning',
'danger': '$--color-danger',
'info': '$--color-info',
'white': '$--color-white',
'black': '$--color-black',
'textPrimary': '$--color-text-primary',
'textRegular': '$--color-text-regular',
'textSecondary': '$--color-text-secondary',
'textPlaceholder': '$--color-text-placeholder',
'borderBase': '$--border-color-base',
'borderLight': '$--border-color-light',
'borderLighter': '$--border-color-lighter',
'borderExtraLight': '$--border-color-extra-light'
};
const original = {
primary: '#409EFF',
success: '#67C23A',
warning: '#E6A23C',
danger: '#F56C6C',
info: '#909399',
white: '#FFFFFF',
black: '#000000',
textPrimary: '#303133',
textRegular: '#606266',
textSecondary: '#909399',
textPlaceholder: '#C0C4CC',
borderBase: '#DCDFE6',
borderLight: '#E4E7ED',
borderLighter: '#EBEEF5',
borderExtraLight: '#F2F6FC'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
primary: '',
success: '',
warning: '',
danger: '',
info: '',
white: '',
black: '',
textPrimary: '',
textRegular: '',
textSecondary: '',
textPlaceholder: '',
borderBase: '',
borderLight: '',
borderLighter: '',
borderExtraLight: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(original).forEach((o) => {
if (value[varMap[o]]) {
this[o] = value[varMap[o]]
} else {
this[o] = original[o]
}
});
}
}
},
}
</script>
<style> <style>
.demo-color-box { .demo-color-box {
position: relative;
border-radius: 4px; border-radius: 4px;
padding: 20px; padding: 20px;
margin: 5px 0; margin: 5px 0;
height: 74px; height: 114px;
box-sizing: border-box; box-sizing: border-box;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
@ -14,6 +106,12 @@
line-height: 24px; line-height: 24px;
} }
} }
.demo-color-box-other {
height: 74px;
margin: 10px 0!important;
border-radius: 4px 4px 4px 4px!important;
padding: 15px 20px;
}
.demo-color-box-group { .demo-color-box-group {
.demo-color-box { .demo-color-box {
border-radius: 0; border-radius: 0;
@ -26,50 +124,42 @@
border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;
} }
} }
.bg-blue { .bg-color-sub {
background-color: #409EFF; width: 100%;
height: 40px;
left: 0;
bottom: 0;
position: absolute;
border-radius: 0 0 4px 4px;
} }
.bg-blue-sub-item {
.bg-success { width: 11.1111111%;
background-color: #13CE66; height: 100%;
display: inline-block;
} }
.bg-warning { .bg-blue-sub-item:first-child {
background-color: #f7ba2a; border-radius: 0 0 0 4px;
} }
.bg-danger { .bg-success-sub-item {
background-color: #ff4949; width: 50%;
height: 100%;
display: inline-block;
} }
.bg-info { .bg-success-sub-item:first-child {
background-color: #909399; border-radius: 0 0 0 4px;
} }
.bg-success-sub-item:last-child {
.bg-text-primary { border-radius: 0 0 4px 0;
background-color: #303133;
} }
.bg-text-regular { .bg-transparent {
background-color: #606266; border: 1px solid #FCC3C3;
color: #303133;
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 98 L100 0 L100 1 L1 98' fill='%23FCC3C3' /></svg>");
background-repeat:no-repeat;
background-position:center center;
background-size: 100% 100%, auto;
} }
.bg-text-secondary { .demo-color-box-lite {
background-color: #909399;
}
.bg-text-placeholder {
background-color: #c0c4cc;
}
.bg-border-base {
background-color: #dcdfe6;
}
.bg-border-light {
background-color: #e4e7ed;
}
.bg-border-lighter {
background-color: #ebeef5;
}
.bg-border-extra-light {
background-color: #f2f6fc;
}
[class*=" bg-border-"] {
color: #303133; color: #303133;
} }
</style> </style>
@ -82,8 +172,24 @@ Element utilise un ensemble de palettes spécifiques afin de fournir un style co
La couleur principale d'Element est un bleu clair et agréable. La couleur principale d'Element est un bleu clair et agréable.
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="10" :xs="{span: 12}">
<div class="demo-color-box bg-blue">Bleu<div class="value">#409EFF</div></div> <div
class="demo-color-box"
:style="{ background: primary }"
>
Brand Color<div class="value">#409EFF</div>
<div
class="bg-color-sub"
:style="{ background: tintColor(primary, 0.9) }"
>
<div
class="bg-blue-sub-item"
v-for="(item, key) in Array(8)"
:key="key"
:style="{ background: tintColor(primary, (key + 1) / 10) }"
>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -93,16 +199,72 @@ En plus de la couleur principale, vous devrez sans doute utiliser d'autres coule
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-success">Succès<div class="value">#67C23A</div></div> <div class="demo-color-box"
:style="{ background: success }"
>Success<div class="value">#67C23A</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(success, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-warning">Avertissement<div class="value">#E6A23C</div></div> <div class="demo-color-box"
:style="{ background: warning }"
>Warning<div class="value">#E6A23C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(warning, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-danger">Danger<div class="value">#F56C6C</div></div> <div class="demo-color-box"
:style="{ background: danger }"
>Danger<div class="value">#F56C6C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(danger, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-info">Information<div class="value">#909399</div></div> <div class="demo-color-box"
:style="{ background: info }"
>Info<div class="value">#909399</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(info, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -113,18 +275,48 @@ Les couleurs neutres sont les couleurs du fond, du texte et des bordures. Vous p
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-text-primary">Texte principal<div class="value">#303133</div></div> <div class="demo-color-box demo-color-box-other"
<div class="demo-color-box bg-text-regular">Texte normal<div class="value">#606266</div></div> :style="{ background: textPrimary }"
<div class="demo-color-box bg-text-secondary">Texte secondaire<div class="value">#909399</div></div> >Texte principal<div class="value">{{textPrimary}}</div></div>
<div class="demo-color-box bg-text-placeholder">Texte de placeholder<div class="value">#C0C4CC</div></div> <div class="demo-color-box demo-color-box-other"
:style="{ background: textRegular }"
>
Texte normal<div class="value">{{textRegular}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textSecondary }"
>Texte secondaire<div class="value">{{textSecondary}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textPlaceholder }"
>Texte de placeholder<div class="value">{{textPlaceholder}}</div></div>
</div> </div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-border-base">Bordure de base<div class="value">#DCDFE6</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
<div class="demo-color-box bg-border-light">Bordure claire<div class="value">#E4E7ED</div></div> :style="{ background: borderBase }"
<div class="demo-color-box bg-border-lighter">Bordure très claire<div class="value">#EBEEF5</div></div> >Bordure de base<div class="value">{{borderBase}}</div></div>
<div class="demo-color-box bg-border-extra-light">Bordure extra claire<div class="value">#F2F6FC</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLight }"
>Bordure claire<div class="value">{{borderLight}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLighter }"
>Bordure très claire<div class="value">{{borderLighter}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderExtraLight }"
>Bordure extra claire<div class="value">{{borderExtraLight}}</div></div>
</div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group">
<div
class="demo-color-box demo-color-box-other"
:style="{ background: black }"
>Basic Black<div class="value">{{black}}</div></div>
<div
class="demo-color-box demo-color-box-other"
:style="{ background: white, color: '#303133', border: '1px solid #eee' }"
>Basic White<div class="value">{{white}}</div></div>
<div class="demo-color-box demo-color-box-other bg-transparent">Transparent<div class="value">Transparent</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -1,74 +1,96 @@
<style> <script>
.demo-typo-box { import bus from '../../bus';
height: 200px; const varMap = [
width: 200px; '$--font-size-extra-large',
position: relative; '$--font-size-large',
border: 1px solid #eaeefb; '$--font-size-medium',
font-size: 40px; '$--font-size-base',
color: #1f2d3d; '$--font-size-small',
text-align: center; '$--font-size-extra-small'
line-height: 162px; ];
padding-bottom: 36px; const original = {
box-sizing: border-box; 'font_size_extra_large': '20px',
display: inline-block; 'font_size_large': '18px',
margin-right: 17px; 'font_size_medium': '16px',
border-radius: 4px; 'font_size_base': '14px',
'font_size_small': '13px',
.name { 'font_size_extra_small': '12px'
position: absolute;
bottom: 0;
width: 100%;
height: 35px;
border-top: 1px solid #eaeefb;
font-size: 14px;
color: #8492a6;
line-height: 35px;
text-align: left;
text-indent: 10px;
font-family: 'Helvetica Neue';
}
} }
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
'font_size_extra_large': '',
'font_size_large': '',
'font_size_medium': '',
'font_size_base': '',
'font_size_small': '',
'font_size_extra_small': ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
varMap.forEach((v) => {
const key = v.replace('$--', '').replace(/-/g, '_')
if (value[v]) {
this[key] = value[v]
} else {
this[key] = original[key]
}
});
}
}
},
}
</script>
<style>
.demo-typo-size { .demo-typo-size {
.h1 {
font-size: 20px;
}
.h2 {
font-size: 18px;
}
.h3 {
font-size: 16px;
}
.text-regular {
font-size: 14px;
}
.text-small {
font-size: 13px;
}
.text-smaller {
font-size: 12px;
}
.color-dark-light { .color-dark-light {
color: #99a9bf; color: #99a9bf;
} }
} }
.typo-PingFang { .demo-term-box img{
font-family: 'PingFang SC'; width: 24%;
margin: 0 4% 20px 0;
} }
.typo-Hiragino {
font-family: 'Hiragino Sans GB'; .lineH-left {
display: inline-block;
height: 80px
} }
.typo-Microsoft { .lineH-right {
font-family: 'Microsoft YaHei'; display: inline-block;
list-style: none;
padding: 0 0 0 90px;
margin: 0;
vertical-align: top;
} }
/* 英文 \*/ .lineH-right li{
.typo-Helvetica-Neue { font-size: 13px;
font-family: 'Helvetica Neue'; color: #666;
height: 20px;
line-height: 20px;
} }
.typo-Helvetica { .lineH-right li span{
font-family: 'Helvetica'; padding-left: 40px;
}
.typo-Arial {
font-family: 'Arial';
} }
</style> </style>
@ -76,34 +98,82 @@
Nous avons créé une convention de police d'écriture afin d'assurer la meilleur présentation possible sur toutes le plateformes. Nous avons créé une convention de police d'écriture afin d'assurer la meilleur présentation possible sur toutes le plateformes.
### Police chinoise ### Police
<div class="demo-typo-box typo-PingFang"> <div class="demo-term-box">
和畅惠风 <img src="../../assets/images/term-pingfang.png" alt="">
<div class="name">PingFang SC</div> <img src="../../assets/images/term-hiragino.png" alt="">
</div> <img src="../../assets/images/term-microsoft.png" alt="">
<div class="demo-typo-box typo-Hiragino"> <img src="../../assets/images/term-sf.png" alt="">
和畅惠风 <img src="../../assets/images/term-helvetica.png" alt="">
<div class="name">Hiragino Sans GB</div> <img src="../../assets/images/term-arial.png" alt="">
</div>
<div class="demo-typo-box typo-Microsoft">
和畅惠风
<div class="name">Microsoft YaHei</div>
</div> </div>
### Police anglaise / numérique ### Convention des polices
<div class="demo-typo-box typo-Helvetica-neue"> <table class="demo-typo-size">
RGag <tbody>
<div class="name">Helvetica Neue</div> <tr
</div> >
<div class="demo-typo-box typo-Helvetica"> <td>Level</td>
RGag <td>Font Size</td>
<div class="name">Helvetica</div> <td class="color-dark-light">Demo</td>
</div> </tr>
<div class="demo-typo-box typo-Arial"> <tr
RGag :style="{ fontSize: font_size_extra_small }"
<div class="name">Arial</div> >
<td>Supplementary text</td>
<td class="color-dark-light">{{font_size_extra_small}} Extra Small</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_small }"
>
<td>Body (small)</td>
<td class="color-dark-light">{{font_size_small}} Small</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_base }"
>
<td>Body</td>
<td class="color-dark-light">{{font_size_base}} Base</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_medium }"
>
<td >Small Title</td>
<td class="color-dark-light">{{font_size_medium}} Medium</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_large }"
>
<td>Title</td>
<td class="color-dark-light">{{font_size_large}} large</td>
<td>Build with Element</td>
</tr>
<tr
:style="{ fontSize: font_size_extra_large }"
>
<td>Main Title</td>
<td class="color-dark-light">{{font_size_extra_large}} Extra large</td>
<td>Build with Element</td>
</tr>
</tbody>
</table>
### Font Line Height
<div>
<img class="lineH-left" src="~examples/assets/images/typography.png" />
<ul class="lineH-right">
<li>line-height:1 <span>No line height</span></li>
<li>line-height:1.3 <span>Compact</span></li>
<li>line-height:1.5 <span>Regular</span></li>
<li>line-height:1.7 <span>Loose</span></li>
</ul>
</div> </div>
### Font-family ### Font-family
@ -111,40 +181,3 @@ Nous avons créé une convention de police d'écriture afin d'assurer la meilleu
```css ```css
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
``` ```
### Convention des polices
<table class="demo-typo-size">
<tbody>
<tr>
<td class="h1">Titre principal</td>
<td class="h1">Construit avec Element</td>
<td class="color-dark-light">20px Extra large</td>
</tr>
<tr>
<td class="h2">Titre</td>
<td class="h2">Construit avec Element</td>
<td class="color-dark-light">18px large</td>
</tr>
<tr>
<td class="h3">Sous-titre</td>
<td class="h3">Construit avec Element</td>
<td class="color-dark-light">16px Medium</td>
</tr>
<tr>
<td class="text-regular">Body</td>
<td class="text-regular">Construit avec Element</td>
<td class="color-dark-light">14px Small</td>
</tr>
<tr>
<td class="text-small">Body (petit)</td>
<td class="text-small">Construit avec Element</td>
<td class="color-dark-light">13px Extra Small</td>
</tr>
<tr>
<td class="text-smaller">Texte supplémentaire</td>
<td class="text-smaller">Construit avec Element</td>
<td class="color-dark-light">12px Extra Extra Small</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,181 @@
<script>
import bus from '../../bus';
const varMap = {
'$--box-shadow-light': 'boxShadowLight',
'$--box-shadow-base': 'boxShadowBase',
'$--border-radius-base': 'borderRadiusBase',
'$--border-radius-small': 'borderRadiusSmall'
};
const original = {
boxShadowLight: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
boxShadowBase: '0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04)',
borderRadiusBase: '4px',
borderRadiusSmall: '2px'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
boxShadowLight: '',
boxShadowBase: '',
borderRadiusBase: '',
borderRadiusSmall: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(varMap).forEach((c) => {
if (value[c]) {
this[varMap[c]] = value[c]
} else {
this[varMap[c]] = original[varMap[c]]
}
});
}
}
}
}
</script>
<style>
.demo-border .text {
width: 15%;
}
.demo-border .line {
width: 70%;
}
.demo-border .line div{
width: 100%;
height: 0;
border: 1px solid #EEE;
}
.demo-border .line .dashed{
border: 2px dashed #EEE;
}
.demo-shadow {
height: 100px;
width: 50%;
border: 1px solid #eee;
}
.demo-shadow-text {
line-height: 50px;
color: #666;
font-size: 14px;
}
.demo-radius .title{
color: #666;
font-size: 18px;
margin: 10px 0;
}
.demo-radius .value{
color: #333;
font-size: 16px;
margin: 10px 0;
}
.demo-radius .radius {
height: 60px;
width: 70%;
border: 1px solid #D7DAE2;
border-radius: 0;
margin-top: 20px;
}
.demo-radius .radius-30 {
border-radius: 30px;
}
</style>
## Border 边框
我们对边框进行统一规范,可用于按钮、卡片、弹窗等组件里。
### 边框
我们提供了一下几种边框样式,以供选择。
<table class="demo-border">
<tbody>
<tr>
<td class="text">名称</td>
<td class="text">粗细</td>
<td class="line">举例</td>
</tr>
<tr>
<td class="text">实线</td>
<td class="text">1px</td>
<td class="line">
<div></div>
</td>
</tr>
<tr>
<td class="text">虚线</td>
<td class="text">2px</td>
<td class="line">
<div class="dashed"></div>
</td>
</tr>
</tbody>
</table>
### 圆角
我们提供了一下几种圆角样式,以供选择。
<el-row :gutter="12" class="demo-radius">
<el-col :span="6" :xs="{span: 12}">
<div class="title">无圆角</div>
<div class="value">border-radius: 0px</div>
<div class="radius"></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">小圆角</div>
<div class="value">border-radius: {{borderRadiusSmall}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusSmall }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">大圆角</div>
<div class="value">border-radius: {{borderRadiusBase}}</div>
<div
class="radius"
:style="{ borderRadius: borderRadiusBase }"
></div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="title">圆形圆角</div>
<div class="value">border-radius: 30px</div>
<div class="radius radius-30"></div>
</el-col>
</el-row>
### 投影
我们提供了一下几种投影样式,以供选择。
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowBase }"
></div>
<span class="demo-shadow-text">基础投影 box-shadow: {{boxShadowBase}}</span>
<div
class="demo-shadow"
:style="{ boxShadow: boxShadowLight }"
></div>
<span class="demo-shadow-text">浅色投影 box-shadow: {{boxShadowLight}}</span>

View File

@ -1,9 +1,101 @@
<script>
import bus from '../../bus';
import { tintColor } from '../../color.js';
const varMap = {
'primary': '$--color-primary',
'success': '$--color-success',
'warning': '$--color-warning',
'danger': '$--color-danger',
'info': '$--color-info',
'white': '$--color-white',
'black': '$--color-black',
'textPrimary': '$--color-text-primary',
'textRegular': '$--color-text-regular',
'textSecondary': '$--color-text-secondary',
'textPlaceholder': '$--color-text-placeholder',
'borderBase': '$--border-color-base',
'borderLight': '$--border-color-light',
'borderLighter': '$--border-color-lighter',
'borderExtraLight': '$--border-color-extra-light'
};
const original = {
primary: '#409EFF',
success: '#67C23A',
warning: '#E6A23C',
danger: '#F56C6C',
info: '#909399',
white: '#FFFFFF',
black: '#000000',
textPrimary: '#303133',
textRegular: '#606266',
textSecondary: '#909399',
textPlaceholder: '#C0C4CC',
borderBase: '#DCDFE6',
borderLight: '#E4E7ED',
borderLighter: '#EBEEF5',
borderExtraLight: '#F2F6FC'
}
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
primary: '',
success: '',
warning: '',
danger: '',
info: '',
white: '',
black: '',
textPrimary: '',
textRegular: '',
textSecondary: '',
textPlaceholder: '',
borderBase: '',
borderLight: '',
borderLighter: '',
borderExtraLight: ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(original).forEach((o) => {
if (value[varMap[o]]) {
this[o] = value[varMap[o]]
} else {
this[o] = original[o]
}
});
}
}
},
}
</script>
<style> <style>
.demo-color-box { .demo-color-box {
position: relative;
border-radius: 4px; border-radius: 4px;
padding: 20px; padding: 20px;
margin: 5px 0; margin: 5px 0;
height: 74px; height: 114px;
box-sizing: border-box; box-sizing: border-box;
color: #fff; color: #fff;
font-size: 14px; font-size: 14px;
@ -14,6 +106,12 @@
line-height: 24px; line-height: 24px;
} }
} }
.demo-color-box-other {
height: 74px;
margin: 10px 0!important;
border-radius: 4px 4px 4px 4px!important;
padding: 15px 20px;
}
.demo-color-box-group { .demo-color-box-group {
.demo-color-box { .demo-color-box {
border-radius: 0; border-radius: 0;
@ -26,50 +124,42 @@
border-radius: 0 0 4px 4px; border-radius: 0 0 4px 4px;
} }
} }
.bg-blue { .bg-color-sub {
background-color: #409EFF; width: 100%;
height: 40px;
left: 0;
bottom: 0;
position: absolute;
border-radius: 0 0 4px 4px;
} }
.bg-blue-sub-item {
.bg-success { width: 11.1111111%;
background-color: #67C23A; height: 100%;
display: inline-block;
} }
.bg-warning { .bg-blue-sub-item:first-child {
background-color: #E6A23C; border-radius: 0 0 0 4px;
} }
.bg-danger { .bg-success-sub-item {
background-color: #F56C6C; width: 50%;
height: 100%;
display: inline-block;
} }
.bg-info { .bg-success-sub-item:first-child {
background-color: #909399; border-radius: 0 0 0 4px;
} }
.bg-success-sub-item:last-child {
.bg-text-primary { border-radius: 0 0 4px 0;
background-color: #303133;
} }
.bg-text-regular { .bg-transparent {
background-color: #606266; border: 1px solid #FCC3C3;
color: #303133;
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' version='1.1' preserveAspectRatio='none' viewBox='0 0 100 100'><path d='M0 98 L100 0 L100 1 L1 98' fill='%23FCC3C3' /></svg>");
background-repeat:no-repeat;
background-position:center center;
background-size: 100% 100%, auto;
} }
.bg-text-secondary { .demo-color-box-lite {
background-color: #909399;
}
.bg-text-placeholder {
background-color: #c0c4cc;
}
.bg-border-base {
background-color: #dcdfe6;
}
.bg-border-light {
background-color: #e4e7ed;
}
.bg-border-lighter {
background-color: #ebeef5;
}
.bg-border-extra-light {
background-color: #f2f6fc;
}
[class*=" bg-border-"] {
color: #303133; color: #303133;
} }
</style> </style>
@ -83,8 +173,24 @@ Element 为了避免视觉传达差异,使用一套特定的调色板来规定
Element 主要品牌颜色是鲜艳、友好的蓝色。 Element 主要品牌颜色是鲜艳、友好的蓝色。
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="10" :xs="{span: 12}">
<div class="demo-color-box bg-blue">Blue<div class="value">#409EFF</div></div> <div
class="demo-color-box"
:style="{ background: primary }"
>
Brand Color<div class="value">#409EFF</div>
<div
class="bg-color-sub"
:style="{ background: tintColor(primary, 0.9) }"
>
<div
class="bg-blue-sub-item"
v-for="(item, key) in Array(8)"
:key="key"
:style="{ background: tintColor(primary, (key + 1) / 10) }"
>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -94,16 +200,72 @@ Element 主要品牌颜色是鲜艳、友好的蓝色。
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-success">Success<div class="value">#67C23A</div></div> <div class="demo-color-box"
:style="{ background: success }"
>Success<div class="value">#67C23A</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(success, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-warning">Warning<div class="value">#E6A23C</div></div> <div class="demo-color-box"
:style="{ background: warning }"
>Warning<div class="value">#E6A23C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(warning, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-danger">Danger<div class="value">#F56C6C</div></div> <div class="demo-color-box"
:style="{ background: danger }"
>Danger<div class="value">#F56C6C</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(danger, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box bg-info">Info<div class="value">#909399</div></div> <div class="demo-color-box"
:style="{ background: info }"
>Info<div class="value">#909399</div>
<div
class="bg-color-sub"
>
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(info, (key + 8) / 10) }"
>
</div>
</div>
</div>
</el-col> </el-col>
</el-row> </el-row>
@ -114,18 +276,48 @@ Element 主要品牌颜色是鲜艳、友好的蓝色。
<el-row :gutter="12"> <el-row :gutter="12">
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-text-primary">主要文字<div class="value">#303133</div></div> <div class="demo-color-box demo-color-box-other"
<div class="demo-color-box bg-text-regular">常规文字<div class="value">#606266</div></div> :style="{ background: textPrimary }"
<div class="demo-color-box bg-text-secondary">次要文字<div class="value">#909399</div></div> >主要文字<div class="value">{{textPrimary}}</div></div>
<div class="demo-color-box bg-text-placeholder">占位文字<div class="value">#C0C4CC</div></div> <div class="demo-color-box demo-color-box-other"
:style="{ background: textRegular }"
>
常规文字<div class="value">{{textRegular}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textSecondary }"
>次要文字<div class="value">{{textSecondary}}</div></div>
<div class="demo-color-box demo-color-box-other"
:style="{ background: textPlaceholder }"
>占位文字<div class="value">{{textPlaceholder}}</div></div>
</div> </div>
</el-col> </el-col>
<el-col :span="6" :xs="{span: 12}"> <el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group"> <div class="demo-color-box-group">
<div class="demo-color-box bg-border-base">一级边框<div class="value">#DCDFE6</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
<div class="demo-color-box bg-border-light">二级边框<div class="value">#E4E7ED</div></div> :style="{ background: borderBase }"
<div class="demo-color-box bg-border-lighter">三级边框<div class="value">#EBEEF5</div></div> >一级边框<div class="value">{{borderBase}}</div></div>
<div class="demo-color-box bg-border-extra-light">四级边框<div class="value">#F2F6FC</div></div> <div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLight }"
>二级边框<div class="value">{{borderLight}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderLighter }"
>三级边框<div class="value">{{borderLighter}}</div></div>
<div class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: borderExtraLight }"
>四级边框<div class="value">{{borderExtraLight}}</div></div>
</div>
</el-col>
<el-col :span="6" :xs="{span: 12}">
<div class="demo-color-box-group">
<div
class="demo-color-box demo-color-box-other"
:style="{ background: black }"
>基础黑色<div class="value">{{black}}</div></div>
<div
class="demo-color-box demo-color-box-other"
:style="{ background: white, color: '#303133', border: '1px solid #eee' }"
>基础白色<div class="value">{{white}}</div></div>
<div class="demo-color-box demo-color-box-other bg-transparent">透明<div class="value">Transparent</div>
</div> </div>
</el-col> </el-col>
</el-row> </el-row>

View File

@ -1,74 +1,96 @@
<style> <script>
.demo-typo-box { import bus from '../../bus';
height: 200px; const varMap = [
width: 200px; '$--font-size-extra-large',
position: relative; '$--font-size-large',
border: 1px solid #eaeefb; '$--font-size-medium',
font-size: 40px; '$--font-size-base',
color: #1f2d3d; '$--font-size-small',
text-align: center; '$--font-size-extra-small'
line-height: 162px; ];
padding-bottom: 36px; const original = {
box-sizing: border-box; 'font_size_extra_large': '20px',
display: inline-block; 'font_size_large': '18px',
margin-right: 17px; 'font_size_medium': '16px',
border-radius: 4px; 'font_size_base': '14px',
'font_size_small': '13px',
.name { 'font_size_extra_small': '12px'
position: absolute;
bottom: 0;
width: 100%;
height: 35px;
border-top: 1px solid #eaeefb;
font-size: 14px;
color: #8492a6;
line-height: 35px;
text-align: left;
text-indent: 10px;
font-family: 'Helvetica Neue';
}
} }
export default {
created() {
bus.$on('user-theme-config-update', this.setGlobal);
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(color, tint) {
return tintColor(color, tint);
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
data() {
return {
global: {},
'font_size_extra_large': '',
'font_size_large': '',
'font_size_medium': '',
'font_size_base': '',
'font_size_small': '',
'font_size_extra_small': ''
}
},
watch: {
global: {
immediate: true,
handler(value) {
varMap.forEach((v) => {
const key = v.replace('$--', '').replace(/-/g, '_')
if (value[v]) {
this[key] = value[v]
} else {
this[key] = original[key]
}
});
}
}
},
}
</script>
<style>
.demo-typo-size { .demo-typo-size {
.h1 {
font-size: 20px;
}
.h2 {
font-size: 18px;
}
.h3 {
font-size: 16px;
}
.text-regular {
font-size: 14px;
}
.text-small {
font-size: 13px;
}
.text-smaller {
font-size: 12px;
}
.color-dark-light { .color-dark-light {
color: #99a9bf; color: #99a9bf;
} }
} }
.typo-PingFang { .demo-term-box img{
font-family: 'PingFang SC'; width: 24%;
margin: 0 4% 20px 0;
} }
.typo-Hiragino {
font-family: 'Hiragino Sans GB'; .lineH-left {
display: inline-block;
height: 80px
} }
.typo-Microsoft { .lineH-right {
font-family: 'Microsoft YaHei'; display: inline-block;
list-style: none;
padding: 0 0 0 90px;
margin: 0;
vertical-align: top;
} }
/* 英文 */ .lineH-right li{
.typo-Helvetica-Neue { font-size: 13px;
font-family: 'Helvetica Neue'; color: #666;
height: 20px;
line-height: 20px;
} }
.typo-Helvetica { .lineH-right li span{
font-family: 'Helvetica'; padding-left: 40px;
}
.typo-Arial {
font-family: 'Arial';
} }
</style> </style>
@ -76,34 +98,81 @@
我们对字体进行统一规范,力求在各个操作系统下都有最佳展示效果。 我们对字体进行统一规范,力求在各个操作系统下都有最佳展示效果。
### 中文字体 ### 字体
<div class="demo-term-box">
<div class="demo-typo-box typo-PingFang"> <img src="../../assets/images/term-pingfang.png" alt="">
和畅惠风 <img src="../../assets/images/term-hiragino.png" alt="">
<div class="name">PingFang SC</div> <img src="../../assets/images/term-microsoft.png" alt="">
</div> <img src="../../assets/images/term-sf.png" alt="">
<div class="demo-typo-box typo-Hiragino"> <img src="../../assets/images/term-helvetica.png" alt="">
和畅惠风 <img src="../../assets/images/term-arial.png" alt="">
<div class="name">Hiragino Sans GB</div>
</div>
<div class="demo-typo-box typo-Microsoft">
和畅惠风
<div class="name">Microsoft YaHei</div>
</div> </div>
### 英文/数字字体 ### 字号
<div class="demo-typo-box typo-Helvetica-neue"> <table class="demo-typo-size">
RGag <tbody>
<div class="name">Helvetica Neue</div> <tr
</div> >
<div class="demo-typo-box typo-Helvetica"> <td>层级</td>
RGag <td>字体大小</td>
<div class="name">Helvetica</div> <td class="color-dark-light">举例</td>
</div> </tr>
<div class="demo-typo-box typo-Arial"> <tr
RGag :style="{ fontSize: font_size_extra_small }"
<div class="name">Arial</div> >
<td>辅助文字</td>
<td class="color-dark-light">{{font_size_extra_small}} Extra Small</td>
<td>用 Element 快速搭建页面</td>
</tr>
<tr
:style="{ fontSize: font_size_small }"
>
<td>正文(小)</td>
<td class="color-dark-light">{{font_size_small}} Small</td>
<td>用 Element 快速搭建页面</td>
</tr>
<tr
:style="{ fontSize: font_size_base }"
>
<td>正文</td>
<td class="color-dark-light">{{font_size_base}} Base</td>
<td>用 Element 快速搭建页面</td>
</tr>
<tr
:style="{ fontSize: font_size_medium }"
>
<td>小标题</td>
<td class="color-dark-light">{{font_size_medium}} Medium</td>
<td>用 Element 快速搭建页面</td>
</tr>
<tr
:style="{ fontSize: font_size_large }"
>
<td>标题</td>
<td class="color-dark-light">{{font_size_large}} large</td>
<td>用 Element 快速搭建页面</td>
</tr>
<tr
:style="{ fontSize: font_size_extra_large }"
>
<td>主标题</td>
<td class="color-dark-light">{{font_size_extra_large}} Extra large</td>
<td>用 Element 快速搭建页面</td>
</tr>
</tbody>
</table>
### 行高
<div>
<img class="lineH-left" src="~examples/assets/images/typography.png" />
<ul class="lineH-right">
<li>line-height:1 <span>无行高</span></li>
<li>line-height:1.3 <span>紧凑</span></li>
<li>line-height:1.5 <span>常规</span></li>
<li>line-height:1.7 <span>宽松</span></li>
</ul>
</div> </div>
### Font-family 代码 ### Font-family 代码
@ -111,40 +180,3 @@
```css ```css
font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif; font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
``` ```
### 字体使用规范
<table class="demo-typo-size">
<tbody>
<tr>
<td class="h1">主标题</td>
<td class="h1">用 Element 快速搭建页面</td>
<td class="color-dark-light">20px Extra large</td>
</tr>
<tr>
<td class="h2">标题</td>
<td class="h2">用 Element 快速搭建页面</td>
<td class="color-dark-light">18px large</td>
</tr>
<tr>
<td class="h3">小标题</td>
<td class="h3">用 Element 快速搭建页面</td>
<td class="color-dark-light">16px Medium</td>
</tr>
<tr>
<td class="text-regular">正文</td>
<td class="text-regular">用 Element 快速搭建页面</td>
<td class="color-dark-light">14px Small</td>
</tr>
<tr>
<td class="text-small">正文(小)</td>
<td class="text-small">用 Element 快速搭建页面</td>
<td class="color-dark-light">13px Extra Small</td>
</tr>
<tr>
<td class="text-smaller">辅助文字</td>
<td class="text-smaller">用 Element 快速搭建页面</td>
<td class="color-dark-light">12px Extra Extra Small</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,75 @@
[
{
"lang": "zh-CN",
"display-name": {
"border-color": "边框颜色",
"font-color": "文字颜色",
"background-color": "背景颜色",
"font-weight": "文字粗细",
"font-size": "文字大小",
"font-line-height": "文字行高",
"border-radius": "边框圆角",
"color": "颜色"
},
"action": {
"theme-editor": "主题编辑器",
"no-config": "暂不可编辑,敬请期待",
"reset-theme": "重置",
"download-theme": "下载"
},
"category": {
"BrandColor": "品牌颜色",
"SecondaryColor": "辅助颜色",
"FontColor": "文字颜色",
"BorderColor": "边框颜色",
"BackgroundColor": "背景颜色",
"Other": "其他",
"Color": "颜色",
"Border": "边框",
"Font": "文字",
"Radius": "边框圆角",
"Shadow": "阴影",
"FontSize": "文字大小",
"FontWeight": "文字粗细",
"LineHeight": "文字行高"
}
},
{
"lang": "en-US",
"display-name": {
"border-color": "border color",
"font-color": "font color",
"background-color": "background color",
"font-weight": "font weight",
"font-size": "font size",
"font-line-height": "font line height",
"border-radius": "border radius"
},
"action": {
"theme-editor": "Theme Editor",
"no-config": "Please stay tuned",
"reset-theme": "Reset",
"download-theme": "Download"
},
"category": {
"BrandColor": "Brand Color",
"SecondaryColor": "Secondary Color",
"FontColor": "Font Color",
"BorderColor": "Border Color",
"BackgroundColor": "Background Color",
"FontSize": "Font Size",
"FontWeight": "Font Weight",
"LineHeight": "Line Height"
}
},
{
"lang": "es",
"display-name": {
}
},
{
"lang": "fr-FR",
"display-name": {
}
}
]

View File

@ -59,6 +59,10 @@
"path": "/typography", "path": "/typography",
"title": "Typography 字体" "title": "Typography 字体"
}, },
{
"path": "/border",
"title": "Border 边框"
},
{ {
"path": "/icon", "path": "/icon",
"title": "Icon 图标" "title": "Icon 图标"
@ -313,6 +317,10 @@
"path": "/typography", "path": "/typography",
"title": "Typography" "title": "Typography"
}, },
{
"path": "/border",
"title": "Border"
},
{ {
"path": "/icon", "path": "/icon",
"title": "Icon" "title": "Icon"
@ -567,6 +575,10 @@
"path": "/typography", "path": "/typography",
"title": "Typography" "title": "Typography"
}, },
{
"path": "/border",
"title": "Border"
},
{ {
"path": "/icon", "path": "/icon",
"title": "Icon" "title": "Icon"
@ -821,6 +833,10 @@
"path": "/typography", "path": "/typography",
"title": "Typography" "title": "Typography"
}, },
{
"path": "/border",
"title": "Border"
},
{ {
"path": "/icon", "path": "/icon",
"title": "Icon" "title": "Icon"

View File

@ -133,6 +133,37 @@
} }
} }
@media (min-width: 1140px) {
.page-component__content {
transition:padding-right 0.3s ease;
&.theme-config {
padding-right: 26%;
}
}
.page-container.page-component {
transition:width 0.3s ease;
&.theme-config {
width: 98%;
}
.page-component__nav {
padding-left: 2%;
}
}
}
@media (min-width: 1600px) {
.page-component__content {
&.theme-config {
padding-right: 25%;
}
}
.page-container.page-component {
&.theme-config {
width: 1600px;
}
}
}
@media (max-width: 768px) { @media (max-width: 768px) {
.page-component { .page-component {
.page-component__nav { .page-component__nav {
@ -163,11 +194,11 @@
</style> </style>
<template> <template>
<el-scrollbar class="page-component__scroll" ref="componentScrollBar"> <el-scrollbar class="page-component__scroll" ref="componentScrollBar">
<div class="page-container page-component"> <div class="page-container page-component" :class="{'theme-config': isThemeConfigVisible}">
<el-scrollbar class="page-component__nav"> <el-scrollbar class="page-component__nav">
<side-nav :data="navsData[lang]" :base="`/${ lang }/component`"></side-nav> <side-nav :data="navsData[lang]" :base="`/${ lang }/component`"></side-nav>
</el-scrollbar> </el-scrollbar>
<div class="page-component__content"> <div class="page-component__content" :class="{'theme-config': isThemeConfigVisible}">
<router-view class="content"></router-view> <router-view class="content"></router-view>
<footer-nav></footer-nav> <footer-nav></footer-nav>
</div> </div>
@ -200,7 +231,8 @@
scrollTop: 0, scrollTop: 0,
showHeader: true, showHeader: true,
componentScrollBar: null, componentScrollBar: null,
componentScrollBoxElement: null componentScrollBoxElement: null,
isThemeConfigVisible: false
}; };
}, },
watch: { watch: {
@ -261,6 +293,9 @@
bus.$on('navFade', val => { bus.$on('navFade', val => {
this.navFaded = val; this.navFaded = val;
}); });
bus.$on('user-theme-config-visible', val => {
this.isThemeConfigVisible = val;
});
window.addEventListener('hashchange', () => { window.addEventListener('hashchange', () => {
if (location.href.match(/#/g).length < 2) { if (location.href.match(/#/g).length < 2) {
document.documentElement.scrollTop = document.body.scrollTop = 0; document.documentElement.scrollTop = document.body.scrollTop = 0;
@ -271,6 +306,9 @@
}); });
}, },
mounted() { mounted() {
if (window.userThemeConfigVisible) {
this.isThemeConfigVisible = window.userThemeConfigVisible;
}
this.componentScrollBar = this.$refs.componentScrollBar; this.componentScrollBar = this.$refs.componentScrollBar;
this.componentScrollBox = this.componentScrollBar.$el.querySelector('.el-scrollbar__wrap'); this.componentScrollBox = this.componentScrollBar.$el.querySelector('.el-scrollbar__wrap');
this.throttledScrollHandler = throttle(300, this.handleScroll); this.throttledScrollHandler = throttle(300, this.handleScroll);

View File

@ -27,9 +27,22 @@
"test": "npm run lint && npm run build:theme && cross-env CI_ENV=/dev/ BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", "test": "npm run lint && npm run build:theme && cross-env CI_ENV=/dev/ BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
"test:watch": "npm run build:theme && cross-env BABEL_ENV=test karma start test/unit/karma.conf.js" "test:watch": "npm run build:theme && cross-env BABEL_ENV=test karma start test/unit/karma.conf.js"
}, },
"faas": { "faas": [
"domain": "element", {
"public": "temp_web/element" "domain": "element",
"public": "temp_web/element"
},
{
"domain": "element-theme",
"public": "examples/element-ui",
"build": [
"yarn",
"npm run deploy:build"
]
}
],
"engines": {
"node": "8"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -9,10 +9,10 @@
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
cursor: pointer; cursor: pointer;
background: $--button-default-fill; background: $--button-default-background-color;
border: $--border-base; border: $--border-base;
border-color: $--button-default-border; border-color: $--button-default-border-color;
color: $--button-default-color; color: $--button-default-font-color;
-webkit-appearance: none; -webkit-appearance: none;
text-align: center; text-align: center;
box-sizing: border-box; box-sizing: border-box;
@ -75,11 +75,11 @@
&, &,
&:hover, &:hover,
&:focus { &:focus {
color: $--button-disabled-color; color: $--button-disabled-font-color;
cursor: not-allowed; cursor: not-allowed;
background-image: none; background-image: none;
background-color: $--button-disabled-fill; background-color: $--button-disabled-background-color;
border-color: $--button-disabled-border; border-color: $--button-disabled-border-color;
} }
&.el-button--text { &.el-button--text {
@ -91,8 +91,8 @@
&:hover, &:hover,
&:focus { &:focus {
background-color: $--color-white; background-color: $--color-white;
border-color: $--button-disabled-border; border-color: $--button-disabled-border-color;
color: $--button-disabled-color; color: $--button-disabled-font-color;
} }
} }
} }
@ -122,19 +122,19 @@
padding: $--button-padding-vertical; padding: $--button-padding-vertical;
} }
@include m(primary) { @include m(primary) {
@include button-variant($--button-primary-color, $--button-primary-fill, $--button-primary-border); @include button-variant($--button-primary-font-color, $--button-primary-background-color, $--button-primary-border-color);
} }
@include m(success) { @include m(success) {
@include button-variant($--button-success-color, $--button-success-fill, $--button-success-border); @include button-variant($--button-success-font-color, $--button-success-background-color, $--button-success-border-color);
} }
@include m(warning) { @include m(warning) {
@include button-variant($--button-warning-color, $--button-warning-fill, $--button-warning-border); @include button-variant($--button-warning-font-color, $--button-warning-background-color, $--button-warning-border-color);
} }
@include m(danger) { @include m(danger) {
@include button-variant($--button-danger-color, $--button-danger-fill, $--button-danger-border); @include button-variant($--button-danger-font-color, $--button-danger-background-color, $--button-danger-border-color);
} }
@include m(info) { @include m(info) {
@include button-variant($--button-info-color, $--button-info-fill, $--button-info-border); @include button-variant($--button-info-font-color, $--button-info-background-color, $--button-info-border-color);
} }
@include m(medium) { @include m(medium) {
@include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, $--button-medium-border-radius); @include button-size($--button-medium-padding-vertical, $--button-medium-padding-horizontal, $--button-medium-font-size, $--button-medium-border-radius);

View File

@ -256,10 +256,10 @@
white-space: nowrap; white-space: nowrap;
vertical-align: middle; vertical-align: middle;
cursor: pointer; cursor: pointer;
background: $--button-default-fill; background: $--button-default-background-color;
border: $--border-base; border: $--border-base;
border-left: 0; border-left: 0;
color: $--button-default-color; color: $--button-default-font-color;
-webkit-appearance: none; -webkit-appearance: none;
text-align: center; text-align: center;
box-sizing: border-box; box-sizing: border-box;
@ -306,15 +306,15 @@
&.is-disabled { &.is-disabled {
& .el-checkbox-button__inner { & .el-checkbox-button__inner {
color: $--button-disabled-color; color: $--button-disabled-font-color;
cursor: not-allowed; cursor: not-allowed;
background-image: none; background-image: none;
background-color: $--button-disabled-fill; background-color: $--button-disabled-background-color;
border-color: $--button-disabled-border; border-color: $--button-disabled-border-color;
box-shadow: none; box-shadow: none;
} }
&:first-child .el-checkbox-button__inner { &:first-child .el-checkbox-button__inner {
border-left-color: $--button-disabled-border; border-left-color: $--button-disabled-border-color;
} }
} }

View File

@ -1,5 +1,8 @@
/* Element Chalk Variables */ /* Element Chalk Variables */
// Special comment for theme configurator
// type|[Chinese Name, English Name, Spanish Name, French Name]|Category|Order
/* Transition /* Transition
-------------------------- */ -------------------------- */
$--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default; $--all-transition: all .3s cubic-bezier(.645,.045,.355,1) !default;
@ -9,12 +12,14 @@ $--md-fade-transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 3
$--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default; $--border-transition-base: border-color .2s cubic-bezier(.645,.045,.355,1) !default;
$--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default; $--color-transition-base: color .2s cubic-bezier(.645,.045,.355,1) !default;
/* Colors /* Color
-------------------------- */ -------------------------- */
$--color-white: #fff !default; /// color|[,primary color,color primario]|BrandColor|0
$--color-black: #000 !default;
$--color-primary: #409EFF !default; $--color-primary: #409EFF !default;
/// color|[,basic white,basic white]|BackgroundColor|4
$--color-white: #FFFFFF !default;
/// color|[,basic black,basic black]|BackgroundColor|4
$--color-black: #000000 !default;
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */ $--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */ $--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */ $--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
@ -24,10 +29,13 @@ $--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /
$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */ $--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
$--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */ $--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
$--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */ $--color-primary-light-9: mix($--color-white, $--color-primary, 90%) !default; /* ecf5ff */
/// color|[,success color,success color]|SecondaryColor|1
$--color-success: #67c23a !default; $--color-success: #67C23A !default;
$--color-warning: #e6a23c !default; /// color|[,warning color,warning color]|SecondaryColor|1
$--color-danger: #f56c6c !default; $--color-warning: #E6A23C !default;
/// color|[,danger color,danger color]|SecondaryColor|1
$--color-danger: #F56C6C !default;
/// color|[,info color,info color]|SecondaryColor|1
$--color-info: #909399 !default; $--color-info: #909399 !default;
$--color-success-light: mix($--color-white, $--color-success, 80%) !default; $--color-success-light: mix($--color-white, $--color-success, 80%) !default;
@ -39,55 +47,81 @@ $--color-success-lighter: mix($--color-white, $--color-success, 90%) !default;
$--color-warning-lighter: mix($--color-white, $--color-warning, 90%) !default; $--color-warning-lighter: mix($--color-white, $--color-warning, 90%) !default;
$--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default; $--color-danger-lighter: mix($--color-white, $--color-danger, 90%) !default;
$--color-info-lighter: mix($--color-white, $--color-info, 90%) !default; $--color-info-lighter: mix($--color-white, $--color-info, 90%) !default;
/// color|[,primary text color,primary text color]|FontColor|2
$--color-text-primary: #303133 !default; $--color-text-primary: #303133 !default;
/// color|[,regular text color,regular text color]|FontColor|2
$--color-text-regular: #606266 !default; $--color-text-regular: #606266 !default;
/// color|[,secondary text color,secondary text color]|FontColor|2
$--color-text-secondary: #909399 !default; $--color-text-secondary: #909399 !default;
$--color-text-placeholder: #c0c4cc !default; /// color|[,placeholder text color,placeholder text color]|FontColor|2
$--color-text-placeholder: #C0C4CC !default;
/// color|[,border color,border color]|BorderColor|3
$--border-color-base: #DCDFE6 !default;
/// color|[,border color light,border color light]|BorderColor|3
$--border-color-light: #E4E7ED !default;
/// color|[,border color lighter,border color lighter]|BorderColor|3
$--border-color-lighter: #EBEEF5 !default;
/// color|[,border color extra light,border color extra light]|BorderColor|3
$--border-color-extra-light: #F2F6FC !default;
// Background
/// color|[,base background color,base background color]|BackgroundColor|4
$--background-color-base: #f5f7fa !default;
/* Link /* Link
-------------------------- */ -------------------------- */
$--link-color: $--color-primary-light-2 !default; $--link-color: $--color-primary-light-2 !default;
$--link-hover-color: $--color-primary !default; $--link-hover-color: $--color-primary !default;
/* Background
-------------------------- */
$--background-color-base: #f5f7fa !default;
/* Border /* Border
-------------------------- */ -------------------------- */
$--border-width-base: 1px !default; $--border-width-base: 1px !default;
$--border-style-base: solid !default; $--border-style-base: solid !default;
$--border-color-base: #dcdfe6 !default;
$--border-color-light: #e4e7ed !default;
$--border-color-lighter: #ebeef5 !default;
$--border-color-extra-light: #f2f6fc !default;
$--border-color-hover: $--color-text-placeholder !default; $--border-color-hover: $--color-text-placeholder !default;
$--border-base: $--border-width-base $--border-style-base $--border-color-base !default; $--border-base: $--border-width-base $--border-style-base $--border-color-base !default;
/// borderRadius|[,border radius base,border radius base]|Radius|0
$--border-radius-base: 4px !default; $--border-radius-base: 4px !default;
/// borderRadius|[,border radius small,border radius small]|Radius|0
$--border-radius-small: 2px !default; $--border-radius-small: 2px !default;
/// borderRadius|[,border radius circle,border radius circle]|Radius|0
$--border-radius-circle: 100% !default; $--border-radius-circle: 100% !default;
/* Box-shadow // Box-shadow
-------------------------- */ /// boxShadow|[,box shadow base,box shadow base]|Shadow|1
$--box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) !default; $--box-shadow-base: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04) !default;
// boxShadow|[,box shadow,box shadow]|Shadow|1
$--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12) !default; $--box-shadow-dark: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .12) !default;
/// boxShadow|[,box shadow,box shadow]|Shadow|1
$--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !default; $--box-shadow-light: 0 2px 12px 0 rgba(0, 0, 0, 0.1) !default;
/* Fill /* Fill
-------------------------- */ -------------------------- */
$--fill-base: $--color-white !default; $--fill-base: $--color-white !default;
/* Font /* Typography
-------------------------- */ -------------------------- */
$--font-path: 'fonts' !default; $--font-path: 'fonts' !default;
$--font-size-base: 14px !default; /// fontSize|[,Extra large font size,Extra large font size]|FontSize|0
$--font-size-small: 13px !default; $--font-size-extra-large: 20px !default;
/// fontSize|[,large font size,large font size]|FontSize|0
$--font-size-large: 18px !default; $--font-size-large: 18px !default;
$--font-color-disabled-base: #bbb !default; /// fontSize|[,Medium font size,Medium font size]|FontSize|0
$--font-size-medium: 16px !default;
/// fontSize|[,base font size,base font size]|FontSize|0
$--font-size-base: 14px !default;
/// fontSize|[,small font size,small font size]|FontSize|0
$--font-size-small: 13px !default;
/// fontSize|[,Extra small font size,Extra small font size]|FontSize|0
$--font-size-extra-small: 12px !default;
/// fontWeight|[,primary font weight,primary font weight]|FontWeight|1
$--font-weight-primary: 500 !default; $--font-weight-primary: 500 !default;
/// fontWeight|[,secondary font weight,secondary font weight]|FontWeight|1
$--font-weight-secondary: 100 !default;
/// fontLineHeight|[,primary font line height,primary font line height]|LineHeight|2
$--font-line-height-primary: 24px !default; $--font-line-height-primary: 24px !default;
/// fontLineHeight|[,secondary font line height,secondary font line height]|LineHeight|2
$--font-line-height-secondary: 16px !default;
$--font-color-disabled-base: #bbb !default;
/* Size /* Size
-------------------------- */ -------------------------- */
$--size-base: 14px !default; $--size-base: 14px !default;
@ -161,15 +195,22 @@ $--checkbox-button-checked-border-color: $--color-primary !default;
/* Radio /* Radio
-------------------------- */ -------------------------- */
$--radio-font-size: 14px !default; /// fontSize|[]|Font|1
$--radio-font-size: $--font-size-base !default;
/// fontWeight|[]|Font|1
$--radio-font-weight: $--font-weight-primary !default; $--radio-font-weight: $--font-weight-primary !default;
$--radio-color: $--color-text-regular !default; /// color|[]|Color|0
$--radio-font-color: $--color-text-regular !default;
$--radio-input-height: 14px !default; $--radio-input-height: 14px !default;
$--radio-input-width: 14px !default; $--radio-input-width: 14px !default;
/// borderRadius|[]|Border|2
$--radio-input-border-radius: $--border-radius-circle !default; $--radio-input-border-radius: $--border-radius-circle !default;
$--radio-input-fill: $--color-white !default; /// color|[]|Color|0
$--radio-input-background-color: $--color-white !default;
$--radio-input-border: $--border-base !default; $--radio-input-border: $--border-base !default;
/// color|[]|Color|0
$--radio-input-border-color: $--border-color-base !default; $--radio-input-border-color: $--border-color-base !default;
/// color|[]|Color|0
$--radio-icon-color: $--color-white !default; $--radio-icon-color: $--color-white !default;
$--radio-disabled-input-border-color: $--disabled-border-base !default; $--radio-disabled-input-border-color: $--disabled-border-base !default;
@ -180,9 +221,13 @@ $--radio-disabled-checked-input-border-color: $--disabled-border-base !default;
$--radio-disabled-checked-input-fill: $--disabled-fill-base !default; $--radio-disabled-checked-input-fill: $--disabled-fill-base !default;
$--radio-disabled-checked-icon-color: $--color-text-placeholder !default; $--radio-disabled-checked-icon-color: $--color-text-placeholder !default;
$--radio-checked-text-color: $--color-primary !default; /// color|[]|Color|0
$--radio-checked-font-color: $--color-primary !default;
/// color|[]|Color|0
$--radio-checked-input-border-color: $--color-primary !default; $--radio-checked-input-border-color: $--color-primary !default;
$--radio-checked-input-fill: $--color-white !default; /// color|[]|Color|0
$--radio-checked-input-background-color: $--color-white !default;
/// color|[]|Color|0
$--radio-checked-icon-color: $--color-primary !default; $--radio-checked-icon-color: $--color-primary !default;
$--radio-input-border-color-hover: $--color-primary !default; $--radio-input-border-color-hover: $--color-primary !default;
@ -202,9 +247,13 @@ $--radio-bordered-mini-input-height: 12px !default;
$--radio-bordered-mini-input-width: 12px !default; $--radio-bordered-mini-input-width: 12px !default;
$--radio-bordered-mini-height: 28px !default; $--radio-bordered-mini-height: 28px !default;
/// fontSize|[]|Font|1
$--radio-button-font-size: $--font-size-base !default; $--radio-button-font-size: $--font-size-base !default;
$--radio-button-checked-fill: $--color-primary !default; /// color|[]|Color|0
$--radio-button-checked-color: $--color-white !default; $--radio-button-checked-background-color: $--color-primary !default;
/// color|[]|Color|0
$--radio-button-checked-font-color: $--color-white !default;
/// color|[]|Color|0
$--radio-button-checked-border-color: $--color-primary !default; $--radio-button-checked-border-color: $--color-primary !default;
$--radio-button-disabled-checked-fill: $--border-color-extra-light !default; $--radio-button-disabled-checked-fill: $--border-color-extra-light !default;
@ -393,17 +442,23 @@ $--tab-vertical-header-count-fill: $--color-text-secondary !default;
/* Button /* Button
-------------------------- */ -------------------------- */
$--button-font-size: 14px !default; /// fontSize|[]|Font|1
$--button-font-size: $--font-size-base !default;
/// fontWeight|[]|Font|1
$--button-font-weight: $--font-weight-primary !default; $--button-font-weight: $--font-weight-primary !default;
/// borderRadius|[]|Border|2
$--button-border-radius: $--border-radius-base !default; $--button-border-radius: $--border-radius-base !default;
$--button-padding-vertical: 12px !default; $--button-padding-vertical: 12px !default;
$--button-padding-horizontal: 20px !default; $--button-padding-horizontal: 20px !default;
$--button-medium-font-size: 14px !default; /// fontSize|[]|Font|1
$--button-medium-font-size: $--font-size-base !default;
/// borderRadius|[]|Border|2
$--button-medium-border-radius: $--border-radius-base !default; $--button-medium-border-radius: $--border-radius-base !default;
$--button-medium-padding-vertical: 10px !default; $--button-medium-padding-vertical: 10px !default;
$--button-medium-padding-horizontal: 20px !default; $--button-medium-padding-horizontal: 20px !default;
/// fontSize|[]|Font|1
$--button-small-font-size: 12px !default; $--button-small-font-size: 12px !default;
$--button-small-border-radius: #{$--border-radius-base - 1} !default; $--button-small-border-radius: #{$--border-radius-base - 1} !default;
$--button-small-padding-vertical: 9px !default; $--button-small-padding-vertical: 9px !default;
@ -414,33 +469,50 @@ $--button-mini-border-radius: #{$--border-radius-base - 1} !default;
$--button-mini-padding-vertical: 7px !default; $--button-mini-padding-vertical: 7px !default;
$--button-mini-padding-horizontal: 15px !default; $--button-mini-padding-horizontal: 15px !default;
$--button-default-color: $--color-text-regular !default; /// color|[]|Color|0
$--button-default-fill: $--color-white !default; $--button-default-font-color: $--color-text-regular !default;
$--button-default-border: $--border-color-base !default; /// color|[]|Color|0
$--button-default-background-color: $--color-white !default;
/// color|[]|Color|0
$--button-default-border-color: $--border-color-base !default;
$--button-disabled-color: $--color-text-placeholder !default; /// color|[]|Color|0
$--button-disabled-fill: $--color-white !default; $--button-disabled-font-color: $--color-text-placeholder !default;
$--button-disabled-border: $--border-color-lighter !default; /// color|[]|Color|0
$--button-disabled-background-color: $--color-white !default;
/// color|[]|Color|0
$--button-disabled-border-color: $--border-color-lighter !default;
$--button-primary-border: $--color-primary !default; /// color|[]|Color|0
$--button-primary-color: $--color-white !default; $--button-primary-border-color: $--color-primary !default;
$--button-primary-fill: $--color-primary !default; /// color|[]|Color|0
$--button-primary-font-color: $--color-white !default;
$--button-success-border: $--color-success !default; /// color|[]|Color|0
$--button-success-color: $--color-white !default; $--button-primary-background-color: $--color-primary !default;
$--button-success-fill: $--color-success !default; /// color|[]|Color|0
$--button-success-border-color: $--color-success !default;
$--button-warning-border: $--color-warning !default; /// color|[]|Color|0
$--button-warning-color: $--color-white !default; $--button-success-font-color: $--color-white !default;
$--button-warning-fill: $--color-warning !default; /// color|[]|Color|0
$--button-success-background-color: $--color-success !default;
$--button-danger-border: $--color-danger !default; /// color|[]|Color|0
$--button-danger-color: $--color-white !default; $--button-warning-border-color: $--color-warning !default;
$--button-danger-fill: $--color-danger !default; /// color|[]|Color|0
$--button-warning-font-color: $--color-white !default;
$--button-info-border: $--color-info !default; /// color|[]|Color|0
$--button-info-color: $--color-white !default; $--button-warning-background-color: $--color-warning !default;
$--button-info-fill: $--color-info !default; /// color|[]|Color|0
$--button-danger-border-color: $--color-danger !default;
/// color|[]|Color|0
$--button-danger-font-color: $--color-white !default;
/// color|[]|Color|0
$--button-danger-background-color: $--color-danger !default;
/// color|[]|Color|0
$--button-info-border-color: $--color-info !default;
/// color|[]|Color|0
$--button-info-font-color: $--color-white !default;
/// color|[]|Color|0
$--button-info-background-color: $--color-info !default;
$--button-hover-tint-percent: 20% !default; $--button-hover-tint-percent: 20% !default;
$--button-active-shade-percent: 10% !default; $--button-active-shade-percent: 10% !default;
@ -470,7 +542,8 @@ $--dialog-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3) !default;
$--dialog-close-hover-color: $--color-primary !default; $--dialog-close-hover-color: $--color-primary !default;
$--dialog-title-font-size: $--font-size-large !default; $--dialog-title-font-size: $--font-size-large !default;
$--dialog-font-size: 14px !default; $--dialog-font-size: 14px !default;
$--dialog-line-height: $--font-line-height-primary !default; /// fontLineHeight|[]
$--dialog-font-line-height: $--font-line-height-primary !default;
$--dialog-padding-primary: 20px !default; $--dialog-padding-primary: 20px !default;
/* Table /* Table

View File

@ -58,7 +58,7 @@
} }
@include e(title) { @include e(title) {
line-height: $--dialog-line-height; line-height: $--dialog-font-line-height;
font-size: $--dialog-title-font-size; font-size: $--dialog-title-font-size;
color: $--color-text-primary; color: $--color-text-primary;
} }

View File

@ -12,11 +12,11 @@
line-height: 1; line-height: 1;
white-space: nowrap; white-space: nowrap;
vertical-align: middle; vertical-align: middle;
background: $--button-default-fill; background: $--button-default-background-color;
border: $--border-base; border: $--border-base;
font-weight: $--button-font-weight; font-weight: $--button-font-weight;
border-left: 0; border-left: 0;
color: $--button-default-color; color: $--button-default-font-color;
-webkit-appearance: none; -webkit-appearance: none;
text-align: center; text-align: center;
box-sizing: border-box; box-sizing: border-box;
@ -57,8 +57,8 @@
&:checked { &:checked {
& + .el-radio-button__inner { & + .el-radio-button__inner {
color: $--radio-button-checked-color; color: $--radio-button-checked-font-color;
background-color: $--radio-button-checked-fill; background-color: $--radio-button-checked-background-color;
border-color: $--radio-button-checked-border-color; border-color: $--radio-button-checked-border-color;
box-shadow: -1px 0 0 0 $--radio-button-checked-border-color; box-shadow: -1px 0 0 0 $--radio-button-checked-border-color;
} }
@ -66,11 +66,11 @@
&:disabled { &:disabled {
& + .el-radio-button__inner { & + .el-radio-button__inner {
color: $--button-disabled-color; color: $--button-disabled-font-color;
cursor: not-allowed; cursor: not-allowed;
background-image: none; background-image: none;
background-color: $--button-disabled-fill; background-color: $--button-disabled-background-color;
border-color: $--button-disabled-border; border-color: $--button-disabled-border-color;
box-shadow: none; box-shadow: none;
} }
&:checked + .el-radio-button__inner { &:checked + .el-radio-button__inner {

View File

@ -4,7 +4,7 @@
@import "common/var"; @import "common/var";
@include b(radio) { @include b(radio) {
color: $--radio-color; color: $--radio-font-color;
font-weight: $--radio-font-weight; font-weight: $--radio-font-weight;
line-height: 1; line-height: 1;
position: relative; position: relative;
@ -135,7 +135,7 @@
} }
& + .el-radio__label { & + .el-radio__label {
color: $--radio-checked-text-color; color: $--radio-checked-font-color;
} }
} }
@ -150,7 +150,7 @@
border-radius: $--radio-input-border-radius; border-radius: $--radio-input-border-radius;
width: $--radio-input-width; width: $--radio-input-width;
height: $--radio-input-height; height: $--radio-input-height;
background-color: $--radio-input-fill; background-color: $--radio-input-background-color;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
display: inline-block; display: inline-block;