npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

jb-searchbar

v3.3.0

Published

searchbar web component

Downloads

489

Readme

jb-searchbar

Published on webcomponents.org GitHub license NPM Version GitHub Created At

jb-searchbar is a compact search and filter web component. It lets you render always-visible filters, optional user-selected filters, and a search button in one responsive bar.

  • Supports any form-associated element as a filter.
  • Supports always-visible filters through slot="filter".
  • Supports optional filters through <jb-extra-filter slot="extra">.
  • Lets users add the same extra filter more than once unless data-max-count limits it.
  • Collects normal and extra filter values through .value.
  • Dispatches search when the search button is clicked or when searchOnChange is enabled.
  • DOM-driven setup: define filters directly in markup instead of passing a large JavaScript configuration object.

When to use

Use jb-searchbar when a page needs a compact query/filter surface for lists, tables, reports, or dashboards. See the normal filter demo for the complete interaction.

Use a normal form when filters need a full-page layout, complex grouping, or submit/reset controls outside the searchbar.

Demo

Using With JS Frameworks

Other integrations: Angular · Vue · Nuxt · Svelte · SvelteKit · SolidJS · Lit · Next.js · Astro · Blazor · Server-rendered templates · WordPress · Alpine.js and HTMX

Installation

npm i jb-searchbar
import 'jb-searchbar';
<jb-searchbar></jb-searchbar>

How it works

jb-searchbar supports two filter types. The normal filter demo shows both in one searchbar:

  • Normal filters: always visible elements placed in slot="filter".
  • Extra filters: hidden filter templates placed inside <jb-extra-filter slot="extra">. The user selects one, fills its value, and submits it into the searchbar as a removable filter chip.

API reference

jb-searchbar attributes

| name | type | default | description | | --- | --- | --- | --- | | search-on-change | boolean | false | Runs search() after selected extra filters change. Empty attribute and "true" mean true; see search-on-change. | | size | 'sm' \| 'md' | md style defaults | Visual size variant; see the size and loading demo. |

jb-searchbar properties

| name | type | readonly | description | | --- | --- | --- | --- | | value | JBSearchbarValue | yes | Current normal filter values plus selected extra filters; see the value example. | | filterList | FilterItem[] | no | Selected extra-filter chips. This is runtime state, not the available filter template list; see filter management. | | searchOnChange | boolean | no | Runs search() after selected extra filters change; see search-on-change. | | isLoading | boolean | no | Plays or stops the search icon loading animation; see the loading demo. |

jb-searchbar methods

| name | returns | description | | --- | --- | --- | | search() | void | Dispatches the search event; see the search interaction. | | deleteFilter(filterIndex) | void | Removes a selected extra filter by index and dispatches change; see filter management. | | createFilterList() | FilterItem[] | Creates the proxied selected-filter list used internally; see filter management. | | renderFilterList() | void | Rerenders all selected filter chips from the current filterList. |

jb-searchbar events

| event | description | | --- | --- | | load | Dispatched from connectedCallback before initialization; see the events demo. | | init | Dispatched from connectedCallback after initialization; see the events demo. | | search | Dispatched when the search button is clicked or search() is called; see the search interaction. | | change | Dispatched when a selected extra filter is added or removed; see filter management. |

jb-searchbar slots

| slot | description | | --- | --- | | filter | Always-visible filter elements; see normal filters. | | extra | One or more <jb-extra-filter> elements; see extra filters. | | divider | Optional divider content between normal filters and extra filters; see the size demo. |

Normal filters

Use slot="filter" for always-visible inputs; see the normal filter demo.

Put always-visible filter elements inside an element with slot="filter". The searchbar gathers elements that have a name and a value property.

<jb-searchbar>
  <div slot="filter">
    <jb-input name="firstName" placeholder="First name"></jb-input>
    <jb-input name="lastName" placeholder="Last name"></jb-input>
    <jb-number-input name="age" placeholder="Age"></jb-number-input>
  </div>
</jb-searchbar>

Extra filters

Use <jb-extra-filter slot="extra"> for optional filters that become removable chips; see the extra filter demo.

