diff --git a/CHANGELOG.md b/CHANGELOG.md index 097be01..74b8d9b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.12.8] +### Added +- onEnterRelease event triggered when the Enter is released from the focused item + ## [2.12.7] ### Added - SSR support, additional checks for `window` object to avoid errors on SSR environments. diff --git a/README.md b/README.md index c234be2..9b6a1bf 100644 --- a/README.md +++ b/README.md @@ -284,18 +284,22 @@ String that is used as a component focus key. Should be **unique**, otherwise it ### `onEnterPress`: function Callback function that is called when the item is currently focused and Enter (OK) key is pressed. +### `onEnterRelease`: function +Callback function that is called when the item is currently focused and Enter (OK) key is released. + Payload: 1. All the props passed to HOC is passed back to this callback. Useful to avoid creating callback functions during render. 2. [Details](#keydetails-object) - info about pressed keys ```jsx const onPress = ({prop1, prop2}, details) => {...}; - +const onRelease = ({prop1, prop2}) => {...}; ... ... ``` diff --git a/package-lock.json b/package-lock.json index 58bc30e..4700499 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@noriginmedia/react-spatial-navigation", - "version": "2.12.7", + "version": "2.12.8", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 5ce42e9..98c6504 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@noriginmedia/react-spatial-navigation", - "version": "2.12.7", + "version": "2.12.8", "description": "HOC-based Spatial Navigation (key navigation) solution for React", "main": "dist/index.js", "files": [ diff --git a/src/spatialNavigation.js b/src/spatialNavigation.js index 949cdea..c082e36 100644 --- a/src/spatialNavigation.js +++ b/src/spatialNavigation.js @@ -443,6 +443,10 @@ class SpatialNavigation { if (this.throttle && !this.throttleKeypresses) { this.keyDownEventListener.cancel(); } + + if (eventType === KEY_ENTER && this.focusKey) { + this.onEnterRelease(); + } }; window.addEventListener('keyup', this.keyUpEventListener); @@ -483,6 +487,26 @@ class SpatialNavigation { component.onEnterPressHandler && component.onEnterPressHandler(details); } + onEnterRelease() { + const component = this.focusableComponents[this.focusKey]; + + /* Guard against last-focused component being unmounted at time of onEnterRelease (e.g due to UI fading out) */ + if (!component) { + this.log('onEnterRelease', 'noComponent'); + + return; + } + + /* Suppress onEnterRelease if the last-focused item happens to lose its 'focused' status. */ + if (!component.focusable) { + this.log('onEnterRelease', 'componentNotFocusable'); + + return; + } + + component.onEnterReleaseHandler && component.onEnterReleaseHandler(); + } + onArrowPress(...args) { const component = this.focusableComponents[this.focusKey]; @@ -722,6 +746,7 @@ class SpatialNavigation { node, parentFocusKey, onEnterPressHandler, + onEnterReleaseHandler, onArrowPressHandler, onBecameFocusedHandler, onBecameBlurredHandler, @@ -739,6 +764,7 @@ class SpatialNavigation { node, parentFocusKey, onEnterPressHandler, + onEnterReleaseHandler, onArrowPressHandler, onBecameFocusedHandler, onBecameBlurredHandler, diff --git a/src/withFocusable.js b/src/withFocusable.js index 4660cc2..7f5e0be 100644 --- a/src/withFocusable.js +++ b/src/withFocusable.js @@ -77,6 +77,12 @@ const withFocusable = ({ }) => (details) => { onEnterPress(rest, details); }, + onEnterReleaseHandler: ({ + onEnterRelease = noop, + ...rest + }) => () => { + onEnterRelease(rest); + }, onArrowPressHandler: ({ onArrowPress = noop, ...rest @@ -106,6 +112,7 @@ const withFocusable = ({ preferredChildFocusKey, forgetLastFocusedChild = false, onEnterPressHandler, + onEnterReleaseHandler, onArrowPressHandler, onBecameFocusedHandler, onBecameBlurredHandler, @@ -125,6 +132,7 @@ const withFocusable = ({ parentFocusKey, preferredChildFocusKey, onEnterPressHandler, + onEnterReleaseHandler, onArrowPressHandler, onBecameFocusedHandler, onBecameBlurredHandler, @@ -169,6 +177,7 @@ const withFocusable = ({ 'onBecameFocusedHandler', 'onBecameBlurredHandler', 'onEnterPressHandler', + 'onEnterReleaseHandler', 'onArrowPressHandler', 'onUpdateFocus', 'onUpdateHasFocusedChild',