BBC's guide to development
  • General

    • About
    • Tools
    • Git(hub)
    • Showpad
    • Hosting
    • Maintenance
    • Security
    • Go live checklist
  • Front-end development

    • Bundlers
    • CSS/SCSS
    • Javascript
    • Vue
    • PHP
    • Mails
    • Dev Faq
  • Functions
  • Mixins
  • General

    • OOP Structure
  • Component Classes

    • Accordion
    • App
    • Component
    • HighwayApp
    • Popup
    • PNG Sequencer
    • Tab
  • Manager Classes

    • BountListenerMgr
    • Cache
    • Configuration
    • InViewStateMgr
    • Instance Manager
    • Event dispatcher
  • Factories

    • SwiperFactory
  • PDF

    • AssetLoader
    • BasePdfDoc
    • TemplatePdfDoc
    • CustomPdfDoc
  • Utility functions

    • canvas
    • Connection Status
    • css
    • dev
    • placeholder
    • dom
    • fetch
    • json
    • object
    • scroll
    • scrollbar
    • spreadsheets
    • string
    • url
  • General

    • ComponentMgr
    • ThreeJsViewer
  • Components

    • ComponentMgr
    • GltfModel
    • Snappable
    • Socket
    • ThreeJsViewer
    • ThreeJsViewerCamera
  • Loaders

    • ConfigurationSerializer
    • GltfBlockParser
  • Utils

    • CanvasInputAdapter
    • CollisionManager
    • SocketGridExpander
    • blender
    • headless
  • General

    • Troubleshooting
    • Legacy
  • Components

    • AssetBar
    • ConfigGenerator
    • ShowpadApp
  • Managers

    • Assets
    • AppsDb
    • Config
  • Utils

    • Connection Status
    • general
    • showpad-interactive
    • showpad-upload
  • Components

    • Accordion
    • BackButton
    • Breadcrumb
    • ByltButton
    • Hamburger
    • Icon
    • Logo
    • Loader
    • Modal
    • Popup
    • Prompt
    • ProgressBar
    • TextLoader
  • Composables

    • useDebugMode
    • useConnectionStatus
  • Utils

    • dom
    • props
  • General

    • General
    • Tracking
  • Components

    • Accordion
    • ActionButton
    • AssetItem
    • AssetList
    • BackButton
    • ConfigGenButton
    • Logo
    • Media
    • Modal
    • Popup
    • Prompt
    • SPButton
    • SPRouterView
    • SPTrackedRouterLink
    • TextLoader
    • View
  • Composables

    • useConnectionStatus
  • Stores

    • useAppsDbStore
    • useBreadcrumbStore
    • useShowpadAPIStore
    • useShowpadSDKStore
    • useSpConfigStore
    • useSpStore
    • useSpTrackingStore
  • The New Kit

    • General
    • Installation & Usage
    • ACF Blocks
    • PHPCS
    • Functions
    • Vite
    • WP Config
    • Staging Deployment
  • Best Practices

    • Page Structure
    • Fonts/Typography
  • Todo
