Skip to content

Commit

Permalink
fix: custom app color
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed May 19, 2024
1 parent f49ced7 commit e6e7f7b
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 21 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"socket.io-client": "4.7.5",
"sortablejs": "1.15.2",
"swrv": "1.0.4",
"tinycolor2": "1.6.0",
"umi-request": "1.4.0",
"unidata.js": "0.8.0",
"validator": "13.12.0",
Expand All @@ -104,6 +105,7 @@
"@types/markdown-escape": "1.1.3",
"@types/qs": "6.9.15",
"@types/sortablejs": "1.15.8",
"@types/tinycolor2": "1.4.6",
"@types/validator": "13.11.10",
"@vitejs/plugin-vue": "5.0.4",
"@vitejs/plugin-vue-jsx": "3.1.0",
Expand Down
16 changes: 16 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

39 changes: 33 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { PortalInjectKey } from '~/hooks/use-portal-element'
import {
darkTheme,
dateZhCN,
lightTheme,
NConfigProvider,
NDialogProvider,
NMessageProvider,
NNotificationProvider,
darkTheme,
dateZhCN,
lightTheme,
useDialog,
useMessage,
useNotification,
useThemeVars,
zhCN,
} from 'naive-ui'
import { defineComponent, onMounted } from 'vue'
import { RouterView } from 'vue-router'
import type { VNode } from 'vue'

import { PortalInjectKey } from '~/hooks/use-portal-element'

import { ThemeColorConfig } from '../theme.config'
import { useUIStore } from './stores/ui'
import type { VNode } from 'vue'
import { colorRef } from './utils/color'

