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:
committed by
Facebook GitHub Bot
parent
c9ab951e84
commit
a492b32bd3
@@ -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);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -8,10 +8,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {AutoComplete, Space} from 'antd';
|
import {Space} from 'antd';
|
||||||
import {PowerSearchConfig} from './PowerSearchConfig';
|
import {PowerSearchConfig} from './PowerSearchConfig';
|
||||||
import {PowerSearchContainer} from './PowerSearchContainer';
|
import {PowerSearchContainer} from './PowerSearchContainer';
|
||||||
import {PowerSearchTerm, SearchExpressionTerm} from './PowerSearchTerm';
|
import {PowerSearchTerm, SearchExpressionTerm} from './PowerSearchTerm';
|
||||||
|
import {
|
||||||
|
PowerSearchTermFinder,
|
||||||
|
PowerSearchTermFinderOption,
|
||||||
|
PowerSearchTermFinderOptionGroup,
|
||||||
|
} from './PowerSearchTermFinder';
|
||||||
|
|
||||||
export {PowerSearchConfig};
|
export {PowerSearchConfig};
|
||||||
|
|
||||||
@@ -19,13 +24,6 @@ type PowerSearchProps = {
|
|||||||
config: PowerSearchConfig;
|
config: PowerSearchConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
type AutocompleteOption = {label: string; value: string};
|
|
||||||
type AutocompleteOptionGroup = {
|
|
||||||
label: string;
|
|
||||||
options: AutocompleteOption[];
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const OPTION_KEY_DELIMITER = '::';
|
const OPTION_KEY_DELIMITER = '::';
|
||||||
|
|
||||||
export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
||||||
@@ -33,18 +31,18 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
|||||||
SearchExpressionTerm[]
|
SearchExpressionTerm[]
|
||||||
>([]);
|
>([]);
|
||||||
|
|
||||||
const options: AutocompleteOptionGroup[] = React.useMemo(() => {
|
const options: PowerSearchTermFinderOptionGroup[] = React.useMemo(() => {
|
||||||
const groupedOptions: AutocompleteOptionGroup[] = [];
|
const groupedOptions: PowerSearchTermFinderOptionGroup[] = [];
|
||||||
|
|
||||||
for (const field of Object.values(config.fields)) {
|
for (const field of Object.values(config.fields)) {
|
||||||
const group: AutocompleteOptionGroup = {
|
const group: PowerSearchTermFinderOptionGroup = {
|
||||||
label: field.label,
|
label: field.label,
|
||||||
options: [],
|
options: [],
|
||||||
value: field.key,
|
value: field.key,
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const operator of Object.values(field.operators)) {
|
for (const operator of Object.values(field.operators)) {
|
||||||
const option: AutocompleteOption = {
|
const option: PowerSearchTermFinderOption = {
|
||||||
label: `${field.label} ${operator.label}`,
|
label: `${field.label} ${operator.label}`,
|
||||||
value: `${field.key}${OPTION_KEY_DELIMITER}${operator.key}`,
|
value: `${field.key}${OPTION_KEY_DELIMITER}${operator.key}`,
|
||||||
};
|
};
|
||||||
@@ -67,9 +65,6 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
|||||||
blur: () => void;
|
blur: () => void;
|
||||||
scrollTo: () => void;
|
scrollTo: () => void;
|
||||||
}>(null);
|
}>(null);
|
||||||
const [searchTermFinderValue, setSearchTermFinderValue] = React.useState<
|
|
||||||
string | null
|
|
||||||
>(null);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PowerSearchContainer>
|
<PowerSearchContainer>
|
||||||
@@ -108,12 +103,10 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
|||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Space>
|
</Space>
|
||||||
<AutoComplete<string, AutocompleteOption>
|
<PowerSearchTermFinder
|
||||||
ref={searchTermFinderRef}
|
ref={searchTermFinderRef}
|
||||||
style={{flex: '1'}}
|
|
||||||
options={options}
|
options={options}
|
||||||
bordered={false}
|
onSelect={(selectedOption) => {
|
||||||
onSelect={(_: string, selectedOption: AutocompleteOption) => {
|
|
||||||
const [fieldKey, operatorKey] =
|
const [fieldKey, operatorKey] =
|
||||||
selectedOption.value.split(OPTION_KEY_DELIMITER);
|
selectedOption.value.split(OPTION_KEY_DELIMITER);
|
||||||
const fieldConfig = config.fields[fieldKey];
|
const fieldConfig = config.fields[fieldKey];
|
||||||
@@ -126,22 +119,6 @@ export const PowerSearch: React.FC<PowerSearchProps> = ({config}) => {
|
|||||||
operator: operatorConfig,
|
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>
|
</PowerSearchContainer>
|
||||||
|
|||||||
Reference in New Issue
Block a user