Skip to content

Commit

Permalink
Reduce generic type
Browse files Browse the repository at this point in the history
  • Loading branch information
geoperez committed Sep 11, 2023
1 parent cfd27c8 commit cc976ee
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 46 deletions.
2 changes: 1 addition & 1 deletion sample/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const defaultData = [
null,
0.05,
false,
['https://www.google.com', '(Google)', 'before', 0.25, true],
['https://www.google.com', '(Google)', 'before'],
'Small text',
],
['Maria', 'NY', new Date('2022-01-05'), 60, 40, 0, 0.55, false, '', 'Small text'],
Expand Down
57 changes: 25 additions & 32 deletions src/Table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactNode, startTransition, useEffect, useState } from 'react';
import React, { PropsWithChildren, startTransition, useEffect, useState } from 'react';
import { renderToString } from 'react-dom/server';
import tw from 'tailwind-styled-components';
import { createCsv, formatter, FormatTypes } from 'uno-js';
Expand Down Expand Up @@ -28,30 +28,23 @@ import { sizing } from '@tremor/react/dist/lib/sizing';
import { border } from '@tremor/react/dist/lib/shape';
import { DataTypes, SortDirection } from '../constants';
import { NoData } from '../NoData';
import { searchData, searchFooter, sortData, TableColumn } from './sortData';
import { searchData, searchFooter, sortData, TableCellTypes, TableColumn } from './sortData';
import { ExportCsvButton } from '../ExportCsvButton';
import { useDebounce } from '../hooks';

export * from './sortData';

export type RenderTableFunc = <TDataIn, TDataOut extends Array<unknown>>(
data: TDataOut[],
definitions: TableColumn[],
rawData: TDataIn,
) => React.ReactNode;

export type TableSettings<TDataIn, TDataOut extends Array<unknown>> = {
export type TableSettings<TDataIn> = {
rawData: TDataIn;
dataCallback: (data: TDataIn) => TDataOut[];
dataCallback: (data: TDataIn) => TableCellTypes[][];
columns: TableColumn[];
isLoading?: boolean;
noDataElement?: React.ReactNode;
searchable?: boolean;
calculateFooter?: (data: TDataIn) => unknown[];
sortable?: boolean;
exportCsv?: boolean;
render?: RenderTableFunc;
children?: React.ReactNode;
render?: (data: TableCellTypes[][], definitions: TableColumn[], rawData: TDataIn | undefined) => React.ReactNode;
className?: string;
};

Expand Down Expand Up @@ -122,25 +115,25 @@ const translateType = (type: DataTypes | undefined): FormatTypes | undefined =>
}
};

