Skip to content

Commit

Permalink
feat: custom theme
Browse files Browse the repository at this point in the history
  • Loading branch information
cole committed Jul 28, 2024
1 parent 0fd49f3 commit 8c44116
Show file tree
Hide file tree
Showing 7 changed files with 325 additions and 46 deletions.
14 changes: 9 additions & 5 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,13 @@ export default defineComponent({
inheritAttrs: false,
setup () {
const localeMessage = ref({})
const customTheme = ref({})

function setCustomTheme (value) {
customTheme.value = value
const theme = ref('dark')
const themeProvider = ref({})

function setConfigTheme (name, value) {
theme.value = name
themeProvider.value = value
}

function setLocaleMessage (value) {
Expand All @@ -23,7 +26,8 @@ export default defineComponent({
}

createAppInstance({
setCustomTheme: setCustomTheme,
theme: theme,
setConfigTheme: setConfigTheme,
setLocaleMessage: setLocaleMessage,
onAvatarAction: onAvatarAction
})
Expand All @@ -32,7 +36,7 @@ export default defineComponent({
const { antd, packages } = unref(localeMessage)

return (
<ConfigProvider locale={antd} theme={unref(customTheme)}>
<ConfigProvider locale={antd} theme={unref(themeProvider)}>
<LocaleProvider locale={packages}>
<RouterView/>
</LocaleProvider>
Expand Down
38 changes: 26 additions & 12 deletions src/layout/compatible/navbar/index.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { defineComponent } from 'vue'
import { defineComponent, ref, unref } from 'vue'
import { ConfigProvider } from 'ant-design-vue'
import Breadcrumb from '../../components/breadcrumb'
import Settings from '../../components/settings'
import Fullscreen from '../../components/fullscreen'
Expand Down Expand Up @@ -29,10 +30,17 @@ export default defineComponent({
const { prefixCls } = useConfigInject('pro-layout-navbar', props)
const [wrapSSR, hashId] = useStyle(prefixCls)

const popupContainer = ref(null)

function onCollapse () {
emit('collapse', !props.collapsed)
}

function getPopupContainer () {
const plain = unref(popupContainer)
return plain ? (plain.$el || plain) : plain
}

return () => {
const { router, collapsed } = props

Expand All @@ -42,18 +50,24 @@ export default defineComponent({

return wrapSSR(
<div class={[prefixCls.value, hashId.value]} {...attrs}>
<div class={`${prefixCls.value}-left`}>
<div class={`${prefixCls.value}-collapse`} onClick={onCollapse}>
<HamburgerOutlined class={collapseClass}/>
<ConfigProvider getPopupContainer={getPopupContainer}>
<div class={`${prefixCls.value}-popup-container`} ref={popupContainer}>
<div class={`${prefixCls.value}-content`}>
<div class={`${prefixCls.value}-left`}>
<div class={`${prefixCls.value}-collapse`} onClick={onCollapse}>
<HamburgerOutlined class={collapseClass}/>
</div>
<Breadcrumb router={router}/>
</div>
<div class={`${prefixCls.value}-right`}>
<Settings/>
<Fullscreen/>
<Language/>
<Avatar/>
</div>
</div>
</div>
<Breadcrumb router={router}/>
</div>
<div class={`${prefixCls.value}-right`}>
<Settings/>
<Fullscreen/>
<Language/>
<Avatar/>
</div>
</ConfigProvider>
</div>
)
}
Expand Down
56 changes: 31 additions & 25 deletions src/layout/compatible/navbar/style/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,41 @@ function genBaseStyle (token) {
const { componentCls, navbarHeight, navbarPaddingInline, navbarCollapseSize } = token
return {
[componentCls]: {
height: navbarHeight,
display: 'flex',
justifyContent: 'space-between',
paddingInline: navbarPaddingInline,
background: token.colorBgContainer,
position: 'relative',
userSelect: 'none',
[`${componentCls}-left, ${componentCls}-right`]: {
[`${componentCls}-popup-container`]: {
position: 'relative'
},
[`${componentCls}-content`]: {
height: navbarHeight,
display: 'flex',
alignItems: 'center'
},
[`${componentCls}-collapse`]: {
width: navbarCollapseSize,
height: navbarCollapseSize,
fontSize: navbarCollapseSize,
lineHeight: `${navbarCollapseSize}px`,
color: token.colorText,
textAlign: 'center',
cursor: 'pointer',
[`&:hover`]: {
color: token.colorPrimaryHover
},
[`&:active`]: {
color: token.colorPrimaryActive
justifyContent: 'space-between',
paddingInline: navbarPaddingInline,
background: token.colorBgContainer,
[`${componentCls}-left, ${componentCls}-right`]: {
height: navbarHeight,
display: 'flex',
alignItems: 'center'
},
[`${componentCls}-collapse-icon`]: {
transition: 'all 0.3s cubic-bezier(0.2, 0, 0, 1) 0s',
[`&__down`]: {
transform: 'rotate(90deg)'
[`${componentCls}-collapse`]: {
width: navbarCollapseSize,
height: navbarCollapseSize,
fontSize: navbarCollapseSize,
lineHeight: `${navbarCollapseSize}px`,
color: token.colorText,
textAlign: 'center',
cursor: 'pointer',
[`&:hover`]: {
color: token.colorPrimaryHover
},
[`&:active`]: {
color: token.colorPrimaryActive
},
[`${componentCls}-collapse-icon`]: {
transition: 'all 0.3s cubic-bezier(0.2, 0, 0, 1) 0s',
[`&__down`]: {
transform: 'rotate(90deg)'
}
}
}
}
Expand Down
144 changes: 144 additions & 0 deletions src/layout/components/settings/ThemeSettings.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { defineComponent, ref, unref, watch } from 'vue'
import { Switch, theme as antTheme, Tooltip } from 'ant-design-vue'
import { CheckOutlined } from '@ant-design/icons-vue'
import { useConfigInject } from '@utils/extend'
import useStyle from './style/theme-settings'
import { useAppInstance } from '@/useAppInstance'

const themeList = [
{
name: 'light',
title: '亮色主题'
},
{
name: 'dark',
title: '暗色主题'
},
{
name: 'real-dark',
title: '暗黑模式'
}
]

const primaryList = [
{
name: 'blue',
title: '拂晓蓝'
},
{
name: 'red',
title: '薄暮'
},
{
name: 'volcano',
title: '火山'
},
{
name: 'gold',
title: '日暮'
},
{
name: 'cyan',
title: '明青'
},
{
name: 'green',
title: '极光绿'
},
{
name: 'geekblue',
title: '极客蓝'
},
{
name: 'purple',
title: '酱紫'
}
]

export default defineComponent({
inheritAttrs: false,
setup (props, { attrs }) {
const { prefixCls } = useConfigInject('pro-theme-settings', props)
const [wrapSSR, hashId] = useStyle(prefixCls)
const { token } = antTheme.useToken()
const { darkAlgorithm, compactAlgorithm } = antTheme

const { setConfigTheme } = useAppInstance()

const theme = ref('dark')
const primary = ref('blue')
const compact = ref(false)

watch([theme, primary, compact], ([themeValue, primaryValue, compactValue]) => {
const algorithm = [
themeValue === 'real-dark' ? darkAlgorithm : null,
compactValue ? compactAlgorithm : null
]
setConfigTheme && setConfigTheme(themeValue, {
algorithm: algorithm.filter((value) => !!value),
token: { colorPrimary: unref(token)[primaryValue] }
})
})

function onThemeClick (value) {
theme.value = value
}

function onPrimaryClick (value) {
primary.value = value
}

return () => {
const themeDom = themeList.map((item) => {
return (
<Tooltip title={item.title}>
<div
class={[`${prefixCls.value}-theme`, `${prefixCls.value}-theme-${item.name}`]}
onClick={onThemeClick.bind(null, item.name)}
>
{unref(theme) === item.name ? <CheckOutlined/> : null}
</div>
</Tooltip>
)
})

const primaryDom = primaryList.map((item) => {
const primaryStyle = { backgroundColor: unref(token)[item.name] }
return (
<Tooltip title={item.title}>
<div
class={`${prefixCls.value}-primary`}
style={primaryStyle}
onClick={onPrimaryClick.bind(null, item.name)}
>
{unref(primary) === item.name ? <CheckOutlined/> : null}
</div>
</Tooltip>
)
})

return wrapSSR(
<div class={[prefixCls.value, hashId.value]} {...attrs}>
<div class={`${prefixCls.value}-block-wrap`}>
<div class={`${prefixCls.value}-title`}>整体风格</div>
<div class={`${prefixCls.value}-theme-block`}>
{themeDom}
</div>
</div>
<div class={`${prefixCls.value}-block-wrap`}>
<div class={`${prefixCls.value}-title`}>主题色</div>
<div class={`${prefixCls.value}-primary-block`}>
{primaryDom}
</div>
</div>
<div class={`${prefixCls.value}-block-wrap`}>
<div class={`${prefixCls.value}-title`}>紧凑主题</div>
<div class={`${prefixCls.value}-compact-block`}>
<Switch v-model:checked={compact.value}/>
</div>
</div>
</div>
)
}
}
})
5 changes: 3 additions & 2 deletions src/layout/components/settings/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { defineComponent, ref, unref } from 'vue'
import { Drawer } from 'ant-design-vue'
import { SettingOutlined } from '@ant-design/icons-vue'
import ThemeSettings from './ThemeSettings'
import { useConfigInject } from '@utils/extend'
import useStyle from './style'

Expand All @@ -24,19 +25,19 @@ export default defineComponent({

return () => {
const drawerProps = {
width: 320,
open: unref(open),
onClose: onDrawerClose,
getContainer: () => unref(popupContainer)
}

return wrapSSR(
<div class={[prefixCls.value, hashId.value]} {...attrs}>
<div class={`${prefixCls.value}-popup-container`} ref={popupContainer}>
<div class={`${prefixCls.value}-content`} onClick={onDrawerOpen}>
<SettingOutlined/>
</div>
<Drawer {...drawerProps}>
自定义主题
<ThemeSettings/>
</Drawer>
</div>
</div>
Expand Down
Loading

0 comments on commit 8c44116

Please sign in to comment.