UNPKG

@momentum-ui/react-collaboration

Version:

Cisco Momentum UI Framework for React Collaboration Applications

98 lines 5.59 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; /* eslint-disable jsx-a11y/no-static-element-interactions */ /* eslint-disable jsx-a11y/click-events-have-key-events */ import React, { useRef, useState, useEffect } from 'react'; import classnames from 'classnames'; import ButtonSimple from '../ButtonSimple'; import { STYLE } from './GlobalSearchInput.constants'; import './GlobalSearchInput.style.scss'; import { useSearchField } from '@react-aria/searchfield'; import { useSearchFieldState } from '@react-stately/searchfield'; import { difference } from 'lodash'; import Icon from '../Icon'; import { useFocusState } from '../../hooks/useFocusState'; import LoadingSpinner from '../LoadingSpinner'; /** * Global search input. Used for global search only */ var GlobalSearchInput = function (props) { var _a = props.initialLabel, initialLabel = _a === void 0 ? '' : _a, className = props.className, id = props.id, style = props.style, searching = props.searching, onKeyDown = props.onKeyDown, onFiltersChange = props.onFiltersChange, _b = props.filters, filters = _b === void 0 ? [] : _b, clearButtonAriaLabel = props.clearButtonAriaLabel, onClear = props.onClear; var _c = useState(filters), previousFilters = _c[0], setPreviousFilters = _c[1]; var _d = useFocusState(props), isFocused = _d.isFocused, focusProps = _d.focusProps; var _e = useState(''), ariaAlert = _e[0], setAriaAlert = _e[1]; var state = useSearchFieldState(props); var ref = useRef(null); useEffect(function () { var newFilters = difference(filters, previousFilters); if (newFilters.length) { setAriaAlert(newFilters[0].translations.filterAdded); } setPreviousFilters(filters); // eslint-disable-next-line react-hooks/exhaustive-deps }, [JSON.stringify(filters)]); var onClearPress = function () { onFiltersChange([]); onClear(); }; var _f = useSearchField(__assign(__assign({}, props), { placeholder: filters.length ? '' : props.placeholder, onClear: onClearPress }), state, ref), inputProps = _f.inputProps, clearButtonProps = _f.clearButtonProps, labelProps = _f.labelProps; // react aria useSearchField is setting excludeFromTabOrder to true // check https://github.com/adobe/react-spectrum/blob/02f242f41f0347b3f11e50b019c197127b7d0a08/packages/%40react-aria/searchfield/src/useSearchField.ts#L118 // but clear button should be focusable, so we overwrite clearButtonProps.excludeFromTabOrder = false to false clearButtonProps.excludeFromTabOrder = false; var handleClick = function () { if (ref.current) { ref.current.focus(); } }; var handleKeyDown = function (e) { var key = e.key; var target = e.target; if (key === 'Backspace') { if (!(target.selectionStart === 0 && target.selectionEnd === 0)) { return; } var filterToRemove = filters[filters.length - 1]; onFiltersChange && filters.length && onFiltersChange(filters.slice(0, filters.length - 1)); filterToRemove && setAriaAlert(filterToRemove.translations.filterRemoved); } else { if (onKeyDown) { onKeyDown(e); } inputProps.onKeyDown(e); } }; var buildFilters = function () { var filterArray = []; var labels = []; filters.forEach(function (filter) { labels.push(filter.value ? filter.translations.nonempty : filter.translations.empty); filterArray.push(React.createElement("div", { key: filter.term, className: STYLE.searchContext }, React.createElement("p", null, filter.translations.text))); }); var label = labels.length ? "".concat(labels.join(', '), ":") : initialLabel; return { filterArray: filterArray, label: label }; }; var _g = buildFilters(), label = _g.label, filterArray = _g.filterArray; return (React.createElement("div", { className: classnames(className, STYLE.wrapper), id: id, onClick: handleClick, style: style, "data-focus": isFocused }, React.createElement("label", __assign({ htmlFor: inputProps.id }, labelProps), label), React.createElement("div", null, searching ? (React.createElement(LoadingSpinner, { className: STYLE.search, variant: "button", scale: 18, "aria-hidden": true })) : (React.createElement(Icon, { weight: "bold", scale: 18, className: STYLE.search, fillColor: "var(--mds-color-theme-text-primary-normal)", name: "search" }))), React.createElement("div", { className: STYLE.container }, filterArray, React.createElement("input", __assign({}, inputProps, focusProps, { ref: ref, onKeyDown: handleKeyDown })), ariaAlert && (React.createElement("div", { className: "aria-alert", "aria-live": "assertive", role: "alert" }, ariaAlert))), (!!state.value || !!filters.length) && (React.createElement(ButtonSimple, __assign({ className: STYLE.clear }, clearButtonProps, { "aria-label": clearButtonAriaLabel }), React.createElement(Icon, { scale: 18, name: "cancel" }))))); }; export default GlobalSearchInput; //# sourceMappingURL=GlobalSearchInput.js.map