Upgrade: Tailwind v4 (#5246)

* temp: move tailwind calls out of the layer

* temp: ts tailwind config

* upgrade: Tailwind v4
This got a little out of hand.
Had to add a relative reference to the stylesheet in any component that uses @apply instead of the utility classes directly.

* upgrade: bg-opacity is now a modifier

* fix: Classic menu buttons assume a border

* Update test expectations [skip ci]

* fix: New preflight removal pattern

* fix: Skeletons don't have skin

* Update test expectations [skip ci]

* fix: Missing @reference

* [auto-fix] Apply ESLint and Prettier fixes

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Alexander Brown
2025-09-03 12:37:43 -07:00
committed by GitHub
parent caee3832a5
commit 85017dbba0
263 changed files with 640 additions and 488 deletions

View File

@@ -79,6 +79,8 @@ const sidebarStateKey = computed(() => {
</script>
<style scoped>
@reference '../assets/css/style.css';
:deep(.p-splitter-gutter) {
pointer-events: auto;
}

View File

@@ -56,7 +56,9 @@ const positionCSS = computed<CSSProperties>(() =>
</script>
<style scoped>
@reference '../assets/css/style.css';
.comfy-menu-hamburger {
@apply fixed z-[9999] flex flex-row;
@apply fixed z-9999 flex flex-row;
}
</style>

View File

@@ -5,7 +5,7 @@
:class="{ 'is-dragging': isDragging, 'is-docked': isDocked }"
>
<div ref="panelRef" class="actionbar-content flex items-center select-none">
<span ref="dragHandleRef" class="drag-handle cursor-move mr-2 p-0!" />
<span ref="dragHandleRef" class="drag-handle cursor-move mr-2" />
<ComfyQueueButton />
</div>
</Panel>
@@ -228,6 +228,8 @@ watch([isDragging, isOverlappingWithTopMenu], ([dragging, overlapping]) => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.actionbar {
pointer-events: all;
position: fixed;

View File

@@ -40,8 +40,8 @@
</div>
</TabList>
</Tabs>
<!-- h-0 to force the div to flex-grow -->
<div class="flex-grow h-0">
<!-- h-0 to force the div to grow -->
<div class="grow h-0">
<ExtensionSlot
v-if="
bottomPanelStore.bottomPanelVisible &&

View File

@@ -18,13 +18,13 @@
:key="command.id"
class="shortcut-item flex justify-between items-center py-2 rounded hover:bg-surface-100 dark-theme:hover:bg-surface-700 transition-colors duration-200"
>
<div class="shortcut-info flex-grow pr-4">
<div class="shortcut-info grow pr-4">
<div class="shortcut-name text-sm font-medium">
{{ t(`commands.${normalizeI18nKey(command.id)}.label`) }}
</div>
</div>
<div class="keybinding-display flex-shrink-0">
<div class="keybinding-display shrink-0">
<div
class="keybinding-combo flex gap-1"
:aria-label="`Keyboard shortcut: ${command.keybinding!.combo.getKeySequences().join(' + ')}`"

View File

@@ -156,6 +156,8 @@ onUpdated(() => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.subgraph-breadcrumb:not(:empty) {
flex: auto;
flex-shrink: 10000;
@@ -196,6 +198,8 @@ onUpdated(() => {
</style>
<style>
@reference '../../assets/css/style.css';
.subgraph-breadcrumb-collapse .p-breadcrumb-list {
.p-breadcrumb-item,
.p-breadcrumb-separator {

View File

@@ -36,7 +36,7 @@
v-if="isEditing"
ref="itemInputRef"
v-model="itemLabel"
class="fixed z-[10000] text-[.8rem] px-2 py-2"
class="fixed z-10000 text-[.8rem] px-2 py-2"
@blur="inputBlur(true)"
@click.stop
@keydown.enter="inputBlur(true)"
@@ -211,6 +211,8 @@ const inputBlur = async (doRename: boolean) => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.p-breadcrumb-item-link,
.p-breadcrumb-item-icon {
@apply select-none;

View File

@@ -1,6 +1,6 @@
<template>
<div
class="flex justify-center items-center flex-shrink-0 outline-none border-none p-0 bg-white text-neutral-950 dark-theme:bg-zinc-700 dark-theme:text-white rounded-lg cursor-pointer"
class="flex justify-center items-center shrink-0 outline-hidden border-none p-0 bg-white text-neutral-950 dark-theme:bg-zinc-700 dark-theme:text-white rounded-lg cursor-pointer"
>
<slot></slot>
</div>

View File

@@ -36,7 +36,7 @@ const {
} = defineProps<IconTextButtonProps>()
const buttonStyle = computed(() => {
const baseClasses = `${getBaseButtonClasses()} !justify-start gap-2`
const baseClasses = `${getBaseButtonClasses()} justify-start! gap-2`
const sizeClasses = getButtonSizeClasses(size)
const typeClasses = border
? getBorderButtonTypeClasses(type)

View File

@@ -23,9 +23,9 @@ const containerClasses = computed(() => {
'flex flex-col bg-white dark-theme:bg-zinc-800 rounded-lg shadow-sm border border-zinc-200 dark-theme:border-zinc-700 overflow-hidden'
const ratioClasses = {
square: 'aspect-[256/308]',
portrait: 'aspect-[256/325]',
tallPortrait: 'aspect-[256/353]'
square: 'aspect-256/308',
portrait: 'aspect-256/325',
tallPortrait: 'aspect-256/353'
}
return `${baseClasses} ${ratioClasses[ratio]}`

View File

@@ -31,8 +31,8 @@ const topStyle = computed(() => {
const baseClasses = 'relative p-0'
const ratioClasses = {
square: 'aspect-[1/1]',
landscape: 'aspect-[48/27]'
square: 'aspect-square',
landscape: 'aspect-48/27'
}
return `${baseClasses} ${ratioClasses[ratio]}`

View File

@@ -1,6 +1,6 @@
<template>
<div
class="inline-flex justify-center items-center gap-1 flex-shrink-0 py-1 px-2 text-xs bg-[#D9D9D966]/40 rounded font-bold text-white/90"
class="inline-flex justify-center items-center gap-1 shrink-0 py-1 px-2 text-xs bg-[#D9D9D966]/40 rounded font-bold text-white/90"
>
<slot name="icon" class="text-xs text-white/90"></slot>
<span>{{ label }}</span>

View File

@@ -1,7 +1,7 @@
<!-- A generalized form item for rendering in a form. -->
<template>
<div class="flex flex-row items-center gap-2">
<div class="form-label flex flex-grow items-center">
<div class="form-label flex grow items-center">
<span
:id="`${props.id}-label`"
class="text-muted"
@@ -112,6 +112,8 @@ function getFormComponent(item: FormItem): Component {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.form-input :deep(.input-slider) .p-inputnumber input,
.form-input :deep(.input-slider) .slider-part {
@apply w-20;

View File

@@ -91,6 +91,8 @@ const clearSearch = () => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
:deep(.p-inputtext) {
--p-form-field-padding-x: 0.625rem;
}

View File

@@ -23,6 +23,8 @@ defineEmits(['remove'])
</script>
<style scoped>
@reference '../../assets/css/style.css';
:deep(.i-badge) {
@apply bg-green-500 text-white;
}

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex items-center">
<span v-if="position === 'left'" class="mr-2 shrink-0">{{ text }}</span>
<Divider :align="align" :type="type" :layout="layout" class="flex-grow" />
<Divider :align="align" :type="type" :layout="layout" class="grow" />
<span v-if="position === 'right'" class="ml-2 shrink-0">{{ text }}</span>
</div>
</template>

View File

@@ -43,6 +43,8 @@ const dialogStore = useDialogStore()
</script>
<style>
@reference '../../assets/css/style.css';
.global-dialog .p-dialog-header {
@apply p-2 2xl:p-[var(--p-dialog-header-padding)];
@apply pb-0;

View File

@@ -59,7 +59,7 @@
class="overflow-y-auto h-64 rounded-lg bg-black"
:class="{
'h-64': index !== focusedLogs.length - 1,
'flex-grow': index === focusedLogs.length - 1
grow: index === focusedLogs.length - 1
}"
@scroll="handleScroll"
>

View File

@@ -1,6 +1,6 @@
<template>
<div class="settings-container">
<ScrollPanel class="settings-sidebar flex-shrink-0 p-2 w-48 2xl:w-64">
<ScrollPanel class="settings-sidebar shrink-0 p-2 w-48 2xl:w-64">
<SearchBox
v-model:modelValue="searchQuery"
class="settings-search-box w-full mb-2"

View File

@@ -6,7 +6,7 @@
:key="createNodeDefKey(nodeDef)"
class="border rounded-lg p-4"
>
<NodePreview :node-def="nodeDef" class="!text-[.625rem] !min-w-full" />
<NodePreview :node-def="nodeDef" class="text-[.625rem]! min-w-full!" />
</div>
</template>
<template v-else-if="isLoading">

View File

@@ -1,5 +1,5 @@
<template>
<div class="w-full aspect-[7/3] overflow-hidden">
<div class="w-full aspect-7/3 overflow-hidden">
<!-- default banner show -->
<div v-if="showDefaultBanner" class="w-full h-full">
<img

View File

@@ -1,10 +1,10 @@
<template>
<div
class="rounded-lg border shadow-sm h-full overflow-hidden flex flex-col"
class="rounded-lg shadow-sm h-full overflow-hidden flex flex-col"
data-virtual-grid-item
>
<!-- Card header - flush with top, approximately 15% of height -->
<div class="w-full px-4 py-3 flex justify-between items-center border-b">
<div class="w-full px-4 py-3 flex justify-between items-center">
<div class="flex items-center">
<div class="w-6 h-6 flex items-center justify-center">
<Skeleton shape="circle" width="1.5rem" height="1.5rem" />
@@ -17,7 +17,7 @@
<!-- Card content with icon on left and text on right -->
<div class="flex-1 p-4 flex">
<!-- Left icon - 64x64 -->
<div class="flex-shrink-0 mr-4">
<div class="shrink-0 mr-4">
<Skeleton width="4rem" height="4rem" border-radius="0.5rem" />
</div>
@@ -42,7 +42,7 @@
</div>
<!-- Card footer - similar to header -->
<div class="w-full px-5 py-4 flex justify-between items-center border-t">
<div class="w-full px-5 py-4 flex justify-between items-center">
<Skeleton width="4rem" height="0.8rem" />
<Skeleton width="6rem" height="0.8rem" />
</div>

View File

@@ -54,7 +54,7 @@
</div>
<template v-if="creditHistory.length > 0">
<div class="flex-grow">
<div class="grow">
<DataTable :value="creditHistory" :show-headers="false">
<Column field="title" :header="$t('g.name')">
<template #body="{ data }">

View File

@@ -295,6 +295,8 @@ async function resetAllKeybindings() {
</script>
<style scoped>
@reference '../../../../assets/css/style.css';
:deep(.p-datatable-tbody) > tr > td {
@apply p-1;
min-height: 2rem;

View File

@@ -2,7 +2,7 @@
<TabPanel :value="props.value" class="h-full w-full" :class="props.class">
<div class="flex flex-col h-full w-full gap-2">
<slot name="header" />
<ScrollPanel class="flex-grow h-0 pr-2">
<ScrollPanel class="grow h-0 pr-2">
<slot />
</ScrollPanel>
<slot name="footer" />

View File

@@ -123,6 +123,8 @@ const handleForgotPassword = async (
</script>
<style scoped>
@reference '../../../../assets/css/style.css';
.text-link-disabled {
@apply opacity-50 cursor-not-allowed;
}

View File

@@ -5,7 +5,7 @@
<!-- Backdrop -->
<div
v-if="hasActivePopup"
class="fixed inset-0 z-[1200]"
class="fixed inset-0 z-1200"
@click="hideModal"
></div>
@@ -52,7 +52,7 @@
icon="pi pi-expand"
:aria-label="fitViewTooltip"
:style="stringifiedMinimapStyles.buttonStyles"
class="hover:dark-theme:!bg-[#444444] hover:!bg-[#E7E6E6]"
class="dark-theme:hover:bg-[#444444]! hover:bg-[#E7E6E6]!"
@click="() => commandStore.execute('Comfy.Canvas.FitView')"
>
<template #icon>
@@ -205,27 +205,27 @@ const focusCommandText = computed(() =>
// Computed properties for button classes and states
const selectButtonClass = computed(() =>
isCanvasUnlocked.value
? 'dark-theme:[&:not(:active)]:!bg-[#262729] [&:not(:active)]:!bg-[#E7E6E6]'
? 'not-active:dark-theme:bg-[#262729]! not-active:bg-[#E7E6E6]!'
: ''
)
const handButtonClass = computed(() =>
isCanvasReadOnly.value
? 'dark-theme:[&:not(:active)]:!bg-[#262729] [&:not(:active)]:!bg-[#E7E6E6]'
? 'not-active:dark-theme:bg-[#262729]! not-active:bg-[#E7E6E6]!'
: ''
)
const zoomButtonClass = computed(() => [
'!w-16',
'w-16!',
isModalVisible.value
? 'dark-theme:[&:not(:active)]:!bg-[#262729] [&:not(:active)]:!bg-[#E7E6E6]'
? 'not-active:dark-theme:bg-[#262729]! not-active:bg-[#E7E6E6]!'
: '',
'hover:dark-theme:!bg-[#262729] hover:!bg-[#E7E6E6]'
'dark-theme:hover:bg-[#262729]! hover:bg-[#E7E6E6]!'
])
const focusButtonClass = computed(() => ({
'hover:dark-theme:!bg-[#262729] hover:!bg-[#E7E6E6]': true,
'dark-theme:[&:not(:active)]:!bg-[#262729] [&:not(:active)]:!bg-[#E7E6E6]':
'dark-theme:hover:bg-[#262729]! hover:bg-[#E7E6E6]!': true,
'not-active:dark-theme:bg-[#262729]! not-active:bg-[#E7E6E6]!':
workspaceStore.focusMode
}))
@@ -254,9 +254,9 @@ const linkVisibilityAriaLabel = computed(() =>
)
const linkVisibleClass = computed(() => [
linkHidden.value
? 'dark-theme:[&:not(:active)]:!bg-[#262729] [&:not(:active)]:!bg-[#E7E6E6]'
? 'not-active:dark-theme:bg-[#262729]! not-active:bg-[#E7E6E6]!'
: '',
'hover:dark-theme:!bg-[#262729] hover:!bg-[#E7E6E6]'
'dark-theme:hover:bg-[#262729]! hover:bg-[#E7E6E6]!'
])
onMounted(() => {

View File

@@ -2,7 +2,7 @@
<div
v-if="visible && initialized"
ref="minimapRef"
class="minimap-main-container flex absolute bottom-[66px] right-2 md:right-11 z-[1000]"
class="minimap-main-container flex absolute bottom-[66px] right-2 md:right-11 z-1000"
>
<MiniMapPanel
v-if="showOptionsPanel"

View File

@@ -1,7 +1,7 @@
<template>
<div
v-if="visible"
class="w-[250px] absolute flex justify-center right-2 md:right-11 z-[1300] bottom-[66px] !bg-inherit !border-0"
class="w-[250px] absolute flex justify-center right-2 md:right-11 z-1300 bottom-[66px] bg-inherit! border-0!"
>
<div
class="bg-white dark-theme:bg-[#2b2b2b] border border-gray-200 dark-theme:border-gray-700 rounded-lg shadow-lg p-4 w-4/5"
@@ -15,7 +15,7 @@
:pt="{
root: {
class:
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:!bg-transparent focus:!bg-transparent active:!bg-transparent'
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:bg-transparent! focus:bg-transparent! active:bg-transparent!'
},
label: {
class: 'flex flex-col items-start w-full'
@@ -41,7 +41,7 @@
:pt="{
root: {
class:
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:!bg-transparent focus:!bg-transparent active:!bg-transparent'
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:bg-transparent! focus:bg-transparent! active:bg-transparent!'
},
label: {
class: 'flex flex-col items-start w-full'
@@ -67,7 +67,7 @@
:pt="{
root: {
class:
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:!bg-transparent focus:!bg-transparent active:!bg-transparent'
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:bg-transparent! focus:bg-transparent! active:bg-transparent!'
},
label: {
class: 'flex flex-col items-start w-full'
@@ -92,7 +92,7 @@
:pt="{
root: {
class:
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:!bg-transparent focus:!bg-transparent active:!bg-transparent'
'flex items-center justify-between cursor-pointer p-2 rounded w-full text-left hover:bg-transparent! focus:bg-transparent! active:bg-transparent!'
},
label: {
class: 'flex flex-col items-start w-full'
@@ -122,7 +122,7 @@
:show-buttons="false"
:use-grouping="false"
:unstyled="true"
input-class="flex-1 bg-transparent border-none outline-none text-sm shadow-none my-0 "
input-class="flex-1 bg-transparent border-none outline-hidden text-sm shadow-none my-0 "
fluid
@input="applyZoom"
@keyup.enter="applyZoom"

View File

@@ -152,6 +152,8 @@ watch(
</script>
<style scoped>
@reference '../../../assets/css/style.css';
.color-picker-container {
transform: translateX(-50%);
}

View File

@@ -26,8 +26,8 @@
"
text
rounded
class="!p-1 !h-4 !w-4 text-gray-400 hover:text-gray-600 dark-theme:hover:text-gray-200 transition"
pt:icon:class="!text-xs"
class="p-1! h-4! w-4! text-gray-400 hover:text-gray-600 hover:dark-theme:text-gray-200 transition"
pt:icon:class="text-xs!"
:icon="editIndex === i ? 'pi pi-times' : 'pi pi-pencil'"
:aria-label="
editIndex === i ? $t('chatHistory.cancelEdit') : $t('g.edit')

View File

@@ -189,6 +189,8 @@ watch(
</script>
<style scoped>
@reference '../../../assets/css/style.css';
.dom-widget > * {
@apply h-full w-full;
}

View File

@@ -5,7 +5,7 @@
<div class="flex items-center gap-2">
<div class="flex-1 break-all flex items-center gap-2">
<span v-html="formattedText"></span>
<Skeleton v-if="isParentNodeExecuting" class="!flex-1 !h-4" />
<Skeleton v-if="isParentNodeExecuting" class="flex-1! h-4!" />
</div>
</div>
</div>

View File

@@ -5,8 +5,8 @@
"
text
rounded
class="!p-1 !h-4 !w-6 text-gray-400 hover:text-gray-600 dark-theme:hover:text-gray-200 transition"
pt:icon:class="!text-xs"
class="p-1! h-4! w-6! text-gray-400 hover:text-gray-600 hover:dark-theme:text-gray-200 transition"
pt:icon:class="text-xs!"
:icon="copied ? 'pi pi-check' : 'pi pi-copy'"
:aria-label="
copied ? $t('chatHistory.copiedTooltip') : $t('chatHistory.copyTooltip')

View File

@@ -47,7 +47,7 @@
:label="$t('g.clearAll')"
type="transparent"
size="fit-content"
class="text-sm !text-blue-500 !dark-theme:text-blue-600"
class="text-sm text-blue-500! dark-theme:text-blue-600!"
@click.stop="selectedItems = []"
/>
</div>
@@ -77,7 +77,7 @@
<template #option="slotProps">
<div class="flex items-center gap-2">
<div
class="flex h-4 w-4 p-0.5 flex-shrink-0 items-center justify-center rounded transition-all duration-200"
class="flex h-4 w-4 p-0.5 shrink-0 items-center justify-center rounded transition-all duration-200"
:class="
slotProps.selected
? 'border-[3px] border-blue-400 bg-blue-400 dark-theme:border-blue-500 dark-theme:bg-blue-500'
@@ -179,7 +179,7 @@ const pt = computed(() => ({
option: ({ context }: MultiSelectPassThroughMethodOptions) => ({
class: [
'flex gap-1 items-center p-2',
'hover:bg-neutral-100/50 dark-theme:hover:bg-zinc-700/50',
'hover:bg-neutral-100/50 hover:dark-theme:bg-zinc-700/50',
// Add focus/highlight state for keyboard navigation
{
'bg-neutral-100/50 dark-theme:bg-zinc-700/50': context?.focused

View File

@@ -6,7 +6,7 @@
:placeholder="placeHolder || 'Search...'"
type="text"
unstyled
class="w-full p-0 border-none outline-none bg-transparent text-xs text-neutral dark-theme:text-white"
class="w-full p-0 border-none outline-hidden bg-transparent text-xs text-neutral dark-theme:text-white"
/>
</div>
</template>

View File

@@ -110,7 +110,7 @@ const pt = computed(() => ({
label: {
class:
// Align with MultiSelect labelContainer spacing
'flex-1 flex items-center overflow-hidden whitespace-nowrap pl-4 py-2 outline-none'
'flex-1 flex items-center overflow-hidden whitespace-nowrap pl-4 py-2 outline-hidden'
},
dropdown: {
class:
@@ -134,7 +134,7 @@ const pt = computed(() => ({
class: [
// Row layout
'flex items-center justify-between gap-3 px-3 py-2',
'hover:bg-neutral-100/50 dark-theme:hover:bg-zinc-700/50',
'hover:bg-neutral-100/50 hover:dark-theme:bg-zinc-700/50',
// Selected state + check icon
{ 'bg-neutral-100/50 dark-theme:bg-zinc-700/50': context.selected },
// Add focus state for keyboard navigation

View File

@@ -160,6 +160,8 @@ const pickGpu = (value: typeof selected.value) => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.p-tag {
--p-tag-gap: 0.5rem;
}
@@ -184,10 +186,10 @@ div.selected {
}
.gpu-button {
@apply w-1/2 m-0 cursor-pointer rounded-lg flex flex-col items-center justify-around bg-neutral-800 bg-opacity-50 hover:bg-opacity-75 transition-colors;
@apply w-1/2 m-0 cursor-pointer rounded-lg flex flex-col items-center justify-around bg-neutral-800/50 hover:bg-neutral-800/75 transition-colors;
&.selected {
@apply opacity-100 bg-neutral-700 bg-opacity-50 hover:bg-opacity-60;
@apply opacity-100 bg-neutral-700/50 hover:bg-neutral-700/60;
}
}

View File

@@ -1,18 +1,15 @@
<template>
<div
class="absolute top-12 left-2 flex flex-col pointer-events-auto z-20 bg-gray-700 bg-opacity-30 rounded-lg"
class="absolute top-12 left-2 flex flex-col pointer-events-auto z-20 bg-gray-700/30 rounded-lg"
>
<div class="relative show-menu">
<Button
class="p-button-rounded p-button-text bg-opacity-30"
@click="toggleMenu"
>
<Button class="p-button-rounded p-button-text" @click="toggleMenu">
<i class="pi pi-bars text-white text-lg" />
</Button>
<div
v-show="isMenuOpen"
class="absolute left-12 top-0 bg-black bg-opacity-50 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 rounded-lg shadow-lg"
>
<div class="flex flex-col">
<Button
@@ -29,7 +26,7 @@
</div>
</div>
<div v-show="activeCategory" class="bg-gray-700 bg-opacity-30 rounded-lg">
<div v-show="activeCategory" class="bg-gray-700/30 rounded-lg">
<SceneControls
v-if="activeCategory === 'scene'"
ref="sceneControlsRef"

View File

@@ -2,7 +2,7 @@
<Transition name="fade">
<div
v-if="modelLoading"
class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50"
class="absolute inset-0 bg-black/50 flex items-center justify-center z-50"
>
<div class="flex flex-col items-center">
<div class="spinner" />

View File

@@ -18,7 +18,7 @@
</Button>
<div
v-show="showFOV"
class="absolute left-12 top-0 bg-black bg-opacity-50 p-4 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 p-4 rounded-lg shadow-lg"
style="width: 150px"
>
<Slider

View File

@@ -15,7 +15,7 @@
</Button>
<div
v-show="showExportFormats"
class="absolute left-12 top-0 bg-black bg-opacity-50 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 rounded-lg shadow-lg"
>
<div class="flex flex-col">
<Button

View File

@@ -15,7 +15,7 @@
</Button>
<div
v-show="showLightIntensity"
class="absolute left-12 top-0 bg-black bg-opacity-50 p-4 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 p-4 rounded-lg shadow-lg"
style="width: 150px"
>
<Slider

View File

@@ -12,7 +12,7 @@
</Button>
<div
v-show="showUpDirection"
class="absolute left-12 top-0 bg-black bg-opacity-50 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 rounded-lg shadow-lg"
>
<div class="flex flex-col">
<Button
@@ -43,7 +43,7 @@
</Button>
<div
v-show="showMaterialMode"
class="absolute left-12 top-0 bg-black bg-opacity-50 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 rounded-lg shadow-lg"
>
<div class="flex flex-col">
<Button
@@ -74,7 +74,7 @@
</Button>
<div
v-show="showEdgeThreshold"
class="absolute left-12 top-0 bg-black bg-opacity-50 p-4 rounded-lg shadow-lg"
class="absolute left-12 top-0 bg-black/50 p-4 rounded-lg shadow-lg"
style="width: 150px"
>
<label class="text-white text-xs mb-1 block"

View File

@@ -1,5 +1,5 @@
<template>
<div class="relative bg-gray-700 bg-opacity-30 rounded-lg">
<div class="relative bg-gray-700/30 rounded-lg">
<div class="flex flex-col gap-2">
<Button
class="p-button-rounded p-button-text"

View File

@@ -1,5 +1,5 @@
<template>
<div class="relative bg-gray-700 bg-opacity-30 rounded-lg">
<div class="relative bg-gray-700/30 rounded-lg">
<div class="flex flex-col gap-2">
<Button class="p-button-rounded p-button-text" @click="openIn3DViewer">
<i

View File

@@ -86,6 +86,8 @@ const isExecuting = useMinLoadingDurationRef(reactiveExecuting, 250)
</script>
<style scoped>
@reference '../../assets/css/style.css';
.task-card-ok {
@apply text-green-500 absolute -right-4 -bottom-4 opacity-100 row-span-full col-span-full transition-opacity;

View File

@@ -76,11 +76,11 @@ describe('NodePreview', () => {
expect(wrapper.find('._sb_preview_badge').text()).toBe('Preview')
})
it('applies overflow-ellipsis class to node header for text truncation', () => {
it('applies text-ellipsis class to node header for text truncation', () => {
const wrapper = mountComponent()
const nodeHeader = wrapper.find('.node_header')
expect(nodeHeader.classes()).toContain('overflow-ellipsis')
expect(nodeHeader.classes()).toContain('text-ellipsis')
expect(nodeHeader.classes()).toContain('mr-4')
})
@@ -105,7 +105,7 @@ describe('NodePreview', () => {
expect(nodeHeader.attributes('title')).toBe(longNameNodeDef.display_name)
// Verify overflow handling classes are applied
expect(nodeHeader.classes()).toContain('overflow-ellipsis')
expect(nodeHeader.classes()).toContain('text-ellipsis')
// The actual text content should still be the full name (CSS handles truncation)
expect(nodeHeader.text()).toContain(longNameNodeDef.display_name)

View File

@@ -6,7 +6,7 @@ https://github.com/Nuked88/ComfyUI-N-Sidebar/blob/7ae7da4a9761009fb6629bc04c6830
<div class="_sb_node_preview">
<div class="_sb_table">
<div
class="node_header overflow-ellipsis mr-4"
class="node_header text-ellipsis mr-4"
:title="nodeDef.display_name"
:style="{
backgroundColor: litegraphColors.NODE_DEFAULT_COLOR,

View File

@@ -36,7 +36,7 @@
<AutoCompletePlus
:model-value="filters"
class="comfy-vue-node-search-box z-10 flex-grow"
class="comfy-vue-node-search-box z-10 grow"
scroll-height="40vh"
:placeholder="placeholder"
:input-id="inputId"

View File

@@ -68,6 +68,8 @@ const submit = () => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
._content {
@apply flex flex-col space-y-2;
}

View File

@@ -94,6 +94,8 @@ const computedTooltip = computed(() => t(tooltip) + tooltipSuffix)
</style>
<style scoped>
@reference '../../assets/css/style.css';
.side-bar-button {
width: var(--sidebar-width);
height: calc(var(--sidebar-width) + 0.5rem);

View File

@@ -1,7 +1,7 @@
<template>
<SidebarTabTemplate
:title="$t('sideToolbar.modelLibrary')"
class="bg-[var(--p-tree-background)]"
class="bg-(--p-tree-background)"
>
<template #tool-buttons>
<Button

View File

@@ -3,7 +3,7 @@
<SidebarTabTemplate
v-if="!isHelpOpen"
:title="$t('sideToolbar.nodeLibrary')"
class="bg-[var(--p-tree-background)]"
class="bg-(--p-tree-background)"
>
<template #tool-buttons>
<Button

View File

@@ -20,8 +20,8 @@
</Toolbar>
<slot name="header" />
</div>
<!-- h-0 to force scrollpanel to flex-grow -->
<ScrollPanel class="comfy-vue-side-bar-body flex-grow h-0">
<!-- h-0 to force scrollpanel to grow -->
<ScrollPanel class="comfy-vue-side-bar-body grow h-0">
<slot name="body" />
</ScrollPanel>
</div>
@@ -38,6 +38,8 @@ const props = defineProps<{
</script>
<style scoped>
@reference '../../../assets/css/style.css';
:deep(.p-toolbar-end) .p-button {
@apply py-1 2xl:py-2;
}

View File

@@ -1,7 +1,7 @@
<template>
<SidebarTabTemplate
:title="$t('sideToolbar.workflows')"
class="workflows-sidebar-tab bg-[var(--p-tree-background)]"
class="workflows-sidebar-tab bg-(--p-tree-background)"
>
<template #tool-buttons>
<Button

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex flex-col h-full bg-[var(--p-tree-background)] overflow-auto">
<div class="flex flex-col h-full bg-(--p-tree-background) overflow-auto">
<div
class="px-3 py-2 flex items-center border-b border-[var(--p-divider-color)]"
class="px-3 py-2 flex items-center border-b border-(--p-divider-color)"
>
<Button
v-tooltip.bottom="$t('g.back')"
@@ -12,7 +12,7 @@
/>
<span class="ml-2 font-semibold">{{ node.display_name }}</span>
</div>
<div class="p-4 flex-grow node-help-content w-full mx-auto">
<div class="p-4 grow node-help-content w-full mx-auto">
<ProgressSpinner
v-if="isLoading"
class="m-auto"
@@ -118,7 +118,9 @@ const outputList = computed(() =>
)
</script>
<style scoped lang="postcss">
<style scoped>
@reference './../../../../assets/css/style.css';
.node-help-content :deep(:is(img, video)) {
@apply max-w-full h-auto block mb-4;
}

View File

@@ -133,6 +133,8 @@ onUnmounted(() => {
</script>
<style scoped>
@reference '../../../../assets/css/style.css';
.node-lib-node-container {
@apply h-full w-full;
}

View File

@@ -313,6 +313,8 @@ const hasActiveStateSiblings = (item: MenuItem): boolean => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
:deep(.p-menubar-submenu.dropdown-direction-up) {
@apply top-auto bottom-full flex-col-reverse;
}

View File

@@ -9,9 +9,7 @@
aria-label="user profile"
@click="popover?.toggle($event)"
>
<div
class="flex items-center rounded-full bg-[var(--p-content-background)]"
>
<div class="flex items-center rounded-full bg-(--p-content-background)">
<UserAvatar :photo-url="photoURL" />
<i class="pi pi-chevron-down px-1" :style="{ fontSize: '0.5rem' }" />

View File

@@ -8,7 +8,7 @@
class="mb-3"
:photo-url="userPhotoUrl"
:pt:icon:class="{
'!text-2xl': !userPhotoUrl
'text-2xl!': !userPhotoUrl
}"
size="large"
/>

View File

@@ -2,7 +2,7 @@
<div>
<div
v-show="showTopMenu && workflowTabsPosition === 'Topbar'"
class="w-full flex content-end z-[1001] h-[38px]"
class="w-full flex content-end z-1001 h-[38px]"
style="background: var(--border-color)"
>
<WorkflowTabs />
@@ -14,19 +14,19 @@
:class="{ dropzone: isDropZone, 'dropzone-active': isDroppable }"
>
<CommandMenubar />
<div class="flex-grow min-w-0 app-drag h-full"></div>
<div class="grow min-w-0 app-drag h-full"></div>
<div
ref="menuRight"
class="comfyui-menu-right flex-shrink-1 overflow-auto"
/>
<Actionbar />
<CurrentUserButton class="flex-shrink-0" />
<CurrentUserButton class="shrink-0" />
</div>
<!-- Virtual top menu for native window (drag handle) -->
<div
v-show="isNativeWindow() && !showTopMenu"
class="fixed top-0 left-0 app-drag w-full h-[var(--comfy-topbar-height)]"
class="fixed top-0 left-0 app-drag w-full h-(--comfy-topbar-height)"
/>
</div>
</template>

View File

@@ -175,6 +175,8 @@ onUnmounted(() => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.status-indicator {
@apply absolute font-bold;
font-size: 1.5rem;

View File

@@ -169,6 +169,8 @@ defineExpose({
</script>
<style scoped>
@reference '../../assets/css/style.css';
.workflow-preview-content {
@apply flex flex-col rounded-xl overflow-hidden;
max-width: var(--popover-width);
@@ -204,6 +206,8 @@ defineExpose({
</style>
<style>
@reference '../../assets/css/style.css';
.workflow-popover-fade {
--p-popover-background: transparent;
--p-popover-content-padding: 0;

View File

@@ -55,7 +55,7 @@
/>
<Button
v-tooltip="{ value: $t('sideToolbar.newBlankWorkflow'), showDelay: 300 }"
class="new-blank-workflow-button flex-shrink-0 no-drag rounded-none"
class="new-blank-workflow-button shrink-0 no-drag rounded-none"
icon="pi pi-plus"
text
severity="secondary"
@@ -65,7 +65,7 @@
<ContextMenu ref="menu" :model="contextMenuItems" />
<div
v-if="menuSetting !== 'Bottom' && isDesktop"
class="window-actions-spacer flex-shrink-0 app-drag"
class="window-actions-spacer shrink-0 app-drag"
/>
</div>
</template>
@@ -302,12 +302,14 @@ onUpdated(() => {
</script>
<style scoped>
@reference '../../assets/css/style.css';
.workflow-tabs-container {
background-color: var(--comfy-menu-secondary-bg);
}
:deep(.p-togglebutton) {
@apply p-0 bg-transparent rounded-none flex-shrink relative border-0 border-r border-solid;
@apply p-0 bg-transparent rounded-none shrink relative border-0 border-r border-solid;
border-right-color: var(--border-color);
min-width: 90px;
}

View File

@@ -38,7 +38,7 @@
v-if="$slots.header"
class="w-full h-16 px-6 py-4 flex justify-between gap-2"
>
<div class="flex-1 flex gap-2 flex-shrink-0">
<div class="flex-1 flex gap-2 shrink-0">
<IconButton v-if="!notMobile" @click="toggleLeftPanel">
<i-lucide:panel-left v-if="!showLeftPanel" class="text-sm" />
<i-lucide:panel-left-close v-else class="text-sm" />

View File

@@ -4,7 +4,7 @@
:class="
active
? 'bg-neutral-100 dark-theme:bg-zinc-700 text-neutral'
: 'text-neutral hover:bg-zinc-100 hover:dark-theme:bg-zinc-700/50'
: 'text-neutral hover:bg-zinc-100 dark-theme:hover:bg-zinc-700/50'
"
role="button"
@click="onClick"