Skip to content

Commit

Permalink
fix(input): clean-up datalist on slot change
Browse files Browse the repository at this point in the history
  • Loading branch information
dpellier committed Nov 4, 2024
1 parent c24f710 commit 51dea32
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ export class OdsInput {
const datalistElement = assignedElements.find((el) => el.tagName === 'DATALIST');

if (datalistElement) {
// Clear previously moved datalist if any
this.el.shadowRoot?.querySelector(`datalist#${this.list}`)?.remove();

datalistElement.setAttribute('id', this.list);
this.el.shadowRoot?.appendChild(datalistElement);
} else {
Expand Down
11 changes: 10 additions & 1 deletion packages/ods/src/components/input/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
</ods-input> -->

<p>With datalist</p>
<ods-input list="my-list">
<ods-input id="input-with-datalist" list="my-list">
<datalist slot="list">
<option value="Chocolate"></option>
<option value="Coconut"></option>
Expand All @@ -139,5 +139,14 @@
<option value="Vanilla"></option>
</datalist>
</ods-input>
<button id="update-datalist">Update Datalist</button>
<script>
const inputWithDatalistEl = document.querySelector('#input-with-datalist');
const updateDatalistBtn = document.querySelector('#update-datalist');

updateDatalistBtn.addEventListener('click', () => {
inputWithDatalistEl.innerHTML = '<datalist slot="list"><option value="Cat"></option><option value="Dog"></option><option value="Rabbit"></option></datalist>';
});
</script>
</body>
</html>
37 changes: 34 additions & 3 deletions packages/ods/src/components/input/tests/rendering/ods-input.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { E2EElement, E2EPage } from '@stencil/core/testing';
import { newE2EPage } from '@stencil/core/testing';
import { type E2EElement, type E2EPage, newE2EPage } from '@stencil/core/testing';

describe('ods-input rendering', () => {
let el: E2EElement;
Expand All @@ -21,6 +20,8 @@ describe('ods-input rendering', () => {
await page.waitForChanges();
}

beforeEach(jest.clearAllMocks);

it('should render the web component', async() => {
await setup('<ods-input></ods-input>');

Expand Down Expand Up @@ -77,11 +78,24 @@ describe('ods-input rendering', () => {

describe('slots', () => {
describe('list', () => {
it('should not render with datalist nodes if not list prop is set', async() => {
beforeEach(() => {
jest.spyOn(console, 'warn').mockImplementation(() => {});
});

it('should not render with datalist nodes if list prop is not set', async() => {
await setup('<ods-input><datalist slot="list"><option value="1"></option><option value="2"></option></datalist></ods-input>');

const innerDatalist = await page.find('ods-input >>> datalist');
expect(innerDatalist).toBeNull();
expect(console.warn).toHaveBeenCalledTimes(1);
});

it('should warn if list prop is set but without a datalist in the slot', async() => {
await setup('<ods-input list="my-list"><p slot="list">Lorem ipsum</p></ods-input>');

const innerDatalist = await page.find('ods-input >>> datalist');
expect(innerDatalist).toBeNull();
expect(console.warn).toHaveBeenCalledTimes(1);
});

it('should render with datalist nodes if list prop is set', async() => {
Expand All @@ -92,6 +106,23 @@ describe('ods-input rendering', () => {

const innerDatalistOptions = await innerDatalist.findAll('option');
expect(innerDatalistOptions.length).toBe(2);
expect(console.warn).toHaveBeenCalledTimes(0);
});

describe('onSlotChange', () => {
it('should render updated datalist', async() => {
await setup('<ods-input list="my-list"><datalist slot="list"><option value="1"></option><option value="2"></option></datalist></ods-input>');

el.innerHTML = '<datalist slot="list"><option value="alone"></option></datalist>';
await page.waitForChanges();

const innerDatalist = await page.find('ods-input >>> datalist');
expect(innerDatalist).not.toBeNull();

const innerDatalistOptions = await innerDatalist.findAll('option');
expect(innerDatalistOptions.length).toBe(1);
expect(console.warn).toHaveBeenCalledTimes(0);
});
});
});
});
Expand Down

0 comments on commit 51dea32

Please sign in to comment.