GitHub
  • General

    • About
    • Tools
    • Git(hub)
    • Showpad
    • Hosting
    • Maintenance
    • Security
    • Go live checklist
  • Front-end development

    • Bundlers
    • CSS/SCSS
    • Javascript
    • Vue
    • PHP
    • Mails
    • Dev Faq
  • Functions
  • Mixins
  • General

    • OOP Structure
  • Component Classes

    • Accordion
    • App
    • Component
    • HighwayApp
    • Popup
    • PNG Sequencer
    • Tab
  • Manager Classes

    • BountListenerMgr
    • Cache
    • Configuration
    • InViewStateMgr
    • Instance Manager
    • Event dispatcher
  • Factories

    • SwiperFactory
  • PDF

    • AssetLoader
    • BasePdfDoc
    • TemplatePdfDoc
    • CustomPdfDoc
  • Utility functions

    • canvas
    • Connection Status
    • css
    • dev
    • placeholder
    • dom
    • fetch
    • json
    • object
    • scroll
    • scrollbar
    • spreadsheets
    • string
    • url
  • General

    • ComponentMgr
    • ThreeJsViewer
  • Components

    • ComponentMgr
    • GltfModel
    • Snappable
    • Socket
    • ThreeJsViewer
    • ThreeJsViewerCamera
  • Loaders

    • ConfigurationSerializer
    • GltfBlockParser
  • Utils

    • CanvasInputAdapter
    • CollisionManager
    • SocketGridExpander
    • blender
    • headless
  • General

    • Troubleshooting
    • Legacy
  • Components

    • AssetBar
    • ConfigGenerator
    • ShowpadApp
  • Managers

    • Assets
    • AppsDb
    • Config
  • Utils

    • Connection Status
    • general
    • showpad-interactive
    • showpad-upload
  • Components

    • Accordion
    • BackButton
    • Breadcrumb
    • ByltButton
    • Hamburger
    • Icon
    • Logo
    • Loader
    • Modal
    • Popup
    • Prompt
    • ProgressBar
    • TextLoader
  • Composables

    • useDebugMode
    • useConnectionStatus
  • Utils

    • dom
    • props
  • General

    • General
    • Tracking
  • Components

    • Accordion
    • ActionButton
    • AssetItem
    • AssetList
    • BackButton
    • ConfigGenButton
    • Logo
    • Media
    • Modal
    • Popup
    • Prompt
    • SPButton
    • SPRouterView
    • SPTrackedRouterLink
    • TextLoader
    • View
  • Composables

    • useConnectionStatus
  • Stores

    • useAppsDbStore
    • useBreadcrumbStore
    • useShowpadAPIStore
    • useShowpadSDKStore
    • useSpConfigStore
    • useSpStore
    • useSpTrackingStore
  • The New Kit

    • General
    • Installation & Usage
    • ACF Blocks
    • PHPCS
    • Functions
    • Vite
    • WP Config
    • Staging Deployment
  • Best Practices

    • Page Structure
    • Fonts/Typography
  • Todo
GitHub
  • Icon

Icon

import { Icon } from '@bbc/front-end-kit/vue'

A base Vue component that is supposed to be extended into a single Specific Icon component. The specific Icon component can contain variants within the same file that can be triggered using the type property

Getting started

<template>
    <Icon>
        <svg>
            ...
        </svg>
    </Icon>
</template>

<script setup>
import { Icon } from '@bbc/front-end-kit/vue'
</script>

Example component

Cross Icon Vue component

// IconCross.vue
<template>
    <Icon class="--cross">
        <svg width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
            <rect x="14.1426" width="1" height="20" transform="rotate(45 14.1426 0)" fill="currentColor"/>
            <rect width="1" height="20" transform="matrix(-0.707107 0.707107 0.707107 0.707107 0.708008 0)" fill="currentColor"/>
        </svg>
    </Icon>
</template>

<script setup>
import { Icon } from '@bbc/front-end-kit/vue';
</script>

<style lang="scss">
	.icon.--cross {
        
    }
</style>

Bookmark icon Vue component which has 2 types

