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

[FRNT-507] Implement data table #124

Merged
merged 30 commits into from
Aug 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
19df318
feat: implement data-table
tatinacher May 27, 2021
09c5391
Merge remote-tracking branch 'origin' into feat/FRNT-507-implement-da…
Jul 13, 2021
d5cdd49
feat(data-table): add head renderer
Jul 14, 2021
ee036e4
Merge branch 'master' into feat/FRNT-507-implement-data-table
Jul 14, 2021
09696ae
feat(data-table): add rowKey
Jul 14, 2021
5bba23c
refactor(data-table): split up things
Jul 14, 2021
5950026
fix(data-table/filter): checkboxes behavior
Jul 14, 2021
5892577
refactor(data-table): small changes
Jul 15, 2021
cc3274a
fix(data-table): types
Jul 15, 2021
7e75823
fix(data-table): import
Jul 15, 2021
eb750e0
Merge branch 'master' into feat/FRNT-507-implement-data-table
Jul 15, 2021
7b0bbd3
feat(data-table): add an export for DataTableColumn type
Jul 15, 2021
131cc48
fix(data-table): usage and types
Jul 15, 2021
54651a0
refactor(data-table): imports
Jul 19, 2021
3ed8663
style(data-table): format
Jul 19, 2021
6489fb1
refactor(data-table): remove unnecessary variable for placeholder
Jul 19, 2021
f00cddb
fix(data-table): replace variant with priority
Jul 19, 2021
19a1b01
Merge branch 'master' into feat/FRNT-507-implement-data-table
Jul 20, 2021
e66ee1c
[FRNT-548] Add documentation configurator (#170)
Jul 22, 2021
1423c86
[FRNT-603] Refactor data-attributes (#181)
Aug 2, 2021
6c5255f
feat: move all dev stuff from lib to dev dir (#182)
rchubarkin Aug 2, 2021
a07d74f
feat(docs): upgrade gatsby theme version (#183)
Aug 3, 2021
5528b75
[FRNT-592] feat: implement level decrement (#179)
rchubarkin Aug 3, 2021
1ed192e
[FRNT-543] create tab and tabbar component (#123)
Irinaristova Aug 6, 2021
f612621
[DS-40] Fix refactored data-icon in box components (#186)
Aug 6, 2021
264b00b
feat(data-table): improve usage
Aug 6, 2021
fe8ede3
Merge remote-tracking branch 'origin' into feat/FRNT-507-implement-da…
Aug 9, 2021
3c2791e
fix(table): text color
Aug 9, 2021
3702f81
fix(data-table): typo
Aug 9, 2021
d533881
fix(table): add comment
Aug 9, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,8 @@
"dependencies": {
"@tippyjs/react": "^4.2.5",
"color-rgba": "^2.2.3",
"effector": "^21.8.12",
"effector-react": "^21.3.3",
"nanoid": "^3.1.23",
"react": "16.14.0",
"react-colorful": "^5.2.3",
Expand Down
9 changes: 7 additions & 2 deletions src/woly/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 { Priority } from 'lib/types';

const map = (properties: { columns: number } & Priority) => ({
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 } & Priority>;

export const Thead = styled.thead`
display: contents;
Expand All @@ -32,9 +32,13 @@ export const Th = styled.th`
align-items: center;
box-sizing: border-box;
max-width: var(--local-cell-max-width);
/* TODO: Replace with box [09.08.2020] */
padding: var(--local-vertical) var(--local-horizontal);
risen228 marked this conversation as resolved.
Show resolved Hide resolved
Irinaristova marked this conversation as resolved.
Show resolved Hide resolved

color: var(--woly-canvas-text-disabled);
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved
font-weight: normal;

line-height: var(--woly-line-height);

background: var(--woly-shape-text-default);
`;
Expand All @@ -46,6 +50,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
10 changes: 5 additions & 5 deletions src/woly/atoms/table/usage.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import {Playground} from 'dev/playground'
import {Table, Tbody, Td, Th, Thead, Tr} from 'ui'

To create a table use Table, Thead, Tbody, Th, Tr, Td components.
To set number of columns pass `columns` prop to the Table component.

### Example

export const tableHead = [
{id: 'id', name: 'Id'},
{id: 'firstName', name: 'First name'},
Expand Down Expand Up @@ -65,11 +70,6 @@ export const tableRows = [
},
];

To create a table use Table, Thead, Tbody, Th, Tr, Td components.
To set number of columns pass `columns` prop to the Table component.

### Example

<Playground>
<block.L style={{ background: '#f5f5f5', padding: '20px' }}>
<Table columns={tableHead.length} priority="primary">
Expand Down
116 changes: 116 additions & 0 deletions src/woly/molecules/data-table/filter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import * as React from 'react';
import styled from 'styled-components';
import { IconArrowDown } from 'static/icons';
import { box } from 'ui/elements/box';

import { Button, Checkbox, ListContainer, Popover, Surface } from '../../index';

interface Option {
name: string;
value: string;
}

interface FilterProps {
title: React.ReactNode | string;
options: Option[];
value: string[];
onChange: (value: string[]) => void;
}

export const Filter: React.FC<FilterProps> = ({
title,
options,
value: checkedValues,
onChange,
}) => {
const [isOpen, setOpen] = React.useReducer((is) => !is, false);

const getUpdatedValue = (value: string) => {
if (checkedValues.includes(value)) {
// remove
Irinaristova marked this conversation as resolved.
Show resolved Hide resolved
return checkedValues.filter((item) => item !== value);
}

// add
return checkedValues.concat(value);
};

const createCheckHandler = (item: string) => {
return () => onChange(getUpdatedValue(item));
};

if (options.length === 0) {
console.log('No options are passed to filter');
return null;
}

return (
<FilterBlock>
<Popover
isOpen={isOpen}
content={
<ListContainer>
<Dropdown>
{options.map(({ name, value }) => (
<Checkbox
id={value}
key={value}
text={name}
checked={checkedValues.includes(value)}
onChange={createCheckHandler(value)}
priority="primary"
/>
))}
</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;

background: var(--woly-shape-text-default);

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);
}
}
`;
71 changes: 71 additions & 0 deletions src/woly/molecules/data-table/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import * as React from 'react';

import { CellProps, DataTableProps, HeadGroupProps, HeadProps } from './types';
import { Table, Tbody, Td, Th, Thead, Tr } from '../../atoms/table';

export function DataTable<TValue, TRowKey extends string>({
rowKey,
columns,
placeholder = '----',
priority = 'secondary',
values,
...rest
}: DataTableProps<TValue, TRowKey>) {
return (
// eslint-disable-next-line react/jsx-props-no-spreading
<Table columns={columns.length} priority={priority} {...rest}>
<TableHeadGroup columns={columns} />
<Tbody>
{values.map((row) => (
<Tr key={row[rowKey]}>
{columns.map((column) => {
const Cell = column.cell || DefaultCell;

return (
<Td key={column.property}>
<Cell
value={row[column.property]}
placeholder={column.placeholder || placeholder}
/>
</Td>
);
})}
</Tr>
))}
</Tbody>
</Table>
);
}

function DefaultCell<T>({ value, placeholder }: CellProps<T>) {
return <>{value || placeholder}</>;
}

function DefaultHead({ title }: HeadProps) {
return <>{title}</>;
}

function TableHeadGroup<T>({ columns }: HeadGroupProps<T>) {
return (
<Thead>
<Tr>
{columns.map(({ title, property, head }) => {
const Head = head || DefaultHead;
const padding = isReactEntity(title) ? '0' : '';
ainursharaev marked this conversation as resolved.
Show resolved Hide resolved

return (
<Th key={property} style={{ padding }}>
<Head title={title} />
</Th>
);
})}
</Tr>
</Thead>
);
}

const isReactComponent = (value: unknown) => typeof value === 'function';
const isReactElement = (value: unknown) => typeof value === 'object';
const isReactEntity = (value: unknown) => isReactComponent(value) || isReactElement(value);

export { DataTableColumn, HeadProps as DataTableHeadProps } from './types';
15 changes: 15 additions & 0 deletions src/woly/molecules/data-table/range-cell.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';

interface RangeProps {
value: {
from: number;
to: number;
};
placeholder: string;
}

export const RangeCell: React.FC<RangeProps> = ({ value, placeholder }) => (
<span>
from {value.from || placeholder} to {value.to || placeholder}
</span>
);
39 changes: 39 additions & 0 deletions src/woly/molecules/data-table/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as React from 'react';
import { Priority } from 'lib/types';

export type CellType<TValue, TRowKey extends string> = {
[key in TRowKey]: string;
} &
Record<string, TValue>;

export interface HeadProps {
title: React.ReactNode | string;
}

export interface CellProps<TValue> {
placeholder?: React.ReactNode | string;
value: TValue;
}

export interface DataTableColumn<TValue> {
title: React.ReactNode | string;
property: string;
head?: React.FC<HeadProps>;
cell?: React.FC<CellProps<TValue>>;
placeholder?: React.ReactNode | string;
}

export type DataTableProps<
TValue,
TRowKey extends string
> = React.HTMLAttributes<HTMLTableElement> &
Priority & {
rowKey: TRowKey;
columns: Array<DataTableColumn<TValue>>;
placeholder?: React.ReactNode | string;
values: Array<CellType<TValue, TRowKey>>;
};

export interface HeadGroupProps<TValue> {
columns: Array<DataTableColumn<TValue>>;
}
Loading