Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/table-component' into feat/…
Browse files Browse the repository at this point in the history
…table-component-tests
  • Loading branch information
chaitanyadeorukhkar committed Nov 24, 2023
2 parents 517f3a1 + 0375390 commit f48719e
Show file tree
Hide file tree
Showing 15 changed files with 556 additions and 510 deletions.
5 changes: 5 additions & 0 deletions .changeset/moody-moles-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@razorpay/blade": minor
---

feat: Add `Table` component
38 changes: 1 addition & 37 deletions packages/blade/src/components/Table/Table.native.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,10 @@
/* eslint-disable react/no-unused-prop-types */
/* eslint-disable @typescript-eslint/no-unused-vars */
import React from 'react';
import type { StyledPropsBlade } from '~components/Box/styledProps';
import type { TableProps } from './types';
import { Text } from '~components/Typography';
import type { SurfaceLevels } from '~tokens/theme/theme';
import { logger } from '~utils/logger';

export type TableNode<Item> = Item & {
id: string;
};

export type TableData<Item> = {
nodes: TableNode<Item>[];
};

export type TableProps<Item> = {
children: (tableData: TableNode<Item>[]) => React.ReactElement;
data: TableData<Item>;
selectionType?: 'none' | 'single' | 'multiple';
onSelectionChange?: ({ values }: { values: TableNode<Item>[] }) => void;
isHeaderSticky?: boolean;
isFooterSticky?: boolean;
isFirstColumnSticky?: boolean;
rowDensity?: 'normal' | 'comfortable';
onSortChange?: ({
sortKey,
isSortReversed,
}: {
sortKey: string;
isSortReversed: boolean;
}) => void;
sortFunctions?: Record<string, (array: TableNode<Item>[]) => TableNode<Item>[]>;
toolbar?: React.ReactElement;
pagination?: React.ReactElement;
height?: string;
showStripedRows?: boolean;
gridTemplateColumns?: string;
surfaceLevel?: SurfaceLevels;
isLoading?: boolean;
isRefreshing?: boolean;
} & StyledPropsBlade;

