Categories
Vuetify

Vuetify — Timeline Avatar and Tooltips

Vuetify is a popular UI framework for Vue apps.

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

Timeline Avatar Dots

The dots on the timeline can be avatars.

For example, we can write:

<template>
  <v-timeline>
    <v-timeline-item v-for="n in 3" :key="n" large>
      <template v-slot:icon>
        <v-avatar>
          <img src="http://i.pravatar.cc/64" />
        </v-avatar>
      </template>
      <template v-slot:opposite>
        <span>Tus eu perfecto</span>
      </template>
      <v-card class="elevation-2">
        <v-card-title class="headline">Lorem ipsum</v-card-title>
        <v-card-text>Lorem ipsum dolor sit amet.</v-card-text>
      </v-card>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

We put the avatar icon in the icon slot to show it.

Colored Dots

The dots can be colored.

To change the color, we set the value for the color prop on the v-timeline-item :

<template>
  <v-card class="mx-auto" max-width="400">
    <v-card-text class="py-0">
      <v-timeline align-top dense>
        <v-timeline-item color="pink" small>
          <v-row class="pt-1">
            <v-col cols="3">
              <strong>5pm</strong>
            </v-col>
            <v-col>
              <strong>New Icon</strong>
              <div class="caption">Mobile App</div>
            </v-col>
          </v-row>
        </v-timeline-item>

        <v-timeline-item color="teal lighten-3" small>
          <v-row class="pt-1">
            <v-col cols="3">
              <strong>3-4pm</strong>
            </v-col>
            <v-col>
              <strong>Meeting</strong>
              <div class="caption mb-2">Hangouts</div>
            </v-col>
          </v-row>
        </v-timeline-item>

        <v-timeline-item color="pink" small>
          <v-row class="pt-1">
            <v-col cols="3">
              <strong>12pm</strong>
            </v-col>
            <v-col>
              <strong>Lunch break</strong>
            </v-col>
          </v-row>
        </v-timeline-item>

        <v-timeline-item color="teal lighten-3" small>
          <v-row class="pt-1">
            <v-col cols="3">
              <strong>9-11am</strong>
            </v-col>
            <v-col>
              <strong>Go Home</strong>
              <div class="caption">Web App</div>
            </v-col>
          </v-row>
        </v-timeline-item>
      </v-timeline>
    </v-card-text>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

Tooltips

We can add tooltips with the v-tooltip component.

For instance, we can write:

<template>
  <div class="text-center">
    <v-tooltip left>
      <template v-slot:activator="{ on, attrs }">
        <v-btn color="primary" dark v-bind="attrs" v-on="on">Left</v-btn>
      </template>
      <span>Left tooltip</span>
    </v-tooltip>
  </div>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({}),
};
</script>

The v-tooltip component has the activator slot to let us place the component for activating the tooltip.

The left prop places the tooltip on the left.

The placement of the toolbar can also be changed with the top , bottom , and right props.

We just pass the on event listeners to the v-on directive and the attrs object to the v-bind directive.

Visibility

We can change the visibility of the tooltip with v-model .

For example, we can write:

<template>
  <v-container fluid class="text-center">
    <v-row class="flex" justify="space-between">
      <v-col cols="12">
        <v-btn @click="show = !show">toggle</v-btn>
      </v-col>

     <v-col cols="12" class="mt-12">
        <v-tooltip v-model="show" top>
          <template v-slot:activator="{ on, attrs }">
            <v-btn icon v-bind="attrs" v-on="on">
              <v-icon color="grey lighten-1">mdi-cart</v-icon>
            </v-btn>
          </template>
          <span>Programmatic tooltip</span>
        </v-tooltip>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    show: false,
  }),
};
</script>

We have a Toggle button to toggle the show prop to toggle the tooltip.

v-model on the v-tooltip controls the tooltip.

Conclusion

We can add avatars and timelines and add tooltips with Vuetify.

Categories
Vuetify

Vuetify — Tabs with Other Components

Vuetify is a popular UI framework for Vue apps.

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

Align Tabs with Toolbar Title

We can align tabs with the toolbar title.

To do that, we write:

<template>
  <v-card>
    <v-toolbar color="cyan" dark flat>
      <v-app-bar-nav-icon></v-app-bar-nav-icon>
      <v-toolbar-title>App</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
      <template v-slot:extension>
        <v-tabs v-model="tab" centered slider-color="yellow" align-with-title>
          <v-tab v-for="i in 3" :key="i" :href="`#tab-${i}`">Item {{ i }}</v-tab>
        </v-tabs>
      </template>
    </v-toolbar>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="i in 3" :key="i" :value="`tab-${i}`">
        <v-card flat>
          <v-card-text v-text="'hello world'"></v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
    };
  },
};
</script>

