From be900aa25ca205c467dcbbab9c284ef680441996 Mon Sep 17 00:00:00 2001 From: Shin'ya Ueoka Date: Mon, 29 Apr 2019 15:27:23 +0900 Subject: Clean settings components --- src/settings/actions/setting.js | 5 +- src/settings/components/form/BlacklistForm.jsx | 52 ++++++++++ src/settings/components/form/BlacklistForm.scss | 9 ++ src/settings/components/form/KeymapsForm.jsx | 47 +++++++++ src/settings/components/form/KeymapsForm.scss | 11 ++ src/settings/components/form/PropertiesForm.jsx | 60 +++++++++++ src/settings/components/form/PropertiesForm.scss | 12 +++ src/settings/components/form/SearchForm.jsx | 78 ++++++++++++++ src/settings/components/form/SearchForm.scss | 28 +++++ src/settings/components/form/blacklist-form.jsx | 52 ---------- src/settings/components/form/blacklist-form.scss | 9 -- src/settings/components/form/keymaps-form.jsx | 118 ---------------------- src/settings/components/form/keymaps-form.scss | 11 -- src/settings/components/form/properties-form.jsx | 60 ----------- src/settings/components/form/properties-form.scss | 12 --- src/settings/components/form/search-form.jsx | 78 -------------- src/settings/components/form/search-form.scss | 28 ----- src/settings/components/index.jsx | 12 +-- src/settings/components/ui/AddButton.jsx | 12 +++ src/settings/components/ui/AddButton.scss | 13 +++ src/settings/components/ui/DeleteButton.jsx | 12 +++ src/settings/components/ui/DeleteButton.scss | 13 +++ src/settings/components/ui/Input.jsx | 52 ++++++++++ src/settings/components/ui/Input.scss | 29 ++++++ src/settings/components/ui/add-button.jsx | 12 --- src/settings/components/ui/add-button.scss | 13 --- src/settings/components/ui/delete-button.jsx | 12 --- src/settings/components/ui/delete-button.scss | 13 --- src/settings/components/ui/input.jsx | 52 ---------- src/settings/components/ui/input.scss | 29 ------ src/settings/index.jsx | 7 +- src/settings/keymaps.js | 74 ++++++++++++++ 32 files changed, 514 insertions(+), 511 deletions(-) create mode 100644 src/settings/components/form/BlacklistForm.jsx create mode 100644 src/settings/components/form/BlacklistForm.scss create mode 100644 src/settings/components/form/KeymapsForm.jsx create mode 100644 src/settings/components/form/KeymapsForm.scss create mode 100644 src/settings/components/form/PropertiesForm.jsx create mode 100644 src/settings/components/form/PropertiesForm.scss create mode 100644 src/settings/components/form/SearchForm.jsx create mode 100644 src/settings/components/form/SearchForm.scss delete mode 100644 src/settings/components/form/blacklist-form.jsx delete mode 100644 src/settings/components/form/blacklist-form.scss delete mode 100644 src/settings/components/form/keymaps-form.jsx delete mode 100644 src/settings/components/form/keymaps-form.scss delete mode 100644 src/settings/components/form/properties-form.jsx delete mode 100644 src/settings/components/form/properties-form.scss delete mode 100644 src/settings/components/form/search-form.jsx delete mode 100644 src/settings/components/form/search-form.scss create mode 100644 src/settings/components/ui/AddButton.jsx create mode 100644 src/settings/components/ui/AddButton.scss create mode 100644 src/settings/components/ui/DeleteButton.jsx create mode 100644 src/settings/components/ui/DeleteButton.scss create mode 100644 src/settings/components/ui/Input.jsx create mode 100644 src/settings/components/ui/Input.scss delete mode 100644 src/settings/components/ui/add-button.jsx delete mode 100644 src/settings/components/ui/add-button.scss delete mode 100644 src/settings/components/ui/delete-button.jsx delete mode 100644 src/settings/components/ui/delete-button.scss delete mode 100644 src/settings/components/ui/input.jsx delete mode 100644 src/settings/components/ui/input.scss create mode 100644 src/settings/keymaps.js (limited to 'src/settings') diff --git a/src/settings/actions/setting.js b/src/settings/actions/setting.js index 0277159..8844252 100644 --- a/src/settings/actions/setting.js +++ b/src/settings/actions/setting.js @@ -1,8 +1,8 @@ import actions from 'settings/actions'; import * as validator from 'shared/settings/validator'; -import KeymapsForm from '../components/form/keymaps-form'; import * as settingsValues from 'shared/settings/values'; import * as settingsStorage from 'shared/settings/storage'; +import keymaps from '../keymaps'; const load = async() => { let settings = await settingsStorage.loadRaw(); @@ -29,8 +29,7 @@ const save = async(settings) => { const switchToForm = (json) => { try { validator.validate(JSON.parse(json)); - // AllowdOps filters operations, this is dirty dependency - let form = settingsValues.formFromJson(json, KeymapsForm.AllowdOps); + let form = settingsValues.formFromJson(json, keymaps.allowedOps); return { type: actions.SETTING_SWITCH_TO_FORM, form, diff --git a/src/settings/components/form/BlacklistForm.jsx b/src/settings/components/form/BlacklistForm.jsx new file mode 100644 index 0000000..13571f1 --- /dev/null +++ b/src/settings/components/form/BlacklistForm.jsx @@ -0,0 +1,52 @@ +import './BlacklistForm.scss'; +import AddButton from '../ui/AddButton'; +import DeleteButton from '../ui/DeleteButton'; +import React from 'react'; + +class BlacklistForm extends React.Component { + + render() { + let value = this.props.value; + if (!value) { + value = []; + } + + return
+ { + value.map((url, index) => { + return
+ + +
; + }) + } + +
; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let name = e.target.name; + let index = e.target.getAttribute('data-index'); + let next = this.props.value ? this.props.value.slice() : []; + + if (name === 'url') { + next[index] = e.target.value; + } else if (name === 'add') { + next.push(''); + } else if (name === 'delete') { + next.splice(index, 1); + } + + this.props.onChange(next); + } +} + +export default BlacklistForm; diff --git a/src/settings/components/form/BlacklistForm.scss b/src/settings/components/form/BlacklistForm.scss new file mode 100644 index 0000000..a230d0d --- /dev/null +++ b/src/settings/components/form/BlacklistForm.scss @@ -0,0 +1,9 @@ +.form-blacklist-form { + &-row { + display: flex; + + .column-url { + flex: 1; + } + } +} diff --git a/src/settings/components/form/KeymapsForm.jsx b/src/settings/components/form/KeymapsForm.jsx new file mode 100644 index 0000000..25a3710 --- /dev/null +++ b/src/settings/components/form/KeymapsForm.jsx @@ -0,0 +1,47 @@ +import './KeymapsForm.scss'; +import React from 'react'; +import Input from '../ui/Input'; +import keymaps from '../../keymaps'; + +class KeymapsForm extends React.Component { + + render() { + let values = this.props.value; + if (!values) { + values = {}; + } + return
+ { + keymaps.fields.map((group, index) => { + return
+ { + group.map((field) => { + let name = field[0]; + let label = field[1]; + let value = values[name]; + return ; + }) + } +
; + }) + } +
; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let next = { ...this.props.value }; + next[e.target.name] = e.target.value; + + this.props.onChange(next); + } +} + +export default KeymapsForm; diff --git a/src/settings/components/form/KeymapsForm.scss b/src/settings/components/form/KeymapsForm.scss new file mode 100644 index 0000000..1a4e5cd --- /dev/null +++ b/src/settings/components/form/KeymapsForm.scss @@ -0,0 +1,11 @@ +.form-keymaps-form { + column-count: 3; + + &-field-group { + margin-top: 24px; + } + + &-field-group:first-of-type { + margin-top: 24px; + } +} diff --git a/src/settings/components/form/PropertiesForm.jsx b/src/settings/components/form/PropertiesForm.jsx new file mode 100644 index 0000000..77991fc --- /dev/null +++ b/src/settings/components/form/PropertiesForm.jsx @@ -0,0 +1,60 @@ +import './PropertiesForm.scss'; +import React from 'react'; + +class PropertiesForm extends React.Component { + + render() { + let types = this.props.types; + let value = this.props.value; + if (!value) { + value = {}; + } + + return
+ { + Object.keys(types).map((name) => { + let type = types[name]; + let inputType = null; + if (type === 'string') { + inputType = 'text'; + } else if (type === 'number') { + inputType = 'number'; + } else if (type === 'boolean') { + inputType = 'checkbox'; + } + return
+ +
; + }) + } +
; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let name = e.target.name; + let next = { ...this.props.value }; + if (e.target.type.toLowerCase() === 'checkbox') { + next[name] = e.target.checked; + } else if (e.target.type.toLowerCase() === 'number') { + next[name] = Number(e.target.value); + } else { + next[name] = e.target.value; + } + + this.props.onChange(next); + } +} + +export default PropertiesForm; diff --git a/src/settings/components/form/PropertiesForm.scss b/src/settings/components/form/PropertiesForm.scss new file mode 100644 index 0000000..7c9e167 --- /dev/null +++ b/src/settings/components/form/PropertiesForm.scss @@ -0,0 +1,12 @@ +.form-properties-form { + &-row { + .column-name { + display: inline-block; + min-width: 5rem; + font-weight: bold; + } + .column-input { + line-height: 2.2rem; + } + } +} diff --git a/src/settings/components/form/SearchForm.jsx b/src/settings/components/form/SearchForm.jsx new file mode 100644 index 0000000..f52fd5f --- /dev/null +++ b/src/settings/components/form/SearchForm.jsx @@ -0,0 +1,78 @@ +import './SearchForm.scss'; +import React from 'react'; +import AddButton from '../ui/AddButton'; +import DeleteButton from '../ui/DeleteButton'; + +class SearchForm extends React.Component { + + render() { + let value = this.props.value; + if (!value) { + value = { default: '', engines: []}; + } + if (!value.engines) { + value.engines = []; + } + + return
+
+
Name
+
URL
+
Default
+
+ { + value.engines.map((engine, index) => { + return
+ + +
+ + +
+
; + }) + } + +
; + } + + bindValue(e) { + if (!this.props.onChange) { + return; + } + + let value = this.props.value; + let name = e.target.name; + let index = e.target.getAttribute('data-index'); + let next = { + default: value.default, + engines: value.engines ? value.engines.slice() : [], + }; + + if (name === 'name') { + next.engines[index][0] = e.target.value; + next.default = this.props.value.engines[index][0]; + } else if (name === 'url') { + next.engines[index][1] = e.target.value; + } else if (name === 'default') { + next.default = this.props.value.engines[index][0]; + } else if (name === 'add') { + next.engines.push(['', '']); + } else if (name === 'delete') { + next.engines.splice(index, 1); + } + + this.props.onChange(next); + } +} + +export default SearchForm; diff --git a/src/settings/components/form/SearchForm.scss b/src/settings/components/form/SearchForm.scss new file mode 100644 index 0000000..26b2f44 --- /dev/null +++ b/src/settings/components/form/SearchForm.scss @@ -0,0 +1,28 @@ +.form-search-form { + @mixin row-base { + display: flex; + + .column-name { + flex: 1; + min-width: 0; + } + .column-url { + flex: 5; + min-width: 0; + } + .column-option { + text-align: right; + flex-basis: 5rem; + } + } + + &-header { + @include row-base; + + font-weight: bold; + } + + &-row { + @include row-base; + } +} diff --git a/src/settings/components/form/blacklist-form.jsx b/src/settings/components/form/blacklist-form.jsx deleted file mode 100644 index 492c3af..0000000 --- a/src/settings/components/form/blacklist-form.jsx +++ /dev/null @@ -1,52 +0,0 @@ -import './blacklist-form.scss'; -import AddButton from '../ui/add-button'; -import DeleteButton from '../ui/delete-button'; -import React from 'react'; - -class BlacklistForm extends React.Component { - - render() { - let value = this.props.value; - if (!value) { - value = []; - } - - return
- { - value.map((url, index) => { - return
- - -
; - }) - } - -
; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let name = e.target.name; - let index = e.target.getAttribute('data-index'); - let next = this.props.value ? this.props.value.slice() : []; - - if (name === 'url') { - next[index] = e.target.value; - } else if (name === 'add') { - next.push(''); - } else if (name === 'delete') { - next.splice(index, 1); - } - - this.props.onChange(next); - } -} - -export default BlacklistForm; diff --git a/src/settings/components/form/blacklist-form.scss b/src/settings/components/form/blacklist-form.scss deleted file mode 100644 index a230d0d..0000000 --- a/src/settings/components/form/blacklist-form.scss +++ /dev/null @@ -1,9 +0,0 @@ -.form-blacklist-form { - &-row { - display: flex; - - .column-url { - flex: 1; - } - } -} diff --git a/src/settings/components/form/keymaps-form.jsx b/src/settings/components/form/keymaps-form.jsx deleted file mode 100644 index 8c0a83f..0000000 --- a/src/settings/components/form/keymaps-form.jsx +++ /dev/null @@ -1,118 +0,0 @@ -import './keymaps-form.scss'; -import React from 'react'; -import Input from '../ui/input'; - -const KeyMapFields = [ - [ - ['scroll.vertically?{"count":1}', 'Scroll down'], - ['scroll.vertically?{"count":-1}', 'Scroll up'], - ['scroll.horizonally?{"count":-1}', 'Scroll left'], - ['scroll.horizonally?{"count":1}', 'Scroll right'], - ['scroll.home', 'Scroll to leftmost'], - ['scroll.end', 'Scroll to rightmost'], - ['scroll.top', 'Scroll to top'], - ['scroll.bottom', 'Scroll to bottom'], - ['scroll.pages?{"count":-0.5}', 'Scroll up by half of screen'], - ['scroll.pages?{"count":0.5}', 'Scroll down by half of screen'], - ['scroll.pages?{"count":-1}', 'Scroll up by a screen'], - ['scroll.pages?{"count":1}', 'Scroll down by a screen'], - ], [ - ['mark.set.prefix', 'Set mark at current position'], - ['mark.jump.prefix', 'Jump to the mark'], - ], [ - ['tabs.close', 'Close a tab'], - ['tabs.close.right', 'Close tabs to the right'], - ['tabs.reopen', 'Reopen closed tab'], - ['tabs.next?{"count":1}', 'Select next Tab'], - ['tabs.prev?{"count":1}', 'Select prev Tab'], - ['tabs.first', 'Select first tab'], - ['tabs.last', 'Select last tab'], - ['tabs.reload?{"cache":false}', 'Reload current tab'], - ['tabs.reload?{"cache":true}', 'Reload with no caches'], - ['tabs.pin.toggle', 'Toggle pinned state'], - ['tabs.duplicate', 'Duplicate a tab'], - ], [ - ['follow.start?{"newTab":false}', 'Follow a link'], - ['follow.start?{"newTab":true}', 'Follow a link in new tab'], - ['navigate.history.prev', 'Go back in histories'], - ['navigate.history.next', 'Go forward in histories'], - ['navigate.link.next', 'Open next link'], - ['navigate.link.prev', 'Open previous link'], - ['navigate.parent', 'Go to parent directory'], - ['navigate.root', 'Go to root directory'], - ['page.source', 'Open page source'], - ['page.home', 'Open start page to current tab'], - ['page.home?{"newTab":true}', 'Open start page in new tab'], - ['focus.input', 'Focus input'], - ], [ - ['find.start', 'Start find mode'], - ['find.next', 'Find next word'], - ['find.prev', 'Find previous word'], - ], [ - ['command.show', 'Open console'], - ['command.show.open?{"alter":false}', 'Open URL'], - ['command.show.open?{"alter":true}', 'Alter URL'], - ['command.show.tabopen?{"alter":false}', 'Open URL in new Tab'], - ['command.show.tabopen?{"alter":true}', 'Alter URL in new Tab'], - ['command.show.winopen?{"alter":false}', 'Open URL in new window'], - ['command.show.winopen?{"alter":true}', 'Alter URL in new window'], - ['command.show.buffer', 'Open buffer command'], - ['command.show.addbookmark?{"alter":true}', 'Open addbookmark command'], - ], [ - ['addon.toggle.enabled', 'Enable or disable'], - ['urls.yank', 'Copy current URL'], - ['urls.paste?{"newTab":false}', 'Open clipboard\'s URL in current tab'], - ['urls.paste?{"newTab":true}', 'Open clipboard\'s URL in new tab'], - ['zoom.in', 'Zoom-in'], - ['zoom.out', 'Zoom-out'], - ['zoom.neutral', 'Reset zoom level'], - ['page.source', 'Open a page source'], - ] -]; - -const AllowdOps = [].concat(...KeyMapFields.map(group => group.map(e => e[0]))); - -class KeymapsForm extends React.Component { - - render() { - let values = this.props.value; - if (!values) { - values = {}; - } - return
- { - KeyMapFields.map((group, index) => { - return
- { - group.map((field) => { - let name = field[0]; - let label = field[1]; - let value = values[name]; - return ; - }) - } -
; - }) - } -
; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let next = { ...this.props.value }; - next[e.target.name] = e.target.value; - - this.props.onChange(next); - } -} - -KeymapsForm.AllowdOps = AllowdOps; - -export default KeymapsForm; diff --git a/src/settings/components/form/keymaps-form.scss b/src/settings/components/form/keymaps-form.scss deleted file mode 100644 index 1a4e5cd..0000000 --- a/src/settings/components/form/keymaps-form.scss +++ /dev/null @@ -1,11 +0,0 @@ -.form-keymaps-form { - column-count: 3; - - &-field-group { - margin-top: 24px; - } - - &-field-group:first-of-type { - margin-top: 24px; - } -} diff --git a/src/settings/components/form/properties-form.jsx b/src/settings/components/form/properties-form.jsx deleted file mode 100644 index 7d591d5..0000000 --- a/src/settings/components/form/properties-form.jsx +++ /dev/null @@ -1,60 +0,0 @@ -import './properties-form.scss'; -import React from 'react'; - -class PropertiesForm extends React.Component { - - render() { - let types = this.props.types; - let value = this.props.value; - if (!value) { - value = {}; - } - - return
- { - Object.keys(types).map((name) => { - let type = types[name]; - let inputType = null; - if (type === 'string') { - inputType = 'text'; - } else if (type === 'number') { - inputType = 'number'; - } else if (type === 'boolean') { - inputType = 'checkbox'; - } - return
- -
; - }) - } -
; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let name = e.target.name; - let next = { ...this.props.value }; - if (e.target.type.toLowerCase() === 'checkbox') { - next[name] = e.target.checked; - } else if (e.target.type.toLowerCase() === 'number') { - next[name] = Number(e.target.value); - } else { - next[name] = e.target.value; - } - - this.props.onChange(next); - } -} - -export default PropertiesForm; diff --git a/src/settings/components/form/properties-form.scss b/src/settings/components/form/properties-form.scss deleted file mode 100644 index 7c9e167..0000000 --- a/src/settings/components/form/properties-form.scss +++ /dev/null @@ -1,12 +0,0 @@ -.form-properties-form { - &-row { - .column-name { - display: inline-block; - min-width: 5rem; - font-weight: bold; - } - .column-input { - line-height: 2.2rem; - } - } -} diff --git a/src/settings/components/form/search-form.jsx b/src/settings/components/form/search-form.jsx deleted file mode 100644 index 81204f3..0000000 --- a/src/settings/components/form/search-form.jsx +++ /dev/null @@ -1,78 +0,0 @@ -import './search-form.scss'; -import React from 'react'; -import AddButton from '../ui/add-button'; -import DeleteButton from '../ui/delete-button'; - -class SearchForm extends React.Component { - - render() { - let value = this.props.value; - if (!value) { - value = { default: '', engines: []}; - } - if (!value.engines) { - value.engines = []; - } - - return
-
-
Name
-
URL
-
Default
-
- { - value.engines.map((engine, index) => { - return
- - -
- - -
-
; - }) - } - -
; - } - - bindValue(e) { - if (!this.props.onChange) { - return; - } - - let value = this.props.value; - let name = e.target.name; - let index = e.target.getAttribute('data-index'); - let next = { - default: value.default, - engines: value.engines ? value.engines.slice() : [], - }; - - if (name === 'name') { - next.engines[index][0] = e.target.value; - next.default = this.props.value.engines[index][0]; - } else if (name === 'url') { - next.engines[index][1] = e.target.value; - } else if (name === 'default') { - next.default = this.props.value.engines[index][0]; - } else if (name === 'add') { - next.engines.push(['', '']); - } else if (name === 'delete') { - next.engines.splice(index, 1); - } - - this.props.onChange(next); - } -} - -export default SearchForm; diff --git a/src/settings/components/form/search-form.scss b/src/settings/components/form/search-form.scss deleted file mode 100644 index 26b2f44..0000000 --- a/src/settings/components/form/search-form.scss +++ /dev/null @@ -1,28 +0,0 @@ -.form-search-form { - @mixin row-base { - display: flex; - - .column-name { - flex: 1; - min-width: 0; - } - .column-url { - flex: 5; - min-width: 0; - } - .column-option { - text-align: right; - flex-basis: 5rem; - } - } - - &-header { - @include row-base; - - font-weight: bold; - } - - &-row { - @include row-base; - } -} diff --git a/src/settings/components/index.jsx b/src/settings/components/index.jsx index 9dae25e..affa2e9 100644 --- a/src/settings/components/index.jsx +++ b/src/settings/components/index.jsx @@ -1,11 +1,11 @@ import './site.scss'; import React from 'react'; import { connect } from 'react-redux'; -import Input from './ui/input'; -import SearchForm from './form/search-form'; -import KeymapsForm from './form/keymaps-form'; -import BlacklistForm from './form/blacklist-form'; -import PropertiesForm from './form/properties-form'; +import Input from './ui/Input'; +import SearchForm from './form/SearchForm'; +import KeymapsForm from './form/KeymapsForm'; +import BlacklistForm from './form/BlacklistForm'; +import PropertiesForm from './form/PropertiesForm'; import * as properties from 'shared/settings/properties'; import * as settingActions from 'settings/actions/setting'; @@ -136,7 +136,7 @@ class SettingsComponent extends React.Component { this.props.dispatch(settingActions.switchToForm(this.props.json)); } - let settings = this.props.getState(); + let settings = this.props.store.getState(); this.props.dispatch(settingActions.save(settings)); } } diff --git a/src/settings/components/ui/AddButton.jsx b/src/settings/components/ui/AddButton.jsx new file mode 100644 index 0000000..185a03b --- /dev/null +++ b/src/settings/components/ui/AddButton.jsx @@ -0,0 +1,12 @@ +import './AddButton.scss'; +import React from 'react'; + +class AddButton extends React.Component { + render() { + return ; + } +} + +export default AddButton; diff --git a/src/settings/components/ui/AddButton.scss b/src/settings/components/ui/AddButton.scss new file mode 100644 index 0000000..beb5688 --- /dev/null +++ b/src/settings/components/ui/AddButton.scss @@ -0,0 +1,13 @@ +.ui-add-button { + border: none; + padding: 4; + display: inline; + background: none; + font-weight: bold; + color: green; + cursor: pointer; + + &:hover { + color: darkgreen; + } +} diff --git a/src/settings/components/ui/DeleteButton.jsx b/src/settings/components/ui/DeleteButton.jsx new file mode 100644 index 0000000..75811cd --- /dev/null +++ b/src/settings/components/ui/DeleteButton.jsx @@ -0,0 +1,12 @@ +import './DeleteButton.scss'; +import React from 'react'; + +class DeleteButton extends React.Component { + render() { + return ; + } +} + +export default DeleteButton; diff --git a/src/settings/components/ui/DeleteButton.scss b/src/settings/components/ui/DeleteButton.scss new file mode 100644 index 0000000..5932a72 --- /dev/null +++ b/src/settings/components/ui/DeleteButton.scss @@ -0,0 +1,13 @@ + +.ui-delete-button { + border: none; + padding: 4; + display: inline; + background: none; + color: red; + cursor: pointer; + + &:hover { + color: darkred; + } +} diff --git a/src/settings/components/ui/Input.jsx b/src/settings/components/ui/Input.jsx new file mode 100644 index 0000000..d090f5b --- /dev/null +++ b/src/settings/components/ui/Input.jsx @@ -0,0 +1,52 @@ +import React from 'react'; +import './Input.scss'; + +class Input extends React.Component { + + renderText(props) { + let inputClassName = props.error ? 'input-error' : ''; + return
+ + +
; + } + + renderRadio(props) { + let inputClassName = props.error ? 'input-error' : ''; + return
+ +
; + } + + renderTextArea(props) { + let inputClassName = props.error ? 'input-error' : ''; + return
+ +