{"id":22880529,"url":"https://github.com/maslianok/react-select-me","last_synced_at":"2025-04-07T08:29:22.208Z","repository":{"id":10160442,"uuid":"64690040","full_name":"maslianok/react-select-me","owner":"maslianok","description":"Fast 🐆. Lightweight 🐜. Configurable 🐙. Easy to use 🦄. Give it a shot 👉🏼","archived":false,"fork":false,"pushed_at":"2022-12-10T17:04:11.000Z","size":5971,"stargazers_count":144,"open_issues_count":9,"forks_count":18,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-31T06:04:27.124Z","etag":null,"topics":["configurable","dropdown","fast","lightweight","react","select"],"latest_commit_sha":null,"homepage":"http://maslianok.github.io/react-select-me/","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/maslianok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-08-01T18:07:51.000Z","updated_at":"2024-10-08T22:04:20.000Z","dependencies_parsed_at":"2023-01-13T15:46:35.420Z","dependency_job_id":null,"html_url":"https://github.com/maslianok/react-select-me","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maslianok%2Freact-select-me","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maslianok%2Freact-select-me/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maslianok%2Freact-select-me/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/maslianok%2Freact-select-me/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/maslianok","download_url":"https://codeload.github.com/maslianok/react-select-me/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247618607,"owners_count":20967813,"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":["configurable","dropdown","fast","lightweight","react","select"],"created_at":"2024-12-13T17:19:03.839Z","updated_at":"2025-04-07T08:29:22.180Z","avatar_url":"https://github.com/maslianok.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-select-me\n\n#### [Live demo](http://maslianok.github.io/react-select-me/)\n\n## Advantages\n\n#### 🐜 Lightweight\n\n![minzip size](https://badgen.net/bundlephobia/minzip/react-select-me)\n\n#### 🐙 Highly scalable and extendable\n\nYou can literally customize any piece of the component using [`listRenderer`](#listrenderer-function), [`optionRenderer`](#optionrenderer-function), [`selectedBlockRenderer`](#selectedblockrenderer-function), [`iconRenderer`](#iconrenderer-function) and [others](#properties).\n\n#### 🦄 Immutable? Virtualized? No problem!\n\nWe have [various HOC's](#hoc) that may help you to integrate with your existing application.\n\n#### 💃 CSS modules\n\nAll of our classes are extendable with CSS modules. Take a look at [list of them](#s-object).\n\n#### 🕵️‍♂️ Debuggable\n\nYes, yes! You can inspect dropdown list with help of DevTools. You know what I'm talking about, right?\n\n**Still not sure? We have a lot of other cool features. Take a look at our [examples](#examples).**\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [Examples](#examples)\n  - [Live](#live)\n  - [Local](#local)\n- [HOC](#hoc)\n- [Properties:](#properties)\n  - [options: Array](#options-array)\n  - [value: Any](#value-any)\n  - [multiple: Bool](#multiple-bool)\n  - [searchable: Bool](#searchable-bool)\n  - [virtualized: Bool](#virtualized-bool)\n  - [onChange: Function](#onchange-function)\n  - [onSearch: Function](#onsearch-function)\n  - [onAddNewItem: Bool](#onaddnewitem-bool)\n  - [selectedValueRenderer: Function](#selectedvaluerenderer-function)\n  - [selectedBlockRenderer: Function](#selectedblockrenderer-function)\n  - [optionRenderer: Function](#optionrenderer-function)\n  - [listRenderer: Function](#listrenderer-function)\n  - [iconRenderer: Function](#iconrenderer-function)\n  - [noItemsFound: Bool | String | Function](#noitemsfound-bool--string--function)\n  - [addNewItem: Bool | String | Function](#addnewitem-bool--string--function)\n  - [isOpened: Bool](#isopened-bool)\n  - [beforeOpen: Function](#beforeopen-function)\n  - [beforeClose: Function](#beforeclose-function)\n  - [onOpen: Function](#onopen-function)\n  - [onClose: Function](#onclose-function)\n  - [searchClearOnClose: Bool](#searchclearonclose-bool)\n  - [listMaxHeight: Number](#listmaxheight-number)\n  - [listHeight: Number](#listheight-number)\n  - [optionHeight: Number | Function](#optionheight-number--function)\n  - [listPosition: String](#listposition-string)\n  - [getWrapper: Function](#getwrapper-function)\n  - [boundaryMargin: Number](#boundarymargin-number)\n  - [forbidPhantomSelection: Bool](#forbidphantomselection-bool)\n  - [s: Object](#s-object)\n\n## Installation\n\n`npm i react-select-me --save`\n\n## Usage\n\n```javascript\nimport Select from 'react-select-me';\n\n// IMPORTANT If you want to provide default styles you have to import them\nimport 'react-select-me/lib/ReactSelectMe.css';\n\nconst options = [\n  { value: 1, label: 'Label 1' },\n  { value: 2, label: 'Label 2' },\n];\n\nexport default class App extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = { value: null };\n    this.onChange = this.onChange.bind(this);\n  }\n  onChange(value) {\n    this.setState({ value });\n  }\n  render() {\n    return \u003cSelect options={options} value={this.state.value} onChange={this.onChange} /\u003e;\n  }\n}\n```\n\n## Examples\n\n### Live\n\nhttp://maslianok.github.io/react-select-me/\n\n### Local\n\n1. Clone the repo\n   `git clone git@github.com:maslianok/react-select-me.git`\n\n2. Go to the directory\n   `cd react-select-me`\n\n3. Install dependencies\n   `npm i`\n\n4. Run demo app\n   `npm start`\n\n5. Open `localhost:3000` in your browser\n\n## HOC\n\nWe've extracted some key features into separate HOCs to keep the main library as small as possible\n\n### makeVirtualized\n\nUses [virtualized list](https://bvaughn.github.io/react-virtualized/#/components/List) to render dropdown options. It allows you to render huge lists without affecting the page performance.\n\n```javascript\nimport Select from 'react-select-me';\nimport makeVirtualized from 'react-select-me/lib/hoc/makeVirtualized';\n\nconst VirtualizedSelect = makeVirtualized(Select);\n\n// now you can use the VirtualizedSelect component as usual\n// ...\n\u003cVirtualizedSelect options={options} value={this.state.value} onChange={this.onChange} /\u003e;\n// ...\n```\n\n### makeImmutable\n\nIntegrates with [immutable-js](https://facebook.github.io/immutable-js/) which allows you to pass immutable structures as component's props.\n\n```javascript\nimport Select from 'react-select-me';\nimport makeImmutable from 'react-select-me/lib/hoc/makeImmutable';\n\nconst ImmutableSelect = makeImmutable(Select);\n\n// now you can pass immutable data as options\n// ...\n\u003cImmutableSelect options={options} value={this.state.value} onChange={this.onChange} /\u003e;\n// ...\n```\n\n## Properties:\n\n### options: Array\n\n_Description: list of dropdown options_\n\nDefault: `undefined`\n\nExamples:\n\n- List of primitives: `[1, 2]`\n- List of objects: `[{value: 1, label: 'Label 1'}, {value: 2, label: 'Label 2'}]`\n\n### value: Any\n\n_Description: selected value / values_\n\nDefault: `undefined`\n\nExamples:\n\n- Primitive: `1`\n- Object: `{value: 1, label: 'Label 1'}`\n- Array of primitives for multiselect: `[1, 2]`\n- Array of objects for multiselect: `[{value: 1, label: 'Label 1'}, {value: 2, label: 'Label 2'}]`\n\n### multiple: Bool\n\n_Description: multi-value dropdown_\n\nDefault: `false`\n\n### searchable: Bool\n\n_Description: ability to search / filter options. [`onSearch`](#onSearch-function) function will be called_\n\nDefault: `false`\n\n### virtualized: Bool\n\n_Description: partly render list options using [react-virtualized](https://bvaughn.github.io/react-virtualized/). Huge time to render boost on large datasets. You have to set [`optionHeight`](#optionheight-number--function) property if your option height differs from default._\n\nDefault: `false`\n\n### immutable: Bool\n\n_Description: parse data as [immutable](https://facebook.github.io/immutable-js/) lists. When this property set to `true` you have to provide [`options`](#options-array) and [`value`](#value-any) as immutable objects._\n\nDefault: `false`\n\n### onChange: Function\n\n_Description: onChange callback. Return `false` to leave dropdown opened._\n\nDefault: `undefined`\n\nArguments:\n\n- `value: Array|Object|String|Number`: selected option (or array of options for multi select)\n\nExample:\n\n```javascript\nonChange(value) {\n  // handle new value\n}\n```\n\n### onSearch: Function\n\n_Description: onSearch callback. Calls on every search input change. You have to process search string inside this function and filter your options based on your needs._\n\nDefault: `undefined`\n\nArguments:\n\n- `search: String`: search string\n\nExample:\n\n```javascript\nconst options = [\n  { value: 1, label: 'Label 1' },\n  { value: 2, label: 'Label 2' },\n];\n\nexport default class App extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = { options };\n    this.onSearch = this.onSearch.bind(this);\n  }\n  onSearch(searchString) {\n    this.setState({\n      options: options.filter(o =\u003e o.label.indexOf(searchString) \u003e -1)\n    });\n  }\n  render() {\n    return (\n      \u003cSelect\n        searchable\n        options={this.state.options}\n        onSearch={this.onSearch}\n        ...\n      /\u003e\n    );\n  }\n}\n```\n\n### onAddNewItem: Bool\n\n_Description: callback to handle click on the 'Add new item' option_\n\nDefault: `undefined`\n\nArguments:\n\n- `search: String`: search string\n\n### selectedValueRenderer: Function\n\n_Description: function to render selected value_\n\nDefault: `undefined`\n\nArguments:\n\n- `option: Object|String|Number`: option to render\n- `onRemove: Function`: default function to remove value\n\nExample:\n\n```javascript\nselectedValueRenderer(option, onRemove) {\n  return \u003cdiv style={{color: 'red'}}\u003e{option.label}\u003c/div\u003e;\n}\n```\n\n### selectedBlockRenderer: Function\n\n_Description: the function to render the whole block with selected options_\n\nDefault: `undefined`\n\nArguments:\n\n- `selectedOptions: Array`: the options to be rendered. These are the selected options. You must render them inside the `selectedBlockRenderer` function\n- `onRemove: Function`: is the function that must be triggered on a certain option when you want to remove it. For example, you receive [1,2,3,4] as the `selectedOptions`, so you have to call `onRemove(1)` in order to deselect option 1\n- `selectedValueRenderer: Function`: is the default value renderer. The library uses this function in order to render every single selected option. Something like `selectedOptions.map(option =\u003e selectedValueRenderer(option))`. You can use it or skip and implement your own value renderer.\n- `searchInputRenderer: Function`: is the default function to render search input. The same as above: use it or implement you own logic\n\nExample:\n\n```javascript\nselectedBlockRenderer(selectedOptions, onRemove) {\n  return \u003cdiv\u003e{selectedOptions.map(option =\u003e option.label).join(', ')}\u003c/div\u003e;\n}\n```\n\n### optionRenderer: Function\n\n_Description: function to render custom options_\n\nDefault: `undefined`\n\nArguments:\n\n- `option: Object|String|Number`: option to render\n- `selectedOptions: Array`: currently selected options\n\nExample:\n\n```javascript\noptionRenderer(option, selectedOptions) {\n  return \u003cdiv style={{color: 'red'}}\u003e{option.label}\u003c/div\u003e;\n}\n```\n\n### listRenderer: Function\n\n_Description: function to render the list_\n\nArguments:\n\n- `options: Array`: list of options\n- `selectedOptions: Array`: currently selected options\n- `optionRenderer: Function`: default option renderer\n- `onChange: Function`: default onChange callback\n- `onToggleList: Function`: toggle list visibility\n\nExample:\n\n- Simple\n\n```javascript\nlistRenderer(options, selectedOptions, optionRenderer) {\n  return \u003cul\u003e{options.map(option =\u003e optionRenderer(option, selectedOptions))}\u003c/ul\u003e;\n}\n```\n\n- Advanced\n\n```javascript\nlistRenderer(options, selectedOptions, optionRenderer, onChange, onToggle) {\n  return (\n    \u003cdiv className={s.listWrapper}\u003e\n      \u003cdiv className={s.options}\u003e\n        {options.map(option =\u003e (\n          \u003cdiv className={s.option} onClick={onChange(option)} key={option.value}\u003e\n            \u003cdiv style={{backgroundColor: option.color}} className={s.circle}\u003e\u003c/div\u003e\n            \u003cdiv\u003e{option.label}\u003c/div\u003e\n          \u003c/div\u003e\n        ))}\n      \u003c/div\u003e\n      \u003cdiv className={s.actions\u003e\n        \u003cbutton className={s.btn} onClick={onToggle}\u003eSave\u003c/button\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n### iconRenderer: Function\n\n_Description: function to render custom icon._\n\nDefault: `undefined`\n\nArguments:\n\n- `isOpened: Bool`: whether the list opened\n\nExample:\n\n```javascript\niconRenderer(isOpened) {\n  return \u003ci className={isOpened ? 'icon-open' : 'icon-close'} /\u003e;\n}\n```\n\n### noItemsFound: Bool | String | Function\n\n_Description: Bool: whether to display 'No items found' option or not. String: 'No items found' label. Function: 'No items found' renderer_\n\nDefault: `true`\n\nExample:\n\n```javascript\nnoItemsFound() {\n  return \u003cdiv className=\"my-awesome-class\"\u003eNo items found\u003c/div\u003e;\n}\n```\n\n### addNewItem: Bool | String | Function\n\n_Description: Bool: whether to display 'Add new item' option or not. String: 'Add new item' label. Function: 'Add new item' renderer. You must handle onClick event via `onAddNewItem` callback or your own callback in case of custom renderer. Note: for the 'Add new item' option to display, `searchable` must be true and `options` must be empty._\n\nDefault: `false`\n\nExample:\n\n```javascript\naddNewItem(search) {\n  return \u003cdiv className=\"my-awesome-class\" onClick={this.addNewItemToDropdownOptions}\u003e{`Add '${search}'`}\u003c/div\u003e;\n}\n```\n\n### isOpened: Bool\n\n_Description: setting this property makes open / close functionality uncontrollable. It always opened when `isOpened === true` and always closed when `isOpened === false`. Setting this property to `undefined` returns component to the usual behaviour._\n\nDefault: `undefined`\n\n### beforeOpen: Function\n\n_Description: before open handler. Return `false` to leave dropdown closed._\n\nDefault: `undefined`\n\nArguments:\n\n- `event: Object`: event\n\n### beforeClose: Function\n\n_Description: before close event. Return `false` to leave dropdown opened._\n\nDefault: `undefined`\n\n### onOpen: Function\n\n_Description: handler for when the menu opens_\n\nDefault: `undefined`\n\n### onClose: Function\n\n_Description: handler for when the menu closes_\n\nDefault: `undefined`\n\n### searchClearOnClose: Bool\n\n_Description: whether to clear the input on close or not_\n\nDefault: `true`\n\n### listMaxHeight: Number\n\n_Description: Dropdown list max height in pixels._\n\nDefault: `400`\n\n### listHeight: Number\n\n_Description: when you set this property the list will always have the constant height despite options length and available space. You have to set this property only when you are creating something like horizontally scrolling lists or some other weird lists :) Otherwise, you probably need to `listMaxHeight`._\n\n### optionHeight: Number | Function\n\n_Description: option height. This property has to be set for virtualized lists, because [react-virtualized](https://github.com/bvaughn/react-virtualized/blob/master/docs/VirtualScroll.md#prop-types) has to know total options height to correctly display scroll. It also used to calculate direction to open the list (in case of `direction=\"auto\"`)._\n\nDefault: `40`\n\n### listPosition: String\n\n_Description: Dropdown list position._\n\nDefault: `auto`\n\nAvailable values:\n\n- `top`: expand to top\n- `bottom`: expand to bottom\n- `auto`: auto detection based on `wrapper` element\n\n### getWrapper: Function\n\n_Description: Function to get wrapper element. Commonly you have to set this parameter if any of component's parents has `overflow: hidden` property. This parameter affects to `listMaxHeight` and `listPosition` properties._\n\n### boundaryMargin: Number\n\n_Description: the minimal distance between screen / `wrapper` boundaries and dropdown list._\n\nDefault: `6`\n\n### forbidPhantomSelection: Bool\n\n_Description: doesn't select a `value` option if it doesn't exist in `options` array_\n\nDefault: `false`\n\n### s: Object\n\n_Description: component classNames._\n\nList of supported classes:\n\n```javascript\n{\n  // wrapper\n  dd__wrapper,\n  // applied to multi select\n  dd__multi,\n  // applied to single select\n  dd__single,\n  // applied when dropdown opened\n  dd__opened,\n  // applied when dropdown has error property\n  dd__error,\n  // disabled\n  dd_disabled: classType,\n  // selected block class\n  dd__selectControl,\n  // selected values wrapper class\n  dd__selected,\n  // placeholder class\n  dd__placeholder,\n  // selected option class\n  dd__selectedItem,\n  // icon to remove selected value class\n  dd__crossIcon,\n  // list class\n  dd__list,\n  // virtualized list class\n  dd__listVirtualized,\n  // applied when select opens to bottom\n  dd__openTobottom,\n  // applied when select opens to top\n  dd__openTotop,\n  // dropdown option\n  dd__option,\n  // virtualized option class\n  dd__optionVirtualized,\n  // selected dropdown option\n  dd__selectedOption,\n}\n```\n\nExamples:\n\n- If you are using css modules you can import default styles directly to the component:\n\n```javascript\nimport Select from 'react-select-me';\nimport s from 'react-select-me/src/ReactSelectMe.css';\n...\n\u003cSelect s={s} {...otherProps} /\u003e\n```\n\n- If you want to customize any element with help of your own classes\n\n```javascript\nconst classNames = {\n  // usual class names\n  dd__wrapper: 'my-super-class',\n  // or even with css modules\n  dd__selectedOption: s.mySuperSelectedOption,\n};\n\u003cSelect s={classNames} {...otherProps} /\u003e;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaslianok%2Freact-select-me","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmaslianok%2Freact-select-me","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmaslianok%2Freact-select-me/lists"}