Socket
Socket
Sign inDemoInstall

downshift

Package Overview
Dependencies
Maintainers
1
Versions
354
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

downshift - npm Package Compare versions

Comparing version 1.0.0-beta.10 to 1.0.0-beta.11

286

dist/autocomplete.js

@@ -78,3 +78,3 @@ 'use strict';

_this.setState({ highlightedIndex }, function () {
_this.internalSetState({ highlightedIndex }, function () {
_this.maybeScrollToHighlightedElement(highlightedIndex);

@@ -85,4 +85,4 @@ });

_this.highlightSelectedItem = function () {
var highlightedIndex = _this.getIndexFromValue(_this.state.selectedValue) || 0;
_this.setState({ highlightedIndex }, function () {
var highlightedIndex = _this.getIndexFromValue(_this.getState().selectedValue) || 0;
_this.internalSetState({ highlightedIndex }, function () {
_this.maybeScrollToHighlightedElement(highlightedIndex, true);

@@ -99,3 +99,3 @@ });

_this.moveHighlightedIndex = function (amount) {
if (_this.state.isOpen) {
if (_this.getState().isOpen) {
_this.changeHighlighedIndex(amount);

@@ -112,4 +112,6 @@ } else {

}
var highlightedIndex = _this.state.highlightedIndex;
var _this$getState = _this.getState(),
highlightedIndex = _this$getState.highlightedIndex;
var baseIndex = highlightedIndex;

@@ -120,4 +122,6 @@ if (baseIndex === null) {

var newIndex = baseIndex + moveAmount;
if (newIndex < 0 || newIndex > itemsLastIndex) {
newIndex = null;
if (newIndex < 0) {
newIndex = itemsLastIndex;
} else if (newIndex > itemsLastIndex) {
newIndex = 0;
}

@@ -128,3 +132,3 @@ _this.setHighlightedIndex(newIndex);

_this.clearSelection = function () {
_this.setState({
_this.internalSetState({
selectedValue: _this.multiple ? [] : '',

@@ -139,9 +143,10 @@ isOpen: false

_this.selectItem = function (itemValue) {
var previousValue = _this.state.selectedValue;
if (!_this.props.multiple) {
_this.reset();
}
_this.setState(function (state) {
_this.internalSetState(function (_ref3) {
var previousValue = _ref3.selectedValue;
if (_this.props.multiple) {
var values = [].concat(_toConsumableArray(state.selectedValue));
var values = [].concat(_toConsumableArray(previousValue));
var pos = values.indexOf(itemValue);

@@ -165,7 +170,2 @@ if (pos > -1) {

}
}, function () {
_this.props.onChange({
selectedValue: _this.state.selectedValue,
previousValue
});
});

@@ -187,3 +187,3 @@ };

_this.selectHighlightedItem = function () {
return _this.selectItemAtIndex(_this.state.highlightedIndex);
return _this.selectItemAtIndex(_this.getState().highlightedIndex);
};

@@ -196,8 +196,8 @@

_this.getRootProps = function () {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref3$refKey = _ref3.refKey,
refKey = _ref3$refKey === undefined ? 'ref' : _ref3$refKey,
onClick = _ref3.onClick,
rest = _objectWithoutProperties(_ref3, ['refKey', 'onClick']);
var _ref4$refKey = _ref4.refKey,
refKey = _ref4$refKey === undefined ? 'ref' : _ref4$refKey,
onClick = _ref4.onClick,
rest = _objectWithoutProperties(_ref4, ['refKey', 'onClick']);

@@ -242,3 +242,3 @@ // this is used in the render to know whether the user has called getRootProps.

event.preventDefault();
if (this.state.isOpen) {
if (this.getState().isOpen) {
this.selectHighlightedItem();

@@ -257,4 +257,9 @@ }

event.preventDefault();
if (this.state.isOpen) {
if (this.state.highlightedIndex === null) {
var _getState = this.getState(),
isOpen = _getState.isOpen,
highlightedIndex = _getState.highlightedIndex;
if (isOpen) {
if (highlightedIndex === null) {
this.closeMenu();

@@ -271,9 +276,10 @@ } else {

_this.getButtonProps = function () {
var _ref4 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var onClick = _ref4.onClick,
onKeyDown = _ref4.onKeyDown,
rest = _objectWithoutProperties(_ref4, ['onClick', 'onKeyDown']);
var onClick = _ref5.onClick,
onKeyDown = _ref5.onKeyDown,
rest = _objectWithoutProperties(_ref5, ['onClick', 'onKeyDown']);
var isOpen = _this.state.isOpen;
var _this$getState2 = _this.getState(),
isOpen = _this$getState2.isOpen;

@@ -306,12 +312,12 @@ return _extends({

_this.getInputProps = function () {
var _ref5 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var onChange = _ref5.onChange,
onKeyDown = _ref5.onKeyDown,
onBlur = _ref5.onBlur,
rest = _objectWithoutProperties(_ref5, ['onChange', 'onKeyDown', 'onBlur']);
var onChange = _ref6.onChange,
onKeyDown = _ref6.onKeyDown,
onBlur = _ref6.onBlur,
rest = _objectWithoutProperties(_ref6, ['onChange', 'onKeyDown', 'onBlur']);
var _this$state = _this.state,
inputValue = _this$state.inputValue,
isOpen = _this$state.isOpen;
var _this$getState3 = _this.getState(),
inputValue = _this$getState3.inputValue,
isOpen = _this$getState3.isOpen;

@@ -340,3 +346,3 @@ return _extends({

_this.input_handleChange = function (event) {
_this.setState({ inputValue: event.target.value });
_this.internalSetState({ inputValue: event.target.value });
};

@@ -351,8 +357,8 @@

_this.getItemProps = function () {
var _ref6 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var _ref7 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var onMouseEnter = _ref6.onMouseEnter,
value = _ref6.value,
index = _ref6.index,
rest = _objectWithoutProperties(_ref6, ['onMouseEnter', 'value', 'index']);
var onMouseEnter = _ref7.onMouseEnter,
value = _ref7.value,
index = _ref7.index,
rest = _objectWithoutProperties(_ref7, ['onMouseEnter', 'value', 'index']);

@@ -368,6 +374,7 @@ _this.items.push({ index, value });

_this.reset = function () {
_this.setState(function (_ref7) {
var selectedValue = _ref7.selectedValue;
_this.reset = function (type) {
_this.internalSetState(function (_ref8) {
var selectedValue = _ref8.selectedValue;
return {
type,
isOpen: false,

@@ -381,4 +388,4 @@ highlightedIndex: null,

_this.toggleMenu = function (newState, cb) {
_this.setState(function (_ref8) {
var isOpen = _ref8.isOpen;
_this.internalSetState(function (_ref9) {
var isOpen = _ref9.isOpen;

@@ -391,4 +398,8 @@ var nextIsOpen = !isOpen;

}, function () {
if (_this.state.isOpen) {
if (_this.state.selectedValue.length > 0) {
var _this$getState4 = _this.getState(),
isOpen = _this$getState4.isOpen,
selectedValue = _this$getState4.selectedValue;
if (isOpen) {
if (selectedValue.length > 0) {
_this.highlightSelectedItem();

@@ -415,3 +426,3 @@ } else {

}
var item = _this.getItemFromIndex(_this.state.highlightedIndex) || {};
var item = _this.getItemFromIndex(_this.getState().highlightedIndex) || {};
var status = _this.props.getA11yStatusMessage({

@@ -435,3 +446,36 @@ resultCount: _this.items.length,

// this is an experimental feature
// so we're not going to document this yet
_createClass(Autocomplete, [{
key: 'getState',
/**
* Gets the state based on internal state or props
* If a state value is passed via props, then that
* is the value given, otherwise it's retrieved from
* stateToMerge
*
* This will perform a shallow merge of the given state object
* with the state coming from props
* (for the controlled component scenario)
* This is used in state updater functions so they're referencing
* the right state regardless of where it comes from.
*
* @param {Object} stateToMerge defaults to this.state
* @return {Object} the state
*/
value: function getState() {
var _this2 = this;
var stateToMerge = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.state;
return Object.keys(stateToMerge).reduce(function (state, key) {
state[key] = _this2.props[key] === undefined ? _this2.state[key] : _this2.props[key];
return state;
}, {});
}
}, {
key: 'maybeScrollToHighlightedElement',

@@ -447,9 +491,70 @@ value: function maybeScrollToHighlightedElement(highlightedIndex, alignToTop) {

}, {
key: 'internalSetState',
// any piece of our state can live in two places:
// 1. Uncontrolled: it's internal (this.state)
// We will call this.setState to update that state
// 2. Controlled: it's external (this.props)
// We will call this.props.onChange to update that state
//
// In addition, we'll always call this.props.onChange if the
// selectedValue is changed because that's important whether
// that property is controlled or not.
value: function internalSetState(stateToSet, cb) {
var _this3 = this;
var onChangeArg = {};
var onStateChangeArg = void 0;
return this.setState(function (state) {
state = _this3.getState(state);
onStateChangeArg = typeof stateToSet === 'function' ? stateToSet(state) : stateToSet;
var nextState = {};
// we need to call on change if the outside world is controlling any of our state
// and we're trying to update that state. OR if the selection has changed and we're
// trying to update the selection
if (onStateChangeArg.hasOwnProperty('selectedValue')) {
onChangeArg.selectedValue = onStateChangeArg.selectedValue;
onChangeArg.previousValue = state.selectedValue;
}
Object.keys(onStateChangeArg).forEach(function (key) {
// the type is useful for the onStateChangeArg
// but we don't actually want to set it in internal state.
// this is an undocumented feature for now... Not all internalSetState
// calls support it and I'm not certain we want them to yet.
// But it enables users controlling the isOpen state to know when
// the isOpen state changes due to mouseup events which is quite handy.
if (key === 'type') {
return;
}
// if it's coming from props, then we don't want to set it internally
if (!_this3.props.hasOwnProperty(key)) {
nextState[key] = onStateChangeArg[key];
}
});
return nextState;
}, function () {
// call the provided callback if it's a callback
(0, _utils.cbToCb)(cb)();
// if the selectedValue changed
// then let's call onChange!
if (Object.keys(onChangeArg).length) {
_this3.props.onChange(onChangeArg);
}
// We call this function whether we're controlled or not
// It's mostly useful if we're controlled, but it can
// definitely be useful for folks to know when something
// happens internally.
_this3.props.onStateChange(onStateChangeArg);
});
}
}, {
key: 'getControllerStateAndHelpers',
value: function getControllerStateAndHelpers() {
var _state = this.state,
highlightedIndex = _state.highlightedIndex,
inputValue = _state.inputValue,
isOpen = _state.isOpen,
selectedValue = _state.selectedValue;
var _getState2 = this.getState(),
highlightedIndex = _getState2.highlightedIndex,
inputValue = _getState2.inputValue,
selectedValue = _getState2.selectedValue,
isOpen = _getState2.isOpen;
var getRootProps = this.getRootProps,

@@ -514,3 +619,3 @@ getButtonProps = this.getButtonProps,

value: function componentDidMount() {
var _this2 = this;
var _this4 = this;

@@ -526,10 +631,10 @@ // the _isMounted property is because we have `updateStatus` in a `debounce`

var onMouseDown = function onMouseDown() {
_this2.isMouseDown = true;
_this4.isMouseDown = true;
};
var onMouseUp = function onMouseUp(event) {
_this2.isMouseDown = false;
_this4.isMouseDown = false;
var target = event.target;
if (!_this2._rootNode.contains(target)) {
_this2.reset();
if (!_this4._rootNode.contains(target)) {
_this4.reset(Autocomplete.stateChangeTypes.mouseUp);
}

@@ -541,3 +646,3 @@ };

this.cleanup = function () {
_this2._isMounted = false;
_this4._isMounted = false;
document.body.removeEventListener('mousedown', onMouseDown);

@@ -550,2 +655,4 @@ document.body.removeEventListener('mouseup', onMouseUp);

value: function componentDidUpdate(prevProps, prevState) {
// TODO: what do we need to do for this when the
// autocomplete is a controlled component?
if (prevState.highlightedIndex !== this.state.highlightedIndex || this.state.selectedValue !== prevState.selectedValue) {

@@ -563,4 +670,6 @@ this.updateStatus();

value: function render() {
var children = this.props.children;
// because the items are rerendered every time we call the children
// we clear this out each render and
this.items = [];

@@ -572,20 +681,17 @@ // we reset this so we know whether the user calls getRootProps during

this.getRootProps.called = false;
var _props = this.props,
children = _props.children,
defaultValue = _props.defaultValue,
getValue = _props.getValue,
getA11yStatusMessage = _props.getA11yStatusMessage,
defaultHighlightedIndex = _props.defaultHighlightedIndex,
multiple = _props.multiple,
onClick = _props.onClick,
onChange = _props.onChange,
rest = _objectWithoutProperties(_props, ['children', 'defaultValue', 'getValue', 'getA11yStatusMessage', 'defaultHighlightedIndex', 'multiple', 'onClick', 'onChange']);
var element = children(this.getControllerStateAndHelpers());
if (this.getRootProps.called) {
// doing React.Children.only for Preact support ⚛️
var element = _react2.default.Children.only(children(this.getControllerStateAndHelpers()));
if (!element) {
// returned null or something...
return element;
} else if (this.getRootProps.called) {
// we assumed they applied the root props correctly
return element;
} else if (typeof element.type === 'string') {
return _react2.default.cloneElement(element, this.getRootProps(_extends({}, rest, element.props)));
// they didn't apply the root props, but we can clone
// this and apply the props ourselves
return _react2.default.cloneElement(element, this.getRootProps(element.props));
} else {
// they didn't apply the root props, but they need to
// otherwise we can't query around the autocomplete
throw new Error('downshift: If you return a non-DOM element, you must use apply the getRootProps function');

@@ -607,3 +713,12 @@ }

onChange: _propTypes2.default.func.isRequired,
onClick: _propTypes2.default.func
onStateChange: _propTypes2.default.func,
onClick: _propTypes2.default.func,
// things we keep in state for uncontrolled components
// but can accept as props for controlled components
/* eslint-disable react/no-unused-prop-types */
selectedValue: _propTypes2.default.any,
isOpen: _propTypes2.default.bool,
inputValue: _propTypes2.default.string,
highlightedIndex: _propTypes2.default.number
/* eslint-enable */
};

@@ -613,6 +728,6 @@ Autocomplete.defaultProps = {

defaultValue: null,
getA11yStatusMessage(_ref9) {
var resultCount = _ref9.resultCount,
highlightedItem = _ref9.highlightedItem,
getValue = _ref9.getValue;
getA11yStatusMessage(_ref10) {
var resultCount = _ref10.resultCount,
highlightedItem = _ref10.highlightedItem,
getValue = _ref10.getValue;

@@ -628,4 +743,7 @@ if (!resultCount) {

return String(i);
}
},
onStateChange: function onStateChange() {} };
Autocomplete.stateChangeTypes = {
mouseUp: '__autocomplete_mouseup__'
};
exports.default = Autocomplete;
{
"name": "downshift",
"version": "1.0.0-beta.10",
"version": "1.0.0-beta.11",
"description": "A set of primitives to build simple, flexible, WAI-ARIA compliant React autocomplete components",

@@ -5,0 +5,0 @@ "main": "dist/index.js",

@@ -125,4 +125,4 @@ <h1 align="center">

This is the only component. It doesn't render anything itself, it just calls the child function and renders that. Wrap
everything in this.
This is the only component. It doesn't render anything itself, it just calls
the child function and renders that. Wrap everything in this.

@@ -168,2 +168,38 @@ #### getValue

#### onStateChange
> `function({highlightedIndex, inputValue, isOpen, selectedValue})` | not required, no useful default
This function is called anytime the internal state changes. This can be useful
if you're using downshift as a "controlled" component, where you manage some or
all of the state (e.g. isOpen, selectedValue, highlightedIndex, etc) and then
pass it as props, rather than letting downshift control all its state itself.
#### highlightedIndex
> `number` | **state prop** (read more below)
The index that should be highlighted
#### inputValue
> `string` | **state prop** (read more below)
The value the input should have
#### isOpen
> `boolean` | **state prop** (read more below)
Whether the menu should be considered open or closed. Some aspects of the
autocomplete component respond differently based on this value (for example, if
`isOpen` is true when the user hits "Enter" on the input field, then the
item at the `highlightedIndex` item is selected).
#### `selectedValue`
> `any`/`Array(any)` | **state prop** (read more below)
The currently selected value.
#### children

@@ -255,2 +291,13 @@

### State Props
You can pass some props which normally the `downshift` will manage for you. If
you pass these props, then they become "controlled" props. In this situation,
`downshift` will no longer update them directly and will instead call your
`onStateChange` handler and expect you to update them. This can be useful if
you want to control the component externally (like selecting an item
from another part of the UI).
State Props are labeled above with **state prop**
## Examples

@@ -257,0 +304,0 @@

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