Combobox example for SolidJS is broken (render is different from state) #1322
-
🐛 Bug reportThe example code for the Combobox in SolidJS is broken. The options rendered do not match the state of the state machine. Here is the code, copied from the docs: import * as combobox from "@zag-js/combobox"
import { normalizeProps, useMachine } from "@zag-js/solid"
import { createMemo, createSignal, createUniqueId, For, Show } from "solid-js"
const comboboxData = [
{ label: "Zambia", code: "ZA" },
{ label: "Benin", code: "BN" },
//...
]
export function Combobox() {
const [options, setOptions] = createSignal(comboboxData)
const collection = createMemo(() =>
combobox.collection({
items: options(),
itemToValue: (item) => item.code,
itemToString: (item) => item.label,
}),
)
const [state, send] = useMachine(
combobox.machine({
id: createUniqueId(),
collection: collection(),
onOpenChange() {
setOptions(comboboxData)
},
onInputValueChange({ value }) {
const filtered = comboboxData.filter((item) =>
item.label.toLowerCase().includes(value.toLowerCase()),
)
setOptions(filtered.length > 0 ? filtered : comboboxData)
},
}),
)
const api = createMemo(() => combobox.connect(state, send, normalizeProps))
return (
<div>
<div {...api().rootProps}>
<label {...api().labelProps}>Select country</label>
<div {...api().controlProps}>
<input {...api().inputProps} />
<button {...api().triggerProps}>▼</button>
</div>
</div>
<div {...api().positionerProps}>
<Show when={options().length > 0}>
<ul {...api().contentProps}>
<For each={options()}>
{(item) => (
<li {...api().getItemProps({ item })}>{item.label}</li>
)}
</For>
</ul>
</Show>
</div>
</div>
)
} The issue is that When you filter down the list, you can arrow through options which are not rendered. 💥 Steps to reproduceI've made an example here that demos the issue very easily.
💻 Link to reproductionStackBlitz reproduction: https://stackblitz.com/edit/solidjs-templates-housf3?file=src%2FApp.tsx,src%2FCombobox.tsx 🧐 Expected behaviorThe documentation should be correct and should show how to make a filterable combobox that updates the state machine properly. 🧭 Possible SolutionThe React 🌍 System information
📝 Additional information |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments
-
I don't understand why this was converted to a discussion. There is a bug in the documentation. The |
Beta Was this translation helpful? Give feedback.
-
Hi @knpwrs, This is not a bug. Here's the correct set up for the combobox machine: const [state, send] = useMachine(
combobox.machine({
id: createUniqueId(),
onOpenChange() {
setOptions(comboboxData);
},
onInputValueChange({ value }) {
const filtered = comboboxData.filter((item) =>
item.label.toLowerCase().includes(value.toLowerCase())
);
setOptions(filtered.length > 0 ? filtered : comboboxData);
},
openOnClick: true,
multiple: true,
}),
// this was missing
{
context: createMemo(() => ({
collection: collection(),
})),
}
); https://stackblitz.com/edit/solidjs-templates-zfgwem?file=src%2FApp.tsx,src%2FCombobox.tsx |
Beta Was this translation helpful? Give feedback.
Hi @knpwrs,
This is not a bug. Here's the correct set up for the combobox machine:
https://stackblitz.com/edit/solidjs-templ…