import { Meta } from '@storybook/addon-docs/blocks'
import { Warning } from '../../../docs/helpers'

<Meta title="pv-grid/Components/Grid/Rows" />

# Rows

## Simple Usage

The most basic way to provide data to the Grid is via an array of objects. The only
requirement is that the objects have an `id` property that has a `string` id.

```tsx
type User = {
    id: string
    name: string
    admin?: boolean
}

const rows: User[] = [
    { id: '123', name: 'Admin', admin: true },
    { id: '234', name: 'User' },
]

return <Grid columns={[]} rows={rows} />
```

## Advanced Usage

If you would like to implement lazy loading, or if you already have your content in a redux store following their recommendations for [normalized state](https://redux.js.org/usage/structuring-reducers/normalizing-state-shape) then you may want to use this approach.

When paired with an object, the `ids` array must contain strings, and the data objects must also have a matching `id` property that is a `string`. If you have `id` of type `number`, you'll want to use the [Map approach](#map) shown below.

### Object

```tsx
type User = {
    id: string
    name: string
    admin?: boolean
}

const ids = ['234', '123', 'not-loaded-3']
const data: Record<string, User> = {
    123: { id: '123', name: 'Admin', admin: true },
    234: { id: '234', name: 'User' },
    /* Since 'not-loaded-3' is missing, it will render a row but no content. This will
    most likely result in a loading state in the future iteration */
}

return <Grid columns={[]} rows={{ ids, data }} />
```

### Map

Map has a number of speed benefits over an `Object`, but is not often used with Redux due to it not being serializable by default. It can also be used with `id: number` records. If you are able to use `Map`, you may see some subtle speed improvements.

```tsx
type User = {
    id: string
    name: string
    admin?: boolean
}

const ids = ['234', '123', 'not-loaded-3']
const data: Map<string, User> = new Map([
    ['123', { id: '123', name: 'Admin', admin: true }],
    ['234', { id: '234', name: 'User' }],
    /* Since 'not-loaded-3' is missing, it will render a row but no content. This will
    most likely result in a loading state in the future iteration */
])

return <Grid columns={[]} rows={{ ids, data }} />
```

### `fetch` method

If along with your `ids` and `data` you provide a `fetch` method, you can fine tune an approach
to lazy loading data. This method will be frequently called by the Grid with a start and end index
of the rows currently in view. In the case where fewer rows of data are provided than fit in the view,
the upper index will reflex the total number of rows visible in the view.

Progressive loading is an advanced technique with a number of pitfalls. Please learning more by reading
our [Progressive loading guides](/docs/pv-grid-guides-6-progressive-loading--docs).

<Warning>
    **This function will be called a lot!** In addition to using a throttle or
    debounce strategy, your code should be smart about not re-loading content
    that is already loaded.
</Warning>

```tsx
const ids = ['234', '123', 'not-loaded-3']
const data: User[] = {
    123: { id: '123', name: 'Admin', admin: true },
    234: { id: '234', name: 'User' },
}
const fetch = (indexes: [fromIndex: number, toIndex: number]) => {
    // Code that will see that that index 3 is missing
    // and will fetch the code
}

return <Grid columns={[]} rows={{ ids, data, fetch }} />
```
