1.1.1 • Published 8 months ago

ktq-react-table v1.1.1

Weekly downloads
-
License
MIT
Repository
github
Last release
8 months ago

Table of Contents

  • Features
  • Installation
  • Import
  • Props
  • Usage
  • Custom

Features

  • Automatically create tables
  • Sort data with static and dynamic data
  • Dynamic data filtering
  • Strong customization capabilities

Installation

You can install the ktq-react-table package using npm:

npm i ktq-react-table

Import

import { KTQTable as Table } from 'ktq-react-table';

Props

Table Props

PropTypeRequiredDescription
columnsIColumn<R>[]YesList of columns in the table.
rowsR[]NoData for the rows in the table.
rowKeyExtract<keyof R, string>YesUnique key to identify each row (must be one of the keys from R).
tableChildPropsTableChildPropsNoCustom props for the child components of the table (see TableChildProps for details).
iconUpReactNodeNoIcon displayed when data is sorted in ascending order.
iconNormalReactNodeNoIcon displayed when no sorting is applied.
iconDownReactNodeNoIcon displayed when data is sorted in descending order.
optionsIOptions<R>NoAdditional table options.
disableAutoShortbooleanNoWhether to disable automatic sorting.
emptyDataTemplateReactNodeNoTemplate to display when there is no data.
loadingTemplateReactNodeNoTemplate to display while data is loading.
persistFilterIDataFilter[]NoFilters that persist across reloads.
showLoadingbooleanNoWhether to show a loading indicator.
addToHistoryBrowserWhenFillterbooleanNoWhether to add the filter state to the browser history.
showFilterbooleanNoWhether to display the filter UI.
refTableFnTRefTableFn<R>NoReference function to interact with the table component.
filterPropsIFilterItemProps<R>NoCustom filter properties.
hightlightResult{ show?: boolean; style?: React.CSSProperties }NoOptions to highlight search results, including visibility and custom styles.
actions{ title?: string | ReactNode; body: (row: R) => ReactNode }NoActions to perform on each row, with customizable title and body.
filterTemplate() => ReactNodeNoCustom template for rendering filters.
onShort(short: ITableShort<R> | null) => voidNoCallback function triggered when sorting changes.
onFilter(filter: ITableFilter<R>[]) => voidNoCallback function triggered when filtering is applied.
onFetchError(error: AxiosError) => voidNoCallback function triggered when there is a fetch error.
onAfterFetch() => voidNoCallback function triggered after data is fetched.
onFetched(response: AxiosResponse<R[]>) => voidNoCallback function triggered when data is successfully fetched.

Table Styles Props

PropTypeRequiredDescription
theadTableTheadPropsNoCustom props for the thead element.
trheadTableTrPropsNoCustom props for the header row (tr in thead).
trbodyTableTrPropsNoCustom props for the body row (tr in tbody).
tbodyTableTbodyPropsNoCustom props for the tbody element.
thTableThPropsNoCustom props for the th elements.
tdTableTdPropsNoCustom props for the td elements.

Options Props

PropTypeRequiredDescription
currentPagenumberNoCurrent page number.
fromnumber \| nullNoStarting point for pagination, or null to reset.
query(params: Record<string, string \| number>) => Promise<AxiosResponse<R[]>>NoFunction that handles querying and fetching data. Returns a promise with the response.
prefixShortstringNoPrefix used for sorting, if applicable.
pathToDatastringNoPath to access data in the response (default is 'data', can be set to 'data.data').
pathToOptionstringNoPath to additional options within the response.
keyOptionsTKeyPagiantionNoKey or identifier used for pagination.

Usage

We use mantine to build UI

Static Data

import { Box } from '@mantine/core';
import { KTQTable as Table } from 'ktq-react-table';
import {IColumn} from 'ktq-react-table/src/type'

const App = () => {

    // Use ui of Mantine

    type User = {
        id: string;
        name: string;
        age: number;
    };

    const userColumns: IColumn<User>[] = [
        {
            title: 'ID',
            key: 'id',
        },
        {
            title: 'Age',
            key: 'age',
        },
        {
            title: 'Name',
            key: 'name',
        },
    ];

    const rows: User[] = [
        {
            id: '1',
            age: 18,
            name: 'Json',
        },
        {
            id: '2',
            age: 19,
            name: 'Ariteca',
        },
        {
            id: '3',
            age: 20,
            name: 'Pyxiko',
        },
        {
            id: '4',
            age: 20,
            name: 'Qitepo',
        },
    ];

    return (
        <Box ta={'center'}>
            <Table showFilter={false} columns={userColumns} rowKey="id" rows={rows} />
        </Box>
    );
};

export default App;

Dynamic Data

