forked from admin/hair-keeper
93 lines
2.6 KiB
TypeScript
93 lines
2.6 KiB
TypeScript
'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>
|
||
)
|
||
} |