Grid
A responsive grid layout component built for React Native that automatically wraps items to new rows when they exceed the column count. Items can span multiple columns, grow to fill available space, and be reordered using CSS flexbox order.
React Native
Usage
The Grid component automatically creates a responsive layout with the specified number of columns:
import { Grid } from '@hoverinc/design-system-react-native';import { Text } from 'react-native';const App = () => { return ( <Grid columns={2} columnGap={16} rowGap={16}> <Grid.Col> <Text>Item 1</Text> </Grid.Col> <Grid.Col> <Text>Item 2</Text> </Grid.Col> <Grid.Col> <Text>Item 3</Text> </Grid.Col> <Grid.Col> <Text>Item 4</Text> </Grid.Col> </Grid> );};
Column Spanning
Items can span multiple columns using the span
prop:
import { Grid } from '@hoverinc/design-system-react-native';import { Text } from 'react-native';const App = () => { return ( <Grid columns={3}> <Grid.Col> <Text>Item 1</Text> </Grid.Col> <Grid.Col> <Text>Item 2</Text> </Grid.Col> <Grid.Col> <Text>Item 3</Text> </Grid.Col> <Grid.Col span={3}> <Text>Full width item</Text> </Grid.Col> <Grid.Col> <Text>Item 5</Text> </Grid.Col> <Grid.Col span={2}> <Text>Two column item</Text> </Grid.Col> </Grid> );};
Growing Columns
Enable the grow
prop on the Grid to make all columns expand to fill the
remaining space in each row:
import { Grid } from '@hoverinc/design-system-react-native';import { Text } from 'react-native';const App = () => { return ( <Grid columns={3} grow> <Grid.Col> <Text>Item 1</Text> </Grid.Col> <Grid.Col> <Text>Item 2</Text> </Grid.Col> <Grid.Col> <Text>Item 3</Text> </Grid.Col> </Grid> );};
Column Ordering
Use the order
prop to control the visual order of items within their row. It
works exactly as CSS' Flexbox order
does.
import { Grid } from '@hoverinc/design-system-react-native';import { Text } from 'react-native';const App = () => { return ( <Grid columns={3}> <Grid.Col> <Text>First item</Text> </Grid.Col> <Grid.Col> <Text>Second item</Text> </Grid.Col> <Grid.Col order={1}> <Text>Third item, first visually</Text> </Grid.Col> <Grid.Col order={-1} span={3}> <Text>Fourth item, appears first</Text> </Grid.Col> </Grid> );};
Virtual Scrolling
For large datasets, you can enable virtual scrolling using the
shouldUseVirtualList
prop. This uses FlashList under the hood for better
performance:
import { Grid } from '@hoverinc/design-system-react-native';import { Text, View } from 'react-native';const App = () => { // Generate a large dataset const items = Array.from({ length: 100 }, (_, index) => ({ id: index, title: `Item ${index + 1}`, })); return ( <Grid columns={2} shouldUseVirtualList> {items.map(item => ( <Grid.Col key={item.id}> <View style={{ backgroundColor: '#f0f0f0', padding: 16, margin: 4 }}> <Text>{item.title}</Text> </View> </Grid.Col> ))} </Grid> );};
When to use virtual scrolling:
- Large datasets (100+ items)
- Performance is critical
- Memory usage needs to be optimized
- Smooth scrolling is required
Advanced Virtual Scrolling
You can customize the FlashList behavior using the flashListProps
prop. This
gives you full control over the underlying FlashList component:
import { Grid } from '@hoverinc/design-system-react-native';import { Text, View, RefreshControl } from 'react-native';const App = () => { const items = Array.from({ length: 1000 }, (_, index) => ({ id: index, title: `Item ${index + 1}`, })); return ( <Grid columns={2} shouldUseVirtualList flashListProps={{ showsVerticalScrollIndicator: false, onEndReached: () => console.log('Reached end'), onEndReachedThreshold: 0.5, refreshControl: ( <RefreshControl refreshing={false} onRefresh={() => {}} /> ), // Override the default estimatedItemSize if needed estimatedItemSize: 200, // Add custom styling contentContainerStyle: { paddingHorizontal: 16 }, // Handle scroll events onScroll: event => console.log('Scrolling', event.nativeEvent), }} > {items.map(item => ( <Grid.Col key={item.id}> <View style={{ backgroundColor: '#f0f0f0', padding: 16, margin: 4 }}> <Text>{item.title}</Text> </View> </Grid.Col> ))} </Grid> );};
Advanced Example
Here's a more complex example showing various Grid features:
import { Grid } from '@hoverinc/design-system-react-native';import { Text, View } from 'react-native';const App = () => { return ( <Grid columns={4} columnGap="$400" rowGap="$300" grow> <Grid.Col span={2}> <View style={{ backgroundColor: '#e3f2fd', padding: 16 }}> <Text>Header (spans 2 columns)</Text> </View> </Grid.Col> <Grid.Col> <View style={{ backgroundColor: '#f3e5f5', padding: 16 }}> <Text>Sidebar</Text> </View> </Grid.Col> <Grid.Col> <View style={{ backgroundColor: '#e8f5e8', padding: 16 }}> <Text>Widget</Text> </View> </Grid.Col> <Grid.Col span={4}> <View style={{ backgroundColor: '#fff3e0', padding: 16 }}> <Text>Full width content</Text> </View> </Grid.Col> <Grid.Col order={1}> <View style={{ backgroundColor: '#fce4ec', padding: 16 }}> <Text>Ordered item</Text> </View> </Grid.Col> <Grid.Col> <View style={{ backgroundColor: '#e0f2f1', padding: 16 }}> <Text>Regular item</Text> </View> </Grid.Col> </Grid> );};
API
Grid
columns number
Number of columns in the grid. Defaults to 2
.
columnGap string | number
Size of the gap between columns. Accepts design token values (e.g., '$200'
) or
numeric values. Defaults to '$200'
.
rowGap string | number
Size of the gap between rows. Accepts design token values (e.g., '$200'
) or
numeric values. Defaults to '$200'
.
grow boolean
Whether all columns should expand to fill the remaining space in each row.
Defaults to false
.
shouldUseVirtualList boolean
Whether to use FlashList for virtual scrolling instead of regular flexbox
layout. Useful for large datasets (100+ items) to improve performance. Defaults
to false
.
flashListProps FlashListProps
Additional props to pass to the underlying FlashList component when virtual
scrolling is enabled. Allows full control over FlashList behavior including
scroll indicators, estimated item size, refresh control, and more. All FlashList
props are supported except data
and renderItem
which are controlled by the
Grid component.
overflow string
Controls how overflow content is handled. Defaults to 'visible'
.
Grid.Col
span number
Number of columns this item should span. Defaults to 1
.
grow boolean
Whether the column should grow to fill available space. Defaults to false
.
order number
Order value to control the visual order of items within their row (used by Grid
component for sorting). Works like CSS flexbox order.
Notes
- The Grid component automatically wraps items to new rows when they exceed the column count
- Items with
span
values that would exceed the column count will be moved to a new row - The
order
prop works similar to CSS flexbox order - negative values appear first - When
grow
is enabled, all columns will expand to fill the remaining space in each row - The component uses flexbox under the hood for responsive behavior
- Both
columnGap
androwGap
accept design token values (e.g.,'$200'
) or numeric values for spacing between columns and rows respectively - Virtual scrolling (
shouldUseVirtualList
) is disabled by default and should be used for large datasets to improve performance - When virtual scrolling is enabled, the component uses FlashList instead of regular flexbox layout