From 2308b25bcf940eb94df913349ffa202a533d762b Mon Sep 17 00:00:00 2001 From: Sagit Date: Thu, 19 Feb 2026 05:55:54 +0000 Subject: [PATCH] fix(frontend): forward refs through shadcn bridge buttons --- .../shadcn-ui-full-migration-2026-02-19.md | 1 + vite-frontend/src/components/ui/button.tsx | 25 +++-- .../src/shadcn-bridge/heroui/button.tsx | 99 ++++++++++--------- 3 files changed, 71 insertions(+), 54 deletions(-) diff --git a/vite-frontend/docs/shadcn-ui-full-migration-2026-02-19.md b/vite-frontend/docs/shadcn-ui-full-migration-2026-02-19.md index e41299f..c0d5be9 100644 --- a/vite-frontend/docs/shadcn-ui-full-migration-2026-02-19.md +++ b/vite-frontend/docs/shadcn-ui-full-migration-2026-02-19.md @@ -46,3 +46,4 @@ - [2026-02-19] 完成 S7:删除全部 HeroUI/NextUI 依赖,补齐 `@internationalized/date` 与 `@react-aria/i18n` 显式依赖 - [2026-02-19] 完成 S8:构建验收通过(`npm run build`),`package.json` 已无 `heroui/nextui` 依赖 - [2026-02-19] 验证结果:业务代码中 `@heroui/*` 导入为 `0`,已统一替换为 `@/shadcn-bridge/heroui/*`(22 文件,106 处) +- [2026-02-19] 后续修复:`src/components/ui/button.tsx` 与 `src/shadcn-bridge/heroui/button.tsx` 改为 `forwardRef`,消除 `DropdownMenuTrigger asChild` 场景 ref 警告;复构建通过 diff --git a/vite-frontend/src/components/ui/button.tsx b/vite-frontend/src/components/ui/button.tsx index 6c22b2f..72fd09f 100644 --- a/vite-frontend/src/components/ui/button.tsx +++ b/vite-frontend/src/components/ui/button.tsx @@ -37,16 +37,21 @@ type ButtonProps = React.ComponentProps<"button"> & asChild?: boolean; }; -function Button({ asChild = false, className, size, variant, ...props }: ButtonProps) { - const Comp = asChild ? Slot : "button"; +const Button = React.forwardRef( + ({ asChild = false, className, size, variant, ...props }, ref) => { + const Comp = asChild ? Slot : "button"; - return ( - - ); -} + return ( + + ); + }, +); + +Button.displayName = "Button"; export { Button, buttonVariants }; diff --git a/vite-frontend/src/shadcn-bridge/heroui/button.tsx b/vite-frontend/src/shadcn-bridge/heroui/button.tsx index ae530ae..14d9b86 100644 --- a/vite-frontend/src/shadcn-bridge/heroui/button.tsx +++ b/vite-frontend/src/shadcn-bridge/heroui/button.tsx @@ -57,49 +57,60 @@ function mapSize(size: HeroButtonSize, isIconOnly: boolean): "default" | "sm" | return "default"; } -export function Button({ - children, - className, - color = "default", - disabled, - endContent, - isIconOnly = false, - isLoading = false, - isDisabled, - onClick, - onPress, - size = "md", - startContent, - type = "button", - variant = "solid", - ...props -}: ButtonProps & { - isDisabled?: boolean; -}) { - const resolvedVariant = mapVariant(color, variant); - const resolvedSize = mapSize(size, isIconOnly); - const resolvedDisabled = Boolean(disabled || isDisabled || isLoading); +export const Button = React.forwardRef< + HTMLButtonElement, + ButtonProps & { + isDisabled?: boolean; + } +>( + ( + { + children, + className, + color = "default", + disabled, + endContent, + isIconOnly = false, + isLoading = false, + isDisabled, + onClick, + onPress, + size = "md", + startContent, + type = "button", + variant = "solid", + ...props + }, + ref, + ) => { + const resolvedVariant = mapVariant(color, variant); + const resolvedSize = mapSize(size, isIconOnly); + const resolvedDisabled = Boolean(disabled || isDisabled || isLoading); - const handleClick = (event: React.MouseEvent) => { - onClick?.(event); - onPress?.(event); - }; + const handleClick = (event: React.MouseEvent) => { + onClick?.(event); + onPress?.(event); + }; - return ( - - {isLoading ? : null} - {startContent} - {isIconOnly ? null : children} - {isIconOnly ? children : null} - {endContent} - - ); -} + return ( + + {isLoading ? : null} + {startContent} + {isIconOnly ? null : children} + {isIconOnly ? children : null} + {endContent} + + ); + }, +); + +Button.displayName = "HeroBridgeButton";