Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(Autocomplete): enhance logic for when to blur #2886

Merged
merged 1 commit into from
Nov 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 76 additions & 64 deletions packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,6 @@ class AutocompleteInstance extends React.PureComponent {
clearTimeout(this._ariaLiveUpdateTimeout)
clearTimeout(this._focusTimeout)
clearTimeout(this._blurTimeout)
clearTimeout(this._toggleVisibleTimeout)
}

setVisible = (args = null, onStateComplete = null) => {
Expand Down Expand Up @@ -564,6 +563,8 @@ class AutocompleteInstance extends React.PureComponent {
const data = this.runFilter(value, options)
const count = this.countData(data)

const { keep_value, keep_value_and_selection } = this.props

if (value && value.length > 0) {
// show the "no_options" message
if (count === 0) {
Expand All @@ -583,15 +584,12 @@ class AutocompleteInstance extends React.PureComponent {
}
}
} else {
if (
!isTrue(this.props.keep_value) &&
!isTrue(this.props.keep_value_and_selection)
) {
if (!isTrue(keep_value) && !isTrue(keep_value_and_selection)) {
// this will not remove selected_item
this.totalReset()
}

if (isTrue(this.props.keep_value)) {
if (isTrue(keep_value)) {
this.resetSelectedItem()
}

Expand Down Expand Up @@ -893,15 +891,38 @@ class AutocompleteInstance extends React.PureComponent {
}
}

onReserveActivityHandler = (event) => {
// Prevent to happen the on_blur event during drawer-list activity
this.__preventFiringBlurEvent =
reserveActivityHandler = (event = null) => {
this.__preventFiringBlurEvent = Boolean(
event.key === 'enter' ||
event.key === 'space' ||
(event.target && getPreviousSibling('dnb-drawer-list', event.target))
(event?.currentTarget
? getPreviousSibling('dnb-drawer-list', event.currentTarget) ||
getPreviousSibling(
'dnb-input__submit-button__button',
event.currentTarget
)
: false)
)

if (this.__preventFiringBlurEvent) {
setTimeout(
() => {
this.__preventFiringBlurEvent = false
},
isTrue(this.props.no_animation) ? 1 : DrawerList.blurDelay
)
}
}

onBlurHandler = (event) => {
if (
this.__preventFiringBlurEvent ||
this.context.drawerList.hasFocusOnElement ||
this.state.hasBlur
) {
this.__preventFiringBlurEvent = null
return false
}

const {
open_on_focus,
keep_value,
Expand All @@ -910,60 +931,54 @@ class AutocompleteInstance extends React.PureComponent {
no_animation,
} = this.props

if (
!this.state.hasBlur &&
!this.__preventFiringBlurEvent &&
!this.context.drawerList.hasFocusOnElement
) {
dispatchCustomElementEvent(this, 'on_blur', {
event,
...this.getEventObjects('on_blur'),
})
dispatchCustomElementEvent(this, 'on_blur', {
event,
...this.getEventObjects('on_blur'),
})

this.setState({
hasBlur: true,
hasFocus: false,
})

if (!isTrue(keep_value) && !isTrue(keep_value_and_selection)) {
this.setState({
hasBlur: true,
hasFocus: false,
typedInputValue: null,
_listenForPropChanges: false,
})
}

if (!isTrue(keep_value_and_selection)) {
this.setState({
typedInputValue: null,
_listenForPropChanges: false,
})
}
if (!isTrue(prevent_selection)) {
const existingValue = this.state.inputValue

if (!isTrue(prevent_selection)) {
const existingValue = this.state.inputValue
if (!isTrue(keep_value) && !isTrue(keep_value_and_selection)) {
this.clearInputValue()
}

const resetAfterClose = () => {
if (
!isTrue(keep_value) ||
!existingValue ||
this.hasSelectedItem()
) {
this.resetActiveItem()
}
this.resetFilter()
}

if (isTrue(no_animation)) {
resetAfterClose()
} else {
clearTimeout(this._blurTimeout)
this._blurTimeout = setTimeout(
resetAfterClose,
DrawerList.blurDelay
) // only to let the animation pass, before we make the effect. Else this would be a visible change
const resetAfterClose = () => {
if (
!isTrue(keep_value) ||
!existingValue ||
this.hasSelectedItem()
) {
this.resetActiveItem()
}
this.resetFilter()
}

if (isTrue(open_on_focus)) {
this.setHidden()
if (isTrue(no_animation)) {
resetAfterClose()
} else {
clearTimeout(this._blurTimeout)
this._blurTimeout = setTimeout(
resetAfterClose,
DrawerList.blurDelay
) // only to let the animation pass, before we make the effect. Else this would be a visible change
}
} else if (this.__preventFiringBlurEvent) {
this.__preventFiringBlurEvent = null
return false
}

if (isTrue(open_on_focus)) {
this.setHidden()
}
}

Expand Down Expand Up @@ -1029,8 +1044,7 @@ class AutocompleteInstance extends React.PureComponent {
(!this.hasValidData() || !this.hasSelectedItem()) &&
!this.hasActiveItem()
) {
clearTimeout(this._toggleVisibleTimeout)
this._toggleVisibleTimeout = setTimeout(this.toggleVisible, 1) // to make sure we first handle the DrawerList key enter, before we update the state with a toggle/visible. Else the submit is not set properly
this.toggleVisible()
} else {
this.setVisible()
}
Expand Down Expand Up @@ -1541,12 +1555,9 @@ class AutocompleteInstance extends React.PureComponent {
} catch (e) {
// do nothing
}
clearTimeout(this._focusTimeout)
this._focusTimeout = setTimeout(() => {
this.setState({
hasFocus: false,
})
}, 1) // we have to wait in order to make sure the focus situation is cleared up
this.setState({
hasFocus: false,
})
}
)
}
Expand Down Expand Up @@ -1895,6 +1906,7 @@ class AutocompleteInstance extends React.PureComponent {
status: !opened && status ? status_state : null,
onKeyDown: this.onTriggerKeyDownHandler,
onSubmit: this.toggleVisible,
onMouseDown: this.reserveActivityHandler,
'aria-haspopup': 'listbox',
'aria-expanded': isExpanded,
'aria-label': !hidden ? submit_button_title : undefined,
Expand Down Expand Up @@ -2057,8 +2069,8 @@ class AutocompleteInstance extends React.PureComponent {
on_select={this.onSelectHandler}
on_hide={this.onHideHandler}
on_pre_change={this.onPreChangeHandler}
on_key_down={this.onReserveActivityHandler}
onMouseDown={this.onReserveActivityHandler}
on_key_down={this.reserveActivityHandler}
onMouseDown={this.reserveActivityHandler}
independent_width={independent_width}
/>
</span>
Expand Down
Loading
Loading