Backport: Css token standardization (#6363) (#6669)

## Summary
Backports the CSS token standardization changes from PR #6363 to the
`core/1.30` branch.

Resolved merge conflict in `MediaTitle.vue` and added missing
`truncateFilename` function to maintain compatibility.

**Original PR**: https://github.com/Comfy-Org/ComfyUI_frontend/pull/6363
**Cherry-picked commit**: bde5244a71

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6669-Backport-Css-token-standardization-6363-2aa6d73d36508153be09cdc67f6ac8a4)
by [Unito](https://www.unito.io)
This commit is contained in:
Christian Byrne
2025-11-12 20:07:53 -08:00
committed by GitHub
parent 85d3bc25d6
commit 3be12e18e8
18 changed files with 150 additions and 46 deletions

View File

@@ -49,27 +49,42 @@
--color-smoke-800: #8a8a8a; --color-smoke-800: #8a8a8a;
--color-sand-100: #e1ded5; --color-sand-100: #e1ded5;
--color-sand-200: #d6cfc2; --color-sand-200: #fff7d5;
--color-sand-300: #888682; --color-sand-300: #888682;
--color-sand-400: #eed7ac;
--color-slate-100: #9c9eab; --color-slate-100: #9c9eab;
--color-slate-200: #9fa2bd; --color-slate-200: #9fa2bd;
--color-slate-300: #5b5e7d; --color-slate-300: #5b5e7d;
--color-white: #ffffff;
--color-black: #000000;
--color-electric-400: #f0ff41; --color-electric-400: #f0ff41;
--color-sapphire-700: #172dd7; --color-sapphire-700: #172dd7;
--color-brand-yellow: var(--color-electric-400); --color-brand-yellow: var(--color-electric-400);
--color-brand-blue: var(--color-sapphire-700); --color-brand-blue: var(--color-sapphire-700);
--color-azure-300: #78bae9;
--color-azure-400: #31b9f4; --color-azure-400: #31b9f4;
--color-azure-600: #0b8ce9; --color-azure-600: #0b8ce9;
--color-cobalt-800: #185a8b;
--color-jade-400: #47e469; --color-jade-400: #47e469;
--color-jade-600: #00cd72; --color-jade-600: #00cd72;
--color-gold-400: #fcbf64; --color-gold-400: #fcbf64;
--color-gold-500: #fdab34;
--color-gold-600: #fd9903; --color-gold-600: #fd9903;
--color-coral-500: #f75951;
--color-coral-600: #e04e48;
--color-coral-700: #b33a3a;
--color-magenta-300: #ceaac9;
--color-magenta-700: #6a246a;
--color-danger-100: #c02323; --color-danger-100: #c02323;
--color-danger-200: #d62952; --color-danger-200: #d62952;
@@ -101,6 +116,11 @@
var(--color-smoke-500) 50%, var(--color-smoke-500) 50%,
transparent transparent
); );
--color-alpha-smoke-500-20: #c5c5c533;
--color-alpha-smoke-400-40: #d9d9d966;
--color-alpha-azure-600-30: #0b8ce94d;
--color-alpha-magenta-700-60: #6a246a99;
--color-alpha-magenta-300-60: #ceaac999;
/* PrimeVue pulled colors */ /* PrimeVue pulled colors */
--color-muted: var(--p-text-muted-color); --color-muted: var(--p-text-muted-color);
@@ -196,6 +216,27 @@
--text-secondary: var(--color-ash-500); --text-secondary: var(--color-ash-500);
--text-primary: var(--color-charcoal-700); --text-primary: var(--color-charcoal-700);
--input-surface: rgb(0 0 0 / 0.15); --input-surface: rgb(0 0 0 / 0.15);
/* Semantic tokens - light mode */
--muted-foreground: var(--color-charcoal-200);
--base-foreground: var(--color-charcoal-800);
--brand-yellow: var(--color-electric-400);
--brand-blue: var(--color-sapphire-700);
--secondary-background: var(--color-smoke-200);
--secondary-background-hover: var(--color-smoke-400);
--secondary-background-selected: var(--color-smoke-600);
--base-background: var(--color-white);
--primary-background: var(--color-azure-400);
--primary-background-hover: var(--color-cobalt-800);
--destructive-background: var(--color-coral-500);
--destructive-background-hover: var(--color-coral-600);
--inverted-background-hover: var(--color-charcoal-600);
--warning-background: var(--color-gold-400);
--warning-background-hover: var(--color-gold-500);
--border-default: var(--color-smoke-600);
--border-subtle: var(--color-smoke-400);
--muted-background: var(--color-smoke-700);
--accent-background: var(--color-smoke-800);
} }
.dark-theme { .dark-theme {
@@ -257,6 +298,27 @@
--text-primary: var(--color-white); --text-primary: var(--color-white);
--input-surface: rgb(130 130 130 / 0.1); --input-surface: rgb(130 130 130 / 0.1);
/* Semantic tokens - dark mode */
--muted-foreground: var(--color-smoke-800);
--base-foreground: var(--color-white);
--brand-yellow: var(--color-electric-400);
--brand-blue: var(--color-sapphire-700);
--secondary-background: var(--color-charcoal-600);
--secondary-background-hover: var(--color-charcoal-400);
--secondary-background-selected: var(--color-charcoal-200);
--base-background: var(--color-charcoal-800);
--primary-background: var(--color-azure-600);
--primary-background-hover: var(--color-azure-400);
--destructive-background: var(--color-coral-700);
--destructive-background-hover: var(--color-coral-600);
--inverted-background-hover: var(--color-smoke-200);
--warning-background: var(--color-gold-600);
--warning-background-hover: var(--color-gold-500);
--border-default: var(--color-charcoal-200);
--border-subtle: var(--color-charcoal-300);
--muted-background: var(--color-charcoal-100);
--accent-background: var(--color-charcoal-100);
} }
@theme inline { @theme inline {
@@ -321,6 +383,27 @@
--color-text-secondary: var(--text-secondary); --color-text-secondary: var(--text-secondary);
--color-text-primary: var(--text-primary); --color-text-primary: var(--text-primary);
--color-input-surface: var(--input-surface); --color-input-surface: var(--input-surface);
/* Semantic tokens */
--color-base-foreground: var(--base-foreground);
--color-muted-foreground: var(--muted-foreground);
--color-base-background: var(--base-background);
--color-secondary-background: var(--secondary-background);
--color-secondary-background-hover: var(--secondary-background-hover);
--color-secondary-background-selected: var(--secondary-background-selected);
--color-primary-background: var(--primary-background);
--color-primary-background-hover: var(--primary-background-hover);
--color-destructive-background: var(--destructive-background);
--color-destructive-background-hover: var(--destructive-background-hover);
--color-inverted-background-hover: var(--inverted-background-hover);
--color-warning-background: var(--warning-background);
--color-warning-background-hover: var(--warning-background-hover);
--color-border-default: var(--border-default);
--color-border-subtle: var(--border-subtle);
--color-muted-background: var(--muted-background);
--color-accent-background: var(--accent-background);
--color-brand-yellow: var(--brand-yellow);
--color-brand-blue: var(--brand-blue);
} }
@custom-variant dark-theme { @custom-variant dark-theme {

View File

@@ -474,3 +474,13 @@ export function formatDuration(milliseconds: number): string {
return parts.join(' ') return parts.join(' ')
} }
/**
* Truncates a filename for display purposes.
* Currently returns the filename as-is since truncation is handled by CSS.
* @param filename The filename to truncate
* @returns The display-ready filename
*/
export function truncateFilename(filename: string): string {
return filename
}

View File

@@ -144,7 +144,7 @@
size="compact" size="compact"
variant="ghost" variant="ghost"
rounded="lg" rounded="lg"
class="hover:bg-white dark-theme:hover:bg-zinc-800" class="hover:bg-base-background"
> >
<template #top> <template #top>
<CardTop ratio="landscape"> <CardTop ratio="landscape">
@@ -178,7 +178,7 @@
variant="ghost" variant="ghost"
rounded="lg" rounded="lg"
:data-testid="`template-workflow-${template.name}`" :data-testid="`template-workflow-${template.name}`"
class="hover:bg-white dark-theme:hover:bg-zinc-800" class="hover:bg-base-background"
@mouseenter="hoveredTemplate = template.name" @mouseenter="hoveredTemplate = template.name"
@mouseleave="hoveredTemplate = null" @mouseleave="hoveredTemplate = null"
@click="onLoadWorkflow(template)" @click="onLoadWorkflow(template)"
@@ -323,7 +323,7 @@
size="compact" size="compact"
variant="ghost" variant="ghost"
rounded="lg" rounded="lg"
class="hover:bg-white dark-theme:hover:bg-zinc-800" class="hover:bg-base-background"
> >
<template #top> <template #top>
<CardTop ratio="square"> <CardTop ratio="square">

View File

@@ -92,7 +92,7 @@ describe('BypassButton', () => {
const button = wrapper.find('button') const button = wrapper.find('button')
expect(button.classes()).not.toContain( expect(button.classes()).not.toContain(
'dark-theme:[&:not(:active)]:!bg-[#262729]' 'dark-theme:[&:not(:active)]:!bg-charcoal-600'
) )
}) })