// Example response
{
    "current_page": 1,
    "data": [],
    "from": 1,
    "per_page": 15,
    "to": 15,
    "total": 0
}
import { faEdit } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Box, Tooltip } from '@mantine/core';
import axios from 'axios';
import { useRef } from 'react';
import { KTQTable as Table } from './module/ktq-react-table';
import { IColumn, TRefTableFn } from './type';

type Root = {
    id: number;
    order_id: number;
    fullname: string;
    customer_email: string;
    phone: string;
    total_price: string;
    currency: string;
    status: string;
    address: string;
    created_at: string;
    updated_at: string;
};

const data = Array(100)
    .fill(0)
    .map((_, index) => `Option ${index}`);

const columns: IColumn<Root>[] = [
    {
        key: 'order_id',
        title: 'ID',
        renderRow: (row, higtlightData) => {
            console.log('higtlightData', higtlightData);

            return <Box style={{ color: 'red' }}>{row.id}</Box>;
        },
        renderColumn(col) {
            return <Box style={{ color: 'blue' }}>{col.title}</Box>;
        },
        style: {
            type: 'single',
            style: {
                width: '10%',
                textAlign: 'right',
            },
        },
        typeFilter: 'number',
    },
    {
        key: 'fullname',
        title: 'Fullname',
    },
    {
        key: 'phone',
        title: 'Phone',
    },
    {
        key: 'customer_email',
        title: 'Email',
        typeFilter: {
            type: 'select',
            data,
        },
    },
    {
        key: 'created_at',
        title: 'Created at',
        typeFilter: 'date',
    },
    {
        key: 'updated_at',
        title: 'Update at',
        typeFilter: 'datetime',
    },
];

const App = () => {
    const refTableFn: TRefTableFn<Root> = useRef({});

    const getDataTable = (params: Record<string, string | number>) => {
        return axios({
            url: 'https://example/api/v1/orders',
            params,
        });
    };

    return (
        <Box ta={'center'}>
            <h1 className="text-3xl  font-bold underline">Table</h1>
            <Box
                style={{
                    padding: '40px',
                }}
            >
                <Box
                    style={{
                        padding: '40px',
                    }}
                >
                    <Table
                        refTableFn={refTableFn} // optional
                        tableChildProps={{ th: { style: { textAlign: 'center' } } }} // optional
                        withColumnBorders // optional
                        withTableBorder // optional
                        rowKey="id"
                        options={{
                            query: getDataTable,
                            pathToData: 'data.data',
                            keyOptions: {
                                to: 'to',
                                from: 'from',
                                total: 'total',
                                last_page: 'lastPage',
                                per_page: 'perPage',
                            },
                        }}
                        columns={columns}
                        onFilter={(data) => {
                            console.log(data);
                        }} // optional
                        onShort={(data) => {
                            console.log(data);
                        }} // optional
                        persistFilter={[
                            {
                                key: 'time_zone',
                                type: 'Asian',
                            },
                        ]} // optional
                        actions={{
                            title: <span>Action</span>,
                            body(row) {
                                return (
                                    <Box>
                                        <Tooltip label={row.id}>
                                            <FontAwesomeIcon color="blue" icon={faEdit} />
                                        </Tooltip>
                                    </Box>
                                );
                            },
                        }} // optional
                    />
                </Box>
            </Box>
        </Box>
    );
};

export default App;

Explanation of pathToData

  • Purpose: Specifies the path within the API response object to access the table data.
  • Default Value: 'data' (data is located within the data property).
  • Customizable: Provides a way to specify a custom path if the data is located elsewhere in the response (e.g., 'data.data').

Explanation of keyOptions

The keyOptions configuration in the table setup is used to map API data keys to the keys required by your table. This helps the table understand and use the data from the API correctly.

For example:

  • to: The key in the API response that contains the total number of items.
  • from: The key in the API response that contains the start date.
  • total: The key in the API response that contains the total number of records.
  • last_page: The key in the API response that contains the last page number.
  • per_page: The key in the API response that contains the number of items per page.

In summary, keyOptions helps the table know how to extract and display pagination information, total items, and other relevant data from the API response accurately.

Custom

highlightResult

  • Example:
    highlightResult={{
        show: true,
        style: {
            color: 'blue',
            backgroundColor: 'red',
          },
      }}

persistFilter

  • Example:
    persistFilter={[
      {
          key: 'time_zone',
          type: 'Asian',
      },
      ]}

actions

  • Example:
    actions={{
          title: <span>Action</span>,
          body(row) {
                      return (
                          <Box>
                              <Tooltip label={row.id}>
                                  <FontAwesomeIcon onClick={open} color="blue" icon={faEdit}/>
                              </Tooltip>
                          </Box>
                          );
                  },
          }}