-
+
![Preview]()
+
+ {{ data.previewSize }}
+
@@ -255,13 +254,13 @@ function getHandleTop(index: number): string {
diff --git a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetNumber.vue b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetNumber.vue
index 414873a21..42cbbb01e 100644
--- a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetNumber.vue
+++ b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetNumber.vue
@@ -105,41 +105,40 @@ function decrement(): void {
display: flex;
align-items: center;
justify-content: center;
- width: 24px;
- height: 26px;
- background: #3f3f46;
- border: 1px solid #3f3f46;
- color: #a1a1aa;
+ width: 26px;
+ height: 24px;
+ background: #2a2a2e;
+ border: none;
+ color: #71717a;
cursor: pointer;
transition: all 0.15s;
}
.number-btn:first-child {
- border-radius: 6px 0 0 6px;
+ border-radius: 4px 0 0 4px;
}
.number-btn:last-child {
- border-radius: 0 6px 6px 0;
+ border-radius: 0 4px 4px 0;
}
.number-btn:hover:not(:disabled) {
- background: #52525b;
- color: #fafafa;
+ background: #3f3f46;
+ color: #a1a1aa;
}
.number-btn:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
.number-input {
flex: 1;
- background: #27272a;
- border: 1px solid #3f3f46;
- border-left: none;
- border-right: none;
- color: #fafafa;
- padding: 4px 8px;
+ height: 24px;
+ background: #2a2a2e;
+ border: none;
+ color: #e4e4e7;
+ padding: 0 8px;
font-size: 11px;
text-align: center;
outline: none;
@@ -154,12 +153,11 @@ function decrement(): void {
}
.number-input:focus {
- border-color: #3b82f6;
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
+ background: #323238;
}
.number-input:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
diff --git a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSelect.vue b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSelect.vue
index cea534ce8..b7103683f 100644
--- a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSelect.vue
+++ b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSelect.vue
@@ -48,32 +48,36 @@ function handleChange(event: Event): void {
.custom-select {
width: 100%;
- background: #27272a;
- border: 1px solid #3f3f46;
- border-radius: 6px;
- color: #fafafa;
- padding: 6px 28px 6px 10px;
+ height: 24px;
+ background: #2a2a2e;
+ border: none;
+ border-radius: 4px;
+ color: #e4e4e7;
+ padding: 0 24px 0 10px;
font-size: 11px;
outline: none;
cursor: pointer;
appearance: none;
- background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%23a1a1aa' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
+ background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%2371717a' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-position: right 8px center;
}
+.custom-select:hover {
+ background: #323238;
+}
+
.custom-select:focus {
- border-color: #3b82f6;
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
+ background: #323238;
}
.custom-select:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
.custom-select option {
- background: #27272a;
- color: #fafafa;
+ background: #2a2a2e;
+ color: #e4e4e7;
}
diff --git a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSlider.vue b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSlider.vue
index 5dbcf5caa..5d4c05c0d 100644
--- a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSlider.vue
+++ b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetSlider.vue
@@ -94,13 +94,13 @@ function handleNumberBlur(event: Event): void {
.widget-slider {
display: flex;
align-items: center;
- gap: 8px;
- padding: 2px 0;
+ gap: 6px;
+ height: 24px;
}
.slider-container {
flex: 1;
- height: 20px;
+ height: 24px;
display: flex;
align-items: center;
}
@@ -109,7 +109,7 @@ function handleNumberBlur(event: Event): void {
-webkit-appearance: none;
appearance: none;
width: 100%;
- height: 4px;
+ height: 3px;
background: linear-gradient(
to right,
#3b82f6 0%,
@@ -117,30 +117,30 @@ function handleNumberBlur(event: Event): void {
#3f3f46 var(--fill-percent),
#3f3f46 100%
);
- border-radius: 4px;
+ border-radius: 2px;
outline: none;
cursor: pointer;
}
.custom-slider:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
.custom-slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
- width: 14px;
- height: 14px;
- background: #fafafa;
- border: 2px solid #3b82f6;
+ width: 12px;
+ height: 12px;
+ background: #e4e4e7;
+ border: none;
border-radius: 50%;
cursor: grab;
transition: background-color 0.15s, transform 0.15s;
}
.custom-slider::-webkit-slider-thumb:hover {
- background: #3b82f6;
+ background: #fafafa;
transform: scale(1.1);
}
@@ -150,17 +150,17 @@ function handleNumberBlur(event: Event): void {
}
.custom-slider::-moz-range-thumb {
- width: 14px;
- height: 14px;
- background: #fafafa;
- border: 2px solid #3b82f6;
+ width: 12px;
+ height: 12px;
+ background: #e4e4e7;
+ border: none;
border-radius: 50%;
cursor: grab;
transition: background-color 0.15s, transform 0.15s;
}
.custom-slider::-moz-range-thumb:hover {
- background: #3b82f6;
+ background: #fafafa;
transform: scale(1.1);
}
@@ -174,12 +174,13 @@ function handleNumberBlur(event: Event): void {
}
.number-input {
- width: 56px;
- background: #27272a;
- border: 1px solid #3f3f46;
- border-radius: 6px;
- color: #fafafa;
- padding: 4px 6px;
+ width: 50px;
+ height: 24px;
+ background: #2a2a2e;
+ border: none;
+ border-radius: 4px;
+ color: #e4e4e7;
+ padding: 0 6px;
font-size: 11px;
text-align: center;
outline: none;
@@ -193,12 +194,11 @@ function handleNumberBlur(event: Event): void {
}
.number-input:focus {
- border-color: #3b82f6;
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
+ background: #323238;
}
.number-input:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
diff --git a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetText.vue b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetText.vue
index c280c0c82..bd8d25651 100644
--- a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetText.vue
+++ b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetText.vue
@@ -53,33 +53,48 @@ function handleInput(event: Event): void {
width: 100%;
}
-.custom-input,
+.custom-input {
+ width: 100%;
+ height: 24px;
+ background: #2a2a2e;
+ border: none;
+ border-radius: 4px;
+ color: #e4e4e7;
+ padding: 0 10px;
+ font-size: 11px;
+ outline: none;
+}
+
.custom-textarea {
width: 100%;
- background: #27272a;
- border: 1px solid #3f3f46;
- border-radius: 6px;
- color: #fafafa;
+ background: #2a2a2e;
+ border: none;
+ border-radius: 4px;
+ color: #e4e4e7;
padding: 6px 10px;
font-size: 11px;
outline: none;
resize: none;
}
+.custom-input:hover,
+.custom-textarea:hover {
+ background: #323238;
+}
+
.custom-input:focus,
.custom-textarea:focus {
- border-color: #3b82f6;
- box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
+ background: #323238;
}
.custom-input:disabled,
.custom-textarea:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
.custom-input::placeholder,
.custom-textarea::placeholder {
- color: #71717a;
+ color: #52525b;
}
diff --git a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetToggle.vue b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetToggle.vue
index e43524bca..85b0e4a97 100644
--- a/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetToggle.vue
+++ b/ComfyUI_vibe/src/components/v2/nodes/widgets/WidgetToggle.vue
@@ -43,6 +43,7 @@ function toggle(): void {
.widget-toggle {
display: flex;
align-items: center;
+ height: 24px;
}
.toggle-button {
@@ -54,16 +55,16 @@ function toggle(): void {
}
.toggle-button:disabled {
- opacity: 0.5;
+ opacity: 0.4;
cursor: not-allowed;
}
.toggle-track {
display: block;
- width: 36px;
- height: 20px;
+ width: 32px;
+ height: 16px;
background: #3f3f46;
- border-radius: 10px;
+ border-radius: 8px;
position: relative;
transition: background-color 0.2s;
}
@@ -76,12 +77,11 @@ function toggle(): void {
position: absolute;
top: 2px;
left: 2px;
- width: 16px;
- height: 16px;
- background: #fafafa;
+ width: 12px;
+ height: 12px;
+ background: #e4e4e7;
border-radius: 50%;
transition: transform 0.2s;
- box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
}
.toggle-button.active .toggle-thumb {
diff --git a/ComfyUI_vibe/src/data/sidebarMockData.ts b/ComfyUI_vibe/src/data/sidebarMockData.ts
index 5d87ef5c6..d25f14fb2 100644
--- a/ComfyUI_vibe/src/data/sidebarMockData.ts
+++ b/ComfyUI_vibe/src/data/sidebarMockData.ts
@@ -244,6 +244,7 @@ export interface SharedWorkflow {
nodes: number
category: string
starred: boolean
+ thumbnail?: string
}
export interface TeamModel {
@@ -254,6 +255,7 @@ export interface TeamModel {
size: string
author: TeamMember
downloads: number
+ thumbnail?: string
}
export interface NodePack {
@@ -264,6 +266,7 @@ export interface NodePack {
nodes: number
author: string
installed: boolean
+ thumbnail?: string
}
export const TEMPLATE_CATEGORIES_DATA: TemplateCategory[] = [
@@ -354,6 +357,7 @@ export function createSharedWorkflowsData(members: TeamMember[]): SharedWorkflow
nodes: 12,
category: 'Production',
starred: true,
+ thumbnail: '/assets/card_images/workflow_01.webp',
},
{
id: '2',
@@ -364,6 +368,7 @@ export function createSharedWorkflowsData(members: TeamMember[]): SharedWorkflow
nodes: 18,
category: 'Marketing',
starred: true,
+ thumbnail: '/assets/card_images/2690a78c-c210-4a52-8c37-3cb5bc4d9e71.webp',
},
{
id: '3',
@@ -374,6 +379,7 @@ export function createSharedWorkflowsData(members: TeamMember[]): SharedWorkflow
nodes: 24,
category: 'Production',
starred: false,
+ thumbnail: '/assets/card_images/bacb46ea-7e63-4f19-a253-daf41461e98f.webp',
},
{
id: '4',
@@ -384,6 +390,7 @@ export function createSharedWorkflowsData(members: TeamMember[]): SharedWorkflow
nodes: 8,
category: 'Marketing',
starred: false,
+ thumbnail: '/assets/card_images/228616f4-12ad-426d-84fb-f20e488ba7ee.webp',
},
]
}
@@ -398,6 +405,7 @@ export function createTeamModelsData(members: TeamMember[]): TeamModel[] {
size: '144 MB',
author: members[0]!,
downloads: 156,
+ thumbnail: '/assets/card_images/683255d3-1d10-43d9-a6ff-ef142061e88a.webp',
},
{
id: '2',
@@ -407,6 +415,7 @@ export function createTeamModelsData(members: TeamMember[]): TeamModel[] {
size: '6.94 GB',
author: members[1]!,
downloads: 89,
+ thumbnail: '/assets/card_images/91f1f589-ddb4-4c4f-b3a7-ba30fc271987.webp',
},
{
id: '3',
@@ -416,6 +425,7 @@ export function createTeamModelsData(members: TeamMember[]): TeamModel[] {
size: '72 MB',
author: members[2]!,
downloads: 234,
+ thumbnail: '/assets/card_images/28e9f7ea-ef00-48e8-849d-8752a34939c7.webp',
},
{
id: '4',
@@ -425,6 +435,7 @@ export function createTeamModelsData(members: TeamMember[]): TeamModel[] {
size: '24 KB',
author: members[0]!,
downloads: 312,
+ thumbnail: '/assets/card_images/comfyui_workflow.jpg',
},
]
}
@@ -438,6 +449,7 @@ export const NODE_PACKS_DATA: NodePack[] = [
nodes: 8,
author: 'Netflix Creative Tech',
installed: true,
+ thumbnail: '/assets/card_images/can-you-rate-my-comfyui-workflow-v0-o9clchhji39c1.webp',
},
{
id: '2',
@@ -447,6 +459,7 @@ export const NODE_PACKS_DATA: NodePack[] = [
nodes: 4,
author: 'Netflix Creative Tech',
installed: true,
+ thumbnail: '/assets/card_images/dda28581-37c8-44da-8822-57d1ccc2118c_2130x1658.png',
},
{
id: '3',
@@ -456,5 +469,6 @@ export const NODE_PACKS_DATA: NodePack[] = [
nodes: 6,
author: 'Netflix Creative Tech',
installed: false,
+ thumbnail: '/assets/card_images/workflow_01.webp',
},
]
diff --git a/ComfyUI_vibe/src/main.ts b/ComfyUI_vibe/src/main.ts
index 1653ad217..966b485b5 100644
--- a/ComfyUI_vibe/src/main.ts
+++ b/ComfyUI_vibe/src/main.ts
@@ -84,7 +84,24 @@ app.use(PrimeVue, {
app.use(ToastService)
app.use(ConfirmationService)
-// PrimeVue directives
-app.directive('tooltip', Tooltip)
+// PrimeVue directives with custom defaults
+app.directive('tooltip', {
+ ...Tooltip,
+ getSSRProps() {
+ return {}
+ },
+ mounted(el, binding) {
+ // Set fast show delay (100ms) as default
+ const value = binding.value
+ if (typeof value === 'string') {
+ binding.value = { value, showDelay: 100, hideDelay: 0 }
+ } else if (typeof value === 'object' && value !== null) {
+ binding.value = { showDelay: 100, hideDelay: 0, ...value }
+ }
+ Tooltip.mounted(el, binding)
+ },
+ updated: Tooltip.updated,
+ unmounted: Tooltip.unmounted
+})
app.mount('#app')
diff --git a/ComfyUI_vibe/src/router.ts b/ComfyUI_vibe/src/router.ts
index 024ddf213..49acdc4c2 100644
--- a/ComfyUI_vibe/src/router.ts
+++ b/ComfyUI_vibe/src/router.ts
@@ -59,6 +59,11 @@ const v2Routes: RouteRecordRaw[] = [
name: 'workspace-templates',
component: () => import('./views/v2/workspace/TemplatesView.vue')
},
+ {
+ path: 'library',
+ name: 'workspace-library',
+ component: () => import('./views/v2/workspace/LibraryView.vue')
+ },
{
path: 'trash',
name: 'workspace-trash',
diff --git a/ComfyUI_vibe/src/views/v2/workspace/LibraryView.vue b/ComfyUI_vibe/src/views/v2/workspace/LibraryView.vue
new file mode 100644
index 000000000..3b265e017
--- /dev/null
+++ b/ComfyUI_vibe/src/views/v2/workspace/LibraryView.vue
@@ -0,0 +1,409 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Switch Library
+
+
+
+
+
+
+
+
+
+ Library Hub
+
+
+ Shared workflows, models, nodepacks, and brand assets
+
+
+
+
+
+
+
+ Linear
+
+
+
+ Node
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
No items found
+
+ {{ searchQuery || filterBy !== 'all' ? 'Try different filters' : 'Add items to get started' }}
+
+
+
+
+
+
+
+
+
+
+
+
+
Icon
+
Name
+
Type
+
Uses
+
Author
+
Updated
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
{{ item.description }}
+
+
+
+ {{ getTypeLabel(item.type) }}
+
+
+
+ {{ formatUses(item.uses) }}
+
+
+ {{ item.author }}
+
+
+ {{ item.updatedAt }}
+
+
+
+
+
+
+
+
+