Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

Commit

Permalink
feat: implement data-table
Browse files Browse the repository at this point in the history
  • Loading branch information
tatinacher committed Jun 16, 2021
1 parent 29ba491 commit 7ec29b8
Show file tree
Hide file tree
Showing 5 changed files with 289 additions and 3 deletions.
10 changes: 8 additions & 2 deletions src/ui/atoms/table/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import styled from 'styled-components';
import styled, { StyledComponent } from 'styled-components';
import { Variant } from 'lib/types';

const map = (properties: { columns: number } & Variant) => ({
Expand All @@ -17,7 +17,7 @@ export const Table = styled.table.attrs(map)`
display: grid;
grid-template-columns: repeat(var(--local-columns), auto);
gap: var(--local-gap);
`;
` as StyledComponent<'table', Record<string, unknown>, { columns: number } & Variant>;

export const Thead = styled.thead`
display: contents;
Expand All @@ -28,11 +28,16 @@ export const Tbody = styled.tbody`
`;

export const Th = styled.th`
display: flex;
align-items: center;
box-sizing: border-box;
max-width: var(--local-cell-max-width);
padding: var(--local-vertical) var(--local-horizontal);
color: var(--woly-canvas-text-disabled);
font-weight: normal;
line-height: var(--woly-line-height);
background: var(--woly-shape-text-default);
`;
Expand All @@ -43,6 +48,7 @@ export const Td = styled.td`
padding: var(--local-vertical) var(--local-horizontal);
color: var(--woly-canvas-text-default);
line-height: var(--woly-line-height);
background: var(--woly-shape-text-default);
`;
Expand Down
88 changes: 88 additions & 0 deletions src/ui/molecules/data-table/filter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import * as React from 'react';
import styled from 'styled-components';
import { Button, ListContainer, Surface } from 'ui/atoms';
import { Popover } from 'ui/molecules';
import { box } from 'ui/elements/box';

import { Checkbox } from '../checkbox';
import { IconArrowDown } from '../../../static/icons';

interface FilterProps {
options: Array<Record<string, string>>;
title: string;
}

export const Filter: React.FC<FilterProps> = ({ options, title }) => {
const [isOpen, setOpen] = React.useReducer((is) => !is, false);
const [isChecked, setChecked] = React.useReducer((is) => !is, false);
if (options.length === 0) return null;

return (
<FilterBlock>
<Popover
isOpen={isOpen}
content={
<ListContainer>
<Dropdown>
{options.map(({ name, value }) => (
<Checkbox
id={value}
key={value}
text={name}
onChange={setChecked}
variant="primary"
checked={isChecked}
/>
))}
<Button variant="primary" outlined text="Применить" />
</Dropdown>
</ListContainer>
}
>
<FilterButton onClick={setOpen}>
<div data-text>{title}</div>
<div data-icon>
<IconArrowDown />
</div>
</FilterButton>
</Popover>
</FilterBlock>
);
};

const Dropdown = styled(Surface)`
position: absolute;
display: flex;
flex-direction: column;
width: 100%;
font-weight: normal;
`;

const FilterBlock = styled.div`
position: relative;
`;

const FilterButton = styled.div`
${box}
display: flex;
align-items: center;
box-sizing: border-box;
border: var(--woly-border-width) solid var(--woly-canvas-default);
cursor: pointer;
[data-icon] {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
svg > path {
fill: var(--woly-canvas-text-disabled);
}
}
`;
57 changes: 57 additions & 0 deletions src/ui/molecules/data-table/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as React from 'react';
import styled, { StyledComponent } from 'styled-components';
import { Table, Tbody, Td, Th, Thead, Tr } from 'ui/atoms';
import { Variant } from 'lib/types';

interface ColumnProps {
property: string;
title: React.ReactNode | string;
}

interface DataTableProps {
className: string;
columns: Array<ColumnProps>;
placeholder: string;
values: Array<Record<string, string | number | null>>;
}

export const DataTableBase: React.FC<DataTableProps & Variant> = ({
className,
columns,
placeholder = '----',
values,
variant = 'secondary',
}) => (
<Table columns={columns.length} variant={variant} className={className}>
<TableHead head={columns} />
<Tbody>
{values.map(({ id, ...row }) => (
<Tr key={id}>
{columns.map(({ property }) => (
<Td key={property}>{row[property] || placeholder}</Td>
))}
</Tr>
))}
</Tbody>
</Table>
);

const TableHead: React.FC<{ head: Array<ColumnProps> }> = ({ head }) => (
<Thead>
<Tr>
{head.map(({ property, title }) => (
<Th key={property} data-filter={typeof title !== 'string'}>
{title}
</Th>
))}
</Tr>
</Thead>
);

export const DataTable = styled(DataTableBase)`
th[data-filter='true'] {
padding: 0;
border: 0;
}
` as StyledComponent<'table', Record<string, unknown>, DataTableProps & Variant>;
134 changes: 134 additions & 0 deletions src/ui/molecules/data-table/usage.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
name: data-table
category: molecules
package: 'woly'
---

import { Playground } from 'lib/playground'
import { DataTable } from 'ui'

import { Filter } from './filter'

export const bankNames = [
{
value: 'vtb',
name: 'ВТБ'
},
{
value: 'tinkoff',
name: 'Тинькофф'
},
{
value: 'alfa',
name: 'Альфа'
},
{
value: 'otkrytie',
name: 'Открытие'
},
]

export const paymentSystems = [
{
value: 'visa-mastercard',
name: 'Visa/Mastercard'
},
{
value: 'mir',
name: 'МИР'
},
]

export const columns = [
{
title: 'ID Дебет',
property: 'id-debet',
},
{
title: 'ID Кредит',
property: 'id-credit',
},
{
title: <Filter title="Название банка" options={bankNames}/>,
property: 'bank-name',
},
{
title: <Filter title="Платежная система" options={paymentSystems}/>,
property: 'payment-system',
},
];

export const values = [
{
id: 1,
'id-debet': 798172,
'id-credit': null,
'bank-name': 'ВТБ',
'payment-system': 'Visa/Mastercard',
},
{
id: 2,
'id-debet': 798173,
'id-credit': null,
'bank-name': 'Альфа-банк',
'payment-system': 'Visa/Mastercard',
},
{
id: 3,
'id-debet': 798174,
'id-credit': null,
'bank-name': 'ВТБ',
'payment-system': 'МИР',
},
{
id: 4,
'id-debet': 798175,
'id-credit': null,
'bank-name': 'Тинькофф',
'payment-system': 'Visa/Mastercard',
},
{
id: 5,
'id-debet': 798176,
'id-credit': null,
'bank-name': 'Открытие',
'payment-system': 'МИР',
},
{
id: 6,
'id-debet': 798177,
'id-credit': null,
'bank-name': 'Альфа-банк',
'payment-system': 'МИР',
}
];

### Example

<Playground>
<block.L style={{ background: '#f5f5f5', padding: '20px' }}>
<DataTable columns={columns} values={values} />
</block.L>
</Playground>

### Components

| Name | Description |
| ----------- | ------------------- |
| `DataTable` | DataTable component |

### DataTable Props

| Name | Type | Default | Description |
| ------------ | ----------------------------------------------- | ------------- | -------------------------------------------- |
| `columns` | `Array<ColumnProps>` | | Table head |
| `emptyValue` | `string` | `'----'` | String that is displayed when value is empty |
| `values` | `Array<Record<string, string ӏ number ӏ null>>` | | Table content |
| `variant` | `string` | `'secondary'` | Variant prop to style DataTable component |

### ColumnProps

| Name | Type | Default | Description |
| ---------- | -------------------------- | ------- | ------------------------------------------------------------------- |
| `property` | `string` | | Unique property of column to connect head with value in a row |
| `title` | `React.ReactNode ӏ string` | | Head of column to show. Can be a simple string or a Filter dropdown |
3 changes: 2 additions & 1 deletion src/ui/molecules/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export { Accordion } from './accordion';
export { Checkbox } from './checkbox';
export { DataTable } from './data-table';
export { Field } from './field';
export { InputPassword } from './input-password';
export { Modal } from './modal';
export { RadioButton } from './radio-button';
export { Popover } from './popover';
export { RadioButton } from './radio-button';
export { Select } from './select';
export { Switch } from './switch';

0 comments on commit 7ec29b8

Please sign in to comment.