const Table = <Item,>(props: TableProps<Item>): React.ReactElement => {
if (__DEV__) {
logger({
Expand Down
2 changes: 1 addition & 1 deletion packages/blade/src/components/Table/Table.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { ComponentStory, Meta } from '@storybook/react';
import type { TableProps } from './Table';
import type { TableProps } from './types';
import { Table as TableComponent } from './Table';
import { TableHeader, TableHeaderRow, TableHeaderCell } from './TableHeader';
import { TableBody, TableRow, TableCell } from './TableBody';
Expand Down
133 changes: 11 additions & 122 deletions packages/blade/src/components/Table/Table.web.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Table as ReactTable } from '@table-library/react-table-library/table';
import { useTheme as useTableTheme } from '@table-library/react-table-library/theme';
import filter from 'lodash/filter';
import type { MiddlewareFunction } from '@table-library/react-table-library/types/common';
import type { Identifier } from '@table-library/react-table-library/table';
import { useSort } from '@table-library/react-table-library/sort';
import { usePagination } from '@table-library/react-table-library/pagination';
import { SelectTypes, useRowSelect } from '@table-library/react-table-library/select';
Expand All @@ -18,130 +17,17 @@ import {
refreshWrapperZIndex,
tablePagination,
} from './tokens';
import type { TableHeaderCellProps } from './TableHeader';
import type { TableProps, TableNode, Identifier } from './types';
import { makeBorderSize, makeMotionTime, useTheme } from '~utils';
import { getComponentId, isValidAllowedChildren } from '~utils/isValidAllowedChildren';
import { throwBladeError } from '~utils/logger';
import type { BoxProps } from '~components/Box';
import { getBaseBoxStyles } from '~components/Box/BaseBox/baseBoxStyles';
import type { SurfaceLevels } from '~tokens/theme/theme';
import BaseBox from '~components/Box/BaseBox';
import { Spinner } from '~components/Spinner';
import { getStyledProps } from '~components/Box/styledProps';
import type { StyledPropsBlade } from '~components/Box/styledProps';
import { MetaConstants, metaAttribute } from '~utils/metaAttribute';

type TableNode<Item> = Item & {
id: Identifier;
};

type TableData<Item> = {
nodes: TableNode<Item>[];
};

type TableProps<Item> = {
/**
* The children of the Table component should be a function that returns TableHeader, TableBody and TableFooter components.
* The function will be called with the tableData prop.
*/
children: (tableData: TableNode<Item>[]) => React.ReactElement;
/**
* The data prop is an object with a nodes property that is an array of objects.
* Each object in the array is a row in the table.
* The object should have an id property that is a unique identifier for the row.
*/
data: TableData<Item>;
/**
* The selectionType prop determines the type of selection that is allowed on the table.
* The selectionType prop can be 'none', 'single' or 'multiple'.
* @default 'none'
**/
selectionType?: 'none' | 'single' | 'multiple';
/**
* The onSelectionChange prop is a function that is called when the selection changes.
* The function is called with an object that has a values property that is an array of the selected rows.
**/
onSelectionChange?: ({ values }: { values: TableNode<Item>[] }) => void;
/**
* The isHeaderSticky prop determines whether the table header is sticky or not.
* The default value is `false`.
**/
isHeaderSticky?: boolean;
/**
* The isFooterSticky prop determines whether the table footer is sticky or not.
* The default value is `false`.
**/
isFooterSticky?: boolean;
/**
* The isFirstColumnSticky prop determines whether the first column is sticky or not.
* The default value is `false`.
**/
isFirstColumnSticky?: boolean;
/**
* The rowDensity prop determines the density of the table.
* The rowDensity prop can be 'normal' or 'comfortable'.
* The default value is `normal`.
**/
rowDensity?: 'normal' | 'comfortable';
/**
* The onSortChange prop is a function that is called when the sort changes.
* The function is called with an object that has a sortKey property that is the key of the column that is sorted and a isSortReversed property that is a boolean that determines whether the sort is reversed or not.
**/
onSortChange?: ({
sortKey,
isSortReversed,
}: {
sortKey: TableHeaderCellProps['headerKey'];
isSortReversed: boolean;
}) => void;
/**
* The sortFunctions prop is an object that has a key for each column that is sortable.
* The value of each key is a function that is called when the column is sorted.
* The function is called with an array of the rows in the table.
* The function should return an array of the rows in the table.
**/
sortFunctions?: Record<string, (array: TableNode<Item>[]) => TableNode<Item>[]>;
/**
* The toolbar prop is a React element that is rendered above the table.
* The toolbar prop should be a `TableToolbar` component.
**/
toolbar?: React.ReactElement;
/**
* The pagination prop is a React element that is rendered below the table.
* The pagination prop should be a `TablePagination` component.
**/
pagination?: React.ReactElement;
/**
* The height prop is a responsive styled prop that determines the height of the table.
**/
height?: BoxProps['height'];
/**
* The showStripedRows prop determines whether the table should have striped rows or not.
* The default value is `false`.
**/
showStripedRows?: boolean;
/**
* The gridTemplateColumns prop determines the grid-template-columns CSS property of the table.
* The default value is `repeat(${columnCount},minmax(100px, 1fr))`.
**/
gridTemplateColumns?: string;
/**
* The surfaceLevel prop determines the surface level of the table.
* The surfaceLevel prop can be 1, 2, 3, 4 or 5.
* The default value is `2`.
**/
surfaceLevel?: SurfaceLevels;
/**
* The isLoading prop determines whether the table is loading or not.
* The default value is `false`.
**/
isLoading?: boolean;
/**
* The isRefreshing prop determines whether the table is refreshing or not.
* The default value is `false`.
**/
isRefreshing?: boolean;
} & StyledPropsBlade;
import { assignWithoutSideEffects } from '~utils/assignWithoutSideEffects';

const rowSelectType: Record<
NonNullable<TableProps<unknown>['selectionType']>,
Expand Down Expand Up @@ -186,12 +72,12 @@ const getTableHeaderCellCount = (children: (data: []) => React.ReactElement): nu
return 0;
};

const StyledReactTable = styled(ReactTable)<{ styledProps?: { height?: BoxProps['height'] } }>(
({ styledProps }) => {
const StyledReactTable = styled(ReactTable)<{ $styledProps?: { height?: BoxProps['height'] } }>(
({ $styledProps }) => {
const { theme } = useTheme();
const styledPropsCSSObject = getBaseBoxStyles({
theme,
height: styledProps?.height,
height: $styledProps?.height,
});

return {
Expand Down Expand Up @@ -219,7 +105,7 @@ const RefreshWrapper = styled(BaseBox)<{
};
});

const Table = <Item,>({
const _Table = <Item,>({
children,
data,
selectionType = 'none',
Expand Down Expand Up @@ -557,7 +443,7 @@ const Table = <Item,>({
theme={tableTheme}
select={selectionType !== 'none' ? rowSelectConfig : null}
sort={sortFunctions ? sort : null}
styledProps={{
$styledProps={{
height,
}}
pagination={hasPagination ? paginationConfig : null}
Expand All @@ -572,5 +458,8 @@ const Table = <Item,>({
);
};

const Table = assignWithoutSideEffects(_Table, {
componentId: ComponentIds.Table,
});

export { Table };
export type { TableProps, TableNode };
Loading

0 comments on commit f48719e

Please sign in to comment.