Skip to content
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

feat(sbb-slider): implement native form support #3071

Merged
merged 12 commits into from
Sep 26, 2024
12 changes: 6 additions & 6 deletions src/elements/checkbox/common/checkbox-common.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ describe(`checkbox common behaviors`, () => {
expect(snapshot.required).not.to.be.ok;
});

it('should should restore form state on formStateRestoreCallback()', async () => {
it('should restore form state on formStateRestoreCallback()', async () => {
// Mimic tab restoration. Does not test the full cycle as we can not set the browser in the required state.
element.formStateRestoreCallback('true', 'restore');
await waitForLitRender(element);
Expand Down Expand Up @@ -537,11 +537,11 @@ describe(`checkbox common behaviors`, () => {
expect(element).not.to.have.attribute('disabled');
}

const disabledElements = Array.from(form.querySelectorAll(':disabled'));

expect(disabledElements.includes(element), ':disabled selector').to.be.equal(
assertions.disabledSelector,
);
if (assertions.disabledSelector) {
expect(element).to.match(':disabled');
} else {
expect(element).not.to.match(':disabled');
}

const snapshot = (await a11ySnapshot({
selector: element.localName,
Expand Down
133 changes: 109 additions & 24 deletions src/elements/slider/__snapshots__/slider.snapshot.spec.snap.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,7 @@ export const snapshots = {};

snapshots["sbb-slider renders DOM"] =
`<sbb-slider
aria-valuemax="100"
aria-valuemin="0"
aria-valuenow="1"
name=""
role="slider"
id="slider-1"
tabindex="0"
value="1"
>
Expand Down Expand Up @@ -48,14 +44,9 @@ snapshots["sbb-slider renders Shadow DOM"] =

snapshots["sbb-slider renders with properties DOM"] =
`<sbb-slider
aria-valuemax="500"
aria-valuemin="0"
aria-valuenow="100"
end-icon="walk-fast-small"
max="500"
min="0"
name=""
role="slider"
start-icon="walk-slow-small"
tabindex="0"
value="100"
Expand Down Expand Up @@ -111,17 +102,12 @@ snapshots["sbb-slider renders with properties Shadow DOM"] =

snapshots["sbb-slider renders disabled DOM"] =
`<sbb-slider
aria-disabled="true"
aria-valuemax="500"
aria-valuemin="0"
aria-valuenow="100"
disabled=""
end-icon="walk-fast-small"
max="500"
min="0"
name=""
role="slider"
start-icon="walk-slow-small"
tabindex="0"
value="100"
>
</sbb-slider>
Expand Down Expand Up @@ -176,16 +162,10 @@ snapshots["sbb-slider renders disabled Shadow DOM"] =

snapshots["sbb-slider renders readonly DOM"] =
`<sbb-slider
aria-readonly="true"
aria-valuemax="500"
aria-valuemin="0"
aria-valuenow="100"
end-icon="walk-fast-small"
max="500"
min="0"
name=""
readonly=""
role="slider"
start-icon="walk-slow-small"
tabindex="0"
value="100"
Expand Down Expand Up @@ -246,9 +226,13 @@ snapshots["sbb-slider renders A11y tree Chrome"] =
"role": "WebArea",
"name": "",
"children": [
{
"role": "text",
"name": "Label"
},
{
"role": "slider",
"name": "",
"name": "Label",
"valuetext": "",
"valuemin": 0,
"valuemax": 100,
Expand Down Expand Up @@ -331,9 +315,13 @@ snapshots["sbb-slider renders A11y tree Firefox"] =
"role": "document",
"name": "",
"children": [
{
"role": "text leaf",
"name": "Label"
},
{
"role": "slider",
"name": "",
"name": "Label",
"valuetext": "1",
"value": "1"
}
Expand Down Expand Up @@ -398,3 +386,100 @@ snapshots["sbb-slider renders readonly A11y tree Firefox"] =
`;
/* end snapshot sbb-slider renders readonly A11y tree Firefox */

snapshots["sbb-slider renders in form DOM"] =
`<sbb-slider
max="10"
min="0"
name="sbb-slider"
tabindex="0"
value="1"
>
</sbb-slider>
`;
/* end snapshot sbb-slider renders in form DOM */

snapshots["sbb-slider renders in form Shadow DOM"] =
`<div class="sbb-slider__height-container">
<div class="sbb-slider__wrapper">
<slot name="prefix">
</slot>
<div
class="sbb-slider__container"
style="--sbb-slider-value-fraction:0.1;"
>
<input
class="sbb-slider__range-input"
max="10"
min="0"
tabindex="-1"
type="range"
value="1"
>
<div class="sbb-slider__line">
<div class="sbb-slider__selected-line">
</div>
</div>
<div class="sbb-slider__knob">
</div>
</div>
<slot name="suffix">
</slot>
</div>
</div>
`;
/* end snapshot sbb-slider renders in form Shadow DOM */

snapshots["sbb-slider renders in form A11y tree Chrome"] =
`<p>
{
"role": "WebArea",
"name": "",
"children": [
{
"role": "slider",
"name": "",
"valuetext": "",
"valuemin": 0,
"valuemax": 10,
"orientation": "horizontal",
"value": 1
},
{
"role": "slider",
"name": "",
"valuetext": "",
"valuemin": 0,
"valuemax": 10,
"orientation": "horizontal",
"value": 1
}
]
}
</p>
`;
/* end snapshot sbb-slider renders in form A11y tree Chrome */

snapshots["sbb-slider renders in form A11y tree Firefox"] =
`<p>
{
"role": "document",
"name": "",
"children": [
{
"role": "slider",
"name": "",
"valuetext": "1",
"value": "1"
},
{
"role": "slider",
"name": "",
"valuetext": "1",
"value": "1"
}
]
}
</p>
`;
/* end snapshot sbb-slider renders in form A11y tree Firefox */

25 changes: 12 additions & 13 deletions src/elements/slider/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,24 @@ The `sbb-slider` has the following behaviour on keypress when focused:

## Properties

| Name | Attribute | Privacy | Type | Default | Description |
| --------------- | ----------------- | ------- | ---------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `disabled` | `disabled` | public | `boolean` | `false` | Whether the component is disabled. |
| `endIcon` | `end-icon` | public | `string \| undefined` | | Name of the icon at component's end, which will be forward to the nested `sbb-icon`. |
| `form` | `form` | public | `string \| undefined` | | The <form> element to associate the inner HTMLInputElement with. |
| `max` | `max` | public | `string \| undefined` | `'100'` | Maximum acceptable value for the inner HTMLInputElement. |
| `min` | `min` | public | `string \| undefined` | `'0'` | Minimum acceptable value for the inner HTMLInputElement. |
| `name` | `name` | public | `string \| undefined` | `''` | Name of the inner HTMLInputElement. |
| `readonly` | `readonly` | public | `boolean \| undefined` | `false` | Readonly state for the inner HTMLInputElement. Since the input range does not allow this attribute, it will be merged with the `disabled` one. |
| `startIcon` | `start-icon` | public | `string \| undefined` | | Name of the icon at component's start, which will be forward to the nested `sbb-icon`. |
| `value` | `value` | public | `string \| undefined` | `''` | Value for the inner HTMLInputElement. |
| `valueAsNumber` | `value-as-number` | public | `number \| undefined` | | Numeric value for the inner HTMLInputElement. |
| Name | Attribute | Privacy | Type | Default | Description |
| --------------- | ----------------- | ------- | ------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `disabled` | `disabled` | public | `boolean` | `false` | Whether the component is disabled. |
| `endIcon` | `end-icon` | public | `string \| undefined` | | Name of the icon at component's end, which will be forward to the nested `sbb-icon`. |
| `form` | - | public | `HTMLFormElement \| null` | | Returns the form owner of internals target element. |
| `max` | `max` | public | `string` | `'100'` | Maximum acceptable value for the inner HTMLInputElement. |
| `min` | `min` | public | `string` | `'0'` | Minimum acceptable value for the inner HTMLInputElement. |
| `name` | `name` | public | `string` | | Name of the form element. Will be read from name attribute. |
| `readonly` | `readonly` | public | `boolean \| undefined` | `false` | Readonly state for the inner HTMLInputElement. Since the input range does not allow this attribute, it will be merged with the `disabled` one. |
| `startIcon` | `start-icon` | public | `string \| undefined` | | Name of the icon at component's start, which will be forward to the nested `sbb-icon`. |
| `value` | `value` | public | `string \| null` | `null` | Value of the form element. If no value is provided, default is the middle point between min and max. |
| `valueAsNumber` | `value-as-number` | public | `number \| null` | | Numeric value for the inner HTMLInputElement. |

## Events

| Name | Type | Description | Inherited From |
| ----------- | ------------------- | -------------------------------------------------------------------------------- | -------------- |
| `didChange` | `CustomEvent<void>` | Deprecated. used for React. Will probably be removed once React 19 is available. | |
| `input` | `InputEvent` | | |

## Slots

Expand Down
6 changes: 3 additions & 3 deletions src/elements/slider/slider.scss
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
}
}

:host([disabled]) {
:host(:disabled) {
--sbb-slider-icon-color: var(--sbb-color-graphite);
--sbb-slider-knob-border-color: var(--sbb-color-smoke);
--sbb-slider-knob-border-size: var(--sbb-border-width-2x);
Expand All @@ -43,7 +43,7 @@
--sbb-slider-knob-border-color: var(--sbb-slider-selected-line-disabled-color);
}

:host([disabled]),
:host(:disabled),
:host([readonly]) {
jeripeierSBB marked this conversation as resolved.
Show resolved Hide resolved
--sbb-slider-line-color: var(--sbb-slider-line-disabled-color);
--sbb-slider-selected-line-color: var(--sbb-slider-selected-line-disabled-color);
Expand Down Expand Up @@ -128,7 +128,7 @@
}

// slider knob resize on click (active / focus)
:host(:not(:is([disabled], [readonly]))) .sbb-slider__range-input:active ~ & {
:host(:not(:is(:disabled, [readonly]))) .sbb-slider__range-input:active ~ & {
--sbb-slider-knob-size: var(--sbb-slider-knob-size-active);
}
}
31 changes: 30 additions & 1 deletion src/elements/slider/slider.snapshot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@ describe(`sbb-slider`, () => {

describe('renders', async () => {
beforeEach(async () => {
element = await fixture(html`<sbb-slider value="1"></sbb-slider>`);
element = (
await fixture(html`
<div>
<label for="slider-1">Label</label>
<sbb-slider value="1" id="slider-1"></sbb-slider>
</div>
`)
).querySelector('sbb-slider')!;
});

it('DOM', async () => {
Expand Down Expand Up @@ -99,4 +106,26 @@ describe(`sbb-slider`, () => {

testA11yTreeSnapshot();
});

describe('renders in form', async () => {
beforeEach(async () => {
const form = await fixture(
html` <form>
<sbb-slider name="sbb-slider" min="0" max="10" value="1"></sbb-slider>
<input type="range" name="input-range" min="0" max="10" value="1" />
</form>`,
);
element = form.querySelector('sbb-slider')!;
});

it('DOM', async () => {
await expect(element).dom.to.be.equalSnapshot();
});

it('Shadow DOM', async () => {
await expect(element).shadowDom.to.be.equalSnapshot();
});

testA11yTreeSnapshot();
});
});
Loading
Loading