build version 400

This commit is contained in:
Mohit Panjwani
2020-12-02 17:54:08 +05:30
parent 326508e567
commit 89ee58590c
963 changed files with 62887 additions and 48868 deletions

View File

@ -1,14 +1,14 @@
function isEmpty (opt) {
function isEmpty(opt) {
if (opt === 0) return false
if (Array.isArray(opt) && opt.length === 0) return true
return !opt
}
function not (fun) {
function not(fun) {
return (...params) => !fun(...params)
}
function includes (str, query) {
function includes(str, query) {
/* istanbul ignore else */
if (str === undefined) str = 'undefined'
if (str === null) str = 'null'
@ -17,22 +17,24 @@ function includes (str, query) {
return text.indexOf(query.trim()) !== -1
}
function filterOptions (options, search, label, customLabel) {
return options.filter(option => includes(customLabel(option, label), search))
function filterOptions(options, search, label, customLabel) {
return options.filter((option) =>
includes(customLabel(option, label), search)
)
}
function stripGroups (options) {
return options.filter(option => !option.$isLabel)
function stripGroups(options) {
return options.filter((option) => !option.$isLabel)
}
function flattenOptions (values, label) {
function flattenOptions(values, label) {
return (options) =>
options.reduce((prev, curr) => {
/* istanbul ignore else */
if (curr[values] && curr[values].length) {
prev.push({
$groupLabel: curr[label],
$isLabel: true
$isLabel: true,
})
return prev.concat(curr[values])
}
@ -40,40 +42,47 @@ function flattenOptions (values, label) {
}, [])
}
function filterGroups (search, label, values, groupLabel, customLabel) {
function filterGroups(search, label, values, groupLabel, customLabel) {
return (groups) =>
groups.map(group => {
groups.map((group) => {
/* istanbul ignore else */
if (!group[values]) {
console.warn(`Options passed to vue-multiselect do not contain groups, despite the config.`)
console.warn(
`Options passed to vue-multiselect do not contain groups, despite the config.`
)
return []
}
const groupOptions = filterOptions(group[values], search, label, customLabel)
const groupOptions = filterOptions(
group[values],
search,
label,
customLabel
)
return groupOptions.length
? {
[groupLabel]: group[groupLabel],
[values]: groupOptions
}
[groupLabel]: group[groupLabel],
[values]: groupOptions,
}
: []
})
}
const flow = (...fns) => x => fns.reduce((v, f) => f(v), x)
const flow = (...fns) => (x) => fns.reduce((v, f) => f(v), x)
export default {
data () {
data() {
return {
search: '',
isOpen: false,
preferredOpenDirection: 'below',
optimizedHeight: this.maxHeight
optimizedHeight: this.maxHeight,
}
},
props: {
initialSearch: {
type: String,
default: ''
default: '',
},
/**
* Decide whether to filter the results based on search query.
@ -82,7 +91,7 @@ export default {
*/
internalSearch: {
type: Boolean,
default: true
default: true,
},
/**
* Array of available options: Objects, Strings or Integers.
@ -92,7 +101,7 @@ export default {
*/
options: {
type: Array,
required: true
required: true,
},
/**
* Equivalent to the `multiple` attribute on a `<select>` input.
@ -101,7 +110,7 @@ export default {
*/
multiple: {
type: Boolean,
default: false
default: false,
},
/**
* Presets the selected options value.
@ -109,9 +118,9 @@ export default {
*/
value: {
type: null,
default () {
default() {
return []
}
},
},
/**
* Key to compare objects
@ -119,7 +128,7 @@ export default {
* @type {String}
*/
trackBy: {
type: String
type: String,
},
/**
* Label to look for in option Object
@ -127,7 +136,7 @@ export default {
* @type {String}
*/
label: {
type: String
type: String,
},
/**
* Enable/disable search in options
@ -136,7 +145,7 @@ export default {
*/
searchable: {
type: Boolean,
default: true
default: true,
},
/**
* Clear the search input after `)
@ -145,7 +154,7 @@ export default {
*/
clearOnSelect: {
type: Boolean,
default: true
default: true,
},
/**
* Hide already selected options
@ -154,7 +163,7 @@ export default {
*/
hideSelected: {
type: Boolean,
default: false
default: false,
},
/**
* Equivalent to the `placeholder` attribute on a `<select>` input.
@ -163,7 +172,7 @@ export default {
*/
placeholder: {
type: String,
default: 'Select option'
default: 'Select option',
},
/**
* Allow to remove all selected values
@ -172,7 +181,7 @@ export default {
*/
allowEmpty: {
type: Boolean,
default: true
default: true,
},
/**
* Reset this.internalValue, this.search after this.internalValue changes.
@ -182,7 +191,7 @@ export default {
*/
resetAfter: {
type: Boolean,
default: false
default: false,
},
/**
* Enable/disable closing after selecting an option
@ -191,7 +200,7 @@ export default {
*/
closeOnSelect: {
type: Boolean,
default: true
default: true,
},
/**
* Function to interpolate the custom label
@ -200,10 +209,10 @@ export default {
*/
customLabel: {
type: Function,
default (option, label) {
default(option, label) {
if (isEmpty(option)) return ''
return label ? option[label] : option
}
},
},
/**
* Disable / Enable tagging
@ -212,16 +221,16 @@ export default {
*/
taggable: {
type: Boolean,
default: false
default: false,
},
/**
* String to show when highlighting a potential tag
* @default 'Press enter to create a tag'
* @type {String}
*/
*/
tagPlaceholder: {
type: String,
default: 'Press enter to create a tag'
default: 'Press enter to create a tag',
},
/**
* By default new tags will appear above the search results.
@ -229,56 +238,56 @@ export default {
* and will proritize the search results
* @default 'top'
* @type {String}
*/
*/
tagPosition: {
type: String,
default: 'top'
default: 'top',
},
/**
* Number of allowed selected options. No limit if 0.
* @default 0
* @type {Number}
*/
*/
max: {
type: [Number, Boolean],
default: false
default: false,
},
/**
* Will be passed with all events as second param.
* Useful for identifying events origin.
* @default null
* @type {String|Integer}
*/
*/
id: {
default: null
default: null,
},
/**
* Limits the options displayed in the dropdown
* to the first X options.
* @default 1000
* @type {Integer}
*/
*/
optionsLimit: {
type: Number,
default: 1000
default: 1000,
},
/**
* Name of the property containing
* the group values
* @default 1000
* @type {String}
*/
*/
groupValues: {
type: String
type: String,
},
/**
* Name of the property containing
* the group label
* @default 1000
* @type {String}
*/
*/
groupLabel: {
type: String
type: String,
},
/**
* Allow to select all group values
@ -288,43 +297,45 @@ export default {
*/
groupSelect: {
type: Boolean,
default: false
default: false,
},
/**
* Array of keyboard keys to block
* when selecting
* @default 1000
* @type {String}
*/
*/
blockKeys: {
type: Array,
default () {
default() {
return []
}
},
},
/**
* Prevent from wiping up the search value
* @default false
* @type {Boolean}
*/
*/
preserveSearch: {
type: Boolean,
default: false
default: false,
},
/**
* Select 1st options if value is empty
* @default false
* @type {Boolean}
*/
*/
preselectFirst: {
type: Boolean,
default: false
}
default: false,
},
},
mounted () {
mounted() {
/* istanbul ignore else */
if (!this.multiple && this.max) {
console.warn('[Vue-Multiselect warn]: Max prop should not be used when prop Multiple equals false.')
console.warn(
'[Vue-Multiselect warn]: Max prop should not be used when prop Multiple equals false.'
)
}
if (
this.preselectFirst &&
@ -339,12 +350,14 @@ export default {
}
},
computed: {
internalValue () {
internalValue() {
return this.value || this.value === 0
? Array.isArray(this.value) ? this.value : [this.value]
? Array.isArray(this.value)
? this.value
: [this.value]
: []
},
filteredOptions () {
filteredOptions() {
const search = this.search || ''
const normalizedSearch = search.toLowerCase().trim()
@ -354,9 +367,16 @@ export default {
if (this.internalSearch) {
options = this.groupValues
? this.filterAndFlat(options, normalizedSearch, this.label)
: filterOptions(options, normalizedSearch, this.label, this.customLabel)
: filterOptions(
options,
normalizedSearch,
this.label,
this.customLabel
)
} else {
options = this.groupValues ? flattenOptions(this.groupValues, this.groupLabel)(options) : options
options = this.groupValues
? flattenOptions(this.groupValues, this.groupLabel)(options)
: options
}
options = this.hideSelected
@ -364,7 +384,11 @@ export default {
: options
/* istanbul ignore else */
if (this.taggable && normalizedSearch.length && !this.isExistingOption(normalizedSearch)) {
if (
this.taggable &&
normalizedSearch.length &&
!this.isExistingOption(normalizedSearch)
) {
if (this.tagPosition === 'bottom') {
options.push({ isTag: true, label: search })
} else {
@ -374,57 +398,71 @@ export default {
return options.slice(0, this.optionsLimit)
},
valueKeys () {
valueKeys() {
if (this.trackBy) {
return this.internalValue.map(element => element[this.trackBy])
return this.internalValue.map((element) => element[this.trackBy])
} else {
return this.internalValue
}
},
optionKeys () {
const options = this.groupValues ? this.flatAndStrip(this.options) : this.options
return options.map(element => this.customLabel(element, this.label).toString().toLowerCase())
optionKeys() {
const options = this.groupValues
? this.flatAndStrip(this.options)
: this.options
return options.map((element) =>
this.customLabel(element, this.label).toString().toLowerCase()
)
},
currentOptionLabel () {
currentOptionLabel() {
return this.multiple
? this.searchable ? '' : this.placeholder
? this.searchable
? ''
: this.placeholder
: this.internalValue.length
? this.getOptionLabel(this.internalValue[0])
: this.searchable ? '' : this.placeholder
}
? this.getOptionLabel(this.internalValue[0])
: this.searchable
? ''
: this.placeholder
},
},
watch: {
internalValue () {
internalValue() {
/* istanbul ignore else */
if (this.resetAfter && this.internalValue.length) {
this.search = ''
this.$emit('input', this.multiple ? [] : null)
}
},
search () {
search() {
this.$emit('search-change', this.search, this.id)
}
},
},
methods: {
/**
* Returns the internalValue in a way it can be emited to the parent
* @returns {Object||Array||String||Integer}
*/
getValue () {
getValue() {
return this.multiple
? this.internalValue
: this.internalValue.length === 0
? null
: this.internalValue[0]
? null
: this.internalValue[0]
},
/**
* Filters and then flattens the options list
* @param {Array}
* @returns {Array} returns a filtered and flat options list
*/
filterAndFlat (options, search, label) {
filterAndFlat(options, search, label) {
return flow(
filterGroups(search, label, this.groupValues, this.groupLabel, this.customLabel),
filterGroups(
search,
label,
this.groupValues,
this.groupLabel,
this.customLabel
),
flattenOptions(this.groupValues, this.groupLabel)
)(options)
},
@ -433,7 +471,7 @@ export default {
* @param {Array}
* @returns {Array} returns a flat options list without group labels
*/
flatAndStrip (options) {
flatAndStrip(options) {
return flow(
flattenOptions(this.groupValues, this.groupLabel),
stripGroups
@ -443,7 +481,7 @@ export default {
* Updates the search value
* @param {String}
*/
updateSearch (query) {
updateSearch(query) {
this.search = query
this.$emit('value', this.search)
},
@ -453,10 +491,8 @@ export default {
* @param {String}
* @returns {Boolean} returns true if element is available
*/
isExistingOption (query) {
return !this.options
? false
: this.optionKeys.indexOf(query) > -1
isExistingOption(query) {
return !this.options ? false : this.optionKeys.indexOf(query) > -1
},
/**
* Finds out if the given element is already present
@ -464,10 +500,8 @@ export default {
* @param {Object||String||Integer} option passed element to check
* @returns {Boolean} returns true if element is selected
*/
isSelected (option) {
const opt = this.trackBy
? option[this.trackBy]
: option
isSelected(option) {
const opt = this.trackBy ? option[this.trackBy] : option
return this.valueKeys.indexOf(opt) > -1
},
/**
@ -475,7 +509,7 @@ export default {
* @param {Object||String||Integer} option passed element to check
* @returns {Boolean} returns true if element is disabled
*/
isOptionDisabled (option) {
isOptionDisabled(option) {
return !!option.$isDisabled
},
/**
@ -486,7 +520,7 @@ export default {
* @param {Object||String||Integer} Passed option
* @returns {Object||String}
*/
getOptionLabel (option) {
getOptionLabel(option) {
if (isEmpty(option)) return ''
/* istanbul ignore else */
if (option.isTag) return option.label
@ -506,19 +540,22 @@ export default {
* @param {Object||String||Integer} option to select/deselect
* @param {Boolean} block removing
*/
select (option, key) {
select(option, key) {
/* istanbul ignore else */
if (option.$isLabel && this.groupSelect) {
this.selectGroup(option)
return
}
if (this.blockKeys.indexOf(key) !== -1 ||
if (
this.blockKeys.indexOf(key) !== -1 ||
this.disabled ||
option.$isDisabled ||
option.$isLabel
) return
)
return
/* istanbul ignore else */
if (this.max && this.multiple && this.internalValue.length === this.max) return
if (this.max && this.multiple && this.internalValue.length === this.max)
return
/* istanbul ignore else */
if (key === 'Tab' && !this.pointerDirty) return
if (option.isTag) {
@ -553,8 +590,8 @@ export default {
*
* @param {Object||String||Integer} group to select/deselect
*/
selectGroup (selectedGroup) {
const group = this.options.find(option => {
selectGroup(selectedGroup) {
const group = this.options.find((option) => {
return option[this.groupLabel] === selectedGroup.$groupLabel
})
@ -564,21 +601,18 @@ export default {
this.$emit('remove', group[this.groupValues], this.id)
const newValue = this.internalValue.filter(
option => group[this.groupValues].indexOf(option) === -1
(option) => group[this.groupValues].indexOf(option) === -1
)
this.$emit('input', newValue, this.id)
} else {
const optionsToAdd = group[this.groupValues].filter(
option => !(this.isOptionDisabled(option) || this.isSelected(option))
(option) =>
!(this.isOptionDisabled(option) || this.isSelected(option))
)
this.$emit('select', optionsToAdd, this.id)
this.$emit(
'input',
this.internalValue.concat(optionsToAdd),
this.id
)
this.$emit('input', this.internalValue.concat(optionsToAdd), this.id)
}
},
/**
@ -586,8 +620,9 @@ export default {
*
* @param {Object} group to validated selected values against
*/
wholeGroupSelected (group) {
return group[this.groupValues].every(option => this.isSelected(option) || this.isOptionDisabled(option)
wholeGroupSelected(group) {
return group[this.groupValues].every(
(option) => this.isSelected(option) || this.isOptionDisabled(option)
)
},
/**
@ -595,7 +630,7 @@ export default {
*
* @param {Object} group to check for disabled values
*/
wholeGroupDisabled (group) {
wholeGroupDisabled(group) {
return group[this.groupValues].every(this.isOptionDisabled)
},
/**
@ -606,7 +641,7 @@ export default {
* @param {type} option description
* @returns {type} description
*/
removeElement (option, shouldClose = true) {
removeElement(option, shouldClose = true) {
/* istanbul ignore else */
if (this.disabled) return
/* istanbul ignore else */
@ -617,13 +652,16 @@ export default {
return
}
const index = typeof option === 'object'
? this.valueKeys.indexOf(option[this.trackBy])
: this.valueKeys.indexOf(option)
const index =
typeof option === 'object'
? this.valueKeys.indexOf(option[this.trackBy])
: this.valueKeys.indexOf(option)
this.$emit('remove', option, this.id)
if (this.multiple) {
const newValue = this.internalValue.slice(0, index).concat(this.internalValue.slice(index + 1))
const newValue = this.internalValue
.slice(0, index)
.concat(this.internalValue.slice(index + 1))
this.$emit('input', newValue, this.id)
} else {
this.$emit('input', null, this.id)
@ -638,25 +676,36 @@ export default {
*
* @fires this#removeElement
*/
removeLastElement () {
removeLastElement() {
/* istanbul ignore else */
if (this.blockKeys.indexOf('Delete') !== -1) return
/* istanbul ignore else */
if (this.search.length === 0 && Array.isArray(this.internalValue) && this.internalValue.length) {
this.removeElement(this.internalValue[this.internalValue.length - 1], false)
if (
this.search.length === 0 &&
Array.isArray(this.internalValue) &&
this.internalValue.length
) {
this.removeElement(
this.internalValue[this.internalValue.length - 1],
false
)
}
},
/**
* Opens the multiselects dropdown.
* Sets this.isOpen to TRUE
*/
activate () {
activate() {
/* istanbul ignore else */
if (this.isOpen || this.disabled) return
this.adjustPosition()
/* istanbul ignore else */
if (this.groupValues && this.pointer === 0 && this.filteredOptions.length) {
if (
this.groupValues &&
this.pointer === 0 &&
this.filteredOptions.length
) {
this.pointer = 1
}
@ -674,7 +723,7 @@ export default {
* Closes the multiselects dropdown.
* Sets this.isOpen to FALSE
*/
deactivate () {
deactivate() {
/* istanbul ignore else */
if (!this.isOpen) return
this.isOpen = false
@ -694,29 +743,33 @@ export default {
* @fires this#activate || this#deactivate
* @property {Boolean} isOpen indicates if dropdown is open
*/
toggle () {
this.isOpen
? this.deactivate()
: this.activate()
toggle() {
this.isOpen ? this.deactivate() : this.activate()
},
/**
* Updates the hasEnoughSpace variable used for
* detecting where to expand the dropdown
*/
adjustPosition () {
adjustPosition() {
if (typeof window === 'undefined') return
const spaceAbove = this.$el.getBoundingClientRect().top
const spaceBelow = window.innerHeight - this.$el.getBoundingClientRect().bottom
const spaceBelow =
window.innerHeight - this.$el.getBoundingClientRect().bottom
const hasEnoughSpaceBelow = spaceBelow > this.maxHeight
if (hasEnoughSpaceBelow || spaceBelow > spaceAbove || this.openDirection === 'below' || this.openDirection === 'bottom') {
if (
hasEnoughSpaceBelow ||
spaceBelow > spaceAbove ||
this.openDirection === 'below' ||
this.openDirection === 'bottom'
) {
this.preferredOpenDirection = 'below'
this.optimizedHeight = Math.min(spaceBelow - 40, this.maxHeight)
} else {
this.preferredOpenDirection = 'above'
this.optimizedHeight = Math.min(spaceAbove - 40, this.maxHeight)
}
}
}
},
},
}