Skip to content

Commit ca5fbfb

Browse files
committed
Updated tables
1 parent 4388e3d commit ca5fbfb

File tree

11 files changed

+164
-27
lines changed

11 files changed

+164
-27
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jspm_packages/
2626
.next
2727
.nuxt
2828
dist
29+
build
2930
.cache/
3031
.vuepress/dist
3132
.serverless/

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"eslint.experimental.useFlatConfig": true,
2+
"eslint.useFlatConfig": true,
33
"eslint.options": { "overrideConfigFile": "./config/eslint.config.mjs" },
44
}

config/esbuild.table.mjs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import esbuild from 'esbuild';
2+
3+
const commonOptions = {
4+
outdir: 'dist',
5+
format: 'esm',
6+
bundle: true,
7+
loader: {
8+
'.svg': 'file',
9+
'.woff': 'file',
10+
'.woff2': 'file',
11+
'.ttf': 'file',
12+
'.otf': 'file',
13+
'.html': 'copy',
14+
'.json': 'copy',
15+
},
16+
logLevel: 'info',
17+
entryPoints: [],
18+
};
19+
20+
// Add the table
21+
commonOptions.entryPoints.push('example/table/index.js', 'example/table/index.html');
22+
23+
// Build the table, and optionally serve it in development
24+
if (process.env.NODE_ENV === 'production') {
25+
await esbuild.build({
26+
...commonOptions,
27+
minify: true,
28+
sourcemap: false,
29+
}).catch(() => process.exit(1));
30+
} else if (process.env.NODE_ENV === 'development') {
31+
let ctx = await esbuild.context({
32+
...commonOptions,
33+
minify: false,
34+
sourcemap: true,
35+
})
36+
let { host, port } = await ctx.serve({
37+
servedir: commonOptions.outdir,
38+
});
39+
await ctx.watch();
40+
}

example/esbuild.js

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

example/table/index.html

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="utf-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>Nanoradio</title>
8+
<script type="module" src="index.js" defer></script>
9+
<link href="index.css" rel="stylesheet">
10+
<style type="text/css">
11+
.content-scroll {
12+
overflow-y: scroll;
13+
}
14+
body {
15+
overflow: hidden;
16+
}
17+
</style>
18+
</head>
19+
20+
<body>
21+
<js-canvas>
22+
<js-nav vertical>
23+
<js-navitem>Home</js-navitem>
24+
</js-nav>
25+
<js-content class="content-scroll">
26+
<js-table id="items-table" data="#items-data">
27+
<js-tablehead body="#items-table"></js-tablehead>
28+
<js-tablecol name="author">Author</js-tablecol>
29+
<js-tablecol name="pubdate">Date</js-tablecol>
30+
<js-tablecol name="title">Title</js-tablecol>
31+
<js-tablecol name="desc">Description</js-tablecol>
32+
<js-tablecol name="media">Media</js-tablecol>
33+
</js-table>
34+
</js-content>
35+
<!-- data source and model for items -->
36+
<js-provider id="items-provider" path="http://cm5.lan:8000/feed/v1/document"></js-provider>
37+
<js-array id="items-data" provider="#items-provider" select="body"></js-array>
38+
</js-canvas>
39+
</body>
40+
41+
</html>

example/table/index.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// This file defines all the styles and elements used for the web components
2+
import '../../src/index';
3+
4+
/* Code to reload in the esbuild serve development environment */
5+
window.addEventListener('load', () => {
6+
// eslint-disable-next-line no-restricted-globals
7+
new EventSource('/esbuild').addEventListener('change', () => location.reload());
8+
});

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"description": "Javascript Framework",
55
"main": "dist/index.js",
66
"scripts": {
7-
"geojson-dev": "rm -fr dist && install -d dist && NODE_ENV=development node config/esbuild.geojson.mjs",
8-
"build": "rm -fr dist && install -d dist && NODE_ENV=production node config/esbuild.geojson.mjs",
7+
"dev": "NODE_ENV=development node config/esbuild.table.mjs",
8+
"build": "rm -fr dist && install -d dist && NODE_ENV=production node esbuild.table.mjs",
99
"lint": "ESLINT_USE_FLAT_CONFIG=true eslint -c config/eslint.config.mjs --cache --fix ./src/**/*.js",
1010
"docs": "jsdoc -c config/jsdoc.config.json"
1111
},

src/element/TableColumnElement.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { LitElement } from "lit";
2+
3+
/**
4+
* @class TableColumnElement
5+
*
6+
* This class provides a table column element, for rendering
7+
* a table cell. It also provides properties for the column.
8+
*
9+
* @example
10+
* <js-tablecol name="id">ID</js-tablecol>
11+
*/
12+
export class TableColumnElement extends LitElement {
13+
static get localName() {
14+
return 'js-tablecol';
15+
}
16+
17+
static get properties() {
18+
return {
19+
name: { type: String, reflect: true },
20+
};
21+
}
22+
}

src/element/TableBodyElement.js renamed to src/element/TableElement.js

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
import { LitElement, html, css } from 'lit';
22
import { EventType } from '../core/EventType';
33
import { TableHeadElement } from './TableHeadElement';
4+
import { TableColumnElement } from './TableColumnElement';
45

