Skip to content

Commit

Permalink
Enable SVC codegen in TypeScript Spec files
Browse files Browse the repository at this point in the history
Summary:
## Context
babel-plugin-codegen:
1. Looks at HostComponent spec files (i.e: *NativeComponent.js files).
2. It runs the Static ViewConfig codegen (i.e: GenerateViewConfigJs.js)
3. It replaces codegenNativeComponent with NativeComponentRegistry.get.

**Before**

[react-native-svg/src/fabric/CircleNativeComponent.ts](https://github.com/react-native-svg/react-native-svg/pull/1847/files#diff-676990c4b50b85e2530021bed11f83744fb646c8ffcc769fd5d982eac1b97e98R9-R55)
```
interface SvgNodeCommonProps {
  name?: string;
  opacity?: WithDefault<Float, 1.0>;
  matrix?: ReadonlyArray<Float>;
  // transform?: ____TransformStyle_Internal, // CATransform3D, custom handling
  mask?: string;
  markerStart?: string;
  markerMid?: string;
  markerEnd?: string;
  clipPath?: string;
  clipRule?: WithDefault<Int32, 0>;
  responsible?: boolean;
  display?: string;
}

type ColorStruct = Readonly<{
  type?: WithDefault<Int32, -1>;
  value?: ColorValue;
  brushRef?: string;
}>;

interface SvgRenderableCommonProps {
  fill?: ColorStruct;
  fillOpacity?: WithDefault<Float, 1.0>;
  fillRule?: WithDefault<Int32, 1>;
  stroke?: ColorStruct;
  strokeOpacity?: WithDefault<Float, 1.0>;
  strokeWidth?: WithDefault<string, '1'>;
  strokeLinecap?: WithDefault<Int32, 0>;
  strokeLinejoin?: WithDefault<Int32, 0>;
  strokeDasharray?: ReadonlyArray<string>;
  strokeDashoffset?: Float;
  strokeMiterlimit?: Float;
  vectorEffect?: WithDefault<Int32, 0>;
  propList?: ReadonlyArray<string>;
}

interface NativeProps
  extends ViewProps,
    SvgNodeCommonProps,
    SvgRenderableCommonProps {
  cx?: string;
  cy?: string;
  r?: string;
}

export default codegenNativeComponent<NativeProps>('RNSVGCircle');
```

**After**
```
var __INTERNAL_VIEW_CONFIG = {
  uiViewClassName: "RNSVGCircle",
  validAttributes: {
    name: true,
    opacity: true,
    matrix: true,
    mask: true,
    markerStart: true,
    markerMid: true,
    markerEnd: true,
    clipPath: true,
    clipRule: true,
    responsible: true,
    display: true,
    fill: true,
    fillOpacity: true,
    fillRule: true,
    stroke: true,
    strokeOpacity: true,
    strokeWidth: true,
    strokeLinecap: true,
    strokeLinejoin: true,
    strokeDasharray: true,
    strokeDashoffset: true,
    strokeMiterlimit: true,
    vectorEffect: true,
    propList: true,
    cx: true,
    cy: true,
    r: true,
  },
};
exports.__INTERNAL_VIEW_CONFIG = __INTERNAL_VIEW_CONFIG;
var _default = NativeComponentRegistry.get(nativeComponentName, function () {
  return __INTERNAL_VIEW_CONFIG;
});
exports.default = _default;

```

## Changes
This babel plugin only worked with Flow HostComponent spec files. After this change, it'll start to work with TypeScript files as well.

## Motivation
Once published, this update will allow us to make react-native-svg static ViewConfigs-compatible.

For usage, see this GitHub commit: [feat: try to add babel plugin](software-mansion/react-native-svg@80fe687)

Changelog: [General][Added] Make babel-plugin-codegen work for TypeScript Spec files

Reviewed By: cipolleschi

Differential Revision: D39136171

fbshipit-source-id: d89d35b591577e7626ce46a9c8e73b4d7ac7f227
  • Loading branch information
RSNara authored and facebook-github-bot committed Aug 30, 2022
1 parent 10ea6fb commit df0b690
Showing 1 changed file with 24 additions and 5 deletions.
29 changes: 24 additions & 5 deletions packages/babel-plugin-codegen/index.js
Expand Up @@ -9,23 +9,42 @@

'use strict';

let flow, RNCodegen;
let flowParser, typeScriptParser, RNCodegen;

const {basename} = require('path');

try {
flow = require('react-native-codegen/src/parsers/flow');
flowParser = require('react-native-codegen/src/parsers/flow');
typeScriptParser = require('react-native-codegen/src/parsers/typescript');
RNCodegen = require('react-native-codegen/src/generators/RNCodegen');
} catch (e) {
// Fallback to lib when source doesn't exit (e.g. when installed as a dev dependency)
flow = require('react-native-codegen/lib/parsers/flow');
flowParser = require('react-native-codegen/lib/parsers/flow');
typeScriptParser = require('react-native-codegen/lib/parsers/typescript');
RNCodegen = require('react-native-codegen/lib/generators/RNCodegen');
}

function parse(filename, code) {
if (filename.endsWith('js')) {
return flowParser.parseString(code);
}

if (filename.endsWith('ts')) {
return typeScriptParser.parseString(code);
}

throw new Error(
`Unable to parse file '${filename}'. Unsupported filename extension.`,
);
}

function generateViewConfig(filename, code) {
const schema = flow.parseString(code);
const schema = parse(filename, code);

const libraryName = basename(filename).replace(/NativeComponent\.js$/, '');
const libraryName = basename(filename).replace(
/NativeComponent\.(js|ts)$/,
'',
);
return RNCodegen.generateViewConfig({
schema,
libraryName,
Expand Down

0 comments on commit df0b690

Please sign in to comment.