Categories
Buefy

Buefy — Customize Tabs and Tags

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.

Tab Size

We can change the tab size with the size prop.

To do that, we write:

<template>
  <div id="app">
    <b-tabs size="is-small" class="block">
      <b-tab-item label="Pictures"></b-tab-item>
      <b-tab-item label="Music"></b-tab-item>
      <b-tab-item label="Videos"></b-tab-item>
    </b-tabs>
  </div>
</template>

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

is-small makes the tabs extra small. We can also set it to is-medium or is-large .

Types

We can change the shape of the tab with the type prop. For example, we can write:

<template>
  <div id="app">
    <b-tabs type="is-toggle">
      <b-tab-item label="Pictures"></b-tab-item>
      <b-tab-item label="Music"></b-tab-item>
      <b-tab-item label="Videos"></b-tab-item>
    </b-tabs>
  </div>
</template>

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

is-toggle changes it to a toggle button.

is-boxed is the default type which looks like tabs.

is-toggle-rounded make the buttons rounded.

Expanded

The expanded prop makes the tabs expanded to fill the width of the screen:

<template>
  <div id="app">
    <b-tabs expanded>
      <b-tab-item label="Pictures"></b-tab-item>
      <b-tab-item label="Music"></b-tab-item>
      <b-tab-item label="Videos"></b-tab-item>
    </b-tabs>
  </div>
</template>

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

Custom Headers

We can populate the header slot to customize the header of the tab item.

For example, we can write:

<template>
  <div id="app">
    <b-tabs expanded>
      <b-tab-item>
        <template slot="header">
          <b>Pictures</b>
        </template>
      </b-tab-item>
      <b-tab-item label="Music"></b-tab-item>
      <b-tab-item label="Videos"></b-tab-item>
    </b-tabs>
  </div>
</template>

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

Now the Pictures tab is bolded.

Vertical Tabs

We can make the tabs vertical with the vertical prop:

<template>
  <div id="app">
    <b-tabs expanded vertical>
      <b-tab-item label="Pictures">pictures</b-tab-item>
      <b-tab-item label="Music">music</b-tab-item>
      <b-tab-item label="Videos">videos</b-tab-item>
    </b-tabs>
  </div>
</template>

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

Tags

Tags are labels we can insert anywhere.

For example, we can write:

<template>
  <div id="app">
    <div class="field">
      <b-tag>Tag 1</b-tag>
    </div>
    <div class="field">
      <b-tag rounded>Tag 2</b-tag>
    </div>
  </div>
</template>

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

We can add tags with the b-tag component and the tag text in between the tags.

Closable Tags

We can make a tag closeable with the closeable tag:

<template>
  <div id="app">
    <div class="field">
      <b-tag
        v-if="isTagActive"
        type="is-primary"
        closable
        @close="isTagActive = false"
      >closable tag</b-tag>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      isTagActive: true
    };
  }
};
</script>

The close event should be emitted when we click the close button that’s displayed.

This way, we can use a reactive property to control when the tag is displayed.

Conclusion

We can customize our tabs and create tags with Buefy.

Categories
Buefy

Buefy — Tabs

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.

Tabs

We can add tabs with the b-tabs component from Buefy.

To add them, we can write:

<template>
  <div id="app">
    <b-tabs v-model="activeTab">
      <b-tab-item label="Pictures">Lorem ipsum dolor sit amet.</b-tab-item>
      <b-tab-item label="Music">Lorem ipsum</b-tab-item>
      <b-tab-item visible label="Books">What light is light, if Silvia be not seen?</b-tab-item>
      <b-tab-item label="Videos" disabled>Nunc nec velit nec libero vestibulum eleifend.</b-tab-item>
    </b-tabs>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      activeTab: undefined
    };
  }
};
</script>

We add the b-tabs component as the wrapper.

b-tab-item has the tab item.

label has the tab headings.

visible prop makes the tab item visible.

disabled prevents us from clicking the tab.

The v-model sets the index of the active tab as we click the tab.

We can also set the index to change the tab programmatically.

Dynamic Tabs

We can toggle tabs on and off dynamically:

<template>
  <section>
    <div class="block">
      <b-switch v-model="showBooks">Show books item</b-switch>
    </div>
    <b-tabs v-model="activeTab" :multiline="multiline">
      <template v-for="tab in tabs">
        <b-tab-item
          v-if="tab.displayed"
          :key="tab.id"
          :value="tab.id"
          :label="tab.label"
        >{{ tab.content }}</b-tab-item>
      </template>
    </b-tabs>
  </section>
