This commit is contained in:
Ivan
2021-06-07 11:56:04 +08:00
commit c3c9fee2fb
1071 changed files with 195655 additions and 0 deletions

View File

@ -0,0 +1,280 @@
<style lang="scss">
.component-preview {
.heading>div{
margin-bottom: 15px;
}
.title {
font-size: 18px;
font-weight:400;
padding: 0 20px
}
.paragraph {
padding: 0 20px
}
.demo-color-box {
margin: 0;
}
.color {
margin-right: -12%;
}
}
</style>
<template>
<div class="component-preview">
<h4>Color</h4>
<div class="color">
<el-row :gutter="12">
<el-col :span="4" v-for="(color, key) in colorLine" :key="key">
<div class="demo-color-box" :style="{ background: dataProxy(color) }">
{{color}}
<div class="value">{{dataProxy(color)}}</div>
<div class="bg-color-sub">
<div
class="bg-success-sub-item"
v-for="(item, key) in Array(2)"
:key="key"
:style="{ background: tintColor(dataProxy(color), (key + 8) / 10) }"
></div>
</div>
</div>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="4">
<div class="demo-color-box demo-color-box-other" :style="{ background: color_text_primary }">
Primary Text
<div class="value">{{color_text_primary}}</div>
</div>
</el-col>
<el-col :span="4">
<div class="demo-color-box demo-color-box-other" :style="{ background: color_text_regular }">
Regular Text
<div class="value">{{color_text_regular}}</div>
</div>
</el-col>
<el-col :span="4">
<div class="demo-color-box demo-color-box-other" :style="{ background: color_text_secondary }">
Secondary Text
<div class="value">{{color_text_secondary}}</div>
</div>
</el-col>
<el-col :span="4">
<div class="demo-color-box demo-color-box-other" :style="{ background: color_text_placeholder }">
Placeholder
<div class="value">{{color_text_placeholder}}</div>
</div>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="4">
<div
class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: border_color_base }"
>
Border Base
<div class="value">{{border_color_base}}</div>
</div>
</el-col>
<el-col :span="4">
<div
class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: border_color_light }"
>
Border Light
<div class="value">{{border_color_light}}</div>
</div>
</el-col>
<el-col :span="4">
<div
class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: border_color_lighter }"
>
Border Lighter
<div class="value">{{border_color_lighter}}</div>
</div>
</el-col>
<el-col :span="4">
<div
class="demo-color-box demo-color-box-other demo-color-box-lite"
:style="{ background: border_color_extra_light }"
>
Border Extralight
<div class="value">{{border_color_extra_light}}</div>
</div>
</el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="4">
<div class="demo-color-box demo-color-box-other" :style="{ background: color_black }">
Background B
<div class="value">{{color_black}}</div>
</div>
</el-col>
<el-col :span="4">
<div
class="demo-color-box demo-color-box-other"
:style="{ background: color_white, color: '#303133', border: '1px solid #eee' }"
>
Background W
<div class="value">{{color_white}}</div>
</div>
</el-col>
<el-col :span="4">
<div class="demo-color-box demo-color-box-other bg-transparent">
Background
<div class="value">Transparent</div>
</div>
</el-col>
</el-row>
</div>
<h4>Typography</h4>
<el-row :gutter="12">
<el-col :span="6" class="heading">
<div :style="{ fontSize: font_size_extra_large }">Heading1</div>
<div :style="{ fontSize: font_size_large }">Heading2</div>
<div :style="{ fontSize: font_size_medium }">Heading3</div>
<div :style="{ fontSize: font_size_base }">Heading4</div>
<div :style="{ fontSize: font_size_small }">Heading5</div>
<div :style="{ fontSize: font_size_extra_small }">Heading6</div>
</el-col>
<el-col :span="9">
<div class="title">Example body text</div>
<p
class="paragraph"
:style="{
fontSize: font_size_base,
fontWeight: font_weight_primary,
lineHeight: font_line_height_primary
}" >
With MySpace becoming more popular every day, there is the constant need to be different. There are millions of users. If MySpace layouts are chosen well, then you can enhance your profile a great deal.</p>
</el-col>
<el-col :span="9">
<div class="title">Example small text</div>
<p
class="paragraph"
:style="{
fontSize: font_size_small,
fontWeight: font_weight_secondary,
lineHeight: font_line_height_secondary
}" >
Computers have become ubiquitous in almost every facet of our lives. At work, desk jockeys spend hours in front of their desktops, while delivery people scan bar codes with handhelds and workers in the field stay in touch with the central office via their notebooks. Computer hardware weaves itself through the fabric of our lives.</p>
</el-col>
</el-row>
</div>
</template>
<script>
import bus from '../../bus';
import { tintColor } from '../../color.js';
import {
ACTION_COMPONECT_SELECT,
ACTION_USER_CONFIG_UPDATE
} from './constant.js';
const original = {
'color_primary': '#409EFF',
'color_success': '#67C23A',
'color_warning': '#E6A23C',
'color_danger': '#F56C6C',
'color_info': '#909399',
'color_white': '#FFFFFF',
'color_black': '#000000',
'color_text_primary': '#303133',
'color_text_regular': '#606266',
'color_text_secondary': '#909399',
'color_text_placeholder': '#C0C4CC',
'border_color_base': '#DCDFE6',
'border_color_light': '#E4E7ED',
'border_color_lighter': '#EBEEF5',
'border_color_extra_light': '#F2F6FC',
'font_size_extra_large': '20px',
'font_size_large': '18px',
'font_size_medium': '16px',
'font_size_base': '14px',
'font_size_small': '13px',
'font_size_extra_small': '12px',
'font_weight_primary': 500,
'font_weight_secondary': 100,
'font_line_height_primary': '24px',
'font_line_height_secondary': '16px'
};
export default {
created() {
bus.$on(ACTION_USER_CONFIG_UPDATE, this.setGlobal);
bus.$on(ACTION_COMPONECT_SELECT, (val) => {
this.$nextTick(() => {
const getSelectElement = Array.from(document.querySelectorAll('h4')).filter((el) => (el.innerText.toLowerCase() === val));
if (getSelectElement[0]) {
const elementTop = getSelectElement[0].getBoundingClientRect().top;
window.scrollTo(0, window.pageYOffset + elementTop - 20); // 20 for padding
}
});
});
},
mounted() {
this.setGlobal();
},
methods: {
tintColor(a, b) {
return tintColor(a, b);
},
dataProxy(value) {
return this[`color_${value.toLowerCase()}`];
},
setGlobal() {
if (window.userThemeConfig) {
this.global = window.userThemeConfig.global;
}
}
},
watch: {
global: {
immediate: true,
handler(value) {
Object.keys(original).forEach((v) => {
const key = `$--${v.replace(/_/g, '-')}`;
if (value[key]) {
this[v] = value[key];
} else {
this[v] = original[v];
}
});
}
}
},
data() {
return {
global: {},
colorLine: ['Primary', 'Success', 'Warning', 'Danger', 'Info'],
'color_primary': '',
'color_success': '',
'color_warning': '',
'color_danger': '',
'color_info': '',
'color_white': '',
'color_black': '',
'color_text_primary': '',
'color_text_regular': '',
'color_text_secondary': '',
'color_text_placeholder': '',
'border_color_base': '',
'border_color_light': '',
'border_color_lighter': '',
'border_color_extra_light': '',
'font_size_extra_large': '',
'font_size_large': '',
'font_size_medium': '',
'font_size_base': '',
'font_size_small': '',
'font_size_extra_small': '',
'font_weight_primary': 0,
'font_weight_secondary': 0,
'font_line_height_primary': '',
'font_line_height_secondary': ''
};
}
};
</script>

