Files
stu-ai-demo/src/components/common/triple-column-adaptive-drawer.tsx

93 lines
2.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'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>
)
}