Skip to content
This repository has been archived by the owner on Feb 16, 2021. It is now read-only.

Commit

Permalink
fix #24, fix #25
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed Jan 23, 2016
1 parent d442848 commit 3b5c8f2
Show file tree
Hide file tree
Showing 29 changed files with 661 additions and 52 deletions.
5 changes: 5 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
stage: 0,
loose: true,
optional: ["runtime"]
}
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
**Note**: Gaps between patch versions are faulty/broken releases.

## v0.8.12

- **New Feature**
- Documentation tool: `parse` module, fix #24
- Documentation tool: `toMarkdown` module, fix #25

## v0.8.11

- **New Feature**
Expand Down
222 changes: 178 additions & 44 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,46 @@

# Features

- builds on [tcomb](https://github.com/gcanti/tcomb) library
- additional fine grained type checks, nestable at arbitrary level
- **by default props are required**, a saner default since it's quite easy to forget `.isRequired`
- **checks for unwanted additional props**
- **documentation** (types and comments) can be automatically extracted
- additional fine grained type checks, nestable at arbitrary level
- builds on [tcomb](https://github.com/gcanti/tcomb), [tcomb-validation](https://github.com/gcanti/tcomb-validation), [tcomb-doc](https://github.com/gcanti/tcomb-doc) libraries

# Prop types

## The `@props` decorator (ES7)

For an equivalent implementation in ES5 see the `propTypes` function below.

**Signature**

```js
type Props = {[key: string]: TcombType};

@props(type: Props | TcombType, options?: Object)
```

where

- `type` can be a map `string -> TcombType`, a `tcomb` struct or a refinement of a struct
- `options`:
- `strict: boolean` (default `true`) if `true` checks for unwanted additional props

# ES7 decorator
**Example** (ES7)

```js
import { props, t } from 'tcomb-react';

const Gender = t.enums.of(['Male', 'Female'], 'Gender');
const URL = t.subtype(t.String, s => s.startsWith('http'), 'URL');
const URL = t.refinement(t.String, (s) => s.startsWith('http'), 'URL');

@props({
name: t.String,
surname: t.maybe(t.String),
age: t.Number,
gender: Gender,
avatar: URL
name: t.String, // a required string
surname: t.maybe(t.String), // an optional string
age: t.Number, // a required number
gender: Gender, // an enum
avatar: URL // a refinement
})
class Card extends React.Component {

Expand All @@ -38,18 +59,9 @@ class Card extends React.Component {
}
```

**Note**. `@props` can accepts a subtype of a struct (see [The subtype combinator](https://github.com/gcanti/tcomb/blob/master/GUIDE.md#the-subtype-combinator)).
**Unwanted additional props**

```js
@props(t.subtype(t.struct({
name: t.String,
...
}), () => { ... }))
```

## Unwanted additional props

By default tcomb-react checks unwanted additional props:
By default `tcomb-react` checks for unwanted additional props:

```js
@props({
Expand All @@ -72,7 +84,7 @@ class Person extends React.Component {
<Person name="Giulio" surname="Canti" />
```

ouput to console:
**Output**

```
Warning: Failed propType: [tcomb] Invalid additional prop(s):
Expand All @@ -84,42 +96,31 @@ Warning: Failed propType: [tcomb] Invalid additional prop(s):
supplied to Person.
```

You can **opt-out** passing an additional argument `{ strict: false }`:
**Note**. You can **opt-out** passing the `option` argument `{ strict: false }`.

```js
@props({
name: t.String
}, { strict: false })
class Person extends React.Component {
## The `propTypes` function (ES5)

render() {
return (
<div>
<p>{this.props.name}</p>
</div>
);
}
**Signature**

}
```
Same as `@props`.

# ES5
**Example** (ES5)

```js
var t = require('tcomb-react').t;
var propTypes = require('tcomb-react').propTypes;

var Gender = t.enums.of(['Male', 'Female'], 'Gender');
var URL = t.subtype(t.String, function (s) { return s.startsWith('http'); }, 'URL');
var URL = t.refinement(t.String, function (s) { return s.startsWith('http'); }, 'URL');

var Card = React.createClass({

propTypes: propTypes({
name: t.String,
surname: t.maybe(t.String),
age: t.Number,
gender: Gender,
avatar: URL
name: t.String, // a required string
surname: t.maybe(t.String), // an optional string
age: t.Number, // a required number
gender: Gender, // an enum
avatar: URL // a refinement
}),

render: function () {
Expand All @@ -134,18 +135,151 @@ var Card = React.createClass({
});
```

# Extract documentation from your components

## The `parse` function

Given a path to a component file returns a JSON / JavaScript blob containing **props types, default values and comments**.

**Signature**

```js
(path: string | Array<string>) => Object
```

**Example**

Source

```js
import { t, props } from 'tcomb-react'

/**
* Component description here
* @param name - name description here
* @param surname - surname description here
*/

@props({
name: t.String, // a required string
surname: t.maybe(t.String) // an optional string
})
export default class Card extends React.Component {

static defaultProps = {
surname: 'Canti' // default value for surname prop
}

render() {
return (
<div>
<p>{this.props.name}</p>
<p>{this.props.surname}</p>
</div>
);
}
}
```

Usage

```js
import parse from 'tcomb-react/lib/parse'
const json = parse('./components/Card.js')
console.log(JSON.stringify(json, null, 2))
```

Output

```json
{
"name": "Card",
"description": "Component description here",
"props": {
"name": {
"kind": "irreducible",
"name": "String",
"required": true,
"description": "name description here"
},
"surname": {
"kind": "irreducible",
"name": "String",
"required": false,
"defaultValue": "Canti",
"description": "surname description here"
}
}
}
```

**Note**. Since `parse` uses runtime type introspection, your components should be `require`able from your script (you may be required to shim the browser environment).

**Parsing multiple components**

```js
import parse from 'tcomb-react/lib/parse'
import path import 'path'
import glob import 'glob'

function getPath(file) {
return path.resolve(process.cwd(), file);
}

parse(glob.sync('./components/*.js').map(getPath));
```

## The `toMarkdown` function

Given a JSON / JavaScript blob returned by `parse` returns a markdown containing the components documentation.

**Signature**

```js
(json: Object) => string
```

**Example**

Usage

```js
import parse from 'tcomb-react/lib/parse'
import toMarkdown from 'tcomb-react/lib/toMarkdown'
const json = parse('./components/Card.js')
console.log(toMarkdown(json));
```

Output

```markdown
## Card

Component description here

**Props**

- `name: String` name description here
- `surname: String` (optional, default: `"Canti"`) surname description here

```

# Augmented pre-defined types

`tcomb-react` exports some useful pre-defined types:

- `t.ReactElement`
- `t.ReactNode`
- `t.ReactChild`
- `t.ReactChildren`

**Example**

```js
import { props, t } from 'tcomb-react';

@props({
children: t.ReactChild // allow only one child
children: t.ReactChild // only one child is allowed
})
class MyComponent extends React.Component {

Expand Down
Loading

0 comments on commit 3b5c8f2

Please sign in to comment.