ListItem

Display rows with titles, subtitles, and icons

ListItem builds consistent rows from titles, subtitles, icons, images, and shared size or theme variants.

Features

  • One size prop for all styles

  • Icons before or after content

  • Themes, animations, and Group support

  • Style variants, including outlined

  • Child color, size, and variant through Apply

Installation

ListItem is already installed in tamagui:

import { ListItem } from 'tamagui'

@tamagui/list-item holds the unstyled half: useListItem and the parts, with no styled ListItem of its own. Import from it when you are building your own list item rather than using ours; see Build your own.

Usage

Basic usage involves providing children or using the title and subTitle props.

import { ListItem, Separator, YGroup } from 'tamagui'
import { ChevronRight } from './components/icons' // Example icon (generate your own, see Lucide Icons)
export default () => (
<YGroup self="center" borderWidth={1} borderColor="border-color" rounded="4" width={240} size="md" >
<YGroup.Item>
<ListItem title="Star" icon={ChevronRight} />
</YGroup.Item>
<YGroup.Item>
<ListItem title="Moon" subTitle="Subtitle for Moon" iconAfter={ChevronRight} />
</YGroup.Item>
<YGroup.Item>
<ListItem>Custom children content</ListItem>
</YGroup.Item>
</YGroup>
)

Sizing

The size prop adjusts padding, minimum height, and the default size for the text and icons inside. It accepts theme size tokens (e.g., "3", "4").

import { ListItem } from 'tamagui'
export default () => <ListItem size="lg" title="Large List Item" />

Title and subTitle

Use the title and subTitle props for a structured layout. These props accept ReactNode, so you can pass strings or more complex JSX.

  • If title or subTitle is provided, children render inside the main text area, under the title and subtitle.
  • Strings render through ListItem.Title and ListItem.Subtitle. Anything else renders as you passed it, so you can style it yourself.
import { ListItem, Avatar } from 'tamagui'
import { User } from './components/icons'
export default () => (
<ListItem icon={ <Avatar circular size="sm"> <Avatar.Image src="/placeholder.png" /> <Avatar.Fallback backgroundColor="background-focus" /> </Avatar> } title="User Profile" subTitle="View and edit your profile details." iconAfter={User} size="md" />
)

Icon theming

Icons can be passed to icon (before content) or iconAfter (after content).

  • Automatic sizing and spacing: icons are sized from the ListItem’s size. Override with iconSize. Spacing comes from the frame gap, so it applies between all direct frame children, not only around icons.
  • Scaling: scaleIcon (number, default 1) adjusts the icon size relative to its base size.
  • Component props: a component passed as an icon receives size (the calculated pixel size) and color.
import { ListItem } from 'tamagui'
import { Star, Settings } from './components/icons'
export default () => (
<>
<ListItem icon={Star} title="Default Icon Size" size="md" />
<ListItem icon={Settings} iconSize="2" title="Explicit Icon Size" subTitle="iconSize='2'" size="lg" />
<ListItem icon={Star} scaleIcon={1.5} title="Scaled Icon" subTitle="scaleIcon={1.5}" size="md" />
</>
)

Variant

ListItem supports a variant prop for different visual styles:

import { ListItem } from 'tamagui'
export default () => <ListItem variant="outlined" title="Outlined Style" />

Currently supports outlined (transparent background with border).

Apply (context)

ListItem.Apply is the styled context every part reads. Use it to pass color, size, and variant to a group of list items at once:

import { ListItem, YGroup } from 'tamagui'
import { Trash } from './components/icons'
export default () => (
<YGroup>
<ListItem.Apply color="red-600">
<YGroup.Item>
<ListItem icon={Trash} title="Delete item" />
</YGroup.Item>
<YGroup.Item>
<ListItem icon={Trash} title="Remove all" />
</YGroup.Item>
</ListItem.Apply>
</YGroup>
)

A ListItem republishes whichever of these it was passed directly, so its own icons and text pick them up without any wiring.

Build your own

@tamagui/list-item exports the behavior and the parts separately, so you can put your own skin on them. useListItem themes the icon props and assembles title, subtitle, and children into the frame’s child; everything else is yours. This is exactly how tamagui’s own ListItem is built:

