1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 *
7 * @format
8 */
9
10import type * as React from 'react';
11
12export type MeasureOnSuccessCallback = (
13  x: number,
14  y: number,
15  width: number,
16  height: number,
17  pageX: number,
18  pageY: number,
19) => void;
20
21export type MeasureInWindowOnSuccessCallback = (
22  x: number,
23  y: number,
24  width: number,
25  height: number,
26) => void;
27
28export type MeasureLayoutOnSuccessCallback = (
29  left: number,
30  top: number,
31  width: number,
32  height: number,
33) => void;
34
35/**
36 * NativeMethods provides methods to access the underlying native component directly.
37 * This can be useful in cases when you want to focus a view or measure its on-screen dimensions,
38 * for example.
39 * The methods described here are available on most of the default components provided by React Native.
40 * Note, however, that they are not available on composite components that aren't directly backed by a
41 * native view. This will generally include most components that you define in your own app.
42 * For more information, see [Direct Manipulation](https://reactnative.dev/docs/direct-manipulation).
43 * @see https://github.com/facebook/react-native/blob/master/Libraries/Renderer/shims/ReactNativeTypes.js#L87
44 */
45export interface NativeMethods {
46  /**
47   * Determines the location on screen, width, and height of the given view and
48   * returns the values via an async callback. If successful, the callback will
49   * be called with the following arguments:
50   *
51   *  - x
52   *  - y
53   *  - width
54   *  - height
55   *  - pageX
56   *  - pageY
57   *
58   * Note that these measurements are not available until after the rendering
59   * has been completed in native. If you need the measurements as soon as
60   * possible, consider using the [`onLayout`
61   * prop](docs/view.html#onlayout) instead.
62   */
63  measure(callback: MeasureOnSuccessCallback): void;
64
65  /**
66   * Determines the location of the given view in the window and returns the
67   * values via an async callback. If the React root view is embedded in
68   * another native view, this will give you the absolute coordinates. If
69   * successful, the callback will be called with the following
70   * arguments:
71   *
72   *  - x
73   *  - y
74   *  - width
75   *  - height
76   *
77   * Note that these measurements are not available until after the rendering
78   * has been completed in native.
79   */
80  measureInWindow(callback: MeasureInWindowOnSuccessCallback): void;
81
82  /**
83   * Like [`measure()`](#measure), but measures the view relative an ancestor,
84   * specified as `relativeToNativeComponentRef`. This means that the returned x, y
85   * are relative to the origin x, y of the ancestor view.
86   * _Can also be called with a relativeNativeNodeHandle but is deprecated._
87   */
88  measureLayout(
89    relativeToNativeComponentRef: HostComponent<unknown> | number,
90    onSuccess: MeasureLayoutOnSuccessCallback,
91    onFail: () => void /* currently unused */,
92  ): void;
93
94  /**
95   * This function sends props straight to native. They will not participate in
96   * future diff process - this means that if you do not include them in the
97   * next render, they will remain active (see [Direct
98   * Manipulation](https://reactnative.dev/docs/direct-manipulation)).
99   */
100  setNativeProps(nativeProps: object): void;
101
102  /**
103   * Requests focus for the given input or view. The exact behavior triggered
104   * will depend on the platform and type of view.
105   */
106  focus(): void;
107
108  /**
109   * Removes focus from an input or view. This is the opposite of `focus()`.
110   */
111  blur(): void;
112
113  refs: {
114    [key: string]: React.Component<any, any>;
115  };
116}
117
118/**
119 * @deprecated Use NativeMethods instead.
120 */
121export type NativeMethodsMixin = NativeMethods;
122/**
123 * @deprecated Use NativeMethods instead.
124 */
125export type NativeMethodsMixinType = NativeMethods;
126
127/**
128 * Represents a native component, such as those returned from `requireNativeComponent`.
129 *
130 * @see https://github.com/facebook/react-native/blob/v0.62.0-rc.5/Libraries/Renderer/shims/ReactNativeTypes.js
131 *
132 * @todo This should eventually be defined as an AbstractComponent, but that
133 *       should first be introduced in the React typings.
134 */
135export interface HostComponent<P>
136  extends Pick<
137    React.ComponentClass<P>,
138    Exclude<keyof React.ComponentClass<P>, 'new'>
139  > {
140  new (props: P, context?: any): React.Component<P> & Readonly<NativeMethods>;
141}
142