Skip to content

Commit

Permalink
feat(dropdown-select): add disabled state for individual options (#2174)
Browse files Browse the repository at this point in the history
  • Loading branch information
dadadcko authored Nov 29, 2023
1 parent 60d33c4 commit b53b711
Show file tree
Hide file tree
Showing 13 changed files with 346 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class DropdownSelectItem {
@Prop() selected?: boolean;
@Prop() focused?: boolean;
@Prop({ reflect: true }) value?: any;
@Prop({ reflect: true }) disabled?: boolean;

render() {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

| Property | Attribute | Description | Type | Default |
| ---------- | ---------- | ----------- | --------- | ----------- |
| `disabled` | `disabled` | | `boolean` | `undefined` |
| `focused` | `focused` | | `boolean` | `undefined` |
| `selected` | `selected` | | `boolean` | `undefined` |
| `value` | `value` | | `any` | `undefined` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,12 @@
color: var(--color);
}

[part~='option']:hover {
[part~='option'][part~='disabled'] {
color: var(--color-disabled);
cursor: not-allowed;
}

[part~='option']:not([part~='disabled']):hover {
background-color: var(--background-hover);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { newE2EPage } from '@stencil/core/testing';
import { E2EElement, E2EPage, newE2EPage } from '@stencil/core/testing';
import { DropdownSelect } from './dropdown-select';

describe('DropdownSelect', function () {
Expand Down Expand Up @@ -59,4 +59,112 @@ describe('DropdownSelect', function () {
expect(comboboxEl).toEqualText('Cedric');
expect(selectEl).toEqualAttribute('value', 'cedric');
});

describe('when contains some disabled options', () => {
let page: E2EPage;
let selectEl: E2EElement;
let comboboxEl: E2EElement;

beforeEach(async () => {
page = await newE2EPage({
components: [DropdownSelect],
html: `
<scale-dropdown-select>
<scale-dropdown-select-item value="adam">Adam</scale-dropdown-select-item>
<scale-dropdown-select-item value="cedrik" disabled>Cedrik</scale-dropdown-select-item>
<scale-dropdown-select-item value="cedric" disabled>Cedric</scale-dropdown-select-item>
<scale-dropdown-select-item value="cem">Cem</scale-dropdown-select-item>
<scale-dropdown-select-item value="chris">Chris</scale-dropdown-select-item>
<scale-dropdown-select-item value="christian">Christian</scale-dropdown-select-item>
<scale-dropdown-select-item value="christiano">Christiano</scale-dropdown-select-item>
</scale-dropdown-select>`,
});

selectEl = await page.find('scale-dropdown-select');
comboboxEl = await page.find(
'scale-dropdown-select >>> [part="combobox"]'
);
});

it('should skip disabled options when navigating with keyboard', async () => {
await page.keyboard.down('Tab');
await page.keyboard.down('Enter');
await page.keyboard.down('ArrowDown');
await page.keyboard.down('ArrowDown');
await page.keyboard.down('Enter');
await page.waitForChanges();

// should skip Cedrik and Cedric
expect(comboboxEl).toEqualText('Cem');
expect(selectEl).toEqualAttribute('value', 'cem');
});

it('should skip disabled options when typing', async () => {
await page.keyboard.down('Tab');
await page.keyboard.down('Enter');
await page.keyboard.down('c');
await page.keyboard.down('e');
await page.keyboard.down('Enter');
await page.waitForChanges();

expect(comboboxEl).toEqualText('Cem');
expect(selectEl).toEqualAttribute('value', 'cem');
});
});

describe('when ALL options are disabled', () => {
let page: E2EPage;
let selectEl: E2EElement;
let comboboxEl: E2EElement;

beforeEach(async () => {
page = await newE2EPage({
components: [DropdownSelect],
html: `
<scale-dropdown-select value="default">
<scale-dropdown-select-item disabled value="adam">Adam</scale-dropdown-select-item>
<scale-dropdown-select-item disabled value="cedrik">Cedrik</scale-dropdown-select-item>
<scale-dropdown-select-item disabled value="cedric">Cedric</scale-dropdown-select-item>
<scale-dropdown-select-item disabled value="cem">Cem</scale-dropdown-select-item>
<scale-dropdown-select-item disabled value="chris">Chris</scale-dropdown-select-item>
<scale-dropdown-select-item disabled value="christian">Christian</scale-dropdown-select-item>
<scale-dropdown-select-item disabled value="christiano">Christiano</scale-dropdown-select-item>
</scale-dropdown-select>`,
});

selectEl = await page.find('scale-dropdown-select');
comboboxEl = await page.find(
'scale-dropdown-select >>> [part="combobox"]'
);
});

it('should not be able to select any option', async () => {
await page.keyboard.down('Tab');
await page.keyboard.down('Enter');
await page.keyboard.down('ArrowDown');
await page.keyboard.down('ArrowDown');
await page.keyboard.down('ArrowDown');
await page.keyboard.down('ArrowUp');
await page.keyboard.down('ArrowUp');
await page.keyboard.down('ArrowDown');
await page.keyboard.down('Enter');
await page.waitForChanges();

expect(comboboxEl).toEqualText('');
expect(selectEl).toEqualAttribute('value', 'default');
});

it('should not be able to select any option by typing', async () => {
await page.keyboard.down('Tab');
await page.keyboard.down('Enter');
await page.keyboard.down('c');
await page.keyboard.down('e');
await page.keyboard.down('d');
await page.keyboard.down('Enter');
await page.waitForChanges();

expect(comboboxEl).toEqualText('');
expect(selectEl).toEqualAttribute('value', 'default');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -82,4 +82,41 @@ describe('DropdownSelect', function () {
})
);
});

describe('when clicking on disabled option', () => {
it('should neither change it`s value, nor emit an event', async () => {
const page = await newSpecPage({
components: [DropdownSelect],
html: `
<scale-dropdown-select value="">
<scale-dropdown-select-item value="caspar">Caspar</scale-dropdown-select-item>
<scale-dropdown-select-item value="cedric" disabled>Cedric</scale-dropdown-select-item>
<scale-dropdown-select-item value="cem" disabled>Cem</scale-dropdown-select-item>
</scale-dropdown-select>`,
});

const clickSpy = jest.fn();
const changeSpy = jest.fn();

const selectEl = page.doc.querySelector('scale-dropdown-select');
selectEl.addEventListener('scale-change', changeSpy);
const comboboxEl: HTMLElement =
selectEl.shadowRoot.querySelector('[part="combobox"]');
comboboxEl.scrollIntoView = function () {};
comboboxEl.focus = function () {};
const optionsEls: NodeListOf<HTMLElement> =
selectEl.shadowRoot.querySelectorAll('[role="option"]');
optionsEls[1].addEventListener('click', clickSpy);

comboboxEl.click();
optionsEls[1].click();

await page.waitForChanges();

expect(comboboxEl.textContent).not.toBe('Cem');
expect(selectEl.value).not.toBe('cem');
expect(clickSpy).toBeCalledTimes(1);
expect(changeSpy).not.toBeCalled();
});
});
});
Loading

0 comments on commit b53b711

Please sign in to comment.