Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-select-search

Package Overview
Dependencies
Maintainers
1
Versions
108
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-select-search - npm Package Compare versions

Comparing version 1.0.0-rc3 to 1.0.0-rc4

.idea/codeStyles/codeStyleConfig.xml

8

__tests__/option.test.jsx

@@ -21,3 +21,3 @@ import React from 'react';

<Context.Provider value={theme}>
<Option name="Helvetica" value="helvetica" optionProps={{ className: classes.option }} />
<Option name="Helvetica" value="helvetica" snapshot={{}} />
</Context.Provider>

@@ -46,3 +46,3 @@ ));

<Context.Provider value={theme}>
<Option name="Helvetica" value="helvetica" optionProps={{ className: classes.option, onClick: mockCallback }} />
<Option name="Helvetica" value="helvetica" onChange={mockCallback} snapshot={{}} />
</Context.Provider>

@@ -62,3 +62,3 @@ ));

<Context.Provider value={theme}>
<Option name="Helvetica" value="helvetica" optionProps={{ className: classes.option, onClick: mockCallback, disabled: true }} />
<Option name="Helvetica" value="helvetica" disabled={true} snapshot={{ highlighted: null }} />
</Context.Provider>

@@ -89,3 +89,3 @@ ));

<Context.Provider value={themeWithRenderer}>
<Option {...option} option={option} optionProps={{ className: classes.option }} />
<Option {...option} option={option} snapshot={{ highlighted: false, value: null }} />
</Context.Provider>

@@ -92,0 +92,0 @@ ));

@@ -44,3 +44,3 @@ import React from 'react';

<Context.Provider value={theme}>
<Options options={groupedOptions} />
<Options options={groupedOptions} snapshot={{}} />
</Context.Provider>

@@ -47,0 +47,0 @@ ));

@@ -154,3 +154,3 @@ import React from 'react';

expect(wrapper.state('value')).toBe('');
expect(wrapper.find(Option).at(10).find('li').hasClass('is-disabled')).toBe(true);
expect(wrapper.find(Option).at(10).find('button').hasClass('is-disabled')).toBe(true);

@@ -157,0 +157,0 @@ done();

@@ -26,2 +26,4 @@ "use strict";

var render = theme.renderers.groupHeader;
var onChange = props.onChange,
snapshot = props.snapshot;
var name = props.name;

@@ -42,3 +44,5 @@

}, name), _react.default.createElement(_Options.default, {
options: props.items
options: props.items,
onChange: onChange,
snapshot: snapshot
})));

@@ -50,3 +54,8 @@ };

name: _propTypes.default.string.isRequired,
items: _propTypes.default.arrayOf(_propTypes.default.object).isRequired
items: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
onChange: _propTypes.default.func.isRequired,
snapshot: _propTypes.default.shape({
value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]),
highlighted: _propTypes.default.number
}).isRequired
};

@@ -53,0 +62,0 @@

