Skip to content

Inputs pages #540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11,539 changes: 0 additions & 11,539 deletions docs/inputs/athletes.csv

This file was deleted.

24 changes: 20 additions & 4 deletions docs/inputs/button.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Button input

A Button emits an *input* event when you click it. Buttons may be used to trigger the evaluation of cells, say to restart an animation.
[API Reference ›](https://github.com/observablehq/inputs/blob/main/README.md#button)

The button input emits an *input* event when you click it. Buttons may be used to trigger the evaluation of cells, say to restart an animation.

For example, below is an animation (using [yield](../javascript/generators)) that progressively hides a bar.

Expand Down Expand Up @@ -81,13 +83,13 @@ const counter = view(Inputs.button([
counter
```

The first argument to Button is the contents of the button. It’s not required, but it’s strongly encouraged.
The first argument to `Inputs.button()` is the contents of the button. It’s not required, but it’s strongly encouraged.

```js echo
const x = view(Inputs.button());
```

The contents of the Button can be an HTML element if desired, say for control over typography.
The contents of the button input can be an HTML element if desired, say for control over typography.

```js echo
const y = view(Inputs.button(html`<i>Fancy</i>`));
Expand All @@ -100,6 +102,7 @@ const confirm = view(Inputs.button("OK", {label: "Continue?"}));
```

You can change the rendered text in Markdown based on whether a button is clicked. Try clicking the `OK` button with the `Continue?` label.

```md echo run=false
confirm ? "Confirmed!" : "Awaiting confirmation..."
```
Expand All @@ -110,4 +113,17 @@ You can also use a button to copy something to the clipboard.

```js echo
Inputs.button("Copy to clipboard", {value: null, reduce: () => navigator.clipboard.writeText(time)})
```
```

## Options

**Inputs.button(*content*, *options*)**

The available button input options are:

* *label* - a label; either a string or an HTML element.
* *required* - if true, the initial value defaults to undefined.
* *value* - the initial value; defaults to 0 or null if *required* is false.
* *reduce* - a function to update the value on click; by default returns *value* + 1.
* *width* - the width of the input (not including the label).
* *disabled* - whether input is disabled; defaults to false.
46 changes: 30 additions & 16 deletions docs/inputs/checkbox.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Checkbox input

A Checkbox allows the user to choose any of a given set of values. (See [Radio](./radio) for single-choice.) A Checkbox is recommended over a [Select](./select) when the number of values to choose from is small — say, seven or fewer — because all choices will be visible up-front, improving usability. For zero or one choice, see [Toggle](./toggle).
[API Reference ›](https://github.com/observablehq/inputs/blob/main/README.md#checkbox)

The initial value of a Checkbox defaults to an empty array. You can override this by specifying the *value* option, which should also be an array (or iterable).
The checkbox input allows the user to choose any of a given set of values. (See the [radio](./radio) input for single-choice.) A checkbox is recommended over a [select](./select) input when the number of values to choose from is small — say, seven or fewer — because all choices will be visible up-front, improving usability. For zero or one choice, see the [toggle](./toggle) input.

The initial value of a checkbox defaults to an empty array. You can override this by specifying the *value* option, which should also be an array (or iterable).

```js echo
const colors = view(Inputs.checkbox(["red", "green", "blue"], {label: "color"}));
Expand All @@ -16,7 +18,7 @@ colors
<div style="display: flex;">${colors.map(color => html`<div style="background-color: ${color}; width: 25px; height: 25px;">`)}
```

A Checkbox’s values need not be strings: they can be anything. Specify a *format* function to control how these values are presented to the reader.
A checkbox’s values need not be strings: they can be anything. Specify a *format* function to control how these values are presented to the reader.

```js echo
const teams = [
Expand All @@ -36,7 +38,7 @@ const watching = view(Inputs.checkbox(teams, {label: "Watching", format: x => x.
watching
```

A Checkbox can be disabled by setting the *disabled* option to true. Alternatively, specific options can be disabled by passing an array of values to disable.
A checkbox can be disabled by setting the *disabled* option to true. Alternatively, specific options can be disabled by passing an array of values to disable.

```js echo
const vowels = view(Inputs.checkbox([..."AEIOUY"], {label: "Vowel", disabled: ["Y"]}));
Expand All @@ -46,7 +48,7 @@ const vowels = view(Inputs.checkbox([..."AEIOUY"], {label: "Vowel", disabled: ["
vowels
```

The *format* function, like the *label*, can return either a text string or an HTML element. This allows extensive control over the appearance of the Checkbox, if desired.
The *format* function, like the *label*, can return either a text string or an HTML element. This allows extensive control over the appearance of the checkbox, if desired.

```js echo
const colors2 = view(Inputs.checkbox(["red", "green", "blue"], {value: ["red"], label: html`<b>Colors</b>`, format: x => html`<span style="text-transform: capitalize; border-bottom: solid 2px ${x}; margin-bottom: -2px;">${x}`}));
Expand All @@ -56,7 +58,7 @@ const colors2 = view(Inputs.checkbox(["red", "green", "blue"], {value: ["red"],
colors2
```

If the Checkbox’s data are specified as a Map, the values will be the map’s values while the keys will be the displayed options. (This behavior can be customized by passing *keyof* and *valueof* function options.) Below, the displayed sizes are named, but the value is the corresponding number of fluid ounces.
If the checkbox’s data are specified as a Map, the values will be the map’s values while the keys will be the displayed options. (This behavior can be customized by passing *keyof* and *valueof* function options.) Below, the displayed sizes are named, but the value is the corresponding number of fluid ounces.

```js echo
const sizes = view(Inputs.checkbox(new Map([["Short", 8], ["Tall", 12], ["Grande", 16], ["Venti", 20]]), {value: [12], label: "Size"}));
Expand All @@ -79,28 +81,40 @@ const size2 = view(Inputs.checkbox(
size2
```

<!--[TODO] check if okay, removed link to Hello, Inputs. -->

Passing a Map to Checkbox is especially useful in conjunction with [d3.group](https://observablehq.com/@d3/d3-group). For example, given a tabular dataset of Olympic athletes, we can use d3.group to group them by gold medal count, and then Checkbox to select the athletes for the chosen count. Note that the value of the Checkbox will be an array of arrays, since d3.group returns a Map from key to array; use [*array*.flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) to merge these arrays if desired.

```js echo
const athletes = FileAttachment("athletes.csv").csv({typed: true});
```
Passing a Map to checkbox is especially useful in conjunction with [d3.group](https://d3js.org/d3-array/group). For example, given a the sample `olympians` dataset of Olympic athletes, we can use d3.group to group them by gold medal count, and then checkbox to select the athletes for the chosen count. Note that the value of the checkbox will be an array of arrays, since d3.group returns a Map from key to array; use [*array*.flat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat) to merge these arrays if desired.

```js echo
const goldAthletes = view(Inputs.checkbox(d3.group(athletes, d => d.gold), {label: "Gold medal count", sort: "descending", key: [4, 5]}));
const goldAthletes = view(Inputs.checkbox(d3.group(olympians, d => d.gold), {label: "Gold medal count", sort: "descending", key: [4, 5]}));
```

```js echo
goldAthletes.flat()
```

If the *sort* and *unique* options are specified, the Checkbox’s keys will be sorted and duplicate keys will be discarded, respectively.
If the *sort* and *unique* options are specified, the checkbox’s keys will be sorted and duplicate keys will be discarded, respectively.

```js echo
const bases = view(Inputs.checkbox("GATTACA", {sort: true, unique: true}));
```

```js echo
bases
```
```

## Options

**Inputs.checkbox(*data*, *options*)**

The available checkbox input options are:

* *label* - a label; either a string or an HTML element.
* *sort* - true, “ascending”, “descending”, or a comparator function to sort keys; defaults to false.
* *unique* - true to only show unique keys; defaults to false.
* *locale* - the current locale; defaults to English.
* *format* - a format function; defaults to [formatLocaleAuto](https://github.com/observablehq/inputs?tab=readme-ov-file#formatLocaleAuto) composed with *keyof*.
* *keyof* - a function to return the key for the given element in *data*.
* *valueof* - a function to return the value of the given element in *data*.
* *value* - the initial value, an array; defaults to an empty array (no selection).
* *disabled* - whether input is disabled, or the disabled values; defaults to false.

<!-- TODO check formatLocaleAuto link-->
14 changes: 11 additions & 3 deletions docs/inputs/color.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Color input

The Color input specifies an RGB color as a hexadecimal string `#rrggbb`. The initial value defaults to black (`#000000`) and can be specified with the *value* option.
[API Reference ›](https://github.com/observablehq/inputs/blob/main/README.md#color)

The color input specifies an RGB color as a hexadecimal string `#rrggbb`. The initial value defaults to black (`#000000`) and can be specified with the *value* option.

```js echo
const color = view(Inputs.color({label: "Favorite color", value: "#4682b4"}));
Expand All @@ -18,7 +20,7 @@ const fill = view(Inputs.color({label: "Fill", value: d3.color("steelblue").form

If you specify the *datalist* option as an array of hexadecimal color strings, the color picker will show this set of colors for convenient picking. (The user will still be allowed to pick another color, however; if you want to limit the choice to a specific set, then a radio or select input may be more appropriate.)

<!-- [TODO] update to the new Observable color palette? -->
<!-- [TODO] update to the new Observable10 color palette? -->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would be lovely, but depends on d3/d3-scale-chromatic#51


```js echo
const stroke = view(Inputs.color({label: "Stroke", datalist: d3.schemeTableau10}));
Expand All @@ -36,4 +38,10 @@ const disabled = view(Inputs.color({label: "Disabled", value: "#f28e2c", disable

```js echo
disabled
```
```

## Options

**Inputs.color(*options*)**

Like [Inputs.text](./text), but where *type* is color. The color value is represented as an RGB hexadecimal string such as #ff00ff. This type of input does not support the following options: *placeholder*, *pattern*, *spellcheck*, *autocomplete*, *autocapitalize*, *min*, *max*, *minlength*, *maxlength*.
25 changes: 23 additions & 2 deletions docs/inputs/date.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Date input

The Date input specifies a date.
[API Reference ›](https://github.com/observablehq/inputs/blob/main/README.md#date)

The date input specifies a date.

```js echo
const date = view(Inputs.date());
Expand Down Expand Up @@ -76,4 +78,23 @@ const readonly = view(Inputs.date({label: "Readonly date", value: "2021-01-01",

```js echo
readonly
```
```

## Options

**Inputs.date(*options*)**

The available date input options are:

* *label* - a label; either a string or an HTML element.
* *value* - the initial value, as a JavaScript Date or formatted as an ISO string (yyyy-mm-dd); defaults to null.
* *min* - [minimum value](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/min) attribute.
* *max* - [maximum value](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/max) attribute.
* *required* - if true, the input must be a valid date.
* *validate* - a function to check whether the text input is valid.
* *width* - the width of the input (not including the label).
* *submit* - whether to require explicit submission before updating; defaults to false.
* *readonly* - whether input is readonly; defaults to false.
* *disabled* - whether input is disabled; defaults to false.

The value of the input is a Date instance at UTC midnight of the specified date, or null if no (valid) value has been specified. Note that the displayed date format is [based on the browser’s locale](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date).
98 changes: 93 additions & 5 deletions docs/inputs/file.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,101 @@
# File input

<!-- [TODO] check okay, updated to point to /javascript/files rather than FileAttachment info in docs -->
[API Reference ›](https://github.com/observablehq/inputs/blob/main/README.md#file)

The File input specifies a local file. The exposed value provides the same interface as an Observable [file attachment](../javascript/files) for convenient parsing in various formats such as text, image, JSON, CSV, ZIP, and XLSX; however, the file is not uploaded and is only available temporarily in memory.
The file input specifies a local file. The exposed value provides the same interface as an Observable [file attachment](../javascript/files) for convenient parsing in various formats such as text, image, JSON, CSV, ZIP, and XLSX; however, the file is not uploaded and is only available temporarily in memory.

By default, any file is allowed, and the value of the input resolves to null.

<!-- [TODO] check error, return to File input after hearing back (Fil has PR submitted) -->
```js echo
const file = view(Inputs.file());
```

```js echo
file
```

We recommend providing a *label* to improve usability.

Specify the *accept* option to limit the allowed file extensions. This is useful when you intend to parse the file as a specific file format, such as CSV. By setting the *required* option to true, the value of the input won’t resolve until the user choses a file.

```js echo
const file = view(Inputs.file())
```
const csvfile = view(Inputs.file({label: "CSV file", accept: ".csv", required: true}));
```

Once a file has been selected, you can read its contents like so:


```js echo
const data = display(await csvfile.csv({typed: true}));
```

Here are examples of other supported file types.

```js echo
const jsonfile = view(Inputs.file({label: "JSON file", accept: ".json", required: true}));
```

```js echo
const data = display(await jsonfile.json());
```

```js echo
const textfile = view(Inputs.file({label: "Text file", accept: ".txt", required: true}));
```

```js echo
const data = display(await textfile.text());
```

```js echo
const imgfile = view(Inputs.file({label: "Image file", accept: ".png,.jpg", required: true}));
```

```js echo
const image = display(await imgfile.image());
```

```js echo
const xlsxfile = view(Inputs.file({label: "Excel file", accept: ".xlsx", required: true}));
```

```js echo
const workbook = display(await xlsxfile.xlsx());
```

```js echo
const zipfile = view(Inputs.file({label: "ZIP archive", accept: ".zip", required: true}));
```

```js echo
const archive = display(await zipfile.zip())
```

The *multiple* option allows the user to pick multiple files. In this mode, the exposed value is an array of files instead of a single file.

```js echo
const files = view(Inputs.file({label: "Files", multiple: true}));
```

```js echo
files
```

## Options

**Inputs.file(*options*)**

The available file input options are:

* *label* - a label; either a string or an HTML element.
* *required* - if true, a valid file must be selected.
* *validate* - a function to check whether the file input is valid.
* *accept* - the [acceptable file types](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept).
* *capture* - for [capturing image or video data](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#capture).
* *multiple* - whether to allow multiple files to be selected; defaults to false.
* *width* - the width of the input (not including the label).
* *disabled* - whether input is disabled; defaults to false.

Note that the value of file input cannot be set programmatically; it can only be changed by the user.

<!-- TODO check: Delete? (In vanilla JavaScript, the Inputs.file method is not exposed directly. Instead, an Inputs.fileOf method is exposed which takes an AbstractFile implementation and returns the Inputs.file method. This avoids a circular dependency between Observable Inputs and the Observable standard library.)-->
16 changes: 14 additions & 2 deletions docs/inputs/form.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Form input

The Form input combines a number of inputs into a single compound input. It’s intended for a more compact display of closely-related inputs, say for a color’s red, green, and blue channels.
[API Reference ›](https://github.com/observablehq/inputs/blob/main/README.md#inputsforminputs-options)

The form input combines a number of inputs into a single compound input. It’s intended for a more compact display of closely-related inputs, say for a color’s red, green, and blue channels.

```js echo
const rgb = view(Inputs.form([
Expand All @@ -26,4 +28,14 @@ const rgb2 = view(Inputs.form({

```js echo
rgb2
```
```

## Options

**Inputs.form(*inputs*, *options*)**

The available form input options are:

* *template* - a function that takes the given *inputs* and returns an HTML element to display.

If the *template* object is not specified, the given inputs are wrapped in a DIV.
Loading