import {
createStyledHOC,
ListItemContext,
ListItemFrame as ListItemBehaviorFrame,
type ListItemIconProps,
ListItemSubtitle,
ListItemText,
ListItemTitle,
styled,
useListItem,
withStaticProperties,
} from '@tamagui/ui'
import { useGetThemedIcon } from '@tamagui/helpers-tamagui'
const ListItemFrame = styled(ListItemBehaviorFrame, {
context: ListItemContext,
backgroundColor: 'background hover:background-hover',
borderColor: 'border-color',
color: 'color',
})
// the icon px is yours to decide; the behavior package only publishes color
const ListItemIcon = ({ children, size = 16 }: ListItemIconProps) => {
const { color } = ListItemContext.useStyledContext()
return useGetThemedIcon({ size, color })(children)
}
const ListItemComponent = createStyledHOC(ListItemFrame, function ListItem(props, ref) {
const { props: listItemProps } = useListItem(props)
return <ListItemFrame ref={ref} {...listItemProps} />
})
export const ListItem = withStaticProperties(ListItemComponent, {
Apply: ListItemContext.Provider,
Frame: ListItemFrame,
Icon: ListItemIcon,
Subtitle: ListItemSubtitle,
Text: ListItemText,
Title: ListItemTitle,
})

Because the frame declares ListItemContext, passing size, color, or variant to it is what publishes them to the text and icons below. There is no context to assemble by hand.

API reference

ListItem

ListItem extends View, inheriting all the Tamagui standard props, plus:

Props

  • title

    React.ReactNode

    Main text content of the list item. A string renders through `ListItem.Title`.

  • subTitle

    React.ReactNode

    Secondary text content, rendered below the title. A string renders through `ListItem.Subtitle`.

  • size

    'xs' | 'sm' | 'md' | 'lg' | 'xl'

    A named size ("xs" to "xl", default "md") is a rung in the sizing ladder: padding, font size, and icon size. Published to the parts through the ListItem context. Subtitles render one step below the title.

  • color

    ColorTokens | string

    Color token or CSS color inherited by `ListItem.Icon` children and the icon props.

  • variant

    'outlined'

    Visual variant style. Currently supports "outlined" (transparent background with border).

  • icon

    JSX.Element | React.ComponentType<{ size?: number; color?: any }>

    Icon element or component displayed before the main content. Receives `size` and `color` if a component.

  • iconAfter

    JSX.Element | React.ComponentType<{ size?: number; color?: any }>

    Icon element or component displayed after the main content. Receives `size` and `color` if a component.

  • iconSize

    number | string

    Explicitly set the icon size, either in pixels or as a sizing-ladder name, overriding the one derived from `size`.

  • scaleIcon

    number

    Scale factor for the icon (default: 1). Applied after `iconSize` or the default size calculation.

  • disabled

    boolean

    If true, reduces opacity and disables pointer events.

  • // Styling Text

    ---

    Text style props are not forwarded from the frame. Style `ListItem.Title`, `ListItem.Subtitle`, or `ListItem.Text` directly, or pass JSX to `title` and `subTitle`.

  • ListItem.Apply

    The styled context provider. Passes color, size, and variant to every ListItem and ListItem part beneath it.

    Props

  • color

    ColorTokens | string

    Color token to pass to icons in children ListItems.

  • size

    'xs' | 'sm' | 'md' | 'lg' | 'xl'

    Named size to apply to children ListItems.

  • variant

    'outlined'

    Variant to apply to children ListItems.

  • ListItem.Frame

    The base View for the ListItem. Renders as li on web with role="listitem".

    ListItem.Text

    Wraps children when title and subTitle are not used. Extends SizableText.

    ListItem.Title

    Renders a string title. Extends SizableText.

    ListItem.Subtitle

    Renders a string subTitle. Extends SizableText. Its font size is one step smaller than the ListItem’s size.

    ListItem.Icon

    Sizes and colors an icon from the surrounding ListItem context.

    Props

  • size

    'xs' | 'sm' | 'md' | 'lg' | 'xl' | number

    Overrides the size taken from context.

  • scaleIcon

    number

    Scale factor applied to the resolved size (default: 1).

  • useListItem

    Themes the icon and iconAfter props and assembles title, subTitle, and children into a single child. Returns the props to spread onto a frame, with the ones it consumed removed and everything else untouched.

    const { props } = useListItem(props)