Skip to content

Commit 34a24df

Browse files
authored
Merge pull request #149 from silinternational/feature/add-Datatable-checkbox
Add datatable checkbox component/story and improve TabBar story docs
2 parents 1fd1120 + 01aa5d0 commit 34a24df

File tree

8 files changed

+214
-26
lines changed

8 files changed

+214
-26
lines changed
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
<script>
2+
import { generateRandomID } from '../../../random'
3+
24
export let clickable = false
5+
6+
const rowId = generateRandomID('row-id-')
37
</script>
48

5-
<tr on:click on:keydown class="mdc-data-table__row {$$props.class}" class:pointer={clickable}>
6-
<slot />
9+
<tr on:click on:keydown data-row-id={rowId} class="mdc-data-table__row {$$props.class}" class:pointer={clickable}>
10+
<slot {rowId} />
711
</tr>

components/mdc/Datatable/Datatable.svelte

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,45 @@
22
<script>
33
import { MDCDataTable } from '@material/data-table'
44
import { createEventDispatcher, onMount } from 'svelte'
5-
5+
/**
6+
* @prop {string}
7+
* @description used for aria-label
8+
*/
69
export let label = ''
10+
/**
11+
* @prop {number}
12+
* @description used to register new Datatable Checkboxes when value changes
13+
*/
14+
export let numberOfCheckboxes = 0
715
816
const dispatch = createEventDispatcher()
17+
let dataTable = {}
918
1019
let element = {}
1120
1221
onMount(() => {
13-
const dataTable = new MDCDataTable(element)
22+
dataTable = new MDCDataTable(element)
1423
1524
dataTable.listen('MDCDataTable:sorted', (event) => {
1625
dispatch('sorted', event.detail)
1726
})
1827
19-
// This does not work because of an MDC bug. See https://github.com/material-components/material-components-web/issues/6385
20-
// If checkboxes are needed, check for a release of the PR linked to the above issue, or pull in the destroy code here.
21-
//return () => dataTable.destroy()
28+
dataTable.listen('MDCDataTable:selectedAll', () => {
29+
dispatch('selectedAll')
30+
})
31+
32+
dataTable.listen('MDCDataTable:unselectedAll', () => {
33+
dispatch('unselectedAll')
34+
})
35+
36+
dataTable.listen('MDCDataTable:rowSelectionChanged', (event) => {
37+
dispatch('rowSelectionChanged', event.detail)
38+
})
39+
40+
return () => dataTable.destroy()
2241
})
42+
43+
$: numberOfCheckboxes && dataTable?.layout()
2344
</script>
2445
2546
<div class="mdc-data-table w-100 {$$props.class}" bind:this={element}>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<script>
2+
import { createEventDispatcher, onMount } from 'svelte'
3+
4+
export let disabled = false
5+
export let rowId = ''
6+
7+
onMount(() => dispatch('mounted'))
8+
9+
const dispatch = createEventDispatcher()
10+
</script>
11+
12+
<td class="mdc-data-table__cell mdc-data-table__cell--checkbox" on:click>
13+
<div class="mdc-checkbox mdc-data-table__row-checkbox">
14+
<input type="checkbox" class="mdc-checkbox__native-control" aria-labelledby={rowId} {disabled} />
15+
<div class="mdc-checkbox__background">
16+
<svg class="mdc-checkbox__checkmark" viewBox="0 0 24 24">
17+
<path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" />
18+
</svg>
19+
<div class="mdc-checkbox__mixedmark" />
20+
</div>
21+
<div class="mdc-checkbox__ripple" />
22+
</div>
23+
</td>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<th class="mdc-data-table__header-cell mdc-data-table__header-cell--checkbox" role="columnheader" scope="col">
2+
<div class="mdc-checkbox mdc-data-table__header-row-checkbox">
3+
<input type="checkbox" class="mdc-checkbox__native-control" aria-label="Toggle all rows" />
4+
<div class="mdc-checkbox__background">
5+
<svg class="mdc-checkbox__checkmark" viewBox="0 0 24 24">
6+
<path class="mdc-checkbox__checkmark-path" fill="none" d="M1.73,12.91 8.1,19.28 22.79,4.59" />
7+
</svg>
8+
<div class="mdc-checkbox__mixedmark" />
9+
</div>
10+
<div class="mdc-checkbox__ripple" />
11+
</div>
12+
</th>
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
@use '@material/data-table/data-table';
1+
@use "@material/checkbox"; // Required only for data table with row selection.
2+
@use "@material/data-table/data-table";
23

4+
@include checkbox.core-styles;
35
@include data-table.core-styles;
46
@include data-table.theme-baseline;

components/mdc/Datatable/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@ import DataRow from './DataRow.svelte'
55
import DataRowItem from './DataRowItem.svelte'
66
import Header from './Header.svelte'
77
import HeaderItem from './HeaderItem.svelte'
8+
import DatatableCheckbox from './DatatableCheckbox.svelte'
9+
import DatatableCheckboxHeader from './DatatableCheckboxHeader.svelte'
810

