Categories
Vuetify

Vuetify — Combobox and File Input

Vuetify is a popular UI framework for Vue apps.

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

Combobox No Data with Chips

We can add a combobox with chips that have no data in it.

To do that, we can populate the no-data slot to provide the context to the user when searching or creating items.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-combobox
          v-model="model"
          :items="items"
          :search-input.sync="search"
          hide-selected
          hint="Maximum of 5 tags"
          label="Add some tags"
          multiple
          persistent-hint
          small-chips
        >
          <template v-slot:no-data>
            <v-list-item>
              <v-list-item-content>
                <v-list-item-title>No results matching {{ search }}</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </template>
        </v-combobox>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: ["Programming", "Vue", "Vuetify"],
    model: ["Vuetify"],
    search: null,
  }),

  watch: {
    model(val) {
      if (val.length > 5) {
        this.$nextTick(() => this.model.pop());
      }
    },
  },
};
</script>

We add the no-data and populate it with text to show when there are no matches.

File Inputs

We can add a file input with the v-file-input component.

For instance, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-file-input multiple label="File input"></v-file-input>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

to add a file input.

The multiple prop allows for multiple file selection.

File Input Accept Formats

We can set the file formats the file input accept with the accept attribute:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-file-input accept="image/*" label="File input"></v-file-input>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

File Input With Chips

We can add file input with chips.

So we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-file-input chips multiple label="File input with chips"></v-file-input>
        <v-file-input small-chips multiple label="File input with small chips"></v-file-input>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

We have the chips and small-chips props with the v-file-input .

Size Display

We can add a file size display with the show-size property.

For instance, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-file-input show-size multiple label="File input"></v-file-input>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

We have the show-size attribute, so the size will be shown.

Counter

We can add a counter prop with the show-size prop to show the total number of files and the size:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-file-input show-size counter multiple label="File input"></v-file-input>
      </v-col>
    </v-row>
  </v-container>
</template>
<script>
export default {
  name: "HelloWorld",
};
</script>

Conclusion

We can add combobox with various kinds of content.

Also, we can add file inputs with the size and counter.

Categories
Vuetify

Vuetify — Footer

Vuetify is a popular UI framework for Vue apps.

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

Footers

We can add a footer with the v-footer component.

For instance, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-card height="150">
          <v-footer absolute class="font-weight-medium">
            <v-col class="text-center" cols="12">
              {{ new Date().getFullYear() }} —
              <strong>ABC Company</strong>
            </v-col>
          </v-footer>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We have the v-footer component with the absolute prop to display the footer at the bottom of the v-card .

Padless Footer

We add the padless prop to remove all the default padding from the footer.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-footer padless class="font-weight-medium">
          <v-col class="text-center" cols="12">
            {{ new Date().getFullYear() }} —
            <strong>ABC Company</strong>
          </v-col>
        </v-footer>
      </v-col>
    </v-row>
  </v-container>
</template>

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

Company Footer

We can create a footer with links:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-footer color="primary lighten-1" padless>
          <v-row justify="center" no-gutters>
            <v-btn
              v-for="link in links"
              :key="link"
              color="white"
              text
              rounded
              class="my-2"
            >{{ link }}</v-btn>
            <v-col class="primary lighten-2 py-4 text-center white--text" cols="12">
              {{ new Date().getFullYear() }} —
              <strong>Vuetify</strong>
            </v-col>
          </v-row>
        </v-footer>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    links: ["Home", "About Us", "Contact Us"],
  }),
};
</script>

We render the buttons with the v-btn component.

And we add the v-col to show another bar below it.

Indigo Footer

We can also make a footer with social media buttons.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-footer dark padless>
          <v-card flat tile class="indigo lighten-1 white--text text-center">
            <v-card-text>
              <v-btn v-for="icon in icons" :key="icon" class="mx-4 white--text" icon>
                <v-icon size="24px">{{ icon }}</v-icon>
              </v-btn>
            </v-card-text>

            <v-card-text
              class="white--text pt-0"
            >Phasellus feugiat arcu sapien, et iaculis ipsum elementum sit amet. Mauris cursus commodo interdum. Praesent ut risus eget metus luctus accumsan id ultrices nunc. Sed at orci sed massa consectetur dignissim a sit amet dui. Duis commodo vitae velit et faucibus. Morbi vehicula lacinia malesuada. Nulla placerat augue vel ipsum ultrices, cursus iaculis dui sollicitudin.</v-card-text>

            <v-divider></v-divider>

            <v-card-text class="white--text">
              {{ new Date().getFullYear() }} —
              <strong>Vuetify</strong>
            </v-card-text>
          </v-card>
        </v-footer>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    icons: ["mdi-facebook", "mdi-twitter", "mdi-linkedin", "mdi-instagram"],
  }),
};
</script>

We have the v-card-text components to show the icons and the text below it.

dark makes the background dark.

padless removes the padding.

Conclusion

We can create footers with various styles with Vuetify.

Categories
Vuetify

Vuetify — Expansion Panel Styles

Vuetify is a popular UI framework for Vue apps.

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

Accordion

We can create an expansion panel with accordion style.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-expansion-panels accordion>
          <v-expansion-panel v-for="(item,i) in 5" :key="i">
            <v-expansion-panel-header>Item</v-expansion-panel-header>
            <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We have the accordion prop to make it display like an accordion.

Focusable

The focusable prop lets us make expansion panel headers focusable.

For instance, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-expansion-panels focusable>
          <v-expansion-panel v-for="(item,i) in 5" :key="i">
            <v-expansion-panel-header>Item</v-expansion-panel-header>
            <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-col>
    </v-row>
  </v-container>
</template>

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

With the focusable prop, the selected expansion panel will have the heading highlighted.

External Control

The v-model prop lets us control which panels are open.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <div>
          <div class="text-center d-flex pb-4">
            <v-btn [@click](http://twitter.com/click "Twitter profile for @click")="all">all</v-btn>
            <div>{{ panel }}</div>
            <v-btn [@click](http://twitter.com/click "Twitter profile for @click")="none">none</v-btn>
          </div>

<v-expansion-panels v-model="panel" multiple>
            <v-expansion-panel v-for="(item,i) in items" :key="i">
              <v-expansion-panel-header>Header {{ item }}</v-expansion-panel-header>
              <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
            </v-expansion-panel>
          </v-expansion-panels>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    panel: [],
    items: 5,
  }),
  methods: {
    all() {
      this.panel = [...Array(this.items).keys()].map((k, i) => i);
    },
    none() {
      this.panel = [];
    },
  },
};
</script>

to create 5 expansion panels.

We have the all method to open all panels.

This works because we have the multiple prop.

The none method closes all the panels by setting this.panel to an empty array.

The v-model on v-expansion-panels controls the open state of the expansion panels.

Custom Icons

We can add custom icons for the top-right icon.

To do that, we write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <div>
          <v-expansion-panels>
            <v-expansion-panel>
              <v-expansion-panel-header>
                Item
                <template v-slot:actions>
                  <v-icon color="primary">$expand</v-icon>
                </template>
              </v-expansion-panel-header>
              <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
            </v-expansion-panel>

            <v-expansion-panel>
              <v-expansion-panel-header disable-icon-rotate>
                Item
                <template v-slot:actions>
                  <v-icon color="teal">mdi-check</v-icon>
                </template>
              </v-expansion-panel-header>
              <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
            </v-expansion-panel>

            <v-expansion-panel>
              <v-expansion-panel-header disable-icon-rotate>
                Item
                <template v-slot:actions>
                  <v-icon color="error">mdi-alert-circle</v-icon>
                </template>
              </v-expansion-panel-header>
              <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
            </v-expansion-panel>
          </v-expansion-panels>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We populate the icon within the actions slot.

Conclusion

We can make expansion panels show in an accordion style.

Also, we can add custom icons to expansion panels.

Categories
Vuetify

Vuetify — Expansion Panels

Vuetify is a popular UI framework for Vue apps.

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

Expansion Panels

The v-expansion-panel component is useful for reducing vertical space with large amount of information.

With the multiple prop, the expansion panel can stay open until it’s closed explicitly.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <div>
          <div class="d-flex">
            <v-checkbox v-model="disabled" label="Disabled"></v-checkbox>
          </div>

          <v-expansion-panels v-model="panel" :disabled="disabled" multiple>
            <v-expansion-panel>
              <v-expansion-panel-header>Panel 1</v-expansion-panel-header>
              <v-expansion-panel-content>Some content</v-expansion-panel-content>
            </v-expansion-panel>

<v-expansion-panel>
              <v-expansion-panel-header>Panel 2</v-expansion-panel-header>
              <v-expansion-panel-content>Some content</v-expansion-panel-content>
            </v-expansion-panel>

            <v-expansion-panel>
              <v-expansion-panel-header>Panel 3</v-expansion-panel-header>
              <v-expansion-panel-content>Some content</v-expansion-panel-content>
            </v-expansion-panel>
          </v-expansion-panels>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    panel: [0, 1],
    disabled: false,
    readonly: false,
  }),
};
</script>

We have the disabled checkbox to disable the panel when we check it.

Also, we have the v-expansion-panels to create the expansion panel container

Then v-expansion-panel component is the expansion panel itself.

The header is displayed and v-expansion-panel-content is displayed when we click on the heading.

The panel state is used for v-model and has the indexes of the panels to open.

Readonly

We can make an expansion panel read-only.

It does the same thing as disabled but doesn’t change the styling.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <div>
          <div class="d-flex">
            <v-checkbox v-model="readonly" label="readonly"></v-checkbox>
          </div>

          <v-expansion-panels v-model="panel" :readonly="readonly" multiple>
            <v-expansion-panel>
              <v-expansion-panel-header>Panel 1</v-expansion-panel-header>
              <v-expansion-panel-content>Some content</v-expansion-panel-content>
            </v-expansion-panel>