56
/**
6-
* @class TableBodyElement
7+
* @class TableElement
78
*
8-
* This class provides a table body element.
9+
* This class provides a table element, in which the header, footer
10+
* and columns are rendered.
911
*
1012
* @example
11-
* <js-tablebody data="#data-source-id"></js-tablebody>
13+
* <js-table data="#data-source-id"><!-- .... --></js-table>
1214
*/
13-
export class TableBodyElement extends LitElement {
15+
export class TableElement extends LitElement {
1416
#data = null;
1517

1618
#head = null;
1719

1820
static get localName() {
19-
return 'js-tablebody';
21+
return 'js-table';
2022
}
2123

2224
static get properties() {
@@ -48,8 +50,7 @@ export class TableBodyElement extends LitElement {
4850
th {
4951
text-transform: capitalize;
5052
}
51-
.wrap {
52-
max-height: 40px;
53+
.cell {
5354
overflow: hidden;
5455
}
5556
code, pre {
@@ -92,6 +93,21 @@ export class TableBodyElement extends LitElement {
9293
firstUpdated() {
9394
// Set the table header
9495
this.#head = this.querySelector(TableHeadElement.localName);
96+
97+
// Get the table columns
98+
const elements = this.childNodes;
99+
for (let i = 0; i < elements.length; i += 1) {
100+
if (elements[i] instanceof TableColumnElement) {
101+
const name = elements[i].getAttribute('name');
102+
if (name && name !== '') {
103+
// Append the column to the list
104+
if (this.columns.indexOf(name) === -1) {
105+
this.columns.push(elements[i].getAttribute('name'));
106+
}
107+
// TODO: Set this column as the renderer
108+
}
109+
}
110+
}
95111
}
96112

97113
render() {
@@ -112,25 +128,35 @@ export class TableBodyElement extends LitElement {
112128
}
113129

114130
#renderColumns(row) {
115-
const columns = [];
116-
131+
const cells = [];
117132
if (row instanceof Object) {
118133
Object.keys(row).forEach((key) => {
119134
if (this.columns.indexOf(key) === -1) {
120135
this.columns.push(key);
121136
}
122-
columns.push(html`<td><div class="wrap">${this.#renderCell(row[key])}</div></td>`);
137+
cells[this.columns.indexOf(key)] = html`<td><div class="cell">${this.#renderCell(row[key])}</div></td>`;
123138
});
124139
} else {
125140
this.columns.push('value');
126-
columns.push(html`<td>${this.#renderCell(row)}</td>`);
141+
cells.push(html`<td>${this.#renderCell(row)}</td>`);
127142
}
128143

129-
return columns;
144+
// Any missing columns we fill
145+
for (let i = 0; i < this.columns.length; i += 1) {
146+
if (!cells[i]) {
147+
cells[i] = html`<td></td>`;
148+
}
149+
}
150+
151+
// Return cells for rendering in a row
152+
return cells;
130153
}
131154

132155
// eslint-disable-next-line class-methods-use-this
133156
#renderCell(cell) {
157+
if (cell === null || cell === undefined || cell === '') {
158+
return html`nil`;
159+
}
134160
if (cell instanceof Object) {
135161
return html`<code>${JSON.stringify(cell)}</code>`;
136162
}

src/element/TableHeadElement.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ export class TableHeadElement extends LitElement {
5656

5757
#renderColumns(row) {
5858
const columns = [];
59-
for (const cell in row) {
60-
columns.push(html`<th>${this.#renderCell(row[cell])}</th>`);
61-
}
59+
Object.keys(row).forEach((key) => {
60+
columns.push(html`<th>${this.#renderCell(row[key])}</th>`);
61+
});
6262
return columns;
6363
}
6464

src/element/element.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
// Elements
2-
import { TableBodyElement } from './TableBodyElement';
3-
import { TableHeadElement } from './TableHeadElement';
42
import { ButtonElement } from './ButtonElement';
53
import { CloseButtonElement } from './CloseButtonElement';
64
import { TagElement } from './TagElement';
@@ -12,9 +10,11 @@ import { NavElement } from './NavElement';
1210
import { NavItemElement } from './NavItemElement';
1311
import { NavSpacerElement } from './NavSpacerElement';
1412

13+
import { TableElement } from './TableElement';
14+
import { TableHeadElement } from './TableHeadElement';
15+
import { TableColumnElement } from './TableColumnElement';
16+
1517
// Define Web Components
16-
customElements.define(TableBodyElement.localName, TableBodyElement); // js-tablebody
17-
customElements.define(TableHeadElement.localName, TableHeadElement); // js-tablehead
1818
customElements.define(ButtonElement.localName, ButtonElement); // js-button
1919
customElements.define(CloseButtonElement.localName, CloseButtonElement); // js-close
2020
customElements.define(TagElement.localName, TagElement); // js-tag
@@ -25,3 +25,7 @@ customElements.define(ToastElement.localName, ToastElement); // js-toast
2525
customElements.define(NavElement.localName, NavElement); // js-nav
2626
customElements.define(NavItemElement.localName, NavItemElement); // js-navitem
2727
customElements.define(NavSpacerElement.localName, NavSpacerElement); // js-navspacer
28+
29+
customElements.define(TableElement.localName, TableElement); // js-table
30+
customElements.define(TableHeadElement.localName, TableHeadElement); // js-tablehead
31+
customElements.define(TableColumnElement.localName, TableColumnElement); // js-tablecol

0 commit comments

Comments
 (0)