We add the align-with-title prop to align the title with toolbar title.

Dynamic Tabs

We can add tabs that can be dynamically added or removed.

For example, we can write:

<template>
  <v-card>
    <v-tabs v-model="tab" background-color="red lighten-2" dark>
      <v-tab v-for="n in length" :key="n">Item {{ n }}</v-tab>
    </v-tabs>
    <v-card-text class="text-center">
      <v-btn text @click="length--">Remove Tab</v-btn>
      <v-divider class="mx-4" vertical></v-divider>
      <v-btn text @click="length++">Add Tab</v-btn>
    </v-card-text>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    length: 10,
    tab: null,
  }),

  watch: {
    length(val) {
      this.tab = val - 1;
    },
  },
};
</script>

We change the length state to add or remove tabs.

We can do that because we’re using length to render the number of tabs with v-for .

Also, we watch the length so that we change to the last tab once a tab is added or removed.

With Search

We can also add tabs with a search box.

To do that, we write:

<template>
  <v-card>
    <v-toolbar color="purple" dark flat prominent>
      <v-text-field
        append-icon="mic"
        class="mx-4"
        flat
        hide-details
        label="Search"
        prepend-inner-icon="search"
        solo-inverted
      ></v-text-field>

      <template v-slot:extension>
        <v-tabs v-model="tabs" centered>
          <v-tab v-for="n in 3" :key="n">Item {{ n }}</v-tab>
        </v-tabs>
      </template>
    </v-toolbar>

    <v-tabs-items v-model="tabs">
      <v-tab-item>
        <v-card flat>
          <v-card-text>Lorem ipsum dolor sit amet.</v-card-text>
        </v-card>
      </v-tab-item>
      <v-tab-item>
        <v-card flat>
          <v-card-title class="headline">Title</v-card-title>
          <v-card-text>
            <p>Duis lobortis massa imperdiet quam.</p>
          </v-card-text>
        </v-card>
      </v-tab-item>
      <v-tab-item>
        <v-card flat>
          <v-card-title class="headline">Title</v-card-title>
          <v-card-text>
            <p>Maecenas ullamcorpe.</p>
          </v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    tabs: null,
    text: "Lorem ipsum dolor sit amet.",
  }),
};
</script>

The v-text-field is added above the extension slot so that we can see the search box above the tabs.

Conclusion

Tabs can be added to toolbars and added with other elements.

Categories
Vuetify

Vuetify — Tabs Customization

Vuetify is a popular UI framework for Vue apps.

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

Custom Icons

We can change the tab scrolling icons with the prev-icon and next-icon props:

<template>
  <v-card>
    <v-tabs
      v-model="tab"
      background-color="primary"
      show-arrows
      dark
      next-icon="mdi-arrow-right-bold-box-outline"
      prev-icon="mdi-arrow-left-bold-box-outline"
    >
      <v-tab v-for="item in items" :key="item.tab">{{ item.tab }}</v-tab>
    </v-tabs>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="item in items" :key="item.tab">
        <v-card flat>
          <v-card-text>{{ item.content }}</v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
      items: [
        { tab: "One", content: "Tab 1 Content" },
        { tab: "Two", content: "Tab 2 Content" },
        { tab: "Three", content: "Tab 3 Content" },
        { tab: "Four", content: "Tab 4 Content" },
        { tab: "Five", content: "Tab 5 Content" },
      ],
    };
  },
};
</script>

We changed the icons to a bold arrow instead of a regular arrow.

Icons and Text

The tab links can have both an icon and text.

For instance, we can write:

<template>
  <v-card>
    <v-tabs v-model="tab" background-color="deep-purple accent-4" centered dark icons-and-text>
      <v-tabs-slider></v-tabs-slider>

       <v-tab href="#tab-1">
        Recents
        <v-icon>mdi-phone</v-icon>
      </v-tab>

      <v-tab href="#tab-2">
        Favorites
        <v-icon>mdi-heart</v-icon>
      </v-tab>

      <v-tab href="#tab-3">
        Map
        <v-icon>mdi-account-box</v-icon>
      </v-tab>
    </v-tabs>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="i in 3" :key="i" :value="`tab-${i}`">
        <v-card flat>
          <v-card-text>hello world</v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
    };
  },
};
</script>

We have the v-icon inside the v-tab component to add the icon.

The icon will show above the text.

Right-Aligned Tabs

The tabs can be aligned to the right.

For example, we can write:

