bootstrap-vue
Version:
BootstrapVue, with over 40 plugins and more than 75 custom components, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-ARIA accessibility markup.
219 lines (178 loc) • 7.32 kB
JavaScript
;
exports.__esModule = true;
exports.default = exports.BButton = exports.props = void 0;
var _vue = _interopRequireDefault(require("../../utils/vue"));
var _vueFunctionalDataMerge = require("vue-functional-data-merge");
var _pluckProps = _interopRequireDefault(require("../../utils/pluck-props"));
var _array = require("../../utils/array");
var _config = require("../../utils/config");
var _dom = require("../../utils/dom");
var _inspect = require("../../utils/inspect");
var _object = require("../../utils/object");
var _link = require("../link/link");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, 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; }
// --- Constants --
var NAME = 'BButton';
var btnProps = {
block: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
size: {
type: String,
default: null
},
variant: {
type: String,
default: function _default() {
return (0, _config.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 = (0, _link.propsFactory)();
delete linkProps.href.default;
delete linkProps.to.default;
var linkPropKeys = (0, _object.keys)(linkProps);
var props = _objectSpread({}, linkProps, btnProps); // --- Helper methods ---
// Focus handler for toggle buttons. Needs class of 'focus' when focused.
exports.props = props;
var handleFocus = function handleFocus(evt) {
if (evt.type === 'focusin') {
(0, _dom.addClass)(evt.target, 'focus');
} else if (evt.type === 'focusout') {
(0, _dom.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 (0, _inspect.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 || (0, _config.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) ? (0, _pluckProps.default)(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
var BButton =
/*#__PURE__*/
_vue.default.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(e) {
/* istanbul ignore if: blink/button disabled should handle this */
if (props.disabled && e instanceof Event) {
e.stopPropagation();
e.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.
(0, _array.concat)(listeners['update:pressed']).forEach(function (fn) {
if ((0, _inspect.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 ? _link.BLink : props.tag, (0, _vueFunctionalDataMerge.mergeData)(data, componentData), children);
}
});
exports.BButton = BButton;
var _default2 = BButton;
exports.default = _default2;