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