mirror of
https://gitee.com/element-plus/element-plus.git
synced 2024-12-04 20:27:44 +08:00
fix(select): should not stop at invisible options by up and down (#2585)
* fix(select): should not stop at invisible options by up and down this also fix another problem (#2562): about unselect user-created tag in ElSelect fix #2563 #2562 * fix(select): checkDefaultFirstOption: exlucde disabled options fix #2562 #2563 * test(select): add test for "default-first-option" (with navigation) check default first option re #2585
This commit is contained in:
parent
5b16f20725
commit
d6fecf9b32
@ -20,6 +20,7 @@ interface SelectProps {
|
||||
automaticDropdown?: boolean
|
||||
multipleLimit?: number
|
||||
popperClass?: string
|
||||
defaultFirstOption?: boolean
|
||||
}
|
||||
|
||||
const _mount = (template: string, data: any = () => ({}), otherObj?) => mount({
|
||||
@ -42,7 +43,7 @@ function getOptions(): HTMLElement[] {
|
||||
}
|
||||
|
||||
const getSelectVm = (configs: SelectProps = {}, options?) => {
|
||||
['multiple', 'clearable', 'filterable', 'allowCreate', 'remote', 'collapseTags', 'automaticDropdown'].forEach(config => {
|
||||
['multiple', 'clearable', 'defaultFirstOption', 'filterable', 'allowCreate', 'remote', 'collapseTags', 'automaticDropdown'].forEach(config => {
|
||||
configs[config] = configs[config] || false
|
||||
})
|
||||
configs.multipleLimit = configs.multipleLimit || 0
|
||||
@ -78,6 +79,7 @@ const getSelectVm = (configs: SelectProps = {}, options?) => {
|
||||
:multiple-limit="multipleLimit"
|
||||
:popper-class="popperClass"
|
||||
:clearable="clearable"
|
||||
:default-first-option="defaultFirstOption"
|
||||
:filterable="filterable"
|
||||
:collapse-tags="collapseTags"
|
||||
:allow-create="allowCreate"
|
||||
@ -99,6 +101,7 @@ const getSelectVm = (configs: SelectProps = {}, options?) => {
|
||||
multiple: configs.multiple,
|
||||
multipleLimit: configs.multipleLimit,
|
||||
clearable: configs.clearable,
|
||||
defaultFirstOption: configs.defaultFirstOption,
|
||||
filterable: configs.filterable,
|
||||
collapseTags: configs.collapseTags,
|
||||
allowCreate: configs.allowCreate,
|
||||
@ -449,6 +452,51 @@ describe('Select', () => {
|
||||
expect(vm.value).toBe('')
|
||||
})
|
||||
|
||||
test('check default first option', async () => {
|
||||
const wrapper = getSelectVm({
|
||||
filterable: true,
|
||||
defaultFirstOption: true,
|
||||
})
|
||||
const select = wrapper.findComponent({ name: 'ElSelect' })
|
||||
const selectVm = select.vm as any
|
||||
const input = wrapper.find('input')
|
||||
input.element.focus()
|
||||
|
||||
expect(selectVm.hoverIndex).toBe(0)
|
||||
selectVm.navigateOptions('next')
|
||||
expect(selectVm.hoverIndex).toBe(1)
|
||||
})
|
||||
|
||||
test('check default first option when the very first option is disabled', async () => {
|
||||
const demoOptions = [{
|
||||
value: 'HTML',
|
||||
label: 'HTML',
|
||||
disabled: true,
|
||||
}, {
|
||||
value: 'CSS',
|
||||
label: 'CSS',
|
||||
disabled: false,
|
||||
}, {
|
||||
value: 'JavaScript',
|
||||
label: 'JavaScript',
|
||||
disabled: false,
|
||||
}]
|
||||
const wrapper = getSelectVm({
|
||||
filterable: true,
|
||||
defaultFirstOption: true,
|
||||
}, demoOptions)
|
||||
const select = wrapper.findComponent({ name: 'ElSelect' })
|
||||
const selectVm = select.vm as any
|
||||
const input = wrapper.find('input')
|
||||
input.element.focus()
|
||||
|
||||
expect(selectVm.hoverIndex).toBe(1) // index 0 was skipped
|
||||
selectVm.navigateOptions('next')
|
||||
expect(selectVm.hoverIndex).toBe(2)
|
||||
selectVm.navigateOptions('next')
|
||||
expect(selectVm.hoverIndex).toBe(1) // index 0 was skipped
|
||||
})
|
||||
|
||||
test('allow create', async () => {
|
||||
const wrapper = getSelectVm({ filterable: true, allowCreate: true })
|
||||
const select = wrapper.findComponent({ name: 'ElSelect' })
|
||||
|
@ -81,12 +81,18 @@ export function useOption(props, states) {
|
||||
}
|
||||
|
||||
const queryChange = (query: string) => {
|
||||
// not in filtering, just show original options only
|
||||
if (!query) {
|
||||
states.visible = !props.created
|
||||
} else {
|
||||
// in filtering, do filter by RegExp
|
||||
const regexp = new RegExp(escapeRegexpString(query), 'i')
|
||||
states.visible = regexp.test(currentLabel.value) || props.created
|
||||
if (!states.visible) {
|
||||
states.visible = regexp.test(currentLabel.value)
|
||||
if (!states.visible && !props.created) {
|
||||
select.filteredOptionsCount--
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
watch(() => currentLabel.value, () => {
|
||||
if (!props.created && !select.props.remote) select.setSelected()
|
||||
|
@ -318,34 +318,21 @@ export const useSelect = (props, states: States, ctx) => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* find and highlight first option as default selected
|
||||
* @remark
|
||||
* - if the first option in dropdown list is user-created,
|
||||
* it would be at the end of the optionsArray
|
||||
* so find it and set hover.
|
||||
* (NOTE: there must be only one user-created option in dropdown list with query)
|
||||
* - if there's no user-created option in list, just find the first one as usual
|
||||
* (NOTE: exclude options that are disabled or in disabled-group)
|
||||
*/
|
||||
const checkDefaultFirstOption = () => {
|
||||
states.hoverIndex = -1
|
||||
// highlight the created option
|
||||
let hasCreated = false
|
||||
for (let i = states.options.size - 1; i >= 0; i--) {
|
||||
if (optionsArray.value[i].created) {
|
||||
hasCreated = true
|
||||
states.hoverIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if (hasCreated) return
|
||||
for (let i = 0; i !== states.options.size; ++i) {
|
||||
const option = optionsArray.value[i]
|
||||
if (states.query) {
|
||||
// highlight first options that passes the filter
|
||||
if (!option.disabled && !option.groupDisabled && option.visible) {
|
||||
states.hoverIndex = i
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// highlight currently selected option
|
||||
if (option.itemSelected) {
|
||||
states.hoverIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
const optionsInDropdown = optionsArray.value.filter(n => n.visible && !n.disabled && !n.groupDisabled)
|
||||
const userCreatedOption = optionsInDropdown.filter(n => n.created)[0]
|
||||
const firstOriginOption = optionsInDropdown[0]
|
||||
states.hoverIndex = getValueIndex(optionsArray.value, userCreatedOption || firstOriginOption)
|
||||
}
|
||||
|
||||
const setSelected = () => {
|
||||
|
Loading…
Reference in New Issue
Block a user