Skip to content

Commit 8eceed6

Browse files
committed
feat(table): implement <Table> component
1 parent d64c136 commit 8eceed6

File tree

7 files changed

+196
-96
lines changed

7 files changed

+196
-96
lines changed

demo/demo.jsx

+139-96
Original file line numberDiff line numberDiff line change
@@ -9,109 +9,152 @@ import {
99
FormGroupCheckbox,
1010
FormGroupRadio,
1111
FormGroupTextarea,
12+
Table,
1213
} from '../src/';
1314

1415
ReactDOM.render(
15-
<Form
16-
initialValues={{ textField: 'abc' }}
17-
onSubmit={(formData, reset) => {
18-
console.log('onSubmit', formData);
19-
return Promise.resolve();
20-
// reset();
21-
}}
22-
onCancel={() => console.log('onCancel')}
23-
>
24-
<div className="row">
25-
<div className="col">
26-
<FormGroupInput name="textField" label="Text field" />
27-
</div>
28-
<div className="col">
29-
<FormGroupInput name="textField2" label="Text field 2" required placeholder="Fill some value" />
30-
</div>
31-
</div>
16+
<div>
17+
<h1 className="mt-3">Forms</h1>
18+
<FormExamples />
19+
<hr className="my-5" />
20+
<h1 className="mt-3">Tables</h1>
21+
<TableExamples />
22+
</div>,
23+
document.getElementById('root')
24+
);
3225

33-
<div className="row">
34-
<div className="col">
35-
<FormGroupSelect name="selectField" label="Select field (list)" options={['A', 'B', 'C']} />
36-
</div>
37-
<div className="col">
38-
<FormGroupSelect
39-
name="selectField2"
40-
label="Select field 2 (array of objects)"
41-
options={[
42-
{ label: 'A', value: 'a' },
43-
{ label: 'B', value: 'b' },
44-
{ label: 'C', value: 'c' },
45-
]}
46-
required
47-
/>
48-
</div>
49-
<div className="col">
50-
<FormGroupSelect
51-
name="selectField3"
52-
label="Select field 3 (function)"
53-
options={(formData) => {
54-
return Object.entries(formData)
55-
.filter(([key]) => key !== 'selectField3')
56-
.map(([_, value]) => value);
57-
}}
58-
placeholder="Select one value"
59-
/>
60-
</div>
61-
<div className="col">
62-
<FormGroupSelect
63-
name="selectField4"
64-
label="Select field 4 (function)"
65-
options={(formData) => {
66-
return Object.entries(formData)
67-
.filter(([key]) => key !== 'selectField4')
68-
.map(([key, value]) => ({
69-
label: key,
70-
value,
71-
}));
72-
}}
73-
/>
74-
</div>
75-
</div>
26+
module.hot.accept();
7627

