Skip to content

Commit

Permalink
feat: multi-handle slider implementation
Browse files Browse the repository at this point in the history
Implement multi-handle slider support as discussed in #1385
  • Loading branch information
Michael Taylor authored and Westbrook committed Jun 11, 2021
1 parent fa9e5e0 commit 8d5a743
Show file tree
Hide file tree
Showing 15 changed files with 1,810 additions and 332 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ executors:
parameters:
current_golden_images_hash:
type: string
default: af2206f0506c49d7127e6ae9070d8f2359b7e12e
default: 26ae0c0f5ea0cd3952923e8c2a0d06cb387ba439
commands:
downstream:
steps:
Expand Down
1 change: 1 addition & 0 deletions packages/bundle/elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import '@spectrum-web-components/sidenav/sp-sidenav.js';
import '@spectrum-web-components/sidenav/sp-sidenav-heading.js';
import '@spectrum-web-components/sidenav/sp-sidenav-item.js';
import '@spectrum-web-components/slider/sp-slider.js';
import '@spectrum-web-components/slider/sp-slider-handle.js';
import '@spectrum-web-components/split-button/sp-split-button.js';
import '@spectrum-web-components/split-view/sp-split-view.js';
import '@spectrum-web-components/status-light/sp-status-light.js';
Expand Down
39 changes: 39 additions & 0 deletions packages/slider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,45 @@ import { Slider } from '@spectrum-web-components/slider';
<sp-slider label="Slider Label - Disabled" variant="ramp" disabled></sp-slider>
```

## Advanced normalization

By default, `sp-slider` assumes a linear scale between the `min` and `max` values.
For advanced applications, it is sometimes necessary to specify a custom
"normalization."

Normalization is the process of converting a slider to a value between 0 and 1 where
0 represents the minimum and 1 represents the maximum. See the <a href="storybook/index.html?path=/story/slider--three-handles-complex" target="_blank">"Three Handles Complex" example in the playground</a>.

## Labels and Formatting

An `<sp-slider>` or `<sp-slider-handle>` element will process its numeric value with `new Intl.NumberFormat(navigator.language, 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 follows.

```html
<sp-slider
min="0"
max="1"
step="0.01"
value="0.5"
label="Slider Label"
format-options='{
"style": "percent"
}'
></sp-slider>
```

More advanced formatting is avialable by specifying a formatting function to
the `getAriaHandleText` property on an `sp-slider` or `sp-slider-handle`. Or,
for a multi-handle slider, you can format the combined value label for all
handles by passing a formatting function to the `getAriaValueText` property
on the parent `sp-slider`.

You can suppress the value label altogether using the `hide-value-label`
attribute.

```html
<sp-slider label="No value label" hide-value-label></sp-slider>
```

## Events

Like the `<input type="range">` element after which the `<sp-slider>` is fashioned it will dispatch `input` events in a stream culminating with a `change` event (representing the final comit of the `value` to the element) once the user has discontinued with the element. Both other these events can access the `value` of their dispatching target via `event.target.value`. In this way a steaming listener patters similar to the following can prove useful:
Expand Down
5 changes: 4 additions & 1 deletion packages/slider/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@
"./src/*": "./src/*",
"./package.json": "./package.json",
"./sp-slider": "./sp-slider.js",
"./sp-slider.js": "./sp-slider.js"
"./sp-slider.js": "./sp-slider.js",
"./sp-slider-handle": "./sp-slider-handle.js",
"./sp-slider-handle.js": "./sp-slider-handle.js"
},
"scripts": {
"test": "echo \"Error: run tests from mono-repo root.\" && exit 1"
Expand All @@ -43,6 +45,7 @@
"lit-html"
],
"dependencies": {
"@internationalized/number": "^3.0.0",
"@spectrum-web-components/base": "^0.4.3",
"@spectrum-web-components/shared": "^0.12.4",
"tslib": "^2.0.0"
Expand Down
77 changes: 77 additions & 0 deletions packages/slider/slider-handle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
## Description

Some advanced slider uses require more than one handle. One example of this is the
range slider above. `sp-slider` supports an arbitrary number of handles via the `<sp-slider-handle>` sub-component, although it would be very rare to ever require more than two handles.

### Usage

[![See it on NPM!](https://img.shields.io/npm/v/@spectrum-web-components/slider?style=for-the-badge)](https://www.npmjs.com/package/@spectrum-web-components/slider)
[![How big is this package in your project?](https://img.shields.io/bundlephobia/minzip/@spectrum-web-components/slider?style=for-the-badge)](https://bundlephobia.com/result?p=@spectrum-web-components/slider)
[![Try it on webcomponents.dev](https://img.shields.io/badge/Try%20it%20on-webcomponents.dev-green?style=for-the-badge)](https://webcomponents.dev/edit/collection/fO75441E1Q5ZlI0e9pgq/U7LQv7LsAVBwJayJXG3B/src/index.ts)

```
yarn add @spectrum-web-components/slider
```

Import the side effectful registration of `<sp-slider>` and `<sp-slider-handle>` via:

```
import '@spectrum-web-components/slider/sp-slider.js';
import '@spectrum-web-components/slider/sp-slider-handle.js';
```

## Examples

### Range Slider

This examples uses the `"range"` variant along with two handles to create a range slider.

```html
<sp-slider variant="range" step="1" min="0" max="255">
Output Levels
<sp-slider-handle
slot="handle"
name="min"
label="Minimum"
value="5"
></sp-slider-handle>
<sp-slider-handle
slot="handle"
name="max"
label="Maximum"
value="250"
></sp-slider-handle>
</sp-slider>
```

## Multi-handle Slider with Ordered Handles

For slider handles that have the same numeric range, you can specify `min="previous"` or `max="next"` to constrain handles by the values of their neighbours.

```html
<sp-slider step="1" min="0" max="255">
Output Levels
<sp-slider-handle
slot="handle"
name="low"
label="Low"
value="5"
max="next"
></sp-slider-handle>
<sp-slider-handle
slot="handle"
name="mid"
label="Mid"
value="100"
min="previous"
max="next"
></sp-slider-handle>
<sp-slider-handle
slot="handle"
name="high"
label="High"
value="250"
min="previous"
></sp-slider-handle>
</sp-slider>
```
20 changes: 20 additions & 0 deletions packages/slider/sp-slider-handle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright 2021 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License.
*/
import { SliderHandle } from './src/SliderHandle.js';

customElements.define('sp-slider-handle', SliderHandle);

declare global {
interface HTMLElementTagNameMap {
'sp-slider-handle': SliderHandle;
}
}
Loading

0 comments on commit 8d5a743

Please sign in to comment.