Categories
Vuetify

Vuetify — Dynamic Toolbar Content and System Bar

Vuetify is a popular UI framework for Vue apps.

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

Floating Toolbar with Search

We can add a floating toolbar easily with Vuetify.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card
          class="pa-4"
          flat
          height="300px"
          img="https://cdn.vuetifyjs.com/images/toolbar/map.jpg"
        >
          <v-toolbar dense floating>
            <v-text-field hide-details single-line></v-text-field>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-toolbar>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We add the v-toolbar in a v-card .

The img prop has the URL of the background image as its value.

The floating prop will make it float on top of the card.

Contextual Action Bars

We can add the contextual action bar that changes when some action is taken.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card max-width="500" class="mx-auto">
          <v-toolbar :color="selection.length ? 'grey darken-4' : 'deep-purple accent-4'" dark>
            <v-app-bar-nav-icon v-if="!selection.length"></v-app-bar-nav-icon>
            <v-btn v-else icon @click="selection = []">
              <v-icon>mdi-close</v-icon>
            </v-btn>

            <v-toolbar-title>{{ selection.length ? `${selection.length} selected` : 'App' }}</v-toolbar-title>

            <v-spacer></v-spacer>

            <v-scale-transition>
              <v-btn v-if="selection.length" key="export" icon>
                <v-icon>mdi-export-variant</v-icon>
              </v-btn>
            </v-scale-transition>
            <v-scale-transition>
              <v-btn v-if="selection.length" key="delete" icon>
                <v-icon>mdi-delete</v-icon>
              </v-btn>
            </v-scale-transition>

            <v-btn icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-toolbar>

          <v-card-text>
            <v-select v-model="selection" :items="items" multiple label="Select an option"></v-select>
          </v-card-text>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: ["apple", "orange", "grape"],
    selection: []
  }),
};
</script>

We have the v-scale-transiton component that changes with the selection state.

The selection state is controlled by the v-select component.

We also set the v-toolbar-title text with the selection change.

Also, we change the color prop when the selection changes.

So when we select items from the dropdown, the toolbar will change.

System Bars

A system bar is another kind of toolbar.

It looks like the system bar on an Android phone.

To add one, we use the v-system-bar component:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-system-bar dark color="primary">
          <v-spacer></v-spacer>
          <v-icon>mdi-wifi-strength-5</v-icon>
          <v-icon>mdi-signal-cellular-outline</v-icon>
          <v-icon>mdi-battery</v-icon>
          <span>12:30</span>
        </v-system-bar>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We add a v-system-bar component with some icons inside.

Conclusion

We can add a system bar with some icons and text inside.

Also, we can make the toolbar change when its state changes.

Categories
Vuetify

Vuetify — Breadcrumbs

Vuetify is a popular UI framework for Vue apps.

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

Breadcrumbs

The v-breadcrumbs component lets us display a navigation helper on pages.

It can accept a Material Icons icon or text characters as a divider.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-breadcrumbs :items="items"></v-breadcrumbs>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        text: "Dashboard",
        disabled: false,
        href: "breadcrumbs_dashboard",
      },
      {
        text: "Foo",
        disabled: false,
        href: "foo",
      },
      {
        text: "Bar",
        disabled: true,
        href: "bar",
      },
    ],
  }),
};
</script>

We have the v-breadcrumbs component that takes the items prop.

The prop takes an array with objects that have the text , disabled , and href props.

text is the link text. disabled is the disabled state of the link.

And href is the URL of the link.

We can add a large prop to make it large.

Custom Divider

We can change the divider to a different icon or character with the divider property.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-breadcrumbs :items="items" divider="-"></v-breadcrumbs>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        text: "Dashboard",
        disabled: false,
        href: "breadcrumbs_dashboard",
      },
      {
        text: "Foo",
        disabled: false,
        href: "foo",
      },
      {
        text: "Bar",
        disabled: true,
        href: "bar",
      },
    ],
  }),
};
</script>

to add the - character as the divider.

Icon Dividers

We can add an icon as the breadcrumb divider by writing:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-breadcrumbs :items="items">
          <template v-slot:divider>
            <v-icon>mdi-forward</v-icon>
          </template>
        </v-breadcrumbs>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        text: "Dashboard",
        disabled: false,
        href: "breadcrumbs_dashboard",
      },
      {
        text: "Foo",
        disabled: false,
        href: "foo",
      },
      {
        text: "Bar",
        disabled: true,
        href: "bar",
      },
    ],
  }),
};
</script>

We populate the divider slot with the divider of our choice.

Item Slot

The item slot lets us display the item in a custom format.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-breadcrumbs :items="items">
          <template v-slot:item="{ item }">
            <v-breadcrumbs-item
              :href="item.href"
              :disabled="item.disabled"
            >{{ item.text.toUpperCase() }}</v-breadcrumbs-item>
          </template>
        </v-breadcrumbs>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      {
        text: "Dashboard",
        disabled: false,
        href: "breadcrumbs_dashboard",
      },
      {
        text: "Foo",
        disabled: false,
        href: "foo",
      },
      {
        text: "Bar",
        disabled: true,
        href: "bar",
      },
    ],
  }),
};
</script>

