add ThemePicker to setting

This commit is contained in:
Pan 2019-03-19 17:46:56 +08:00
parent 6c6f03f664
commit 27322ac4d3
4 changed files with 49 additions and 55 deletions

View File

@ -2,9 +2,7 @@
<div ref="rightPanel" :class="{show:show}" class="rightPanel-container"> <div ref="rightPanel" :class="{show:show}" class="rightPanel-container">
<div class="rightPanel-background" /> <div class="rightPanel-background" />
<div class="rightPanel"> <div class="rightPanel">
<div class="handle-button" :style="{'top':buttonTop+'px'}" type="primary" circle @click="show=!show"> <el-button class="handle-button" :style="{'top':buttonTop+'px'}" type="primary" circle :icon="show?'el-icon-close':'el-icon-setting'" @click="show=!show" />
<i :class="show?'el-icon-close':'el-icon-setting'" />
</div>
<div class="rightPanel-items"> <div class="rightPanel-items">
<slot /> <slot />
</div> </div>
@ -121,20 +119,12 @@ export default {
.handle-button { .handle-button {
position: absolute; position: absolute;
left: -48px; left: -48px;
border-radius: 4px 0 0 4px !important; border-radius: 6px 0 0 6px !important;
width: 48px; width: 48px;
height: 48px; height: 48px;
background: #1890ff;
cursor: pointer;
pointer-events: auto; pointer-events: auto;
z-index: 0; z-index: 0;
font-size: 24px;
text-align: center; text-align: center;
color: #fff;
line-height: 48px;
i {
font-size: 24px;
line-height: 48px;
}
} }
</style> </style>

View File

@ -19,12 +19,21 @@ export default {
} }
}, },
watch: { watch: {
theme(val) { async theme(val) {
const oldVal = this.theme const oldVal = this.theme
if (typeof val !== 'string') return if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', '')) const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
console.log(themeCluster, originalCluster) console.log(themeCluster, originalCluster)
const $message = this.$message({
message: ' Compiling the theme',
customClass: 'theme-message',
type: 'success',
duration: 0,
iconClass: 'el-icon-loading'
})
const getHandler = (variable, id) => { const getHandler = (variable, id) => {
return () => { return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
@ -40,15 +49,15 @@ export default {
} }
} }
const chalkHandler = getHandler('chalk', 'chalk-style')
if (!this.chalk) { if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css` const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
this.getCSSString(url, chalkHandler, 'chalk') await this.getCSSString(url, 'chalk')
} else {
chalkHandler()
} }
const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style')) const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => { .filter(style => {
const text = style.innerText const text = style.innerText
@ -59,39 +68,32 @@ export default {
if (typeof innerText !== 'string') return if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
}) })
this.$message({
message: '换肤成功', $message.close()
type: 'success'
})
} }
}, },
methods: { methods: {
updateStyle(style, oldCluster, newCluster) { updateStyle(style, oldCluster, newCluster) {
const colorOverrides = [] // only capture color overides let newStyle = style
oldCluster.forEach((color, index) => { oldCluster.forEach((color, index) => {
const value = newCluster[index] newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
const color_plain = color.replace(/([()])/g, '\\$1')
const repl = new RegExp(`(^|})([^{]+{[^{}]+)${color_plain}\\b([^}]*)(?=})`, 'gi')
const nestRepl = new RegExp(color_plain, 'ig') // for greed matching before the 'color'
let v
while ((v = repl.exec(style))) {
colorOverrides.push(v[2].replace(nestRepl, value) + value + v[3] + '}') // '}' not captured in the regexp repl to reserve it as locator-boundary
}
}) })
return colorOverrides.join('') return newStyle
}, },
getCSSString(url, callback, variable) { getCSSString(url, variable) {
const xhr = new XMLHttpRequest() return new Promise(resolve => {
xhr.onreadystatechange = () => { const xhr = new XMLHttpRequest()
if (xhr.readyState === 4 && xhr.status === 200) { xhr.onreadystatechange = () => {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') if (xhr.readyState === 4 && xhr.status === 200) {
callback() this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
} }
} xhr.open('GET', url)
xhr.open('GET', url) xhr.send()
xhr.send() })
}, },
getThemeCluster(theme) { getThemeCluster(theme) {
@ -143,10 +145,14 @@ export default {
</script> </script>
<style> <style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}
.theme-picker .el-color-picker__trigger { .theme-picker .el-color-picker__trigger {
margin-top: 12px; height: 26px !important;
height: 26px!important; width: 26px !important;
width: 26px!important;
padding: 2px; padding: 2px;
} }

View File

@ -18,9 +18,6 @@
<lang-select class="right-menu-item hover-effect" /> <lang-select class="right-menu-item hover-effect" />
<el-tooltip :content="$t('navbar.theme')" effect="dark" placement="bottom">
<theme-picker class="right-menu-item hover-effect" />
</el-tooltip>
</template> </template>
<el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click"> <el-dropdown class="avatar-container right-menu-item hover-effect" trigger="click">
@ -56,7 +53,6 @@ import ErrorLog from '@/components/ErrorLog'
import Screenfull from '@/components/Screenfull' import Screenfull from '@/components/Screenfull'
import SizeSelect from '@/components/SizeSelect' import SizeSelect from '@/components/SizeSelect'
import LangSelect from '@/components/LangSelect' import LangSelect from '@/components/LangSelect'
import ThemePicker from '@/components/ThemePicker'
import Search from '@/components/HeaderSearch' import Search from '@/components/HeaderSearch'
export default { export default {
@ -67,7 +63,6 @@ export default {
Screenfull, Screenfull,
SizeSelect, SizeSelect,
LangSelect, LangSelect,
ThemePicker,
Search Search
}, },
computed: { computed: {

View File

@ -6,20 +6,23 @@
</h3> </h3>
<div class="drawer-item"> <div class="drawer-item">
<span>开启 Tags-View</span> <span>开启 Tags-View</span>
<el-switch v-model="tagsView" class="drawer-switch" /> <el-switch v-model="tagsView" class="drawer-switch" />
</div> </div>
<!-- <div class="drawer-item"> <div class="drawer-item">
<span>显示 Logo</span> <span>主题色</span>
<el-switch v-model="sidebarLogo" class="drawer-switch" /> <theme-picker style="float: right;height: 26px;margin: -3px 5px 0 0;" />
</div> --> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import ThemePicker from '@/components/ThemePicker'
export default { export default {
components: { ThemePicker },
data() { data() {
return { return {
sidebarLogo: true sidebarLogo: true