From 4bbbe6a5baa3ce8ad53564ebe5c991854fa5eca7 Mon Sep 17 00:00:00 2001 From: Eli White Date: Tue, 28 Jan 2020 15:11:53 -0800 Subject: [PATCH] Pressability: Create `usePressability` Hook Summary: Creates `usePressability`, a hook to simplify using `Pressability` from functional components. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D18742613 fbshipit-source-id: 55cf48ad60a16a6a5c2c3fa2785f61f784a46b45 --- Libraries/Pressability/Pressability.js | 2 +- Libraries/Pressability/usePressability.js | 43 +++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 Libraries/Pressability/usePressability.js diff --git a/Libraries/Pressability/Pressability.js b/Libraries/Pressability/Pressability.js index d77baa8c11..88ec49a2c3 100644 --- a/Libraries/Pressability/Pressability.js +++ b/Libraries/Pressability/Pressability.js @@ -147,7 +147,7 @@ export type PressabilityConfig = $ReadOnly<{| onStartShouldSetResponder_DEPRECATED?: ?() => boolean, |}>; -type EventHandlers = $ReadOnly<{| +export type EventHandlers = $ReadOnly<{| onBlur: (event: BlurEvent) => void, onClick: (event: PressEvent) => void, onFocus: (event: FocusEvent) => void, diff --git a/Libraries/Pressability/usePressability.js b/Libraries/Pressability/usePressability.js new file mode 100644 index 0000000000..54a40ec4b8 --- /dev/null +++ b/Libraries/Pressability/usePressability.js @@ -0,0 +1,43 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import Pressability, { + type EventHandlers, + type PressabilityConfig, +} from './Pressability.js'; +import {useEffect, useRef} from 'react'; + +export default function usePressability( + config: PressabilityConfig, +): EventHandlers { + const pressabilityRef = useRef(null); + if (pressabilityRef.current == null) { + pressabilityRef.current = new Pressability(config); + } + const pressability = pressabilityRef.current; + + // On the initial mount, this is a no-op. On updates, `pressability` will be + // re-configured to use the new configuration. + useEffect(() => { + pressability.configure(config); + }, [config, pressability]); + + // On unmount, reset pending state and timers inside `pressability`. This is + // a separate effect because we do not want to reset when `config` changes. + useEffect(() => { + return () => { + pressability.reset(); + }; + }, [pressability]); + + return pressability.getEventHandlers(); +}