Categories
Vuetify

Vuetify — Overlays

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Overlays

We can add overlays with the v-overlay component.

It’s used to provide emphasis on particular elements or parts of it.

And it’s useful for signaling state change.

We can create one by writing:

<template>
  <v-row align="center" justify="center">
    <v-card height="300" width="250">
      <v-row justify="center">
        <v-btn color="success" class="mt-12" @click="overlay = !overlay">Show Overlay</v-btn>

        <v-overlay :absolute="absolute" :value="overlay">
          <v-btn color="success" @click="overlay = false">Hide Overlay</v-btn>
        </v-overlay>
      </v-row>
    </v-card>
  </v-row>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    absolute: true,
    overlay: false,
  }),
};
</script>

We have the v-btn component to add a button to show an overlay.

And we have the v-overlay component that’s triggered by clicking the button.

The absolute prop makes it positioned with an absolute position.

value lets us set the overlay.

Opacity

We can change the opacity of the v-overlay component.

For example, we can write:

<template>
  <v-row align="center" justify="center">
    <v-card height="300" width="250">
      <v-row justify="center">
        <v-btn color="orange lighten-2" class="mt-12" @click="overlay = !overlay">Show Overlay</v-btn>

        <v-overlay :absolute="absolute" :opacity="opacity" :value="overlay">
          <v-btn color="orange lighten-2" @click="overlay = false">Hide Overlay</v-btn>
        </v-overlay>
      </v-row>
    </v-card>
  </v-row>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    absolute: true,
    opacity: 1,
    overlay: false,
  }),
};
</script>

The opacity prop lets us change the opacity of the v-overlay .

Z Index

The z-index of the overlay can be changed with the z-index prop.

For example, we can write:

<template>
  <v-row justify="center">
    <v-btn class="white--text" color="teal" @click="overlay = !overlay">Show Overlay</v-btn>

    <v-overlay :z-index="zIndex" :value="overlay">
      <v-btn class="white--text" color="teal" @click="overlay = false">Hide Overlay</v-btn>
    </v-overlay>
  </v-row>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    overlay: false,
    zIndex: 0,
  }),
};
</script>

We change the z-index prop to the value we want to place it above other elements.

Loader

The overlay can have a loader icon placed on top of it.

For example, we can write:

<template>
  <div class="text-center">
    <v-btn color="deep-purple accent-4" class="white--text" @click="overlay = !overlay">
      Launch Application
      <v-icon right>mdi-open-in-new</v-icon>
    </v-btn>

    <v-overlay :value="overlay">
      <v-progress-circular indeterminate size="64"></v-progress-circular>
    </v-overlay>
  </div>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    overlay: false,
  }),

  watch: {
    overlay(val) {
      val &&
        setTimeout(() => {
          this.overlay = false;
        }, 3000);
    },
  },
};
</script>

The v-overlay component has the v-progress-circular component to display the circular progress display.

The overlay watcher sets the this.overlay to false after 3 seconds.

Advanced Overlays

We can have overlays that go over a card.

For example, we can write:

<template>
  <v-hover>
    <template v-slot:default="{ hover }">
      <v-card class="mx-auto" max-width="344">
        <v-img src="https://cdn.vuetifyjs.com/images/cards/forest-art.jpg"></v-img>

        <v-card-text>
          <h2 class="title primary--text">Forests</h2>
          <p>Lorem ipsum</p>
        </v-card-text>

        <v-card-title>
          <v-rating :value="4" dense color="orange" background-color="orange" hover class="mr-2"></v-rating>
          <span class="primary--text subtitle-2">100 Reviews</span>
        </v-card-title>

        <v-fade-transition>
          <v-overlay v-if="hover" absolute color="#036358">
            <v-btn>See more info</v-btn>
          </v-overlay>
        </v-fade-transition>
      </v-card>
    </template>
  </v-hover>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    overlay: false,
  }),
};
</script>

The v-fade-transition adds the transition effect when we display the overlay.

The v-overlay is inside the the v-fade-transition component.

Conclusion

We can add overlays with the v-overlay component with Vuetify.

Categories
Vuetify

Vuetify — Temporary Drawer

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Temporary Drawer

We can create a temporary drawer that sits above the app and use an overlay to darken the background.

