Skip to content

Commit

Permalink
Merge branch 'main' into fil/format-arrays-objects
Browse files Browse the repository at this point in the history
  • Loading branch information
Fil authored Apr 2, 2024
2 parents 4cad345 + 130d8cf commit 5a60f6a
Show file tree
Hide file tree
Showing 16 changed files with 103 additions and 80 deletions.
30 changes: 0 additions & 30 deletions .github/workflows/node.js.yml

This file was deleted.

22 changes: 22 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Test

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 16
cache: 'yarn'
- run: yarn --frozen-lockfile
- run: |
echo ::add-matcher::.github/eslint.json
yarn run eslint src test --format=compact
- run: yarn test:mocha
64 changes: 32 additions & 32 deletions README.md

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@observablehq/inputs",
"description": "User interface components for Observable notebooks",
"version": "0.10.4",
"version": "0.10.6",
"author": {
"name": "Observable, Inc.",
"url": "https://observablehq.com"
Expand All @@ -28,7 +28,9 @@
"node": ">=14.5.0"
},
"scripts": {
"test": "mkdir -p test/output && mocha -r module-alias/register 'test/**/*-test.js' test/input.js && eslint src test",
"test": "yarn test:mocha && yarn test:lint",
"test:mocha": "mkdir -p test/output && mocha -r module-alias/register 'test/**/*-test.js' test/input.js",
"test:lint": "eslint src test",
"prepublishOnly": "rm -rf dist && rollup -c",
"postpublish": "git push && git push --tags",
"dev": "snowpack dev"
Expand Down
3 changes: 2 additions & 1 deletion src/button.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export function button(content = "≡", {
if (!required && value === undefined) value = null;
disabled = new Set(disabled === true ? Array.from(content, ([content]) => content) : disabled || undefined);
}
const form = html`<form class=__ns__ onsubmit=${preventDefault}>`;
const form = html`<form class=__ns__>`;
form.addEventListener("submit", preventDefault);
const style = {width: length(width)};
const buttons = Array.from(content, ([content, reduce = identity]) => {
if (typeof reduce !== "function") throw new TypeError("reduce is not a function");
Expand Down
10 changes: 5 additions & 5 deletions src/chooser.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function createChooser({multiple: fixedMultiple, render, selectedIndexes,
locale,
keyof = data instanceof Map ? first : identity,
valueof = data instanceof Map ? second : identity,
format = data instanceof Map ? first : formatLocaleAuto(locale),
format = (f => (d, i, data) => f(keyof(d, i, data)))(formatLocaleAuto(locale)),
multiple,
key,
value,
Expand Down Expand Up @@ -49,11 +49,11 @@ export function createChooser({multiple: fixedMultiple, render, selectedIndexes,
size
}
);
form.onchange = dispatchInput;
form.oninput = oninput;
form.onsubmit = preventDefault;
form.addEventListener("input", oninput);
form.addEventListener("change", dispatchInput);
form.addEventListener("submit", preventDefault);
function oninput(event) {
if (event && event.isTrusted) form.onchange = null;
if (event && event.isTrusted) form.removeEventListener("change", dispatchInput);
if (multiple) {
value = selectedIndexes(input).map(i => valueof(data[i], i, data));
} else {
Expand Down
5 changes: 4 additions & 1 deletion src/date.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,11 @@ function formatDate(value) {
: value;
}

// The datetime-local input uses YYYY-MM-DDThh:mm like ISO 8601, but in local
// time rather than UTC, so we apply the offset before calling toISOString.
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/datetime-local
function formatDatetime(value) {
return (value = coerce(value))
? value.toISOString().slice(0, 16)
? (new Date(+value - value.getTimezoneOffset() * 1000 * 60)).toISOString().slice(0, 16)
: value;
}
3 changes: 2 additions & 1 deletion src/range.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,12 @@ function createRange({
range = null;
transform = invert = identity;
}
const form = html`<form class=__ns__ onsubmit=${preventDefault} style=${maybeWidth(width)}>
const form = html`<form class=__ns__ style=${maybeWidth(width)}>
${maybeLabel(label, number)}<div class=__ns__-input>
${number}${range}
</div>
</form>`;
form.addEventListener("submit", preventDefault);
// If range, use an untransformed range to round to the nearest valid value.
function coerce(v) {
if (!irange) return +v;
Expand Down
7 changes: 4 additions & 3 deletions src/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,12 @@ export function search(data, {
oninput=${oninput}
>`;
const output = html`<output name=output>`;
const form = html`<form class=__ns__ onsubmit=${preventDefault} style=${maybeWidth(width)}>
const form = html`<form class=__ns__ style=${maybeWidth(width)}>
${maybeLabel(label, input)}<div class=__ns__-input>
${input}${output}
</div>${list}
</form>`;
form.addEventListener("submit", preventDefault);
function oninput() {
value = input.value || required ? data.filter(filter(input.value)) : [];
if (columns !== undefined) value.columns = columns;
Expand Down Expand Up @@ -117,11 +118,11 @@ function* valuesof(d) {
}

function termFilter(term) {
return new RegExp(`\\b${escapeRegExp(term)}`, "i");
return new RegExp(`(?:^|[^\\p{L}-])${escapeRegExp(term)}`, "iu");
}

function escapeRegExp(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
return text.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
}

const formatResults = localize(locale => {
Expand Down
1 change: 0 additions & 1 deletion src/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,6 @@ form.__ns__-checkbox {
form.__ns__-table {
display: block;
overflow-y: auto;
margin: 0 -14px;
width: 100%;
}

Expand Down
4 changes: 2 additions & 2 deletions src/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -249,11 +249,11 @@ function initialize(
value = undefined; // lazily computed
}

root.onscroll = () => {
root.addEventListener("scroll", () => {
if (root.scrollHeight - root.scrollTop < rows * rowHeight * 1.5 && n < minlengthof(n + 1)) {
appendRows(n, n = minlengthof(n + rows));
}
};
});

if (sort === undefined && reverse) {
materialize();
Expand Down
2 changes: 1 addition & 1 deletion src/text.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function createText(form, input, value, {
if (submit) after(button);
set(input, value);
value = validate(input) ? get(input) : undefined;
form.onsubmit = onsubmit;
form.addEventListener("submit", onsubmit);
input.oninput = oninput;
function update() {
if (validate(input)) {
Expand Down
3 changes: 2 additions & 1 deletion src/textarea.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {html} from "htl";
import {maybeWidth} from "./css.js";
import {bubbles} from "./event.js";
import {maybeLabel} from "./label.js";
import {createText, onoff, truefalse} from "./text.js";

Expand Down Expand Up @@ -47,7 +48,7 @@ export function textarea({
</form>`;
function onkeydown(event) {
if (options.submit && event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
return form.onsubmit(event);
return form.dispatchEvent(new Event("submit", bubbles));
}
}
return createText(form, input, value, options);
Expand Down
4 changes: 4 additions & 0 deletions test/inputs/searches.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export async function searchLabelQuery() {
return Inputs.search(["red", "green", "blue", "black"], {label: "colors", query: "bl"});
}

export async function searchLabelQueryCyrillic() {
return Inputs.search(["red", "green", "blue", "чёрный"], {label: "colors", query: "чёрн"});
}

export async function searchPlaceholder() {
return Inputs.search(["red", "green", "blue"], {placeholder: "dollars&pounds"});
}
Expand Down
6 changes: 6 additions & 0 deletions test/output/searchLabelQueryCyrillic.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<form class="__ns__">
<label for="__ns__-1">colors</label>
<div class="__ns__-input">
<input name="input" type="search" placeholder="Search" value="чёрн" id="__ns__-1"><output name="output">1 result</output>
</div>
</form>
13 changes: 13 additions & 0 deletions test/search-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as Inputs from "@observablehq/inputs";
import assert from "assert";
import it from "./jsdom.js";

it("Inputs.search(data) handles word boundaries", () => {
const s = Inputs.search(["red", "blue", "The Real", "Mr.Real", "un-real"], {query: "re"});
assert.deepStrictEqual(s.value, ["red", "The Real", "Mr.Real"]);
});

it("Inputs.search(data) supports Cyrillic symbols", () => {
const s = Inputs.search(["red", "дом", "чудо", "Река Дон"], {query: "до"});
assert.deepStrictEqual(s.value, ["дом", "Река Дон"]);
});

0 comments on commit 5a60f6a

Please sign in to comment.