Skip to content

Commit

Permalink
Merge 4de8a7d into be8265e
Browse files Browse the repository at this point in the history
  • Loading branch information
it-vegard authored Oct 23, 2023
2 parents be8265e + 4de8a7d commit 040563e
Show file tree
Hide file tree
Showing 5 changed files with 622 additions and 430 deletions.
5 changes: 5 additions & 0 deletions .changeset/early-colts-sneeze.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/ds-react": patch
---

Autocomplete in combobox will not change formatting of the letters while being typed, but will use the casing of the autocompleted word when selecting the option.
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ export const FilteredOptionsProvider = ({ children, value: props }) => {
shouldAutocomplete &&
normalizeText(searchTerm) !== "" &&
(previousSearchTerm?.length || 0) < searchTerm.length &&
filteredOptions.length > 0 &&
!isValueInList(searchTerm, filteredOptions)
filteredOptions.length > 0
) {
setValue(
`${searchTerm}${filteredOptions[0].substring(searchTerm.length)}`
Expand Down
23 changes: 19 additions & 4 deletions @navikt/core/react/src/form/combobox/Input/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const Input = forwardRef<HTMLInputElement, InputProps>(
allowNewValues,
currentOption,
filteredOptions,
isValueNew,
toggleIsListOpen,
isListOpen,
filteredOptionsIndex,
Expand All @@ -46,29 +47,43 @@ const Input = forwardRef<HTMLInputElement, InputProps>(

const onEnter = useCallback(
(event: React.KeyboardEvent) => {
const isTextInSelectedOptions = (text: string) => {
return selectedOptions.find(
(item) => item.toLocaleLowerCase() === text.toLocaleLowerCase()
);
};

if (currentOption) {
event.preventDefault();
// Selecting a value from the dropdown / FilteredOptions
toggleOption(currentOption, event);
if (!isMultiSelect && !selectedOptions.includes(currentOption))
if (!isMultiSelect && !isTextInSelectedOptions(currentOption))
toggleIsListOpen(false);
} else if (shouldAutocomplete && selectedOptions.includes(value)) {
} else if (shouldAutocomplete && isTextInSelectedOptions(value)) {
event.preventDefault();
// Trying to set the same value that is already set, so just clearing the input
clearInput(event);
} else if ((allowNewValues || shouldAutocomplete) && value !== "") {
event.preventDefault();
// Autocompleting or adding a new value
toggleOption(value, event);
if (!isMultiSelect && !selectedOptions.includes(value))
const selectedValue =
allowNewValues && isValueNew ? value : filteredOptions[0];
toggleOption(selectedValue, event);
if (
!isMultiSelect &&
!isTextInSelectedOptions(filteredOptions[0] || selectedValue)
) {
toggleIsListOpen(false);
}
}
},
[
allowNewValues,
clearInput,
currentOption,
filteredOptions,
isMultiSelect,
isValueNew,
selectedOptions,
shouldAutocomplete,
toggleIsListOpen,
Expand Down
44 changes: 44 additions & 0 deletions @navikt/core/react/src/form/combobox/combobox.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,50 @@ export const TestThatCallbacksOnlyFireWhenExpected: StoryObj<{
},
};

export const TestCasingWhenAutoCompleting = {
args: {
onChange: jest.fn(),
onClear: jest.fn(),
onToggleSelected: jest.fn(),
},
render: (props) => {
return (
<UNSAFE_Combobox
options={["Camel Case", "lowercase", "UPPERCASE"]}
label="Liker du best store eller små bokstaver?"
shouldAutocomplete
allowNewValues
{...props}
/>
);
},
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const input = canvas.getByRole<HTMLInputElement>("combobox");

// With exisiting option
userEvent.click(input);
await userEvent.type(input, "cAmEl CaSe", { delay: 250 });
await sleep(250);
expect(input.value).toBe("cAmEl CaSe");
await userEvent.type(input, "{Enter}");
await sleep(250);
const chips = canvas.getAllByRole("list")[0];
const selectedUpperCaseChip = within(chips).getAllByRole("listitem")[0];
expect(selectedUpperCaseChip).toHaveTextContent("Camel Case"); // A weird issue is preventing the accessible name from being used in the test, even if it works in VoiceOver

// With custom option
userEvent.click(input);
await userEvent.type(input, "cAmEl{Backspace}", { delay: 250 });
await sleep(250);
expect(input.value).toBe("cAmEl");
await userEvent.type(input, "{Enter}");
await sleep(250);
const selectedNewValueChip = within(chips).getAllByRole("listitem")[0];
expect(selectedNewValueChip).toHaveTextContent("cAmEl"); // A weird issue is preventing the accessible name from being used in the test, even if it works in VoiceOver
},
};

export const TestHoverAndFocusSwitching: StoryObject = {
render: () => {
return (
Expand Down
Loading

0 comments on commit 040563e

Please sign in to comment.