mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-05 15:40:10 +00:00
Add support for custom light color palette (#2156)
Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { Palette } from '../src/types/colorPaletteTypes'
|
||||
import { comfyPageFixture as test } from './fixtures/ComfyPage'
|
||||
|
||||
const customColorPalettes = {
|
||||
const customColorPalettes: Record<string, Palette> = {
|
||||
obsidian: {
|
||||
version: 102,
|
||||
id: 'obsidian',
|
||||
@@ -128,6 +129,19 @@ const customColorPalettes = {
|
||||
'tr-odd-bg-color': 'rgba(19,19,19,.9)'
|
||||
}
|
||||
}
|
||||
},
|
||||
// A custom light theme with fg color red
|
||||
light_red: {
|
||||
id: 'light_red',
|
||||
name: 'Light Red',
|
||||
light_theme: true,
|
||||
colors: {
|
||||
node_slot: {},
|
||||
litegraph_base: {},
|
||||
comfy_base: {
|
||||
'fg-color': '#ff0000'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,6 +156,12 @@ test.describe('Color Palette', () => {
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'custom-color-palette-obsidian-dark.png'
|
||||
)
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'light_red')
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'custom-color-palette-light-red.png'
|
||||
)
|
||||
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'dark')
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('default-color-palette.png')
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 102 KiB |
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"id": "light",
|
||||
"name": "Light",
|
||||
"light_theme": true,
|
||||
"colors": {
|
||||
"node_slot": {
|
||||
"CLIP": "#FFA726",
|
||||
@@ -13,7 +14,12 @@
|
||||
"MASK": "#9CCC65",
|
||||
"MODEL": "#7E57C2",
|
||||
"STYLE_MODEL": "#D4E157",
|
||||
"VAE": "#FF7043"
|
||||
"VAE": "#FF7043",
|
||||
"NOISE": "#B0B0B0",
|
||||
"GUIDER": "#66FFFF",
|
||||
"SAMPLER": "#ECB4B4",
|
||||
"SIGMAS": "#CDFFCD",
|
||||
"TAESD": "#DCC274"
|
||||
},
|
||||
"litegraph_base": {
|
||||
"BACKGROUND_IMAGE": "data:image/gif;base64,R0lGODlhZABkALMAAAAAAP///+vr6+rq6ujo6Ofn5+bm5uXl5d3d3f///wAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAkALAAAAABkAGQAAAT/UMhJq7046827HkcoHkYxjgZhnGG6si5LqnIM0/fL4qwwIMAg0CAsEovBIxKhRDaNy2GUOX0KfVFrssrNdpdaqTeKBX+dZ+jYvEaTf+y4W66mC8PUdrE879f9d2mBeoNLfH+IhYBbhIx2jkiHiomQlGKPl4uZe3CaeZifnnijgkESBqipqqusra6vsLGys62SlZO4t7qbuby7CLa+wqGWxL3Gv3jByMOkjc2lw8vOoNSi0czAncXW3Njdx9Pf48/Z4Kbbx+fQ5evZ4u3k1fKR6cn03vHlp7T9/v8A/8Gbp4+gwXoFryXMB2qgwoMMHyKEqA5fxX322FG8tzBcRnMW/zlulPbRncmQGidKjMjyYsOSKEF2FBlJQMCbOHP6c9iSZs+UnGYCdbnSo1CZI5F64kn0p1KnTH02nSoV3dGTV7FFHVqVq1dtWcMmVQZTbNGu72zqXMuW7danVL+6e4t1bEy6MeueBYLXrNO5Ze36jQtWsOG97wIj1vt3St/DjTEORss4nNq2mDP3e7w4r1bFkSET5hy6s2TRlD2/mSxXtSHQhCunXo26NevCpmvD/UU6tuullzULH76q92zdZG/Ltv1a+W+osI/nRmyc+fRi1Xdbh+68+0vv10dH3+77KD/i6IdnX669/frn5Zsjh4/2PXju8+8bzc9/6fj27LFnX11/+IUnXWl7BJfegm79FyB9JOl3oHgSklefgxAC+FmFGpqHIYcCfkhgfCohSKKJVo044YUMttggiBkmp6KFXw1oII24oYhjiDByaKOOHcp3Y5BD/njikSkO+eBREQAAOw==",
|
||||
|
||||
@@ -11,14 +11,15 @@
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
|
||||
import SidebarIcon from './SidebarIcon.vue'
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const currentTheme = computed(() => settingStore.get('Comfy.ColorPalette'))
|
||||
const colorPaletteStore = useColorPaletteStore()
|
||||
const icon = computed(() =>
|
||||
currentTheme.value !== 'light' ? 'pi pi-moon' : 'pi pi-sun'
|
||||
colorPaletteStore.completedActivePalette.light_theme
|
||||
? 'pi pi-sun'
|
||||
: 'pi pi-moon'
|
||||
)
|
||||
|
||||
const commandStore = useCommandStore()
|
||||
|
||||
@@ -4,7 +4,7 @@ import github from '@/assets/palettes/github.json'
|
||||
import light from '@/assets/palettes/light.json'
|
||||
import nord from '@/assets/palettes/nord.json'
|
||||
import solarized from '@/assets/palettes/solarized.json'
|
||||
import type { ColorPalettes } from '@/types/colorPaletteTypes'
|
||||
import type { ColorPalettes, CompletedPalette } from '@/types/colorPaletteTypes'
|
||||
|
||||
export const CORE_COLOR_PALETTES: ColorPalettes = {
|
||||
dark,
|
||||
@@ -15,4 +15,6 @@ export const CORE_COLOR_PALETTES: ColorPalettes = {
|
||||
github
|
||||
} as const
|
||||
|
||||
export const DEFAULT_COLOR_PALETTE = dark
|
||||
export const DEFAULT_COLOR_PALETTE: CompletedPalette = dark
|
||||
export const DEFAULT_DARK_COLOR_PALETTE: CompletedPalette = dark
|
||||
export const DEFAULT_LIGHT_COLOR_PALETTE: CompletedPalette = light
|
||||
|
||||
@@ -5,6 +5,10 @@ import {
|
||||
LiteGraph
|
||||
} from '@comfyorg/litegraph'
|
||||
|
||||
import {
|
||||
DEFAULT_DARK_COLOR_PALETTE,
|
||||
DEFAULT_LIGHT_COLOR_PALETTE
|
||||
} from '@/constants/coreColorPalettes'
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
@@ -16,6 +20,7 @@ import { useSettingStore } from '@/stores/settingStore'
|
||||
import { useToastStore } from '@/stores/toastStore'
|
||||
import { type ComfyWorkflow, useWorkflowStore } from '@/stores/workflowStore'
|
||||
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { useSearchBoxStore } from '@/stores/workspace/searchBoxStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
|
||||
@@ -23,6 +28,7 @@ export function useCoreCommands(): ComfyCommand[] {
|
||||
const workflowService = useWorkflowService()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const dialogService = useDialogService()
|
||||
const colorPaletteStore = useColorPaletteStore()
|
||||
const getTracker = () => workflowStore.activeWorkflow?.changeTracker
|
||||
|
||||
const getSelectedNodes = (): LGraphNode[] => {
|
||||
@@ -410,18 +416,18 @@ export function useCoreCommands(): ComfyCommand[] {
|
||||
label: 'Toggle Theme (Dark/Light)',
|
||||
versionAdded: '1.3.12',
|
||||
function: (() => {
|
||||
let previousDarkTheme: string = 'dark'
|
||||
let previousDarkTheme: string = DEFAULT_DARK_COLOR_PALETTE.id
|
||||
let previousLightTheme: string = DEFAULT_LIGHT_COLOR_PALETTE.id
|
||||
|
||||
// Official light theme is the only light theme supported now.
|
||||
const isDarkMode = (themeId: string) => themeId !== 'light'
|
||||
return () => {
|
||||
const settingStore = useSettingStore()
|
||||
const currentTheme = settingStore.get('Comfy.ColorPalette')
|
||||
if (isDarkMode(currentTheme)) {
|
||||
previousDarkTheme = currentTheme
|
||||
settingStore.set('Comfy.ColorPalette', 'light')
|
||||
} else {
|
||||
const theme = colorPaletteStore.completedActivePalette
|
||||
if (theme.light_theme) {
|
||||
previousLightTheme = theme.id
|
||||
settingStore.set('Comfy.ColorPalette', previousDarkTheme)
|
||||
} else {
|
||||
previousDarkTheme = theme.id
|
||||
settingStore.set('Comfy.ColorPalette', previousLightTheme)
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
@@ -3,7 +3,9 @@ import { computed, ref } from 'vue'
|
||||
|
||||
import {
|
||||
CORE_COLOR_PALETTES,
|
||||
DEFAULT_COLOR_PALETTE
|
||||
DEFAULT_COLOR_PALETTE,
|
||||
DEFAULT_DARK_COLOR_PALETTE,
|
||||
DEFAULT_LIGHT_COLOR_PALETTE
|
||||
} from '@/constants/coreColorPalettes'
|
||||
import type {
|
||||
ColorPalettes,
|
||||
@@ -63,20 +65,24 @@ export const useColorPaletteStore = defineStore('colorPalette', () => {
|
||||
palette.colors.comfy_base['comfy-menu-bg']
|
||||
}
|
||||
|
||||
const defaultPalette = palette.light_theme
|
||||
? DEFAULT_LIGHT_COLOR_PALETTE
|
||||
: DEFAULT_DARK_COLOR_PALETTE
|
||||
|
||||
return {
|
||||
...palette,
|
||||
colors: {
|
||||
...palette.colors,
|
||||
node_slot: {
|
||||
...DEFAULT_COLOR_PALETTE.colors.node_slot,
|
||||
...defaultPalette.colors.node_slot,
|
||||
...palette.colors.node_slot
|
||||
},
|
||||
litegraph_base: {
|
||||
...DEFAULT_COLOR_PALETTE.colors.litegraph_base,
|
||||
...defaultPalette.colors.litegraph_base,
|
||||
...palette.colors.litegraph_base
|
||||
},
|
||||
comfy_base: {
|
||||
...DEFAULT_COLOR_PALETTE.colors.comfy_base,
|
||||
...defaultPalette.colors.comfy_base,
|
||||
...palette.colors.comfy_base
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,8 @@ export const paletteSchema = z
|
||||
.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
colors: partialColorsSchema
|
||||
colors: partialColorsSchema,
|
||||
light_theme: z.boolean().optional()
|
||||
})
|
||||
.passthrough()
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import type { ToastMessageOptions } from 'primevue/toast'
|
||||
import { useToast } from 'primevue/usetoast'
|
||||
import { computed, onBeforeUnmount, onMounted, watch, watchEffect } from 'vue'
|
||||
import { onBeforeUnmount, onMounted, watch, watchEffect } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import BrowserTabTitle from '@/components/BrowserTabTitle.vue'
|
||||
@@ -41,6 +41,7 @@ import {
|
||||
import { useServerConfigStore } from '@/stores/serverConfigStore'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore'
|
||||
import { useColorPaletteStore } from '@/stores/workspace/colorPaletteStore'
|
||||
import { useSidebarTabStore } from '@/stores/workspace/sidebarTabStore'
|
||||
import { useWorkspaceStore } from '@/stores/workspaceStore'
|
||||
import { StatusWsMessageStatus } from '@/types/apiTypes'
|
||||
@@ -51,18 +52,16 @@ const { t } = useI18n()
|
||||
const toast = useToast()
|
||||
const settingStore = useSettingStore()
|
||||
const executionStore = useExecutionStore()
|
||||
|
||||
const theme = computed<string>(() => settingStore.get('Comfy.ColorPalette'))
|
||||
const colorPaletteStore = useColorPaletteStore()
|
||||
|
||||
watch(
|
||||
theme,
|
||||
() => colorPaletteStore.completedActivePalette,
|
||||
(newTheme) => {
|
||||
const DARK_THEME_CLASS = 'dark-theme'
|
||||
const isDarkTheme = newTheme !== 'light'
|
||||
if (isDarkTheme) {
|
||||
document.body.classList.add(DARK_THEME_CLASS)
|
||||
} else {
|
||||
if (newTheme.light_theme) {
|
||||
document.body.classList.remove(DARK_THEME_CLASS)
|
||||
} else {
|
||||
document.body.classList.add(DARK_THEME_CLASS)
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
|
||||
Reference in New Issue
Block a user