feat(projects): support grayscale. fixed #385
This commit is contained in:
parent
0d45b86cde
commit
d335df6f46
@ -21,6 +21,10 @@ function handleSegmentChange(value: string | number) {
|
||||
themeStore.setThemeScheme(value as UnionKey.ThemeScheme);
|
||||
}
|
||||
|
||||
function handleGrayscaleChange(value: boolean) {
|
||||
themeStore.setGrayscale(value);
|
||||
}
|
||||
|
||||
const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layout.mode.includes('vertical'));
|
||||
</script>
|
||||
|
||||
@ -46,6 +50,9 @@ const showSiderInverted = computed(() => !themeStore.darkMode && themeStore.layo
|
||||
<NSwitch v-model:value="themeStore.sider.inverted" />
|
||||
</SettingItem>
|
||||
</Transition>
|
||||
<SettingItem :label="$t('theme.grayscale')">
|
||||
<NSwitch :value="themeStore.grayscale" @update:value="handleGrayscaleChange" />
|
||||
</SettingItem>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -57,6 +57,7 @@ const local: App.I18n.Schema = {
|
||||
dark: 'Dark',
|
||||
auto: 'Follow System'
|
||||
},
|
||||
grayscale: 'Grayscale',
|
||||
layoutMode: {
|
||||
title: 'Layout Mode',
|
||||
vertical: 'Vertical Menu Mode',
|
||||
|
@ -57,6 +57,7 @@ const local: App.I18n.Schema = {
|
||||
dark: '暗黑模式',
|
||||
auto: '跟随系统'
|
||||
},
|
||||
grayscale: '灰度模式',
|
||||
layoutMode: {
|
||||
title: '布局模式',
|
||||
vertical: '左侧菜单模式',
|
||||
|
@ -5,7 +5,14 @@ import { useEventListener, usePreferredColorScheme } from '@vueuse/core';
|
||||
import { getColorPalette } from '@sa/color-palette';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import { localStg } from '@/utils/storage';
|
||||
import { addThemeVarsToHtml, createThemeToken, getNaiveTheme, initThemeSettings, toggleCssDarkMode } from './shared';
|
||||
import {
|
||||
addThemeVarsToHtml,
|
||||
createThemeToken,
|
||||
getNaiveTheme,
|
||||
initThemeSettings,
|
||||
toggleCssDarkMode,
|
||||
toggleGrayscaleMode
|
||||
} from './shared';
|
||||
|
||||
/** Theme store */
|
||||
export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
@ -23,6 +30,9 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
return settings.value.themeScheme === 'dark';
|
||||
});
|
||||
|
||||
/** grayscale mode */
|
||||
const grayscaleMode = computed(() => settings.value.grayscale);
|
||||
|
||||
/** Theme colors */
|
||||
const themeColors = computed(() => {
|
||||
const { themeColor, otherColor, isInfoFollowPrimary } = settings.value;
|
||||
@ -60,6 +70,15 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
settings.value.themeScheme = themeScheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set grayscale value
|
||||
*
|
||||
* @param isGrayscale
|
||||
*/
|
||||
function setGrayscale(isGrayscale: boolean) {
|
||||
settings.value.grayscale = isGrayscale;
|
||||
}
|
||||
|
||||
/** Toggle theme scheme */
|
||||
function toggleThemeScheme() {
|
||||
const themeSchemes: UnionKey.ThemeScheme[] = ['light', 'dark', 'auto'];
|
||||
@ -130,12 +149,19 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(
|
||||
grayscaleMode,
|
||||
val => {
|
||||
toggleGrayscaleMode(val);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// themeColors change, update css vars and storage theme color
|
||||
watch(
|
||||
themeColors,
|
||||
val => {
|
||||
setupThemeVarsToHtml();
|
||||
|
||||
localStg.set('themeColor', val.primary);
|
||||
},
|
||||
{ immediate: true }
|
||||
@ -153,6 +179,7 @@ export const useThemeStore = defineStore(SetupStoreId.Theme, () => {
|
||||
themeColors,
|
||||
naiveTheme,
|
||||
settingsJson,
|
||||
setGrayscale,
|
||||
resetStore,
|
||||
setThemeScheme,
|
||||
toggleThemeScheme,
|
||||
|
@ -3,6 +3,7 @@ import { getColorByPaletteNumber, getColorPalette } from '@sa/color-palette';
|
||||
import { addColorAlpha, getRgbOfColor } from '@sa/utils';
|
||||
import { overrideThemeSettings, themeSettings } from '@/theme/settings';
|
||||
import { themeVars } from '@/theme/vars';
|
||||
import { toggleHtmlClass } from '@/utils/common';
|
||||
import { localStg } from '@/utils/storage';
|
||||
|
||||
const DARK_CLASS = 'dark';
|
||||
@ -167,18 +168,29 @@ export function addThemeVarsToHtml(tokens: App.Theme.BaseToken, darkTokens: App.
|
||||
* @param darkMode Is dark mode
|
||||
*/
|
||||
export function toggleCssDarkMode(darkMode = false) {
|
||||
function addDarkClass() {
|
||||
document.documentElement.classList.add(DARK_CLASS);
|
||||
}
|
||||
|
||||
function removeDarkClass() {
|
||||
document.documentElement.classList.remove(DARK_CLASS);
|
||||
}
|
||||
const { add, remove } = toggleHtmlClass(DARK_CLASS);
|
||||
|
||||
if (darkMode) {
|
||||
addDarkClass();
|
||||
add();
|
||||
} else {
|
||||
removeDarkClass();
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle grayscale mode
|
||||
*
|
||||
* @param grayscaleMode Is grayscale mode
|
||||
*/
|
||||
export function toggleGrayscaleMode(grayscaleMode = false) {
|
||||
const GRAYSCALE_CLASS = 'grayscale';
|
||||
|
||||
const { add, remove } = toggleHtmlClass(GRAYSCALE_CLASS);
|
||||
|
||||
if (grayscaleMode) {
|
||||
add();
|
||||
} else {
|
||||
remove();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,3 +11,7 @@ body,
|
||||
html {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
html.grayscale {
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/** Default theme settings */
|
||||
export const themeSettings: App.Theme.ThemeSetting = {
|
||||
themeScheme: 'light',
|
||||
grayscale: false,
|
||||
themeColor: '#646cff',
|
||||
otherColor: {
|
||||
info: '#2080f0',
|
||||
|
3
src/typings/app.d.ts
vendored
3
src/typings/app.d.ts
vendored
@ -20,6 +20,8 @@ declare namespace App {
|
||||
themeScheme: UnionKey.ThemeScheme;
|
||||
/** Theme color */
|
||||
themeColor: string;
|
||||
/** grayscale mode */
|
||||
grayscale: boolean;
|
||||
/** Other color */
|
||||
otherColor: OtherColor;
|
||||
/** Whether info color is followed by the primary color */
|
||||
@ -298,6 +300,7 @@ declare namespace App {
|
||||
};
|
||||
theme: {
|
||||
themeSchema: { title: string } & Record<UnionKey.ThemeScheme, string>;
|
||||
grayscale: string;
|
||||
layoutMode: { title: string } & Record<UnionKey.ThemeLayoutMode, string>;
|
||||
themeColor: {
|
||||
title: string;
|
||||
|
@ -36,3 +36,23 @@ export function translateOptions(options: CommonType.Option<string>[]) {
|
||||
label: $t(option.label as App.I18n.I18nKey)
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle html class
|
||||
*
|
||||
* @param className
|
||||
*/
|
||||
export function toggleHtmlClass(className: string) {
|
||||
function add() {
|
||||
document.documentElement.classList.add(className);
|
||||
}
|
||||
|
||||
function remove() {
|
||||
document.documentElement.classList.remove(className);
|
||||
}
|
||||
|
||||
return {
|
||||
add,
|
||||
remove
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user