Categories
BootstrapVue

BootstrapVue — Customizing Tabs

To make good looking Vue apps we need to style our components. To make our lives easier, we can use components with styles built-in. Let’s look at how to customize the tabs that we added.

Vertical Tabs

We can make tabs vertical with the vertical prop:

<template>
  <div id="app">
    <b-card no-body>
      <b-tabs pills card vertical>
        <b-tab title="Tab 1" active>
          <b-card-text>Tab 1</b-card-text>
        </b-tab>
        <b-tab title="Tab 2">
          <b-card-text>Tab 2</b-card-text>
        </b-tab>
      </b-tabs>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

By default, the controls are rendered on the left.

We can place vertical tab controls on the right with the end prop:

<template>
  <div id="app">
    <b-card no-body>
      <b-tabs pills card vertical end>
        <b-tab title="Tab 1" active>
          <b-card-text>Tab 1</b-card-text>
        </b-tab>
        <b-tab title="Tab 2">
          <b-card-text>Tab 2</b-card-text>
        </b-tab>
      </b-tabs>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We can change the width of the tab controls with utility classes:

<template>
  <div id="app">
    <b-card no-body>
      <b-tabs pills card vertical nav-wrapper-class="w-75">
        <b-tab title="Tab 1" active>
          <b-card-text>Tab 1</b-card-text>
        </b-tab>
        <b-tab title="Tab 2">
          <b-card-text>Tab 2</b-card-text>
        </b-tab>
      </b-tabs>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

The w-75 class makes the controls take up 3/4 of the width of the card.

Active Classes

We can change the active classes by passing in some props.

active-nav-item-class lets us set the class for an active item.

active-tab-class lets us set the class for the active tab content.

content-class lets us set the class for the displayed content.

For example, we can write:

<template>
  <div id="app">
    <b-card no-body>
      <b-tabs
        active-nav-item-class="font-weight-bold"
        active-tab-class="text-success"
        content-class="mt-3"
      >
        <b-tab title="Tab 1" active>
          <b-card-text>Tab 1</b-card-text>
        </b-tab>
        <b-tab title="Tab 2">
          <b-card-text>Tab 2</b-card-text>
        </b-tab>
      </b-tabs>
    </b-card>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We set active-nav-item-class to font-weight-bold so the control text for the active tab is bold.

active-tab-class is set to text-success , so the content text for the active tab is green.

content-class is set to mt-3 so that we have some margins on top.

Disable Fade

We can add the no-fade prop to disable fade transitions.

Tabs Without Content

We can add tabs without content by populating the tabs-end or tabs-start slot. The tabs without content will be added to the end or start respectively.

For example, we can write:

<template>
  <div id="app">
    <b-tabs>
      <b-tab title="Tab 1" active>
        <b-card-text>Tab 1</b-card-text>
      </b-tab>
      <b-tab title="Tab 2">
        <b-card-text>Tab 2</b-card-text>
      </b-tab>

      <template v-slot:tabs-end>
        <b-nav-item href="#" role="presentation" @click="() => {}">Empty 1</b-nav-item>
        <li class="nav-item align-self-center">Empty 2</li>
      </template>
    </b-tabs>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

Now we have the Empty 1 and Empty 2 tabs that have no content to the right of the other tabs.

Custom Content in Tab Title

We can populate slots to add custom content to them.

To do that, we populate the title slot of each tab.

For example, we can write:

<template>
  <div id="app">
    <b-tabs>
      <b-tab active>
        <template v-slot:title>
          <b-spinner small></b-spinner>
          <b>Tab 1</b>
        </template>
        <p class="p-3">Tab 1</p>
      </b-tab>

      <b-tab>
        <template v-slot:title>Tab 2</template>
        <p class="p-3">Tab 2</p>
      </b-tab>
    </b-tabs>
  </div>
</template>
<script>
export default {
  name: "App"
};
</script>

We populated the title slot of each tab with our own content.

In the first tab, we added a spinner with text.

In the 2nd tab, we just have text.

Conclusion

We can make tabs vertical or wider than usual. The text of the tabs can also be changed. Tabs also don’t have to have content.

Categories
BootstrapVue

BootstrapVue — Tabs

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

We look at how to add tabs to our Vue apps.

Tabs

We can add tabbable panes into our app with the b-tabs component.

For example, we can write:

<template>  
  <div id="app">  
    <b-tabs content-class="mt-3">  
      <b-tab title="First" active>  
        <p>first tab</p>  
      </b-tab>  
      <b-tab title="Second">  
        <p>second tab</p>  
      </b-tab>  
      <b-tab title="Disabled" disabled>  
        <p>Bisabled tab</p>  
      </b-tab>  
    </b-tabs>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We added the b-tabs component which houses the b-tab components.