</template>

<script>
export default {
  data() {
    return {
      activeTab: "pictures",
      showMusic: true,
      showBooks: false,
      multiline: true
    };
  },
  computed: {
    baseTabs() {
      return [
        {
          id: "pictures",
          label: "Pictures",
          content: "Pictures: Lorem ipsum",
          displayed: true
        },
        {
          id: "music",
          label: "Music",
          content: "Music: Lorem ipsum",
          displayed: this.showMusic
        },
        {
          id: "videos",
          label: "Videos",
          content: "Videos: Lorem ipsum",
          displayed: true
        }
      ];
    },
    tabs() {
      const tabs = [...this.baseTabs];
      if (this.showBooks) {
        tabs.splice(tabs.length - 2, 0, this.bookTab);
      }
      return tabs;
    },
    bookTab() {
      return {
        id: "books",
        label: "Books",
        content: "Books: Lorem ipsum.",
        displayed: true
      };
    }
  }
};
</script>

We have the tabs computed property to insert the Books tab when the showBooks reactive property is true .

Position

We can change the positions of the tabs with the position prop:

<template>
  <section>
    <b-tabs position="is-centered" class="block">
      <b-tab-item label="Pictures"></b-tab-item>
      <b-tab-item label="Music"></b-tab-item>
      <b-tab-item label="Videos"></b-tab-item>
    </b-tabs>
  </section>
</template>

<script>
export default {};
</script>

is-centered centers the tabs. is-right puts the tabs on the right.

Icons

We can add icons to the tab items with the icon and icon-pack props:

<template>
  <section>
    <b-tabs position="is-centered" class="block">
      <b-tab-item label="Pictures" icon="address-book" icon-pack="fa"></b-tab-item>
      <b-tab-item label="Music" icon="bandcamp" icon-pack="fa"></b-tab-item>
      <b-tab-item label="Videos" icon="drivers-license-o" icon-pack="fa"></b-tab-item>
    </b-tabs>
  </section>
</template>

<script>
export default {};
</script>

We have the icon-pack prop to set the icon pack name.

fa is for Font Awesome.

We add the CSS into the public/index.html file:

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

Conclusion

We can add tabs to our Vue app with Buefy.

Categories
Buefy

Buefy — Sticky Headers and Footers

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.

Sticky Headers and Columns

We can add the sticky-header prop to show a scrolling table with fixed headers.

For example, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" sticky-header height="100px"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

to add the prop and set the height so that we can see the scrolling content with the sticky header.

We can add the sticky property to make a column sticky when we scroll:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" sticky-header></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true,
          sticky: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

Toggle Columns

We can show and hide columns with the visible prop:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" sticky-header></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true,
          visible: true
        },
        {
          field: "first_name",
          label: "First Name",
          visible: true
        },
        {
          field: "last_name",
          label: "Last Name",
          visible: false
        }
      ]
    };
  }
};
</script>

We set the visible property on the column definition object to show and hide columns.

Footer

We can populate the footer slot with the columns. For example, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns">
      <template slot="footer">
        <th>
          <div class="th-wrap is-numeric">ID</div>
        </th>
        <th>
          <div class="th-wrap">First Name</div>
        </th>
        <th>
          <div class="th-wrap">Last Name</div>
        </th>
      </template>
    </b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

We add the th elements into the footer to populate the cells.

Conclusion

We can add sticky headers and footers. Also, we can toggle the visibility of the columns.

Categories
Buefy

Buefy — Customize Table Rows and Columns

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.

Row Status

We can set the row-class prop by checking the row data with a function.

For example, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" :row-class="(row, index) => row.id === 1 && 'is-info'"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  }
};
</script>

<style>
tr.is-info {
  background: #167df0;
  color: #fff;
}
</style>

to add the is-info class to add the class to the given row.

Custom Headers

We can customize the header by populating the header slot. To do that, we write:

<template>
  <div id="app">
    <b-table :data="data">
      <b-table-column field="id" label="ID" width="40" numeric>
        <template v-slot:header="{ column }">
          <b-tooltip :label="column.label" append-to-body dashed>{{ column.label }}</b-tooltip>
        </template>
        <template v-slot="props">{{ props.row.id }}</template>
      </b-table-column>

      <b-table-column field="user.first_name" label="First Name">
        <template v-slot:header="{ column }">
          <b-tooltip :label="column.label" append-to-body dashed>{{ column.label }}</b-tooltip>
        </template>
        <template v-slot="props">{{ props.row.first_name }}</template>
      </b-table-column>

      <b-table-column field="user.last_name" label="Last Name">
        <template v-slot:header="{ column }">
          <b-tooltip :label="column.label" append-to-body dashed>{{ column.label }}</b-tooltip>
        </template>
        <template v-slot="props">{{ props.row.last_name }}</template>
      </b-table-column>
    </b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data
    };
  }
};
</script>

We add the b-table-column component to add the column.

The header slot lets us populate the content we want in the column headers.

column is an object that has the column data including the label property.

Subheadings

We can add subheadings with the subheadings property.

For example, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns"></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true,
          subheading: "Total:"
        },
        {
          field: "first_name",
          label: "First Name",
          subheading: 100
        },
        {
          field: "last_name",
          label: "Last Name",
          subheading: 200
        }
      ]
    };
  }
};
</script>

We add the subheading property to the column definition objects.

Conclusion

We can add various things for table rows and columns with Buefy.

Categories
Buefy

Buefy — Sorting Multiple Columns and Row Details

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.

Sorting Multiple Columns

We can enable the sorting of multiple columns with the sort-multiple prop.

For instance, we can write:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" sort-multiple></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name",
          sortable: true
        },
        {
          field: "last_name",
          label: "Last Name",
          sortable: true
        }
      ]
    };
  }
};
</script>

to enable sorting the first name and last name columns with the sortable property set to true .

We can set the sorting priority of the column with the sort-multiple prop:

<template>
  <div id="app">
    <b-table :data="data" :columns="columns" :sort-multiple-data="sortingPriority" sort-multiple></b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      sortingPriority: [
        { field: "first_name", order: 1 },
        { field: "last_name", order: 2 }
      ],
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name",
          sortable: true
        },
        {
          field: "last_name",
          label: "Last Name",
          sortable: true
        }
      ]
    };
  }
};
</script>

We set the value of the prop to an array with objects with the field and order properties to set the sorting priority.

Detailed Rows

We can add rows with details with the detail slot. To do that, we can write:

<template>
  <div id="app">
    <b-table
      :data="data"
      :columns="columns"
      detailed
      detail-key="id"
      ref="table"
      @details-open="(row) => $buefy.toast.open(`Expanded ${row.first_name}`)"
    >
      <b-table-column field="first_name" label="First Name" sortable v-slot="props">
        <template v-if="showDetailIcon">{{ props.row.first_name }}</template>
        <template v-else>
          <a @click="toggle(props.row)">{{ props.row.first_name }}</a>
        </template>
      </b-table-column>

      <b-table-column
        field="last_name"
        label="Last Name"
        sortable
        v-slot="props"
      >{{ props.row.last_name }}</b-table-column>

<template slot="detail" slot-scope="props">
        <article class="media">
          <div class="media-content">
            <div class="content">
              <p>
                <strong>{{ props.row.first_name }} {{ props.row.last_name }}</strong>
              </p>
            </div>
          </div>
        </article>
      </template>
    </b-table>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    const data = [
      {
        id: 1,
        first_name: "james",
        last_name: "smith"
      },
      {
        id: 2,
        first_name: "mary",
        last_name: "jones"
      },
      {
        id: 3,
        first_name: "alex",
        last_name: "wong"
      }
    ];
    return {
      data,
      columns: [
        {
          field: "id",
          label: "ID",
          width: "40",
          numeric: true
        },
        {
          field: "first_name",
          label: "First Name"
        },
        {
          field: "last_name",
          label: "Last Name"
        }
      ]
    };
  },
  methods: {
    toggle(row) {
      this.$refs.table.toggleDetails(row);
    }
  }
};
</script>

In the b-table-column components, we have the a tag which we can click to call toggle to toggle the detail pane on and off.

toggle takes the row , and calls this.$refs.table.toggleDetails(row) method to toggle the detail pane.

The details-open event is emitted whenever we toggle the details pane on.

Conclusion

We can add sorting to multiple columns and toggle details for a row.