77-
<div className="row">
78-
<div className="col">
79-
<FormGroupSwitch id="switchFieldId" name="switchField" label="Switch field" trueLabel="ON" falseLabel="OFF" />
28+
function FormExamples() {
29+
return (
30+
<Form
31+
initialValues={{ textField: 'abc' }}
32+
onSubmit={(formData, reset) => {
33+
console.log('onSubmit', formData);
34+
// return Promise.resolve();
35+
reset();
36+
}}
37+
onCancel={() => console.log('onCancel')}
38+
>
39+
<div className="row">
40+
<div className="col">
41+
<FormGroupInput name="textField" label="Text field" />
42+
</div>
43+
<div className="col">
44+
<FormGroupInput name="textField2" label="Text field 2" required placeholder="Fill some value" />
45+
</div>
8046
</div>
81-
<div className="col">
82-
<FormGroupCheckbox
83-
id="checkboxFieldId"
84-
name="checkboxField"
85-
label="Checkbox field"
86-
valueLabel="Checkbox description"
87-
/>
47+
48+
<div className="row">
49+
<div className="col">
50+
<FormGroupSelect name="selectField" label="Select field (list)" options={['A', 'B', 'C']} />
51+
</div>
52+
<div className="col">
53+
<FormGroupSelect
54+
name="selectField2"
55+
label="Select field 2 (array of objects)"
56+
options={[
57+
{ label: 'A', value: 'a' },
58+
{ label: 'B', value: 'b' },
59+
{ label: 'C', value: 'c' },
60+
]}
61+
required
62+
/>
63+
</div>
64+
<div className="col">
65+
<FormGroupSelect
66+
name="selectField3"
67+
label="Select field 3 (function)"
68+
options={(formData) => {
69+
return Object.entries(formData)
70+
.filter(([key]) => key !== 'selectField3')
71+
.map(([_, value]) => value);
72+
}}
73+
placeholder="Select one value"
74+
/>
75+
</div>
76+
<div className="col">
77+
<FormGroupSelect
78+
name="selectField4"
79+
label="Select field 4 (function)"
80+
options={(formData) => {
81+
return Object.entries(formData)
82+
.filter(([key]) => key !== 'selectField4')
83+
.map(([key, value]) => ({
84+
label: key,
85+
value,
86+
}));
87+
}}
88+
/>
89+
</div>
8890
</div>
89-
<div className="col">
90-
<FormGroupRadio
91-
id="radioFieldId"
92-
name="radioField"
93-
label="Radio field"
94-
options={[
95-
{
96-
value: 'a',
97-
label: 'A',
98-
},
99-
{
100-
value: 'b',
101-
label: 'B',
102-
},
103-
{
104-
value: 'c',
105-
label: 'C',
106-
},
107-
]}
108-
/>
91+
92+
<div className="row">
93+
<div className="col">
94+
<FormGroupSwitch id="switchFieldId" name="switchField" label="Switch field" trueLabel="ON" falseLabel="OFF" />
95+
</div>
96+
<div className="col">
97+
<FormGroupCheckbox
98+
id="checkboxFieldId"
99+
name="checkboxField"
100+
label="Checkbox field"
101+
valueLabel="Checkbox description"
102+
/>
103+
</div>
104+
<div className="col">
105+
<FormGroupRadio
106+
id="radioFieldId"
107+
name="radioField"
108+
label="Radio field"
109+
options={[
110+
{
111+
value: 'a',
112+
label: 'A',
113+
},
114+
{
115+
value: 'b',
116+
label: 'B',
117+
},
118+
{
119+
value: 'c',
120+
label: 'C',
121+
},
122+
]}
123+
/>
124+
</div>
109125
</div>
110-
</div>
111126

112-
<FormGroupTextarea name="textareaField" label="Textarea field" />
113-
</Form>,
114-
document.getElementById('root')
115-
);
127+
<FormGroupTextarea name="textareaField" label="Textarea field" />
128+
</Form>
129+
);
130+
}
116131

117-
module.hot.accept();
132+
function TableExamples() {
133+
return (
134+
<div>
135+
<h2>Simple Table</h2>
136+
<Table
137+
columns={['a', 'b', 'c']}
138+
docs={[
139+
{ a: 1, b: 2, c: 3 },
140+
{ a: 4, b: 5, c: 6 },
141+
{ a: 7, b: 8, c: 9 },
142+
]}
143+
/>
144+
145+
<h2>Table with formated colums</h2>
146+
<Table
147+
columns={[
148+
{ attribute: 'a', label: 'A', align: 'center' },
149+
{ attribute: 'b', label: 'B', align: 'right' },
150+
{ attribute: 'c', label: 'C' },
151+
]}
152+
docs={[
153+
{ a: 1, b: 2, c: 3 },
154+
{ a: 4, b: 5, c: 6 },
155+
{ a: 7, b: 8, c: 9 },
156+
]}
157+
/>
158+
</div>
159+
);
160+
}

src/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from './forms';
2+
export * from './table';

src/table/Table.jsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
import { TableHead } from './TableHead';
3+
import { TableBody } from './TableBody';
4+
import { normalizeColumns } from './table-helpers';
5+
6+
export function Table({ docs, columns }) {
7+
const normalizedColumns = normalizeColumns(columns);
8+
9+
return (
10+
<table className="table">
11+
<TableHead columns={normalizedColumns} />
12+
<TableBody docs={docs} columns={normalizedColumns} />
13+
</table>
14+
);
15+
}

src/table/TableBody.jsx

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import React from 'react';
2+
3+
export function TableBody({ columns, docs }) {
4+
return (
5+
<tbody>
6+
{docs.map((doc, docIndex) => (
7+
<tr key={docIndex}>
8+
{columns.map(({ attribute }, columnIndex) => (
9+
<td key={columnIndex}>{doc[attribute]}</td>
10+
))}
11+
</tr>
12+
))}
13+
</tbody>
14+
);
15+
}

src/table/TableHead.jsx

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React from 'react';
2+
3+
export function TableHead({ columns }) {
4+
return (
5+
<thead>
6+
<tr>
7+
{columns.map(({ label }, columnIndex) => (
8+
<th key={columnIndex}>{label}</th>
9+
))}
10+
</tr>
11+
</thead>
12+
);
13+
}

src/table/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Table';

src/table/table-helpers.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export function normalizeColumns(columns) {
2+
return columns.map((column) => {
3+
if (typeof column !== 'string') {
4+
return column;
5+
}
6+
7+
return {
8+
attribute: column,
9+
label: column,
10+
};
11+
});
12+
}

0 commit comments

Comments
 (0)