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

react-autocomplete

Package Overview
Dependencies
Maintainers
2
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-autocomplete - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

build/lib/Autocomplete.js

401

lib/Autocomplete.js

@@ -1,13 +0,8 @@

'use strict';
const React = require('react')
const scrollIntoView = require('dom-scroll-into-view')
var _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; };
let _debugStates = []
var React = require('react');
var scrollIntoView = require('dom-scroll-into-view');
let Autocomplete = React.createClass({
var _debugStates = [];
var Autocomplete = React.createClass({
displayName: 'Autocomplete',
propTypes: {

@@ -23,13 +18,11 @@ initialValue: React.PropTypes.any,

getDefaultProps: function getDefaultProps() {
getDefaultProps () {
return {
inputProps: {},
onChange: function onChange() {},
onSelect: function onSelect(value, item) {},
renderMenu: function renderMenu(items, value, style) {
return React.createElement('div', { style: _extends({ style: style }, this.menuStyle), children: items });
onChange () {},
onSelect (value, item) {},
renderMenu (items, value, style) {
return <div style={{style, ...this.menuStyle}} children={items}/>
},
shouldItemRender: function shouldItemRender() {
return true;
},
shouldItemRender () { return true },
menuStyle: {

@@ -43,69 +36,69 @@ borderRadius: '3px',

overflow: 'auto',
maxHeight: '50%' }
};
maxHeight: '50%', // TODO: don't cheat, let it flow to the bottom
}
}
},
// TODO: don't cheat, let it flow to the bottom
getInitialState: function getInitialState() {
getInitialState () {
return {
value: this.props.initialValue || '',
isOpen: false,
highlightedIndex: null
};
highlightedIndex: null,
}
},
componentWillMount: function componentWillMount() {
this._ignoreBlur = false;
this._performAutoCompleteOnUpdate = false;
this._performAutoCompleteOnKeyUp = false;
componentWillMount () {
this._ignoreBlur = false
this._performAutoCompleteOnUpdate = false
this._performAutoCompleteOnKeyUp = false
},
componentWillReceiveProps: function componentWillReceiveProps() {
this._performAutoCompleteOnUpdate = true;
componentWillReceiveProps () {
this._performAutoCompleteOnUpdate = true
},
componentDidUpdate: function componentDidUpdate(prevProps, prevState) {
if (this.state.isOpen === true && prevState.isOpen === false) this.setMenuPositions();
componentDidUpdate (prevProps, prevState) {
if (this.state.isOpen === true && prevState.isOpen === false)
this.setMenuPositions()
if (this.state.isOpen && this._performAutoCompleteOnUpdate) {
this._performAutoCompleteOnUpdate = false;
this.maybeAutoCompleteText();
this._performAutoCompleteOnUpdate = false
this.maybeAutoCompleteText()
}
this.maybeScrollItemIntoView();
this.maybeScrollItemIntoView()
},
maybeScrollItemIntoView: function maybeScrollItemIntoView() {
maybeScrollItemIntoView () {
if (this.state.isOpen === true && this.state.highlightedIndex !== null) {
var itemNode = React.findDOMNode(this.refs['item-' + this.state.highlightedIndex]);
var menuNode = React.findDOMNode(this.refs.menu);
scrollIntoView(itemNode, menuNode, { onlyScrollIfNeeded: true });
var itemNode = React.findDOMNode(this.refs[`item-${this.state.highlightedIndex}`])
var menuNode = React.findDOMNode(this.refs.menu)
scrollIntoView(itemNode, menuNode, { onlyScrollIfNeeded: true })
}
},
handleKeyDown: function handleKeyDown(event) {
if (this.keyDownHandlers[event.key]) this.keyDownHandlers[event.key].call(this, event);else {
handleKeyDown (event) {
if (this.keyDownHandlers[event.key])
this.keyDownHandlers[event.key].call(this, event)
else {
this.setState({
highlightedIndex: null,
isOpen: true
});
})
}
},
handleChange: function handleChange(event) {
var _this = this;
console.log(event.target.value);
this._performAutoCompleteOnKeyUp = true;
handleChange (event) {
this._performAutoCompleteOnKeyUp = true
this.setState({
value: event.target.value
}, function () {
_this.props.onChange(event, _this.state.value);
});
value: event.target.value,
}, () => {
this.props.onChange(event, this.state.value)
})
},
handleKeyUp: function handleKeyUp() {
handleKeyUp () {
if (this._performAutoCompleteOnKeyUp) {
this._performAutoCompleteOnKeyUp = false;
this.maybeAutoCompleteText();
this._performAutoCompleteOnKeyUp = false
this.maybeAutoCompleteText()
}

@@ -115,41 +108,45 @@ },

keyDownHandlers: {
ArrowDown: function ArrowDown() {
event.preventDefault();
var highlightedIndex = this.state.highlightedIndex;
var index = highlightedIndex === null || highlightedIndex === this.getFilteredItems().length - 1 ? 0 : highlightedIndex + 1;
this._performAutoCompleteOnKeyUp = true;
ArrowDown () {
event.preventDefault()
var { highlightedIndex } = this.state
var index = (
highlightedIndex === null ||
highlightedIndex === this.getFilteredItems().length - 1
) ? 0 : highlightedIndex + 1
this._performAutoCompleteOnKeyUp = true
this.setState({
highlightedIndex: index,
isOpen: true
});
isOpen: true,
})
},
ArrowUp: function ArrowUp(event) {
event.preventDefault();
var highlightedIndex = this.state.highlightedIndex;
var index = highlightedIndex === 0 || highlightedIndex === null ? this.getFilteredItems().length - 1 : highlightedIndex - 1;
this._performAutoCompleteOnKeyUp = true;
ArrowUp (event) {
event.preventDefault()
var { highlightedIndex } = this.state
var index = (
highlightedIndex === 0 ||
highlightedIndex === null
) ? this.getFilteredItems().length - 1 : highlightedIndex - 1
this._performAutoCompleteOnKeyUp = true
this.setState({
highlightedIndex: index,
isOpen: true
});
isOpen: true,
})
},
Enter: function Enter(event) {
var _this2 = this;
Enter (event) {
if (this.state.isOpen === false) {
// already selected this, do nothing
return;
} else if (this.state.highlightedIndex == null) {
return
}
else if (this.state.highlightedIndex == null) {
// hit enter after focus but before typing anything so no autocomplete attempt yet
this.setState({
isOpen: false
}, function () {
React.findDOMNode(_this2.refs.input).select();
});
} else {
var item = this.getFilteredItems()[this.state.highlightedIndex];
}, () => {
React.findDOMNode(this.refs.input).select()
})
}
else {
var item = this.getFilteredItems()[this.state.highlightedIndex]
this.setState({

@@ -159,66 +156,72 @@ value: this.props.getItemValue(item),

highlightedIndex: null
}, function () {
}, () => {
//React.findDOMNode(this.refs.input).focus() // TODO: file issue
React.findDOMNode(_this2.refs.input).setSelectionRange(_this2.state.value.length, _this2.state.value.length);
_this2.props.onSelect(_this2.state.value, item);
});
React.findDOMNode(this.refs.input).setSelectionRange(
this.state.value.length,
this.state.value.length
)
this.props.onSelect(this.state.value, item)
})
}
},
Escape: function Escape(event) {
Escape (event) {
this.setState({
highlightedIndex: null,
isOpen: false
});
})
}
},
getFilteredItems: function getFilteredItems() {
var _this3 = this;
getFilteredItems () {
let items = this.props.items
var items = this.props.items;
if (this.props.shouldItemRender) {
items = items.filter(function (item) {
return _this3.props.shouldItemRender(item, _this3.state.value);
});
items = items.filter((item) => (
this.props.shouldItemRender(item, this.state.value)
))
}
if (this.props.sortItems) {
items.sort(function (a, b) {
return _this3.props.sortItems(a, b, _this3.state.value);
});
items.sort((a, b) => (
this.props.sortItems(a, b, this.state.value)
))
}
return items;
return items
},
maybeAutoCompleteText: function maybeAutoCompleteText() {
var _this4 = this;
if (this.state.value === '') return;
var highlightedIndex = this.state.highlightedIndex;
var items = this.getFilteredItems();
if (items.length === 0) return;
var matchedItem = highlightedIndex !== null ? items[highlightedIndex] : items[0];
var itemValue = this.props.getItemValue(matchedItem);
var itemValueDoesMatch = itemValue.toLowerCase().indexOf(this.state.value.toLowerCase()) === 0;
maybeAutoCompleteText () {
if (this.state.value === '')
return
var { highlightedIndex } = this.state
var items = this.getFilteredItems()
if (items.length === 0)
return
var matchedItem = highlightedIndex !== null ?
items[highlightedIndex] : items[0]
var itemValue = this.props.getItemValue(matchedItem)
var itemValueDoesMatch = (itemValue.toLowerCase().indexOf(
this.state.value.toLowerCase()
) === 0)
if (itemValueDoesMatch) {
var node = React.findDOMNode(this.refs.input);
var setSelection = function setSelection() {
node.value = itemValue;
node.setSelectionRange(_this4.state.value.length, itemValue.length);
};
if (highlightedIndex === null) this.setState({ highlightedIndex: 0 }, setSelection);else setSelection();
var node = React.findDOMNode(this.refs.input)
var setSelection = () => {
node.value = itemValue
node.setSelectionRange(this.state.value.length, itemValue.length)
}
if (highlightedIndex === null)
this.setState({ highlightedIndex: 0 }, setSelection)
else
setSelection()
}
},
setMenuPositions: function setMenuPositions() {
var node = React.findDOMNode(this.refs.input);
var rect = node.getBoundingClientRect();
var computedStyle = getComputedStyle(node);
var marginBottom = parseInt(computedStyle.marginBottom, 10);
var marginLeft = parseInt(computedStyle.marginLeft, 10);
var marginRight = parseInt(computedStyle.marginRight, 10);
setMenuPositions () {
var node = React.findDOMNode(this.refs.input)
var rect = node.getBoundingClientRect()
var computedStyle = getComputedStyle(node)
var marginBottom = parseInt(computedStyle.marginBottom, 10)
var marginLeft = parseInt(computedStyle.marginLeft, 10)
var marginRight = parseInt(computedStyle.marginRight, 10)
this.setState({

@@ -228,12 +231,10 @@ menuTop: rect.bottom + marginBottom,

menuWidth: rect.width + marginLeft + marginRight
});
})
},
highlightItemFromMouse: function highlightItemFromMouse(index) {
this.setState({ highlightedIndex: index });
highlightItemFromMouse (index) {
this.setState({ highlightedIndex: index })
},
selectItemFromMouse: function selectItemFromMouse(item) {
var _this5 = this;
selectItemFromMouse (item) {
this.setState({

@@ -243,43 +244,41 @@ value: this.props.getItemValue(item),

highlightedIndex: null
}, function () {
_this5.props.onSelect(_this5.state.value, item);
React.findDOMNode(_this5.refs.input).focus();
_this5.setIgnoreBlur(false);
});
}, () => {
this.props.onSelect(this.state.value, item)
React.findDOMNode(this.refs.input).focus()
this.setIgnoreBlur(false)
})
},
setIgnoreBlur: function setIgnoreBlur(ignore) {
this._ignoreBlur = ignore;
setIgnoreBlur (ignore) {
this._ignoreBlur = ignore
},
renderMenu: function renderMenu() {
var _this6 = this;
var items = this.getFilteredItems().map(function (item, index) {
var element = _this6.props.renderItem(item, _this6.state.highlightedIndex === index, { cursor: 'default' });
renderMenu () {
var items = this.getFilteredItems().map((item, index) => {
var element = this.props.renderItem(
item,
this.state.highlightedIndex === index,
{cursor: 'default'}
)
return React.cloneElement(element, {
onMouseDown: function onMouseDown() {
return _this6.setIgnoreBlur(true);
},
onMouseEnter: function onMouseEnter() {
return _this6.highlightItemFromMouse(index);
},
onClick: function onClick() {
return _this6.selectItemFromMouse(item);
},
ref: 'item-' + index
});
});
onMouseDown: () => this.setIgnoreBlur(true),
onMouseEnter: () => this.highlightItemFromMouse(index),
onClick: () => this.selectItemFromMouse(item),
ref: `item-${index}`,
})
})
var style = {
left: this.state.menuLeft,
top: this.state.menuTop,
minWidth: this.state.menuWidth
};
var menu = this.props.renderMenu(items, this.state.value, style);
return React.cloneElement(menu, { ref: 'menu' });
minWidth: this.state.menuWidth,
}
var menu = this.props.renderMenu(items, this.state.value, style)
return React.cloneElement(menu, { ref: 'menu' })
},
getActiveItemValue: function getActiveItemValue() {
if (this.state.highlightedIndex === null) return '';else {
var item = this.props.items[this.state.highlightedIndex];
getActiveItemValue () {
if (this.state.highlightedIndex === null)
return ''
else {
var item = this.props.items[this.state.highlightedIndex]
// items can match when we maybeAutoCompleteText, but then get replaced by the app

@@ -289,65 +288,61 @@ // for the next render? I think? TODO: file an issue (alab -> enter -> type 'a' for

// better way)
return item ? this.props.getItemValue(item) : '';
return item ? this.props.getItemValue(item) : ''
}
},
handleInputBlur: function handleInputBlur() {
if (this._ignoreBlur) return;
handleInputBlur () {
if (this._ignoreBlur)
return
this.setState({
isOpen: false,
highlightedIndex: null
});
})
},
handleInputFocus: function handleInputFocus() {
if (this._ignoreBlur) return;
this.setState({ isOpen: true });
handleInputFocus () {
if (this._ignoreBlur)
return
this.setState({ isOpen: true })
},
handleInputClick: function handleInputClick() {
if (this.state.isOpen === false) this.setState({ isOpen: true });
handleInputClick () {
if (this.state.isOpen === false)
this.setState({ isOpen: true })
},
render: function render() {
var _this7 = this;
if (this.props.debug) {
// you don't like it, you love it
render () {
if (this.props.debug) { // you don't like it, you love it
_debugStates.push({
id: _debugStates.length,
state: this.state
});
})
}
return React.createElement(
'div',
{ style: { display: 'inline-block' } },
React.createElement('input', _extends({}, this.props.inputProps, {
role: 'combobox',
'aria-autocomplete': 'both',
'aria-label': this.getActiveItemValue(),
ref: 'input',
onFocus: this.handleInputFocus,
onBlur: this.handleInputBlur,
onChange: function (event) {
return _this7.handleChange(event);
},
onKeyDown: function (event) {
return _this7.handleKeyDown(event);
},
onKeyUp: function (event) {
return _this7.handleKeyUp(event);
},
onClick: this.handleInputClick,
value: this.state.value
})),
this.state.isOpen && this.renderMenu(),
this.props.debug && React.createElement(
'pre',
{ style: { marginLeft: 300 } },
JSON.stringify(_debugStates.slice(_debugStates.length - 5, _debugStates.length), null, 2)
)
);
return (
<div style={{display: 'inline-block'}}>
<input
{...this.props.inputProps}
role="combobox"
aria-autocomplete="both"
aria-label={this.getActiveItemValue()}
ref="input"
onFocus={this.handleInputFocus}
onBlur={this.handleInputBlur}
onChange={(event) => this.handleChange(event)}
onKeyDown={(event) => this.handleKeyDown(event)}
onKeyUp={(event) => this.handleKeyUp(event)}
onClick={this.handleInputClick}
value={this.state.value}
/>
{this.state.isOpen && this.renderMenu()}
{this.props.debug && (
<pre style={{marginLeft: 300}}>
{JSON.stringify(_debugStates.slice(_debugStates.length - 5, _debugStates.length), null, 2)}
</pre>
)}
</div>
)
}
});
})
module.exports = Autocomplete;
module.exports = Autocomplete

@@ -1,3 +0,1 @@

'use strict';
module.exports = require('./Autocomplete');
module.exports = require('./Autocomplete')
{
"name": "react-autocomplete",
"version": "0.1.0",
"version": "0.1.1",
"description": "Accessible, extensible, Autocomplete for React.js",

@@ -15,2 +15,6 @@ "main": "./lib/index.js",

},
"scripts": {
"test": "echo 'lol'",
"start": "rackt server"
},
"authors": [

@@ -20,2 +24,6 @@ "Ryan Florence <rpflorence@gmail.com>"

"license": "MIT",
"devDependencies": {
"rackt-cli": "^0.4.0",
"react": "^0.13.3"
},
"tags": [

@@ -31,2 +39,2 @@ "react",

}
}
}
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