const Root = defineComponent({
name: 'RootView',
Expand Down Expand Up @@ -70,13 +73,14 @@ const App = defineComponent({
locale={zhCN}
dateLocale={dateZhCN}
themeOverrides={{
common: ThemeColorConfig,
common: colorRef.value,
}}
theme={naiveUIDark ? darkTheme : isDark ? darkTheme : lightTheme}
>
<NNotificationProvider>
<NMessageProvider>
<NDialogProvider>
<AccentColorInjector />
<Root />
</NDialogProvider>
</NMessageProvider>
Expand All @@ -87,5 +91,28 @@ const App = defineComponent({
},
})

const AccentColorInjector = defineComponent({
setup() {
const vars = useThemeVars()
watchEffect(() => {
const { primaryColor, primaryColorHover, primaryColorSuppl } = vars.value

document.documentElement.style.setProperty(
'--color-primary',
primaryColor,
)
document.documentElement.style.setProperty(
'--color-primary-shallow',
primaryColorHover,
)
document.documentElement.style.setProperty(
'--color-primary-deep',
primaryColorSuppl,
)
})

return () => null
},
})
// eslint-disable-next-line import/no-default-export
export default App
25 changes: 21 additions & 4 deletions src/components/config-form/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useStoreRef } from '~/hooks/use-store-ref'
import { O } from 'crossbell.js/dist/index-LKLW_17H'
import { get, set } from 'lodash-es'
import { marked } from 'marked'
import {
Expand All @@ -14,9 +14,12 @@ import {
NSwitch,
NText,
} from 'naive-ui'
import { isVNode } from 'vue'
import type { ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'

import { useStoreRef } from '~/hooks/use-store-ref'
import { UIStore } from '~/stores/ui'
import { uuid } from '~/utils'
import type { ComputedRef, InjectionKey, PropType, Ref } from 'vue'

const NFormPrefixCls = 'mt-6'
const NFormBaseProps = {
Expand Down Expand Up @@ -53,9 +56,15 @@ export const ConfigForm = defineComponent({
required: false,
default: (key: string) => key,
},

extendConfigView: {
type: Object as PropType<{
[key: string]: VNode
}>,
},
},

setup(props) {
setup(props, { slots }) {
const formData = ref(props.initialValue)

watchEffect(
Expand Down Expand Up @@ -131,7 +140,10 @@ export const ConfigForm = defineComponent({
dataKey={props.getKey(key)}
formData={formData}
schema={schema}
property={key}
/>
{props.extendConfigView?.[key]}
{slots[key]?.()}
</NForm>
</NCollapseItem>
)
Expand Down Expand Up @@ -168,16 +180,20 @@ const SchemaSection = defineComponent({
type: String as PropType<string>,
required: true,
},
property: {
type: String as PropType<string>,
},
},
setup(props) {
const { definitions, getKey } = inject(JSONSchemaFormInjectKey, {} as any)

return () => {
const { schema, formData, dataKey: key } = props
const { schema, formData, dataKey: key, property } = props

if (!schema) {
return null
}

return (
<>
{Object.keys(schema.properties).map((property) => {
Expand All @@ -193,6 +209,7 @@ const SchemaSection = defineComponent({
dataKey={`${getKey(key)}.${property}`}
formData={formData}
schema={nestSchmea}
property={property}
/>
)
}
Expand Down
28 changes: 28 additions & 0 deletions src/utils/color.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import tinycolor from 'tinycolor2'

import { ThemeColorConfig } from '~/../theme.config'

export const colorRef = useStorage('mx-admin-color', ThemeColorConfig)

interface Colors {
primaryColor: string
primaryColorHover: string
primaryColorPressed: string
primaryColorSuppl: string
}

export function defineColors(baseColor: string): Colors {
const base = tinycolor(baseColor)

const primaryColor = base.toHexString()
const primaryColorHover = base.brighten(10).toHexString()
const primaryColorPressed = base.darken(10).toHexString()
const primaryColorSuppl = base.darken(15).toHexString()

return {
primaryColor,
primaryColorHover,
primaryColorPressed,
primaryColorSuppl,
}
}
68 changes: 60 additions & 8 deletions src/views/setting/tabs/system.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { HeaderActionButton } from '~/components/button/rounded-button'
import { ConfigForm } from '~/components/config-form'
import { CheckCircleOutlinedIcon } from '~/components/icons'
import { useStoreRef } from '~/hooks/use-store-ref'
import { useLayout } from '~/layouts/content'
import { camelCase, cloneDeep, isEmpty, merge } from 'lodash-es'
import { UIStore } from '~/stores/ui'
import { RESTManager, deepDiff } from '~/utils'
import { NButton, NColorPicker, NFormItem, useThemeVars } from 'naive-ui'
import { ThemeColorConfig } from 'theme.config'
import {
defineComponent,
onBeforeUnmount,
Expand All @@ -16,6 +11,15 @@ import {
watch,
} from 'vue'

import { HeaderActionButton } from '~/components/button/rounded-button'
import { ConfigForm } from '~/components/config-form'
import { CheckCircleOutlinedIcon } from '~/components/icons'
import { useStoreRef } from '~/hooks/use-store-ref'
import { useLayout } from '~/layouts/content'
import { UIStore } from '~/stores/ui'
import { deepDiff, RESTManager } from '~/utils'
import { colorRef, defineColors } from '~/utils/color'

const NFormPrefixCls = 'mt-6'
const NFormBaseProps = {
class: NFormPrefixCls,
Expand Down Expand Up @@ -153,8 +157,56 @@ export const TabSystem = defineComponent(() => {
.replace('Dto', '')
}}
schema={schema.value}
/>
>
{{
AdminExtraDto() {
return (
<>
<NFormItem label={'主题色'}>
<AppColorSetter />
</NFormItem>
</>
)
},
}}
</ConfigForm>
)}
</Fragment>
)
})

const AppColorSetter = defineComponent({
setup() {
const vars = useThemeVars()

const $style = document.createElement('style')
$style.innerHTML = `* { transition: none !important; }`

return () => (
<div class={'flex items-center gap-2'}>
<NColorPicker
class={'w-36'}
value={vars.value.primaryColor}
onUpdateValue={(value) => {
document.head.appendChild($style)

Object.assign(colorRef.value, defineColors(value))
setTimeout(() => {
document.head.removeChild($style)
})
}}
></NColorPicker>

<NButton
size="small"
ghost
onClick={() => {
Object.assign(colorRef.value, ThemeColorConfig)
}}
>
<span>重置</span>
</NButton>
</div>
)
},
})
6 changes: 3 additions & 3 deletions windi.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export default defineConfig({
},
colors: {
primary: {
default: ThemeColorConfig.primaryColor,
deep: ThemeColorConfig.primaryColorPressed,
shallow: ThemeColorConfig.primaryColorHover,
default: 'var(--color-primary)',
deep: 'var(--color-primary-deep)',
shallow: 'var(--color-primary-shallow)',
},
gray$: {
default: '#ddd',
Expand Down

0 comments on commit e6e7f7b

Please sign in to comment.