Skip to content

Commit

Permalink
Move movements should "take over" from keyboard focus in Combobox dro…
Browse files Browse the repository at this point in the history
…pdown list, and vice versa, acting like a native select.

Fixes #2165
  • Loading branch information
it-vegard committed Aug 23, 2023
1 parent 6fcbb72 commit 8c8b07b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 4 deletions.
8 changes: 4 additions & 4 deletions @navikt/core/css/form/combobox.css
Original file line number Diff line number Diff line change
Expand Up @@ -256,15 +256,15 @@
}

.navds-combobox__list-item--focus,
.navds-combobox__list-item:hover {
.navds-combobox__list--with-hover .navds-combobox__list-item:hover {
background-color: var(--ac-combobox-list-item-hover-bg, var(--a-surface-hover));
cursor: pointer;
border-left: 4px solid var(--ac-combobox-list-item-hover-border-left, var(--a-border-strong));
padding-left: calc(var(--a-spacing-3) - 4px);
}

.navds-form-field--small .navds-combobox__list-item--focus,
.navds-form-field--small .navds-combobox__list-item:hover {
.navds-combobox__list--with-hover .navds-form-field--small .navds-combobox__list-item:hover {
padding-left: calc(var(--a-spacing-2) - 4px);
}

Expand All @@ -277,7 +277,7 @@
}

.navds-combobox__list-item--selected.navds-combobox__list-item--focus,
.navds-combobox__list-item--selected:hover {
.navds-combobox__list--with-hover .navds-combobox__list-item--selected:hover {
background-color: var(--ac-combobox-list-item-selected-hover-bg, var(--a-surface-action-subtle-hover));
border-left: 4px solid var(--ac-combobox-list-item-selected-hover-border-left, var(--a-border-focus));
padding-left: calc(var(--a-spacing-3) - 4px);
Expand All @@ -291,7 +291,7 @@
gap: 0.25rem;
}

.navds-combobox__list-item__new-option:hover {
.navds-combobox__list--with-hover .navds-combobox__list-item__new-option:hover {
border-bottom: 1px solid var(--a-border-divider);
background: var(--a-surface-neutral-subtle-hover);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ const FilteredOptions = () => {
filteredOptions,
filteredOptionsIndex,
filteredOptionsRef,
isMouseLastUsedInputDevice,
setIsMouseLastUsedInputDevice,
isValueNew,
setFilteredOptionsIndex,
toggleIsListOpen,
} = useFilteredOptionsContext();
const { isMultiSelect, selectedOptions, toggleOption } =
Expand All @@ -30,6 +33,7 @@ const FilteredOptions = () => {
ref={filteredOptionsRef}
className={cl("navds-combobox__list", {
"navds-combobox__list--closed": !isListOpen,
"navds-combobox__list--with-hover": isMouseLastUsedInputDevice,
})}
id={`${id}-filtered-options`}
role="listbox"
Expand All @@ -48,6 +52,12 @@ const FilteredOptions = () => {
{isValueNew && allowNewValues && (
<li
tabIndex={-1}
onMouseMove={() => {
if (filteredOptionsIndex !== -1) {
setFilteredOptionsIndex(-1);
setIsMouseLastUsedInputDevice(true);
}
}}
onPointerUp={(event) => {
toggleOption(value, event);
if (!isMultiSelect && !selectedOptions.includes(value))
Expand Down Expand Up @@ -90,6 +100,12 @@ const FilteredOptions = () => {
id={`${id}-option-${option.replace(" ", "-")}`}
key={option}
tabIndex={-1}
onMouseMove={() => {
if (filteredOptionsIndex !== index) {
setFilteredOptionsIndex(index);
setIsMouseLastUsedInputDevice(true);
}
}}
onPointerUp={(event) => {
toggleOption(option, event);
if (!isMultiSelect && !selectedOptions.includes(option))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import React, {
useCallback,
useRef,
useLayoutEffect,
SetStateAction,
} from "react";
import cl from "clsx";
import { useCustomOptionsContext } from "../customOptionsContext";
Expand Down Expand Up @@ -35,6 +36,8 @@ type FilteredOptionsContextType = {
isListOpen: boolean;
isLoading?: boolean;
filteredOptions: string[];
isMouseLastUsedInputDevice: boolean;
setIsMouseLastUsedInputDevice: React.Dispatch<SetStateAction<boolean>>;
isValueNew: boolean;
toggleIsListOpen: (newState?: boolean) => void;
currentOption: string | null;
Expand Down Expand Up @@ -84,6 +87,9 @@ export const FilteredOptionsProvider = ({ children, value: props }) => {

const previousSearchTerm = usePrevious(searchTerm);

const [isMouseLastUsedInputDevice, setIsMouseLastUsedInputDevice] =
useState(false);

useLayoutEffect(() => {
if (
shouldAutocomplete &&
Expand Down Expand Up @@ -246,6 +252,8 @@ export const FilteredOptionsProvider = ({ children, value: props }) => {
isListOpen,
isLoading,
filteredOptions,
isMouseLastUsedInputDevice,
setIsMouseLastUsedInputDevice,
isValueNew,
toggleIsListOpen,
currentOption,
Expand Down
3 changes: 3 additions & 0 deletions @navikt/core/react/src/form/combobox/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
moveFocusToInput,
moveFocusToEnd,
setFilteredOptionsIndex,
setIsMouseLastUsedInputDevice,
shouldAutocomplete,
} = useFilteredOptionsContext();

Expand Down Expand Up @@ -102,6 +103,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(

const handleKeyDown = useCallback(
(e) => {
setIsMouseLastUsedInputDevice(false);
if (e.key === "Backspace") {
if (value === "") {
const lastSelectedOption =
Expand Down Expand Up @@ -132,6 +134,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
isListOpen,
filteredOptionsIndex,
moveFocusUp,
setIsMouseLastUsedInputDevice,
]
);

Expand Down

0 comments on commit 8c8b07b

Please sign in to comment.