vue-radio-toggle-buttons
Version:
Radio toggle buttons for Vue.
675 lines (641 loc) • 24.2 kB
JavaScript
;
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var Color = _interopDefault(require('color'));
var tslib = require('tslib');
var Vue = _interopDefault(require('vue'));
var COLOR = '#333';
var TEXT_COLOR = '#333';
var SELECTED_TEXT_COLOR = '#eee';
function isColor(color) {
if (typeof color !== 'string' || color.length === 0) {
return false;
}
try {
Color(color);
return true;
}
catch (_) {
return false;
}
}
var options = {
color: COLOR,
textColor: TEXT_COLOR,
selectedTextColor: SELECTED_TEXT_COLOR
};
/**
* vue-class-component v7.1.0
* (c) 2015-present Evan You
* @license MIT
*/
// The rational behind the verbose Reflect-feature check below is the fact that there are polyfills
// which add an implementation for Reflect.defineMetadata but not for Reflect.getOwnMetadataKeys.
// Without this check consumers will encounter hard to track down runtime errors.
var reflectionIsSupported = typeof Reflect !== 'undefined' && Reflect.defineMetadata && Reflect.getOwnMetadataKeys;
function copyReflectionMetadata(to, from) {
forwardMetadata(to, from);
Object.getOwnPropertyNames(from.prototype).forEach(function (key) {
forwardMetadata(to.prototype, from.prototype, key);
});
Object.getOwnPropertyNames(from).forEach(function (key) {
forwardMetadata(to, from, key);
});
}
function forwardMetadata(to, from, propertyKey) {
var metaKeys = propertyKey
? Reflect.getOwnMetadataKeys(from, propertyKey)
: Reflect.getOwnMetadataKeys(from);
metaKeys.forEach(function (metaKey) {
var metadata = propertyKey
? Reflect.getOwnMetadata(metaKey, from, propertyKey)
: Reflect.getOwnMetadata(metaKey, from);
if (propertyKey) {
Reflect.defineMetadata(metaKey, metadata, to, propertyKey);
}
else {
Reflect.defineMetadata(metaKey, metadata, to);
}
});
}
var fakeArray = { __proto__: [] };
var hasProto = fakeArray instanceof Array;
function createDecorator(factory) {
return function (target, key, index) {
var Ctor = typeof target === 'function'
? target
: target.constructor;
if (!Ctor.__decorators__) {
Ctor.__decorators__ = [];
}
if (typeof index !== 'number') {
index = undefined;
}
Ctor.__decorators__.push(function (options) { return factory(options, key, index); });
};
}
function isPrimitive(value) {
var type = typeof value;
return value == null || (type !== 'object' && type !== 'function');
}
function collectDataFromConstructor(vm, Component) {
// override _init to prevent to init as Vue instance
var originalInit = Component.prototype._init;
Component.prototype._init = function () {
var _this = this;
// proxy to actual vm
var keys = Object.getOwnPropertyNames(vm);
// 2.2.0 compat (props are no longer exposed as self properties)
if (vm.$options.props) {
for (var key in vm.$options.props) {
if (!vm.hasOwnProperty(key)) {
keys.push(key);
}
}
}
keys.forEach(function (key) {
if (key.charAt(0) !== '_') {
Object.defineProperty(_this, key, {
get: function () { return vm[key]; },
set: function (value) { vm[key] = value; },
configurable: true
});
}
});
};
// should be acquired class property values
var data = new Component();
// restore original _init to avoid memory leak (#209)
Component.prototype._init = originalInit;
// create plain data object
var plainData = {};
Object.keys(data).forEach(function (key) {
if (data[key] !== undefined) {
plainData[key] = data[key];
}
});
return plainData;
}
var $internalHooks = [
'data',
'beforeCreate',
'created',
'beforeMount',
'mounted',
'beforeDestroy',
'destroyed',
'beforeUpdate',
'updated',
'activated',
'deactivated',
'render',
'errorCaptured',
'serverPrefetch' // 2.6
];
function componentFactory(Component, options) {
if (options === void 0) { options = {}; }
options.name = options.name || Component._componentTag || Component.name;
// prototype props.
var proto = Component.prototype;
Object.getOwnPropertyNames(proto).forEach(function (key) {
if (key === 'constructor') {
return;
}
// hooks
if ($internalHooks.indexOf(key) > -1) {
options[key] = proto[key];
return;
}
var descriptor = Object.getOwnPropertyDescriptor(proto, key);
if (descriptor.value !== void 0) {
// methods
if (typeof descriptor.value === 'function') {
(options.methods || (options.methods = {}))[key] = descriptor.value;
}
else {
// typescript decorated data
(options.mixins || (options.mixins = [])).push({
data: function () {
var _a;
return _a = {}, _a[key] = descriptor.value, _a;
}
});
}
}
else if (descriptor.get || descriptor.set) {
// computed properties
(options.computed || (options.computed = {}))[key] = {
get: descriptor.get,
set: descriptor.set
};
}
});
(options.mixins || (options.mixins = [])).push({
data: function () {
return collectDataFromConstructor(this, Component);
}
});
// decorate options
var decorators = Component.__decorators__;
if (decorators) {
decorators.forEach(function (fn) { return fn(options); });
delete Component.__decorators__;
}
// find super
var superProto = Object.getPrototypeOf(Component.prototype);
var Super = superProto instanceof Vue
? superProto.constructor
: Vue;
var Extended = Super.extend(options);
forwardStaticMembers(Extended, Component, Super);
if (reflectionIsSupported) {
copyReflectionMetadata(Extended, Component);
}
return Extended;
}
var shouldIgnore = {
prototype: true,
arguments: true,
callee: true,
caller: true
};
function forwardStaticMembers(Extended, Original, Super) {
// We have to use getOwnPropertyNames since Babel registers methods as non-enumerable
Object.getOwnPropertyNames(Original).forEach(function (key) {
// Skip the properties that should not be overwritten
if (shouldIgnore[key]) {
return;
}
// Some browsers does not allow reconfigure built-in properties
var extendedDescriptor = Object.getOwnPropertyDescriptor(Extended, key);
if (extendedDescriptor && !extendedDescriptor.configurable) {
return;
}
var descriptor = Object.getOwnPropertyDescriptor(Original, key);
// If the user agent does not support `__proto__` or its family (IE <= 10),
// the sub class properties may be inherited properties from the super class in TypeScript.
// We need to exclude such properties to prevent to overwrite
// the component options object which stored on the extended constructor (See #192).
// If the value is a referenced value (object or function),
// we can check equality of them and exclude it if they have the same reference.
// If it is a primitive value, it will be forwarded for safety.
if (!hasProto) {
// Only `cid` is explicitly exluded from property forwarding
// because we cannot detect whether it is a inherited property or not
// on the no `__proto__` environment even though the property is reserved.
if (key === 'cid') {
return;
}
var superDescriptor = Object.getOwnPropertyDescriptor(Super, key);
if (!isPrimitive(descriptor.value) &&
superDescriptor &&
superDescriptor.value === descriptor.value) {
return;
}
}
Object.defineProperty(Extended, key, descriptor);
});
}
function Component(options) {
if (typeof options === 'function') {
return componentFactory(options);
}
return function (Component) {
return componentFactory(Component, options);
};
}
Component.registerHooks = function registerHooks(keys) {
$internalHooks.push.apply($internalHooks, keys);
};
/** vue-property-decorator verson 8.2.2 MIT LICENSE copyright 2019 kaorun343 */
/** @see {@link https://github.com/vuejs/vue-class-component/blob/master/src/reflect.ts} */
var reflectMetadataIsSupported = typeof Reflect !== 'undefined' && typeof Reflect.getMetadata !== 'undefined';
function applyMetadata(options, target, key) {
if (reflectMetadataIsSupported) {
if (!Array.isArray(options) &&
typeof options !== 'function' &&
typeof options.type === 'undefined') {
options.type = Reflect.getMetadata('design:type', target, key);
}
}
}
/**
* decorator of model
* @param event event name
* @param options options
* @return PropertyDecorator
*/
function Model(event, options) {
if (options === void 0) { options = {}; }
return function (target, key) {
applyMetadata(options, target, key);
createDecorator(function (componentOptions, k) {
(componentOptions.props || (componentOptions.props = {}))[k] = options;
componentOptions.model = { prop: k, event: event || k };
})(target, key);
};
}
/**
* decorator of a prop
* @param options the options for the prop
* @return PropertyDecorator | void
*/
function Prop(options) {
if (options === void 0) { options = {}; }
return function (target, key) {
applyMetadata(options, target, key);
createDecorator(function (componentOptions, k) {
(componentOptions.props || (componentOptions.props = {}))[k] = options;
})(target, key);
};
}
/**
* decorator of a watch function
* @param path the path or the expression to observe
* @param WatchOption
* @return MethodDecorator
*/
function Watch(path, options) {
if (options === void 0) { options = {}; }
var _a = options.deep, deep = _a === void 0 ? false : _a, _b = options.immediate, immediate = _b === void 0 ? false : _b;
return createDecorator(function (componentOptions, handler) {
if (typeof componentOptions.watch !== 'object') {
componentOptions.watch = Object.create(null);
}
var watch = componentOptions.watch;
if (typeof watch[path] === 'object' && !Array.isArray(watch[path])) {
watch[path] = [watch[path]];
}
else if (typeof watch[path] === 'undefined') {
watch[path] = [];
}
watch[path].push({ handler: handler, deep: deep, immediate: immediate });
});
}
var RadioToggle = /** @class */ (function (_super) {
tslib.__extends(RadioToggle, _super);
function RadioToggle() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.currentValue = _this.mValue; // Represent current value of all radio buttons in group
_this.isHovered = false;
return _this;
}
RadioToggle.prototype.onClick = function (e) {
if (this.disabled) {
e.preventDefault();
}
};
RadioToggle.prototype.onMouseOver = function () {
this.isHovered = true;
};
RadioToggle.prototype.onMouseOut = function () {
this.isHovered = false;
};
Object.defineProperty(RadioToggle.prototype, "computedValue", {
// For internal radio's v-model
get: function () {
return this.currentValue;
},
set: function (newValue) {
this.currentValue = newValue;
this.$emit('input', newValue);
},
enumerable: true,
configurable: true
});
Object.defineProperty(RadioToggle.prototype, "isSelected", {
get: function () {
return this.currentValue === this.value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(RadioToggle.prototype, "classes", {
get: function () {
return {
'is-selected': this.isSelected,
'is-hovered': this.isHovered
};
},
enumerable: true,
configurable: true
});
Object.defineProperty(RadioToggle.prototype, "style", {
get: function () {
var _a = this, color = _a.color, textColor = _a.textColor, selectedTextColor = _a.selectedTextColor, disabled = _a.disabled, isHovered = _a.isHovered, isSelected = _a.isSelected;
var mainColor = Color(color);
var hoverColor = mainColor.isDark()
? mainColor.lighten(0.5).string()
: mainColor.darken(0.3).string();
var styles = {
color: textColor
};
if (!disabled && isHovered) {
styles.color = color;
styles.borderColor = color;
}
if (!disabled && isSelected) {
styles.color = selectedTextColor;
if (isHovered) {
styles.backgroundColor = hoverColor;
styles.borderColor = hoverColor;
}
else {
styles.backgroundColor = color;
styles.borderColor = color;
}
}
if (disabled) {
var disabledColor = '#bababa';
styles.color = disabledColor;
styles.cursor = 'no-drop';
}
return styles;
},
enumerable: true,
configurable: true
});
// Catch this component's v-model change
RadioToggle.prototype.onMValueChange = function (newValuue) {
this.currentValue = newValuue;
};
tslib.__decorate([
Model()
], RadioToggle.prototype, "mValue", void 0);
tslib.__decorate([
Prop(String)
], RadioToggle.prototype, "value", void 0);
tslib.__decorate([
Prop({ type: String, default: COLOR })
], RadioToggle.prototype, "color", void 0);
tslib.__decorate([
Prop({ type: String, default: TEXT_COLOR })
], RadioToggle.prototype, "textColor", void 0);
tslib.__decorate([
Prop({ type: String, default: SELECTED_TEXT_COLOR })
], RadioToggle.prototype, "selectedTextColor", void 0);
tslib.__decorate([
Prop({ type: Boolean, default: false })
], RadioToggle.prototype, "disabled", void 0);
tslib.__decorate([
Watch('mValue')
], RadioToggle.prototype, "onMValueChange", null);
RadioToggle = tslib.__decorate([
Component({
name: 'RadioToggle'
})
], RadioToggle);
return RadioToggle;
}(Vue));
function normalizeComponent(template, style, script, scopeId, isFunctionalTemplate, moduleIdentifier /* server only */, shadowMode, createInjector, createInjectorSSR, createInjectorShadow) {
if (typeof shadowMode !== 'boolean') {
createInjectorSSR = createInjector;
createInjector = shadowMode;
shadowMode = false;
}
// Vue.extend constructor export interop.
const options = typeof script === 'function' ? script.options : script;
// render functions
if (template && template.render) {
options.render = template.render;
options.staticRenderFns = template.staticRenderFns;
options._compiled = true;
// functional template
if (isFunctionalTemplate) {
options.functional = true;
}
}
// scopedId
if (scopeId) {
options._scopeId = scopeId;
}
let hook;
if (moduleIdentifier) {
// server build
hook = function (context) {
// 2.3 injection
context =
context || // cached call
(this.$vnode && this.$vnode.ssrContext) || // stateful
(this.parent && this.parent.$vnode && this.parent.$vnode.ssrContext); // functional
// 2.2 with runInNewContext: true
if (!context && typeof __VUE_SSR_CONTEXT__ !== 'undefined') {
context = __VUE_SSR_CONTEXT__;
}
// inject component styles
if (style) {
style.call(this, createInjectorSSR(context));
}
// register component module identifier for async chunk inference
if (context && context._registeredComponents) {
context._registeredComponents.add(moduleIdentifier);
}
};
// used by ssr in case component is cached and beforeCreate
// never gets called
options._ssrRegister = hook;
}
else if (style) {
hook = shadowMode
? function (context) {
style.call(this, createInjectorShadow(context, this.$root.$options.shadowRoot));
}
: function (context) {
style.call(this, createInjector(context));
};
}
if (hook) {
if (options.functional) {
// register for functional component in vue file
const originalRender = options.render;
options.render = function renderWithStyleInjection(h, context) {
hook.call(context);
return originalRender(h, context);
};
}
else {
// inject component registration as beforeCreate hook
const existing = options.beforeCreate;
options.beforeCreate = existing ? [].concat(existing, hook) : [hook];
}
}
return script;
}
/* script */
const __vue_script__ = RadioToggle;
/* template */
var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:"radio-toggle-button",class:_vm.classes,style:(_vm.style),on:{"click":_vm.onClick,"mouseover":_vm.onMouseOver,"mouseout":_vm.onMouseOut}},[_c('input',{directives:[{name:"model",rawName:"v-model",value:(_vm.computedValue),expression:"computedValue"}],attrs:{"type":"radio"},domProps:{"value":_vm.value,"checked":_vm._q(_vm.computedValue,_vm.value)},on:{"change":function($event){_vm.computedValue=_vm.value;}}}),_vm._t("default")],2)};
var __vue_staticRenderFns__ = [];
/* style */
const __vue_inject_styles__ = undefined;
/* scoped */
const __vue_scope_id__ = undefined;
/* module identifier */
const __vue_module_identifier__ = undefined;
/* functional template */
const __vue_is_functional_template__ = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__ = normalizeComponent(
{ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ },
__vue_inject_styles__,
__vue_script__,
__vue_scope_id__,
__vue_is_functional_template__,
__vue_module_identifier__,
false,
undefined,
undefined,
undefined
);
var RadioToggleButtons = /** @class */ (function (_super) {
tslib.__extends(RadioToggleButtons, _super);
function RadioToggleButtons() {
return _super !== null && _super.apply(this, arguments) || this;
}
Object.defineProperty(RadioToggleButtons.prototype, "actualColor", {
get: function () {
if (this.color) {
return this.color;
}
return options.color;
},
enumerable: true,
configurable: true
});
Object.defineProperty(RadioToggleButtons.prototype, "actualTextColor", {
get: function () {
if (this.textColor) {
return this.textColor;
}
return options.textColor;
},
enumerable: true,
configurable: true
});
Object.defineProperty(RadioToggleButtons.prototype, "actualSelectedTextColor", {
get: function () {
if (this.selectedTextColor) {
return this.selectedTextColor;
}
return options.selectedTextColor;
},
enumerable: true,
configurable: true
});
RadioToggleButtons.prototype.onInput = function (newValue) {
this.$emit('change', newValue);
};
tslib.__decorate([
Model('change')
], RadioToggleButtons.prototype, "mValue", void 0);
tslib.__decorate([
Prop({ type: Array, required: true })
], RadioToggleButtons.prototype, "values", void 0);
tslib.__decorate([
Prop({ type: String, validator: isColor })
], RadioToggleButtons.prototype, "color", void 0);
tslib.__decorate([
Prop({ type: String, validator: isColor })
], RadioToggleButtons.prototype, "textColor", void 0);
tslib.__decorate([
Prop({ type: String, validator: isColor })
], RadioToggleButtons.prototype, "selectedTextColor", void 0);
RadioToggleButtons = tslib.__decorate([
Component({
name: 'RadioToggleButtons',
components: {
RadioToggle: __vue_component__
}
})
], RadioToggleButtons);
return RadioToggleButtons;
}(Vue));
/* script */
const __vue_script__$1 = RadioToggleButtons;
/* template */
var __vue_render__$1 = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',_vm._l((_vm.values),function(value){return _c('RadioToggle',{key:value.value,attrs:{"mValue":_vm.mValue,"value":value.value,"color":_vm.actualColor,"textColor":_vm.actualTextColor,"selectedTextColor":_vm.actualSelectedTextColor,"disabled":value.disabled},on:{"input":_vm.onInput}},[_vm._v(_vm._s(value.label))])}),1)};
var __vue_staticRenderFns__$1 = [];
/* style */
const __vue_inject_styles__$1 = undefined;
/* scoped */
const __vue_scope_id__$1 = undefined;
/* module identifier */
const __vue_module_identifier__$1 = undefined;
/* functional template */
const __vue_is_functional_template__$1 = false;
/* style inject */
/* style inject SSR */
/* style inject shadow dom */
const __vue_component__$1 = normalizeComponent(
{ render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 },
__vue_inject_styles__$1,
__vue_script__$1,
__vue_scope_id__$1,
__vue_is_functional_template__$1,
__vue_module_identifier__$1,
false,
undefined,
undefined,
undefined
);
var VueRadioToggleButtons = {
install: function (Vue, options$1) {
var _a, _b, _c, _d;
options.color = isColor((_a = options$1) === null || _a === void 0 ? void 0 : _a.color) ? options$1.color : COLOR;
options.textColor = isColor((_b = options$1) === null || _b === void 0 ? void 0 : _b.textColor)
? options$1.textColor
: TEXT_COLOR;
options.selectedTextColor = isColor((_c = options$1) === null || _c === void 0 ? void 0 : _c.selectedTextColor)
? (_d = options$1) === null || _d === void 0 ? void 0 : _d.selectedTextColor : SELECTED_TEXT_COLOR;
Vue.component('RadioToggleButtons', __vue_component__$1);
}
};
if (typeof window !== 'undefined' && window.Vue) {
VueRadioToggleButtons.install(window.Vue);
}
VueRadioToggleButtons.components = {
RadioToggleButtons: __vue_component__$1
};
module.exports = VueRadioToggleButtons;
//# sourceMappingURL=vue-radio-toggle-buttons.cjs.js.map