diff --git a/packages/@headlessui-react/src/components/listbox/listbox.test.tsx b/packages/@headlessui-react/src/components/listbox/listbox.test.tsx
index c3cbe4b..fba55b1 100644
--- a/packages/@headlessui-react/src/components/listbox/listbox.test.tsx
+++ b/packages/@headlessui-react/src/components/listbox/listbox.test.tsx
@@ -579,6 +579,59 @@ describe('Keyboard interactions', () => {
})
)
+ it(
+ 'should be possible to open the listbox with Enter, and focus the selected option (with a list of objects)',
+ suppressConsoleLogs(async () => {
+ const myOptions = [
+ { id: 'a', name: 'Option A' },
+ { id: 'b', name: 'Option B' },
+ { id: 'c', name: 'Option C' },
+ ]
+ const selectedOption = myOptions[1]
+ render(
+
+ Trigger
+
+ {myOptions.map(myOption => (
+
+ {myOption.name}
+
+ ))}
+
+
+ )
+
+ assertListboxButton({
+ state: ListboxState.Closed,
+ attributes: { id: 'headlessui-listbox-button-1' },
+ })
+ assertListbox({ state: ListboxState.Closed })
+
+ // Focus the button
+ getListboxButton()?.focus()
+
+ // Open listbox
+ await press(Keys.Enter)
+
+ // Verify it is open
+ assertListboxButton({ state: ListboxState.Open })
+ assertListbox({
+ state: ListboxState.Open,
+ attributes: { id: 'headlessui-listbox-options-2' },
+ })
+ assertActiveElement(getListbox())
+ assertListboxButtonLinkedWithListbox()
+
+ // Verify we have listbox options
+ const options = getListboxOptions()
+ expect(options).toHaveLength(3)
+ options.forEach((option, i) => assertListboxOption(option, { selected: i === 1 }))
+
+ // Verify that the second listbox option is active (because it is already selected)
+ assertActiveListboxOption(options[1])
+ })
+ )
+
it(
'should have no active listbox option when there are no listbox options at all',
suppressConsoleLogs(async () => {
diff --git a/packages/@headlessui-vue/examples/src/components/listbox/listbox.vue b/packages/@headlessui-vue/examples/src/components/listbox/listbox.vue
index 081a90c..77b94a8 100644
--- a/packages/@headlessui-vue/examples/src/components/listbox/listbox.vue
+++ b/packages/@headlessui-vue/examples/src/components/listbox/listbox.vue
@@ -12,7 +12,7 @@
- {{ active }}
+ {{ active.name }}
{
})
)
+ it(
+ 'should be possible to open the listbox with Enter, and focus the selected option (with a list of objects)',
+ suppressConsoleLogs(async () => {
+ renderTemplate({
+ template: `
+
+ Trigger
+
+ {{ option.name }}
+
+
+ `,
+ setup: () => {
+ const options = [
+ { id: 'a', name: 'Option A' },
+ { id: 'b', name: 'Option B' },
+ { id: 'c', name: 'Option C' },
+ ]
+ const value = ref(options[1])
+
+ return { value, options }
+ },
+ })
+
+ assertListboxButton({
+ state: ListboxState.Closed,
+ attributes: { id: 'headlessui-listbox-button-1' },
+ })
+ assertListbox({ state: ListboxState.Closed })
+
+ // Focus the button
+ getListboxButton()?.focus()
+
+ // Open listbox
+ await press(Keys.Enter)
+
+ // Verify it is open
+ assertListboxButton({ state: ListboxState.Open })
+ assertListbox({
+ state: ListboxState.Open,
+ attributes: { id: 'headlessui-listbox-options-2' },
+ })
+ assertActiveElement(getListbox())
+ assertListboxButtonLinkedWithListbox()
+
+ // Verify we have listbox options
+ const options = getListboxOptions()
+ expect(options).toHaveLength(3)
+ options.forEach((option, i) => assertListboxOption(option, { selected: i === 1 }))
+
+ // Verify that the second listbox option is active (because it is already selected)
+ assertActiveListboxOption(options[1])
+ })
+ )
+
it(
'should have no active listbox option when there are no listbox options at all',
suppressConsoleLogs(async () => {
diff --git a/packages/@headlessui-vue/src/components/listbox/listbox.ts b/packages/@headlessui-vue/src/components/listbox/listbox.ts
index 5012cb1..6457811 100644
--- a/packages/@headlessui-vue/src/components/listbox/listbox.ts
+++ b/packages/@headlessui-vue/src/components/listbox/listbox.ts
@@ -11,6 +11,7 @@ import {
Ref,
ComputedRef,
watchEffect,
+ toRaw,
} from 'vue'
import { match } from '../../utils/match'
import { render } from '../../utils/render'
@@ -476,7 +477,7 @@ export const ListboxOption = defineComponent({
: false
})
- const selected = computed(() => api.value.value === value)
+ const selected = computed(() => toRaw(api.value.value) === toRaw(value))
const dataRef = ref({ disabled, value, textValue: '' })
onMounted(() => {