View File

@ -0,0 +1,539 @@
<style lang="scss">
.component-preview {
padding-right: 10px;
&:last-of-type {
padding-bottom: 20px;
}
h4 {
font-size: 20px;
margin: 40px 0 20px;
color: #909399
}
.demo-item {
margin-top: 10px;
margin-right: 40px;
}
.demo-line {
margin: 15px 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n + 1) {
background-color: #d3dce6;
}
.el-avatar:not(:last-child) {
margin-right: 20px;
}
.avatar-demo {
display: flex;
align-items: center;
}
}
</style>
<template>
<div class="component-preview">
<h4>Button</h4>
<el-row class="demo-line">
<el-button>Default</el-button>
<el-button type="primary">Primary</el-button>
<el-button type="success">Success</el-button>
<el-button type="info">Info</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</el-row>
<el-row class="demo-line">
<el-button plain>Plain</el-button>
<el-button type="primary" plain>Primary</el-button>
<el-button type="success" plain>Success</el-button>
<el-button type="info" plain>Info</el-button>
<el-button type="warning" plain>Warning</el-button>
<el-button type="danger" plain>Danger</el-button>
</el-row>
<el-row class="demo-line">
<el-button round>Round</el-button>
<el-button type="primary" round>Primary</el-button>
<el-button type="success" round>Success</el-button>
<el-button type="info" round>Info</el-button>
<el-button type="warning" round>Warning</el-button>
<el-button type="danger" round>Danger</el-button>
</el-row>
<el-row class="demo-line">
<el-button icon="el-icon-search" circle></el-button>
<el-button type="primary" icon="el-icon-edit" circle></el-button>
<el-button type="success" icon="el-icon-check" circle></el-button>
<el-button type="info" icon="el-icon-message" circle></el-button>
<el-button type="warning" icon="el-icon-star-off" circle></el-button>
<el-button type="danger" icon="el-icon-delete" circle></el-button>
</el-row>
<el-row class="demo-line">
<el-button>Default</el-button>
<el-button size="medium">Medium</el-button>
<el-button size="small">Small</el-button>
<el-button size="mini">Mini</el-button>
</el-row>
<h4>Radio</h4>
<el-row class="demo-line">
<el-radio v-model="radio" label="1">Option A</el-radio>
<el-radio v-model="radio" label="2">Option B</el-radio>
</el-row>
<el-row class="demo-line">
<el-radio-group v-model="radio1">
<el-radio-button label="New York"></el-radio-button>
<el-radio-button label="Washington"></el-radio-button>
<el-radio-button label="Los Angeles"></el-radio-button>
<el-radio-button label="Chicago"></el-radio-button>
</el-radio-group>
</el-row>
<el-row class="demo-line">
<el-radio v-model="radio2" label="1" border>Option A</el-radio>
<el-radio v-model="radio2" label="2" border>Option B</el-radio>
</el-row>
<h4>Checkbox</h4>
<el-row class="demo-line">
<el-checkbox v-model="checked">Option</el-checkbox>
</el-row>
<el-row class="demo-line">
<el-checkbox-group v-model="checked1">
<el-checkbox-button v-for="city in ['Shanghai', 'Beijing', 'Guangzhou', 'Shenzhen']" :label="city" :key="city">{{city}}</el-checkbox-button>
</el-checkbox-group>
</el-row>
<el-row class="demo-line">
<el-checkbox v-model="checked2" label="Option1" border></el-checkbox>
</el-row>
<h4>Input</h4>
<el-row style="width: 180px">
<el-input placeholder="Please input" v-model="input"></el-input>
</el-row>
<h4>InputNumber</h4>
<el-row>
<el-input-number v-model="inputNumber" :min="1" :max="10"></el-input-number>
</el-row>
<h4>Select</h4>
<el-row>
<el-select v-model="selectValue" placeholder="Select">
<el-option
v-for="item in selectOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-row>
<h4>Cascader</h4>
<el-row>
<el-cascader :options="cascadeOptions" v-model="cascaderValue"></el-cascader>
</el-row>
<h4>Switch</h4>
<el-row>
<el-switch v-model="switchValue"></el-switch>
<el-switch
style="margin-left: 40px"
v-model="switchValue"
active-text="Pay by month"
inactive-text="Pay by year">
</el-switch>
</el-row>
<h4>Slider</h4>
<el-row style="width: 380px">
<el-slider v-model="slider"></el-slider>
</el-row>
<h4>DatePicker</h4>
<el-row>
<el-date-picker v-model="datePicker" type="date"></el-date-picker>
</el-row>
<h4>Rate</h4>
<el-row>
<el-rate class="demo-line" v-model="rate"></el-rate>
<el-rate
class="demo-line"
v-model="rate"
show-score
text-color="#ff9900"
score-template="{value} points">
</el-rate>
</el-row>
<h4>Transfer</h4>
<el-row>
<el-transfer v-model="transfer" filterable :data="transferData">
<el-button class="transfer-footer" slot="left-footer" size="small">Operation</el-button>
<el-button class="transfer-footer" slot="right-footer" size="small">Operation</el-button>
</el-transfer>
</el-row>
<h4>Table</h4>
<el-row>
<el-table :data="tableData" style="width: 70%">
<el-table-column prop="date" label="Date" width="180"></el-table-column>
<el-table-column prop="name" label="Name" width="180"></el-table-column>
<el-table-column prop="address" label="Address"></el-table-column>
</el-table>
</el-row>
<h4>Tag</h4>
<el-row>
<el-tag class="demo-item" closable>Tag One</el-tag>
<el-tag class="demo-item" closable type="success">Tag Two</el-tag>
<el-tag class="demo-item" closable type="info">Tag Three</el-tag>
<el-tag class="demo-item" closable type="warning">Tag Four</el-tag>
<el-tag class="demo-item" closable type="danger">Tag Five</el-tag>
</el-row>
<h4>Progress</h4>
<el-row style="width: 380px">
<el-progress :percentage="20"></el-progress>
<el-progress :percentage="60" status="exception"></el-progress>
<el-progress :percentage="100" status="success"></el-progress>
</el-row>
<h4>Tree</h4>
<el-row style="width: 380px">
<el-tree :data="treeData" :props="defaultTreeProps" ></el-tree>
</el-row>
<h4>Pagination</h4>
<el-row>
<el-pagination layout="prev, pager, next" :total="1000"></el-pagination>
</el-row>
<h4>Badge</h4>
<el-row>
<el-badge :value="12" class="demo-item">
<el-button size="small">comments</el-button>
</el-badge>
<el-badge :value="3" class="demo-item">
<el-button size="small">replies</el-button>
</el-badge>
<el-badge :value="1" class="demo-item" type="primary">
<el-button size="small">comments</el-button>
</el-badge>
<el-badge :value="2" class="demo-item" type="warning">
<el-button size="small">replies</el-button>
</el-badge>
</el-row>
<h4>Alert</h4>
<el-row style="width: 380px;">
<el-alert class="demo-item" title="success alert" type="success" show-icon></el-alert>
<el-alert class="demo-item" title="info alert" type="info" close-text="Gotcha" show-icon></el-alert>
<el-alert class="demo-item" title="warning alert" type="warning" show-icon></el-alert>
<el-alert
class="demo-item"
title="error alert"
type="error"
description="more text description"
show-icon>
</el-alert>
</el-row>
<h4>Loading</h4>
<el-row>
<el-table :data="tableData" style="width: 90%" v-loading="true">
<el-table-column prop="date" label="Date" width="180"></el-table-column>
<el-table-column prop="name" label="Name" width="180"></el-table-column>
<el-table-column prop="address" label="Address"></el-table-column>
</el-table>
</el-row>
<h4>Message</h4>
<el-row>
<div role="alert" class="demo-item el-message el-message--success el-message-fade-leave-active el-message-fade-leave-to" style="top: 0;left: 0;width: 100px; opacity: 1; position: relative;transform: none;"><i class="el-message__icon el-icon-success"></i><p class="el-message__content">Congrats, this is a success message.</p><!----></div>
<div role="alert" class="demo-item el-message el-message--warning el-message-fade-leave-active el-message-fade-leave-to" style="top: 0;left: 0;width: 100px; opacity: 1; position: relative;transform: none;"><i class="el-message__icon el-icon-warning"></i><p class="el-message__content">Warning, this is a warning message.</p><!----></div>
<div role="alert" class="demo-item el-message el-message--info el-message-fade-leave-active el-message-fade-leave-to" style="top: 0;left: 0;width: 100px; opacity: 1; position: relative;transform: none;"><i class="el-message__icon el-icon-info"></i><p class="el-message__content">This is a message.</p><!----></div>
<div role="alert" class="demo-item el-message el-message--error is-closable el-message-fade-leave-active el-message-fade-leave-to" style="top: 0;left: 0;width: 100px; opacity: 1; position: relative;transform: none;"><i class="el-message__icon el-icon-error"></i><p class="el-message__content">Oops, this is a error message.</p><i class="el-message__closeBtn el-icon-close"></i></div>
</el-row>
<h4>MessageBox</h4>
<el-row>
<div class="el-message-box"><div class="el-message-box__header"><div class="el-message-box__title"><!----><span>Warning</span></div><button type="button" aria-label="Close" class="el-message-box__headerbtn"><i class="el-message-box__close el-icon-close"></i></button></div><div class="el-message-box__content"><div class="el-message-box__status el-icon-warning"></div><div class="el-message-box__message"><p>This will permanently delete the file. Continue?</p></div><div class="el-message-box__input" style="display: none;"><div class="el-input"><!----><input type="text" autocomplete="off" placeholder="" class="el-input__inner"><!----><!----><!----></div><div class="el-message-box__errormsg" style="visibility: hidden;"></div></div></div><div class="el-message-box__btns"><button type="button" class="el-button el-button--default el-button--small"><!----><!----><span>
Cancel
</span></button><button type="button" class="el-button el-button--default el-button--small el-button--primary "><!----><!----><span>
OK
</span></button></div></div>
</el-row>
<h4>Notification</h4>
<el-row>
<div role="alert" class="el-notification right" style="position: relative; left: 0;"><!----><div class="el-notification__group"><span class="el-notification__title">Notification</span><div class="el-notification__content"><div>This is a message </div></div><div class="el-notification__closeBtn el-icon-close"></div></div></div>
</el-row>
<h4>Menu</h4>
<el-row>
<el-menu :default-active="menu" class="el-menu-demo" mode="horizontal">
<el-menu-item index="1">Processing Center</el-menu-item>
<el-submenu index="2">
<template slot="title">Workspace</template>
<el-menu-item index="2-1">item one</el-menu-item>
<el-menu-item index="2-2">item two</el-menu-item>
<el-menu-item index="2-3">item three</el-menu-item>
<el-submenu index="2-4">
<template slot="title">item four</template>
<el-menu-item index="2-4-1">item one</el-menu-item>
<el-menu-item index="2-4-2">item two</el-menu-item>
<el-menu-item index="2-4-3">item three</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="3" disabled>Info</el-menu-item>
<el-menu-item index="4">
<a href="https://www.ele.me" target="_blank">Orders</a>
</el-menu-item>
</el-menu>
<el-menu
default-active="2"
class="demo-line"
>
<el-submenu index="1">
<template slot="title">
<i class="el-icon-location"></i>
<span>Navigator One</span>
</template>
<el-menu-item-group title="Group One">
<el-menu-item index="1-1">item one</el-menu-item>
<el-menu-item index="1-2">item one</el-menu-item>
</el-menu-item-group>
<el-menu-item-group title="Group Two">
<el-menu-item index="1-3">item three</el-menu-item>
</el-menu-item-group>
<el-submenu index="1-4">
<template slot="title">item four</template>
<el-menu-item index="1-4-1">item one</el-menu-item>
</el-submenu>
</el-submenu>
<el-menu-item index="2">
<i class="el-icon-menu"></i>
<span>Navigator Two</span>
</el-menu-item>
<el-menu-item index="3" disabled>
<i class="el-icon-document"></i>
<span>Navigator Three</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-setting"></i>
<span>Navigator Four</span>
</el-menu-item>
</el-menu>
</el-row>
<h4>Tabs</h4>
<el-row>
<el-tabs v-model="tab" class="demo-item">
<el-tab-pane label="User" name="first">User</el-tab-pane>
<el-tab-pane label="Config" name="second">Config</el-tab-pane>
<el-tab-pane label="Role" name="third">Role</el-tab-pane>
<el-tab-pane label="Task" name="fourth">Task</el-tab-pane>
</el-tabs>
<el-tabs type="card" class="demo-item">
<el-tab-pane label="User">User</el-tab-pane>
<el-tab-pane label="Config">Config</el-tab-pane>
<el-tab-pane label="Role">Role</el-tab-pane>
<el-tab-pane label="Task">Task</el-tab-pane>
</el-tabs>
</el-row>
<h4>Dialog</h4>
<el-row>
<div role="dialog" aria-modal="true" aria-label="Tips" class="el-dialog" style="margin: 0"><div class="el-dialog__header"><span class="el-dialog__title">Tips</span><button type="button" aria-label="Close" class="el-dialog__headerbtn"><i class="el-dialog__close el-icon el-icon-close"></i></button></div><div class="el-dialog__body"><span>This is a message</span> </div><div class="el-dialog__footer"><span class="dialog-footer"><button type="button" class="el-button el-button--default"><!----><!----><span>Cancel</span></button> <button type="button" class="el-button el-button--primary"><!----><!----><span>Confirm</span></button></span></div></div>
</el-row>
<h4>Tooltip</h4>
<el-row>
<div role="tooltip" x-placement="top" class="el-tooltip__popper is-dark" style="position: relative; width: 40px;text-align: center;">Dark<div x-arrow="" class="popper__arrow"></div>
</div>
<div role="tooltip" x-placement="top" class="el-tooltip__popper is-light" style="margin-top: 10px;position: relative; width: 40px;text-align: center;">Light<div x-arrow="" class="popper__arrow"></div>
</div>
</el-row>
<h4>Popover</h4>
<el-row>
<div role="tooltip" x-placement="top" id="el-popover-2936" aria-hidden="true" class="el-popover el-popper el-popover--plain" tabindex="0" style="width: 200px; position: relative; "><div class="el-popover__title">Title</div>this is content, this is content, this is content<div x-arrow="" class="popper__arrow"></div></div>
</el-row>
<h4>Card</h4>
<el-row>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>Card name</span>
</div>
</el-card>
</el-row>
<h4>Carousel</h4>
<el-row>
<el-carousel height="150px">
<el-carousel-item v-for="item in 4" :key="item">
<h3>{{ item }}</h3>
</el-carousel-item>
</el-carousel>
</el-row>
<h4>Collapse</h4>
<el-row>
<el-collapse v-model="collapse">
<el-collapse-item title="Consistent" name="1">
<div>Consistent with real life: in line with the process and logic of real life, and comply with languages and habits that the users are used to;</div>
</el-collapse-item>
<el-collapse-item title="Feedback" name="2">
<div>Operation feedback: enable the users to clearly perceive their operations by style updates and interactive effects;</div>
</el-collapse-item>
</el-collapse>
</el-row>
<h4>Avatar</h4>
<el-row class="demo-line avatar-demo">
<el-avatar icon="el-icon-user-solid"/>
<el-avatar> avatar </el-avatar>
<el-avatar shape="square" fit="contain" :src="avatarData.url"></el-avatar>
<el-avatar size="large"> large </el-avatar>
<el-avatar size="medium"> medium </el-avatar>
<el-avatar size="small"> small </el-avatar>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
radio: '1',
radio1: 'Washington',
radio2: '1',
checked: true,
checked1: ['Shanghai'],
checked2: true,
input: 'Element',
inputNumber: 1,
selectOptions: [
{
value: 'Option1',
label: 'Option1'
},
{
value: 'Option2',
label: 'Option2'
},
{
value: 'Option3',
label: 'Option3'
},
{
value: 'Option4',
label: 'Option4'
},
{
value: 'Option5',
label: 'Option5'
}
],
selectValue: '',
cascadeOptions: [
{
value: 'guide',
label: 'Guide',
children: [
{
value: 'disciplines',
label: 'Disciplines',
children: [
{
value: 'consistency',
label: 'Consistency'
},
{
value: 'feedback',
label: 'Feedback'
}
]
}
]
},
{
value: 'resource',
label: 'Resource',
children: [
{
value: 'axure',
label: 'Axure Components'
},
{
value: 'sketch',
label: 'Sketch Templates'
},
{
value: 'docs',
label: 'Design Documentation'
}
]
}
],
cascaderValue: [],
switchValue: true,
slider: 28,
datePicker: '',
rate: null,
transferData: (() => {
const data = [];
for (let i = 1; i <= 15; i++) {
data.push({
key: i,
label: `Option ${i}`,
disabled: i % 4 === 0
});
}
return data;
})(),
transfer: [1, 4],
tableData: [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles'
}
],
menu: '1',
tab: 'first',
collapse: ['1'],
treeData: [{
label: 'Level one 1',
children: [{
label: 'Level two 1-1',
children: [{
label: 'Level three 1-1-1'
}]
}]
}, {
label: 'Level one 2',
children: [{
label: 'Level two 2-1',
children: [{
label: 'Level three 2-1-1'
}]
}, {
label: 'Level two 2-2',
children: [{
label: 'Level three 2-2-1'
}]
}]
}, {
label: 'Level one 3',
children: [{
label: 'Level two 3-1',
children: [{
label: 'Level three 3-1-1'
}]
}, {
label: 'Level two 3-2',
children: [{
label: 'Level three 3-2-1'
}]
}]
}],
defaultTreeProps: {
children: 'children',
label: 'label'
},
avatarData: {
url: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg'
}
};
}
};
</script>

View File

@ -0,0 +1,16 @@
export const DEFAULT_THEME_CONFIG = {
global: {},
local: {}
};
export const ELEMENT_THEME_USER_CONFIG = 'ELEMENT_THEME_USER_CONFIG';
export const ELEMENT_THEME_PREVIEW_CONFIG = 'ELEMENT_THEME_PREVIEW_CONFIG';
export const ACTION_DOWNLOAD_THEME = 'ELEMENT_THEME_ACTION_DOWNLOAD';
export const ACTION_APPLY_THEME = 'ELEMENT_THEME_ACTION_ALLPY_CSS';
export const ACTION_COMPONECT_SELECT = 'ELEMENT_THEME_ACTION_COMPONECT_SELECT';
export const ACTION_USER_CONFIG_UPDATE = 'ELEMENT_THEME_USER_CONFIG_UPDATE';

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,24 @@
import Element from 'main/index.js';
import { post, get } from './ajax';
const { version } = Element;
const hostList = {
local: 'http://localhost:3008/',
alpha: 'https://element-api.ar.elenet.me/element/theme/',
production: 'https://element-api.ele.me/element/theme/'
};
const host = hostList[process.env.FAAS_ENV] || hostList.production;
export const getVars = () => {
return get(`${host}getVariable?version=${version}`);
};
export const getTestEle = () => {
return get(`${hostList.alpha}getVariable`);
};
export const updateVars = (data, cb) => {
return post(`${host}updateVariable?version=${version}`, data, cb);
};

