Skip to content

React Native Flexible Grid is an advanced grid layout system inspired by CSS Grid, designed to facilitate responsive, customisable, and dynamic grid layouts in React Native applications.

License

Notifications You must be signed in to change notification settings

iNerdStack/react-native-flexible-grid

Repository files navigation

React Native Flexible Grid

CI npm package npm downloads

React Native Flexible Grid is an advanced grid layout system inspired by CSS Grid, designed to facilitate responsive, customizable, and dynamic grid layouts in React Native applications. It supports both responsive and fixed layouts, enabling the creation of intricate designs with minimal effort.

React Native Flexible Grid

🌟 Features

  • Responsive Design: Adapts fluidly to both screen and container sizes, ensuring your content looks perfect on any device. This guarantees that your grid will seamlessly accommodate different resolutions and orientations, making it ideal for responsive mobile applications.
  • Dynamic Item Sizing: Offers great flexibility to define both fixed and dynamic grid item dimensions, enabling a diverse range of layout configurations. Whether you're aiming for a Masonry-style list, arranging items with uneven widths and heights, or replicating complex layouts similar to Instagram Explore and Pinterest.
  • Virtualization Support: Dramatically boosts the performance of grids handling large data by employing virtualization. By rendering only the items in the immediate viewport and a buffer zone, this feature ensures smooth scrolling and responsive interactions.
  • Two-Way Scrolling Support: Facilitates navigation beyond the initial viewport in both horizontal and vertical directions. This advanced scrolling capability enhances user experience by providing fluid access to off-screen content, making it easier to explore large grids without compromising on performance.
  • Customizable: Offers a wide range of customization options, allowing fine-tuning of the grid according to specific requirements. From styling adjustments to functional tweaks.
  • Minimal Dependencies: Built exclusively with React Native components for better integration and ensures broad compatibility while maintaining a minimal footprint.
  • Universal Compatibility: Seamlessly supports Android & iOS and tested extensively with Expo & web.

🎥 Demo

Instagram Explore Example Grid System Demo
Instagram Explore Example Pinterest Example
Grid Board Example
Grid Board Example

📦 Installation

npm install react-native-flexible-grid

or

yarn add react-native-flexible-grid

💡 Usage

1. Flex Grid

FlexGrid is designed for creating highly flexible and dynamic grid layouts, capable of two-way scrolling to accommodate content that extends beyond both the viewport's width and height. By leveraging maxColumnRatioUnits, itemSizeUnit, and smooth scrolling mechanics, FlexGrid facilitates precise control over the grid's arrangement, dimensions, and scrolling behavior. This makes it exceptionally suited for applications requiring a versatile grid system that can display content in both horizontally and vertically overflowed layouts with ease.

Use Cases:

  • Interactive Galleries: Optimal for galleries where users can explore content through both horizontal and vertical navigation.
  • Board Layout: Ideal for creating grid board with documents or media or files in a grid that exceeds the viewport, allowing for comprehensive exploration.
  • Complex Layouts: Perfect for applications demanding intricate grid arrangements that go beyond simple lists, including dashboards or design portfolios.
import { FlexGrid } from 'react-native-flexible-grid';

export default function App() {
  const data = [
    { imageUrl: 'https://picsum.photos/200/300?random=1', widthRatio: 1, heightRatio: 1, text: "Item 1", id: 1 },
    { imageUrl: 'https://picsum.photos/200/300?random=2', widthRatio: 2, heightRatio: 1, text: "Item 2", id: 2 },
    { imageUrl: 'https://picsum.photos/200/300?random=3', widthRatio: 2, heightRatio: 1, text: "Item 3", id: 3 },
  ];

  const renderItem = ({item, index}) => (
      <View style={styles.boxContainer}>
        <Image
          source={{ uri: item.imageUrl }}
          style={styles.box}
          resizeMode="cover"
        />
        <Text style={styles.text}>{item.text}</Text>
      </View>
  );

  return (
    <View style={styles.container}>
      <FlexGrid
        keyExtractor={(item) => item.id.toString()}
        maxColumnRatioUnits={60}
        itemSizeUnit={60}
        data={data}
        virtualizedBufferFactor={2}
        renderItem={renderItem}
        virtualization={true}
        showScrollIndicator={false}
        style={{ flex: 1 }}
      />
    </View>
  );
}

