first
85
examples/app.vue
Normal file
@@ -0,0 +1,85 @@
|
||||
<template>
|
||||
<div id="app" :class="{ 'is-component': isComponent }">
|
||||
<main-header v-if="lang !== 'play'"></main-header>
|
||||
<div class="main-cnt">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
<main-footer v-if="lang !== 'play' && !isComponent"></main-footer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { use } from 'main/locale';
|
||||
import zhLocale from 'main/locale/lang/zh-CN';
|
||||
import enLocale from 'main/locale/lang/en';
|
||||
import esLocale from 'main/locale/lang/es';
|
||||
import frLocale from 'main/locale/lang/fr';
|
||||
|
||||
const lang = location.hash.replace('#', '').split('/')[1] || 'zh-CN';
|
||||
const localize = lang => {
|
||||
switch (lang) {
|
||||
case 'zh-CN':
|
||||
use(zhLocale);
|
||||
break;
|
||||
case 'es':
|
||||
use(esLocale);
|
||||
break;
|
||||
case 'fr-FR':
|
||||
use(frLocale);
|
||||
break;
|
||||
default:
|
||||
use(enLocale);
|
||||
}
|
||||
};
|
||||
localize(lang);
|
||||
|
||||
export default {
|
||||
name: 'app',
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.path.split('/')[1] || 'zh-CN';
|
||||
},
|
||||
isComponent() {
|
||||
return /^component-/.test(this.$route.name || '');
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
lang(val) {
|
||||
if (val === 'zh-CN') {
|
||||
this.suggestJump();
|
||||
}
|
||||
localize(val);
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
suggestJump() {
|
||||
if (process.env.NODE_ENV !== 'production') return;
|
||||
|
||||
const href = location.href;
|
||||
const preferGithub = localStorage.getItem('PREFER_GITHUB');
|
||||
const cnHref = href.indexOf('eleme.cn') > -1 || href.indexOf('element-cn') > -1 || href.indexOf('element.faas') > -1;
|
||||
if (cnHref || preferGithub) return;
|
||||
setTimeout(() => {
|
||||
if (this.lang !== 'zh-CN') return;
|
||||
this.$confirm('建议大陆用户访问部署在国内的站点,是否跳转?', '提示')
|
||||
.then(() => {
|
||||
location.replace('https://element.eleme.cn');
|
||||
})
|
||||
.catch(() => {
|
||||
localStorage.setItem('PREFER_GITHUB', 'true');
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
localize(this.lang);
|
||||
if (this.lang === 'zh-CN') {
|
||||
this.suggestJump();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
41
examples/assets/images/Axure-Components.svg
Normal file
@@ -0,0 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="110px" height="87px" viewBox="0 0 110 87" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="background: #FFFFFF;">
|
||||
<!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Axure Components_icon</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Axure-Components_icon">
|
||||
<g id="sitemap">
|
||||
<g id="Group">
|
||||
<path d="M87.2413867,49.517832 L56.8966406,49.517832 L56.8966406,41.9316992 L53.1035742,41.9316992 L53.1035742,49.517832 L22.7586133,49.517832 C21.71125,49.517832 20.8619727,50.3671094 20.8619727,51.4144727 L20.8619727,60.8972461 L24.6550391,60.8972461 L24.6550391,53.3111133 L53.1033594,53.3111133 L53.1033594,60.8972461 L56.8964258,60.8972461 L56.8964258,53.3111133 L85.3447461,53.3111133 L85.3447461,60.8972461 L89.1378125,60.8972461 L89.1378125,51.4142578 C89.1380273,50.3668945 88.28875,49.517832 87.2413867,49.517832 L87.2413867,49.517832 Z" id="Shape" fill="#DEEBFD"></path>
|
||||
<path d="M104.310293,0 L5.68970703,0 C2.54740234,0 0,2.54014599 0,5.673764 L0,81.3260218 C0,84.4596398 2.54740234,87 5.68970703,87 L104.310293,87 C107.452598,87 110,84.4596398 110,81.3260218 L110,5.673764 C110,2.54014599 107.452598,0 104.310293,0 L104.310293,0 Z M106.206934,81.5516797 C106.206934,82.599043 105.357656,83.4483203 104.310293,83.4483203 L5.68970703,83.4483203 C4.64234375,83.4483203 3.79306641,82.599043 3.79306641,81.5516797 L3.79306641,13.2758398 C3.79306641,12.2284766 4.64234375,11.3791992 5.68970703,11.3791992 L104.310293,11.3791992 C105.357656,11.3791992 106.206934,12.2284766 106.206934,13.2758398 L106.206934,81.5516797 L106.206934,81.5516797 Z" id="Shape" fill="#F2F8FE"></path>
|
||||
</g>
|
||||
<circle id="Oval" fill="#DDEAFC" cx="5.68970703" cy="5.89703125" r="1.89664062"></circle>
|
||||
<circle id="Oval" fill="#DDEAFC" cx="11.3794141" cy="5.89703125" r="1.89664062"></circle>
|
||||
<circle id="Oval" fill="#DDEAFC" cx="17.0689062" cy="5.89703125" r="1.89664062"></circle>
|
||||
<path d="M34.2899219,43.828125 C33.1585547,43.828125 32.2413867,42.910957 32.2413867,41.7795898 L32.2413867,19.3249805 C32.2413867,18.1936133 33.1585547,17.2764453 34.2899219,17.2764453 L75.7100781,17.2764453 C76.8414453,17.2764453 77.7586133,18.1936133 77.7586133,19.3249805 L77.7586133,41.7795898 C77.7586133,42.910957 76.8414453,43.828125 75.7100781,43.828125 L34.2899219,43.828125 Z" id="Shape" fill="#20A0FF"></path>
|
||||
<path d="M66.9534766,77.9661523 L43.0465234,77.9661523 C42.3162695,77.9661523 41.7241602,77.3742578 41.7241602,76.6437891 L41.7241602,60.3227539 C41.7241602,59.5922852 42.3160547,59.0003906 43.0465234,59.0003906 L66.9536914,59.0003906 C67.6841602,59.0003906 68.2760547,59.5922852 68.2760547,60.3227539 L68.2760547,76.6437891 C68.2758398,77.374043 67.6839453,77.9661523 66.9534766,77.9661523 L66.9534766,77.9661523 Z" id="Shape" fill="#FFD6D2"></path>
|
||||
<g id="Group" transform="translate(35.878906, 21.054688)" fill="#2198F0">
|
||||
<path d="M36.19,11.3940234 L2.0521875,11.3940234 C1.00482422,11.3940234 0.155546875,10.5447461 0.155546875,9.49738281 L0.155546875,9.49738281 C0.155546875,8.45001953 1.00482422,7.60074219 2.0521875,7.60074219 L36.1902148,7.60074219 C37.2375781,7.60074219 38.0868555,8.45001953 38.0868555,9.49738281 L38.0868555,9.49738281 C38.0866406,10.5449609 37.2373633,11.3940234 36.19,11.3940234 L36.19,11.3940234 Z" id="Shape"></path>
|
||||
<path d="M32.3969336,3.80789063 L5.84525391,3.80789063 C4.79789062,3.80789063 3.94861328,2.95861328 3.94861328,1.91125 L3.94861328,1.91125 C3.94861328,0.863886719 4.79789062,0.014609375 5.84525391,0.014609375 L32.3969336,0.014609375 C33.4442969,0.014609375 34.2935742,0.863886719 34.2935742,1.91125 L34.2935742,1.91125 C34.2935742,2.95882813 33.4442969,3.80789063 32.3969336,3.80789063 L32.3969336,3.80789063 Z" id="Shape"></path>
|
||||
<path d="M24.8108008,18.9803711 L13.4313867,18.9803711 C12.3840234,18.9803711 11.5347461,18.1310938 11.5347461,17.0837305 L11.5347461,17.0837305 C11.5347461,16.0363672 12.3840234,15.1870898 13.4313867,15.1870898 L24.8108008,15.1870898 C25.8581641,15.1870898 26.7074414,16.0363672 26.7074414,17.0837305 L26.7074414,17.0837305 C26.7072266,18.1310938 25.8581641,18.9803711 24.8108008,18.9803711 L24.8108008,18.9803711 Z" id="Shape"></path>
|
||||
</g>
|
||||
<g id="Group" transform="translate(45.332031, 62.734375)" fill="#FFACAD">
|
||||
<path d="M13.4610352,11.4384961 L5.87490234,11.4384961 C4.82753906,11.4384961 3.97826172,10.5892188 3.97826172,9.54185547 L3.97826172,9.54185547 C3.97826172,8.49449219 4.82753906,7.64521484 5.87490234,7.64521484 L13.4610352,7.64521484 C14.5083984,7.64521484 15.3576758,8.49449219 15.3576758,9.54185547 L15.3576758,9.54185547 C15.3576758,10.5894336 14.5083984,11.4384961 13.4610352,11.4384961 L13.4610352,11.4384961 Z" id="Shape"></path>
|
||||
<path d="M17.2541016,3.85236328 L2.08183594,3.85236328 C1.03447266,3.85236328 0.185195313,3.00308594 0.185195313,1.95572266 L0.185195313,1.95572266 C0.185195313,0.908359375 1.03447266,0.0590820312 2.08183594,0.0590820312 L17.2543164,0.0590820312 C18.3016797,0.0590820312 19.150957,0.908359375 19.150957,1.95572266 L19.150957,1.95572266 C19.1507422,3.00308594 18.3014648,3.85236328 17.2541016,3.85236328 L17.2541016,3.85236328 Z" id="Shape"></path>
|
||||
</g>
|
||||
<path d="M99.1948633,77.9661523 L75.2879102,77.9661523 C74.5574414,77.9661523 73.9655469,77.3742578 73.9655469,76.6437891 L73.9655469,60.3227539 C73.9655469,59.5922852 74.5574414,59.0003906 75.2879102,59.0003906 L99.1950781,59.0003906 C99.9255469,59.0003906 100.517441,59.5922852 100.517441,60.3227539 L100.517441,76.6437891 C100.517227,77.374043 99.925332,77.9661523 99.1948633,77.9661523 L99.1948633,77.9661523 Z" id="Shape" fill="#F2F8FE"></path>
|
||||
<g id="Group" transform="translate(77.558594, 62.734375)" fill="#DEEBF8">
|
||||
<path d="M13.4758594,11.4384961 L5.88972656,11.4384961 C4.84236328,11.4384961 3.99308594,10.5892188 3.99308594,9.54185547 L3.99308594,9.54185547 C3.99308594,8.49449219 4.84236328,7.64521484 5.88972656,7.64521484 L13.4758594,7.64521484 C14.5232227,7.64521484 15.3725,8.49449219 15.3725,9.54185547 L15.3725,9.54185547 C15.3725,10.5894336 14.5232227,11.4384961 13.4758594,11.4384961 L13.4758594,11.4384961 Z" id="Shape"></path>
|
||||
<path d="M17.2689258,3.85236328 L2.09644531,3.85236328 C1.04908203,3.85236328 0.199804688,3.00308594 0.199804688,1.95572266 L0.199804688,1.95572266 C0.199804688,0.908359375 1.04908203,0.0590820312 2.09644531,0.0590820312 L17.2689258,0.0590820312 C18.3162891,0.0590820312 19.1655664,0.908359375 19.1655664,1.95572266 L19.1655664,1.95572266 C19.1655664,3.00308594 18.3162891,3.85236328 17.2689258,3.85236328 L17.2689258,3.85236328 Z" id="Shape"></path>
|
||||
</g>
|
||||
<path d="M34.7120898,77.9661523 L10.8051367,77.9661523 C10.0748828,77.9661523 9.48277344,77.3742578 9.48277344,76.6437891 L9.48277344,60.3227539 C9.48277344,59.5922852 10.074668,59.0003906 10.8051367,59.0003906 L34.7123047,59.0003906 C35.4425586,59.0003906 36.034668,59.5922852 36.034668,60.3227539 L36.034668,76.6437891 C36.0344531,77.374043 35.4425586,77.9661523 34.7120898,77.9661523 L34.7120898,77.9661523 Z" id="Shape" fill="#80A8E1"></path>
|
||||
<g id="Group" transform="translate(13.105469, 62.734375)" fill="#6496DC">
|
||||
<path d="M13.4462109,11.4384961 L5.86007813,11.4384961 C4.81271484,11.4384961 3.9634375,10.5892188 3.9634375,9.54185547 L3.9634375,9.54185547 C3.9634375,8.49449219 4.81271484,7.64521484 5.86007813,7.64521484 L13.4462109,7.64521484 C14.4935742,7.64521484 15.3428516,8.49449219 15.3428516,9.54185547 L15.3428516,9.54185547 C15.3428516,10.5894336 14.4935742,11.4384961 13.4462109,11.4384961 L13.4462109,11.4384961 Z" id="Shape"></path>
|
||||
<path d="M17.2392773,3.85236328 L2.06701172,3.85236328 C1.01964844,3.85236328 0.170371094,3.00308594 0.170371094,1.95572266 L0.170371094,1.95572266 C0.170371094,0.908359375 1.01964844,0.0590820312 2.06701172,0.0590820312 L17.2394922,0.0590820312 C18.2868555,0.0590820312 19.1361328,0.908359375 19.1361328,1.95572266 L19.1361328,1.95572266 C19.135918,3.00308594 18.2866406,3.85236328 17.2392773,3.85236328 L17.2392773,3.85236328 Z" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.5 KiB |
62
examples/assets/images/Module.svg
Normal file
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="81px" height="77px" viewBox="0 0 81 77" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Module_icon</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<rect id="path-1" x="6" y="57" width="11" height="11" rx="5.5"></rect>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-2">
|
||||
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0.466666667 0 0 0 0 0.807843137 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-3" x="6" y="57" width="11" height="11" rx="5.5"></rect>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-4">
|
||||
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feColorMatrix values="0 0 0 0 0.392156863 0 0 0 0 0.588235294 0 0 0 0 0.862745098 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
<rect id="path-5" x="6" y="57" width="11" height="11" rx="5.5"></rect>
|
||||
<filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-6">
|
||||
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
|
||||
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.674509804 0 0 0 0 0.678431373 0 0 0 1 0" type="matrix" in="shadowOffsetOuter1"></feColorMatrix>
|
||||
</filter>
|
||||
</defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Module_icon">
|
||||
<g id="Group-5">
|
||||
<g id="folder-3">
|
||||
<g id="Group">
|
||||
<rect id="Rectangle-path" fill="#DEEBF8" x="0" y="54" width="23" height="23"></rect>
|
||||
<rect id="Rectangle-path" fill="#F2F8FE" x="0" y="0" width="23" height="54"></rect>
|
||||
<rect id="Rectangle" fill="#DEEBF9" x="7" y="6" width="9" height="30" rx="3"></rect>
|
||||
<g id="Rectangle-path">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
|
||||
<use fill="#20A0FF" fill-rule="evenodd" xlink:href="#path-1"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="folder-3-copy" transform="translate(29.000000, 0.000000)">
|
||||
<g id="Group">
|
||||
<rect id="Rectangle-path" fill="#DEEBF8" x="0" y="54" width="23" height="23"></rect>
|
||||
<rect id="Rectangle-path" fill="#F2F8FE" x="0" y="0" width="23" height="54"></rect>
|
||||
<rect id="Rectangle" fill="#DEEBF9" x="7" y="6" width="9" height="30" rx="3"></rect>
|
||||
<g id="Rectangle-path">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
|
||||
<use fill="#80A8E1" fill-rule="evenodd" xlink:href="#path-3"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="folder-3-copy" transform="translate(58.000000, 0.000000)">
|
||||
<g id="Group">
|
||||
<rect id="Rectangle-path" fill="#DEEBF8" x="0" y="54" width="23" height="23"></rect>
|
||||
<rect id="Rectangle-path" fill="#F2F8FE" x="0" y="0" width="23" height="54"></rect>
|
||||
<rect id="Rectangle" fill="#DEEBF9" x="7" y="6" width="9" height="30" rx="3"></rect>
|
||||
<g id="Rectangle-path">
|
||||
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
|
||||
<use fill="#FFD6D2" fill-rule="evenodd" xlink:href="#path-5"></use>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.1 KiB |
37
examples/assets/images/Sketch-Template.svg
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="88px" height="77px" viewBox="0 0 88 77" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 39.1 (31720) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Sketch Template_icon</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Sketch-Template_icon">
|
||||
<g id="Group-25">
|
||||
<g id="browser">
|
||||
<g id="Group" transform="translate(0.042735, 6.772269)" fill="#C9E1FB" opacity="0.23880597">
|
||||
<path d="M3.20088476,28.5057337 L44.1701391,28.5057337 C45.9105265,28.5057337 47.3217575,27.1026312 47.3217575,25.3722682 L47.3217575,0.305608725 C47.3217575,2.03597172 45.9105265,3.43907426 44.1701391,3.43907426 L3.20088476,3.43907426 C1.46049739,3.43907426 0.0492663503,2.03597172 0.0492663503,0.305608725 L0.0492663503,25.3722682 C0.0492663503,27.1029861 1.46014038,28.5057337 3.20088476,28.5057337 L3.20088476,28.5057337 Z" id="Shape"></path>
|
||||
<path d="M59.9271601,28.5057337 L78.8361566,28.5057337 C80.576544,28.5057337 81.987775,27.1026312 81.987775,25.3722682 L81.987775,0.305608725 C81.987775,2.03597172 80.576544,3.43907426 78.8361566,3.43907426 L59.9271601,3.43907426 C58.1867728,3.43907426 56.7755417,2.03597172 56.7755417,0.305608725 L56.7755417,25.3722682 C56.7755417,27.1029861 58.1867728,28.5057337 59.9271601,28.5057337 L59.9271601,28.5057337 Z" id="Shape"></path>
|
||||
</g>
|
||||
<path d="M3.24361929,10.2116986 L44.2128736,10.2116986 C45.953261,10.2116986 47.364492,8.80859603 47.364492,7.07823304 L47.364492,3.94476751 C47.364492,2.21440451 45.953261,0.811301969 44.2128736,0.811301969 L3.24361929,0.811301969 C1.50323191,0.811301969 0.0920008764,2.21440451 0.0920008764,3.94476751 L0.0920008764,7.07823304 C0.0920008764,8.80859603 1.50287491,10.2116986 3.24361929,10.2116986 L3.24361929,10.2116986 Z" id="Shape" fill="#FFD6D2"></path>
|
||||
<path d="M59.9698947,10.2116986 L78.8788911,10.2116986 C80.6192785,10.2116986 82.0305096,8.80859603 82.0305096,7.07823304 L82.0305096,3.94476751 C82.0305096,2.21440451 80.6192785,0.811301969 78.8788911,0.811301969 L59.9698947,0.811301969 C58.2295073,0.811301969 56.8182763,2.21440451 56.8182763,3.94476751 L56.8182763,7.07823304 C56.8182763,8.80859603 58.2295073,10.2116986 59.9698947,10.2116986 L59.9698947,10.2116986 Z" id="Shape" fill="#20A0FF"></path>
|
||||
<g id="Group" transform="translate(6.111778, 44.396572)" fill="#C9E1FB" opacity="0.23880597">
|
||||
<path d="M3.63949659,28.4815974 C3.63949659,30.2119604 2.13657137,31.6150629 0.283103013,31.6150629 L62.5667088,31.6150629 C64.4201772,31.6150629 65.9231024,30.2119604 65.9231024,28.4815974 L65.9231024,3.41493792 C65.9231024,1.68457492 64.4201772,0.28147238 62.5667088,0.28147238 L0.283103013,0.28147238 C2.13657137,0.28147238 3.63949659,1.68457492 3.63949659,3.41493792 L3.63949659,28.4815974 Z" id="Shape"></path>
|
||||
</g>
|
||||
<path d="M3.24361929,76.0112803 L6.3952377,76.0112803 C8.13562508,76.0112803 9.54685611,74.6081778 9.54685611,72.8778148 L9.54685611,47.8111553 C9.54685611,46.265021 8.42013066,44.9801712 6.93862628,44.7241059 C6.76209851,44.6935946 6.58053368,44.6776898 6.3952377,44.6776898 L3.24361929,44.6776898 C1.50323191,44.6776898 0.0920008764,46.0807923 0.0920008764,47.8111553 L0.0920008764,72.8778148 C0.0920008764,74.6081778 1.50287491,76.0112803 3.24361929,76.0112803 L3.24361929,76.0112803 Z" id="Shape" fill="#20A0FF"></path>
|
||||
</g>
|
||||
<g id="diamond" transform="translate(53.000000, 45.000000)">
|
||||
<polygon id="Shape" fill="#AFC8EB" points="24.1753264 8.86069795 17.1851852 28.8357025 34.3703704 8.86069795"></polygon>
|
||||
<g id="Group">
|
||||
<polygon id="Shape" fill="#80A8E1" points="7.1111088 0.0481841797 0 8.86069795 10.195044 8.86069795"></polygon>
|
||||
<polygon id="Shape" fill="#80A8E1" points="24.1753264 8.86069795 34.3703704 8.86069795 27.2592616 0.0481841797"></polygon>
|
||||
<polygon id="Shape" fill="#AFC8EA" points="24.1753264 8.86069795 17.1851852 0.0481841797 10.195044 8.86069795"></polygon>
|
||||
</g>
|
||||
<polygon id="Shape" fill="#6496DC" points="17.1851852 0.0481841797 7.1111088 0.0481841797 10.195044 8.86069795"></polygon>
|
||||
<polygon id="Shape" fill="#93B8EE" points="27.2592616 0.0481841797 17.1851852 0.0481841797 24.1753264 8.86069795"></polygon>
|
||||
<polygon id="Shape" fill="#80A8E1" points="10.195044 8.86069795 17.1851852 28.8357025 24.1753264 8.86069795"></polygon>
|
||||
<polygon id="Shape" fill="#6496DC" points="0 8.86069795 17.1851852 28.8357025 10.195044 8.86069795"></polygon>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 4.9 KiB |
BIN
examples/assets/images/button-d-cn.png
Normal file
After Width: | Height: | Size: 7.6 KiB |
BIN
examples/assets/images/button-d-en.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
examples/assets/images/button-l-cn.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
examples/assets/images/button-l-en.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
examples/assets/images/cloud-1.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
examples/assets/images/cloud-2.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
examples/assets/images/compo-1.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
examples/assets/images/compo-2.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
examples/assets/images/compo-3.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
examples/assets/images/component.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
examples/assets/images/consistency.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
examples/assets/images/controllability.png
Normal file
After Width: | Height: | Size: 5.9 KiB |
BIN
examples/assets/images/dialog-close.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
examples/assets/images/efficiency.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
examples/assets/images/element-demo.jpeg
Normal file
After Width: | Height: | Size: 363 KiB |
12
examples/assets/images/element-logo-small.svg
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="30px" height="30px" viewBox="0 0 38 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 40 (33762) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Shape Copy</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="v2.2.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="首页-默认效果-copy-2" transform="translate(-70.000000, -19.000000)" fill="#409EFF">
|
||||
<path d="M212.135441,45.1578077 Z M103.416502,46.2175511 C103.407008,47.7945682 102.587841,48.1463474 102.587841,48.1463474 C102.587841,48.1463474 88.4520478,56.3145087 87.5329956,56.8262751 C86.622336,57.2171561 86.0136703,56.8262751 86.0136703,56.8262751 C86.0136703,56.8262751 71.2225706,48.2479572 70.6826962,47.8708444 C70.1426843,47.4937316 70.1301643,46.9063774 70.1301643,46.9063774 C70.1301643,46.9063774 70.1450232,29.9199174 70.1301643,29.1333364 C70.1153053,28.3466177 71.0969576,27.7555461 71.0969576,27.7555461 L85.8755373,19.2134387 C86.7853714,18.7332016 87.6711286,19.2134387 87.6711286,19.2134387 C87.6711286,19.2134387 100.726623,26.8020937 102.173442,27.6177257 C103.591507,28.2919577 103.416502,29.6843424 103.416502,29.6843424 C103.416502,29.6843424 103.425307,44.7519192 103.416502,46.2175511 L103.416502,46.2175511 Z M97.5160105,29.1691339 C94.4900173,27.4274483 87.3615842,23.2971063 87.3615842,23.2971063 C87.3615842,23.2971063 86.6661039,22.9212326 85.9517747,23.2971063 L74.3487406,29.98215 C74.3487406,29.98215 73.5780025,30.4449014 73.589697,31.0604805 C73.6013915,31.6760597 73.589697,44.9698708 73.589697,44.9698708 C73.589697,44.9698708 73.5994654,45.4295932 74.0234951,45.7246472 C74.4473873,46.0197011 86.0601898,52.7332451 86.0601898,52.7332451 C86.0601898,52.7332451 86.538152,53.0391759 87.2530315,52.7332451 C87.9746526,52.3327262 99.0730335,45.9402582 99.0730335,45.9402582 C99.0730335,45.9402582 99.7162325,45.6648929 99.7236619,44.4307056 C99.7257257,44.0747959 99.7265512,42.6932881 99.7266887,40.9575229 L86.6600502,48.8752394 L86.6600502,45.846221 C86.6600502,44.6021205 87.6231289,43.7809811 87.6231289,43.7809811 L99.1807607,36.8165793 C99.6168978,36.3611251 99.7068768,35.6315447 99.7254505,35.3556287 C99.7250378,34.0904627 99.7244874,32.9852841 99.7240747,32.2851678 L86.6600502,40.2012321 L86.6600502,37.034531 C86.6600502,35.7904305 87.4855462,35.2446564 87.4855462,35.2446564 L97.5160105,29.1691339 Z" id="Shape-Copy"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
12
examples/assets/images/element-logo.svg
Normal file
After Width: | Height: | Size: 9.5 KiB |
BIN
examples/assets/images/feedback.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
examples/assets/images/figure-1.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
examples/assets/images/figure-2.png
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
examples/assets/images/guide.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
examples/assets/images/hamburger.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
examples/assets/images/icon-check.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
examples/assets/images/icon-copy.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
examples/assets/images/icon-download.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
examples/assets/images/icon-edit.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
19
examples/assets/images/icon-redo.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="13px" height="12px" viewBox="0 0 13 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
|
||||
<title>icon-redo</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="theme" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="element-theme-editor" transform="translate(-1118.000000, -167.000000)" fill="#606266" fill-rule="nonzero">
|
||||
<g id="custom" transform="translate(1060.000000, 146.000000)">
|
||||
<g id="Group-2" transform="translate(30.000000, 15.000000)">
|
||||
<g id="Group" transform="translate(0.000000, 4.000000)">
|
||||
<g id="icon-clockwise" transform="translate(26.000000, 0.000000)">
|
||||
<path d="M12.2585,3.59833136 L12.2585,2.3085 L13.2585,2.3085 L13.2585,5.6365 L9.9295,5.6365 L9.9295,4.6365 L11.8833737,4.6365 C10.9510824,3.62012881 9.6272717,3.0179 8.2,3.0179 C5.43814237,3.0179 3.2,5.25604237 3.2,8.0179 C3.2,10.7797576 5.43814237,13.0179 8.2,13.0179 C10.9618576,13.0179 13.2,10.7797576 13.2,8.0179 L14.2,8.0179 C14.2,11.3320424 11.5141424,14.0179 8.2,14.0179 C4.88585763,14.0179 2.2,11.3320424 2.2,8.0179 C2.2,4.70375763 4.88585763,2.0179 8.2,2.0179 C9.73531163,2.0179 11.1716793,2.59926473 12.2585,3.59833136 Z" id="icon-redo"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.5 KiB |
19
examples/assets/images/icon-undo.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="13px" height="12px" viewBox="0 0 13 12" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
|
||||
<title>icon-undo</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="theme" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="element-theme-editor" transform="translate(-1092.000000, -167.000000)" fill="#606266" fill-rule="nonzero">
|
||||
<g id="custom" transform="translate(1060.000000, 146.000000)">
|
||||
<g id="Group-2" transform="translate(30.000000, 15.000000)">
|
||||
<g id="Group" transform="translate(0.000000, 4.000000)">
|
||||
<g id="icon-clockwise">
|
||||
<path d="M12.2585,3.59833136 L12.2585,2.3085 L13.2585,2.3085 L13.2585,5.6365 L9.9295,5.6365 L9.9295,4.6365 L11.8833737,4.6365 C10.9510824,3.62012881 9.6272717,3.0179 8.2,3.0179 C5.43814237,3.0179 3.2,5.25604237 3.2,8.0179 C3.2,10.7797576 5.43814237,13.0179 8.2,13.0179 C10.9618576,13.0179 13.2,10.7797576 13.2,8.0179 L14.2,8.0179 C14.2,11.3320424 11.5141424,14.0179 8.2,14.0179 C4.88585763,14.0179 2.2,11.3320424 2.2,8.0179 C2.2,4.70375763 4.88585763,2.0179 8.2,2.0179 C9.73531163,2.0179 11.1716793,2.59926473 12.2585,3.59833136 Z" id="icon-undo" transform="translate(8.200000, 8.017900) scale(-1, 1) translate(-8.200000, -8.017900) "></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.6 KiB |
19
examples/assets/images/icon-upload.svg
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="26px" height="26px" viewBox="0 0 26 26" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 54.1 (76490) - https://sketchapp.com -->
|
||||
<title>icon_upload</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<g id="theme" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="element-theme" transform="translate(-207.000000, -662.000000)" fill="#909399">
|
||||
<g id="section" transform="translate(70.000000, 511.000000)">
|
||||
<g id="card" transform="translate(0.000000, 60.000000)">
|
||||
<g id="btn" transform="translate(108.000000, 91.000000)">
|
||||
<g id="icon-upload" transform="translate(29.000000, 0.000000)">
|
||||
<path d="M13,-0.000600000001 L3.015,9.9854 L4.429,11.3984 L12,3.8284 L12,20.4854 L14.001,20.4854 L14.001,3.8284 L21.572,11.3984 L22.986,9.9854 L14.415,1.4144 L13,-0.000600000001 Z M13,2.8284 L13.158,2.9844 L12.843,2.9844 L13,2.8284 Z M24.001,19.9854 L24.001,23.9854 L2,23.9854 L2,19.9854 L0,19.9854 L0,25.9854 L26.001,25.9854 L26.001,19.9854 L24.001,19.9854 Z" id="icon_upload"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
BIN
examples/assets/images/intro-theme-b.png
Normal file
After Width: | Height: | Size: 34 KiB |
1
examples/assets/images/maximize.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:#1677ff;}.cls-2{fill:none;}</style></defs><title>最大化</title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><path class="cls-1" d="M0,1V15H16V1ZM15,14H1V4H15Z"/><rect class="cls-2" width="16" height="16"/></g></g></svg>
|
After Width: | Height: | Size: 340 B |
1
examples/assets/images/minimize.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><defs><style>.cls-1{fill:none;}.cls-2{fill:#1677ff;}</style></defs><title>最小化</title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><rect class="cls-1" width="16" height="16"/><path class="cls-2" d="M1,1V15H15V1ZM2.57,14.06,6.44,10.2v2.52h.9V8.66H3.28v.9H5.8L1.94,13.43V1.94H13.43L9.56,5.8V3.28h-.9V7.34h4.06v-.9H10.2l3.86-3.87V14.06Z"/></g></g></svg>
|
After Width: | Height: | Size: 448 B |
BIN
examples/assets/images/navbar_0.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
examples/assets/images/navbar_1.png
Normal file
After Width: | Height: | Size: 21 KiB |
BIN
examples/assets/images/navbar_2.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
examples/assets/images/navbar_3.png
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
examples/assets/images/plant-1.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
examples/assets/images/plant-2.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
BIN
examples/assets/images/qrcode.png
Normal file
After Width: | Height: | Size: 12 KiB |
23
examples/assets/images/resource-placeholder.svg
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
examples/assets/images/resource.png
Normal file
After Width: | Height: | Size: 10 KiB |
1
examples/assets/images/search-by-algolia.svg
Normal file
After Width: | Height: | Size: 8.3 KiB |
BIN
examples/assets/images/term-arial.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
examples/assets/images/term-helvetica.png
Normal file
After Width: | Height: | Size: 50 KiB |
BIN
examples/assets/images/term-hiragino.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
examples/assets/images/term-microsoft.png
Normal file
After Width: | Height: | Size: 61 KiB |
BIN
examples/assets/images/term-pingfang.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
examples/assets/images/term-sf.png
Normal file
After Width: | Height: | Size: 53 KiB |
BIN
examples/assets/images/theme-index-blue.png
Normal file
After Width: | Height: | Size: 59 KiB |
1
examples/assets/images/theme-index-icon.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 240"><defs><style>.cls-1{fill:none;}.cls-2{fill:#eff5fd;}.cls-3{fill:#fff;}.cls-4{fill:#26a1ff;}.cls-5{fill:snow;}.cls-6{fill:#fdaca9;}.cls-7{fill:#fd9da0;}.cls-8{fill:#fed5d0;}.cls-9{fill:#ffe8e6;}</style></defs><title>资源 104</title><g id="图层_2" data-name="图层 2"><g id="图层_1-2" data-name="图层 1"><rect class="cls-1" width="320" height="240"/><circle class="cls-2" cx="160" cy="120" r="120"/><path class="cls-3" d="M160,55H105.64A20.64,20.64,0,0,0,85,75.64V200a5,5,0,0,0,5,5h70Z"/><rect class="cls-4" x="95" y="145" width="130" height="40" rx="5"/><path class="cls-5" d="M230,55H160V205h70a5,5,0,0,0,5-5V60A5,5,0,0,0,230,55Z"/><path class="cls-6" d="M220,145H160v40h60a5,5,0,0,0,5-5V150A5,5,0,0,0,220,145Z"/><path class="cls-6" d="M160,99.78a2.5,2.5,0,0,1,0-5c48.71,0,62.17-28.57,62.72-29.79a2.5,2.5,0,1,1,4.56,2C226.69,68.36,212.13,99.78,160,99.78Z"/><path class="cls-2" d="M124.26,171.58V154.4h6.44a7.91,7.91,0,0,1,3.16.52,4,4,0,0,1,1.86,1.6,4.26,4.26,0,0,1,.68,2.27,3.89,3.89,0,0,1-.6,2.08,4.36,4.36,0,0,1-1.8,1.57,4.45,4.45,0,0,1,2.39,1.56,4.15,4.15,0,0,1,.84,2.6,5,5,0,0,1-.51,2.24,4.32,4.32,0,0,1-1.26,1.6,5.18,5.18,0,0,1-1.88.85,11.48,11.48,0,0,1-2.77.29Zm2.27-10h3.72a8.34,8.34,0,0,0,2.16-.2,2.39,2.39,0,0,0,1.31-.86,2.49,2.49,0,0,0,.44-1.5,2.76,2.76,0,0,0-.41-1.5,2,2,0,0,0-1.17-.89,9.84,9.84,0,0,0-2.62-.24h-3.43Zm0,7.93h4.28a10.68,10.68,0,0,0,1.55-.08,3.81,3.81,0,0,0,1.31-.47,2.44,2.44,0,0,0,.86-1,2.92,2.92,0,0,0,.34-1.44,2.84,2.84,0,0,0-.49-1.67,2.56,2.56,0,0,0-1.36-1,8.51,8.51,0,0,0-2.52-.29h-4Z"/><path class="cls-2" d="M148.25,171.58v-1.83a4.55,4.55,0,0,1-3.95,2.11,5.06,5.06,0,0,1-2.06-.42,3.42,3.42,0,0,1-1.42-1.06,4.06,4.06,0,0,1-.65-1.57,11.22,11.22,0,0,1-.13-2v-7.71h2.11V166a11.86,11.86,0,0,0,.13,2.23,2.18,2.18,0,0,0,.84,1.31,2.68,2.68,0,0,0,1.6.47,3.52,3.52,0,0,0,1.78-.48,2.76,2.76,0,0,0,1.18-1.33,6.68,6.68,0,0,0,.34-2.43v-6.67h2.11v12.45Z"/><path class="cls-2" d="M158,169.69l.31,1.86a7.59,7.59,0,0,1-1.6.19,3.64,3.64,0,0,1-1.78-.36,2,2,0,0,1-.89-1,7.55,7.55,0,0,1-.26-2.49v-7.16h-1.54v-1.64h1.54v-3.08l2.1-1.27v4.35H158v1.64h-2.12v7.28a3.83,3.83,0,0,0,.11,1.16.92.92,0,0,0,.37.41,1.38,1.38,0,0,0,.72.15A6,6,0,0,0,158,169.69Z"/><path class="cls-5" d="M167.69,169.69l.3,1.86a7.43,7.43,0,0,1-1.59.19,3.61,3.61,0,0,1-1.78-.36,2,2,0,0,1-.89-1,7.28,7.28,0,0,1-.26-2.49v-7.16h-1.55v-1.64h1.55v-3.08l2.1-1.27v4.35h2.12v1.64h-2.12v7.28a3.51,3.51,0,0,0,.11,1.16.84.84,0,0,0,.36.41,1.43,1.43,0,0,0,.72.15A6.1,6.1,0,0,0,167.69,169.69Z"/><path class="cls-5" d="M169,165.35a6.43,6.43,0,0,1,1.93-5.12,5.79,5.79,0,0,1,3.91-1.38,5.6,5.6,0,0,1,4.2,1.68,6.42,6.42,0,0,1,1.62,4.65,8.25,8.25,0,0,1-.72,3.78,5.13,5.13,0,0,1-2.09,2.14,6.2,6.2,0,0,1-3,.76,5.57,5.57,0,0,1-4.22-1.68A6.65,6.65,0,0,1,169,165.35Zm2.17,0a5.26,5.26,0,0,0,1.05,3.58,3.47,3.47,0,0,0,5.23,0,5.41,5.41,0,0,0,1.05-3.65,5.13,5.13,0,0,0-1.05-3.49,3.48,3.48,0,0,0-5.23,0A5.25,5.25,0,0,0,171.13,165.35Z"/><path class="cls-5" d="M183.1,171.58V159.13H185v1.77a4.46,4.46,0,0,1,4-2.05,5.2,5.2,0,0,1,2.07.41,3.25,3.25,0,0,1,1.41,1.06,4,4,0,0,1,.65,1.55,11.89,11.89,0,0,1,.12,2.06v7.65H191.1V164a5.85,5.85,0,0,0-.24-1.93,2,2,0,0,0-.88-1,2.82,2.82,0,0,0-1.47-.38,3.39,3.39,0,0,0-2.32.85c-.66.57-1,1.66-1,3.25v6.8Z"/><circle class="cls-4" cx="71.9" cy="76.81" r="30"/><path class="cls-3" d="M62.69,68.35h4.89v2.5H59.25V62.53h2.5v3.23a15,15,0,0,1,25.15,11H84.4A12.5,12.5,0,0,0,63.06,68C62.93,68.09,62.81,68.22,62.69,68.35Zm19.36,19.5a15,15,0,0,1-25.15-11h2.5a12.51,12.51,0,0,0,21.34,8.85l.37-.39H76.22v-2.5h8.33v8.32h-2.5Z"/><path class="cls-7" d="M46.94,47.79a2.92,2.92,0,0,1-2.25-1l-7-8.38a2.93,2.93,0,1,1,4.48-3.77L49.17,43a2.92,2.92,0,0,1-.35,4.12A2.88,2.88,0,0,1,46.94,47.79Z"/><path class="cls-8" d="M37.06,59.93h-.25L25.89,59a2.93,2.93,0,0,1,.51-5.83l10.91,1a2.93,2.93,0,0,1-.25,5.84Z"/><path class="cls-8" d="M60.58,40.14l-.25,0A2.93,2.93,0,0,1,57.66,37l.94-10.91a2.93,2.93,0,1,1,5.83.5l-.94,10.91A2.93,2.93,0,0,1,60.58,40.14Z"/><rect class="cls-2" x="99" y="128.31" width="15" height="6.27"/><rect class="cls-2" x="123.56" y="112.59" width="15" height="22"/><rect class="cls-9" x="160" y="106.81" width="7.5" height="27.78"/><rect class="cls-2" x="152.5" y="106.81" width="7.5" height="27.78"/><rect class="cls-9" x="206" y="91.81" width="15" height="42.78"/><rect class="cls-9" x="179.25" y="103.64" width="15" height="30.94"/><path class="cls-4" d="M95,130.81a2.62,2.62,0,0,1-1-.21,2.5,2.5,0,0,1-1.26-3.31C93.31,126,107.88,94.78,160,94.78a2.5,2.5,0,0,1,0,5c-48.91,0-62.59,29.26-62.72,29.56A2.5,2.5,0,0,1,95,130.81Z"/><path class="cls-6" d="M226,63.73a2.5,2.5,0,0,0-3.3,1.26c-.55,1.22-14,29.79-62.72,29.79h0v5h0c52.13,0,66.69-31.42,67.28-32.75A2.5,2.5,0,0,0,226,63.73Z"/></g></g></svg>
|
After Width: | Height: | Size: 4.6 KiB |
BIN
examples/assets/images/theme-index-red.png
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
examples/assets/images/theme-intro.png
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
examples/assets/images/typography.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
examples/assets/images/web.png
Normal file
After Width: | Height: | Size: 9.8 KiB |
169
examples/assets/styles/common.css
Normal file
@@ -0,0 +1,169 @@
|
||||
html, body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
font-family: 'Helvetica Neue',Helvetica,'PingFang SC','Hiragino Sans GB','Microsoft YaHei',SimSun,sans-serif;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
|
||||
&.is-component {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
|
||||
&.is-component {
|
||||
overflow-y: hidden;
|
||||
|
||||
.main-cnt {
|
||||
padding: 0;
|
||||
margin-top: 0;
|
||||
height: 100%;
|
||||
min-height: auto;
|
||||
}
|
||||
|
||||
.headerWrapper {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1500;
|
||||
|
||||
.container {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #409EFF;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
code {
|
||||
background-color: #f9fafc;
|
||||
padding: 0 4px;
|
||||
border: 1px solid #eaeefb;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
button, input, select, textarea {
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
line-height: 1.8;
|
||||
font-family: Menlo, Monaco, Consolas, Courier, monospace;
|
||||
font-size: 12px;
|
||||
padding: 18px 24px;
|
||||
background-color: #fafafa;
|
||||
border: solid 1px #eaeefb;
|
||||
margin-bottom: 25px;
|
||||
border-radius: 4px;
|
||||
-webkit-font-smoothing: auto;
|
||||
}
|
||||
|
||||
.main-cnt {
|
||||
margin-top: -80px;
|
||||
padding: 80px 0 340px;
|
||||
box-sizing: border-box;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.container,
|
||||
.page-container {
|
||||
width: 1140px;
|
||||
padding: 0;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.page-container {
|
||||
padding-top: 55px;
|
||||
|
||||
h2 {
|
||||
font-size: 28px;
|
||||
color: #1f2d3d;
|
||||
margin: 0;
|
||||
}
|
||||
h3 {
|
||||
font-size: 22px;
|
||||
}
|
||||
h2, h3, h4, h5 {
|
||||
font-weight: normal;
|
||||
color: #1f2f3d;
|
||||
|
||||
&:hover a {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
a {
|
||||
float: left;
|
||||
margin-left: -20px;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: .4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
color: #5e6d82;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 8px 16px;
|
||||
background-color: #ECF8FF;
|
||||
border-radius: 4px;
|
||||
border-left: #50bfff 5px solid;
|
||||
margin: 20px 0;
|
||||
|
||||
code {
|
||||
background-color: rgba(255, 255, 255, .7);
|
||||
color: #445368;
|
||||
}
|
||||
}
|
||||
|
||||
.warning {
|
||||
padding: 8px 16px;
|
||||
background-color: #fff6f7;
|
||||
border-radius: 4px;
|
||||
border-left: #FE6C6F 5px solid;
|
||||
margin: 20px 0;
|
||||
|
||||
code {
|
||||
background-color: rgba(255, 255, 255, .7);
|
||||
color: #445368;
|
||||
}
|
||||
}
|
||||
}
|
||||
.demo {
|
||||
margin: 20px 0;
|
||||
}
|
||||
@media (max-width: 1140px) {
|
||||
.container,
|
||||
.page-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.container,
|
||||
.page-container {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
#app.is-component .headerWrapper .container {
|
||||
padding: 0 12px;
|
||||
}
|
||||
}
|
BIN
examples/assets/styles/fonts/icomoon.eot
Normal file
14
examples/assets/styles/fonts/icomoon.svg
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="icomoon" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||
<glyph unicode="" glyph-name="rate-face-off" d="M0 448c0 282.766 229.234 512 512 512s512-229.234 512-512c0-282.766-229.234-512-512-512s-512 229.234-512 512zM947.2 448c0 240.351-194.849 435.2-435.2 435.2s-435.2-194.849-435.2-435.2c0-240.351 194.849-435.2 435.2-435.2s435.2 194.849 435.2 435.2zM294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM361.143 281.6c-22.711 0-41.143-18.637-41.143-41.6s18.432-41.6 41.143-41.6h301.714c22.711 0 41.143 18.637 41.143 41.6s-18.432 41.6-41.143 41.6h-301.714z" />
|
||||
<glyph unicode="" glyph-name="rate-face-1" d="M512.001 960c-282.771 0-512.001-229.23-512.001-512.002 0-282.77 229.23-511.998 512.001-511.998 282.769 0 511.999 229.227 511.999 511.998s-229.23 512.002-511.999 512.002zM294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM694.529 181.197l-3.422 1.216c-56.15 27.872-116.388 42.047-178.882 42.047-64.556 0-125.611-14.316-181.515-42.45l-3.382-1.132c-2.102-0.628-4.945-1.529-8.489-1.529-20.554 0-37.239 18.29-37.239 40.734 0 10.655 4.571 21.361 12.114 29.399l-0.456 2.483 9.516 4.698c66.74 33.104 139.336 50.537 209.907 50.537 71.889 0 142.336-16.984 210.314-50.948 11.943-7.181 19.405-20.953 19.405-35.903 0-26.328-21.71-47.958-47.871-39.153z" />
|
||||
<glyph unicode="" glyph-name="rate-face-2" d="M512-64c-282.766 0-512 229.234-512 512s229.234 512 512 512c282.766 0 512-229.234 512-512s-229.234-512-512-512zM294.4 588.853v-51.307c0-28.482 22.923-51.147 51.2-51.147 28.474 0 51.2 22.899 51.2 51.147v51.307c0 28.482-22.923 51.147-51.2 51.147-28.474 0-51.2-22.899-51.2-51.147zM627.2 588.853v-51.307c0-28.482 22.923-51.147 51.2-51.147 28.474 0 51.2 22.899 51.2 51.147v51.307c0 28.482-22.923 51.147-51.2 51.147-28.474 0-51.2-22.899-51.2-51.147zM361.143 281.6c-22.711 0-41.143-18.637-41.143-41.6s18.432-41.6 41.143-41.6h301.714c22.711 0 41.143 18.637 41.143 41.6s-18.432 41.6-41.143 41.6h-301.714z" />
|
||||
<glyph unicode="" glyph-name="rate-face-3" d="M512.001 960c-282.77 0-512.001-229.23-512.001-511.999s229.23-512.001 512.001-512.001c282.77 0 511.999 229.23 511.999 511.999s-229.229 512.001-511.999 512.001zM817.495 305.565c-0.445-1.485-0.963-2.939-1.569-4.35-0.676-1.572-1.455-3.089-2.317-4.556-55.631-107.613-169.518-181.459-301.323-181.459-0.096 0-0.19 0.002-0.286 0.002s-0.19-0.002-0.286-0.002c-131.804 0-245.693 73.845-301.323 181.459-0.862 1.467-1.641 2.984-2.317 4.556-0.606 1.41-1.124 2.865-1.569 4.35-1.103 3.68-1.705 7.569-1.705 11.597 0 6.566 1.579 12.771 4.372 18.282 6.897 13.601 21.239 22.955 37.822 22.955s30.927-9.355 37.823-22.955h0.676c41.411-81.453 127.131-137.544 226.507-137.652 99.375 0.108 185.095 56.2 226.507 137.652h0.676c6.897 13.601 21.239 22.955 37.823 22.955s30.927-9.355 37.822-22.955c2.794-5.511 4.372-11.715 4.372-18.282 0-4.029-0.602-7.918-1.705-11.597zM627.2 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307zM294.4 588.853c0 28.247 22.726 51.147 51.2 51.147 28.277 0 51.2-22.664 51.2-51.147v-51.307c0-28.247-22.726-51.147-51.2-51.147-28.277 0-51.2 22.664-51.2 51.147v51.307z" />
|
||||
</font></defs></svg>
|
After Width: | Height: | Size: 4.0 KiB |
BIN
examples/assets/styles/fonts/icomoon.ttf
Normal file
BIN
examples/assets/styles/fonts/icomoon.woff
Normal file
39
examples/assets/styles/fonts/style.css
Normal file
@@ -0,0 +1,39 @@
|
||||
@font-face {
|
||||
font-family: 'icomoon';
|
||||
src: url('icomoon.eot?h6xgdm');
|
||||
src: url('icomoon.eot?h6xgdm#iefix') format('embedded-opentype'),
|
||||
url('icomoon.ttf?h6xgdm') format('truetype'),
|
||||
url('icomoon.woff?h6xgdm') format('woff'),
|
||||
url('icomoon.svg?h6xgdm#icomoon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
[class^="icon-"], [class*=" icon-"] {
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: 'icomoon' !important;
|
||||
speak: none;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
text-transform: none;
|
||||
line-height: 1;
|
||||
|
||||
/* Better Font Rendering =========== */
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-rate-face-off:before {
|
||||
content: "\e900";
|
||||
}
|
||||
.icon-rate-face-1:before {
|
||||
content: "\e901";
|
||||
}
|
||||
.icon-rate-face-2:before {
|
||||
content: "\e902";
|
||||
}
|
||||
.icon-rate-face-3:before {
|
||||
content: "\e903";
|
||||
}
|
||||
|
2
examples/bus.js
Normal file
@@ -0,0 +1,2 @@
|
||||
import Vue from 'vue';
|
||||
export default new Vue();
|
18
examples/color.js
Normal 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 }`;
|
||||
}
|
||||
};
|
337
examples/components/demo-block.vue
Normal file
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div
|
||||
class="demo-block"
|
||||
:class="[blockClass, { 'hover': hovering }]"
|
||||
@mouseenter="hovering = true"
|
||||
@mouseleave="hovering = false">
|
||||
<div class="source">
|
||||
<slot name="source"></slot>
|
||||
</div>
|
||||
<div class="meta" ref="meta">
|
||||
<div class="description" v-if="$slots.default">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="highlight">
|
||||
<slot name="highlight"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="demo-block-control"
|
||||
ref="control"
|
||||
:class="{ 'is-fixed': fixedControl }"
|
||||
@click="isExpanded = !isExpanded">
|
||||
<transition name="arrow-slide">
|
||||
<i :class="[iconClass, { 'hovering': hovering }]"></i>
|
||||
</transition>
|
||||
<transition name="text-slide">
|
||||
<span v-show="hovering">{{ controlText }}</span>
|
||||
</transition>
|
||||
<el-tooltip effect="dark" :content="langConfig['tooltip-text']" placement="right">
|
||||
<transition name="text-slide">
|
||||
<el-button
|
||||
v-show="hovering || isExpanded"
|
||||
size="small"
|
||||
type="text"
|
||||
class="control-button"
|
||||
@click.stop="goCodepen">
|
||||
{{ langConfig['button-text'] }}
|
||||
</el-button>
|
||||
</transition>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.demo-block {
|
||||
border: solid 1px #ebebeb;
|
||||
border-radius: 3px;
|
||||
transition: .2s;
|
||||
|
||||
&.hover {
|
||||
box-shadow: 0 0 8px 0 rgba(232, 237, 250, .6), 0 2px 4px 0 rgba(232, 237, 250, .5);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: Menlo, Monaco, Consolas, Courier, monospace;
|
||||
}
|
||||
|
||||
.demo-button {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.source {
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.meta {
|
||||
background-color: #fafafa;
|
||||
border-top: solid 1px #eaeefb;
|
||||
overflow: hidden;
|
||||
height: 0;
|
||||
transition: height .2s;
|
||||
}
|
||||
|
||||
.description {
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
border: solid 1px #ebebeb;
|
||||
border-radius: 3px;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: #666;
|
||||
word-break: break-word;
|
||||
margin: 10px;
|
||||
background-color: #fff;
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
line-height: 26px;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #5e6d82;
|
||||
background-color: #e6effb;
|
||||
margin: 0 4px;
|
||||
display: inline-block;
|
||||
padding: 1px 5px;
|
||||
font-size: 12px;
|
||||
border-radius: 3px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.highlight {
|
||||
pre {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
code.hljs {
|
||||
margin: 0;
|
||||
border: none;
|
||||
max-height: none;
|
||||
border-radius: 0;
|
||||
|
||||
&::before {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.demo-block-control {
|
||||
border-top: solid 1px #eaeefb;
|
||||
height: 44px;
|
||||
box-sizing: border-box;
|
||||
background-color: #fff;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
text-align: center;
|
||||
margin-top: -1px;
|
||||
color: #d3dce6;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
&.is-fixed {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
width: 868px;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 16px;
|
||||
line-height: 44px;
|
||||
transition: .3s;
|
||||
&.hovering {
|
||||
transform: translateX(-40px);
|
||||
}
|
||||
}
|
||||
|
||||
> span {
|
||||
position: absolute;
|
||||
transform: translateX(-30px);
|
||||
font-size: 14px;
|
||||
line-height: 44px;
|
||||
transition: .3s;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
background-color: #f9fafc;
|
||||
}
|
||||
|
||||
& .text-slide-enter,
|
||||
& .text-slide-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateX(10px);
|
||||
}
|
||||
|
||||
.control-button {
|
||||
line-height: 26px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 14px;
|
||||
padding-left: 5px;
|
||||
padding-right: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/babel">
|
||||
import compoLang from '../i18n/component.json';
|
||||
import Element from 'main/index.js';
|
||||
import { stripScript, stripStyle, stripTemplate } from '../util';
|
||||
const { version } = Element;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
codepen: {
|
||||
script: '',
|
||||
html: '',
|
||||
style: ''
|
||||
},
|
||||
hovering: false,
|
||||
isExpanded: false,
|
||||
fixedControl: false,
|
||||
scrollParent: null
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
goCodepen() {
|
||||
// since 2.6.2 use code rather than jsfiddle https://blog.codepen.io/documentation/api/prefill/
|
||||
const { script, html, style } = this.codepen;
|
||||
const resourcesTpl = '<scr' + 'ipt src="//unpkg.com/vue/dist/vue.js"></scr' + 'ipt>' +
|
||||
'\n<scr' + `ipt src="//unpkg.com/element-ui@${ version }/lib/index.js"></scr` + 'ipt>';
|
||||
let jsTpl = (script || '').replace(/export default/, 'var Main =').trim();
|
||||
let htmlTpl = `${resourcesTpl}\n<div id="app">\n${html.trim()}\n</div>`;
|
||||
let cssTpl = `@import url("//unpkg.com/element-ui@${ version }/lib/theme-chalk/index.css");\n${(style || '').trim()}\n`;
|
||||
jsTpl = jsTpl
|
||||
? jsTpl + '\nvar Ctor = Vue.extend(Main)\nnew Ctor().$mount(\'#app\')'
|
||||
: 'new Vue().$mount(\'#app\')';
|
||||
const data = {
|
||||
js: jsTpl,
|
||||
css: cssTpl,
|
||||
html: htmlTpl
|
||||
};
|
||||
const form = document.getElementById('fiddle-form') || document.createElement('form');
|
||||
while (form.firstChild) {
|
||||
form.removeChild(form.firstChild);
|
||||
}
|
||||
form.method = 'POST';
|
||||
form.action = 'https://codepen.io/pen/define/';
|
||||
form.target = '_blank';
|
||||
form.style.display = 'none';
|
||||
|
||||
const input = document.createElement('input');
|
||||
input.setAttribute('name', 'data');
|
||||
input.setAttribute('type', 'hidden');
|
||||
input.setAttribute('value', JSON.stringify(data));
|
||||
|
||||
form.appendChild(input);
|
||||
document.body.appendChild(form);
|
||||
|
||||
form.submit();
|
||||
},
|
||||
|
||||
scrollHandler() {
|
||||
const { top, bottom, left } = this.$refs.meta.getBoundingClientRect();
|
||||
this.fixedControl = bottom > document.documentElement.clientHeight &&
|
||||
top + 44 <= document.documentElement.clientHeight;
|
||||
this.$refs.control.style.left = this.fixedControl ? `${ left }px` : '0';
|
||||
},
|
||||
|
||||
removeScrollHandler() {
|
||||
this.scrollParent && this.scrollParent.removeEventListener('scroll', this.scrollHandler);
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.path.split('/')[1];
|
||||
},
|
||||
|
||||
langConfig() {
|
||||
return compoLang.filter(config => config.lang === this.lang)[0]['demo-block'];
|
||||
},
|
||||
|
||||
blockClass() {
|
||||
return `demo-${ this.lang } demo-${ this.$router.currentRoute.path.split('/').pop() }`;
|
||||
},
|
||||
|
||||
iconClass() {
|
||||
return this.isExpanded ? 'el-icon-caret-top' : 'el-icon-caret-bottom';
|
||||
},
|
||||
|
||||
controlText() {
|
||||
return this.isExpanded ? this.langConfig['hide-text'] : this.langConfig['show-text'];
|
||||
},
|
||||
|
||||
codeArea() {
|
||||
return this.$el.getElementsByClassName('meta')[0];
|
||||
},
|
||||
|
||||
codeAreaHeight() {
|
||||
if (this.$el.getElementsByClassName('description').length > 0) {
|
||||
return this.$el.getElementsByClassName('description')[0].clientHeight +
|
||||
this.$el.getElementsByClassName('highlight')[0].clientHeight + 20;
|
||||
}
|
||||
return this.$el.getElementsByClassName('highlight')[0].clientHeight;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
isExpanded(val) {
|
||||
this.codeArea.style.height = val ? `${ this.codeAreaHeight + 1 }px` : '0';
|
||||
if (!val) {
|
||||
this.fixedControl = false;
|
||||
this.$refs.control.style.left = '0';
|
||||
this.removeScrollHandler();
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.scrollParent = document.querySelector('.page-component__scroll > .el-scrollbar__wrap');
|
||||
this.scrollParent && this.scrollParent.addEventListener('scroll', this.scrollHandler);
|
||||
this.scrollHandler();
|
||||
}, 200);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
const highlight = this.$slots.highlight;
|
||||
if (highlight && highlight[0]) {
|
||||
let code = '';
|
||||
let cur = highlight[0];
|
||||
if (cur.tag === 'pre' && (cur.children && cur.children[0])) {
|
||||
cur = cur.children[0];
|
||||
if (cur.tag === 'code') {
|
||||
code = cur.children[0].text;
|
||||
}
|
||||
}
|
||||
if (code) {
|
||||
this.codepen.html = stripTemplate(code);
|
||||
this.codepen.script = stripScript(code);
|
||||
this.codepen.style = stripStyle(code);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
let highlight = this.$el.getElementsByClassName('highlight')[0];
|
||||
if (this.$el.getElementsByClassName('description').length === 0) {
|
||||
highlight.style.width = '100%';
|
||||
highlight.borderRight = 'none';
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
this.removeScrollHandler();
|
||||
}
|
||||
};
|
||||
</script>
|
121
examples/components/footer-nav.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="footer-nav">
|
||||
<span
|
||||
v-if="leftNav"
|
||||
class="footer-nav-link footer-nav-left"
|
||||
@click="handleNavClick('prev')">
|
||||
<i class="el-icon-arrow-left"></i>
|
||||
{{ leftNav.title || leftNav.name }}
|
||||
</span>
|
||||
<span
|
||||
v-if="rightNav"
|
||||
class="footer-nav-link footer-nav-right"
|
||||
@click="handleNavClick('next')">
|
||||
{{ rightNav.title || rightNav.name }}
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.footer-nav {
|
||||
padding: 40px 0;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
& i {
|
||||
transition: .3s;
|
||||
color: #999;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
|
||||
.footer-nav-link {
|
||||
cursor: pointer;
|
||||
transition: .3s;
|
||||
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
|
||||
& i {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-nav-left {
|
||||
float: left;
|
||||
margin-left: -4px;
|
||||
}
|
||||
|
||||
.footer-nav-right {
|
||||
float: right;
|
||||
margin-right: -4px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import navConfig from '../nav.config.json';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
currentComponent: null,
|
||||
nav: [],
|
||||
currentIndex: -1,
|
||||
leftNav: null,
|
||||
rightNav: null
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.meta.lang;
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
'$route.path'() {
|
||||
this.setNav();
|
||||
this.updateNav();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
setNav() {
|
||||
let nav = navConfig[this.lang];
|
||||
this.nav = [nav[0]].concat(nav[3].children);
|
||||
nav[4].groups.map(group => group.list).forEach(list => {
|
||||
this.nav = this.nav.concat(list);
|
||||
});
|
||||
},
|
||||
|
||||
updateNav() {
|
||||
this.currentComponent = '/' + this.$route.path.split('/')[3];
|
||||
for (let i = 0, len = this.nav.length; i < len; i++) {
|
||||
if (this.nav[i].path === this.currentComponent) {
|
||||
this.currentIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.leftNav = this.nav[this.currentIndex - 1];
|
||||
this.rightNav = this.nav[this.currentIndex + 1];
|
||||
},
|
||||
|
||||
handleNavClick(direction) {
|
||||
this.$router.push(`/${ this.lang }/component${ direction === 'prev' ? this.leftNav.path : this.rightNav.path }`);
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.setNav();
|
||||
this.updateNav();
|
||||
}
|
||||
};
|
||||
</script>
|
188
examples/components/footer.vue
Normal file
@@ -0,0 +1,188 @@
|
||||
<template>
|
||||
<footer class="footer">
|
||||
<div class="container">
|
||||
<div class="footer-main">
|
||||
<h4>{{ langConfig.links }}</h4>
|
||||
<a href="https://github.com/ElemeFE/element" class="footer-main-link" target="_blank">{{ langConfig.repo }}</a>
|
||||
<a href="https://github.com/ElemeFE/element/releases" class="footer-main-link" target="_blank">{{ langConfig.changelog }}</a>
|
||||
<a href="https://github.com/ElemeFE/element/blob/dev/FAQ.md" class="footer-main-link" target="_blank">{{ langConfig.faq }}</a>
|
||||
<a href="https://github.com/ElementUI/element-starter" class="footer-main-link" target="_blank">{{ langConfig.starter }}</a>
|
||||
<a :href="'/#/' + lang + '/component/custom-theme'" class="footer-main-link" target="_blank">{{ langConfig.theme }}</a>
|
||||
<a href="https://github.com/elemefe/element-react" class="footer-main-link" target="_blank">Element-React</a>
|
||||
<a href="https://github.com/ElemeFE/element-angular" class="footer-main-link" target="_blank">Element-Angular</a>
|
||||
</div>
|
||||
<div class="footer-main">
|
||||
<h4>{{ langConfig.community }}</h4>
|
||||
<a :href="gitterLink" class="footer-main-link" target="_blank">{{ langConfig.gitter }}</a>
|
||||
<a href="https://github.com/ElemeFE/element/issues" class="footer-main-link" target="_blank">{{ langConfig.feedback }}</a>
|
||||
<a :href="`https://github.com/ElemeFE/element/blob/master/.github/CONTRIBUTING.${ lang }.md`" class="footer-main-link" target="_blank">{{ langConfig.contribution }}</a>
|
||||
<a href="https://segmentfault.com/t/element-ui" class="footer-main-link" target="_blank">SegmentFault</a>
|
||||
<a href="https://github.com/ElementUI/awesome-element" class="footer-main-link" target="_blank">Awesome Element</a>
|
||||
</div>
|
||||
<div class="footer-social">
|
||||
<p class="footer-social-title">Element {{ version && version.slice(0, 3) }} Fullerene</p>
|
||||
<el-popover
|
||||
ref="weixin"
|
||||
placement="top"
|
||||
width="120"
|
||||
popper-class="footer-popover"
|
||||
trigger="hover">
|
||||
<div class="footer-popover-title">{{ langConfig.eleme }} UED</div>
|
||||
<img src="../assets/images/qrcode.png" alt="">
|
||||
</el-popover>
|
||||
<i class="doc-icon-weixin elementdoc" v-popover:weixin></i>
|
||||
<a href="https://github.com/elemefe" target="_blank">
|
||||
<i class="doc-icon-github elementdoc"></i>
|
||||
</a>
|
||||
<a :href="gitterLink" target="_blank">
|
||||
<i class="doc-icon-gitter elementdoc"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.footer {
|
||||
background-color: #F7FBFD;
|
||||
width: 100%;
|
||||
padding: 40px 150px;
|
||||
margin-top: -340px;
|
||||
box-sizing: border-box;
|
||||
height: 340px;
|
||||
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.footer-main {
|
||||
font-size: 0;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-right: 110px;
|
||||
|
||||
h4 {
|
||||
font-size: 18px;
|
||||
color: #333;
|
||||
line-height: 1;
|
||||
margin: 0 0 15px 0;
|
||||
}
|
||||
|
||||
.footer-main-link {
|
||||
display: block;
|
||||
margin: 0;
|
||||
line-height: 2;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
|
||||
&:hover {
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-social {
|
||||
float: right;
|
||||
text-align: right;
|
||||
|
||||
.footer-social-title {
|
||||
color: #666;
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
margin: 0 0 20px 0;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.elementdoc {
|
||||
transition: .3s;
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
color: #c8d6e8;
|
||||
background-color: transparent;
|
||||
size: 32px;
|
||||
font-size: 32px;
|
||||
vertical-align: middle;
|
||||
margin-right: 20px;
|
||||
&:hover {
|
||||
transform: scale(1.2);
|
||||
color: #8D99AB;
|
||||
}
|
||||
}
|
||||
|
||||
.doc-icon-gitter {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-popover.footer-popover {
|
||||
padding: 0;
|
||||
min-width: 120px;
|
||||
line-height: normal;
|
||||
box-shadow: 0 0 11px 0 rgba(174, 187, 211, 0.24);
|
||||
|
||||
.footer-popover-title {
|
||||
border-bottom: solid 1px #eaeefb;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
color: #99a9bf;
|
||||
background-color: #f8f9fe;
|
||||
}
|
||||
|
||||
img {
|
||||
size: 100px;
|
||||
margin: 10px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 1140px) {
|
||||
.footer {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.footer-social {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.footer {
|
||||
.footer-main {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/babel">
|
||||
import compoLang from '../i18n/component.json';
|
||||
import Element from 'main/index.js';
|
||||
const { version } = Element;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
version
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.path.split('/')[1] || 'zh-CN';
|
||||
},
|
||||
|
||||
langConfig() {
|
||||
return compoLang.filter(config => config.lang === this.lang)[0]['footer'];
|
||||
},
|
||||
|
||||
gitterLink() {
|
||||
return this.lang === 'zh-CN' ? 'https://gitter.im/ElemeFE/element' : 'https://gitter.im/element-en/Lobby';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
524
examples/components/header.vue
Normal file
@@ -0,0 +1,524 @@
|
||||
<style lang="scss" scoped>
|
||||
.headerWrapper {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
#v3-banner {
|
||||
background-color: #409EFF;
|
||||
min-height: 30px;
|
||||
padding: 5px 60px;
|
||||
z-index: 19;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
color: #eee;
|
||||
}
|
||||
|
||||
#v3-banner a {
|
||||
color: #FFF;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 80px;
|
||||
background-color: #fff;
|
||||
color: #fff;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
line-height: 80px;
|
||||
z-index: 100;
|
||||
position: relative;
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 1px solid #DCDFE6;
|
||||
}
|
||||
|
||||
.nav-lang-spe {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
float: left;
|
||||
font-size: 32px;
|
||||
font-weight: normal;
|
||||
|
||||
a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
display: inline-block;
|
||||
width: 34px;
|
||||
height: 18px;
|
||||
border: 1px solid rgba(255, 255, 255, .5);
|
||||
text-align: center;
|
||||
line-height: 18px;
|
||||
vertical-align: middle;
|
||||
margin-left: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav {
|
||||
float: right;
|
||||
height: 100%;
|
||||
line-height: 80px;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
&::before, &::after {
|
||||
display: table;
|
||||
content: "";
|
||||
}
|
||||
&::after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-gap {
|
||||
position: relative;
|
||||
width: 1px;
|
||||
height: 80px;
|
||||
padding: 0 20px;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: calc(50% - 8px);
|
||||
width: 1px;
|
||||
height: 16px;
|
||||
background: #ebebeb;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-logo,
|
||||
.nav-logo-small {
|
||||
vertical-align: sub;
|
||||
}
|
||||
|
||||
.nav-logo-small {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
margin: 0;
|
||||
float: left;
|
||||
list-style: none;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
&.nav-algolia-search {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
&.lang-item,
|
||||
&:last-child {
|
||||
cursor: default;
|
||||
margin-left: 34px;
|
||||
|
||||
span {
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.nav-lang {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
color: #888;
|
||||
|
||||
&:hover {
|
||||
color: #409EFF;
|
||||
}
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #1989FA;
|
||||
opacity: 0.5;
|
||||
display: block;
|
||||
padding: 0 22px;
|
||||
|
||||
&.active,
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&.active::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: calc(50% - 15px);
|
||||
width: 30px;
|
||||
height: 2px;
|
||||
background: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-dropdown {
|
||||
margin-bottom: 6px;
|
||||
padding-left: 18px;
|
||||
width: 100%;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
color: #888;
|
||||
line-height: 40px;
|
||||
transition: .2s;
|
||||
padding-bottom: 6px;
|
||||
user-select: none;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
transition: .2s;
|
||||
font-size: 12px;
|
||||
color: #979797;
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.is-active {
|
||||
span, i {
|
||||
color: #409EFF;
|
||||
}
|
||||
i {
|
||||
transform: rotateZ(180deg) translateY(3px);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
span, i {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-dropdown-list {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 850px) {
|
||||
.header {
|
||||
.nav-logo {
|
||||
display: none;
|
||||
}
|
||||
.nav-logo-small {
|
||||
display: inline-block;
|
||||
}
|
||||
.nav-item {
|
||||
margin-left: 6px;
|
||||
|
||||
&.lang-item,
|
||||
&:last-child {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
a {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
.nav-theme-switch, .nav-algolia-search {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.header {
|
||||
.container {
|
||||
padding: 0 12px;
|
||||
}
|
||||
.nav-item {
|
||||
a {
|
||||
font-size: 12px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&.lang-item {
|
||||
height: 100%;
|
||||
|
||||
.nav-lang {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.nav-dropdown {
|
||||
padding: 0;
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
.nav-gap {
|
||||
padding: 0 8px;
|
||||
}
|
||||
.nav-versions {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="headerWrapper">
|
||||
<div id="v3-banner" v-if="isHome">
|
||||
<template v-if="lang === 'zh-CN'">
|
||||
您正在浏览基于 Vue 2.x 的 Element UI 文档;
|
||||
<a href="https://element-plus.org/#/zh-CN">点击这里</a> 查看 Vue 3.x 的升级版本
|
||||
</template>
|
||||
<template v-else>
|
||||
You’re browsing the documentation of Element UI for Vue 2.x version.
|
||||
<a href="https://element-plus.org">Click here</a> for Vue 3.x version
|
||||
</template>
|
||||
</div>
|
||||
<header class="header" ref="header">
|
||||
<div class="container">
|
||||
<h1><router-link :to="`/${ lang }`">
|
||||
<!-- logo -->
|
||||
<slot>
|
||||
<img
|
||||
src="../assets/images/element-logo.svg"
|
||||
alt="element-logo"
|
||||
class="nav-logo">
|
||||
<img
|
||||
src="../assets/images/element-logo-small.svg"
|
||||
alt="element-logo"
|
||||
class="nav-logo-small">
|
||||
</slot>
|
||||
|
||||
</router-link></h1>
|
||||
|
||||
<!-- nav -->
|
||||
<ul class="nav">
|
||||
<li class="nav-item nav-algolia-search" v-show="isComponentPage">
|
||||
<algolia-search></algolia-search>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="`/${ lang }/guide`">{{ langConfig.guide }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="`/${ lang }/component`">{{ langConfig.components }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
class="nav-item nav-item-theme"
|
||||
>
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="`/${ lang }/theme`">{{ langConfig.theme }}
|
||||
</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="`/${ lang }/resource`"
|
||||
exact>{{ langConfig.resource }}
|
||||
</router-link>
|
||||
</li>
|
||||
|
||||
<!-- gap -->
|
||||
<li class="nav-item" v-show="isComponentPage">
|
||||
<div class="nav-gap"></div>
|
||||
</li>
|
||||
|
||||
<!-- 版本选择器 -->
|
||||
<li class="nav-item nav-versions" v-show="isComponentPage">
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
class="nav-dropdown"
|
||||
:class="{ 'is-active': verDropdownVisible }">
|
||||
<span>
|
||||
{{ version }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu
|
||||
slot="dropdown"
|
||||
class="nav-dropdown-list"
|
||||
@input="handleVerDropdownToggle">
|
||||
<el-dropdown-item
|
||||
v-for="item in Object.keys(versions)"
|
||||
:key="item"
|
||||
@click.native="switchVersion(item)">
|
||||
{{ item }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</li>
|
||||
|
||||
<!-- 语言选择器 -->
|
||||
<li class="nav-item lang-item">
|
||||
<el-dropdown
|
||||
trigger="click"
|
||||
class="nav-dropdown nav-lang"
|
||||
:class="{ 'is-active': langDropdownVisible }">
|
||||
<span>
|
||||
{{ displayedLang }}
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</span>
|
||||
<el-dropdown-menu
|
||||
slot="dropdown"
|
||||
class="nav-dropdown-list"
|
||||
@input="handleLangDropdownToggle">
|
||||
<el-dropdown-item
|
||||
v-for="(value, key) in langs"
|
||||
:key="key"
|
||||
@click.native="switchLang(key)">
|
||||
{{ value }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import ThemePicker from './theme-picker.vue';
|
||||
import AlgoliaSearch from './search.vue';
|
||||
import compoLang from '../i18n/component.json';
|
||||
import Element from 'main/index.js';
|
||||
import themeLoader from './theme/loader';
|
||||
import { getTestEle } from './theme/loader/api.js';
|
||||
import bus from '../bus';
|
||||
import { ACTION_USER_CONFIG_UPDATE } from './theme/constant.js';
|
||||
|
||||
const { version } = Element;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
active: '',
|
||||
versions: [],
|
||||
version,
|
||||
verDropdownVisible: true,
|
||||
langDropdownVisible: true,
|
||||
langs: {
|
||||
'zh-CN': '中文',
|
||||
'en-US': 'English',
|
||||
'es': 'Español',
|
||||
'fr-FR': 'Français'
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
mixins: [themeLoader],
|
||||
|
||||
components: {
|
||||
ThemePicker,
|
||||
AlgoliaSearch
|
||||
},
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.path.split('/')[1] || 'zh-CN';
|
||||
},
|
||||
displayedLang() {
|
||||
return this.langs[this.lang] || '中文';
|
||||
},
|
||||
langConfig() {
|
||||
return compoLang.filter(config => config.lang === this.lang)[0]['header'];
|
||||
},
|
||||
isComponentPage() {
|
||||
return /^component/.test(this.$route.name);
|
||||
},
|
||||
isHome() {
|
||||
return /^home/.test(this.$route.name);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
getTestEle()
|
||||
.then(() => {
|
||||
this.$isEle = true;
|
||||
ga('send', 'event', 'DocView', 'Ele', 'Inner');
|
||||
})
|
||||
.catch((err) => {
|
||||
ga('send', 'event', 'DocView', 'Ele', 'Outer');
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
const testInnerImg = new Image();
|
||||
testInnerImg.onload = () => {
|
||||
this.$isEle = true;
|
||||
ga('send', 'event', 'DocView', 'Ali', 'Inner');
|
||||
};
|
||||
testInnerImg.onerror = (err) => {
|
||||
ga('send', 'event', 'DocView', 'Ali', 'Outer');
|
||||
console.error(err);
|
||||
};
|
||||
testInnerImg.src = `https://private-alipayobjects.alipay.com/alipay-rmsdeploy-image/rmsportal/VmvVUItLdPNqKlNGuRHi.png?t=${Date.now()}`;
|
||||
},
|
||||
methods: {
|
||||
switchVersion(version) {
|
||||
if (version === this.version) return;
|
||||
location.href = `${ location.origin }/${ this.versions[version] }/${ location.hash } `;
|
||||
},
|
||||
|
||||
switchLang(targetLang) {
|
||||
if (this.lang === targetLang) return;
|
||||
localStorage.setItem('ELEMENT_LANGUAGE', targetLang);
|
||||
this.$router.push(this.$route.path.replace(this.lang, targetLang));
|
||||
},
|
||||
|
||||
handleVerDropdownToggle(visible) {
|
||||
this.verDropdownVisible = visible;
|
||||
},
|
||||
|
||||
handleLangDropdownToggle(visible) {
|
||||
this.langDropdownVisible = visible;
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = _ => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
const versions = JSON.parse(xhr.responseText);
|
||||
this.versions = Object.keys(versions).reduce((prev, next) => {
|
||||
prev[next] = versions[next];
|
||||
return prev;
|
||||
}, {});
|
||||
}
|
||||
};
|
||||
xhr.open('GET', '/versions.json');
|
||||
xhr.send();
|
||||
let primaryLast = '#409EFF';
|
||||
bus.$on(ACTION_USER_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>
|
222
examples/components/search.vue
Normal file
@@ -0,0 +1,222 @@
|
||||
<template>
|
||||
<el-autocomplete
|
||||
v-model="query"
|
||||
size="small"
|
||||
:popper-class="`algolia-search${ isEmpty ? ' is-empty' : '' }`"
|
||||
:fetch-suggestions="querySearch"
|
||||
:placeholder="placeholder"
|
||||
:trigger-on-focus="false"
|
||||
@select="handleSelect"
|
||||
highlight-first-item>
|
||||
<template slot-scope="props">
|
||||
<p class="algolia-search-title" v-if="props.item.title">
|
||||
<span v-html="props.item.highlightedCompo"></span>
|
||||
<span class="algolia-search-separator"></span>
|
||||
<span v-html="props.item.title"></span>
|
||||
</p>
|
||||
<p
|
||||
class="algolia-search-content"
|
||||
v-if="props.item.content"
|
||||
v-html="props.item.content"></p>
|
||||
<a
|
||||
class="algolia-search-link"
|
||||
v-if="props.item.img"
|
||||
target="_blank"
|
||||
href="https://www.algolia.com/docsearch">
|
||||
<img
|
||||
class="algolia-search-logo"
|
||||
src="../assets/images/search-by-algolia.svg"
|
||||
alt="algolia-logo">
|
||||
</a>
|
||||
<p
|
||||
class="algolia-search-empty"
|
||||
v-if="props.item.isEmpty">{{ emptyText }}</p>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.algolia-search {
|
||||
width: 450px !important;
|
||||
|
||||
&.is-empty {
|
||||
.el-autocomplete-suggestion__list {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-autocomplete-suggestion__list {
|
||||
position: static !important;
|
||||
padding-bottom: 28px;
|
||||
}
|
||||
|
||||
li {
|
||||
border-bottom: solid 1px #ebebeb;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.algolia-highlight {
|
||||
color: #409EFF;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.algolia-search-title {
|
||||
font-size: 14px;
|
||||
margin: 6px 0;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.algolia-search-separator {
|
||||
padding: 0 6px;
|
||||
}
|
||||
|
||||
.algolia-search-content {
|
||||
font-size: 12px;
|
||||
margin: 6px 0;
|
||||
line-height: 2.4;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.algolia-search-link {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding-right: 20px;
|
||||
background-color: #e4e7ed;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
|
||||
&:hover {
|
||||
background-color: #e4e7ed;
|
||||
}
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
height: 17px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.algolia-search-empty {
|
||||
margin: 5px 0;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import algoliasearch from 'algoliasearch';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
index: null,
|
||||
query: '',
|
||||
isEmpty: false,
|
||||
langs: {
|
||||
'zh-CN': {
|
||||
search: '搜索文档',
|
||||
empty: '无匹配结果',
|
||||
index: 'zh'
|
||||
},
|
||||
'en-US': {
|
||||
search: 'Search',
|
||||
empty: 'No results',
|
||||
index: 'en'
|
||||
},
|
||||
'es': {
|
||||
search: 'Buscar',
|
||||
empty: 'No hay datos que coincidan',
|
||||
index: 'es'
|
||||
},
|
||||
'fr-FR': {
|
||||
search: 'Rechercher',
|
||||
empty: 'Aucun résultat',
|
||||
index: 'fr'
|
||||
}
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
lang() {
|
||||
return this.$route.meta.lang;
|
||||
},
|
||||
|
||||
placeholder() {
|
||||
return this.lang ? this.langs[this.lang].search : '';
|
||||
},
|
||||
|
||||
emptyText() {
|
||||
return this.lang ? this.langs[this.lang].empty : '';
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
lang() {
|
||||
this.initIndex();
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
initIndex() {
|
||||
const client = algoliasearch('4C63BTGP6S', '0729c3c7f4dc8db7395ad0b19c0748d2');
|
||||
this.index = client.initIndex(`element-${ this.lang ? this.langs[this.lang].index : 'zh' }`);
|
||||
},
|
||||
|
||||
querySearch(query, cb) {
|
||||
if (!query) return;
|
||||
this.index.search({ query, hitsPerPage: 6 }, (err, res) => {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
if (res.hits.length > 0) {
|
||||
this.isEmpty = false;
|
||||
cb(res.hits.map(hit => {
|
||||
let content = hit._highlightResult.content.value.replace(/\s+/g, ' ');
|
||||
const highlightStart = content.indexOf('<span class="algolia-highlight">');
|
||||
if (highlightStart > -1) {
|
||||
const startEllipsis = highlightStart - 15 > 0;
|
||||
content = (startEllipsis ? '...' : '') +
|
||||
content.slice(Math.max(0, highlightStart - 15), content.length);
|
||||
} else if (content.indexOf('|') > -1) {
|
||||
content = '';
|
||||
}
|
||||
return {
|
||||
anchor: hit.anchor,
|
||||
component: hit.component,
|
||||
highlightedCompo: hit._highlightResult.component.value,
|
||||
title: hit._highlightResult.title.value,
|
||||
content
|
||||
};
|
||||
}).concat({ img: true }));
|
||||
} else {
|
||||
this.isEmpty = true;
|
||||
cb([{ isEmpty: true }]);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
handleSelect(val) {
|
||||
if (val.img || val.isEmpty) return;
|
||||
const component = val.component || '';
|
||||
const anchor = val.anchor;
|
||||
this.$router.push(`/${ this.lang }/component/${ component }${ anchor ? `#${ anchor }` : '' }`);
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.initIndex();
|
||||
}
|
||||
};
|
||||
</script>
|
274
examples/components/side-nav.vue
Normal file
@@ -0,0 +1,274 @@
|
||||
<style lang="scss">
|
||||
.side-nav {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-right: 30px;
|
||||
transition: opacity .3s;
|
||||
&.is-fade {
|
||||
transition: opacity 3s;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
> ul > .nav-item > a {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
> ul > .nav-item:nth-child(-n + 4) > a {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
a {
|
||||
font-size: 16px;
|
||||
color: #333;
|
||||
line-height: 40px;
|
||||
height: 40px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
position: relative;
|
||||
transition: .15s ease-out;
|
||||
font-weight: bold;
|
||||
|
||||
&.active {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
a {
|
||||
display: block;
|
||||
height: 40px;
|
||||
color: #444;
|
||||
line-height: 40px;
|
||||
font-size: 14px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: normal;
|
||||
|
||||
&:hover,
|
||||
&.active {
|
||||
color: #409EFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.sponsors {
|
||||
& > .sub-nav {
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
& > a {
|
||||
color: #777;
|
||||
font-weight: 300;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
display: inline-block;
|
||||
|
||||
a {
|
||||
height: auto;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 8px 12px 12px 0;
|
||||
|
||||
img {
|
||||
width: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
&:first-child a img {
|
||||
width: 36px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.nav-group__title {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
line-height: 26px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#code-sponsor-widget {
|
||||
margin: 0 0 0 -20px;
|
||||
}
|
||||
}
|
||||
.nav-dropdown-list {
|
||||
width: 120px;
|
||||
margin-top: -8px;
|
||||
li {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div
|
||||
class="side-nav"
|
||||
@mouseenter="isFade = false"
|
||||
:class="{ 'is-fade': isFade }"
|
||||
:style="navStyle">
|
||||
<ul>
|
||||
<li
|
||||
class="nav-item"
|
||||
v-for="(item, key) in data"
|
||||
:key="key">
|
||||
<a v-if="!item.path && !item.href" @click="expandMenu">{{item.name}}</a>
|
||||
<a v-if="item.href" :href="item.href" target="_blank">{{item.name}}</a>
|
||||
<router-link
|
||||
v-if="item.path"
|
||||
active-class="active"
|
||||
:to="base + item.path"
|
||||
exact
|
||||
v-text="item.title || item.name">
|
||||
</router-link>
|
||||
<ul class="pure-menu-list sub-nav" v-if="item.children">
|
||||
<li
|
||||
class="nav-item"
|
||||
v-for="(navItem, key) in item.children"
|
||||
:key="key">
|
||||
<router-link
|
||||
class=""
|
||||
active-class="active"
|
||||
:to="base + navItem.path"
|
||||
exact
|
||||
v-text="navItem.title || navItem.name">
|
||||
</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<template v-if="item.groups">
|
||||
<div
|
||||
class="nav-group"
|
||||
v-for="(group, key) in item.groups"
|
||||
:key="key"
|
||||
>
|
||||
<div class="nav-group__title" @click="expandMenu">{{group.groupName}}</div>
|
||||
<ul class="pure-menu-list">
|
||||
<li
|
||||
class="nav-item"
|
||||
v-for="(navItem, key) in group.list"
|
||||
v-show="!navItem.disabled"
|
||||
:key="key">
|
||||
<router-link
|
||||
active-class="active"
|
||||
:to="base + navItem.path"
|
||||
exact
|
||||
v-text="navItem.title"></router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
<!--<div id="code-sponsor-widget"></div>-->
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import bus from '../bus';
|
||||
import compoLang from '../i18n/component.json';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
data: Array,
|
||||
base: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
highlights: [],
|
||||
navState: [],
|
||||
isSmallScreen: false,
|
||||
isFade: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
'$route.path'() {
|
||||
this.handlePathChange();
|
||||
},
|
||||
isFade(val) {
|
||||
bus.$emit('navFade', val);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
navStyle() {
|
||||
const style = {};
|
||||
if (this.isSmallScreen) {
|
||||
style.paddingBottom = '60px';
|
||||
}
|
||||
style.opacity = this.isFade ? '0.5' : '1';
|
||||
return style;
|
||||
},
|
||||
lang() {
|
||||
return this.$route.meta.lang;
|
||||
},
|
||||
langConfig() {
|
||||
return compoLang.filter(config => config.lang === this.lang)[0]['nav'];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleResize() {
|
||||
this.isSmallScreen = document.documentElement.clientWidth < 768;
|
||||
this.handlePathChange();
|
||||
},
|
||||
handlePathChange() {
|
||||
if (!this.isSmallScreen) {
|
||||
this.expandAllMenu();
|
||||
return;
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.hideAllMenu();
|
||||
let activeAnchor = this.$el.querySelector('a.active');
|
||||
let ul = activeAnchor.parentNode;
|
||||
while (ul.tagName !== 'UL') {
|
||||
ul = ul.parentNode;
|
||||
}
|
||||
ul.style.height = 'auto';
|
||||
});
|
||||
},
|
||||
hideAllMenu() {
|
||||
[].forEach.call(this.$el.querySelectorAll('.pure-menu-list'), ul => {
|
||||
ul.style.height = '0';
|
||||
});
|
||||
},
|
||||
expandAllMenu() {
|
||||
[].forEach.call(this.$el.querySelectorAll('.pure-menu-list'), ul => {
|
||||
ul.style.height = 'auto';
|
||||
});
|
||||
},
|
||||
expandMenu(event) {
|
||||
if (!this.isSmallScreen) return;
|
||||
let target = event.currentTarget;
|
||||
if (!target.nextElementSibling || target.nextElementSibling.tagName !== 'UL') return;
|
||||
this.hideAllMenu();
|
||||
event.currentTarget.nextElementSibling.style.height = 'auto';
|
||||
}
|
||||
},
|
||||
created() {
|
||||
bus.$on('fadeNav', () => {
|
||||
this.isFade = true;
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.handleResize();
|
||||
window.addEventListener('resize', this.handleResize);
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.handleResize);
|
||||
}
|
||||
};
|
||||
</script>
|
153
examples/components/theme-configurator/action.vue
Normal file
@@ -0,0 +1,153 @@
|
||||
<template>
|
||||
<div class="configurator-action">
|
||||
<div class="action-group">
|
||||
<el-tooltip :content="getActionDisplayName('undo')">
|
||||
<img
|
||||
src="../../assets/images/icon-undo.svg"
|
||||
@click="onUndo"
|
||||
:class="{ 'active': userConfigHistory.length > 0 }"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<el-tooltip :content="getActionDisplayName('redo')">
|
||||
<img
|
||||
src="../../assets/images/icon-redo.svg"
|
||||
@click="onRedo"
|
||||
:class="{ 'active': userConfigRedoHistory.length > 0 }"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<div class="button-group">
|
||||
<el-button
|
||||
class="reset"
|
||||
type="primary"
|
||||
round
|
||||
size="mini"
|
||||
:disabled="isOfficial"
|
||||
@click="onReset"
|
||||
>
|
||||
{{getActionDisplayName('reset-theme')}}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="download"
|
||||
type="primary"
|
||||
round
|
||||
size="mini"
|
||||
:disabled="downloadDisabled"
|
||||
@click="onDownload"
|
||||
>
|
||||
{{getActionDisplayName('download-theme')}}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<el-select v-model="selectedComponent" class="selector">
|
||||
<el-option
|
||||
v-for="item in selectOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="line"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.configurator-action {
|
||||
padding: 15px 18px 0;
|
||||
.action-group {
|
||||
padding: 5px 0;
|
||||
img {
|
||||
cursor: not-allowed;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
padding: 7px 0;
|
||||
margin-left: 5px;
|
||||
opacity: .5;
|
||||
&.active {
|
||||
opacity: 1;
|
||||
cursor: pointer;
|
||||
}
|
||||
&:last-of-type {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.button-group {
|
||||
float: right;
|
||||
.el-button {
|
||||
padding: 6px 15px;
|
||||
&.is-disabled {
|
||||
color: #C0C4CC;
|
||||
background-color: #fff;
|
||||
border-color: #EBEEF5;
|
||||
}
|
||||
}
|
||||
.reset {
|
||||
background: #E6F1FC;
|
||||
color: #1989FA;
|
||||
border-color: #A2CFFC;
|
||||
}
|
||||
.download {
|
||||
background: #1989FA;
|
||||
color: #FFF;
|
||||
border-color: #1989FA
|
||||
}
|
||||
}
|
||||
}
|
||||
.selector {
|
||||
width: 100%;
|
||||
input {
|
||||
background: #f5f7fa;
|
||||
border: none;
|
||||
font-size: 18px;
|
||||
padding-left: 0;
|
||||
color: #606266;
|
||||
}
|
||||
}
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
border-bottom: 1px solid #DCDFE6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import { getActionDisplayName } from './utils/utils';
|
||||
export default {
|
||||
props: {
|
||||
selectOptions: Array,
|
||||
userConfigHistory: Array,
|
||||
userConfigRedoHistory: Array,
|
||||
isOfficial: Boolean,
|
||||
onUndo: Function,
|
||||
onRedo: Function
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selectedComponent: 'color',
|
||||
downloadDisabled: false
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
selectedComponent: {
|
||||
handler(val) {
|
||||
this.$emit('select', val);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getActionDisplayName(key) {
|
||||
return getActionDisplayName(key);
|
||||
},
|
||||
onReset() {
|
||||
this.$parent.onReset();
|
||||
},
|
||||
onDownload() {
|
||||
this.downloadDisabled = true;
|
||||
this.$parent.onDownload();
|
||||
setTimeout(() => {
|
||||
this.downloadDisabled = false;
|
||||
}, 2500);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<theme-input
|
||||
v-if="isGlobal"
|
||||
:val="value"
|
||||
@change="onChange"
|
||||
></theme-input>
|
||||
<el-select
|
||||
size="medium"
|
||||
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>
|
158
examples/components/theme-configurator/editor/boxShadow.vue
Normal file
@@ -0,0 +1,158 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
<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%;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.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>
|
@@ -0,0 +1,8 @@
|
||||
import ColorPicker from './src/main';
|
||||
|
||||
/* istanbul ignore next */
|
||||
ColorPicker.install = function(Vue) {
|
||||
Vue.component(ColorPicker.name, ColorPicker);
|
||||
};
|
||||
|
||||
export default ColorPicker;
|
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@@ -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>
|
@@ -0,0 +1,111 @@
|
||||
<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 class="color-list-item-value">
|
||||
{{item.info.value}}
|
||||
</div>
|
||||
</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;
|
||||
position: relative;
|
||||
}
|
||||
.color-list-item:hover {
|
||||
background: #efefef;
|
||||
}
|
||||
.color-list-item-ball {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
margin-top: 2px;
|
||||
margin-left: 5px;
|
||||
border-radius: 100%;
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
.color-list-item-label {
|
||||
margin-left: 35px;
|
||||
font-size: 13px;
|
||||
line-height: 24px;
|
||||
display: inline-block;
|
||||
width: 85%;
|
||||
overflow: hidden;
|
||||
}
|
||||
.color-list-item-value {
|
||||
float: right;
|
||||
}
|
||||
</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>
|
@@ -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>
|
@@ -0,0 +1,135 @@
|
||||
<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"
|
||||
type="primary"
|
||||
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>
|
@@ -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>
|
@@ -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>
|
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
@@ -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>
|
93
examples/components/theme-configurator/editor/color.vue
Normal file
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<div class="content-80">
|
||||
<el-input
|
||||
size="medium"
|
||||
:value=displayValue
|
||||
readonly
|
||||
slot="reference"
|
||||
@click.native="onInputClick"
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="content-20">
|
||||
<color-picker
|
||||
size="medium"
|
||||
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>
|
104
examples/components/theme-configurator/editor/fontLineHeight.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<el-select
|
||||
v-model="value"
|
||||
class="select"
|
||||
size="medium"
|
||||
@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>
|
105
examples/components/theme-configurator/editor/fontSize.vue
Normal file
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<el-select
|
||||
v-model="value"
|
||||
class="select"
|
||||
size="medium"
|
||||
@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',
|
||||
'22px',
|
||||
'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>
|
109
examples/components/theme-configurator/editor/fontWeight.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<el-select
|
||||
v-model="value"
|
||||
class="select"
|
||||
size="medium"
|
||||
@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>
|
45
examples/components/theme-configurator/editor/input.vue
Normal 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>
|
81
examples/components/theme-configurator/editor/mixin.vue
Normal file
@@ -0,0 +1,81 @@
|
||||
<style>
|
||||
.config {
|
||||
padding: 5px 0;
|
||||
}
|
||||
.config-label {
|
||||
color: #606266;;
|
||||
font-size: 14px;
|
||||
padding-bottom: 8px;
|
||||
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);
|
||||
},
|
||||
displayKeyName() {
|
||||
if (this.config.name) {
|
||||
return this.config.key.replace('$--', '');
|
||||
}
|
||||
return this.config.key.replace(`$--${this.componentName}-`, '');
|
||||
},
|
||||
isGlobal() {
|
||||
return !this.config.value.startsWith('$');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(value) {
|
||||
this.$emit('onChange', {
|
||||
key: this.config.key,
|
||||
value
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
41
examples/components/theme-configurator/editor/simpleText.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<section class="config" :key="displayName">
|
||||
<div class="config-label">
|
||||
<el-tooltip :content="displayName" placement="top">
|
||||
<span>{{displayKeyName}}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="config-content">
|
||||
<theme-input
|
||||
:val="value"
|
||||
size="medium"
|
||||
@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>
|
195
examples/components/theme-configurator/index.vue
Normal file
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div class="main-configurator" ref='configurator'>
|
||||
<action-panel
|
||||
:selectOptions="selectOptions"
|
||||
:userConfigHistory="userConfigHistory"
|
||||
:userConfigRedoHistory="userConfigRedoHistory"
|
||||
:onUndo="undo"
|
||||
:onRedo="redo"
|
||||
:isOfficial="isOfficial"
|
||||
@select="onSelectChange"
|
||||
></action-panel>
|
||||
<main-panel
|
||||
v-if="defaultConfig"
|
||||
:currentConfig="currentConfig"
|
||||
:defaultConfig="defaultConfig"
|
||||
:userConfig="userConfig"
|
||||
:globalValue="globalValue"
|
||||
@onChange="userConfigChange"
|
||||
></main-panel>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.main-configurator {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import bus from '../../bus.js';
|
||||
import { getVars } from '../theme/loader/api.js';
|
||||
import mainPanel from './main';
|
||||
import actionPanel from './action';
|
||||
import {
|
||||
filterConfigType,
|
||||
filterGlobalValue,
|
||||
getActionDisplayName
|
||||
} from './utils/utils.js';
|
||||
import Shortcut from './shortcut';
|
||||
import {
|
||||
ACTION_APPLY_THEME,
|
||||
ACTION_DOWNLOAD_THEME,
|
||||
ACTION_COMPONECT_SELECT
|
||||
} from '../theme/constant.js';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
themeConfig: Object,
|
||||
previewConfig: Object,
|
||||
isOfficial: Boolean,
|
||||
onUserConfigUpdate: Function
|
||||
},
|
||||
components: {
|
||||
mainPanel,
|
||||
actionPanel
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
init: false,
|
||||
defaultConfig: null,
|
||||
currentConfig: null,
|
||||
userConfig: {
|
||||
global: {},
|
||||
local: {}
|
||||
},
|
||||
userConfigHistory: [],
|
||||
userConfigRedoHistory: [],
|
||||
hasLocalConfig: false,
|
||||
selectOptions: [],
|
||||
selectedComponent: 'color'
|
||||
};
|
||||
},
|
||||
mixins: [Shortcut],
|
||||
computed: {
|
||||
globalValue() {
|
||||
return filterGlobalValue(this.defaultConfig, this.userConfig);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
ga('send', 'event', 'ThemeConfigurator', 'Init');
|
||||
this.showConfigurator();
|
||||
this.enableShortcut();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.disableShortcut();
|
||||
},
|
||||
methods: {
|
||||
getActionDisplayName(key) {
|
||||
return getActionDisplayName(key);
|
||||
},
|
||||
showConfigurator() {
|
||||
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 && this.onError(err);
|
||||
})
|
||||
.then(() => {
|
||||
setTimeout(() => {
|
||||
if (defaultConfig) {
|
||||
this.defaultConfig = defaultConfig;
|
||||
this.setSelectOption();
|
||||
this.filterCurrentConfig();
|
||||
this.init = true;
|
||||
}
|
||||
loading.close();
|
||||
}, 300); // action after transition
|
||||
});
|
||||
});
|
||||
},
|
||||
setSelectOption() {
|
||||
this.selectOptions = this.defaultConfig.map((config) => ({
|
||||
label: config.name.charAt(0).toUpperCase() + config.name.slice(1),
|
||||
value: config.name
|
||||
})).sort((a, b) => {
|
||||
const A = a.label;
|
||||
const B = b.label;
|
||||
if (A < B) return -1;
|
||||
if (A > B) return 1;
|
||||
return 0;
|
||||
});
|
||||
},
|
||||
filterCurrentConfig() {
|
||||
this.currentConfig = this.defaultConfig.find(config => {
|
||||
return (
|
||||
config.name === this.selectedComponent
|
||||
);
|
||||
});
|
||||
},
|
||||
userConfigChange(e) {
|
||||
this.userConfigHistory.push(JSON.stringify(this.userConfig));
|
||||
this.userConfigRedoHistory = [];
|
||||
this.$set(
|
||||
this.userConfig[filterConfigType(this.currentConfig.name)],
|
||||
e.key,
|
||||
e.value
|
||||
);
|
||||
this.onAction();
|
||||
},
|
||||
onReset() {
|
||||
this.userConfigRedoHistory = [];
|
||||
this.userConfigHistory = [];
|
||||
this.userConfig = {
|
||||
global: {},
|
||||
local: {}
|
||||
};
|
||||
this.onAction();
|
||||
},
|
||||
onDownload() {
|
||||
bus.$emit(ACTION_DOWNLOAD_THEME, this.userConfig, this.previewConfig.name);
|
||||
},
|
||||
onAction() {
|
||||
this.onUserConfigUpdate(this.userConfig);
|
||||
bus.$emit(ACTION_APPLY_THEME, this.userConfig);
|
||||
},
|
||||
undo() {
|
||||
if (this.userConfigHistory.length > 0) {
|
||||
this.userConfigRedoHistory.push(JSON.stringify(this.userConfig));
|
||||
this.userConfig = JSON.parse(this.userConfigHistory.pop());
|
||||
this.onAction();
|
||||
}
|
||||
},
|
||||
redo() {
|
||||
if (this.userConfigRedoHistory.length > 0) {
|
||||
this.userConfigHistory.push(JSON.stringify(this.userConfig));
|
||||
this.userConfig = JSON.parse(this.userConfigRedoHistory.shift());
|
||||
this.onAction();
|
||||
}
|
||||
},
|
||||
onSelectChange(val) {
|
||||
bus.$emit(ACTION_COMPONECT_SELECT, val);
|
||||
this.selectedComponent = val;
|
||||
this.filterCurrentConfig();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
themeConfig: {
|
||||
handler(val, oldVal) {
|
||||
if (!oldVal.globnal) {
|
||||
this.userConfig = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
130
examples/components/theme-configurator/main.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="editor-main" ref="mainPanel">
|
||||
<!-- <span>{{configName}}</span> -->
|
||||
<div v-for="(config, key) in configByOrder" :key="key">
|
||||
<span
|
||||
v-if="showCategory(config.category, key + 1)"
|
||||
class="category-name"
|
||||
>
|
||||
{{config.category}}
|
||||
</span>
|
||||
<component
|
||||
:is="editorComponent(config.type)"
|
||||
:componentName=configName
|
||||
:config=config
|
||||
:userConfig=userConfigByType
|
||||
:golbalValue=globalValue
|
||||
@onChange=onChange
|
||||
>
|
||||
</component>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.editor-main {
|
||||
padding: 0 18px 15px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.category-name {
|
||||
color: #C0C4CC;
|
||||
font-size: 18px;
|
||||
display: block;
|
||||
margin: 13px 0 3px 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 } 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: {
|
||||
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: {}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
currentConfig: {
|
||||
handler() {
|
||||
this.$nextTick(() => {
|
||||
this.$refs.mainPanel.scrollTo(0, 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
27
examples/components/theme-configurator/shortcut.vue
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
downloading: false
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
shortcut(e) {
|
||||
if (e.keyCode === 90 && (e.ctrlKey || e.metaKey)) {
|
||||
if (e.shiftKey) {
|
||||
this.redo();
|
||||
} else {
|
||||
this.undo();
|
||||
}
|
||||
}
|
||||
},
|
||||
enableShortcut() {
|
||||
document.addEventListener('keydown', this.shortcut);
|
||||
},
|
||||
disableShortcut() {
|
||||
document.removeEventListener('keydown', this.shortcut);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
59
examples/components/theme-configurator/utils/boxShadow.js
Normal 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(', ');
|
68
examples/components/theme-configurator/utils/utils.js
Normal file
@@ -0,0 +1,68 @@
|
||||
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 getVariableDisplayName = (key) => {
|
||||
return getNameFromI18N('variable-name')[key] || key;
|
||||
};
|
||||
|
||||
export const getStyleDisplayName = (config, componentName) => {
|
||||
const displayNameMap = getNameFromI18N('display-name');
|
||||
if (config.name) {
|
||||
return getVariableDisplayName(config.key.replace('$--', ''));
|
||||
}
|
||||
let displayName = config.key.replace(`$--${componentName}-`, '');
|
||||
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;
|
||||
};
|
157
examples/components/theme-picker.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<el-color-picker
|
||||
class="theme-picker"
|
||||
popper-class="theme-picker-dropdown"
|
||||
v-model="theme"></el-color-picker>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.theme-picker {
|
||||
height: 80px;
|
||||
display: inline-block;
|
||||
// @utils-vertical-center;
|
||||
}
|
||||
|
||||
.theme-picker .el-color-picker__trigger {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.theme-picker-dropdown .el-color-dropdown__link-btn {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import Element from 'main/index.js';
|
||||
const { version } = Element;
|
||||
|
||||
const ORIGINAL_THEME = '#409EFF';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chalk: '', // content of theme-chalk css
|
||||
docs: '', // content of docs css
|
||||
theme: ORIGINAL_THEME
|
||||
};
|
||||
},
|
||||
|
||||
watch: {
|
||||
theme(val, oldVal) {
|
||||
if (typeof val !== 'string') return;
|
||||
const themeCluster = this.getThemeCluster(val.replace('#', ''));
|
||||
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''));
|
||||
const getHandler = (variable, id) => {
|
||||
return () => {
|
||||
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''));
|
||||
let newStyle = this.updateStyle(this[variable], originalCluster, themeCluster);
|
||||
|
||||
let styleTag = document.getElementById(id);
|
||||
if (!styleTag) {
|
||||
styleTag = document.createElement('style');
|
||||
styleTag.setAttribute('id', id);
|
||||
document.head.appendChild(styleTag);
|
||||
}
|
||||
styleTag.innerText = newStyle;
|
||||
};
|
||||
};
|
||||
|
||||
const chalkHandler = getHandler('chalk', 'chalk-style');
|
||||
const docsHandler = getHandler('docs', 'docs-style');
|
||||
|
||||
if (!this.chalk) {
|
||||
const url = `https://unpkg.com/element-ui@${ version }/lib/theme-chalk/index.css`;
|
||||
this.getCSSString(url, chalkHandler, 'chalk');
|
||||
} else {
|
||||
chalkHandler();
|
||||
}
|
||||
|
||||
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, originalCluster, themeCluster);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateStyle(style, oldCluster, newCluster) {
|
||||
let newStyle = style;
|
||||
oldCluster.forEach((color, index) => {
|
||||
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]);
|
||||
});
|
||||
return newStyle;
|
||||
},
|
||||
|
||||
getCSSString(url, callback, variable) {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '');
|
||||
callback();
|
||||
}
|
||||
};
|
||||
xhr.open('GET', url);
|
||||
xhr.send();
|
||||
},
|
||||
|
||||
getThemeCluster(theme) {
|
||||
const tintColor = (color, tint) => {
|
||||
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 }`;
|
||||
}
|
||||
};
|
||||
|
||||
const shadeColor = (color, shade) => {
|
||||
let red = parseInt(color.slice(0, 2), 16);
|
||||
let green = parseInt(color.slice(2, 4), 16);
|
||||
let blue = parseInt(color.slice(4, 6), 16);
|
||||
|
||||
red = Math.round((1 - shade) * red);
|
||||
green = Math.round((1 - shade) * green);
|
||||
blue = Math.round((1 - shade) * blue);
|
||||
|
||||
red = red.toString(16);
|
||||
green = green.toString(16);
|
||||
blue = blue.toString(16);
|
||||
|
||||
return `#${ red }${ green }${ blue }`;
|
||||
};
|
||||
|
||||
const clusters = [theme];
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))));
|
||||
}
|
||||
clusters.push(shadeColor(theme, 0.1));
|
||||
return clusters;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
280
examples/components/theme/basic-tokens-preview.vue
Normal 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>
|
539
examples/components/theme/components-preview.vue
Normal 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>
|