Categories
Buefy

Buefy — Snackbar and Steppers

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Snackbar

A snackbar is a simple popup component.

We call the this.$buefy.snackbar.open method to open it:

<template>
  <section>
    <button class="button is-medium" @click="snackbar">Launch snackbar</button>
  </section>
</template>

<script>
export default {
  methods: {
    snackbar() {
      this.$buefy.snackbar.open(`snackbar`);
    }
  }
};
</script>

We can add more options to it”

<template>
  <section>
    <button class="button is-medium" @click="snackbar">Launch snackbar</button>
  </section>
</template>

<script>
export default {
  methods: {
    snackbar() {
      this.$buefy.snackbar.open({
        duration: 5000,
        message: "<b>snackbar</b>",
        type: "is-danger",
        position: "is-bottom-left",
        actionText: "Undo",
        queue: false,
        onAction: () => {
          this.$buefy.toast.open({
            message: "Action pressed",
            queue: false
          });
        }
      });
    }
  }
};
</script>

duration sets how long it’s shown in milliseconds.

message sets the message text. It can include HTML.

type sets the color of the snackbar text.

position sets the position.

actionText sets the text of the action.

queue sets whether the snackbar should queue with other notices.

onAction is run when the action text is clicked.

Steps

Buefy comes with a stepper to display the steps that users should take.

For example, we can write:

<template>
  <section>
    <b-steps
      v-model="activeStep"
      :animated="isAnimated"
      :rounded="isRounded"
      :has-navigation="hasNavigation"
      :icon-prev="prevIcon"
      :icon-next="nextIcon"
      :label-position="labelPosition"
      :mobile-mode="mobileMode"
      icon-pack="fa"
    >
      <b-step-item step="1" label="First" :clickable="isStepsClickable">
        <h1 class="title has-text-centered">Account</h1>
      </b-step-item>

      <b-step-item
        step="2"
        label="Second"
        :clickable="isStepsClickable"
        :type="{'is-success': isProfileSuccess}"
      >
        <h1 class="title has-text-centered">Profile</h1>
      </b-step-item>

      <b-step-item step="3" :visible="showSocial" label="Social" :clickable="isStepsClickable">
        <h1 class="title has-text-centered">Social</h1>
      </b-step-item>

      <b-step-item
        :step="showSocial ? '4' : '3'"
        label="Finish"
        :clickable="isStepsClickable"
        disabled
      >
        <h1 class="title has-text-centered">Finish</h1>
      </b-step-item>

      <template v-if="customNavigation" slot="navigation" slot-scope="{previous, next}">
        <b-button
          outlined
          type="is-danger"
          icon-pack="fa"
          icon-left="arrow-circle-left"
          :disabled="previous.disabled"
          @click.prevent="previous.action"
        >Previous</b-button>
        <b-button
          outlined
          type="is-success"
          icon-pack="fa"
          icon-right="arrow-circle-right"
          :disabled="next.disabled"
          @click.prevent="next.action"
        >Next</b-button>
      </template>
    </b-steps>
  </section>
</template>

<script>
export default {
  data() {
    return {
      activeStep: 0,

      showSocial: false,
      isAnimated: true,
      isRounded: true,
      isStepsClickable: false,

      hasNavigation: true,
      customNavigation: false,
      isProfileSuccess: false,

      prevIcon: "arrow-circle-left",
      nextIcon: "arrow-circle-right",
      labelPosition: "bottom",
      mobileMode: "minimalist"
    };
  }
};
</script>

We add the b-steps component to add the steps.

b-step-item has the content that we display below the step number.

icon-prev has the icon for the previous button.

icon-next has the icon for the next button.

animated lets us enable or disable animation.

rounded lets us make the step icon rounded.

icon-pack sets the icon pack to use.

'fa' is for Font Awesome.

has-navigation enables or disables navigation buttons.

The icons are added by the link tag:

<link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
      integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
      crossorigin="anonymous"
    />

with the public/index.html.

The navigation slot lets us add our own navigation controls.

previous and next has the methods to let us go forward and backward.

disabled lets us know when to disable the nav buttons.

Conclusion

We can add notifications and steps display with Buefy.

Categories
Buefy

Buefy — Loading Placeholder and Sidebar

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Skeleton Loading Placeholder

Buefy comes with a skeleton component that we can use as a placeholder to show when content is loading.

To add it, we can use the b-skeleton component:

<template>
  <section>
    <b-skeleton width="20%" animated></b-skeleton>
    <b-skeleton width="40%" animated></b-skeleton>
    <b-skeleton width="60%" animated></b-skeleton>
    <b-skeleton width="80%" animated></b-skeleton>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {}
};
</script>

width has the width of the bar as the percentage of the screen viewport.

animated makes it animated.

Also, we can add a circle placeholder with the circle prop:

<template>
  <section>
    <figure class="media-left">
      <p class="image is-64x64">
        <b-skeleton circle width="64px" height="64px"></b-skeleton>
      </p>
    </figure>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {}
};
</script>

Sidebar

We can add a sidebar with the b-sidebar component.

For instance, we can write:

<template>
  <section>
    <b-sidebar
      type="is-light"
      :fullheight="fullheight"
      :fullwidth="fullwidth"
      :overlay="overlay"
      :right="right"
      v-model="open"
    >
      <div class="p-1">
        <img src="https://picsum.photos/id/1/100/50" alt="logo">
        <b-menu>
          <b-menu-list label="Menu">
            <b-menu-item label="Info"></b-menu-item>
            <b-menu-item icon="settings">
              <template slot="label" slot-scope="props">Administrator
                <b-icon class="is-pulled-right" :icon="props.expanded ? 'menu-down' : 'menu-up'"></b-icon>
              </template>
              <b-menu-item label="Users"></b-menu-item>
              <b-menu-item>
                <template slot="label">Devices
                  <b-dropdown aria-role="list" class="is-pulled-right" position="is-bottom-left">
                    <b-icon icon="dots-vertical" slot="trigger"></b-icon>
                    <b-dropdown-item>action 1</b-dropdown-item>
                    <b-dropdown-item>action 2</b-dropdown-item>
                  </b-dropdown>
                </template>
              </b-menu-item>
            </b-menu-item>
          </b-menu-list>
          <b-menu-list label="Actions">
            <b-menu-item label="Logout"></b-menu-item>
          </b-menu-list>
        </b-menu>
      </div>
    </b-sidebar>
  </section>
</template>

<script>
export default {
  data() {
    return {
      open: true,
      overlay: true,
      fullheight: true,
      fullwidth: false,
      right: false
    };
  }
};
</script>

<style>
.p-1 {
  padding: 1em;
}
</style>

to add a sidebar with the b-sidebar component.

type sets the color style.

fullHeight makes it full height.

fullWidth makes it full width.

overlay add an overlay below the sidebar.

right makes it display on the right.

v-model controls the open state of the sidebar.

We can make it static with the position prop et to 'static' :

<template>
  <section>
    <b-sidebar
      position="static"
      :fullheight="fullheight"
      :fullwidth="fullwidth"
      :right="right"
      v-model="open"
    >
      <div class="p-1">
        <img src="https://picsum.photos/id/1/100/50" alt="logo">
        <b-menu>
          <b-menu-list label="Menu">
            <b-menu-item label="Info"></b-menu-item>
            <b-menu-item icon="settings">
              <template slot="label" slot-scope="props">Administrator
                <b-icon class="is-pulled-right" :icon="props.expanded ? 'menu-down' : 'menu-up'"></b-icon>
              </template>
              <b-menu-item label="Users"></b-menu-item>
              <b-menu-item>
                <template slot="label">Devices
                  <b-dropdown aria-role="list" class="is-pulled-right" position="is-bottom-left">
                    <b-icon icon="dots-vertical" slot="trigger"></b-icon>
                    <b-dropdown-item>action 1</b-dropdown-item>
                    <b-dropdown-item>action 2</b-dropdown-item>
                  </b-dropdown>
                </template>
              </b-menu-item>
            </b-menu-item>
          </b-menu-list>
          <b-menu-list label="Actions">
            <b-menu-item label="Logout"></b-menu-item>
          </b-menu-list>
        </b-menu>
      </div>
    </b-sidebar>
  </section>
</template>

<script>
export default {
  data() {
    return {
      open: true,
      overlay: true,
      fullheight: true,
      fullwidth: false,
      right: false
    };
  }
};
</script>

<style>
.p-1 {
  padding: 1em;
}
</style>

Conclusion

We can add placeholders to show when content is loading and a sidebar with Buefy.

Categories
Vue

Add Photo Tiles to a Vue App with the vue-masonry Plugin

We can add a photo grid easily to a Vue app easily with the vue-masonry plugin.

In this article, we’ll look at how to add photo tiles with it.

Installation

We can install it by running:

npm install vue-masonry --save

or add it with a script tag:

<script src="https://unpkg.com/vue-masonry@0.11.3/dist/vue-masonry-plugin-window.js"></script>

If we install the package, then we register the plugin by writing:

import Vue from "vue";
import App from "./App.vue";
import { VueMasonryPlugin } from "vue-masonry";
Vue.use(VueMasonryPlugin);
Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App)
}).$mount("#app");

in main.js .

If we add the script tag, then we write:

var VueMasonryPlugin = window["vue-masonry-plugin"].VueMasonryPlugin
Vue.use(VueMasonryPlugin)

to register it.

Usage

Once we did that, we write:

<template>
  <div id="app">
    <div v-masonry transition-duration="0.3s" item-selector=".item">
      <div v-masonry-tile class="item" v-for="n in 100" :key="n">
        <img :src="`https://picsum.photos/id/${n}/200/300`">
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

to add the photo grid.

The v-masonry-tile makes the div a tile.

v-masonry makes an element the container for the photo grid.

transition-duration is how long a transition runs.

item-selector has the DOM item selector for the list element.

Other props includes column-width for setting the column width with a number.

origin-left sets the group elements to the right instead of the left if it’s false .

origin-top sets the group elements to the bottom instead of the top if it’s false .

stamp specifies which elements are stamped with the layout.

fit-width sets the width of the container to fit the available number of columns.

stagger sets the duration to stagger the item transition so items transition incrementally one after the other.

For example, we can write:

stagger="0.03s"

to set it.

destroy-detail is the duration in milliseconds to wait before unloading the masonry tiles via masonry.destroy() .

We can also trigger redraw manually with the this.$redrawVueMasonry(‘containerId’) method.

containerId is the ID of the block where we want to trigger the redraw.

Conclusion

We can add a photo masonry grid to a Vue app easily with the vue-masonry package.

Categories
Buefy

Buefy — Pagination and Progress Bar

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Pagination

Buefy comes with a pagination component.

We can add it with the b-pagination component:

<template>
  <section>
    <b-pagination
      :total="total"
      v-model="current"
      :range-before="rangeBefore"
      :range-after="rangeAfter"
      :order="order"
      :size="size"
      :simple="isSimple"
      :rounded="isRounded"
      :per-page="perPage"
      :icon-prev="prevIcon"
      :icon-next="nextIcon"
      :iconPack="iconPack"
    ></b-pagination>
  </section>
</template>

<script>
export default {
  data() {
    return {
      total: 200,
      current: 10,
      perPage: 10,
      rangeBefore: 3,
      rangeAfter: 1,
      order: "",
      size: "",
      isSimple: false,
      isRounded: false,
      iconPack: "fa",
      prevIcon: "arrow-circle-left",
      nextIcon: "arrow-circle-right"
    };
  },
  methods: {}
};
</script>

iconPack has the icon pack to use.

'fa' is for Font Awesome.

prevIcon has the icon for going to the previous page.

nextIcon has the icon for going to the next page.

current has the current page.

total is the total number of pages.

perPage has the number of entries per page.

We add the icons by putting:

<link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
      integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
      crossorigin="anonymous"
    />

in the head tag of public/index.html .

Progress

We can add the progress bar with the b-progress component:

<template>
  <section>
    <b-progress></b-progress>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {}
};
</script>

Since the value prop isn’t set, it’ll animate indefinitely.

We can set the progress value with the value prop:

<template>
  <section>
    <b-progress :value="80" show-value format="percent"></b-progress>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {}
};
</script>

format has the text form to show in the bar.

The size prop changes the size:

<template>
  <section>
    <b-progress size="is-large"></b-progress>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {}
};
</script>

We can add other props to it:

<template>
  <section>
    <b-progress
      :type="type"
      :size="size"
      :max="50000"
      :value="indeterminate ? undefined : 40000"
      :show-value="showValue"
      :format="format"
      :precision="precision"
      :keep-trailing-zeroes="keepTrailingZeroes"
      :locale="locale"
    ></b-progress>
  </section>
</template>

<script>
export default {
  data() {
    return {
      indeterminate: false,
      type: null,
      size: "is-medium",
      showValue: true,
      format: "raw",
      precision: 2,
      keepTrailingZeroes: false,
      locale: undefined
    };
  },
  methods: {}
};
</script>

keepTrailingZeroes lets us set whether to show the railing zeroes in the value.

format is the number format.

indeterminate lets us set whether to animate forever.

size has the size.

showValue lets us set whether to show the value.

We can customize the value display by populating the default slot:

<template>
  <section>
    <b-progress :value="65" size="is-medium" show-value>65 / 100</b-progress>
  </section>
</template>

<script>
export default {
  data() {
    return {};
  },
  methods: {}
};
</script>

Conclusion

We an add pagination links and progress bars with Buefy.

Categories
Buefy

Buefy — Navbars and Notifications

Buefy is a UI framework that’s based on Bulma.

In this article, we’ll look at how to use Buefy in our Vue app.

Navbar

Buefy comes with a navbar component.

We can add it with the b-navbar component:

<template>
  <div id="app">
    <b-navbar>
      <template slot="brand">
        <b-navbar-item tag="router-link" :to="{ path: '/' }">
          <img src="http://placekitten.com/100/100" alt="cat icon">
        </b-navbar-item>
      </template>
      <template slot="start">
        <b-navbar-item href="#">Home</b-navbar-item>
        <b-navbar-dropdown label="Info">
          <b-navbar-item href="#">About</b-navbar-item>
          <b-navbar-item href="#">Contact</b-navbar-item>
        </b-navbar-dropdown>
      </template>

      <template slot="end">
        <b-navbar-item tag="div">
          <div class="buttons">
            <a class="button is-primary">
              <strong>Sign up</strong>
            </a>
            <a class="button is-light">Sign in</a>
          </div>
        </b-navbar-item>
      </template>
    </b-navbar>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We populate the brand slot with our logo.

start slot has the navbar items.

end slot has the buttons at the end of the navbar.

b-navbar-item has the navbar items.

Notification

We can show notifications with the b-notification component.

For example, we can write:

<template>
  <section>
    <button class="button block" @click="isActive = !isActive">Toggle</button>
    <b-notification
      v-model="isActive"
    >Lorem ipsum dolor sit amet</b-notification>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  }
};
</script>

to add a toggle for the notification.

And we use v-model to bind to the open state of the notification.

We can set the type prop to set the background color of the notification:

<template>
  <section>
    <button class="button block" @click="isActive = !isActive">Toggle</button>
    <b-notification v-model="isActive" type="is-success">Lorem ipsum dolor sit amet</b-notification>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  }
};
</script>

Also, we can add icons with the has-icon prop:

<template>
  <section>
    <button class="button block" @click="isActive = !isActive">Toggle</button>
    <b-notification
      v-model="isActive"
      has-icon
      icon="address-book"
      icon-pack="fa"
    >Lorem ipsum dolor sit amet</b-notification>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  }
};
</script>

The icon prop has the icon name.

icon-pack has the icon library name.

'fa' is Font Awesome.

We can add the CSS by adding:

<link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"
      integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
      crossorigin="anonymous"
    />

to the head tag of public/index.html .

We can set it to auto close with the auto-close and the duration props:

<template>
  <section>
    <button class="button block" @click="isActive = !isActive">Toggle</button>
    <b-notification v-model="isActive" auto-close :duration="2000">Lorem ipsum dolor sit amet</b-notification>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  }
};
</script>

We set the duration so that it auto closes after a given number of milliseconds.

Also, we can open it programmatically with the this.$vuefy.notification.open method:

<template>
  <section>
    <button class="button block" @click="open">Toggle</button>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  },
  methods: {
    open() {
      this.$buefy.notification.open("lorem ipsum");
    }
  }
};
</script>

The notification displays on the top right corner.

We can also pass in an object:

<template>
  <section>
    <button class="button block" @click="open">Toggle</button>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  },
  methods: {
    open() {
      this.$buefy.notification.open({
        duration: 5000,
        message: `lorem  <b>ipsum</b>`,
        position: "is-bottom-right",
        type: "is-danger",
        hasIcon: false
      });
    }
  }
};
</script>

message has the message.

position is the position.

type has the color style.

hasIcon lets us add an icon.

We can listen to the close event to do something when the notification closes:

<template>
  <section>
    <button class="button block" @click="open">Toggle</button>
  </section>
</template>

<script>
export default {
  data() {
    return {
      isActive: true
    };
  },
  methods: {
    open() {
      const notif = this.$buefy.notification.open({
        duration: 5000,
        message: `lorem  <b>ipsum</b>`,
        position: "is-bottom-right",
        type: "is-danger",
        hasIcon: true
      });
      notif.$on("close", () => {
        this.$buefy.notification.open("Custom notification closed!");
      });
    }
  }
};
</script>

Conclusion

We can add navbars and notifications to our Vue app with Buefy.