<template>
  <v-card>
    <v-tabs background-color="white" color="deep-purple accent-4" right>
      <v-tab>Foo</v-tab>
      <v-tab>Bar</v-tab>
      <v-tab>Baz</v-tab>

      <v-tab-item v-for="n in 3" :key="n">
        <v-container fluid>
          <v-row>
            <v-col v-for="i in 6" :key="i" cols="12" md="4">
              <v-img
                :src="`https://picsum.photos/500/300?image=${i}`"
                :lazy-src="`https://picsum.photos/10/6?image=${i}`"
                aspect-ratio="1"
              ></v-img>
            </v-col>
          </v-row>
        </v-container>
      </v-tab-item>
    </v-tabs>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
    };
  },
};
</script>

The right prop makes the tab links align to the right.

Tab and Toolbar

We can put v-tabs inside the extension slow of the v-toolbar .

This will make it show at the bottom of the toolbar.

To do that, we write:

<template>
  <v-card>
    <v-toolbar color="cyan" dark flat>
      <v-app-bar-nav-icon></v-app-bar-nav-icon>
      <v-toolbar-title>App</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
      <template v-slot:extension>
        <v-tabs v-model="tab" centered slider-color="yellow">
          <v-tab v-for="i in 3" :key="i" :href="`#tab-${i}`">Item {{ i }}</v-tab>
        </v-tabs>
      </template>
    </v-toolbar>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="i in 3" :key="i" :value="`tab-${i}`">
        <v-card flat>
          <v-card-text v-text="'hello world'"></v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
    };
  },
};
</script>

The extension slot lets us place the tab links inside the toolbar.

Conclusion

We can add tabs with icons and in different positions.

Categories
Vuetify

Vuetify — Desktop Tabs

Vuetify is a popular UI framework for Vue apps.

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

Desktop Tabs

Tab actions can be represented with single icons.

For example, we can write:

<template>
  <v-card>
    <v-toolbar flat>
      <v-app-bar-nav-icon></v-app-bar-nav-icon>
      <v-toolbar-title>App</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>
      <template v-slot:extension>
        <v-tabs v-model="tabs" fixed-tabs>
          <v-tabs-slider></v-tabs-slider>
          <v-tab href="#mobile-tabs-5-1" class="primary--text">
            <v-icon>mdi-phone</v-icon>
          </v-tab>
          <v-tab href="#mobile-tabs-5-2" class="primary--text">
            <v-icon>mdi-heart</v-icon>
          </v-tab>
          <v-tab href="#mobile-tabs-5-3" class="primary--text">
            <v-icon>mdi-account-box</v-icon>
          </v-tab>
        </v-tabs>
      </template>
    </v-toolbar>

    <v-tabs-items v-model="tabs">
      <v-tab-item v-for="i in 3" :key="i" :value="`mobile-tabs-5-${i}`">
        <v-card flat>
          <v-card-text v-text="text"></v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    tabs: null,
    text: "Lorem ipsum dolor sit amet.",
  }),
};
</script>

We add the v-icon without the text within the v-tab component to add tabs with only icons.

Tabs With Menu

We can add a menu to hold additional tabs.

When we click them, we’ll see the active one moved to the tab bar from the menu.

This can be done with our own logic.

To do that, we write:

<template>
  <v-card>
    <v-toolbar color="deep-purple accent-4" dark flat>
      <v-app-bar-nav-icon></v-app-bar-nav-icon>
      <v-toolbar-title>App</v-toolbar-title>
      <v-spacer></v-spacer>
      <v-btn icon>
        <v-icon>mdi-magnify</v-icon>
      </v-btn>
      <v-btn icon>
        <v-icon>mdi-dots-vertical</v-icon>
      </v-btn>

      <template v-slot:extension>
        <v-tabs v-model="currentItem" fixed-tabs slider-color="white">
          <v-tab v-for="item in items" :key="item" :href="`#tab-${item}`">{{ item }}</v-tab>

          <v-menu v-if="more.length" bottom left>
            <template v-slot:activator="{ on, attrs }">
              <v-btn text class="align-self-center mr-4" v-bind="attrs" v-on="on">
                more
                <v-icon right>mdi-menu-down</v-icon>
              </v-btn>
            </template>

            <v-list class="grey lighten-3">
              <v-list-item v-for="item in more" :key="item" @click="addItem(item)">{{ item }}</v-list-item>
            </v-list>
          </v-menu>
        </v-tabs>
      </template>
    </v-toolbar>

    <v-tabs-items v-model="currentItem">
      <v-tab-item v-for="item in items.concat(more)" :key="item" :value="`tab-${item}`">
        <v-card flat>
          <v-card-text>
            <h2>{{ item }}</h2>
            {{ text }}
          </v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    currentItem: "tab-Web",
    items: ["Web", "Offers", "Videos", "Hames"],
    more: ["News", "Maps", "Books", "Flights", "Play"],
    text:
      "Lorem ipsum dolor sit amet.",
  }),

  methods: {
    addItem(item) {
      const removed = this.items.splice(0, 1);
      this.items.push(...this.more.splice(this.more.indexOf(item), 1));
      this.more.push(...removed);
      this.$nextTick(() => {
        this.currentItem = `tab-${item}`;
      });
    },
  },
};
</script>