We get the breadcrumb item with the item slot prop and we set the href and format the breadcrumb text to upper case in the slot.

Conclusion

Breadcrumbs lets us add navigation to our page easily.

Categories
Vuetify

Vuetify — Bottom Sheet Content

Vuetify is a popular UI framework for Vue apps.

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

Inset Bottom Sheet

A bottom sheet can be inset, so that the maximum width on the desktop is 70%.

It can be reduced more with the width prop.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div class="text-center">
          <v-bottom-sheet v-model="sheet" inset>
            <template v-slot:activator="{ on, attrs }">
              <v-btn color="orange" dark v-bind="attrs" v-on="on">Open Inset</v-btn>
            </template>
            <v-sheet class="text-center" height="200px">
              <v-btn class="mt-6" text color="error" @click="sheet = !sheet">close</v-btn>
              <div class="my-3">Lorem ipsum</div>
            </v-sheet>
          </v-bottom-sheet>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We add the inset prop to reduce the width of the bottom sheet.

Music Player

The bottom sheet can be used to display a music player.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div class="text-center">
          <v-bottom-sheet inset>
            <template v-slot:activator="{ on, attrs }">
              <v-btn color="red" dark v-bind="attrs" v-on="on">Open Player</v-btn>
            </template>
            <v-card tile>
              <v-progress-linear :value="50" class="my-0" height="3"></v-progress-linear>

<v-list>
                <v-list-item>
                  <v-list-item-content>
                    <v-list-item-title>Violin Sonata No. 9 in A Major, Op. 47</v-list-item-title>
                    <v-list-item-subtitle>Ludwig van Beethoven</v-list-item-subtitle>
                  </v-list-item-content>

                  <v-spacer></v-spacer>

                  <v-list-item-icon>
                    <v-btn icon>
                      <v-icon>mdi-rewind</v-icon>
                    </v-btn>
                  </v-list-item-icon>

<v-list-item-icon :class="{ 'mx-5': $vuetify.breakpoint.mdAndUp }">
                    <v-btn icon>
                      <v-icon>mdi-pause</v-icon>
                    </v-btn>
                  </v-list-item-icon>

                  <v-list-item-icon class="ml-0" :class="{ 'mr-3': $vuetify.breakpoint.mdAndUp }">
                    <v-btn icon>
                      <v-icon>mdi-fast-forward</v-icon>
                    </v-btn>
                  </v-list-item-icon>
                </v-list-item>
              </v-list>
            </v-card>
          </v-bottom-sheet>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We have the v-card inside the v-bottom-sheet which is used as the container for our content.

v-list inside the v-card hs the text.

v-list-item-content has the title and subtitle.

And the v-list-item-icon has the rewind, pause, and fast forward buttons.

Open in List

We can show a list in a bottom sheet.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div class="text-center">
          <v-bottom-sheet v-model="sheet">
            <template v-slot:activator="{ on, attrs }">
              <v-btn color="purple" dark v-bind="attrs" v-on="on">Open In</v-btn>
            </template>
            <v-list>
              <v-subheader>Open in</v-subheader>
              <v-list-item v-for="tile in tiles" :key="tile.title" @click="sheet = false">
                <v-list-item-avatar>
                  <v-avatar size="32px" tile>
                    <img
                      :src="`https://cdn.vuetifyjs.com/images/bottom-sheets/${tile.img}`"
                      :alt="tile.title"
                    />
                  </v-avatar>
                </v-list-item-avatar>
                <v-list-item-title>{{ tile.title }}</v-list-item-title>
              </v-list-item>
            </v-list>
          </v-bottom-sheet>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    sheet: false,
    tiles: [
      { img: "keep.png", title: "Keep" },
      { img: "inbox.png", title: "Inbox" },
      { img: "hangouts.png", title: "Hangouts" },
      { img: "messenger.png", title: "Messenger" },
      { img: "google.png", title: "Google+" },
    ],
  }),
};
</script>

We have the tiles which are rendered as v-list-item s in a v-list .

The v-list is in the v-bottom-sheet .

So we see the list displayed when we open the bottom sheet.

Conclusion

We can have any content in our bottom sheet.

Categories
Vuetify

Vuetify — Bottom Sheet

Vuetify is a popular UI framework for Vue apps.

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

Bottom Nav Bar Scroll Threshold

We can set the scroll-threshold of the v-bottom-navigation to show the navbar depending on the threshold.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden mx-auto" height="200" max-width="500">
          <v-bottom-navigation
            scroll-target="#scroll-area"
            hide-on-scroll
            absolute
            horizontal
            scroll-threshold="500"
          >
            <v-btn text color="deep-purple accent-4">
              <span>History</span>
              <v-icon>mdi-history</v-icon>
            </v-btn>

            <v-btn text color="deep-purple accent-4">
              <span>Favorites</span>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn text color="deep-purple accent-4">
              <span>Map</span>
              <v-icon>mdi-map-marker</v-icon>
            </v-btn>
          </v-bottom-navigation>

          <v-sheet id="scroll-area" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1500px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We add the scroll-threshold prop to set the number of pixels to scroll down until the navbar is shown.

