Hair Keeper v1.0.0:一个高度集成、深度定制、约定优于配置的全栈Web应用模板,旨在保持灵活性的同时提供一套基于成熟架构的开发底座,自带身份认证、权限控制、丰富前端组件、文件上传、后台任务、智能体开发等丰富功能,提供AI开发辅助,免于纠结功能如何实现,可快速上手专注于业务逻辑

This commit is contained in:
2025-11-13 15:24:54 +08:00
commit 42be39b343
249 changed files with 38843 additions and 0 deletions

View File

@@ -0,0 +1,93 @@
'use client'
import { ReactNode } from 'react'
import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
import {
Drawer,
DrawerContent,
DrawerTitle,
DrawerDescription,
DrawerTrigger,
} from '@/components/ui/drawer'
import { CarouselLayout, CarouselColumn } from '@/components/layout/carousel-layout'
export interface TripleColumnConfig {
/** 列的唯一标识 */
id: string
/** 列的标题 */
title: string
/** 列的内容 */
content: ReactNode
}
export interface TripleColumnAdaptiveDrawerProps {
/** 触发器元素 */
trigger: ReactNode
/** 抽屉标题(用于无障碍访问) */
drawerTitle: string
/** 抽屉描述(用于无障碍访问) */
drawerDescription: string
/** 三列配置 */
columns: [TripleColumnConfig, TripleColumnConfig, TripleColumnConfig]
/** 默认激活的列(移动端) */
defaultActiveColumn?: 0 | 1 | 2
/** 抽屉高度类名 */
heightClassName?: string
/** 是否打开(受控) */
open: boolean
/** 打开状态变化回调 */
onOpenChange: (open: boolean) => void
}
/**
* 三栏自适应抽屉组件
*
* 在桌面端显示三栏并排布局,在移动端通过拖拽左右切换栏目
*/
export function TripleColumnAdaptiveDrawer({
trigger,
drawerTitle,
drawerDescription,
columns,
defaultActiveColumn = 1,
heightClassName = 'h-[85vh] md:h-[70vh] 2xl:h-[50vh]',
open,
onOpenChange,
}: TripleColumnAdaptiveDrawerProps) {
const handleOpenChange = (newOpen: boolean) => {
if (newOpen) {
// 使当前拥有焦点的元素通常是用来触发打开这个drawer的控件失去焦点不然控制台会警告焦点在一个要被隐藏于屏幕阅读器的控件上
(document.activeElement as HTMLElement)?.blur();
}
onOpenChange(newOpen)
}
// 转换为 CarouselColumn 格式
const carouselColumns: CarouselColumn[] = columns.map((column) => ({
id: column.id,
title: column.title,
content: column.content,
desktopClassName: 'flex-1 p-4',
mobileClassName: 'p-4',
}))
return (
<Drawer open={open} onOpenChange={handleOpenChange}>
<DrawerTrigger asChild>
{trigger}
</DrawerTrigger>
<DrawerContent className={heightClassName}>
<VisuallyHidden>
<DrawerTitle>{drawerTitle}</DrawerTitle>
<DrawerDescription>{drawerDescription}</DrawerDescription>
</VisuallyHidden>
<CarouselLayout
columns={carouselColumns}
defaultActiveIndex={defaultActiveColumn}
showDesktopDivider={true}
className="w-full h-full"
/>
</DrawerContent>
</Drawer>
)
}