Components

Base Components

List View

List item component with multiple layout variants and optional background. Use for rows with icon, title, secondary text, and value.

Example

List view renders rows with optional icon, title, secondary info, and value. Use List as a wrapper that takes list view components (e.g. ListItem children). Choose a variant for the layout and set withBackground for the optional rounded background.
Variants
TitleSecondary info
Value
TitleSecondary info
Value
Title
Value
Title
Value
Value
With background
TitleSecondary info
Value
TitleSecondary info
Value
Title
Value
Title
Value
Value

Installation

Install the following dependencies:

npm install class-variance-authority

Create a list-view.tsx file and paste the following code into it.

"use client"import * as React from "react"import { cva, type VariantProps } from "class-variance-authority"import { cn } from "@/lib/utils"const listItemVariants = cva(  "flex w-full min-w-0 gap-3 border-b border-border py-2.5 text-left last:border-b-0",  {    variants: {      variant: {        iconTitleSecondaryValue: "items-start",        titleSecondaryValue: "items-start",        iconTitleValue: "items-center",        titleValue: "items-center",        valueOnly: "items-center",      },      withBackground: {        true: "rounded-lg bg-[#F9F6F1] px-3 dark:bg-muted/50",        false: "",      },    },    defaultVariants: {      variant: "iconTitleSecondaryValue",      withBackground: false,    },  })export interface ListItemProps  extends Omit<React.HTMLAttributes<HTMLDivElement>, "title">,    VariantProps<typeof listItemVariants> {  icon?: React.ReactNode  title?: React.ReactNode  secondary?: React.ReactNode  value?: React.ReactNode  asChild?: boolean}const ListItem = React.forwardRef<HTMLDivElement, ListItemProps>(  (    {      className,      variant = "iconTitleSecondaryValue",      withBackground = false,      icon,      title,      secondary,      value,      children,      ...props    },    ref  ) => {    const showIcon =      variant === "iconTitleSecondaryValue" || variant === "iconTitleValue"    const showTitle =      variant === "iconTitleSecondaryValue" ||      variant === "titleSecondaryValue" ||      variant === "iconTitleValue" ||      variant === "titleValue"    const showSecondary =      variant === "iconTitleSecondaryValue" || variant === "titleSecondaryValue"    const showValue =      variant === "iconTitleSecondaryValue" ||      variant === "titleSecondaryValue" ||      variant === "iconTitleValue" ||      variant === "titleValue" ||      variant === "valueOnly"    const hasMainBlock = showTitle || showSecondary    return (      <div        ref={ref}        data-slot="list-item"        data-variant={variant}        data-with-background={withBackground}        className={cn(listItemVariants({ variant, withBackground }), className)}        {...props}      >        {showIcon && icon != null && (          <span className="flex shrink-0 text-muted-foreground [&>svg]:size-5">            {icon}          </span>        )}        {hasMainBlock && (          <div className="flex min-w-0 flex-1 flex-col gap-0.5">            {showTitle && title != null && (              <span className="truncate text-sm font-medium text-foreground">                {title}              </span>            )}            {showSecondary && secondary != null && (              <span className="truncate text-xs text-muted-foreground">                {secondary}              </span>            )}          </div>        )}        {showValue && value != null && (          <span            className={cn(              "shrink-0 text-sm text-muted-foreground",              hasMainBlock && "text-right"            )}          >            {value}          </span>        )}        {children}      </div>    )  })ListItem.displayName = "ListItem"function ListView({  className,  ...props}: React.HTMLAttributes<HTMLDivElement>) {  return (    <div      data-slot="list-view"      role="list"      className={cn("flex flex-col", className)}      {...props}    />  )}ListView.displayName = "ListView"export interface ListProps extends React.HTMLAttributes<HTMLDivElement> {  /** Optional header content (e.g. title) rendered above the list */  header?: React.ReactNode}const List = React.forwardRef<HTMLDivElement, ListProps>(  ({ className, header, children, ...props }, ref) => {    return (      <div        ref={ref}        data-slot="list"        className={cn("flex flex-col", className)}        {...props}      >        {header != null && (          <div className="mb-2 text-sm font-medium text-foreground">            {header}          </div>        )}        <ListView>{children}</ListView>      </div>    )  })List.displayName = "List"export { List, ListItem, ListView, listItemVariants }

Check the import paths to ensure they match your project setup.

Usage

Use List as the wrapper (optionally with a header) and pass ListItem children. You can also use ListView directly. Set variant and withBackground on each item as needed.
import { List, ListItem } from "@/components/ui/list-view";
import { FileText } from "lucide-react";

<List header="Documents">
  <ListItem
    variant="iconTitleSecondaryValue"
    icon={<FileText />}
    title="Report.pdf"
    secondary="Last edited 2h ago"
    value="12 KB"
  />
  <ListItem
    variant="iconTitleSecondaryValue"
    icon={<FileText />}
    title="Notes.txt"
    secondary="Updated yesterday"
    value="2 KB"
  />
</List>

Variants

VariantShows
iconTitleSecondaryValueIcon, title, secondary, value (default)
titleSecondaryValueTitle, secondary, value
iconTitleValueIcon, title, value
titleValueTitle, value
valueOnlyValue only
Set withBackground to true to add a rounded background (e.g. #F9F6F1 in light mode).

Examples

List wrapper

List wraps list view components and can show an optional header above the items.
Recent files
Report.pdfLast edited 2h ago
12 KB
Notes.txtUpdated yesterday
2 KB
Draft.docxCreated today
24 KB

iconTitleSecondaryValue (full)

TitleSecondary info
Value
Another rowExtra detail
123

titleSecondaryValue

TitleSecondary info
Value
Second itemMore details
Value

iconTitleValue

Title
Value
Another
Value

titleValue

Title
Value
Second
Value

valueOnly

Value
Value

With background (all variants)

TitleSecondary
Value
TitleSecondary
Value
Title
Value
Title
Value
Value

API Reference

List

Wrapper that renders an optional header and a ListView containing its children. Pass ListItem (or other list view components) as children.
PropTypeDescription
headerReact.ReactNodeOptional title/content above the list
classNamestringApplied to the wrapper div

ListItem

iconReactNode
Default: -
titleReactNode
Default: -
secondaryReactNode
Default: -
valueReactNode
Default: -
asChildboolean
Default: -
variant"iconTitleSecondaryValue" | "titleSecondaryValue" | "iconTitleValue" | "titleValue" | "valueOnly" | null
Default: iconTitleSecondaryValue
withBackgroundboolean | null
Default: false
PropTypeDefaultDescription
iconReactNode--
titleReactNode--
secondaryReactNode--
valueReactNode--
asChildboolean--
variant"iconTitleSecondaryValue" | "titleSecondaryValue" | "iconTitleValue" | "titleValue" | "valueOnly" | nulliconTitleSecondaryValue-
withBackgroundboolean | nullfalse-
Exports: List, ListView, ListItem, listItemVariants.

On this page