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

@lendi-ui/auto-complete

Package Overview
Dependencies
Maintainers
26
Versions
75
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lendi-ui/auto-complete - npm Package Compare versions

Comparing version 5.2.0 to 5.2.1

dist/auto-complete.cjs.dev.js

16

CHANGELOG.md
## [5.1.0] 2020-03-17 [FUNNEL-1124](
## 5.2.1
### Patch Changes
- fix publish issue
- Updated dependencies [undefined]
- @lendi-ui/icon@9.7.1
- @lendi-ui/breakpoint@5.2.1
- @lendi-ui/color@5.1.1
- @lendi-ui/depth@4.1.1
- @lendi-ui/spacing@7.1.1
- @lendi-ui/spinner@4.1.1
- @lendi-ui/text-input@4.2.1
- @lendi-ui/typography@5.1.1
- @lendi-ui/utils@5.1.1
## 5.2.0

@@ -4,0 +20,0 @@

12

dist/auto-complete.cjs.d.ts

@@ -1,11 +0,1 @@

// are you seeing an error that a default export doesn't exist but your source file has a default export?
// you should run `yarn` or `yarn preconstruct dev` if preconstruct dev isn't in your postinstall hook
// curious why you need to?
// this file exists so that you can import from the entrypoint normally
// except that it points to your source file and you don't need to run build constantly
// which means we need to re-export all of the modules from your source file
// and since export * doesn't include default exports, we need to read your source file
// to check for a default export and re-export it if it exists
// it's not ideal, but it works pretty well ¯\_(ツ)_/¯
export * from "../src/index";
export * from "./declarations/src/index";

@@ -1,21 +0,7 @@

"use strict";
// this file might look strange and you might be wondering what it's for
// it's lets you import your source files by importing this entrypoint
// as you would import it if it was built with preconstruct build
// this file is slightly different to some others though
// it has a require hook which compiles your code with Babel
// this means that you don't have to set up @babel/register or anything like that
// but you can still require this module and it'll be compiled
'use strict';
const path = require("path");
// this bit of code imports the require hook and registers it
let unregister = require("../../../node_modules/@preconstruct/hook/dist/hook.cjs.js").___internalHook(path.resolve(__dirname, "../../.."), path.resolve(__dirname, ".."));
// this re-exports the source file
module.exports = require("../src/index.tsx");
// this unregisters the require hook so that any modules required after this one
// aren't compiled with the require hook in case you have some other require hook
// or something that should be used on other modules
unregister();
if (process.env.NODE_ENV === "production") {
module.exports = require("./auto-complete.cjs.prod.js");
} else {
module.exports = require("./auto-complete.cjs.dev.js");
}

@@ -1,15 +0,847 @@