@@ -22,101 +22,152 @@ "use strict";

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var Option = function Option(props) {
var type = props.type,
groupId = props.groupId,
name = props.name,
optionProps = props.optionProps,
highlighted = props.highlighted,
selected = props.selected,
option = props.option,
disabled = props.disabled,
focus = props.focus;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
if (type && type === 'group') {
return _react.default.createElement(_Group.default, _extends({}, props, {
name: name,
key: groupId
}));
}
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
var ref = (0, _react.createRef)();
var theme = (0, _react.useContext)(_Context.default);
var scrollConf = {
behavior: 'auto',
block: 'center'
};
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
if (!theme.multiple) {
(0, _react.useEffect)(function () {
if (!selected) return;
ref.current.scrollIntoView(scrollConf);
}, [selected, focus]);
}
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
(0, _react.useEffect)(function () {
if (!highlighted) return;
ref.current.scrollIntoView(scrollConf);
}, [highlighted]);
var renderOption = theme.renderers.option;
var className = theme.classes.row;
var optionSnapshot = {
highlighted: highlighted,
selected: selected
};
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
if (disabled) {
className += ' is-disabled';
}
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
if (typeof renderOption === 'function') {
return _react.default.createElement("li", {
ref: ref,
role: "presentation",
className: className
}, renderOption(optionProps, option, optionSnapshot));
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
var Option =
/*#__PURE__*/
function (_React$PureComponent) {
_inherits(Option, _React$PureComponent);
function Option(props) {
var _this;
_classCallCheck(this, Option);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Option).call(this, props));
_this.ref = (0, _react.createRef)();
return _this;
}
return _react.default.createElement("li", {
ref: ref,
role: "presentation",
className: className
}, _react.default.createElement("button", _extends({}, optionProps, {
type: "button"
}), name));
};
_createClass(Option, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var _this2 = this;
var prevSnap = prevProps.snapshot;
var prevFocus = prevSnap.focus;
var _this$props = this.props,
snapshot = _this$props.snapshot,
value = _this$props.value,
index = _this$props.index;
var focus = snapshot.focus,
highlighted = snapshot.highlighted;
var scrollConf = {
behavior: 'auto',
block: 'center'
};
setImmediate(function () {
if (focus) {
var selected = Array.isArray(snapshot.value) && snapshot.value.indexOf(value) >= 0 || value === snapshot.value;
var isHighlighted = index === highlighted;
var prevIsHighlighted = index === prevSnap.highlighted;
if (isHighlighted && isHighlighted !== prevIsHighlighted || selected && focus !== prevFocus) {
_this2.ref.current.scrollIntoView(scrollConf);
}
}
});
}
}, {
key: "render",
value: function render() {
if (this.props.type === 'group') {
return _react.default.createElement(_Group.default, this.props);
}
var _this$props2 = this.props,
name = _this$props2.name,
value = _this$props2.value,
index = _this$props2.index,
disabled = _this$props2.disabled,
onChange = _this$props2.onChange,
snapshot = _this$props2.snapshot;
var optionClass = [this.context.classes.option];
var renderOption = this.context.renderers.option;
var highlighted = index === snapshot.highlighted;
var selected = Array.isArray(snapshot.value) && snapshot.value.indexOf(value) >= 0 || value === snapshot.value;
if (selected) {
optionClass.push('is-selected');
}
if (highlighted) {
optionClass.push('is-highlighted');
}
if (disabled) {
optionClass.push('is-disabled');
}
var optionSnapshot = {
highlighted: highlighted,
selected: selected
};
var optionProps = {
disabled: disabled,
value: value,
className: optionClass.join(' '),
onClick: onChange,
tabIndex: -1,
role: 'menuitem',
'data-selected': selected ? 'true' : null,
'data-highlighted': highlighted ? 'true' : null,
key: value
};
var content = typeof renderOption === 'function' ? renderOption(optionProps, this.props, optionSnapshot) : _react.default.createElement("button", _extends({}, optionProps, {
type: "button"
}), name);
return _react.default.createElement("li", {
ref: this.ref,
key: value,
role: "presentation",
className: this.context.classes.row
}, content);
}
}]);
return Option;
}(_react.default.PureComponent);
Option.contextType = _Context.default;
Option.defaultProps = {
type: null,
groupId: null,
type: null,
selected: false,
highlighted: false,
disabled: false,
items: [],
optionProps: null,
option: null
index: null,
value: null,
items: null
};
Option.propTypes = {
highlighted: _propTypes.default.bool,
selected: _propTypes.default.bool,
disabled: _propTypes.default.bool,
name: _propTypes.default.string.isRequired,
optionProps: _propTypes.default.shape({
'data-selected': _propTypes.default.string,
role: _propTypes.default.string,
onClick: _propTypes.default.func,
className: _propTypes.default.string,
disabled: _propTypes.default.bool
}),
value: _propTypes.default.string,
type: _propTypes.default.string,
groupId: _propTypes.default.string,
items: _propTypes.default.arrayOf(_propTypes.default.object),
groupId: _propTypes.default.string,
type: _propTypes.default.string,
option: _propTypes.default.shape({
name: _propTypes.default.string.isRequired,
value: _propTypes.default.string.isRequired
})
disabled: _propTypes.default.bool,
onChange: _propTypes.default.func.isRequired,
index: _propTypes.default.number,
snapshot: _propTypes.default.shape({
value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]),
highlighted: _propTypes.default.number,
focus: _propTypes.default.bool
}).isRequired
};
var _default = (0, _react.memo)(Option);
var _default = Option;
exports.default = _default;

@@ -25,3 +25,5 @@ "use strict";