In the extension slot, we have the v-tab component with the tabs displayed on the tab bar.

And the v-menu has the additional tab buttons.

When we click on the ones on the menu, the addItem method to remove the entry from the menu and put that on the tab bar by adding it to the items array.

The menu is created with the v-btn component by passing it in the on with the v-on attribute and v-bind has the attributes for the styling the menu button.

v-on has the listeners to make the menu open and close.

Conclusion

We can make tab buttons display in a menu and move it to the tab bar when clicked.

Categories
Vuetify

Vuetify — Tabs

Vuetify is a popular UI framework for Vue apps.

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

Tabs

We can add tabs to our Vuetify app with the v-tabs component.

For example, we can write:

<template>
  <v-tabs fixed-tabs background-color="indigo" dark>
    <v-tab>One</v-tab>
    <v-tab>Two</v-tab>
    <v-tab>Three</v-tab>
  </v-tabs>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

to show tabs.

background-color has the background color.

fixed-tabs makes its position fixed.

dark makes the text of the non-active tabs gray.

The active tab is always centered.

Tab Items

We can add the v-tab-items component to let us customize the content per tab.

For example, we can write:

<template>
  <v-card>
    <v-tabs v-model="tab" background-color="primary" dark>
      <v-tab v-for="item in items" :key="item.tab">{{ item.tab }}</v-tab>
    </v-tabs>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="item in items" :key="item.tab">
        <v-card flat>
          <v-card-text>{{ item.content }}</v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
      items: [
        { tab: "One", content: "Tab 1 Content" },
        { tab: "Two", content: "Tab 2 Content" },
        { tab: "Three", content: "Tab 3 Content" },
        { tab: "Four", content: "Tab 4 Content" },
        { tab: "Five", content: "Tab 5 Content" },
      ],
    };
  },
};
</script>

to add tabs and populate the headings and content.

v-tab has the tab headings and v-tab-items has the tab items.

The tab state has the index of the active tab.

v-model lets us control which tab is active programmatically.

We just render all the tab content with the v-tab-item component and the right one will be displayed automatically.

Grow Tabs

We can add the grow prop to make the tag items take up all available space up to a max-width of 300px:

<template>
  <v-card>
    <v-tabs v-model="tab" background-color="primary" grow dark>
      <v-tab v-for="item in items" :key="item.tab">{{ item.tab }}</v-tab>
    </v-tabs>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="item in items" :key="item.tab">
        <v-card flat>
          <v-card-text>{{ item.content }}</v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
      items: [
        { tab: "One", content: "Tab 1 Content" },
        { tab: "Two", content: "Tab 2 Content" },
        { tab: "Three", content: "Tab 3 Content" },
        { tab: "Four", content: "Tab 4 Content" },
        { tab: "Five", content: "Tab 5 Content" },
      ],
    };
  },
};
</script>

We have the grow prop to make it grow to fix the screen.

Pagination

The show-arrows prop will make the arrow display so that we can scroll through the tabs:

<template>
  <v-card>
    <v-tabs v-model="tab" background-color="primary" show-arrows dark>
      <v-tab v-for="item in items" :key="item.tab">{{ item.tab }}</v-tab>
    </v-tabs>

    <v-tabs-items v-model="tab">
      <v-tab-item v-for="item in items" :key="item.tab">
        <v-card flat>
          <v-card-text>{{ item.content }}</v-card-text>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data() {
    return {
      tab: null,
      items: [
        { tab: "One", content: "Tab 1 Content" },
        { tab: "Two", content: "Tab 2 Content" },
        { tab: "Three", content: "Tab 3 Content" },
        { tab: "Four", content: "Tab 4 Content" },
        { tab: "Five", content: "Tab 5 Content" },
      ],
    };
  },
};
</script>

The arrows will show when the tabs overflow the page.

Conclusion

We can add tabs with the v-tabs and tab content with the v-tab-item component.