Skip to content

Commit

Permalink
fix(components): [select] optimize the triggering of blur event (#11524)
Browse files Browse the repository at this point in the history
* fix(components): [select] drop-down selection is not closed when blur

closed #10893, #10992

* fix(components): [select] optimize the triggering of blur event

* refactor(components): [select] optimize code
  • Loading branch information
tolking committed May 28, 2023
1 parent 6222629 commit a99dbb3
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 22 deletions.
3 changes: 3 additions & 0 deletions packages/components/select/__tests__/select.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { ArrowDown, CaretTop, CircleClose } from '@element-plus/icons-vue'
import { usePopperContainerId } from '@element-plus/hooks'
import { hasClass } from '@element-plus/utils'
import { ElFormItem } from '@element-plus/components/form'
import sleep from '@element-plus/test-utils/sleep'
import Select from '../src/select.vue'
import Group from '../src/option-group.vue'
import Option from '../src/option.vue'
Expand Down Expand Up @@ -1223,6 +1224,7 @@ describe('Select', () => {
await input.trigger('focus')
expect(handleFocus).toHaveBeenCalled()
await input.trigger('blur')
await sleep(0)
expect(handleBlur).toHaveBeenCalled()
})

Expand All @@ -1249,6 +1251,7 @@ describe('Select', () => {
await input.trigger('focus')
expect(handleFocus).toHaveBeenCalled()
await input.trigger('blur')
await sleep(0)
expect(handleBlur).toHaveBeenCalled()
})

Expand Down
2 changes: 1 addition & 1 deletion packages/components/select/src/option.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export default defineComponent({
function selectOptionClick() {
if (props.disabled !== true && states.groupDisabled !== true) {
select.handleOptionSelect(vm, true)
select.handleOptionSelect(vm)
}
}
Expand Down
4 changes: 0 additions & 4 deletions packages/components/select/src/select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -522,15 +522,13 @@ export default defineComponent({
inputLength,
filteredOptionsCount,
visible,
softFocus,
selectedLabel,
hoverIndex,
query,
inputHovering,
currentPlaceholder,
menuVisibleOnFocus,
isOnComposition,
isSilentBlur,
options,
cachedOptions,
optionsCount,
Expand Down Expand Up @@ -650,15 +648,13 @@ export default defineComponent({
inputLength,
filteredOptionsCount,
visible,
softFocus,
selectedLabel,
hoverIndex,
query,
inputHovering,
currentPlaceholder,
menuVisibleOnFocus,
isOnComposition,
isSilentBlur,
options,
resetInputHeight,
managePlaceholder,
Expand Down
2 changes: 1 addition & 1 deletion packages/components/select/src/token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export interface SelectContext {
setSelected(): void
onOptionCreate(vm: SelectOptionProxy): void
onOptionDestroy(key: number | string | Record<string, any>): void
handleOptionSelect(vm: unknown, byClick: boolean): void
handleOptionSelect(vm: unknown): void
}

// For individual build sharing injection key, we had to make `Symbol` to string
Expand Down
29 changes: 14 additions & 15 deletions packages/components/select/src/useSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ export function useSelectStates(props) {
optionsCount: 0,
filteredOptionsCount: 0,
visible: false,
softFocus: false,
selectedLabel: '',
hoverIndex: -1,
query: '',
Expand All @@ -56,12 +55,12 @@ export function useSelectStates(props) {
currentPlaceholder: t('el.select.placeholder') as string | (() => string),
menuVisibleOnFocus: false,
isOnComposition: false,
isSilentBlur: false,
prefixWidth: 11,
tagInMultiLine: false,
mouseEnter: false,
})
}
let ignoreFocusEvent = false

type States = ReturnType<typeof useSelectStates>

Expand Down Expand Up @@ -657,7 +656,7 @@ export const useSelect = (props, states: States, ctx) => {
ctx.emit('clear')
}

const handleOptionSelect = (option, byClick) => {
const handleOptionSelect = (option) => {
if (props.multiple) {
const value = (props.modelValue || []).slice()
const optionIndex = getValueIndex(value, option.value)
Expand All @@ -682,7 +681,7 @@ export const useSelect = (props, states: States, ctx) => {
emitChange(option.value)
states.visible = false
}
states.isSilentBlur = byClick

setSoftFocus()
if (states.visible) return
nextTick(() => {
Expand All @@ -706,7 +705,6 @@ export const useSelect = (props, states: States, ctx) => {
}

const setSoftFocus = () => {
states.softFocus = true
const _input = input.value || reference.value
if (_input) {
_input?.focus()
Expand Down Expand Up @@ -788,7 +786,7 @@ export const useSelect = (props, states: States, ctx) => {
}

const handleFocus = (event: FocusEvent) => {
if (!states.softFocus) {
if (!ignoreFocusEvent) {
if (props.automaticDropdown || props.filterable) {
if (props.filterable && !states.visible) {
states.menuVisibleOnFocus = true
Expand All @@ -797,7 +795,7 @@ export const useSelect = (props, states: States, ctx) => {
}
ctx.emit('focus', event)
} else {
states.softFocus = false
ignoreFocusEvent = false
}
}

Expand All @@ -808,15 +806,16 @@ export const useSelect = (props, states: States, ctx) => {
}

const handleBlur = (event: FocusEvent) => {
// https://github.com/ElemeFE/element/pull/10822
nextTick(() => {
if (states.isSilentBlur) {
states.isSilentBlur = false
} else {
ctx.emit('blur', event)
setTimeout(() => {
// validate current focus event is inside el-tooltip-content
// if so, ignore the blur event and the next focus event
if (tooltipRef.value?.isFocusInsideContent()) {
ignoreFocusEvent = true
return
}
states.visible && handleClose()
ctx.emit('blur', event)
})
states.softFocus = false
}

const handleClearClick = (event: Event) => {
Expand Down Expand Up @@ -858,7 +857,7 @@ export const useSelect = (props, states: States, ctx) => {
toggleMenu()
} else {
if (optionsArray.value[states.hoverIndex]) {
handleOptionSelect(optionsArray.value[states.hoverIndex], undefined)
handleOptionSelect(optionsArray.value[states.hoverIndex])
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/components/tree-select/src/tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ export const useTree = (
const option = select.value?.options.get(
getNodeValByProp('value', data)
)
select.value?.handleOptionSelect(option, true)
select.value?.handleOptionSelect(option)
}
} else if (props.expandOnClickNode) {
e.proxy.handleExpandIconClick()
Expand Down

0 comments on commit a99dbb3

Please sign in to comment.