UNPKG

5.91 kBJavaScriptView Raw
1import * as React from 'react';
2import styles from '@patternfly/react-styles/css/components/SearchInput/search-input';
3import { Button } from '../Button';
4import { ActionGroup, Form, FormGroup } from '../Form';
5import { TextInput } from '../TextInput';
6import { GenerateId, KEY_CODES } from '../../helpers';
7export const AdvancedSearchMenu = ({ parentRef, parentInputRef, value = '', attributes = [], formAdditionalItems, hasWordsAttrLabel = 'Has words', advancedSearchDelimiter, getAttrValueMap, onChange, onSearch, onClear, resetButtonLabel = 'Reset', submitSearchButtonLabel = 'Search', isSearchMenuOpen, onToggleAdvancedMenu }) => {
8 const firstAttrRef = React.useRef(null);
9 const [putFocusBackOnInput, setPutFocusBackOnInput] = React.useState(false);
10 React.useEffect(() => {
11 if (attributes.length > 0 && !advancedSearchDelimiter) {
12 // eslint-disable-next-line no-console
13 console.error('AdvancedSearchMenu: An advancedSearchDelimiter prop is required when advanced search attributes are provided using the attributes prop');
14 }
15 });
16 React.useEffect(() => {
17 if (isSearchMenuOpen && firstAttrRef && firstAttrRef.current) {
18 firstAttrRef.current.focus();
19 setPutFocusBackOnInput(true);
20 }
21 else if (!isSearchMenuOpen && putFocusBackOnInput && parentInputRef && parentInputRef.current) {
22 parentInputRef.current.focus();
23 }
24 }, [isSearchMenuOpen]);
25 React.useEffect(() => {
26 document.addEventListener('mousedown', onDocClick);
27 document.addEventListener('touchstart', onDocClick);
28 document.addEventListener('keydown', onEscPress);
29 return function cleanup() {
30 document.removeEventListener('mousedown', onDocClick);
31 document.removeEventListener('touchstart', onDocClick);
32 document.removeEventListener('keydown', onEscPress);
33 };
34 });
35 const onDocClick = (event) => {
36 const clickedWithinSearchInput = parentRef && parentRef.current.contains(event.target);
37 if (isSearchMenuOpen && !clickedWithinSearchInput) {
38 onToggleAdvancedMenu(event);
39 }
40 };
41 const onEscPress = (event) => {
42 const keyCode = event.keyCode || event.which;
43 if (isSearchMenuOpen &&
44 keyCode === KEY_CODES.ESCAPE_KEY &&
45 parentRef &&
46 parentRef.current.contains(event.target)) {
47 onToggleAdvancedMenu(event);
48 if (parentInputRef) {
49 parentInputRef.current.focus();
50 }
51 }
52 };
53 const onSearchHandler = (event) => {
54 event.preventDefault();
55 if (onSearch) {
56 onSearch(value, event, getAttrValueMap());
57 }
58 if (isSearchMenuOpen) {
59 onToggleAdvancedMenu(event);
60 }
61 };
62 const handleValueChange = (attribute, newValue, event) => {
63 const newMap = getAttrValueMap();
64 newMap[attribute] = newValue;
65 let updatedValue = '';
66 Object.entries(newMap).forEach(([k, v]) => {
67 if (v.trim() !== '') {
68 if (k !== 'haswords') {
69 updatedValue = `${updatedValue} ${k}${advancedSearchDelimiter}${v}`;
70 }
71 else {
72 updatedValue = `${updatedValue} ${v}`;
73 }
74 }
75 });
76 updatedValue = updatedValue.replace(/^\s+/g, '');
77 if (onChange) {
78 onChange(updatedValue, event);
79 }
80 };
81 const getValue = (attribute) => {
82 const map = getAttrValueMap();
83 return map.hasOwnProperty(attribute) ? map[attribute] : '';
84 };
85 const buildFormGroups = () => {
86 const formGroups = [];
87 attributes.forEach((attribute, index) => {
88 const display = typeof attribute === 'string' ? attribute : attribute.display;
89 const queryAttr = typeof attribute === 'string' ? attribute : attribute.attr;
90 if (index === 0) {
91 formGroups.push(React.createElement(FormGroup, { label: display, fieldId: `${queryAttr}_${index}`, key: `${attribute}_${index}` },
92 React.createElement(TextInput, { ref: firstAttrRef, type: "text", id: `${queryAttr}_${index}`, value: getValue(queryAttr), onChange: (value, evt) => handleValueChange(queryAttr, value, evt) })));
93 }
94 else {
95 formGroups.push(React.createElement(FormGroup, { label: display, fieldId: `${queryAttr}_${index}`, key: `${attribute}_${index}` },
96 React.createElement(TextInput, { type: "text", id: `${queryAttr}_${index}`, value: getValue(queryAttr), onChange: (value, evt) => handleValueChange(queryAttr, value, evt) })));
97 }
98 });
99 formGroups.push(React.createElement(GenerateId, { key: 'hasWords' }, randomId => (React.createElement(FormGroup, { label: hasWordsAttrLabel, fieldId: randomId },
100 React.createElement(TextInput, { type: "text", id: randomId, value: getValue('haswords'), onChange: (value, evt) => handleValueChange('haswords', value, evt) })))));
101 return formGroups;
102 };
103 return isSearchMenuOpen ? (React.createElement("div", { className: styles.searchInputMenu },
104 React.createElement("div", { className: styles.searchInputMenuBody },
105 React.createElement(Form, null,
106 buildFormGroups(),
107 formAdditionalItems ? formAdditionalItems : null,
108 React.createElement(ActionGroup, null,
109 React.createElement(Button, { variant: "primary", type: "submit", onClick: onSearchHandler }, submitSearchButtonLabel),
110 !!onClear && (React.createElement(Button, { variant: "link", type: "reset", onClick: onClear }, resetButtonLabel))))))) : null;
111};
112AdvancedSearchMenu.displayName = 'SearchInput';
113//# sourceMappingURL=AdvancedSearchMenu.js.map
\No newline at end of file