<v-expansion-panel>
              <v-expansion-panel-header>Panel 2</v-expansion-panel-header>
              <v-expansion-panel-content>Some content</v-expansion-panel-content>
            </v-expansion-panel>

            <v-expansion-panel>
              <v-expansion-panel-header>Panel 3</v-expansion-panel-header>
              <v-expansion-panel-content>Some content</v-expansion-panel-content>
            </v-expansion-panel>
          </v-expansion-panels>
        </div>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    panel: [0, 1],
    readonly: false,
  }),
};
</script>

Popout

We can make expansion panels have the popout design.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-expansion-panels popout>
          <v-expansion-panel v-for="(item,i) in 5" :key="i">
            <v-expansion-panel-header>Item</v-expansion-panel-header>
            <v-expansion-panel-content>Lorem ipsum.</v-expansion-panel-content>
          </v-expansion-panel>
        </v-expansion-panels>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We just add the popout prop to make the expanded expansion panel wider than the others.

Conclusion

We can add expansion panels to display vertical content that can be expanded.

Categories
Vuetify

Vuetify — Dividing List Items

Vuetify is a popular UI framework for Vue apps.

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

Dividers and Subheaders

We can add dividers to subheaders.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-card>
          <v-toolbar color="orange lighten-1" dark>
            <v-app-bar-nav-icon></v-app-bar-nav-icon>
            <v-toolbar-title>Message Board</v-toolbar-title>
            <v-spacer></v-spacer>
            <v-btn icon>
              <v-icon>mdi-magnify</v-icon>
            </v-btn>
          </v-toolbar>

          <v-list two-line>
            <template v-for="(item, index) in items">
              <v-divider v-if="item.divider" :key="index" inset></v-divider>
              <v-list-item v-else :key="item.title" ripple>
                <v-list-item-avatar>
                  <img :src="item.avatar" />
                </v-list-item-avatar>
                <v-list-item-content>
                  <v-list-item-title v-html="item.title"></v-list-item-title>
                  <v-list-item-subtitle v-html="item.subtitle"></v-list-item-subtitle>
                </v-list-item-content>
              </v-list-item>
            </template>
          </v-list>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
export default {
  name: "HelloWorld",
  data: () => ({
    items: [
      { divider: true },
      {
        avatar: "https://picsum.photos/250/300?image=660",
        title: "Meeting",
        subtitle: "subtitle",
      },
      { divider: true },
      {
        avatar: "https://picsum.photos/250/300?image=146",
        title: "So long",
        subtitle: "subtitle",
      },
      { divider: true },
      {
        avatar: "https://picsum.photos/250/300?image=1008",
        title: "Breakfast",
        subtitle: "subtitle",
      },
    ],
  }),
};
</script>

We added the v-divider dynamically in with the v-divider and v-if directive.

We used it to divide the v-list-item .

v-list-item has the items we’re dividing.

Dividers in Portrait View

Also, we can add dividers in portrait view.

For example, we can write:

<template>
  <v-container>
    <v-row>
      <v-col col="12">
        <v-card>
          <v-card-title class="cyan darken-1">
            <span class="headline white--text">Sarah Smith</span>

            <v-spacer></v-spacer>

            <v-btn dark icon>
              <v-icon>mdi-chevron-left</v-icon>
            </v-btn>

            <v-btn dark icon>
              <v-icon>mdi-pencil</v-icon>
            </v-btn>

            <v-btn dark icon>
              <v-icon>mdi-dots-vertical</v-icon>
            </v-btn>
          </v-card-title>

          <v-list>
            <v-list-item>
              <v-list-item-action>
                <v-icon>mdi-phone</v-icon>
              </v-list-item-action>

              <v-list-item-content>
                <v-list-item-title>123-456-7890</v-list-item-title>
              </v-list-item-content>
              <v-list-item-action>
                <v-icon>mdi-message-text</v-icon>
              </v-list-item-action>
            </v-list-item>

            <v-divider inset></v-divider>

            <v-list-item>
              <v-list-item-action>
                <v-icon>mdi-email</v-icon>
              </v-list-item-action>

              <v-list-item-content>
                <v-list-item-title>sarah@example.com</v-list-item-title>
              </v-list-item-content>
            </v-list-item>

            <v-divider inset></v-divider>

            <v-list-item>
              <v-list-item-action>
                <v-icon>mdi-map-marker</v-icon>
              </v-list-item-action>

              <v-list-item-content>
                <v-list-item-title>New York</v-list-item-title>
              </v-list-item-content>
            </v-list-item>
          </v-list>

          <v-img src="http://placekitten.com/600/200" height="200px"></v-img>
        </v-card>
      </v-col>
    </v-row>
  </v-container>
</template>

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

We have the v-divider between the v-list-item s with the inset props.

This will make the divider shown below the text on the right side.

The icons won’t have the divider below them.

Conclusion

We can add dividers to separate list items.