Skip to content

Commit 8b2abdb

Browse files
authored
fix(Combobox): 🐛 Click to open/close should now close when open (#2184)
fixes #2180
1 parent b72dc91 commit 8b2abdb

File tree

6 files changed

+37
-13
lines changed

6 files changed

+37
-13
lines changed

.changeset/config.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,11 @@
77
"access": "restricted",
88
"baseBranch": "main",
99
"updateInternalDependencies": "patch",
10-
"ignore": ["@digdir/design-system-react"]
10+
"ignore": [
11+
"@digdir/design-system-react",
12+
"storefront",
13+
"theme",
14+
"figma-plugin",
15+
"@digdir/components"
16+
]
1117
}

.changeset/friendly-islands-punch.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@digdir/designsystemet-react": patch
3+
---
4+
5+
fix(Combobox): :bug: Button for toggling open/close should now close when open

.github/workflows/release-snapshot.yml

+10-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ name: Release Snapshot
33

44
on:
55
workflow_dispatch:
6+
inputs:
7+
tag:
8+
description: 'NPM tag'
9+
default: ''
610

711
jobs:
812
snapshot:
@@ -11,6 +15,10 @@ jobs:
1115
steps:
1216
- uses: actions/checkout@v4
1317
- uses: ./.github/actions/gh-setup
18+
- name: Build
19+
run: yarn build
20+
- id: variables
21+
run: echo "tag=${{ github.event.inputs.tag != '' && github.event.inputs.tag || github.ref_name }}" >> $GITHUB_OUTPUT
1422
- name: Creating .npmrc
1523
run: |
1624
cat << EOF > "$HOME/.npmrc"
@@ -20,9 +28,9 @@ jobs:
2028
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
2129
- name: Create Snapshot Release
2230
run: |
23-
yarn run version-packages --snapshot "${{ github.ref_name }}"
31+
yarn run version-packages --snapshot "${{ steps.variables.outputs.tag }}"
2432
echo '---'
2533
echo 'Detected Changes:'
2634
git diff
2735
echo '---'
28-
yarn run publish --tag "${{ github.ref_name }}" --no-git-tag
36+
yarn run publish --tag "${{ steps.variables.outputs.tag }}" --no-git-tag

packages/react/src/components/form/Combobox/Combobox.test.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,6 @@ describe('Combobox', () => {
322322
await act(async () => await user.click(combobox));
323323
await act(async () => await user.click(screen.getByText('Leikanger')));
324324

325-
await act(async () => await user.click(combobox));
326-
327325
expect(screen.getByText('Leikanger')).toBeInTheDocument();
328326
expect(screen.getByText('Oslo')).toBeInTheDocument();
329327
expect(screen.getByText('Brønnøysund')).toBeInTheDocument();

packages/react/src/components/form/Combobox/internal/ComboboxClearButton.tsx

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1-
import { useContext } from 'react';
1+
import { forwardRef, useContext } from 'react';
22
import { XMarkIcon } from '@navikt/aksel-icons';
33
import cl from 'clsx/lite';
44

55
import { ComboboxContext } from '../ComboboxContext';
66

7-
const ComboboxClearButton = () => {
7+
const ComboboxClearButton = forwardRef<
8+
HTMLButtonElement,
9+
React.ButtonHTMLAttributes<HTMLButtonElement>
10+
>((props, ref) => {
811
const context = useContext(ComboboxContext);
912

1013
if (!context) {
@@ -15,6 +18,8 @@ const ComboboxClearButton = () => {
1518

1619
return (
1720
<button
21+
{...props}
22+
ref={ref}
1823
disabled={disabled}
1924
className={cl('ds-combobox__clear-button', `ds-focus`)}
2025
onClick={() => {
@@ -39,7 +44,7 @@ const ComboboxClearButton = () => {
3944
/>
4045
</button>
4146
);
42-
};
47+
});
4348

4449
ComboboxClearButton.displayName = 'ComboboxClearButton';
4550

packages/react/src/components/form/Combobox/internal/ComboboxInput.tsx

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { ChangeEvent } from 'react';
2-
import { useContext } from 'react';
2+
import { useContext, useRef } from 'react';
33
import cl from 'clsx/lite';
44
import { ChevronUpIcon, ChevronDownIcon } from '@navikt/aksel-icons';
55
import { useMergeRefs } from '@floating-ui/react';
@@ -32,6 +32,7 @@ const ComboboxInput = ({
3232
}: ComboboxInputProps) => {
3333
const context = useContext(ComboboxContext);
3434
const idDispatch = useComboboxIdDispatch();
35+
const clearButtonRef = useRef<HTMLButtonElement>(null);
3536

3637
if (!context) {
3738
throw new Error('ComboboxContext is missing');
@@ -89,11 +90,12 @@ const ComboboxInput = ({
8990
'aria-controls': null,
9091
'aria-expanded': null,
9192
'aria-haspopup': null,
92-
/* If we click the wrapper, open the list, set index to first option, and focus the input */
93-
onClick() {
93+
/* If we click the wrapper, toggle open, set index to first option, and focus the input */
94+
onClick(event: React.MouseEvent<HTMLDivElement>) {
9495
if (disabled) return;
9596
if (readOnly) return;
96-
setOpen(true);
97+
if (clearButtonRef.current?.contains(event.target as Node)) return;
98+
setOpen(!open);
9799
setActiveIndex(0);
98100
inputRef.current?.focus();
99101
},
@@ -152,7 +154,7 @@ const ComboboxInput = ({
152154
</Paragraph>
153155
</div>
154156
{/* Clear button if we are in multiple mode and have at least one active value */}
155-
{showClearButton && <ComboboxClearButton />}
157+
{showClearButton && <ComboboxClearButton ref={clearButtonRef} />}
156158
{/* Arrow for combobox. Click is handled by the wrapper */}
157159
<div className={'ds-combobox__arrow'}>
158160
{open ? (

0 commit comments

Comments
 (0)