1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 | 'use strict'
|
8 |
|
9 | import {wrap} from 'breact'
|
10 | import classnames from 'classnames'
|
11 | import {ApStyle} from 'apeman-react-style'
|
12 | import uuid from 'uuid'
|
13 | import {spinalcase} from 'stringcase'
|
14 | import React, {PropTypes as types} from 'react'
|
15 | import {alpha} from 'apemancolor'
|
16 |
|
17 | const noop = () => null
|
18 |
|
19 |
|
20 | function withForm (Component) {
|
21 | return wrap(Component, {
|
22 | propTypes: {
|
23 |
|
24 | id: types.string,
|
25 |
|
26 | onSubmit: types.func,
|
27 |
|
28 | onCancel: types.func,
|
29 |
|
30 | onUpdate: types.func.isRequired,
|
31 |
|
32 | values: types.object.isRequired,
|
33 |
|
34 | errors: types.object,
|
35 |
|
36 | errorColor: types.string
|
37 | },
|
38 |
|
39 | getDefaultProps () {
|
40 | return {
|
41 | onSubmit: noop,
|
42 | onCancel: noop,
|
43 | onUpdate: noop,
|
44 | values: {},
|
45 | errors: null,
|
46 | errorColor: '#E11'
|
47 | }
|
48 | },
|
49 |
|
50 | render () {
|
51 | const s = this
|
52 | let { props } = s
|
53 | let {
|
54 | id = `form-${s.uuid}`,
|
55 | errors
|
56 | } = props
|
57 | let errorList = s.renderErrorList(errors, id)
|
58 | let errorStyle = s.renderErrorStyle(errors, id)
|
59 | let idOf = (name) => `${id}-${spinalcase(name)}`
|
60 | return (
|
61 | <Component { ...props }
|
62 | id={ id }
|
63 | idOf={ idOf }
|
64 | errorStyle={ errorStyle }
|
65 | errorList={ errorList }
|
66 | />
|
67 | )
|
68 | },
|
69 |
|
70 | componentWillMount () {
|
71 | const s = this
|
72 | s.uuid = uuid.v4()
|
73 | },
|
74 |
|
75 |
|
76 |
|
77 |
|
78 |
|
79 | renderErrorList (errors, id) {
|
80 | let names = Object.keys(errors || {})
|
81 | let className = classnames('ap-form-error-list', {
|
82 | 'ap-form-error-list-empty': names.length === 0
|
83 | })
|
84 | return (
|
85 | <ul className={ className }
|
86 | id={ `error-list-for-${id}` }
|
87 | >
|
88 | {
|
89 | names.map((name) => (
|
90 | <li key={ name }
|
91 | className='ap-form-error-list-item'
|
92 | >{ errors[ name ] }</li>
|
93 | ))
|
94 | }
|
95 | </ul>
|
96 | )
|
97 | },
|
98 |
|
99 | renderErrorStyle (errors, id) {
|
100 | const s = this
|
101 | let { errorColor } = s.props
|
102 | let data = Object.keys(errors || {})
|
103 | .reduce((data, name) => Object.assign(data, {
|
104 | [`#${id} [name="${name}"]`]: {
|
105 | borderColor: errorColor,
|
106 | backgroundColor: alpha(errorColor, 0.1)
|
107 | }
|
108 | }), {})
|
109 | return (
|
110 | <ApStyle data={ data }/>
|
111 | )
|
112 | }
|
113 | })
|
114 | }
|
115 |
|
116 | export default withForm
|