Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Data Display

Description List

Data Display

Description List React component for Tailwind CSS v4

CountdownDiff Viewer
Live props
Layout
columns2
layout
labelWidth160px
Appearance
variant
size
Behavior
copyable
Content
copyLabel
copiedLabel
emptyValue
title
description
titleAs
State
loading
skeletonCount6
Code
import { DescriptionList } from "@/components/ui/description-list"

<DescriptionList />
  1. Home
  2. Components
  3. Data Display
  4. Description List
Pro

Description List React component for Tailwind CSS v4

v1.0.0·Added in 1.0.0

A React description list for detail pages: key-value grids for clients, invoices and profiles, with copy buttons, skeletons and iOS rows.

Read the details in document order: label above value on phones and in narrow cards, one to three columns once the container is wide enough (it follows its container, not the window). Hover a row with a mouse or Tab into it and a copy button appears next to a copyable value; click it or press Enter and the icon turns into a check while the tooltip says Copied. On a phone the copy buttons are always visible and have a 44px hit area. Tab only stops on real controls (copy buttons, actions, inline edits). While loading, values are skeleton bars that crossfade into the real text. The grouped variant reads like iOS settings: label left, value right, long values move under the label on narrow screens.

Description List is a Pro React component in the React data display components category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add description-list, together with Copy Button, Skeleton, Motion presets and UIProvider and the npm package motion.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add description-list

Description List is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import DescriptionList from @/components/ui/description-list.

import { Pencil } from "lucide-react"
import { Button } from "@/components/ui/button"
import { DescriptionList, type DescriptionListItem } from "@/components/ui/description-list"

const CLIENT: DescriptionListItem[] = [
  { label: "Company", value: "Tech Solutions Inc." },
  { label: "Tax ID", value: "12-3456789", copy: true, mono: true },
  { label: "Registration no.", value: "DE-5512345", mono: true },
  { label: "Address", value: "233 S Wacker Dr, Chicago, IL 60606", span: 2 },
  { label: "IBAN", value: "GB29 NWBK 6016 1331 9268 19", copy: "GB29NWBK60161331926819", mono: true },
  { label: "Balance", value: "$12,480.00" },
]

export function ClientDetails({ loading }: { loading: boolean }) {
  return (
    <DescriptionList
      title="Client details"
      description="Billing details"
      actions={<Button variant="soft" size="sm" leftIcon={<Pencil />}>Edit</Button>}
      items={CLIENT}
      loading={loading}
    />
  )
}

Props

  • items
    DescriptionListItem[]

    { id?, label, value, description?, icon?, copy?: boolean | string, span?: 1 | 2 | 3 | "full", mono?, action?, hidden? }. copy: true copies a string or number value, a string copies that string, false opts out of copyable. span clamps to columns; hidden items are skipped.

  • columnsdefault 2
    1 | 2 | 3

    Columns once the container is at least 32rem (2) or 48rem (3) wide. Always one column below 32rem, so it stacks on phones and in narrow cards.

  • layoutdefault "auto"
    "auto" | "stacked" | "inline"

    stacked: label above value. inline: a label column and a value column (from 24rem of container width, so phones stack). auto: inline when there is one column and the container is at least 40rem wide, stacked otherwise.

  • labelWidthdefault 160
    number

    Width of the label column in px for the inline layout. Never more than 35% of the row.

  • variantdefault "divided"
    "plain" | "divided" | "surface" | "grouped"

    plain: no lines. divided: hairlines between rows, per column. surface: the whole list, header included, on a raised panel. grouped: iOS inset rows on a panel, label left and value right, 44px rows (ignores columns and layout).

  • sizedefault "md"
    "sm" | "md" | "lg"

    Label 12 / 13 / 14px, value 13 / 14 / 15px, row padding 8 / 12 / 16px.

  • copyabledefault false
    boolean

    Every item with a string or number value gets a copy button. Items opt out with copy: false; React element values need copy set to a string.

  • copyLabeldefault "Copy"
    string

    The copy button's tooltip and aria-label, followed by the item label: "Copy CUI".

  • copiedLabeldefault "Copied"
    string

    Tooltip and screen reader announcement after a copy.

  • emptyValuedefault "–"
    ReactNode

    Shown, muted, for null, undefined, false and "" values. Empty values are never copyable.

  • loadingdefault false
    boolean

    Values become skeleton bars (widths vary by row, the same on the server and in the browser) and the <dl> gets aria-busy. With no items, skeletonCount fake rows show. Skeletons crossfade into the values.

  • skeletonCountdefault 6
    number

    Rows to fake while loading before any items exist.

  • titledefault ""
    ReactNode

    The header title. With a title the root becomes a <section> labelled by it.

  • descriptiondefault ""
    ReactNode

    A muted line under the title.

  • titleAsdefault "h3"
    "h2" | "h3" | "h4"

    Heading level of the title, to fit the page outline.

  • actions
    ReactNode

    Buttons at the end of the header, like an Edit button.

  • children
    ReactNode

    Rows built from parts instead of items: DescriptionItem, or DescriptionTerm and DescriptionDetails for full control (see Parts).

  • classNames
    Partial<Record<"header" | "title" | "description" | "actions" | "body" | "grid" | "item" | "term" | "icon" | "details" | "value" | "hint" | "copy" | "action" | "skeleton", string>>

    Extra classes for the inner parts. grid is the <dl>, item the row <div>, term the <dt>, details the <dd>, copy the copy button.

  • className
    string

    Extra classes for the root, merged last.

