-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[RNMobile] Fix issues related to editing text and dragging gesture (#…
…40480) * Add input state functionality to Aztec * Control drag enabling with Aztec input state * Force disabling text editing when dragging * Add documentation to AztecInputState * Update changelog * Add tests for Aztec input state * Update focus change listener logic * Update listen to focus change event test * Fix react-native-aztec module mock * Fix wrong call to removeFocusChangeListener * Fix updating currentFocusedElement value * Check if an inner block is selected when enabling dragging * Wrap draggable long-press handler with useCallback * Add documentation to notifyListeners function
- Loading branch information
Showing
6 changed files
with
282 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import TextInputState from 'react-native/Libraries/Components/TextInput/TextInputState'; | ||
|
||
/** @typedef {import('@wordpress/element').RefObject} RefObject */ | ||
|
||
const focusChangeListeners = []; | ||
|
||
let currentFocusedElement = null; | ||
|
||
/** | ||
* Adds a listener that will be called in the following cases: | ||
* | ||
* - An Aztec view is being focused and all were previously unfocused. | ||
* - An Aztec view is being unfocused and none will be focused. | ||
* | ||
* Note that this listener won't be called when switching focus between Aztec views. | ||
* | ||
* @param {Function} listener | ||
*/ | ||
export const addFocusChangeListener = ( listener ) => { | ||
focusChangeListeners.push( listener ); | ||
}; | ||
|
||
/** | ||
* Removes a listener from the focus change listeners list. | ||
* | ||
* @param {Function} listener | ||
*/ | ||
export const removeFocusChangeListener = ( listener ) => { | ||
const itemIndex = focusChangeListeners.indexOf( listener ); | ||
if ( itemIndex !== -1 ) { | ||
focusChangeListeners.splice( itemIndex, 1 ); | ||
} | ||
}; | ||
|
||
/** | ||
* Notifies listeners about changes in focus. | ||
* | ||
* @param {Object} event Event data to be notified to listeners. | ||
* @param {boolean} event.isFocused True if any Aztec view is currently focused. | ||
*/ | ||
const notifyListeners = ( { isFocused } ) => { | ||
focusChangeListeners.forEach( ( listener ) => { | ||
listener( { isFocused } ); | ||
} ); | ||
}; | ||
|
||
/** | ||
* Determines if any Aztec view is focused. | ||
* | ||
* @return {boolean} True if focused. | ||
*/ | ||
export const isFocused = () => { | ||
return currentFocusedElement !== null; | ||
}; | ||
|
||
/** | ||
* Returns the current focused element. | ||
* | ||
* @return {RefObject} Ref of the current focused element or `null` otherwise. | ||
*/ | ||
export const getCurrentFocusedElement = () => { | ||
return currentFocusedElement; | ||
}; | ||
|
||
/** | ||
* Notifies that an Aztec view is being focused or unfocused. | ||
*/ | ||
export const notifyInputChange = () => { | ||
const focusedInput = TextInputState.currentlyFocusedInput(); | ||
const hasAnyFocusedInput = focusedInput !== null; | ||
|
||
if ( hasAnyFocusedInput ) { | ||
if ( ! currentFocusedElement ) { | ||
notifyListeners( { isFocused: true } ); | ||
} | ||
currentFocusedElement = focusedInput; | ||
} else if ( currentFocusedElement ) { | ||
notifyListeners( { isFocused: false } ); | ||
currentFocusedElement = null; | ||
} | ||
}; | ||
|
||
/** | ||
* Focuses the specified element. | ||
* | ||
* @param {RefObject} element Element to be focused. | ||
*/ | ||
export const focus = ( element ) => { | ||
TextInputState.focusTextInput( element ); | ||
}; | ||
|
||
/** | ||
* Unfocuses the specified element. | ||
* | ||
* @param {RefObject} element Element to be unfocused. | ||
*/ | ||
export const blur = ( element ) => { | ||
TextInputState.blurTextInput( element ); | ||
}; | ||
|
||
/** | ||
* Unfocuses the current focused element. | ||
*/ | ||
export const blurCurrentFocusedElement = () => { | ||
if ( isFocused() ) { | ||
blur( getCurrentFocusedElement() ); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.