Bottom Sheets

The bottom sheet is another container for content.

It shows at the bottom of the page.

We can add one with the v-bottom-sheet component:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden mx-auto" height="200" max-width="500">
          <v-bottom-sheet v-model="sheet" persistent>
            <template v-slot:activator="{ on, attrs }">
              <v-btn color="green" dark v-bind="attrs" v-on="on">Open Persistent</v-btn>
            </template>
            <v-sheet class="text-center" height="200px">
              <v-btn class="mt-6" text color="error" @click="sheet = !sheet">close</v-btn>
              <div class="py-3">Lorem ipsum</div>
            </v-sheet>
          </v-bottom-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We add the v-bottom-sheet component to show the sheet content when we click on the Open Persistent button.

The Open Persistent button should be in the activator slot to let us toggle the bottom sheet.

The v-model sets the open state of the bottom sheet.

It’ll open when it’s true .

v-model Control

We can use v-model to control the bottom sheet.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div class="text-center">
          <v-btn color="blue" dark @click="sheet = !sheet">Open v-model</v-btn>
          <v-bottom-sheet v-model="sheet">
            <v-sheet class="text-center" height="200px">
              <v-btn class="mt-6" text color="red" @click="sheet = !sheet">close</v-btn>
              <div class="py-3">Lorem ipsum</div>
            </v-sheet>
          </v-bottom-sheet>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We have the Open v-model button to toggle the bottom sheet.

Conclusion

We can add a bottom sheet to display content at the bottom of the page.

It can be toggled.

Categories
Vuetify

Vuetify — Bottom Nav Bar

Vuetify is a popular UI framework for Vue apps.

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

Horizontal Nav Bar

We can add the horizontal prop to make the bottom nav text show beside the icon instead of below it:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-bottom-navigation :value="activeBtn" color="purple lighten-1" horizontal>
          <v-btn>
            <span>History</span>
            <v-icon>mdi-history</v-icon>
          </v-btn>

          <v-btn>
            <span>Favorites</span>
            <v-icon>mdi-heart</v-icon>
          </v-btn>

          <v-btn>
            <span>Map</span>
            <v-icon>mdi-map-marker</v-icon>
          </v-btn>
        </v-bottom-navigation>
      </v-col>
    </v-row>
  </v-container>
</template>

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

Shift

The shift prop lets us hide the button text until it’s active.

The v-btn text in the bar should be wrapped with a span tag.

For instance, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-bottom-navigation :value="activeBtn" color="purple lighten-1" shift>
          <v-btn>
            <span>History</span>
            <v-icon>mdi-history</v-icon>
          </v-btn>

          <v-btn>
            <span>Favorites</span>
            <v-icon>mdi-heart</v-icon>
          </v-btn>

          <v-btn>
            <span>Map</span>
            <v-icon>mdi-map-marker</v-icon>
          </v-btn>
        </v-bottom-navigation>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We just add a shift prop to make the text show only when an icon is clicked.

Toggle

The display state of the v-bottom-navigation can be toggled with the input-value prop.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <div class="overflow-hidden">
          <div class="text-center mb-2">
            <v-btn text color="deep-purple" @click="showNav = !showNav">Toggle Nav</v-btn>
          </div>

<v-bottom-navigation :value="activeBtn" color="purple lighten-1" :input-value="showNav">
            <v-btn>
              <span>History</span>
              <v-icon>mdi-history</v-icon>
            </v-btn>

            <v-btn>
              <span>Favorites</span>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn>
              <span>Map</span>
              <v-icon>mdi-map-marker</v-icon>
            </v-btn>
          </v-bottom-navigation>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We added a v-btn to toggle the nav.

When showNav is true then it’s shown.

Otherwise, it’s hidden.

We set the input-value to show the nav.

Hide on Scroll

We can show the v-bottom-navigation only when the target element is scrolled.

To do that, we add the hide-on-scroll prop with the scroll-target prop set to the selector of them item we’re scrolling.

For example, we can write:

<template>
  <v-container>
    <v-row class="text-center">
      <v-col col="12">
        <v-card class="overflow-hidden mx-auto" height="200" max-width="500">
          <v-bottom-navigation scroll-target="#scroll-area" hide-on-scroll absolute horizontal>
            <v-btn text color="deep-purple accent-4">
              <span>History</span>
              <v-icon>mdi-history</v-icon>
            </v-btn>

            <v-btn text color="deep-purple accent-4">
              <span>Favorites</span>
              <v-icon>mdi-heart</v-icon>
            </v-btn>

            <v-btn text color="deep-purple accent-4">
              <span>Map</span>
              <v-icon>mdi-map-marker</v-icon>
            </v-btn>
          </v-bottom-navigation>

          <v-sheet id="scroll-area" class="overflow-y-auto" max-height="600">
            <v-container style="height: 1500px;"></v-container>
          </v-sheet>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

The scroll-target is added to the v-bottom-navigation component.

hide-on-scroll makes it hide on scroll.

Conclusion

We can make the bottom nav bar behave the way we want with Vuetify.