Skip to content

Commit 624696f

Browse files
Filmbostock
andauthored
0.11.0 (#262)
* hide and disable the selection inputs closes #136 * check inputof * document the select option * document inputs for vanilla, notebook and framework contexts closes observablehq/framework#344 * checkpoint * publish inputs.css; fix namespace * index.css * excise viewof; link new examples * module-alias stopped working * 0.11.0 * clean imports * update dependencies * fix main, module * fix description * adopt vite * link to framework * test & publish workflows * prettier arrow functions * simplify; remove width:0 * use inputs-3a86ea to match framework * fix link typo --------- Co-authored-by: Mike Bostock <[email protected]>
1 parent 5160ab7 commit 624696f

39 files changed

+1373
-3059
lines changed

.github/workflows/publish.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Publish
2+
3+
on:
4+
workflow_dispatch: {}
5+
release:
6+
types: [published]
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: read
13+
packages: write
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: 20
19+
registry-url: 'https://registry.npmjs.org'
20+
cache: 'yarn'
21+
- run: yarn --frozen-lockfile
22+
- run: yarn test
23+
- run: npm publish
24+
env:
25+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/test.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ on:
77
branches: [main]
88

99
jobs:
10-
build:
10+
test:
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v3
14-
- uses: actions/setup-node@v3
13+
- uses: actions/checkout@v4
14+
- uses: actions/setup-node@v4
1515
with:
16-
node-version: 16
16+
node-version: 20
17+
registry-url: 'https://registry.npmjs.org'
1718
cache: 'yarn'
1819
- run: yarn --frozen-lockfile
1920
- run: |

DEVELOPMENT.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@ cd inputs
88
yarn
99
```
1010

11-
Inputs is written in ES modules and uses [Snowpack](https://snowpack.dev/) for development; this means that you can edit the Inputs source code and examples, and they’ll update live as you save changes. To start, copy over the example scratch.html file:
11+
Inputs is written in ES modules and uses [Vite](https://vitejs.dev/) for development; this means that you can edit the Inputs source code and examples, and they’ll update live as you save changes. To start, copy over the example scratch.html file:
1212

1313
```
1414
mkdir scratch
1515
cp test/scratch.html scratch/index.html
1616
```
1717

18-
Then start Snowpack:
18+
Then start Vite:
1919

2020
```
2121
yarn dev

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright 2021 Observable, Inc.
1+
Copyright 2021–2024 Observable, Inc.
22

33
Permission to use, copy, modify, and/or distribute this software for any purpose
44
with or without fee is hereby granted, provided that the above copyright notice

README.md

Lines changed: 83 additions & 70 deletions
Large diffs are not rendered by default.

bin/clean-css.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import {stdin} from "node:process";
2+
import CleanCSS from "clean-css";
3+
4+
stdin.setEncoding("utf-8");
5+
6+
let input = "";
7+
8+
for await (const chunk of stdin) {
9+
input += chunk;
10+
}
11+
12+
// A unique namespace for our styles.
13+
const styleNs = "inputs-3a86ea";
14+
15+
process.stdout.write(new CleanCSS().minify(input.replace(/\.__ns__\b/g, `.${styleNs}`)).styles);

package.json

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,30 @@
11
{
22
"name": "@observablehq/inputs",
3-
"description": "User interface components for Observable notebooks",
4-
"version": "0.10.6",
3+
"description": "Lightweight user interface components",
4+
"version": "0.11.0",
55
"author": {
66
"name": "Observable, Inc.",
77
"url": "https://observablehq.com"
88
},
99
"license": "ISC",
1010
"type": "module",
11-
"main": "src/index.js",
12-
"module": "src/index.js",
11+
"main": "dist/index.js",
12+
"module": "dist/index.js",
1313
"jsdelivr": "dist/inputs.min.js",
1414
"unpkg": "dist/inputs.min.js",
1515
"exports": {
16-
"umd": "./dist/inputs.min.js",
17-
"default": "./src/index.js"
16+
".": {
17+
"umd": "./dist/inputs.min.js",
18+
"default": "./dist/index.js"
19+
},
20+
"./dist/index.css": "./dist/index.css"
1821
},
1922
"repository": {
2023
"type": "git",
2124
"url": "https://github.com/observablehq/inputs.git"
2225
},
2326
"files": [
27+
"dist/**/*.css",
2428
"dist/**/*.js",
2529
"src/**/*.js"
2630
],
@@ -29,34 +33,33 @@
2933
},
3034
"scripts": {
3135
"test": "yarn test:mocha && yarn test:lint",
32-
"test:mocha": "mkdir -p test/output && mocha -r module-alias/register 'test/**/*-test.js' test/input.js",
36+
"test:mocha": "mkdir -p test/output && mocha 'test/**/*-test.js' test/input.js",
3337
"test:lint": "eslint src test",
34-
"prepublishOnly": "rm -rf dist && rollup -c",
38+
"prepublishOnly": "rm -rf dist && rollup -c && node bin/clean-css < src/style.css > dist/index.css",
3539
"postpublish": "git push && git push --tags",
36-
"dev": "snowpack dev"
40+
"dev": "vite dev"
3741
},
3842
"_moduleAliases": {
3943
"@observablehq/inputs": "./src/index.js"
4044
},
4145
"devDependencies": {
42-
"@rollup/plugin-json": "4",
43-
"@rollup/plugin-node-resolve": "13",
44-
"@rollup/plugin-replace": "3",
45-
"apache-arrow": "17",
46-
"clean-css": "5",
47-
"d3": "7",
48-
"eslint": "8",
49-
"js-beautify": "1",
50-
"jsdom": "19",
51-
"jsesc": "3",
52-
"mocha": "9",
53-
"module-alias": "2",
54-
"rollup": "2",
55-
"rollup-plugin-terser": "7",
56-
"snowpack": "3"
46+
"@rollup/plugin-json": "^4.1.0",
47+
"@rollup/plugin-node-resolve": "^13.3.0",
48+
"@rollup/plugin-replace": "^3.1.0",
49+
"apache-arrow": "^17.0.0",
50+
"clean-css": "^5.3.3",
51+
"d3": "^7.9.0",
52+
"eslint": "^8.57.0",
53+
"js-beautify": "^1.15.1",
54+
"jsdom": "^24.1.1",
55+
"jsesc": "^3.0.2",
56+
"mocha": "^10.7.0",
57+
"rollup": "^2.79.1",
58+
"rollup-plugin-terser": "^7.0.2",
59+
"vite": "^5.3.5"
5760
},
5861
"dependencies": {
59-
"htl": "0.3",
62+
"htl": "^0.3.1",
6063
"isoformat": "^0.2.0"
6164
},
6265
"publishConfig": {

rollup.config.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import crypto from "crypto";
21
import fs from "fs";
32
import path from "path";
43
import {terser} from "rollup-plugin-terser";
@@ -22,10 +21,10 @@ const copyrights = fs.readFileSync("./LICENSE", "utf-8")
2221
.filter(line => /^copyright\s+/i.test(line))
2322
.map(line => line.replace(/^copyright\s+/i, ""));
2423

25-
// Create a content-hashed namespace for our styles.
24+
// A unique namespace for our styles.
25+
const styleNs = "inputs-3a86ea";
26+
2627
const stylePath = path.resolve("./src/style.css");
27-
const styleHash = crypto.createHash("sha256").update(fs.readFileSync(stylePath, "utf8")).digest("hex").slice(0, 6);
28-
const styleNs = `oi-${styleHash}`;
2928

3029
// A lil’ Rollup plugin to allow importing of style.css.
3130
const css = {
@@ -86,5 +85,19 @@ export default [
8685
...config.plugins,
8786
terser({output: {preamble: config.output.banner}})
8887
]
88+
},
89+
{
90+
input: "src/index.js",
91+
external: ["htl", "isoformat"],
92+
output: {
93+
indent: false,
94+
banner: `// ${meta.name} v${meta.version} Copyright ${copyrights.join(", ")}`,
95+
format: "es",
96+
file: "dist/index.js"
97+
},
98+
plugins: [
99+
node(),
100+
replace({__ns__: styleNs, preventAssignment: true})
101+
]
89102
}
90103
];

snowpack.config.js

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

src/table.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function initialize(
5454
rows = 11.5, // maximum number of rows to show
5555
width = {}, // object of column name to width, or overall table width
5656
multiple = true,
57+
select: selectable = true, // is the table selectable?
5758
layout // "fixed" or "auto"
5859
} = {}
5960
) {
@@ -96,8 +97,8 @@ function initialize(
9697
let anchor = null, head = null;
9798

9899
const tbody = html`<tbody>`;
99-
const tr = html`<tr><td><input type=${multiple ? "checkbox" : "radio"} name=${multiple ? null : "radio"}></td>${columns.map(() => html`<td>`)}`;
100-
const theadr = html`<tr><th><input type=checkbox onclick=${reselectAll} disabled=${!multiple}></th>${columns.map((column) => html`<th title=${column} onclick=${event => resort(event, column)}><span></span>${header && column in header ? header[column] : column}</th>`)}</tr>`;
100+
const tr = html`<tr><td>${selectable ? html`<input type=${multiple ? "checkbox" : "radio"} name=${multiple ? null : "radio"}>` : null}</td>${columns.map(() => html`<td>`)}`;
101+
const theadr = html`<tr><th>${selectable ? html`<input type=checkbox onclick=${reselectAll} disabled=${!multiple}>` : null}</th>${columns.map((column) => html`<th title=${column} onclick=${event => resort(event, column)}><span></span>${header && column in header ? header[column] : column}</th>`)}</tr>`;
101102
root.appendChild(html.fragment`<table style=${{tableLayout: layout}}>
102103
<thead>${minlengthof(1) || columns.length ? theadr : null}</thead>
103104
${tbody}
@@ -125,9 +126,11 @@ function initialize(
125126
function appendRow(d, i) {
126127
const itr = tr.cloneNode(true);
127128
const input = inputof(itr);
128-
input.onclick = reselect;
129-
input.checked = selected.has(i);
130-
input.value = i;
129+
if (input != null) {
130+
input.onclick = reselect;
131+
input.checked = selected.has(i);
132+
input.value = i;
133+
}
131134
if (d != null) for (let j = 0; j < columns.length; ++j) {
132135
let column = columns[j];
133136
let value = d[column];
@@ -243,6 +246,7 @@ function initialize(
243246

244247
function reinput() {
245248
const check = inputof(theadr);
249+
if (check == null) return;
246250
check.disabled = !multiple && !selected.size;
247251
check.indeterminate = multiple && selected.size && selected.size !== N; // assume materalized!
248252
check.checked = selected.size;

test/arrow-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import assert from "assert";
2-
import {table} from "@observablehq/inputs";
1+
import assert from "node:assert";
32
import {tableFromJSON} from "apache-arrow";
43
import {autoType, csv} from "d3";
4+
import {table} from "../src/index.js";
55
import it from "./jsdom.js";
66

77
it("Inputs.table() detects dates in Arrow tables", async () => {

test/bind-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import assert from "assert";
2-
import * as Inputs from "@observablehq/inputs";
1+
import assert from "node:assert";
2+
import * as Inputs from "../src/index.js";
33
import it from "./jsdom.js";
44

55
it("Inputs.bind(button, button) dispatches click events", () => {

test/checkbox-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
2-
import assert from "assert";
1+
import assert from "node:assert";
2+
import * as Inputs from "../src/index.js";
33
import it from "./jsdom.js";
44

55
it("Inputs.checkbox([]) handles empty options", () => {

test/date-test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
2-
import assert from "assert";
1+
import assert from "node:assert";
2+
import * as Inputs from "../src/index.js";
33
import it from "./jsdom.js";
44

55
it("Inputs.date() sets the initial value to null", () => {

test/input.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import assert from "assert";
2-
import {promises as fs} from "fs";
3-
import * as path from "path";
1+
import assert from "node:assert";
2+
import * as fs from "node:fs/promises";
3+
import * as path from "node:path";
44
import beautify from "js-beautify";
55
import it from "./jsdom.js";
66
import * as inputs from "./inputs/index.js";

test/inputs/buttons.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function button() {
55
return Inputs.button();

test/inputs/checkboxes.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function checkbox() {
55
return Inputs.checkbox(["red", "green", "blue"]);

test/inputs/colors.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function color() {
55
return Inputs.color();

test/inputs/dates.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as Inputs from "@observablehq/inputs";
1+
import * as Inputs from "../../src/index.js";
22

33
export async function date() {
44
return Inputs.date();

test/inputs/files.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as Inputs from "@observablehq/inputs";
1+
import * as Inputs from "../../src/index.js";
22

33
const Inputs_file = Inputs.fileOf(class AbstractFile {});
44

test/inputs/forms.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import * as Inputs from "@observablehq/inputs";
1+
import * as Inputs from "../../src/index.js";
22

33
export async function formArray() {
44
return Inputs.form([

test/inputs/numbers.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function number() {
55
return Inputs.number();

test/inputs/radios.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function radio() {
55
return Inputs.radio(["red", "green", "blue"]);

test/inputs/ranges.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function range() {
55
return Inputs.range();

test/inputs/searches.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function search() {
55
return Inputs.search(["red", "green", "blue"]);

test/inputs/selects.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import {html} from "htl";
2+
import * as Inputs from "../../src/index.js";
33

44
export async function select() {
55
return Inputs.select(["red", "green", "blue"]);

test/inputs/tables.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import * as Inputs from "@observablehq/inputs";
21
import * as d3 from "d3";
32
import {html} from "htl";
3+
import * as Inputs from "../../src/index.js";
44

55
export async function table() {
66
const athletes = await d3.csv("data/athletes.csv");

0 commit comments

Comments
 (0)