Files
ComfyUI_frontend/src/renderer/extensions/vueNodes/widgets/components/WidgetInputText.vue
Jin Yi 96fd25de5c feat: add Logo C fill and Comfy wave loading indicator components (#9433)
## Summary

Add SVG-based brand loading indicators (LogoCFillLoader,
LogoComfyWaveLoader) and use the wave loader as the app loading screen.

## Changes

- **What**: New `LogoCFillLoader` (bottom-to-top fill, plays once) and
`LogoComfyWaveLoader` (wave water-fill animation) components with
`size`, `color`, `bordered`, and `disableAnimation` props. Move all
loaders from `components/common/` to `components/loader/`. Use
`LogoComfyWaveLoader` in `App.vue` and `WorkspaceAuthGate.vue`. Render
loader above BlockUI overlay (z-1200) to prevent dim wash-out.
- **Dependencies**: None

## Review Focus

- SVG mask-based animation approach using `currentColor` for flexible
theming
- z-index layering: loader at z-1200 renders above PrimeVue BlockUI's
z-1100 modal overlay
- `disableAnimation` prop used in WorkspaceAuthGate to show static logo
outline during auth loading

## Screenshots (if applicable)

[loading_record.webm](https://github.com/user-attachments/assets/b34f7296-9904-4a42-9273-a7d5fda49d15)

Storybook stories added for both components under `Components/Loader/`.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-9433-feat-add-Logo-C-fill-and-Comfy-wave-loading-indicator-components-31a6d73d3650811cacfdcf867b1f835f)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-03-06 00:32:20 -08:00

75 lines
1.8 KiB
Vue

<template>
<WidgetLayoutField :widget="layoutWidget">
<div class="relative">
<Loader
v-if="loading"
size="sm"
class="absolute top-1/2 left-3 z-10 -translate-y-1/2 text-component-node-foreground"
/>
<InputText
v-model="modelValue"
v-bind="filteredProps"
:class="
cn(
WidgetInputBaseClass,
'w-full px-4 hover:bg-component-node-widget-background-hovered',
size === 'large' ? 'py-3 text-sm' : 'py-2 text-xs',
loading && 'pl-9'
)
"
:aria-label="widget.name"
:readonly="isReadOnly"
size="small"
:pt="{ root: 'truncate min-w-[4ch]' }"
/>
</div>
</WidgetLayoutField>
</template>
<script setup lang="ts">
import InputText from 'primevue/inputtext'
import { computed } from 'vue'
import Loader from '@/components/loader/Loader.vue'
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
import { cn } from '@/utils/tailwindUtil'
import {
INPUT_EXCLUDED_PROPS,
filterWidgetProps
} from '@/utils/widgetPropFilter'
import { WidgetInputBaseClass } from './layout'
import WidgetLayoutField from './layout/WidgetLayoutField.vue'
const {
widget,
size = 'medium',
invalid = false,
loading = false
} = defineProps<{
widget: SimplifiedWidget<string>
size?: 'medium' | 'large'
invalid?: boolean
loading?: boolean
}>()
const modelValue = defineModel<string>({ default: '' })
const filteredProps = computed(() =>
filterWidgetProps(widget.options, INPUT_EXCLUDED_PROPS)
)
const isReadOnly = computed(() =>
Boolean(widget.options?.read_only || widget.options?.disabled)
)
const layoutWidget = computed(() => ({
name: widget.name,
label: widget.label,
borderStyle: cn(
widget.borderStyle,
invalid && 'border border-destructive-background'
)
}))
</script>