From 018fe7a9d3ddf8cb48e3690c816bb5d09fc3f74c Mon Sep 17 00:00:00 2001
From: yyh <92089059+lyzno1@users.noreply.github.com>
Date: Thu, 23 Jul 2026 09:07:08 +0800
Subject: [PATCH] fix(dify-ui): preserve link semantics in button story
(#39430)
---
packages/dify-ui/src/button/index.stories.tsx | 27 ++++++++++++++-----
packages/dify-ui/src/button/index.tsx | 2 +-
2 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/packages/dify-ui/src/button/index.stories.tsx b/packages/dify-ui/src/button/index.stories.tsx
index dec3a3aaf6f..be16f4cd36b 100644
--- a/packages/dify-ui/src/button/index.stories.tsx
+++ b/packages/dify-ui/src/button/index.stories.tsx
@@ -1,7 +1,7 @@
import type { Meta, StoryObj } from '@storybook/react-vite'
import * as React from 'react'
import { expect, fn } from 'storybook/test'
-import { Button } from '.'
+import { Button, buttonVariants } from '.'
const meta = {
title: 'Base/UI/Button',
@@ -151,11 +151,24 @@ export const LargeSize: Story = {
},
}
-export const AsLink: Story = {
- args: {
- variant: 'ghost-accent',
- render: ,
- nativeButton: false,
- children: 'Link Button',
+export const StyledLink: Story = {
+ render: () => (
+
+ Link styled as a button
+
+ ),
+ play: async ({ canvas }) => {
+ await expect(canvas.getByRole('link', { name: 'Link styled as a button' })).toHaveAttribute(
+ 'href',
+ 'https://example.com',
+ )
+ },
+ parameters: {
+ docs: {
+ description: {
+ story:
+ 'Rendering an anchor through `Button` is an anti-pattern because Base UI enforces button semantics. Keep the native link and apply `buttonVariants` directly when a link needs button styling. See the [Base UI Button usage guidelines](https://base-ui.com/react/components/button#rendering-links-as-buttons).',
+ },
+ },
},
}
diff --git a/packages/dify-ui/src/button/index.tsx b/packages/dify-ui/src/button/index.tsx
index 631680fa950..cd8d0a8b7bb 100644
--- a/packages/dify-ui/src/button/index.tsx
+++ b/packages/dify-ui/src/button/index.tsx
@@ -6,7 +6,7 @@ import { Button as BaseButton } from '@base-ui/react/button'
import { cva } from 'class-variance-authority'
import { cn } from '../cn'
-const buttonVariants = cva(
+export const buttonVariants = cva(
'inline-flex cursor-pointer items-center justify-center whitespace-nowrap outline-hidden focus-visible:ring-2 focus-visible:ring-state-accent-solid data-[disabled]:cursor-not-allowed',
{
variants: {