Skip to content
This repository has been archived by the owner on Nov 10, 2017. It is now read-only.

Commit

Permalink
add use case and better examples
Browse files Browse the repository at this point in the history
  • Loading branch information
sylvaindethier committed Feb 20, 2016
1 parent c8554d5 commit d7162b6
Showing 1 changed file with 83 additions and 61 deletions.
144 changes: 83 additions & 61 deletions README.md
Expand Up @@ -32,26 +32,14 @@ Instal via npm: `npm install --save react-custom-props`

View the [JSbin demo][demo-url]


## API
See the [API documentation file](API.md)


## Use case: Add custom props to elements
Say we have a customizable `HelloWorld` component which has:
* a required `name` props
* an optional `custom` props
* an optional `customOptions` props

Use with no `custom` props (trivial).
```jsx
const node = (
<HelloWorld name="foo" />
);
```

Use with `custom` props values.
```jsx
### Use with `custom` props values
```javascript
const custom = {
// optional custom props can be a value
className: 'hello-world'
Expand All @@ -60,58 +48,118 @@ const node = (
<HelloWorld name="foo" custom={custom} />
);
```
```jsx
// or if you prefer
const custom = { custom: {
Or if you prefer (further examples will use this notation):
```javascript
const props = { name: 'foo', custom: {
className: 'hello-world'
}};
const node = (
<HelloWorld name="foo" {...custom} />
<HelloWorld {...props} />
);
```

Use with `custom` props functions.
### Use with `custom` props functions
Hanlders are not evaluated by default (props name matches `/^on\w/` RegExp).
```jsx
```javascript
const custom = { custom: {
// optional custom props can be a function
className: (...args) => ('hello-world'),

// handlers /^on\w/ are not evaluated by default
onClick: (ev) => {
ev.preventDefault(); return false;
}
}};
```

Use with `custom.children` array (indexed child)
```jsx
### Use with `custom.children` array (indexed child)
```javascript
const custom = { custom: {
// optional children custom props can be an array
children: [
// will be applied to the first child
{
style: {backgroundColor: 'yellow'}
}
]
}};
```

Use with `custom.children` object (named child)
```jsx
### Use with `custom.children` object (named child)
```javascript
const custom = { custom: {
// optional children custom props can be an object
children: {
// will be applied to the 'span' child
span: {
style: {backgroundColor: 'yellow'}
}
}
}};
```

## Use case: Design a fully configurable component
### Use with `customOptions` props
Available `customOptions` are:
* `ignore`: A `matcher` to ignore some props. The matched props are ignored
in the resulting custom props.
Default is `null`.
* `raw`: A `matcher` to copy as is some props. The matched props are copied as is
in the resulting custom props.
Default is `/^on\w/`, so that handlers are not evaluated.
* `bind`: A value for `this` in the evaluated custom props function.
Default is `null`

A `matcher` can be either:
* a value: The custom props name matches if it equals the value.
* `null` or `undefined` (void): The custom props name never matches.
* a `RegExp`: The custom props name matches if it the RegExp test success
(i.e. /^foo/.test(name) w/ name = 'foo' is a success).
* a `Function`: The custom props name matches if the function returns
a truthly value.
* an `Array` of the previous `matcher` types: The custom props name matches if
it matches every matchers.

```javascript
import custom from 'react-custom-props';

const props = {
custom: {
shouldBeIgnored: 'value', // should be ignored
ignoreThisOneToo: 'value', // ignored too
onClick: (ev) => (false), // handlers are raw
rawValue: 'rawValue', //
rawFunc: () => ('rawFunc')
propValue: 'propValue',
propFunc: () => ('propFunc'), // should be evaluated to 'propFunc'
prop: (value) => (value) // should be evaluated to the passed in value
},
customOptions: {
ignore: ['shouldBeIgnored', /^ignore/],
raw: [/^on\w/, (name) => (name.substr(0, 3) === 'raw')]
// let `bind` be the default (null)
}
};
const customProps = custom(props)('argument');
console.log(customProps);
/*
{
onClick: (ev) => (false),
rawValue: 'rawValue',
rawFunc: () => ('rawFunc'),
propValue: 'propValue',
propFunc: 'propFunc',
prop: 'argument'
}
*/
```

* With stateless function
## Use case: Design a fully configurable component

### With stateless function
Custom props are evaluated with `props` in the following example.
```jsx
```javascript
import React, {PropTypes} from 'react';
import {custom, addPropTypesCustom} from 'react-custom-props';
import custom, {addPropTypesCustom} from 'react-custom-props';

export default function HelloWorld(props) {
return (
Expand All @@ -134,44 +182,16 @@ HelloWorld.propTypes = {
addPropTypesCustom(HelloWorld);
```

* With `CustomPropsComponent` class

### With React `Component` class
Custom props are evaluated with `this.props` and `this.state` in the following example.
```jsx
import React, {PropTypes} from 'react';
import {CustomPropsComponent} from 'react-custom-props';

class HelloWorld extends CustomPropsComponent {
render() {
return (
// inject optional root props
<h1 {...this.custom()(this.props, this.state)}>
Hello
// inject optional named child props
<span {...this.custom('span')(this.props, this.state)}>
{props.name}
</span> !
</h1>
);
}
}

HelloWorld.propTypes = {
name: PropTypes.string.isRequired
};
```

* Or with React `Component` class

Custom props are resolved with `this.props` and `this.state` in the following example.
```jsx
```javascript
import React, {PropTypes, Component} from 'react';
import {custom, addPropTypesCustom} from 'react-custom-props';
import custom, {addPropTypesCustom} from 'react-custom-props';

class HelloWorld extends Component {
render() {
return (
// inject optional root custom props
// inject optional root props
<h1 {...custom(this.props)(this.props, this.state)}>
Hello
// inject optional named child props
Expand All @@ -184,7 +204,9 @@ class HelloWorld extends Component {
}

HelloWorld.propTypes = {
name: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
};

// add PropTypes Custom (not required)
addPropTypesCustom(HelloWorld);
```

0 comments on commit d7162b6

Please sign in to comment.