首页 > 解决方案 > 如何在反应表中对齐标题文本?

问题描述

我正在使用 react-table 并在某些列上启用了过滤。问题是我希望没有过滤的列的标题文本与有过滤的列对齐。我该怎么办?标题

另外,是否可以设置过滤文本字段以扩展列的整个宽度?

import React, { useState } from 'react';
import { useSortBy, useTable, useFilters } from 'react-table';
import { Cells, ColumnHeader, DeleteButton, EditButton, TableContainer } from './view-items.styles';

function DefaultColumnFilter({
                                 column: { filterValue, preFilteredRows, setFilter },
                             }) {
    const count = preFilteredRows.length

    return (
        <input
            value={filterValue || ''}
            onChange={e => {
                setFilter(e.target.value || undefined) // Set undefined to remove the filter entirely
            }}
            placeholder={`Search ${count} records...`}
        />
    )
}

function SelectColumnFilter({column: { filterValue, setFilter, preFilteredRows, id }, })
{
    // Calculate the options for filtering
    // using the preFilteredRows
    const options = React.useMemo(() =>
    {
        const options = new Set();
        preFilteredRows.forEach(row =>
        {
            options.add(row.values[id]);
        });
        return [...options.values()];
    }, [id, preFilteredRows]);

    // Render a multi-select box
    return (
        <select
            value={filterValue}
            onChange={e =>
            {
                setFilter(e.target.value || undefined);
            }}
        >
            <option value=''>All</option>
            {options.map((option, i) => (
                <option key={i} value={option}>
                    {option}
                </option>
            ))}
        </select>
    );
}

const ViewItems = ({ collections }) =>
{
    const [data] = useState(React.useMemo(() =>
    {
        let init = new Array(0);

        for (let i = 0; i < collections.length; i++)
        {
            Object.entries(collections[i]).map(([key, value]) =>
            {
                if (Array.isArray(value))
                {
                    for (let j = 0; j < value.length; j++)
                    {
                        value[j].description = collections[i].title + ' ' + value[j].name;
                        value[j].category = collections[i].title;
                        value[j].price = `$${value[j].price}`;
                        value[j].onHand = Math.floor((Math.random() * 99) + 1);
                        init.push(value[j]);
                    }
                }
            });
        }

        return init;
    }, []));

    const handleEdit = (value) =>
    {
        console.log(value);
    };

    const handleDelete = (value) =>
    {
        console.log(value);
    };

    const columns = React.useMemo(
        () => [
            {
                Header: 'ID',
                accessor: 'id',
            },
            {
                Header: 'Name',
                accessor: 'name',
            },
            {
                Header: 'Description',
                accessor: 'description',
            },
            {
                Header: 'Price',
                accessor: 'price',
                disableFilters: true,
                disableSortBy: true,
            },
            {
                Header: 'On Hand',
                accessor: 'onHand',
                disableFilters: true,
                disableSortBy: true,
            },
            {
                Header: 'Category',
                accessor: 'category',
                Filter: SelectColumnFilter,
                filter: 'includes',
            },
            {
                Header: 'Edit',
                //headerStyle: {textAlign: 'right'},
                accessor: '',
                disableFilters: true,
                disableSortBy: true,
                Cell: ({ cell }) => <EditButton onClick={() => handleEdit(cell.row.values)}>Edit</EditButton>,
            },
            {
                Header: 'Delete',
                accessor: '',
                disableFilters: true,
                disableSortBy: true,
                Cell: ({ cell }) => <DeleteButton onClick={() => handleDelete(cell.row.values)}>Delete</DeleteButton>,
            },
        ], [],
    );
    
    return (
        <Table columns={columns} data={data}/>
    )
    
};

function Table({ columns, data })
{
    const filterTypes = React.useMemo(
        () => ({
            // Add a new fuzzyTextFilterFn filter type.
            // Or, override the default text filter to use
            // "startWith"
            text: (rows, id, filterValue) =>
            {
                return rows.filter(row =>
                {
                    const rowValue = row.values[id]
                    return rowValue !== undefined
                        ? String(rowValue)
                            .toLowerCase()
                            .startsWith(String(filterValue).toLowerCase())
                        : true
                })
            },
        }),
        []
    )

    const defaultColumn = React.useMemo(
        () => ({
            // Let's set up our default Filter UI
            Filter: DefaultColumnFilter,
        }),
        []
    )

    const {
        getTableProps,
        getTableBodyProps,
        headerGroups,
        rows,
        prepareRow,
    } = useTable({ columns, data, defaultColumn, filterTypes }, useFilters, useSortBy);

    return (
        <TableContainer>
            <table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
                <thead>
                {headerGroups.map(headerGroup => (
                    <tr {...headerGroup.getHeaderGroupProps()}>
                        {headerGroup.headers.map(column => (
                            <ColumnHeader {...column.getHeaderProps(column.getSortByToggleProps())}>
                                {column.render('Header')}
                                <div>{ column.canFilter ? column.render('Filter') : null}</div>
                                {/*{*/}
                                {/* <span>*/}
                                {/*     {column.isSorted ? column.isSortedDesc ? ' ' : ' ' : ''}*/}
                                {/* </span>*/}
                                {/*}*/}
                            </ColumnHeader>
                        ))}
                    </tr>
                ))}
                </thead>
                <tbody {...getTableBodyProps()}>
                {rows.map(row =>
                {
                    prepareRow(row);
                    return (
                        <tr {...row.getRowProps()}>
                            {row.cells.map(cell =>
                            {
                                return (
                                    <Cells{...cell.getCellProps()}>{cell.render('Cell')}</Cells>
                                );
                            })}
                        </tr>
                    );
                })}
                </tbody>
            </table>
        </TableContainer>
    );
}

export default ViewItems;

标签: cssreactjsreact-table

解决方案


推荐阅读