blb-table
TypeScript icon, indicating that this package has built-in type declarations

1.0.30 • Public • Published

BlackLightBurn Table

BlackLightBurn table component

Installation

npm install --save blb-table

Import styles

Import styles in app.js

import 'blb-table/dist/variables.css';

export default function App({ Component, pageProps }: any) {
	return <Component {...pageProps} />;
}

Usage

// index.tsx

import { useState, useEffect } from 'react';
import { Table, QueryParams, ColumnDef } from 'blb-table';
import { EmptyData } from '@/components/EmptyData';
import { Pagination } from '@/components/Pagination';
import { Search } from '@/components/Search';
import { FilterForm } from '@/components/FilterForm';

interface InitialDataProps {
  title: string;
  subscribers: number;
  views: number;
}

const initialData = {
  data: [
    {
      title: 'One',
      subscribers: 1000,
      views: 123,
    },
    {
      title: 'Two',
      subscribers: 2000,
      views: 544,
    },
    {
      title: 'Three',
      subscribers: 3000,
      views: 56626,
    },
  ],
  count: 3
};

export default function Home() {
    const [data, setData] = useState(() => initialData)
    const [queryParams, setQueryParams] = useState<QueryParams>({
        limit: 3,
        sort: [{
          id: 'title',
          desc: false,
        }],
    });

	const columns: ColumnDef<InitialDataProps>[] = [
		{
			accessorKey: 'title',
			header: () => <span>Name</span>,
			cell: (info) => info.getValue(),
			enableSorting: false,
		},
		{
			accessorKey: 'subscribers',
			header: () => <span>Subscribers</span>,
			cell: (info) => info.getValue(),
			enableSorting: true,
		},
		{
			accessorKey: 'views',
			header: () => <span>Views</span>,
			cell: (info) => info.getValue(),
			enableSorting: true,
		},
	];
	
     useEffect(() => {
        setData((prevData) => {
          const filtered = !queryParams.search
            ? initialData.data
            : prevData.data.filter((itm) => itm.title.includes(queryParams.search || ''));
          return {
            data: filtered,
            count: filtered.length,
          };
        });
      }, [queryParams]);

	return (
	  <Table
	    data={data}
		columns={columns}
		isLoading={false}
		onChange={setQueryParams}
		initialState={queryParams}
		template={['50%', '30%', '20%']}
		components={{
          EmptyData: ({ isLoading, isEmpty }) => (
            <EmptyData isLoading={isLoading} isEmpty={isEmpty} />
          ),
          Pagination: ({ pageCount, pageIndex, setPageIndex }) => (
            <Pagination
              pageCount={pageCount}
              onChange={({ selected }) => {
                setQueryParams((prev) => ({ ...prev, skip: queryParams.limit * selected }));
                setPageIndex({ selected });
              }}
            />
          ),
          Search: ({ openFilters }) => (
            <Search
              onChange={(value) => {
                setQueryParams((prev) => ({
                  ...prev,
                  search: value,
                  skip: 0,
                }));
              }}
              openFilters={openFilters}
            />
          ),
          Filters: () => (
            <FilterForm
              onSubmit={(data) => {
                setQueryParams((prev) => ({
                  ...prev,
                  filter: {
                    ...prev.filter,
                    ...data,
                  },
                  skip: 0,
                }));
              }}
            />
          ),
        }}
      />
	)
}
// Example FilterForm.tsx

export const FilterForm = ({ onSubmit: _onSubmit }) => {
  const onSubmit = (data) => {
    let _data = {};
    let viewsFrom;
    let viewsTo;
    if (data.target.name === 'viewsFrom') {
      viewsFrom = data.target.value;
    }
    if (data.target.name === 'viewsTo') {
      viewsTo = data.target.value;
    }
    _data = {
      views: [viewsFrom ? Number(viewsFrom) : null, viewsTo ? Number(viewsTo) : null],
    };

    if (_onSubmit) _onSubmit(_data);
  };
  return (
    <form onChange={onSubmit}>
      <input name="viewsFrom"  />
      <input name="viewsTo" />
    </form>
  );
};
// Example Search.tsx

import { useState } from "react";

interface SearchProps {
  onChange: (value: string) => void;
  openFilters: () => void;
}

export const Search = ({ onChange, openFilters }: SearchProps) => {
  const [searchValue, setSearchValue] = useState('');
  return (
    <>
    <input
      value={searchValue}
      onChange={(e) => {
        setSearchValue(e.target.value);
        onChange(e.target.value);
      }}
    />
    <button type="button" onClick={openFilters}>open filters</button>
    </>
  )
}
// Example Pagination.tsx

interface PaginationProps {
  pageCount: number;
  onChange: ({ selected }: { selected: number }) => void;
}

export const Pagination = ({ pageCount, onChange }: PaginationProps) => {
  return (
    <>
      {Array.from({ length: pageCount }, (_, index) => 0 + index).map((item) => (
        <button type="button" key={item} onClick={() => onChange({ selected: item })}>{item + 1}</button>
      ))}
    </>
  );
};
// Example EmptyData.tsx

interface EmptyDataProps {
  isLoading: boolean;
  isEmpty: boolean;
}

export const EmptyData = ({ isLoading, isEmpty }: EmptyDataProps) => {
  if (isLoading) {
    return 'Loading...'
  }
  return 'Empty';
};

API

  • data: { data: Array<object>; count: number; }

    Count is a total count of elements

  • isLoading: boolean
  • onChange: Dispatch<SetStateAction<QueryParams>>
  • initialState: { limit: number; sort?: QueryParams['sort']}

    Limit for pagination page size and for number of elements to display and default sort state

  • columns: any[]
  • search?: string
  • template?: string[]

    Defines the width of each column (in %). For example ['50%', '30%', '20%']

  • components?: { components API }

    For your custom components

Components API

  • Pagination?: (props: { pageCount: number; pageIndex: number; setPageIndex: ({ selected }: { selected: number }) => void; }) => React.ReactElement;

    pageCount - total page count

    pageIndex - current index of page

    setPageIndex - function for set the page number

  • EmptyData?: (props: { isLoading: boolean; isEmpty: boolean }) => React.ReactElement;

  • Search?: (props: { openFilters: () => void; }) => React.ReactElement;

    openFilter - open/close filters

  • Filters?: () => React.ReactElement;

Contributing

This project is open for improvements and maintenance. Feel free to fork and make your own modifications.

License

MIT

Readme

Keywords

Package Sidebar

Install

npm i blb-table

Weekly Downloads

0

Version

1.0.30

License

MIT

Unpacked Size

95.8 kB

Total Files

67

Last publish

Collaborators

  • blacklightburn