{"id":18868286,"url":"https://github.com/buuntu/react-final-table","last_synced_at":"2025-04-14T14:31:47.773Z","repository":{"id":42737760,"uuid":"282511874","full_name":"Buuntu/react-final-table","owner":"Buuntu","description":"React hooks for headless table components","archived":false,"fork":false,"pushed_at":"2023-03-05T07:53:59.000Z","size":4054,"stargazers_count":33,"open_issues_count":13,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-10T09:20:56.281Z","etag":null,"topics":["headless","react","reacthooks","table","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Buuntu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-25T19:31:11.000Z","updated_at":"2025-03-16T05:04:32.000Z","dependencies_parsed_at":"2024-06-21T14:22:44.846Z","dependency_job_id":"07eb70bc-7716-422a-b53c-747602055dfc","html_url":"https://github.com/Buuntu/react-final-table","commit_stats":{"total_commits":55,"total_committers":6,"mean_commits":9.166666666666666,"dds":0.6181818181818182,"last_synced_commit":"f6c9314217f03dae68f4051c8666fd69a2b1623b"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buuntu%2Freact-final-table","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buuntu%2Freact-final-table/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buuntu%2Freact-final-table/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Buuntu%2Freact-final-table/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Buuntu","download_url":"https://codeload.github.com/Buuntu/react-final-table/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248897213,"owners_count":21179557,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["headless","react","reacthooks","table","typescript"],"created_at":"2024-11-08T05:13:20.145Z","updated_at":"2025-04-14T14:31:47.133Z","avatar_url":"https://github.com/Buuntu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React Final Table \u003c!-- omit in toc --\u003e\n\n![CI](https://github.com/Buuntu/react-final-table/workflows/tests/badge.svg)\n[![License:\nMIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)\n[![codecov](https://codecov.io/gh/Buuntu/react-final-table/branch/master/graph/badge.svg)](https://codecov.io/gh/Buuntu/react-final-table)\n![minzipped-size](https://img.shields.io/bundlephobia/minzip/react-final-table)\n![release](https://img.shields.io/npm/v/react-final-table)\n[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)\n\nA [headless UI component\nlibray](https://www.merrickchristensen.com/articles/headless-user-interface-components/)\nfor managing complex table state in React.\n\nInspired by [react-table](https://github.com/tannerlinsley/react-table) but with\nTypescript support built in and a simpler API.\n\n## Features\n\n- Type safe\n- Global row filtering\n- Row selection\n- Custom column rendering\n- Column sorting\n- Data memoization for performance\n- **Zero** dependencies\n\n## Table of Contents\n\n- [Motivation](#motivation)\n- [Install](#install)\n- [Demos](#demos)\n  - [CodeSandbox Demo](#codesandbox-demo)\n  - [Material UI Demo](#material-ui-demo)\n- [`useTable`](#usetable)\n- [Examples](#examples)\n  - [Basic example](#basic-example)\n  - [Searching](#searching)\n  - [Row Selection](#row-selection)\n  - [Pagination](#pagination)\n- [Performance](#performance)\n- [Contributing](#contributing)\n\n## Motivation\n\nWhile there is an abundance of table libraries out there to help with sorting,\nfiltering, pagination, and more, most are opinionated about the user interface.\nOpinionated UIs can seem nice at first, but they quickly become limiting. To\nembrace the Unix philosphy of separation of concerns, the interface should be\nseparate from the engine (from [The Art of Unix\nProgramming](https://www.goodreads.com/book/show/104745.The_Art_of_UNIX_Programming)).\n\nThis is a minimal, type-safe, headless UI component library that you can plugin\nto whatever frontend you're using, as long as you're using React 16 and\n[Hooks](https://reactjs.org/docs/hooks-intro.html). You are then free to style\nyour table any way you want while using **React Final Table** to manage complex\nstate changes.\n\n## Install\n\n```bash\nnpm install react-final-table\n```\n\n## Demos\n\n### [Basic Demo](https://githubbox.com/Buuntu/react-final-table/tree/master/examples/basic)\n\n### [Material UI Demo](https://githubbox.com/Buuntu/react-final-table/tree/master/examples/material-ui)\n\n## `useTable`\n\nThis is the main hook exposed by the library and should be your entrypoint for\nany table functionality. Only `columns` and `rows` are required as arguments:\n\n```jsx\nconst { headers, rows } = useTable(columns, rows);\n```\n\n1. `columns`: The first argument is an array of columns of type ColumnType. Only\n   the name of each column is required. Each column has the following type\n   signature:\n\n```typescript\ntype ColumnType\u003cT\u003e = {\n  name: string;\n  label?: string;\n  hidden?: boolean;\n  sort?: ((a: RowType\u003cT\u003e, b: RowType\u003cT\u003e) =\u003e number) | undefined;\n  render?: ({ value, row }: { value: any; row: T }) =\u003e React.ReactNode;\n  headerRender?: ({ label }: { label: string }) =\u003e React.ReactNode;\n};\n```\n\n2. `rows`: Rows is the second argument to useTable and can be an array of any\n   _object_ type.\n\n## Examples\n\n### Basic example\n\n```tsx\nimport { useTable } from 'react-final-table';\n\nconst columns = [\n  {\n    name: 'firstName',\n    label: 'First Name',\n    render: ({ value }) =\u003e \u003ch1\u003e{value}\u003c/h1\u003e,\n  },\n  {\n    name: 'lastName',\n    label: 'Last Name',\n  },\n];\n\nconst data = [\n  {\n    firstName: 'Frodo',\n    lastName: 'Baggins',\n  },\n  {\n    firstName: 'Samwise',\n    lastName: 'Gamgee',\n  },\n];\n\nconst MyTable = () =\u003e {\n  const { headers, rows } = useTable(columns, data);\n\n  return (\n    \u003ctable\u003e\n      \u003cthead\u003e\n        \u003ctr\u003e\n          {headers.map((header, idx) =\u003e (\n            \u003cth key={idx}\u003e{header.label}\u003c/th\u003e\n          ))}\n        \u003c/tr\u003e\n      \u003c/thead\u003e\n      \u003ctbody\u003e\n        {rows.map((row, idx) =\u003e (\n          \u003ctr key={idx}\u003e\n            {row.cells.map((cell, idx) =\u003e (\n              \u003ctd key={idx}\u003e{cell.render()}\u003c/td\u003e\n            ))}\n          \u003c/tr\u003e\n        ))}\n      \u003c/tbody\u003e\n    \u003c/table\u003e\n  );\n};\n```\n\n### Searching\n\n```jsx\nconst Table: FC = () =\u003e {\n    const { headers, rows, setSearchString } = useTable(\n      columns,\n      data,\n    );\n\n    return (\n      \u003c\u003e\n        \u003cinput\n          type=\"text\"\n          onChange={e =\u003e {\n            setSearchString(e.target.value);\n          }}\n        \u003e\u003c/input\u003e\n        \u003ctable\u003e\n          \u003cthead\u003e\n            \u003ctr\u003e\n              {headers.map((header, idx) =\u003e (\n                \u003cth key={idx}\u003e\n                  {header.render()}\n                \u003c/th\u003e\n              ))}\n            \u003c/tr\u003e\n          \u003c/thead\u003e\n          \u003ctbody\u003e\n            {rows.map((row, idx) =\u003e (\n              \u003ctr key={idx}\u003e\n                {row.cells.map((cell, idx) =\u003e (\n                  \u003ctd key={idx}\u003e{cell.render()}\u003c/td\u003e\n                ))}\n              \u003c/tr\u003e\n            ))}\n          \u003c/tbody\u003e\n        \u003c/table\u003e\n      \u003c/\u003e\n    );\n```\n\n### Row Selection\n\n```jsx\nimport React, { useMemo } from 'react';\nimport { useTable } from 'react-final-table';\nimport makeData from 'makeData'; // replace this with your own data\n\nfunction App() {\n  const { columns, rows } = makeData();\n\n  const { headers, rows, selectRow, selectedRows } = useTable(\n    memoColumns,\n    memoData,\n    {\n      selectable: true,\n    }\n  );\n\n  return (\n    \u003c\u003e\n      \u003ctable\u003e\n        \u003cthead\u003e\n          \u003ctr\u003e\n            \u003cth\u003e\u003c/th\u003e\n            {headers.map((header, idx) =\u003e (\n              \u003cth key={idx}\u003e{header.label}\u003c/th\u003e\n            ))}\n          \u003c/tr\u003e\n        \u003c/thead\u003e\n        \u003ctbody\u003e\n          {rows.map((row, idx) =\u003e (\n            \u003ctr key={idx}\u003e\n              \u003ctd\u003e\n                \u003cinput\n                  type=\"checkbox\"\n                  onChange={e =\u003e {\n                    selectRow(row.id);\n                  }}\n                /\u003e\n              \u003c/td\u003e\n              {row.cells.map((cell, idx) =\u003e (\n                \u003ctd key={idx}\u003e{cell.render()}\u003c/td\u003e\n              ))}\n            \u003c/tr\u003e\n          ))}\n        \u003c/tbody\u003e\n      \u003c/table\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Pagination\n\n```jsx\nexport const App: FC = () =\u003e {\n  const memoColumns = useMemo(() =\u003e columns, []);\n  const memoData = useMemo(() =\u003e data, []);\n\n  const { headers, rows, pagination } = useTable\u003c{\n    firstName: string;\n    lastName: string;\n  }\u003e(memoColumns, memoData, { pagination: true });\n\n  return (\n    \u003c\u003e\n      \u003ctable\u003e\n        \u003cthead\u003e\n          \u003ctr\u003e\n            {headers.map((header, idx) =\u003e (\n              \u003cth key={idx}\u003e{header.render()}\u003c/th\u003e\n            ))}\n          \u003c/tr\u003e\n        \u003c/thead\u003e\n        \u003ctbody\u003e\n          {rows.map((row, idx) =\u003e (\n            \u003ctr key={idx}\u003e\n              {row.cells.map((cell, idx) =\u003e (\n                \u003ctd key={idx}\u003e{cell.render()}\u003c/td\u003e\n              ))}\n            \u003c/tr\u003e\n          ))}\n        \u003c/tbody\u003e\n      \u003c/table\u003e\n      \u003cdiv\u003e\n        \u003cbutton\n          disabled={pagination.canPrev}\n          onClick={() =\u003e pagination.prevPage()}\n        \u003e\n          {'\u003c'}\n        \u003c/button\u003e\n        \u003cbutton\n          disabled={pagination.canNext}\n          onClick={() =\u003e pagination.nextPage()}\n        \u003e\n          {'\u003e'}\n        \u003c/button\u003e\n      \u003c/div\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n## Performance\n\nIt's recommended that you memoize your columns and data using `useMemo`. This is\nto prevent the table from rerendering everytime your component rerenders, which\ncan have negative consequences on performance.\n\n## Contributing\n\nContributing is welcome. Please read the [CONTRIBUTING doc](CONTRIBUTING.md) for more.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuuntu%2Freact-final-table","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuuntu%2Freact-final-table","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuuntu%2Freact-final-table/lists"}