var Options = function Options(_ref) {
var options = _ref.options;
var options = _ref.options,
snapshot = _ref.snapshot,
onChange = _ref.onChange;
var theme = (0, _react.useContext)(_Context.default);

@@ -34,2 +36,4 @@ return _react.default.createElement("ul", {

return _react.default.createElement(_Option.default, _extends({}, option, {
snapshot: snapshot,
onChange: onChange,
key: key

@@ -41,3 +45,8 @@ }));

Options.propTypes = {
options: _propTypes.default.arrayOf(_propTypes.default.object).isRequired
options: _propTypes.default.arrayOf(_propTypes.default.object).isRequired,
onChange: _propTypes.default.func.isRequired,
snapshot: _propTypes.default.shape({
value: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.arrayOf(_propTypes.default.string)]),
highlighted: _propTypes.default.number
}).isRequired
};

@@ -44,0 +53,0 @@

@@ -42,6 +42,2 @@ "use strict";

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -71,4 +67,5 @@

// eslint-disable-next-line global-require
fuse = require('fuse.js');
Fuse = require('fuse.js');
} catch (e) {
/* istanbul ignore next */
if (process.env.NODE_ENV !== 'production') {

@@ -110,2 +107,6 @@ console.warn('React Select Search: Not using fuzzy search. Please install fuse.js to enable this feature.');

_defineProperty(_assertThisInitialized(_this), "onOptionClick", function (e) {
return _this.onChange(e.currentTarget.value);
});
_defineProperty(_assertThisInitialized(_this), "onChange", function (value) {

@@ -294,48 +295,2 @@ var currentValue = _this.getValue().slice();

}, {
key: "getOptionsForRender",
value: function getOptionsForRender() {
var _this3 = this;
var multiple = this.props.multiple;
var _this$state2 = this.state,
options = _this$state2.options,
focus = _this$state2.focus,
highlighted = _this$state2.highlighted;
var value = this.getValue();
var mappedOptions = options.map(function (option, i) {
var selected = multiple && Array.isArray(value) && value.indexOf(option.value) >= 0 || option.value === value;
var isHighlighted = i === highlighted;
var className = _this3.theme.classes.option;
if (isHighlighted) {
className += ' is-highlighted';
}
if (selected) {
className += ' is-selected';
}
return _objectSpread({}, option, {
option: option,
selected: selected,
focus: focus,
highlighted: isHighlighted,
disabled: option.disabled,
optionProps: {
className: className,
onClick: function onClick() {
return _this3.onChange(option.value);
},
tabIndex: -1,
role: 'menuitem',
'data-selected': selected ? 'true' : null,
'data-highlighted': highlighted ? 'true' : null,
disabled: _this3.props.disabled || option.disabled
},
key: "".concat(option.value, "-option")
});
});
return (0, _GroupOptions.default)(mappedOptions);
}
}, {
key: "getValueProps",

@@ -348,6 +303,6 @@ value: function getValueProps(value) {

multiple = _this$props2.multiple;
var _this$state3 = this.state,
focus = _this$state3.focus,
error = _this$state3.error,
searching = _this$state3.searching;
var _this$state2 = this.state,
focus = _this$state2.focus,
error = _this$state2.error,
searching = _this$state2.searching;
var search = this.state.search;

@@ -408,3 +363,3 @@ var val = value ? value.name : '';

value: function search() {
var _this4 = this;
var _this3 = this;

@@ -415,5 +370,5 @@ if (this.searchPromise) {

var _this$state4 = this.state,
defaultOptions = _this$state4.defaultOptions,
search = _this$state4.search;
var _this$state3 = this.state,
defaultOptions = _this$state3.defaultOptions,
search = _this$state3.search;
var promise = this.getNewOptionsList(defaultOptions, (0, _toString.default)(search));

@@ -425,8 +380,8 @@ this.searchPromise = (0, _cancelablePromise.default)(promise);

this.searchPromise.promise.then(function (options) {
_this4.setState({
options: options,
_this3.setState({
options: (0, _GroupOptions.default)(options),
searching: false
});
}).catch(function (error) {
_this4.setState({
_this3.setState({
error: error,

@@ -440,14 +395,8 @@ searching: false

value: function fuzzySearch(options, value, fuseOptions) {
var _this5 = this;
var _this4 = this;
return new Promise(function (resolve) {
if (!Fuse) {
resolve(options);
return;
}
if (_this5.props.fuse && options && options.length > 0 && value && value.length > 0) {
var _fuse = new Fuse(options, fuseOptions);
var newOptions = _fuse.search(value).map(function (item, index) {
if (Fuse && _this4.props.fuse && options.length > 0 && value && value.length > 0) {
var fuse = new Fuse(options, fuseOptions);
var newOptions = fuse.search(value).map(function (item, index) {
return Object.assign({}, item, {

@@ -457,7 +406,7 @@ index: index

});
resolve(newOptions);
} else {
resolve(options);
return;
}
resolve(options);
});

@@ -521,6 +470,8 @@ }

value: function render() {
var _this$state5 = this.state,
defaultOptions = _this$state5.defaultOptions,
focus = _this$state5.focus,
searching = _this$state5.searching;
var _this$state4 = this.state,
defaultOptions = _this$state4.defaultOptions,
focus = _this$state4.focus,
searching = _this$state4.searching,
options = _this$state4.options,
highlighted = _this$state4.highlighted;
var _this$props3 = this.props,

@@ -530,5 +481,10 @@ search = _this$props3.search,

disabled = _this$props3.disabled;
var selectedOption = (0, _findByValue.default)(defaultOptions, this.getValue());
var mappedOptions = this.getOptionsForRender();
var value = this.getValue();
var selectedOption = (0, _findByValue.default)(defaultOptions, value);
var valueProps = this.getValueProps(selectedOption);
var snapshot = {
value: value,
highlighted: highlighted,
focus: focus
};
var className = this.theme.classes.main;

@@ -566,3 +522,5 @@

}, _react.default.createElement(_Options.default, {
options: mappedOptions
options: options,
snapshot: snapshot,
onChange: this.onOptionClick
}))));

@@ -569,0 +527,0 @@ }

@@ -10,2 +10,4 @@ import React, { useContext, memo } from 'react';

var render = theme.renderers.groupHeader;
var onChange = props.onChange,
snapshot = props.snapshot;
var name = props.name;

@@ -26,3 +28,5 @@

}, name), React.createElement(Options, {
options: props.items
options: props.items,
onChange: onChange,
snapshot: snapshot
})));

@@ -34,4 +38,9 @@ };

name: PropTypes.string.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired
items: PropTypes.arrayOf(PropTypes.object).isRequired,
onChange: PropTypes.func.isRequired,
snapshot: PropTypes.shape({
value: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
highlighted: PropTypes.number
}).isRequired
};
export default memo(Group);

@@ -0,4 +1,22 @@

function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useContext, memo, useEffect, createRef } from 'react';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
import React, { createRef } from 'react';
import PropTypes from 'prop-types';

@@ -8,96 +26,131 @@ import Context from '../Context';

var Option = function Option(props) {
var type = props.type,
groupId = props.groupId,
name = props.name,
optionProps = props.optionProps,
highlighted = props.highlighted,
selected = props.selected,
option = props.option,
disabled = props.disabled,
focus = props.focus;
var Option =
/*#__PURE__*/
function (_React$PureComponent) {
_inherits(Option, _React$PureComponent);
if (type && type === 'group') {
return React.createElement(Group, _extends({}, props, {
name: name,
key: groupId
}));
}
function Option(props) {
var _this;
var ref = createRef();
var theme = useContext(Context);
var scrollConf = {
behavior: 'auto',
block: 'center'
};
_classCallCheck(this, Option);
if (!theme.multiple) {
useEffect(function () {
if (!selected) return;
ref.current.scrollIntoView(scrollConf);
}, [selected, focus]);
_this = _possibleConstructorReturn(this, _getPrototypeOf(Option).call(this, props));
_this.ref = createRef();
return _this;
}
useEffect(function () {
if (!highlighted) return;
ref.current.scrollIntoView(scrollConf);
}, [highlighted]);
var renderOption = theme.renderers.option;
var className = theme.classes.row;
var optionSnapshot = {
highlighted: highlighted,
selected: selected
};
_createClass(Option, [{
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
var _this2 = this;
if (disabled) {
className += ' is-disabled';
}
var prevSnap = prevProps.snapshot;
var prevFocus = prevSnap.focus;
var _this$props = this.props,
snapshot = _this$props.snapshot,
value = _this$props.value,
index = _this$props.index;
var focus = snapshot.focus,
highlighted = snapshot.highlighted;
var scrollConf = {
behavior: 'auto',
block: 'center'
};
setImmediate(function () {
if (focus) {
var selected = Array.isArray(snapshot.value) && snapshot.value.indexOf(value) >= 0 || value === snapshot.value;
var isHighlighted = index === highlighted;
var prevIsHighlighted = index === prevSnap.highlighted;
if (typeof renderOption === 'function') {
return React.createElement("li", {
ref: ref,
role: "presentation",
className: className
}, renderOption(optionProps, option, optionSnapshot));
}
if (isHighlighted && isHighlighted !== prevIsHighlighted || selected && focus !== prevFocus) {
_this2.ref.current.scrollIntoView(scrollConf);
}
}
});
}
}, {
key: "render",
value: function render() {
if (this.props.type === 'group') {
return React.createElement(Group, this.props);
}
return React.createElement("li", {
ref: ref,
role: "presentation",
className: className
}, React.createElement("button", _extends({}, optionProps, {
type: "button"
}), name));
};
var _this$props2 = this.props,
name = _this$props2.name,
value = _this$props2.value,
index = _this$props2.index,
disabled = _this$props2.disabled,
onChange = _this$props2.onChange,
snapshot = _this$props2.snapshot;
var optionClass = [this.context.classes.option];
var renderOption = this.context.renderers.option;
var highlighted = index === snapshot.highlighted;
var selected = Array.isArray(snapshot.value) && snapshot.value.indexOf(value) >= 0 || value === snapshot.value;
if (selected) {
optionClass.push('is-selected');
}
if (highlighted) {
optionClass.push('is-highlighted');
}
if (disabled) {
optionClass.push('is-disabled');
}
var optionSnapshot = {
highlighted: highlighted,
selected: selected
};
var optionProps = {
disabled: disabled,
value: value,
className: optionClass.join(' '),
onClick: onChange,
tabIndex: -1,
role: 'menuitem',
'data-selected': selected ? 'true' : null,
'data-highlighted': highlighted ? 'true' : null,
key: value
};
var content = typeof renderOption === 'function' ? renderOption(optionProps, this.props, optionSnapshot) : React.createElement("button", _extends({}, optionProps, {
type: "button"
}), name);
return React.createElement("li", {
ref: this.ref,
key: value,
role: "presentation",
className: this.context.classes.row
}, content);
}
}]);
return Option;
}(React.PureComponent);
Option.contextType = Context;
Option.defaultProps = {
type: null,
groupId: null,
type: null,
selected: false,
highlighted: false,
disabled: false,
items: [],
optionProps: null,
option: null
index: null,
value: null,
items: null
};
Option.propTypes = {
highlighted: PropTypes.bool,
selected: PropTypes.bool,
disabled: PropTypes.bool,
name: PropTypes.string.isRequired,
optionProps: PropTypes.shape({
'data-selected': PropTypes.string,
role: PropTypes.string,
onClick: PropTypes.func,
className: PropTypes.string,
disabled: PropTypes.bool
}),
value: PropTypes.string,
type: PropTypes.string,
groupId: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.object),
groupId: PropTypes.string,
type: PropTypes.string,
option: PropTypes.shape({
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired
})
disabled: PropTypes.bool,
onChange: PropTypes.func.isRequired,
index: PropTypes.number,
snapshot: PropTypes.shape({
value: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
highlighted: PropTypes.number,
focus: PropTypes.bool
}).isRequired
};
export default memo(Option);
export default Option;

@@ -9,3 +9,5 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

var Options = function Options(_ref) {
var options = _ref.options;
var options = _ref.options,
snapshot = _ref.snapshot,
onChange = _ref.onChange;
var theme = useContext(Context);

@@ -18,2 +20,4 @@ return React.createElement("ul", {

return React.createElement(Option, _extends({}, option, {
snapshot: snapshot,
onChange: onChange,
key: key

@@ -25,4 +29,9 @@ }));

Options.propTypes = {
options: PropTypes.arrayOf(PropTypes.object).isRequired
options: PropTypes.arrayOf(PropTypes.object).isRequired,
onChange: PropTypes.func.isRequired,
snapshot: PropTypes.shape({
value: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
highlighted: PropTypes.number
}).isRequired
};
export default memo(Options);

@@ -11,6 +11,2 @@ function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }

@@ -51,4 +47,5 @@

// eslint-disable-next-line global-require
fuse = require('fuse.js');
Fuse = require('fuse.js');
} catch (e) {
/* istanbul ignore next */
if (process.env.NODE_ENV !== 'production') {

@@ -90,2 +87,6 @@ console.warn('React Select Search: Not using fuzzy search. Please install fuse.js to enable this feature.');

_defineProperty(_assertThisInitialized(_this), "onOptionClick", function (e) {
return _this.onChange(e.currentTarget.value);
});
_defineProperty(_assertThisInitialized(_this), "onChange", function (value) {

@@ -274,48 +275,2 @@ var currentValue = _this.getValue().slice();

}, {
key: "getOptionsForRender",
value: function getOptionsForRender() {
var _this3 = this;
var multiple = this.props.multiple;
var _this$state2 = this.state,
options = _this$state2.options,
focus = _this$state2.focus,
highlighted = _this$state2.highlighted;
var value = this.getValue();
var mappedOptions = options.map(function (option, i) {
var selected = multiple && Array.isArray(value) && value.indexOf(option.value) >= 0 || option.value === value;
var isHighlighted = i === highlighted;
var className = _this3.theme.classes.option;
if (isHighlighted) {
className += ' is-highlighted';
}
if (selected) {
className += ' is-selected';
}
return _objectSpread({}, option, {
option: option,
selected: selected,
focus: focus,
highlighted: isHighlighted,
disabled: option.disabled,
optionProps: {
className: className,
onClick: function onClick() {
return _this3.onChange(option.value);
},
tabIndex: -1,
role: 'menuitem',
'data-selected': selected ? 'true' : null,
'data-highlighted': highlighted ? 'true' : null,
disabled: _this3.props.disabled || option.disabled
},
key: "".concat(option.value, "-option")
});
});
return GroupOptions(mappedOptions);
}
}, {
key: "getValueProps",

@@ -328,6 +283,6 @@ value: function getValueProps(value) {

multiple = _this$props2.multiple;
var _this$state3 = this.state,
focus = _this$state3.focus,
error = _this$state3.error,
searching = _this$state3.searching;
var _this$state2 = this.state,
focus = _this$state2.focus,
error = _this$state2.error,
searching = _this$state2.searching;
var search = this.state.search;

@@ -388,3 +343,3 @@ var val = value ? value.name : '';

value: function search() {
var _this4 = this;
var _this3 = this;

@@ -395,5 +350,5 @@ if (this.searchPromise) {

var _this$state4 = this.state,
defaultOptions = _this$state4.defaultOptions,
search = _this$state4.search;
var _this$state3 = this.state,
defaultOptions = _this$state3.defaultOptions,
search = _this$state3.search;
var promise = this.getNewOptionsList(defaultOptions, toString(search));

@@ -405,8 +360,8 @@ this.searchPromise = cancelablePromise(promise);

this.searchPromise.promise.then(function (options) {
_this4.setState({
options: options,
_this3.setState({
options: GroupOptions(options),
searching: false
});
}).catch(function (error) {
_this4.setState({
_this3.setState({
error: error,

@@ -420,14 +375,8 @@ searching: false

value: function fuzzySearch(options, value, fuseOptions) {
var _this5 = this;
var _this4 = this;
return new Promise(function (resolve) {
if (!Fuse) {
resolve(options);
return;
}
if (_this5.props.fuse && options && options.length > 0 && value && value.length > 0) {
var _fuse = new Fuse(options, fuseOptions);
var newOptions = _fuse.search(value).map(function (item, index) {
if (Fuse && _this4.props.fuse && options.length > 0 && value && value.length > 0) {
var fuse = new Fuse(options, fuseOptions);
var newOptions = fuse.search(value).map(function (item, index) {
return Object.assign({}, item, {

@@ -437,7 +386,7 @@ index: index

});
resolve(newOptions);
} else {
resolve(options);
return;
}
resolve(options);
});

@@ -501,6 +450,8 @@ }

value: function render() {
var _this$state5 = this.state,
defaultOptions = _this$state5.defaultOptions,
focus = _this$state5.focus,
searching = _this$state5.searching;
var _this$state4 = this.state,
defaultOptions = _this$state4.defaultOptions,
focus = _this$state4.focus,
searching = _this$state4.searching,
options = _this$state4.options,
highlighted = _this$state4.highlighted;
var _this$props3 = this.props,

@@ -510,5 +461,10 @@ search = _this$props3.search,

disabled = _this$props3.disabled;
var selectedOption = findByValue(defaultOptions, this.getValue());
var mappedOptions = this.getOptionsForRender();
var value = this.getValue();
var selectedOption = findByValue(defaultOptions, value);
var valueProps = this.getValueProps(selectedOption);
var snapshot = {
value: value,
highlighted: highlighted,
focus: focus
};
var className = this.theme.classes.main;

@@ -546,3 +502,5 @@

}, React.createElement(Options, {
options: mappedOptions
options: options,
snapshot: snapshot,
onChange: this.onOptionClick
}))));

@@ -549,0 +507,0 @@ }

{
"name": "react-select-search",
"version": "1.0.0-rc3",
"version": "1.0.0-rc4",
"description": "React powered selectbox with search",

@@ -49,3 +49,3 @@ "main": "dist/esm/index.js",

"coveralls": "^3.0.7",
"css-loader": "^0.28.9",
"css-loader": "^3.2.0",
"enzyme": "^3.10.0",

@@ -58,2 +58,3 @@ "enzyme-adapter-react-16": "^1.15.1",

"eslint-plugin-react": "^7.16.0",
"fuse.js": "^3.4.5",
"html-webpack-plugin": "^3.2.0",

@@ -70,3 +71,5 @@ "jest": "^24.9.0",

"dependencies": {},
"optionalDependencies": {}
"optionalDependencies": {
"fuse.js": "^3.4.5"
}
}

@@ -21,2 +21,5 @@ <p align="center">

</a>
<a href="https://bundlephobia.com/result?p=react-select-search@next">
<img src="https://badgen.net/bundlephobia/minzip/react-select-search@next" />
</a>
<a href="https://beerpay.io/tbleckert/react-select-search">

@@ -28,2 +31,3 @@ <img src="https://beerpay.io/tbleckert/react-select-search/badge.svg?style=flat" />

## Features
* Lightweight, with zero dependencies*
* Full test coverage

@@ -38,2 +42,4 @@ * Accessible

_*One optional dependency required for built-in fuzzy search_
## Demo

@@ -40,0 +46,0 @@

@@ -10,2 +10,3 @@ import React, { useContext, memo } from 'react';

const { groupHeader: render } = theme.renderers;
const { onChange, snapshot } = props;
let { name } = props;

@@ -23,2 +24,4 @@

options={props.items}
onChange={onChange}
snapshot={snapshot}
/>

@@ -34,4 +37,12 @@ </div>

items: PropTypes.arrayOf(PropTypes.object).isRequired,
onChange: PropTypes.func.isRequired,
snapshot: PropTypes.shape({
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string),
]),
highlighted: PropTypes.number,
}).isRequired
};
export default memo(Group);

@@ -1,2 +0,2 @@

import React, { useContext, memo, useEffect, createRef } from 'react';
import React, { createRef } from 'react';
import PropTypes from 'prop-types';

@@ -6,101 +6,129 @@ import Context from '../Context';

const Option = (props) => {
const {
type,
groupId,
name,
optionProps,
highlighted,
selected,
option,
disabled,
focus,
} = props;
class Option extends React.PureComponent {
constructor(props) {
super(props);
if (type && type === 'group') {
return (
<Group
{...props}
name={name}
key={groupId}
/>
);
this.ref = createRef();
}
const ref = createRef();
const theme = useContext(Context);
const scrollConf = {
behavior: 'auto',
block: 'center',
};
componentDidUpdate(prevProps) {
const prevSnap = prevProps.snapshot;
const prevFocus = prevSnap.focus;
const { snapshot, value, index } = this.props;
const { focus, highlighted } = snapshot;
const scrollConf = { behavior: 'auto', block: 'center' };
if (!theme.multiple) {
useEffect(() => {
if (!selected) return;
ref.current.scrollIntoView(scrollConf);
}, [selected, focus]);
setImmediate(() => {
if (focus) {
const selected = (
(Array.isArray(snapshot.value) && snapshot.value.indexOf(value) >= 0)
|| value === snapshot.value
);
const isHighlighted = index === highlighted;
const prevIsHighlighted = index === prevSnap.highlighted;
if (
(isHighlighted && isHighlighted !== prevIsHighlighted)
|| (selected && focus !== prevFocus)
) {
this.ref.current.scrollIntoView(scrollConf);
}
}
});
}
useEffect(() => {
if (!highlighted) return;
ref.current.scrollIntoView(scrollConf);
}, [highlighted]);
render() {
if (this.props.type === 'group') {
return <Group {...this.props} />;
}
const { option: renderOption } = theme.renderers;
let className = theme.classes.row;
const optionSnapshot = { highlighted, selected };
const {
name,
value,
index,
disabled,
onChange,
snapshot,
} = this.props;
if (disabled) {
className += ' is-disabled';
}
const optionClass = [this.context.classes.option];
const { option: renderOption } = this.context.renderers;
const highlighted = index === snapshot.highlighted;
const selected = (
(Array.isArray(snapshot.value) && snapshot.value.indexOf(value) >= 0)
|| value === snapshot.value
);
if (typeof renderOption === 'function') {
if (selected) {
optionClass.push('is-selected');
}
if (highlighted) {
optionClass.push('is-highlighted');
}
if (disabled) {
optionClass.push('is-disabled');
}
const optionSnapshot = { highlighted, selected };
const optionProps = {
disabled,
value,
className: optionClass.join(' '),
onClick: onChange,
tabIndex: -1,
role: 'menuitem',
'data-selected': (selected) ? 'true' : null,
'data-highlighted': (highlighted) ? 'true' : null,
key: value,
};
const content = (typeof renderOption === 'function') ?
renderOption(optionProps, this.props, optionSnapshot) :
(
<button {...optionProps} type="button">
{name}
</button>
);
return (
<li ref={ref} role="presentation" className={className}>
{renderOption(optionProps, option, optionSnapshot)}
<li ref={this.ref} key={value} role="presentation" className={this.context.classes.row}>
{content}
</li>
);
}
}
return (
<li ref={ref} role="presentation" className={className}>
<button {...optionProps} type="button">
{name}
</button>
</li>
);
};
Option.contextType = Context;
Option.defaultProps = {
type: null,
groupId: null,
type: null,
selected: false,
highlighted: false,
disabled: false,
items: [],
optionProps: null,
option: null,
index: null,
value: null,
items: null,
};
Option.propTypes = {
highlighted: PropTypes.bool,
selected: PropTypes.bool,
disabled: PropTypes.bool,
name: PropTypes.string.isRequired,
optionProps: PropTypes.shape({
'data-selected': PropTypes.string,
role: PropTypes.string,
onClick: PropTypes.func,
className: PropTypes.string,
disabled: PropTypes.bool,
}),
value: PropTypes.string,
type: PropTypes.string,
groupId: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.object),
groupId: PropTypes.string,
type: PropTypes.string,
option: PropTypes.shape({
name: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}),
disabled: PropTypes.bool,
onChange: PropTypes.func.isRequired,
index: PropTypes.number,
snapshot: PropTypes.shape({
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string),
]),
highlighted: PropTypes.number,
focus: PropTypes.bool,
}).isRequired,
};
export default memo(Option);
export default Option;

@@ -6,3 +6,3 @@ import React, { useContext, memo } from 'react';

const Options = ({ options }) => {
const Options = ({ options, snapshot, onChange }) => {
const theme = useContext(Context);

@@ -16,3 +16,3 @@

return (
<Option {...option} key={key} />
<Option {...option} snapshot={snapshot} onChange={onChange} key={key} />
);

@@ -26,4 +26,12 @@ })}

options: PropTypes.arrayOf(PropTypes.object).isRequired,
onChange: PropTypes.func.isRequired,
snapshot: PropTypes.shape({
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.arrayOf(PropTypes.string),
]),
highlighted: PropTypes.number,
}).isRequired,
};
export default memo(Options);

@@ -17,4 +17,5 @@ import React from 'react';

// eslint-disable-next-line global-require
fuse = require('fuse.js');
Fuse = require('fuse.js');
} catch (e) {
/* istanbul ignore next */
if (process.env.NODE_ENV !== 'production') {

@@ -146,2 +147,4 @@ console.warn('React Select Search: Not using fuzzy search. Please install fuse.js to enable this feature.');

onOptionClick = e => this.onChange(e.currentTarget.value);
onChange = (value) => {

@@ -244,51 +247,2 @@ let currentValue = this.getValue().slice();

getOptionsForRender() {
const { multiple } = this.props;
const {
options,
focus,
highlighted,
} = this.state;
const value = this.getValue();
const mappedOptions = options.map((option, i) => {
const selected = (
(multiple && Array.isArray(value) && value.indexOf(option.value) >= 0)
|| option.value === value
);
const isHighlighted = i === highlighted;
let className = this.theme.classes.option;
if (isHighlighted) {
className += ' is-highlighted';
}
if (selected) {
className += ' is-selected';
}
return {
...option,
option,
selected,
focus,
highlighted: isHighlighted,
disabled: option.disabled,
optionProps: {
className,
onClick: () => this.onChange(option.value),
tabIndex: -1,
role: 'menuitem',
'data-selected': (selected) ? 'true' : null,
'data-highlighted': (highlighted) ? 'true' : null,
disabled: this.props.disabled || option.disabled,
},
key: `${option.value}-option`,
};
});
return GroupOptions(mappedOptions);
}
getValueProps(value) {

@@ -365,3 +319,6 @@ const {

this.searchPromise.promise.then((options) => {
this.setState({ options, searching: false });
this.setState({
options: GroupOptions(options),
searching: false,
});
}).catch((error) => {

@@ -374,9 +331,3 @@ this.setState({ error, searching: false });

return new Promise((resolve) => {
if (!Fuse) {
resolve(options);
return;
}
if (this.props.fuse && options && options.length > 0 && value && value.length > 0) {
if (Fuse && this.props.fuse && options.length > 0 && value && value.length > 0) {
const fuse = new Fuse(options, fuseOptions);

@@ -388,5 +339,7 @@ const newOptions = fuse

resolve(newOptions);
} else {
resolve(options);
return;
}
resolve(options);
});

@@ -446,2 +399,4 @@ }

searching,
options,
highlighted,
} = this.state;

@@ -454,5 +409,12 @@

} = this.props;
const selectedOption = findByValue(defaultOptions, this.getValue());
const mappedOptions = this.getOptionsForRender();
const value = this.getValue();
const selectedOption = findByValue(defaultOptions, value);
const valueProps = this.getValueProps(selectedOption);
const snapshot = {
value,
highlighted,
focus,
};
let className = this.theme.classes.main;

@@ -489,3 +451,7 @@

<div className={this.theme.classes.select}>
<Options options={mappedOptions} />
<Options
options={options}
snapshot={snapshot}
onChange={this.onOptionClick}
/>
</div>

@@ -492,0 +458,0 @@ )}

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc