import { classList, objectWithKey } from '../utils' import { computed, defineComponent, watch } from 'vue' import { icon as faIcon, parse as faParse } from '@fortawesome/fontawesome-svg-core' import convert from '../converter' import log from '../logger' function normalizeIconArgs(icon) { if (icon && typeof icon === 'object' && icon.prefix && icon.iconName && icon.icon) { return icon } if (faParse.icon) { return faParse.icon(icon) } if (icon === null) { return null } if (typeof icon === 'object' && icon.prefix && icon.iconName) { return icon } if (Array.isArray(icon) && icon.length === 2) { return { prefix: icon[0], iconName: icon[1] } } if (typeof icon === 'string') { return { prefix: 'fas', iconName: icon } } } export default defineComponent({ name: 'FontAwesomeIcon', props: { border: { type: Boolean, default: false }, // the fixedWidth property has been deprecated as of version 7 fixedWidth: { type: Boolean, default: false }, flip: { type: [Boolean, String], default: false, validator: (value) => [true, false, 'horizontal', 'vertical', 'both'].indexOf(value) > -1 }, icon: { type: [Object, Array, String], required: true }, mask: { type: [Object, Array, String], default: null }, maskId: { type: String, default: null }, listItem: { type: Boolean, default: false }, pull: { type: String, default: null, validator: (value) => ['right', 'left'].indexOf(value) > -1 }, pulse: { type: Boolean, default: false }, rotation: { type: [String, Number], default: null, validator: (value) => [90, 180, 270].indexOf(Number.parseInt(value, 10)) > -1 }, // the rotateBy property is only supported in version 7.0.0 and later rotateBy: { type: Boolean, default: false }, swapOpacity: { type: Boolean, default: false }, size: { type: String, default: null, validator: (value) => ['2xs', 'xs', 'sm', 'lg', 'xl', '2xl', '1x', '2x', '3x', '4x', '5x', '6x', '7x', '8x', '9x', '10x'].indexOf(value) > -1 }, spin: { type: Boolean, default: false }, transform: { type: [String, Object], default: null }, symbol: { type: [Boolean, String], default: false }, title: { type: String, default: null }, titleId: { type: String, default: null }, inverse: { type: Boolean, default: false }, bounce: { type: Boolean, default: false }, shake: { type: Boolean, default: false }, beat: { type: Boolean, default: false }, fade: { type: Boolean, default: false }, beatFade: { type: Boolean, default: false }, flash: { type: Boolean, default: false }, spinPulse: { type: Boolean, default: false }, spinReverse: { type: Boolean, default: false }, // the widthAuto property is only supported in version 7.0.0 and later widthAuto: { type: Boolean, default: false }, // the canvasSquare and canvasRoomy properties are only supported in version 7.3.0 and later canvasSquare: { type: Boolean, default: false }, canvasRoomy: { type: Boolean, default: false }, gradientFill: { type: Object, default: null, validator(value) { if (typeof value.id !== 'string' || !value.id) { console.warn('FontAwesomeIcon: gradientFill.id must be a non-empty string') return false } if (value.type !== 'linear' && value.type !== 'radial') { console.warn('FontAwesomeIcon: gradientFill.type must be "linear" or "radial"') return false } return true } }, // the following animation properties are only supported in version 7.3.0 and later flip360: { type: Boolean, default: false }, buzz: { type: Boolean, default: false }, float: { type: Boolean, default: false }, jello: { type: Boolean, default: false }, spinSnap: { type: Boolean, default: false }, spinSnap4: { type: Boolean, default: false }, spinSnap8: { type: Boolean, default: false }, swing: { type: Boolean, default: false }, wag: { type: Boolean, default: false } }, setup(props, { attrs }) { const icon = computed(() => normalizeIconArgs(props.icon)) const classes = computed(() => objectWithKey('classes', classList(props))) const transform = computed(() => objectWithKey('transform', typeof props.transform === 'string' ? faParse.transform(props.transform) : props.transform)) const mask = computed(() => objectWithKey('mask', normalizeIconArgs(props.mask))) const renderedIcon = computed(() => { const iconProps = { ...classes.value, ...transform.value, ...mask.value, symbol: props.symbol, maskId: props.maskId } // the title attribute will only apply to versions prior to version 7.0.0 iconProps.title = props.title iconProps.titleId = props.titleId return faIcon(icon.value, iconProps) }) watch( renderedIcon, (value) => { if (!value) { return log('Could not find one or more icon(s)', icon.value, mask.value) } }, { immediate: true } ) if (props.gradientFill && props.symbol) { log('gradientFill is not supported when symbol is true and will be ignored') } const vnode = computed(() => renderedIcon.value ? convert(renderedIcon.value.abstract[0], { gradientFill: props.symbol ? null : props.gradientFill }, attrs) : null ) return () => vnode.value } })