Skip to content

Commit

Permalink
Remove searchfield ref, add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kyledurand committed Mar 20, 2024
1 parent 31fc7ff commit 5a76c2f
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 38 deletions.
22 changes: 11 additions & 11 deletions polaris-react/playground/DetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
TopBar,
FooterHelp,
Link,
Picker,
AlphaPicker,
} from '../src';
import type {DropZoneProps, PageProps} from '../src';

Expand Down Expand Up @@ -695,21 +695,21 @@ export function DetailsPage() {
value={selected}
/>
<br />
<Picker
activator={{label: 'Vendor'}}
<AlphaPicker
searchField={{
label: 'Search vendors',
placeholder: 'Search vendors',
autoComplete: 'off',
}}
activator={{
label: 'Tags',
placeholder: 'Search tags',
}}
options={[
{
value: 'Burberry',
children: 'Burberry',
},
{
value: 'Gucci',
children: 'Gucci',
},
{
value: 'Prada',
children: 'Prada',
},
]}
/>
</LegacyCard.Section>
Expand Down
12 changes: 7 additions & 5 deletions polaris-react/playground/Playground.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from 'react';
import {PlusCircleIcon} from '@shopify/polaris-icons';

import {BlockStack, Card, Layout, Page, Picker, Text} from '../src';
import {BlockStack, Card, Layout, Page, AlphaPicker, Text} from '../src';

export function Playground() {
const [selected, setSelected] = React.useState('');
const [query, setQuery] = React.useState('');
const options = [
{
value: '012345678',
Expand Down Expand Up @@ -51,12 +52,13 @@ export function Playground() {
<Card>
<BlockStack gap="200">
<Text as="h3">Organization</Text>
<Picker
<AlphaPicker
searchField={{
label: 'Search for a product',
value: query,
placeholder: 'Search for a product',
autoComplete: 'off',
onChange: (value) => console.log(value),
onChange: (value: string) => setQuery(value),
}}
activator={{
label: 'Product',
Expand All @@ -65,8 +67,8 @@ export function Playground() {
options={options}
onSelect={setSelected}
addAction={{
value: 'addy',
children: 'Add product',
value: query,
children: `Add ${query}`,
icon: PlusCircleIcon,
}}
/>
Expand Down
16 changes: 8 additions & 8 deletions polaris-react/src/components/Picker/Picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {Listbox} from '../Listbox';
import type {IconProps} from '../Icon';
import {Icon} from '../Icon';

import {Activator, TextField} from './components';
import {Activator, SearchField} from './components';
import type {ActivatorProps} from './components';

export interface PickerProps extends Omit<ListboxProps, 'children'> {
Expand Down Expand Up @@ -71,7 +71,7 @@ export function Picker({
);
const [popoverActive, setPopoverActive] = useState(false);
const [activeOptionId, setActiveOptionId] = useState<string>();
const [active, setActive] = useState<string>();
const [activeItem, setActiveItem] = useState<string>();
const [textFieldLabelId, setTextFieldLabelId] = useState<string>();
const [listboxId, setListboxId] = useState<string>();
const [textFieldFocused, setTextFieldFocused] = useState<boolean>(false);
Expand All @@ -88,7 +88,7 @@ export function Picker({
}, []);

const handleSelect = useCallback((selected: string) => {
setActive(selected);
setActiveItem(selected);
}, []);

const onOptionSelected = useCallback(() => {
Expand Down Expand Up @@ -189,7 +189,7 @@ export function Picker({
);

const firstSelectedOption = reactChildrenText(
options.find((option) => option.value === active)?.children,
options.find((option) => option.value === activeItem)?.children,
);
const firstSelectedLabel = firstSelectedOption
? firstSelectedOption?.toString()
Expand Down Expand Up @@ -227,7 +227,7 @@ export function Picker({
borderColor="border"
>
<ComboboxTextFieldContext.Provider value={textFieldContextValue}>
<TextField
<SearchField
{...searchField}
value={query}
onChange={(value) => {
Expand All @@ -236,6 +236,8 @@ export function Picker({
}}
prefix={<Icon source={SearchIcon} />}
labelHidden
focused
autoFocus
/>
</ComboboxTextFieldContext.Provider>
</Box>
Expand All @@ -257,7 +259,7 @@ export function Picker({
{filteredOptions?.map((option) => (
<Listbox.Option
key={option.value}
selected={option.value === active}
selected={option.value === activeItem}
{...option}
/>
))}
Expand All @@ -280,5 +282,3 @@ const reactChildrenText = (children: React.ReactNode): string => {
? reactChildrenText(children?.props?.children)
: '';
};

Picker.TextField = TextField;
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export function Activator({
return (
<UnstyledButton
className={classNames(styles.Activator, disabled && styles.disabled)}
disabled={disabled}
onClick={onClick}
>
<BlockStack as="span" gap="100">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import {mountWithApp} from 'tests/utilities';

import {Activator} from '../Activator';
import {UnstyledButton} from '../../../../UnstyledButton';

describe('<Activator />', () => {
it('renders a label', () => {
const activator = mountWithApp(<Activator label="label" />);

expect(activator).toContainReactText('label');
});

it('renders a placeholder', () => {
const activator = mountWithApp(<Activator placeholder="placeholder" />);

expect(activator).toContainReactText('placeholder');
});

it('renders a disabled activator', () => {
const activator = mountWithApp(<Activator disabled />);

expect(activator).toContainReactComponent(UnstyledButton, {disabled: true});
});
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.TextField {
.SearchField {
flex-grow: 1;
padding: var(--p-space-100) 0;
outline: none;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React, {useMemo, useId, useCallback, useEffect, useRef} from 'react';
import React, {useMemo, useId, useCallback, useEffect} from 'react';

import {Label, labelID} from '../../../Label';
import type {TextFieldProps} from '../../../TextField';
import {useComboboxTextField} from '../../../../utilities/combobox';
import {InlineStack} from '../../../InlineStack';

import styles from './TextField.module.css';
import styles from './SearchField.module.css';

export function TextField({
export function SearchField({
value,
id: idProp,
type = 'text',
Expand All @@ -18,8 +18,9 @@ export function TextField({
labelHidden,
prefix,
placeholder,
focused,
autoFocus,
}: TextFieldProps) {
const inputRef = useRef<HTMLInputElement>(null);
const comboboxTextFieldContext = useComboboxTextField();

const {
Expand Down Expand Up @@ -70,8 +71,6 @@ export function TextField({
[onChange, onTextFieldChange],
);

if (inputRef.current) inputRef.current.focus();

return (
<>
<Label id={textFieldId} hidden={labelHidden}>
Expand All @@ -80,8 +79,7 @@ export function TextField({
<InlineStack gap="100" blockAlign="center">
<span>{prefix}</span>
<input
className={styles.TextField}
ref={inputRef}
className={styles.SearchField}
value={value}
id={textFieldId}
type={type}
Expand All @@ -94,6 +92,7 @@ export function TextField({
aria-controls={listboxId}
onFocus={handleFocus}
onBlur={handleBlur}
autoFocus={focused ?? autoFocus}
onChange={({target}) => handleChange(target.value, textFieldId)}
/>
</InlineStack>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {SearchField} from './SearchField';
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import React from 'react';
import {mountWithApp} from 'tests/utilities';

import {SearchField} from '../SearchField';
import {Label} from '../../../../Label';
import type {ComboboxTextFieldType} from '../../../../../utilities/combobox';
import {ComboboxTextFieldContext} from '../../../../../utilities/combobox';
import type {TextFieldProps} from '../../../../TextField';

function mountWithProvider(
props: {
textFieldProps?: Partial<TextFieldProps>;
textFieldProviderValue?: Partial<ComboboxTextFieldType>;
} = {},
) {
const textField = mountWithApp(
<ComboboxTextFieldContext.Provider
value={{...props.textFieldProviderValue}}
>
<SearchField
label="label"
onChange={noop}
autoComplete="off"
{...props.textFieldProps}
/>
</ComboboxTextFieldContext.Provider>,
);

return textField;
}

describe('<TextField />', () => {
it('renders a label', () => {
const picker = mountWithProvider({
textFieldProps: {
label: 'Field',
},
});

expect(picker).toContainReactComponent(Label, {children: 'Field'});
});

it('renders a prefix', () => {
const picker = mountWithProvider({
textFieldProps: {
prefix: <div>Prefix</div>,
},
});

expect(picker).toContainReactComponent('div', {children: 'Prefix'});
});

it('renders accessibility attributes', () => {
const picker = mountWithProvider({
textFieldProviderValue: {
activeOptionId: 'option1',
listboxId: 'listbox1',
setTextFieldLabelId: () => 'TextFieldLabel',
},
});

expect(picker).toContainReactComponent('input', {
role: 'combobox',
'aria-activedescendant': 'option1',
'aria-haspopup': 'listbox',
'aria-autocomplete': 'list',
'aria-expanded': 'true',
'aria-controls': 'listbox1',
});
});
});

function noop() {}

This file was deleted.

2 changes: 1 addition & 1 deletion polaris-react/src/components/Picker/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export {TextField} from './TextField';
export {SearchField} from './SearchField';
export * from './Activator';
1 change: 0 additions & 1 deletion polaris-react/src/components/Picker/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './Picker';
export {TextField as PickerTextField} from './components';
Loading

0 comments on commit 5a76c2f

Please sign in to comment.