From d1c9a716bd6a80c48bedd64b76d6d9dc31f0c70f Mon Sep 17 00:00:00 2001 From: Kyle Durand Date: Wed, 27 Mar 2024 09:24:33 -0400 Subject: [PATCH] manage focus manually --- polaris-react/playground/DetailsPage.tsx | 22 +----- .../components/Combobox/Combobox.stories.tsx | 1 - .../src/components/Picker/Picker.tsx | 29 ++++---- .../Picker/components/Activator/Activator.tsx | 71 ++++++++++--------- .../Activator/tests/Activator.test.tsx | 3 +- .../components/SearchField/SearchField.tsx | 50 ++++++------- .../components/Picker/tests/Picker.test.tsx | 9 ++- 7 files changed, 85 insertions(+), 100 deletions(-) diff --git a/polaris-react/playground/DetailsPage.tsx b/polaris-react/playground/DetailsPage.tsx index 1b414f8b25d..409a2fba949 100644 --- a/polaris-react/playground/DetailsPage.tsx +++ b/polaris-react/playground/DetailsPage.tsx @@ -45,8 +45,6 @@ import { FooterHelp, Link, AlphaPicker, - Box, - Popover, } from '../src'; import type {DropZoneProps, PageProps} from '../src'; @@ -644,7 +642,6 @@ export function DetailsPage() { - -
setQuery(value), @@ -680,14 +670,6 @@ export function DetailsPage() { children: `Add ${query}`, }} /> - - click me} - onClose={() => {}} - > -

hello

-
diff --git a/polaris-react/src/components/Combobox/Combobox.stories.tsx b/polaris-react/src/components/Combobox/Combobox.stories.tsx index c46f7925624..4bbd0c0bb30 100644 --- a/polaris-react/src/components/Combobox/Combobox.stories.tsx +++ b/polaris-react/src/components/Combobox/Combobox.stories.tsx @@ -98,7 +98,6 @@ export function Default() { {optionsMarkup} ) : null} - ); } diff --git a/polaris-react/src/components/Picker/Picker.tsx b/polaris-react/src/components/Picker/Picker.tsx index ec79ec3bf82..8f6981af1fa 100644 --- a/polaris-react/src/components/Picker/Picker.tsx +++ b/polaris-react/src/components/Picker/Picker.tsx @@ -58,21 +58,23 @@ export function Picker({ onClose, ...listboxProps }: PickerProps) { - const [query, setQuery] = useState(''); - const [filteredOptions, setFilteredOptions] = useState( - options, - ); + const activatorRef = React.createRef(); + const [activeItem, setActiveItem] = useState(); const [popoverActive, setPopoverActive] = useState(false); const [activeOptionId, setActiveOptionId] = useState(); - const [activeItem, setActiveItem] = useState(); const [textFieldLabelId, setTextFieldLabelId] = useState(); const [listboxId, setListboxId] = useState(); - const shouldOpen = !popoverActive; + const [query, setQuery] = useState(''); + const [filteredOptions, setFilteredOptions] = useState( + options, + ); + const shouldOpen = !popoverActive; const handleClose = useCallback(() => { setPopoverActive(false); onClose?.(); - }, [onClose]); + activatorRef.current?.focus(); + }, [activatorRef, onClose]); const handleOpen = useCallback(() => { setPopoverActive(true); @@ -164,27 +166,26 @@ export function Picker({ options.find((option) => option.value === activeItem)?.children, ); - const firstSelectedLabel = firstSelectedOption - ? firstSelectedOption?.toString() - : activator.placeholder; - const queryMatchesExistingOption = options.some((option) => QUERY_REGEX(query).exec(reactChildrenText(option.children)), ); return ( } + active={popoverActive} autofocusTarget="none" - preferredPosition="cover" onClose={handleClose} + preferredPosition="cover" + preventFocusOnClose > {searchField ? ( diff --git a/polaris-react/src/components/Picker/components/Activator/Activator.tsx b/polaris-react/src/components/Picker/components/Activator/Activator.tsx index 3a29ab500ec..ecafab7cd83 100644 --- a/polaris-react/src/components/Picker/components/Activator/Activator.tsx +++ b/polaris-react/src/components/Picker/components/Activator/Activator.tsx @@ -1,49 +1,54 @@ import {SelectIcon} from '@shopify/polaris-icons'; -import React from 'react'; +import React, {forwardRef} from 'react'; import {BlockStack} from '../../../BlockStack'; import {Icon} from '../../../Icon'; import {Text} from '../../../Text'; -import {UnstyledButton} from '../../../UnstyledButton'; import {classNames} from '../../../../utilities/css'; import styles from './Activator.module.css'; export interface ActivatorProps { + disabled?: boolean; label?: string; placeholder?: string; - disabled?: boolean; + selected?: string; onClick?(): void; } -export function Activator({ - disabled, - label, - placeholder, - onClick, -}: ActivatorProps) { - return ( - - - {label && ( - - {label} - - )} +export const Activator = forwardRef( + ({disabled, label, placeholder, selected, onClick}, ref) => { + return ( + + ); + }, +); + +Activator.displayName = 'Activator'; diff --git a/polaris-react/src/components/Picker/components/Activator/tests/Activator.test.tsx b/polaris-react/src/components/Picker/components/Activator/tests/Activator.test.tsx index 4455e55f1e0..8da2160efea 100644 --- a/polaris-react/src/components/Picker/components/Activator/tests/Activator.test.tsx +++ b/polaris-react/src/components/Picker/components/Activator/tests/Activator.test.tsx @@ -2,7 +2,6 @@ import React from 'react'; import {mountWithApp} from 'tests/utilities'; import {Activator} from '../Activator'; -import {UnstyledButton} from '../../../../UnstyledButton'; describe('', () => { it('renders a label', () => { @@ -20,6 +19,6 @@ describe('', () => { it('renders a disabled activator', () => { const activator = mountWithApp(); - expect(activator).toContainReactComponent(UnstyledButton, {disabled: true}); + expect(activator).toContainReactComponent('button', {disabled: true}); }); }); diff --git a/polaris-react/src/components/Picker/components/SearchField/SearchField.tsx b/polaris-react/src/components/Picker/components/SearchField/SearchField.tsx index 4082a8fbdb4..e0b7ee4fe32 100644 --- a/polaris-react/src/components/Picker/components/SearchField/SearchField.tsx +++ b/polaris-react/src/components/Picker/components/SearchField/SearchField.tsx @@ -4,6 +4,7 @@ import {Label, labelID} from '../../../Label'; import type {TextFieldProps} from '../../../TextField'; import {useComboboxTextField} from '../../../../utilities/combobox'; import {InlineStack} from '../../../InlineStack'; +import {Text} from '../../../Text'; import styles from './SearchField.module.css'; @@ -15,7 +16,6 @@ export function SearchField({ onBlur, onChange, label, - labelHidden, prefix, placeholder, focused, @@ -76,30 +76,30 @@ export function SearchField({ } return ( - <> - - + + - + + handleChange(target.value, textFieldId)} + /> + ); } diff --git a/polaris-react/src/components/Picker/tests/Picker.test.tsx b/polaris-react/src/components/Picker/tests/Picker.test.tsx index a25e8671b79..21403990284 100644 --- a/polaris-react/src/components/Picker/tests/Picker.test.tsx +++ b/polaris-react/src/components/Picker/tests/Picker.test.tsx @@ -3,7 +3,6 @@ import {mountWithApp} from 'tests/utilities'; import {Picker} from '../Picker'; import {Activator, SearchField} from '../components'; -import {UnstyledButton} from '../../UnstyledButton'; import {Listbox} from '../../Listbox'; describe('', () => { @@ -26,7 +25,7 @@ describe('', () => { />, ); - picker.find(UnstyledButton)!.trigger('onClick'); + picker.find('button')!.trigger('onClick'); expect(picker).toContainReactComponent(SearchField); }); @@ -39,7 +38,7 @@ describe('', () => { const picker = mountWithApp(); - picker.find(UnstyledButton)!.trigger('onClick'); + picker.find('button')!.trigger('onClick'); expect(picker).toContainReactComponent(Listbox); expect(picker).toContainReactComponentTimes(Listbox.Option, options.length); @@ -56,7 +55,7 @@ describe('', () => { />, ); - picker.find(UnstyledButton)!.trigger('onClick'); + picker.find('button')!.trigger('onClick'); picker.find(SearchField)!.trigger('onChange', 'Add'); expect(picker).toContainReactComponent(Listbox.Action); @@ -76,7 +75,7 @@ describe('', () => { />, ); - picker.find(UnstyledButton)!.trigger('onClick'); + picker.find('button')!.trigger('onClick'); expect(picker).toContainReactComponentTimes(Listbox.Option, options.length); picker.find(SearchField)!.trigger('onChange', 'One');