react-bootstrap-typeahead
Version:
React typeahead with Bootstrap styling
94 lines (90 loc) • 3.52 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
var _excluded = ["children", "className", "inputClassName", "inputRef", "referenceElementRef", "selected"];
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
import cx from 'classnames';
import React from 'react';
import Hint from '../Hint';
import Input from '../Input';
import { isSelectable, propsWithBsClassName } from '../../utils';
function TypeaheadInputMulti(props) {
var wrapperRef = React.useRef(null);
var inputElem = React.useRef(null);
var _propsWithBsClassName = propsWithBsClassName(props),
children = _propsWithBsClassName.children,
className = _propsWithBsClassName.className,
inputClassName = _propsWithBsClassName.inputClassName,
inputRef = _propsWithBsClassName.inputRef,
referenceElementRef = _propsWithBsClassName.referenceElementRef,
selected = _propsWithBsClassName.selected,
rest = _objectWithoutProperties(_propsWithBsClassName, _excluded);
function getInputRef(input) {
inputElem.current = input;
props.inputRef(input);
}
/**
* Forward click or focus events on the container element to the input.
*/
function handleContainerClickOrFocus(e) {
// Don't focus the input if it's disabled.
if (props.disabled) {
e.currentTarget.blur();
return;
}
var inputNode = inputElem.current;
if (!inputNode ||
// Ignore if the clicked element is a child of the container, ie: a token
// or the input itself.
e.currentTarget.contains(e.target) && e.currentTarget !== e.target) {
return;
}
if (isSelectable(inputNode)) {
// Move cursor to the end if the user clicks outside the actual input.
inputNode.selectionStart = inputNode.value.length;
}
inputNode.focus();
}
function handleKeyDown(e) {
if (e.key === 'Backspace' && selected.length && !props.value) {
var _wrapperRef$current;
// Prevent browser from going back.
e.preventDefault();
// If the input is selected and there is no text, focus the last
// token when the user hits backspace.
var wrapperChildren = (_wrapperRef$current = wrapperRef.current) === null || _wrapperRef$current === void 0 ? void 0 : _wrapperRef$current.children;
if (wrapperChildren !== null && wrapperChildren !== void 0 && wrapperChildren.length) {
var lastToken = wrapperChildren[wrapperChildren.length - 2];
lastToken === null || lastToken === void 0 || lastToken.focus();
}
}
props.onKeyDown && props.onKeyDown(e);
}
return /*#__PURE__*/React.createElement("div", {
className: cx('rbt-input-multi', {
disabled: props.disabled
}, className),
onClick: handleContainerClickOrFocus,
onFocus: handleContainerClickOrFocus,
ref: referenceElementRef,
tabIndex: -1
}, /*#__PURE__*/React.createElement("div", {
className: "rbt-input-wrapper",
ref: wrapperRef
}, children, /*#__PURE__*/React.createElement(Hint, null, /*#__PURE__*/React.createElement(Input, _extends({}, rest, {
className: inputClassName,
onKeyDown: handleKeyDown,
ref: getInputRef,
style: {
backgroundColor: 'transparent',
border: 0,
boxShadow: 'none',
cursor: 'inherit',
outline: 'none',
padding: 0,
width: '100%',
zIndex: 1
}
})))));
}
export default TypeaheadInputMulti;