From d9b43f7ef8e26fa3b3bce5356bb0696521da9030 Mon Sep 17 00:00:00 2001 From: Bram Kaashoek Date: Wed, 10 Sep 2025 09:36:08 +0200 Subject: [PATCH] chore: disable browser autocomplete --- .changeset/disable-browser-autocomplete.md | 5 ++++ README.md | 27 +++++++++-------- src/index.test.tsx | 35 ++++++++++++++++++++++ src/index.tsx | 10 +++++-- src/testing/snapshots/index.test.tsx.snap | 5 ++++ 5 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 .changeset/disable-browser-autocomplete.md diff --git a/.changeset/disable-browser-autocomplete.md b/.changeset/disable-browser-autocomplete.md new file mode 100644 index 0000000..89fdfad --- /dev/null +++ b/.changeset/disable-browser-autocomplete.md @@ -0,0 +1,5 @@ +--- +"react-loqate": minor +--- + +Add disableBrowserAutocomplete prop to prevent browser autocomplete interference with address suggestions. This prop defaults to true, disabling browser autocomplete by setting autoComplete="react-loqate-address-search" on the input field. \ No newline at end of file diff --git a/README.md b/README.md index d99a3fa..979bb16 100644 --- a/README.md +++ b/README.md @@ -32,19 +32,20 @@ import 'react-loqate/dist/index.css'; ### Props -| name | type | required | example | description | -| ---------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | -| apiKey | string | yes | "AA11-AA11-AA11-AA11" | Loqate API key | -| locale | string | yes | "en-GB" | Language to be used | -| onSelect | (address) => void | yes | address => console.log(address) | Callback with for Loqate response | -| countries | string[] | no | ["GB", "NL"] | Countries to search in | -| limit | number | no | 10 | Number of options to show | -| classes | `{ input?: string, list?: string, listItem?: string}` | no | { list: 'list' } | Classnames for the components | -| components | see [Customization](#Customization) | no | { Input: CustomInput, List: CustomList, ListItem: CustomListItem, } | Components to overwrite the default ones | -| inline | boolean | no | true | Render results inline with the input | -| debounce | number | no | 100 | Debounce the calls to the Loqate API | -| bias | boolean | no | true | Bias feature when using capture v4 enabled key.
Requires origin to be set. | -| origin | string | no | "93.184.216.34" | Name or ISO 2 or 3 character code of a country, WGS84 coordinates (comma separated) or IP address | +| name | type | required | example | description | +| -------------------------- | ----------------------------------------------------- | -------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | +| apiKey | string | yes | "AA11-AA11-AA11-AA11" | Loqate API key | +| locale | string | yes | "en-GB" | Language to be used | +| onSelect | (address) => void | yes | address => console.log(address) | Callback with for Loqate response | +| countries | string[] | no | ["GB", "NL"] | Countries to search in | +| limit | number | no | 10 | Number of options to show | +| classes | `{ input?: string, list?: string, listItem?: string}` | no | { list: 'list' } | Classnames for the components | +| components | see [Customization](#Customization) | no | { Input: CustomInput, List: CustomList, ListItem: CustomListItem, } | Components to overwrite the default ones | +| inline | boolean | no | true | Render results inline with the input | +| debounce | number | no | 100 | Debounce the calls to the Loqate API | +| bias | boolean | no | true | Bias feature when using capture v4 enabled key.
Requires origin to be set. | +| origin | string | no | "93.184.216.34" | Name or ISO 2 or 3 character code of a country, WGS84 coordinates (comma separated) or IP address | +| disableBrowserAutocomplete | boolean | no | false | Disable browser autocomplete on the input field (defaults to true) | ### Customization diff --git a/src/index.test.tsx b/src/index.test.tsx index 5c9ef64..e1b6953 100644 --- a/src/index.test.tsx +++ b/src/index.test.tsx @@ -377,3 +377,38 @@ it('accepts origin and bias options', async () => { text: 'a', }); }); + +it('disables browser autocomplete by default', () => { + render(); + + const input = screen.getByRole('textbox'); + expect(input).toHaveAttribute('autocomplete', 'react-loqate-address-search'); +}); + +it('allows enabling browser autocomplete when disableBrowserAutocomplete is false', () => { + render( + + ); + + const input = screen.getByRole('textbox'); + expect(input).not.toHaveAttribute('autocomplete'); +}); + +it('disables browser autocomplete when disableBrowserAutocomplete is true', () => { + render( + + ); + + const input = screen.getByRole('textbox'); + expect(input).toHaveAttribute('autocomplete', 'react-loqate-address-search'); +}); diff --git a/src/index.tsx b/src/index.tsx index 3d04d3e..0db9738 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,7 +1,7 @@ import clsx from 'clsx'; import React, { - ChangeEvent, - ComponentType, + type ChangeEvent, + type ComponentType, useMemo, useRef, useState, @@ -32,6 +32,7 @@ export interface Props { apiUrl?: string; bias?: boolean; origin?: string; + disableBrowserAutocomplete?: boolean; } interface Components { @@ -134,6 +135,7 @@ function AddressSearch(props: Props): JSX.Element { apiUrl, bias, origin, + disableBrowserAutocomplete = true, } = props; const loqate = useMemo(() => Loqate.create(apiKey, apiUrl), [apiKey]); @@ -227,6 +229,10 @@ function AddressSearch(props: Props): JSX.Element { className={clsx(classes?.input)} onChange={handleChange} value={value} + // disabling autocomplete in order to avoid conflict with loqate suggestions + autoComplete={ + disableBrowserAutocomplete ? 'react-loqate-address-search' : undefined + } onKeyDown={(e) => { if (e.key === 'Escape') { setSuggestions([]); diff --git a/src/testing/snapshots/index.test.tsx.snap b/src/testing/snapshots/index.test.tsx.snap index d606a5a..48d34e3 100644 --- a/src/testing/snapshots/index.test.tsx.snap +++ b/src/testing/snapshots/index.test.tsx.snap @@ -4,6 +4,7 @@ exports[`allows for alternative url 1`] = `
@@ -43,6 +44,7 @@ exports[`renders default 1`] = `
@@ -169,6 +171,7 @@ exports[`renders with custom components 1`] = `
@@ -413,6 +417,7 @@ exports[`renders with portal results 1`] = ` data-testid="react-loqate" >