View File

@ -0,0 +1,62 @@
<script>
const ORIGINAL_THEME = '#409EFF';
import { get as ajaxGet } from './ajax.js';
import { updateDomHeadStyle } from '../utils.js';
export default {
data() {
return {
docs: '', // content of docs css
theme: ORIGINAL_THEME,
asyncCb: true
};
},
methods: {
updateDocStyle(e, cb) {
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);
this.asyncCb && cb();
};
};
const docsHandler = getHandler('docs', 'docs-style');
if (!this.docs) {
const links = [].filter.call(document.querySelectorAll('link'), link => {
return /docs\..+\.css/.test(link.href || '');
});
if (links[0]) {
this.getCSSString(links[0].href, docsHandler, 'docs');
} else {
this.asyncCb = false;
}
} 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;
!this.asyncCb && cb();
},
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,106 @@
<script>
import bus from '../../../bus.js';
import Loading from './loading';
import DocStyle from './docStyle';
import { updateVars } from './api.js';
import { updateDomHeadStyle } from '../utils.js';
import {
ACTION_APPLY_THEME,
ACTION_DOWNLOAD_THEME,
ACTION_USER_CONFIG_UPDATE
} from '../constant.js';
import {
loadUserThemeFromLocal,
loadPreviewFromLocal
} from '../localstorage.js';
import { getActionDisplayName } from '../../theme-configurator/utils/utils';
export default {
mixins: [Loading, DocStyle],
mounted() {
this.checkLocalThemeConfig();
bus.$on(ACTION_APPLY_THEME, val => {
this.userConfig = val;
this.onAction();
});
bus.$on(ACTION_DOWNLOAD_THEME, (themeConfig, themeName) => {
this.onDownload(themeConfig, themeName);
});
},
data() {
return {
userConfig: {},
lastApply: 0
};
},
methods: {
applyStyle(res, time) {
if (time < this.lastApply) return;
this.updateDocs(() => {
updateDomHeadStyle('chalk-style', res);
});
this.lastApply = time;
},
onDownload(themeConfig, themeName) {
this.triggertProgressBar(true);
updateVars(
Object.assign({}, themeConfig, { download: true }),
xhr => {
xhr.responseType = 'blob';
}
).then()
.catch((err) => {
this.onError(err);
})
.then(() => {
this.triggertProgressBar(false);
});
ga('send', 'event', 'ThemeConfigurator', 'Download', themeName);
},
onAction() {
this.triggertProgressBar(true);
const time = +new Date();
updateVars(this.userConfig)
.then(res => {
this.applyStyle(res, time);
})
.catch(err => {
this.onError(err);
})
.then(() => {
this.triggertProgressBar(false);
});
},
onError(err) {
let message;
try {
message = JSON.parse(err).message;
} catch (e) {
message = err;
}
this.$message.error(message);
},
triggertProgressBar(isLoading) {
bus.$emit('user-theme-config-loading', isLoading);
},
updateDocs(cb) {
window.userThemeConfig = JSON.parse(JSON.stringify(this.userConfig));
bus.$emit(ACTION_USER_CONFIG_UPDATE, this.userConfig);
this.updateDocStyle(this.userConfig, cb);
},
checkLocalThemeConfig() {
// load user local theme
const previewConfig = loadPreviewFromLocal();
if (previewConfig.type === 'user') {
const userConfig = loadUserThemeFromLocal();
this.$message(getActionDisplayName('load-local-theme-config'));
const config = userConfig.filter(theme => (theme.name === previewConfig.name));
if (config && config[0]) {
this.userConfig = JSON.parse(config[0].theme);
this.onAction();
}
}
}
}
};
</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,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,38 @@
import {
ELEMENT_THEME_PREVIEW_CONFIG,
ELEMENT_THEME_USER_CONFIG
} from './constant';
export const saveToLocal = (key, value) => {
localStorage.setItem(key, JSON.stringify(value));
};
export const loadFromLocal = (key) => {
try {
return JSON.parse(localStorage.getItem(key));
} catch (e) {
console.error(e);
return null;
}
};
export const savePreviewToLocal = (value) => {
saveToLocal(ELEMENT_THEME_PREVIEW_CONFIG, value);
};
export const loadPreviewFromLocal = () => {
return loadFromLocal(ELEMENT_THEME_PREVIEW_CONFIG) || {};
};
export const removePreviewFromLocal = () => {
return localStorage.removeItem(ELEMENT_THEME_PREVIEW_CONFIG);
};
export const saveUserThemeToLocal = (value) => {
saveToLocal(ELEMENT_THEME_USER_CONFIG, value);
};
export const loadUserThemeFromLocal = () => {
return loadFromLocal(ELEMENT_THEME_USER_CONFIG);
};

