Skip to content

Commit

Permalink
default format for arrays, objects, null and explicit undefined, in t…
Browse files Browse the repository at this point in the history
…ables

closes #166 #164
  • Loading branch information
Fil committed Feb 25, 2022
1 parent 86fa5c0 commit a0a80ff
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 6 deletions.
32 changes: 32 additions & 0 deletions src/format.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {format as isoformat} from "isoformat";
import {html} from "htl";

// Note: use formatAuto (or any other localized format) to present values to the
// user; stringify is only intended for machine values.
Expand All @@ -18,6 +19,33 @@ export const formatLocaleNumber = localize(locale => {
return value => value === 0 ? "0" : value.toLocaleString(locale); // handle negative zero
});

export function formatObjects(format, circular = true) {
return value => value === null ? gray("null")
: value === undefined ? gray("undefined")
: Number.isNaN(value) ? gray(NaN)
: circular && Array.isArray(value) ? formatArray(value)
: circular && isTypedArray(value) ? formatArray(value)
: value instanceof Date ? formatDate(value)
: circular && typeof value === "object" ? formatObject(value)
: format(value);
}

function isTypedArray(_) {
return _?.prototype?.__proto__?.constructor?.name == "TypedArray";
}

function formatObject(o) {
const subformat = formatObjects(formatAuto, false);
return `{${Object.entries(o).map(([key, value]) => `${key}: ${subformat(value)}`).join(", ")}}`;
}

function formatArray(value) {
const subformat = formatObjects(formatAuto, false);
const l = value.length;
value = Array.from({length: Math.min(30, l)}, (_, i) => subformat(value[i]));
return `[${value.join(", ")}${l > 30 ? "…" : "" }]`;
}

export const formatAuto = formatLocaleAuto();

export const formatNumber = formatLocaleNumber();
Expand Down Expand Up @@ -45,3 +73,7 @@ export function localize(f) {
let key = localize, value;
return (locale = "en") => locale === key ? value : (value = f(key = locale));
}

function gray(label) {
return html`<span class=gray>${label}`;
}
4 changes: 4 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,10 @@ form.__ns__-table {
padding: 3px 6.5px 3px 0;
}

.__ns__-table td .gray {
color: #888;
}

.__ns__-table tr > :not(:first-of-type) {
padding-left: var(--length2);
}
Expand Down
12 changes: 6 additions & 6 deletions src/table.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {html} from "htl";
import {arrayify, maybeColumns} from "./array.js";
import {length} from "./css.js";
import {formatDate, formatLocaleAuto, formatLocaleNumber} from "./format.js";
import {formatDate, formatLocaleAuto, formatLocaleNumber, formatObjects} from "./format.js";
import {newId} from "./id.js";
import {identity} from "./identity.js";
import {defined, ascending, descending} from "./sort.js";
import {ascending, descending} from "./sort.js";

const rowHeight = 22;

Expand Down Expand Up @@ -130,8 +130,8 @@ function initialize(
input.value = i;
if (d != null) for (let j = 0; j < columns.length; ++j) {
let column = columns[j];
if (!(column in d)) continue;
let value = d[column];
if (!defined(value)) continue;
value = format[column](value, i, data);
if (!(value instanceof Node)) value = document.createTextNode(value);
itr.childNodes[j + 1].appendChild(value);
Expand Down Expand Up @@ -334,9 +334,9 @@ function formatof(base = {}, data, columns, locale) {
continue;
}
switch (type(data, column)) {
case "number": format[column] = formatLocaleNumber(locale); break;
case "date": format[column] = formatDate; break;
default: format[column] = formatLocaleAuto(locale); break;
case "number": format[column] = formatObjects(formatLocaleNumber(locale)); break;
case "date": format[column] = formatObjects(formatDate); break;
default: format[column] = formatObjects(formatLocaleAuto(locale)); break;
}
}
return format;
Expand Down
23 changes: 23 additions & 0 deletions test/inputs/tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,26 @@ export function tableCustomHeader() {
export function tableCustomHeaderHtml() {
return Inputs.table([{foo: "hello"}], {header: {foo: html`<i>Foo</i>`}});
}

export function tableVariousObjects() {
return Inputs.table([
{A: null},
{A: undefined}, // explicit undefined
{},
{A: ["a", "b"]},
{A: Float32Array.from([1, 2, 3])},
{A: Array.from({length: 30}, (_, i)=> i)},
{A: Array.from({length: 31}, (_, i)=> i)},
{A: [[1, 2], ["a"]]},
{A: {key: "value"}},
{A: {key: {key: "value"}}}
]);
}

export function tableCircular() {
const o = {};
o.circular = o;
return Inputs.table([
{A: o}
]);
}
17 changes: 17 additions & 0 deletions test/output/tableCircular.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<form class="__ns__ __ns__-table" id="__ns__-1" style="max-height: 274px;">
<table style="table-layout: fixed;">
<thead>
<tr>
<th><input type="checkbox"></th>
<th title="A"><span></span>A</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" value="0"></td>
<td>{circular: [object Object]}</td>
</tr>
</tbody>
</table>
<style></style>
</form>
53 changes: 53 additions & 0 deletions test/output/tableVariousObjects.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<form class="__ns__ __ns__-table" id="__ns__-1" style="max-height: 274px;">
<table style="table-layout: fixed;">
<thead>
<tr>
<th><input type="checkbox"></th>
<th title="A"><span></span>A</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="checkbox" value="0"></td>
<td><span class="gray">null</span></td>
</tr>
<tr>
<td><input type="checkbox" value="1"></td>
<td><span class="gray">undefined</span></td>
</tr>
<tr>
<td><input type="checkbox" value="2"></td>
<td></td>
</tr>
<tr>
<td><input type="checkbox" value="3"></td>
<td>[a, b]</td>
</tr>
<tr>
<td><input type="checkbox" value="4"></td>
<td>{0: 1, 1: 2, 2: 3}</td>
</tr>
<tr>
<td><input type="checkbox" value="5"></td>
<td>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29]</td>
</tr>
<tr>
<td><input type="checkbox" value="6"></td>
<td>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29…]</td>
</tr>
<tr>
<td><input type="checkbox" value="7"></td>
<td>[1,2, a]</td>
</tr>
<tr>
<td><input type="checkbox" value="8"></td>
<td>{key: value}</td>
</tr>
<tr>
<td><input type="checkbox" value="9"></td>
<td>{key: [object Object]}</td>
</tr>
</tbody>
</table>
<style></style>
</form>

0 comments on commit a0a80ff

Please sign in to comment.