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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@brunnerh/autocomplete

v0.1.2

Published

An autocomplete component.

Downloads

8

Readme

Autocomplete Component

An autocomplete component which can be used as a regular ES module import or as a Svelte component.

It has no dependencies, handles synchronous and asynchronous data sources, supports item templating and escapes any HTML automatically.

(Change log)

Install

npm install @brunnerh/autocomplete

Usage

In a Svelte project the component can be imported in a <script> section and then used in the HTML like any other:

<script>
	// (Named import!)
	import { AutoComplete } from '@brunnerh/autocomplete';

	const items = ['Apple', 'Orange', 'Pear'];
</script>

<AutoComplete items={() => items}/>

In any other type of project, the component can be instantiated in the script:

<div id="autocomplete-target"></div>

<script type="module">
	import { AutoComplete } from '@brunnerh/autocomplete';

	const items = ['Apple', 'Orange', 'Pear'];
	new AutoComplete({
		target: document.querySelector('#autocomplete-target'),
		props: { items: () => items },
	});
</script>

For documentation of how to interact with component instances see Client-side component API in the Svelte docs.

Properties

| Prop | Type | Default | Description | |--------------------|--------------------------------------|-------------|-------------| | id | string \| null | null | Sets the id of the input element. | | name | string \| null | null | Sets the name of the input element. | | className | string | '' | Sets additional class name/names of the input element (should be space separated). | | placeholder | string \| null | null | Sets the placeholder of the input element. | | title | string \| null | null | Sets the title of the input element. | | required | boolean | false | Sets the required attribute on the input element if true. | | disabled | boolean | false | Sets the disabled attribute on the input element if true. | | tabindex | number \| undefined | undefined | Sets the tabindex attribute on the input element. | | autoScroll | boolean | true | Automatically scrolls the component into view.Can be helpful if the component is at the bottom a scrollable area and the dropdown ends up off-screen. | | autoScrollCursor | boolean | true | Automatically scrolls to the cursor position in the list.Turn off if there are performance issues. | | items | () => Item[] | | Sets the suggestions. See Items Property. | | isOpen | boolean | false | Gets or sets whether the suggestions dropdown is open. | | key | any | null | Gets the last selected key. See Items Property. | | value | any | null | Gets the last selected value. See Items Property. | | results | any[] | [] | Gets the subset of items that match the user input, reduced to the first maxItems items. | | search | string | '' | Gets or sets the current search term/input value. | | isLoading | boolean | false | Gets whether the component is currently loading the suggestions (if items returns a promise). | | cursor | number | 0 | Gets or sets the index of the currently highlighted item within the suggestions list. | | cursorItem | any | undefined | Gets the currently highlighted item. | | maxItems | number? | undefined | Sets the maximal number of items to show in suggestions list at a time. | | fromStart | boolean | false | Sets whether the search string has to appear at the start of the item. | | caseSensitive | boolean | false | Sets whether the search is case-sensitive. | | minChar | number | 0 | Sets the minimum number of characters required to trigger a search. | | debounce | number | 0 | Sets the time to wait in milliseconds before triggering a search. | | blindSelection | boolean | false | Sets whether suggested items are directly selected upon pressing arrow up/down while the dropdown is closed. | | lazyDropdown | boolean | false | Whether the DOM elements for the suggestions list are only created upon filtering/opening the suggestions dropdown. | | searchRegEx | (search: string) => RegExp \| null | null | Custom search RegEx generator.If set, fromStart and caseSensitive will not be used. | | searchFunction | Search Function | null | Custom search function. See Search Function Property. |

Items Property

The items property has to be a function returning a list of items for the auto-completion.

The return value can be a promise to load data asynchronously. Returning an existing promise if the list of suggestions can be cached is recommended. E.g.:

<script>
	// Fetch once:
	const suggestions = fetch('/api/items');
</script>
<AutoComplete items={() => suggestions}/>

The items have to be strings or of the form:

{
	key: string,
	value?: any,
}

The key will be used for the search and displayed in the suggestions dropdown by default.

The value represents a technical item value that is assigned to the value property of the component upon selection. If no value is set, the whole item will be assigned.

For strings, the string will serve as key and value.

Search Function Property

The property searchFunction can be used to provide custom search logic when a custom regular expression (searchRegEx) is not enough.

The type of the function is as follows:

(search: string) => (text: string) => {
	/** Whether the item `text` matches `search`. */
	matches: boolean,
	/**
	 * An array of start and end index tuples for parts of the text that should be highlighted as matching.
	 * Should be an empty array if nothing matches or no highlighting should be shown.
	 */
	highlights: [number, number][],
}

If set, fromStart, caseSensitive and searchRegEx will not be used.

Events

The following events are emitted by the component, event data/forwarded event can be found in the detail property:

