Add icon to radio / checkbox tabs

Learn how to create an alternative view with icon.

First create a component called RadiogroupRadio_tabIcons.vue and copy RadiogroupRadio_tabs template to it and apply some changes:

vue
<!-- RadiogroupRadio_tabIcons.vue -->

<template>
  <label
    v-bind="attrs"
    :class="classes.container"
    tabindex="0"
    role="radio"
    :aria-checked="checked"
    @keypress.space.prevent="el$.update(value)"
    @keydown="handleKeydown"
  >
    <slot
      v-bind="{ name }"
      :classes="classes"
      :is-disabled="isDisabled"
      :id="id"
      :item="item"
      :value="value"
      :items="items"
      :index="index"
    >
      <div :class="classes.wrapper">
        <input
          type="radio"
          v-model="el$.model"
          :value="value"
          :class="classes.input"
          :name="name"
          :id="id"
          :disabled="isDisabled"
        />
        <span 
          :class="classes.icon"
          v-html="`${item.icon}`"
        />
        <span 
          :class="classes.text"
          v-html="`${item.label}`"
        />
      </div>
    </slot>
  </label>
</template>

<script>
import tailwindTheme from '@vueform/vueform/dist/tailwind'

export default {
  name: 'RadiogroupRadio_tabIcons',
  data() {
    return {
      merge: true,
      defaultClasses: {
        ...tailwindTheme.classes.RadiogroupRadio_tabs,
        icon: 'mr-2',
      }
    }
  }
}
</script>
vue
<!-- RadiogroupRadio_tabIcons.vue -->

<template>
  <label
    v-bind="attrs"
    :class="classes.container"
    tabindex="0"
    role="radio"
    :aria-checked="checked"
    @keypress.space.prevent="el$.update(value)"
    @keydown="handleKeydown"
  >
    <slot
      v-bind="{ name }"
      :classes="classes"
      :is-disabled="isDisabled"
      :id="id"
      :item="item"
      :value="value"
      :items="items"
      :index="index"
    >
      <div :class="classes.wrapper">
        <input
          type="radio"
          v-model="el$.model"
          :value="value"
          :class="classes.input"
          :name="name"
          :id="id"
          :disabled="isDisabled"
        />
        <span 
          :class="classes.icon"
          v-html="`${item.icon}`"
        />
        <span 
          :class="classes.text"
          v-html="`${item.label}`"
        />
      </div>
    </slot>
  </label>
</template>

<script>
import vueformTheme from '@vueform/vueform/dist/vueform'

export default {
  name: 'RadiogroupRadio_tabIcons',
  data() {
    return {
      merge: true,
      defaultClasses: {
        ...vueformTheme.templates.RadiogroupRadio_tabs.data().defaultClasses,
        icon: 'vf-radio-tabs-icon',
      }
    }
  }
}
</script>

<style>
.vf-radio-tabs-icon {
  margin-right: 20px;
}
</style>

Changes made:

  • we added a wrapper for our icon
  • we included the tailwind / vueform theme and copied the default classes of RadiogroupRadio_tabs
  • we added an extra class for icon which adds some margin
  • we defined .vf-radio-tabs-icon class that adds some margin to the icon (Vueform Theme only)

The next step is to register the view in vueform.config.js:

js
// vueform.config.js

import { defineConfig } from '@vueform/vueform'
import tailwindTheme from '@vueform/vueform/dist/tailwind'
import RadiogroupRadio_tabIcons from './RadiogroupRadio_tabIcons.vue'

tailwindTheme.classes.RadiogroupElement_tabIcons = {
  ...tailwind.classes.RadiogroupElement_tabs,
}

export default defaultConfig({
  theme: tailwindTheme,
  templates: {
    RadiogroupRadio_tabIcons,
  },
})
js
// vueform.config.js

import { defineConfig } from '@vueform/vueform'
import vueformTheme from '@vueform/vueform/dist/vueform'
import RadiogroupRadio_tabIcons from './RadiogroupRadio_tabIcons.vue'

vueformTheme.classes.RadiogroupElement_tabIcons = {
  ...vueformTheme.templates.RadiogroupElement_tabs.data().defaultClasses
}

export default defaultConfig({
  theme: vueformTheme,
  templates: {
    RadiogroupRadio_tabIcons,
  },
})

Notice that we copied RadiogroupElement_tabs classes to RadiogroupElement_tabIcons as well. This is because RadiogroupElement_tabs contains the grid structure that is required for RadiogroupRadio_tabs. As we created RadiogroupRadio_tabIcons based on RadiogroupRadio_tabs, we need to copy its parent element classes as well.

Once the custom view is registered we can use it the following way:

vue
<RadiogroupElement
  view="tabIcons"
  :items="[
    { value: 1, label: 'Hate', icon: '😤' },
    { value: 2, label: 'Dislike', icon: '🙁' },
    { value: 3, label: 'Neutral', icon: '😐' },
    { value: 4, label: 'Like', icon: '🙂' },
    { value: 5, label: 'Love', icon: '🤩' },
  ]"
/>
  
👋 Hire Vueform team for form customizations and developmentLearn more