Categories
Vuetify

Vuetify — Timelines

Vuetify is a popular UI framework for Vue apps.

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

Timelines

We can use the v-timeline component to display data chronologically.

For example, we can write:

<template>
  <v-timeline :dense="$vuetify.breakpoint.smAndDown">
    <v-timeline-item color="purple lighten-2" fill-dot right>
      <v-card>
        <v-card-title class="purple lighten-2">
          <v-icon dark size="42" class="mr-4">mdi-magnify</v-icon>
          <h2 class="display-1 white--text font-weight-light">Title 1</h2>
        </v-card-title>
        <v-container>
          <v-row>
            <v-col cols="12" md="10">Lorem ipsum dolor sit amet, no nam oblique veritus.</v-col>
            <v-col class="hidden-sm-and-down text-right" md="2">
              <v-icon size="64">mdi-calendar-text</v-icon>
            </v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-timeline-item>

    <v-timeline-item color="amber lighten-1" fill-dot left small>
      <v-card>
        <v-card-title class="amber lighten-1 justify-end">
          <h2 class="display-1 mr-4 white--text font-weight-light">Title 2</h2>
          <v-icon dark size="42">mdi-home-outline</v-icon>
        </v-card-title>
        <v-container>
          <v-row>
            <v-col cols="12" md="8">Lorem ipsum dolor sit amet.</v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-timeline-item>

    <v-timeline-item color="cyan lighten-1" fill-dot right>
      <v-card>
        <v-card-title class="cyan lighten-1">
          <v-icon class="mr-4" dark size="42">mdi-email-outline</v-icon>
          <h2 class="display-1 white--text font-weight-light">Title 3</h2>
        </v-card-title>
        <v-container>
          <v-row>
            <v-col v-for="n in 3" :key="n" cols="12" md="4">Lorem ipsum dolor sit amet.</v-col>
          </v-row>
        </v-container>
      </v-card>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

We have the v-timeline component with the v-timeline-item components inside it.

The v-timeline-item has the cards to display the content we want.

The v-card-title has the title.

And v-container has the content.

The right prop makes the entry display to the right of the line.

The left prop makes the entry display to the left of the line.

fill-dot makes the dot filled.

Icon Dots

We can change the dots on the timeline to be icons instead.

For example, we can write:

<template>
  <v-timeline align-top :dense="$vuetify.breakpoint.smAndDown">
    <v-timeline-item
      v-for="(item, i) in items"
      :key="i"
      :color="item.color"
      :icon="item.icon"
      fill-dot
    >
      <v-card :color="item.color" dark>
        <v-card-title class="title">Lorem Ipsum Dolor</v-card-title>
        <v-card-text class="white text--primary">
          <p>Lorem ipsum dolor sit amet.</p>
          <v-btn :color="item.color" class="mx-0" outlined>Button</v-btn>
        </v-card-text>
      </v-card>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        color: "red lighten-2",
        icon: "mdi-star",
      },
      {
        color: "purple darken-1",
        icon: "mdi-book-variant",
      },
      {
        color: "green lighten-1",
        icon: "mdi-airballoon",
      },
    ],
  }),
};
</script>

We render the items with the v-timeline-item by setting the icon prop to set the icon name to display.

The color prop also changes the color.

Conclusion

We can add a timeline to display items in chronological order

Categories
Vuetify

Vuetify — Timeline Customization

Vuetify is a popular UI framework for Vue apps.

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

Reverse Direction

We can reverse the direction of the timeline items with the reverse prop:

<template>
  <v-timeline align-top :dense="$vuetify.breakpoint.smAndDown" reverse>
    <v-timeline-item
      v-for="(item, i) in items"
      :key="i"
      :color="item.color"
      :icon="item.icon"
      fill-dot
    >
      <v-card :color="item.color" dark>
        <v-card-title class="title">Lorem Ipsum Dolor</v-card-title>
        <v-card-text class="white text--primary">
          <p>Lorem ipsum dolor sit amet.</p>
          <v-btn :color="item.color" class="mx-0" outlined>Button</v-btn>
        </v-card-text>
      </v-card>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        color: "red lighten-2",
        icon: "mdi-star",
      },
      {
        color: "purple darken-1",
        icon: "mdi-book-variant",
      },
      {
        color: "green lighten-1",
        icon: "mdi-airballoon",
      },
    ],
  }),
};
</script>

Timeline Card

We can place a v-card in a v-timeline-item component.

A caret will appear on the side of the card.

For example, we can write:

<template>
  <v-timeline>
    <v-timeline-item v-for="n in 3" :key="n" color="red lighten-2" large>
      <template v-slot:opposite>
        <span>Foo</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>

The opposite slot has some text.

And the cards will be displayed on the side opposite of the opposite slot.

Dense Alert

We can make the timeline smaller with the dense prop.

For example, we can write:

<template>
  <v-card class="mx-auto" max-width="600">
    <v-card-title class="blue-grey white--text">
      <span class="title">Logs</span>
    </v-card-title>
    <v-card-text class="py-0">
      <v-timeline dense>
        <v-slide-x-reverse-transition group hide-on-leave>
          <v-timeline-item v-for="item in items" :key="item.id" :color="item.color" small fill-dot>
            <v-alert
              :value="true"
              :color="item.color"
              :icon="item.icon"
              class="white--text"
            >Lorem ipsum dolor sit amet.</v-alert>
          </v-timeline-item>
        </v-slide-x-reverse-transition>
      </v-timeline>
    </v-card-text>
  </v-card>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        id: 1,
        color: "red lighten-2",
        icon: "mdi-star",
      },
      {
        id: 2,
        color: "purple darken-1",
        icon: "mdi-book-variant",
      },
      {
        id: 3,
        color: "green lighten-1",
        icon: "mdi-airballoon",
      },
    ],
  }),
};
</script>

We added the dense prop to the v-timeline to display items in a compressed form.

The entries will all be on the right side and they’re smaller than the default size.

Opposite Slot

The opposite slot lets us put items to the opposite side of the timeline item.

For example, we can write:

<template>
  <v-timeline>
    <v-timeline-item v-for="(year, i) in years" :key="i" :color="year.color" small>
      <template v-slot:opposite>
        <span :class="`headline font-weight-bold ${year.color}--text`" v-text="year.year"></span>
      </template>
      <div class="py-4">
        <h2 :class="`headline font-weight-light mb-4 ${year.color}--text`">Lorem ipsum</h2>
        <div>Lorem ipsum dolor sit amet.</div>
      </div>
    </v-timeline-item>
  </v-timeline>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    years: [
      {
        color: "cyan",
        year: "1960",
      },
      {
        color: "green",
        year: "1970",
      },
      {
        color: "pink",
        year: "1980",
      },
    ],
  }),
};
</script>

We have the opposite slot to add items to the opposite side of our main timeline item content.

Conclusion

We can add timeline items in various ways with Vuetify.

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.