mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-02 14:27:40 +00:00
## 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:
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()"
|
||||
|
||||
@@ -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
|
||||
}"
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
>
|
||||
|
||||
21
src/platform/assets/components/MediaTitle.vue
Normal file
21
src/platform/assets/components/MediaTitle.vue
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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'
|
||||
: ''
|
||||
)
|
||||
"
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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') }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user