Skip to content

Conversation

@Haviles04
Copy link
Contributor

@Haviles04 Haviles04 commented Dec 6, 2025

Description

resolves #22400

Markup

<template>
  <v-app>
    <v-container>
      <v-select
        v-model="selectedItems"
        :items="items"
        :menu-props="{offset:[40,40]}"
        class="rounded-lg"
        item-title="value"
        multiple
      >

        <template #list-header>
          <div class="bg-blue pa-2 10">
            <span>{{ headerText }}</span>
          </div>
        </template>
      </v-select>
    </v-container>
  </v-app>
</template>

<script setup>

  import { computed, shallowRef } from 'vue'
  const selectedItems = shallowRef([])

  const headerText = computed(() => {
    return `${selectedItems.value.length} selected`
  })

  const items = Array.from({ length: 15 }, (_, i) => ({ id: i, value: i * 10 }))

</script>

@J-Sek
Copy link
Contributor

J-Sek commented Dec 6, 2025

<VSheet style="display: flex; flex-direction: column;"> around both list and header would help eliminate the shadow bleading up. It will require change to onBlur so we won't auto-close the menu when header contains focusable element.

@Haviles04 Haviles04 marked this pull request as ready for review December 8, 2025 16:20
@Haviles04 Haviles04 requested a review from J-Sek December 8, 2025 17:35
@Haviles04 Haviles04 changed the title feat: add list-header slot feat:(V-Select) add list-header slot Dec 8, 2025
@Haviles04 Haviles04 changed the title feat:(V-Select) add list-header slot feat:(VSelect) add list-header slot Dec 8, 2025
@Haviles04 Haviles04 changed the title feat:(VSelect) add list-header slot feat(VSelect): Add list-header slot Dec 8, 2025
@J-Sek
Copy link
Contributor

J-Sek commented Dec 8, 2025

Proper tab-focus navigation is challenging. I am trying to get slots working with interactive elements within.

Playground
<template>
  <v-app theme="dark">
    <v-container class="d-flex align-center ga-3" max-width="600">
      <v-btn text="btn before" />
      <v-select
        v-model="selectedItems"
        :items="items"
        class="rounded-lg"
        item-title="value"
        hide-details
        multiple
      >
        <template #list-header>
          <div class="pa-2 border-b">
            <v-text-field
              density="compact"
              prepend-inner-icon="mdi-magnify"
              hide-details
            />
          </div>
        </template>
        <template #list-footer>
          <div class="d-flex align-center px-4 border-t">
            <span>Show all items</span>
            <v-spacer />
            <v-switch color="purple" hide-details />
          </div>
        </template>
      </v-select>
      <v-btn text="btn after" />
    </v-container>
  </v-app>
</template>

<script setup>
  import { computed, shallowRef } from 'vue'
  const selectedItems = shallowRef([])
  const footerText = computed(() => `${selectedItems.value.length} selected`)
  const items = Array.from({ length: 15 }, (_, i) => ({ id: i, value: i * 10 }))
</script>

Try getting focus within, by opening with , then Tab - focus skips to the v-switch in the footer. We can workaround it with a quick hack, but now any tab or shift+tab escapes the menu.

onFocus={ () => listRef.value?.focus('first') }
tabindex="0"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] VSelect - header/footer slots in the dropdown menu

3 participants