| Type | Description | |-----------------|--------------| | filtered | Fired after the suggestion list has been filtered. | | item-selected | Fired upon item selection, either by pressing Enter or clicking on one.The event data is the selected item. | | focus | Forwarded from input. | | blur | Forwarded from input. | | input | Forwarded from input. | | keydown | Forwarded from input. | | click | Forwarded from input. |

Slots

The following slots can be used in Svelte projects:

| Name | Injected Props | Description | |------------|-------------------|-------------| | loading | | The loading indicator that is displayed while items are loading asynchronously.Default: Loading data... | | template | result | A custom template for rendering the items. See Template |

template

By default, items show the item key with matching parts of the text highlighted. This slot can be used to customize this output.

The injected result prop has the following type:

{
	/** The index of the item in the filtered results list (0-based). */
	index: number,

	/** The key of the item. Either the `key` property or the item itself, if it a string. */
	key: string,

	/** The value of the item. Either the `value` property or the whole item. */
	value: any,

	/** An HTML string that contains highlighted parts in spans with the class `ac-match`. */
	label: string,
}

Example:

<AutoComplete items={() => data} let:result>
	<!-- Renders item with index prefix and value in parentheses on a second line. -->
	<div slot="template">
		{result.index + 1}: {@html result.label}
		<br/>
		<span style="font-size: smaller; opacity: 0.7">({result.value})</span>
	</div>
</AutoComplete>

Styling

The component comes with a default style and defines various CSS custom properties to make theming easier.

It can also be styled via the classes of the various parts.

Structure

.autocomplete
	input.autocomplete-input
	.autocomplete-results-dropdown
		.autocomplete-loading
		ul.autocomplete-results-list
			li.autocomplete-result[.ac-highlighted]
				span[.ac-match]
  • ac-highlighted is applied to the item highlighted via arrow/up or mouse hover.
  • ac-match is applied to the parts of the item text that match the search.
    • E.g.: Search: ap, item text: Apple => <span class="ac-match">Ap</span>ple

CSS Custom Properties

| Target | Name | Default Value | |---------------------------------------|-----------------------------------------|---------------| | .autocomplete-input | --ac-input-color | black | | .autocomplete-input | --ac-input-background | white | | .autocomplete-input | --ac-input-border | 1px solid hsl(0, 0%, 60%) | | .autocomplete-input | --ac-input-border-radius | 0 | | .autocomplete-input | --ac-input-padding | 3px | | .autocomplete-input | --ac-input-margin | 0 | | .autocomplete-input | --ac-input-font-size | small | | .autocomplete-input | --ac-input-font-weight | normal | | .autocomplete-results-dropdown | --ac-dropdown-color | Fallback: --ac-input-color | | .autocomplete-results-dropdown | --ac-dropdown-background | Fallback: --ac-input-background | | .autocomplete-results-dropdown | --ac-dropdown-box-shadow | 0px 2px 5px hsla(0, 0%, 0%, 0.7) | | .autocomplete-results-dropdown | --ac-dropdown-margin: | 0 | | .autocomplete-results-dropdown | --ac-dropdown-padding: | 0 | | .autocomplete-results-dropdown | --ac-dropdown-border-radius | 0 | | .autocomplete-loading | --ac-loading-color | inherit | | .autocomplete-loading | --ac-loading-background | none | | .autocomplete-loading | --ac-loading-padding | 0 | | .autocomplete-loading | --ac-loading-margin | 5px | | .autocomplete-result | --ac-result-color | inherit | | .autocomplete-result | --ac-result-background | none | | .autocomplete-result | --ac-result-border | none | | .autocomplete-result | --ac-result-margin | 0 | | .autocomplete-result | --ac-result-padding | 0.2em 0.5em | | .autocomplete-result | --ac-result-border-radius | 0 | | .autocomplete-result.ac-highlighted | --ac-result-highlighted-color | inherit + Fallback: --ac-result-color | | .autocomplete-result.ac-highlighted | --ac-result-highlighted-background | #dbdbdb + Fallback: --ac-result-background | | .autocomplete-result.ac-highlighted | --ac-result-highlighted-border | Fallback: --ac-result-border | | .autocomplete-result.ac-highlighted | --ac-result-highlighted-margin | Fallback: --ac-result-margin | | .autocomplete-result.ac-highlighted | --ac-result-highlighted-padding | Fallback: --ac-result-padding | | .autocomplete-result.ac-highlighted | --ac-result-highlighted-border-radius | Fallback: --ac-result-border-radius | | .autocomplete-result .ac-match | --ac-result-match-color | inherit | | .autocomplete-result .ac-match | --ac-result-match-background | none | | .autocomplete-result .ac-match | --ac-result-match-border-radius | 0 | | .autocomplete-result .ac-match | --ac-result-match-font-weight | bold | | .autocomplete-result .ac-match | --ac-result-match-font-style | inherit |

Attribution