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
Iconto 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
monoas the basic Icon type which is the Mono version of the icon where the colored part extends from the parents font color using thecurrenColoras 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:
| Modifier | Effect |
|---|---|
--spin | Continuously 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)