A data table for structured tabular content with row selection, controlled sorting, and an opt-in virtualized body.
import { Table } from 'heroui-native-pro' ;
< Table >
< Table.ScrollContainer >
< Table.Content >
< Table.Header >
< Table.Column >...</ Table.Column >
</ Table.Header >
< Table.Body >
< Table.Row >
< Table.Cell >...</ Table.Cell >
</ Table.Row >
</ Table.Body >
</ Table.Content >
</ Table.ScrollContainer >
< Table.Footer >...</ Table.Footer >
</ Table >
Table : Root shell. Owns the visual variant, selection state, and sort descriptor. Cascades disable-all to animated descendants. The table never reorders data itself.
Table.Background : Absolute-fill layer behind the shell. With no children, the active library theme decides the content (glass renders a blur layer). Mounted for the primary variant only; replaceable via the background prop on Table.
Table.ScrollContainer : Horizontal ScrollView so wide tables scroll while the shell and footer keep the available width.
Table.Content : Vertical column hosting the header row and the body. Grows to fill the scroll content width.
Table.Header : Header row hosting Table.Column and optionally Table.SelectAllCell parts. Injects column positions so body cells align with their columns.
Table.Column : Header cell. Declares the column width behavior (width, or flex + minWidth). With allowsSorting, pressing it toggles the sort descriptor and an animated chevron reflects the direction.
Table.Body : Body container. Renders static Table.Row children, an items collection through a render function, or a virtualized FlatList. Shows renderEmptyState when there are no rows.
Table.Row : Body row. Pressing it toggles selection when selectionMode is not "none". disabledKeys and isDisabled block interaction and dim the row.
Table.Cell : Body cell. Resolves its width from the header column at the same position. Plain string/number children are wrapped in a styled Text.
Table.SelectAllCell : Header checkbox cell for selectionMode="multiple" tables. Registers a fixed-width selection column.
Table.SelectionCell : Row checkbox cell bound to the row's selection state. Place it at the same position as Table.SelectAllCell.
Table.Footer : Row below the table content, outside the horizontal scroll area, for load-more actions or summaries.
Compose a header of columns and a body of rows. Wrap the content in Table.ScrollContainer so wide tables can scroll horizontally.
< Table >
< Table.ScrollContainer >
< Table.Content >
< Table.Header >
< Table.Column >Name</ Table.Column >
< Table.Column >Role</ Table.Column >
< Table.Column >Status</ Table.Column >
</ Table.Header >
< Table.Body >
< Table.Row >
< Table.Cell >Ava Thompson</ Table.Cell >
< Table.Cell >Design</ Table.Cell >
< Table.Cell >Active</ Table.Cell >
</ Table.Row >
< Table.Row >
< Table.Cell >Liam Nguyen</ Table.Cell >
< Table.Cell >Engineering</ Table.Cell >
< Table.Cell >Paused</ Table.Cell >
</ Table.Row >
</ Table.Body >
</ Table.Content >
</ Table.ScrollContainer >
</ Table >
Set variant="secondary" for a flat root with a rounded header band and border-separated body rows.
< Table variant = "secondary" >...</ Table >
Sorting is controlled. The table never reorders data itself. Mark columns with allowsSorting, give each an id, and sort your items from sortDescriptor.
const [ sortDescriptor , setSortDescriptor ] = useState < TableSortDescriptor >({
column: 'name' ,
direction: 'ascending' ,
});
const sortedItems = useMemo (() => {
const sorted = [ ... items]. sort (( a , b ) => {
const comparison =
sortDescriptor.column === 'tasks'
? a.tasks - b.tasks
: a.name. localeCompare (b.name);
return sortDescriptor.direction === 'descending' ? - comparison : comparison;
});
return sorted;
}, [items, sortDescriptor]);
< Table sortDescriptor = {sortDescriptor} onSortChange = {setSortDescriptor}>
...
< Table.Header >
< Table.Column id = "name" allowsSorting >
Name
</ Table.Column >
< Table.Column id = "tasks" allowsSorting >
Open tasks
</ Table.Column >
</ Table.Header >
< Table.Body items = {sortedItems}>
{( item ) => (
< Table.Row id = {item.id}>
< Table.Cell >{item.name}</ Table.Cell >
< Table.Cell >{item.tasks}</ Table.Cell >
</ Table.Row >
)}
</ Table.Body >
...
</ Table >;
Enable selectionMode="multiple" and add the checkbox cells. Rows also toggle on press.
< Table
selectionMode = "multiple"
defaultSelectedKeys = {[ '1' ]}
onSelectionChange = {( keys ) => console. log ([ ... keys])}
disabledKeys = {[ '3' ]}
>
...
< Table.Header >
< Table.SelectAllCell />
< Table.Column >Name</ Table.Column >
</ Table.Header >
< Table.Body items = {items}>
{( item ) => (
< Table.Row id = {item.id}>
< Table.SelectionCell />
< Table.Cell >{item.name}</ Table.Cell >
</ Table.Row >
)}
</ Table.Body >
...
</ Table >
Set selectionMode="single". Pressing a row selects it. Checkbox cells are not required.
< Table selectionMode = "single" defaultSelectedKeys = {[ '2' ]}>
...
</ Table >
Columns are flexible (flex: 1) by default. Fixed and minimum widths push wide tables into horizontal scrolling.
< Table.Header >
< Table.Column width = { 220 }>Name</ Table.Column >
< Table.Column minWidth = { 140 }>Role</ Table.Column >
< Table.Column flex = { 2 }>Notes</ Table.Column >
</ Table.Header >
Pass renderEmptyState to show centered content when the body has no rows.
< Table.Body renderEmptyState = {() => < EmptyState >...</ EmptyState >} />
For large collections, render rows through a FlatList. Requires items with the render function form of children and a bounded height on the body.
< Table.Body
virtualized
className = "h-96"
items = {manyItems}
keyExtractor = {( item ) => item.id}
>
{( item ) => (
< Table.Row id = {item.id}>
< Table.Cell >{item.name}</ Table.Cell >
</ Table.Row >
)}
</ Table.Body >
Table.Footer sits outside the horizontal scroll area. Compose load-more actions or summary content inside it.
< Table >
< Table.ScrollContainer >...</ Table.ScrollContainer >
< Table.Footer >...</ Table.Footer >
</ Table >
import { Chip } from 'heroui-native' ;
import { Table } from 'heroui-native-pro' ;
import { View } from 'react-native' ;
const MEMBERS = [
{
id: '1' ,
name: 'Ava Thompson' ,
role: 'Design' ,
status: 'Active' ,
statusColor: 'success' as const ,
},
{
id: '2' ,
name: 'Liam Nguyen' ,
role: 'Engineering' ,
status: 'Paused' ,
statusColor: 'warning' as const ,
},
{
id: '3' ,
name: 'Maya Patel' ,
role: 'Product' ,
status: 'Active' ,
statusColor: 'success' as const ,
},
];
export default function TableExample () {
return (
< View className = "flex-1 px-5 justify-center" >
< Table >
< Table.ScrollContainer >
< Table.Content >
< Table.Header >
< Table.Column flex = { 1.3 }>Name</ Table.Column >
< Table.Column >Role</ Table.Column >
< Table.Column width = { 110 }>Status</ Table.Column >
</ Table.Header >
< Table.Body >
{ MEMBERS . map (( member ) => (
< Table.Row key = {member.id} id = {member.id}>
< Table.Cell >{member.name}</ Table.Cell >
< Table.Cell textProps = {{ numberOfLines: 1 }}>
{member.role}
</ Table.Cell >
< Table.Cell >
< Chip color = {member.statusColor} size = "sm" variant = "soft" >
{member.status}
</ Chip >
</ Table.Cell >
</ Table.Row >
))}
</ Table.Body >
</ Table.Content >
</ Table.ScrollContainer >
</ Table >
</ View >
);
}
prop type default description childrenReact.ReactNode- Compound parts rendered inside the table shell variantTableVariant'primary'Visual variant selectionModeTableSelectionMode'none'Row selection behavior selectedKeysIterable<TableKey>- Controlled selected row keys defaultSelectedKeysIterable<TableKey>- Initially selected row keys (uncontrolled) disabledKeysIterable<TableKey>- Row keys that cannot be selected or pressed disallowEmptySelectionbooleanfalsePrevents deselecting the last selected row sortDescriptorTableSortDescriptor- Controlled sort descriptor defaultSortDescriptorTableSortDescriptor- Initial sort descriptor (uncontrolled) classNamestring- Additional CSS classes for the outer shell backgroundReact.ReactNode- Background layer behind the shell (undefined theme default, node replaces, null removes) onSelectionChange(keys: Set<TableKey>) => void- Called with the new set of selected keys onSortChange(descriptor: TableSortDescriptor) => void- Called with the next descriptor when a sortable column is pressed animationTableRootAnimation- "disable-all" cascades to animated descendants...ViewPropsViewProps- All standard React Native View props are supported
type description 'primary' | 'secondary'primary is a gray shell with the body as an elevated card. secondary is a flat root with a rounded header band
type description string | numberUnique identifier for a row or column
type description 'none' | 'single' | 'multiple'Row selection behavior
prop type description columnTableKeyKey of the column driving the sort directionTableSortDirectionDirection the column is sorted in
type description 'ascending' | 'descending'Direction of an active column sort
Animation configuration for the Table root. Can be:
"disable-all": Disable all animations including children (cascades down through AnimationSettingsProvider)
undefined: Use default animations
Absolute-fill container rendered behind the table shell. With no children, the active library theme decides the default content (e.g. a glass blur layer); pass children to host custom content with the same positioning and clipping.
prop type default description childrenReact.ReactNode- Custom background content; theme decides the default when omitted classNamestring- Additional CSS classes ...ViewPropsViewProps- All standard React Native View props are supported
prop type default description childrenReact.ReactNode- Header and body content (typically Table.Content) classNamestring- Additional CSS classes for the scroll view contentContainerClassNamestring- Additional CSS classes for the scroll content container ...ScrollViewPropsScrollViewProps- All standard React Native ScrollView props are supported
prop type default description childrenReact.ReactNode- Header and body parts classNamestring- Additional CSS classes for the content column ...ViewPropsViewProps- All standard React Native View props are supported
prop type default description childrenReact.ReactNode- Column parts classNamestring- Additional CSS classes for the header row ...ViewPropsViewProps- All standard React Native View props are supported
prop type default description childrenReact.ReactNode- Column label; plain strings are wrapped in a styled Text idTableKeyindex Column key used by the sort descriptor widthnumber- Fixed column width in pixels (wins over flex) minWidthnumber- Minimum column width in pixels (used with flexible columns) flexnumber1Flex grow factor when no fixed width is set allowsSortingbooleanfalsePressing the column toggles sorting classNamestring- Additional CSS classes for the column container classNamesElementSlots<ColumnSlots>- Additional CSS classes for individual slots stylesTableColumnStyles- Inline style overrides for individual slots indicatorReact.ReactNode- Custom sort indicator replacing the default chevron textPropsTextProps- Additional props forwarded to the inner label Text animationTableColumnAnimation- Sort indicator animation configuration (rotation / opacity) isAnimatedStyleActivebooleantrueWhen false, animated styles are not applied to the sort indicator ...PressablePropsPressableProps- All standard React Native Pressable props are supported
slot description containerColumn pressable container labelColumn label text indicatorSort indicator wrapper (animated) separatorTrailing vertical separator between columns
slot type description containerViewStyleStyle for the column pressable container labelTextStyleStyle for the column label text indicatorViewStyleStyle for the sort indicator wrapper separatorViewStyleStyle for the trailing vertical separator
The indicator slot has animated style properties that cannot be set via className: opacity (visibility) and transform (rotate, for the sort direction flip). To customize, use the animation prop. To disable animated styles, set isAnimatedStyleActive={false}.
Animation configuration for the column sort indicator. Can be:
false or "disabled": Disable the sort indicator animation
true or undefined: Use default animations
object: Custom animation configuration
prop type default description rotationAnimationValue- Rotation of the indicator chevron in degrees for [ascending, descending] opacityAnimationValue- Opacity of the indicator for [hidden, visible]
prop type default description value[number, number][0, 180]Rotation values [ascending, descending] in degrees timingConfigWithTimingConfig{ duration: 150 }Animation timing configuration
prop type default description value[number, number][0, 1]Opacity values [hidden, visible] timingConfigWithTimingConfig{ duration: 150 }Animation timing configuration
prop type default description childrenReact.ReactNode | (item: TItem, index: number) => React.ReactElement- Static rows, or a render function when items is provided itemsreadonly TItem[]- Dynamic collection rendered through the render function keyExtractor(item: TItem, index: number) => TableKey- Resolves the row key for an item (required for virtualized select-all) virtualizedbooleanfalseRenders rows through a FlatList; requires items and a bounded height renderEmptyState() => React.ReactNode- Rendered centered inside the body when there are no rows classNamestring- Additional CSS classes for the body container classNamesElementSlots<BodySlots>- Additional CSS classes for individual slots stylesPartial<Record<BodySlots, ViewStyle>>- Inline style overrides for individual slots flatListPropsOmit<FlatListProps<TItem>, 'data' | 'renderItem' | 'keyExtractor'>- Extra props for the virtualized FlatList ...ViewPropsViewProps- All standard React Native View props are supported
slot description containerBody container emptyEmpty state wrapper inside the body
slot type description containerViewStyleStyle for the body container emptyViewStyleStyle for the empty state wrapper
prop type default description childrenReact.ReactNode- Cell parts idTableKeyindex Row key used by selection and disabledKeys isDisabledbooleanfalseDisables the row regardless of disabledKeys classNamestring- Additional CSS classes for the row ...PressablePropsPressableProps- All standard React Native Pressable props are supported
prop type default description childrenReact.ReactNode- Cell content; plain strings are wrapped in a styled Text classNamestring- Additional CSS classes for the cell container classNamesElementSlots<CellSlots>- Additional CSS classes for individual slots stylesTableCellStyles- Inline style overrides for individual slots textPropsTextProps- Additional props forwarded to the inner Text ...ViewPropsViewProps- All standard React Native View props are supported
slot description containerCell container textCell text (only when children are plain strings/numbers)
slot type description containerViewStyleStyle for the cell container textTextStyleStyle for the cell text
prop type default description widthnumber48Fixed width of the selection column in pixels classNamestring- Additional CSS classes for the cell container checkboxPropsTableSelectionCheckboxProps- Additional props forwarded to the select-all checkbox ...ViewPropsViewProps- All standard React Native View props are supported
Props forwarded to the checkbox rendered by Table.SelectAllCell and Table.SelectionCell. Selection state and change handling are owned by the table. Omits isSelected, onSelectedChange, and isDisabled from CheckboxProps.
The table renders the checkboxes at a compact 20pt size with a reduced corner radius. The header select-all checkbox defaults to the primary variant; row checkboxes default to secondary. Override via variant, className, or children.
prop type default description classNamestring- Additional CSS classes for the cell container checkboxPropsTableSelectionCheckboxProps- Additional props forwarded to the row selection checkbox ...ViewPropsViewProps- All standard React Native View props are supported
prop type default description childrenReact.ReactNode- Footer content classNamestring- Additional CSS classes for the footer row ...ViewPropsViewProps- All standard React Native View props are supported