From a492b32bd389d49400b342abf1d4ef98115c6150 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Wed, 30 Aug 2023 07:26:35 -0700 Subject: [PATCH] Extract PowerSearchTermFinder Summary: Project doc: https://docs.google.com/document/d/1miofxds9DJgWScj0zFyBbdpRH5Rj0T9FqiCapof5-vU Reviewed By: lblasa Differential Revision: D48599226 fbshipit-source-id: 29c5a8182312e5f8c09d78d5cc223ef65cfc841d --- .../ui/PowerSearch/PowerSearchTermFinder.tsx | 68 +++++++++++++++++++ .../src/ui/PowerSearch/index.tsx | 47 ++++--------- 2 files changed, 80 insertions(+), 35 deletions(-) create mode 100644 desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx diff --git a/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx b/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx new file mode 100644 index 000000000..2afacb233 --- /dev/null +++ b/desktop/flipper-plugin/src/ui/PowerSearch/PowerSearchTermFinder.tsx @@ -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 ( + + 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); + } + }} + /> + ); +}); diff --git a/desktop/flipper-plugin/src/ui/PowerSearch/index.tsx b/desktop/flipper-plugin/src/ui/PowerSearch/index.tsx index 815ff3072..961db2a7b 100644 --- a/desktop/flipper-plugin/src/ui/PowerSearch/index.tsx +++ b/desktop/flipper-plugin/src/ui/PowerSearch/index.tsx @@ -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 = ({config}) => { @@ -33,18 +31,18 @@ export const PowerSearch: React.FC = ({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 = ({config}) => { blur: () => void; scrollTo: () => void; }>(null); - const [searchTermFinderValue, setSearchTermFinderValue] = React.useState< - string | null - >(null); return ( @@ -108,12 +103,10 @@ export const PowerSearch: React.FC = ({config}) => { ); })} - + { + 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 = ({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); - } }} />