mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
Adds a system for selecting the inputs and outputs which should be displayed when inside linear mode. Functions only in litegraph currently. Vue support will require a separate, larger PR. Inputs and outputs can be re-ordered by dragging and dropping on the side panel.  ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8965-Add-App-I-O-selection-system-30b6d73d365081569b36c1682a1fdbc5) by [Unito](https://www.unito.io)
115 lines
3.5 KiB
Vue
115 lines
3.5 KiB
Vue
<template>
|
|
<nav
|
|
class="fixed top-[calc(var(--workflow-tabs-height)+var(--spacing)*1.5)] left-1/2 z-[1000] -translate-x-1/2"
|
|
:aria-label="t('builderToolbar.label')"
|
|
>
|
|
<div
|
|
class="inline-flex items-center gap-1 rounded-2xl border border-border-default bg-base-background p-2 shadow-interface"
|
|
>
|
|
<template
|
|
v-for="(step, index) in [selectStep, arrangeStep]"
|
|
:key="step.id"
|
|
>
|
|
<button
|
|
:class="
|
|
cn(
|
|
stepClasses,
|
|
activeStep === step.id && 'bg-interface-builder-mode-background',
|
|
activeStep !== step.id &&
|
|
'hover:bg-secondary-background bg-transparent'
|
|
)
|
|
"
|
|
:aria-current="activeStep === step.id ? 'step' : undefined"
|
|
@click="appModeStore.setMode(step.id)"
|
|
>
|
|
<StepBadge :step :index :model-value="activeStep" />
|
|
<StepLabel :step />
|
|
</button>
|
|
|
|
<div class="mx-1 h-px w-4 bg-border-default" role="separator" />
|
|
</template>
|
|
|
|
<!-- Save -->
|
|
<ConnectOutputPopover
|
|
v-if="!appModeStore.hasOutputs"
|
|
:is-select-active="activeStep === 'builder:select'"
|
|
@switch="appModeStore.setMode('builder:select')"
|
|
>
|
|
<button :class="cn(stepClasses, 'opacity-30 bg-transparent')">
|
|
<StepBadge :step="saveStep" :index="2" :model-value="activeStep" />
|
|
<StepLabel :step="saveStep" />
|
|
</button>
|
|
</ConnectOutputPopover>
|
|
<button
|
|
v-else
|
|
:class="
|
|
cn(
|
|
stepClasses,
|
|
activeStep === 'save'
|
|
? 'bg-interface-builder-mode-background'
|
|
: 'hover:bg-secondary-background bg-transparent'
|
|
)
|
|
"
|
|
@click="appModeStore.setBuilderSaving(true)"
|
|
>
|
|
<StepBadge :step="saveStep" :index="2" :model-value="activeStep" />
|
|
<StepLabel :step="saveStep" />
|
|
</button>
|
|
</div>
|
|
</nav>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { useEventListener } from '@vueuse/core'
|
|
|
|
import { useAppModeStore } from '@/stores/appModeStore'
|
|
import type { AppMode } from '@/stores/appModeStore'
|
|
import { cn } from '@/utils/tailwindUtil'
|
|
|
|
import ConnectOutputPopover from './ConnectOutputPopover.vue'
|
|
import StepBadge from './StepBadge.vue'
|
|
import StepLabel from './StepLabel.vue'
|
|
import type { BuilderToolbarStep } from './types'
|
|
|
|
const { t } = useI18n()
|
|
const appModeStore = useAppModeStore()
|
|
|
|
useEventListener(document, 'keydown', (e: KeyboardEvent) => {
|
|
if (e.key !== 'Escape') return
|
|
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
void appModeStore.exitBuilder()
|
|
})
|
|
|
|
const activeStep = computed(() =>
|
|
appModeStore.isBuilderSaving ? 'save' : appModeStore.mode
|
|
)
|
|
|
|
const stepClasses =
|
|
'inline-flex h-14 min-h-8 cursor-pointer items-center gap-3 rounded-lg py-2 pr-4 pl-2 transition-colors border-none'
|
|
|
|
const selectStep: BuilderToolbarStep<AppMode> = {
|
|
id: 'builder:select',
|
|
title: t('builderToolbar.select'),
|
|
subtitle: t('builderToolbar.selectDescription'),
|
|
icon: 'icon-[lucide--mouse-pointer-click]'
|
|
}
|
|
|
|
const arrangeStep: BuilderToolbarStep<AppMode> = {
|
|
id: 'builder:arrange',
|
|
title: t('builderToolbar.arrange'),
|
|
subtitle: t('builderToolbar.arrangeDescription'),
|
|
icon: 'icon-[lucide--layout-panel-left]'
|
|
}
|
|
|
|
const saveStep: BuilderToolbarStep<'save'> = {
|
|
id: 'save',
|
|
title: t('builderToolbar.save'),
|
|
subtitle: t('builderToolbar.saveDescription'),
|
|
icon: 'icon-[lucide--cloud-upload]'
|
|
}
|
|
</script>
|