├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── docs ├── 0.bundle.js ├── bundle.js └── index.html ├── example ├── components │ ├── CodeMirror.js │ ├── Preview.js │ ├── index.js │ ├── sample.js │ └── utils.js └── index.js ├── lib └── index.js ├── package.json ├── src └── index.js ├── webpack ├── build.sh ├── index-template.html ├── webpack.config.dev.js ├── webpack.config.docs.js └── webpack.config.lib.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["es2015", {"modules": false}], "stage-0", "react"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | lib 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": {"browser": true}, 3 | "parser": "babel-eslint", 4 | "extends": "airbnb", 5 | "plugins": ["babel"], 6 | "rules": { 7 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }], 8 | "react/prefer-stateless-function": ["off"], 9 | "import/prefer-default-export": ["off"], 10 | "jsx-a11y/no-static-element-interactions": ["off"], 11 | "no-console": ["error", { allow: ["warn"] }], 12 | "semi": ["error", "never"], 13 | "max-len": ["error", 80] 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | docs 4 | example 5 | src 6 | wepback 7 | .babelrc 8 | .eslintrc 9 | .eslintignore 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 In Extenso Digital 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### [Live](https://inextensodigital.github.io/react-enhanced-form/) 2 | ### [Show-room](https://inextensodigital.github.io/react-showroom/#input) 3 | 4 | # react-enhanced-form 5 | 6 | ## Usage 7 | 8 | ```sh 9 | yarn add react-enhanced-form 10 | ``` 11 | 12 | ```jsx 13 | import React from 'react' 14 | import Input from 'react-enhanced-form' 15 | 16 | class Main extends React.Component { 17 | 18 | style = { 19 | default: { width: 300 }, 20 | onFocus: { borderBottom: '1px solid green' }, 21 | onError: { borderBottom: '1px solid red' } 22 | } 23 | 24 | check = newValue => newValue < 10 25 | format = value => `${value} $` 26 | 27 | render = () => ( 28 |
29 | console.log('change', data, error)} 33 | onMount={(data,error) => console.log('mount', data, error)} 34 | style={this.style} 35 | check={this.check} 36 | format={this.format} 37 | required 38 | /> 39 |
40 | ) 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | react-enhanced-form 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/components/CodeMirror.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import debounce from 'lodash/debounce' 3 | import PropTypes from 'prop-types' 4 | import styled from 'styled-components' 5 | import codemirror from 'codemirror/lib/codemirror' 6 | import 'codemirror/lib/codemirror.css' 7 | import 'codemirror/theme/material.css' 8 | import 'codemirror/mode/jsx/jsx' 9 | 10 | 11 | const Container = styled.div` 12 | width: 100%; 13 | height: 100%; 14 | .CodeMirror { 15 | height: 100%; 16 | } 17 | ` 18 | 19 | const normalizeLineEndings = (str) => { 20 | if (!str) return str 21 | return str.replace(/\r\n|\r/g, '\n') 22 | } 23 | 24 | class CodeMirror extends React.Component { 25 | componentWillMount = () => { 26 | this.componentWillReceiveProps = debounce(this.componentWillReceiveProps, 0) 27 | } 28 | 29 | componentDidMount = () => { 30 | this.codeMirror = codemirror.fromTextArea(this.textarea, this.props.options) 31 | this.codeMirror.on('change', this.codemirrorValueChanged) 32 | this.codeMirror.setValue(this.props.defaultValue || this.props.value || '') 33 | } 34 | 35 | componentWillReceiveProps = (nextProps) => { 36 | if (this.codeMirror && nextProps.value !== undefined) { 37 | const codeValue = normalizeLineEndings(this.codeMirror.getValue()) 38 | const propsValue = normalizeLineEndings(nextProps.value) 39 | 40 | if (codeValue !== propsValue) { 41 | this.codeMirror.setValue(nextProps.value) 42 | } 43 | } 44 | 45 | const options = nextProps.options 46 | if (options) { 47 | Object.keys(options).forEach((optionName) => { 48 | if (options[optionName]) { 49 | this.codeMirror.setOption(optionName, options[optionName]) 50 | } 51 | }) 52 | } 53 | } 54 | 55 | componentWillUnmount = () => { 56 | if (this.codeMirror) { this.codeMirror.toTextArea() } 57 | } 58 | 59 | codemirrorValueChanged = (doc, change) => { 60 | if (this.props.onChange && change.origin !== 'setValue') { 61 | this.props.onChange(doc.getValue(), change) 62 | } 63 | } 64 | 65 | render = () => ( 66 | 67 |