Clicking outside the drawer will cause it to close.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-sheet height="400" class="overflow-hidden" style="position: relative;">
        <v-container class="fill-height">
          <v-row align="center" justify="center">
            <v-btn color="pink" dark @click.stop="drawer = !drawer">Toggle</v-btn>
          </v-row>
        </v-container>

        <v-navigation-drawer v-model="drawer" absolute temporary>
          <v-list-item>
            <v-list-item-avatar>
              <v-img src="https://randomuser.me/api/portraits/men/78.jpg"></v-img>
            </v-list-item-avatar>

            <v-list-item-content>
              <v-list-item-title>John Smith</v-list-item-title>
            </v-list-item-content>
          </v-list-item>

          <v-divider></v-divider>

          <v-list dense>
            <v-list-item v-for="item in items" :key="item.title" link>
              <v-list-item-icon>
                <v-icon>{{ item.icon }}</v-icon>
              </v-list-item-icon>

              <v-list-item-content>
                <v-list-item-title>{{ item.title }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list>
        </v-navigation-drawer>
      </v-sheet>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    drawer: null,
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We have the v-navigation-drawer component to add the drawer that opens when we click on the Toggle button.

The Toggle button is created with a v-btn component with the click listener.

We just toggle the drawer variable between true and false to toggle the menu.

The drawer state is used by the v-navigation-drawer ‘s v-model directive to control the opening and closing of the drawer.

The drawer items are in the v-list-item components.

Right Positioned Menu

We can position the menu on the right side of the screen.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card height="350px">
        <v-navigation-drawer absolute permanent right>
          <template v-slot:prepend>
            <v-list-item two-line>
              <v-list-item-avatar>
                <img src="https://randomuser.me/api/portraits/women/81.jpg" />
              </v-list-item-avatar>

<v-list-item-content>
                <v-list-item-title>Jane Smith</v-list-item-title>
                <v-list-item-subtitle>Logged In</v-list-item-subtitle>
              </v-list-item-content>
            </v-list-item>
          </template>

<v-divider></v-divider>

<v-list dense>
            <v-list-item v-for="item in items" :key="item.title">
              <v-list-item-icon>
                <v-icon>{{ item.icon }}</v-icon>
              </v-list-item-icon>

              <v-list-item-content>
                <v-list-item-title>{{ item.title }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list>
        </v-navigation-drawer>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    drawer: null,
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

to place it on the right with the right prop.

Conclusion

We add the temporary drawer and place it on the left or right side of the screen with Vuetify.

Categories
Vuetify

Vuetify — Menu Transitions and Positions

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Menu Custom Transitions

Custom transitions can be added to menus.

Vuetify comes with 3 standard transitions, which are scale , slide-x and slide-y .

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-menu bottom origin="center center" transition="scale-transition">
      <template v-slot:activator="{ on, attrs }">
        <v-btn color="primary" dark v-bind="attrs" v-on="on">Scale Transition</v-btn>
      </template>

      <v-list>
        <v-list-item v-for="(item, i) in items" :key="i">
          <v-list-item-title>{{ item.title }}</v-list-item-title>
        </v-list-item>
      </v-list>
    </v-menu>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We have the transition prop to set the transition effect.

The on object is passed in as the value of v-on .

This lets us listen to events for the menu.

And attrs are props that we passed into v-bind so that we can set the props to show the menu.

The other choices for the transition prop are slide-x-transition and slide-y-transition .

Disabled Menu

We can disable the menu with the disabled prop.

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-menu bottom origin="center center" transition="scale-transition" disabled>
      <template v-slot:activator="{ on, attrs }">
        <v-btn color="primary" dark v-bind="attrs" v-on="on">Menu</v-btn>
      </template>

<v-list>
        <v-list-item v-for="(item, i) in items" :key="i">
          <v-list-item-title>{{ item.title }}</v-list-item-title>
        </v-list-item>
      </v-list>
    </v-menu>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

then the button won’t open the menu.

X Offset

We can move the menu horizontally to make the activator visible.

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-col cols="12">
      <v-menu bottom origin="center center" transition="scale-transition" offset-x>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">Menu</v-btn>
        </template>

        <v-list>
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We move the menu to the right of the button with the offset-x prop.

Y Offset

Similarly, we can move the menu vertically.

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-col cols="12">
      <v-menu bottom origin="center center" transition="scale-transition" offset-y>
        <template v-slot:activator="{ on, attrs }">
          <v-btn color="primary" dark v-bind="attrs" v-on="on">Menu</v-btn>
        </template>

        <v-list>
          <v-list-item v-for="(item, i) in items" :key="i">
            <v-list-item-title>{{ item.title }}</v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

to move the menu above the menu button.

Conclusion

We can add menus with different transitions and positions.

Categories
Vuetify

Vuetify — Menus and Drawers

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Menus

We can place menus in any component.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12" sm="6" offset-sm="3">
      <v-card height="200px">
        <v-card-title class="blue white--text">
          <span class="headline">Menu</span>

          <v-spacer></v-spacer>

          <v-menu bottom left>
            <template v-slot:activator="{ on, attrs }">
              <v-btn dark icon v-bind="attrs" v-on="on">
                <v-icon>mdi-dots-vertical</v-icon>
              </v-btn>
            </template>

            <v-list>
              <v-list-item v-for="(item, i) in items" :key="i">
                <v-list-item-title>{{ item.title }}</v-list-item-title>
              </v-list-item>
            </v-list>
          </v-menu>
        </v-card-title>

        <v-card-text>Lorem Ipsum</v-card-text>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We put our v-menu in the v-card component.

Then v-menu has the bottom and left props so that we can place it at the bottom left of the card.

Navigation Drawers

To add a navigation drawer, we can add the v-navigation-drawer component.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="mx-auto" height="400" width="256">
        <v-navigation-drawer class="deep-purple accent-4" dark permanent>
          <v-list>
            <v-list-item v-for="item in items" :key="item.title" link>
              <v-list-item-icon>
                <v-icon>{{ item.icon }}</v-icon>
              </v-list-item-icon>

              <v-list-item-content>
                <v-list-item-title>{{ item.title }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list>

          <template v-slot:append>
            <div class="pa-2">
              <v-btn block>Logout</v-btn>
            </div>
          </template>
        </v-navigation-drawer>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We have the v-list to show a list of items.

This is put inside the v-navigation-drawer to make it show in the drawer.

Permanent Floating Drawer

We can add a navigation drawer that floats on the page.

For example, we can write:

<template>
  <v-row>
    <v-col cols="12">
      <v-card class="pa-12" color="indigo darken-2" flat>
        <v-card elevation="12" width="256">
          <v-navigation-drawer floating permanent>
            <v-list dense rounded>
              <v-list-item v-for="item in items" :key="item.title" link>
                <v-list-item-icon>
                  <v-icon>{{ item.icon }}</v-icon>
                </v-list-item-icon>

                <v-list-item-content>
                  <v-list-item-title>{{ item.title }}</v-list-item-title>
                </v-list-item-content>
              </v-list-item>
            </v-list>
          </v-navigation-drawer>
        </v-card>
      </v-card>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We have the menu floating on the page with the permanent and floating props.

Conclusion

We can add the various kinds of menus with Vuetify.

Categories
Vuetify

Vuetify — Menus and Context Menu

Vuetify is a popular UI framework for Vue apps.

In this article, we’ll look at how to work with the Vuetify framework.

Rounded

We round the menu corners with the rounded prop.

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-col cols="12">
      <v-menu rounded="rounded" offset-y>
        <template v-slot:activator="{ attrs, on }">
          <v-btn color="primary" class="white--text ma-8" v-bind="attrs" v-on="on">Menu</v-btn>
        </template>

        <v-list>
          <v-list-item v-for="item in items" :key="item.title" link>
            <v-list-item-title v-text="item.title"></v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

We set the rounded prop to rounded so that we can have a big menu.

Close on Click

Menus can be closed when focus is lost.

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-col cols="12">
      <v-menu close-on-click>
        <template v-slot:activator="{ attrs, on }">
          <v-btn color="primary" class="white--text ma-8" v-bind="attrs" v-on="on">Menu</v-btn>
        </template>

        <v-list>
          <v-list-item v-for="item in items" :key="item.title" link>
            <v-list-item-title v-text="item.title"></v-list-item-title>
          </v-list-item>
        </v-list>
      </v-menu>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
};
</script>

The close-on-click will make the menu close on click.

Absolute Position without Activator

We can place our menu with absolute position without a component to trigger it.

For example, we can write:

<template>
  <v-row justify="space-around">
    <v-col cols="12">
      <div>
        <v-row class="flex" justify="center">
          <v-card
            :ripple="false"
            class="portrait"
            img="https://placekitten.com/600/600"
            height="300px"
            width="300px"
            @contextmenu="show"
          ></v-card>
        </v-row>

<v-menu v-model="showMenu" :position-x="x" :position-y="y" absolute offset-y>
          <v-list>
            <v-list-item v-for="(item, index) in items" :key="index">
              <v-list-item-title>{{ item.title }}</v-list-item-title>
            </v-list-item>
          </v-list>
        </v-menu>
      </div>
    </v-col>
  </v-row>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    showMenu: false,
    x: 0,
    y: 0,
    items: [
      { title: "Click Me" },
      { title: "Click Me 2" },
      { title: "Click Me 3" },
    ],
  }),
  methods: {
    show(e) {
      e.preventDefault();
      this.showMenu = false;
      this.x = e.clientX;
      this.y = e.clientY;
      this.$nextTick(() => {
        this.showMenu = true;
      });
    },
  },
};
</script>

We have the card that has the contextmenu event listener to listen to right clicks.

When we right-click on the card, the show method is run.

We set the showMenu state to false to clear the existing menu.

And set the x and y states are set so that we positon the menu to where the right click is done.

We set x and y to the position-x and position-y props to set the menu position.

Also, we need the absolute prop to make the menu position in absolute position.

Conclusion

We can make the menu rounded and create a context menu with Vuetify.