1 | # react-prop-types
|
2 |
|
3 | [![Travis Build Status][build-badge]][build]
|
4 |
|
5 | This is a library of some custom validators for React components properties.
|
6 | Initially they were part of the [React-Bootstrap](https://github.com/react-bootstrap/react-bootstrap/) project.
|
7 |
|
8 | ### Usage
|
9 |
|
10 | All validators can be imported as
|
11 | ```js
|
12 | import elementType from 'react-prop-types/elementType';
|
13 | // or
|
14 | import { elementType } from 'react-prop-types';
|
15 | ...
|
16 | propTypes: {
|
17 | someProp: elementType
|
18 | ```
|
19 | or
|
20 | ```js
|
21 | import CustomPropTypes from 'react-prop-types';
|
22 | // and then used as usual
|
23 | propTypes: {
|
24 | someProp: CustomPropTypes.elementType
|
25 | ```
|
26 |
|
27 | If you use `webpack` and only want to bundle the validators you need, prefer the following approach:
|
28 | ```js
|
29 | import elementType from 'react-prop-types/elementType'
|
30 | ```
|
31 |
|
32 | ---
|
33 | #### all(...arrayOfValidators)
|
34 |
|
35 | This validator allows to have complex validation like this:
|
36 | ```js
|
37 | propTypes: {
|
38 | vertical: React.PropTypes.bool,
|
39 | /**
|
40 | * Display block buttons, only useful when used with the "vertical" prop.
|
41 | * @type {bool}
|
42 | */
|
43 | block: CustomPropTypes.all(
|
44 | React.PropTypes.bool,
|
45 | function(props, propName, componentName) {
|
46 | if (props.block && !props.vertical) {
|
47 | return new Error('The block property requires the vertical property to be set to have any effect');
|
48 | }
|
49 | }
|
50 | )
|
51 | ```
|
52 |
|
53 | All validators will be validated one by one, stopping on the first failure.
|
54 |
|
55 | The `all()` validator will only succeed when all validators provided also succeed.
|
56 |
|
57 | ---
|
58 | #### elementType
|
59 |
|
60 | Checks whether a property provides a type of element.
|
61 | The type of element can be provided in two forms:
|
62 | - tag name (string)
|
63 | - a return value of `React.createClass(...)`
|
64 |
|
65 | Example
|
66 | ```js
|
67 | propTypes: {
|
68 | componentClass: CustomPropTypes.elementType
|
69 | ```
|
70 | Then, `componentClass` can be set by doing:
|
71 | ```js
|
72 | <Component componentClass='span' />
|
73 | ```
|
74 | or
|
75 | ```js
|
76 | const Button = React.createClass(...);
|
77 | ...
|
78 | <Component componentClass={Button} />
|
79 | ```
|
80 |
|
81 | ---
|
82 | #### isRequiredForA11y(requiredType)
|
83 |
|
84 | This is kind of `React.PropTypes.<type>.isRequired` with the custom error message:
|
85 | `The prop <propName> is required for users using assistive technologies`
|
86 |
|
87 | Example
|
88 | ```js
|
89 | propTypes: {
|
90 | /**
|
91 | * An html id attribute, necessary for accessibility
|
92 | * @type {string}
|
93 | * @required
|
94 | */
|
95 | id: CustomPropTypes.isRequiredForA11y(React.PropTypes.string)
|
96 | ```
|
97 |
|
98 | ---
|
99 | #### keyOf(object)
|
100 |
|
101 | Checks whether provided string value is one of provided object's keys.
|
102 |
|
103 | Example
|
104 | ```js
|
105 | const SIZES = {
|
106 | 'large': 'lg',
|
107 | 'small': 'sm'
|
108 | }
|
109 |
|
110 | propTypes: {
|
111 | size: CustomPropTypes.keyOf(SIZES)
|
112 | }
|
113 |
|
114 | // this validates OK
|
115 | <Component size="large" />
|
116 |
|
117 | // this throws the error `expected one of ["large", "small"]`
|
118 | <Component size="middle" />
|
119 | ```
|
120 |
|
121 | A more extended example
|
122 | ```js
|
123 | const styleMaps = {
|
124 | CLASSES: {
|
125 | 'alert': 'alert',
|
126 | 'button': 'btn'
|
127 | ...
|
128 | SIZES: {
|
129 | 'large': 'lg',
|
130 | 'medium': 'md',
|
131 | 'small': 'sm',
|
132 | 'xsmall': 'xs'
|
133 | }
|
134 | ...
|
135 | propTypes: {
|
136 | /**
|
137 | * bootstrap className
|
138 | * @private
|
139 | */
|
140 | bsClass: CustomPropTypes.keyOf(styleMaps.CLASSES),
|
141 | /**
|
142 | * Style variants
|
143 | * @type {("default"|"primary"|"success"|"info"|"warning"|"danger"|"link")}
|
144 | */
|
145 | bsStyle: CustomPropTypes.keyOf(styleMaps.STYLES),
|
146 | /**
|
147 | * Size variants
|
148 | * @type {("xsmall"|"small"|"medium"|"large")}
|
149 | */
|
150 | bsSize: CustomPropTypes.keyOf(styleMaps.SIZES)
|
151 | }
|
152 | ```
|
153 |
|
154 | ---
|
155 | #### mountable
|
156 |
|
157 | Checks whether a prop provides a DOM element
|
158 | The element can be provided in two forms:
|
159 | - Directly passed
|
160 | - Or passed an object that has a `render` method
|
161 |
|
162 | Example
|
163 | ```js
|
164 | propTypes: {
|
165 | modal: React.PropTypes.node.isRequired,
|
166 | /**
|
167 | * The DOM Node that the Component will render it's children into
|
168 | */
|
169 | container: CustomPropTypes.mountable
|
170 | ```
|
171 |
|
172 | A variant of usage `<Overlay container={this}>`
|
173 | ```js
|
174 | const Example = React.createClass({
|
175 | getInitialState(){ return { show: true } },
|
176 | toggle(){ this.setState({ show: !this.state.show }) },
|
177 |
|
178 | render(){
|
179 | const tooltip = <Tooltip>Tooltip overload!</Tooltip>;
|
180 |
|
181 | return (
|
182 | <div>
|
183 | <Button ref='target' onClick={this.toggle}>
|
184 | Click me!
|
185 | </Button>
|
186 |
|
187 | <Overlay container={this}>
|
188 | { tooltip }
|
189 | </Overlay>
|
190 | </div>
|
191 | );
|
192 | }
|
193 | });
|
194 |
|
195 | React.render(<Example/>, mountNode);
|
196 | ```
|
197 |
|
198 | ---
|
199 | #### singlePropFrom(...propertyNames)
|
200 |
|
201 | Used when it needs to assure that only one of properties can be used.
|
202 |
|
203 | Imagine we need the `value` for our `ButtonInput` component could be set
|
204 | by only one of two ways:
|
205 | - through `children`
|
206 | - through `value` preperty
|
207 | But not both.
|
208 |
|
209 | Like this:
|
210 | ```js
|
211 | <ButtonInput> ButtonValue </ButtonInput>
|
212 | ```
|
213 | or
|
214 | ```js
|
215 | <ButtonInput value="ButtonValue" />
|
216 | ```
|
217 |
|
218 | But this should throw the `only one of the following may be provided` error
|
219 | ```js
|
220 | <ButtonInput value="ButtonValue"> SomeChildren </ButtonInput>
|
221 | ```
|
222 |
|
223 | The possible solution
|
224 | ```js
|
225 | import { singlePropFrom } from 'react-prop-types/singlePropFrom';
|
226 |
|
227 | const typeList = [React.PropTypes.number, React.PropTypes.string];
|
228 |
|
229 | function childrenValueValidation(props, propName, componentName) {
|
230 | let error = singlePropFrom('children', 'value')(props, propName, componentName);
|
231 | if (!error) {
|
232 | const oneOfType = React.PropTypes.oneOfType(typeList);
|
233 | error = oneOfType(props, propName, componentName);
|
234 | }
|
235 | return error;
|
236 | }
|
237 |
|
238 | ...
|
239 |
|
240 | ButtonInput.propTypes = {
|
241 | children: childrenValueValidation,
|
242 | value: childrenValueValidation
|
243 | ```
|
244 |
|
245 | ---
|
246 | #### deprecated(propType, explanation)
|
247 |
|
248 | Helps with properties deprecations
|
249 |
|
250 | Example
|
251 | ```js
|
252 | propTypes: {
|
253 | collapsable: deprecated(React.PropTypes.bool, 'Use "collapsible" instead.')
|
254 | ```
|
255 |
|
256 | In development mode it will write to the development console of a browser:
|
257 | ```
|
258 | "collapsable" property of "ComponentName" has been deprecated.
|
259 | Use "collapsible" instead.
|
260 | ```
|
261 |
|
262 | _Notice: this custom validator uses 'warning' package under the hood.
|
263 | And this package uses `console.error` channel instead of `console.warn`._
|
264 |
|
265 | [build-badge]: https://travis-ci.org/react-bootstrap/react-prop-types.svg?branch=master
|
266 | [build]: https://travis-ci.org/react-bootstrap/react-prop-types
|