全栈开发

ShadCN学习记录

1、自定义主题

nextjs项目global.css

添加自定义变量并设置对应颜色

:root {
...
--custom-color: oklch(0.6 0.2 150);
}

对主题生效,比如输入text-会提示text-custom-color

@theme inline {
...
--color-custom-color: var(--custom-color);
}

2、cn工具函数

方便类名与变量表达式混用

import {cn} from "@/lib/utils";

const CustomButton = (
    {
        disabled,
        isRounded
    }: {
        disabled: boolean;
        isRounded: boolean;
    }
) => {
    return (
        <button className={cn(
            "text-sm",
            disabled ? "bg-gray-300" : "bg-blue-500",
            isRounded && "rounded-full"
        )}>
            Hello
        </button>
    )
}

export default CustomButton;
  • disabled ? "bg-gray-300" : "bg-blue-500" 直接使用变量名进行逻辑判断

3、Dropdown menu

<DropdownMenuTrigger asChild>
  <Button variant="outline">Open</Button>
</DropdownMenuTrigger>
  • asChild:DropdownMenuTrigger默认渲染的是一个button元素作为触发器,当子元素是交互元素,比如button的时候,通过asChild可以避免嵌套的按钮结构,直接使用子组件作为触发器
  • button不能嵌套button,会报错!
  • 无asChild会渲染一个button元素,有asChild则不会渲染button
<!-- 无asChild时的渲染结果 -->
<button data-radix-collection-item>
  <button class="btn">Open</button>
</button>

<!-- 有asChild时的渲染结果 -->
<button class="btn" data-radix-collection-item>Open</button>

4、侧边栏Sidebar

      <Sidebar collapsible="icon">
            {/*侧边栏头部LOGO*/}
            <SidebarHeader>
                <SidebarMenu>
                    <SidebarMenuItem>
                        <SidebarMenuButton asChild>
                            <a href="#">
                                <ChartBar/>
                                Dashboard
                            </a>
                        </SidebarMenuButton>
                    </SidebarMenuItem>
                </SidebarMenu>
            </SidebarHeader>
            <SidebarSeparator/>
            <SidebarContent>
                {/*列式菜单*/}
                <SidebarGroup>
                    <SidebarGroupLabel>主导航</SidebarGroupLabel>
                    <SidebarGroupContent>
                        <SidebarMenu>
                            {items.map((item) => (
                                <SidebarMenuItem key={item.title}>
                                    <SidebarMenuButton asChild>
                                        <a href={item.url}>
                                            <item.icon/>
                                            <span>{item.title}</span>
                                        </a>
                                    </SidebarMenuButton>
                                </SidebarMenuItem>
                            ))}
                        </SidebarMenu>
                    </SidebarGroupContent>
                </SidebarGroup>
                {/*收缩展开式菜单*/}
                <Collapsible defaultOpen className="group/collapsible">
                    <SidebarGroup>
                        <SidebarGroupLabel asChild>
                            <CollapsibleTrigger>
                                帮助中心
                                <ChevronDown
                                    className="ml-auto transition-transform group-data-[state=open]/collapsible:rotate-180"/>
                            </CollapsibleTrigger>
                        </SidebarGroupLabel>
                        <CollapsibleContent>
                            <SidebarGroupContent>
                                <SidebarMenu>
                                    <SidebarMenuItem key="Support">
                                        <SidebarMenuButton asChild>
                                            <a href="#">
                                                <HelpCircle/>
                                                <span>Support</span>
                                            </a>
                                        </SidebarMenuButton>
                                    </SidebarMenuItem>
                                    <SidebarMenuItem key="Feedback">
                                        <SidebarMenuButton asChild>
                                            <a href="#">
                                                <Film/>
                                                <span>Feedback</span>
                                            </a>
                                        </SidebarMenuButton>
                                        <SidebarMenuBadge>20</SidebarMenuBadge>
                                    </SidebarMenuItem>
                                </SidebarMenu>
                            </SidebarGroupContent>
                        </CollapsibleContent>
                    </SidebarGroup>
                </Collapsible>
            </SidebarContent>
            <SidebarFooter>
                {/*侧边栏底部用户信息菜单*/}
                <SidebarMenu>
                    <SidebarMenuItem>
                        <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                                <SidebarMenuButton>
                                    <User2/> admin
                                    <ChevronUp className="ml-auto"/>
                                </SidebarMenuButton>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent
                                side="top"
                                className="w-(--radix-popper-anchor-width)"
                            >
                                <DropdownMenuItem>
                                    <span>Account</span>
                                </DropdownMenuItem>
                                <DropdownMenuItem>
                                    <span>Billing</span>
                                </DropdownMenuItem>
                                <DropdownMenuItem>
                                    退出登录
                                </DropdownMenuItem>
                            </DropdownMenuContent>
                        </DropdownMenu>
                    </SidebarMenuItem>
                </SidebarMenu>
            </SidebarFooter>
        </Sidebar>
  • 底部侧边栏 在DropdownMenuContent添加了自定义样式w-(--radix-popper-anchor-width)设置弹出菜单宽度和侧边栏一样
  • 触发侧边栏按钮
// 默认
import {SidebarTrigger} from "@/components/ui/sidebar";
// 使用方式
<SidebarTrigger/>

// 自定义
import {useSidebar} from "@/components/ui/sidebar";
const {toggleSidebar} = useSidebar()

<Button variant="outline" onClick={toggleSidebar}>
    Custom Button
</Button>