Skip to content

Commit d7b5534

Browse files
authored
fix(Combobox): a few issues (#1799)
1 parent ac5d727 commit d7b5534

File tree

6 files changed

+51
-10
lines changed

6 files changed

+51
-10
lines changed

.changeset/cruel-cities-know.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"bits-ui": patch
3+
---
4+
5+
fix(Combobox): recompute whether the `ScrollDown` but should render when the input value changes

.changeset/good-parrots-greet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"bits-ui": patch
3+
---
4+
5+
fix(Combobox): dont set the input value to an unselected item when `type='multiple'`

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,4 +85,5 @@ docs/src/routes/api/demos.json/demos.json
8585
__screenshots__
8686
bundle-analyzer/.temp-bundle-analysis
8787
bundle-analyzer/bundle-reports/*
88-
!bundle-analyzer/bundle-reports/latest.json
88+
!bundle-analyzer/bundle-reports/latest.json
89+
.tmp

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"pnpm": ">=10.12.1",
4949
"node": ">=20"
5050
},
51-
"packageManager": "[email protected].0",
51+
"packageManager": "[email protected].1",
5252
"private": true,
5353
"pnpm": {
5454
"onlyBuiltDependencies": [

packages/bits-ui/src/lib/bits/select/select.svelte.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,10 @@ export class SelectSingleRootState extends SelectBaseRootState {
198198
readonly hasValue = $derived.by(() => this.opts.value.current !== "");
199199
readonly currentLabel = $derived.by(() => {
200200
if (!this.opts.items.current.length) return "";
201-
const match = this.opts.items.current.find(
202-
(item) => item.value === this.opts.value.current
203-
)?.label;
204-
return match ?? "";
201+
return (
202+
this.opts.items.current.find((item) => item.value === this.opts.value.current)?.label ??
203+
""
204+
);
205205
});
206206
readonly candidateLabels = $derived.by(() => {
207207
if (!this.opts.items.current.length) return [];
@@ -239,8 +239,11 @@ export class SelectSingleRootState extends SelectBaseRootState {
239239
}
240240

241241
toggleItem(itemValue: string, itemLabel: string = itemValue) {
242-
this.opts.value.current = this.includesItem(itemValue) ? "" : itemValue;
243-
this.opts.inputValue.current = itemLabel;
242+
const newValue = this.includesItem(itemValue) ? "" : itemValue;
243+
this.opts.value.current = newValue;
244+
if (newValue !== "") {
245+
this.opts.inputValue.current = itemLabel;
246+
}
244247
}
245248

246249
setInitialHighlightedNode() {
@@ -1054,8 +1057,6 @@ export class SelectItemState {
10541057
*/
10551058
onpointerup(e: BitsPointerEvent) {
10561059
if (e.defaultPrevented || !this.opts.ref.current) return;
1057-
// prevent any default behavior
1058-
10591060
/**
10601061
* For one reason or another, when it's a touch pointer and _not_ on IOS,
10611062
* we need to listen for the immediate click event to handle the selection,
@@ -1377,6 +1378,22 @@ export class SelectScrollDownButtonState {
13771378
return on(this.content.viewportNode, "scroll", () => this.handleScroll());
13781379
});
13791380

1381+
/**
1382+
* If the input value changes, this means that the filtered items may have changed,
1383+
* so we need to re-evaluate the scroll-ability of the list.
1384+
*/
1385+
watch(
1386+
[
1387+
() => this.root.opts.inputValue.current,
1388+
() => this.content.viewportNode,
1389+
() => this.content.isPositioned,
1390+
],
1391+
() => {
1392+
if (!this.content.viewportNode || !this.content.isPositioned) return;
1393+
this.handleScroll(true);
1394+
}
1395+
);
1396+
13801397
watch(
13811398
() => this.scrollButtonState.mounted,
13821399
() => {

tests/src/tests/combobox/combobox.browser.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,19 @@ describe("combobox - multiple", () => {
773773
await expect.element(t.input).toHaveValue("");
774774
expect(t.getHiddenInputs()).toHaveLength(0);
775775
});
776+
777+
it("should not update the input value when the item is deselected", async () => {
778+
const t = await openMultiple({});
779+
const [item1, item2] = getItems(page.getByTestId);
780+
await expectNotSelected([item1, item2]);
781+
await item1.click();
782+
await item2.click();
783+
await expectSelected([item1, item2]);
784+
await expect.element(t.input).toHaveValue("B");
785+
await item1.click();
786+
await expectNotSelected(item1);
787+
await expect.element(t.input).toHaveValue("A");
788+
});
776789
});
777790

778791
function getItems(getter: typeof page.getByTestId, items = testItems) {

0 commit comments

Comments
 (0)