Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/components/Layout/LayoutBasic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
<div class="inner-content">
<router-view />
</div>
<Settings />
</main>
</section>
</div>
Expand All @@ -17,12 +18,14 @@
import NavigationMenuBar from '@/components/Navigation/MenuBar/index'
import NavigationNavBar from '@/components/Navigation/NavBar'
import NavigationPageHeader from '@/components/Navigation/PageHeader'
import Settings from '@/components/Layout/components/Settings'
export default {
name: 'LayoutBasic',
components: {
NavigationMenuBar,
NavigationNavBar,
NavigationPageHeader
NavigationPageHeader,
Settings
}
}
</script>
Expand Down
100 changes: 100 additions & 0 deletions src/components/Layout/components/Settings/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<div class="right-panel">
<transition name="setting-icon">
<el-button
v-if="!isSetting"
type="primary"
class="wrap-settings"
@click="handleDrawer()"
>
<i class="el-icon-setting"></i>
</el-button>
</transition>
<el-drawer
title="主题配置"
size="22%"
:visible="isSetting"
@close="handleDrawer()"
>
<div class="wrap-slot">
<div
v-for="(slotItem, slotIndex) in slotList"
:key="slotIndex"
class="slot-item"
>
<div class="slot-title">
{{ slotItem.title }}
</div>
<component
:is="slotItem.component"
/>
</div>
</div>
</el-drawer>
</div>
</template>

<script>
import ThemePocker from '@/components/ThemePicker'
export default {
name: 'RightPanel',
components: {
ThemePocker
},
data () {
return {
isSetting: false,
isDrawer: true,
slotList: [
{
title: '主题色',
component: 'ThemePocker'
}
]
}
},
methods: {
handleDrawer () {
this.isSetting = !this.isSetting
}
}
}
</script>

<style scoped lang="scss">
.right-panel {
.setting-icon-enter-active {
transition: opacity .5s .1s;
}
.setting-icon-enter, .setting-icon-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
.wrap-settings {
width: 45px;
height: 45px;
position: fixed;
right: 0px;
top: 50%;
border-radius: 6px 0px 0px 6px;
cursor: pointer;
z-index: 99999;
transform: translateY(-50%);
padding: 0px;
.el-icon-setting {
font-size: 30px;
}
}
/deep/ .wrap-slot {
width: 100%;
height: 100%;
padding: 20px;
.slot-item {
display: flex;
align-items: center;
.slot-title {
flex: 1;
}
}
}
}
</style>
4 changes: 2 additions & 2 deletions src/components/Navigation/MenuBar/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
:default-active="getCurrentRoute"
class="menubar-menu-list"
:collapse="isCollapse"
:collapse-transition="false"
:active-text-color="getActiveTextColor"
@select="handleMenuSelect"
>
<!-- :collapse-transition="false" -->
<!-- :active-text-color="getActiveTextColor" -->
<NavigationMenuBarItem
v-for="(route, index) in getRoutes"
:key="index"
Expand Down
175 changes: 175 additions & 0 deletions src/components/ThemePicker/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<template>
<el-color-picker
v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker"
popper-class="theme-picker-dropdown"
/>
</template>

<script>
const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color

export default {
data () {
return {
chalk: '', // content of theme-chalk css
theme: ''
}
},
computed: {
defaultTheme () {
return ORIGINAL_THEME
}
},
watch: {
defaultTheme: {
handler: function (val, oldVal) {
this.theme = val
},
immediate: true
},
async theme (val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
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) => {
return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const 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
}
}

// if (!this.chalk) {
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
await this.getCSSString(url, 'chalk')
// }

const chalkHandler = getHandler('chalk', 'chalk-style')

chalkHandler()

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)
})

this.$emit('change', val)

$message.close()
}
},

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, variable) {
return new Promise(resolve => {
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve()
}
}
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>

<style>
.theme-message,
.theme-picker-dropdown {
z-index: 99999 !important;
}

.theme-picker .el-color-picker__trigger {
height: 26px !important;
width: 26px !important;
padding: 2px;
}

.theme-picker-dropdown .el-color-dropdown__link-btn {
display: none;
}
</style>
6 changes: 3 additions & 3 deletions src/styles/element-variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ $--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5;
$--table-border: 1px solid #dfe6ec;

:export {
colorPrimary: $--color-primary;
}
// :export {
// colorPrimary: $--color-primary;
// }
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2116,10 +2116,10 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428"
integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA==

axios@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.20.0.tgz#057ba30f04884694993a8cd07fa394cff11c50bd"
integrity sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies:
follow-redirects "^1.10.0"

Expand Down