From 7fd7213ebeb848299a438c14742df729831de154 Mon Sep 17 00:00:00 2001 From: Kyle Durand Date: Fri, 15 Mar 2024 22:51:33 -0400 Subject: [PATCH] add addAction --- polaris-react/playground/Playground.tsx | 1 + polaris-react/src/components/Picker/Picker.tsx | 18 ++++++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/polaris-react/playground/Playground.tsx b/polaris-react/playground/Playground.tsx index 610d088be60..4ab7562a096 100644 --- a/polaris-react/playground/Playground.tsx +++ b/polaris-react/playground/Playground.tsx @@ -58,6 +58,7 @@ export function Playground() { activator={{label: 'Product', placeholder: 'Select a product'}} options={options} onSelect={(selected) => console.log(selected)} + addAction={{value: 'add', children: 'Add product'}} /> diff --git a/polaris-react/src/components/Picker/Picker.tsx b/polaris-react/src/components/Picker/Picker.tsx index 78dcac7f629..3ab15b98c1d 100644 --- a/polaris-react/src/components/Picker/Picker.tsx +++ b/polaris-react/src/components/Picker/Picker.tsx @@ -37,6 +37,8 @@ export interface PickerProps extends Omit { allowMultiple?: boolean; /** The options to be listed within the picker */ options?: OptionProps[]; + /** Used to add a new picker option that isn't listed */ + addAction?: OptionProps; /** Whether or not more options are available to lazy load when the bottom of the listbox reached. Use the hasMoreResults boolean provided by the GraphQL API of the paginated data. */ willLoadMoreOptions?: boolean; /** Height to set on the Popover Pane. */ @@ -47,6 +49,11 @@ export interface PickerProps extends Omit { onClose?(): void; } +const filterRegex = (value: string) => new RegExp(value, 'i'); + +// regex match string exact upper or lower case +const filterRegexExact = (value: string) => new RegExp(`^${value}$`, 'i'); + export function Picker({ activator, allowMultiple, @@ -54,6 +61,7 @@ export function Picker({ options = [], willLoadMoreOptions, height, + addAction, onScrolledToBottom, onClose, ...listboxProps @@ -173,9 +181,8 @@ export function Picker({ return; } - const filterRegex = new RegExp(value, 'i'); const resultOptions = options?.filter((option) => - reactChildrenText(option.children)?.match(filterRegex), + filterRegex(value).exec(reactChildrenText(option.children)), ); setFilteredOptions(resultOptions ?? []); }, @@ -189,6 +196,10 @@ export function Picker({ ? firstSelectedOption?.toString() : activator.placeholder; + const queryMatchesExistingOption = options.some((option) => + filterRegexExact(query).exec(reactChildrenText(option.children)), + ); + return ( ))} + {addAction && query !== '' && !queryMatchesExistingOption ? ( + + ) : null}