-
Notifications
You must be signed in to change notification settings - Fork 221
docs(number-field): updated for accessbility #5385
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
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
9f6b61f
docs(number-field): updated for accessibility
nikkimk 80a4bb9
docs(number-field): updated for accessibility
nikkimk 899e250
docs(number-field): added better variant examples
nikkimk eda483c
Merge branch 'main' into nikkimk/number-field-docs
nikkimk 5492bd0
Merge branch 'main' into nikkimk/number-field-docs
nikkimk ea4c46f
Merge branch 'main' into nikkimk/number-field-docs
nikkimk 7743287
Merge branch 'main' into nikkimk/number-field-docs
nikkimk 5a4a121
Merge branch 'main' into nikkimk/number-field-docs
nikkimk 70bbbcf
docs(number-field): fixed typos
nikkimk 1110a17
docs(number-field): removed changes to sizing
nikkimk 1d2411f
docs(number-field): updates based on feedback
nikkimk aab44cc
docs(number-field): fixed example
nikkimk 8d3f67b
docs(number-field): rewording
nikkimk 9219a5b
docs(number-field): adjusted script
nikkimk a11aa95
Merge branch 'main' into nikkimk/number-field-docs
nikkimk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
## Description | ||
## Overview | ||
|
||
`<sp-number-field>` elements are used for numeric inputs. Upon interaction via the <kbd>ArrowUp</kbd> or <kbd>ArrowDown</kbd> keys, the scroll wheel, or the stepper UI, when not hidden by the `hide-stepper` attribute, the input value incrementally increases or decreases by the value of the `step` attribute. The <kbd>shift</kbd> key can be used to apply steps at 10 time (or the value of the `step-modifier` attribute times) their normal rate. | ||
`<sp-number-field>` elements are used for numeric inputs. | ||
|
||
### Usage | ||
|
||
|
@@ -24,7 +24,27 @@ When looking to leverage the `NumberField` base class as a type and/or for exten | |
import { NumberField } from '@spectrum-web-components/number-field'; | ||
``` | ||
|
||
## Sizes | ||
### Anatomy | ||
|
||
A number field consists of an input field for numeric values and optional stepper buttons for incrementing and decrementing the value. The stepper UI can be hidden using the `hide-stepper` attribute. | ||
|
||
```html | ||
<sp-field-label> | ||
What is the air-speed velocity of an unladen swallow? | ||
</sp-field-label> | ||
<sp-number-field | ||
id="anatomy" | ||
format-options='{ | ||
"style": "unit", | ||
"unit": "MPH", | ||
"unitDisplay": "long" | ||
}' | ||
></sp-number-field> | ||
``` | ||
|
||
### Options | ||
|
||
#### Sizes | ||
|
||
<sp-tabs selected="m" auto label="Size Attribute Options"> | ||
<sp-tab value="s">Small</sp-tab> | ||
|
@@ -35,7 +55,6 @@ import { NumberField } from '@spectrum-web-components/number-field'; | |
label="Size" | ||
value="1024" | ||
size="s" | ||
style="--spectrum-stepper-width: 85px" | ||
></sp-number-field> | ||
``` | ||
|
||
|
@@ -48,7 +67,6 @@ import { NumberField } from '@spectrum-web-components/number-field'; | |
label="Size" | ||
value="1024" | ||
size="m" | ||
style="--spectrum-stepper-width: 110px" | ||
></sp-number-field> | ||
``` | ||
|
||
|
@@ -61,7 +79,6 @@ import { NumberField } from '@spectrum-web-components/number-field'; | |
label="Size" | ||
value="1024" | ||
size="l" | ||
style="--spectrum-stepper-width: 135px" | ||
></sp-number-field> | ||
``` | ||
|
||
|
@@ -74,20 +91,21 @@ import { NumberField } from '@spectrum-web-components/number-field'; | |
label="Size" | ||
value="1024" | ||
size="xl" | ||
style="--spectrum-stepper-width: 160px" | ||
></sp-number-field> | ||
``` | ||
|
||
</sp-tab-panel> | ||
</sp-tabs> | ||
|
||
## Number formatting | ||
#### Formatting | ||
|
||
An `<sp-number-field>` element will process its numeric value with `new Intl.NumberFormat(this.resolvedLanguage, this.formatOptions).format(this.value)` in order to prepare it for visual delivery in the input. In order to customize this processing supply your own `Intl.NumberFormatOptions` via the `formatOptions` property, or `format-options` attribute as seen below. | ||
|
||
`this.resolvedLanguage` represents the language in which the `<sp-number-field>` element is currently being delivered. By default, this value will represent the language established by the `lang` attribute on the root `<html>` element while falling back to `navigator.language` when that is not present. This value can be customized via a language context provided by a parent element that listens for the `sp-language-context` event and supplies update language settings to the `callback` function contained therein. Applications leveraging the [`<sp-theme>`](./components/theme) element to manage the visual delivery or text direction of their content will be also be provided a reactive context for supplying language information to its descendants. | ||
|
||
### Decimals | ||
<sp-tabs selected="decimals" auto label="Number Formatting"> | ||
<sp-tab value="decimals">Decimals</sp-tab> | ||
<sp-tab-panel value="decimals"> | ||
|
||
The following example uses the `signDisplay` option to include the plus sign for positive numbers, for example to display an offset from some value. In addition, it always displays a minimum of 1 digit after the decimal point, and allows up to 2 fraction digits. If the user enters more than 2 fraction digits, the result will be rounded. | ||
|
||
|
@@ -96,7 +114,6 @@ The following example uses the `signDisplay` option to include the plus sign for | |
<sp-number-field | ||
id="decimals" | ||
value="0" | ||
style="width: 100px" | ||
format-options='{ | ||
"signDisplay": "exceptZero", | ||
"minimumFractionDigits": 1, | ||
|
@@ -105,23 +122,26 @@ The following example uses the `signDisplay` option to include the plus sign for | |
></sp-number-field> | ||
``` | ||
|
||
### Percentages | ||
</sp-tab-panel> | ||
<sp-tab value="percentages">Percentages</sp-tab> | ||
<sp-tab-panel value="percentages"> | ||
|
||
The `style: 'percent'` option can be passed to the `formatOptions` property to treat the value as a percentage. In this mode, the value is multiplied by 100 before it is displayed, i.e. `0.45` is displayed as "45%". The reverse is also true: when the user enters a value, the `change` event will be triggered with the entered value divided by 100. When the percent option is enabled, the default step automatically changes to 0.01 such that incrementing and decrementing occurs by 1%. This can be overridden with the step property. | ||
|
||
```html | ||
<sp-field-label for="percents">Sales tax</sp-field-label> | ||
<sp-number-field | ||
id="percents" | ||
style="width: 200px" | ||
value="0.05" | ||
format-options='{ | ||
"style": "percent" | ||
}' | ||
></sp-number-field> | ||
``` | ||
|
||
### Currency values | ||
</sp-tab-panel> | ||
<sp-tab value="currency">Currency values</sp-tab> | ||
<sp-tab-panel value="currency"> | ||
|
||
The `style: 'currency'` option can be passed to the `formatOptions` property to treat the value as a currency value. The `currency` option must also be passed to set the currency code (e.g. `USD`) to use. In addition, the `currencyDisplay` option can be used to choose whether to display the currency `symbol`, currency `code`, or currency `name`. Finally, the `currencySign` option can be set to `accounting` to use accounting notation for negative numbers, which uses parentheses rather than a minus sign in some locales. | ||
|
||
|
@@ -131,7 +151,6 @@ If you need to allow the user to change the currency, you should include a separ | |
<sp-field-label for="currency">Transaction amount</sp-field-label> | ||
<sp-number-field | ||
id="currency" | ||
style="width: 200px" | ||
value="45" | ||
format-options='{ | ||
"style": "currency", | ||
|
@@ -142,7 +161,9 @@ If you need to allow the user to change the currency, you should include a separ | |
></sp-number-field> | ||
``` | ||
|
||
### Units | ||
</sp-tab-panel> | ||
<sp-tab value="units">Units</sp-tab> | ||
<sp-tab-panel value="units"> | ||
|
||
The `style: 'unit'` option can be passed to the `formatOptions` property to format the value with a unit of measurement. The `unit` option must also be passed to set which unit to use (e.g. `inch`). In addition, the `unitDisplay` option can be used to choose whether to display the unit in `long`, `short`, or `narrow` format. | ||
|
||
|
@@ -154,7 +175,6 @@ Note: The unit style is not currently supported in Safari. A [polyfill](https:// | |
<sp-field-label for="units">Package width</sp-field-label> | ||
<sp-number-field | ||
id="units" | ||
style="width: 200px" | ||
value="4" | ||
format-options='{ | ||
"style": "unit", | ||
|
@@ -164,15 +184,16 @@ Note: The unit style is not currently supported in Safari. A [polyfill](https:// | |
></sp-number-field> | ||
``` | ||
|
||
### Units not included in `Intl.NumberFormatOptions` | ||
</sp-tab-panel> | ||
<sp-tab value="custom-units">Custom Units</sp-tab> | ||
<sp-tab-panel value="custom-units"> | ||
|
||
While `Intl.NumberFormatOptions` does support a [wide range of units](https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier), it is possible to encounter units (e.g. the graphics units of `pixel`, `pixels`, `points`, etc.) that are not supported therein. When this occurs, an `<sp-number-field>` element will attempt to polyfill support for this unit. See the following example delivering `{ style: "unit", unit: "px" }` below: | ||
|
||
```html | ||
<sp-field-label for="units">Document width in pixels</sp-field-label> | ||
<sp-number-field | ||
id="units" | ||
style="width: 200px" | ||
value="500" | ||
format-options='{ | ||
"style": "unit", | ||
|
@@ -183,9 +204,11 @@ While `Intl.NumberFormatOptions` does support a [wide range of units](https://tc | |
|
||
Note: the polyfilling done here is very simplistic and is triggered by supplying options that would otherwise cause the `Intl.NumberFormat()` call to throw an error. Once the unsupporting unit of `px` causes the construction of the object to throw, a back up formatter/parser pair will be created without the supplied unit data. When the `style` is set to `unit`, the `unit` value of will be adopted as the _static_ unit display. This means that neither pluralization or translation will be handled within the `<sp-number-field>` element itself. If pluralization or translation is important to the delivered interface, please be sure to handle passing those strings into to element via the `formatOptions` property reactively to the value of the element or locale of that page in question. | ||
|
||
## Minimum and maximum values | ||
</sp-tab-panel> | ||
<sp-tab value="min-max">Minimum and maximum values</sp-tab> | ||
<sp-tab-panel value="min-max"> | ||
|
||
nikkimk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
The `max` and `max` properties can be used to limit the entered value to a specific range. The value will be clamped when the user commits the value to the `<sp-number-field>` element. In addition, the increment and decrement buttons will be disabled when the value is within one step value from the bounds. Ranges can be open ended by only providing a value for either `min` or `max` rather than both. | ||
The `min` and `max` properties can be used to limit the entered value to a specific range. The value will be clamped when the user commits the value to the `<sp-number-field>` element. In addition, the increment and decrement buttons will be disabled when the value is within one step value from the bounds. Ranges can be open ended by only providing a value for either `min` or `max` rather than both. | ||
|
||
If a valid range is known ahead of time, it is a good idea to provide it to `<sp-number-field>` so it can optimize the experience. For example, when the minimum value is greater than or equal to zero, it is possible to use a numeric keyboard on iOS rather than a full text keyboard (necessary to enter a minus sign). | ||
|
||
|
@@ -194,7 +217,9 @@ If a valid range is known ahead of time, it is a good idea to provide it to `<sp | |
<sp-number-field id="red" value="4" min="0" max="255"></sp-number-field> | ||
``` | ||
|
||
## Step values | ||
</sp-tab-panel> | ||
<sp-tab value="step">Step values</sp-tab> | ||
<sp-tab-panel value="step"> | ||
|
||
The step prop can be used to snap the value to certain increments. If there is a `min` defined, the steps are calculated starting from that minimum value. For example, if `min === 2`, and `step === 3`, the valid step values would be 2, 5, 8, 11, etc. If no `min` is defined, the steps are calculated starting from zero and extending in both directions. In other words, such that the values are evenly divisible by the step. A step can be any positive decimal. If no step is defined, any decimal value may be typed, but incrementing and decrementing snaps the value to an integer. | ||
|
||
|
@@ -230,52 +255,164 @@ If the user types a value that is between two steps and blurs the input, the val | |
></sp-number-field> | ||
``` | ||
|
||
## Default value | ||
</sp-tab-panel> | ||
</sp-tabs> | ||
|
||
### States | ||
|
||
nikkimk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#### Invalid | ||
|
||
The `invalid` attribute indicates that the number field's value is invalid. When set, appropriate ARIA attributes will be automatically applied. | ||
|
||
```html | ||
<sp-field-label for="invalid"> | ||
It's one banana, Michael, how much could it cost? | ||
</sp-field-label> | ||
<sp-number-field | ||
id="invalid" | ||
invalid | ||
style="width: 130px" | ||
value="10" | ||
min="0" | ||
max="0.3" | ||
step="0.01" | ||
format-options='{ | ||
"style": "currency", | ||
"currency": "USD", | ||
"currencyDisplay": "code", | ||
"currencySign": "accounting", | ||
"minimumFractionDigits": 2, | ||
"maximumFractionDigits": 2 | ||
}' | ||
></sp-number-field> | ||
<sp-help-text variant="negative"> | ||
Value should be between $0 and $0.3. | ||
</sp-help-text> | ||
``` | ||
|
||
#### Valid | ||
|
||
The `valid` attribute indicates that the number field's value is valid. | ||
|
||
```html | ||
<sp-field-label for="valid"> | ||
It's one banana, Michael, how much could it cost? | ||
</sp-field-label> | ||
<sp-number-field | ||
id="valid" | ||
valid | ||
style="width: 130px" | ||
value="0.23" | ||
min="0" | ||
max="0.3" | ||
step="0.01" | ||
format-options='{ | ||
"style": "currency", | ||
"currency": "USD", | ||
"currencyDisplay": "code", | ||
"currencySign": "accounting", | ||
"minimumFractionDigits": 2, | ||
"maximumFractionDigits": 2 | ||
}' | ||
></sp-number-field> | ||
``` | ||
|
||
#### Required | ||
|
||
Use the `required` attribute to indicate a number field value is required. Dictate the validity or invalidity state of the text entry with the `valid` or `invalid` attributes. | ||
|
||
```html | ||
<sp-field-label for="number-1" required>Count</sp-field-label> | ||
<sp-number-field id="number-1" valid value="123"></sp-number-field> | ||
<sp-field-label for="number-2" required>Size</sp-field-label> | ||
<sp-number-field id="number-2" invalid value="152"></sp-number-field> | ||
``` | ||
|
||
#### Disabled | ||
|
||
The `disabled` attribute prevents the number field from receiving focus or events. The number field will appear faded. | ||
|
||
```html | ||
<sp-field-label for="disabled" disabled>Number of tickets</sp-field-label> | ||
<sp-number-field id="disabled" disabled value="0"></sp-number-field> | ||
``` | ||
|
||
#### Read-only | ||
|
||
Number fields have a `readonly` attribute for when they’re in the disabled state but still need their labels to be shown. This allows for content to be copied, but not interacted with or changed. | ||
|
||
```html | ||
<sp-field-label for="readonly">Number of tickets</sp-field-label> | ||
<sp-number-field id="readonly" readonly value="0"></sp-number-field> | ||
``` | ||
|
||
### Behaviors | ||
|
||
The number field works with the following interactions: | ||
|
||
- the input field, | ||
- <kbd>ArrowUp</kbd> or <kbd>ArrowDown</kbd> keys, | ||
- the scroll wheel, or | ||
- the stepper UI, when not hidden by the `hide-stepper` attribute. | ||
|
||
The input value incrementally increases or decreases by the value of the `step` attribute. The <kbd>shift</kbd> key can be used to apply steps at 10 times (or the value of the `step-modifier` attribute times) their normal rate. | ||
|
||
#### Default value | ||
|
||
The `<sp-number-field>` component doesn't manage a default value by itself. This means that consumers can set the value of the number-field as an empty string by clearing the input. If we want the number-field to reset to a `default-value` when the user clears the input, we can listen for the `change` event on the number-field component and set its value to the desired `default-value` if the input is empty. | ||
|
||
```html-live | ||
```html | ||
<sp-field-label for="default"> | ||
Default value of this number field is 42 | ||
</sp-field-label> | ||
nikkimk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
<sp-number-field id="default" value="20"></sp-number-field> | ||
|
||
<script type="module"> | ||
customElements.whenDefined('sp-number-field').then(() => { | ||
const numberField = document.querySelector('#default'); | ||
|
||
numberField.addEventListener('change', (event) => { | ||
const target = event.target; | ||
if (isNaN(target.value)) { | ||
target.value = '42'; | ||
} | ||
}); | ||
const numberField = document.querySelector('#default'); | ||
|
||
numberField.addEventListener('change', (event) => { | ||
alert('change'); | ||
const target = event.target; | ||
if (isNaN(target.value)) { | ||
target.value = '42'; | ||
} | ||
}); | ||
</script> | ||
|
||
``` | ||
|
||
### Accessibility | ||
|
||
#### Labels | ||
|
||
Every number field must have a label that clearly describes its purpose. The label can be provided either via the `label` attribute or with an associated `<sp-field-label>` element. | ||
|
||
#### Keyboard Navigation | ||
|
||
Number fields support the following keyboard interactions: | ||
|
||
- <kbd>ArrowUp</kbd> and <kbd>ArrowDown</kbd> keys increment and decrement the value | ||
- <kbd>Shift</kbd> + <kbd>ArrowUp</kbd> or <kbd>ArrowDown</kbd> applies steps at 10 times (or the value of `step-modifier`) the normal rate | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Love the use of kbd here! <3 |
||
- The scroll wheel can be used to increment and decrement the value when focused | ||
|
||
#### Help Text | ||
|
||
Consider providing help text to explain: | ||
|
||
- The expected format of the input | ||
- Any minimum or maximum values | ||
- The meaning of units or special formatting (e.g., currency, percentages) | ||
- Step increments if they differ from the default | ||
|
||
<script type="module"> | ||
customElements.whenDefined('sp-number-field').then(() => { | ||
const numberField = document.querySelector('#default'); | ||
|
||
numberField.addEventListener('change', (event) => { | ||
alert('change'); | ||
const target = event.target; | ||
if (isNaN(target.value)) { | ||
target.value = '42'; | ||
} | ||
}); | ||
}); | ||
</script> | ||
|
||
## States | ||
|
||
Use the `required` attribute to indicate a number field value is required. Dictate the validity or invalidity state of the text entry with the `valid` or `invalid` attributes. | ||
|
||
```html | ||
<sp-field-label for="number-1" required>Count</sp-field-label> | ||
<sp-number-field id="number-1" valid value="12343"></sp-number-field> | ||
<br /> | ||
<sp-field-label for="number-2" required>Size</sp-field-label> | ||
<sp-number-field id="number-2" invalid value="15212"></sp-number-field> | ||
``` |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marissahuysentruyt glad you enjoyed my little Easter egg.