mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-02 04:02:20 +00:00
## 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>
75 lines
1.8 KiB
Vue
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>
|