Skip to content

Commit

Permalink
Re-add TypeScript definitions for React Native renderer
Browse files Browse the repository at this point in the history
Summary:
changelog: [internal]

Fix CircleCI

Reviewed By: jacdebug

Differential Revision: D40466738

fbshipit-source-id: 0057a98f07cdd07227c3ac8e09eb8b0d51974685
  • Loading branch information
sammy-SC authored and facebook-github-bot committed Oct 18, 2022
1 parent 8f33753 commit f6cfcc3
Show file tree
Hide file tree
Showing 2 changed files with 290 additions and 0 deletions.
149 changes: 149 additions & 0 deletions Libraries/Renderer/implementations/ReactNativeRenderer.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

import {GestureResponderEvent} from '../../Types/CoreEventTypes';

/**
* Gesture recognition on mobile devices is much more complicated than web.
* A touch can go through several phases as the app determines what the user's intention is.
* For example, the app needs to determine if the touch is scrolling, sliding on a widget, or tapping.
* This can even change during the duration of a touch. There can also be multiple simultaneous touches.
*
* The touch responder system is needed to allow components to negotiate these touch interactions
* without any additional knowledge about their parent or child components.
* This system is implemented in ResponderEventPlugin.js, which contains further details and documentation.
*
* Best Practices
* Users can feel huge differences in the usability of web apps vs. native, and this is one of the big causes.
* Every action should have the following attributes:
* Feedback/highlighting- show the user what is handling their touch, and what will happen when they release the gesture
* Cancel-ability- when making an action, the user should be able to abort it mid-touch by dragging their finger away
*
* These features make users more comfortable while using an app,
* because it allows people to experiment and interact without fear of making mistakes.
*
* TouchableHighlight and Touchable*
* The responder system can be complicated to use.
* So we have provided an abstract Touchable implementation for things that should be "tappable".
* This uses the responder system and allows you to easily configure tap interactions declaratively.
* Use TouchableHighlight anywhere where you would use a button or link on web.
*/
export interface GestureResponderHandlers {
/**
* A view can become the touch responder by implementing the correct negotiation methods.
* There are two methods to ask the view if it wants to become responder:
*/

/**
* Does this view want to become responder on the start of a touch?
*/
onStartShouldSetResponder?:
| ((event: GestureResponderEvent) => boolean)
| undefined;

/**
* Called for every touch move on the View when it is not the responder: does this view want to "claim" touch responsiveness?
*/
onMoveShouldSetResponder?:
| ((event: GestureResponderEvent) => boolean)
| undefined;

/**
* If the View returns true and attempts to become the responder, one of the following will happen:
*/

onResponderEnd?: ((event: GestureResponderEvent) => void) | undefined;

/**
* The View is now responding for touch events.
* This is the time to highlight and show the user what is happening
*/
onResponderGrant?: ((event: GestureResponderEvent) => void) | undefined;

/**
* Something else is the responder right now and will not release it
*/
onResponderReject?: ((event: GestureResponderEvent) => void) | undefined;

/**
* If the view is responding, the following handlers can be called:
*/

/**
* The user is moving their finger
*/
onResponderMove?: ((event: GestureResponderEvent) => void) | undefined;

/**
* Fired at the end of the touch, ie "touchUp"
*/
onResponderRelease?: ((event: GestureResponderEvent) => void) | undefined;

onResponderStart?: ((event: GestureResponderEvent) => void) | undefined;

/**
* Something else wants to become responder.
* Should this view release the responder? Returning true allows release
*/
onResponderTerminationRequest?:
| ((event: GestureResponderEvent) => boolean)
| undefined;

/**
* The responder has been taken from the View.
* Might be taken by other views after a call to onResponderTerminationRequest,
* or might be taken by the OS without asking (happens with control center/ notification center on iOS)
*/
onResponderTerminate?: ((event: GestureResponderEvent) => void) | undefined;

/**
* onStartShouldSetResponder and onMoveShouldSetResponder are called with a bubbling pattern,
* where the deepest node is called first.
* That means that the deepest component will become responder when multiple Views return true for *ShouldSetResponder handlers.
* This is desirable in most cases, because it makes sure all controls and buttons are usable.
*
* However, sometimes a parent will want to make sure that it becomes responder.
* This can be handled by using the capture phase.
* Before the responder system bubbles up from the deepest component,
* it will do a capture phase, firing on*ShouldSetResponderCapture.
* So if a parent View wants to prevent the child from becoming responder on a touch start,
* it should have a onStartShouldSetResponderCapture handler which returns true.
*/
onStartShouldSetResponderCapture?:
| ((event: GestureResponderEvent) => boolean)
| undefined;

/**
* onStartShouldSetResponder and onMoveShouldSetResponder are called with a bubbling pattern,
* where the deepest node is called first.
* That means that the deepest component will become responder when multiple Views return true for *ShouldSetResponder handlers.
* This is desirable in most cases, because it makes sure all controls and buttons are usable.
*
* However, sometimes a parent will want to make sure that it becomes responder.
* This can be handled by using the capture phase.
* Before the responder system bubbles up from the deepest component,
* it will do a capture phase, firing on*ShouldSetResponderCapture.
* So if a parent View wants to prevent the child from becoming responder on a touch start,
* it should have a onStartShouldSetResponderCapture handler which returns true.
*/
onMoveShouldSetResponderCapture?:
| ((event: GestureResponderEvent) => boolean)
| undefined;
}

/**
* React Native also implements unstable_batchedUpdates
*/
export function unstable_batchedUpdates<A, B>(
callback: (a: A, b: B) => any,
a: A,
b: B,
): void;
export function unstable_batchedUpdates<A>(callback: (a: A) => any, a: A): void;
export function unstable_batchedUpdates(callback: () => any): void;
141 changes: 141 additions & 0 deletions Libraries/Renderer/shims/ReactNativeTypes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/

import type * as React from 'react';

export type MeasureOnSuccessCallback = (
x: number,
y: number,
width: number,
height: number,
pageX: number,
pageY: number,
) => void;

export type MeasureInWindowOnSuccessCallback = (
x: number,
y: number,
width: number,
height: number,
) => void;

export type MeasureLayoutOnSuccessCallback = (
left: number,
top: number,
width: number,
height: number,
) => void;

/**
* NativeMethods provides methods to access the underlying native component directly.
* This can be useful in cases when you want to focus a view or measure its on-screen dimensions,
* for example.
* The methods described here are available on most of the default components provided by React Native.
* Note, however, that they are not available on composite components that aren't directly backed by a
* native view. This will generally include most components that you define in your own app.
* For more information, see [Direct Manipulation](https://reactnative.dev/docs/direct-manipulation).
* @see https://github.com/facebook/react-native/blob/master/Libraries/Renderer/shims/ReactNativeTypes.js#L87
*/
export interface NativeMethods {
/**
* Determines the location on screen, width, and height of the given view and
* returns the values via an async callback. If successful, the callback will
* be called with the following arguments:
*
* - x
* - y
* - width
* - height
* - pageX
* - pageY
*
* Note that these measurements are not available until after the rendering
* has been completed in native. If you need the measurements as soon as
* possible, consider using the [`onLayout`
* prop](docs/view.html#onlayout) instead.
*/
measure(callback: MeasureOnSuccessCallback): void;

/**
* Determines the location of the given view in the window and returns the
* values via an async callback. If the React root view is embedded in
* another native view, this will give you the absolute coordinates. If
* successful, the callback will be called with the following
* arguments:
*
* - x
* - y
* - width
* - height
*
* Note that these measurements are not available until after the rendering
* has been completed in native.
*/
measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;

/**
* Like [`measure()`](#measure), but measures the view relative an ancestor,
* specified as `relativeToNativeComponentRef`. This means that the returned x, y
* are relative to the origin x, y of the ancestor view.
* _Can also be called with a relativeNativeNodeHandle but is deprecated._
*/
measureLayout(
relativeToNativeComponentRef: HostComponent<unknown> | number,
onSuccess: MeasureLayoutOnSuccessCallback,
onFail: () => void /* currently unused */,
): void;

/**
* This function sends props straight to native. They will not participate in
* future diff process - this means that if you do not include them in the
* next render, they will remain active (see [Direct
* Manipulation](https://reactnative.dev/docs/direct-manipulation)).
*/
setNativeProps(nativeProps: object): void;

/**
* Requests focus for the given input or view. The exact behavior triggered
* will depend on the platform and type of view.
*/
focus(): void;

/**
* Removes focus from an input or view. This is the opposite of `focus()`.
*/
blur(): void;

refs: {
[key: string]: React.Component<any, any>;
};
}

/**
* @deprecated Use NativeMethods instead.
*/
export type NativeMethodsMixin = NativeMethods;
/**
* @deprecated Use NativeMethods instead.
*/
export type NativeMethodsMixinType = NativeMethods;

/**
* Represents a native component, such as those returned from `requireNativeComponent`.
*
* @see https://github.com/facebook/react-native/blob/v0.62.0-rc.5/Libraries/Renderer/shims/ReactNativeTypes.js
*
* @todo This should eventually be defined as an AbstractComponent, but that
* should first be introduced in the React typings.
*/
export interface HostComponent<P>
extends Pick<
React.ComponentClass<P>,
Exclude<keyof React.ComponentClass<P>, 'new'>
> {
new (props: P, context?: any): React.Component<P> & Readonly<NativeMethods>;
}

0 comments on commit f6cfcc3

Please sign in to comment.