Extract PowerSearchTermFinder

Summary: Project doc: https://docs.google.com/document/d/1miofxds9DJgWScj0zFyBbdpRH5Rj0T9FqiCapof5-vU

Reviewed By: lblasa

Differential Revision: D48599226

fbshipit-source-id: 29c5a8182312e5f8c09d78d5cc223ef65cfc841d
This commit is contained in:
Andrey Goncharov
2023-08-30 07:26:35 -07:00
committed by Facebook GitHub Bot
parent c9ab951e84
commit a492b32bd3
2 changed files with 80 additions and 35 deletions

View File

@@ -0,0 +1,68 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {AutoComplete} from 'antd';
import * as React from 'react';
export type PowerSearchTermFinderOption = {label: string; value: string};
export type PowerSearchTermFinderOptionGroup = {
label: string;
options: PowerSearchTermFinderOption[];
value: string;
};
export type PowerSearchTermFinderRef = {
focus: () => void;
blur: () => void;
};
type PowerSearchTermFinderProps = {
options: PowerSearchTermFinderOptionGroup[];
onSelect: (selectedOption: PowerSearchTermFinderOption) => void;
};
export const PowerSearchTermFinder = React.forwardRef<
PowerSearchTermFinderRef,
PowerSearchTermFinderProps
>(({options, onSelect}, ref) => {
const [searchTermFinderValue, setSearchTermFinderValue] = React.useState<
string | null
>(null);
return (
<AutoComplete<string, PowerSearchTermFinderOption>
ref={
ref as React.Ref<{
focus: () => void;
blur: () => void;
scrollTo: () => void;
}>
}
style={{flex: '1'}}
options={options}
bordered={false}
onSelect={(_: string, selectedOption: PowerSearchTermFinderOption) => {
onSelect(selectedOption);
setSearchTermFinderValue(null);
}}
filterOption={(inputValue, option) => {
return !!option?.label.toLowerCase().includes(inputValue.toLowerCase());
}}
value={searchTermFinderValue}
onChange={setSearchTermFinderValue}
onBlur={() => {
setSearchTermFinderValue(null);
}}
onInputKeyDown={(event) => {
if (event.key === 'Enter') {
setSearchTermFinderValue(null);
}
}}
/>
);
});

View File

@@ -8,10 +8,15 @@
*/
import * as React from 'react';
import {AutoComplete, Space} from 'antd';
import {Space} from 'antd';
import {PowerSearchConfig} from './PowerSearchConfig';
import {PowerSearchContainer} from './PowerSearchContainer';
import {PowerSearchTerm, SearchExpressionTerm} from './PowerSearchTerm';
import {
PowerSearchTermFinder,
PowerSearchTermFinderOption,
PowerSearchTermFinderOptionGroup,
} from './PowerSearchTermFinder';
export {PowerSearchConfig};
@@ -19,13 +24,6 @@ type PowerSearchProps = {
config: PowerSearchConfig;
};
type AutocompleteOption = {label: string; value: string};
type AutocompleteOptionGroup = {
label: string;
options: AutocompleteOption[];
value: string;
};
const OPTION_KEY_DELIMITER = '::';
export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
@@ -33,18 +31,18 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
SearchExpressionTerm[]
>([]);
const options: AutocompleteOptionGroup[] = React.useMemo(() => {
const groupedOptions: AutocompleteOptionGroup[] = [];
const options: PowerSearchTermFinderOptionGroup[] = React.useMemo(() => {
const groupedOptions: PowerSearchTermFinderOptionGroup[] = [];
for (const field of Object.values(config.fields)) {
const group: AutocompleteOptionGroup = {
const group: PowerSearchTermFinderOptionGroup = {
label: field.label,
options: [],
value: field.key,
};
for (const operator of Object.values(field.operators)) {
const option: AutocompleteOption = {
const option: PowerSearchTermFinderOption = {
label: `${field.label} ${operator.label}`,
value: `${field.key}${OPTION_KEY_DELIMITER}${operator.key}`,
};
@@ -67,9 +65,6 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
blur: () => void;
scrollTo: () => void;
}>(null);
const [searchTermFinderValue, setSearchTermFinderValue] = React.useState<
string | null
>(null);
return (
<PowerSearchContainer>
@@ -108,12 +103,10 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
);
})}
</Space>
<AutoComplete<string, AutocompleteOption>
<PowerSearchTermFinder
ref={searchTermFinderRef}
style={{flex: '1'}}
options={options}
bordered={false}
onSelect={(_: string, selectedOption: AutocompleteOption) => {
onSelect={(selectedOption) => {
const [fieldKey, operatorKey] =
selectedOption.value.split(OPTION_KEY_DELIMITER);
const fieldConfig = config.fields[fieldKey];
@@ -126,22 +119,6 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
operator: operatorConfig,
},
]);
setSearchTermFinderValue(null);
}}
filterOption={(inputValue, option) => {
return !!option?.label
.toLowerCase()
.includes(inputValue.toLowerCase());
}}
value={searchTermFinderValue}
onChange={setSearchTermFinderValue}
onBlur={() => {
setSearchTermFinderValue(null);
}}
onInputKeyDown={(event) => {
if (event.key === 'Enter') {
setSearchTermFinderValue(null);
}
}}
/>
</PowerSearchContainer>