Component: Button migration 1: TextButton (#7537)

## Summary

Setup the variants and migrate existing uses of
TextButton/TextIconButton/IconButton to a single Button component.

Still a work in progress.

## Changes

- **What**: Add a new Button
- **What**: Migrate old buttons
- **What**: Delete old buttons
- **Dependencies**: CVA, upgrade Storybook

## Review Focus

<!-- Critical design decisions or edge cases that need attention -->

<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->

## Screenshots (if applicable)

<!-- Add screenshots or video recording to help explain your changes -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-7537-WIP-Component-Button-migration-2cb6d73d36508156a81bfc7bbddb36e9)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
Alexander Brown
2025-12-16 20:38:24 -08:00
committed by GitHub
parent ab76d02823
commit 8d7dd9ed67
19 changed files with 275 additions and 260 deletions

View File

@@ -80,12 +80,14 @@
</div>
</div>
<TextButton
class="h-6 min-w-[120px] flex-1 px-2 py-0 text-[12px]"
type="secondary"
:label="t('sideToolbar.queueProgressOverlay.viewAllJobs')"
<Button
class="min-w-30 flex-1 px-2 py-0"
variant="secondary"
size="sm"
@click="$emit('viewAllJobs')"
/>
>
{{ t('sideToolbar.queueProgressOverlay.viewAllJobs') }}
</Button>
</div>
</div>
</template>
@@ -95,7 +97,7 @@ import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import IconButton from '@/components/button/IconButton.vue'
import TextButton from '@/components/button/TextButton.vue'
import Button from '@/components/ui/button/Button.vue'
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
defineProps<{

View File

@@ -31,20 +31,17 @@
</div>
<footer class="flex items-center justify-end px-4 py-4">
<div class="flex items-center gap-4 text-[14px] leading-none">
<TextButton
class="min-h-[24px] px-1 py-1 text-[14px] leading-[1] text-text-secondary hover:text-text-primary"
type="transparent"
:label="t('g.cancel')"
@click="onCancel"
/>
<TextButton
class="min-h-[32px] px-4 py-2 text-[12px] font-normal leading-[1]"
type="secondary"
:label="t('g.clear')"
<div class="flex items-center gap-4 leading-none">
<Button variant="muted-textonly" size="lg" @click="onCancel">
{{ t('g.cancel') }}
</Button>
<Button
variant="secondary"
size="lg"
:disabled="isClearing"
@click="onConfirm"
/>
>{{ t('g.clear') }}</Button
>
</div>
</footer>
</section>
@@ -55,7 +52,7 @@ import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
import IconButton from '@/components/button/IconButton.vue'
import TextButton from '@/components/button/TextButton.vue'
import Button from '@/components/ui/button/Button.vue'
import { useErrorHandling } from '@/composables/useErrorHandling'
import { useDialogStore } from '@/stores/dialogStore'
import { useQueueStore } from '@/stores/queueStore'

View File

@@ -2,17 +2,16 @@
<div class="flex items-center justify-between gap-2 px-3">
<div class="min-w-0 flex-1 overflow-x-auto">
<div class="inline-flex items-center gap-1 whitespace-nowrap">
<TextButton
<Button
v-for="tab in visibleJobTabs"
:key="tab"
class="h-6 px-3 py-1 text-[12px] leading-none hover:opacity-90"
:type="selectedJobTab === tab ? 'secondary' : 'transparent'"
:class="[
selectedJobTab === tab ? 'text-text-primary' : 'text-text-secondary'
]"
:label="tabLabel(tab)"
:variant="selectedJobTab === tab ? 'secondary' : 'muted-textonly'"
size="sm"
class="px-3"
@click="$emit('update:selectedJobTab', tab)"
/>
>
{{ tabLabel(tab) }}
</Button>
</div>
</div>
<div class="ml-2 flex shrink-0 items-center gap-2">
@@ -155,7 +154,7 @@ import { useI18n } from 'vue-i18n'
import IconButton from '@/components/button/IconButton.vue'
import IconTextButton from '@/components/button/IconTextButton.vue'
import TextButton from '@/components/button/TextButton.vue'
import Button from '@/components/ui/button/Button.vue'
import { jobSortModes, jobTabs } from '@/composables/queue/useJobList'
import type { JobSortMode, JobTab } from '@/composables/queue/useJobList'
import { buildTooltipConfig } from '@/composables/useTooltipConfig'

View File

@@ -154,14 +154,14 @@
>
<i class="icon-[lucide--x] size-4" />
</IconButton>
<TextButton
<Button
v-else-if="props.state === 'completed'"
class="h-6 transform gap-1 rounded bg-modal-card-button-surface px-2 py-0 text-text-primary transition duration-150 ease-in-out hover:-translate-y-px hover:opacity-95"
type="transparent"
:label="t('menuLabels.View')"
:aria-label="t('menuLabels.View')"
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
v-if="props.showMenu !== undefined ? props.showMenu : true"
v-tooltip.top="moreTooltipConfig"
@@ -204,9 +204,9 @@ import { computed, nextTick, ref, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import IconButton from '@/components/button/IconButton.vue'
import TextButton from '@/components/button/TextButton.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'
import { buildTooltipConfig } from '@/composables/useTooltipConfig'
import type { JobState } from '@/types/queue'
import { iconForJobState } from '@/utils/queueDisplay'