{"id":13422107,"url":"https://github.com/tbleckert/react-select-search","last_synced_at":"2025-03-15T10:31:41.242Z","repository":{"id":31739761,"uuid":"35305786","full_name":"tbleckert/react-select-search","owner":"tbleckert","description":"⚡️ Lightweight select component for React","archived":false,"fork":false,"pushed_at":"2024-09-23T22:02:23.000Z","size":12618,"stargazers_count":689,"open_issues_count":63,"forks_count":148,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-03-06T12:05:56.483Z","etag":null,"topics":["component","dropdown","javascript","lightweight","react","search","select","selectbox"],"latest_commit_sha":null,"homepage":"https://react-select-search.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tbleckert.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["tbleckert"]}},"created_at":"2015-05-08T22:53:43.000Z","updated_at":"2025-02-26T22:05:08.000Z","dependencies_parsed_at":"2024-01-13T10:09:37.946Z","dependency_job_id":"76ed0a06-7f82-4c58-a9b9-da98894fca6f","html_url":"https://github.com/tbleckert/react-select-search","commit_stats":{"total_commits":517,"total_committers":36,"mean_commits":14.36111111111111,"dds":"0.15860735009671179","last_synced_commit":"6639c27c20a9c2a696bf63b6ddcc6e167b96db1e"},"previous_names":[],"tags_count":75,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbleckert%2Freact-select-search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbleckert%2Freact-select-search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbleckert%2Freact-select-search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tbleckert%2Freact-select-search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tbleckert","download_url":"https://codeload.github.com/tbleckert/react-select-search/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243719114,"owners_count":20336592,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","dropdown","javascript","lightweight","react","search","select","selectbox"],"created_at":"2024-07-30T23:00:37.019Z","updated_at":"2025-03-15T10:31:40.594Z","avatar_url":"https://github.com/tbleckert.png","language":"JavaScript","funding_links":["https://github.com/sponsors/tbleckert"],"categories":["UI Components"],"sub_categories":["Form Components"],"readme":"## ⚠️ Looking for maintainers\n\nFirst of all, I want to thank you all for the amazing support over the years. This was one of my first open source projects and also my first successful one. I am beyond grateful for all the [33! contributors](https://github.com/tbleckert/react-select-search/graphs/contributors), wouldn't have been possible to run this project without you.\n\nA lot happened last year. I had my first born son, I had a few time consuming freelance gigs and a few startups that grew. This took time away from open source and I feel I can't do this component justice anymore. Not by myself at least.\n\nI still believe in a tiny, super fast and zero-dependency select component. If there's anyone out there that wants to co-maintain this with me, please reach out to discuss the next steps. Send me an email at hola@tobiasbleckert.se or hit me up on [Twitter](https://twitter.com/tbleckert)\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://user-images.githubusercontent.com/263465/175054036-90835869-74dc-40f1-a541-adea18da9b8f.png\" alt=\"React Select Search\" /\u003e\n\u003c/p\u003e\n\n\u003ch6 align=\"center\"\u003e\n  \u003ca href=\"https://react-select-search.com\"\u003eDemo\u003c/a\u003e\n  ·\n  \u003ca href=\"https://github.com/tbleckert/react-select-search#quick-start\"\u003eQuick start\u003c/a\u003e\n  ·\n  \u003ca href=\"https://github.com/tbleckert/react-select-search#config\"\u003eConfig\u003c/a\u003e\n·\n  \u003ca href=\"https://github.com/tbleckert/react-select-search#headless-mode-with-hooks\"\u003eHeadless\u003c/a\u003e\n\u003c/h6\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href='https://coveralls.io/github/tbleckert/react-select-search'\u003e\n        \u003cimg src='https://img.shields.io/coveralls/github/tbleckert/react-select-search?style=for-the-badge' alt='Coverage Status' /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.npmjs.com/package/react-select-search\"\u003e\n        \u003cimg src=\"https://img.shields.io/npm/dm/react-select-search.svg?style=for-the-badge\" style=\"max-width:100%;\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://bundlephobia.com/result?p=react-select-search\"\u003e\n        \u003cimg src=\"https://img.shields.io/bundlephobia/minzip/react-select-search?style=for-the-badge\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"#contributors\"\u003e\n        \u003cimg src=\"https://img.shields.io/github/contributors/tbleckert/react-select-search?style=for-the-badge\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## Features\n* Lightweight, with zero dependencies\n* Accessible\n* Headless mode\n* Basic HTML select functionality, including multiple\n* Search/filter options\n* Async options\n* Apply renderers to change markup and behavior\n* Keyboard support\n* Group options with group names, you can search group names\n* Fully stylable\n\n## Install\n\nInstall it with npm (`npm i react-select-search`) or yarn (`yarn add react-select-search`) and import it like you normally would.\n\n## Quick start\n\n```jsx harmony\nimport SelectSearch from 'react-select-search';\n\n/**\n * The options array should contain objects.\n * Required keys are \"name\" and \"value\" but you can have and use any number of key/value pairs.\n */\nconst options = [\n    {name: 'Swedish', value: 'sv'},\n    {name: 'English', value: 'en'},\n    {\n        type: 'group',\n        name: 'Group name',\n        items: [\n            {name: 'Spanish', value: 'es'},\n        ]\n    },\n];\n\n/* Simple example */\n\u003cSelectSearch options={options} value=\"sv\" name=\"language\" placeholder=\"Choose your language\" /\u003e\n```\nFor more examples, you can take a look in the [stories](stories) directory.\n\nYou will also need some CSS to make it look right. Example theme can be found in [style.css](style.css). You can also import it:\n\n```javascript\nimport 'react-select-search/style.css'\n```\n\n## Use with SSR\n\nFor use with SSR you might need to use the commonjs bundle (react-select-search/dist/cjs). If you want to utilise the example theme ([style.css](style.css)) you need to check if your build script manipulates class names, for example minifies them. If that's the case, you can use CSS modules to get the class names from the style.css file and apply them using the [className object](#custom-class-names). Example can be seen [here](stories/3-Custom.stories.js#L64) as well as here https://react-select-search.com/?path=/story/custom--css-modules.\n\n## Headless mode with hooks\n\nIf you want complete control (more than styling and [custom renderers](#custom-renderers)) you can use hooks to pass data to your own components and build it yourself.\n\n```jsx harmony\nimport React from 'react';\nimport { useSelect } from 'react-select-search';\n\nconst CustomSelect = ({ options, value, multiple, disabled }) =\u003e {\n    const [snapshot, valueProps, optionProps] = useSelect({\n        options,\n        value,\n        multiple,\n        disabled,\n    });\n\n    return (\n        \u003cdiv\u003e\n            \u003cbutton {...valueProps}\u003e{snapshot.displayValue}\u003c/button\u003e\n            {snapshot.focus \u0026\u0026 (\n                \u003cul\u003e\n                    {snapshot.options.map((option) =\u003e (\n                        \u003cli key={option.value}\u003e\n                            \u003cbutton {...optionProps} value={option.value}\u003e{option.name}\u003c/button\u003e\n                        \u003c/li\u003e\n                    ))}\n                \u003c/ul\u003e\n            )}\n        \u003c/div\u003e\n    );\n};\n```\n\n## Configuration\n\nBelow is all the available options you can pass to the component. Options without defaults are required.\n\n| Name | Type           | Default | Description                                                                                                                                                       |\n| ---- |----------------| ------- |-------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| options | array          | | See the [options documentation](#the-options-object) below                                                                                                        |\n| getOptions | function       | null | Get options through a function call, can return a promise for async usage. See [get options](#get-options) for more.                                              |\n| filterOptions | array          | null | An array of functions that takes the last filtered options and a search query if any. Runs after getOptions. |\n| value | string, array  | null | The value should be an array if multiple mode.                                                                                                                    |\n| multiple | boolean        | false | Set to true if you want to allow multiple selected options.                                                                                                       |\n| search | boolean        | false | Set to true to enable search functionality                                                                                                                        |\n| disabled | boolean        | false | Disables all functionality                                                                                                                                        |\n| closeOnSelect | boolean        | true | The selectbox will blur by default when selecting an option. Set this to false to prevent this behavior.                                                          |\n| debounce | number         | 0 | Number of ms to wait until calling [get options](#get-options) when searching.                                                                                    |\n| placeholder | string         | empty string | Displayed if no option is selected and/or when search field is focused with empty value.                                                                          |\n| id | string         | null | HTML ID on the top level element.                                                                                                                                 |\n| autoComplete | string, on/off | off | Disables/Enables autoComplete functionality in search field.                                                                                                      |\n| autoFocus | boolean        | false | Autofocus on select                                                                                                                                               |\n| className | string, object | select-search-box | Set a base class string or pass a function for complete control. Se [custom classNames](#custom-class-names) for more.                                            |\n| renderOption | function       | null | Function that renders the options. See [custom renderers](#custom-renderers) for more.                                                                            |\n| renderGroupHeader | function       | null | Function that renders the group header. See [custom renderers](#custom-renderers) for more.                                                                       |\n| renderValue | function       | null | Function that renders the value/search field. See [custom renderers](#custom-renderers) for more.                                                                 |\n| emptyMessage | React node     | null | Set empty message for empty options list, you can provide render function without arguments instead plain string message                                          |\n| onChange | function       | null | Function to receive and handle value changes.                                                                                                                     |\n| onFocus | function       | null | Focus callback.                                                                                                                                                   |\n| onBlur | function       | null | Blur callback.                                                                                                                                                    |\n\n## The options object\n\nThe options object can contain any properties and values you like. The only required one is `name`.\n\n| Property | Type | Description | Required |\n| -------- | ---- | ----------- | -------- |\n| name     | string | The name of the option | Yes |\n| value    | string | The value of the option | Yes, if the type is not \"group\" |\n| type     | string | If you set the type to \"group\" you can add an array of options that will be grouped | No |\n| items    | array | Array of option objects that will be used if the type is set to \"group\" | Yes, if `type` is set to \"group\" |\n| disabled | boolean | Set to `true` to disable this option | No |\n\n## Custom class names\n\nIf you set a string as the `className` attribute value, the component will use that as a base for all elements.\nIf you want to fully control the class names you can pass an object with classnames. The following keys exists:\n\n* container\n* value\n* input\n* select\n* options\n* row\n* option\n* group\n* group-header\n* is-selected\n* is-highlighted\n* is-loading\n* is-multiple\n* has-focus\n\n## Custom renderers\n\nIf CSS isn't enough, you can also control the HTML for the different parts of the component.\n\n| Callback | Args                                                                                | Description |\n| -------- |-------------------------------------------------------------------------------------| ----------- |\n| renderOption | optionsProps: object, optionData: object, optionSnapshot: object, className: string | Controls the rendering of the options. |\n| renderGroupHeader | name: string                                                                        | Controls the rendering of the group header name |\n| renderValue | valueProps: object, snapshot: object, className: string                             | Controls the rendering of the value/input element |\n\nThe optionProps and the valueProps are needed for the component you render to work. For example:\n\n```jsx\n\u003cSelectSearch renderValue={(valueProps) =\u003e \u003cinput {...valueProps} /\u003e} /\u003e\n```\n\nMonkeypatch it if you need to but make sure to not remove important props.\n\nThe optionSnapshot is an object that contains the object state: `{ selected: bool, highlighted: bool }`.\n\n## Get options\n\nYou can fetch options asynchronously with the `getOptions` property. You can either return options directly or through a `Promise`.\n\n```jsx\nfunction getOptions(query) {\n    return new Promise((resolve, reject) =\u003e {\n        fetch(`https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${query}`)\n            .then(response =\u003e response.json())\n            .then(({ drinks }) =\u003e {\n                resolve(drinks.map(({ idDrink, strDrink }) =\u003e ({ value: idDrink, name: strDrink })))\n            })\n            .catch(reject);\n    });\n}\n```\n\nThe function runs on each search query update, so you might want to throttle the fetches.\nIf you return a promise, the class `is-loading` will be applied to the main element, giving you a chance\nto change the appearance, like adding a spinner. The property `fetching` is also available in the snapshot that is sent to your render callbacks.\n\n## Contributors\n\n\u003ca href=\"https://github.com/tbleckert/react-select-search/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=tbleckert/react-select-search\" /\u003e\n\u003c/a\u003e\n\nMade with [contrib.rocks](https://contrib.rocks).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftbleckert%2Freact-select-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftbleckert%2Freact-select-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftbleckert%2Freact-select-search/lists"}