911
Datatable.Data = Data
1012
Datatable.Data.Row = DataRow
1113
Datatable.Data.Row.Item = DataRowItem
1214
Datatable.Header = Header
1315
Datatable.Header.Item = HeaderItem
16+
Datatable.Header.Checkbox = DatatableCheckboxHeader
17+
Datatable.Checkbox = DatatableCheckbox
1418

1519
export default Datatable

stories/Datatable.stories.svelte

Lines changed: 135 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
<script>
2-
import { Meta, Template, Story } from '@storybook/addon-svelte-csf'
2+
import { Meta, Story } from '@storybook/addon-svelte-csf'
33
import { Datatable, isAboveMobile, isAboveTablet, Progress } from '../components/mdc'
4-
import { copyAndModifyArgs } from './helpers.js'
54
import { onMount } from 'svelte'
65
76
const args = {
87
class: '', //only works for global classes
9-
onSorted: () => {},
10-
clickable: false,
8+
'on:sorted': (e) => alert('you sorted the table'),
9+
'on:selectedAll': (e) => alert('you selected all rows'),
10+
'on:unselectedAll': (e) => alert('you unselected all rows'),
11+
'on:rowSelectionChanged': (e) => alert(`row ${e.detail.rowId} was ${e.detail.selected ? 'selected' : 'unselected'}`),
12+
'on:click': (e) => alert(`you clicked on row ${e.detail}`),
1113
}
1214
1315
let loaded = false
16+
let numberOfCheckboxes = 0
1417
1518
onMount(() =>
1619
setTimeout(() => {
@@ -19,10 +22,23 @@ onMount(() =>
1922
)
2023
</script>
2124

22-
<Meta title="Molecule/Datatable" component={Datatable} />
25+
<Meta
26+
title="Molecule/Datatable"
27+
component={Datatable}
28+
argTypes={{
29+
label: { control: 'text' },
30+
clickable: { control: 'boolean' },
31+
}}
32+
/>
2333

24-
<Template let:args>
25-
<Datatable {...args} on:sorted={args.onSorted}>
34+
<Story name="Default" {args}>
35+
<Datatable
36+
class={args.class}
37+
on:sorted={args['on:sorted']}
38+
on:rowSelectionChanged={args['on:rowSelectionChanged']}
39+
on:unselectedAll={args['on:unselectedAll']}
40+
on:selectedAll={args['on:selectedAll']}
41+
>
2642
<Datatable.Header>
2743
<Datatable.Header.Item class={isAboveTablet() ? 'w-50' : ''}>Name</Datatable.Header.Item>
2844
<Datatable.Header.Item>Date</Datatable.Header.Item>
@@ -51,10 +67,118 @@ onMount(() =>
5167
</Datatable.Data.Row>
5268
</Datatable.Data>
5369
</Datatable>
54-
</Template>
70+
</Story>
5571

56-
<Story name="Default" {args} />
72+
<Story name="Checkbox" {args}>
73+
<Datatable
74+
{numberOfCheckboxes}
75+
class={args.class}
76+
on:sorted={args['on:sorted']}
77+
on:rowSelectionChanged={args['on:rowSelectionChanged']}
78+
on:unselectedAll={args['on:unselectedAll']}
79+
on:selectedAll={args['on:selectedAll']}
80+
>
81+
<Datatable.Header>
82+
<Datatable.Header.Checkbox />
83+
<Datatable.Header.Item class={isAboveTablet() ? 'w-50' : ''}>Name</Datatable.Header.Item>
84+
<Datatable.Header.Item>Date</Datatable.Header.Item>
85+
</Datatable.Header>
86+
87+
<Datatable.Data>
88+
<Datatable.Data.Row clickable={args.clickable} let:rowId>
89+
<Datatable.Checkbox on:mounted={() => numberOfCheckboxes++} {rowId} />
90+
<Datatable.Data.Row.Item>item</Datatable.Data.Row.Item>
91+
<Datatable.Data.Row.Item>today</Datatable.Data.Row.Item>
92+
</Datatable.Data.Row>
93+
94+
<Datatable.Data.Row>
95+
<Datatable.Checkbox on:mounted={() => numberOfCheckboxes++} />
96+
<Datatable.Data.Row.Item>item2</Datatable.Data.Row.Item>
97+
<Datatable.Data.Row.Item>tomorrow</Datatable.Data.Row.Item>
98+
</Datatable.Data.Row>
99+
100+
<Datatable.Data.Row>
101+
<Datatable.Checkbox on:mounted={() => numberOfCheckboxes++} />
102+
<Datatable.Data.Row.Item colspan={isAboveMobile() ? 6 : 2}>
103+
{#if loaded}
104+
Done loading
105+
{:else}
106+
Loading...
107+
<Progress.Linear barColorProvided={false} indeterminate />
108+
{/if}
109+
</Datatable.Data.Row.Item>
110+
</Datatable.Data.Row>
111+
</Datatable.Data>
112+
</Datatable>
113+
</Story>
114+
115+
<Story name="Label">
116+
<Datatable
117+
class={args.class}
118+
label={'Label'}
119+
on:sorted={args['on:sorted']}
120+
on:rowSelectionChanged={args['on:rowSelectionChanged']}
121+
on:unselectedAll={args['on:unselectedAll']}
122+
on:selectedAll={args['on:selectedAll']}
123+
>
124+
<Datatable.Header>
125+
<Datatable.Header.Item class={isAboveTablet() ? 'w-50' : ''}>Name</Datatable.Header.Item>
126+
<Datatable.Header.Item>Date</Datatable.Header.Item>
127+
</Datatable.Header>
128+
129+
<Datatable.Data>
130+
<Datatable.Data.Row clickable={args.clickable}>
131+
<Datatable.Data.Row.Item>item</Datatable.Data.Row.Item>
132+
<Datatable.Data.Row.Item>today</Datatable.Data.Row.Item>
133+
</Datatable.Data.Row>
134+
135+
<Datatable.Data.Row>
136+
<Datatable.Data.Row.Item>item2</Datatable.Data.Row.Item>
137+
<Datatable.Data.Row.Item>tomorrow</Datatable.Data.Row.Item>
138+
</Datatable.Data.Row>
139+
140+
<Datatable.Data.Row>
141+
<Datatable.Data.Row.Item colspan={isAboveMobile() ? 6 : 2}>
142+
{#if loaded}
143+
Done loading
144+
{:else}
145+
Loading...
146+
<Progress.Linear barColorProvided={false} indeterminate />
147+
{/if}
148+
</Datatable.Data.Row.Item>
149+
</Datatable.Data.Row>
150+
</Datatable.Data>
151+
</Datatable>
152+
</Story>
153+
154+
<Story name="Clickable row">
155+
<Datatable class={args.class} on:sorted={args['on:sorted']}>
156+
<Datatable.Header>
157+
<Datatable.Header.Item class={isAboveTablet() ? 'w-50' : ''}>Name</Datatable.Header.Item>
158+
<Datatable.Header.Item>Date</Datatable.Header.Item>
159+
</Datatable.Header>
160+
161+
<Datatable.Data>
162+
<Datatable.Data.Row on:click={args['on:click']} clickable="true}">
163+
<Datatable.Data.Row.Item>item</Datatable.Data.Row.Item>
164+
<Datatable.Data.Row.Item>today</Datatable.Data.Row.Item>
165+
</Datatable.Data.Row>
57166

58-
<Story name="Label" args={copyAndModifyArgs(args, { label: 'label' })} />
167+
<Datatable.Data.Row on:click={args['on:click']} clickable="true}">
168+
<Datatable.Data.Row.Item>item2</Datatable.Data.Row.Item>
169+
<Datatable.Data.Row.Item>tomorrow</Datatable.Data.Row.Item>
170+
</Datatable.Data.Row>
59171

60-
<Story name="Clickable row" args={copyAndModifyArgs(args, { clickable: 'true' })} />
172+
<Datatable.Data.Row on:click={args['on:click']} clickable="true}">
173+
<Datatable.Data.Row.Item colspan={isAboveMobile() ? 6 : 2}>
174+
{#if loaded}
175+
Done loading
176+
{:else}
177+
Loading...
178+
<Progress.Linear barColorProvided={false} indeterminate />
179+
{/if}
180+
</Datatable.Data.Row.Item>
181+
</Datatable.Data.Row>
182+
</Datatable.Data>
183+
</Datatable>
184+
</Story>

stories/TabBar.stories.svelte

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script>
2-
import { Meta, Template, Story } from '@storybook/addon-svelte-csf'
2+
import { Meta, Story } from '@storybook/addon-svelte-csf'
33
import { TabBar } from '../components/mdc'
44
55
const args = {
@@ -9,16 +9,14 @@ const args = {
99
}
1010
</script>
1111

12-
<Meta title="Atoms/TabBar" component={TabBar} />
12+
<Meta title="Molecule/TabBar" component={TabBar} />
1313

14-
<Template let:args>
15-
<TabBar {...args}>
14+
<Story name="Default" {args}>
15+
<TabBar tab={args.tab}>
1616
<TabBar.Scroller>
1717
<TabBar.Tab label="tab 1" on:click={args['on:click']} active={args.tab === 0} />
1818
<TabBar.Tab label="tab 2" on:click={args['on:click']} active={args.tab === 1} />
1919
<TabBar.Tab label="tab 3" on:click={args['on:click']} active={args.tab === 2} />
2020
</TabBar.Scroller>
2121
</TabBar>
22-
</Template>
23-
24-
<Story name="Default" {args} />
22+
</Story>

0 commit comments

Comments
 (0)