From d59b511d740b751be06fc9bb70ea0d64e12ad26c Mon Sep 17 00:00:00 2001 From: Matias Ribichich Date: Wed, 15 Mar 2017 21:58:01 -0300 Subject: [PATCH] Added the parsing of bindings from the propTypes when present --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ index.tsx | 8 ++++++-- test.tsx | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 95 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 30f1ac5..aea1136 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,49 @@ angular > ``` +## Usage 2 (Alternative) + +As an alternative you can specify the propTypes in your component, and it'll be use automatically as the bindings + +### 1. Create a React component + +```js +import { Component } from 'react' + +class MyComponent extends Component { + static propTypes = { + fooBar: React.PropTypes.number.isRequired, + baz: React.PropTypes.string.isRequired + } + + render() { + return
+

FooBar: {this.props.fooBar}

+

Baz: {this.props.baz}

+
+ } +} +``` + +### 2. Expose it to Angular + +```js +import { react2angular } from 'react2angular' + +angular + .module('myModule', []) + .component('myComponent', react2angular(MyComponent)) +``` + +### 3. Use it in your Angular 1 code + +```html + +``` + ## Tests ```sh diff --git a/index.tsx b/index.tsx index cf70672..8b7bcba 100644 --- a/index.tsx +++ b/index.tsx @@ -17,10 +17,14 @@ import { render, unmountComponentAtNode } from 'react-dom' */ export function react2angular( Class: React.ComponentClass | React.SFC, - bindingNames: (keyof Props)[] = [] + bindingNames?: (keyof Props)[] ): IComponentOptions { + const names = bindingNames + || (Class.propTypes && Object.keys(Class.propTypes)) + || [] + return { - bindings: fromPairs(bindingNames.map(_ => [_, '<'])), + bindings: fromPairs(names.map(_ => [_, '<'])), controller: ['$element', class extends NgComponent { constructor(private $element: IAugmentedJQuery) { super() diff --git a/test.tsx b/test.tsx index 1b76f1b..175715e 100644 --- a/test.tsx +++ b/test.tsx @@ -14,7 +14,7 @@ class TestOne extends React.Component { {this.props.children} } - componentWillUnmount() {} + componentWillUnmount() { } } const TestTwo: React.StatelessComponent = props => @@ -22,9 +22,27 @@ const TestTwo: React.StatelessComponent = props =>

Foo: {props.foo}

Bar: {props.bar.join(',')}

props.baz(42)}>Baz

- {props.children} + {props.children} +class TestThreeWithPropTypes extends React.Component { + static propTypes = { + bar: React.PropTypes.array.isRequired, + baz: React.PropTypes.func.isRequired, + foo: React.PropTypes.number.isRequired + } + + render() { + return
+

Foo: {this.props.foo}

+

Bar: {this.props.bar.join(',')}

+

this.props.baz(42)}>Baz

+ {this.props.children} +
+ } + componentWillUnmount() { } +} + const TestAngularOne = react2angular(TestOne, ['foo', 'bar', 'baz']) const TestAngularTwo = react2angular(TestTwo, ['foo', 'bar', 'baz']) @@ -46,7 +64,7 @@ describe('react2angular', () => { beforeEach(() => { mock.module('test') - mock.inject(function(_$compile_: ICompileService) { + mock.inject(function (_$compile_: ICompileService) { $compile = _$compile_ }) }) @@ -56,6 +74,30 @@ describe('react2angular', () => { expect(TestAngularOne.controller).not.toBe(undefined) }) + it('should use the propTypes when present and no bindingNames were specified', () => { + const reactAngularComponent = react2angular(TestThreeWithPropTypes) + + expect(reactAngularComponent.bindings).toEqual({ + bar: '<', + baz: '<', + foo: '<' + }) + }) + + it('should use the bindingNames when present over the propTypes', () => { + const reactAngularComponent = react2angular(TestThreeWithPropTypes, ['foo']) + + expect(reactAngularComponent.bindings).toEqual({ + foo: '<' + }) + }) + + it('should have empty bindings when parameter is an empty array', () => { + const reactAngularComponent = react2angular(TestThreeWithPropTypes, []) + + expect(reactAngularComponent.bindings).toEqual({}) + }) + describe('react classes', () => { it('should render', () => { @@ -160,7 +202,7 @@ describe('react2angular', () => { }) // TODO: figure out how to test this - xit('should destroy', () => {}) + xit('should destroy', () => { }) it('should take callbacks', () => { const baz = jasmine.createSpy('baz')