mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-08 06:30:04 +00:00
## Summary
Remove 46 unused snake_case SVG icons from design-system and use lucide
icon for LoadImage.
## Changes
- **What**: Remove unreferenced snake_case SVG files, replace LoadImage
custom icon with `lucide--image-up`, add `preview-image.svg` (renamed
from `image-preview.svg` to match `kebabCase('PreviewImage')`), extract
`ESSENTIALS_ICON_OVERRIDES` to `essentialsNodes.ts`
- Remove `load-image` from safelist in `style.css`
<img width="307" height="701" alt="image"
src="https://github.com/user-attachments/assets/de5e1bde-03eb-415e-ac76-f2e653a5eeb2"
/>
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9359-fix-clean-up-unused-icons-and-add-LoadImage-lucide-icon-override-3186d73d36508159be05ce6f4145be56)
by [Unito](https://www.unito.io)
127 lines
3.5 KiB
TypeScript
127 lines
3.5 KiB
TypeScript
/**
|
|
* Single source of truth for Essentials tab node categorization and ordering.
|
|
*
|
|
* Adding a new node to the Essentials tab? Add it here and nowhere else.
|
|
*
|
|
* Source: https://www.notion.so/comfy-org/2fe6d73d365080d0a951d14cdf540778
|
|
*/
|
|
|
|
export const ESSENTIALS_ICON_OVERRIDES: Record<string, string> = {
|
|
LoadImage: 'icon-s1.3-[lucide--image-up]',
|
|
LoadImageOutput: 'icon-s1.3-[lucide--image-up]',
|
|
SaveImage: 'icon-s1.3-[lucide--image-down]',
|
|
PrimitiveStringMultiline: 'icon-s1.3-[lucide--text]',
|
|
ImageCrop: 'icon-s1.3-[lucide--crop]',
|
|
VideoCrop: 'icon-s1.3-[lucide--crop]',
|
|
KlingLipSyncAudioToVideoNode: 'icon-s1.3-[lucide--mic-vocal]',
|
|
WebcamCapture: 'icon-s1.3-[lucide--camera]'
|
|
}
|
|
|
|
export const ESSENTIALS_CATEGORIES = [
|
|
'basics',
|
|
'text generation',
|
|
'image generation',
|
|
'video generation',
|
|
'image tools',
|
|
'video tools',
|
|
'audio',
|
|
'3D'
|
|
] as const
|
|
|
|
export type EssentialsCategory = (typeof ESSENTIALS_CATEGORIES)[number]
|
|
|
|
/**
|
|
* Ordered list of nodes per category.
|
|
* Array order = display order in the Essentials tab.
|
|
* Presence in a category = the node's essentials_category mock fallback.
|
|
*/
|
|
export const ESSENTIALS_NODES: Record<EssentialsCategory, readonly string[]> = {
|
|
basics: [
|
|
'LoadImage',
|
|
'LoadVideo',
|
|
'Load3D',
|
|
'SaveImage',
|
|
'SaveVideo',
|
|
'SaveGLB',
|
|
'PrimitiveStringMultiline',
|
|
'PreviewImage'
|
|
],
|
|
'text generation': ['OpenAIChatNode'],
|
|
'image generation': [
|
|
'LoraLoader',
|
|
'LoraLoaderModelOnly',
|
|
'ConditioningCombine'
|
|
],
|
|
'video generation': [
|
|
'SubgraphBlueprint.pose_to_video_ltx_2_0',
|
|
'SubgraphBlueprint.canny_to_video_ltx_2_0',
|
|
'KlingLipSyncAudioToVideoNode',
|
|
'KlingOmniProEditVideoNode'
|
|
],
|
|
'image tools': [
|
|
'ImageBatch',
|
|
'ImageCrop',
|
|
'ImageCropV2',
|
|
'ImageScale',
|
|
'ImageScaleBy',
|
|
'ImageRotate',
|
|
'ImageBlur',
|
|
'ImageBlend',
|
|
'ImageInvert',
|
|
'ImageCompare',
|
|
'Canny',
|
|
'RecraftRemoveBackgroundNode',
|
|
'RecraftVectorizeImageNode',
|
|
'LoadImageMask',
|
|
'GLSLShader'
|
|
],
|
|
'video tools': ['GetVideoComponents', 'CreateVideo', 'Video Slice'],
|
|
audio: [
|
|
'LoadAudio',
|
|
'SaveAudio',
|
|
'SaveAudioMP3',
|
|
'StabilityTextToAudio',
|
|
'EmptyLatentAudio'
|
|
],
|
|
'3D': ['TencentTextToModelNode', 'TencentImageToModelNode']
|
|
}
|
|
|
|
/**
|
|
* Flat map: node name → category (derived from ESSENTIALS_NODES).
|
|
* Used as mock/fallback when backend doesn't provide essentials_category.
|
|
*/
|
|
export const ESSENTIALS_CATEGORY_MAP: Record<string, EssentialsCategory> =
|
|
Object.fromEntries(
|
|
Object.entries(ESSENTIALS_NODES).flatMap(([category, nodes]) =>
|
|
nodes.map((node) => [node, category])
|
|
)
|
|
) as Record<string, EssentialsCategory>
|
|
|
|
/**
|
|
* Case-insensitive lookup: lowercase category → canonical category.
|
|
* Used to normalize backend categories (which may be title-cased) to the
|
|
* canonical form used in ESSENTIALS_CATEGORIES.
|
|
*/
|
|
export const ESSENTIALS_CATEGORY_CANONICAL: ReadonlyMap<
|
|
string,
|
|
EssentialsCategory
|
|
> = new Map(ESSENTIALS_CATEGORIES.map((c) => [c.toLowerCase(), c]))
|
|
|
|
/**
|
|
* "Novel" toolkit nodes for telemetry — basics excluded.
|
|
* Derived from ESSENTIALS_NODES minus the 'basics' category.
|
|
*/
|
|
export const TOOLKIT_NOVEL_NODE_NAMES: ReadonlySet<string> = new Set(
|
|
Object.entries(ESSENTIALS_NODES)
|
|
.filter(([cat]) => cat !== 'basics')
|
|
.flatMap(([, nodes]) => nodes)
|
|
.filter((n) => !n.startsWith('SubgraphBlueprint.'))
|
|
)
|
|
|
|
/**
|
|
* python_module values that identify toolkit blueprint nodes.
|
|
*/
|
|
export const TOOLKIT_BLUEPRINT_MODULES: ReadonlySet<string> = new Set([
|
|
'comfy_essentials'
|
|
])
|