{"id":49772191,"url":"https://github.com/tk-o/colrow","last_synced_at":"2026-05-11T13:45:02.988Z","repository":{"id":57203561,"uuid":"118982432","full_name":"tk-o/colrow","owner":"tk-o","description":"Simple toolset to build super-powered table components in React 🗓","archived":false,"fork":false,"pushed_at":"2018-02-04T23:33:33.000Z","size":124,"stargazers_count":22,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-20T20:50:04.265Z","etag":null,"topics":["collection","primitives","react","sorting","table","ui-components"],"latest_commit_sha":null,"homepage":"https://npm.im/colrow","language":"JavaScript","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/tk-o.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-26T00:04:59.000Z","updated_at":"2025-10-12T13:57:31.000Z","dependencies_parsed_at":"2022-09-16T15:20:20.785Z","dependency_job_id":null,"html_url":"https://github.com/tk-o/colrow","commit_stats":null,"previous_names":["kopacki/colrow"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/tk-o/colrow","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tk-o%2Fcolrow","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tk-o%2Fcolrow/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tk-o%2Fcolrow/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tk-o%2Fcolrow/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tk-o","download_url":"https://codeload.github.com/tk-o/colrow/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tk-o%2Fcolrow/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32897924,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["collection","primitives","react","sorting","table","ui-components"],"created_at":"2026-05-11T13:45:01.910Z","updated_at":"2026-05-11T13:45:02.978Z","avatar_url":"https://github.com/tk-o.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Colrow\nSimple toolset to build super-powered table components in React 🗓\n\n[![CircleCI](https://img.shields.io/circleci/project/github/kopacki/colrow.svg?style=flat-square)](https://circleci.com/gh/kopacki/colrow)\n[![Coveralls github](https://img.shields.io/coveralls/github/kopacki/colrow.svg?style=flat-square)](https://coveralls.io/github/kopacki/colrow)\n\n\u003e This project has been inspired by [downshift](https://github.com/paypal/downshift) project and [Advanced React Component Patterns](https://egghead.io/courses/advanced-react-component-patterns) online course. [Kent C. Dodds](https://kentcdodds.com/) thanks for creating these!\n\n## Problem\nRecently I faced this situation when you are supposed to deliver something for yesterday. I had to create a few similar components to present the same collection, however each single one in unique way:\n- table\n- carousel\n- definition list\n\nOf course all of these variations required sorting feature.\n\nI couldn't find any existing library which already addresses that kind of problem. Therefore I wrote it all myself.\n\n## Solution\nAs I mentioned, my inspiration was [downshift](https://github.com/paypal/downshift) project. Once I looked at its code I already knew I would like to use [render props pattern](https://reactjs.org/docs/render-props.html) for my project. This very pattern allows to easily decouple JSX syntax from the logic. This is really powerful, as you have full flexibility on how you structure your template while the logic remain the same and is at hand when needed.\n\n## Demo\nI prepared small demo that presents what I wrote about above. Two templates - totally different. One logic available via set of primitives. That's it. It works. Please, have a glance 🙃:\n\n[![Edit colrow](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/5w7om43qqp?view=preview)\n\n### Features\n- [x] displays columns\n- [x] displays rows\n- [x] sorts collection by given column\n- [x] sorting reset\n- [x] custom value resolver for cell - provide raw value for sorting\n- [ ] custom value presenter for cell - provide decorated value for presentation\n- [ ] pagination features\n- [ ] loading state\n- [ ] predefined table components\n- [ ] storybook\n\n### Installation\n\u003e This project's _peerDependencies_ require `react` and `prop-types` packages to be available.\n```\nyarn add colrow\n```\n\n### Usage\n```jsx\nimport Colrow, { SortingDirection } from 'colrow';\n//\n// define props (please glance at \"Prop definitions\" section below\n//\n// Colrow instance somewhere in your app\n\u003cColrow columns={columns}\n  rows={rows}\n  render={render}\n  comparator={comparator}\n  sortByColumnIdx={sortByColumnIdx}\n  sortDirection={sortDirection}\n  onSorting={onSorting}\n  onSorted={onSorted}\n/\u003e\n```\n#### Prop definitions\n\n**columns**\n\u003eThis one is required to be an array and contains at least one object (as we're about to present some data ;))\n\u003eYou can define any properties within `columnItem`, so feel free to put there whatever you'd need to present.\n\u003eOne important thing about `columnItem` is you can enhance it with `itemKey` and `valueResolver` properties.\n\u003ePlease have a look at the explanation beneath.\n```jsx\nconst columnItem1 = {\n  itemKey: 'x.y.z',\n  // default `valueResolver` will evaluate 'x.y.z' string and extract value from a particular row object\n  // for row object `{ x: { y: { z: 1 } } } the cell will have value `1`\n};\n\nconst columnItem2 = {\n  valueResolver(currentRow, itemKey) {\n    return (\n      \u003cbutton onClick={doSomethingWithCurrentRowData(currentRow)}\u003e\n        Button in column no. {itemKey}\n      \u003c/button\u003e\n    );\n  }\n  // default `itemKey` is 0-based index of columnItem that indicates its position in `columns` array\n};\n\nconst columnItem3 = {\n  valueResolver(currentRow, itemKey) {\n    const someRowPropertyValue = currentRow[itemKey];\n    const { link, label } = someRowPropertyValue;\n    return (\n      \u003ca href={link}\u003e{label}\u003c/a\u003e\n    );\n  },\n  itemKey: 'someRowPropertyName',\n  // for row object\n  // { someRowPropertyName: { link: 'https://twitter.com/tomasz_kopacki', label: 'Follow Tomasz on Twitter' } }\n  // it'll display the following contents inside the cell\n  // \u003ca href=\"https://twitter.com/tomasz_kopacki\"\u003eFollow Tomasz on Twitter\u003c/a\u003e\n  \n};\n\nconst columns = [\n  columnItem1,\n  columnItem2,\n  columnItem3,\n];\n```\n\n**rows**\n\u003eThis one is should be an array (either of nested arrays or plain objects). And that's all :) Of course it'd be better for rows array not being empty, as again, we'd like to present some data.\n\n_rows as array of arrays_\n```jsx\nconst rows = [\n  ['Bitcoin', 'BTC', '1234.98'],\n  ['Litecoin', 'LTC', '321.03'],\n  ['Ripple', 'XRP', '2.12'],\n];\nconst columnsExample = [\n  { label: 'Name'},\n  { label: 'Symbol' },\n  {\n    label: 'Price',\n    valueResolver(row, itemKey) {\n      const stringPrice = row[itemKey]; // row[itemKey] is equal to row[2]\n      return parseFloat(stringPrice); // we want a numeric value for `Price` (especially for sorting)\n    }\n  },\n];\n```\n_rows as array of plain objects_\n```jsx\n// nested arrays\nconst rows = [\n  [{ texts: ['Bitcoin', 'BTC'], { numbers: { price: 1234.98 } },\n  [{ texts: ['Litecoin', 'LTC'], { numbers: { price: 321.03 } },\n  [{ texts: ['Ripple', 'XRP'], { numbers: { price: 2.12 } },\n];\nconst columnsExample = [\n  {\n    label: 'Name',\n    itemKey: 'texts',\n    valueResolver(row, itemKey) {\n      const texts = row[itemKey]\n      const coinName = texts[0];\n      return coinName;\n    }\n  },\n  {\n    label: 'Symbol',\n    valueResolver(row) {\n      const coinSymbol = row.texts[1];\n      return coinSymbol;\n    }\n  },\n  {\n    label: 'Price',\n    valueResolver(row, itemKey) {\n      return parseFloat(row[itemKey]); // we want a numeric value for `Price`\n    }\n    itemKey: 'numbers.price',\n  },\n];\n```\n### License\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftk-o%2Fcolrow","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftk-o%2Fcolrow","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftk-o%2Fcolrow/lists"}