View File

@@ -7,7 +7,7 @@
severity="secondary" severity="secondary"
text text
data-testid="bypass-button" data-testid="bypass-button"
class="hover:bg-[#E7E6E6] hover:dark-theme:bg-charcoal-600" class="hover:bg-secondary-background"
@click="toggleBypass" @click="toggleBypass"
> >
<template #icon> <template #icon>

View File

@@ -4,7 +4,7 @@
value: t('selectionToolbox.executeButton.tooltip'), value: t('selectionToolbox.executeButton.tooltip'),
showDelay: 1000 showDelay: 1000
}" }"
class="size-8 bg-[#31B9F4] !p-0 dark-theme:bg-[#0B8CE9]" class="size-8 bg-azure-400 !p-0 dark-theme:bg-azure-600"
text text
@mouseenter="() => handleMouseEnter()" @mouseenter="() => handleMouseEnter()"
@mouseleave="() => handleMouseLeave()" @mouseleave="() => handleMouseLeave()"

View File

@@ -27,9 +27,9 @@
:severity="option.badge === 'new' ? 'info' : 'secondary'" :severity="option.badge === 'new' ? 'info' : 'secondary'"
:value="t(option.badge)" :value="t(option.badge)"
:class="{ :class="{
'rounded-4xl bg-[#31B9F4] dark-theme:bg-[#0B8CE9]': 'rounded-4xl bg-azure-400 dark-theme:bg-azure-600':
option.badge === 'new', option.badge === 'new',
'rounded-4xl bg-[#9C9EAB] dark-theme:bg-[#000]': 'rounded-4xl bg-slate-100 dark-theme:bg-black':
option.badge === 'deprecated', option.badge === 'deprecated',
'h-4 gap-2.5 px-1 text-[9px] text-white uppercase': true 'h-4 gap-2.5 px-1 text-[9px] text-white uppercase': true
}" }"