View File

@ -0,0 +1,406 @@
<style lang="scss">
.theme-card-item {
user-select: none;
border-radius: 4px;
overflow: hidden;
background: #fff;
height: 90%;
margin: 25px 0;
box-shadow: 0 0 1px 0 #666;
&.is-hidden {
opacity: 0;
height: 0;
}
.upload {
cursor: pointer;
background: #f5f7fa;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items:center;
.upload-action {
width: 40%;
margin: 0 auto;
text-align: center;
color: #606266;
img {
display: block;
margin: 0 auto;
}
span {
display: block;
font-size: 14px;
margin-top: 8px;
}
}
}
.preview {
position: relative;
height: 70%;
width: 100%;
.line {
height: 50%;
}
.line-2 {
width: 50%;
height: 100%;
display: inline-block;
}
.line-4 {
width: 25%;
height: 100%;
display: inline-block;
}
.action {
transition: all .3s;
position: absolute;
opacity: 0;
top: 0;
left: 0;
right: 0;
bottom: 0;
.action-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #000;
opacity: 0.4;
}
.action-block {
position: absolute;
width: 50%;
height: 50%;
left: 25%;
top: 25%;
}
.action-item {
cursor: pointer;
display: inline-block;
height: 100%;
width: 30%;
color: #eee;
&:hover {
color: #fff;
.circle {
border-color: #fff;
}
}
.icon {
height: 50%;
font-size: 22px;
text-align: center;
display: flex;
justify-content:center;
align-items:center;
img {
width: 130%;
}
}
.name {
font-size: 12px;
height: 50%;
text-align: center;
display: flex;
justify-content:center;
align-items:center;
margin-top: 4px;
}
}
.action-item-right {
margin-left: 40%;
}
}
}
.info {
height: 30%;
line-height: 16px;
display: flex;
align-items: center;
.info-center {
width: 100%;
}
.title {
font-weight: bold;
font-size: 16px;
color: #303133;
padding: 0 12px;
justify-content: space-between;
}
.right {
float: right;
font-weight: normal;
font-size: 14px;
color: #909399;
}
.more {
font-size: 16px;
cursor: pointer;
}
.description {
padding: 0 12px;
font-size: 14px;
color: #606266;
margin-top: 10px;
}
}
&.is-upload {
box-shadow: none;
border: 1px dashed #DCDFE6;
}
&.is-upload:hover {
box-shadow: none;
}
&:hover {
box-shadow: 0 0 10px 0 #999;
.action {
opacity: 1;
}
}
}
</style>
<template>
<section class="theme-card-item" :class="{'is-hidden': !config || !config.name, 'is-upload': isUpload}">
<template v-if="isUpload">
<div class="upload" @click="uploadClick">
<div class="upload-action">
<img src="../../assets/images/icon-upload.svg"/>
<span>{{getActionDisplayName('upload-theme')}}</span>
</div>
</div>
<input
class="el-upload__input"
type="file"
ref="input"
@change="uploadAction"
accept="application/json"
/>
</template>
<template v-else>
<div class="preview">
<div class="line">
<span class="line-2" :style="{background: mainColor}"></span>
<span class="line-2" :style="{background: textPrimaryColor}"></span>
</div>
<div class="line">
<span class="line-4" :style="{background: mainColor50}"></span>
<span class="line-4" :style="{background: mainColor80}"></span>
<span class="line-4" :style="{background: borderBaseColor}"></span>
<span class="line-4" :style="{background: textSecondaryColor}"></span>
</div>
<div class="action">
<div class="action-mask"></div>
<div class="action-block">
<div
class="action-item"
:class="index && 'action-item-right'"
v-for="(item, index) in actionArray"
:key="index"
@click="iconClick(item.action)"
>
<div class="icon">
<img :src="item.icon"/>
<span class="circle"></span>
</div>
<div class="name">
<span>{{item.name}}</span>
</div>
</div>
</div>
</div>
</div>
<div class="info">
<div class="info-center">
<div class="title">
<span>{{config.name}}</span>
<span class="right" v-if="isOfficial">by {{config.author}}</span>
<span class="right more" v-else>
<el-dropdown @command="actionClick">
<i class="el-icon-more"></i>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="rename">{{getActionDisplayName('rename-theme')}}</el-dropdown-item>
<el-dropdown-item command="copy">{{getActionDisplayName('copy-theme')}}</el-dropdown-item>
<el-dropdown-item
command="delete"
style="color: #F56C6C;"
>
{{getActionDisplayName('delete-theme')}}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</span>
</div>
<div class="description" v-if="isOfficial">{{getActionDisplayName(getDescriptionKey(config.name))}} </div>
<div class="description" v-else>{{getActionDisplayName('last-modified')}} {{formatDate(config.update)}}</div>
</div>
</div>
</template>
</section>
</template>
<script>
import bus from '../../bus';
import {
DEFAULT_THEME_CONFIG,
ACTION_DOWNLOAD_THEME
} from './constant.js';
import { savePreviewToLocal } from './localstorage';
import { tintColor } from '../../color.js';
import dateUtil from 'element-ui/src/utils/date';
import { getActionDisplayName } from '../theme-configurator/utils/utils';
export default {
props: {
config: Object,
type: String,
base: {
type: String,
default: ''
},
from: String
},
data() {
return {
deleteVisible: false
};
},
methods: {
getActionDisplayName(key) {
return getActionDisplayName(key);
},
getDescriptionKey(name) {
return name ? `description-${name.toLowerCase()}` : '';
},
formatDate(timestamp) {
if (!timestamp) return '';
return dateUtil.format(new Date(timestamp), 'yyyy-MM-dd HH:mm');
},
uploadClick() {
this.$refs.input.value = null;
this.$refs.input.click();
},
uploadAction(ev) {
const files = ev.target.files;
if (!files) return;
var reader = new FileReader();
reader.onload = (e) => {
try {
const jsonString = e.target.result;
const jsonObject = JSON.parse(jsonString);
if (!jsonObject.global || !jsonObject.local) {
return this.$message.error('JSON format error');
}
this.$emit('action', 'upload', jsonString);
} catch (e) {
this.$message.error('Upload error');
console.error(e);
}
};
reader.readAsText(files[0]);
},
actionClick(e) {
this.$emit('action', e, this.config);
},
iconClick(e) {
switch (e) {
case 'preview':
case 'edit':
if (this.from) {
this.$emit('action', e, this.config);
return;
}
const { name, theme } = this.config;
savePreviewToLocal({
type: this.type,
name,
theme
});
this.$router.push({
name: `theme-preview-${this.$route.meta.lang}`,
params: {
refer: 'theme'
}
});
this.$nextTick(() => {
window.scrollTo(0, 0);
});
break;
case 'download':
bus.$emit(ACTION_DOWNLOAD_THEME, this.theme, this.config.name);
break;
default:
this.$emit('action', e, this.config);
return;
}
},
deleteUserTheme() {
this.deleteVisible = false;
this.$emit('action', 'delete', this.config);
}
},
computed: {
isUpload() {
return this.type === 'upload';
},
theme() {
if (this.config.theme) {
return JSON.parse(this.config.theme);
}
return DEFAULT_THEME_CONFIG;
},
mainColor() {
return this.theme.global['$--color-primary'] || '#1989FA';
},
mainColor50() {
return tintColor(this.mainColor, 0.5);
},
mainColor80() {
return tintColor(this.mainColor, 0.8);
},
textPrimaryColor() {
return this.theme.global['$--color-text-primary'] || '#303133';
},
borderBaseColor() {
return this.theme.global['$--border-color-base'] || '#DCDFE6';
},
textSecondaryColor() {
return this.theme.global['$--color-text-secondary'] || '#909399';
},
isOfficial() {
return this.type === 'official';
},
actionArray() {
if (this.isOfficial) {
return [
{
icon: require('../../assets/images/icon-check.png'),
name: getActionDisplayName('theme-check'),
action: 'preview'
},
{
icon: require('../../assets/images/icon-copy.png'),
name: getActionDisplayName('theme-copy'),
action: 'copy'
}
];
}
return [
{
icon: require('../../assets/images/icon-edit.png'),
name: getActionDisplayName('theme-edit'),
action: 'edit'
},
{
icon: require('../../assets/images/icon-download.png'),
name: getActionDisplayName('download-theme'),
action: 'download'
}
];
}
}
};
</script>

