bootstrap-vue
Version:
BootstrapVue, with over 40 plugins and more than 80 custom components, custom directives, and over 300 icons, provides one of the most comprehensive implementations of Bootstrap v4 components and grid system for Vue.js. With extensive and automated WAI-AR
137 lines (133 loc) • 4.29 kB
JavaScript
import Vue from '../../utils/vue';
import { from as arrayFrom, isArray } from '../../utils/array';
import { htmlOrText } from '../../utils/html';
import idMixin from '../../mixins/id';
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 optionsMixin from './helpers/mixin-options';
import { BFormSelectOption } from './form-select-option';
import { BFormSelectOptionGroup } from './form-select-option-group'; // @vue/component
export var BFormSelect =
/*#__PURE__*/
Vue.extend({
name: 'BFormSelect',
mixins: [idMixin, normalizeSlotMixin, formMixin, formSizeMixin, formStateMixin, formCustomMixin, optionsMixin],
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;
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'), this.formOptions.map(function (option, index) {
var key = "option_".concat(index, "_opt");
var options = option.options;
return isArray(options) ? h(BFormSelectOptionGroup, {
props: {
label: option.label,
options: options
},
key: key
}) : h(BFormSelectOption, {
props: {
value: option.value,
disabled: option.disabled
},
domProps: htmlOrText(option.html, option.text),
key: key
});
}), this.normalizeSlot('default')]);
}
});