robust-react-ui
Version:
A React component library, built with a focus on accessibility, extensibility and reusability.
158 lines (153 loc) • 7.13 kB
JavaScript
;
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var React = require('react');
var React__default = _interopDefault(React);
var index = require('../../utils/getClassNames/index.js');
var _tslib = require('../../_virtual/_tslib.js');
var AutoComplete = function (_a) {
var labelId = _a.labelId, labelText = _a.labelText, options = _a.options, value = _a.value, onChangeFunction = _a.onChangeFunction, onSelectOptionFunction = _a.onSelectOptionFunction, onClearOptionsFunction = _a.onClearOptionsFunction;
var _b = React.useState([]), moddedOptions = _b[0], setModdedOptions = _b[1];
var _c = React.useState(false), open = _c[0], setOpen = _c[1];
var _d = React.useState(false), mouseIn = _d[0], setMouseIn = _d[1];
var ref = React.useRef(null);
React.useEffect(function () {
var refList = options.map(function (option, i) { return ({
i: i,
option: option,
selected: false,
id: "result_" + i,
}); });
setModdedOptions(refList);
}, [options]);
var changePseudoFocus = function (index) {
return setModdedOptions(moddedOptions.map(function (x) {
if (x.i === index) {
return _tslib.__assign(_tslib.__assign({}, x), { selected: true });
}
return _tslib.__assign(_tslib.__assign({}, x), { selected: false });
}));
};
var selectAndCloseMenu = function () {
var selected = moddedOptions.find(function (x) { return x.selected; });
if (ref.current && selected) {
onSelectOptionFunction(selected.option);
}
onClearOptionsFunction();
};
var switchFocus = function (dir) {
var length = moddedOptions.length;
var max = length - 1;
var anySelected = moddedOptions.find(function (x) { return x.selected; });
// If there are more than 0 items, navigate
if (length > 0) {
if (anySelected) {
// get current index
if (dir === 'UP') {
if (anySelected.i === 0) {
changePseudoFocus(max);
}
else {
changePseudoFocus(anySelected.i - 1);
}
}
if (dir === 'DOWN') {
if (anySelected.i === max) {
changePseudoFocus(0);
}
else {
changePseudoFocus(anySelected.i + 1);
}
}
}
else {
if (dir === 'UP') {
changePseudoFocus(max);
}
if (dir === 'DOWN') {
changePseudoFocus(0);
}
}
}
};
var handleKeyDown = function (event) {
// down
if (event.keyCode === 40) {
switchFocus('DOWN');
}
// up
if (event.keyCode === 38) {
switchFocus('UP');
}
if (event.keyCode === 13) {
selectAndCloseMenu();
}
// end
if (event.keyCode === 35) {
var length_1 = moddedOptions.length;
if (length_1) {
changePseudoFocus(length_1 - 1);
}
}
// home
if (event.keyCode === 36) {
var length_2 = moddedOptions.length;
if (length_2)
changePseudoFocus(0);
}
// escape
if (event.keyCode === 27) {
onClearOptionsFunction();
}
};
var handleOnChange = function (event) {
event.preventDefault();
onChangeFunction(event.target.value);
};
var currentFocus = moddedOptions.find(function (x) { return x.selected; });
React.useEffect(function () {
if (options.length > 0)
setOpen(true);
}, [options.length]);
React.useEffect(function () {
if (value.length === 0)
setOpen(false);
}, [value]);
return (React__default.createElement("div", { "data-testid": "AutoComplete", className: index({
'rrui-autocomplete': true,
}), id: "ex1" },
React__default.createElement("label", { "data-testid": "AutoCompleteLabel", htmlFor: "ex1-input", id: labelId, className: "rrui-autocomplete__label" }, labelText),
React__default.createElement("div", { className: "rrui-autocomplete__wrapper" },
React__default.createElement("div", {
// eslint-disable-next-line jsx-a11y/role-has-required-aria-props
role: "combobox", "aria-expanded": open ? 'true' : 'false', "aria-owns": "ex1-listbox", "aria-haspopup": "listbox", id: "ex1-combobox" },
React__default.createElement("input", { onBlur: function (event) {
event.preventDefault();
if (!mouseIn) {
setOpen(false);
}
}, onFocus: function (event) {
event.preventDefault();
setOpen(true);
}, "data-testid": "AutoCompleteInput", ref: ref, value: value, type: "text", "aria-autocomplete": "list", "aria-controls": "ex1-listbox", id: "ex1-input", "aria-activedescendant": currentFocus ? currentFocus.id : null, onChange: handleOnChange, onKeyDown: handleKeyDown })),
React__default.createElement("ul", { "aria-labelledby": labelId, role: "listbox", id: "ex1-listbox", className: index({
'rrui-autocomplete__listbox': true,
'rrui-autocomplete__listbox--show': open,
}), "data-testid": "AutoCompleteListBox" }, moddedOptions.map(function (item, i) { return (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
React__default.createElement("li", { "data-testid": "AutoCompleteResult", onMouseEnter: function (event) {
event.preventDefault();
setMouseIn(true);
changePseudoFocus(i);
}, onMouseLeave: function (event) {
event.preventDefault();
setMouseIn(false);
}, onClick: function (event) {
event.preventDefault();
selectAndCloseMenu();
}, key: item.id, className: index({
'rrui-autocomplete__result': true,
'rrui-autocomplete__result--selected': item.id === (currentFocus === null || currentFocus === void 0 ? void 0 : currentFocus.id),
}), role: "option", id: item.id, "aria-selected": item.id === (currentFocus === null || currentFocus === void 0 ? void 0 : currentFocus.id) }, item.option)); })))));
};
module.exports = AutoComplete;
//# sourceMappingURL=AutoComplete.js.map