Parts

  • DescriptionItem

    component

    One row, for lists written as JSX. Takes the same fields as an item (label, value or children, description, icon, copy, span, mono, action, hidden) and reads size, variant and the copy labels from the list. Without a label its children render as they are, so you can compose the term and details yourself.

    • label
      ReactNode

      The term. Leave it out to write DescriptionTerm and DescriptionDetails as children.

    • value
      ReactNode

      The details; children work too.

    • copy
      boolean | string

      A copy button for the value, or for the given string.

    • span
      1 | 2 | 3 | "full"

      Columns the row spans in the grid layout.

    • mono
      boolean

      Monospaced value, for IDs, IBANs and keys.

  • DescriptionTerm

    component

    The <dt> with the label look and an optional icon prop. Use it inside a DescriptionItem without a label.

  • DescriptionDetails

    component

    The <dd> with the value look: muted, end-aligned and tabular in grouped rows, plain text elsewhere.

  • DescriptionListItem

    type

    One entry of items: id, label, value, description, icon, copy, span, mono, action and hidden.

Examples

Invoice summary, grouped

iOS inset rows: label left, value right, a long value moves under its label on a phone.

Inline edit

InlineEdit as the value: click to edit, Enter saves, Escape cancels.

Three columns

An order on a surface panel; three columns from 48rem of container width, the address spans the row.

Loading

Labels stay, values are skeletons that crossfade in after 1.2s. Reload to replay.

Inline profile, small

layout="inline", size="sm", copyable with custom copy labels; stacks below 24rem (phones).

Narrow container

A 280px sidebar card stacks into one column on desktop too; built from DescriptionItem parts.

Dependencies

motioncopy-buttonskeletonmotionui-config

Files

  • components/ui/description-list.tsx

FAQ

Is the React Description List component free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Description List?

Run npx wingo-ui@latest add description-list. It also adds the Wingo UI items it builds on (Copy Button, Skeleton, Motion presets and UIProvider) and the npm package motion. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/description-list.

How does Description List behave on phones?

Read the details in document order: label above value on phones and in narrow cards, one to three columns once the container is wide enough (it follows its container, not the window). On a phone the copy buttons are always visible and have a 44px hit area.

See also

Copy ButtonInline EditCardPage HeaderTable

Used in

Admin Dashboard PageCRM Contact PageCRM Pipeline PageInvoice PageListing Detail PageOrder History PageIntegration Detail Page

More React data display components

Diff ViewerFile ListFolderGanttJSON ViewerLog Viewer
All 23 React data display components

Articles using this component

  • Order History Page Design: List, Detail and Actions

    Build it: screens and apps · Nov 6, 2026 · 9 min read

  • Responsive Table Mobile Layout: Rows to Cards in React

    Mobile UI in React · Oct 9, 2026 · 11 min read

PreviousCountdownNext Diff Viewer

Client details

Billing details and the contact person

Company
Tech Solutions Inc.
Tax ID
12-3456789
Registration no.
DE-5512345
Bank
Chase
Address
233 S Wacker Dr, Suite 2800, Chicago, IL 60606
Bank account
Routing 021000021 · Account 4839 2017 5
Contact person
DBDaniel Brooks
Email
daniel.brooks@techsolutions.com
Phone
+1 (312) 555-0147
Website
–
Balance
$12,480.00

Last invoice: Sep 18, 2026

Owner
Emma Carter
Client since
Mar 14, 2021

Hover a row or Tab to a copy button · it answers “Copied” · Sync refetches with skeletons in place