// IconBookmark.vue
<template>
    <Icon class="--bookmark">
        <template #default="{ type }">
            <svg v-if="type === 'mono'" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M3.53125 13.6C3.44045 13.6777 3.3293 13.7277 3.21096 13.7441C3.09262 13.7605 2.97204 13.7427 2.86353 13.6927C2.75501 13.6427 2.66309 13.5627 2.59866 13.4621C2.53423 13.3615 2.49999 13.2445 2.5 13.125V3.125C2.5 2.62772 2.69754 2.15081 3.04917 1.79917C3.40081 1.44754 3.87772 1.25 4.375 1.25H10.625C11.1223 1.25 11.5992 1.44754 11.9508 1.79917C12.3025 2.15081 12.5 2.62772 12.5 3.125V13.125C12.5 13.2445 12.4658 13.3615 12.4013 13.4621C12.3369 13.5627 12.245 13.6427 12.1365 13.6927C12.028 13.7427 11.9074 13.7605 11.789 13.7441C11.6707 13.7277 11.5595 13.6777 11.4688 13.6L7.5 10.1975L3.53125 13.6ZM11.25 11.7656V3.125C11.25 2.95924 11.1842 2.80027 11.0669 2.68306C10.9497 2.56585 10.7908 2.5 10.625 2.5H4.375C4.20924 2.5 4.05027 2.56585 3.93306 2.68306C3.81585 2.80027 3.75 2.95924 3.75 3.125V11.7663L7.09375 8.90063C7.20696 8.80379 7.35103 8.75058 7.5 8.75058C7.64897 8.75058 7.79304 8.80379 7.90625 8.90063L11.25 11.7656Z" fill="currentColor"/>
            </svg>

            <svg v-else-if="type === 'filled'" width="15" height="15" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path fill-rule="evenodd" clip-rule="evenodd" d="M3.53125 13.6C3.44045 13.6777 3.3293 13.7277 3.21096 13.7441C3.09262 13.7605 2.97204 13.7427 2.86353 13.6927C2.75501 13.6427 2.66309 13.5627 2.59866 13.4621C2.53423 13.3615 2.49999 13.2445 2.5 13.125V3.125C2.5 2.62772 2.69754 2.15081 3.04917 1.79917C3.40081 1.44754 3.87772 1.25 4.375 1.25H10.625C11.1223 1.25 11.5992 1.44754 11.9508 1.79917C12.3025 2.15081 12.5 2.62772 12.5 3.125V13.125C12.5 13.2445 12.4658 13.3615 12.4013 13.4621C12.3369 13.5627 12.245 13.6427 12.1365 13.6927C12.028 13.7427 11.9074 13.7605 11.789 13.7441C11.6707 13.7277 11.5595 13.6777 11.4688 13.6L7.5 10.1975L3.53125 13.6Z" fill="currentColor"/>
            </svg>

        </template>
    </Icon>
</template>

<script setup>
import { Icon } from '@bbc/front-end-kit/vue';
</script>

<style lang="scss">
    .icon.--bookmark {

    }
</style>

Tips

There might be other usefull ways to apply the type value to the component. Every specific Icon is free to use that value as they please as long as they don't break with the guidelines.

Guidelines

  • Always extend or wrap the component, provide it with default values, and ensure consistency across the project.
  • Always prefix the name of an Icon Vue component with Icon to avoid possible naming conflicts with other Vue components (ex: Calendar vs Calendar, one is the Icon the other is the Component)
  • Always provide specific Icons with a BEM modifier of the same name so they can easily be styled when used & extended.
  • Always use mono as the basic Icon type which is the Mono version of the icon where the colored part extends from the parents font color using the currenColor as color value.

API

Properties

type

The type of component to render. This value is passed to the default slot scope and applied as a --{type} BEM modifier class on the wrapping <span>. The specific icon component decides how to use it.

Values: String

Default: 'mono'

Slots

default

The slot that expects the icon specific content. Can be an svg, series of svgs triggered by v-if statements based on type or any other logic. It is up to the specific icon to decide.

Props:

  • type: the type value passed to the properties when the icons is used.

Built-in CSS modifiers

The base .icon class exposes one built-in modifier you can apply from outside:

ModifierEffect
--spinContinuously rotates the icon (2s linear loop). Useful for loading states.

Icons provided by the kit

The kit comes with a small set of icons already extended from Icon.vue. They can be imported from @bbc/front-end-kit/vue like any other component and are located at @bbc/front-end-kit/vue/components/icons/{IconName}.vue

Warning

Icons in the kit are named with the Icon prefix! (ex: Cross => IconCross)

Cross
MagicWand
Placeholder
Edit this page
Last Updated: 4/27/26, 12:56 PM
Contributors: Nicolas Jaenen