From 043539307f9873b36ff42bbe04c306cb59eed82f Mon Sep 17 00:00:00 2001 From: ragulka Date: Tue, 19 Nov 2024 16:24:21 +0200 Subject: [PATCH] Add defaultToFirstOption prop to Combobox --- .../src/components/combobox/combobox.test.ts | 40 +++++++++++++++++++ .../src/components/combobox/combobox.ts | 6 ++- .../combobox/combobox-with-pure-tailwind.vue | 9 +---- 3 files changed, 46 insertions(+), 9 deletions(-) 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