Icon
A component to display any icon from Iconify.
Demo
Related Theme
This requires the following theme to be installed:
Component
vue
<script lang="ts">
import theme from '@/ui/theme/icon'
import { Primitive } from 'reka-ui'
import { tv } from 'tailwind-variants'
import { computed } from 'vue'
const icon = tv(theme)
export interface IconProps {
as?: any
name?: string
class?: any
}
export interface IconEmits {}
export interface IconSlots {}
</script>
<script lang="ts" setup>
const props = withDefaults(defineProps<IconProps>(), {
as: 'span',
})
defineEmits<IconEmits>()
defineSlots<IconSlots>()
const ui = computed(() => icon({
class: [props.name, props.class],
}))
</script>
<template>
<Primitive :as="as" :class="ui" />
</template>vue
<script lang="ts">
import theme from '@/UI/Theme/icon'
import { Primitive } from 'reka-ui'
import { tv } from 'tailwind-variants'
import { computed } from 'vue'
const icon = tv(theme)
export interface IconProps {
as?: any
name?: string
class?: any
}
export interface IconEmits {}
export interface IconSlots {}
</script>
<script lang="ts" setup>
const props = withDefaults(defineProps<IconProps>(), {
as: 'span',
})
defineEmits<IconEmits>()
defineSlots<IconSlots>()
const ui = computed(() => icon({
class: [props.name, props.class],
}))
</script>
<template>
<Primitive :as="as" :class="ui" />
</template>Theme
ts
export default {
base: '',
}View Nuxt UI theme
ts
export default {
base: 'inline-block',
}Test
To test this component, you can use the following test file:
ts
import type { RenderOptions } from '@testing-library/vue'
import Icon from '@/ui/components/Icon.vue'
import { render, screen } from '@testing-library/vue'
import { describe, expect, it } from 'vitest'
describe('icon', () => {
const props = { name: 'i-lucide-alarm-clock' }
it.each<[string, RenderOptions<typeof Icon>]>([
// Props
['with icon', { props }],
['with as', { props: { ...props, as: 'div' } }],
['with class', { props: { ...props, class: 'custom-class' } }],
])('renders %s correctly', (name, options) => {
render(Icon, {
attrs: {
'data-testid': 'icon',
},
...options,
})
expect(screen.getByTestId('icon')).matchSnapshot()
})
})ts
import type { RenderOptions } from '@testing-library/vue'
import Icon from '@/UI/Components/Icon.vue'
import { render, screen } from '@testing-library/vue'
import { describe, expect, it } from 'vitest'
describe('icon', () => {
const props = { name: 'i-lucide-alarm-clock' }
it.each<[string, RenderOptions<typeof Icon>]>([
// Props
['with icon', { props }],
['with as', { props: { ...props, as: 'div' } }],
['with class', { props: { ...props, class: 'custom-class' } }],
])('renders %s correctly', (name, options) => {
render(Icon, {
attrs: {
'data-testid': 'icon',
},
...options,
})
expect(screen.getByTestId('icon')).matchSnapshot()
})
})