diff --git a/UNRELEASED.md b/UNRELEASED.md index 2ff6214bf7f..2ec5de018c5 100644 --- a/UNRELEASED.md +++ b/UNRELEASED.md @@ -6,6 +6,7 @@ Use [the changelog guidelines](https://git.io/polaris-changelog-guidelines) to f - Updated `react` and `react-dom` to version 16.14.0. This is now the minimum version of React required to use the `@shopify/polaris` library. - Dropping support for node 10.x +- Made `autoComplete` prop in `TextField` a required string ([#4267](https://github.com/Shopify/polaris-react/pull/4267)). If you do not want the browser to autofill a user's information (for example an email input which is a customer's email, but not the email of the user who is entering the information), we recommend setting `autoComplete` to `"off"`. ### Enhancements diff --git a/examples/create-react-app-ts-react-testing/src/App.tsx b/examples/create-react-app-ts-react-testing/src/App.tsx index 3bdbb40f06a..b7a9e445fb6 100644 --- a/examples/create-react-app-ts-react-testing/src/App.tsx +++ b/examples/create-react-app-ts-react-testing/src/App.tsx @@ -99,12 +99,14 @@ export function App() { label="First name" placeholder="Tom" onChange={handleFirstChange} + autoComplete="given-name" /> @@ -113,6 +115,7 @@ export function App() { label="Email" placeholder="example@email.com" onChange={handleEmailChange} + autoComplete="email" /> @@ -106,6 +108,7 @@ export function App() { label="Email" placeholder="example@email.com" onChange={handleEmailChange} + autoComplete="email" /> { - setConnected(!connected); - }, - [connected], - ); + const toggleConnection = useCallback(() => { + setConnected(!connected); + }, [connected]); const breadcrumbs = [{content: 'Sample apps'}, {content: 'next.js'}]; const primaryAction = {content: 'New product'}; @@ -95,12 +92,14 @@ export default function App() { label="First name" placeholder="Tom" onChange={handleFirstChange} + autoComplete="given-name" /> @@ -109,6 +108,7 @@ export default function App() { label="Email" placeholder="example@email.com" onChange={handleEmailChange} + autoComplete="email" /> { - setConnected(!connected); - }, - [connected], - ); + const toggleConnection = useCallback(() => { + setConnected(!connected); + }, [connected]); const breadcrumbs = [{content: 'Sample apps'}, {content: 'webpack'}]; const primaryAction = {content: 'New product'}; @@ -95,12 +92,14 @@ export default function App() { label="First name" placeholder="Tom" onChange={handleFirstChange} + autoComplete="given-name" /> @@ -109,6 +108,7 @@ export default function App() { label="Email" placeholder="example@email.com" onChange={handleEmailChange} + autoComplete="email" /> setIsDirty(true)} + autoComplete="off" /> @@ -653,11 +655,13 @@ export function DetailsPage() { label="Subject" value={supportSubject} onChange={handleSubjectChange} + autoComplete="off" /> diff --git a/src/components/Autocomplete/components/ComboBox/tests/ComboBox.test.tsx b/src/components/Autocomplete/components/ComboBox/tests/ComboBox.test.tsx index dd7de0edffc..44e5be9514b 100644 --- a/src/components/Autocomplete/components/ComboBox/tests/ComboBox.test.tsx +++ b/src/components/Autocomplete/components/ComboBox/tests/ComboBox.test.tsx @@ -621,7 +621,7 @@ describe('', () => { function noop() {} function renderTextField() { - return ; + return ; } function renderNodeWithId() { diff --git a/src/components/Autocomplete/components/TextField/TextField.tsx b/src/components/Autocomplete/components/TextField/TextField.tsx index 5597c8b7988..880fe3513da 100644 --- a/src/components/Autocomplete/components/TextField/TextField.tsx +++ b/src/components/Autocomplete/components/TextField/TextField.tsx @@ -11,7 +11,7 @@ export function TextField(props: TextFieldProps) { ', () => { function noop() {} function renderTextField() { - return ; + return ( + + ); } function handleOnSelect(this: any, updatedSelection: string[]) { diff --git a/src/components/ChoiceList/README.md b/src/components/ChoiceList/README.md index e63693e2903..87b417f0cc2 100644 --- a/src/components/ChoiceList/README.md +++ b/src/components/ChoiceList/README.md @@ -322,6 +322,7 @@ function SingleOrMultiChoiceListWithChildrenContextExample() { labelHidden onChange={handleTextFieldChange} value={textFieldValue} + autoComplete="off" /> ), [handleTextFieldChange, textFieldValue], @@ -372,6 +373,7 @@ function SingleOrMultuChoiceListWithChildrenContextWhenSelectedExample() { labelHidden onChange={handleTextFieldChange} value={textFieldValue} + autoComplete="off" /> ), [handleTextFieldChange, textFieldValue], diff --git a/src/components/Filters/Filters.tsx b/src/components/Filters/Filters.tsx index ad65dab43d2..a9efe1bf107 100644 --- a/src/components/Filters/Filters.tsx +++ b/src/components/Filters/Filters.tsx @@ -287,6 +287,7 @@ class FiltersInner extends Component { clearButton onClearButtonClick={onQueryClear} disabled={disabled} + autoComplete="off" /> )} diff --git a/src/components/Filters/README.md b/src/components/Filters/README.md index e4880e96c7e..fcfb3d4d003 100644 --- a/src/components/Filters/README.md +++ b/src/components/Filters/README.md @@ -211,6 +211,7 @@ function ResourceListFiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -423,6 +424,7 @@ function DataTableFiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -555,6 +557,7 @@ function FiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -681,6 +684,7 @@ function DisableAllFiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -816,6 +820,7 @@ function DisableSomeFiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -829,6 +834,7 @@ function DisableSomeFiltersExample() { label="Vendor" value={vendor} onChange={handleVendorChange} + autoComplete="off" labelHidden /> ), @@ -960,6 +966,7 @@ function Playground() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -1131,6 +1138,7 @@ function ResourceListFiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -1331,6 +1339,7 @@ function ResourceListFiltersExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), diff --git a/src/components/Form/README.md b/src/components/Form/README.md index 15ba3eefef2..4faf1c6b79f 100644 --- a/src/components/Form/README.md +++ b/src/components/Form/README.md @@ -65,6 +65,7 @@ function FormOnSubmitExample() { onChange={handleEmailChange} label="Email" type="email" + autoComplete="email" helpText={ We’ll use this email address to inform you on future changes to @@ -100,6 +101,7 @@ function FormWithoutNativeValidationExample() { onChange={handleUrlChange} label="App URL" type="url" + autoComplete="off" /> diff --git a/src/components/FormLayout/README.md b/src/components/FormLayout/README.md index 0a56066ecd1..7e0870bf5c7 100644 --- a/src/components/FormLayout/README.md +++ b/src/components/FormLayout/README.md @@ -102,8 +102,13 @@ Use to stack form fields vertically, which makes them easier to scan and complet ```jsx - {}} /> - {}} /> + {}} autoComplete="off" /> + {}} + autoComplete="email" + /> ``` @@ -130,8 +135,18 @@ Field groups will wrap automatically on smaller screens. ```jsx - {}} /> - {}} /> + {}} + autoComplete="off" + /> + {}} + autoComplete="off" + /> ``` @@ -157,10 +172,10 @@ For very short inputs, the width of the inputs may be reduced in order to fit mo ```jsx - {}} /> - {}} /> - {}} /> - {}} /> + {}} autoComplete="off" /> + {}} autoComplete="off" /> + {}} autoComplete="off" /> + {}} autoComplete="off" /> ``` diff --git a/src/components/FormLayout/components/Group/tests/Group.test.tsx b/src/components/FormLayout/components/Group/tests/Group.test.tsx index ef592a2fbcc..dbe1e5cb3a7 100644 --- a/src/components/FormLayout/components/Group/tests/Group.test.tsx +++ b/src/components/FormLayout/components/Group/tests/Group.test.tsx @@ -12,7 +12,7 @@ describe('', () => { let item: any; beforeAll(() => { - children = ; + children = ; title = 'Title'; helpText = 'Help text'; item = mountWithAppProvider( diff --git a/src/components/FormLayout/components/Item/tests/Item.test.tsx b/src/components/FormLayout/components/Item/tests/Item.test.tsx index cb7d28448cc..895f980beb6 100644 --- a/src/components/FormLayout/components/Item/tests/Item.test.tsx +++ b/src/components/FormLayout/components/Item/tests/Item.test.tsx @@ -7,7 +7,9 @@ import {Item} from '../Item'; describe('', () => { it('renders its children', () => { - const children = ; + const children = ( + + ); const item = mountWithAppProvider({children}); expect(item.contains(children)).toBe(true); }); diff --git a/src/components/FormLayout/tests/FormLayout.test.tsx b/src/components/FormLayout/tests/FormLayout.test.tsx index 016dc0ca970..f79ce9a08c5 100644 --- a/src/components/FormLayout/tests/FormLayout.test.tsx +++ b/src/components/FormLayout/tests/FormLayout.test.tsx @@ -7,7 +7,9 @@ import {FormLayout} from '../FormLayout'; describe('', () => { it('renders its children', () => { - const children = ; + const children = ( + + ); const formLayout = mountWithAppProvider( {children}, ); diff --git a/src/components/Frame/README.md b/src/components/Frame/README.md index 2725d9c6c9c..bde4a651b9c 100644 --- a/src/components/Frame/README.md +++ b/src/components/Frame/README.md @@ -245,12 +245,14 @@ function FrameExample() { label="Full name" value={nameFieldValue} onChange={handleNameFieldChange} + autoComplete="name" /> @@ -292,11 +294,13 @@ function FrameExample() { label="Subject" value={supportSubject} onChange={handleSubjectChange} + autoComplete="off" /> @@ -579,12 +583,14 @@ function FrameExample() { label="Full name" value={nameFieldValue} onChange={handleNameFieldChange} + autoComplete="name" /> @@ -626,11 +632,13 @@ function FrameExample() { label="Subject" value={supportSubject} onChange={handleSubjectChange} + autoComplete="off" /> diff --git a/src/components/IndexTable/README.md b/src/components/IndexTable/README.md index 7c69e72bb47..46c3b1c75a0 100644 --- a/src/components/IndexTable/README.md +++ b/src/components/IndexTable/README.md @@ -603,6 +603,7 @@ function IndexTableWithFilteringExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -864,6 +865,7 @@ function IndexTableWithAllElementsExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -1049,6 +1051,7 @@ function SmallScreenIndexTableWithAllElementsExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), diff --git a/src/components/Layout/README.md b/src/components/Layout/README.md index af5a543b6a1..983d61cb9be 100644 --- a/src/components/Layout/README.md +++ b/src/components/Layout/README.md @@ -416,8 +416,13 @@ Use for settings pages. When settings are grouped thematically in annotated sect > - {}} /> - {}} /> + {}} autoComplete="off" /> + {}} + autoComplete="email" + /> @@ -441,8 +446,13 @@ Use for settings pages that need a banner or other content at the top. > - {}} /> - {}} /> + {}} autoComplete="off" /> + {}} + autoComplete="email" + /> diff --git a/src/components/Modal/README.md b/src/components/Modal/README.md index 35500d4c463..9bf36b32b41 100644 --- a/src/components/Modal/README.md +++ b/src/components/Modal/README.md @@ -369,6 +369,7 @@ function ModalWithPrimaryActionExample() { onFocus={handleFocus} value={DISCOUNT_LINK} onChange={() => {}} + autoComplete="off" connectedRight={ diff --git a/src/components/Popover/components/PopoverOverlay/tests/PopoverOverlay.test.tsx b/src/components/Popover/components/PopoverOverlay/tests/PopoverOverlay.test.tsx index 34255fe5b3e..917fd515381 100644 --- a/src/components/Popover/components/PopoverOverlay/tests/PopoverOverlay.test.tsx +++ b/src/components/Popover/components/PopoverOverlay/tests/PopoverOverlay.test.tsx @@ -236,7 +236,14 @@ describe('', () => { activator={activator} onClose={spy} > - ( {}} />) + ( + {}} + autoComplete="off" + /> + ) , ); @@ -267,6 +274,7 @@ describe('', () => { label="Store name" value="Click me" onChange={() => {}} + autoComplete="off" /> ) , diff --git a/src/components/RangeSlider/README.md b/src/components/RangeSlider/README.md index 07b4dc7efe6..a611bb2169f 100644 --- a/src/components/RangeSlider/README.md +++ b/src/components/RangeSlider/README.md @@ -352,6 +352,7 @@ function DualThumbRangeSliderExample() { step={step} onChange={handleLowerTextFieldChange} onBlur={handleLowerTextFieldBlur} + autoComplete="off" /> diff --git a/src/components/ResourceList/README.md b/src/components/ResourceList/README.md index 0dfbc97453e..4a8baa5eb01 100644 --- a/src/components/ResourceList/README.md +++ b/src/components/ResourceList/README.md @@ -595,6 +595,7 @@ function ResourceListWithFilteringExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -710,6 +711,7 @@ function ResourceListWithFilteringExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), @@ -1094,6 +1096,7 @@ function ResourceListExample() { label="Tagged with" value={taggedWith} onChange={handleTaggedWithChange} + autoComplete="off" labelHidden /> ), diff --git a/src/components/ResourceList/components/FilterControl/FilterControl.tsx b/src/components/ResourceList/components/FilterControl/FilterControl.tsx index e88283077ad..ed5d4808b15 100644 --- a/src/components/ResourceList/components/FilterControl/FilterControl.tsx +++ b/src/components/ResourceList/components/FilterControl/FilterControl.tsx @@ -159,6 +159,7 @@ export function FilterControl({ onBlur={onSearchBlur} focused={focused} disabled={selectMode} + autoComplete="off" /> {appliedFiltersWrapper} diff --git a/src/components/ResourceList/components/FilterControl/components/DateSelector/DateSelector.tsx b/src/components/ResourceList/components/FilterControl/components/DateSelector/DateSelector.tsx index df2a817bead..e4f99bf8dc3 100644 --- a/src/components/ResourceList/components/FilterControl/components/DateSelector/DateSelector.tsx +++ b/src/components/ResourceList/components/FilterControl/components/DateSelector/DateSelector.tsx @@ -202,7 +202,7 @@ export const DateSelector = memo(function DateSelector({ value={dateTextFieldValue} error={userInputDateError} prefix={} - autoComplete={false} + autoComplete="off" onChange={handleDateFieldChange} onBlur={handleDateBlur} /> diff --git a/src/components/ResourceList/components/FilterControl/components/FilterValueSelector/FilterValueSelector.tsx b/src/components/ResourceList/components/FilterControl/components/FilterValueSelector/FilterValueSelector.tsx index ef0c53bf5b0..e07e467b5d8 100644 --- a/src/components/ResourceList/components/FilterControl/components/FilterValueSelector/FilterValueSelector.tsx +++ b/src/components/ResourceList/components/FilterControl/components/FilterValueSelector/FilterValueSelector.tsx @@ -86,6 +86,7 @@ export function FilterValueSelector({ value={value} type={filter.textFieldType} onChange={onChange} + autoComplete="off" /> ); diff --git a/src/components/Select/README.md b/src/components/Select/README.md index 778f35b1e93..c2c8baa41c3 100644 --- a/src/components/Select/README.md +++ b/src/components/Select/README.md @@ -294,6 +294,7 @@ function SeparateValidationErrorExample() { value={weight} onChange={handleWeightChange} error={Boolean(!weight && unit)} + autoComplete="off" /> ); } @@ -400,6 +451,7 @@ function RightAlignExample() { labelHidden value={textFieldValue} onChange={handleTextFieldChange} + autoComplete="off" align="right" /> @@ -426,6 +478,7 @@ function PlaceholderExample() { value={textFieldValue} onChange={handleTextFieldChange} placeholder="Example: North America, Europe" + autoComplete="off" /> ); } @@ -465,6 +518,7 @@ function HelpTextExample() { value={textFieldValue} onChange={handleTextFieldChange} helpText="We’ll use this address if we need to contact you about your account." + autoComplete="email" /> ); } @@ -505,6 +559,7 @@ function PrefixExample() { value={textFieldValue} onChange={handleTextFieldChange} prefix="$" + autoComplete="off" /> ); } @@ -550,6 +605,7 @@ function ConnectedFieldsExample() { type="number" value={textFieldValue} onChange={handleTextFieldChange} + autoComplete="off" connectedLeft={ `onClick`', () => { const textField = mountWithApp( - , + , ); expect(document.activeElement).not.toBe(textField.find('input')!.domNode); @@ -1062,6 +1166,7 @@ describe('', () => { onChange={noop} type="text" value="test value" + autoComplete="off" clearButton />, ); @@ -1075,6 +1180,7 @@ describe('', () => { label="TextField" type="text" onChange={noop} + autoComplete="off" clearButton />, ); @@ -1094,6 +1200,7 @@ describe('', () => { onChange={noop} onClearButtonClick={spy} value="test value" + autoComplete="off" clearButton />, ); @@ -1109,6 +1216,7 @@ describe('', () => { onChange={noop} type="text" value="test value" + autoComplete="off" />, ); expect(findByTestID(textField, 'clearButton').exists()).toBeFalsy(); @@ -1121,6 +1229,7 @@ describe('', () => { onChange={noop} connectedLeft={
} connectedRight={
} + autoComplete="off" />, ); expect(textField).toContainReactComponent('div', { @@ -1132,7 +1241,12 @@ describe('', () => { describe('requiredIndicator', () => { it('passes requiredIndicator prop to Labelled', () => { const element = mountWithAppProvider( - , + , ); const labelled = element.find(Labelled); @@ -1143,14 +1257,24 @@ describe('', () => { describe('monospaced', () => { it('passes monospaced prop to TextField', () => { const element = mountWithAppProvider( - , + , ); expect(element.prop('monospaced')).toBe(true); }); it('applies the monospaced style', () => { const input = mountWithAppProvider( - , + , ).find('input'); expect(input.prop('className')).toContain('monospaced'); diff --git a/src/components/Tooltip/README.md b/src/components/Tooltip/README.md index e8b9cb81071..e91a2bc8490 100644 --- a/src/components/Tooltip/README.md +++ b/src/components/Tooltip/README.md @@ -94,7 +94,7 @@ Use when the tooltip overlays interactive elements when active, for example a fo - +
``` diff --git a/src/components/TrapFocus/tests/TrapFocus.test.tsx b/src/components/TrapFocus/tests/TrapFocus.test.tsx index 9d4711508d3..0ab42aecee8 100644 --- a/src/components/TrapFocus/tests/TrapFocus.test.tsx +++ b/src/components/TrapFocus/tests/TrapFocus.test.tsx @@ -113,7 +113,13 @@ describe('', () => { const trapFocus = mountWithApp( - + , ); @@ -124,7 +130,7 @@ describe('', () => { const trapFocus = mountWithApp( - + , ); @@ -159,7 +165,13 @@ describe('', () => { it('allows default when trapping is false', () => { const trapFocus = mountWithApp( - + , ); @@ -175,7 +187,13 @@ describe('', () => { it('allows default when the related target is a child', () => { const trapFocus = mountWithApp( - + , ); diff --git a/src/components/VisuallyHidden/README.md b/src/components/VisuallyHidden/README.md index bf47e597366..a7c39d5d539 100644 --- a/src/components/VisuallyHidden/README.md +++ b/src/components/VisuallyHidden/README.md @@ -51,8 +51,14 @@ Always provide a heading for a major page section such as a card. In rare cases label="Title" value="Artisanal Wooden Spoon" onChange={() => {}} + autoComplete="off" + /> + {}} + autoComplete="off" /> - {}} /> ```