diff --git a/packages/@headlessui-vue/src/components/combobox/combobox.test.ts b/packages/@headlessui-vue/src/components/combobox/combobox.test.ts
index 433fddddad..651c6b9395 100644
--- a/packages/@headlessui-vue/src/components/combobox/combobox.test.ts
+++ b/packages/@headlessui-vue/src/components/combobox/combobox.test.ts
@@ -2708,6 +2708,46 @@ describe.each([{ virtual: true }, { virtual: false }])(
assertNoActiveComboboxOption()
})
)
+
+ it(
+ 'should be possible to go to the first item if no value is set and first option is not active by default',
+ suppressConsoleLogs(async () => {
+ renderTemplate({
+ template: html`
+
+
+ Trigger
+
+ Option A
+ Option B
+ Option C
+
+
+ `,
+ setup: () => ({ value: ref(null) }),
+ })
+
+ assertComboboxButton({
+ state: ComboboxState.InvisibleUnmounted,
+ attributes: { id: 'headlessui-combobox-button-2' },
+ })
+ assertComboboxList({ state: ComboboxState.InvisibleUnmounted })
+
+ // Open combobox
+ await click(getComboboxButton())
+
+ let options = getComboboxOptions()
+
+ // Verify that we have no active option
+ assertNoActiveComboboxOption()
+
+ // Go down once
+ await press(Keys.ArrowDown)
+
+ // We should be on the next item
+ assertActiveComboboxOption(options[0])
+ })
+ )
})
describe('`ArrowUp` key', () => {
diff --git a/packages/@headlessui-vue/src/components/combobox/combobox.ts b/packages/@headlessui-vue/src/components/combobox/combobox.ts
index 27b2a1c1d2..5b0f775aa1 100644
--- a/packages/@headlessui-vue/src/components/combobox/combobox.ts
+++ b/packages/@headlessui-vue/src/components/combobox/combobox.ts
@@ -252,6 +252,7 @@ export let Combobox = defineComponent({
>,
default: undefined,
},
+ defaultToFirstOption: { type: [Boolean], default: false },
form: { type: String, optional: true },
name: { type: String, optional: true },
nullable: { type: Boolean, default: false },
@@ -459,7 +460,7 @@ export let Combobox = defineComponent({
activeOptionIndex.value = null
},
openCombobox() {
- defaultToFirstOption.value = true
+ defaultToFirstOption.value = props.defaultToFirstOption
if (props.disabled) return
if (comboboxState.value === ComboboxStates.Open) return
@@ -526,7 +527,7 @@ export let Combobox = defineComponent({
// It's possible that the activeOptionIndex is set to `null` internally, but
// this means that we will fallback to the first non-disabled option by default.
// We have to take this into account.
- if (adjustedState.activeOptionIndex === null) {
+ if (adjustedState.activeOptionIndex === null && props.defaultToFirstOption) {
let localActiveOptionIndex = adjustedState.options.findIndex(
(option) => !option.dataRef.disabled
)
@@ -743,6 +744,7 @@ export let Combobox = defineComponent({
...omit(theirProps, [
'by',
'defaultValue',
+ 'defaultToFirstOption',
'immediate',
'modelValue',
'multiple',
diff --git a/playgrounds/vue/src/components/combobox/combobox-with-pure-tailwind.vue b/playgrounds/vue/src/components/combobox/combobox-with-pure-tailwind.vue
index 3ffcd11fd9..c926547b88 100644
--- a/playgrounds/vue/src/components/combobox/combobox-with-pure-tailwind.vue
+++ b/playgrounds/vue/src/components/combobox/combobox-with-pure-tailwind.vue
@@ -33,7 +33,7 @@ export default defineComponent({
},
setup() {
let query = ref('')
- let activePerson = ref(everybody[2]) // everybody[Math.floor(Math.random() * everybody.length)]
+ let activePerson = ref(null)
let filteredPeople = computed(() => {
return query.value === ''
? everybody
@@ -42,11 +42,6 @@ export default defineComponent({
})
})
- // Choose a random person on mount
- onMounted(() => {
- activePerson.value = everybody[Math.floor(Math.random() * everybody.length)]
- })
-
watch(activePerson, () => {
query.value = ''
})
@@ -67,7 +62,7 @@ export default defineComponent({
Selected person: {{ activePerson?.name ?? 'Nobody yet' }}
-
+
Assigned to