Skip to content

Commit 924bfe7

Browse files
committed
Make all manual actions (button clicks) work
1 parent 84a283d commit 924bfe7

File tree

8 files changed

+215
-142
lines changed

8 files changed

+215
-142
lines changed

frameworks/keyed/fast/src/ActionTriggers.ts

Lines changed: 0 additions & 43 deletions
This file was deleted.

frameworks/keyed/fast/src/App.ts

Lines changed: 88 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import './index'; // import all our components
2-
import { customElement, FASTElement, html, attr, css, FAST, repeat } from '@microsoft/fast-element';
3-
import { DataItem, buildData } from './utils/build-dummy-data';
2+
import { customElement, FASTElement, html, observable, when } from '@microsoft/fast-element';
3+
import { RowItem, buildData } from './utils/build-dummy-data';
44

55
const template = html<BenchmarkApp>`
66
<div class="jumbotron">
@@ -10,30 +10,26 @@ const template = html<BenchmarkApp>`
1010
</div>
1111
<div class="col-md-6">
1212
<div class="row">
13-
<action-triggers></action-triggers>
13+
<action-triggers
14+
@action=${(x, c) => {
15+
x.onAction(c.event);
16+
}}
17+
></action-triggers>
1418
</div>
1519
</div>
1620
</div>
1721
</div>
18-
<table class="table table-hover table-striped test-data">
19-
<tbody id="tbody">
20-
${repeat(
21-
x => x.data,
22-
html<DataItem>`
23-
<tr data-id="${x => x.id}">
24-
<td class="col-md-1">${x => x.id}</td>
25-
<td class="col-md-4">
26-
<a class="lbl">${x => x.label}</a>
27-
</td>
28-
<td class="col-md-1">
29-
<a class="remove"> <span class="remove glyphicon glyphicon-remove" aria-hidden="true"></span></a>
30-
</td>
31-
<td class="col-md-6"></td>
32-
</tr>
33-
`
34-
)}
35-
</tbody>
36-
</table>
22+
${when(
23+
x => x.rows?.length,
24+
html`
25+
<data-table
26+
:rows=${x => x.rows}
27+
@action=${(x, c) => {
28+
x.onAction(c.event);
29+
}}
30+
></data-table>
31+
`
32+
)}
3733
`;
3834

3935
/**
@@ -49,10 +45,76 @@ const template = html<BenchmarkApp>`
4945
shadowOptions: null
5046
})
5147
export class BenchmarkApp extends FASTElement {
52-
data: DataItem[];
48+
@observable rows?: RowItem[];
5349

54-
constructor() {
55-
super();
56-
this.data = buildData();
50+
createOneThousandRows() {
51+
this.clear();
52+
this.rows = buildData();
53+
}
54+
55+
createTenThousandRows() {
56+
this.rows = buildData(10000);
57+
}
58+
59+
appendOneThousandRows() {
60+
const lastRowId = this.rows ? this.rows[this.rows.length - 1].id : 0;
61+
this.rows = this.rows ? this.rows.concat(buildData(1000, lastRowId)) : buildData();
62+
}
63+
64+
updateEveryTenthRowLabel() {
65+
if (!this.rows) return;
66+
67+
for (let i = 0; i < this.rows.length; i += 10) {
68+
this.rows[i].label += ' !!!';
69+
}
70+
71+
this.triggerRerender();
72+
}
73+
74+
clear() {
75+
this.rows = [];
76+
}
77+
78+
swapTwoRows() {
79+
if (!this.rows) return;
80+
81+
if (this.rows.length > 998) {
82+
const secondRow = this.rows[1];
83+
const secondToLastRow = this.rows[998];
84+
this.rows[1] = secondToLastRow;
85+
this.rows[998] = secondRow;
86+
}
87+
88+
this.triggerRerender();
89+
}
90+
91+
deleteSingleRow(rowId: number) {
92+
if (!this.rows) return;
93+
94+
const rowIndex = this.rows.findIndex(row => row.id === rowId);
95+
if (rowIndex > -1) {
96+
this.rows.splice(rowIndex, 1);
97+
}
98+
}
99+
100+
onAction(event: Event) {
101+
const eventDetails = (event as CustomEvent).detail;
102+
const { name, data } = eventDetails;
103+
104+
if (name === 'run') return this.createOneThousandRows();
105+
if (name === 'runlots') return this.createTenThousandRows();
106+
if (name === 'add') return this.appendOneThousandRows();
107+
if (name === 'update') return this.updateEveryTenthRowLabel();
108+
if (name === 'clear') return this.clear();
109+
if (name === 'swaprows') return this.swapTwoRows();
110+
if (name === 'deleteRow') return this.deleteSingleRow(data);
111+
112+
throw new Error('unknown event name!');
113+
}
114+
115+
private triggerRerender() {
116+
if (!this.rows) return;
117+
// trigger an update
118+
this.rows = this.rows.slice();
57119
}
58120
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import { customElement, FASTElement, html, attr, css, FAST } from '@microsoft/fast-element';
2+
3+
// NOTE - element IDs must remain here because the benchmark lib needs them
4+
const template = html<ActionTriggers>`
5+
<div class="col-sm-6 smallpad">
6+
<button type="button" class="btn btn-primary btn-block" id="run" @click=${x => x.run()}>Create 1,000 rows</button>
7+
</div>
8+
<div class="col-sm-6 smallpad">
9+
<button type="button" class="btn btn-primary btn-block" id="runlots" @click=${x => x.runlots()}>
10+
Create 10,000 rows
11+
</button>
12+
</div>
13+
<div class="col-sm-6 smallpad">
14+
<button type="button" class="btn btn-primary btn-block" id="add" @click=${x => x.add()}>Append 1,000 rows</button>
15+
</div>
16+
<div class="col-sm-6 smallpad">
17+
<button type="button" class="btn btn-primary btn-block" id="update" @click=${x => x.update()}>
18+
Update every 10th row
19+
</button>
20+
</div>
21+
<div class="col-sm-6 smallpad">
22+
<button type="button" class="btn btn-primary btn-block" id="clear" @click=${x => x.clear()}>Clear</button>
23+
</div>
24+
<div class="col-sm-6 smallpad">
25+
<button type="button" class="btn btn-primary btn-block" id="swaprows" @click=${x => x.swaprows()}>Swap Rows</button>
26+
</div>
27+
`;
28+
29+
/**
30+
* We're using `shadowOptions: null` to avoid Shadow DOM.
31+
* This way we can get global Bootstrap styles applied
32+
* because our component is rendered to Light DOM.
33+
*
34+
* https://www.fast.design/docs/fast-element/working-with-shadow-dom#shadow-dom-configuration
35+
*/
36+
@customElement({
37+
name: 'action-triggers',
38+
template,
39+
shadowOptions: null
40+
})
41+
export class ActionTriggers extends FASTElement {
42+
run() {
43+
this.$emit('action', { name: 'run' });
44+
}
45+
runlots() {
46+
this.$emit('action', { name: 'runlots' });
47+
}
48+
add() {
49+
this.$emit('action', { name: 'add' });
50+
}
51+
update() {
52+
this.$emit('action', { name: 'update' });
53+
}
54+
clear() {
55+
this.$emit('action', { name: 'clear' });
56+
}
57+
swaprows() {
58+
this.$emit('action', { name: 'swaprows' });
59+
}
60+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { customElement, FASTElement, html, repeat, observable } from '@microsoft/fast-element';
2+
import { RowItem } from 'src/utils/build-dummy-data';
3+
4+
const template = html<Table>`
5+
<table class="table table-hover table-striped test-data">
6+
<tbody id="tbody">
7+
${repeat(
8+
x => x.rows,
9+
html`
10+
<tr data-id="${row => row.id}">
11+
<td class="col-md-1">${row => row.id}</td>
12+
<td class="col-md-4">
13+
<a class="lbl">${row => row.label}</a>
14+
</td>
15+
<td class="col-md-1">
16+
<a class="remove" data-row-id="${row => row.id}" @click=${(x, c) => c.parent.handleClick(c.event)}>
17+
<span class="remove glyphicon glyphicon-remove" aria-hidden="true"></span
18+
></a>
19+
</td>
20+
<td class="col-md-6"></td>
21+
</tr>
22+
`,
23+
/**
24+
* List Rendering without view recycling
25+
*
26+
* With positioning set to true, and resycle set to false,
27+
* Fast wil re-render when internal properties of
28+
* RowItem[] change (e.g. id or label)
29+
*
30+
* https://www.fast.design/docs/fast-element/using-directives
31+
*/
32+
{ positioning: true, recycle: false }
33+
)}
34+
</tbody>
35+
</table>
36+
`;
37+
38+
/**
39+
* We're using `shadowOptions: null` to avoid Shadow DOM.
40+
* This way we can get global Bootstrap styles applied
41+
* because our component is rendered to Light DOM.
42+
*
43+
* https://www.fast.design/docs/fast-element/working-with-shadow-dom#shadow-dom-configuration
44+
*/
45+
@customElement({
46+
name: 'data-table',
47+
template,
48+
shadowOptions: null
49+
})
50+
export class Table extends FASTElement {
51+
@observable rows!: RowItem[];
52+
53+
handleClick(event: Event) {
54+
const currentTarget = event.currentTarget as HTMLElement;
55+
56+
if (currentTarget.classList.contains('remove')) {
57+
const rowId = currentTarget.dataset['rowId'];
58+
this.$emit('action', { name: 'deleteRow', data: Number(rowId) });
59+
}
60+
}
61+
}

frameworks/keyed/fast/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
export * from './ActionTriggers';
1+
export * from './components/ActionTriggers';
2+
export * from './components/Table';

frameworks/keyed/fast/src/main.ts

Lines changed: 0 additions & 24 deletions
This file was deleted.

frameworks/keyed/fast/src/todo-item.ts

Lines changed: 0 additions & 44 deletions
This file was deleted.

0 commit comments

Comments
 (0)