Menu

Change language

GitHub repo

List

listui

List and Item row primitives with List, ListItem, ListItemMedia, ListItemContent, ListItemTitle, ListItemDescription, ListItemActions, and ListSubheader for structured rows, settings lists, and feeds.

Installation

$npx shadcn@latest add https://uipkge.dev/r/react/list.json
Named registry:npx shadcn@latest add @uipkge-react/listInstalls to:components/ui/list/

Examples

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
as'ul' | 'ol' | 'div'—optional

Files installed (2)

  • components/ui/list/list.tsx5.1 kB
    import * as React from 'react'
    import { cn } from '@/lib/utils'
    
    export interface ListProps extends React.HTMLAttributes<HTMLElement> {
      as?: 'ul' | 'ol' | 'div'
    }
    
    const List = React.forwardRef<HTMLElement, ListProps>(({ as: Comp = 'ul', className, children, ...props }, ref) => (
      <Comp ref={ref as never} data-uipkge="" data-slot="list" className={cn('list-none space-y-1', className)} {...props}>
        {children}
      </Comp>
    ))
    List.displayName = 'List'
    
    export interface ListItemProps extends React.HTMLAttributes<HTMLElement> {
      as?: 'li' | 'div' | 'a'
      active?: boolean
      disabled?: boolean
      href?: string
    }
    
    const ListItem = React.forwardRef<HTMLElement, ListItemProps>(
      ({ as: Comp = 'li', active, disabled, className, children, onClick, href, ...props }, ref) => {
        // Only show pointer/hover affordances when the item is actually interactive.
        const isInteractive = !disabled && (Comp === 'a' || href != null || typeof onClick === 'function')
    
        return (
          <Comp
            ref={ref as never}
            {...props}
            data-uipkge=""
            data-slot="list-item"
            data-active={active ? '' : undefined}
            data-disabled={disabled ? '' : undefined}
            aria-disabled={disabled ? 'true' : undefined}
            aria-current={active ? 'true' : undefined}
            tabIndex={disabled ? -1 : undefined}
            href={Comp === 'a' && !disabled ? href : undefined}
            className={cn(
              'rounded-md px-2 py-1.5 text-sm transition-colors duration-200 select-none focus-visible:outline-none',
              'has-[>[data-slot=list-item-content]]:flex has-[>[data-slot=list-item-content]]:items-center has-[>[data-slot=list-item-content]]:gap-3',
              isInteractive && 'hover:bg-accent focus-visible:bg-accent cursor-pointer',
              active && 'bg-accent text-accent-foreground',
              disabled && 'pointer-events-none cursor-not-allowed opacity-50',
              className,
            )}
            onClick={
              disabled
                ? (e: React.MouseEvent) => {
                    e.preventDefault()
                    e.stopPropagation
                  }
                : onClick
            }
          >
            {children}
          </Comp>
        )
      },
    )
    ListItem.displayName = 'ListItem'
    
    export interface ListItemMediaProps extends React.HTMLAttributes<HTMLDivElement> {}
    
    const ListItemMedia = React.forwardRef<HTMLDivElement, ListItemMediaProps>(({ className, children, ...props }, ref) => (
      <div
        ref={ref}
        data-uipkge=""
        data-slot="list-item-media"
        className={cn('flex shrink-0 items-center justify-center self-center', className)}
        {...props}
      >
        {children}
      </div>
    ))
    ListItemMedia.displayName = 'ListItemMedia'
    
    export interface ListItemContentProps extends React.HTMLAttributes<HTMLDivElement> {}
    
    const ListItemContent = React.forwardRef<HTMLDivElement, ListItemContentProps>(
      ({ className, children, ...props }, ref) => (
        <div
          ref={ref}
          data-uipkge=""
          data-slot="list-item-content"
          className={cn('flex min-w-0 flex-1 flex-col gap-0.5 self-center', className)}
          {...props}
        >
          {children}
        </div>
      ),
    )
    ListItemContent.displayName = 'ListItemContent'
    
    export interface ListItemTitleProps extends React.HTMLAttributes<HTMLDivElement> {}
    
    const ListItemTitle = React.forwardRef<HTMLDivElement, ListItemTitleProps>(({ className, children, ...props }, ref) => (
      <div
        ref={ref}
        data-uipkge=""
        data-slot="list-item-title"
        className={cn('text-foreground truncate text-sm leading-none font-medium', className)}
        {...props}
      >
        {children}
      </div>
    ))
    ListItemTitle.displayName = 'ListItemTitle'
    
    export interface ListItemDescriptionProps extends React.HTMLAttributes<HTMLDivElement> {}
    
    const ListItemDescription = React.forwardRef<HTMLDivElement, ListItemDescriptionProps>(
      ({ className, children, ...props }, ref) => (
        <div
          ref={ref}
          data-uipkge=""
          data-slot="list-item-description"
          className={cn('text-muted-foreground line-clamp-1 text-xs', className)}
          {...props}
        >
          {children}
        </div>
      ),
    )
    ListItemDescription.displayName = 'ListItemDescription'
    
    export interface ListItemActionsProps extends React.HTMLAttributes<HTMLDivElement> {}
    
    const ListItemActions = React.forwardRef<HTMLDivElement, ListItemActionsProps>(
      ({ className, children, ...props }, ref) => (
        <div
          ref={ref}
          data-uipkge=""
          data-slot="list-item-actions"
          className={cn('text-muted-foreground flex shrink-0 items-center gap-1.5 self-center', className)}
          {...props}
        >
          {children}
        </div>
      ),
    )
    ListItemActions.displayName = 'ListItemActions'
    
    export interface ListSubheaderProps extends React.HTMLAttributes<HTMLDivElement> {}
    
    const ListSubheader = React.forwardRef<HTMLDivElement, ListSubheaderProps>(({ className, children, ...props }, ref) => (
      <div
        ref={ref}
        data-uipkge=""
        data-slot="list-subheader"
        className={cn('text-muted-foreground px-2 py-1 text-xs font-medium tracking-wider uppercase', className)}
        {...props}
      >
        {children}
      </div>
    ))
    ListSubheader.displayName = 'ListSubheader'
    
    export {
      List,
      ListItem,
      ListItemMedia,
      ListItemContent,
      ListItemTitle,
      ListItemDescription,
      ListItemActions,
      ListSubheader,
    }
    
  • components/ui/list/index.ts0.4 kB

Raw manifest:https://uipkge.dev/r/react/list.json