See Examples:

  1. Grid Board Example

2. Responsive Grid

The ResponsiveGrid is designed for optimal responsiveness, dynamically adjusting grid items based on the container's width or a specified width within the component's style properties. Utilizing a combination of maxItemsPerColumn alongside item-specific widthRatio and heightRatio, it efficiently organizes content into a vertically scrollable grid. This component is ideally suited for layouts where vertical scrolling is preferred and where the grid's adaptability to varying container widths or device width is crucial.

Use Cases:

  • Content Feeds: Perfect for vertically scrolling content feeds that require adaptability to different screen sizes.
  • Image Galleries: Ideal for image galleries where images need to be displayed in a responsive, organized or uneven manner.
  • Product Listings: Suitable for e-commerce apps needing to showcase products in a neatly arranged, responsive grid.
import { ResponsiveGrid } from 'react-native-flexible-grid';

export default function App() {
  const data = [
    { imageUrl: 'https://picsum.photos/200/300?random=1', widthRatio: 1, heightRatio: 1, text: "Item 1", id: 1 },
    { imageUrl: 'https://picsum.photos/200/300?random=2', widthRatio: 2, heightRatio: 1, text: "Item 2", id: 2 },
    { imageUrl: 'https://picsum.photos/200/300?random=3', widthRatio: 2, heightRatio: 1, text: "Item 3", id: 3 },
  ];

  const renderItem = ({item, index}) => (
  <View style={styles.boxContainer}>
        <Image
          source={{ uri: item.imageUrl }}
          style={styles.box}
          resizeMode="cover"
        />
      </View>
  );

  return (
    <View style={styles.container}>
      <ResponsiveGrid
        keyExtractor={(item) => item.id.toString()}
        maxItemsPerColumn={3}
        data={data}
        renderItem={renderItem}
        style={{ padding: 5 }}
      />
    </View>
  );
}

See Examples:

  1. Instagram Explore Example
  2. Pinterest Example

⚙️ Props

1. FlexGrid Props

Prop Type Default Required Description
data Array [] true The array of items to be rendered in the grid.
renderItem Function () => null true Defines how each individual item should appear, it allows utilizing the item's properties to construct a custom layout or UI for that item within the grid.
keyExtractor (item, index) => string Function false Defines a function that extracts a unique key for a given item in the list. By default, the keyExtractor uses the item's index in the array as the key. This is crucial for optimizing the rendering and re-rendering of list items by providing a stable identity. The function receives an item from the data array and its index, and should return a unique string. Providing a custom keyExtractor is recommended when the items have a unique identifier other than the index, especially in cases where the list's order might change, or items are dynamically added or removed, to ensure consistent and efficient updates.
maxColumnRatioUnits Number 1 true The value controls the maximum number of ratio units that can be allocated to a single column, either from one item or cumulatively from multiple items that a column can accommodate, this defines the grid layout density and item sizing and positioning within each column of the grid.
itemSizeUnit Number 50 true Defines the base unit size for grid items. The actual displayed size of each item in the grid is calculated by multiplying this unit by the item's widthRatio and heightRatio
virtualization Boolean true false Virtualization significantly optimizes performance by only rendering the items currently visible in the viewport, plus buffer. This reduces the number of components rendered at any given time, leading to improved frame rates and smoother scrolling experiences, especially with large data.

Disabling virtualization results in all items being rendered at once, regardless of their visibility. It can impact performance and responsiveness for larger data. This is only suitable for grids with a small number of items to render.
virtualizedBufferFactor Number 2 false Defines the buffer size for pre-loading items outside the current viewport. The buffer's actual dimensions are determined by multiplying this factor by the containerHeight for vertical scrolling and containerWidth for horizontal scrolling.

A higher buffer factor increases the number of items pre-loaded outside the viewport, contributing to a smoother scrolling experience as more content is ready for immediate display when scrolling. However, setting a large buffer factor can affect overall performance, especially on devices with limited resources, as it increases the number of components rendered off-screen.

