<li> lists.
Reads text from <a> tags (including <small>), normalizes diacritics, supports nested menus and debounced input.import filterMenu from '@pim.sk/utils/filter-menu.mjs'
Filter <li> items using a CSS selector. Text is read from the <a> tag — including nested <small> — and is diacritics-normalized automatically.
filterMenu({
input: inputEl, // HTMLInputElement
selector: 'ul.menu-list li', // CSS selector for <li> items
})
import filterMenu from '@pim.sk/utils/filter-menu.mjs'
const input = document.querySelector('input[type="search"]')
filterMenu({ input, selector: 'ul.menu-list li' })
Zero-JS approach — on import, the module auto-initializes every <input type="search"> carrying a data-filter-menu attribute. The attribute value is the CSS selector for the <li> items.
<input type="search"
data-filter-menu="ul.menu-list li"
placeholder="Filter..." />
<!-- no JavaScript needed — import is enough -->
import '@pim.sk/utils/filter-menu.mjs'
// auto-init finds all [data-filter-menu] inputs on import — no extra code
When a child <li> matches the query, its parent <li> stays visible even if the parent text does not match. The selector must cover all levels.
// selector must include ALL li levels (parent + child)
filterMenu({ input, selector: 'ul.menu-list li' })
// "catalog" → parent "Products" stays visible
// "archive" → parent "Orders" stays visible
// "orders" → "Orders" + all its children
filterMenu({
input,
selector: 'ul.menu-list li', // both parent and child li
})
Pass a NodeList or Array of <li> elements directly — useful when items are already collected or managed by a component.
const liEls = document.querySelectorAll("ul li")
filterMenu({
input,
items: liEls, // NodeList or Array
})
const liEls = document.querySelectorAll("ul li")
filterMenu({ input, items: liEls })
Delay in ms after the last keystroke before filtering runs. Default is 250ms — good for most cases. Set to 0 for instant filtering when items are few or rendering is cheap.
debounceWait: 250 // default
debounceWait: 0 // instant — no delay
debounceWait: 500 // slower inputs / heavy rendering
filterMenu({
input,
selector: 'ul li',
debounceWait: 0, // instant
})