Skip to content

Commit

Permalink
feat (Dropdown): add new methods addItem, removeItem and removeAllItems
Browse files Browse the repository at this point in the history
  • Loading branch information
firestar300 committed Oct 3, 2024
1 parent 307c1ec commit 7a90666
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 2 deletions.
43 changes: 41 additions & 2 deletions examples/accessible-dropdown/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ <h3>Dropdown only for &lt; 1024px devices</h3>
<li role="option">Paint</li>
</ul>
</div>

<h3>Action buttons</h3>

<div id="dropdown-6" class="dropdown">
<span class="dropdown__label">Choose an element</span>
<button aria-haspopup="listbox">Choose an element</button>
<ul tabindex="-1" role="listbox">
<li role="option">Book</li>
<li role="option">Movies</li>
<li role="option">Music</li>
<li role="option">Video games</li>
<li role="option">Paint</li>
</ul>
</div>

<button id="add">Add a dummy item</button>
<button id="remove">Remove the first item</button>
<button id="remove-all">Remove all items</button>

<h2>Code</h2>

Expand Down Expand Up @@ -126,10 +144,31 @@ <h2>Code</h2>
},
'#dropdown-5': {
mediaQuery: window.matchMedia('(max-width: 1024px)')
}
},
'#dropdown-6': {},
}

Dropdown.initFromPreset()

const addBtn = document.getElementById('add')
const removeBtn = document.getElementById('remove')
const removeAllBtn = document.getElementById('remove-all')
const dropdownInstance = Dropdown.getInstance('#dropdown-6')

addBtn.addEventListener('click', function() {
const listItem = document.createElement('li')
listItem.innerText = 'Dummy'
dropdownInstance.addItem(listItem)
})

removeBtn.addEventListener('click', function() {
dropdownInstance.removeItem(document.getElementById('dropdown-6').querySelectorAll('li')[0])
})

removeAllBtn.addEventListener('click', function() {
dropdownInstance.removeAllItems()
})

</script>
</body>
</html>
52 changes: 52 additions & 0 deletions src/classes/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,58 @@ class Dropdown extends AbstractDomElement {
return this
}

/**
* Adds a new item to the list.
*
* @param {HTMLElement} listItem - The list item to be added.
* @returns {void}
*/
addItem(listItem) {
const el = this._element
listItem.role = 'option'
listItem.id = `${this.id}-item-${this.listItems.length + 1}`
listItem.addEventListener('click', this._handleListItemClick)

if (this.listItems.length === 0) {
listItem.setAttribute('aria-selected', 'true')
}

this.list.appendChild(listItem)
this.listItems = el.querySelectorAll('li')
this.updateFocusedListItem(el.querySelector('li[aria-selected="true"]'))

if (this.button.hasAttribute('hidden')) {
this.button.removeAttribute('hidden')
}
}

/**
* Removes a specific item from the list.
*
* @param {HTMLElement} listItem - The list item to be removed.
* @returns {void}
*/
removeItem(listItem) {
const el = this._element
listItem.remove()
this.listItems = el.querySelectorAll('li')
this.listItems[0].setAttribute('aria-selected', 'true')
this.updateFocusedListItem(el.querySelector('li[aria-selected="true"]'))
}

/**
* Removes all items from the list.
*
* @returns {void}
*/
removeAllItems() {
this.listItems.forEach((listItem) => {
listItem.remove()
})
this.listItems = this._element.querySelectorAll('li')
this.button.setAttribute('hidden', 'hidden')
}

/**
* Check if media query matches
*
Expand Down
23 changes: 23 additions & 0 deletions src/classes/Dropdown.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,27 @@ test.describe('Dropdown', () => {

expect(display).toBe('none')
})

test('Click on "Add item" button, expect there is a Dummy list item.', async ({ page }) => {
await page.click('#add')

const lastItemText = await page.locator('#dropdown-6 li').last().textContent()
expect(lastItemText).toBe('Dummy')
})

test('Click on "Remove first item" button, expect the new first item is "Movies".', async ({ page }) => {
await page.click('#remove')

const firstItemText = await page.locator('#dropdown-6 li').first().textContent()
expect(firstItemText).toBe('Movies')
})

test('Click on "Remove all items" button, expect there is not list items anymore.', async ({ page }) => {
await page.click('#remove-all')

const isListItemsEmpty = await page
.locator('#dropdown-6 ul')
.evaluate((element) => element.textContent.trim() === '')
expect(isListItemsEmpty).toBe(true)
})
})

0 comments on commit 7a90666

Please sign in to comment.