Extra filters are filter templates that the user can choose from a dropdown. Place them inside <jb-extra-filter slot="extra">.

<jb-searchbar>
  <jb-extra-filter slot="extra" placeholder="Choose filter">
    <jb-input name="firstName" data-label="First name"></jb-input>
    <jb-input name="lastName" data-label="Last name"></jb-input>
    <jb-number-input name="age" data-label="Age"></jb-number-input>
  </jb-extra-filter>
</jb-searchbar>

Use label or data-label on each filter template. Use data-label when the visible input label should not be used as the selected filter label.

By Pressing Esc key intent field (selected field) will disappear and filter go to select column step again.

data-max-count

Use data-max-count on a filter template to limit how many times it can be selected. The normal filter demo includes a one-time filter.

<jb-extra-filter slot="extra">
  <jb-number-input name="age" data-label="Age" data-max-count="1"></jb-number-input>
</jb-extra-filter>

Updating filterList

filterList contains the extra filters that are currently selected and displayed as chips. Update the existing array with push() and remove items with deleteFilter() so jb-searchbar can keep the rendered chips in sync. Do not replace filterList with a new array.

const searchbar = document.querySelector('jb-searchbar');

// Add a selected filter chip.
searchbar.filterList.push({
  name: 'status',
  label: 'Status',
  value: 'active',
  displayValue: 'Active',
});
// rerender filter list base on your update
searchbar.renderFilterList();
// Remove the selected filter at index 0.
searchbar.deleteFilter(0);

Each item requires name, label, value, and displayValue. Calling filterList.push() immediately renders the new chip, but changing a property of an existing item does not rerender that chip. Call renderFilterList() after editing existing items:

searchbar.filterList[0].value = 'inactive';
searchbar.filterList[0].displayValue = 'Inactive';
searchbar.renderFilterList();

To replace an existing item, you can also remove it with deleteFilter(index) and then add the new item with filterList.push(...). Direct calls to filterList.push() and renderFilterList() update the chip UI but do not dispatch change; call searchbar.search() afterward if the programmatic update should immediately trigger a search.

This property manages selected filter chips. To add or remove the available filter templates instead, update the children of <jb-extra-filter> and call updateSlotElements().

jb-extra-filter API

jb-extra-filter attributes

| name | type | default | description | | --- | --- | --- | --- | | placeholder | string | localized default | Placeholder for the filter select; see the extra filter demo. | | size | 'sm' \| 'md' | md style defaults | Visual size forwarded to the internal select; see the size demo. | | autofocus | boolean | false | Focuses the internal select after it initializes when set as an empty attribute. |

jb-extra-filter properties

| name | type | readonly | description | | --- | --- | --- | --- | | inputState | 'SELECT_COLUMN' \| 'FILL_VALUE' | no | Current UI state; see the extra filter interaction. | | intentColumn | IntentColumn | no | Current selected filter draft before it is submitted. | | extractDisplayValue | ExtractDisplayValueCallback | no | Converts a filter value to the display string shown in the selected filter chip; see display formatting. |

jb-extra-filter methods

| name | returns | description | | --- | --- | --- | | updateSlotElements() | void | Re-reads slotted filter templates and updates the select options; see the dynamic filters demo. | | setFilterListSelectOptionList() | void | Updates the available option list after selected filters change; see filter management. |

jb-extra-filter events

| event | detail | description | | --- | --- | --- | | load | none | Dispatched from connectedCallback before parent lookup; see the events demo. | | init | none | Dispatched from connectedCallback after parent lookup; see the events demo. | | intent-submit | { name, label, displayValue, value } | Dispatched when the user submits an extra filter value; see the events demo. |

Value

Read .value in a search or change handler; the search interaction shows the collected shape.

Read .value from the searchbar to get normal filters and selected extra filters.

const searchbar = document.querySelector('jb-searchbar');

searchbar.addEventListener('search', () => {
  console.log(searchbar.value);
});

Each item contains:

| field | description | | --- | --- | | name | Filter element name. | | label | Filter label from label, data-label, or fallback extraction. | | value | Raw filter value. | | displayValue | Display string for selected extra-filter chips. |

Search on change