While, a lower buffer factor reduces the off-screen component count, optimizing performance and resource usage. This setting is beneficial for large data or resource-constrained environments. However, it may lead to brief moments where content needs to catch up with the user's scroll speed, momentarily displaying blank areas until new items are rendered.

scrollEventInterval Number 200 false Defines the interval, in milliseconds, at which scroll events are processed for the purpose of recalculating visible items and buffer in a virtualized grid. By setting this prop, developers can throttle the frequency of scroll event handling, optimizing performance during rapid scrolling by reducing the computational load associated with updating the list of visible items and buffer.

A lower value results in more frequent updates, offering smoother visual updates of the grid's content at the potential cost of higher computational overhead. While, a higher interval decreases the frequency of updates, potentially improving performance but with less immediate recalculation triggered by scroll actions. This is crucial for fine-tuning the performance and experience of virtualized grid.

showScrollIndicator Boolean true false Controls the visibility of the scroll indicator.
style ViewStyle {} false Accepts a React Native ViewStyle object. This property applies to the outermost container of the component and can be used to set various styling aspects such as fixed width, height, background color, margin, padding, and more.
itemContainerStyle ViewStyle {} false Accepts a React Native ViewStyle object. This applies to the container of each item in the grid layout and can be used to create a gap between each grid item with padding, apply background color, etc.
onHorizontalEndReached () => void undefined false Defines a callback function that is called when the horizontal scroll position reaches the onHorizontalEndReachedThreshold. Useful for loading more data as the user scrolls horizontally.
onHorizontalEndReachedThreshold number 0.5 false Defines the threshold for triggering onHorizontalEndReached. Represented as a fraction of the total width of the scrollable grid, indicating how far from the end the horizontal scroll must be to trigger the event.
onVerticalEndReached () => void undefined false Defines a callback function that is called when the vertical scroll position reaches the onVerticalEndReachedThreshold. Useful for loading more data as the user scrolls vertically.
onVerticalEndReachedThreshold number 0.5 false Defines the threshold for triggering onVerticalEndReached. Represented as a fraction of the total height of the scrollable grid, indicating how far from the end the vertical scroll must be to trigger the event.
autoAdjustItemWidth boolean true false Prevents width overflow by adjusting items with width ratios that exceed available columns in their row & width overlap by adjusting items that would overlap with items extending from previous rows
HeaderComponent React.ComponentType<any> | React.ReactElement | null | undefined null false Accepts a React component or element that will be rendered at the top of the grid, before any grid items are displayed. Suitable for titles, search bar, etc
FooterComponent React.ComponentType<any> | React.ReactElement | null | undefined null false Accepts a React component or element that will be rendered at the bottom of the grid, after all the grid items have been displayed. Suitable for load more buttons, indicator or component


2. ResponsiveGrid Props

Prop Type Default Required Description
data Array [] true The array of items to be rendered in the grid.
renderItem Function () => null true Defines how each individual item should appear, it allows utilizing the item's properties to construct a custom layout or UI for that item within the grid.
keyExtractor (item, index) => string Function false Defines a function that extracts a unique key for a given item in the list. By default, the keyExtractor uses the item's index in the array as the key. This is crucial for optimizing the rendering and re-rendering of list items by providing a stable identity. The function receives an item from the data array and its index, and should return a unique string. Providing a custom keyExtractor is recommended when the items have a unique identifier other than the index, especially in cases where the list's order might change, or items are dynamically added or removed, to ensure consistent and efficient updates.
maxItemsPerColumn Number 3 true Defines the maximum number of items that can be displayed within a single column of the grid. This property is required for ensuring a balanced and visually appealing layout across various screen sizes and orientations, optimizing the use of available space. Suitable for responsive designs, allows for dynamic adjustments based on the container's width, ensuring a consistent and adaptable presentation of content.
itemUnitHeight Number containerWidth / maxItemsPerColumn false Defines the base unit height for items within the grid. This value serves as a foundational measure to determine the actual height of each grid item. The item's final height is calculated by multiplying this base unit height (itemUnitHeight) by the item's heightRatio, allowing for proportional scaling of items based on their content or design requirements. While widthRatio affects the item's width in relation to the column width, itemUnitHeight and heightRatio together define the item's vertical dimension, enabling dynamic grid layouts that adapt seamlessly to varying content sizes.
direction string ltr false Determines the direction for arranging grid items in the layout: left-to-right (ltr) or right-to-left (rtl).
virtualization Boolean true false Virtualization significantly optimizes performance by only rendering the items currently visible in the viewport, plus buffer. This reduces the number of components rendered at any given time, leading to improved frame rates and smoother scrolling experiences, especially with large data.