View File

@@ -27,8 +27,7 @@
:class=" :class="
cn( cn(
'mb-2 m-0 text-base font-semibold line-clamp-2 wrap-anywhere', 'mb-2 m-0 text-base font-semibold line-clamp-2 wrap-anywhere',
'text-slate-800', 'text-base-foreground'
'dark-theme:text-white'
) )
" "
> >
@@ -111,7 +110,7 @@ const cardClasses = computed(() => {
'appearance-none bg-transparent p-0 m-0', 'appearance-none bg-transparent p-0 m-0',
'font-inherit text-inherit outline-none cursor-pointer text-left', 'font-inherit text-inherit outline-none cursor-pointer text-left',
'bg-smoke-100 dark-theme:bg-charcoal-800', 'bg-smoke-100 dark-theme:bg-charcoal-800',
'hover:bg-smoke-200 dark-theme:hover:bg-charcoal-600', 'hover:bg-secondary-background',
'border-none', 'border-none',
'focus:outline-solid outline-azure-600 outline-4' 'focus:outline-solid outline-azure-600 outline-4'
) )

View File

@@ -3,7 +3,7 @@
<IconTextButton <IconTextButton
v-if="asset?.kind !== '3D'" v-if="asset?.kind !== '3D'"
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Inspect asset" label="Inspect asset"
@click="handleInspect" @click="handleInspect"
> >
@@ -14,7 +14,7 @@
<IconTextButton <IconTextButton
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Add to current workflow" label="Add to current workflow"
@click="handleAddToWorkflow" @click="handleAddToWorkflow"
> >
@@ -25,7 +25,7 @@
<IconTextButton <IconTextButton
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Download" label="Download"
@click="handleDownload" @click="handleDownload"
> >
@@ -39,7 +39,7 @@
<IconTextButton <IconTextButton
v-if="showWorkflowOptions" v-if="showWorkflowOptions"
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Open as workflow in new tab" label="Open as workflow in new tab"
@click="handleOpenWorkflow" @click="handleOpenWorkflow"
> >
@@ -51,7 +51,7 @@
<IconTextButton <IconTextButton
v-if="showWorkflowOptions" v-if="showWorkflowOptions"
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Export workflow" label="Export workflow"
@click="handleExportWorkflow" @click="handleExportWorkflow"
> >
@@ -64,7 +64,7 @@
<IconTextButton <IconTextButton
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Copy job ID" label="Copy job ID"
@click="handleCopyJobId" @click="handleCopyJobId"
> >
@@ -77,7 +77,7 @@
<IconTextButton <IconTextButton
type="transparent" type="transparent"
class="dark-theme:text-white" class="text-base-foreground"
label="Delete" label="Delete"
@click="handleDelete" @click="handleDelete"
> >

