@ishitatsuyuki/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
240 lines (234 loc) • 7.81 kB
JavaScript
import { defineComponent, openBlock, createBlock, Fragment, createCommentVNode, resolveDynamicComponent } from 'vue';
import { getValueByPath, merge } from './helpers.mjs';
import { getOptions } from './config.mjs';
import { B as BaseComponentMixin } from './BaseComponentMixin-d78ed3dc.mjs';
const mdiIcons = {
sizes: {
'default': 'mdi-24px',
'small': null,
'medium': 'mdi-36px',
'large': 'mdi-48px'
},
iconPrefix: 'mdi-'
};
const faIcons = () => {
const iconComponent = getValueByPath(getOptions(), 'iconComponent');
const faIconPrefix = iconComponent ? '' : 'fa-';
return {
sizes: {
'default': null,
'small': null,
'medium': faIconPrefix + 'lg',
'large': faIconPrefix + '2x'
},
iconPrefix: faIconPrefix,
internalIcons: {
'check': 'check',
'information': 'info-circle',
'alert': 'exclamation-triangle',
'alert-circle': 'exclamation-circle',
'arrow-up': 'arrow-up',
'chevron-right': 'angle-right',
'chevron-left': 'angle-left',
'chevron-down': 'angle-down',
'chevron-up': 'angle-up',
'eye': 'eye',
'eye-off': 'eye-slash',
'caret-down': 'caret-down',
'caret-up': 'caret-up',
'close-circle': 'times-circle',
'close': 'times',
'loading': 'circle-notch'
}
};
};
const getIcons = () => {
let icons = {
mdi: mdiIcons,
fa: faIcons(),
fas: faIcons(),
far: faIcons(),
fad: faIcons(),
fab: faIcons(),
fal: faIcons()
};
const customIconPacks = getValueByPath(getOptions(), 'customIconPacks');
if (customIconPacks) {
icons = merge(icons, customIconPacks, true);
}
return icons;
};
/**
* Icons take an important role of any application
* @displayName Icon
* @style _icon.scss
*/
var script = defineComponent({
name: 'OIcon',
mixins: [BaseComponentMixin],
configField: 'icon',
props: {
/**
* Color of the icon, optional
* @values primary, info, success, warning, danger, and any other custom color
*/
variant: [String, Object],
/**
* Icon component name
*/
component: String,
/**
* Icon pack to use
* @values mdi, fa, fas and any other custom icon pack
*/
pack: String,
/**
* Icon name
*/
icon: String,
/**
* Icon size, optional
* @values small, medium, large
*/
size: String,
/**
* Overrides icon font size, optional
* @values Depends on library: null (smallest), fa-lg, fa-2x, fa-3x, fa-4x, fa-5x, mdi-18px, mdi-24px, mdi-36px, mdi-48px
*/
customSize: String,
/**
* Add class to icon font, optional. See here for MDI, here for FontAwesome 4 and here for FontAwesome 5 custom classes
*/
customClass: String,
/**
* When true makes icon clickable
*/
clickable: Boolean,
/** Enable spin effect on icon */
spin: Boolean,
/** Rotation 0-360 */
rotation: [Number, String],
/** @ignore */
both: Boolean,
rootClass: [String, Function, Array],
clickableClass: [String, Function, Array],
spinClass: [String, Function, Array],
sizeClass: [String, Function, Array],
variantClass: [String, Function, Array]
},
computed: {
rootClasses() {
return [
this.computedClass('rootClass', 'o-icon'),
{ [this.computedClass('clickableClass', 'o-icon--clickable')]: this.clickable },
{ [this.computedClass('spinClass', 'o-icon--spin')]: this.spin },
{ [this.computedClass('sizeClass', 'o-icon--', this.size)]: this.size },
{ [this.computedClass('variantClass', 'o-icon--', this.newVariant)]: this.newVariant }
];
},
rootStyle() {
const style = {};
if (this.rotation) {
style['transform'] = `rotate(${this.rotation}deg)`;
}
return style;
},
iconConfig() {
return getIcons()[this.newPack];
},
iconPrefix() {
if (this.iconConfig && this.iconConfig.iconPrefix) {
return this.iconConfig.iconPrefix;
}
return '';
},
/**
* Internal icon name based on the pack.
* If pack is 'fa', gets the equivalent FA icon name of the MDI,
* internal icons are always MDI.
*/
newIcon() {
return `${this.iconPrefix}${this.getEquivalentIconOf(this.icon)}`;
},
newPack() {
return this.pack || getValueByPath(getOptions(), 'iconPack', 'mdi');
},
newVariant() {
if (!this.variant)
return;
let newVariant = '';
if (typeof this.variant === 'string') {
newVariant = this.variant;
}
else {
newVariant = Object.keys(this.variant).filter(key => this.variant[key])[0];
}
return newVariant;
},
newCustomSize() {
return this.customSize || this.customSizeByPack;
},
customSizeByPack() {
if (this.iconConfig && this.iconConfig.sizes) {
if (this.size && this.iconConfig.sizes[this.size] !== undefined) {
return this.iconConfig.sizes[this.size];
}
else if (this.iconConfig.sizes.default) {
return this.iconConfig.sizes.default;
}
}
return null;
},
useIconComponent() {
if (this.component)
return this.component;
const component = getValueByPath(getOptions(), 'iconComponent');
if (component)
return component;
return null;
}
},
methods: {
/**
* Equivalent icon name of the MDI.
*/
getEquivalentIconOf(value) {
// Only transform the class if the both prop is set to true
if (!this.both) {
return value;
}
if (this.iconConfig &&
this.iconConfig.internalIcons &&
this.iconConfig.internalIcons[value]) {
return this.iconConfig.internalIcons[value];
}
return value;
}
}
});
function render(_ctx, _cache, $props, $setup, $data, $options) {
return openBlock(), createBlock("span", {
class: _ctx.rootClasses,
style: _ctx.rootStyle
}, [!_ctx.useIconComponent ? (openBlock(), createBlock("i", {
key: 0,
class: [_ctx.newPack, _ctx.newIcon, _ctx.newCustomSize, _ctx.customClass]
}, null, 2
/* CLASS */
)) : (openBlock(), createBlock(Fragment, {
key: 1
}, [createCommentVNode(" custom icon component "), (openBlock(), createBlock(resolveDynamicComponent(_ctx.useIconComponent), {
icon: [_ctx.newPack, _ctx.newIcon],
size: _ctx.newCustomSize,
class: [_ctx.customClass]
}, null, 8
/* PROPS */
, ["icon", "size", "class"]))], 64
/* STABLE_FRAGMENT */
))], 6
/* CLASS, STYLE */
);
}
script.render = render;
script.__file = "src/components/icon/Icon.vue";
export { script as s };