Disabling virtualization results in all items being rendered at once, regardless of their visibility. It can impact performance and responsiveness for larger data. This is only suitable for grids with a small number of items to render.
virtualizedBufferFactor Number 2 false Defines the buffer size for pre-loading items outside the current viewport. The buffer's actual dimensions are determined by multiplying this factor by the containerHeight for vertical scrolling

A higher buffer factor increases the number of items pre-loaded outside the viewport, contributing to a smoother scrolling experience as more content is ready for immediate display when scrolling. However, setting a large buffer factor can affect overall performance, especially on devices with limited resources, as it increases the number of components rendered off-screen.

While, a lower buffer factor reduces the off-screen component count, optimizing performance and resource usage. This setting is beneficial for large data or resource-constrained environments. However, it may lead to brief moments where content needs to catch up with the user's scroll speed, momentarily displaying blank areas until new items are rendered.

scrollEventInterval Number 200 false Defines the interval, in milliseconds, at which scroll events are processed for the purpose of recalculating visible items and buffer in a virtualized grid. By setting this prop, developers can throttle the frequency of scroll event handling, optimizing performance during rapid scrolling by reducing the computational load associated with updating the list of visible items and buffer.

A lower value results in more frequent updates, offering smoother visual updates of the grid's content at the potential cost of higher computational overhead. While, a higher interval decreases the frequency of updates, potentially improving performance but with less immediate recalculation triggered by scroll actions. This is crucial for fine-tuning the performance and experience of virtualized grid.

showScrollIndicator Boolean true false Controls the visibility of the scroll indicator.
style ViewStyle {} false Accepts a React Native ViewStyle object. This property applies to the outermost container of the component and can be used to set various styling aspects such as fixed width, height, background color, margin, padding, and more.
itemContainerStyle ViewStyle {} false Accepts a React Native ViewStyle object. This applies to the container of each item in the grid layout and can be used to create a gap between each grid item with padding, apply background color, etc.
onEndReached () => void undefined false Defines a callback function that is triggered when the scroll reaches near the end of the scrollable grid. Useful for loading more data as the user scrolls horizontally
onEndReachedThreshold number 0.5 false Defines the distance from the end of the content at which onEndReached should be triggered, expressed as a proportion of the total content length. For example, a value of 0.1 triggers the callback when the user has scrolled to within 10% of the end of the content.
autoAdjustItemWidth boolean true false Prevents width overflow by adjusting items with width ratios that exceed available columns in their row & width overlap by adjusting items that would overlap with items extending from previous rows
HeaderComponent React.ComponentType<any> | React.ReactElement | null | undefined null false Accepts a React component or element that will be rendered at the top of the grid, before any grid items are displayed. Suitable for titles, search bar, etc
FooterComponent React.ComponentType<any> | React.ReactElement | null | undefined null false Accepts a React component or element that will be rendered at the bottom of the grid, after all the grid items have been displayed. Suitable for load more buttons, indicator or component

🚀 Vision and Roadmap

Our mission is not just to provide a flexible layout solution but to improve grid systems and layout flexibility in React Native. By continuously refining our algorithm and incorporating feedback, we aim to bring CSS Grid-like capabilities to the React Native ecosystem, fostering creativity and pushing the boundaries of what's possible in app design with React Native.

🤝 Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

📄 License

MIT


About

React Native Flexible Grid is an advanced grid layout system inspired by CSS Grid, designed to facilitate responsive, customisable, and dynamic grid layouts in React Native applications.

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

 

Packages

No packages published

Contributors 3

  •  
  •  
  •