npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

colrow

v0.3.1

Published

Simple toolset to build super-powered table components in React 🗓

Downloads

5

Readme

Colrow

Simple toolset to build super-powered table components in React 🗓

This project has been inspired by downshift project and Advanced React Component Patterns online course. Kent C. Dodds thanks for creating these!

Problem

Recently 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:

  • table
  • carousel
  • definition list

Of course all of these variations required sorting feature.

I couldn't find any existing library which already addresses that kind of problem. Therefore I wrote it all myself.

Solution

As I mentioned, my inspiration was downshift project. Once I looked at its code I already knew I would like to use render props pattern 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.

Demo

I 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 🙃:

Edit colrow

Features

  • [x] displays columns
  • [x] displays rows
  • [x] sorts collection by given column
  • [x] sorting reset
  • [x] custom value resolver for cell - provide raw value for sorting
  • [ ] custom value presenter for cell - provide decorated value for presentation
  • [ ] pagination features
  • [ ] loading state
  • [ ] predefined table components
  • [ ] storybook

Installation

This project's peerDependencies require react and prop-types packages to be available.

yarn add colrow

Usage

import Colrow, { SortingDirection } from 'colrow';
//
// define props (please glance at "Prop definitions" section below
//
// Colrow instance somewhere in your app
<Colrow columns={columns}
  rows={rows}
  render={render}
  comparator={comparator}
  sortByColumnIdx={sortByColumnIdx}
  sortDirection={sortDirection}
  onSorting={onSorting}
  onSorted={onSorted}
/>

Prop definitions

columns

This one is required to be an array and contain at least one object (as we're about to present some data ;)) You can define any properties within columnItem, so feel free to put there whatever you'd need to present. One important thing about columnItem is you can enhance it with itemKey and valueResolver properties. Please have a look at the explanation beneath.

const columnItem1 = {
  itemKey: 'x.y.z',
  // default `valueResolver` will evaluate 'x.y.z' string and extract value from a particular row object
  // for row object `{ x: { y: { z: 1 } } } the cell will have value `1`
};

const columnItem2 = {
  valueResolver(currentRow, itemKey) {
    return (
      <button onClick={doSomethingWithCurrentRowData(currentRow)}>
        Button in column no. {itemKey}
      </button>
    );
  }
  // default `itemKey` is 0-based index of columnItem that indicates its position in `columns` array
};

const columnItem3 = {
  valueResolver(currentRow, itemKey) {
    const someRowPropertyValue = currentRow[itemKey];
    const { link, label } = someRowPropertyValue;
    return (
      <a href={link}>{label}</a>
    );
  },
  itemKey: 'someRowPropertyName',
  // for row object
  // { someRowPropertyName: { link: 'https://twitter.com/tomasz_kopacki', label: 'Follow Tomasz on Twitter' } }
  // it'll display the following contents inside the cell
  // <a href="https://twitter.com/tomasz_kopacki">Follow Tomasz on Twitter</a>
  
};

const columns = [
  columnItem1,
  columnItem2,
  columnItem3,
];

rows

This 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.

rows as array of arrays

const rows = [
  ['Bitcoin', 'BTC', '1234.98'],
  ['Litecoin', 'LTC', '321.03'],
  ['Ripple', 'XRP', '2.12'],
];
const columnsExample = [
  { label: 'Name'},
  { label: 'Symbol' },
  {
    label: 'Price',
    valueResolver(row, itemKey) {
      const stringPrice = row[itemKey]; // row[itemKey] is equal to row[2]
      return parseFloat(stringPrice); // we want a numeric value for `Price` (especially for sorting)
    }
  },
];

_rows as array of plain objects

// nested arrays
const rows = [
  [{ texts: ['Bitcoin', 'BTC'], { numbers: { price: 1234.98 } },
  [{ texts: ['Litecoin', 'LTC'], { numbers: { price: 321.03 } },
  [{ texts: ['Ripple', 'XRP'], { numbers: { price: 2.12 } },
];
const columnsExample = [
  {
    label: 'Name',
    itemKey: 'texts',
    valueResolver(row, itemKey) {
      const texts = row[itemKey]
      const coinName = texts[0];
      return coinName;
    }
  },
  {
    label: 'Symbol',
    valueResolver(row) {
      const coinSymbol = row.texts[1];
      return coinSymbol;
    }
  },
  {
    label: 'Price',
    valueResolver(row, itemKey) {
      return parseFloat(row[itemKey]); // we want a numeric value for `Price`
    }
    itemKey: 'numbers.price',
  },
];

License

MIT