Style: Standardize icon use Part 1 (#5947)
## Summary Remove the mix of class based and component style icons in favor of just [classes](https://iconify.design/docs/usage/css/tailwind/tailwind4/#basic-usage). ## Changes - **What**: Migrate existing lucide icons ## Review Focus What differs between the icons before and now? ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5947-Style-Standardize-icon-use-Part-1-2846d73d365081bfa66ceb6bdaa9ff02) by [Unito](https://www.unito.io) --------- Co-authored-by: github-actions <github-actions@github.com>
@@ -211,18 +211,17 @@ This Storybook setup includes:
|
||||
|
||||
## Icon Usage in Storybook
|
||||
|
||||
In this project, the `<i-lucide:... />` syntax from unplugin-icons is not supported in Storybook.
|
||||
In this project, only the `<i class="icon-[lucide--folder]" />` syntax from unplugin-icons is supported in Storybook.
|
||||
|
||||
**Example:**
|
||||
|
||||
```vue
|
||||
<script setup lang="ts">
|
||||
import { Trophy, Settings } from 'lucide-vue-next'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Trophy :size="16" class="text-neutral" />
|
||||
<Settings :size="16" class="text-neutral" />
|
||||
<i class="icon-[lucide--trophy] text-neutral size-4" />
|
||||
<i class="icon-[lucide--settings] text-neutral size-4" />
|
||||
</template>
|
||||
```
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ pnpm format
|
||||
The project supports three types of icons, all with automatic imports (no manual imports needed):
|
||||
|
||||
1. **PrimeIcons** - Built-in PrimeVue icons using CSS classes: `<i class="pi pi-plus" />`
|
||||
2. **Iconify Icons** - 200,000+ icons from various libraries: `<i-lucide:settings />`, `<i-mdi:folder />`
|
||||
2. **Iconify Icons** - 200,000+ icons from various libraries: `<i class="icon-[lucide--settings]" />`, `<i class="icon-[mdi--folder]" />`
|
||||
3. **Custom Icons** - Your own SVG icons: `<i-comfy:workflow />`
|
||||
|
||||
Icons are powered by the unplugin-icons system, which automatically discovers and imports icons as Vue components. Custom icons are stored in `packages/design-system/src/icons/` and processed by `packages/design-system/src/iconCollection.ts` with automatic validation.
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
:value="$t('install.gpuPicker.recommended')"
|
||||
class="bg-neutral-300 text-neutral-900 rounded-full text-sm font-bold px-2 py-[1px]"
|
||||
/>
|
||||
<i-lucide:badge-check class="text-neutral-300 text-lg" />
|
||||
<i class="icon-[lucide--badge-check] text-neutral-300 text-lg" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB |
|
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 68 KiB |
@@ -26,9 +26,9 @@ ComfyUI supports three types of icons that can be used throughout the interface.
|
||||
```vue
|
||||
<template>
|
||||
<!-- Primary icon set: Lucide -->
|
||||
<i-lucide:download />
|
||||
<i-lucide:settings />
|
||||
<i-lucide:workflow class="text-2xl" />
|
||||
<i class="icon-[lucide--download]" />
|
||||
<i class="icon-[lucide--settings]" />
|
||||
<i class="icon-[lucide--workflow]" class="text-2xl" />
|
||||
|
||||
<!-- Other popular icon sets -->
|
||||
<i-mdi:folder-open />
|
||||
@@ -41,7 +41,7 @@ ComfyUI supports three types of icons that can be used throughout the interface.
|
||||
<!-- Carbon Icons -->
|
||||
|
||||
<!-- With styling -->
|
||||
<i-lucide:save class="w-6 h-6 text-blue-500" />
|
||||
<i class="icon-[lucide--save]" class="w-6 h-6 text-blue-500" />
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -77,7 +77,7 @@ ComfyUI supports three types of icons that can be used throughout the interface.
|
||||
<!-- Iconify/Custom in button (template) -->
|
||||
<Button>
|
||||
<template #icon>
|
||||
<i-lucide:save />
|
||||
<i class="icon-[lucide--save]" />
|
||||
</template>
|
||||
Save File
|
||||
</Button>
|
||||
@@ -88,8 +88,8 @@ ComfyUI supports three types of icons that can be used throughout the interface.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<i-lucide:eye v-if="isVisible" />
|
||||
<i-lucide:eye-off v-else />
|
||||
<i class="icon-[lucide--eye]" v-if="isVisible" />
|
||||
<i class="icon-[lucide--eye-off]" v-else />
|
||||
|
||||
<!-- Or with ternary -->
|
||||
<component :is="isLocked ? 'i-lucide:lock' : 'i-lucide:lock-open'" />
|
||||
@@ -100,7 +100,7 @@ ComfyUI supports three types of icons that can be used throughout the interface.
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<i-lucide:info
|
||||
<i class="icon-[lucide--info]"
|
||||
v-tooltip="'Click for more information'"
|
||||
class="cursor-pointer"
|
||||
/>
|
||||
@@ -174,20 +174,20 @@ No imports needed - icons are auto-discovered!
|
||||
```vue
|
||||
<template>
|
||||
<!-- Size with Tailwind classes -->
|
||||
<i-lucide:plus class="w-4 h-4" />
|
||||
<i class="icon-[lucide--plus]" class="w-4 h-4" />
|
||||
<!-- 16px -->
|
||||
<i-lucide:plus class="w-6 h-6" />
|
||||
<i class="icon-[lucide--plus]" class="w-6 h-6" />
|
||||
<!-- 24px (default) -->
|
||||
<i-lucide:plus class="w-8 h-8" />
|
||||
<i class="icon-[lucide--plus]" class="w-8 h-8" />
|
||||
<!-- 32px -->
|
||||
|
||||
<!-- Or text size -->
|
||||
<i-lucide:plus class="text-sm" />
|
||||
<i-lucide:plus class="text-2xl" />
|
||||
<i class="icon-[lucide--plus]" class="text-sm" />
|
||||
<i class="icon-[lucide--plus]" class="text-2xl" />
|
||||
|
||||
<!-- Colors -->
|
||||
<i-lucide:check class="text-green-500" />
|
||||
<i-lucide:x class="text-red-500" />
|
||||
<i class="icon-[lucide--check]" class="text-green-500" />
|
||||
<i class="icon-[lucide--x]" class="text-red-500" />
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -219,7 +219,7 @@ Always use `currentColor` in SVGs for automatic theme adaptation:
|
||||
<!-- After -->
|
||||
<Button>
|
||||
<template #icon>
|
||||
<i-lucide:download />
|
||||
<i class="icon-[lucide--download]" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
@@ -4,22 +4,13 @@ import { addDynamicIconSelectors } from '@iconify/tailwind'
|
||||
import { iconCollection } from './src/iconCollection'
|
||||
|
||||
export default {
|
||||
content: [],
|
||||
safelist: [
|
||||
'icon-[lucide--folder]',
|
||||
'icon-[lucide--package]',
|
||||
'icon-[lucide--image]',
|
||||
'icon-[lucide--video]',
|
||||
'icon-[lucide--box]',
|
||||
'icon-[lucide--audio-waveform]',
|
||||
'icon-[lucide--message-circle]'
|
||||
],
|
||||
plugins: [
|
||||
addDynamicIconSelectors({
|
||||
iconSets: {
|
||||
comfy: iconCollection,
|
||||
lucide
|
||||
},
|
||||
scale: 1.2,
|
||||
prefix: 'icon'
|
||||
})
|
||||
]
|
||||
|
||||
@@ -16,10 +16,16 @@
|
||||
@click="queuePrompt"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:list-start v-if="workspaceStore.shiftDown" />
|
||||
<i-lucide:play v-else-if="queueMode === 'disabled'" />
|
||||
<i-lucide:fast-forward v-else-if="queueMode === 'instant'" />
|
||||
<i-lucide:step-forward v-else-if="queueMode === 'change'" />
|
||||
<i v-if="workspaceStore.shiftDown" class="icon-[lucide--list-start]" />
|
||||
<i v-else-if="queueMode === 'disabled'" class="icon-[lucide--play]" />
|
||||
<i
|
||||
v-else-if="queueMode === 'instant'"
|
||||
class="icon-[lucide--fast-forward]"
|
||||
/>
|
||||
<i
|
||||
v-else-if="queueMode === 'change'"
|
||||
class="icon-[lucide--step-forward]"
|
||||
/>
|
||||
</template>
|
||||
<template #item="{ item }">
|
||||
<Button
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="relative inline-flex items-center">
|
||||
<IconButton @click="toggle">
|
||||
<i-lucide:more-vertical class="text-sm" />
|
||||
<i class="icon-[lucide--more-vertical] text-sm" />
|
||||
</IconButton>
|
||||
|
||||
<Popover
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
@click="resetFilters"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:filter-x />
|
||||
<i class="icon-[lucide--filter-x]" />
|
||||
</template>
|
||||
</IconTextButton>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@
|
||||
:show-clear-button="true"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:cpu />
|
||||
<i class="icon-[lucide--cpu]" />
|
||||
</template>
|
||||
</MultiSelect>
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
:show-clear-button="true"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:target />
|
||||
<i class="icon-[lucide--target]" />
|
||||
</template>
|
||||
</MultiSelect>
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
:show-clear-button="true"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:file-text />
|
||||
<i class="icon-[lucide--file-text]" />
|
||||
</template>
|
||||
</MultiSelect>
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
class="min-w-[270px]"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:arrow-up-down />
|
||||
<i class="icon-[lucide--arrow-up-down]" />
|
||||
</template>
|
||||
</SingleSelect>
|
||||
</div>
|
||||
@@ -111,7 +111,7 @@
|
||||
v-if="!isLoading && filteredTemplates.length === 0"
|
||||
class="flex flex-col items-center justify-center h-64 text-neutral-500"
|
||||
>
|
||||
<i-lucide:search class="w-12 h-12 mb-4 opacity-50" />
|
||||
<i class="icon-[lucide--search] w-12 h-12 mb-4 opacity-50" />
|
||||
<p class="text-lg mb-2">
|
||||
{{ $t('templateWorkflows.noResults', 'No templates found') }}
|
||||
</p>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
@click="() => commandStore.execute('Comfy.Canvas.Unlock')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:mouse-pointer-2 />
|
||||
<i class="icon-[lucide--mouse-pointer-2]" />
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
@click="() => commandStore.execute('Comfy.Canvas.Lock')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:hand />
|
||||
<i class="icon-[lucide--hand]" />
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
@click="() => commandStore.execute('Comfy.Canvas.FitView')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:focus />
|
||||
<i class="icon-[lucide--focus]" />
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
>
|
||||
<span class="inline-flex text-xs">
|
||||
<span>{{ canvasStore.appScalePercentage }}%</span>
|
||||
<i-lucide:chevron-down />
|
||||
<i class="icon-[lucide--chevron-down]" />
|
||||
</span>
|
||||
</Button>
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
@click="() => commandStore.execute('Workspace.ToggleFocusMode')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:lightbulb />
|
||||
<i class="icon-[lucide--lightbulb]" />
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
@click="() => commandStore.execute('Comfy.Canvas.ToggleLinkVisibility')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:route-off />
|
||||
<i class="icon-[lucide--route-off]" />
|
||||
</template>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
@click="toggleBypass"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:ban class="w-4 h-4" />
|
||||
<i class="icon-[lucide--ban] w-4 h-4" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
@click="() => commandStore.execute('Comfy.Graph.UnpackSubgraph')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:expand class="w-4 h-4" />
|
||||
<i class="icon-[lucide--expand] w-4 h-4" />
|
||||
</template>
|
||||
</Button>
|
||||
<Button
|
||||
@@ -26,7 +26,7 @@
|
||||
@click="() => commandStore.execute('Comfy.Graph.ConvertToSubgraph')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:shrink />
|
||||
<i class="icon-[lucide--shrink]" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@mouseleave="() => handleMouseLeave()"
|
||||
@click="handleClick"
|
||||
>
|
||||
<i-lucide:play class="fill-path-white w-4 h-4" />
|
||||
<i class="icon-[lucide--play] fill-path-white w-4 h-4" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
severity="secondary"
|
||||
@click="frameNodes"
|
||||
>
|
||||
<i-lucide:frame class="w-4 h-4" />
|
||||
<i class="icon-[lucide--frame] w-4 h-4" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
severity="secondary"
|
||||
@click="toggleHelp"
|
||||
>
|
||||
<i-lucide:info class="w-4 h-4" />
|
||||
<i class="icon-[lucide--info] w-4 h-4" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -14,10 +14,10 @@
|
||||
<span v-if="option.shortcut" class="text-xs opacity-60">
|
||||
{{ option.shortcut }}
|
||||
</span>
|
||||
<i-lucide:chevron-right
|
||||
<i
|
||||
v-if="option.hasSubmenu"
|
||||
:size="14"
|
||||
class="opacity-60"
|
||||
class="icon-[lucide--chevron-right] opacity-60"
|
||||
/>
|
||||
<Badge
|
||||
v-if="option.badge"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
severity="secondary"
|
||||
@click="handleClick"
|
||||
>
|
||||
<i-lucide:more-vertical class="w-4 h-4" />
|
||||
<i class="icon-[lucide--more-vertical] w-4 h-4" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
data-testid="refresh-button"
|
||||
@click="refreshSelected"
|
||||
>
|
||||
<i-lucide:refresh-cw class="w-4 h-4" />
|
||||
<i class="icon-[lucide--refresh-cw] w-4 h-4" />
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@click="() => commandStore.execute('Comfy.PublishSubgraph')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:book-open />
|
||||
<i class="icon-[lucide--book-open]" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
:style="{ backgroundColor: subOption.color }"
|
||||
/>
|
||||
<template v-else-if="!subOption.color">
|
||||
<i-lucide:check
|
||||
<i
|
||||
v-if="isShapeSelected(subOption)"
|
||||
class="w-4 h-4 flex-shrink-0"
|
||||
class="icon-[lucide--check] w-4 h-4 flex-shrink-0"
|
||||
/>
|
||||
<div v-else class="w-4 flex-shrink-0" />
|
||||
<span>{{ subOption.label }}</span>
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
<!-- Chevron size identical to current -->
|
||||
<template #dropdownicon>
|
||||
<i-lucide:chevron-down class="text-lg text-neutral-400" />
|
||||
<i class="icon-[lucide--chevron-down] text-lg text-neutral-400" />
|
||||
</template>
|
||||
|
||||
<!-- Custom option row: square checkbox + label (unchanged layout/colors) -->
|
||||
@@ -89,9 +89,9 @@
|
||||
: 'bg-neutral-100 dark-theme:bg-zinc-700'
|
||||
"
|
||||
>
|
||||
<i-lucide:check
|
||||
<i
|
||||
v-if="slotProps.selected"
|
||||
class="text-xs text-bold text-white"
|
||||
class="icon-[lucide--check] text-xs text-bold text-white"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div :class="wrapperStyle" @click="focusInput">
|
||||
<i-lucide:search :class="iconColorStyle" />
|
||||
<i class="icon-[lucide--search]" :class="iconColorStyle" />
|
||||
<InputText
|
||||
ref="input"
|
||||
v-model="searchQuery"
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<!-- Trigger caret -->
|
||||
<template #dropdownicon>
|
||||
<i-lucide:chevron-down class="text-base text-neutral-500" />
|
||||
<i class="icon-[lucide--chevron-down] text-base text-neutral-500" />
|
||||
</template>
|
||||
|
||||
<!-- Option row -->
|
||||
@@ -48,9 +48,9 @@
|
||||
:style="optionStyle"
|
||||
>
|
||||
<span class="truncate">{{ option.name }}</span>
|
||||
<i-lucide:check
|
||||
<i
|
||||
v-if="selected"
|
||||
class="text-neutral-600 dark-theme:text-white"
|
||||
class="icon-[lucide--check] text-neutral-600 dark-theme:text-white"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
@click="toggleShortcutsPanel"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:keyboard />
|
||||
<i class="icon-[lucide--keyboard]" />
|
||||
</template>
|
||||
</SidebarIcon>
|
||||
</template>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
@click.stop="editBlueprint"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:square-pen />
|
||||
<i class="icon-[lucide--square-pen]" />
|
||||
</template>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<template #leftPanel>
|
||||
<LeftSidePanel v-model="selectedNavItem" :nav-items="tempNavigation">
|
||||
<template #header-icon>
|
||||
<i-lucide:puzzle class="text-neutral" />
|
||||
<i class="icon-[lucide--puzzle] text-neutral" />
|
||||
</template>
|
||||
<template #header-title>
|
||||
<span class="text-neutral text-base">{{ t('g.title') }}</span>
|
||||
@@ -19,7 +19,7 @@
|
||||
<div class="flex gap-2">
|
||||
<IconTextButton type="primary" label="Upload Model" @click="() => {}">
|
||||
<template #icon>
|
||||
<i-lucide:upload />
|
||||
<i class="icon-[lucide--upload]" />
|
||||
</template>
|
||||
</IconTextButton>
|
||||
<MoreButton>
|
||||
@@ -34,7 +34,7 @@
|
||||
"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:download />
|
||||
<i class="icon-[lucide--download]" />
|
||||
</template>
|
||||
</IconTextButton>
|
||||
<IconTextButton
|
||||
@@ -47,7 +47,7 @@
|
||||
"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:scroll />
|
||||
<i class="icon-[lucide--scroll]" />
|
||||
</template>
|
||||
</IconTextButton>
|
||||
</template>
|
||||
@@ -79,7 +79,7 @@
|
||||
class="w-[135px]"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:filter />
|
||||
<i class="icon-[lucide--filter]" />
|
||||
</template>
|
||||
</SingleSelect>
|
||||
</div>
|
||||
@@ -99,7 +99,7 @@
|
||||
class="!bg-white !text-neutral-900"
|
||||
@click="() => {}"
|
||||
>
|
||||
<i-lucide:info />
|
||||
<i class="icon-[lucide--info]" />
|
||||
</IconButton>
|
||||
</template>
|
||||
<template #bottom-right>
|
||||
@@ -107,7 +107,7 @@
|
||||
<SquareChip label="1.2 MB" />
|
||||
<SquareChip label="LoRA">
|
||||
<template #icon>
|
||||
<i-lucide:folder />
|
||||
<i class="icon-[lucide--folder]" />
|
||||
</template>
|
||||
</SquareChip>
|
||||
</template>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:class="rightPanelButtonClasses"
|
||||
@click="toggleRightPanel"
|
||||
>
|
||||
<i-lucide:panel-right class="text-sm" />
|
||||
<i class="icon-[lucide--panel-right] text-sm" />
|
||||
</IconButton>
|
||||
<IconButton :class="closeButtonClasses" @click="closeDialog">
|
||||
<i class="pi pi-times text-sm"></i>
|
||||
@@ -29,8 +29,11 @@
|
||||
<header v-if="$slots.header" :class="headerClasses">
|
||||
<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" />
|
||||
<i
|
||||
v-if="!showLeftPanel"
|
||||
class="icon-[lucide--panel-left] text-sm"
|
||||
/>
|
||||
<i v-else class="icon-[lucide--panel-left-close] text-sm" />
|
||||
</IconButton>
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
@@ -40,7 +43,7 @@
|
||||
v-if="isRightPanelOpen && hasRightPanel"
|
||||
@click="toggleRightPanel"
|
||||
>
|
||||
<i-lucide:panel-right-close class="text-sm" />
|
||||
<i class="icon-[lucide--panel-right-close] text-sm" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
@click="onClick"
|
||||
>
|
||||
<NavIcon v-if="icon" :icon="icon" />
|
||||
<i-lucide:folder v-else class="text-xs text-neutral" />
|
||||
<i v-else class="icon-[lucide--folder] text-xs text-neutral" />
|
||||
<span class="flex items-center">
|
||||
<slot></slot>
|
||||
</span>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<header class="flex items-center justify-between h-16 px-6">
|
||||
<div class="flex items-center gap-2 pl-1">
|
||||
<slot name="icon">
|
||||
<i-lucide:puzzle class="text-neutral text-base" />
|
||||
<i class="icon-[lucide--puzzle] text-neutral text-base" />
|
||||
</slot>
|
||||
<h2 class="font-bold text-base text-neutral">
|
||||
<slot></slot>
|
||||
|
||||
@@ -66,15 +66,15 @@
|
||||
"
|
||||
>
|
||||
<span v-if="asset.stats.stars" class="flex items-center gap-1">
|
||||
<i-lucide:star class="size-3" />
|
||||
<i class="icon-[lucide--star] size-3" />
|
||||
{{ asset.stats.stars }}
|
||||
</span>
|
||||
<span v-if="asset.stats.downloadCount" class="flex items-center gap-1">
|
||||
<i-lucide:download class="size-3" />
|
||||
<i class="icon-[lucide--download] size-3" />
|
||||
{{ asset.stats.downloadCount }}
|
||||
</span>
|
||||
<span v-if="asset.stats.formattedDate" class="flex items-center gap-1">
|
||||
<i-lucide:clock class="size-3" />
|
||||
<i class="icon-[lucide--clock] size-3" />
|
||||
{{ asset.stats.formattedDate }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
@update:model-value="handleFilterChange"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:arrow-up-down class="size-3" />
|
||||
<i class="icon-[lucide--arrow-up-down] size-3" />
|
||||
</template>
|
||||
</SingleSelect>
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
)
|
||||
"
|
||||
>
|
||||
<i-lucide:search class="size-10 mb-4" />
|
||||
<i class="icon-[lucide--search] size-10 mb-4" />
|
||||
<h3 class="text-lg font-medium mb-2">
|
||||
{{ $t('assetBrowser.noAssetsFound') }}
|
||||
</h3>
|
||||
@@ -39,7 +39,8 @@
|
||||
v-if="loading"
|
||||
class="col-span-full flex items-center justify-center py-16"
|
||||
>
|
||||
<i-lucide:loader
|
||||
<i
|
||||
class="icon-[lucide--loader]"
|
||||
:class="
|
||||
cn('size-6 animate-spin', 'text-stone-300 dark-theme:text-stone-200')
|
||||
"
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</Message>
|
||||
<Message v-if="commandLineArgs" severity="secondary" pt:text="w-full">
|
||||
<template #icon>
|
||||
<i-lucide:terminal class="text-xl font-bold" />
|
||||
<i class="icon-[lucide--terminal] text-xl font-bold" />
|
||||
</template>
|
||||
<div class="flex items-center justify-between">
|
||||
<p>{{ commandLineArgs }}</p>
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
@click.stop="toggleOptionsPanel"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:settings-2 />
|
||||
<i class="icon-[lucide--settings-2]" />
|
||||
</template>
|
||||
</Button>
|
||||
<Button
|
||||
@@ -40,7 +40,7 @@
|
||||
@click.stop="() => commandStore.execute('Comfy.Canvas.ToggleMinimap')"
|
||||
>
|
||||
<template #icon>
|
||||
<i-lucide:x />
|
||||
<i class="icon-[lucide--x]" />
|
||||
</template>
|
||||
</Button>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
(value) => $emit('updateOption', 'Comfy.Minimap.NodeColors', value)
|
||||
"
|
||||
/>
|
||||
<i-lucide:palette />
|
||||
<i class="icon-[lucide--palette]" />
|
||||
<label for="node-colors">{{ $t('minimap.nodeColors') }}</label>
|
||||
</div>
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
(value) => $emit('updateOption', 'Comfy.Minimap.ShowLinks', value)
|
||||
"
|
||||
/>
|
||||
<i-lucide:route />
|
||||
<i class="icon-[lucide--route]" />
|
||||
<label for="show-links">{{ $t('minimap.showLinks') }}</label>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
(value) => $emit('updateOption', 'Comfy.Minimap.ShowGroups', value)
|
||||
"
|
||||
/>
|
||||
<i-lucide:frame />
|
||||
<i class="icon-[lucide--frame]" />
|
||||
<label for="show-groups">{{ $t('minimap.showGroups') }}</label>
|
||||
</div>
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
$emit('updateOption', 'Comfy.Minimap.RenderBypassState', value)
|
||||
"
|
||||
/>
|
||||
<i-lucide:circle-slash-2 />
|
||||
<i class="icon-[lucide--circle-slash-2]" />
|
||||
<label for="render-bypass">{{ $t('minimap.renderBypassState') }}</label>
|
||||
</div>
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
$emit('updateOption', 'Comfy.Minimap.RenderErrorState', value)
|
||||
"
|
||||
/>
|
||||
<i-lucide:message-circle-warning />
|
||||
<i class="icon-[lucide--message-circle-warning]" />
|
||||
<label for="render-error">{{ $t('minimap.renderErrorState') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
v-if="videoError"
|
||||
class="w-full h-[352px] flex flex-col items-center justify-center text-white text-center bg-gray-800/50"
|
||||
>
|
||||
<i-lucide:video-off class="w-12 h-12 mb-2 text-gray-400" />
|
||||
<i class="icon-[lucide--video-off] w-12 h-12 mb-2 text-gray-400" />
|
||||
<p class="text-sm text-gray-300">{{ $t('g.videoFailedToLoad') }}</p>
|
||||
<p class="text-xs text-gray-400 mt-1">
|
||||
{{ getVideoFilename(currentVideoUrl) }}
|
||||
@@ -54,7 +54,7 @@
|
||||
:aria-label="$t('g.downloadVideo')"
|
||||
@click="handleDownload"
|
||||
>
|
||||
<i-lucide:download class="w-4 h-4" />
|
||||
<i class="icon-[lucide--download] w-4 h-4" />
|
||||
</button>
|
||||
|
||||
<!-- Close Button -->
|
||||
@@ -64,7 +64,7 @@
|
||||
:aria-label="$t('g.removeVideo')"
|
||||
@click="handleRemove"
|
||||
>
|
||||
<i-lucide:x class="w-4 h-4" />
|
||||
<i class="icon-[lucide--x] w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
v-if="imageError"
|
||||
class="w-full h-[352px] flex flex-col items-center justify-center text-white text-center bg-gray-800/50"
|
||||
>
|
||||
<i-lucide:image-off class="w-12 h-12 mb-2 text-gray-400" />
|
||||
<i class="icon-[lucide--image-off] w-12 h-12 mb-2 text-gray-400" />
|
||||
<p class="text-sm text-gray-300">{{ $t('g.imageFailedToLoad') }}</p>
|
||||
<p class="text-xs text-gray-400 mt-1">
|
||||
{{ getImageFilename(currentImageUrl) }}
|
||||
@@ -53,7 +53,7 @@
|
||||
:aria-label="$t('g.editOrMaskImage')"
|
||||
@click="handleEditMask"
|
||||
>
|
||||
<i-lucide:venetian-mask class="w-4 h-4" />
|
||||
<i class="icon-[lucide--venetian-mask] w-4 h-4" />
|
||||
</button>
|
||||
|
||||
<!-- Download Button -->
|
||||
@@ -63,7 +63,7 @@
|
||||
:aria-label="$t('g.downloadImage')"
|
||||
@click="handleDownload"
|
||||
>
|
||||
<i-lucide:download class="w-4 h-4" />
|
||||
<i class="icon-[lucide--download] w-4 h-4" />
|
||||
</button>
|
||||
|
||||
<!-- Close Button -->
|
||||
@@ -73,7 +73,7 @@
|
||||
:aria-label="$t('g.removeImage')"
|
||||
@click="handleRemove"
|
||||
>
|
||||
<i-lucide:x class="w-4 h-4" />
|
||||
<i class="icon-[lucide--x] w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -50,9 +50,9 @@
|
||||
@edit="handleTitleEdit"
|
||||
@cancel="handleTitleCancel"
|
||||
/>
|
||||
<i-lucide:pin
|
||||
<i
|
||||
v-if="isPinned"
|
||||
class="size-5 text-node-component-header-icon"
|
||||
class="icon-[lucide--pin] size-5 text-node-component-header-icon"
|
||||
data-testid="node-pin-indicator"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -73,7 +73,7 @@ const theButtonStyle = computed(() =>
|
||||
{{ selectedItems.map((item) => (item as any)?.name).join(', ') }}
|
||||
</span>
|
||||
</span>
|
||||
<i-lucide:chevron-down :class="chevronClass" />
|
||||
<i class="icon-[lucide--chevron-down]" :class="chevronClass" />
|
||||
</button>
|
||||
<!-- Open File -->
|
||||
<label
|
||||
@@ -86,7 +86,7 @@ const theButtonStyle = computed(() =>
|
||||
)
|
||||
"
|
||||
>
|
||||
<i-lucide:folder-search class="size-4" />
|
||||
<i class="icon-[lucide--folder-search] size-4" />
|
||||
<input
|
||||
type="file"
|
||||
class="opacity-0 absolute inset-0 -z-1"
|
||||
|
||||
@@ -73,9 +73,9 @@ const searchQuery = defineModel<string>('searchQuery')
|
||||
v-if="items.length === 0"
|
||||
class="flex justify-center items-center absolute inset-0"
|
||||
>
|
||||
<i-lucide:circle-off
|
||||
<i
|
||||
title="No items"
|
||||
class="size-30 text-zinc-500/20"
|
||||
class="icon-[lucide--circle-off] size-30 text-zinc-500/20"
|
||||
/>
|
||||
</div>
|
||||
<!-- Item -->
|
||||
|
||||
@@ -56,11 +56,11 @@ function handleSortSelected(item: SortOption) {
|
||||
)
|
||||
"
|
||||
>
|
||||
<i-lucide:loader-circle
|
||||
<i
|
||||
v-if="isQuerying"
|
||||
class="mr-2 size-4 animate-spin"
|
||||
class="icon-[lucide--loader-circle] mr-2 size-4 animate-spin"
|
||||
/>
|
||||
<i-lucide:search v-else class="mr-2 size-4" />
|
||||
<i v-else class="icon-[lucide--search] mr-2 size-4" />
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
@@ -87,7 +87,7 @@ function handleSortSelected(item: SortOption) {
|
||||
v-if="sortSelected !== 'default'"
|
||||
class="size-2 absolute top-[-2px] left-[-2px] bg-blue-500 rounded-full"
|
||||
/>
|
||||
<i-lucide:arrow-up-down class="size-4" />
|
||||
<i class="icon-[lucide--arrow-up-down] size-4" />
|
||||
</button>
|
||||
<!-- Sort Popover -->
|
||||
<Popover
|
||||
@@ -127,7 +127,10 @@ function handleSortSelected(item: SortOption) {
|
||||
@click="handleSortSelected(item)"
|
||||
>
|
||||
<span>{{ item.name }}</span>
|
||||
<i-lucide:check v-if="sortSelected === item.id" class="size-4" />
|
||||
<i
|
||||
v-if="sortSelected === item.id"
|
||||
class="icon-[lucide--check] size-4"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</Popover>
|
||||
@@ -153,7 +156,7 @@ function handleSortSelected(item: SortOption) {
|
||||
"
|
||||
@click="layoutMode = 'list'"
|
||||
>
|
||||
<i-lucide:list class="size-4" />
|
||||
<i class="icon-[lucide--list] size-4" />
|
||||
</button>
|
||||
<button
|
||||
:class="
|
||||
@@ -167,7 +170,7 @@ function handleSortSelected(item: SortOption) {
|
||||
"
|
||||
@click="layoutMode = 'grid'"
|
||||
>
|
||||
<i-lucide:layout-grid class="size-4" />
|
||||
<i class="icon-[lucide--layout-grid] size-4" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,9 @@ function handleVideoLoad(event: Event) {
|
||||
v-if="selected"
|
||||
class="rounded-full bg-blue-500 border-1 border-white size-4 absolute top-1 left-1"
|
||||
>
|
||||
<i-lucide:check class="size-3 text-white -translate-y-[0.5px]" />
|
||||
<i
|
||||
class="icon-[lucide--check] size-3 text-white -translate-y-[0.5px]"
|
||||
/>
|
||||
</div>
|
||||
<video
|
||||
v-if="mediaSrc && isVideo"
|
||||
|
||||