Skip to content

Combobox Input Value Not Updating When Value Changes Programmatically #1317

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
tsegreto opened this issue Mar 23, 2025 · 0 comments · Fixed by #1517
Closed

Combobox Input Value Not Updating When Value Changes Programmatically #1317

tsegreto opened this issue Mar 23, 2025 · 0 comments · Fixed by #1517
Labels
bug Something isn't working

Comments

@tsegreto
Copy link

tsegreto commented Mar 23, 2025

Describe the bug

Description

When programmatically changing the value of a Combobox component created following the docs at https://next.bits-ui.com/docs/components/combobox, the dropdown selection updates correctly, but the input field text doesn't reflect the change.

Steps to Reproduce

Create a reusable Combobox component following the documentation:

<script lang="ts">
	import { Combobox, type WithoutChildrenOrChild, mergeProps } from "bits-ui";
	import { Icon, ChevronUpDown } from "svelte-hero-icons";
	type Item = { value: string; label: string };
	type Props = Combobox.RootProps & {
		items: Item[];
		inputProps?: WithoutChildrenOrChild<Combobox.InputProps>;
		contentProps?: WithoutChildrenOrChild<Combobox.ContentProps>;
	};
	let {
		items,
		value = $bindable(),
		open = $bindable(false),
		inputProps,
		contentProps,
		...restProps
	}: Props = $props();
	let searchValue = $state("");
	const filteredItems = $derived.by(() => {
		if (searchValue === "") return items;
		return items.filter((item) => item.label.toLowerCase().includes(searchValue.toLowerCase()));
	});
	function handleInput(e: Event & { currentTarget: HTMLInputElement }) {
		searchValue = e.currentTarget.value;
	}
	function handleOpenChange(newOpen: boolean) {
		if (!newOpen) searchValue = "";
	}
	const mergedRootProps = $derived(mergeProps(restProps, { onOpenChange: handleOpenChange }));
	const mergedInputProps = $derived(mergeProps(inputProps, { oninput: handleInput }));
</script>
<Combobox.Root bind:value bind:open {...mergedRootProps} type="single">
	<div class="relative">
		<Combobox.Input
			{...mergedInputProps}
			class="border-input bg-background placeholder:text-muted-foreground flex h-10 w-full rounded-md border px-3 py-2 text-base file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm"
		/>
		<Combobox.Trigger class="absolute end-3 top-1/2 size-6 -translate-y-1/2"><Icon src={ChevronUpDown} class="w-5 h-5 text-neutral-600" /></Combobox.Trigger>
	</div>
	<Combobox.Portal>
		<Combobox.Content {...contentProps} class="z-50  bg-white w-[var(--bits-combobox-anchor-width)] min-w-[var(--bits-combobox-anchor-width)]  rounded-md border shadow-md outline-none mt-2 p-1">
			{#each filteredItems as item, i (item.value)}
				<Combobox.Item value={item.value} label={item.label} class="relative flex w-full select-none items-center rounded-sm p-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50 cursor-pointer">
					{#snippet children({ selected })}
						<div class="flex flex-col w-full">
							<span class={selected ? "font-medium text-red-500" : ""}>{item.label}</span>
						</div>
					{/snippet}
				</Combobox.Item>
			{:else}
				<span> No results found </span>
			{/each}
		</Combobox.Content>
	</Combobox.Portal>
</Combobox.Root>

Use this component in another file with programmatic value changes:

let myValue = $state("");
const testItems = [
	{ value: "mango", label: "Mango" },
	{ value: "watermelon", label: "Watermelon" },
	{ value: "apple", label: "Apple" },
];
<button onclick={() => (myValue = "apple")}> Select Apple </button>
<Combobox items={testItems} bind:value={myValue} />

Click the "Select Apple" button

Expected Behavior

When clicking the "Select Apple" button (setting myValue = "apple" programmatically), both the dropdown selection AND the input field text should update to display "Apple".

Actual Behavior

The dropdown correctly shows "Apple" as selected, but the input field remains empty or unchanged.

Reproduction

https://stackblitz.com/edit/github-cfbnbfta-fwh7ndgr?file=src%2Froutes%2F%2Bpage.svelte

Logs

System Info

"bits-ui": "1.3.13",
"svelte": "^5.0.0",

Severity

annoyance

@tsegreto tsegreto added the triage A maintainer needs to review this issue and label it appropriately label Mar 23, 2025
@huntabyte huntabyte added docs Improvements or additions to documentation bug Something isn't working and removed triage A maintainer needs to review this issue and label it appropriately docs Improvements or additions to documentation labels Mar 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants