UNPKG

bootstrap-vue

Version:

BootstrapVue, with more than 85 custom components, over 45 plugins, several custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated W

311 lines (285 loc) 8.52 kB
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import Vue from '../../utils/vue'; import pluckProps from '../../utils/pluck-props'; import { getComponentConfig } from '../../utils/config'; import { isNumber, isString } from '../../utils/inspect'; import { toFloat } from '../../utils/number'; import { BButton } from '../button/button'; import { BLink } from '../link/link'; import { BIcon } from '../../icons/icon'; import { BIconPersonFill } from '../../icons/icons'; import normalizeSlotMixin from '../../mixins/normalize-slot'; // --- Constants --- var NAME = 'BAvatar'; var CLASS_NAME = 'b-avatar'; var RX_NUMBER = /^[0-9]*\.?[0-9]+$/; var FONT_SIZE_SCALE = 0.4; var BADGE_FONT_SIZE_SCALE = FONT_SIZE_SCALE * 0.7; var DEFAULT_SIZES = { sm: '1.5em', md: '2.5em', lg: '3.5em' }; // --- Props --- var linkProps = { href: { type: String // default: null }, to: { type: [String, Object] // default: null }, append: { type: Boolean, default: false }, replace: { type: Boolean, default: false }, disabled: { type: Boolean, default: false }, rel: { type: String // default: null }, target: { type: String // default: null }, activeClass: { type: String // default: null }, exact: { type: Boolean, default: false }, exactActiveClass: { type: String // default: null }, noPrefetch: { type: Boolean, default: false } }; var props = _objectSpread(_objectSpread({ src: { type: String // default: null }, text: { type: String // default: null }, icon: { type: String // default: null }, alt: { type: String, default: 'avatar' }, variant: { type: String, default: function _default() { return getComponentConfig(NAME, 'variant'); } }, size: { type: [Number, String], default: null }, square: { type: Boolean, default: false }, rounded: { type: [Boolean, String], default: false }, button: { type: Boolean, default: false }, buttonType: { type: String, default: 'button' }, badge: { type: [Boolean, String], default: false }, badgeVariant: { type: String, default: function _default() { return getComponentConfig(NAME, 'badgeVariant'); } }, badgeTop: { type: Boolean, default: false }, badgeLeft: { type: Boolean, default: false }, badgeOffset: { type: String, default: '0px' } }, linkProps), {}, { ariaLabel: { type: String // default: null } }); // --- Utility methods --- var computeSize = function computeSize(value) { // Default to `md` size when `null`, or parse to // number when value is a float-like string value = value === null ? 'md' : isString(value) && RX_NUMBER.test(value) ? toFloat(value, 0) : value; // Convert all numbers to pixel values // Handle default sizes when `sm`, `md` or `lg` // Or use value as is return isNumber(value) ? "".concat(value, "px") : DEFAULT_SIZES[value] || value; }; // --- Main component --- // @vue/component export var BAvatar = /*#__PURE__*/Vue.extend({ name: NAME, mixins: [normalizeSlotMixin], props: props, data: function data() { return { localSrc: this.src || null }; }, computed: { computedSize: function computedSize() { return computeSize(this.size); }, fontSize: function fontSize() { var size = this.computedSize; return size ? "calc(".concat(size, " * ").concat(FONT_SIZE_SCALE, ")") : null; }, badgeStyle: function badgeStyle() { var size = this.computedSize, badgeTop = this.badgeTop, badgeLeft = this.badgeLeft, badgeOffset = this.badgeOffset; var offset = badgeOffset || '0px'; return { fontSize: size ? "calc(".concat(size, " * ").concat(BADGE_FONT_SIZE_SCALE, " )") : null, top: badgeTop ? offset : null, bottom: badgeTop ? null : offset, left: badgeLeft ? offset : null, right: badgeLeft ? null : offset }; } }, watch: { src: function src(newSrc, oldSrc) { if (newSrc !== oldSrc) { this.localSrc = newSrc || null; } } }, methods: { onImgError: function onImgError(evt) { this.localSrc = null; this.$emit('img-error', evt); }, onClick: function onClick(evt) { this.$emit('click', evt); } }, render: function render(h) { var _class2; var variant = this.variant, disabled = this.disabled, square = this.square, icon = this.icon, src = this.localSrc, text = this.text, fontSize = this.fontSize, size = this.computedSize, isButton = this.button, type = this.buttonType, badge = this.badge, badgeVariant = this.badgeVariant, badgeStyle = this.badgeStyle; var isBLink = !isButton && (this.href || this.to); var tag = isButton ? BButton : isBLink ? BLink : 'span'; var rounded = square ? false : this.rounded === '' ? true : this.rounded || 'circle'; var alt = this.alt || null; var ariaLabel = this.ariaLabel || null; var $content = null; if (this.hasNormalizedSlot('default')) { // Default slot overrides props $content = h('span', { staticClass: 'b-avatar-custom' }, [this.normalizeSlot('default')]); } else if (src) { $content = h('img', { style: variant ? {} : { width: '100%', height: '100%' }, attrs: { src: src, alt: alt }, on: { error: this.onImgError } }); } else if (icon) { $content = h(BIcon, { props: { icon: icon }, attrs: { 'aria-hidden': 'true', alt: alt } }); } else if (text) { $content = h('span', { staticClass: 'b-avatar-text', style: { fontSize: fontSize } }, [h('span', text)]); } else { // Fallback default avatar content $content = h(BIconPersonFill, { attrs: { 'aria-hidden': 'true', alt: alt } }); } var $badge = h(); var hasBadgeSlot = this.hasNormalizedSlot('badge'); if (badge || badge === '' || hasBadgeSlot) { var badgeText = badge === true ? '' : badge; $badge = h('span', { staticClass: 'b-avatar-badge', class: _defineProperty({}, "badge-".concat(badgeVariant), !!badgeVariant), style: badgeStyle }, [hasBadgeSlot ? this.normalizeSlot('badge') : badgeText]); } var componentData = { staticClass: CLASS_NAME, class: (_class2 = {}, _defineProperty(_class2, "badge-".concat(variant), !isButton && variant), _defineProperty(_class2, "rounded", rounded === true), _defineProperty(_class2, 'rounded-0', square), _defineProperty(_class2, "rounded-".concat(rounded), rounded && rounded !== true), _defineProperty(_class2, "disabled", disabled), _class2), style: { width: size, height: size }, attrs: { 'aria-label': ariaLabel || null }, props: isButton ? { variant: variant, disabled: disabled, type: type } : isBLink ? pluckProps(linkProps, this) : {}, on: isBLink || isButton ? { click: this.onClick } : {} }; return h(tag, componentData, [$content, $badge]); } });