const renderLinkString = (data: unknown) => {
const renderLinkString = (data: TableCellTypes) => {
if (data instanceof Array) {
return (data as string[])[0] ? (
return data[0] ? (
<>
{(data as string[])[3] && <span>{`${(data as string[])[2]} `}</span>}
<a href={(data as string[])[0]} target='_blank' rel='noopener noreferrer'>
{(data as string[])[1]}
{data[3] && <span>{`${data[2]} `}</span>}
<a href={data[0]} target='_blank' rel='noopener noreferrer' className='underline'>
{data[1]}
</a>
{!(data as string[])[3] && (data as string[])[2] && <span>{` ${(data as string[])[2]}`}</span>}
{!data[3] && data[2] && <span>{` ${data[2]}`}</span>}
</>
) : (
(data as string[])[1]
data[1]
);
}

if (typeof data !== 'string') return null;

return (
<a href={data} target='_blank' rel='noopener noreferrer'>
<a href={data} target='_blank' rel='noopener noreferrer' className='underline'>
{data}
</a>
);
Expand All @@ -162,7 +155,7 @@ const LongTextCell = ({ text }: { text: string }) => {
);
};

export const renderTableCell = (data: unknown, definition: TableColumn | undefined) => {
export const renderTableCell = (data: TableCellTypes, definition: TableColumn | undefined) => {
if (!data && definition?.dataType === 'money') return '$0.00';
if (data == null || data === ' ') return definition?.formatterOptions?.nullValue ?? 'N/A';

Expand Down Expand Up @@ -254,10 +247,10 @@ const TableFooter = ({ footer, definition }: TableFooterProps) => (
</TableFoot>
);

const getRows: RenderTableFunc = (data: unknown[][], definitions: TableColumn[]) =>
data.map((row: unknown[]) => (
const getRows = (data: TableCellTypes[][], definitions: TableColumn[]) =>
data.map((row: TableCellTypes[]) => (
<TableRow key={objectHash(row)}>
{row.map((cell: unknown, index: number) => (
{row.map((cell: TableCellTypes, index: number) => (
<TableCell
key={objectHash({ a: definitions[index], c: cell })}
className={`p-2 whitespace-normal text-xs/[13px] ${getAlignment(definitions[index], index)}`}
Expand All @@ -268,9 +261,9 @@ const getRows: RenderTableFunc = (data: unknown[][], definitions: TableColumn[])
</TableRow>
));

const renderToRowString = <TDataOut extends Array<unknown>>(data: TDataOut[], definitions: TableColumn[]) =>
data.map((row: TDataOut) =>
row.map((cell: unknown, index: number) => {
const renderToRowString = (data: TableCellTypes[][], definitions: TableColumn[]) =>
data.map((row: TableCellTypes[]) =>
row.map((cell: TableCellTypes, index: number) => {
const dataType = definitions[index]?.dataType;
if (dataType === 'boolean') return cell ? 'TRUE' : 'FALSE';
if (!cell && dataType === 'money') return '$0.00';
Expand All @@ -294,7 +287,7 @@ const ShimmerTable = ({ colSpan }: { colSpan: number }) =>
</TableRow>
));

const SpanTable = ({ colSpan, children }: { colSpan: number; children: ReactNode }) => (
const SpanTable = ({ colSpan, children }: PropsWithChildren<{ colSpan: number }>) => (
<TableRow>
<TableCell colSpan={colSpan} className='p-2'>
<Flex alignItems='center' className='w-full'>
Expand All @@ -304,7 +297,7 @@ const SpanTable = ({ colSpan, children }: { colSpan: number; children: ReactNode
</TableRow>
);

export const Table = <TDataIn, TDataOut extends Array<unknown>>({
export const Table = <TDataIn,>({
columns,
isLoading,
noDataElement,
Expand All @@ -317,11 +310,11 @@ export const Table = <TDataIn, TDataOut extends Array<unknown>>({
children,
dataCallback,
className = '',
}: TableSettings<TDataIn, TDataOut>) => {
}: PropsWithChildren<TableSettings<TDataIn>>) => {
const [rawDataState, setRawDataState] = useState<TDataIn>();
const [definitions, setDefinitions] = useState(columns);
const [data, setData] = useState<TDataOut[]>([]);
const [searched, setSearched] = useState<TDataOut[]>([]);
const [data, setData] = useState<TableCellTypes[][]>([]);
const [searched, setSearched] = useState<TableCellTypes[][]>([]);
const [footerData, setFooterData] = useState<unknown[]>();
const [search, setSearch] = useState('');

Expand Down
24 changes: 11 additions & 13 deletions src/Table/sortData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { compareDates, defaultStringFilter, sortComparer, sortNumericString } from 'uno-js';
import { DataTypes, SortDirection, TextAlign } from '../constants';

export type TableCellTypes = string | number | Array<string> | Date | boolean | null;

export type TableColumn = {
label: string;
dataType?: DataTypes;
Expand All @@ -16,27 +18,23 @@ export type TableColumn = {
};
};

export const searchData = <TDataOut extends Array<unknown>>(
search: string | undefined,
newData: TDataOut[],
definitions: TableColumn[],
) => {
export const searchData = (search: string | undefined, newData: TableCellTypes[][], definitions: TableColumn[]) => {
if (!search) return newData;

const ignoreColumns = definitions
.filter((y) => y.disableSearch === true)
.map((x) => definitions.findIndex((z) => z.label === x.label));

return newData.filter((section: TDataOut) =>
section.filter((_, i) => !ignoreColumns.includes(i)).some(defaultStringFilter(search)),
return newData.filter((section: TableCellTypes[]) =>
section.filter((_: unknown, i: number) => !ignoreColumns.includes(i)).some(defaultStringFilter(search)),
);
};

const numericTypes: DataTypes[] = ['number', 'decimal', 'percentage', 'money', 'days', 'months', 'boolean'];

const sortOneColumn = <T extends TableColumn, TDataOut extends Array<unknown>>(
left: TDataOut,
right: TDataOut,
const sortOneColumn = <T extends TableColumn>(
left: TableCellTypes[],
right: TableCellTypes[],
{ sortOrder, dataType, sortDirection }: T,
getSortIndex: (order: number) => number,
) => {
Expand Down Expand Up @@ -76,12 +74,12 @@ export const searchFooter = <TDataIn extends Array<Record<string, unknown>> | Re
) as TDataIn)
: newRaw;

export const sortData = <TDataOut extends Array<unknown>, T extends TableColumn>(
data: TDataOut[],
export const sortData = <T extends TableColumn>(
data: TableCellTypes[][],
definition: T[],
getSortIndex?: (order: number) => number,
) => {
data.sort((left: TDataOut, right: TDataOut) => {
data.sort((left: TableCellTypes[], right: TableCellTypes[]) => {
const sortColumns = definition
.filter((x) => x.sortOrder && x.sortOrder >= 1)
.sort((x, y) => Number(x.sortOrder) - Number(y.sortOrder));
Expand Down

0 comments on commit cc976ee

Please sign in to comment.