b-tab has the tab heading as set by the title .

We can click on a tab heading to go to a tab.

disabled means the tab is disabled.

We can’t go to a disabled tab.

Cards Integration

We can put tabs into cards.

For instance, we can write:

<template>  
  <div id="app">  
    <b-card no-body>  
      <b-tabs card>  
        <b-tab title="One" active>  
          <b-card-text>Tab 1</b-card-text>  
        </b-tab>  
        <b-tab title="Two">  
          <b-card-text>Tab 2</b-card-text>  
        </b-tab>  
      </b-tabs>  
    </b-card>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

We disable the card body with the no-body prop.

Then we can display the tab content by putting b-tabs inside the b-card .

We can use b-card-text in a b-tab to display the content in the card.

We set the default active tab with the active prop.

The card prop on b-tabs make it work in card mode so that it looks correct in a card.

Subcomponents in b-tab will have the card-body class applied if it’s in card mode.

For example, if we have:

<template>  
  <div id="app">  
    <b-card no-body>  
      <b-tabs card>  
        <b-tab title="One" active>  
          <b-card-img bottom src="https://placekitten.com/200/200" alt="kitten"></b-card-img>  
          <b-card-footer>kitten</b-card-footer>  
        </b-tab>  
        <b-tab title="Two">  
          <b-card-text>Tab 2</b-card-text>  
        </b-tab>  
      </b-tabs>  
    </b-card>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Then everything inside has the card-body class added.

Pills

We can display tabs in pills form with the pills prop:

<template>  
  <div id="app">  
    <b-card no-body>  
      <b-tabs pills card>  
        <b-tab title="Tab 1" active>  
          <b-card-text>Tab 1</b-card-text>  
        </b-tab>  
        <b-tab title="Tab 2">  
          <b-card-text>Tab 2</b-card-text>  
        </b-tab>  
      </b-tabs>  
    </b-card>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Fill

The fill prop can be used to fill the available horizontal space proportionally with the tabs.

For example, we can write:

<template>  
  <div id="app">  
    <b-tabs fill>  
      <b-tab title="Tab 1" active>  
        <b-card-text>Tab 1</b-card-text>  
      </b-tab>  
      <b-tab title="Tab 2">  
        <b-card-text>Tab 2</b-card-text>  
      </b-tab>  
    </b-tabs>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Justified

The justified prop lets us make the tabs equal width:

<template>  
  <div id="app">  
    <b-tabs justified>  
      <b-tab title="Tab 1" active>  
        <b-card-text>Tab 1</b-card-text>  
      </b-tab>  
      <b-tab title="Tab 2">  
        <b-card-text>Tab 2</b-card-text>  
      </b-tab>  
    </b-tabs>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Alignment

The align prop lets us align the tabs.

The possible values are left , center , and right .

Therefore, we can write:

<template>  
  <div id="app">  
    <b-tabs align="center">  
      <b-tab title="Tab 1" active>  
        <b-card-text>Tab 1</b-card-text>  
      </b-tab>  
      <b-tab title="Tab 2">  
        <b-card-text>Tab 2</b-card-text>  
      </b-tab>  
    </b-tabs>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

Bottom Placement of Tab Controls

We can place the tab controls below the tab content with the end prop:

<template>  
  <div id="app">  
    <b-card no-body>  
      <b-tabs pills card end>  
        <b-tab title="Tab 1" active>  
          <b-card-text>Tab 1</b-card-text>  
        </b-tab>  
        <b-tab title="Tab 2">  
          <b-card-text>Tab 2</b-card-text>  
        </b-tab>  
      </b-tabs>  
    </b-card>  
  </div>  
</template>  
<script>  
export default {  
  name: "App"  
};  
</script>

It looks better will the pills prop to make the controls look like a button.

Conclusion

We can add tabs to display tabbed content.

It also integrates with cards.

Categories
BootstrapVue

BootstrapVue — Custom Tables

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

We look at how to customizing tables.

Fields

We can add a fields prop to specify how we want to display the fields.

For example, we can write:

<template>
  <div id="app">
    <b-table striped hover :items="items" :fields="fields"></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fields: [
        {
          key: "lastName",
          sortable: true,
          label: "Last"
        },
        {
          key: "firstName",
          sortable: false,
          label: "First"
        }
      ],
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We have the fields array with the label to display.

label is what we display nd key ios the property name of the entry to display.

Styling

There are many props we can add to b-table for styling.

striped makes the row striped.

border makes the table bordered.

borderless makes the table borderless.

outlined adds a thin border on all sides of the table.

small makes tables more compact by cutting cell padding in half.

hover enables hover highlighting on table rows.