View File

@@ -0,0 +1,21 @@
<template>
<h3
class="m-0 line-clamp-1 text-sm font-bold text-base-foreground"
:title="fullName"
>
{{ displayName }}
</h3>
</template>
<script setup lang="ts">
import { computed } from 'vue'
import { truncateFilename } from '@/utils/formatUtil'
const props = defineProps<{
fileName: string
}>()
const fullName = computed(() => props.fileName)
const displayName = computed(() => truncateFilename(props.fileName))
</script>

View File

@@ -112,7 +112,7 @@
<!-- Audio player --> <!-- Audio player -->
<div class="group relative px-2"> <div class="group relative px-2">
<div <div
class="flex items-center gap-4 rounded-lg bg-[#1a1b1e] p-4" class="flex items-center gap-4 rounded-lg bg-charcoal-800 p-4"
style="border: 1px solid #262729" style="border: 1px solid #262729"
> >
<!-- Audio icon --> <!-- Audio icon -->
@@ -135,7 +135,7 @@
<!-- Delete button --> <!-- Delete button -->
<button <button
:aria-label="$t('g.deleteAudioFile')" :aria-label="$t('g.deleteAudioFile')"
class="flex h-8 w-8 items-center justify-center rounded border-none transition-all duration-150 hover:bg-[#262729] focus:outline-none" class="flex h-8 w-8 items-center justify-center rounded border-none transition-all duration-150 hover:bg-charcoal-600 focus:outline-none"
@click="clearFile" @click="clearFile"
> >
<i class="pi pi-times text-sm text-white"></i> <i class="pi pi-times text-sm text-white"></i>

View File

@@ -48,7 +48,7 @@
class="flex size-8 animate-pulse items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors" class="flex size-8 animate-pulse items-center justify-center rounded-full border-0 bg-smoke-500/33 transition-colors"
@click="handleStopRecording" @click="handleStopRecording"
> >
<div class="size-2.5 rounded-sm bg-[#C02323]" /> <div class="size-2.5 rounded-sm bg-danger-100" />
</button> </button>
<button <button

View File

@@ -38,9 +38,7 @@
</div> </div>
<!-- Time Display --> <!-- Time Display -->
<div <div class="text-sm font-normal text-nowrap text-base-foreground">
class="text-sm font-normal text-nowrap text-black dark-theme:text-white"
>
{{ formatTime(currentTime) }} / {{ formatTime(duration) }} {{ formatTime(currentTime) }} / {{ formatTime(duration) }}
</div> </div>
</div> </div>
@@ -116,10 +114,9 @@
> >
<template #item="{ item }"> <template #item="{ item }">
<div v-if="item.key === 'volume'" class="w-48 px-4 py-2"> <div v-if="item.key === 'volume'" class="w-48 px-4 py-2">
<label <label class="mb-2 block text-xs text-base-foreground">{{
class="mb-2 block text-xs text-black dark-theme:text-white" item.label
>{{ item.label }}</label }}</label>
>
<Slider <Slider
:model-value="volume * 10" :model-value="volume * 10"
:min="0" :min="0"
@@ -134,12 +131,10 @@
class="flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10" class="flex cursor-pointer items-center px-4 py-2 text-xs hover:bg-white/10"
@click="item.onClick?.()" @click="item.onClick?.()"
> >
<span class="text-black dark-theme:text-white">{{ <span class="text-base-foreground">{{ item.label }}</span>
item.label
}}</span>
<i <i
v-if="item.selected" v-if="item.selected"
class="ml-auto icon-[lucide--check] size-4 text-black dark-theme:text-white" class="ml-auto icon-[lucide--check] size-4 text-base-foreground"
/> />
</div> </div>
</template> </template>

View File

