DX-react-grid введение в интерактивные таблицы

Если вы сталкивались с созданием интерактивных таблиц для сайта, то знаете на сколько это больно. Формирование такой таблицы состоит из создания хедера с заголовками, и body. И далее привязки сложной логики. Как упростить задачу? Разберёмся в этом видео

Библиотек, которые заточены специально под такие цели много. Я расскажу о react-grid. Будет 4 видео-урока. В этом видео вы увидите как работает библиотека и научитесь создавать простые таблицы.

Ссылка на github урока. Ссылка на документацию dx-react-grid

Пример на видео несколько отличается от кода в github. В данном видео рассказано как пользоваться dx-react-grid на примере material-ui. Рассмотрены компоненты: Table, TableHeaderRow, TableBandHeader, DataProvider

Установка

npm i --save @devexpress/dx-react-core @devexpress/dx-react-grid @devexpress/dx-react-grid-material-ui

Код

// data.js
export const rows = [
    {
        id: 1,
        piceWhitVat: 100,
        priceWhitoutVat: 72,
        VAT: 18,
        name: 'Консервы',
        quantity: 40,
        unit: 'шт',
        finalQuantity: 39
    },
    {
        id: 2,
        piceWhitVat: 200,
        priceWhitoutVat: 144,
        VAT: 18,
        name: 'Ананасы',
        quantity: 10,
        unit: 'банки',
        finalQuantity: 10
    }
]
// index.jsx
import React, { useCallback } from 'react'
import { DataTypeProvider } from '@devexpress/dx-react-grid'
import { Grid, Table, TableHeaderRow, TableBandHeader } from '@devexpress/dx-react-grid-material-ui'
import { rows } from './data'
import './styles.css'

const getRowId = (row) => row.id

const columns = [
    {name: 'name', title: 'наименование'},
    {name: 'piceWhitVat', title: 'цена с ндс'},
    {name: 'priceWhitoutVat', title: 'цена без ндс'},
    {name: 'VAT', title: 'НДС'},
    {name: 'quantity', title: 'заказано'},
    {name: 'finalQuantity', title: 'принято'},

]

const columnBands = [
    { columnName: 'goods', title: 'Товар', children: [
        {
            columnName: 'name'
        },
    ] },
    { columnName: 'price', title: 'Цена', children: [
            {
                columnName: 'piceWhitVat'
            },
            {
                columnName: 'priceWhitoutVat'
            },
            {
                columnName: 'VAT'
            }
        ]  
    },
    {
        columnName: 'count', title: 'количество', children: [
            { columnName: 'quantity' },
            { columnName: 'finalQuantity' },
        ]
    }
]

export const Lesson1 = () => {

    const rowComponent = useCallback((props)=>{
        const { row: {
            quantity, finalQuantity
        } } = props
        const className = quantity !== finalQuantity ? 'discrepancies' : ''
        return <Table.Row {...props} className={className}/>
    }, [])

    return <Grid columns={columns} rows={rows} getRowId={getRowId}>
        <Table
            columnExtensions={[
                { columnName: 'name', wordWrapEnabled: true, width: '300px' }
            ]}
            rowComponent={rowComponent}
        />
        <TableHeaderRow/>
        <TableBandHeader columnBands={columnBands}/>
        <PriceProvider for={['name']}/>
    </Grid>
}


const PriceProvider = (props) => {
    return <DataTypeProvider formatterComponent={(props)=>{
    console.log({ props })
        const { value, row: {
            unit
        } } = props
        return <div className='price'>
            <div>{value}</div>
            <div><span className={'unit'}>ед. изм.</span>{unit}</div>
        </div>
    }} {...props}/>
}
// styles.css
.price{
    display: grid;
    grid-template-columns: auto;
    row-gap: 7px;
} 
.unit{
    color: #e2e2e2;
    display: inline-block;
    margin-right: 5px;
}
.discrepancies{ 
    background: #ff7800db;
}