mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-23 08:14:06 +00:00
Component: Button Migration 2: IconButton (#7598)
## Summary Still a work in progress. Buttons with just icons are already in the stories for button. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7598-WIP-Component-Button-Migration-2-IconButton-2cc6d73d365081c09143c63464ac60b7) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<IconButton
|
||||
type="secondary"
|
||||
size="fit-content"
|
||||
class="group w-full justify-between gap-3 rounded-lg p-1 text-left font-normal hover:cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-background"
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="lg"
|
||||
class="group w-full justify-between gap-3 p-1 text-left font-normal hover:cursor-pointer focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary-background"
|
||||
:aria-label="props.ariaLabel"
|
||||
@click="emit('click', $event)"
|
||||
>
|
||||
@@ -81,11 +81,11 @@
|
||||
>
|
||||
<i class="icon-[lucide--chevron-down] block size-4 leading-none" />
|
||||
</span>
|
||||
</IconButton>
|
||||
</Button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import type {
|
||||
CompletionSummary,
|
||||
CompletionSummaryMode
|
||||
|
||||
@@ -42,19 +42,18 @@
|
||||
t('sideToolbar.queueProgressOverlay.running')
|
||||
}}</span>
|
||||
</span>
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="runningCount > 0"
|
||||
v-tooltip.top="cancelJobTooltip"
|
||||
type="secondary"
|
||||
size="sm"
|
||||
class="size-6 bg-destructive-background hover:bg-destructive-background-hover"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.interruptAll')"
|
||||
@click="$emit('interruptAll')"
|
||||
>
|
||||
<i
|
||||
class="icon-[lucide--x] block size-4 leading-none text-text-primary"
|
||||
/>
|
||||
</IconButton>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -64,26 +63,25 @@
|
||||
t('sideToolbar.queueProgressOverlay.queuedSuffix')
|
||||
}}</span>
|
||||
</span>
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="queuedCount > 0"
|
||||
v-tooltip.top="clearQueueTooltip"
|
||||
type="secondary"
|
||||
size="sm"
|
||||
class="size-6 bg-secondary-background hover:bg-destructive-background"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.clearQueued')"
|
||||
@click="$emit('clearQueued')"
|
||||
>
|
||||
<i
|
||||
class="icon-[lucide--list-x] block size-4 leading-none text-text-primary"
|
||||
/>
|
||||
</IconButton>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
class="min-w-30 flex-1 px-2 py-0"
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
size="md"
|
||||
@click="$emit('viewAllJobs')"
|
||||
>
|
||||
{{ t('sideToolbar.queueProgressOverlay.viewAllJobs') }}
|
||||
@@ -96,7 +94,6 @@
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
|
||||
|
||||
|
||||
@@ -31,18 +31,16 @@
|
||||
t('sideToolbar.queueProgressOverlay.queuedSuffix')
|
||||
}}</span>
|
||||
</div>
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="queuedCount > 0"
|
||||
class="group ml-2 size-6 bg-secondary-background hover:bg-destructive-background"
|
||||
type="secondary"
|
||||
size="sm"
|
||||
class="ml-2"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.clearQueued')"
|
||||
@click="$emit('clearQueued')"
|
||||
>
|
||||
<i
|
||||
class="pointer-events-none icon-[lucide--list-x] block size-4 leading-none text-text-primary transition-colors group-hover:text-base-background"
|
||||
/>
|
||||
</IconButton>
|
||||
<i class="icon-[lucide--list-x] size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -80,8 +78,8 @@
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import type {
|
||||
JobGroup,
|
||||
JobListItem,
|
||||
|
||||
@@ -18,18 +18,17 @@
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="!isCloud" class="flex items-center gap-1">
|
||||
<IconButton
|
||||
<Button
|
||||
v-tooltip.top="moreTooltipConfig"
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="size-6 bg-transparent hover:bg-secondary-background hover:opacity-100"
|
||||
variant="textonly"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.moreOptions')"
|
||||
@click="onMoreClick"
|
||||
>
|
||||
<i
|
||||
class="icon-[lucide--more-horizontal] block size-4 leading-none text-text-secondary"
|
||||
/>
|
||||
</IconButton>
|
||||
</Button>
|
||||
<Popover
|
||||
ref="morePopoverRef"
|
||||
:dismissable="true"
|
||||
@@ -72,8 +71,8 @@ import type { PopoverMethods } from 'primevue/popover'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
|
||||
|
||||
@@ -8,15 +8,14 @@
|
||||
<p class="m-0 text-[14px] font-normal leading-none">
|
||||
{{ t('sideToolbar.queueProgressOverlay.clearHistoryDialogTitle') }}
|
||||
</p>
|
||||
<IconButton
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="size-6 bg-transparent text-text-secondary hover:bg-secondary-background hover:opacity-100"
|
||||
<Button
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
:aria-label="t('g.close')"
|
||||
@click="onCancel"
|
||||
>
|
||||
<i class="icon-[lucide--x] block size-4 leading-none" />
|
||||
</IconButton>
|
||||
</Button>
|
||||
</header>
|
||||
|
||||
<div class="flex flex-col gap-4 px-4 py-4 text-[14px] text-text-secondary">
|
||||
@@ -51,7 +50,6 @@
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
|
||||
@@ -20,18 +20,15 @@
|
||||
class="flex min-w-0 items-center text-[0.75rem] leading-normal font-normal text-text-secondary"
|
||||
>
|
||||
<span class="block min-w-0 truncate">{{ row.value }}</span>
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="row.canCopy"
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="ml-2 size-6 bg-transparent hover:opacity-90"
|
||||
size="icon"
|
||||
variant="muted-textonly"
|
||||
:aria-label="copyAriaLabel"
|
||||
@click.stop="copyJobId"
|
||||
>
|
||||
<i
|
||||
class="icon-[lucide--copy] block size-4 leading-none text-text-secondary"
|
||||
/>
|
||||
</IconButton>
|
||||
<i class="icon-[lucide--copy] size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
@@ -101,10 +98,9 @@
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useCopyToClipboard } from '@/composables/useCopyToClipboard'
|
||||
import { t } from '@/i18n'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
@@ -128,7 +124,7 @@ const workflowStore = useWorkflowStore()
|
||||
const queueStore = useQueueStore()
|
||||
const executionStore = useExecutionStore()
|
||||
const dialog = useDialogService()
|
||||
const { locale } = useI18n()
|
||||
const { locale, t } = useI18n()
|
||||
|
||||
const workflowValue = computed(() => {
|
||||
const wid = props.workflowId
|
||||
|
||||
@@ -15,23 +15,20 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-2 flex shrink-0 items-center gap-2">
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="showWorkflowFilter"
|
||||
v-tooltip.top="filterTooltipConfig"
|
||||
type="secondary"
|
||||
size="sm"
|
||||
class="relative size-6 bg-secondary-background hover:bg-secondary-background-hover hover:opacity-90"
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.filterJobs')"
|
||||
@click="onFilterClick"
|
||||
>
|
||||
<i
|
||||
class="icon-[lucide--list-filter] block size-4 leading-none text-text-primary"
|
||||
/>
|
||||
<i class="icon-[lucide--list-filter] size-4" />
|
||||
<span
|
||||
v-if="selectedWorkflowFilter !== 'all'"
|
||||
class="pointer-events-none absolute -top-1 -right-1 inline-block size-2 rounded-full bg-base-foreground"
|
||||
/>
|
||||
</IconButton>
|
||||
</Button>
|
||||
<Popover
|
||||
v-if="showWorkflowFilter"
|
||||
ref="filterPopoverRef"
|
||||
@@ -87,22 +84,19 @@
|
||||
</IconTextButton>
|
||||
</div>
|
||||
</Popover>
|
||||
<IconButton
|
||||
<Button
|
||||
v-tooltip.top="sortTooltipConfig"
|
||||
type="secondary"
|
||||
size="sm"
|
||||
class="relative size-6 bg-secondary-background hover:bg-secondary-background-hover hover:opacity-90"
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
:aria-label="t('sideToolbar.queueProgressOverlay.sortJobs')"
|
||||
@click="onSortClick"
|
||||
>
|
||||
<i
|
||||
class="icon-[lucide--arrow-up-down] block size-4 leading-none text-text-primary"
|
||||
/>
|
||||
<i class="icon-[lucide--arrow-up-down] size-4" />
|
||||
<span
|
||||
v-if="selectedSortMode !== 'mostRecent'"
|
||||
class="pointer-events-none absolute -top-1 -right-1 inline-block size-2 rounded-full bg-base-foreground"
|
||||
/>
|
||||
</IconButton>
|
||||
</Button>
|
||||
<Popover
|
||||
ref="sortPopoverRef"
|
||||
:dismissable="true"
|
||||
@@ -152,7 +146,6 @@ import Popover from 'primevue/popover'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import IconTextButton from '@/components/button/IconTextButton.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { jobSortModes, jobTabs } from '@/composables/queue/useJobList'
|
||||
|
||||
@@ -128,51 +128,47 @@
|
||||
key="actions"
|
||||
class="inline-flex items-center gap-2 pr-1"
|
||||
>
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="props.state === 'failed' && computedShowClear"
|
||||
v-tooltip.top="deleteTooltipConfig"
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="size-6 transform gap-1 rounded bg-destructive-background text-text-primary transition duration-150 ease-in-out hover:-translate-y-px hover:bg-destructive-background-hover hover:opacity-95"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('g.delete')"
|
||||
@click.stop="onDeleteClick"
|
||||
>
|
||||
<i class="icon-[lucide--trash-2] size-4" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
</Button>
|
||||
<Button
|
||||
v-else-if="
|
||||
props.state !== 'completed' &&
|
||||
props.state !== 'running' &&
|
||||
computedShowClear
|
||||
"
|
||||
v-tooltip.top="cancelTooltipConfig"
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="size-6 transform gap-1 rounded bg-destructive-background text-text-primary transition duration-150 ease-in-out hover:-translate-y-px hover:bg-destructive-background-hover hover:opacity-95"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('g.cancel')"
|
||||
@click.stop="onCancelClick"
|
||||
>
|
||||
<i class="icon-[lucide--x] size-4" />
|
||||
</IconButton>
|
||||
</Button>
|
||||
<Button
|
||||
v-else-if="props.state === 'completed'"
|
||||
class="transform bg-modal-card-button-surface px-2 py-0 transition duration-150 ease-in-out hover:-translate-y-px hover:opacity-95"
|
||||
variant="textonly"
|
||||
size="sm"
|
||||
@click.stop="emit('view')"
|
||||
>{{ t('menuLabels.View') }}</Button
|
||||
>
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="props.showMenu !== undefined ? props.showMenu : true"
|
||||
v-tooltip.top="moreTooltipConfig"
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="size-6 transform gap-1 rounded bg-modal-card-button-surface text-text-primary transition duration-150 ease-in-out hover:-translate-y-px hover:opacity-95"
|
||||
variant="textonly"
|
||||
size="icon-sm"
|
||||
:aria-label="t('g.more')"
|
||||
@click.stop="emit('menu', $event)"
|
||||
>
|
||||
<i class="icon-[lucide--more-horizontal] size-4" />
|
||||
</IconButton>
|
||||
</Button>
|
||||
</div>
|
||||
<div
|
||||
v-else-if="props.state !== 'running'"
|
||||
@@ -183,17 +179,16 @@
|
||||
</div>
|
||||
</Transition>
|
||||
<!-- Running job cancel button - always visible -->
|
||||
<IconButton
|
||||
<Button
|
||||
v-if="props.state === 'running' && computedShowClear"
|
||||
v-tooltip.top="cancelTooltipConfig"
|
||||
type="transparent"
|
||||
size="sm"
|
||||
class="size-6 transform gap-1 rounded bg-destructive-background text-text-primary transition duration-150 ease-in-out hover:-translate-y-px hover:bg-destructive-background-hover hover:opacity-95"
|
||||
variant="destructive"
|
||||
size="icon"
|
||||
:aria-label="t('g.cancel')"
|
||||
@click.stop="onCancelClick"
|
||||
>
|
||||
<i class="icon-[lucide--x] size-4" />
|
||||
</IconButton>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,7 +198,6 @@
|
||||
import { computed, nextTick, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import IconButton from '@/components/button/IconButton.vue'
|
||||
import JobDetailsPopover from '@/components/queue/job/JobDetailsPopover.vue'
|
||||
import QueueAssetPreview from '@/components/queue/job/QueueAssetPreview.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
|
||||
Reference in New Issue
Block a user