@@ -21,7 +21,7 @@ const actionButtonStyle =
const resetInputStyle = 'bg-transparent border-0 outline-0 ring-0 text-left' const resetInputStyle = 'bg-transparent border-0 outline-0 ring-0 text-left'
const layoutSwitchItemStyle = const layoutSwitchItemStyle =
'size-6 flex justify-center items-center rounded-sm cursor-pointer transition-all duration-150 hover:scale-108 hover:text-black hover:dark-theme:text-white active:scale-95' 'size-6 flex justify-center items-center rounded-sm cursor-pointer transition-all duration-150 hover:scale-108 hover:text-base-foreground active:scale-95'
const sortPopoverRef = useTemplateRef('sortPopoverRef') const sortPopoverRef = useTemplateRef('sortPopoverRef')
const sortTriggerRef = useTemplateRef('sortTriggerRef') const sortTriggerRef = useTemplateRef('sortTriggerRef')
@@ -50,7 +50,7 @@ function handleSortSelected(item: SortOption) {
cn( cn(
actionButtonStyle, actionButtonStyle,
'flex-1 flex px-2 items-center text-base leading-none cursor-text', 'flex-1 flex px-2 items-center text-base leading-none cursor-text',
searchQuery?.trim() !== '' ? 'text-black dark-theme:text-white' : '', searchQuery?.trim() !== '' ? 'text-base-foreground' : '',
'hover:!outline-blue-500/80', 'hover:!outline-blue-500/80',
'focus-within:!outline-blue-500/80' 'focus-within:!outline-blue-500/80'
) )
@@ -150,7 +150,7 @@ function handleSortSelected(item: SortOption) {
resetInputStyle, resetInputStyle,
layoutSwitchItemStyle, layoutSwitchItemStyle,
layoutMode === 'list' layoutMode === 'list'
? 'bg-neutral-500/50 text-black dark-theme:text-white' ? 'bg-neutral-500/50 text-base-foreground'
: '' : ''
) )
" "
@@ -164,7 +164,7 @@ function handleSortSelected(item: SortOption) {
resetInputStyle, resetInputStyle,
layoutSwitchItemStyle, layoutSwitchItemStyle,
layoutMode === 'grid' layoutMode === 'grid'
? 'bg-neutral-500/50 text-black dark-theme:text-white' ? 'bg-neutral-500/50 text-base-foreground'
: '' : ''
) )
" "

View File

@@ -19,10 +19,10 @@ const filterSelected = defineModel<OptionId>('filterSelected')
cn( cn(
'px-4 py-2 rounded-md inline-flex justify-center items-center cursor-pointer select-none', 'px-4 py-2 rounded-md inline-flex justify-center items-center cursor-pointer select-none',
'transition-all duration-150', 'transition-all duration-150',
'hover:text-black hover:dark-theme:text-white hover:bg-zinc-500/10', 'hover:text-base-foreground hover:bg-zinc-500/10',
'active:scale-95', 'active:scale-95',
filterSelected === option.id filterSelected === option.id
? '!bg-zinc-500/20 text-black dark-theme:text-white' ? '!bg-zinc-500/20 text-base-foreground'
: 'bg-transparent' : 'bg-transparent'
) )
" "

View File

@@ -51,9 +51,7 @@
type="transparent" type="transparent"
@click="dismissWarningBanner" @click="dismissWarningBanner"
> >
<i <i class="pi pi-times text-xs text-base-foreground"></i>
class="pi pi-times text-xs text-neutral-900 dark-theme:text-white"
></i>
</IconButton> </IconButton>
</div> </div>
<RegistrySearchBar <RegistrySearchBar

View File

@@ -4,9 +4,7 @@
<div class="flex h-full w-full flex-col gap-2 px-4 py-6"> <div class="flex h-full w-full flex-col gap-2 px-4 py-6">
<!-- Description --> <!-- Description -->
<div v-if="showAfterWhatsNew"> <div v-if="showAfterWhatsNew">
<p <p class="m-0 mb-4 text-sm leading-4 text-base-foreground">
class="m-0 mb-4 text-sm leading-4 text-neutral-800 dark-theme:text-white"
>
{{ $t('manager.conflicts.description') }} {{ $t('manager.conflicts.description') }}
<br /><br /> <br /><br />
{{ $t('manager.conflicts.info') }} {{ $t('manager.conflicts.info') }}

View File

@@ -6,7 +6,7 @@
@click="showImportFailedDialog" @click="showImportFailedDialog"
> >
<i class="pi pi-code text-base"></i> <i class="pi pi-code text-base"></i>
<span class="text-sm dark-theme:text-white">{{ <span class="text-sm text-base-foreground">{{
t('serverStart.openLogs') t('serverStart.openLogs')
}}</span> }}</span>
</button> </button>