用途
该技能面向 8bitcn-ui 项目,提供包装 shadcn/ui 组件的最佳实践。它适用于为现有 shadcn/ui 组件创建 8 位(8-bit)复古风格变体的场景。其核心理念是:8-bit 组件包装 shadcn/ui 组件,而不是替换它们,从而在添加复古样式的同时保持兼容性。
主要能力
- 基础包装模式:通过别名导入基础组件,使用 class-variance-authority 定义变体,导出独立的 props 接口,并使用 ref 属性(React 19 中不再使用 forwardRef)。
- 再导出基础组件:对于包含多个子组件的组件,将未改动的部分直接再导出。
- Card 包装模式:使用外层包装器实现像素化边框,同时保留基础组件。
使用方式
基础包装模式的结构包括:
- 使用别名导入基础组件,例如
import { Button as ShadcnButton } from "@/components/ui/button"; - 使用 class-variance-authority 定义变体,例如
export const buttonVariants = cva("", { variants: { font: { normal: "", retro: "retro" }, variant: { default: "bg-foreground" } }, defaultVariants: { variant: "default", size: "default" } }); - 导出独立的 props 接口,例如
export interface BitButtonProps extends React.ButtonHTMLAttributes, VariantProps { asChild?: boolean; ref?: React.Ref; } - 在组件函数中透传属性,并叠加复古样式类,例如
className={cn("rounded-none active:translate-y-1 transition-transform", className)}。
对于多子组件,可再导出未改动的部分:
import {
Dialog as ShadcnDialog,
DialogHeader as ShadcnDialogHeader,
DialogFooter as ShadcnDialogFooter,
DialogDescription as ShadcnDialogDescription,
} from "@/components/ui/dialog";
const Dialog = ShadcnDialog;
const DialogHeader = ShadcnDialogHeader;
const DialogFooter = ShadcnDialogFooter;
const DialogDescription = ShadcnDialogDescription;
export {
Dialog,
DialogHeader,
DialogFooter,
DialogDescription,
};
Card 包装模式使用外层包装器实现像素化边框:
function Card({ className, font, ...props }: BitCardProps) {
return (
<div
className={cn(
"relative border-y-6 border-foreground dark:border-ring !p-0",
className
)}
>
<ShadcnCard
{...props}
className={cn(
"rounded-none border-0 !w-full",
font !== "normal" && "retro",
className
)}
/>
<div
className="absolute inset-0 border-x-6 -mx-1.5 border-foreground dark:border-ring pointer-events-none"
aria-hidden="true"
/>
</div>
);
}
关键原则
- 别名导入:对基础组件使用
as ShadcnComponent模式。 - 空 cva 基础:变体通常以空字符串开始,依赖 CSS 进行样式处理。
- 独立 props 接口:导出
BitComponentProps以支持 TypeScript。 - React 19 ref:使用
ref?: React.Ref<T>而非 forwardRef。 - rounded-none:移除基础组件的所有边框圆角。
- 属性透传:转发所有属性,包括 size、variant、className。
- 条件式 retro:使用
font !== "normal" && "retro"模式。
组件示例
components/ui/8bit/button.tsx:带像素边框的基础包装器。components/ui/8bit/card.tsx:带外层包装器的 Card。components/ui/8bit/dialog.tsx:多子组件包装器。
适用场景与限制
该技能适用于在 8bitcn-ui 项目中为 shadcn/ui 组件添加 8 位复古风格变体,尤其适合需要保持与基础组件兼容性的场景。资料未提供关于收费、价格、平台支持范围或具体效果的信息。