From 8fccf6276598061c3d6f5ade8148e34b55566f75 Mon Sep 17 00:00:00 2001 From: Vegard Haugstvedt Date: Fri, 4 Oct 2024 13:07:19 +0200 Subject: [PATCH 1/3] Disable autocomplete in Combobox to "fix" issue where autocomplete is broken in Firefox on Android The bug is that after three "correct" characters are entered in a row, the autocomplete inserts the third character incorrectly, messing up the text in the input. This also happens in other implementations of autocomple, like W3C's ARIA Authoring Practices Guide combobox with inline autocomple. --- .../core/react/src/form/combobox/ComboboxProvider.tsx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx b/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx index 402445e43df..804c80ab501 100644 --- a/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx +++ b/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef } from "react"; +import React, { forwardRef, useEffect, useState } from "react"; import Combobox from "./Combobox"; import { FilteredOptionsProvider } from "./FilteredOptions/filteredOptionsContext"; import { InputContextProvider } from "./Input/Input.context"; @@ -58,6 +58,12 @@ const ComboboxProvider = forwardRef( const options = mapToComboboxOptionArray(externalOptions) || []; const filteredOptions = mapToComboboxOptionArray(externalFilteredOptions); const selectedOptions = mapToComboboxOptionArray(externalSelectedOptions); + + const [isFirefoxOnAndroid, setIsFirefoxOnAndroid] = useState(false); + useEffect(() => { + setIsFirefoxOnAndroid(/Android.+Firefox\//.test(navigator.userAgent)); + }, []); + return ( ( value, onChange, onClear, - shouldAutocomplete, + shouldAutocomplete: !isFirefoxOnAndroid && shouldAutocomplete, size, }} > From c0967f212f5e27eae9ec7ff3849609b3dbc2ec82 Mon Sep 17 00:00:00 2001 From: Vegard Haugstvedt Date: Fri, 4 Oct 2024 13:08:28 +0200 Subject: [PATCH 2/3] Add changeset --- .changeset/rotten-moons-build.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/rotten-moons-build.md diff --git a/.changeset/rotten-moons-build.md b/.changeset/rotten-moons-build.md new file mode 100644 index 00000000000..e063ca2eac2 --- /dev/null +++ b/.changeset/rotten-moons-build.md @@ -0,0 +1,5 @@ +--- +"@navikt/ds-react": patch +--- + +Combobox: Disable autocomple in Firefox on Android to prevent bug From 973d9288698d159d3ea5499a685fa188c3776249 Mon Sep 17 00:00:00 2001 From: Vegard Haugstvedt Date: Tue, 8 Oct 2024 12:09:59 +0200 Subject: [PATCH 3/3] Use type checking instead of useEffect to prevent client code from running server side --- .../react/src/form/combobox/ComboboxProvider.tsx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx b/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx index 804c80ab501..4845f5f254d 100644 --- a/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx +++ b/@navikt/core/react/src/form/combobox/ComboboxProvider.tsx @@ -1,4 +1,4 @@ -import React, { forwardRef, useEffect, useState } from "react"; +import React, { forwardRef } from "react"; import Combobox from "./Combobox"; import { FilteredOptionsProvider } from "./FilteredOptions/filteredOptionsContext"; import { InputContextProvider } from "./Input/Input.context"; @@ -51,7 +51,7 @@ const ComboboxProvider = forwardRef( value, onChange, onClear, - shouldAutocomplete, + shouldAutocomplete: externalShouldAutocomplete, size, ...rest } = props; @@ -59,10 +59,12 @@ const ComboboxProvider = forwardRef( const filteredOptions = mapToComboboxOptionArray(externalFilteredOptions); const selectedOptions = mapToComboboxOptionArray(externalSelectedOptions); - const [isFirefoxOnAndroid, setIsFirefoxOnAndroid] = useState(false); - useEffect(() => { - setIsFirefoxOnAndroid(/Android.+Firefox\//.test(navigator.userAgent)); - }, []); + const userAgent = + typeof navigator === "undefined" ? "" : navigator.userAgent; + const isFirefoxOnAndroid = + userAgent.includes("Android") && userAgent.includes("Firefox/"); + const shouldAutocomplete = + !isFirefoxOnAndroid && externalShouldAutocomplete; return ( ( value, onChange, onClear, - shouldAutocomplete: !isFirefoxOnAndroid && shouldAutocomplete, + shouldAutocomplete, size, }} >