Set searchOnChange when selecting or removing an extra filter should trigger search() automatically. See the search-on-change demo.

<jb-searchbar search-on-change></jb-searchbar>
const searchbar = document.querySelector('jb-searchbar');

searchbar.searchOnChange = true;

Size and RTL

Use size="sm" for compact layouts, and verify the searchbar in right-to-left layouts with the size/loading demo and RTL demo.

Loading state

Set isLoading while a search request is running; see the size and loading demo.

const searchbar = document.querySelector('jb-searchbar');

searchbar.isLoading = true;
searchbar.isLoading = false;

Display value formatting

Use extractDisplayValue to control the text shown in selected filter chips; the normal filter demo includes a custom date formatter.

Use extractDisplayValue on <jb-extra-filter> when the raw value should be displayed differently.

const extraFilter = document.querySelector('jb-extra-filter');

extraFilter.extractDisplayValue = ({ name, value, dom }) => {
  if (name === 'createdAt') {
    return dom.inputValue;
  }
  return String(value);
};

Dynamic filter templates

When filter templates are added or removed at runtime, call updateSlotElements() on jb-extra-filter; the dynamic filter demo shows the available options updating.

CSS parts and variables

jb-searchbar parts

See the normal searchbar demo for these parts in context.

| part | description | | --- | --- | | dynamic-wrapper | Wrapper around normal filters, selected extra filters, divider, and extra filter slot. | | filter-list | Selected extra-filter chip list. | | search-button | Search button wrapper. |

jb-extra-filter parts

See the extra filter interaction for the selector, intent input, and submit button parts.

| part | description | | --- | --- | | column-select-wrapper | Wrapper around the filter selector. | | intent-wrapper | Wrapper shown while the user fills a selected filter value. | | intent-input-wrapper | Wrapper where the selected filter input is moved. | | intent-submit-button | Button that submits the selected extra filter value. |

| CSS variable name | description | | --- | --- | | --jb-searchbar-divider-bg-color | Divider background color. | | --jb-searchbar-filter-item-bg-color | Selected extra-filter chip background color. | | --jb-searchbar-filter-item-border-radius | Selected extra-filter chip border radius. | | --jb-searchbar-filter-item-color | Selected extra-filter chip text color. | | --jb-searchbar-min-height | Base searchbar minimum height. | | --jb-searchbar-min-height-sm | Searchbar minimum height for size="sm". | | --jb-searchbar-search-button-size | Base search button size. | | --jb-searchbar-search-button-size-sm | Search button size for size="sm". | | --jb-extra-filter-submit-height | Extra filter submit button height. | | --jb-extra-filter-submit-height-sm | Extra filter submit button height for size="sm". | | --jb-extra-filter-submit-width | Extra filter submit button width. | | --jb-extra-filter-submit-width-sm | Extra filter submit button width for size="sm". |

jb-searchbar {
  --jb-searchbar-filter-item-bg-color: #2563eb;
  --jb-searchbar-filter-item-color: #fff;
}

Accessibility notes

  • The search button is a clickable wrapper with an SVG icon. Add surrounding text or an external button if your page needs a visible text action; see the search interaction.
  • Filter elements keep their own accessibility behavior while slotted or moved into the extra-filter intent area.
  • Extra filter templates must have name attributes so values can be collected.

Related Docs

AI agent notes

  • Import jb-searchbar once before using <jb-searchbar> or <jb-extra-filter>.
  • Put always-visible filters inside an element with slot="filter".
  • Put <jb-extra-filter slot="extra"> inside <jb-searchbar> for optional filters.
  • Put optional filter templates as children of <jb-extra-filter>.
  • Use data-label on filter templates when the selected chip label should differ from the input label.
  • Use data-max-count="1" when a filter can only be selected once.
  • Read searchbar.value inside search or change events.
  • Use searchOnChange as a JavaScript property or search-on-change as an HTML attribute.
  • This package includes custom-elements.json and points to it with the package.json customElements field. The field is documented by the Custom Elements Manifest project in Referencing manifests from npm packages.
  • In custom-elements.json, exports.kind: "custom-element-definition" maps jb-searchbar and jb-extra-filter tag names to their implementation classes.