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-sand-100: #e1ded5;
--color-sand-200: #d6cfc2;
--color-sand-200: #fff7d5;
--color-sand-300: #888682;
--color-sand-400: #eed7ac;
--color-slate-100: #9c9eab;
--color-slate-200: #9fa2bd;
--color-slate-300: #5b5e7d;
--color-white: #ffffff;
--color-black: #000000;
--color-electric-400: #f0ff41;
--color-sapphire-700: #172dd7;
--color-brand-yellow: var(--color-electric-400);
--color-brand-blue: var(--color-sapphire-700);
--color-azure-300: #78bae9;
--color-azure-400: #31b9f4;
--color-azure-600: #0b8ce9;
--color-cobalt-800: #185a8b;
--color-jade-400: #47e469;
--color-jade-600: #00cd72;
--color-gold-400: #fcbf64;
--color-gold-500: #fdab34;
--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-200: #d62952;
@@ -101,6 +116,11 @@
var(--color-smoke-500) 50%,
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 */
--color-muted: var(--p-text-muted-color);
@@ -196,6 +216,27 @@
--text-secondary: var(--color-ash-500);
--text-primary: var(--color-charcoal-700);
--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 {
@@ -257,6 +298,27 @@
--text-primary: var(--color-white);
--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 {
@@ -321,6 +383,27 @@
--color-text-secondary: var(--text-secondary);
--color-text-primary: var(--text-primary);
--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 {

View File

@@ -474,3 +474,13 @@ export function formatDuration(milliseconds: number): string {
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"
variant="ghost"
rounded="lg"
class="hover:bg-white dark-theme:hover:bg-zinc-800"
class="hover:bg-base-background"
>
<template #top>
<CardTop ratio="landscape">
@@ -178,7 +178,7 @@
variant="ghost"
rounded="lg"
: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"
@mouseleave="hoveredTemplate = null"
@click="onLoadWorkflow(template)"
@@ -323,7 +323,7 @@
size="compact"
variant="ghost"
rounded="lg"
class="hover:bg-white dark-theme:hover:bg-zinc-800"
class="hover:bg-base-background"
>
<template #top>
<CardTop ratio="square">

View File

@@ -92,7 +92,7 @@ describe('BypassButton', () => {
const button = wrapper.find('button')
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"
text
data-testid="bypass-button"
class="hover:bg-[#E7E6E6] hover:dark-theme:bg-charcoal-600"
class="hover:bg-secondary-background"
@click="toggleBypass"
>
<template #icon>

View File

@@ -4,7 +4,7 @@
value: t('selectionToolbox.executeButton.tooltip'),
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
@mouseenter="() => handleMouseEnter()"
@mouseleave="() => handleMouseLeave()"

View File

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

View File

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

View File

@@ -3,7 +3,7 @@
<IconTextButton
v-if="asset?.kind !== '3D'"
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Inspect asset"
@click="handleInspect"
>
@@ -14,7 +14,7 @@
<IconTextButton
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Add to current workflow"
@click="handleAddToWorkflow"
>
@@ -25,7 +25,7 @@
<IconTextButton
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Download"
@click="handleDownload"
>
@@ -39,7 +39,7 @@
<IconTextButton
v-if="showWorkflowOptions"
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Open as workflow in new tab"
@click="handleOpenWorkflow"
>
@@ -51,7 +51,7 @@
<IconTextButton
v-if="showWorkflowOptions"
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Export workflow"
@click="handleExportWorkflow"
>
@@ -64,7 +64,7 @@
<IconTextButton
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Copy job ID"
@click="handleCopyJobId"
>
@@ -77,7 +77,7 @@
<IconTextButton
type="transparent"
class="dark-theme:text-white"
class="text-base-foreground"
label="Delete"
@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 -->
<div class="group relative px-2">
<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"
>
<!-- Audio icon -->
@@ -135,7 +135,7 @@
<!-- Delete button -->
<button
: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"
>
<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"
@click="handleStopRecording"
>
<div class="size-2.5 rounded-sm bg-[#C02323]" />
<div class="size-2.5 rounded-sm bg-danger-100" />
</button>
<button

View File

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

View File

@@ -21,7 +21,7 @@ const actionButtonStyle =
const resetInputStyle = 'bg-transparent border-0 outline-0 ring-0 text-left'
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 sortTriggerRef = useTemplateRef('sortTriggerRef')
@@ -50,7 +50,7 @@ function handleSortSelected(item: SortOption) {
cn(
actionButtonStyle,
'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',
'focus-within:!outline-blue-500/80'
)
@@ -150,7 +150,7 @@ function handleSortSelected(item: SortOption) {
resetInputStyle,
layoutSwitchItemStyle,
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,
layoutSwitchItemStyle,
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(
'px-4 py-2 rounded-md inline-flex justify-center items-center cursor-pointer select-none',
'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',
filterSelected === option.id
? '!bg-zinc-500/20 text-black dark-theme:text-white'
? '!bg-zinc-500/20 text-base-foreground'
: 'bg-transparent'
)
"

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
@click="showImportFailedDialog"
>
<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')
}}</span>
</button>