Skip to content

Commit dad3a34

Browse files
committed
✨ Add Table components
1 parent 1701337 commit dad3a34

File tree

10 files changed

+422
-2
lines changed

10 files changed

+422
-2
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ import { Accordion } from 'webcoreui/react'
150150
- [Rating](https://github.com/Frontendland/webcoreui/tree/main/src/components/Rating)
151151
- [Spinner](https://github.com/Frontendland/webcoreui/tree/main/src/components/Spinner)
152152
- [Switch](https://github.com/Frontendland/webcoreui/tree/main/src/components/Switch)
153+
- [Table](https://github.com/Frontendland/webcoreui/tree/main/src/components/Table)
153154
- [Tabs](https://github.com/Frontendland/webcoreui/tree/main/src/components/Tabs)
154155
- [Timeline](https://github.com/Frontendland/webcoreui/blob/main/src/pages/timeline.astro)
155156
- [Toast](https://github.com/Frontendland/webcoreui/tree/main/src/components/Toast)

scripts/buildTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ const buildTypes = type => {
4141
'Icon',
4242
'Rating',
4343
'Spinner',
44+
'Table',
4445
'TimelineItem',
4546
'Progress'
4647
]

src/components/Table/Table.astro

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
import type { TableProps } from './table'
3+
import './table.scss'
4+
5+
interface Props extends TableProps {}
6+
7+
const {
8+
headings,
9+
footer,
10+
data,
11+
hover,
12+
striped,
13+
offsetStripe,
14+
compact,
15+
className
16+
} = Astro.props
17+
18+
const classes = [
19+
'w-table',
20+
hover && 'hover',
21+
striped && `striped-${striped}s`,
22+
offsetStripe && 'offset',
23+
compact && 'compact',
24+
className
25+
]
26+
---
27+
28+
<div class:list={classes}>
29+
<table>
30+
{headings?.length && (
31+
<thead>
32+
<tr>
33+
{headings.map(heading => (
34+
<th>{heading}</th>
35+
))}
36+
</tr>
37+
</thead>
38+
)}
39+
<tbody>
40+
{data.map(row => (
41+
<tr>
42+
{row.map(column => (
43+
<td>
44+
<Fragment set:html={column} />
45+
</td>
46+
))}
47+
</tr>
48+
))}
49+
</tbody>
50+
{footer?.length && (
51+
<tfoot>
52+
<tr>
53+
{footer.map(data => (
54+
<td>{data}</td>
55+
))}
56+
</tr>
57+
</tfoot>
58+
)}
59+
</table>
60+
</div>

src/components/Table/Table.svelte

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<script lang="ts">
2+
import type { TableProps } from './table'
3+
import './table.scss'
4+
5+
export let headings: TableProps['headings'] = []
6+
export let footer: TableProps['footer'] = []
7+
export let data: TableProps['data'] = []
8+
export let hover: TableProps['hover'] = false
9+
export let striped: TableProps['striped'] = null
10+
export let offsetStripe: TableProps['offsetStripe'] = false
11+
export let compact: TableProps['compact'] = false
12+
export let className: TableProps['className'] = ''
13+
14+
const classes = [
15+
'w-table',
16+
hover && 'hover',
17+
striped && `striped-${striped}s`,
18+
offsetStripe && 'offset',
19+
compact && 'compact',
20+
className
21+
].filter(Boolean).join(' ')
22+
</script>
23+
24+
<div class={classes}>
25+
<table>
26+
{#if headings?.length}
27+
<thead>
28+
<tr>
29+
{#each headings as heading}
30+
<th>{heading}</th>
31+
{/each}
32+
</tr>
33+
</thead>
34+
{/if}
35+
<tbody>
36+
{#each data as row}
37+
<tr>
38+
{#each row as column}
39+
<td>{@html column}</td>
40+
{/each}
41+
</tr>
42+
{/each}
43+
</tbody>
44+
{#if footer?.length}
45+
<tfoot>
46+
<tr>
47+
{#each footer as data}
48+
<td>{data}</td>
49+
{/each}
50+
</tr>
51+
</tfoot>
52+
{/if}
53+
</table>
54+
</div>

src/components/Table/Table.tsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import React from 'react'
2+
import type { TableProps } from './table'
3+
4+
import './table.scss'
5+
6+
const Table = ({
7+
headings,
8+
footer,
9+
data,
10+
hover,
11+
striped,
12+
offsetStripe,
13+
compact,
14+
className
15+
}: TableProps) => {
16+
const classes = [
17+
'w-table',
18+
hover && 'hover',
19+
striped && `striped-${striped}s`,
20+
offsetStripe && 'offset',
21+
compact && 'compact',
22+
className
23+
].filter(Boolean).join(' ')
24+
25+
return (
26+
<div className={classes}>
27+
<table>
28+
{headings?.length && (
29+
<thead>
30+
<tr>
31+
{headings.map((heading, index) => (
32+
<th key={index}>{heading}</th>
33+
))}
34+
</tr>
35+
</thead>
36+
)}
37+
<tbody>
38+
{data.map((row, rowIndex) => (
39+
<tr key={rowIndex}>
40+
{row.map((column, columnIndex) => (
41+
<td
42+
key={columnIndex}
43+
dangerouslySetInnerHTML={{ __html: column }}
44+
/>
45+
))}
46+
</tr>
47+
))}
48+
</tbody>
49+
{footer?.length && (
50+
<tfoot>
51+
<tr>
52+
{footer.map((data, index) => (
53+
<td key={index}>{data}</td>
54+
))}
55+
</tr>
56+
</tfoot>
57+
)}
58+
</table>
59+
</div>
60+
)
61+
}
62+
63+
export default Table

src/components/Table/table.scss

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
@import '../../scss/config.scss';
2+
3+
.w-table {
4+
overflow-x: auto;
5+
6+
table {
7+
width: 100%;
8+
border-collapse: collapse;
9+
text-align: left;
10+
font-size: 16px;
11+
}
12+
13+
thead,
14+
tfoot {
15+
font-family: Bold;
16+
}
17+
18+
th,
19+
td {
20+
padding: 5px 10px;
21+
white-space: nowrap;
22+
}
23+
24+
thead,
25+
tr {
26+
border-bottom: 1px solid #252525;
27+
28+
&:last-child {
29+
border-bottom: 0;
30+
}
31+
}
32+
33+
a {
34+
text-decoration: underline;
35+
}
36+
37+
tfoot,
38+
&.hover tr:hover,
39+
&.striped-rows tbody tr:nth-child(odd),
40+
&.striped-rows.offset tbody tr:nth-child(even),
41+
&.striped-columns td:nth-child(odd),
42+
&.striped-columns.offset td:nth-child(even) {
43+
background: #111;
44+
}
45+
46+
&.striped-rows tr,
47+
&.striped-rows thead,
48+
&.striped-columns tr,
49+
&.striped-columns thead {
50+
border-bottom: 0;
51+
}
52+
53+
&.striped-rows.offset tbody tr:nth-child(odd),
54+
&.striped-rows.offset tfoot,
55+
&.striped-columns.offset td:nth-child(odd),
56+
&.striped-columns tfoot {
57+
background: transparent;
58+
}
59+
60+
&.compact {
61+
th, td {
62+
padding: 3px 10px;
63+
}
64+
}
65+
}

src/components/Table/table.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export type TableProps = {
2+
headings?: string[]
3+
footer?: string[]
4+
data: string[][]
5+
hover?: boolean
6+
striped?: 'column' | 'row' | null
7+
offsetStripe?: boolean
8+
compact?: boolean
9+
className?: string
10+
}

src/pages/index.astro

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import Radio from '@components/Radio/Radio.astro'
1515
import Rating from '@components/Rating/Rating.astro'
1616
import Spinner from '@components/Spinner/Spinner.astro'
1717
import Switch from '@components/Switch/Switch.astro'
18+
import Table from '@components/Table/Table.astro'
1819
import Tabs from '@components/Tabs/Tabs.astro'
1920
import Timeline from '@components/Timeline/Timeline.astro'
2021
import TimelineItem from '@components/TimelineItem/TimelineItem.astro'
@@ -133,6 +134,12 @@ const tabItems = [{
133134
<CardWrapper title="Switch" href="/switch">
134135
<Switch toggled={true} />
135136
</CardWrapper>
137+
<CardWrapper title="Table" href="/table">
138+
<Table
139+
headings={['ID', 'Name']}
140+
data={[['1', 'John Doe']]}
141+
/>
142+
</CardWrapper>
136143
<CardWrapper title="Tabs" href="/tabs">
137144
<Tabs items={tabItems} theme="boxed" />
138145
</CardWrapper>

0 commit comments

Comments
 (0)