shadcn/ui组件比较灵活,但是功能相比ant之类组件还是缺少太多功能,本文为shadcn/ui为button组件增加图标,加载中动画等效果。
- 安装Lucide
bash
npm install lucide
- Lucide组件
typescript
import { cn } from '@/lib/utils';
import { icons } from 'lucide-react';
const LcIcon = ({ name, color, size, className }: { name: string, color?: string, size: number, className?: string}) => {
const LucideIcon = (icons as any)[name];
if(LucideIcon == null) {
return <></>
}
if(color != null) {
return <LucideIcon color={color} size={size} />
} else {
return <LucideIcon size={size} className={cn("", className)}/>
}
};
export default LcIcon;
- 创建组件CustomButton
typescript
"use client"
import React, { MouseEventHandler } from "react";
import { Button } from "../ui/button";
import LcIcon from "./lc-icon";
/**
* Button扩展,增加图标功能
* <CustomButton icon="Loader" onClick={handleSubmit}>Button</CustomButton>
* */
export const CustomButton = (props: {
className?: string,
icon?: string,
loading?: boolean
disabled?: boolean,
type?: string,
onClick?: MouseEventHandler<HTMLButtonElement>,
children?: any
}) => {
const buildIcon = () => {
if(props.loading != null && props.loading) {
return <LcIcon name="Loader" size={16} className="mr-1 animate-spin"/>
}
else if(props.icon != null) {
return <LcIcon name={props.icon} size={16} className="mr-1"/>
}
return ""
}
return (
<Button type={props.type ?? 'button' as any} className={props.className} disabled={props.disabled} onClick={props.onClick}>
{ buildIcon() }
{ props.children }
</Button>
)
}
- 组件使用,
显示加载中
typescript
import { CustomButton } from "@/components/app/custom-button";
<CustomButton loading={true} disabled={true} >测试</CustomButton>
显示图标
typescript
import { CustomButton } from "@/components/app/custom-button";
<CustomButton icon="Home">测试</CustomButton>