feat: add input stepper component

This commit is contained in:
Hardik Pithva 2020-09-22 13:22:48 +02:00 committed by Thomas Allmer
parent 526aee2006
commit ba72b32b00
11 changed files with 527 additions and 18 deletions

View file

@ -0,0 +1,5 @@
---
'@lion/input-stepper': minor
---
Release initial version of an input stepper

View file

@ -54,6 +54,7 @@ The accessibility column indicates whether the functionality is accessible in it
| [input-email](https://lion-web-components.netlify.app/?path=/docs/forms-input-email--main) | [![input-email](https://img.shields.io/npm/v/@lion/input-email.svg)](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | ✔️ | | [input-email](https://lion-web-components.netlify.app/?path=/docs/forms-input-email--main) | [![input-email](https://img.shields.io/npm/v/@lion/input-email.svg)](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | ✔️ |
| [input-iban](https://lion-web-components.netlify.app/?path=/docs/forms-input-iban--main) | [![input-iban](https://img.shields.io/npm/v/@lion/input-iban.svg)](https://www.npmjs.com/package/@lion/input-iban) | Input element for IBANs | ✔️ | | [input-iban](https://lion-web-components.netlify.app/?path=/docs/forms-input-iban--main) | [![input-iban](https://img.shields.io/npm/v/@lion/input-iban.svg)](https://www.npmjs.com/package/@lion/input-iban) | Input element for IBANs | ✔️ |
| [input-range](https://lion-web-components.netlify.app/?path=/docs/forms-input-range--main) | [![input-range](https://img.shields.io/npm/v/@lion/input-range.svg)](https://www.npmjs.com/package/@lion/input-range) | Input element for a range of values | ✔️ | | [input-range](https://lion-web-components.netlify.app/?path=/docs/forms-input-range--main) | [![input-range](https://img.shields.io/npm/v/@lion/input-range.svg)](https://www.npmjs.com/package/@lion/input-range) | Input element for a range of values | ✔️ |
| [input-stepper](https://lion-web-components.netlify.app/?path=/docs/forms-input-stepper--main) | [![input-stepper](https://img.shields.io/npm/v/@lion/input-stepper.svg)](https://www.npmjs.com/package/@lion/input-stepper) | Input stepper element for the predefined range | ✔️ |
| [radio-group](https://lion-web-components.netlify.app/?path=/docs/forms-radio-group--main) | [![radio-group](https://img.shields.io/npm/v/@lion/radio-group.svg)](https://www.npmjs.com/package/@lion/radio-group) | Group of radios | ✔️ | | [radio-group](https://lion-web-components.netlify.app/?path=/docs/forms-radio-group--main) | [![radio-group](https://img.shields.io/npm/v/@lion/radio-group.svg)](https://www.npmjs.com/package/@lion/radio-group) | Group of radios | ✔️ |
| [select](https://lion-web-components.netlify.app/?path=/docs/forms-select--main) | [![select](https://img.shields.io/npm/v/@lion/select.svg)](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | ✔️ | | [select](https://lion-web-components.netlify.app/?path=/docs/forms-select--main) | [![select](https://img.shields.io/npm/v/@lion/select.svg)](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | ✔️ |
| [select-rich](https://lion-web-components.netlify.app/?path=/docs/forms-select-rich--main) | [![select-rich](https://img.shields.io/npm/v/@lion/select-rich.svg)](https://www.npmjs.com/package/@lion/select-rich) | 'rich' version of the native dropdown element | [#243][i243] | | [select-rich](https://lion-web-components.netlify.app/?path=/docs/forms-select-rich--main) | [![select-rich](https://img.shields.io/npm/v/@lion/select-rich.svg)](https://www.npmjs.com/package/@lion/select-rich) | 'rich' version of the native dropdown element | [#243][i243] |

View file

@ -20,21 +20,22 @@ For a more in depth description look into the [Form System Overview](?path=/docs
## Packages ## Packages
| Package | Version | Description | | Package | Version | Description |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- | | -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| [checkbox-group](?path=/docs/forms-checkbox-group--main) | [![checkbox-group](https://img.shields.io/npm/v/@lion/checkbox-group.svg)](https://www.npmjs.com/package/@lion/checkbox-group) | Group of checkboxes | | [checkbox-group](?path=/docs/forms-checkbox-group--main) | [![checkbox-group](https://img.shields.io/npm/v/@lion/checkbox-group.svg)](https://www.npmjs.com/package/@lion/checkbox-group) | Group of checkboxes |
| [form-core](?path=/docs/forms-system-overview--page) | [![form-core](https://img.shields.io/npm/v/@lion/form-core.svg)](https://www.npmjs.com/package/@lion/form-core) | Core functionality for all controls | | [form-core](?path=/docs/forms-system-overview--page) | [![form-core](https://img.shields.io/npm/v/@lion/form-core.svg)](https://www.npmjs.com/package/@lion/form-core) | Core functionality for all controls |
| [form-integrations](?path=/docs/forms-features-overview--main) | [![form-integrations](https://img.shields.io/npm/v/@lion/form-integrations.svg)](https://www.npmjs.com/package/@lion/form-integrations) | Shows form elements in an integrated way | | [form-integrations](?path=/docs/forms-features-overview--main) | [![form-integrations](https://img.shields.io/npm/v/@lion/form-integrations.svg)](https://www.npmjs.com/package/@lion/form-integrations) | Shows form elements in an integrated way |
| [fieldset](?path=/docs/forms-fieldset-overview--main) | [![fieldset](https://img.shields.io/npm/v/@lion/fieldset.svg)](https://www.npmjs.com/package/@lion/fieldset) | Group for form inputs | | [fieldset](?path=/docs/forms-fieldset-overview--main) | [![fieldset](https://img.shields.io/npm/v/@lion/fieldset.svg)](https://www.npmjs.com/package/@lion/fieldset) | Group for form inputs |
| [form](?path=/docs/forms-form-overview--main) | [![form](https://img.shields.io/npm/v/@lion/form.svg)](https://www.npmjs.com/package/@lion/form) | Wrapper for multiple form elements | | [form](?path=/docs/forms-form-overview--main) | [![form](https://img.shields.io/npm/v/@lion/form.svg)](https://www.npmjs.com/package/@lion/form) | Wrapper for multiple form elements |
| [input](?path=/docs/forms-input--main) | [![input](https://img.shields.io/npm/v/@lion/input.svg)](https://www.npmjs.com/package/@lion/input) | Input element for strings | | [input](?path=/docs/forms-input--main) | [![input](https://img.shields.io/npm/v/@lion/input.svg)](https://www.npmjs.com/package/@lion/input) | Input element for strings |
| [input-amount](?path=/docs/forms-input-amount--main) | [![input-amount](https://img.shields.io/npm/v/@lion/input-amount.svg)](https://www.npmjs.com/package/@lion/input-amount) | Input element for amounts | | [input-amount](?path=/docs/forms-input-amount--main) | [![input-amount](https://img.shields.io/npm/v/@lion/input-amount.svg)](https://www.npmjs.com/package/@lion/input-amount) | Input element for amounts |
| [input-date](?path=/docs/forms-input-date--main) | [![input-date](https://img.shields.io/npm/v/@lion/input-date.svg)](https://www.npmjs.com/package/@lion/input-date) | Input element for dates | | [input-date](?path=/docs/forms-input-date--main) | [![input-date](https://img.shields.io/npm/v/@lion/input-date.svg)](https://www.npmjs.com/package/@lion/input-date) | Input element for dates |
| [input-datepicker](?path=/docs/forms-input-datepicker--main) | [![input-datepicker](https://img.shields.io/npm/v/@lion/input-datepicker.svg)](https://www.npmjs.com/package/@lion/input-datepicker) | Input element for dates with a datepicker | | [input-datepicker](?path=/docs/forms-input-datepicker--main) | [![input-datepicker](https://img.shields.io/npm/v/@lion/input-datepicker.svg)](https://www.npmjs.com/package/@lion/input-datepicker) | Input element for dates with a datepicker |
| [input-email](?path=/docs/forms-input-email--main) | [![input-email](https://img.shields.io/npm/v/@lion/input-email.svg)](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails | | [input-email](?path=/docs/forms-input-email--main) | [![input-email](https://img.shields.io/npm/v/@lion/input-email.svg)](https://www.npmjs.com/package/@lion/input-email) | Input element for e-mails |
| [input-iban](?path=/docs/forms-input-iban--main) | [![input-iban](https://img.shields.io/npm/v/@lion/input-iban.svg)](https://www.npmjs.com/package/@lion/input-iban) | Input element for IBANs | | [input-iban](?path=/docs/forms-input-iban--main) | [![input-iban](https://img.shields.io/npm/v/@lion/input-iban.svg)](https://www.npmjs.com/package/@lion/input-iban) | Input element for IBANs |
| [input-range](?path=/docs/forms-input-range--main) | [![input-range](https://img.shields.io/npm/v/@lion/input-range.svg)](https://www.npmjs.com/package/@lion/input-range) | Input element for a range of values | | [input-range](?path=/docs/forms-input-range--main) | [![input-range](https://img.shields.io/npm/v/@lion/input-range.svg)](https://www.npmjs.com/package/@lion/input-range) | Input element for a range of values |
| [radio-group](?path=/docs/forms-radio-group--main) | [![radio-group](https://img.shields.io/npm/v/@lion/radio-group.svg)](https://www.npmjs.com/package/@lion/radio-group) | Group of radios | | [input-stepper](?path=/docs/forms-input-stepper--main) | [![input-stepper](https://img.shields.io/npm/v/@lion/input-stepper.svg)](https://www.npmjs.com/package/@lion/input-stepper) | Input stepper element for the predefined range |
| [select](?path=/docs/forms-select--main) | [![select](https://img.shields.io/npm/v/@lion/select.svg)](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element | | [radio-group](?path=/docs/forms-radio-group--main) | [![radio-group](https://img.shields.io/npm/v/@lion/radio-group.svg)](https://www.npmjs.com/package/@lion/radio-group) | Group of radios |
| [select-rich](?path=/docs/forms-select-rich--main) | [![select-rich](https://img.shields.io/npm/v/@lion/select-rich.svg)](https://www.npmjs.com/package/@lion/select-rich) | 'rich' version of the native dropdown element | | [select](?path=/docs/forms-select--main) | [![select](https://img.shields.io/npm/v/@lion/select.svg)](https://www.npmjs.com/package/@lion/select) | Simple native dropdown element |
| [textarea](?path=/docs/forms-textarea--main) | [![textarea](https://img.shields.io/npm/v/@lion/textarea.svg)](https://www.npmjs.com/package/@lion/textarea) | Multiline text input | | [select-rich](?path=/docs/forms-select-rich--main) | [![select-rich](https://img.shields.io/npm/v/@lion/select-rich.svg)](https://www.npmjs.com/package/@lion/select-rich) | 'rich' version of the native dropdown element |
| [textarea](?path=/docs/forms-textarea--main) | [![textarea](https://img.shields.io/npm/v/@lion/textarea.svg)](https://www.npmjs.com/package/@lion/textarea) | Multiline text input |

View file

@ -17,6 +17,7 @@ import '@lion/input-datepicker/lion-input-datepicker.js';
import '@lion/input-email/lion-input-email.js'; import '@lion/input-email/lion-input-email.js';
import '@lion/input-iban/lion-input-iban.js'; import '@lion/input-iban/lion-input-iban.js';
import '@lion/input-range/lion-input-range.js'; import '@lion/input-range/lion-input-range.js';
import '@lion/input-stepper/lion-input-stepper.js';
import '@lion/input/lion-input.js'; import '@lion/input/lion-input.js';
import '@lion/radio-group/lion-radio-group.js'; import '@lion/radio-group/lion-radio-group.js';
import '@lion/radio-group/lion-radio.js'; import '@lion/radio-group/lion-radio.js';
@ -123,6 +124,12 @@ export const main = () => {
> >
<lion-checkbox label="I blindly accept all terms and conditions"></lion-checkbox> <lion-checkbox label="I blindly accept all terms and conditions"></lion-checkbox>
</lion-checkbox-group> </lion-checkbox-group>
<lion-input-stepper max="5" min="0" name="rsvp">
<label slot="label">RSVP</label>
<div slot="help-text">
Max. 5 guests
</div>
</lion-input-stepper>
<lion-textarea name="comments" label="Comments"></lion-textarea> <lion-textarea name="comments" label="Comments"></lion-textarea>
<div class="buttons"> <div class="buttons">
<lion-button raised>Submit</lion-button> <lion-button raised>Submit</lion-button>

View file

@ -0,0 +1 @@
# Change Log

View file

@ -0,0 +1,136 @@
# Input Stepper
`lion-input-stepper` enables the user to increase and decrease a numeric value by predefined range. It is a combination of two buttons and a number input field with an optional slot `after` to suffix the extra information.
```js script
import { html } from 'lit-html';
import '@lion/form/lion-form.js';
import './lion-input-stepper.js';
export default {
title: 'Forms/Input Stepper',
};
```
```js preview-story
export const main = () => html`
<lion-input-stepper max="5" min="0" name="count">
<label slot="label">RSVP</label>
<div slot="help-text">Max. 5 guests</div>
</lion-input-stepper>
`;
```
## Features
- Based on [lion-input](?path=/docs/forms-input--main#input).
- Set `min` and `max` value to define the range.
- Set `step` value in integer or decimal to increase and decrease the value.
- Use `ArrowUp` or `ArrowDown` to update the value.
## How to use
### Installation
```bash
npm i --save @lion/input-stepper
```
```js
import { LionInputStepper } from '@lion/input-stepper';
// or
import '@lion/input-stepper/lion-input-stepper.js';
```
### Usage
```html
<lion-input-stepper max="5" min="0" name="count">
<label slot="label">RSVP</label>
<div slot="help-text">Max. 5 guests</div>
</lion-input-stepper>
```
### Examples
#### Default with no specification
When no range or step is defined, it can go infinite with default step value as `1`. You can also specify prefix content using `after` slot.
```js preview-story
export const defaultMode = () => html`
<label>How old is the existence?</label>
<lion-input-stepper name="year">
<div slot="after">In Billion Years</div>
</lion-input-stepper>
`;
```
#### Step and Value
Use `step` attribute to specify the incrementor or decrementor difference and `value` to set the default value.
```js preview-story
export const steps = () => html`
<p><strong>Min:</strong> 100, <strong>Value:</strong> 200, <strong>Step:</strong> 100</p>
<lion-input-stepper min="100" step="100" name="value" value="200"></lion-input-stepper>
`;
```
#### Range
Use `min` and `max` attribute to specify range.
```js preview-story
export const range = () => html`
<p><strong>Min:</strong> 200, <strong>Max:</strong> 500, <strong>Step:</strong> 100</p>
<lion-input-stepper min="200" max="500" name="value" step="100" value="200"></lion-input-stepper>
`;
```
#### Validation
Only numbers are allowed in the field.
```js preview-story
export const validation = () => html`
<p>
<strong>Min:</strong> 100, <strong>Max:</strong> 500, <strong>Step:</strong> 100,
<strong>Value:</strong> Test
</p>
<lion-input-stepper min="100" max="500" name="value" step="100" value="Test"></lion-input-stepper>
`;
```
#### Form
```js preview-story
export const usingForm = () => html`
<lion-form
@submit=${e => {
console.log(e.target.serializedValue);
const code = document.getElementById('code');
code.style = 'background-color:#DEDEDE;padding:12px;';
code.innerHTML = `<code>${JSON.stringify(e.target.serializedValue, null, 4)}</code>`;
}}
>
<form>
<lion-input name="fullname" label="Full name"></lion-input>
<br />
<lion-input-stepper min="0" max="5" name="count">
<label slot="label">RSVP</label>
<div slot="help-text">Max. 5 guests</div>
</lion-input-stepper>
<br />
<lion-button raised>Submit</lion-button>
<lion-button
type="button"
raised
@click=${ev => ev.currentTarget.parentElement.parentElement.resetGroup()}
>Reset</lion-button
>
</form>
</lion-form>
<pre id="code"></pre>
`;
```

View file

@ -0,0 +1 @@
export { LionInputStepper } from './src/LionInputStepper.js';

View file

@ -0,0 +1,3 @@
import { LionInputStepper } from './src/LionInputStepper.js';
customElements.define('lion-input-stepper', LionInputStepper);

View file

@ -0,0 +1,48 @@
{
"name": "@lion/input-stepper",
"version": "0.0.0",
"description": "This component enables the user to increase and decrease a numeric value by predefined range.",
"license": "MIT",
"author": "ing-bank",
"homepage": "https://github.com/ing-bank/lion/",
"repository": {
"type": "git",
"url": "https://github.com/ing-bank/lion.git",
"directory": "packages/input-stepper"
},
"main": "index.js",
"module": "index.js",
"files": [
"*.d.ts",
"*.js",
"docs",
"src",
"test",
"test-helpers",
"translations",
"types"
],
"scripts": {
"prepublishOnly": "../../scripts/npm-prepublish.js",
"start": "cd ../../ && yarn dev-server --open packages/input-stepper/README.md",
"test": "cd ../../ && yarn test:browser --grep \"packages/input-stepper/test/**/*.test.js\"",
"test:watch": "cd ../../ && yarn test:browser:watch --grep \"packages/input-stepper/test/**/*.test.js\""
},
"sideEffects": [
"lion-input-stepper.js"
],
"dependencies": {
"@lion/core": "0.12.0",
"@lion/form-core": "0.6.1",
"@lion/input": "0.9.2"
},
"keywords": [
"input",
"input-stepper",
"lion",
"web-components"
],
"publishConfig": {
"access": "public"
}
}

View file

@ -0,0 +1,238 @@
import { html, css } from '@lion/core';
import { LionInput } from '@lion/input';
import { IsNumber, MinNumber, MaxNumber } from '@lion/form-core';
/**
* `LionInputStepper` is a class for custom input-stepper element (`<lion-input-stepper>` web component).
*
* @customElement lion-input-stepper
* @extends LitElement
*/
export class LionInputStepper extends LionInput {
static get styles() {
return [
super.styles,
css`
.input-group__container > .input-group__input ::slotted(.form-control) {
text-align: center;
}
`,
];
}
static get properties() {
return {
min: Number,
max: Number,
step: Number,
modelValue: Number,
__disableIncrementor: Boolean,
__disableDecrementor: Boolean,
};
}
get currentValue() {
return parseFloat(this.value || 0);
}
constructor() {
super();
this.parser = modelValue => parseFloat(modelValue);
this.__disableIncrementor = false;
this.__disableDecrementor = false;
}
connectedCallback() {
if (super.connectedCallback) {
super.connectedCallback();
}
this.role = 'spinbutton';
this.addEventListener('keydown', this.__keyDownHandler);
this._inputNode.setAttribute('inputmode', 'decimal');
this._inputNode.setAttribute('autocomplete', 'off');
this.step = this.hasAttribute('step') ? this.step : 1;
this.__setAriaLabelsAndValidator();
this.__toggleSpinnerButtonsState();
}
disconnectedCallback() {
if (super.disconnectedCallback) {
super.disconnectedCallback();
}
this.removeEventListener('keydown', this.__keyDownHandler);
}
/**
* Update native input values
* @param {Object} changedProps - changed props
*/
updated(changedProps) {
super.updated(changedProps);
if (changedProps.has('min')) {
this._inputNode.min = this.min;
}
if (changedProps.has('max')) {
this._inputNode.max = this.max;
}
if (changedProps.has('step')) {
this._inputNode.step = this.step;
}
}
/**
* Set aria labels and apply validators
* @private
*/
__setAriaLabelsAndValidator() {
this.values = {
max: parseFloat(this.max || Infinity),
min: parseFloat(this.min || Infinity),
step: parseFloat(this.step),
};
const ariaAttributes = {
'aria-valuemax': this.values.max,
'aria-valuemin': this.values.min,
};
let validators = Object.entries(ariaAttributes)
.map(([key, val]) => {
if (val !== Infinity) {
this.setAttribute(key, val);
return key === 'aria-valuemax' ? new MaxNumber(val) : new MinNumber(val);
}
return null;
})
.filter(validator => validator);
validators = [new IsNumber(), ...validators];
this.defaultValidators.push(...validators);
}
/**
* Update values on keyboard arrow up and down event
* @param {KeyboardEvent} e - keyboard event
* @private
*/
__keyDownHandler(e) {
if (e.key === 'ArrowUp') {
this.__increment();
}
if (e.key === 'ArrowDown') {
this.__decrement();
}
}
/**
* Toggle disabled state for the buttons
* @private
*/
__toggleSpinnerButtonsState() {
const { min, max } = this.values;
this.__disableIncrementor = this.currentValue >= max && max !== Infinity;
this.__disableDecrementor = this.currentValue <= min && min !== Infinity;
this.setAttribute('aria-valuenow', this.currentValue);
this.dispatchEvent(
new CustomEvent('user-input-changed', {
bubbles: true,
}),
);
}
/**
* Increment the value based on given step or default step value is 1
* @private
*/
__increment() {
const { step, max } = this.values;
const newValue = this.currentValue + step;
if (newValue <= max || max === Infinity) {
this.value = newValue;
this.__toggleSpinnerButtonsState();
}
}
/**
* Decrement the value based on given step or default step value is 1
* @private
*/
__decrement() {
const { step, min } = this.values;
const newValue = this.currentValue - step;
if (newValue >= min || min === Infinity) {
this.value = newValue;
this.__toggleSpinnerButtonsState();
}
}
/**
* Toggle +/- buttons on change
* @override
*/
_onChange() {
super._onChange();
this.__toggleSpinnerButtonsState();
}
/**
* Override after template to none
* @override
*/
// eslint-disable-next-line class-methods-use-this
_inputGroupAfterTemplate() {
return html``;
}
/**
* Override before template to none
* @override
*/
// eslint-disable-next-line class-methods-use-this
_inputGroupBeforeTemplate() {
return html``;
}
/**
* Override prefix template for the increment button
* @override
*/
// eslint-disable-next-line class-methods-use-this
_inputGroupPrefixTemplate() {
return html`
<button
?disabled=${this.disabled || this.readOnly || this.__disableDecrementor}
@click=${this.__decrement}
tabindex="-1"
name="decrement"
type="button"
aria-label="decrement"
>
-
</button>
`;
}
/**
* Override suffix template for the decrement button and add after slot
* @override
*/
// eslint-disable-next-line class-methods-use-this
_inputGroupSuffixTemplate() {
return html`
<button
?disabled=${this.disabled || this.readOnly || this.__disableIncrementor}
@click=${this.__increment}
tabindex="-1"
name="increment"
type="button"
aria-label="increment"
>
+
</button>
<slot name="after"></slot>
`;
}
}

View file

@ -0,0 +1,68 @@
import { expect, fixture, nextFrame, html } from '@open-wc/testing';
import '../lion-input-stepper.js';
const defaultInputStepper = html`
<lion-input-stepper name="year" label="Years"></lion-input-stepper>
`;
const inputStepperWithAttrs = html`<lion-input-stepper min="100" max="200"></lion-input-stepper>`;
describe('<lion-input-stepper>', () => {
describe('Stepper', () => {
it('has a type text', async () => {
const el = await fixture(defaultInputStepper);
expect(el._inputNode.type).to.equal('text');
});
});
describe('User interaction', () => {
it('should increment the value to 1 on + button click', async () => {
const el = await fixture(defaultInputStepper);
expect(el.value).to.equal('');
const incrementButton = el.shadowRoot.querySelector('[name=increment]');
incrementButton.dispatchEvent(new Event('click'));
expect(el.value).to.equal('1');
});
it('should decrement the value to -1 on - button click', async () => {
const el = await fixture(defaultInputStepper);
expect(el.value).to.equal('');
const incrementButton = el.shadowRoot.querySelector('[name=decrement]');
incrementButton.dispatchEvent(new Event('click'));
expect(el.value).to.equal('-1');
});
it('should update min and max attributes when min and max property change', async () => {
const el = await fixture(inputStepperWithAttrs);
el.min = '100';
el.max = '200';
await nextFrame();
expect(el._inputNode.min).to.equal(el.min);
expect(el._inputNode.max).to.equal(el.max);
});
});
describe('Accessibility', () => {
it('is a11y AXE accessible', async () => {
const el = await fixture(defaultInputStepper);
await expect(el).to.be.accessible();
});
it('is accessible when disabled', async () => {
const el = await fixture(`<lion-input-stepper label="rsvp" disabled></lion-input-stepper>`);
await expect(el).to.be.accessible();
});
it('adds aria-valuemax and aria-valuemin when min and max are provided', async () => {
const el = await fixture(inputStepperWithAttrs);
expect(el).to.have.attribute('aria-valuemax', '200');
expect(el).to.have.attribute('aria-valuemin', '100');
});
it('updates aria-valuenow when stepper is changed', async () => {
const el = await fixture(inputStepperWithAttrs);
const incrementButton = el.shadowRoot.querySelector('[name=increment]');
incrementButton.dispatchEvent(new Event('click'));
expect(el).to.have.attribute('aria-valuenow', '1');
});
});
});