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,188 @@
<style>
.page-changelog {
padding-bottom: 100px;
.fr {
float: right;
padding: 0;
&.el-button {
transform: translateY(-3px);
}
a {
display: block;
padding: 10px 15px;
color: #333;
}
&:hover a {
color: #409EFF;
}
}
.heading {
font-size: 24px;
margin-bottom: 60px;
color: #333;
}
.timeline {
padding: 0;
padding-bottom: 10px;
position: relative;
color: #5e6d82;
> li {
position: relative;
padding-bottom: 15px;
list-style: none;
line-height: 1.8;
border: 1px solid #ddd;
border-radius: 4px;
&:not(:last-child) {
margin-bottom: 50px;
}
}
ul {
padding: 30px 30px 15px;
ul {
padding: 0;
padding-top: 5px;
padding-left: 27px;
li {
padding-left: 0;
color: #555;
word-break: normal;
}
li::before {
content: '';
circle: 4px #fff;
border: solid 1px #333;
margin-right: -12px;
display: inline-block;
vertical-align: middle;
}
}
}
li li {
font-size: 16px;
list-style: none;
padding-left: 20px;
padding-bottom: 5px;
color: #333;
word-break: break-all;
&:before {
content: '';
circle: 6px #333;
transform: translateX(-20px);
display: inline-block;
vertical-align: middle;
}
}
i {
padding: 0 20px;
display: inline-block;
}
h3 {
margin:0;
padding: 15px 30px;
border-bottom: 1px solid #ddd;
font-size: 20px;
color: #333;
font-weight: bold;
a {
opacity: 1;
font-size: 20px;
float: none;
margin-left: 0;
color: #333;
}
}
h4 {
margin: 0;
margin-bottom: -10px;
font-size: 18px;
padding-left: 54px;
padding-top: 30px;
font-weight: bold;
}
p {
margin: 0;
}
em {
position: absolute;
right: 30px;
font-style: normal;
top: 23px;
font-size: 16px;
color: #666;
}
}
}
</style>
<template>
<div class="page-changelog">
<div class="heading">
<el-button class="fr">
<a href="https://github.com/ElemeFE/element/releases" target="_blank">GitHub Releases</a>
</el-button>
<%= 1 >
</div>
<ul class="timeline" ref="timeline">
</ul>
<change-log ref="changeLog"></change-log>
</div>
</template>
<script>
import ChangeLog from '../../../CHANGELOG.<%= 2 >.md';
export default {
components: {
ChangeLog
},
data() {
return {
count: 3
};
},
mounted() {
const changeLog = this.$refs.changeLog;
const changeLogNodes = changeLog.$el.children;
let a = changeLogNodes[1].querySelector('a');
a && a.remove();
let release = changeLogNodes[1].textContent.trim();
let fragments = `<li><h3><a href="https://github.com/ElemeFE/element/releases/tag/v${release}" target="_blank">${release}</a></h3>`;
for (let len = changeLogNodes.length, i = 2; i < len; i++) {
let node = changeLogNodes[i];
a = changeLogNodes[i].querySelector('a');
a && a.getAttribute('class') === 'header-anchor' && a.remove();
if (node.tagName !== 'H3') {
fragments += changeLogNodes[i].outerHTML;
} else {
release = changeLogNodes[i].textContent.trim();
fragments += `</li><li><h3><a href="https://github.com/ElemeFE/element/releases/tag/v${release}" target="_blank">${release}</a></h3>`;
}
}
fragments = fragments.replace(/#(\d+)/g, '<a href="https://github.com/ElemeFE/element/issues/$1" target="_blank">#$1</a>');
fragments = fragments.replace(/@([\w-]+)/g, '<a href="https://github.com/$1" target="_blank">@$1</a>');
this.$refs.timeline.innerHTML = `${fragments}</li>`;
changeLog.$el.remove();
}
};
</script>

View File

@@ -0,0 +1,255 @@
<style>
.page-component__scroll {
height: calc(100% - 80px);
margin-top: 80px;
> .el-scrollbar__wrap {
overflow-x: auto;
}
}
.page-component {
box-sizing: border-box;
height: 100%;
&.page-container {
padding: 0;
}
.page-component__nav {
width: 240px;
position: fixed;
top: 0;
bottom: 0;
margin-top: 80px;
transition: padding-top .3s;
> .el-scrollbar__wrap {
height: 100%;
overflow-x: auto;
}
&.is-extended {
padding-top: 0;
}
}
.side-nav {
height: 100%;
padding-top: 50px;
padding-bottom: 50px;
padding-right: 0;
& > ul {
padding-bottom: 50px;
}
}
.page-component__content {
padding-left: 270px;
padding-bottom: 100px;
box-sizing: border-box;
}
.content {
padding-top: 50px;
> {
h3 {
margin: 55px 0 20px;
}
table {
border-collapse: collapse;
width: 100%;
background-color: #fff;
font-size: 14px;
margin-bottom: 45px;
line-height: 1.5em;
strong {
font-weight: normal;
}
td, th {
border-bottom: 1px solid #dcdfe6;
padding: 15px;
max-width: 250px;
}
th {
text-align: left;
white-space: nowrap;
color: #909399;
font-weight: normal;
}
td {
color: #606266;
}
th:first-child, td:first-child {
padding-left: 10px;
}
}
ul:not(.timeline) {
margin: 10px 0;
padding: 0 0 0 20px;
font-size: 14px;
color: #5e6d82;
line-height: 2em;
}
}
}
}
@media (max-width: 768px) {
.page-component {
.page-component__nav {
width: 100%;
position: static;
margin-top: 0;
}
.side-nav {
padding-top: 0;
padding-left: 50px;
}
.page-component__content {
padding-left: 10px;
padding-right: 10px;
}
.content {
padding-top: 0;
}
.content > table {
overflow: auto;
display: block;
}
}
}
</style>
<template>
<el-scrollbar class="page-component__scroll" ref="componentScrollBar">
<div class="page-container page-component">
<el-scrollbar class="page-component__nav">
<side-nav :data="navsData[lang]" :base="`/${ lang }/component`"></side-nav>
</el-scrollbar>
<div class="page-component__content">
<router-view class="content"></router-view>
<footer-nav></footer-nav>
</div>
<el-backtop
v-if="showBackToTop"
target=".page-component__scroll .el-scrollbar__wrap"
:right="100"
:bottom="150"
></el-backtop>
</div>
</el-scrollbar>
</template>
<script>
import bus from '../../bus';
import navsData from '../../nav.config.json';
import throttle from 'throttle-debounce/throttle';
export default {
data() {
return {
lang: this.$route.meta.lang,
navsData,
scrollTop: 0,
showHeader: true,
componentScrollBar: null,
componentScrollBoxElement: null
};
},
watch: {
'$route.path'() {
//
this.componentScrollBox.scrollTop = 0;
this.$nextTick(() => {
this.componentScrollBar.update();
});
}
},
methods: {
renderAnchorHref() {
if (/changelog/g.test(location.href)) return;
const anchors = document.querySelectorAll('h2 a,h3 a,h4 a,h5 a');
const basePath = location.href.split('#').splice(0, 2).join('#');
[].slice.call(anchors).forEach(a => {
const href = a.getAttribute('href');
a.href = basePath + href;
});
},
goAnchor() {
if (location.href.match(/#/g).length > 1) {
const anchor = location.href.match(/#[^#]+$/g);
if (!anchor) return;
const elm = document.querySelector(anchor[0]);
if (!elm) return;
setTimeout(_ => {
this.componentScrollBox.scrollTop = elm.offsetTop;
}, 50);
}
},
handleScroll() {
const scrollTop = this.componentScrollBox.scrollTop;
if (this.showHeader !== this.scrollTop > scrollTop) {
this.showHeader = this.scrollTop > scrollTop;
}
if (scrollTop === 0) {
this.showHeader = true;
}
if (!this.navFaded) {
bus.$emit('fadeNav');
}
this.scrollTop = scrollTop;
}
},
computed: {
showBackToTop() {
return !this.$route.path.match(/backtop/);
}
},
created() {
bus.$on('navFade', val => {
this.navFaded = val;
});
},
mounted() {
this.componentScrollBar = this.$refs.componentScrollBar;
this.componentScrollBox = this.componentScrollBar.$el.querySelector('.el-scrollbar__wrap');
this.throttledScrollHandler = throttle(300, this.handleScroll);
this.componentScrollBox.addEventListener('scroll', this.throttledScrollHandler);
this.renderAnchorHref();
this.goAnchor();
document.body.classList.add('is-component');
},
destroyed() {
document.body.classList.remove('is-component');
},
beforeDestroy() {
this.componentScrollBox.removeEventListener('scroll', this.throttledScrollHandler);
},
beforeRouteUpdate(to, from, next) {
next();
setTimeout(() => {
const toPath = to.path;
const fromPath = from.path;
if (toPath === fromPath && to.hash) {
this.goAnchor();
}
if (toPath !== fromPath) {
document.documentElement.scrollTop = document.body.scrollTop = 0;
this.renderAnchorHref();
}
}, 100);
}
};
</script>

View File

@@ -0,0 +1,82 @@
<style scoped>
.cards {
margin: 30px 0 70px;
}
.card {
background: #fbfcfd;
height: 204px;
text-align: center;
img {
margin: 40px auto 25px;
width: 80px;
height: 80px;
}
h4 {
font-size: 18px;
color: #1f2d3d;
font-weight: normal;
margin: 0;
}
span {
font-size: 14px;
color: #99a9bf;
}
}
</style>
<template>
<div>
<h2><%= 1 ></h2>
<el-row :gutter="14" class="cards">
<el-col :xs="12" :sm="6">
<div class="card">
<img src="~examples/assets/images/consistency.png" alt="Consistency">
<h4><%= 2 ></h4>
<span><%= 3 ></span>
</div>
</el-col>
<el-col :xs="12" :sm="6">
<div class="card">
<img src="~examples/assets/images/feedback.png" alt="Feedback">
<h4><%= 4 ></h4>
<span><%= 5 ></span>
</div>
</el-col>
<el-col :xs="12" :sm="6">
<div class="card">
<img src="~examples/assets/images/efficiency.png" alt="Efficiency">
<h4><%= 6 ></h4>
<span><%= 7 ></span>
</div>
</el-col>
<el-col :xs="12" :sm="6">
<div class="card">
<img src="~examples/assets/images/controllability.png" alt="Controllability">
<h4><%= 8 ></h4>
<span><%= 9 ></span>
</div>
</el-col>
</el-row>
<h3><%= 10 ></h3>
<ul>
<li><strong><%= 11 ></strong><%= 12 ></li>
<li><strong><%= 13 ></strong><%= 14 ></li>
</ul>
<h3><%= 15 ></h3>
<ul>
<li><strong><%= 16 ></strong><%= 17 ></li>
<li><strong><%= 18 ></strong><%= 19 ></li>
</ul>
<h3><%= 20 ></h3>
<ul>
<li><strong><%= 21 ></strong><%= 22 ></li>
<li><strong><%= 23 ></strong><%= 24 ></li>
<li><strong><%= 25 ></strong><%= 26 ></li>
</ul>
<h3><%= 27 ></h3>
<ul>
<li><strong><%= 28 ></strong><%= 29 ></li>
<li><strong><%= 30 ></strong><%= 31 ></li>
</ul>
</div>
</template>

View File

@@ -0,0 +1,91 @@
<style>
.page-guide {
padding: 55px 30px 95px;
box-sizing: border-box;
.content {
padding-left: 25px;
margin-left: -1px;
h2 {
margin-bottom: 10px;
}
h3 {
font-size: 22px;
font-weight: normal;
margin: 0 0 30px;
color: #1f2d3d;
}
p {
line-height: 1.6;
font-size: 14px;
color: #5e6d82;
}
ul {
margin-bottom: 50px;
padding-left: 0;
}
li {
font-size: 14px;
margin-bottom: 10px;
color: #99a9bf;
list-style: none;
&:before {
content: '';
display: inline-block;
width: 4px;
height: 4px;
border-radius: 50%;
vertical-align: middle;
background-color: #5e6d82;
margin-right: 5px;
}
strong {
color: #5e6d82;
font-weight: 400;
}
}
}
}
@media (max-width: 768px) {
.page-guide {
.content {
padding-left: 0;
}
}
}
</style>
<template>
<div class="page-container page-guide">
<el-row>
<el-col :xs="24" :sm="5">
<side-nav :data="navsData" :base="`/${ lang }/guide`"></side-nav>
</el-col>
<el-col :xs="24" :sm="19">
<router-view class="content"></router-view>
</el-col>
</el-row>
</div>
</template>
<script>
export default {
data() {
return {
lang: this.$route.meta.lang,
navsData: [
{
path: '/design',
name: '<%= 1 >'
},
{
path: '/nav',
name: '<%= 2 >'
}
]
};
}
};
</script>

View File

@@ -0,0 +1,388 @@
<style scoped>
.banner {
text-align: center;
}
.banner-desc {
padding-top: 50px;
h1 {
font-size: <%= titleSize >px;
margin: 0;
line-height: 48px;
color: #555;
}
p {
font-size: <%= paraSize >px;
line-height: 28px;
color: #888;
margin: 10px 0 5px;
}
}
.sponsors {
display: flex;
justify-content: center;
}
.sponsor {
margin: 0 20px 50px;
display: inline-flex;
width: 300px;
height: 100px;
justify-content: center;
img {
margin-right: 20px;
}
div {
display: flex;
flex-direction: column;
justify-content: center;
}
p {
margin: 0;
line-height: 1.8;
color: #999;
font-size: 14px;
}
}
.jumbotron {
width: 890px;
margin: 30px auto;
position: relative;
img {
width: 100%;
}
.jumbotron-red {
transition: height .1s;
background: #FFF;
position: absolute;
left: 0;
top:0;
overflow: hidden;
}
}
.cards {
margin: 0 auto 110px;
width: 1140px;
.container {
padding: 0;
margin: 0 -11px;
width: auto;
&::before, &::after {
display: table;
content: "";
}
&::after {
clear: both;
}
}
li {
width: 25%;
padding: 0 19px;
box-sizing: border-box;
float: left;
list-style: none;
}
img {
width: 160px;
height: 120px;
}
}
.card {
height: 430px;
width: 100%;
background:#ffffff;
border:1px solid #eaeefb;
border-radius:5px;
box-sizing: border-box;
text-align: center;
position: relative;
transition: all .3s ease-in-out;
bottom: 0;
img {
margin: 66px auto 60px;
}
h3 {
margin: 0;
font-size: 18px;
color: #1f2f3d;
font-weight: normal;
}
p {
font-size: 14px;
color: #99a9bf;
padding: 0 25px;
line-height: 20px;
}
a {
height: 53px;
line-height: 52px;
font-size: 14px;
color: #409EFF;
text-align: center;
border: 0;
border-top: 1px solid #eaeefb;
padding: 0;
cursor: pointer;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
background-color: #fff;
border-radius: 0 0 5px 5px;
transition: all .3s;
text-decoration: none;
display: block;
&:hover {
color: #fff;
background: #409EFF;
}
}
&:hover {
bottom: 6px;
box-shadow: 0 6px 18px 0 rgba(232,237,250,0.50);
}
}
@media (max-width: 1140px) {
.cards {
width: 100%;
.container {
width: 100%;
margin: 0;
}
}
.banner .container {
width: 100%;
box-sizing: border-box;
}
.banner img {
right: 0;
}
}
@media (max-width: 1000px) {
.banner .container {
img {
display: none;
}
}
.jumbotron {
display: none;
}
}
@media (max-width: 768px) {
.cards {
li {
width: 80%;
margin: 0 auto 20px;
float: none;
}
.card {
height: auto;
padding-bottom: 54px;
}
}
.banner-stars {
display: none;
}
.banner-desc {
#line2 {
display: none;
}
h2 {
font-size: 32px;
}
p {
width: auto;
}
}
}
.theme-intro-b {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 200;
.intro-banner {
position: absolute
}
img {
width: 300px;
}
.title {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
color: #FFF;
text-align: center;
font-weight: bold;
font-size: 20px;
display: flex;
justify-content: center;
align-items: center;
p {
padding: 0;
margin: 10px 0;
}
}
}
.theme-intro-a {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
z-index: 200;
.mask{
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: #000;
opacity: .5;
}
.intro-banner {
top: 50%;
left: 50%;
position: fixed;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
box-sizing: border-box;
text-align: center;
z-index: 100;
img {
width: 100%;
}
.intro-text {
position: absolute;
top: 50%;
left: 0;
right: 0;
p {
padding: 0;
margin: 0;
font-size: 48px;
font-weight: bold;
color: #FFF;
}
}
}
}
</style>
<template>
<div>
<div class="banner">
<div class="banner-desc">
<h1><%= 1 ></h1>
<p><%= 2 ></p>
</div>
</div>
<div class="jumbotron" ref="indexMainImg">
<img src="~examples/assets/images/theme-index-blue.png" alt="">
<div class="jumbotron-red" :style="{
height: mainImgOffset + 'px'
}">
<img src="~examples/assets/images/theme-index-red.png" alt="">
</div>
</div>
<div class="cards">
<ul class="container">
<li>
<div class="card">
<img src="~examples/assets/images/guide.png" alt="">
<h3><%= 3 ></h3>
<p><%= 4 ></p>
<router-link
active-class="active"
to="/<%= lang >/guide/design"
exact><%= 5 >
</router-link>
</div>
</li>
<li>
<div class="card">
<img src="~examples/assets/images/component.png" alt="">
<h3><%= 6 ></h3>
<p><%= 7 ></p>
<router-link
active-class="active"
to="/<%= lang >/component/layout"
exact><%= 5 >
</router-link>
</div>
</li>
<li>
<div class="card">
<img src="~examples/assets/images/theme-index-icon.svg" alt="">
<h3><%= 10 ></h3>
<p><%= 11 ></p>
<router-link
active-class="active"
to="/<%= lang >/theme"
exact><%= 5 >
</router-link>
</div>
</li>
<li>
<div class="card">
<img src="~examples/assets/images/resource.png" alt="">
<h3><%= 8 ></h3>
<p><%= 9 ></p>
<router-link
active-class="active"
to="/<%= lang >/resource"
exact><%= 5 >
</router-link>
</div>
</li>
</ul>
</div>
</div>
</template>
<script>
import throttle from 'throttle-debounce/throttle';
export default {
created() {
this.throttledHandleScroll = throttle(10, true, index => {
this.handleScroll(index);
});
},
methods: {
handleScroll(index) {
const ele = this.$refs.indexMainImg;
const rect = ele.getBoundingClientRect();
const eleHeight = ele.clientHeight + 55;
let calHeight = (180 - rect.top) * 2;
if (calHeight < 0) calHeight = 0;
if (calHeight > eleHeight) calHeight = eleHeight;
this.mainImgOffset = calHeight;
}
},
data() {
return {
lang: this.$route.meta.lang,
mainImgOffset: 0
};
},
beforeDestroy() {
window.removeEventListener('scroll', this.throttledHandleScroll);
},
mounted() {
window.addEventListener('scroll', this.throttledHandleScroll);
}
};
</script>

View File

@@ -0,0 +1,166 @@
<style scoped>
h3 {
margin-bottom: 15px;
}
.block {
margin-bottom: 55px;
}
p {
margin: 0 0 15px;
}
.nav-demos {
p {
margin-bottom: 50px;
}
h5 {
margin: 0;
}
img {
padding: 15px;
background-color: #F9FAFC;
width: 100%;
margin-bottom: 15px;
cursor: pointer;
}
}
.dialog-img {
position: fixed;
overflow: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
-webkit-overflow-scrolling: touch;
outline: 0;
.imgWrap {
margin: 0 auto;
position: relative;
top: 100px;
padding-bottom: 50px;
}
img {
display: block;
width: 100%;
}
}
.mask {
position: fixed;
top: 0;
right: 0;
left: 0;
bottom: 0;
background-color: #373737;
background-color: rgba(55, 55, 55, 0.6);
height: 100%;
z-index: 1000;
}
.zoom-enter-active,
.zoom-leave-active {
transition: transform .3s cubic-bezier(0.78, 0.14, 0.15, 0.86), opacity .3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
}
.zoom-enter,
.zoom-leave-active {
transform: scale(0.3);
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity .3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
}
.fade-enter,
.fade-leave-active {
opacity: 0;
}
</style>
<template>
<div>
<h2><%= 1 ></h2>
<div class="block">
<p><%= 2 ></p>
</div>
<div class="block">
<h3><%= 3 ></h3>
<p><%= 4 ></p>
</div>
<div class="block">
<h3><%= 5 ></h3>
<el-row :gutter="20">
<el-col :span="9">
<p><%= 6 ></p>
</el-col>
<el-col :span="15" class="nav-demos">
<img src="~examples/assets/images/navbar_1.png" alt="<%= 7 >" @click="enlarge(846, $event)">
<h5><%= 7 ></h5>
<p><%= 8 ></p>
<img src="~examples/assets/images/navbar_2.png" alt="<%= 9 >" @click="enlarge(846, $event)">
<h5><%= 9 ></h5>
<p><%= 10 ></p>
<img src="~examples/assets/images/navbar_3.png" alt="<%= 11 >" @click="enlarge(846, $event)">
<h5><%= 11 ></h5>
<p><%= 12 ></p>
</el-col>
</el-row>
</div>
<div class="block">
<h3><%= 13 ></h3>
<el-row>
<el-col :span="10">
<p><%= 14 ></p>
</el-col>
<el-col :span="14" class="nav-demos">
<img src="~examples/assets/images/navbar_0.png" alt="" @click="enlarge(846, $event)">
<p><%= 15 ></p>
</el-col>
</el-row>
</div>
<transition name="fade">
<div class="mask" v-show="showDialog" @click="showDialog = false"></div>
</transition>
<transition name="zoom">
<div class="dialog-img" :style='imgWrapStyle' v-show="showDialog" @click="showDialog = false">
<div class="imgWrap" :style="imgStyle">
<img :src="imgUrl" alt="">
</div>
</div>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
imgUrl: '',
imgBound: {},
showDialog: false,
imgStyle: {},
imgWrapStyle: {}
};
},
watch: {
showDialog(val) {
document.body.style.overflow = val ? 'hidden' : '';
}
},
methods: {
enlarge(imgWidth, ev) {
var imgNode = ev.target;
// var bound = imgNode.getBoundingClientRect();
var offset = {};
var doc = document;
offset.left = (doc.body.scrollWidth - imgWidth) / 2;
offset.top = 100;
this.imgUrl = imgNode.src;
this.imgBound = imgNode.getBoundingClientRect();
this.imgWrapStyle.transformOrigin = `${ev.clientX}px ${ev.clientY}px`;
// this.imgStyle.transformOrigin = `${ev.clientX}px ${ev.clientY}px`;
this.imgStyle.width = imgWidth + 'px';
this.showDialog = true;
}
}
};
</script>

