mui / mui-x

MUI X: Build complex and data-rich applications using a growing list of advanced React components, like the Data Grid, Date and Time Pickers, Charts, and more!
https://mui.com/x/
4.56k stars 1.33k forks source link

[data grid] Base UI support, hook API #1016

Open oliviertassinari opened 3 years ago

oliviertassinari commented 3 years ago

Summary 💡

Provide a hook-only version of the data grid, a.k.a. "headless" version.

This is not to be confused with "unstyled" which is about replacing slots with your own components #10143.

Examples 🌈

import { useDataGrid, pluginA, pluginB } from '@mui/x-data-grid';

function MyApp() {
  const {
    getTableProps,
    getTableBodyProps,
    headers,
    rows,
  } = useDataGrid({ columns, rows }, pluginA, pluginB);

  return (
    <table {...getTableProps()}>
      <thead>
        {headers.map(header => (
          <tr {...header.getHeaderGroupProps()}>
            {header.columns.map(column => (
              <th {...column.getHeaderProps()}>
                {column.render('Header')}
              </th>
            ))}
          </tr>
        ))}
      </thead>
      <tbody {...getTableBodyProps()}>
        {rows.map(row => (
          <tr {...row.getRowProps()}>
            {row.cells.map(cell => (
              <td {...cell.getCellProps()}>
               {cell.render('Cell')}
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  )
}

We might need more than one hook.

Motivation 🔦

The objective is to offer a different tradeoff to the current fully featured component. We already do it with the combo box and pagination components, so we might as well do it more. I'm not entirely convinced yet that such an effort would be worth the cost. However, I think that it could be healthy from an architectural point of view.

Pros:

Cons:

This issue #924 is related to the effort. The solution of one will help the other.

Benchmark

Side note

It could make sense to make all the Pro plan available under this headless API as MIT. It's too early to say if this can work, but if after deeper research, we realize that most of the buy decision is about the pain to style, then it could fly.

joserodolfofreitas commented 2 years ago

Quoting a request from a user interview

Similar to react-table, I would like to use the Data Grid as a headless table library. Right now we are using data grids also for simple tables where we don't need cell logic, if possible, I would like to use a lighter version of the Data Grid, one that is focused only on row logic.

ArmandRedgate commented 3 months ago

Hello. I just want to give you another testimony that this would be really useful. For the record, our support key is 65425.

We pages where we'd like to show several views, e.g. a datagrid, card and list view, and would like to allow users to filter items in a uniform way across views using GridRowModel and the GridFilterPanel (or similar).

I spent some time last night and tried to get this working with undocumented APIs and found that I could not because:

  const [filterLookup, setFilterLookup] = useState<Record<string, boolean>>({});

  const apiRef = useGridApiRef();

  useEffect(() => {
    return apiRef.current.subscribeEvent("filteredRowsSet", () => {
      setFilterLookup(apiRef.current.state.filter.filteredRowsLookup);
    });
  }, [apiRef]);

  const filtered = filterLookup
    ? unfiltered?.filter((item) => filterLookup[item.id])
    : [];

Which means whenever you filter your DataGrid, it also filters your data into filtered, which you can use for your other views.

If you don't have a component to filter with however, it's a bit useless.