dark inverts the color.

fixed makes the columns fixed width.

responsives makes the table responsive by letting it scroll horizontally.

sticky-header makes the header sticky.

stacked makes a responsive stacked table.

caption-top lets us add a caption above the table.

table-variant gives the table a theme color variant.

head-variant use 'light' or 'dark' to make the table header appear light or dark gray respectively.

foot-variant turns on the table footer with the same contents as the table header.

foot-clone turns on the table footer with the same contents as the table header.

no-footer-sorting disables sorting icons and clicks.

no-border-collapse disables collapsing of table borders.

For example, we can write:

<template>
  <div id="app">
    <b-table striped hover :items="items" borderless small></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

to shrink the cells and make the table borderless with the small and borderless props respectively.

We also have striped to make the table rows alternate in color.

hover makes the row highlight when it’s hovered.

Responsive Tables

We can add the responsive prop to make the table responsive.

For instance, we can write:

<template>
  <div id="app">
    <b-table :items="items" responsive></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

Then when the screen is narrow, the table can be scrolled horizontally to see all the content.

Stacked Tables

Stacked tables are tables that can be rendered in a visually stacked format.

We can do that across all viewports by setting the stacked prop to true .

Or we can do it for specific breakpoints like sm , md , lg , or xl .

For instance, we can write:

<template>
  <div id="app">
    <b-table :items="items" stacked="md"></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

and make it stacked only when the screen is less than 768px wide.

When a table is stacked, the content can’t be sorted by clicking the field labels.

top-row and bottom-row slots will also be hidden.

Always stacked tables won’t have the table header, footer, top, and bottom row slots won’t be rendered.

Table Caption

To add a caption to our table, we can add the caption prop.

For example, we can write:

<template>
  <div id="app">
    <b-table :items="items" >
      <template v-slot:table-caption>table of names</template>
    </b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We populate the table-caption slot with our content.

Conclusion

There are many props to let us style tables the way we like.

Also, we can create responsive or stacked tables to make tables look good on any screen.

Categories
BootstrapVue

BootstrapVue — Simple Tables

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

We look at how to customize table contents by using the b-table-simple component.

Simple Tables

The b-table-simple component lets us create a table as we do in regular HTML.

Therefore, we have full control of each cell.

We can add the striped , bordered , borderless , outlined , small , hover , dark , fixed , responsive , and sticky-header props to style the table the way we like.

For example, we can create one by writing:

<template>
  <div id="app">
    <b-table-simple responsive>
      <b-thead>
        <b-tr>
          <b-th>id</b-th>
          <b-th>first</b-th>
          <b-th>last</b-th>
        </b-tr>
      </b-thead>
      <b-tbody>
        <b-tr v-for="i of items" :key="i.id">
          <b-td>{{i.id}}</b-td>
          <b-td>{{i.firstName}}</b-td>
          <b-td>{{i.lastName}}</b-td>
        </b-tr>
      </b-tbody>
    </b-table-simple>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      items: [
        { id: 1, firstName: "alex", lastName: "green" },
        {
          id: 2,
          firstName: "may",
          lastName: "smith"
        },
        { id: 3, firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We have the b-table-simple component.

Inside it, we have the b-thead component to add the table header.

b-tr add the rows.

b-th add the header cells.

b-tbody adds the table body.

And b-td adds the body cells.

Simple tables can be stacked like regular tables.

For example, we can write:

<template>
  <div id="app">
    <b-table-simple stacked>
      <b-tbody>
        <b-tr v-for="i of items" :key="i.id">
          <b-td stacked-heading="id">{{i.id}}</b-td>
          <b-td stacked-heading="first">{{i.firstName}}</b-td>
          <b-td stacked-heading="last">{{i.lastName}}</b-td>
        </b-tr>
      </b-tbody>
    </b-table-simple>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      items: [
        { id: 1, firstName: "alex", lastName: "green" },
        {
          id: 2,
          firstName: "may",
          lastName: "smith"
        },
        { id: 3, firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We have the stacked prop with the stacked-heading on each table cell to specify the field name to display.

Simple Tables and Sticky Columns

We can make a column sticky with the sticky-column prop.

For instance, we can write:

<template>
  <div id="app">
    <b-table-simple responsive>
      <b-thead>
        <b-tr>
          <b-th sticky-column>id</b-th>
          <b-th>first</b-th>
          <b-th>last</b-th>
        </b-tr>
      </b-thead>
      <b-tbody>
        <b-tr v-for="i of items" :key="i.id">
          <b-td sticky-column>{{i.id}}</b-td>
          <b-td>{{i.firstName}}</b-td>
          <b-td>{{i.lastName}}</b-td>
        </b-tr>
      </b-tbody>
    </b-table-simple>
  </div>
</template>
<script>
export default {
  name: "App",
  data() {
    return {
      items: [
        { id: 1, firstName: "alex", lastName: "green" },
        {
          id: 2,
          firstName: "may",
          lastName: "smith"
        },
        { id: 3, firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We just put the sticky-column prop on the column cells to make the column sticky.

Helper Components

Helper components are added to tables to let us render things in a custom manner.

b-table-simple can include b-tbody , b-thead , b-tfoot , b-te , b-td , and b-th components.

b-table can only include b-tr , b-td , and b-th components.

Conclusion

We can use the b-table-simple component to let us create tables in a more flexible manner.

Also, we can add sticky columns into our table

They can be also be shown as a stacked table.

Categories
BootstrapVue

BootstrapVue — Customizing Spinner and Basic Tables

To make good looking Vue apps, we need to style our components.

To make our lives easier, we can use components with styles built-in.

We look at how to customize spinners and add basic tables.

Aligning Spinners

We can add classes or alignment.

For instance, we can write:

<template>
  <div id="app">
    <b-spinner class="m-5"></b-spinner>
  </div>
</template>

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

to add the m-5 class to add some margins around the spinner.

Placement

The placement of the spinner can be changed.

For example, we can write:

<template>
  <div id="app">
    <div class="d-flex align-items-center">
      <b-spinner></b-spinner>
    </div>
  </div>
</template>

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

to center align the spinner.

Floats

We can apply the float classes that come with Bootstrap to put the spinner left or right.

So we can write:

<template>
  <div id="app">
    <div class="clearfix">
      <b-spinner class="float-right"></b-spinner>
    </div>
  </div>
</template>

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

to use the clearfix class so that we can float the spinner to the right.

Text Align

We can use the text-center class to align the spinner to the center of the page:

<template>
  <div id="app">
    <div class="text-center">
      <b-spinner></b-spinner>
    </div>
  </div>
</template>

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

Spinners in Buttons

We can put spinners in buttons.

For example, we can write:

<template>
  <div id="app">
    <b-button variant="primary" disabled>
      <b-spinner small></b-spinner>Loading...
    </b-button>
  </div>
</template>

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

We have the spinner inside a button along with some text.

Tables

BootstrapVue comes with the b-table component to let us display tables.

There are 2 lighter weight alternatives, which are b-table-lite and b-table-simple .

For example, we can write:

<template>
  <div id="app">
    <b-table striped hover :items="items"></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { firstName: "alex", lastName: "green" },
        { firstName: "may", lastName: "smith" },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We have the items prop that takes an array of objects to render into a table.

striped makes the rows alternate in color.

hover makes the rows highlight when it’s hovered.

The property names are automatically mapped to individual words and capitalize each word.

This conversion is done for kebab case, snake case, or camelCase property names.

We can add the _rowVariant or _cellVariant properties to change the styles of various cells.

For example, we can write:

<template>
  <div id="app">
    <b-table striped hover :items="items"></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { firstName: "alex", lastName: "green", _rowVariant: "success" },
        {
          firstName: "may",
          lastName: "smith",
          _cellVariants: { lastName: "info", firstName: "warning" }
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

_rowVariant makes the whole row the same color.

'success' makes the background green

_cellVariants makes individual cells a different color.

So lastName is light blue since it hs variant 'info' .

And firstName ‘s variant is 'warning' so it’s yellow.

The _cellVariants and _rowVariants only applies to the entry that they are in.

Fields

We can specify how the fields are displayed explicitly.

b-table can take a fields prop with an array of field to display.

For example, we can write:

<template>
  <div id="app">
    <b-table striped hover :items="items" :fields='fields'></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fields: ["firstName"],
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

Since fields is [“firstName”] , only the First Name column is displayed.

Fields as an Array of Objects

We can have an array of objects for the fields array.

For example, we can write:

<template>
  <div id="app">
    <b-table striped hover :items="items" :fields="fields"></b-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      fields: [
        {
          key: "lastName",
          sortable: true
        },
        {
          key: "firstName",
          sortable: false,
          variant: "success"
        }
      ],
      items: [
        { firstName: "alex", lastName: "green" },
        {
          firstName: "may",
          lastName: "smith"
        },
        { firstName: "james", lastName: "jones" }
      ]
    };
  }
};
</script>

We have the fields array with the entries being key , sortable , and variant .

key is the property name of the items entries.

variant is the styling variant like primary or success ,

sortable indicates whether the column is sortable.

Therefore, the Last Column is sortable and First Name is not.

Conclusion

We can style and place spinners the way we like with some classes.

Also, we can create simple tables by passing in a few arrays as props into the b-table component.