Ayeye Brazo
Ayeye Brazo

Reputation: 3476

Force collapse of all active items in Vuetify v-list-group

I'm building a navigation inside a permanent drawer using the v-list and I following the guide I completed it.

When the drawer is collapsed it display just the icons, on hover it expand showing the name of the navigation items as well.

A few items are groups and if I click on them I can see sub items.

The issue comes when I wish to force to collapse the active sub items when my drawer collapse.

Here is the code:

<v-navigation-drawer
  v-model="mainSidebarDrawer"
  :mini-variant.sync="mini"
  fixed
  expand-on-hover
  permanent
>
  <v-list>
    <template v-for="(n, i) in nav">
      <v-list-item v-if="n.to" :key="`${i}-a`" :to="n.to" link>
        <v-list-item-icon>
          <v-icon small>{{ n.icon }}</v-icon>
        </v-list-item-icon>
        <v-list-item-content>
          <v-list-item-title>{{ n.label }}</v-list-item-title>
        </v-list-item-content>
      </v-list-item>
      <v-list-group
        v-if="n.subItems"
        :key="`${i}-b`"
        :prepend-icon="`${n.icon} fa-em`"
        :value="subItemsValue" // this looks always false
        append-icon="fas fa-chevron-down fa-sm"
      >
        <template v-slot:activator>
          <v-list-item-content>
            <v-list-item-title>{{ n.label }}</v-list-item-title>
          </v-list-item-content>
        </template>
        <v-list-item
          v-for="(s, y) in n.subItems"
          :key="y"
          :to="s.to"
          link
          class="pl-8"
        >
          <v-list-item-icon>
            <v-icon small>{{ s.icon }}</v-icon>
          </v-list-item-icon>
          <v-list-item-content>
            <v-list-item-title>{{ s.label }}</v-list-item-title>
          </v-list-item-content>
        </v-list-item>
      </v-list-group>
    </template>
  </v-list>
</v-navigation-drawer>

The Vue code has:

data() {
  return {
    mainSidebarDrawer: true,
    mini: true,
    subItemsValue: false
  }
}

So, just to recap:

  1. drawer is collapsed showing just the icons of my navigation list
  2. on hover it expand, icon and text are visible
  3. clicking on a list group it expand the sub-items
  4. moving the mouse away from the drawer cause it to collapse like point 1
  5. list group remain expanded. I wish to collapse it back

What I tried so far is to listen at the mini property and doing this:

<v-navigation-drawer
  ...
  @update:mini-variant="collapseSubItems"
</v-navigation-drawer>

methods: {
  collapseSubItems() {
    if (this.mini) {
      this.subItemsValue = false
    }
  }
}

Unfortunately the subItemsValue never change. I tried also to move it in the v-model.

How can achieve my result? Thanks

Upvotes: 4

Views: 10087

Answers (1)

Carol Skelly
Carol Skelly

Reputation: 362630

I think instead of using a single var like subItemsValue, use an "active" state var on each nav item. Then use the transitionend event to set the open nav item to back to active: false...

<v-navigation-drawer
      v-model="mainSidebarDrawer"
      permanent
      expand-on-hover
      @transitionend="collapseSubItems"
    >
    <v-list>
        <template v-for="(n, i) in nav">
          <v-list-item v-if="n.to" :key="`${i}-a`" :to="n.to" link>
            <v-list-item-icon>
              <v-icon small>{{ n.icon }}</v-icon>
            </v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title>{{ n.label }}</v-list-item-title>
            </v-list-item-content>
          </v-list-item>
          <v-list-group
            v-if="n.subItems"
            :key="`${i}-b`"
            :prepend-icon="`${n.icon} fa-em`"
            v-model="n.active"
            append-icon="fas fa-chevron-down fa-sm"
          >
            <template v-slot:activator>
              <v-list-item-content>
                <v-list-item-title>{{ n.label }}</v-list-item-title>
              </v-list-item-content>
            </template>
            <v-list-item
              v-for="(s, y) in n.subItems"
              :key="y"
              :to="s.to"
              link
              class="pl-8"
            >
              <v-list-item-icon>
                <v-icon small>{{ s.icon }}</v-icon>
              </v-list-item-icon>
              <v-list-item-content>
                <v-list-item-title>{{ s.label }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list-group>
        </template>
     </v-list>
 </v-navigation-drawer>

 collapseSubItems() {
      this.nav.map((item)=>item.active=false)
 },

Demo: https://codeply.com/p/qzrKTPSzrB

Upvotes: 6

Related Questions