first commit

This commit is contained in:
DanielRamirezGe
2020-01-14 20:43:08 -06:00
parent 3557894f7f
commit 5eecfbf6cd
26326 changed files with 2434803 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
import Vue, { PluginFunction, PluginObject } from 'vue'
import { BvPlugin } from './'
export declare const BVConfigPlugin: BvPlugin
+7
View File
@@ -0,0 +1,7 @@
//
// Utility Plugin for setting the configuration
//
import { pluginFactory } from './utils/plugins';
export var BVConfigPlugin =
/*#__PURE__*/
pluginFactory();
+193
View File
@@ -0,0 +1,193 @@
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 { getComponentConfig } from '../../utils/config';
import { requestAF } from '../../utils/dom';
import { isBoolean } from '../../utils/inspect';
import BVTransition from '../../utils/bv-transition';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import { BButtonClose } from '../button/button-close';
var NAME = 'BAlert'; // Convert `show` value to a number
var parseCountDown = function parseCountDown(show) {
if (show === '' || isBoolean(show)) {
return 0;
}
show = parseInt(show, 10);
return show > 0 ? show : 0;
}; // Convert `show` value to a boolean
var parseShow = function parseShow(show) {
if (show === '' || show === true) {
return true;
}
if (parseInt(show, 10) < 1) {
// Boolean will always return false for the above comparison
return false;
}
return Boolean(show);
}; // Is a value number like (i.e. a number or a number as string)
var isNumericLike = function isNumericLike(value) {
return !isNaN(parseInt(value, 10));
}; // @vue/component
export var BAlert =
/*#__PURE__*/
Vue.extend({
name: NAME,
mixins: [normalizeSlotMixin],
model: {
prop: 'show',
event: 'input'
},
props: {
variant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'variant');
}
},
dismissible: {
type: Boolean,
default: false
},
dismissLabel: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'dismissLabel');
}
},
show: {
type: [Boolean, Number, String],
default: false
},
fade: {
type: Boolean,
default: false
}
},
data: function data() {
return {
countDownTimerId: null,
countDown: 0,
// If initially shown, we need to set these for SSR
localShow: parseShow(this.show)
};
},
watch: {
show: function show(newVal) {
this.countDown = parseCountDown(newVal);
this.localShow = parseShow(newVal);
},
countDown: function countDown(newVal) {
var _this = this;
this.clearTimer();
if (isNumericLike(this.show)) {
// Ignore if this.show transitions to a boolean value.
this.$emit('dismiss-count-down', newVal);
if (this.show !== newVal) {
// Update the v-model if needed
this.$emit('input', newVal);
}
if (newVal > 0) {
this.localShow = true;
this.countDownTimerId = setTimeout(function () {
_this.countDown--;
}, 1000);
} else {
// Slightly delay the hide to allow any UI updates
this.$nextTick(function () {
requestAF(function () {
_this.localShow = false;
});
});
}
}
},
localShow: function localShow(newVal) {
if (!newVal && (this.dismissible || isNumericLike(this.show))) {
// Only emit dismissed events for dismissible or auto dismissing alerts
this.$emit('dismissed');
}
if (!isNumericLike(this.show) && this.show !== newVal) {
// Only emit booleans if we weren't passed a number via `this.show`
this.$emit('input', newVal);
}
}
},
created: function created() {
this.countDown = parseCountDown(this.show);
this.localShow = parseShow(this.show);
},
mounted: function mounted() {
this.countDown = parseCountDown(this.show);
this.localShow = parseShow(this.show);
},
beforeDestroy: function beforeDestroy() {
this.clearTimer();
},
methods: {
dismiss: function dismiss() {
this.clearTimer();
this.countDown = 0;
this.localShow = false;
},
clearTimer: function clearTimer() {
if (this.countDownTimerId) {
clearInterval(this.countDownTimerId);
this.countDownTimerId = null;
}
}
},
render: function render(h) {
var $alert; // undefined
if (this.localShow) {
var $dismissBtn = h();
if (this.dismissible) {
// Add dismiss button
$dismissBtn = h(BButtonClose, {
attrs: {
'aria-label': this.dismissLabel
},
on: {
click: this.dismiss
}
}, [this.normalizeSlot('dismiss')]);
}
$alert = h('div', {
key: this._uid,
staticClass: 'alert',
class: _defineProperty({
'alert-dismissible': this.dismissible
}, "alert-".concat(this.variant), this.variant),
attrs: {
role: 'alert',
'aria-live': 'polite',
'aria-atomic': true
}
}, [$dismissBtn, this.normalizeSlot('default')]);
$alert = [$alert];
}
return h(BVTransition, {
props: {
noFade: !this.fade
}
}, $alert);
}
});
+13
View File
@@ -0,0 +1,13 @@
//
// Alert
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const AlertPlugin: BvPlugin
// Component: b-alert
export declare class BAlert extends BvComponent {
dismiss: () => void
}
+10
View File
@@ -0,0 +1,10 @@
import { BAlert } from './alert';
import { pluginFactory } from '../../utils/plugins';
var AlertPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BAlert: BAlert
}
});
export { AlertPlugin, BAlert };
+55
View File
@@ -0,0 +1,55 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import { getComponentConfig } from '../../utils/config';
import pluckProps from '../../utils/pluck-props';
import { BLink, propsFactory as linkPropsFactory } from '../link/link';
var NAME = 'BBadge';
var linkProps = linkPropsFactory();
delete linkProps.href.default;
delete linkProps.to.default;
export var props = _objectSpread({}, linkProps, {
tag: {
type: String,
default: 'span'
},
variant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'variant');
}
},
pill: {
type: Boolean,
default: false
}
}); // @vue/component
export var BBadge =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var tag = !props.href && !props.to ? props.tag : BLink;
var componentData = {
staticClass: 'badge',
class: [props.variant ? "badge-".concat(props.variant) : 'badge-secondary', {
'badge-pill': Boolean(props.pill),
active: props.active,
disabled: props.disabled
}],
props: pluckProps(linkProps, props)
};
return h(tag, mergeData(data, componentData), children);
}
});
+11
View File
@@ -0,0 +1,11 @@
//
// Badge
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const BadgePlugin: BvPlugin
// Component: b-badge
export declare class BBadge extends BvComponent {}
+10
View File
@@ -0,0 +1,10 @@
import { BBadge } from './badge';
import { pluginFactory } from '../../utils/plugins';
var BadgePlugin =
/*#__PURE__*/
pluginFactory({
components: {
BBadge: BBadge
}
});
export { BadgePlugin, BBadge };
@@ -0,0 +1,24 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
import { BBreadcrumbLink, props } from './breadcrumb-link'; // @vue/component
export var BBreadcrumbItem =
/*#__PURE__*/
Vue.extend({
name: 'BBreadcrumbItem',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h('li', mergeData(data, {
staticClass: 'breadcrumb-item',
class: {
active: props.active
}
}), [h(BBreadcrumbLink, {
props: props
}, children)]);
}
});
@@ -0,0 +1,54 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import pluckProps from '../../utils/pluck-props';
import { htmlOrText } from '../../utils/html';
import { BLink, propsFactory as linkPropsFactory } from '../link/link';
export var props = _objectSpread({}, linkPropsFactory(), {
text: {
type: String,
default: null
},
html: {
type: String,
default: null
},
ariaCurrent: {
type: String,
default: 'location'
}
}); // @vue/component
export var BBreadcrumbLink =
/*#__PURE__*/
Vue.extend({
name: 'BBreadcrumbLink',
functional: true,
props: props,
render: function render(h, _ref) {
var suppliedProps = _ref.props,
data = _ref.data,
children = _ref.children;
var tag = suppliedProps.active ? 'span' : BLink;
var componentData = {
props: pluckProps(props, suppliedProps)
};
if (suppliedProps.active) {
componentData.attrs = {
'aria-current': suppliedProps.ariaCurrent
};
}
if (!children) {
componentData.domProps = htmlOrText(suppliedProps.html, suppliedProps.text);
}
return h(tag, mergeData(data, componentData), children);
}
});
+64
View File
@@ -0,0 +1,64 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import toString from '../../utils/to-string';
import { isArray, isObject } from '../../utils/inspect';
import { BBreadcrumbItem } from './breadcrumb-item';
export var props = {
items: {
type: Array,
default: null
}
}; // @vue/component
export var BBreadcrumb =
/*#__PURE__*/
Vue.extend({
name: 'BBreadcrumb',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var childNodes = children; // Build child nodes from items if given.
if (isArray(props.items)) {
var activeDefined = false;
childNodes = props.items.map(function (item, idx) {
if (!isObject(item)) {
item = {
text: toString(item)
};
} // Copy the value here so we can normalize it.
var active = item.active;
if (active) {
activeDefined = true;
}
if (!active && !activeDefined) {
// Auto-detect active by position in list.
active = idx + 1 === props.items.length;
}
return h(BBreadcrumbItem, {
props: _objectSpread({}, item, {
active: active
})
});
});
}
return h('ol', mergeData(data, {
staticClass: 'breadcrumb'
}), childNodes);
}
});
+17
View File
@@ -0,0 +1,17 @@
//
// Breadcrumb
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const BreadcrumbPlugin: BvPlugin
// Component: b-breadcrumb
export declare class BBreadcrumb extends BvComponent {}
// Component: b-breadcrumb-item
export declare class BBreadcrumbItem extends BvComponent {}
// Component: b-breadcrumb-link
export declare class BBreadcrumbLink extends BvComponent {}
+14
View File
@@ -0,0 +1,14 @@
import { BBreadcrumb } from './breadcrumb';
import { BBreadcrumbItem } from './breadcrumb-item';
import { BBreadcrumbLink } from './breadcrumb-link';
import { pluginFactory } from '../../utils/plugins';
var BreadcrumbPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BBreadcrumb: BBreadcrumb,
BBreadcrumbItem: BBreadcrumbItem,
BBreadcrumbLink: BBreadcrumbLink
}
});
export { BreadcrumbPlugin, BBreadcrumb, BBreadcrumbItem, BBreadcrumbLink };
+48
View File
@@ -0,0 +1,48 @@
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 { mergeData } from 'vue-functional-data-merge';
import { getComponentConfig } from '../../utils/config';
var NAME = 'BButtonGroup';
export var props = {
vertical: {
type: Boolean,
default: false
},
size: {
type: String,
default: function _default() {
return getComponentConfig('BButton', 'size');
}
},
tag: {
type: String,
default: 'div'
},
ariaRole: {
type: String,
default: 'group'
}
}; // @vue/component
export var BButtonGroup =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.tag, mergeData(data, {
class: _defineProperty({
'btn-group': !props.vertical,
'btn-group-vertical': props.vertical
}, "btn-group-".concat(props.size), Boolean(props.size)),
attrs: {
role: props.ariaRole
}
}), children);
}
});
+11
View File
@@ -0,0 +1,11 @@
//
// Button Group
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const ButtonGroupPlugin: BvPlugin
// Component: b-button-group
export declare class BButtonGroup extends BvComponent {}
+11
View File
@@ -0,0 +1,11 @@
import { BButtonGroup } from './button-group';
import { pluginFactory } from '../../utils/plugins';
var ButtonGroupPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BButtonGroup: BButtonGroup,
BBtnGroup: BButtonGroup
}
});
export { ButtonGroupPlugin, BButtonGroup };
@@ -0,0 +1,113 @@
import Vue from '../../utils/vue';
import { isVisible, selectAll } from '../../utils/dom';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import KeyCodes from '../../utils/key-codes';
var ITEM_SELECTOR = ['.btn:not(.disabled):not([disabled]):not(.dropdown-item)', '.form-control:not(.disabled):not([disabled])', 'select:not(.disabled):not([disabled])', 'input[type="checkbox"]:not(.disabled)', 'input[type="radio"]:not(.disabled)'].join(','); // @vue/component
export var BButtonToolbar =
/*#__PURE__*/
Vue.extend({
name: 'BButtonToolbar',
mixins: [normalizeSlotMixin],
props: {
justify: {
type: Boolean,
default: false
},
keyNav: {
type: Boolean,
default: false
}
},
mounted: function mounted() {
if (this.keyNav) {
// Pre-set the tabindexes if the markup does not include tabindex="-1" on the toolbar items
this.getItems();
}
},
methods: {
onFocusin: function onFocusin(evt) {
if (evt.target === this.$el) {
evt.preventDefault();
evt.stopPropagation();
this.focusFirst(evt);
}
},
stop: function stop(evt) {
evt.preventDefault();
evt.stopPropagation();
},
onKeydown: function onKeydown(evt) {
if (!this.keyNav) {
/* istanbul ignore next: should never happen */
return;
}
var key = evt.keyCode;
var shift = evt.shiftKey;
if (key === KeyCodes.UP || key === KeyCodes.LEFT) {
this.stop(evt);
shift ? this.focusFirst(evt) : this.focusPrev(evt);
} else if (key === KeyCodes.DOWN || key === KeyCodes.RIGHT) {
this.stop(evt);
shift ? this.focusLast(evt) : this.focusNext(evt);
}
},
setItemFocus: function setItemFocus(item) {
item && item.focus && item.focus();
},
focusFirst: function focusFirst(evt) {
var items = this.getItems();
this.setItemFocus(items[0]);
},
focusPrev: function focusPrev(evt) {
var items = this.getItems();
var index = items.indexOf(evt.target);
if (index > -1) {
items = items.slice(0, index).reverse();
this.setItemFocus(items[0]);
}
},
focusNext: function focusNext(evt) {
var items = this.getItems();
var index = items.indexOf(evt.target);
if (index > -1) {
items = items.slice(index + 1);
this.setItemFocus(items[0]);
}
},
focusLast: function focusLast(evt) {
var items = this.getItems().reverse();
this.setItemFocus(items[0]);
},
getItems: function getItems() {
var items = selectAll(ITEM_SELECTOR, this.$el);
items.forEach(function (item) {
// Ensure tabfocus is -1 on any new elements
item.tabIndex = -1;
});
return items.filter(function (el) {
return isVisible(el);
});
}
},
render: function render(h) {
return h('div', {
staticClass: 'btn-toolbar',
class: {
'justify-content-between': this.justify
},
attrs: {
role: 'toolbar',
tabindex: this.keyNav ? '0' : null
},
on: this.keyNav ? {
focusin: this.onFocusin,
keydown: this.onKeydown
} : {}
}, [this.normalizeSlot('default')]);
}
});
+11
View File
@@ -0,0 +1,11 @@
//
// Button Toolbar
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const ButtonToolbarPlugin: BvPlugin
// Component: b-button-toolbar
export declare class BButtonToolbar extends BvComponent {}
+11
View File
@@ -0,0 +1,11 @@
import { BButtonToolbar } from './button-toolbar';
import { pluginFactory } from '../../utils/plugins';
var ButtonToolbarPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BButtonToolbar: BButtonToolbar,
BBtnToolbar: BButtonToolbar
}
});
export { ButtonToolbarPlugin, BButtonToolbar };
+71
View File
@@ -0,0 +1,71 @@
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 { mergeData } from 'vue-functional-data-merge';
import { getComponentConfig } from '../../utils/config';
import { isEvent } from '../../utils/inspect';
import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot';
var NAME = 'BButtonClose';
var props = {
disabled: {
type: Boolean,
default: false
},
ariaLabel: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'ariaLabel');
}
},
textVariant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'textVariant');
}
}
}; // @vue/component
export var BButtonClose =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
listeners = _ref.listeners,
slots = _ref.slots,
scopedSlots = _ref.scopedSlots;
var $slots = slots();
var $scopedSlots = scopedSlots || {};
var componentData = {
staticClass: 'close',
class: _defineProperty({}, "text-".concat(props.textVariant), props.textVariant),
attrs: {
type: 'button',
disabled: props.disabled,
'aria-label': props.ariaLabel ? String(props.ariaLabel) : null
},
on: {
click: function click(evt) {
// Ensure click on button HTML content is also disabled
/* istanbul ignore if: bug in JSDOM still emits click on inner element */
if (props.disabled && isEvent(evt)) {
evt.stopPropagation();
evt.preventDefault();
}
}
}
}; // Careful not to override the default slot with innerHTML
if (!hasNormalizedSlot('default', $scopedSlots, $slots)) {
componentData.domProps = {
innerHTML: '&times;'
};
}
return h('button', mergeData(data, componentData), normalizeSlot('default', {}, $scopedSlots, $slots));
}
});
+199
View File
@@ -0,0 +1,199 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import pluckProps from '../../utils/pluck-props';
import { concat } from '../../utils/array';
import { getComponentConfig } from '../../utils/config';
import { addClass, removeClass } from '../../utils/dom';
import { isBoolean, isEvent, isFunction } from '../../utils/inspect';
import { keys } from '../../utils/object';
import { BLink, propsFactory as linkPropsFactory } from '../link/link'; // --- Constants --
var NAME = 'BButton';
var btnProps = {
block: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
size: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'size');
}
},
variant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'variant');
}
},
type: {
type: String,
default: 'button'
},
tag: {
type: String,
default: 'button'
},
pill: {
type: Boolean,
default: false
},
squared: {
type: Boolean,
default: false
},
pressed: {
// tri-state prop: true, false or null
// => on, off, not a toggle
type: Boolean,
default: null
}
};
var linkProps = linkPropsFactory();
delete linkProps.href.default;
delete linkProps.to.default;
var linkPropKeys = keys(linkProps);
export var props = _objectSpread({}, linkProps, {}, btnProps); // --- Helper methods ---
// Focus handler for toggle buttons. Needs class of 'focus' when focused.
var handleFocus = function handleFocus(evt) {
if (evt.type === 'focusin') {
addClass(evt.target, 'focus');
} else if (evt.type === 'focusout') {
removeClass(evt.target, 'focus');
}
}; // Is the requested button a link?
var isLink = function isLink(props) {
// If tag prop is set to `a`, we use a b-link to get proper disabled handling
return Boolean(props.href || props.to || props.tag && String(props.tag).toLowerCase() === 'a');
}; // Is the button to be a toggle button?
var isToggle = function isToggle(props) {
return isBoolean(props.pressed);
}; // Is the button "really" a button?
var isButton = function isButton(props) {
if (isLink(props)) {
return false;
} else if (props.tag && String(props.tag).toLowerCase() !== 'button') {
return false;
}
return true;
}; // Is the requested tag not a button or link?
var isNonStandardTag = function isNonStandardTag(props) {
return !isLink(props) && !isButton(props);
}; // Compute required classes (non static classes)
var computeClass = function computeClass(props) {
var _ref;
return ["btn-".concat(props.variant || getComponentConfig(NAME, 'variant')), (_ref = {}, _defineProperty(_ref, "btn-".concat(props.size), Boolean(props.size)), _defineProperty(_ref, 'btn-block', props.block), _defineProperty(_ref, 'rounded-pill', props.pill), _defineProperty(_ref, 'rounded-0', props.squared && !props.pill), _defineProperty(_ref, "disabled", props.disabled), _defineProperty(_ref, "active", props.pressed), _ref)];
}; // Compute the link props to pass to b-link (if required)
var computeLinkProps = function computeLinkProps(props) {
return isLink(props) ? pluckProps(linkPropKeys, props) : null;
}; // Compute the attributes for a button
var computeAttrs = function computeAttrs(props, data) {
var button = isButton(props);
var link = isLink(props);
var toggle = isToggle(props);
var nonStdTag = isNonStandardTag(props);
var role = data.attrs && data.attrs.role ? data.attrs.role : null;
var tabindex = data.attrs ? data.attrs.tabindex : null;
if (nonStdTag) {
tabindex = '0';
}
return {
// Type only used for "real" buttons
type: button && !link ? props.type : null,
// Disabled only set on "real" buttons
disabled: button ? props.disabled : null,
// We add a role of button when the tag is not a link or button for ARIA.
// Don't bork any role provided in data.attrs when isLink or isButton
role: nonStdTag ? 'button' : role,
// We set the aria-disabled state for non-standard tags
'aria-disabled': nonStdTag ? String(props.disabled) : null,
// For toggles, we need to set the pressed state for ARIA
'aria-pressed': toggle ? String(props.pressed) : null,
// autocomplete off is needed in toggle mode to prevent some browsers from
// remembering the previous setting when using the back button.
autocomplete: toggle ? 'off' : null,
// Tab index is used when the component is not a button.
// Links are tabbable, but don't allow disabled, while non buttons or links
// are not tabbable, so we mimic that functionality by disabling tabbing
// when disabled, and adding a tabindex of '0' to non buttons or non links.
tabindex: props.disabled && !button ? '-1' : tabindex
};
}; // @vue/component
export var BButton =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref2) {
var props = _ref2.props,
data = _ref2.data,
listeners = _ref2.listeners,
children = _ref2.children;
var toggle = isToggle(props);
var link = isLink(props);
var on = {
click: function click(evt) {
/* istanbul ignore if: blink/button disabled should handle this */
if (props.disabled && isEvent(evt)) {
evt.stopPropagation();
evt.preventDefault();
} else if (toggle && listeners && listeners['update:pressed']) {
// Send .sync updates to any "pressed" prop (if .sync listeners)
// Concat will normalize the value to an array
// without double wrapping an array value in an array.
concat(listeners['update:pressed']).forEach(function (fn) {
if (isFunction(fn)) {
fn(!props.pressed);
}
});
}
}
};
if (toggle) {
on.focusin = handleFocus;
on.focusout = handleFocus;
}
var componentData = {
staticClass: 'btn',
class: computeClass(props),
props: computeLinkProps(props),
attrs: computeAttrs(props, data),
on: on
};
return h(link ? BLink : props.tag, mergeData(data, componentData), children);
}
});
+14
View File
@@ -0,0 +1,14 @@
//
// Buttons
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const ButtonPlugin: BvPlugin
// Component: b-button
export declare class BButton extends BvComponent {}
// Component: b-button-close
export declare class BButtonClose extends BvComponent {}
+14
View File
@@ -0,0 +1,14 @@
import { BButton } from './button';
import { BButtonClose } from './button-close';
import { pluginFactory } from '../../utils/plugins';
var ButtonPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BButton: BButton,
BBtn: BButton,
BButtonClose: BButtonClose,
BBtnClose: BButtonClose
}
});
export { ButtonPlugin, BButton, BButtonClose };
+71
View File
@@ -0,0 +1,71 @@
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import prefixPropName from '../../utils/prefix-prop-name';
import copyProps from '../../utils/copy-props';
import pluckProps from '../../utils/pluck-props';
import cardMixin from '../../mixins/card';
import { BCardTitle, props as titleProps } from './card-title';
import { BCardSubTitle, props as subTitleProps } from './card-sub-title';
export var props = _objectSpread({}, copyProps(cardMixin.props, prefixPropName.bind(null, 'body')), {
bodyClass: {
type: [String, Object, Array],
default: null
}
}, titleProps, {}, subTitleProps, {
overlay: {
type: Boolean,
default: false
}
}); // @vue/component
export var BCardBody =
/*#__PURE__*/
Vue.extend({
name: 'BCardBody',
functional: true,
props: props,
render: function render(h, _ref) {
var _ref2;
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var cardTitle = h();
var cardSubTitle = h();
var cardContent = children || [h()];
if (props.title) {
cardTitle = h(BCardTitle, {
props: pluckProps(titleProps, props)
});
}
if (props.subTitle) {
cardSubTitle = h(BCardSubTitle, {
props: pluckProps(subTitleProps, props),
class: ['mb-2']
});
}
return h(props.bodyTag, mergeData(data, {
staticClass: 'card-body',
class: [(_ref2 = {
'card-img-overlay': props.overlay
}, _defineProperty(_ref2, "bg-".concat(props.bodyBgVariant), Boolean(props.bodyBgVariant)), _defineProperty(_ref2, "border-".concat(props.bodyBorderVariant), Boolean(props.bodyBorderVariant)), _defineProperty(_ref2, "text-".concat(props.bodyTextVariant), Boolean(props.bodyTextVariant)), _ref2), props.bodyClass || {}]
}), [cardTitle, cardSubTitle].concat(_toConsumableArray(cardContent)));
}
});
+47
View File
@@ -0,0 +1,47 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import prefixPropName from '../../utils/prefix-prop-name';
import copyProps from '../../utils/copy-props';
import { htmlOrText } from '../../utils/html';
import cardMixin from '../../mixins/card';
export var props = _objectSpread({}, copyProps(cardMixin.props, prefixPropName.bind(null, 'footer')), {
footer: {
type: String,
default: null
},
footerHtml: {
type: String,
default: null
},
footerClass: {
type: [String, Object, Array],
default: null
}
}); // @vue/component
export var BCardFooter =
/*#__PURE__*/
Vue.extend({
name: 'BCardFooter',
functional: true,
props: props,
render: function render(h, _ref) {
var _ref2;
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.footerTag, mergeData(data, {
staticClass: 'card-footer',
class: [props.footerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(props.footerBgVariant), Boolean(props.footerBgVariant)), _defineProperty(_ref2, "border-".concat(props.footerBorderVariant), Boolean(props.footerBorderVariant)), _defineProperty(_ref2, "text-".concat(props.footerTextVariant), Boolean(props.footerTextVariant)), _ref2)]
}), children || [h('div', {
domProps: htmlOrText(props.footerHtml, props.footer)
})]);
}
});
+40
View File
@@ -0,0 +1,40 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
tag: {
type: String,
default: 'div'
},
deck: {
type: Boolean,
default: false
},
columns: {
type: Boolean,
default: false
}
}; // @vue/component
export var BCardGroup =
/*#__PURE__*/
Vue.extend({
name: 'BCardGroup',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var baseClass = 'card-group';
if (props.deck) {
baseClass = 'card-deck';
} else if (props.columns) {
baseClass = 'card-columns';
}
return h(props.tag, mergeData(data, {
class: baseClass
}), children);
}
});
+47
View File
@@ -0,0 +1,47 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import prefixPropName from '../../utils/prefix-prop-name';
import copyProps from '../../utils/copy-props';
import { htmlOrText } from '../../utils/html';
import cardMixin from '../../mixins/card';
export var props = _objectSpread({}, copyProps(cardMixin.props, prefixPropName.bind(null, 'header')), {
header: {
type: String,
default: null
},
headerHtml: {
type: String,
default: null
},
headerClass: {
type: [String, Object, Array],
default: null
}
}); // @vue/component
export var BCardHeader =
/*#__PURE__*/
Vue.extend({
name: 'BCardHeader',
functional: true,
props: props,
render: function render(h, _ref) {
var _ref2;
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.headerTag, mergeData(data, {
staticClass: 'card-header',
class: [props.headerClass, (_ref2 = {}, _defineProperty(_ref2, "bg-".concat(props.headerBgVariant), Boolean(props.headerBgVariant)), _defineProperty(_ref2, "border-".concat(props.headerBorderVariant), Boolean(props.headerBorderVariant)), _defineProperty(_ref2, "text-".concat(props.headerTextVariant), Boolean(props.headerTextVariant)), _ref2)]
}), children || [h('div', {
domProps: htmlOrText(props.headerHtml, props.header)
})]);
}
});
+76
View File
@@ -0,0 +1,76 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { omit } from '../../utils/object';
import { mergeData } from 'vue-functional-data-merge';
import { BImgLazy, props as imgLazyProps } from '../image/img-lazy'; // Copy of `<b-img-lazy>` props, and remove conflicting/non-applicable props
// The `omit()` util creates a new object, so we can just pass the original props
var lazyProps = omit(imgLazyProps, ['left', 'right', 'center', 'block', 'rounded', 'thumbnail', 'fluid', 'fluidGrow']);
export var props = _objectSpread({}, lazyProps, {
top: {
type: Boolean,
default: false
},
bottom: {
type: Boolean,
default: false
},
start: {
type: Boolean,
default: false
},
left: {
// alias of 'start'
type: Boolean,
default: false
},
end: {
type: Boolean,
default: false
},
right: {
// alias of 'end'
type: Boolean,
default: false
}
}); // @vue/component
export var BCardImgLazy =
/*#__PURE__*/
Vue.extend({
name: 'BCardImgLazy',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data;
var baseClass = 'card-img';
if (props.top) {
baseClass += '-top';
} else if (props.right || props.end) {
baseClass += '-right';
} else if (props.bottom) {
baseClass += '-bottom';
} else if (props.left || props.start) {
baseClass += '-left';
} // False out the left/center/right props before passing to b-img-lazy
var lazyProps = _objectSpread({}, props, {
left: false,
right: false,
center: false
});
return h(BImgLazy, mergeData(data, {
class: [baseClass],
props: lazyProps
}));
}
});
+80
View File
@@ -0,0 +1,80 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
src: {
type: String,
default: null,
required: true
},
alt: {
type: String,
default: null
},
top: {
type: Boolean,
default: false
},
bottom: {
type: Boolean,
default: false
},
start: {
type: Boolean,
default: false
},
left: {
// alias of 'start'
type: Boolean,
default: false
},
end: {
type: Boolean,
default: false
},
right: {
// alias of 'end'
type: Boolean,
default: false
},
height: {
type: [Number, String],
default: null
},
width: {
type: [Number, String],
default: null
}
}; // @vue/component
export var BCardImg =
/*#__PURE__*/
Vue.extend({
name: 'BCardImg',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data;
var baseClass = 'card-img';
if (props.top) {
baseClass += '-top';
} else if (props.right || props.end) {
baseClass += '-right';
} else if (props.bottom) {
baseClass += '-bottom';
} else if (props.left || props.start) {
baseClass += '-left';
}
return h('img', mergeData(data, {
class: [baseClass],
attrs: {
src: props.src,
alt: props.alt,
height: props.height,
width: props.width
}
}));
}
});
+37
View File
@@ -0,0 +1,37 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
import { getComponentConfig } from '../../utils/config';
var NAME = 'BCardSubTitle';
export var props = {
subTitle: {
type: String,
default: ''
},
subTitleTag: {
type: String,
default: 'h6'
},
subTitleTextVariant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'subTitleTextVariant');
}
}
}; // @vue/component
export var BCardSubTitle =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.subTitleTag, mergeData(data, {
staticClass: 'card-subtitle',
class: [props.subTitleTextVariant ? "text-".concat(props.subTitleTextVariant) : null]
}), children || props.subTitle);
}
});
+24
View File
@@ -0,0 +1,24 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
textTag: {
type: String,
default: 'p'
}
}; // @vue/component
export var BCardText =
/*#__PURE__*/
Vue.extend({
name: 'BCardText',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.textTag, mergeData(data, {
staticClass: 'card-text'
}), children);
}
});
+28
View File
@@ -0,0 +1,28 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
title: {
type: String,
default: ''
},
titleTag: {
type: String,
default: 'h4'
}
}; // @vue/component
export var BCardTitle =
/*#__PURE__*/
Vue.extend({
name: 'BCardTitle',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.titleTag, mergeData(data, {
staticClass: 'card-title'
}), children || props.title);
}
});
+104
View File
@@ -0,0 +1,104 @@
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import prefixPropName from '../../utils/prefix-prop-name';
import unPrefixPropName from '../../utils/unprefix-prop-name';
import copyProps from '../../utils/copy-props';
import pluckProps from '../../utils/pluck-props';
import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot';
import cardMixin from '../../mixins/card';
import { BCardBody, props as bodyProps } from './card-body';
import { BCardHeader, props as headerProps } from './card-header';
import { BCardFooter, props as footerProps } from './card-footer';
import { BCardImg, props as imgProps } from './card-img';
var cardImgProps = copyProps(imgProps, prefixPropName.bind(null, 'img'));
cardImgProps.imgSrc.required = false;
export var props = _objectSpread({}, bodyProps, {}, headerProps, {}, footerProps, {}, cardImgProps, {}, copyProps(cardMixin.props), {
align: {
type: String,
default: null
},
noBody: {
type: Boolean,
default: false
}
}); // @vue/component
export var BCard =
/*#__PURE__*/
Vue.extend({
name: 'BCard',
functional: true,
props: props,
render: function render(h, _ref) {
var _class;
var props = _ref.props,
data = _ref.data,
slots = _ref.slots,
scopedSlots = _ref.scopedSlots;
var $slots = slots(); // Vue < 2.6.x may return undefined for scopedSlots
var $scopedSlots = scopedSlots || {}; // Create placeholder elements for each section
var imgFirst = h();
var header = h();
var content = h();
var footer = h();
var imgLast = h();
if (props.imgSrc) {
var img = h(BCardImg, {
props: pluckProps(cardImgProps, props, unPrefixPropName.bind(null, 'img'))
});
if (props.imgBottom) {
imgLast = img;
} else {
imgFirst = img;
}
}
if (props.header || hasNormalizedSlot('header', $scopedSlots, $slots)) {
header = h(BCardHeader, {
props: pluckProps(headerProps, props)
}, normalizeSlot('header', {}, $scopedSlots, $slots));
}
content = normalizeSlot('default', {}, $scopedSlots, $slots) || [];
if (!props.noBody) {
// Wrap content in card-body
content = [h(BCardBody, {
props: pluckProps(bodyProps, props)
}, _toConsumableArray(content))];
}
if (props.footer || hasNormalizedSlot('footer', $scopedSlots, $slots)) {
footer = h(BCardFooter, {
props: pluckProps(footerProps, props)
}, normalizeSlot('footer', {}, $scopedSlots, $slots));
}
return h(props.tag, mergeData(data, {
staticClass: 'card',
class: (_class = {
'flex-row': props.imgLeft || props.imgStart,
'flex-row-reverse': (props.imgRight || props.imgEnd) && !(props.imgLeft || props.imgStart)
}, _defineProperty(_class, "text-".concat(props.align), Boolean(props.align)), _defineProperty(_class, "bg-".concat(props.bgVariant), Boolean(props.bgVariant)), _defineProperty(_class, "border-".concat(props.borderVariant), Boolean(props.borderVariant)), _defineProperty(_class, "text-".concat(props.textVariant), Boolean(props.textVariant)), _class)
}), [imgFirst, header].concat(_toConsumableArray(content), [footer, imgLast]));
}
});
+38
View File
@@ -0,0 +1,38 @@
//
// Card
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const CardPlugin: BvPlugin
// Component: b-card
export declare class BCard extends BvComponent {}
// Component: b-card-header
export declare class BCardHeader extends BvComponent {}
// Component: b-card-footer
export declare class BCardFooter extends BvComponent {}
// Component: b-card-body
export declare class BCardBody extends BvComponent {}
// Component: b-card-title
export declare class BCardTitle extends BvComponent {}
// Component: b-card-sub-title
export declare class BCardSubTitle extends BvComponent {}
// Component: b-card-img
export declare class BCardImg extends BvComponent {}
// Component: b-card-img-lazy
export declare class BCardImgLazy extends BvComponent {}
// Component: b-card-text
export declare class BCardText extends BvComponent {}
// Component: b-card-group
export declare class BCardGroup extends BvComponent {}
+28
View File
@@ -0,0 +1,28 @@
import { BCard } from './card';
import { BCardHeader } from './card-header';
import { BCardBody } from './card-body';
import { BCardTitle } from './card-title';
import { BCardSubTitle } from './card-sub-title';
import { BCardFooter } from './card-footer';
import { BCardImg } from './card-img';
import { BCardImgLazy } from './card-img-lazy';
import { BCardText } from './card-text';
import { BCardGroup } from './card-group';
import { pluginFactory } from '../../utils/plugins';
var CardPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BCard: BCard,
BCardHeader: BCardHeader,
BCardBody: BCardBody,
BCardTitle: BCardTitle,
BCardSubTitle: BCardSubTitle,
BCardFooter: BCardFooter,
BCardImg: BCardImg,
BCardImgLazy: BCardImgLazy,
BCardText: BCardText,
BCardGroup: BCardGroup
}
});
export { CardPlugin, BCard, BCardHeader, BCardBody, BCardTitle, BCardSubTitle, BCardFooter, BCardImg, BCardImgLazy, BCardText, BCardGroup };
+150
View File
@@ -0,0 +1,150 @@
import Vue from '../../utils/vue';
import idMixin from '../../mixins/id';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import { hasTouchSupport } from '../../utils/env';
import { htmlOrText } from '../../utils/html';
import { BImg } from '../image/img';
export var props = {
imgSrc: {
type: String // default: undefined
},
imgAlt: {
type: String // default: undefined
},
imgWidth: {
type: [Number, String] // default: undefined
},
imgHeight: {
type: [Number, String] // default: undefined
},
imgBlank: {
type: Boolean,
default: false
},
imgBlankColor: {
type: String,
default: 'transparent'
},
contentVisibleUp: {
type: String
},
contentTag: {
type: String,
default: 'div'
},
caption: {
type: String
},
captionHtml: {
type: String
},
captionTag: {
type: String,
default: 'h3'
},
text: {
type: String
},
textHtml: {
type: String
},
textTag: {
type: String,
default: 'p'
},
background: {
type: String
}
}; // @vue/component
export var BCarouselSlide =
/*#__PURE__*/
Vue.extend({
name: 'BCarouselSlide',
mixins: [idMixin, normalizeSlotMixin],
inject: {
bvCarousel: {
default: function _default() {
return {
// Explicitly disable touch if not a child of carousel
noTouch: true
};
}
}
},
props: props,
computed: {
contentClasses: function contentClasses() {
return [this.contentVisibleUp ? 'd-none' : '', this.contentVisibleUp ? "d-".concat(this.contentVisibleUp, "-block") : ''];
},
computedWidth: function computedWidth() {
// Use local width, or try parent width
return this.imgWidth || this.bvCarousel.imgWidth || null;
},
computedHeight: function computedHeight() {
// Use local height, or try parent height
return this.imgHeight || this.bvCarousel.imgHeight || null;
}
},
render: function render(h) {
var noDrag = !this.bvCarousel.noTouch && hasTouchSupport;
var img = this.normalizeSlot('img');
if (!img && (this.imgSrc || this.imgBlank)) {
img = h(BImg, {
props: {
fluidGrow: true,
block: true,
src: this.imgSrc,
blank: this.imgBlank,
blankColor: this.imgBlankColor,
width: this.computedWidth,
height: this.computedHeight,
alt: this.imgAlt
},
// Touch support event handler
on: noDrag ? {
dragstart: function dragstart(e) {
/* istanbul ignore next: difficult to test in JSDOM */
e.preventDefault();
}
} : {}
});
}
if (!img) {
img = h();
}
var content = h();
var contentChildren = [this.caption || this.captionHtml ? h(this.captionTag, {
domProps: htmlOrText(this.captionHtml, this.caption)
}) : false, this.text || this.textHtml ? h(this.textTag, {
domProps: htmlOrText(this.textHtml, this.text)
}) : false, this.normalizeSlot('default') || false];
if (contentChildren.some(Boolean)) {
content = h(this.contentTag, {
staticClass: 'carousel-caption',
class: this.contentClasses
}, contentChildren.map(function (i) {
return i || h();
}));
}
return h('div', {
staticClass: 'carousel-item',
style: {
background: this.background || this.bvCarousel.background || null
},
attrs: {
id: this.safeId(),
role: 'listitem'
}
}, [img, content]);
}
});
+708
View File
@@ -0,0 +1,708 @@
import Vue from '../../utils/vue';
import KeyCodes from '../../utils/key-codes';
import noop from '../../utils/noop';
import observeDom from '../../utils/observe-dom';
import { getComponentConfig } from '../../utils/config';
import { selectAll, reflow, addClass, removeClass, setAttr, eventOn, eventOff } from '../../utils/dom';
import { isBrowser, hasTouchSupport, hasPointerEventSupport } from '../../utils/env';
import { isUndefined } from '../../utils/inspect';
import idMixin from '../../mixins/id';
import normalizeSlotMixin from '../../mixins/normalize-slot';
var NAME = 'BCarousel'; // Slide directional classes
var DIRECTION = {
next: {
dirClass: 'carousel-item-left',
overlayClass: 'carousel-item-next'
},
prev: {
dirClass: 'carousel-item-right',
overlayClass: 'carousel-item-prev'
}
}; // Fallback Transition duration (with a little buffer) in ms
var TRANS_DURATION = 600 + 50; // Time for mouse compat events to fire after touch
var TOUCH_EVENT_COMPAT_WAIT = 500; // Number of pixels to consider touch move a swipe
var SWIPE_THRESHOLD = 40; // PointerEvent pointer types
var PointerType = {
TOUCH: 'touch',
PEN: 'pen'
}; // Transition Event names
var TransitionEndEvents = {
WebkitTransition: 'webkitTransitionEnd',
MozTransition: 'transitionend',
OTransition: 'otransitionend oTransitionEnd',
transition: 'transitionend'
};
var EventOptions = {
passive: true,
capture: false
}; // Return the browser specific transitionEnd event name
var getTransitionEndEvent = function getTransitionEndEvent(el) {
for (var name in TransitionEndEvents) {
if (!isUndefined(el.style[name])) {
return TransitionEndEvents[name];
}
} // Fallback
/* istanbul ignore next */
return null;
}; // @vue/component
export var BCarousel =
/*#__PURE__*/
Vue.extend({
name: NAME,
mixins: [idMixin, normalizeSlotMixin],
provide: function provide() {
return {
bvCarousel: this
};
},
model: {
prop: 'value',
event: 'input'
},
props: {
labelPrev: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'labelPrev');
}
},
labelNext: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'labelNext');
}
},
labelGotoSlide: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'labelGotoSlide');
}
},
labelIndicators: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'labelIndicators');
}
},
interval: {
type: Number,
default: 5000
},
indicators: {
type: Boolean,
default: false
},
controls: {
type: Boolean,
default: false
},
noAnimation: {
// Disable slide/fade animation
type: Boolean,
default: false
},
fade: {
// Enable cross-fade animation instead of slide animation
type: Boolean,
default: false
},
noWrap: {
// Disable wrapping/looping when start/end is reached
type: Boolean,
default: false
},
noTouch: {
// Sniffed by carousel-slide
type: Boolean,
default: false
},
noHoverPause: {
// Disable pause on hover
type: Boolean,
default: false
},
imgWidth: {
// Sniffed by carousel-slide
type: [Number, String] // default: undefined
},
imgHeight: {
// Sniffed by carousel-slide
type: [Number, String] // default: undefined
},
background: {
type: String // default: undefined
},
value: {
type: Number,
default: 0
}
},
data: function data() {
return {
index: this.value || 0,
isSliding: false,
transitionEndEvent: null,
slides: [],
direction: null,
isPaused: !(parseInt(this.interval, 10) > 0),
// Touch event handling values
touchStartX: 0,
touchDeltaX: 0
};
},
computed: {
numSlides: function numSlides() {
return this.slides.length;
}
},
watch: {
value: function value(newVal, oldVal) {
if (newVal !== oldVal) {
this.setSlide(parseInt(newVal, 10) || 0);
}
},
interval: function interval(newVal, oldVal) {
if (newVal === oldVal) {
/* istanbul ignore next */
return;
}
if (!newVal) {
// Pausing slide show
this.pause(false);
} else {
// Restarting or Changing interval
this.pause(true);
this.start(false);
}
},
isPaused: function isPaused(newVal, oldVal) {
if (newVal !== oldVal) {
this.$emit(newVal ? 'paused' : 'unpaused');
}
},
index: function index(to, from) {
if (to === from || this.isSliding) {
/* istanbul ignore next */
return;
}
this.doSlide(to, from);
}
},
created: function created() {
// Create private non-reactive props
this._intervalId = null;
this._animationTimeout = null;
this._touchTimeout = null; // Set initial paused state
this.isPaused = !(parseInt(this.interval, 10) > 0);
},
mounted: function mounted() {
// Cache current browser transitionend event name
this.transitionEndEvent = getTransitionEndEvent(this.$el) || null; // Get all slides
this.updateSlides(); // Observe child changes so we can update slide list
observeDom(this.$refs.inner, this.updateSlides.bind(this), {
subtree: false,
childList: true,
attributes: true,
attributeFilter: ['id']
});
},
beforeDestroy: function beforeDestroy() {
clearTimeout(this._animationTimeout);
clearTimeout(this._touchTimeout);
clearInterval(this._intervalId);
this._intervalId = null;
this._animationTimeout = null;
this._touchTimeout = null;
},
methods: {
// Set slide
setSlide: function setSlide(slide) {
var _this = this;
var direction = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
// Don't animate when page is not visible
/* istanbul ignore if: difficult to test */
if (isBrowser && document.visibilityState && document.hidden) {
return;
}
var noWrap = this.noWrap;
var numSlides = this.numSlides; // Make sure we have an integer (you never know!)
slide = Math.floor(slide); // Don't do anything if nothing to slide to
if (numSlides === 0) {
return;
} // Don't change slide while transitioning, wait until transition is done
if (this.isSliding) {
// Schedule slide after sliding complete
this.$once('sliding-end', function () {
return _this.setSlide(slide, direction);
});
return;
}
this.direction = direction; // Set new slide index
// Wrap around if necessary (if no-wrap not enabled)
this.index = slide >= numSlides ? noWrap ? numSlides - 1 : 0 : slide < 0 ? noWrap ? 0 : numSlides - 1 : slide; // Ensure the v-model is synched up if no-wrap is enabled
// and user tried to slide pass either ends
if (noWrap && this.index !== slide && this.index !== this.value) {
this.$emit('input', this.index);
}
},
// Previous slide
prev: function prev() {
this.setSlide(this.index - 1, 'prev');
},
// Next slide
next: function next() {
this.setSlide(this.index + 1, 'next');
},
// Pause auto rotation
pause: function pause(evt) {
if (!evt) {
this.isPaused = true;
}
if (this._intervalId) {
clearInterval(this._intervalId);
this._intervalId = null;
}
},
// Start auto rotate slides
start: function start(evt) {
if (!evt) {
this.isPaused = false;
}
/* istanbul ignore next: most likely will never happen, but just in case */
if (this._intervalId) {
clearInterval(this._intervalId);
this._intervalId = null;
} // Don't start if no interval, or less than 2 slides
if (this.interval && this.numSlides > 1) {
this._intervalId = setInterval(this.next, Math.max(1000, this.interval));
}
},
// Restart auto rotate slides when focus/hover leaves the carousel
restart: function restart(evt)
/* istanbul ignore next: difficult to test */
{
if (!this.$el.contains(document.activeElement)) {
this.start();
}
},
doSlide: function doSlide(to, from) {
var _this2 = this;
var isCycling = Boolean(this.interval); // Determine sliding direction
var direction = this.calcDirection(this.direction, from, to);
var overlayClass = direction.overlayClass;
var dirClass = direction.dirClass; // Determine current and next slides
var currentSlide = this.slides[from];
var nextSlide = this.slides[to]; // Don't do anything if there aren't any slides to slide to
if (!currentSlide || !nextSlide) {
/* istanbul ignore next */
return;
} // Start animating
this.isSliding = true;
if (isCycling) {
this.pause(false);
}
this.$emit('sliding-start', to); // Update v-model
this.$emit('input', this.index);
if (this.noAnimation) {
addClass(nextSlide, 'active');
removeClass(currentSlide, 'active');
this.isSliding = false; // Notify ourselves that we're done sliding (slid)
this.$nextTick(function () {
return _this2.$emit('sliding-end', to);
});
} else {
addClass(nextSlide, overlayClass); // Trigger a reflow of next slide
reflow(nextSlide);
addClass(currentSlide, dirClass);
addClass(nextSlide, dirClass); // Transition End handler
var called = false;
/* istanbul ignore next: difficult to test */
var onceTransEnd = function onceTransEnd(evt) {
if (called) {
return;
}
called = true;
/* istanbul ignore if: transition events cant be tested in JSDOM */
if (_this2.transitionEndEvent) {
var events = _this2.transitionEndEvent.split(/\s+/);
events.forEach(function (evt) {
return eventOff(currentSlide, evt, onceTransEnd, EventOptions);
});
}
_this2._animationTimeout = null;
removeClass(nextSlide, dirClass);
removeClass(nextSlide, overlayClass);
addClass(nextSlide, 'active');
removeClass(currentSlide, 'active');
removeClass(currentSlide, dirClass);
removeClass(currentSlide, overlayClass);
setAttr(currentSlide, 'aria-current', 'false');
setAttr(nextSlide, 'aria-current', 'true');
setAttr(currentSlide, 'aria-hidden', 'true');
setAttr(nextSlide, 'aria-hidden', 'false');
_this2.isSliding = false;
_this2.direction = null; // Notify ourselves that we're done sliding (slid)
_this2.$nextTick(function () {
return _this2.$emit('sliding-end', to);
});
}; // Set up transitionend handler
/* istanbul ignore if: transition events cant be tested in JSDOM */
if (this.transitionEndEvent) {
var events = this.transitionEndEvent.split(/\s+/);
events.forEach(function (event) {
return eventOn(currentSlide, event, onceTransEnd, EventOptions);
});
} // Fallback to setTimeout()
this._animationTimeout = setTimeout(onceTransEnd, TRANS_DURATION);
}
if (isCycling) {
this.start(false);
}
},
// Update slide list
updateSlides: function updateSlides() {
this.pause(true); // Get all slides as DOM elements
this.slides = selectAll('.carousel-item', this.$refs.inner);
var numSlides = this.slides.length; // Keep slide number in range
var index = Math.max(0, Math.min(Math.floor(this.index), numSlides - 1));
this.slides.forEach(function (slide, idx) {
var n = idx + 1;
if (idx === index) {
addClass(slide, 'active');
setAttr(slide, 'aria-current', 'true');
} else {
removeClass(slide, 'active');
setAttr(slide, 'aria-current', 'false');
}
setAttr(slide, 'aria-posinset', String(n));
setAttr(slide, 'aria-setsize', String(numSlides));
}); // Set slide as active
this.setSlide(index);
this.start(this.isPaused);
},
calcDirection: function calcDirection() {
var direction = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
var curIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var nextIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
if (!direction) {
return nextIndex > curIndex ? DIRECTION.next : DIRECTION.prev;
}
return DIRECTION[direction];
},
handleClick: function handleClick(evt, fn) {
var keyCode = evt.keyCode;
if (evt.type === 'click' || keyCode === KeyCodes.SPACE || keyCode === KeyCodes.ENTER) {
evt.preventDefault();
evt.stopPropagation();
fn();
}
},
handleSwipe: function handleSwipe()
/* istanbul ignore next: JSDOM doesn't support touch events */
{
var absDeltaX = Math.abs(this.touchDeltaX);
if (absDeltaX <= SWIPE_THRESHOLD) {
return;
}
var direction = absDeltaX / this.touchDeltaX; // Reset touch delta X
// https://github.com/twbs/bootstrap/pull/28558
this.touchDeltaX = 0;
if (direction > 0) {
// Swipe left
this.prev();
} else if (direction < 0) {
// Swipe right
this.next();
}
},
touchStart: function touchStart(evt)
/* istanbul ignore next: JSDOM doesn't support touch events */
{
if (hasPointerEventSupport && PointerType[evt.pointerType.toUpperCase()]) {
this.touchStartX = evt.clientX;
} else if (!hasPointerEventSupport) {
this.touchStartX = evt.touches[0].clientX;
}
},
touchMove: function touchMove(evt)
/* istanbul ignore next: JSDOM doesn't support touch events */
{
// Ensure swiping with one touch and not pinching
if (evt.touches && evt.touches.length > 1) {
this.touchDeltaX = 0;
} else {
this.touchDeltaX = evt.touches[0].clientX - this.touchStartX;
}
},
touchEnd: function touchEnd(evt)
/* istanbul ignore next: JSDOM doesn't support touch events */
{
if (hasPointerEventSupport && PointerType[evt.pointerType.toUpperCase()]) {
this.touchDeltaX = evt.clientX - this.touchStartX;
}
this.handleSwipe(); // If it's a touch-enabled device, mouseenter/leave are fired as
// part of the mouse compatibility events on first tap - the carousel
// would stop cycling until user tapped out of it;
// here, we listen for touchend, explicitly pause the carousel
// (as if it's the second time we tap on it, mouseenter compat event
// is NOT fired) and after a timeout (to allow for mouse compatibility
// events to fire) we explicitly restart cycling
this.pause(false);
if (this._touchTimeout) {
clearTimeout(this._touchTimeout);
}
this._touchTimeout = setTimeout(this.start, TOUCH_EVENT_COMPAT_WAIT + Math.max(1000, this.interval));
}
},
render: function render(h) {
var _this3 = this;
// Wrapper for slides
var inner = h('div', {
ref: 'inner',
class: ['carousel-inner'],
attrs: {
id: this.safeId('__BV_inner_'),
role: 'list'
}
}, [this.normalizeSlot('default')]); // Prev and next controls
var controls = h();
if (this.controls) {
var prevHandler = function prevHandler(evt) {
/* istanbul ignore next */
if (!_this3.isSliding) {
_this3.handleClick(evt, _this3.prev);
} else {
evt.preventDefault();
}
};
var nextHandler = function nextHandler(evt) {
/* istanbul ignore next */
if (!_this3.isSliding) {
_this3.handleClick(evt, _this3.next);
} else {
evt.preventDefault();
}
};
controls = [h('a', {
class: ['carousel-control-prev'],
attrs: {
href: '#',
role: 'button',
'aria-controls': this.safeId('__BV_inner_'),
'aria-disabled': this.isSliding ? 'true' : null
},
on: {
click: prevHandler,
keydown: prevHandler
}
}, [h('span', {
class: ['carousel-control-prev-icon'],
attrs: {
'aria-hidden': 'true'
}
}), h('span', {
class: ['sr-only']
}, [this.labelPrev])]), h('a', {
class: ['carousel-control-next'],
attrs: {
href: '#',
role: 'button',
'aria-controls': this.safeId('__BV_inner_'),
'aria-disabled': this.isSliding ? 'true' : null
},
on: {
click: nextHandler,
keydown: nextHandler
}
}, [h('span', {
class: ['carousel-control-next-icon'],
attrs: {
'aria-hidden': 'true'
}
}), h('span', {
class: ['sr-only']
}, [this.labelNext])])];
} // Indicators
var indicators = h('ol', {
class: ['carousel-indicators'],
directives: [{
name: 'show',
rawName: 'v-show',
value: this.indicators,
expression: 'indicators'
}],
attrs: {
id: this.safeId('__BV_indicators_'),
'aria-hidden': this.indicators ? 'false' : 'true',
'aria-label': this.labelIndicators,
'aria-owns': this.safeId('__BV_inner_')
}
}, this.slides.map(function (slide, n) {
return h('li', {
key: "slide_".concat(n),
class: {
active: n === _this3.index
},
attrs: {
role: 'button',
id: _this3.safeId("__BV_indicator_".concat(n + 1, "_")),
tabindex: _this3.indicators ? '0' : '-1',
'aria-current': n === _this3.index ? 'true' : 'false',
'aria-label': "".concat(_this3.labelGotoSlide, " ").concat(n + 1),
'aria-describedby': _this3.slides[n].id || null,
'aria-controls': _this3.safeId('__BV_inner_')
},
on: {
click: function click(evt) {
_this3.handleClick(evt, function () {
_this3.setSlide(n);
});
},
keydown: function keydown(evt) {
_this3.handleClick(evt, function () {
_this3.setSlide(n);
});
}
}
});
}));
var on = {
mouseenter: this.noHoverPause ? noop : this.pause,
mouseleave: this.noHoverPause ? noop : this.restart,
focusin: this.pause,
focusout: this.restart,
keydown: function keydown(evt) {
if (/input|textarea/i.test(evt.target.tagName)) {
/* istanbul ignore next */
return;
}
var keyCode = evt.keyCode;
if (keyCode === KeyCodes.LEFT || keyCode === KeyCodes.RIGHT) {
evt.preventDefault();
evt.stopPropagation();
_this3[keyCode === KeyCodes.LEFT ? 'prev' : 'next']();
}
}
}; // Touch support event handlers for environment
if (!this.noTouch && hasTouchSupport) {
// Attach appropriate listeners (prepend event name with '&' for passive mode)
/* istanbul ignore next: JSDOM doesn't support touch events */
if (hasPointerEventSupport) {
on['&pointerdown'] = this.touchStart;
on['&pointerup'] = this.touchEnd;
} else {
on['&touchstart'] = this.touchStart;
on['&touchmove'] = this.touchMove;
on['&touchend'] = this.touchEnd;
}
} // Return the carousel
return h('div', {
staticClass: 'carousel',
class: {
slide: !this.noAnimation,
'carousel-fade': !this.noAnimation && this.fade,
'pointer-event': !this.noTouch && hasTouchSupport && hasPointerEventSupport
},
style: {
background: this.background
},
attrs: {
role: 'region',
id: this.safeId(),
'aria-busy': this.isSliding ? 'true' : 'false'
},
on: on
}, [inner, controls, indicators]);
}
});
+20
View File
@@ -0,0 +1,20 @@
//
// Carousel
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const CarouselPlugin: BvPlugin
// Component: b-carousel
export declare class BCarousel extends BvComponent {
setSlide: (slide: number) => void
prev: () => void
next: () => void
start: () => void
pause: () => void
}
// Component: b-carousel-slide
export declare class BCarouselSlide extends BvComponent {}
+12
View File
@@ -0,0 +1,12 @@
import { BCarousel } from './carousel';
import { BCarouselSlide } from './carousel-slide';
import { pluginFactory } from '../../utils/plugins';
var CarouselPlugin =
/*#__PURE*/
pluginFactory({
components: {
BCarousel: BCarousel,
BCarouselSlide: BCarouselSlide
}
});
export { CarouselPlugin, BCarousel, BCarouselSlide };
+274
View File
@@ -0,0 +1,274 @@
import Vue from '../../utils/vue';
import idMixin from '../../mixins/id';
import listenOnRootMixin from '../../mixins/listen-on-root';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import { isBrowser } from '../../utils/env';
import { addClass, hasClass, removeClass, closest, matches, reflow, getCS, getBCR, eventOn, eventOff } from '../../utils/dom'; // Events we emit on $root
var EVENT_STATE = 'bv::collapse::state';
var EVENT_ACCORDION = 'bv::collapse::accordion'; // Private event we emit on `$root` to ensure the toggle state is
// always synced. It gets emitted even if the state has not changed!
// This event is NOT to be documented as people should not be using it
var EVENT_STATE_SYNC = 'bv::collapse::sync::state'; // Events we listen to on `$root`
var EVENT_TOGGLE = 'bv::toggle::collapse';
var EVENT_STATE_REQUEST = 'bv::request::collapse::state'; // Event listener options
var EventOptions = {
passive: true,
capture: false
}; // @vue/component
export var BCollapse =
/*#__PURE__*/
Vue.extend({
name: 'BCollapse',
mixins: [idMixin, listenOnRootMixin, normalizeSlotMixin],
model: {
prop: 'visible',
event: 'input'
},
props: {
isNav: {
type: Boolean,
default: false
},
accordion: {
type: String,
default: null
},
visible: {
type: Boolean,
default: false
},
tag: {
type: String,
default: 'div'
}
},
data: function data() {
return {
show: this.visible,
transitioning: false
};
},
computed: {
classObject: function classObject() {
return {
'navbar-collapse': this.isNav,
collapse: !this.transitioning,
show: this.show && !this.transitioning
};
}
},
watch: {
visible: function visible(newVal) {
if (newVal !== this.show) {
this.show = newVal;
}
},
show: function show(newVal, oldVal) {
if (newVal !== oldVal) {
this.emitState();
}
}
},
created: function created() {
this.show = this.visible;
},
mounted: function mounted() {
var _this = this;
this.show = this.visible; // Listen for toggle events to open/close us
this.listenOnRoot(EVENT_TOGGLE, this.handleToggleEvt); // Listen to other collapses for accordion events
this.listenOnRoot(EVENT_ACCORDION, this.handleAccordionEvt);
if (this.isNav) {
// Set up handlers
this.setWindowEvents(true);
this.handleResize();
}
this.$nextTick(function () {
_this.emitState();
}); // Listen for "Sync state" requests from `v-b-toggle`
this.listenOnRoot(EVENT_STATE_REQUEST, function (id) {
if (id === _this.safeId()) {
_this.$nextTick(_this.emitSync);
}
});
},
updated: function updated() {
// Emit a private event every time this component updates to ensure
// the toggle button is in sync with the collapse's state
// It is emitted regardless if the visible state changes
this.emitSync();
},
deactivated: function deactivated()
/* istanbul ignore next */
{
if (this.isNav) {
this.setWindowEvents(false);
}
},
activated: function activated()
/* istanbul ignore next */
{
if (this.isNav) {
this.setWindowEvents(true);
}
this.emitSync();
},
beforeDestroy: function beforeDestroy() {
// Trigger state emit if needed
this.show = false;
if (this.isNav && isBrowser) {
this.setWindowEvents(false);
}
},
methods: {
setWindowEvents: function setWindowEvents(on) {
var method = on ? eventOn : eventOff;
method(window, 'resize', this.handleResize, EventOptions);
method(window, 'orientationchange', this.handleResize, EventOptions);
},
toggle: function toggle() {
this.show = !this.show;
},
onEnter: function onEnter(el) {
el.style.height = 0;
reflow(el);
el.style.height = el.scrollHeight + 'px';
this.transitioning = true; // This should be moved out so we can add cancellable events
this.$emit('show');
},
onAfterEnter: function onAfterEnter(el) {
el.style.height = null;
this.transitioning = false;
this.$emit('shown');
},
onLeave: function onLeave(el) {
el.style.height = 'auto';
el.style.display = 'block';
el.style.height = getBCR(el).height + 'px';
reflow(el);
this.transitioning = true;
el.style.height = 0; // This should be moved out so we can add cancellable events
this.$emit('hide');
},
onAfterLeave: function onAfterLeave(el) {
el.style.height = null;
this.transitioning = false;
this.$emit('hidden');
},
emitState: function emitState() {
this.$emit('input', this.show); // Let v-b-toggle know the state of this collapse
this.$root.$emit(EVENT_STATE, this.safeId(), this.show);
if (this.accordion && this.show) {
// Tell the other collapses in this accordion to close
this.$root.$emit(EVENT_ACCORDION, this.safeId(), this.accordion);
}
},
emitSync: function emitSync() {
// Emit a private event every time this component updates to ensure
// the toggle button is in sync with the collapse's state
// It is emitted regardless if the visible state changes
this.$root.$emit(EVENT_STATE_SYNC, this.safeId(), this.show);
},
checkDisplayBlock: function checkDisplayBlock() {
// Check to see if the collapse has `display: block !important;` set.
// We can't set `display: none;` directly on this.$el, as it would
// trigger a new transition to start (or cancel a current one).
var restore = hasClass(this.$el, 'show');
removeClass(this.$el, 'show');
var isBlock = getCS(this.$el).display === 'block';
restore && addClass(this.$el, 'show');
return isBlock;
},
clickHandler: function clickHandler(evt) {
// If we are in a nav/navbar, close the collapse when non-disabled link clicked
var el = evt.target;
if (!this.isNav || !el || getCS(this.$el).display !== 'block') {
/* istanbul ignore next: can't test getComputedStyle in JSDOM */
return;
}
if (matches(el, '.nav-link,.dropdown-item') || closest('.nav-link,.dropdown-item', el)) {
if (!this.checkDisplayBlock()) {
// Only close the collapse if it is not forced to be 'display: block !important;'
this.show = false;
}
}
},
handleToggleEvt: function handleToggleEvt(target) {
if (target !== this.safeId()) {
return;
}
this.toggle();
},
handleAccordionEvt: function handleAccordionEvt(openedId, accordion) {
if (!this.accordion || accordion !== this.accordion) {
return;
}
if (openedId === this.safeId()) {
// Open this collapse if not shown
if (!this.show) {
this.toggle();
}
} else {
// Close this collapse if shown
if (this.show) {
this.toggle();
}
}
},
handleResize: function handleResize() {
// Handler for orientation/resize to set collapsed state in nav/navbar
this.show = getCS(this.$el).display === 'block';
}
},
render: function render(h) {
var content = h(this.tag, {
class: this.classObject,
directives: [{
name: 'show',
value: this.show
}],
attrs: {
id: this.safeId()
},
on: {
click: this.clickHandler
}
}, [this.normalizeSlot('default')]);
return h('transition', {
props: {
enterClass: '',
enterActiveClass: 'collapsing',
enterToClass: '',
leaveClass: '',
leaveActiveClass: 'collapsing',
leaveToClass: ''
},
on: {
enter: this.onEnter,
afterEnter: this.onAfterEnter,
leave: this.onLeave,
afterLeave: this.onAfterLeave
}
}, [content]);
}
});
+13
View File
@@ -0,0 +1,13 @@
//
// Collapse
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const CollapsePlugin: BvPlugin
// Component: b-collapse
export declare class BCollapse extends BvComponent {
toggle: () => void
}
+14
View File
@@ -0,0 +1,14 @@
import { BCollapse } from './collapse';
import { VBToggle } from '../../directives/toggle/toggle';
import { pluginFactory } from '../../utils/plugins';
var CollapsePlugin =
/*#__PURE__*/
pluginFactory({
components: {
BCollapse: BCollapse
},
directives: {
VBToggle: VBToggle
}
});
export { CollapsePlugin, BCollapse };
+40
View File
@@ -0,0 +1,40 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
export var props = {
tag: {
type: String,
default: 'hr'
}
}; // @vue/component
export var BDropdownDivider =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownDivider',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data;
var $attrs = data.attrs || {};
data.attrs = {};
return h('li', mergeData(data, {
attrs: {
role: 'presentation'
}
}), [h(props.tag, {
staticClass: 'dropdown-divider',
attrs: _objectSpread({}, $attrs, {
role: 'separator',
'aria-orientation': 'horizontal'
}),
ref: 'divider'
})]);
}
});
+48
View File
@@ -0,0 +1,48 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import { BForm, props as formProps } from '../form/form';
export var BDropdownForm =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownForm',
functional: true,
props: _objectSpread({}, formProps, {
disabled: {
type: Boolean,
default: false
}
}),
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var $attrs = data.attrs || {};
var $listeners = data.on || {};
data.attrs = {};
data.on = {};
return h('li', mergeData(data, {
attrs: {
role: 'presentation'
}
}), [h(BForm, {
ref: 'form',
staticClass: 'b-dropdown-form',
class: {
disabled: props.disabled
},
props: props,
attrs: _objectSpread({}, $attrs, {
disabled: props.disabled,
// Tab index of -1 for keyboard navigation
tabindex: props.disabled ? null : '-1'
}),
on: $listeners
}, children)]);
}
});
+81
View File
@@ -0,0 +1,81 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot';
export var props = {
id: {
type: String,
default: null
},
header: {
type: String,
default: null
},
headerTag: {
type: String,
default: 'header'
},
headerVariant: {
type: String,
default: null
},
headerClasses: {
type: [String, Array, Object],
default: null
},
ariaDescribedby: {
type: String,
default: null
}
}; // @vue/component
export var BDropdownGroup =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownGroup',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
slots = _ref.slots,
scopedSlots = _ref.scopedSlots;
var $slots = slots();
var $scopedSlots = scopedSlots || {};
var $attrs = data.attrs || {};
data.attrs = {};
var header;
var headerId = null;
if (hasNormalizedSlot('header', $scopedSlots, $slots) || props.header) {
headerId = props.id ? "_bv_".concat(props.id, "_group_dd_header") : null;
header = h(props.headerTag, {
staticClass: 'dropdown-header',
class: [props.headerClasses, _defineProperty({}, "text-".concat(props.variant), props.variant)],
attrs: {
id: headerId,
role: 'heading'
}
}, normalizeSlot('header', {}, $scopedSlots, $slots) || props.header);
}
var adb = [headerId, props.ariaDescribedBy].filter(Boolean).join(' ').trim();
return h('li', mergeData(data, {
attrs: {
role: 'presentation'
}
}), [header || h(), h('ul', {
staticClass: 'list-unstyled',
attrs: _objectSpread({}, $attrs, {
id: props.id || null,
role: 'group',
'aria-describedby': adb || null
})
}, normalizeSlot('default', {}, $scopedSlots, $slots))]);
}
});
+50
View File
@@ -0,0 +1,50 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
export var props = {
id: {
type: String,
default: null
},
tag: {
type: String,
default: 'header'
},
variant: {
type: String,
default: null
}
}; // @vue/component
export var BDropdownHeader =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownHeader',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var $attrs = data.attrs || {};
data.attrs = {};
return h('li', mergeData(data, {
attrs: {
role: 'presentation'
}
}), [h(props.tag, {
staticClass: 'dropdown-header',
class: _defineProperty({}, "text-".concat(props.variant), props.variant),
attrs: _objectSpread({}, $attrs, {
id: props.id || null,
role: 'heading'
}),
ref: 'header'
}, children)]);
}
});
@@ -0,0 +1,72 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 nomalizeSlotMixin from '../../mixins/normalize-slot';
export var props = {
active: {
type: Boolean,
default: false
},
activeClass: {
type: String,
default: 'active'
},
disabled: {
type: Boolean,
default: false
},
variant: {
type: String,
default: null
}
}; // @vue/component
export var BDropdownItemButton =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownItemButton',
mixins: [nomalizeSlotMixin],
inheritAttrs: false,
inject: {
bvDropdown: {
default: null
}
},
props: props,
methods: {
closeDropdown: function closeDropdown() {
if (this.bvDropdown) {
this.bvDropdown.hide(true);
}
},
onClick: function onClick(evt) {
this.$emit('click', evt);
this.closeDropdown();
}
},
render: function render(h) {
var _class;
return h('li', {
attrs: {
role: 'presentation'
}
}, [h('button', {
staticClass: 'dropdown-item',
class: (_class = {}, _defineProperty(_class, this.activeClass, this.active), _defineProperty(_class, "text-".concat(this.variant), this.variant && !(this.active || this.disabled)), _class),
attrs: _objectSpread({}, this.$attrs, {
role: 'menuitem',
type: 'button',
disabled: this.disabled
}),
on: {
click: this.onClick
},
ref: 'button'
}, this.normalizeSlot('default'))]);
}
});
+64
View File
@@ -0,0 +1,64 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { requestAF } from '../../utils/dom';
import nomalizeSlotMixin from '../../mixins/normalize-slot';
import { BLink, propsFactory as linkPropsFactory } from '../link/link';
export var props = linkPropsFactory(); // @vue/component
export var BDropdownItem =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownItem',
mixins: [nomalizeSlotMixin],
inheritAttrs: false,
inject: {
bvDropdown: {
default: null
}
},
props: _objectSpread({}, props, {
variant: {
type: String,
default: null
}
}),
methods: {
closeDropdown: function closeDropdown() {
var _this = this;
// Close on next animation frame to allow <b-link> time to process
requestAF(function () {
if (_this.bvDropdown) {
_this.bvDropdown.hide(true);
}
});
},
onClick: function onClick(evt) {
this.$emit('click', evt);
this.closeDropdown();
}
},
render: function render(h) {
return h('li', {
attrs: {
role: 'presentation'
}
}, [h(BLink, {
props: this.$props,
staticClass: 'dropdown-item',
class: _defineProperty({}, "text-".concat(this.variant), this.variant && !(this.active || this.disabled)),
attrs: _objectSpread({}, this.$attrs, {
role: 'menuitem'
}),
on: {
click: this.onClick
},
ref: 'item'
}, this.normalizeSlot('default'))]);
}
});
+39
View File
@@ -0,0 +1,39 @@
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 { mergeData } from 'vue-functional-data-merge'; // @vue/component
export var BDropdownText =
/*#__PURE__*/
Vue.extend({
name: 'BDropdownText',
functional: true,
props: {
tag: {
type: String,
default: 'p'
},
variant: {
type: String,
default: null
}
},
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var $attrs = data.attrs || {};
data.attrs = {};
return h('li', mergeData(data, {
attrs: {
role: 'presentation'
}
}), [h(props.tag, {
staticClass: 'b-dropdown-text',
class: _defineProperty({}, "text-".concat(props.variant), props.variant),
props: props,
attrs: $attrs,
ref: 'text'
}, children)]);
}
});
+205
View File
@@ -0,0 +1,205 @@
import Vue from '../../utils/vue';
import { arrayIncludes } from '../../utils/array';
import { stripTags } from '../../utils/html';
import { getComponentConfig } from '../../utils/config';
import { HTMLElement } from '../../utils/safe-types';
import idMixin from '../../mixins/id';
import dropdownMixin from '../../mixins/dropdown';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import { BButton } from '../button/button';
var NAME = 'BDropdown';
export var props = {
toggleText: {
// This really should be toggleLabel
type: String,
default: function _default() {
return getComponentConfig(NAME, 'toggleText');
}
},
size: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'size');
}
},
variant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'variant');
}
},
block: {
type: Boolean,
default: false
},
menuClass: {
type: [String, Array],
default: null
},
toggleTag: {
type: String,
default: 'button'
},
toggleClass: {
type: [String, Array],
default: null
},
noCaret: {
type: Boolean,
default: false
},
split: {
type: Boolean,
default: false
},
splitHref: {
type: String // default: undefined
},
splitTo: {
type: [String, Object] // default: undefined
},
splitVariant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'splitVariant');
}
},
splitButtonType: {
type: String,
default: 'button',
validator: function validator(value) {
return arrayIncludes(['button', 'submit', 'reset'], value);
}
},
role: {
type: String,
default: 'menu'
},
boundary: {
// String: `scrollParent`, `window` or `viewport`
// HTMLElement: HTML Element reference
type: [String, HTMLElement],
default: 'scrollParent'
}
}; // @vue/component
export var BDropdown =
/*#__PURE__*/
Vue.extend({
name: NAME,
mixins: [idMixin, dropdownMixin, normalizeSlotMixin],
props: props,
computed: {
dropdownClasses: function dropdownClasses() {
return [this.directionClass, {
show: this.visible,
// The 'btn-group' class is required in `split` mode for button alignment
// It needs also to be applied when `block` is disabled to allow multiple
// dropdowns to be aligned one line
'btn-group': this.split || !this.block,
// When `block` is enabled and we are in `split` mode the 'd-flex' class
// needs to be applied to allow the buttons to stretch to full width
'd-flex': this.block && this.split,
// Position `static` is needed to allow menu to "breakout" of the `scrollParent`
// boundaries when boundary is anything other than `scrollParent`
// See: https://github.com/twbs/bootstrap/issues/24251#issuecomment-341413786
'position-static': this.boundary !== 'scrollParent' || !this.boundary
}];
},
menuClasses: function menuClasses() {
return [this.menuClass, {
'dropdown-menu-right': this.right,
show: this.visible
}];
},
toggleClasses: function toggleClasses() {
return [this.toggleClass, {
'dropdown-toggle-split': this.split,
'dropdown-toggle-no-caret': this.noCaret && !this.split
}];
}
},
render: function render(h) {
var split = h();
var buttonContent = this.normalizeSlot('button-content') || this.html || stripTags(this.text);
if (this.split) {
var btnProps = {
variant: this.splitVariant || this.variant,
size: this.size,
block: this.block,
disabled: this.disabled
}; // We add these as needed due to router-link issues with defined property with undefined/null values
if (this.splitTo) {
btnProps.to = this.splitTo;
} else if (this.splitHref) {
btnProps.href = this.splitHref;
} else if (this.splitButtonType) {
btnProps.type = this.splitButtonType;
}
split = h(BButton, {
ref: 'button',
props: btnProps,
attrs: {
id: this.safeId('_BV_button_')
},
on: {
click: this.click
}
}, [buttonContent]);
}
var toggle = h(BButton, {
ref: 'toggle',
staticClass: 'dropdown-toggle',
class: this.toggleClasses,
props: {
tag: this.toggleTag,
variant: this.variant,
size: this.size,
block: this.block && !this.split,
disabled: this.disabled
},
attrs: {
id: this.safeId('_BV_toggle_'),
'aria-haspopup': 'true',
'aria-expanded': this.visible ? 'true' : 'false'
},
on: {
click: this.toggle,
// click
keydown: this.toggle // enter, space, down
}
}, [this.split ? h('span', {
class: ['sr-only']
}, [this.toggleText]) : buttonContent]);
var menu = h('ul', {
ref: 'menu',
staticClass: 'dropdown-menu',
class: this.menuClasses,
attrs: {
role: this.role,
tabindex: '-1',
'aria-labelledby': this.safeId(this.split ? '_BV_button_' : '_BV_toggle_')
},
on: {
keydown: this.onKeydown // up, down, esc
}
}, !this.lazy || this.visible ? this.normalizeSlot('default', {
hide: this.hide
}) : [h()]);
return h('div', {
staticClass: 'dropdown b-dropdown',
class: this.dropdownClasses,
attrs: {
id: this.safeId()
}
}, [split, toggle, menu]);
}
});
+36
View File
@@ -0,0 +1,36 @@
//
// Dropdown
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const DropdownPlugin: BvPlugin
// Component: b-dropdown
export declare class BDropdown extends BvComponent {
// Public methods
show: () => void
hide: (refocus?: boolean) => void
}
// Component: b-dropdown-item
export declare class BDropdownItem extends BvComponent {}
// Component: b-dropdown-item-button
export declare class BDropdownItemButton extends BvComponent {}
// Component: b-dropdown-divider
export declare class BDropdownDivider extends BvComponent {}
// Component: b-dropdown-form
export declare class BDropdownForm extends BvComponent {}
// Component: b-dropdown-text
export declare class BDropdownText extends BvComponent {}
// Component: b-dropdown-group
export declare class BDropdownGroup extends BvComponent {}
// Component: b-dropdown-header
export declare class BDropdownHeader extends BvComponent {}
+34
View File
@@ -0,0 +1,34 @@
import { BDropdown } from './dropdown';
import { BDropdownItem } from './dropdown-item';
import { BDropdownItemButton } from './dropdown-item-button';
import { BDropdownHeader } from './dropdown-header';
import { BDropdownDivider } from './dropdown-divider';
import { BDropdownForm } from './dropdown-form';
import { BDropdownText } from './dropdown-text';
import { BDropdownGroup } from './dropdown-group';
import { pluginFactory } from '../../utils/plugins';
var DropdownPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BDropdown: BDropdown,
BDd: BDropdown,
BDropdownItem: BDropdownItem,
BDdItem: BDropdownItem,
BDropdownItemButton: BDropdownItemButton,
BDropdownItemBtn: BDropdownItemButton,
BDdItemButton: BDropdownItemButton,
BDdItemBtn: BDropdownItemButton,
BDropdownHeader: BDropdownHeader,
BDdHeader: BDropdownHeader,
BDropdownDivider: BDropdownDivider,
BDdDivider: BDropdownDivider,
BDropdownForm: BDropdownForm,
BDdForm: BDropdownForm,
BDropdownText: BDropdownText,
BDdText: BDropdownText,
BDropdownGroup: BDropdownGroup,
BDdGroup: BDropdownGroup
}
});
export { DropdownPlugin, BDropdown, BDropdownItem, BDropdownItemButton, BDropdownHeader, BDropdownDivider, BDropdownForm, BDropdownText, BDropdownGroup };
+43
View File
@@ -0,0 +1,43 @@
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 { mergeData } from 'vue-functional-data-merge';
import { arrayIncludes } from '../../utils/array';
export var props = {
type: {
type: String,
default: 'iframe',
validator: function validator(str) {
return arrayIncludes(['iframe', 'embed', 'video', 'object', 'img', 'b-img', 'b-img-lazy'], str);
}
},
tag: {
type: String,
default: 'div'
},
aspect: {
type: String,
default: '16by9'
}
}; // @vue/component
export var BEmbed =
/*#__PURE__*/
Vue.extend({
name: 'BEmbed',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.tag, {
ref: data.ref,
staticClass: 'embed-responsive',
class: _defineProperty({}, "embed-responsive-".concat(props.aspect), Boolean(props.aspect))
}, [h(props.type, mergeData(data, {
ref: '',
staticClass: 'embed-responsive-item'
}), children)]);
}
});
+11
View File
@@ -0,0 +1,11 @@
//
// Embed
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const EmbedPlugin: BvPlugin
// Component: b-embed
export declare class BEmbed extends BvComponent {}
+10
View File
@@ -0,0 +1,10 @@
import { BEmbed } from './embed';
import { pluginFactory } from '../../utils/plugins';
var EmbedPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BEmbed: BEmbed
}
});
export { EmbedPlugin, BEmbed };
@@ -0,0 +1,42 @@
import Vue from '../../utils/vue';
import idMixin from '../../mixins/id';
import formMixin from '../../mixins/form';
import formOptionsMixin from '../../mixins/form-options';
import formRadioCheckGroupMixin from '../../mixins/form-radio-check-group';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
export var props = {
switches: {
// Custom switch styling
type: Boolean,
default: false
},
checked: {
type: Array,
default: null
}
}; // @vue/component
export var BFormCheckboxGroup =
/*#__PURE__*/
Vue.extend({
name: 'BFormCheckboxGroup',
mixins: [idMixin, formMixin, formRadioCheckGroupMixin, // Includes render function
formOptionsMixin, formSizeMixin, formStateMixin],
provide: function provide() {
return {
bvCheckGroup: this
};
},
props: props,
data: function data() {
return {
localChecked: this.checked || []
};
},
computed: {
isRadioGroup: function isRadioGroup() {
return false;
}
}
});
@@ -0,0 +1,130 @@
import Vue from '../../utils/vue';
import looseEqual from '../../utils/loose-equal';
import looseIndexOf from '../../utils/loose-index-of';
import { isArray } from '../../utils/inspect';
import formMixin from '../../mixins/form';
import formRadioCheckMixin from '../../mixins/form-radio-check';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
import idMixin from '../../mixins/id'; // @vue/component
export var BFormCheckbox =
/*#__PURE__*/
Vue.extend({
name: 'BFormCheckbox',
mixins: [formRadioCheckMixin, // Includes shared render function
idMixin, formMixin, formSizeMixin, formStateMixin],
inject: {
bvGroup: {
from: 'bvCheckGroup',
default: false
}
},
props: {
value: {
// type: [String, Number, Boolean, Object],
default: true
},
uncheckedValue: {
// type: [String, Number, Boolean, Object],
// Not applicable in multi-check mode
default: false
},
indeterminate: {
// Not applicable in multi-check mode
type: Boolean,
default: false
},
switch: {
// Custom switch styling
type: Boolean,
default: false
},
checked: {
// v-model (Array when multiple checkboxes have same name)
// type: [String, Number, Boolean, Object, Array],
default: null
}
},
computed: {
isChecked: function isChecked() {
var checked = this.computedLocalChecked;
var value = this.value;
if (isArray(checked)) {
return looseIndexOf(checked, value) > -1;
} else {
return looseEqual(checked, value);
}
},
isRadio: function isRadio() {
return false;
},
isCheck: function isCheck() {
return true;
}
},
watch: {
computedLocalChecked: function computedLocalChecked(newVal, oldVal) {
this.$emit('input', newVal);
if (this.$refs && this.$refs.input) {
this.$emit('update:indeterminate', this.$refs.input.indeterminate);
}
},
indeterminate: function indeterminate(newVal, oldVal) {
this.setIndeterminate(newVal);
}
},
mounted: function mounted() {
// Set initial indeterminate state
this.setIndeterminate(this.indeterminate);
},
methods: {
handleChange: function handleChange(_ref) {
var _ref$target = _ref.target,
checked = _ref$target.checked,
indeterminate = _ref$target.indeterminate;
var localChecked = this.computedLocalChecked;
var value = this.value;
var isArr = isArray(localChecked);
var uncheckedValue = isArr ? null : this.uncheckedValue; // Update computedLocalChecked
if (isArr) {
var idx = looseIndexOf(localChecked, value);
if (checked && idx < 0) {
// Add value to array
localChecked = localChecked.concat(value);
} else if (!checked && idx > -1) {
// Remove value from array
localChecked = localChecked.slice(0, idx).concat(localChecked.slice(idx + 1));
}
} else {
localChecked = checked ? value : uncheckedValue;
}
this.computedLocalChecked = localChecked; // Change is only emitted on user interaction
this.$emit('change', checked ? value : uncheckedValue); // If this is a child of form-checkbox-group, we emit a change event on it as well
if (this.isGroup) {
this.bvGroup.$emit('change', localChecked);
}
this.$emit('update:indeterminate', indeterminate);
},
setIndeterminate: function setIndeterminate(state) {
// Indeterminate only supported in single checkbox mode
if (isArray(this.computedLocalChecked)) {
state = false;
}
if (this.$refs && this.$refs.input) {
this.$refs.input.indeterminate = state; // Emit update event to prop
this.$emit('update:indeterminate', state);
}
}
}
});
+14
View File
@@ -0,0 +1,14 @@
//
// Form Checkbox
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormCheckboxPlugin: BvPlugin
// Component: b-form-checkbox
export declare class BFormCheckbox extends BvComponent {}
// Component: b-form-checkbox-group
export declare class BFormCheckboxGroup extends BvComponent {}
+16
View File
@@ -0,0 +1,16 @@
import { BFormCheckbox } from './form-checkbox';
import { BFormCheckboxGroup } from './form-checkbox-group';
import { pluginFactory } from '../../utils/plugins';
var FormCheckboxPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormCheckbox: BFormCheckbox,
BCheckbox: BFormCheckbox,
BCheck: BFormCheckbox,
BFormCheckboxGroup: BFormCheckboxGroup,
BCheckboxGroup: BFormCheckboxGroup,
BCheckGroup: BFormCheckboxGroup
}
});
export { FormCheckboxPlugin, BFormCheckbox, BFormCheckboxGroup };
+366
View File
@@ -0,0 +1,366 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { from as arrayFrom, isArray, concat } from '../../utils/array';
import { getComponentConfig } from '../../utils/config';
import { isFile, isFunction, isUndefinedOrNull } from '../../utils/inspect';
import { File } from '../../utils/safe-types';
import { warn } from '../../utils/warn';
import formCustomMixin from '../../mixins/form-custom';
import formMixin from '../../mixins/form';
import formStateMixin from '../../mixins/form-state';
import idMixin from '../../mixins/id';
import normalizeSlotMixin from '../../mixins/normalize-slot';
var NAME = 'BFormFile'; // @vue/component
export var BFormFile =
/*#__PURE__*/
Vue.extend({
name: NAME,
mixins: [idMixin, formMixin, formStateMixin, formCustomMixin, normalizeSlotMixin],
inheritAttrs: false,
model: {
prop: 'value',
event: 'input'
},
props: {
size: {
type: String,
default: function _default() {
return getComponentConfig('BFormControl', 'size');
}
},
value: {
type: [File, Array],
default: null,
validator: function validator(val) {
/* istanbul ignore next */
if (val === '') {
warn("".concat(NAME, " - setting value/v-model to an empty string for reset is deprecated. Set to 'null' instead"));
return true;
}
return isUndefinedOrNull(val) || isFile(val) || isArray(val) && (val.length === 0 || val.every(isFile));
}
},
accept: {
type: String,
default: ''
},
// Instruct input to capture from camera
capture: {
type: Boolean,
default: false
},
placeholder: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'placeholder');
}
},
browseText: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'browseText');
}
},
dropPlaceholder: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'dropPlaceholder');
}
},
multiple: {
type: Boolean,
default: false
},
directory: {
type: Boolean,
default: false
},
noTraverse: {
type: Boolean,
default: false
},
noDrop: {
type: Boolean,
default: false
},
fileNameFormatter: {
type: Function,
default: null
}
},
data: function data() {
return {
selectedFile: null,
dragging: false,
hasFocus: false
};
},
computed: {
selectLabel: function selectLabel() {
// Draging active
if (this.dragging && this.dropPlaceholder) {
return this.dropPlaceholder;
} // No file chosen
if (!this.selectedFile || this.selectedFile.length === 0) {
return this.placeholder;
} // Convert selectedFile to an array (if not already one)
var files = concat(this.selectedFile).filter(Boolean);
if (this.hasNormalizedSlot('file-name')) {
// There is a slot for formatting the files/names
return [this.normalizeSlot('file-name', {
files: files,
names: files.map(function (f) {
return f.name;
})
})];
} else {
// Use the user supplied formatter, or the built in one.
return isFunction(this.fileNameFormatter) ? String(this.fileNameFormatter(files)) : files.map(function (file) {
return file.name;
}).join(', ');
}
}
},
watch: {
selectedFile: function selectedFile(newVal, oldVal) {
// The following test is needed when the file input is "reset" or the
// exact same file(s) are selected to prevent an infinite loop.
// When in `multiple` mode we need to check for two empty arrays or
// two arrays with identical files
if (newVal === oldVal || isArray(newVal) && isArray(oldVal) && newVal.length === oldVal.length && newVal.every(function (v, i) {
return v === oldVal[i];
})) {
return;
}
if (!newVal && this.multiple) {
this.$emit('input', []);
} else {
this.$emit('input', newVal);
}
},
value: function value(newVal) {
if (!newVal || isArray(newVal) && newVal.length === 0) {
this.reset();
}
}
},
methods: {
focusHandler: function focusHandler(evt) {
// Bootstrap v4 doesn't have focus styling for custom file input
// Firefox has a '[type=file]:focus ~ sibling' selector issue,
// so we add a 'focus' class to get around these bugs
if (this.plain || evt.type === 'focusout') {
this.hasFocus = false;
} else {
// Add focus styling for custom file input
this.hasFocus = true;
}
},
reset: function reset() {
try {
// Wrapped in try in case IE 11 craps out
this.$refs.input.value = '';
} catch (e) {} // IE 11 doesn't support setting `input.value` to '' or null
// So we use this little extra hack to reset the value, just in case.
// This also appears to work on modern browsers as well.
this.$refs.input.type = '';
this.$refs.input.type = 'file';
this.selectedFile = this.multiple ? [] : null;
},
onFileChange: function onFileChange(evt) {
var _this = this;
// Always emit original event
this.$emit('change', evt); // Check if special `items` prop is available on event (drop mode)
// Can be disabled by setting no-traverse
var items = evt.dataTransfer && evt.dataTransfer.items;
/* istanbul ignore next: not supported in JSDOM */
if (items && !this.noTraverse) {
var queue = [];
for (var i = 0; i < items.length; i++) {
var item = items[i].webkitGetAsEntry();
if (item) {
queue.push(this.traverseFileTree(item));
}
}
Promise.all(queue).then(function (filesArr) {
_this.setFiles(arrayFrom(filesArr));
});
return;
} // Normal handling
this.setFiles(evt.target.files || evt.dataTransfer.files);
},
setFiles: function setFiles() {
var files = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
if (!files) {
/* istanbul ignore next: this will probably not happen */
this.selectedFile = null;
} else if (this.multiple) {
// Convert files to array
var filesArray = [];
for (var i = 0; i < files.length; i++) {
filesArray.push(files[i]);
} // Return file(s) as array
this.selectedFile = filesArray;
} else {
// Return single file object
this.selectedFile = files[0] || null;
}
},
onReset: function onReset() {
// Triggered when the parent form (if any) is reset
this.selectedFile = this.multiple ? [] : null;
},
onDragover: function onDragover(evt)
/* istanbul ignore next: difficult to test in JSDOM */
{
evt.preventDefault();
evt.stopPropagation();
if (this.noDrop || !this.custom) {
return;
}
this.dragging = true;
evt.dataTransfer.dropEffect = 'copy';
},
onDragleave: function onDragleave(evt)
/* istanbul ignore next: difficult to test in JSDOM */
{
evt.preventDefault();
evt.stopPropagation();
this.dragging = false;
},
onDrop: function onDrop(evt)
/* istanbul ignore next: difficult to test in JSDOM */
{
evt.preventDefault();
evt.stopPropagation();
if (this.noDrop) {
return;
}
this.dragging = false;
if (evt.dataTransfer.files && evt.dataTransfer.files.length > 0) {
this.onFileChange(evt);
}
},
traverseFileTree: function traverseFileTree(item, path)
/* istanbul ignore next: not supported in JSDOM */
{
var _this2 = this;
// Based on http://stackoverflow.com/questions/3590058
return new Promise(function (resolve) {
path = path || '';
if (item.isFile) {
// Get file
item.file(function (file) {
file.$path = path; // Inject $path to file obj
resolve(file);
});
} else if (item.isDirectory) {
// Get folder contents
item.createReader().readEntries(function (entries) {
var queue = [];
for (var i = 0; i < entries.length; i++) {
queue.push(_this2.traverseFileTree(entries[i], path + item.name + '/'));
}
Promise.all(queue).then(function (filesArr) {
resolve(arrayFrom(filesArr));
});
});
}
});
}
},
render: function render(h) {
// Form Input
var input = h('input', {
ref: 'input',
class: [{
'form-control-file': this.plain,
'custom-file-input': this.custom,
focus: this.custom && this.hasFocus
}, this.stateClass],
attrs: _objectSpread({}, this.$attrs, {
type: 'file',
id: this.safeId(),
name: this.name,
disabled: this.disabled,
required: this.required,
form: this.form || null,
capture: this.capture || null,
accept: this.accept || null,
multiple: this.multiple,
webkitdirectory: this.directory,
'aria-required': this.required ? 'true' : null
}),
on: {
change: this.onFileChange,
focusin: this.focusHandler,
focusout: this.focusHandler,
reset: this.onReset
}
});
if (this.plain) {
return input;
} // Overlay Labels
var label = h('label', {
staticClass: 'custom-file-label',
class: [this.dragging ? 'dragging' : null],
attrs: {
for: this.safeId(),
'data-browse': this.browseText || null
}
}, this.selectLabel); // Return rendered custom file input
return h('div', {
staticClass: 'custom-file b-form-file',
class: [this.stateClass, _defineProperty({}, "b-custom-control-".concat(this.size), Boolean(this.size))],
attrs: {
id: this.safeId('_BV_file_outer_')
},
on: {
dragover: this.onDragover,
dragleave: this.onDragleave,
drop: this.onDrop
}
}, [input, label]);
}
});
+14
View File
@@ -0,0 +1,14 @@
//
// Form File
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormFilePlugin: BvPlugin
// Component: b-form-file
export declare class BFormFile extends BvComponent {
focus: () => void
reset: () => void
}
+11
View File
@@ -0,0 +1,11 @@
import { BFormFile } from './form-file';
import { pluginFactory } from '../../utils/plugins';
var FormFilePlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormFile: BFormFile,
BFile: BFormFile
}
});
export { FormFilePlugin, BFormFile };
+434
View File
@@ -0,0 +1,434 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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; }
// Utils
import memoize from '../../utils/memoize';
import upperFirst from '../../utils/upper-first';
import { arrayIncludes } from '../../utils/array';
import { getBreakpointsUpCached } from '../../utils/config';
import { select, selectAll, isVisible, setAttr, removeAttr, getAttr } from '../../utils/dom';
import { isBrowser } from '../../utils/env';
import { isBoolean } from '../../utils/inspect';
import { keys, create } from '../../utils/object'; // Mixins
import formStateMixin from '../../mixins/form-state';
import idMixin from '../../mixins/id';
import normalizeSlotMixin from '../../mixins/normalize-slot'; // Sub components
import { BCol } from '../layout/col';
import { BFormRow } from '../layout/form-row';
import { BFormText } from '../form/form-text';
import { BFormInvalidFeedback } from '../form/form-invalid-feedback';
import { BFormValidFeedback } from '../form/form-valid-feedback'; // Component name
var NAME = 'BFormGroup'; // Selector for finding first input in the form-group
var SELECTOR = 'input:not([disabled]),textarea:not([disabled]),select:not([disabled])'; // Render helper functions (here rather than polluting the instance with more methods)
var renderInvalidFeedback = function renderInvalidFeedback(h, ctx) {
var content = ctx.normalizeSlot('invalid-feedback') || ctx.invalidFeedback;
var invalidFeedback = h();
if (content) {
invalidFeedback = h(BFormInvalidFeedback, {
props: {
id: ctx.invalidFeedbackId,
// If state is explicitly false, always show the feedback
state: ctx.computedState,
tooltip: ctx.tooltip,
ariaLive: ctx.feedbackAriaLive,
role: ctx.feedbackAriaLive ? 'alert' : null
},
attrs: {
tabindex: content ? '-1' : null
}
}, [content]);
}
return invalidFeedback;
};
var renderValidFeedback = function renderValidFeedback(h, ctx) {
var content = ctx.normalizeSlot('valid-feedback') || ctx.validFeedback;
var validFeedback = h();
if (content) {
validFeedback = h(BFormValidFeedback, {
props: {
id: ctx.validFeedbackId,
// If state is explicitly true, always show the feedback
state: ctx.computedState,
tooltip: ctx.tooltip,
ariaLive: ctx.feedbackAriaLive,
role: ctx.feedbackAriaLive ? 'alert' : null
},
attrs: {
tabindex: content ? '-1' : null
}
}, [content]);
}
return validFeedback;
};
var renderHelpText = function renderHelpText(h, ctx) {
// Form help text (description)
var content = ctx.normalizeSlot('description') || ctx.description;
var description = h();
if (content) {
description = h(BFormText, {
attrs: {
id: ctx.descriptionId,
tabindex: content ? '-1' : null
}
}, [content]);
}
return description;
};
var renderLabel = function renderLabel(h, ctx) {
// Render label/legend inside b-col if necessary
var content = ctx.normalizeSlot('label') || ctx.label;
var labelFor = ctx.labelFor;
var isLegend = !labelFor;
var isHorizontal = ctx.isHorizontal;
var labelTag = isLegend ? 'legend' : 'label';
if (!content && !isHorizontal) {
return h();
} else if (ctx.labelSrOnly) {
var label = h();
if (content) {
label = h(labelTag, {
class: 'sr-only',
attrs: {
id: ctx.labelId,
for: labelFor || null
}
}, [content]);
}
return h(isHorizontal ? BCol : 'div', {
props: isHorizontal ? ctx.labelColProps : {}
}, [label]);
} else {
return h(isHorizontal ? BCol : labelTag, {
on: isLegend ? {
click: ctx.legendClick
} : {},
props: isHorizontal ? _objectSpread({
tag: labelTag
}, ctx.labelColProps) : {},
attrs: {
id: ctx.labelId,
for: labelFor || null,
// We add a tab index to legend so that screen readers
// will properly read the aria-labelledby in IE.
tabindex: isLegend ? '-1' : null
},
class: [// When horizontal or if a legend is rendered, add col-form-label
// for correct sizing as Bootstrap has inconsistent font styling
// for legend in non-horizontal form-groups.
// See: https://github.com/twbs/bootstrap/issues/27805
isHorizontal || isLegend ? 'col-form-label' : '', // Emulate label padding top of 0 on legend when not horizontal
!isHorizontal && isLegend ? 'pt-0' : '', // If not horizontal and not a legend, we add d-block to label
// so that label-align works
!isHorizontal && !isLegend ? 'd-block' : '', ctx.labelSize ? "col-form-label-".concat(ctx.labelSize) : '', ctx.labelAlignClasses, ctx.labelClass]
}, [content]);
}
}; // -- BFormGroup Prop factory -- used for lazy generation of props
// Memoize this function to return cached values to
// save time in computed functions
var makePropName = memoize(function () {
var breakpoint = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var prefix = arguments.length > 1 ? arguments[1] : undefined;
return "".concat(prefix).concat(upperFirst(breakpoint));
}); // BFormGroup prop generator for lazy generation of props
var generateProps = function generateProps() {
var BREAKPOINTS = getBreakpointsUpCached(); // Generate the labelCol breakpoint props
var bpLabelColProps = BREAKPOINTS.reduce(function (props, breakpoint) {
// i.e. label-cols, label-cols-sm, label-cols-md, ...
props[makePropName(breakpoint, 'labelCols')] = {
type: [Number, String, Boolean],
default: breakpoint ? false : null
};
return props;
}, create(null)); // Generate the labelAlign breakpoint props
var bpLabelAlignProps = BREAKPOINTS.reduce(function (props, breakpoint) {
// label-align, label-align-sm, label-align-md, ...
props[makePropName(breakpoint, 'labelAlign')] = {
type: String,
// left, right, center
default: null
};
return props;
}, create(null));
return _objectSpread({
label: {
type: String,
default: null
},
labelFor: {
type: String,
default: null
},
labelSize: {
type: String,
default: null
},
labelSrOnly: {
type: Boolean,
default: false
}
}, bpLabelColProps, {}, bpLabelAlignProps, {
labelClass: {
type: [String, Array, Object],
default: null
},
description: {
type: String,
default: null
},
invalidFeedback: {
type: String,
default: null
},
validFeedback: {
type: String,
default: null
},
tooltip: {
// Enable tooltip style feedback
type: Boolean,
default: false
},
feedbackAriaLive: {
type: String,
default: 'assertive'
},
validated: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
}
});
}; // We do not use Vue.extend here as that would evaluate the props
// immediately, which we do not want to happen
// @vue/component
export var BFormGroup = {
name: NAME,
mixins: [idMixin, formStateMixin, normalizeSlotMixin],
get props() {
// Allow props to be lazy evaled on first access and
// then they become a non-getter afterwards.
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get#Smart_self-overwriting_lazy_getters
delete this.props; // eslint-disable-next-line no-return-assign
return this.props = generateProps();
},
computed: {
labelColProps: function labelColProps() {
var _this = this;
var props = {};
getBreakpointsUpCached().forEach(function (breakpoint) {
// Grab the value if the label column breakpoint prop
var propVal = _this[makePropName(breakpoint, 'labelCols')]; // Handle case where the prop's value is an empty string,
// which represents true
propVal = propVal === '' ? true : propVal || false;
if (!isBoolean(propVal) && propVal !== 'auto') {
// Convert to column size to number
propVal = parseInt(propVal, 10) || 0; // Ensure column size is greater than 0
propVal = propVal > 0 ? propVal : false;
}
if (propVal) {
// Add the prop to the list of props to give to b-col
// If breakpoint is '' (labelCols=true), then we use the
// col prop to make equal width at xs
var bColPropName = breakpoint || (isBoolean(propVal) ? 'col' : 'cols'); // Add it to the props
props[bColPropName] = propVal;
}
});
return props;
},
labelAlignClasses: function labelAlignClasses() {
var _this2 = this;
var classes = [];
getBreakpointsUpCached().forEach(function (breakpoint) {
// Assemble the label column breakpoint align classes
var propVal = _this2[makePropName(breakpoint, 'labelAlign')] || null;
if (propVal) {
var className = breakpoint ? "text-".concat(breakpoint, "-").concat(propVal) : "text-".concat(propVal);
classes.push(className);
}
});
return classes;
},
isHorizontal: function isHorizontal() {
// Determine if the resultant form-group will be rendered
// horizontal (meaning it has label-col breakpoints)
return keys(this.labelColProps).length > 0;
},
labelId: function labelId() {
return this.hasNormalizedSlot('label') || this.label ? this.safeId('_BV_label_') : null;
},
descriptionId: function descriptionId() {
return this.hasNormalizedSlot('description') || this.description ? this.safeId('_BV_description_') : null;
},
hasInvalidFeedback: function hasInvalidFeedback() {
// Used for computing aria-describedby
return this.computedState === false && (this.hasNormalizedSlot('invalid-feedback') || this.invalidFeedback);
},
invalidFeedbackId: function invalidFeedbackId() {
return this.hasInvalidFeedback ? this.safeId('_BV_feedback_invalid_') : null;
},
hasValidFeedback: function hasValidFeedback() {
// Used for computing aria-describedby
return this.computedState === true && (this.hasNormalizedSlot('valid-feedback') || this.validFeedback);
},
validFeedbackId: function validFeedbackId() {
return this.hasValidFeedback ? this.safeId('_BV_feedback_valid_') : null;
},
describedByIds: function describedByIds() {
// Screen readers will read out any content linked to by aria-describedby
// even if the content is hidden with `display: none;`, hence we only include
// feedback IDs if the form-group's state is explicitly valid or invalid.
return [this.descriptionId, this.invalidFeedbackId, this.validFeedbackId].filter(Boolean).join(' ') || null;
}
},
watch: {
describedByIds: function describedByIds(add, remove) {
if (add !== remove) {
this.setInputDescribedBy(add, remove);
}
}
},
mounted: function mounted() {
var _this3 = this;
this.$nextTick(function () {
// Set the aria-describedby IDs on the input specified by label-for
// We do this in a nextTick to ensure the children have finished rendering
_this3.setInputDescribedBy(_this3.describedByIds);
});
},
methods: {
legendClick: function legendClick(evt) {
if (this.labelFor) {
// Don't do anything if labelFor is set
/* istanbul ignore next: clicking a label will focus the input, so no need to test */
return;
}
var tagName = evt.target ? evt.target.tagName : '';
if (/^(input|select|textarea|label|button|a)$/i.test(tagName)) {
// If clicked an interactive element inside legend,
// we just let the default happen
/* istanbul ignore next */
return;
}
var inputs = selectAll(SELECTOR, this.$refs.content).filter(isVisible);
if (inputs && inputs.length === 1 && inputs[0].focus) {
// if only a single input, focus it, emulating label behaviour
inputs[0].focus();
}
},
setInputDescribedBy: function setInputDescribedBy(add, remove) {
// Sets the `aria-describedby` attribute on the input if label-for is set.
// Optionally accepts a string of IDs to remove as the second parameter.
// Preserves any aria-describedby value(s) user may have on input.
if (this.labelFor && isBrowser) {
var input = select("#".concat(this.labelFor), this.$refs.content);
if (input) {
var adb = 'aria-describedby';
var ids = (getAttr(input, adb) || '').split(/\s+/);
add = (add || '').split(/\s+/);
remove = (remove || '').split(/\s+/); // Update ID list, preserving any original IDs
// and ensuring the ID's are unique
ids = ids.filter(function (id) {
return !arrayIncludes(remove, id);
}).concat(add).filter(Boolean);
ids = keys(ids.reduce(function (memo, id) {
return _objectSpread({}, memo, _defineProperty({}, id, true));
}, {})).join(' ').trim();
if (ids) {
setAttr(input, adb, ids);
} else {
// No IDs, so remove the attribute
removeAttr(input, adb);
}
}
}
}
},
render: function render(h) {
var isFieldset = !this.labelFor;
var isHorizontal = this.isHorizontal; // Generate the label
var label = renderLabel(h, this); // Generate the content
var content = h(isHorizontal ? BCol : 'div', {
ref: 'content',
attrs: {
tabindex: isFieldset ? '-1' : null,
role: isFieldset ? 'group' : null
}
}, [this.normalizeSlot('default') || h(), renderInvalidFeedback(h, this), renderValidFeedback(h, this), renderHelpText(h, this)]); // Create the form-group
var data = {
staticClass: 'form-group',
class: [this.validated ? 'was-validated' : null, this.stateClass],
attrs: {
id: this.safeId(),
disabled: isFieldset ? this.disabled : null,
role: isFieldset ? null : 'group',
'aria-invalid': this.computedState === false ? 'true' : null,
// Only apply aria-labelledby if we are a horizontal fieldset
// as the legend is no longer a direct child of fieldset
'aria-labelledby': isFieldset && isHorizontal ? this.labelId : null,
// Only apply aria-describedby IDs if we are a fieldset
// as the input will have the IDs when not a fieldset
'aria-describedby': isFieldset ? this.describedByIds : null
}
}; // Return it wrapped in a form-group
// Note: Fieldsets do not support adding `row` or `form-row` directly
// to them due to browser specific render issues, so we move the `form-row`
// to an inner wrapper div when horizontal and using a fieldset
return h(isFieldset ? 'fieldset' : isHorizontal ? BFormRow : 'div', data, isHorizontal && isFieldset ? [h(BFormRow, {}, [label, content])] : [label, content]);
}
};
+11
View File
@@ -0,0 +1,11 @@
//
// Form Group
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormGroupPlugin: BvPlugin
// Component: b-form-group
export declare class BFormGroup extends BvComponent {}
+11
View File
@@ -0,0 +1,11 @@
import { BFormGroup } from './form-group';
import { pluginFactory } from '../../utils/plugins';
var FormGroupPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormGroup: BFormGroup,
BFormFieldset: BFormGroup
}
});
export { FormGroupPlugin, BFormGroup };
+149
View File
@@ -0,0 +1,149 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 idMixin from '../../mixins/id';
import formMixin from '../../mixins/form';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
import formTextMixin from '../../mixins/form-text';
import formSelectionMixin from '../../mixins/form-selection';
import formValidityMixin from '../../mixins/form-validity';
import { arrayIncludes } from '../../utils/array';
import { eventOn, eventOff } from '../../utils/dom'; // Valid supported input types
var TYPES = ['text', 'password', 'email', 'number', 'url', 'tel', 'search', 'range', 'color', 'date', 'time', 'datetime', 'datetime-local', 'month', 'week']; // @vue/component
export var BFormInput =
/*#__PURE__*/
Vue.extend({
name: 'BFormInput',
mixins: [idMixin, formMixin, formSizeMixin, formStateMixin, formTextMixin, formSelectionMixin, formValidityMixin],
props: {
// value prop defined in form-text mixin
// value: { },
type: {
type: String,
default: 'text',
validator: function validator(type) {
return arrayIncludes(TYPES, type);
}
},
noWheel: {
// Disable mousewheel to prevent wheel from changing values (i.e. number/date).
type: Boolean,
default: false
},
min: {
type: [String, Number],
default: null
},
max: {
type: [String, Number],
default: null
},
step: {
type: [String, Number],
default: null
},
list: {
type: String,
default: null
}
},
computed: {
localType: function localType() {
// We only allow certain types
return arrayIncludes(TYPES, this.type) ? this.type : 'text';
}
},
watch: {
noWheel: function noWheel(newVal) {
this.setWheelStopper(newVal);
}
},
mounted: function mounted() {
this.setWheelStopper(this.noWheel);
},
deactivated: function deactivated() {
// Turn off listeners when keep-alive component deactivated
/* istanbul ignore next */
this.setWheelStopper(false);
},
activated: function activated() {
// Turn on listeners (if no-wheel) when keep-alive component activated
/* istanbul ignore next */
this.setWheelStopper(this.noWheel);
},
beforeDestroy: function beforeDestroy() {
/* istanbul ignore next */
this.setWheelStopper(false);
},
methods: {
setWheelStopper: function setWheelStopper(on) {
var input = this.$el; // We use native events, so that we don't interfere with propgation
if (on) {
eventOn(input, 'focus', this.onWheelFocus);
eventOn(input, 'blur', this.onWheelBlur);
} else {
eventOff(input, 'focus', this.onWheelFocus);
eventOff(input, 'blur', this.onWheelBlur);
eventOff(document, 'wheel', this.stopWheel);
}
},
onWheelFocus: function onWheelFocus(evt) {
eventOn(document, 'wheel', this.stopWheel);
},
onWheelBlur: function onWheelBlur(evt) {
eventOff(document, 'wheel', this.stopWheel);
},
stopWheel: function stopWheel(evt) {
evt.preventDefault();
this.$el.blur();
}
},
render: function render(h) {
var self = this;
return h('input', {
ref: 'input',
class: self.computedClass,
directives: [{
name: 'model',
rawName: 'v-model',
value: self.localValue,
expression: 'localValue'
}],
attrs: {
id: self.safeId(),
name: self.name,
form: self.form || null,
type: self.localType,
disabled: self.disabled,
placeholder: self.placeholder,
required: self.required,
autocomplete: self.autocomplete || null,
readonly: self.readonly || self.plaintext,
min: self.min,
max: self.max,
step: self.step,
list: self.localType !== 'password' ? self.list : null,
'aria-required': self.required ? 'true' : null,
'aria-invalid': self.computedAriaInvalid
},
domProps: {
value: self.localValue
},
on: _objectSpread({}, self.$listeners, {
input: self.onInput,
change: self.onChange,
blur: self.onBlur
})
});
}
});
+13
View File
@@ -0,0 +1,13 @@
//
// Form Input
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormInputPlugin: BvPlugin
// Component: b-form-input
export declare class BFormInput extends BvComponent {
focus: () => void
}
+11
View File
@@ -0,0 +1,11 @@
import { BFormInput } from './form-input';
import { pluginFactory } from '../../utils/plugins';
var FormInputPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormInput: BFormInput,
BInput: BFormInput
}
});
export { FormInputPlugin, BFormInput };
@@ -0,0 +1,37 @@
import Vue from '../../utils/vue';
import idMixin from '../../mixins/id';
import formMixin from '../../mixins/form';
import formOptionsMixin from '../../mixins/form-options';
import formRadioCheckGroupMixin from '../../mixins/form-radio-check-group';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
export var props = {
checked: {
// type: [String, Number, Boolean, Object],
default: null
}
}; // @vue/component
export var BFormRadioGroup =
/*#__PURE__*/
Vue.extend({
name: 'BFormRadioGroup',
mixins: [idMixin, formMixin, formRadioCheckGroupMixin, // Includes render function
formOptionsMixin, formSizeMixin, formStateMixin],
provide: function provide() {
return {
bvRadioGroup: this
};
},
props: props,
data: function data() {
return {
localChecked: this.checked
};
},
computed: {
isRadioGroup: function isRadioGroup() {
return true;
}
}
});
+60
View File
@@ -0,0 +1,60 @@
import Vue from '../../utils/vue';
import idMixin from '../../mixins/id';
import formMixin from '../../mixins/form';
import formStateMixin from '../../mixins/form-state';
import formSizeMixin from '../../mixins/form-size';
import formRadioCheckMixin from '../../mixins/form-radio-check';
import looseEqual from '../../utils/loose-equal'; // @vue/component
export var BFormRadio =
/*#__PURE__*/
Vue.extend({
name: 'BFormRadio',
mixins: [idMixin, formRadioCheckMixin, // Includes shared render function
formMixin, formSizeMixin, formStateMixin],
inject: {
bvGroup: {
from: 'bvRadioGroup',
default: false
}
},
props: {
checked: {
// v-model
// type: [String, Number, Boolean, Object],
default: null
}
},
computed: {
// Radio Groups can only have a single value, so determining if checked is simple
isChecked: function isChecked() {
return looseEqual(this.value, this.computedLocalChecked);
},
// Flags for form-radio-check mixin
isRadio: function isRadio() {
return true;
},
isCheck: function isCheck() {
return false;
}
},
watch: {
// Radio Groups can only have a single value, so our watchers are simple
computedLocalChecked: function computedLocalChecked(newVal, oldVal) {
this.$emit('input', this.computedLocalChecked);
}
},
methods: {
handleChange: function handleChange(_ref) {
var checked = _ref.target.checked;
var value = this.value;
this.computedLocalChecked = value; // Change is only emitted on user interaction
this.$emit('change', checked ? value : null); // If this is a child of form-radio-group, we emit a change event on it as well
if (this.isGroup) {
this.bvGroup.$emit('change', checked ? value : null);
}
}
}
});
+14
View File
@@ -0,0 +1,14 @@
//
// Form Radio
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormRadioPlugin: BvPlugin
// Component: b-form-radio
export declare class BFormRadio extends BvComponent {}
// Component: b-form-radio-group
export declare class BFormRadioGroup extends BvComponent {}
+14
View File
@@ -0,0 +1,14 @@
import { BFormRadio } from './form-radio';
import { BFormRadioGroup } from './form-radio-group';
import { pluginFactory } from '../../utils/plugins';
var FormRadioPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormRadio: BFormRadio,
BRadio: BFormRadio,
BFormRadioGroup: BFormRadioGroup,
BRadioGroup: BFormRadioGroup
}
});
export { FormRadioPlugin, BFormRadio, BFormRadioGroup };
+135
View File
@@ -0,0 +1,135 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 idMixin from '../../mixins/id';
import formOptionsMixin from '../../mixins/form-options';
import formMixin from '../../mixins/form';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
import formCustomMixin from '../../mixins/form-custom';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import { from as arrayFrom } from '../../utils/array';
import { htmlOrText } from '../../utils/html'; // @vue/component
export var BFormSelect =
/*#__PURE__*/
Vue.extend({
name: 'BFormSelect',
mixins: [idMixin, normalizeSlotMixin, formMixin, formSizeMixin, formStateMixin, formCustomMixin, formOptionsMixin],
model: {
prop: 'value',
event: 'input'
},
props: {
value: {// type: [Object, Array, String, Number, Boolean],
// default: undefined
},
multiple: {
type: Boolean,
default: false
},
selectSize: {
// Browsers default size to 0, which shows 4 rows in most browsers in multiple mode
// Size of 1 can bork out Firefox
type: Number,
default: 0
},
ariaInvalid: {
type: [Boolean, String],
default: false
}
},
data: function data() {
return {
localValue: this.value
};
},
computed: {
computedSelectSize: function computedSelectSize() {
// Custom selects with a size of zero causes the arrows to be hidden,
// so dont render the size attribute in this case
return !this.plain && this.selectSize === 0 ? null : this.selectSize;
},
inputClass: function inputClass() {
return [this.plain ? 'form-control' : 'custom-select', this.size && this.plain ? "form-control-".concat(this.size) : null, this.size && !this.plain ? "custom-select-".concat(this.size) : null, this.stateClass];
},
computedAriaInvalid: function computedAriaInvalid() {
if (this.ariaInvalid === true || this.ariaInvalid === 'true') {
return 'true';
}
return this.stateClass === 'is-invalid' ? 'true' : null;
}
},
watch: {
value: function value(newVal, oldVal) {
this.localValue = newVal;
},
localValue: function localValue(newVal, oldVal) {
this.$emit('input', this.localValue);
}
},
methods: {
focus: function focus() {
this.$refs.input.focus();
},
blur: function blur() {
this.$refs.input.blur();
}
},
render: function render(h) {
var _this = this;
var options = this.formOptions.map(function (option, index) {
return h('option', {
key: "option_".concat(index, "_opt"),
attrs: {
disabled: Boolean(option.disabled)
},
domProps: _objectSpread({}, htmlOrText(option.html, option.text), {
value: option.value
})
});
});
return h('select', {
ref: 'input',
class: this.inputClass,
directives: [{
name: 'model',
rawName: 'v-model',
value: this.localValue,
expression: 'localValue'
}],
attrs: {
id: this.safeId(),
name: this.name,
form: this.form || null,
multiple: this.multiple || null,
size: this.computedSelectSize,
disabled: this.disabled,
required: this.required,
'aria-required': this.required ? 'true' : null,
'aria-invalid': this.computedAriaInvalid
},
on: {
change: function change(evt) {
var target = evt.target;
var selectedVal = arrayFrom(target.options).filter(function (o) {
return o.selected;
}).map(function (o) {
return '_value' in o ? o._value : o.value;
});
_this.localValue = target.multiple ? selectedVal : selectedVal[0];
_this.$nextTick(function () {
_this.$emit('change', _this.localValue);
});
}
}
}, [this.normalizeSlot('first'), options, this.normalizeSlot('default')]);
}
});
+11
View File
@@ -0,0 +1,11 @@
//
// Form Select
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormSelectPlugin: BvPlugin
// Component: b-form-select
export declare class BFormSelect extends BvComponent {}
+11
View File
@@ -0,0 +1,11 @@
import { BFormSelect } from './form-select';
import { pluginFactory } from '../../utils/plugins';
var FormSelectPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormSelect: BFormSelect,
BSelect: BFormSelect
}
});
export { FormSelectPlugin, BFormSelect };
@@ -0,0 +1,211 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { VBVisible } from '../../directives/visible/visible';
import idMixin from '../../mixins/id';
import formMixin from '../../mixins/form';
import formSizeMixin from '../../mixins/form-size';
import formStateMixin from '../../mixins/form-state';
import formTextMixin from '../../mixins/form-text';
import formSelectionMixin from '../../mixins/form-selection';
import formValidityMixin from '../../mixins/form-validity';
import listenOnRootMixin from '../../mixins/listen-on-root';
import { getCS, isVisible, requestAF } from '../../utils/dom';
import { isNull } from '../../utils/inspect'; // @vue/component
export var BFormTextarea =
/*#__PURE__*/
Vue.extend({
name: 'BFormTextarea',
directives: {
'b-visible': VBVisible
},
mixins: [idMixin, listenOnRootMixin, formMixin, formSizeMixin, formStateMixin, formTextMixin, formSelectionMixin, formValidityMixin],
props: {
rows: {
type: [Number, String],
default: 2
},
maxRows: {
type: [Number, String],
default: null
},
wrap: {
// 'soft', 'hard' or 'off'. Browser default is 'soft'
type: String,
default: 'soft'
},
noResize: {
// Disable the resize handle of textarea
type: Boolean,
default: false
},
noAutoShrink: {
// When in auto resize mode, disable shrinking to content height
type: Boolean,
default: false
}
},
data: function data() {
return {
heightInPx: null
};
},
computed: {
computedStyle: function computedStyle() {
var styles = {
// Setting `noResize` to true will disable the ability for the user to
// manually resize the textarea. We also disable when in auto height mode
resize: !this.computedRows || this.noResize ? 'none' : null
};
if (!this.computedRows) {
// Conditionally set the computed CSS height when auto rows/height is enabled
// We avoid setting the style to `null`, which can override user manual resize handle
styles.height = this.heightInPx; // We always add a vertical scrollbar to the textarea when auto-height is
// enabled so that the computed height calculation returns a stable value
styles.overflowY = 'scroll';
}
return styles;
},
computedMinRows: function computedMinRows() {
// Ensure rows is at least 2 and positive (2 is the native textarea value)
// A value of 1 can cause issues in some browsers, and most browsers
// only support 2 as the smallest value
return Math.max(parseInt(this.rows, 10) || 2, 2);
},
computedMaxRows: function computedMaxRows() {
return Math.max(this.computedMinRows, parseInt(this.maxRows, 10) || 0);
},
computedRows: function computedRows() {
// This is used to set the attribute 'rows' on the textarea
// If auto-height is enabled, then we return `null` as we use CSS to control height
return this.computedMinRows === this.computedMaxRows ? this.computedMinRows : null;
}
},
watch: {
localValue: function localValue(newVal, oldVal) {
this.setHeight();
}
},
mounted: function mounted() {
this.setHeight();
},
methods: {
// Called by intersection observer directive
visibleCallback: function visibleCallback(visible)
/* istanbul ignore next */
{
if (visible) {
// We use a `$nextTick()` here just to make sure any
// transitions or portalling have completed
this.$nextTick(this.setHeight);
}
},
setHeight: function setHeight() {
var _this = this;
this.$nextTick(function () {
requestAF(function () {
_this.heightInPx = _this.computeHeight();
});
});
},
computeHeight: function computeHeight()
/* istanbul ignore next: can't test getComputedStyle in JSDOM */
{
if (this.$isServer || !isNull(this.computedRows)) {
return null;
}
var el = this.$el; // Element must be visible (not hidden) and in document
// Must be checked after above checks
if (!isVisible(el)) {
return null;
} // Get current computed styles
var computedStyle = getCS(el); // Height of one line of text in px
var lineHeight = parseFloat(computedStyle.lineHeight); // Calculate height of border and padding
var border = (parseFloat(computedStyle.borderTopWidth) || 0) + (parseFloat(computedStyle.borderBottomWidth) || 0);
var padding = (parseFloat(computedStyle.paddingTop) || 0) + (parseFloat(computedStyle.paddingBottom) || 0); // Calculate offset
var offset = border + padding; // Minimum height for min rows (which must be 2 rows or greater for cross-browser support)
var minHeight = lineHeight * this.computedMinRows + offset; // Get the current style height (with `px` units)
var oldHeight = el.style.height || computedStyle.height; // Probe scrollHeight by temporarily changing the height to `auto`
el.style.height = 'auto';
var scrollHeight = el.scrollHeight; // Place the original old height back on the element, just in case `computedProp`
// returns the same value as before
el.style.height = oldHeight; // Calculate content height in 'rows' (scrollHeight includes padding but not border)
var contentRows = Math.max((scrollHeight - padding) / lineHeight, 2); // Calculate number of rows to display (limited within min/max rows)
var rows = Math.min(Math.max(contentRows, this.computedMinRows), this.computedMaxRows); // Calculate the required height of the textarea including border and padding (in pixels)
var height = Math.max(Math.ceil(rows * lineHeight + offset), minHeight); // Computed height remains the larger of `oldHeight` and new `height`,
// when height is in `sticky` mode (prop `no-auto-shrink` is true)
if (this.noAutoShrink && (parseFloat(oldHeight) || 0) > height) {
return oldHeight;
} // Return the new computed CSS height in px units
return "".concat(height, "px");
}
},
render: function render(h) {
// Using self instead of this helps reduce code size during minification
var self = this;
return h('textarea', {
ref: 'input',
class: self.computedClass,
style: self.computedStyle,
directives: [{
name: 'model',
value: self.localValue
}, {
name: 'b-visible',
value: this.visibleCallback,
// If textarea is within 640px of viewport, consider it visible
modifiers: {
'640': true
}
}],
attrs: {
id: self.safeId(),
name: self.name,
form: self.form || null,
disabled: self.disabled,
placeholder: self.placeholder,
required: self.required,
autocomplete: self.autocomplete || null,
readonly: self.readonly || self.plaintext,
rows: self.computedRows,
wrap: self.wrap || null,
'aria-required': self.required ? 'true' : null,
'aria-invalid': self.computedAriaInvalid
},
domProps: {
value: self.localValue
},
on: _objectSpread({}, self.$listeners, {
input: self.onInput,
change: self.onChange,
blur: self.onBlur
})
});
}
});
+13
View File
@@ -0,0 +1,13 @@
//
// Form Textarea
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormTextareaPlugin: BvPlugin
// Component: b-form-textarea
export declare class BFormTextarea extends BvComponent {
focus: () => void
}
+11
View File
@@ -0,0 +1,11 @@
import { BFormTextarea } from './form-textarea';
import { pluginFactory } from '../../utils/plugins';
var FormTextareaPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BFormTextarea: BFormTextarea,
BTextarea: BFormTextarea
}
});
export { FormTextareaPlugin, BFormTextarea };
+42
View File
@@ -0,0 +1,42 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 formOptionsMixin from '../../mixins/form-options';
import normalizeSlotMixin from '../../mixins/normalize-slot';
import { htmlOrText } from '../../utils/html'; // @vue/component
export var BFormDatalist =
/*#__PURE__*/
Vue.extend({
name: 'BFormDatalist',
mixins: [formOptionsMixin, normalizeSlotMixin],
props: {
id: {
type: String,
default: null,
required: true
}
},
render: function render(h) {
var options = this.formOptions.map(function (option, index) {
return h('option', {
key: "option_".concat(index, "_opt"),
attrs: {
disabled: option.disabled
},
domProps: _objectSpread({}, htmlOrText(option.html, option.text), {
value: option.value
})
});
});
return h('datalist', {
attrs: {
id: this.id
}
}, [options, this.normalizeSlot('default')]);
}
});
@@ -0,0 +1,59 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
id: {
type: String,
default: null
},
tag: {
type: String,
default: 'div'
},
tooltip: {
type: Boolean,
default: false
},
forceShow: {
type: Boolean,
default: false
},
state: {
type: Boolean,
default: null
},
ariaLive: {
type: String,
default: null
},
role: {
type: String,
default: null
}
}; // @vue/component
export var BFormInvalidFeedback =
/*#__PURE__*/
Vue.extend({
name: 'BFormInvalidFeedback',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var show = props.forceShow === true || props.state === false;
return h(props.tag, mergeData(data, {
class: {
'invalid-feedback': !props.tooltip,
'invalid-tooltip': props.tooltip,
'd-block': show
},
attrs: {
id: props.id,
role: props.role,
'aria-live': props.ariaLive,
'aria-atomic': props.ariaLive ? 'true' : null
}
}), children);
}
});
+47
View File
@@ -0,0 +1,47 @@
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 { mergeData } from 'vue-functional-data-merge';
import { getComponentConfig } from '../../utils/config';
var NAME = 'BFormText';
export var props = {
id: {
type: String,
default: null
},
tag: {
type: String,
default: 'small'
},
textVariant: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'textVariant');
}
},
inline: {
type: Boolean,
default: false
}
}; // @vue/component
export var BFormText =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.tag, mergeData(data, {
class: _defineProperty({
'form-text': !props.inline
}, "text-".concat(props.textVariant), Boolean(props.textVariant)),
attrs: {
id: props.id
}
}), children);
}
});
+59
View File
@@ -0,0 +1,59 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
id: {
type: String,
default: null
},
tag: {
type: String,
default: 'div'
},
tooltip: {
type: Boolean,
default: false
},
forceShow: {
type: Boolean,
default: false
},
state: {
type: Boolean,
default: null
},
ariaLive: {
type: String,
default: null
},
role: {
type: String,
default: null
}
}; // @vue/component
export var BFormValidFeedback =
/*#__PURE__*/
Vue.extend({
name: 'BFormValidFeedback',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
var show = props.forceShow === true || props.state === true;
return h(props.tag, mergeData(data, {
class: {
'valid-feedback': !props.tooltip,
'valid-tooltip': props.tooltip,
'd-block': show
},
attrs: {
id: props.id,
role: props.role,
'aria-live': props.ariaLive,
'aria-atomic': props.ariaLive ? 'true' : null
}
}), children);
}
});
+43
View File
@@ -0,0 +1,43 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
id: {
type: String,
default: null
},
inline: {
type: Boolean,
default: false
},
novalidate: {
type: Boolean,
default: false
},
validated: {
type: Boolean,
default: false
}
}; // @vue/component
export var BForm =
/*#__PURE__*/
Vue.extend({
name: 'BForm',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h('form', mergeData(data, {
class: {
'form-inline': props.inline,
'was-validated': props.validated
},
attrs: {
id: props.id,
novalidate: props.novalidate
}
}), children);
}
});
+23
View File
@@ -0,0 +1,23 @@
//
// Form
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const FormPlugin: BvPlugin
// Component: b-form
export declare class BForm extends BvComponent {}
// Component: b-form-text
export declare class BFormText extends BvComponent {}
// Component: b-form-invalid-feedback
export declare class BFormInvalidFeedback extends BvComponent {}
// Component: b-form-valid-feedback
export declare class BFormValidFeedback extends BvComponent {}
// Component: b-form-datalist
export declare class BFormDatalist extends BvComponent {}
+24
View File
@@ -0,0 +1,24 @@
import { BForm } from './form';
import { BFormDatalist } from './form-datalist';
import { BFormText } from './form-text';
import { BFormInvalidFeedback } from './form-invalid-feedback';
import { BFormValidFeedback } from './form-valid-feedback';
import { BFormRow } from '../layout/form-row';
import { pluginFactory } from '../../utils/plugins';
var FormPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BForm: BForm,
BFormDatalist: BFormDatalist,
BDatalist: BFormDatalist,
BFormText: BFormText,
BFormInvalidFeedback: BFormInvalidFeedback,
BFormFeedback: BFormInvalidFeedback,
BFormValidFeedback: BFormValidFeedback,
// Added here for convenience
BFormRow: BFormRow
}
}); // BFormRow is not exported here as a named export, as it is exported by Layout
export { FormPlugin, BForm, BFormDatalist, BFormText, BFormInvalidFeedback, BFormValidFeedback };
+211
View File
@@ -0,0 +1,211 @@
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 { concat } from '../../utils/array';
import { getComponentConfig } from '../../utils/config';
import { hasIntersectionObserverSupport } from '../../utils/env';
import { VBVisible } from '../../directives/visible/visible';
import { BImg } from './img';
var NAME = 'BImgLazy';
export var props = {
src: {
type: String,
default: null,
required: true
},
srcset: {
type: [String, Array],
default: null
},
sizes: {
type: [String, Array],
default: null
},
alt: {
type: String,
default: null
},
width: {
type: [Number, String],
default: null
},
height: {
type: [Number, String],
default: null
},
blankSrc: {
// If null, a blank image is generated
type: String,
default: null
},
blankColor: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'blankColor');
}
},
blankWidth: {
type: [Number, String],
default: null
},
blankHeight: {
type: [Number, String],
default: null
},
show: {
type: Boolean,
default: false
},
fluid: {
type: Boolean,
default: false
},
fluidGrow: {
type: Boolean,
default: false
},
block: {
type: Boolean,
default: false
},
thumbnail: {
type: Boolean,
default: false
},
rounded: {
type: [Boolean, String],
default: false
},
left: {
type: Boolean,
default: false
},
right: {
type: Boolean,
default: false
},
center: {
type: Boolean,
default: false
},
offset: {
// Distance away from viewport (in pixels) before being
// considered "visible"
type: [Number, String],
default: 360
}
}; // @vue/component
export var BImgLazy =
/*#__PURE__*/
Vue.extend({
name: NAME,
directives: {
bVisible: VBVisible
},
props: props,
data: function data() {
return {
isShown: this.show
};
},
computed: {
computedSrc: function computedSrc() {
return !this.blankSrc || this.isShown ? this.src : this.blankSrc;
},
computedBlank: function computedBlank() {
return !(this.isShown || this.blankSrc);
},
computedWidth: function computedWidth() {
return this.isShown ? this.width : this.blankWidth || this.width;
},
computedHeight: function computedHeight() {
return this.isShown ? this.height : this.blankHeight || this.height;
},
computedSrcset: function computedSrcset() {
var srcset = concat(this.srcset).filter(Boolean).join(',');
return !this.blankSrc || this.isShown ? srcset : null;
},
computedSizes: function computedSizes() {
var sizes = concat(this.sizes).filter(Boolean).join(',');
return !this.blankSrc || this.isShown ? sizes : null;
}
},
watch: {
show: function show(newVal, oldVal) {
if (newVal !== oldVal) {
// If IntersectionObserver support is not available, image is always shown
var visible = hasIntersectionObserverSupport ? newVal : true;
this.isShown = visible;
if (visible !== newVal) {
// Ensure the show prop is synced (when no IntersectionObserver)
this.$nextTick(this.updateShowProp);
}
}
},
isShown: function isShown(newVal, oldVal) {
if (newVal !== oldVal) {
// Update synched show prop
this.updateShowProp();
}
}
},
mounted: function mounted() {
// If IntersectionObserver is not available, image is always shown
this.isShown = hasIntersectionObserverSupport ? this.show : true;
},
methods: {
updateShowProp: function updateShowProp() {
this.$emit('update:show', this.isShown);
},
doShow: function doShow(visible) {
// If IntersectionObserver is not supported, the callback
// will be called with `null` rather than `true` or `false`
if ((visible || visible === null) && !this.isShown) {
this.isShown = true;
}
}
},
render: function render(h) {
var directives = [];
if (!this.isShown) {
var _modifiers;
// We only add the visible directive if we are not shown
directives.push({
// Visible directive will silently do nothing if
// IntersectionObserver is not supported
name: 'b-visible',
// Value expects a callback (passed one arg of `visible` = `true` or `false`)
value: this.doShow,
modifiers: (_modifiers = {}, _defineProperty(_modifiers, "".concat(parseInt(this.offset, 10) || 0), true), _defineProperty(_modifiers, "once", true), _modifiers)
});
}
return h(BImg, {
directives: directives,
props: {
// Computed value props
src: this.computedSrc,
blank: this.computedBlank,
width: this.computedWidth,
height: this.computedHeight,
srcset: this.computedSrcset || null,
sizes: this.computedSizes || null,
// Passthrough props
alt: this.alt,
blankColor: this.blankColor,
fluid: this.fluid,
fluidGrow: this.fluidGrow,
block: this.block,
thumbnail: this.thumbnail,
rounded: this.rounded,
left: this.left,
right: this.right,
center: this.center
}
});
}
});
+161
View File
@@ -0,0 +1,161 @@
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 { mergeData } from 'vue-functional-data-merge';
import { concat } from '../../utils/array';
import { getComponentConfig } from '../../utils/config';
import { isString } from '../../utils/inspect'; // --- Constants --
var NAME = 'BImg'; // Blank image with fill template
var BLANK_TEMPLATE = '<svg width="%{w}" height="%{h}" ' + 'xmlns="http://www.w3.org/2000/svg" ' + 'viewBox="0 0 %{w} %{h}" preserveAspectRatio="none">' + '<rect width="100%" height="100%" style="fill:%{f};"></rect>' + '</svg>';
export var props = {
src: {
type: String,
default: null
},
srcset: {
type: [String, Array],
default: null
},
sizes: {
type: [String, Array],
default: null
},
alt: {
type: String,
default: null
},
width: {
type: [Number, String],
default: null
},
height: {
type: [Number, String],
default: null
},
block: {
type: Boolean,
default: false
},
fluid: {
type: Boolean,
default: false
},
fluidGrow: {
// Gives fluid images class `w-100` to make them grow to fit container
type: Boolean,
default: false
},
rounded: {
// rounded can be:
// false: no rounding of corners
// true: slightly rounded corners
// 'top': top corners rounded
// 'right': right corners rounded
// 'bottom': bottom corners rounded
// 'left': left corners rounded
// 'circle': circle/oval
// '0': force rounding off
type: [Boolean, String],
default: false
},
thumbnail: {
type: Boolean,
default: false
},
left: {
type: Boolean,
default: false
},
right: {
type: Boolean,
default: false
},
center: {
type: Boolean,
default: false
},
blank: {
type: Boolean,
default: false
},
blankColor: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'blankColor');
}
}
}; // --- Helper methods ---
var makeBlankImgSrc = function makeBlankImgSrc(width, height, color) {
var src = encodeURIComponent(BLANK_TEMPLATE.replace('%{w}', String(width)).replace('%{h}', String(height)).replace('%{f}', color));
return "data:image/svg+xml;charset=UTF-8,".concat(src);
}; // @vue/component
export var BImg =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var _class;
var props = _ref.props,
data = _ref.data;
var src = props.src;
var width = parseInt(props.width, 10) ? parseInt(props.width, 10) : null;
var height = parseInt(props.height, 10) ? parseInt(props.height, 10) : null;
var align = null;
var block = props.block;
var srcset = concat(props.srcset).filter(Boolean).join(',');
var sizes = concat(props.sizes).filter(Boolean).join(',');
if (props.blank) {
if (!height && Boolean(width)) {
height = width;
} else if (!width && Boolean(height)) {
width = height;
}
if (!width && !height) {
width = 1;
height = 1;
} // Make a blank SVG image
src = makeBlankImgSrc(width, height, props.blankColor || 'transparent'); // Disable srcset and sizes
srcset = null;
sizes = null;
}
if (props.left) {
align = 'float-left';
} else if (props.right) {
align = 'float-right';
} else if (props.center) {
align = 'mx-auto';
block = true;
}
return h('img', mergeData(data, {
attrs: {
src: src,
alt: props.alt,
width: width ? String(width) : null,
height: height ? String(height) : null,
srcset: srcset || null,
sizes: sizes || null
},
class: (_class = {
'img-thumbnail': props.thumbnail,
'img-fluid': props.fluid || props.fluidGrow,
'w-100': props.fluidGrow,
rounded: props.rounded === '' || props.rounded === true
}, _defineProperty(_class, "rounded-".concat(props.rounded), isString(props.rounded) && props.rounded !== ''), _defineProperty(_class, align, Boolean(align)), _defineProperty(_class, 'd-block', block), _class)
}));
}
});
+14
View File
@@ -0,0 +1,14 @@
//
// Image
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const ImagePlugin: BvPlugin
// Component: b-img
export declare class BImg extends BvComponent {}
// Component: b-img-lazy
export declare class BImgLazy extends BvComponent {}
+12
View File
@@ -0,0 +1,12 @@
import { BImg } from './img';
import { BImgLazy } from './img-lazy';
import { pluginFactory } from '../../utils/plugins';
var ImagePlugin =
/*#__PURE__*/
pluginFactory({
components: {
BImg: BImg,
BImgLazy: BImgLazy
}
});
export { ImagePlugin, BImg, BImgLazy };
+44
View File
@@ -0,0 +1,44 @@
import { BvPlugin } from '../'
// Plugin that installs all plugins
export declare const componentsPlugin: BvPlugin
// Export all components as named exports
export * from './alert'
export * from './badge'
export * from './breadcrumb'
export * from './button'
export * from './button-group'
export * from './button-toolbar'
export * from './card'
export * from './carousel'
export * from './collapse'
export * from './dropdown'
export * from './embed'
export * from './form'
export * from './form-checkbox'
export * from './form-file'
export * from './form-group'
export * from './form-input'
export * from './form-radio'
export * from './form-select'
export * from './form-textarea'
export * from './image'
export * from './input-group'
export * from './jumbotron'
export * from './layout'
export * from './link'
export * from './list-group'
export * from './media'
export * from './modal'
export * from './nav'
export * from './navbar'
export * from './pagination'
export * from './pagination-nav'
export * from './popover'
export * from './progress'
export * from './spinner'
export * from './table'
export * from './tabs'
export * from './toast'
export * from './tooltip'
+86
View File
@@ -0,0 +1,86 @@
import { pluginFactory } from '../utils/plugins'; // Component group plugins
import { AlertPlugin } from './alert';
import { BadgePlugin } from './badge';
import { BreadcrumbPlugin } from './breadcrumb';
import { ButtonPlugin } from './button';
import { ButtonGroupPlugin } from './button-group';
import { ButtonToolbarPlugin } from './button-toolbar';
import { CardPlugin } from './card';
import { CarouselPlugin } from './carousel';
import { CollapsePlugin } from './collapse';
import { DropdownPlugin } from './dropdown';
import { EmbedPlugin } from './embed';
import { FormPlugin } from './form';
import { FormGroupPlugin } from './form-group';
import { FormCheckboxPlugin } from './form-checkbox';
import { FormRadioPlugin } from './form-radio';
import { FormInputPlugin } from './form-input';
import { FormTextareaPlugin } from './form-textarea';
import { FormFilePlugin } from './form-file';
import { FormSelectPlugin } from './form-select';
import { ImagePlugin } from './image';
import { InputGroupPlugin } from './input-group';
import { JumbotronPlugin } from './jumbotron';
import { LayoutPlugin } from './layout';
import { LinkPlugin } from './link';
import { ListGroupPlugin } from './list-group';
import { MediaPlugin } from './media';
import { ModalPlugin } from './modal';
import { NavPlugin } from './nav';
import { NavbarPlugin } from './navbar';
import { PaginationPlugin } from './pagination';
import { PaginationNavPlugin } from './pagination-nav';
import { PopoverPlugin } from './popover';
import { ProgressPlugin } from './progress';
import { SpinnerPlugin } from './spinner'; // Table plugin includes TableLitePlugin and TableSimplePlugin
import { TablePlugin } from './table';
import { TabsPlugin } from './tabs';
import { ToastPlugin } from './toast';
import { TooltipPlugin } from './tooltip'; // Main plugin to install all component group plugins
export var componentsPlugin =
/*#__PURE__*/
pluginFactory({
plugins: {
AlertPlugin: AlertPlugin,
BadgePlugin: BadgePlugin,
BreadcrumbPlugin: BreadcrumbPlugin,
ButtonPlugin: ButtonPlugin,
ButtonGroupPlugin: ButtonGroupPlugin,
ButtonToolbarPlugin: ButtonToolbarPlugin,
CardPlugin: CardPlugin,
CarouselPlugin: CarouselPlugin,
CollapsePlugin: CollapsePlugin,
DropdownPlugin: DropdownPlugin,
EmbedPlugin: EmbedPlugin,
FormPlugin: FormPlugin,
FormGroupPlugin: FormGroupPlugin,
FormCheckboxPlugin: FormCheckboxPlugin,
FormRadioPlugin: FormRadioPlugin,
FormInputPlugin: FormInputPlugin,
FormTextareaPlugin: FormTextareaPlugin,
FormFilePlugin: FormFilePlugin,
FormSelectPlugin: FormSelectPlugin,
ImagePlugin: ImagePlugin,
InputGroupPlugin: InputGroupPlugin,
JumbotronPlugin: JumbotronPlugin,
LayoutPlugin: LayoutPlugin,
LinkPlugin: LinkPlugin,
ListGroupPlugin: ListGroupPlugin,
MediaPlugin: MediaPlugin,
ModalPlugin: ModalPlugin,
NavPlugin: NavPlugin,
NavbarPlugin: NavbarPlugin,
PaginationPlugin: PaginationPlugin,
PaginationNavPlugin: PaginationNavPlugin,
PopoverPlugin: PopoverPlugin,
ProgressPlugin: ProgressPlugin,
SpinnerPlugin: SpinnerPlugin,
TablePlugin: TablePlugin,
TabsPlugin: TabsPlugin,
ToastPlugin: ToastPlugin,
TooltipPlugin: TooltipPlugin
}
});
+23
View File
@@ -0,0 +1,23 @@
//
// InputGroup
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const InputGroupPlugin: BvPlugin
// Component: b-input-group
export declare class BInputGroup extends BvComponent {}
// Component: b-input-group-append
export declare class BInputGroupAppend extends BvComponent {}
// Component: b-input-group-prepend
export declare class BInputGroupPrepend extends BvComponent {}
// Component: b-input-group-text
export declare class BInputGroupText extends BvComponent {}
// Component: b-input-group-addon
export declare class BInputGroupAddon extends BvComponent {}
+18
View File
@@ -0,0 +1,18 @@
import { BInputGroup } from './input-group';
import { BInputGroupAddon } from './input-group-addon';
import { BInputGroupPrepend } from './input-group-prepend';
import { BInputGroupAppend } from './input-group-append';
import { BInputGroupText } from './input-group-text';
import { pluginFactory } from '../../utils/plugins';
var InputGroupPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BInputGroup: BInputGroup,
BInputGroupAddon: BInputGroupAddon,
BInputGroupPrepend: BInputGroupPrepend,
BInputGroupAppend: BInputGroupAppend,
BInputGroupText: BInputGroupText
}
});
export { InputGroupPlugin, BInputGroup, BInputGroupAddon, BInputGroupPrepend, BInputGroupAppend, BInputGroupText };
@@ -0,0 +1,50 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import { BInputGroupText } from './input-group-text';
export var commonProps = {
id: {
type: String,
default: null
},
tag: {
type: String,
default: 'div'
},
isText: {
type: Boolean,
default: false
}
}; // @vue/component
export var BInputGroupAddon =
/*#__PURE__*/
Vue.extend({
name: 'BInputGroupAddon',
functional: true,
props: _objectSpread({}, commonProps, {
append: {
type: Boolean,
default: false
}
}),
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.tag, mergeData(data, {
class: {
'input-group-append': props.append,
'input-group-prepend': !props.append
},
attrs: {
id: props.id
}
}), props.isText ? [h(BInputGroupText, children)] : children);
}
});
@@ -0,0 +1,28 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import { BInputGroupAddon, commonProps } from './input-group-addon'; // @vue/component
export var BInputGroupAppend =
/*#__PURE__*/
Vue.extend({
name: 'BInputGroupAppend',
functional: true,
props: commonProps,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
// pass all our props/attrs down to child, and set`append` to true
return h(BInputGroupAddon, mergeData(data, {
props: _objectSpread({}, props, {
append: true
})
}), children);
}
});
@@ -0,0 +1,28 @@
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(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(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 { mergeData } from 'vue-functional-data-merge';
import { BInputGroupAddon, commonProps } from './input-group-addon'; // @vue/component
export var BInputGroupPrepend =
/*#__PURE__*/
Vue.extend({
name: 'BInputGroupPrepend',
functional: true,
props: commonProps,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
// pass all our props/attrs down to child, and set`append` to false
return h(BInputGroupAddon, mergeData(data, {
props: _objectSpread({}, props, {
append: false
})
}), children);
}
});
@@ -0,0 +1,24 @@
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
export var props = {
tag: {
type: String,
default: 'div'
}
}; // @vue/component
export var BInputGroupText =
/*#__PURE__*/
Vue.extend({
name: 'BInputGroupText',
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
children = _ref.children;
return h(props.tag, mergeData(data, {
staticClass: 'input-group-text'
}), children);
}
});
+100
View File
@@ -0,0 +1,100 @@
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; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
import Vue from '../../utils/vue';
import { mergeData } from 'vue-functional-data-merge';
import { getComponentConfig } from '../../utils/config';
import { htmlOrText } from '../../utils/html';
import { hasNormalizedSlot, normalizeSlot } from '../../utils/normalize-slot';
import { BInputGroupPrepend } from './input-group-prepend';
import { BInputGroupAppend } from './input-group-append';
import { BInputGroupText } from './input-group-text';
var NAME = 'BInputGroup';
export var props = {
id: {
type: String
},
size: {
type: String,
default: function _default() {
return getComponentConfig(NAME, 'size');
}
},
prepend: {
type: String
},
prependHtml: {
type: String
},
append: {
type: String
},
appendHtml: {
type: String
},
tag: {
type: String,
default: 'div'
}
}; // @vue/component
export var BInputGroup =
/*#__PURE__*/
Vue.extend({
name: NAME,
functional: true,
props: props,
render: function render(h, _ref) {
var props = _ref.props,
data = _ref.data,
slots = _ref.slots,
scopedSlots = _ref.scopedSlots;
var $slots = slots();
var $scopedSlots = scopedSlots || {};
var childNodes = []; // Prepend prop/slot
if (props.prepend || props.prependHtml || hasNormalizedSlot('prepend', $scopedSlots, $slots)) {
childNodes.push(h(BInputGroupPrepend, [// Prop
props.prepend || props.prependHtml ? h(BInputGroupText, {
domProps: htmlOrText(props.prependHtml, props.prepend)
}) : h(), // Slot
normalizeSlot('prepend', {}, $scopedSlots, $slots) || h()]));
} else {
childNodes.push(h());
} // Default slot
if (hasNormalizedSlot('default', $scopedSlots, $slots)) {
childNodes.push.apply(childNodes, _toConsumableArray(normalizeSlot('default', {}, $scopedSlots, $slots)));
} else {
childNodes.push(h());
} // Append prop
if (props.append || props.appendHtml || hasNormalizedSlot('append', $scopedSlots, $slots)) {
childNodes.push(h(BInputGroupAppend, [// prop
props.append || props.appendHtml ? h(BInputGroupText, {
domProps: htmlOrText(props.appendHtml, props.append)
}) : h(), // Slot
normalizeSlot('append', {}, $scopedSlots, $slots) || h()]));
} else {
childNodes.push(h());
}
return h(props.tag, mergeData(data, {
staticClass: 'input-group',
class: _defineProperty({}, "input-group-".concat(props.size), Boolean(props.size)),
attrs: {
id: props.id || null,
role: 'group'
}
}), childNodes);
}
});
+11
View File
@@ -0,0 +1,11 @@
//
// Jumbotron
//
import Vue from 'vue'
import { BvPlugin, BvComponent } from '../../'
// Plugin
export declare const JumbotronPlugin: BvPlugin
// Component: b-jumbotron
export declare class BJumbotron extends BvComponent {}
+10
View File
@@ -0,0 +1,10 @@
import { BJumbotron } from './jumbotron';
import { pluginFactory } from '../../utils/plugins';
var JumbotronPlugin =
/*#__PURE__*/
pluginFactory({
components: {
BJumbotron: BJumbotron
}
});
export { JumbotronPlugin, BJumbotron };

Some files were not shown because too many files have changed in this diff Show More