View File

@@ -0,0 +1,173 @@
<style scoped>
.page-resource {
padding-top: 55px;
box-sizing: border-box;
.resource-placeholder {
margin: 50px auto 100px;
text-align: center;
img {
width: 150px;
}
h4 {
margin: 20px 0 16px;
font-size: 16px;
color: #1f2f3d;
line-height: 1;
}
p {
margin: 0;
font-size: 14px;
color: #99a9bf;
line-height: 1;
}
}
}
.cards {
margin: 35px auto 110px;
.container {
&::before, &::after {
display: table;
content: "";
}
&::after {
clear: both;
}
padding: 0;
margin: 0 -11px;
width: auto;
}
li {
width: 33.33333%;
padding: 0 11px;
box-sizing: border-box;
float: left;
list-style: none;
}
}
h2 {
font-size: 28px;
margin: 0;
}
p {
font-size: 14px;
color: #5e6d82;
}
.card {
height: 394px;
width: 100%;
background:#ffffff;
border:1px solid #eaeefb;
border-radius:5px;
box-sizing: border-box;
text-align: center;
position: relative;
transition: bottom .3s;
bottom: 0;
img {
margin: 75px auto 35px;
height: 87px;
}
h3 {
margin: 0 0 10px;
font-size: 18px;
color: #1f2f3d;
font-weight: normal;
height: 22px;
}
p {
font-size: 14px;
color: #99a9bf;
padding: 0 30px;
margin: 0;
word-break: break-all;
line-height: <%= paraHeight >;
}
a {
height: 42px;
width: 190px;
display: inline-block;
line-height: 42px;
font-size: 14px;
background-color: #409EFF;
color: #fff;
text-align: center;
border: 0;
padding: 0;
cursor: pointer;
border-radius: 2px;
transition: all .3s;
text-decoration: none;
margin-top: 20px;
}
}
@media (max-width: 850px) {
.cards {
li {
max-width: 500px;
float: none;
margin: 10px auto 30px;
width: 80%;
.card {
height: auto;
padding-bottom: 20px;
}
}
h3 {
height: auto;
}
}
}
</style>
<template>
<div class="page-container page-resource">
<h2><%= 1 ></h2>
<!--<div class="resource-placeholder">-->
<!--<img src="~examples/assets/images/resource-placeholder.svg" alt="">-->
<!--<h4><%= placeholder1 ></h4>-->
<!--<p><%= placeholder2 ></p>-->
<!--</div>-->
<p><%= placeholder2 ></p>
<div class="cards">
<ul class="container">
<li>
<div class="card">
<img src="~examples/assets/images/Axure-Components.svg" alt="">
<h3><%= 3 ></h3>
<p><%= 4 ></p>
<a
onclick="ga('send', 'event', 'ResourceDownload', 'Download', 'Axure');"
href="https://github.com/ElementUI/Resources/raw/master/Element_Components_v2.1.0.rplib"
><%= 5 ></a>
</div>
</li>
<li>
<div class="card">
<img src="~examples/assets/images/Sketch-Template.svg" alt="">
<h3><%= 6 ></h3>
<p><%= 7 ></p>
<a
onclick="ga('send', 'event', 'ResourceDownload', 'Download', 'Sketch');"
href="https://github.com/ElementUI/Resources/raw/master/Element%20UI%20Kit_v2.0.sketch"
><%= 5 ></a>
</div>
</li>
<!--<li>-->
<!--<div class="card">-->
<!--<img src="~examples/assets/images/Module.svg" alt="">-->
<!--<h3><%= 8 ></h3>-->
<!--<p><%= 9 ></p>-->
<!--<a href="https://github.com/ElementUI/Resources/raw/master/Element%20Components%20Documentation.zip"><%= 5 ></a>-->
<!--</div>-->
<!--</li>-->
</ul>
</div>
</div>
</template>

