Files
react-native/packages/react-native-codegen/e2e/__test_fixtures__/EventPropsNativeComponent.js
T
Rick Hanlon 9a84970c35 Add paperTopLevelNameDeprecated
Summary:
This diff adds a way for the codegen to handle view configs with non-standard top event names by adding a `paperTopLevelNameDeprecated` field to events in the schema.

## The problem
The problem this is solving is that Android host components build their own options for event settings in the view config. So instead of enforcing `onChange` to use the top level event name `topChange` like iOS does, Android can use `change` or `forbarChange` or anything the person adding the component wanted at the time:

```
// Expected
topChange: {
  registrationName: 'onChange',
},

// Android
bringBackStargateYouCowards: {
  registrationName: 'onChange',
},
```

This is possible because of the way Android builds these settings
```
// On iOS, notice that there's no option to change the top level name:
RCT_EXPORT_VIEW_PROPERTY(onChange, RCTDirectEventBlock);

// On Android, you provide the top level event name
Override
public Map getExportedCustomDirectEventTypeConstants() {
  return MapBuilder.of(
      "bringBackStargateYouCowards",
      MapBuilder.of("registrationName", "onChange"));
}
```

Since the codegen does not allow us to specify the top level event name (similar to iOS), we don't have a way to customize the names to support android

## The solution
To fix this, we're adding an extra option the event flow types:

```
onBubblingChange: (event: BubblingEvent<Event, 'customBubblingName'>) => void,
onDirectChange: (event: DirectEvent<Event, 'customDirectName'>) => void,
```

These will register **both** top level names in the view config:

```
{
  directEventTypes: {
     // Notice the same registration name is configured for different top level events
    topChange: {
      registrationName: 'onChange',
    },
    bringBackStargateYouCowards: {
      registrationName: 'onChange',
    },
  }
}
```
This means when either `topChange` or `bringBackStargateYouCowards` fires it will call the onChange listener. **This gives us the flexibility to rename the native event name without breaking backwards compatibility.** Old apps will work when `bringBackStargateYouCowards` is fired, and new apps with an update will work when `topChange` fires.

Note: only the correct name will be generated for Fabric so technically we don't even really need to migrate the paper names and this prop can be deleted when paper is gone.

Reviewed By: cpojer

Differential Revision: D16042065

fbshipit-source-id: 40d076b43ffbbfc6c65c3c19de481d922a2add62
2019-06-28 06:50:36 -07:00

58 lines
1.4 KiB
JavaScript

/**
* 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.
*
* @format
* @flow
*/
'use strict';
import type {
Int32,
Float,
BubblingEvent,
DirectEvent,
WithDefault,
} from '../../../../Libraries/Types/CodegenTypes';
import type {ViewProps} from '../../../../Libraries/Components/View/ViewPropTypes';
import codegenNativeComponent from '../../../../Libraries/Utilities/codegenNativeComponent';
type OnChangeEvent = $ReadOnly<{|
value: boolean,
source?: string,
progress: ?Int32,
scale?: ?Float,
|}>;
type OnEventDirect = $ReadOnly<{|
value: boolean,
|}>;
type OnOrientationChangeEvent = $ReadOnly<{|
orientation: 'landscape' | 'portrait',
|}>;
type NativeProps = $ReadOnly<{|
...ViewProps,
// Props
disabled?: WithDefault<boolean, false>,
// Events
onChange?: ?(event: BubblingEvent<OnChangeEvent>) => void,
onEventDirect?: ?(event: DirectEvent<OnEventDirect>) => void,
onEventDirectWithPaperName?: ?(
event: DirectEvent<OnEventDirect, 'paperDirectName'>,
) => void,
onOrientationChange?: ?(event: DirectEvent<OnOrientationChangeEvent>) => void,
onEnd?: ?(event: BubblingEvent<null>) => void,
onEventBubblingWithPaperName?: ?(
event: BubblingEvent<null, 'paperBubblingName'>,
) => void,
|}>;
export default codegenNativeComponent<NativeProps>('EventPropsNativeComponent');