68 lines
1.9 KiB
Vue
68 lines
1.9 KiB
Vue
<template>
|
|
<i
|
|
:class="iconClass"
|
|
:style="iconStyle"
|
|
aria-hidden="true"
|
|
></i>
|
|
</template>
|
|
|
|
<script setup>
|
|
/**
|
|
* FaIcon — Font Awesome 5 icon wrapper component.
|
|
*
|
|
* Usage:
|
|
* <FaIcon icon="fa fas fa-cog" />
|
|
* <FaIcon icon="fa-cog" /> → defaults to solid FA5
|
|
* <FaIcon icon="fa fab fa-github" />
|
|
* <FaIcon :size="18" icon="fa fas fa-heart" />
|
|
* <FaIcon spin icon="fa fas fa-spinner" />
|
|
*/
|
|
import { computed } from 'vue'
|
|
|
|
const props = defineProps({
|
|
/** FA5 class string, e.g. "fa fas fa-cog", "fa fab fa-github", or just "fa-cog" */
|
|
icon: { type: String, required: true },
|
|
/** Pixel size — maps to font-size */
|
|
size: { type: [Number, String], default: null },
|
|
/** Fixed width icon */
|
|
fw: { type: Boolean, default: false },
|
|
/** Spin animation */
|
|
spin: { type: Boolean, default: false },
|
|
/** Pulse animation */
|
|
pulse: { type: Boolean, default: false },
|
|
/** Rotation (90, 180, 270) */
|
|
rotate: { type: [Number, String], default: null },
|
|
/** Flip direction ('horizontal', 'vertical', 'both') */
|
|
flip: { type: String, default: null },
|
|
/** Additional CSS classes */
|
|
extraClass: { type: String, default: '' },
|
|
})
|
|
|
|
const iconClass = computed(() => {
|
|
const parts = []
|
|
|
|
// Auto-prefix: if only "fa-circle" is given, use the solid FA5 style.
|
|
const raw = props.icon.trim()
|
|
if (raw.startsWith('fa-')) {
|
|
parts.push('fa', 'fas', raw)
|
|
} else {
|
|
parts.push(...raw.split(/\s+/))
|
|
}
|
|
|
|
if (props.fw) parts.push('fa-fw')
|
|
if (props.spin) parts.push('fa-spin')
|
|
if (props.pulse) parts.push('fa-pulse')
|
|
if (props.rotate) parts.push(`fa-rotate-${props.rotate}`)
|
|
if (props.flip) parts.push(`fa-flip-${props.flip}`)
|
|
if (props.extraClass) parts.push(props.extraClass)
|
|
|
|
return parts.join(' ')
|
|
})
|
|
|
|
const iconStyle = computed(() => {
|
|
if (!props.size) return {}
|
|
const s = typeof props.size === 'number' ? `${props.size}px` : props.size
|
|
return { fontSize: s }
|
|
})
|
|
</script>
|