View File

@@ -0,0 +1,3 @@
<template>
<router-view></router-view>
</template>

View File

@@ -0,0 +1,196 @@
<style lang="scss">
.page-container.page-theme-preview {
padding-top: 30px;
.display {
width: 75%;
display: inline-block;
vertical-align: top;
h3 {
font-size: 28px;
margin: 30px 0 0 0;
}
}
.side {
display: inline-block;
width: 25%;
.editor {
overflow: hidden;
background: #f5f7fa;
border: 1px solid #ebeef5;
border-radius: 5px;
margin-bottom: 20px;
&.fixed {
position: fixed;
width: 285px;
box-sizing: border-box;
}
}
}
}
</style>
<template>
<div class="page-container page-theme-preview" ref="themePreview">
<section class="display">
<el-button type="text" icon="el-icon-back" @click="navBack">
<%= 1 >
</el-button>
<h3>{{previewConfig.name}}</h3>
<basic-tokens-preview>
</basic-tokens-preview>
<components-preview>
</components-preview>
</section>
<aside class="side">
<section class="editor" :style="{top: `${editorTop}px`, height: `${editorHeight}px`}" :class="{'fixed': isFixed}">
<theme-configurator
:isOfficial="isOfficial"
:themeConfig="themeConfig"
:previewConfig="previewConfig"
:onUserConfigUpdate="onUserConfigUpdate"
>
</theme-configurator>
</section>
</aside>
</div>
</template>
<script>
import bus from '../../bus.js';
import ThemeConfigurator from '../../components/theme-configurator';
import ComponentsPreview from '../../components/theme/components-preview';
import BasicTokensPreview from '../../components/theme/basic-tokens-preview';
import {
loadPreviewFromLocal,
loadUserThemeFromLocal,
saveUserThemeToLocal
} from '../../components/theme/localstorage';
import {
getThemeConfigObject
} from '../../components/theme/utils';
import {
ACTION_APPLY_THEME
} from '../../components/theme/constant.js';
import throttle from 'throttle-debounce/throttle';
import { getActionDisplayName } from '../../components/theme-configurator/utils/utils';
const maxUserTheme = 8;
export default {
components: {
ThemeConfigurator,
BasicTokensPreview,
ComponentsPreview
},
data() {
return {
previewConfig: {},
themeConfig: {},
userTheme: [],
editorTop: 0,
editorHeight: 1000,
isFixed: false
};
},
computed: {
isOfficial() {
return this.previewConfig.type === 'official';
}
},
created() {
this.throttledHandleScroll = throttle(10, true, index => {
this.handleScroll(index);
});
},
methods: {
navBack() {
this.$router.go(-1);
this.$nextTick(() => {
window.scrollTo(0, 0);
});
},
getNewUserThemeName(originName) {
let n = 1;
let name;
while (true) {
name = `${originName}-${n}`;
if (this.userTheme.filter(theme => (theme.name === name)).length === 0) {
break;
}
n += 1;
}
return name;
},
onUserConfigUpdate(userConfig) {
const themeConfig = JSON.stringify(userConfig);
const { type, name } = this.previewConfig;
if (this.isOfficial) {
if (this.userTheme.length >= maxUserTheme) {
this.$message.error(getActionDisplayName('max-user-theme'));
return;
}
const autoUserName = this.getNewUserThemeName(name);
this.previewConfig.name = autoUserName;
this.previewConfig.type = 'user';
this.userTheme.push({
update: Date.now(),
name: autoUserName,
theme: themeConfig
});
saveUserThemeToLocal(this.userTheme);
return;
}
if (type === 'user') {
this.userTheme.forEach((config) => {
if (config.name === name) {
config.update = Date.now();
config.theme = themeConfig;
}
});
saveUserThemeToLocal(this.userTheme);
}
},
handleScroll() {
const rect = this.$refs.themePreview.getBoundingClientRect();
let offsetTop = rect.top;
let offsetBottom = rect.bottom;
const calHeight = this.editorHeight + 30 + 20;
if (offsetTop < 0) {
this.isFixed = true;
if (offsetBottom < calHeight) {
this.editorTop = 30 - calHeight + offsetBottom;
} else {
this.editorTop = 30;
}
} else {
this.isFixed = false;
this.editorTop = 0;
}
}
},
beforeDestroy() {
window.removeEventListener('scroll', this.throttledHandleScroll);
},
mounted() {
this.editorHeight = window.innerHeight - 40 - 5;
window.addEventListener('scroll', this.throttledHandleScroll);
this.userTheme = loadUserThemeFromLocal();
const previewConfig = loadPreviewFromLocal();
const pageRefer = this.$route.params.refer;
if (!previewConfig || !pageRefer) {
this.$alert(getActionDisplayName('no-preview-config'), getActionDisplayName('notice'), {
confirmButtonText: getActionDisplayName('confirm'),
callback: action => {
const newPath = this.$route.path.replace('/preview', '');
this.$router.replace(newPath);
}
});
return;
}
this.previewConfig = previewConfig;
const themeConfig = getThemeConfigObject(previewConfig.theme);
if (themeConfig) {
this.themeConfig = themeConfig;
bus.$emit(ACTION_APPLY_THEME, themeConfig);
}
}
};
</script>

