Marketing
Research List
Index of articles with cover, topic and localised date.
pnpm dlx shadcn@latest add @paragon/research-listBrings in@base-ui/reactcn
registry/paragon/components/research-list.tsx
import * as React from "react"
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import { cn } from "cn"
function ResearchList({ className, ...props }: React.ComponentProps<"ul">) {
return (
<ul
data-slot="research-list"
className={cn("flex flex-col border-b", className)}
{...props}
/>
)
}
/**
* One row of the research index: cover, title, topic and date.
* `date` takes a Date or ISO string and is formatted in `locale`.
*/
function ResearchItem({
title,
topic,
date,
locale = "en-GB",
cover,
className,
render,
...props
}: Omit<useRender.ComponentProps<"a">, "title" | "children"> & {
title: React.ReactNode
topic?: React.ReactNode
date?: Date | string
locale?: string
/** Artwork for the 4:3 cover. A sand swatch is shown when omitted. */
cover?: React.ReactNode
}) {
const when = date ? new Date(date) : undefined
const row = useRender({
defaultTagName: "a",
props: mergeProps<"a">(
{
className: cn(
"group/research grid grid-cols-[6rem_1fr] items-center gap-x-5 gap-y-1 border-t py-[1.125rem] outline-none focus-visible:ring-3 focus-visible:ring-ring/40 sm:grid-cols-[9rem_1fr_auto] sm:gap-x-6",
className
),
children: (
<>
<span className="row-span-2 aspect-[4/3] overflow-hidden rounded-[0.625rem] bg-sand sm:row-span-1 [&>*]:size-full [&>img]:object-cover [&>img]:transition-transform [&>img]:duration-700 [&>img]:ease-paragon group-hover/research:[&>img]:scale-[1.04]">
{cover}
</span>
<span className="flex min-w-0 flex-col gap-1">
<span className="text-lg leading-snug font-medium tracking-[-0.01em] text-balance decoration-1 underline-offset-4 group-hover/research:underline">
{title}
</span>
{topic ? <span className="text-[0.90625rem] text-muted-foreground">{topic}</span> : null}
</span>
{when ? (
<time
dateTime={when.toISOString().slice(0, 10)}
className="col-start-2 text-[0.90625rem] text-muted-foreground tabular-nums sm:col-start-auto"
>
{new Intl.DateTimeFormat(locale, { day: "numeric", month: "short", year: "numeric", timeZone: "UTC" }).format(when)}
</time>
) : null}
</>
),
},
props
),
render,
state: { slot: "research-item" },
})
return <li>{row}</li>
}
export { ResearchList, ResearchItem }