View File

@ -0,0 +1,15 @@
export const themeList = [
{
name: 'Element',
author: 'Element',
theme: '{"global":{"$--color-primary":"#409EFF"},"local":{}}'
}
];
export const eleThemeList = [
{
name: 'Kiwi',
author: 'Element',
theme: '{"global":{"$--color-primary":"#1989FA","$--color-success":"#5CB87A","$--color-warning":"#E6A23C","$--color-danger":"#F56C6C","$--color-info":"#8896B3","$--font-size-small":"13px","$--font-size-base":"14px","$--font-size-medium":"16px","$--font-size-large":"22px","$--font-size-extra-large":"28px","$--font-line-height-secondary":"20px"},"local":{"$--button-primary-background-color":"$--color-primary","$--switch-font-size":"14px","$--datepicker-active-color":"$--color-primary","$--tooltip-border-color":"$--border-color-base","$--tooltip-color":"#FFFFFF","$--tooltip-padding":"10px","$--collapse-header-font-size":"14px","$--collapse-content-font-size":"14px","$--collapse-content-font-color":"$--color-text-regular","$--radio-input-background-color":"#FFFFFF","$--radio-icon-color":"$--color-warning","$--radio-button-checked-background-color":"$--color-primary","$--input-border-radius":"$--border-radius-base","$--select-input-focus-border-color":"$--color-primary","$--select-font-size":"14px","$--select-option-selected-font-color":"$--color-primary","$--select-input-font-size":"14px","$--select-option-height":"34px","$--slider-main-background-color":"$--color-primary","$--tag-font-color":"$--color-primary","$--tag-default-hover-background-color":"$--color-primary","$--message-warning-font-color":"$--color-warning","$--alert-title-font-size":"14px","$--alert-icon-size":"14px","$--alert-icon-large-size":"22px","$--alert-close-customed-font-size":"12px","$--notification-title-font-size":"16px","$--notification-content-font-size":"14px","$--menu-item-font-color":"$--color-primary"}}'
}
];

View File

@ -0,0 +1,24 @@
export const isEmptyObject = (obj) => (JSON.stringify(obj) === '{}');
export const getThemeConfigObject = (config) => {
try {
const conf = JSON.parse(config);
const { global, local } = conf;
if (!isEmptyObject(global) || !isEmptyObject(local)) {
return conf;
}
return false;
} catch (e) {
return false;
}
};
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{[^}]+}/, '');
};