View File

@@ -0,0 +1,230 @@
<style lang="scss">
.page-theme {
&:last-child {
margin-bottom: 55px;
}
h2 {
font-size: 28px;
line-height: 28px;
margin: 0;
}
ul {
list-style: none;
padding: 0;
margin: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.theme-card {
display: inline-block;
height: 150px;
height: 16vw;
max-height: 230px;
flex: 0 0 24%;
cursor: default;
vertical-align: bottom;
}
.theme-section {
margin-bottom: 20px;
}
.second-section {
margin-top: 60px;
}
}
</style>
<template>
<div class="page-container page-theme">
<section class="theme-section">
<h2><%= 1 ></h2>
<ul>
<li class="theme-card" v-for="item in officialTheme" :key="item.name">
<theme-card
type="official"
:config="item"
@action="onAction"
></theme-card>
</li>
</ul>
</section>
<section class="theme-section second-section">
<h2><%= 2 > ({{userThemeCount}}/{{maxUserTheme}})</h2>
<ul>
<li class="theme-card" v-if="showUserUpload">
<theme-card
type="upload"
:config="{name: 'upload'}"
@action="onAction"
></theme-card>
</li>
<li class="theme-card" v-for="item in displayUserTheme" :key="item.name">
<theme-card
type="user"
:config="item"
@action="onAction"
></theme-card>
</li>
</ul>
</section>
<el-dialog :visible.sync="copyDialogVisible">
<el-form :model="copyForm" ref="copyForm" :rules="copyFormRule">
<el-form-item label="<%= 3 >" prop="name">
<el-input v-model="copyForm.name"></el-input>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="closeCopyForm">{{getActionDisplayName('cancel')}}</el-button>
<el-button type="primary" @click="copyToUser">{{getActionDisplayName('confirm')}}</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import ThemeCard from '../../components/theme/theme-card.vue';
import { themeList, eleThemeList } from '../../components/theme/theme-list.js';
import { saveUserThemeToLocal, loadUserThemeFromLocal } from '../../components/theme/localstorage';
import { getActionDisplayName } from '../../components/theme-configurator/utils/utils';
const maxUserTheme = 8;
export default {
components: {
ThemeCard
},
mounted() {
this.userTheme = loadUserThemeFromLocal();
if (!Array.isArray(this.userTheme)) {
this.userTheme = [];
saveUserThemeToLocal(this.userTheme);
}
this.$nextTick(() => {
window.scrollTo(0, 0);
});
},
data() {
return {
userTheme: [],
maxUserTheme,
copyDialogVisible: false,
copyForm: {},
copyFormRule: {
name: [{
validator: this.validateCopyName,
trigger: 'blur'
}]
}
};
},
computed: {
officialTheme() {
return this.padEmpeyTheme(themeList.concat(this.$isEle ? eleThemeList : []));
},
userThemeCount() {
return this.userTheme.length;
},
showUserUpload() {
return this.userThemeCount < maxUserTheme;
},
displayUserTheme() {
return this.padEmpeyTheme(this.userTheme, this.showUserUpload ? 1 : 0);
}
},
methods: {
getActionDisplayName(key) {
return getActionDisplayName(key);
},
validateCopyName(rule, value, callback) {
if (!value) {
callback(new Error(this.getActionDisplayName('require-them-name')));
} else if (this.filterUserThemeByName(value).length > 0) {
callback(new Error(this.getActionDisplayName('duplicate-them-name')));
} else {
callback();
}
},
filterUserThemeByName(name, include = true) {
return this.userTheme.filter((theme) => (include ? theme.name === name : theme.name !== name));
},
padEmpeyTheme(theme, add = 0) {
if (!theme.length) return [];
const pad = 4 - ((theme.length + add) % 4);
if (pad < 4) return theme.concat(Array(pad).fill({}));
return theme;
},
onAction(name, item) {
switch (name) {
case 'copy':
this.openCopyForm(item.theme);
break;
case 'upload':
this.openCopyForm(item);
break;
case 'rename':
this.openRenameForm(item.name);
break;
case 'delete':
this.$confirm(this.getActionDisplayName('confirm-delete-theme'), this.getActionDisplayName('notice'), {
confirmButtonText: this.getActionDisplayName('confirm'),
cancelButtonText: this.getActionDisplayName('cancel'),
type: 'warning'
}).then(() => {
this.deleteUserThemeByName(item.name);
}).catch(() => {});
break;
default:
return;
}
},
deleteUserThemeByName(name) {
this.userTheme = this.filterUserThemeByName(name, false);
this.saveToLocal();
},
openRenameForm(name) {
this.copyForm.oldname = name;
this.copyDialogVisible = true;
},
openCopyForm(theme) {
if (this.userTheme.length >= 8) {
this.$message.error(this.getActionDisplayName('max-user-theme'));
return;
}
this.copyForm.theme = theme;
this.copyDialogVisible = true;
},
closeCopyForm() {
this.copyDialogVisible = false;
this.$nextTick(() => {
this.copyForm = {};
});
},
copyToUser() {
this.$refs.copyForm.validate((valid) => {
if (valid) {
const { theme, name, oldname } = this.copyForm;
if (theme) {
// copy
this.userTheme.push({
update: Date.now(),
name,
theme
});
} else {
// rename
this.userTheme.forEach((config) => {
if (config.name === oldname) {
config.update = Date.now();
config.name = name;
}
});
}
this.saveToLocal();
this.closeCopyForm();
}
});
},
saveToLocal() {
saveUserThemeToLocal(this.userTheme);
}
}
};
</script>