import * as React from "react"
import { ChevronRightIcon } from "lucide-react"
import { cn } from "@/lib/utils"
export type ListItem = {
key: string
title: React.ReactNode
description?: React.ReactNode
avatar?: React.ReactNode
extra?: React.ReactNode
href?: string
disabled?: boolean
onClick?: () => void
}
export type ListProps = React.ComponentProps<"div"> & {
items?: ListItem[]
bordered?: boolean
split?: boolean
size?: "sm" | "md" | "lg"
renderItem?: (item: ListItem, index: number) => React.ReactNode
}
const itemPadding = {
sm: "px-3 py-2",
md: "px-4 py-3",
lg: "px-5 py-4",
}
function List({ items, bordered = true, split = true, size = "md", renderItem, className, children, ...props }: ListProps) {
return (
{items?.map((item, index) => renderItem?.(item, index) ?? )}
{children}
)
}
export type ListRowProps = React.ComponentProps<"div"> & {
item: ListItem
split?: boolean
size?: "sm" | "md" | "lg"
}
function ListRow({ item, split = true, size = "md", className, ...props }: ListRowProps) {
const clickable = Boolean(item.href || item.onClick)
const content = (
<>
{item.avatar && {item.avatar}
}
{item.title}
{item.description &&
{item.description}
}
{item.extra && {item.extra}
}
{clickable && }
>
)
const rowClassName = cn(
"flex items-center gap-3 bg-card transition-colors",
itemPadding[size],
split && "border-b last:border-b-0",
clickable && !item.disabled && "cursor-pointer hover:bg-muted/50",
item.disabled && "pointer-events-none opacity-55",
className
)
if (item.href) {
return (
)}
>
{content}
)
}
return (
)}
>
{content}
)
}
export { List, ListRow }