// 👋 hey!!
// you might be reading this and seeing .esm in the filename
// and being confused why there is commonjs below this filename
// DON'T WORRY!
// this is intentional
// it's only commonjs with `preconstruct dev`
// when you run `preconstruct build`, it will be ESM
// why is it commonjs?
// we need to re-export every export from the source file
// but we can't do that with ESM without knowing what the exports are (because default exports aren't included in export/import *)
// and they could change after running `preconstruct dev` so we can't look at the file without forcing people to
// run preconstruct dev again which wouldn't be ideal
// this solution could change but for now, it's working
import { Component, createElement, createRef, cloneElement } from 'react';
import { debounce } from 'lodash';
import { Input } from '@lendi-ui/text-input';
import styled, { css } from 'styled-components';
import Spinner from '@lendi-ui/spinner';
import { normalise, deriveSize } from '@lendi-ui/utils';
import { gte, map } from '@lendi-ui/breakpoint';
import { m, py, px, p } from '@lendi-ui/spacing';
import { bg, fg } from '@lendi-ui/color';
import { Close } from '@lendi-ui/icon';
import { depth } from '@lendi-ui/depth';
import { select } from '@lendi-ui/theme';
module.exports = require("../src/index.tsx")
function _templateObject13() {
var data = _taggedTemplateLiteral(["\n top: ", ";\n width: ", ";\n height: ", ";\n "]);
_templateObject13 = function _templateObject13() {
return data;
};
return data;
}
function _templateObject12() {
var data = _taggedTemplateLiteral(["\n top: ", ";\n width: ", ";\n height: ", ";\n "]);
_templateObject12 = function _templateObject12() {
return data;
};
return data;
}
function _templateObject11() {
var data = _taggedTemplateLiteral(["\n top: ", ";\n width: ", ";\n height: ", ";\n "]);
_templateObject11 = function _templateObject11() {
return data;
};
return data;
}
function _templateObject10() {
var data = _taggedTemplateLiteral(["\n ", ";\n"]);
_templateObject10 = function _templateObject10() {
return data;
};
return data;
}
function _templateObject9() {
var data = _taggedTemplateLiteral(["\n ", ";\n"]);
_templateObject9 = function _templateObject9() {
return data;
};
return data;
}
function _templateObject8() {
var data = _taggedTemplateLiteral(["\n cursor: pointer;\n"]);
_templateObject8 = function _templateObject8() {
return data;
};
return data;
}
function _templateObject7() {
var data = _taggedTemplateLiteral(["\n ", ";\n"]);
_templateObject7 = function _templateObject7() {
return data;
};
return data;
}
function _templateObject6() {
var data = _taggedTemplateLiteral(["\n ", ";\n min-width: 110px;\n"]);
_templateObject6 = function _templateObject6() {
return data;
};
return data;
}
function _templateObject5() {
var data = _taggedTemplateLiteral(["\n background-color: initial;\n color: initial;\n "]);
_templateObject5 = function _templateObject5() {
return data;
};
return data;
}
function _templateObject4() {
var data = _taggedTemplateLiteral(["\n ", ";\n ", ";\n "]);
_templateObject4 = function _templateObject4() {
return data;
};
return data;
}
function _templateObject3() {
var data = _taggedTemplateLiteral(["\n max-height: 40px;\n "]);
_templateObject3 = function _templateObject3() {
return data;
};
return data;
}
function _templateObject2() {
var data = _taggedTemplateLiteral(["\n width: auto;\n word-wrap: break-word;\n list-style: none;\n ", ";\n ", ";\n max-height: 48px;\n ", ";\n font-family: ", ";\n :hover {\n ", ";\n ", " cursor: pointer;\n font-weight: 700;\n }\n\n ", ";\n"]);
_templateObject2 = function _templateObject2() {
return data;
};
return data;
}
function _templateObject() {
var data = _taggedTemplateLiteral(["\n ", ";\n ", ";\n ", ";\n border-radius: ", ";\n max-height: 192px;\n position: absolute;\n ", ";\n z-index: 1;\n ", ";\n overflow: auto;\n outline: none;\n width: ", ";\n"]);
_templateObject = function _templateObject() {
return data;
};
return data;
}
function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
var AutoCompleteList = styled.ul(_templateObject(), m('nil'), py('xxs'), px('nil'), select('borderRadius'), bg('shade.0'), depth(1), props => props.customWidth ? props.customWidth + 'px' : 'auto');
var AutoCompleteListItem = styled.li(_templateObject2(), px('sm'), py('xs'), gte('tablet')(_templateObject3()), select('typography.body.fontFamily'), bg('secondary.500'), fg('shade.0'), (_ref) => {
var {
isActive
} = _ref;
return isActive ? css(_templateObject4(), bg('secondary.500'), fg('shade.0')) : css(_templateObject5());
});
var AutoCompleteWrapper = styled.div(_templateObject6(), normalise);
var AfterIconWrapper = styled.span(_templateObject7(), p('sm'));
var CloseWrapper = styled.span(_templateObject8());
var SpinnerWrapper = styled(Spinner)(_templateObject9(), (_ref2) => {
var {
size
} = _ref2;
return iconBySizeMixin(size);
});
var CloseIcon = styled(Close)(_templateObject10(), (_ref3) => {
var {
size
} = _ref3;
return iconBySizeMixin(size);
});
var iconBySizeMixin = size => map(size, val => {
switch (val) {
case 'sm':
return css(_templateObject11(), deriveSize(0.35), deriveSize(1), deriveSize(1));
case 'md':
return css(_templateObject12(), deriveSize(0.45), deriveSize(1.25), deriveSize(1.25));
case 'lg':
return css(_templateObject13(), deriveSize(0.35), deriveSize(1.75), deriveSize(1.75));
default:
return undefined;
}
});
var KEY_UP = 'ArrowUp';
var KEY_DOWN = 'ArrowDown';
var KEY_ENTER = 'Enter';
var KEY_TAB = 'Tab';
var KEY_ESCAPE = 'Escape';
class AutoCompleteMenuList extends Component {
componentDidMount() {
this.props.debounceWindowResize();
}
render() {
var {
filteredDataSource,
onSelectItem = () => {},
activeSelection = 0,
menuWidth,
innerRef,
onMouseEnter: _onMouseEnter = () => {}
} = this.props;
return /*#__PURE__*/createElement(AutoCompleteList, {
customWidth: menuWidth,
ref: innerRef
}, filteredDataSource.map((option, index) => /*#__PURE__*/createElement(AutoCompleteListItem, {
key: index,
tabIndex: index,
className: index === activeSelection ? 'selectedItem' : '',
isActive: index === activeSelection,
onClick: () => onSelectItem(option),
value: option.value,
onMouseEnter: () => _onMouseEnter(index)
}, /*#__PURE__*/createElement("div", {
dangerouslySetInnerHTML: {
__html: option.label
}
}))));
}
}
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function extractData(_x, _x2) {
return _extractData.apply(this, arguments);
}
function _extractData() {
_extractData = _asyncToGenerator(function* (userInput, dataSource) {
var filteredDataSource = [];
if (userInput !== '') {
if (!Array.isArray(dataSource)) {
filteredDataSource = yield dataSource(userInput);
} else {
filteredDataSource = dataSource.filter(data => data.label.toLowerCase().indexOf(userInput.toLowerCase()) > -1);
}
filteredDataSource = filteredDataSource.map(d => makeInputKeyBold(d, userInput.toLowerCase()));
} else {
filteredDataSource = [];
}
return filteredDataSource;
});
return _extractData.apply(this, arguments);
}
var makeInputKeyBold = (str, find) => {
var regex = new RegExp(escapeSpecialCharacters(find), 'gi');
var matchings = str.label.match(regex);
if (matchings) {
return {
label: str.label.replace(new RegExp(escapeSpecialCharacters(matchings[0]), 'g'), '<b>' + matchings[0] + '</b>'),
value: str.value
};
} else {
return str;
}
};
function escapeSpecialCharacters(text) {
return text.replace(/[-[\]{}()*+?.,\\/^$|#\s]/g, '\\$&');
}
var getOffsetScrollTop = menuContainer => {
// The idea is to calculate the new scrollTop for menuContainer as you scroll up/down. Just a simple mathematics to scroll the
// container by selected item height. If the additon of selectedItem's offsetTop and offsetHeight cannot be accomodated inside menucontainer,
// which means if their addition is bigger than menuContainer's offsetHeight then we will make its difference to menuContainer's scrollTop
// and the addiiton of 7, is just to have extra padding to accodomate the padding we are giving at menuContainer's level - ${py('xxs')};
// for example - if we change the padding ${py('xxs')} to ${py('xs')}, then we need to change this factor of 7 to 12.
var newScrollTop = 0;
if (menuContainer.current) {
menuContainer.current.scrollTop = 0; // just a reset and calculate again.
newScrollTop = menuContainer.current.querySelector('.selectedItem').offsetTop + menuContainer.current.querySelector('.selectedItem').offsetHeight - menuContainer.current.offsetHeight + 7;
}
return newScrollTop;
}; // makeInputKeyBold makes you item label to contain html <b> tag to make your selection
// bold, this function remove that, before we send the item to consumer.
function transformedItem(item) {
return {
label: item.label.replace(/<\/?[^>]+(>|$)/g, ''),
// remove html tag like <b>
value: item.value
};
}
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 _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
function _asyncToGenerator$1(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var DEBOUNCE_WAIT = 300;
var WINDOW_RESIZE_WAIT = 100;
class AutoComplete extends Component {
constructor(props) {
var _this;
super(props);
_this = this;
_defineProperty(this, "state", {
activeSelection: 0,
filteredDataSource: [],
userInput: this.props.initialValue || '',
showList: false,
isLoading: false,
menuWidth: 0
});
_defineProperty(this, "menuContainerRef", /*#__PURE__*/createRef());
_defineProperty(this, "inputWrapper", /*#__PURE__*/createRef());
_defineProperty(this, "calcInputWidth", () => {
// @TODO - Future enhancement, ref forwarding https://creditandfinance.atlassian.net/browse/HUB-510
if (this.inputWrapper && this.inputWrapper.current) {
var inputChild = this.inputWrapper.current.firstElementChild;
if (inputChild !== null) {
this.setState({
menuWidth: inputChild.offsetWidth
});
}
}
});
_defineProperty(this, "getFilteredData", /*#__PURE__*/function () {
var _ref = _asyncToGenerator$1(function* (userInput) {
var {
dataSource,
backupOption
} = _this.props;
var filteredDataSource = yield extractData(userInput, dataSource);
if (!filteredDataSource.length && backupOption) {
filteredDataSource.push(backupOption);
}
_this.setState({
activeSelection: 0,
filteredDataSource,
showList: true,
isLoading: false
});
});
return function (_x) {
return _ref.apply(this, arguments);
};
}());
_defineProperty(this, "onHoverOff", e => {
// this component is uncontrolled component, and showing-menu is internal to it,
// so just checking if consumer clicks outside `AC`, it will find out and close the menu
var theClickedElement = e.target.parentElement; // @TODO - Future enhancement, ref forwarding https://creditandfinance.atlassian.net/browse/HUB-510
var inputChild = this.inputWrapper.current.firstElementChild;
if (inputChild !== theClickedElement) {
this.setState({
showList: false
});
}
});
_defineProperty(this, "renderAfterIcon", () => /*#__PURE__*/createElement(AfterIconWrapper, null, this.state.isLoading ? /*#__PURE__*/createElement(SpinnerWrapper, {
size: this.props.size,
variant: "dark"
}) : /*#__PURE__*/createElement(CloseWrapper, {
onClick: this.clearInput
}, /*#__PURE__*/createElement(CloseIcon, {
color: "primary.500",
size: this.props.size
}))));
_defineProperty(this, "listComponent", () => {
if (this.state.userInput && !this.state.isLoading && this.state.filteredDataSource.length > 0) {
return /*#__PURE__*/createElement(AutoCompleteMenuList, {
onSelectItem: this.onSelectItem,
activeSelection: this.state.activeSelection,
filteredDataSource: this.state.filteredDataSource,
innerRef: this.menuContainerRef,
menuWidth: this.state.menuWidth,
debounceWindowResize: this.calcInputWidth,
onMouseEnter: index => this.highlightItemFromMouse(index)
});
}
return;
});
_defineProperty(this, "onSelectItem", item => {
var {
onSelectItem = () => {}
} = this.props;
var textWithoutHTMLJunk = transformedItem(item).label;
onSelectItem(transformedItem(item));
this.setState({
activeSelection: 0,
filteredDataSource: [],
userInput: textWithoutHTMLJunk,
showList: false
});
});
_defineProperty(this, "onChange", event => {
event.persist();
var {
onChange = () => {}
} = this.props;
onChange(event);
var userInput = event.currentTarget.value;
this.setState({
userInput: userInput,
isLoading: true,
filteredDataSource: []
}, () => this.getFilteredData(event.target.value));
});
_defineProperty(this, "onKeyDown", event => {
var {
activeSelection,
filteredDataSource
} = this.state;
var {
onSelectItem = () => {}
} = this.props;
switch (event.key) {
case KEY_ENTER:
if (!filteredDataSource.length) return;
this.setState({
activeSelection: 0,
userInput: filteredDataSource[activeSelection].label.replace(/<\/?[^>]+(>|$)/g, ''),
showList: false
}, () => {
onSelectItem(transformedItem(filteredDataSource[activeSelection]));
});
return;
case KEY_UP:
if (activeSelection === 0) {
return;
}
this.setState({
activeSelection: activeSelection - 1
}, this.focusItem);
return;
case KEY_DOWN:
if (activeSelection === filteredDataSource.length - 1) {
return this.setState({
activeSelection: 0
}, this.focusItem);
}
this.setState({
activeSelection: activeSelection + 1
}, this.focusItem);
return;
case KEY_TAB:
case KEY_ESCAPE:
this.setState({
activeSelection: 0,
showList: false,
filteredDataSource: []
});
return;
default:
return;
}
});
_defineProperty(this, "clearInput", () => {
var {
onSelectItem = () => {}
} = this.props;
return this.setState({
activeSelection: 0,
filteredDataSource: [],
userInput: '',
showList: false
}, () => onSelectItem({
label: '',
value: ''
}));
});
this.getFilteredData = debounce(this.getFilteredData, DEBOUNCE_WAIT);
this.calcInputWidth = debounce(this.calcInputWidth, WINDOW_RESIZE_WAIT);
}
componentDidMount() {
window.addEventListener('click', this.onHoverOff);
window.addEventListener('resize', this.calcInputWidth);
this.calcInputWidth();
}
componentWillUnmount() {
window.removeEventListener('resize', this.calcInputWidth);
window.removeEventListener('click', this.onHoverOff);
}
highlightItemFromMouse(index) {
this.setState({
activeSelection: index
});
} // Event fired when the input value is changed
focusItem() {
if (this.menuContainerRef.current) {
this.menuContainerRef.current.scrollTop = getOffsetScrollTop(this.menuContainerRef);
}
}
render() {
var _this$props = this.props,
{
dataSource = [],
placeholder = '',
size = 'md',
onSelectItem = () => {}
} = _this$props,
inputProps = _objectWithoutProperties(_this$props, ["dataSource", "placeholder", "size", "onSelectItem"]);
return /*#__PURE__*/createElement(AutoCompleteWrapper, {
ref: this.inputWrapper
}, /*#__PURE__*/createElement(Input, _extends({}, inputProps, {
size: size,
autoComplete: "off" // The attribute specifies whether or not an input field should have autocomplete enabled
,
placeholder: placeholder,
onChange: this.onChange,
onKeyDown: this.onKeyDown,
value: String(this.state.userInput),
after: this.state.userInput && this.renderAfterIcon()
})), this.state.showList && this.listComponent());
}
}
function _extends$1() { _extends$1 = 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$1.apply(this, arguments); }
function _objectWithoutProperties$1(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose$1(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose$1(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
function _defineProperty$1(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
class AutoCompleteStateless extends Component {
constructor(_props) {
super(_props);
_defineProperty$1(this, "inputWrapper", /*#__PURE__*/createRef());
_defineProperty$1(this, "menuContainerRef", /*#__PURE__*/createRef());
_defineProperty$1(this, "state", {
isOpen: false,
highlightedIndex: null,
menuWidth: 0
});
_defineProperty$1(this, "calcInputWidth", () => {
if (this.inputWrapper.current && this.inputWrapper.current.firstElementChild) {
this.setState({
menuWidth: this.inputWrapper.current.firstElementChild.offsetWidth
});
}
});
_defineProperty$1(this, "renderComposeMenu", children => {
return /*#__PURE__*/createElement(AutoCompleteList, {
customWidth: this.state.menuWidth,
ref: this.menuContainerRef
}, children);
});
_defineProperty$1(this, "renderItem", (item, isHighlighted, index) => /*#__PURE__*/createElement(AutoCompleteListItem, {
isActive: index === this.state.highlightedIndex,
className: "".concat(isHighlighted ? 'selectedItem' : ''),
key: index,
value: item.value
}, /*#__PURE__*/createElement("div", {
dangerouslySetInnerHTML: {
__html: item.label
}
})));
_defineProperty$1(this, "renderAfterIcon", () => /*#__PURE__*/createElement(AfterIconWrapper, null, this.props.isLoading ? /*#__PURE__*/createElement(SpinnerWrapper, {
size: this.props.size,
variant: "dark"
}) : /*#__PURE__*/createElement(CloseWrapper, {
onClick: this.clearInput
}, /*#__PURE__*/createElement(CloseIcon, {
color: "primary.500",
size: this.props.size
}))));
_defineProperty$1(this, "handleChange", event => {
var {
onChange = () => {}
} = this.props;
onChange(event);
});
_defineProperty$1(this, "handleInputBlur", event => {
var selectCallback;
var {
highlightedIndex
} = this.state;
if (highlightedIndex !== null) {
var items = this.getFilteredItems(this.props);
var item = items[highlightedIndex];
selectCallback = () => this.props.onSelectItem(transformedItem(item));
}
this.setState({
isOpen: false,
highlightedIndex: null
}, selectCallback);
var {
onBlur
} = this.props;
if (onBlur) {
onBlur(event);
}
});
_defineProperty$1(this, "selectItemFromMouse", item => {
this.setState({
isOpen: false,
highlightedIndex: null
}, () => {
this.props.onSelectItem(transformedItem(item));
});
});
_defineProperty$1(this, "clearInput", () => {
var {
onReset = () => {}
} = this.props;
this.setState({
isOpen: false,
highlightedIndex: null
});
onReset();
});
_defineProperty$1(this, "getFilteredItems", props => {
var items = props.dataSource; // some extra processing can be done here like make the input bold in the selections.
items = items.map(d => makeInputKeyBold(d, String(props.value).toLowerCase()));
return items;
});
_defineProperty$1(this, "isOpen", () => {
return 'open' in this.props ? this.props.open : this.state.isOpen;
});
this.calcInputWidth = debounce(this.calcInputWidth, AutoCompleteStateless.WINDOW_RESIZE_WAIT);
}
componentDidMount() {
window.addEventListener('resize', this.calcInputWidth);
this.calcInputWidth();
}
componentDidUpdate(_prevProps, prevState) {
var {
onMenuVisibilityChange = () => {}
} = this.props;
if (prevState.isOpen !== this.state.isOpen) {
onMenuVisibilityChange(this.state.isOpen);
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.calcInputWidth);
}
renderMenu() {
var children = this.getFilteredItems(this.props).map((item, index) => {
var element = this.renderItem(item, this.state.highlightedIndex === index, index);
return /*#__PURE__*/cloneElement(element, {
onClick: () => this.selectItemFromMouse(item),
onMouseEnter: () => this.highlightItemFromMouse(index)
});
});
return this.renderComposeMenu(children);
}
highlightItemFromMouse(index) {
this.setState({
highlightedIndex: index
});
}
handleKeyDown(event) {
// this is internal keyDown event to do interacttion upon Key_UP/Down, Enter, Tab
var items = this.getFilteredItems(this.props);
var {
highlightedIndex
} = this.state;
var index = 0;
switch (event.key) {
case KEY_DOWN:
if (!items.length) return;
index = highlightedIndex === null ? -1 : highlightedIndex;
var p = (index + 1) % items.length;
index = p;
if (index > -1 && index !== highlightedIndex) {
this.setState({
highlightedIndex: index,
isOpen: true
}, this.focusItem);
}
return;
case KEY_UP:
if (!items.length) return;
index = highlightedIndex === null ? items.length : highlightedIndex;
index = (index - 1 + items.length) % items.length;
if (index !== items.length) {
this.setState({
highlightedIndex: index,
isOpen: true
}, this.focusItem);
}
return;
case KEY_ENTER:
// menu is closed so there is no selection to accept -> do nothing
if (!items.length || !this.isOpen()) {
return;
} else if (this.state.highlightedIndex == null) {
// input has focus but no menu item is selected + enter is hit -> close the menu, highlight whatever's in input
this.setState({
isOpen: false
});
} else {
// text entered + menu item has been highlighted + enter is hit -> update value to that of selected menu item, close the menu
event.preventDefault();
var item = this.getFilteredItems(this.props)[this.state.highlightedIndex];
this.setState({
isOpen: false,
highlightedIndex: null
}, () => {
this.props.onSelectItem(transformedItem(item));
});
}
return;
case KEY_TAB:
case KEY_ESCAPE:
return this.setState({
highlightedIndex: null,
isOpen: false
});
default:
if (!this.isOpen()) {
this.setState({
isOpen: true
});
}
} // if there is an external keydown event
var {
onKeyDown
} = this.props;
if (onKeyDown) {
onKeyDown(event);
}
}
focusItem() {
if (this.menuContainerRef.current) this.menuContainerRef.current.scrollTop = getOffsetScrollTop(this.menuContainerRef);
}
render() {
var open = this.isOpen();
var _this$props = this.props,
{
dataSource,
value = '',
onChange = () => {},
placeholder = '',
size = 'md',
onSelectItem = () => {},
onMenuVisibilityChange
} = _this$props,
inputProps = _objectWithoutProperties$1(_this$props, ["dataSource", "value", "onChange", "placeholder", "size", "onSelectItem", "onMenuVisibilityChange"]);
return /*#__PURE__*/createElement(AutoCompleteWrapper, {
ref: this.inputWrapper
}, /*#__PURE__*/createElement(Input, _extends$1({}, inputProps, {
size: size,
placeholder: placeholder,
autoComplete: "off" // The attribute specifies whether or not an input field should have autocomplete enabled
,
onChange: this.handleChange,
onKeyDown: event => this.handleKeyDown(event),
value: String(this.props.value),
after: (this.props.isLoading || this.props.value) && this.renderAfterIcon(),
onBlur: this.handleInputBlur
})), open && dataSource.length > 0 && this.renderMenu());
}
}
_defineProperty$1(AutoCompleteStateless, "WINDOW_RESIZE_WAIT", 100);
export { AutoComplete, AutoCompleteStateless };
{
"name": "@lendi-ui/auto-complete",
"version": "5.2.0",
"version": "5.2.1",
"license": "ISC",

@@ -19,11 +19,11 @@ "source": "src/index.tsx",

"dependencies": {
"@lendi-ui/breakpoint": "^5.2.0",
"@lendi-ui/color": "^5.1.0",
"@lendi-ui/depth": "^4.1.0",
"@lendi-ui/icon": "^9.7.0",
"@lendi-ui/spacing": "^7.1.0",
"@lendi-ui/spinner": "^4.1.0",
"@lendi-ui/text-input": "^4.2.0",
"@lendi-ui/typography": "^5.1.0",
"@lendi-ui/utils": "^5.1.0",
"@lendi-ui/breakpoint": "^5.2.1",
"@lendi-ui/color": "^5.1.1",
"@lendi-ui/depth": "^4.1.1",
"@lendi-ui/icon": "^9.7.1",
"@lendi-ui/spacing": "^7.1.1",
"@lendi-ui/spinner": "^4.1.1",
"@lendi-ui/text-input": "^4.2.1",
"@lendi-ui/typography": "^5.1.1",
"@lendi-ui/utils": "^5.1.1",
"@types/lodash": "^4.14.144",

@@ -33,3 +33,3 @@ "lodash": "^4.17.15"

"devDependencies": {
"@lendi-ui/field": "^3.1.0",
"@lendi-ui/field": "^3.1.1",
"@lendi-ui/theme": "*",

@@ -36,0 +36,0 @@ "@types/react": "^16.4.8",

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