From 8d7dd9ed6769f9396b342cd90e43c15926ff02fb Mon Sep 17 00:00:00 2001 From: Alexander Brown Date: Tue, 16 Dec 2025 20:38:24 -0800 Subject: [PATCH] Component: Button migration 1: TextButton (#7537) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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 ## Screenshots (if applicable) ┆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 --- package.json | 1 + pnpm-lock.yaml | 20 ++++ pnpm-workspace.yaml | 1 + src/components/button/TextButton.stories.ts | 91 ------------------- src/components/button/TextButton.vue | 54 ----------- .../dialog/confirm/ConfirmFooter.vue | 21 ++--- .../dialog/content/MissingNodesFooter.vue | 20 ++-- src/components/input/MultiSelect.vue | 33 +++---- src/components/queue/QueueOverlayActive.vue | 14 +-- .../queue/dialogs/QueueClearHistoryDialog.vue | 23 ++--- src/components/queue/job/JobFiltersBar.vue | 17 ++-- src/components/queue/job/QueueJobItem.vue | 14 +-- .../sidebar/tabs/AssetsSidebarTab.vue | 23 +++-- src/components/ui/button/Button.stories.ts | 68 ++++++++++++++ src/components/ui/button/Button.vue | 28 ++++++ src/components/ui/button/button.variants.ts | 49 ++++++++++ .../assets/components/UploadModelFooter.vue | 34 +++---- .../UploadModelUpgradeModalFooter.vue | 20 ++-- vite.config.mts | 4 +- 19 files changed, 275 insertions(+), 260 deletions(-) delete mode 100644 src/components/button/TextButton.stories.ts delete mode 100644 src/components/button/TextButton.vue create mode 100644 src/components/ui/button/Button.stories.ts create mode 100644 src/components/ui/button/Button.vue create mode 100644 src/components/ui/button/button.variants.ts diff --git a/package.json b/package.json index 991b228fc..8a672dacf 100644 --- a/package.json +++ b/package.json @@ -161,6 +161,7 @@ "algoliasearch": "catalog:", "axios": "catalog:", "chart.js": "^4.5.0", + "cva": "catalog:", "dompurify": "^3.2.5", "dotenv": "catalog:", "es-toolkit": "^1.39.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7e541bff1..063ac6948 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -138,6 +138,9 @@ catalogs: cross-env: specifier: ^10.1.0 version: 10.1.0 + cva: + specifier: 1.0.0-beta.4 + version: 1.0.0-beta.4 dotenv: specifier: ^16.4.5 version: 16.6.1 @@ -419,6 +422,9 @@ importers: chart.js: specifier: ^4.5.0 version: 4.5.0 + cva: + specifier: 'catalog:' + version: 1.0.0-beta.4(typescript@5.9.2) dompurify: specifier: ^3.2.5 version: 3.2.5 @@ -4669,6 +4675,14 @@ packages: csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + cva@1.0.0-beta.4: + resolution: {integrity: sha512-F/JS9hScapq4DBVQXcK85l9U91M6ePeXoBMSp7vypzShoefUBxjQTo3g3935PUHgQd+IW77DjbPRIxugy4/GCQ==} + peerDependencies: + typescript: '>= 4.5.5' + peerDependenciesMeta: + typescript: + optional: true + data-urls@5.0.0: resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} engines: {node: '>=18'} @@ -12808,6 +12822,12 @@ snapshots: csstype@3.2.3: {} + cva@1.0.0-beta.4(typescript@5.9.2): + dependencies: + clsx: 2.1.1 + optionalDependencies: + typescript: 5.9.2 + data-urls@5.0.0: dependencies: whatwg-mimetype: 4.0.0 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 682e80044..1a48dfd5d 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -47,6 +47,7 @@ catalog: algoliasearch: ^5.21.0 axios: ^1.8.2 cross-env: ^10.1.0 + cva: 1.0.0-beta.4 dotenv: ^16.4.5 eslint: ^9.39.1 eslint-config-prettier: ^10.1.8 diff --git a/src/components/button/TextButton.stories.ts b/src/components/button/TextButton.stories.ts deleted file mode 100644 index 9c055a48b..000000000 --- a/src/components/button/TextButton.stories.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/vue3-vite' - -import TextButton from './TextButton.vue' - -const meta: Meta = { - title: 'Components/Button/TextButton', - component: TextButton, - tags: ['autodocs'], - argTypes: { - label: { - control: 'text', - defaultValue: 'Click me' - }, - size: { - control: { type: 'select' }, - options: ['sm', 'md'], - defaultValue: 'md' - }, - border: { - control: 'boolean', - description: 'Toggle border attribute' - }, - disabled: { - control: 'boolean', - description: 'Toggle disable status' - }, - type: { - control: { type: 'select' }, - options: ['primary', 'secondary', 'transparent'], - defaultValue: 'primary' - }, - onClick: { action: 'clicked' } - } -} - -export default meta -type Story = StoryObj - -export const Primary: Story = { - args: { - label: 'Primary Button', - type: 'primary', - size: 'md' - } -} - -export const Secondary: Story = { - args: { - label: 'Secondary Button', - type: 'secondary', - size: 'md' - } -} - -export const Transparent: Story = { - args: { - label: 'Transparent Button', - type: 'transparent', - size: 'md' - } -} - -export const Small: Story = { - args: { - label: 'Small Button', - type: 'primary', - size: 'sm' - } -} - -export const AllVariants: Story = { - render: () => ({ - components: { TextButton }, - template: ` -
-
- - -
-
- - -
-
- - -
-
- ` - }) -} diff --git a/src/components/button/TextButton.vue b/src/components/button/TextButton.vue deleted file mode 100644 index 4dbe53b9c..000000000 --- a/src/components/button/TextButton.vue +++ /dev/null @@ -1,54 +0,0 @@ - - - diff --git a/src/components/dialog/confirm/ConfirmFooter.vue b/src/components/dialog/confirm/ConfirmFooter.vue index f7d68b674..9cdd6e37b 100644 --- a/src/components/dialog/confirm/ConfirmFooter.vue +++ b/src/components/dialog/confirm/ConfirmFooter.vue @@ -1,19 +1,16 @@ + + diff --git a/src/components/ui/button/button.variants.ts b/src/components/ui/button/button.variants.ts new file mode 100644 index 000000000..45114393c --- /dev/null +++ b/src/components/ui/button/button.variants.ts @@ -0,0 +1,49 @@ +import type { VariantProps } from 'cva' +import { cva } from 'cva' + +export const buttonVariants = cva({ + base: 'inline-flex items-center justify-center gap-2 cursor-pointer whitespace-nowrap appearance-none border-none rounded-md text-sm font-medium font-inter transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', + variants: { + variant: { + secondary: + 'bg-secondary-background text-secondary-foreground hover:bg-secondary-background-hover', + primary: + 'bg-primary-background text-base-foreground hover:bg-primary-background-hover', + inverted: + 'bg-base-foreground text-base-background hover:bg-base-foreground/80', + destructive: + 'bg-destructive-background text-base-foreground hover:bg-destructive-background-hover', + textonly: + 'text-base-foreground bg-transparent hover:bg-secondary-background-hover', + 'muted-textonly': + 'text-muted-foreground bg-transparent hover:bg-secondary-background-hover' + }, + size: { + sm: 'h-6 rounded-sm px-2 py-1 text-xs', + md: 'h-8 rounded-lg p-2 text-xs', + lg: 'h-10 rounded-lg px-4 py-2 text-sm', + icon: 'size-9' + } + }, + + defaultVariants: { + variant: 'secondary', + size: 'md' + } +}) + +export type ButtonVariants = VariantProps + +const variants = [ + 'secondary', + 'primary', + 'inverted', + 'destructive', + 'textonly', + 'muted-textonly' +] as const satisfies Array +const sizes = ['sm', 'md', 'lg', 'icon'] as const satisfies Array< + ButtonVariants['size'] +> + +export const FOR_STORIES = { variants, sizes } as const diff --git a/src/platform/assets/components/UploadModelFooter.vue b/src/platform/assets/components/UploadModelFooter.vue index 82f597dd7..68c9bcdff 100644 --- a/src/platform/assets/components/UploadModelFooter.vue +++ b/src/platform/assets/components/UploadModelFooter.vue @@ -13,24 +13,26 @@ - - + {{ $t('g.cancel') }} + + - + > + {{ $t('assetBrowser.finish') }} + {{ $t('g.learnMore') }} - - + +