bootstrap-vue
Version:
With more than 85 components, over 45 available plugins, several directives, and 1000+ icons, BootstrapVue provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system available for Vue.js v2.6, complete with extens
66 lines (57 loc) • 1.9 kB
JavaScript
import { extend } from '../../vue'
import { NAME_ASPECT } from '../../constants/components'
import { PROP_TYPE_NUMBER_STRING, PROP_TYPE_STRING } from '../../constants/props'
import { RX_ASPECT, RX_ASPECT_SEPARATOR } from '../../constants/regex'
import { mathAbs } from '../../utils/math'
import { toFloat } from '../../utils/number'
import { makeProp, makePropsConfigurable } from '../../utils/props'
import { normalizeSlotMixin } from '../../mixins/normalize-slot'
// --- Constants ---
const CLASS_NAME = 'b-aspect'
// --- Props ---
export const props = makePropsConfigurable(
{
// Accepts a number (i.e. `16 / 9`, `1`, `4 / 3`)
// Or a string (i.e. '16/9', '16:9', '4:3' '1:1')
aspect: makeProp(PROP_TYPE_NUMBER_STRING, '1:1'),
tag: makeProp(PROP_TYPE_STRING, 'div')
},
NAME_ASPECT
)
// --- Main component ---
// @vue/component
export const BAspect = /*#__PURE__*/ extend({
name: NAME_ASPECT,
mixins: [normalizeSlotMixin],
props,
computed: {
padding() {
const { aspect } = this
let ratio = 1
if (RX_ASPECT.test(aspect)) {
// Width and/or Height can be a decimal value below `1`, so
// we only fallback to `1` if the value is `0` or `NaN`
const [width, height] = aspect.split(RX_ASPECT_SEPARATOR).map(v => toFloat(v) || 1)
ratio = width / height
} else {
ratio = toFloat(aspect) || 1
}
return `${100 / mathAbs(ratio)}%`
}
},
render(h) {
const $sizer = h('div', {
staticClass: `${CLASS_NAME}-sizer flex-grow-1`,
style: { paddingBottom: this.padding, height: 0 }
})
const $content = h(
'div',
{
staticClass: `${CLASS_NAME}-content flex-grow-1 w-100 mw-100`,
style: { marginLeft: '-100%' }
},
this.normalizeSlot()
)
return h(this.tag, { staticClass: `${CLASS_NAME} d-flex` }, [$sizer, $content])
}
})