diff --git a/src/components/auth/PanelTransition.jsx b/src/components/auth/PanelTransition.jsx
index 7976099..027fdd1 100644
--- a/src/components/auth/PanelTransition.jsx
+++ b/src/components/auth/PanelTransition.jsx
@@ -4,7 +4,7 @@ import { connect } from 'react-redux';
import { TransitionMotion, spring } from 'react-motion';
import { Panel, PanelBody, PanelFooter, PanelHeader } from 'components/ui/Panel';
-import { Form } from 'components/ui/Form';
+import { Form } from 'components/ui/form';
import {helpLinks as helpLinksStyles} from 'components/auth/helpLinks.scss';
import panelStyles from 'components/ui/panel.scss';
import icons from 'components/ui/icons.scss';
diff --git a/src/components/auth/activation/Activation.jsx b/src/components/auth/activation/Activation.jsx
index c2217be..5a56fe0 100644
--- a/src/components/auth/activation/Activation.jsx
+++ b/src/components/auth/activation/Activation.jsx
@@ -4,7 +4,7 @@ import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet';
import buttons from 'components/ui/buttons.scss';
-import { Input } from 'components/ui/Form';
+import { Input } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
import styles from './activation.scss';
diff --git a/src/components/auth/activation/activation.scss b/src/components/auth/activation/activation.scss
index 0924ae8..22a4895 100644
--- a/src/components/auth/activation/activation.scss
+++ b/src/components/auth/activation/activation.scss
@@ -19,7 +19,7 @@
}
.activationCodeInput {
- composes: blueTextField from 'components/ui/form.scss';
+ composes: blueTextField from 'components/ui/form/form.scss';
text-align: center;
}
diff --git a/src/components/auth/changePassword/ChangePassword.jsx b/src/components/auth/changePassword/ChangePassword.jsx
index 3c29fd3..b87da0a 100644
--- a/src/components/auth/changePassword/ChangePassword.jsx
+++ b/src/components/auth/changePassword/ChangePassword.jsx
@@ -4,7 +4,7 @@ import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet';
import buttons from 'components/ui/buttons.scss';
-import { Input } from 'components/ui/Form';
+import { Input } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
import icons from 'components/ui/icons.scss';
diff --git a/src/components/auth/forgotPassword/ForgotPassword.jsx b/src/components/auth/forgotPassword/ForgotPassword.jsx
index 0ff039f..1d37462 100644
--- a/src/components/auth/forgotPassword/ForgotPassword.jsx
+++ b/src/components/auth/forgotPassword/ForgotPassword.jsx
@@ -4,7 +4,7 @@ import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet';
import buttons from 'components/ui/buttons.scss';
-import { Input } from 'components/ui/Form';
+import { Input } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
import messages from './ForgotPassword.messages';
diff --git a/src/components/auth/login/Login.jsx b/src/components/auth/login/Login.jsx
index 50d5267..61d482a 100644
--- a/src/components/auth/login/Login.jsx
+++ b/src/components/auth/login/Login.jsx
@@ -5,7 +5,7 @@ import Helmet from 'react-helmet';
import { Link } from 'react-router';
import buttons from 'components/ui/buttons.scss';
-import { Input } from 'components/ui/Form';
+import { Input } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
import passwordMessages from 'components/auth/password/Password.messages';
diff --git a/src/components/auth/password/Password.jsx b/src/components/auth/password/Password.jsx
index 54b14b8..2458ab8 100644
--- a/src/components/auth/password/Password.jsx
+++ b/src/components/auth/password/Password.jsx
@@ -6,7 +6,7 @@ import { Link } from 'react-router';
import buttons from 'components/ui/buttons.scss';
import icons from 'components/ui/icons.scss';
-import { Input, Checkbox } from 'components/ui/Form';
+import { Input, Checkbox } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
import styles from './password.scss';
diff --git a/src/components/auth/register/Register.jsx b/src/components/auth/register/Register.jsx
index 07fc4eb..68056eb 100644
--- a/src/components/auth/register/Register.jsx
+++ b/src/components/auth/register/Register.jsx
@@ -4,7 +4,7 @@ import { FormattedMessage as Message } from 'react-intl';
import Helmet from 'react-helmet';
import buttons from 'components/ui/buttons.scss';
-import { Input, Checkbox } from 'components/ui/Form';
+import { Input, Checkbox } from 'components/ui/form';
import BaseAuthBody from 'components/auth/BaseAuthBody';
import activationMessages from 'components/auth/activation/Activation.messages';
diff --git a/src/components/profile/changePassword/ChangePassword.jsx b/src/components/profile/changePassword/ChangePassword.jsx
index e85d970..e188a10 100644
--- a/src/components/profile/changePassword/ChangePassword.jsx
+++ b/src/components/profile/changePassword/ChangePassword.jsx
@@ -4,9 +4,8 @@ import { FormattedMessage as Message } from 'react-intl';
import { Link } from 'react-router';
import Helmet from 'react-helmet';
-import { Input, Button, Checkbox } from 'components/ui/Form';
+import { Input, Button, Checkbox, Form } from 'components/ui/form';
import FormModel from 'models/Form';
-import { Form } from 'components/ui/Form';
import styles from 'components/profile/profileForm.scss';
import messages from './ChangePassword.messages';
diff --git a/src/components/profile/passwordRequestForm/PasswordRequestForm.jsx b/src/components/profile/passwordRequestForm/PasswordRequestForm.jsx
index f0f6b36..6219d8f 100644
--- a/src/components/profile/passwordRequestForm/PasswordRequestForm.jsx
+++ b/src/components/profile/passwordRequestForm/PasswordRequestForm.jsx
@@ -3,7 +3,7 @@ import React, { Component, PropTypes } from 'react';
import { FormattedMessage as Message } from 'react-intl';
import FormModel from 'models/Form';
-import { Form, Button, Input } from 'components/ui/Form';
+import { Form, Button, Input } from 'components/ui/form';
import messages from './PasswordRequestForm.messages';
diff --git a/src/components/ui/Form.jsx b/src/components/ui/Form.jsx
deleted file mode 100644
index 133bc3c..0000000
--- a/src/components/ui/Form.jsx
+++ /dev/null
@@ -1,280 +0,0 @@
-import React, { Component, PropTypes } from 'react';
-
-import classNames from 'classnames';
-import { intlShape } from 'react-intl';
-
-import { uniqueId } from 'functions';
-
-import icons from './icons.scss';
-import styles from './form.scss';
-import buttons from './buttons.scss';
-
-export class Input extends Component {
- static displayName = 'Input';
-
- static propTypes = {
- placeholder: PropTypes.oneOfType([
- PropTypes.shape({
- id: PropTypes.string
- }),
- PropTypes.string
- ]),
- label: PropTypes.oneOfType([
- PropTypes.shape({
- id: PropTypes.string
- }),
- PropTypes.string
- ]).isRequired,
- error: PropTypes.string,
- icon: PropTypes.string,
- skin: PropTypes.oneOf(['dark', 'light']),
- color: PropTypes.oneOf(['green', 'blue', 'red', 'lightViolet', 'darkBlue'])
- };
-
- static contextTypes = {
- intl: intlShape.isRequired
- };
-
- render() {
- let { icon, color = 'green', skin = 'dark', error, label } = this.props;
-
- const props = {
- type: 'text',
- ...this.props
- };
-
- if (label) {
- if (!props.id) {
- props.id = uniqueId('input');
- }
-
- if (label.id) {
- label = this.context.intl.formatMessage(label);
- }
-
- label = (
-
- );
- }
-
- if (props.placeholder && props.placeholder.id) {
- props.placeholder = this.context.intl.formatMessage(props.placeholder);
- }
-
- let baseClass = styles.formRow;
- if (icon) {
- baseClass = styles.formIconRow;
- icon = (
-
- );
- }
-
- if (error) {
- error = (
-
- error
-
- );
- }
-
- return (
-
- {label}
-
-
- {icon}
-
- {error}
-
- );
- }
-
- setEl = (el) => {
- this.el = el;
- };
-
- getValue() {
- return this.el.value;
- }
-
- focus() {
- this.el.focus();
- setTimeout(this.el.focus.bind(this.el), 10);
- }
-}
-
-export class Checkbox extends Component {
- static displayName = 'Checkbox';
-
- static propTypes = {
- color: PropTypes.oneOf(['green', 'blue', 'red']),
- skin: PropTypes.oneOf(['dark', 'light']),
- label: PropTypes.oneOfType([
- PropTypes.shape({
- id: PropTypes.string
- }),
- PropTypes.string
- ]).isRequired
- };
-
- static contextTypes = {
- intl: intlShape.isRequired
- };
-
- render() {
- let { label, color = 'green', skin = 'dark' } = this.props;
-
- if (label && label.id) {
- label = this.context.intl.formatMessage(label);
- }
-
- return (
-
- );
- }
-
- setEl = (el) => {
- this.el = el;
- };
-
- getValue() {
- return this.el.checked ? 1 : 0;
- }
-
- focus() {
- this.el.focus();
- }
-}
-
-
-export class Button extends Component {
- static displayName = 'Button';
-
- static propTypes = {
- label: PropTypes.oneOfType([
- PropTypes.shape({
- id: PropTypes.string
- }),
- PropTypes.string
- ]).isRequired,
- block: PropTypes.bool,
- color: PropTypes.oneOf(['green', 'blue', 'red', 'lightViolet', 'darkBlue'])
- };
-
- static contextTypes = {
- intl: intlShape.isRequired
- };
-
- render() {
- const { color = 'green', block } = this.props;
-
- const props = {
- ...this.props
- };
-
- if (props.label.id) {
- props.label = this.context.intl.formatMessage(props.label);
- }
-
- return (
-
- );
- }
-}
-
-export class Form extends Component {
- static displayName = 'Form';
-
- static propTypes = {
- id: PropTypes.string, // and id, that uniquely identifies form contents
- isLoading: PropTypes.bool,
- onSubmit: PropTypes.func,
- onInvalid: PropTypes.func,
- children: PropTypes.oneOfType([
- PropTypes.arrayOf(PropTypes.node),
- PropTypes.node
- ])
- };
-
- static defaultProps = {
- id: 'default',
- isLoading: false,
- onSubmit() {},
- onInvalid() {}
- };
-
- state = {
- isTouched: false
- };
-
- componentWillReceiveProps(nextProps) {
- if (nextProps.id !== this.props.id) {
- this.setState({
- isTouched: false
- });
- }
- }
-
- render() {
- const {isLoading} = this.props;
-
- return (
-
- );
- }
-
- onFormSubmit = (event) => {
- event.preventDefault();
-
- if (!this.state.isTouched) {
- this.setState({
- isTouched: true
- });
- }
-
- const form = event.currentTarget;
-
- if (form.checkValidity()) {
- this.props.onSubmit();
- } else {
- const firstError = form.querySelectorAll(':invalid')[0];
- firstError.focus();
-
- let errorMessage = firstError.validationMessage;
- if (firstError.validity.valueMissing) {
- errorMessage = `error.${firstError.name}_required`;
- } else if (firstError.validity.typeMismatch) {
- errorMessage = `error.${firstError.name}_invalid`;
- }
-
- this.props.onInvalid(errorMessage);
- }
- };
-}
diff --git a/src/components/ui/form/Button.jsx b/src/components/ui/form/Button.jsx
new file mode 100644
index 0000000..e838139
--- /dev/null
+++ b/src/components/ui/form/Button.jsx
@@ -0,0 +1,45 @@
+import React, { Component, PropTypes } from 'react';
+
+import classNames from 'classnames';
+import { intlShape } from 'react-intl';
+
+import buttons from 'components/ui/buttons.scss';
+
+export default class Button extends Component {
+ static displayName = 'Button';
+
+ static propTypes = {
+ label: PropTypes.oneOfType([
+ PropTypes.shape({
+ id: PropTypes.string
+ }),
+ PropTypes.string
+ ]).isRequired,
+ block: PropTypes.bool,
+ color: PropTypes.oneOf(['green', 'blue', 'red', 'lightViolet', 'darkBlue'])
+ };
+
+ static contextTypes = {
+ intl: intlShape.isRequired
+ };
+
+ render() {
+ const { color = 'green', block } = this.props;
+
+ const props = {
+ ...this.props
+ };
+
+ if (props.label.id) {
+ props.label = this.context.intl.formatMessage(props.label);
+ }
+
+ return (
+
+ );
+ }
+}
diff --git a/src/components/ui/form/Checkbox.jsx b/src/components/ui/form/Checkbox.jsx
new file mode 100644
index 0000000..388f201
--- /dev/null
+++ b/src/components/ui/form/Checkbox.jsx
@@ -0,0 +1,55 @@
+import React, { Component, PropTypes } from 'react';
+
+import classNames from 'classnames';
+import { intlShape } from 'react-intl';
+
+import styles from './form.scss';
+
+export default class Checkbox extends Component {
+ static displayName = 'Checkbox';
+
+ static propTypes = {
+ color: PropTypes.oneOf(['green', 'blue', 'red']),
+ skin: PropTypes.oneOf(['dark', 'light']),
+ label: PropTypes.oneOfType([
+ PropTypes.shape({
+ id: PropTypes.string
+ }),
+ PropTypes.string
+ ]).isRequired
+ };
+
+ static contextTypes = {
+ intl: intlShape.isRequired
+ };
+
+ render() {
+ let { label, color = 'green', skin = 'dark' } = this.props;
+
+ if (label && label.id) {
+ label = this.context.intl.formatMessage(label);
+ }
+
+ return (
+
+ );
+ }
+
+ setEl = (el) => {
+ this.el = el;
+ };
+
+ getValue() {
+ return this.el.checked ? 1 : 0;
+ }
+
+ focus() {
+ this.el.focus();
+ }
+}
diff --git a/src/components/ui/form/Form.jsx b/src/components/ui/form/Form.jsx
new file mode 100644
index 0000000..1bf1d6e
--- /dev/null
+++ b/src/components/ui/form/Form.jsx
@@ -0,0 +1,87 @@
+import React, { Component, PropTypes } from 'react';
+
+import classNames from 'classnames';
+
+import styles from './form.scss';
+
+export default class Form extends Component {
+ static displayName = 'Form';
+
+ static propTypes = {
+ id: PropTypes.string, // and id, that uniquely identifies form contents
+ isLoading: PropTypes.bool,
+ onSubmit: PropTypes.func,
+ onInvalid: PropTypes.func,
+ children: PropTypes.oneOfType([
+ PropTypes.arrayOf(PropTypes.node),
+ PropTypes.node
+ ])
+ };
+
+ static defaultProps = {
+ id: 'default',
+ isLoading: false,
+ onSubmit() {},
+ onInvalid() {}
+ };
+
+ state = {
+ isTouched: false
+ };
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.id !== this.props.id) {
+ this.setState({
+ isTouched: false
+ });
+ }
+ }
+
+ render() {
+ const {isLoading} = this.props;
+
+ return (
+
+ );
+ }
+
+ onFormSubmit = (event) => {
+ event.preventDefault();
+
+ if (!this.state.isTouched) {
+ this.setState({
+ isTouched: true
+ });
+ }
+
+ const form = event.currentTarget;
+
+ if (form.checkValidity()) {
+ this.props.onSubmit();
+ } else {
+ const firstError = form.querySelectorAll(':invalid')[0];
+ firstError.focus();
+
+ let errorMessage = firstError.validationMessage;
+ if (firstError.validity.valueMissing) {
+ errorMessage = `error.${firstError.name}_required`;
+ } else if (firstError.validity.typeMismatch) {
+ errorMessage = `error.${firstError.name}_invalid`;
+ }
+
+ this.props.onInvalid(errorMessage);
+ }
+ };
+}
diff --git a/src/components/ui/form/Input.jsx b/src/components/ui/form/Input.jsx
new file mode 100644
index 0000000..dbf5d78
--- /dev/null
+++ b/src/components/ui/form/Input.jsx
@@ -0,0 +1,108 @@
+import React, { Component, PropTypes } from 'react';
+
+import classNames from 'classnames';
+import { intlShape } from 'react-intl';
+
+import { uniqueId } from 'functions';
+import icons from 'components/ui/icons.scss';
+
+import styles from './form.scss';
+
+export default class Input extends Component {
+ static displayName = 'Input';
+
+ static propTypes = {
+ placeholder: PropTypes.oneOfType([
+ PropTypes.shape({
+ id: PropTypes.string
+ }),
+ PropTypes.string
+ ]),
+ label: PropTypes.oneOfType([
+ PropTypes.shape({
+ id: PropTypes.string
+ }),
+ PropTypes.string
+ ]).isRequired,
+ error: PropTypes.string,
+ icon: PropTypes.string,
+ skin: PropTypes.oneOf(['dark', 'light']),
+ color: PropTypes.oneOf(['green', 'blue', 'red', 'lightViolet', 'darkBlue'])
+ };
+
+ static contextTypes = {
+ intl: intlShape.isRequired
+ };
+
+ render() {
+ let { icon, color = 'green', skin = 'dark', error, label } = this.props;
+
+ const props = {
+ type: 'text',
+ ...this.props
+ };
+
+ if (label) {
+ if (!props.id) {
+ props.id = uniqueId('input');
+ }
+
+ if (label.id) {
+ label = this.context.intl.formatMessage(label);
+ }
+
+ label = (
+
+ );
+ }
+
+ if (props.placeholder && props.placeholder.id) {
+ props.placeholder = this.context.intl.formatMessage(props.placeholder);
+ }
+
+ let baseClass = styles.formRow;
+ if (icon) {
+ baseClass = styles.formIconRow;
+ icon = (
+
+ );
+ }
+
+ if (error) {
+ error = (
+
+ error
+
+ );
+ }
+
+ return (
+
+ {label}
+
+
+ {icon}
+
+ {error}
+
+ );
+ }
+
+ setEl = (el) => {
+ this.el = el;
+ };
+
+ getValue() {
+ return this.el.value;
+ }
+
+ focus() {
+ this.el.focus();
+ setTimeout(this.el.focus.bind(this.el), 10);
+ }
+}
diff --git a/src/components/ui/form.scss b/src/components/ui/form/form.scss
similarity index 98%
rename from src/components/ui/form.scss
rename to src/components/ui/form/form.scss
index 7d4fb58..bb7c5f3 100644
--- a/src/components/ui/form.scss
+++ b/src/components/ui/form/form.scss
@@ -213,7 +213,7 @@
.checkbox {
composes: checkboxPosition;
- composes: checkmark from './icons.scss';
+ composes: checkmark from 'components/ui/icons.scss';
border: 2px #dcd8cd solid;
diff --git a/src/components/ui/images/loader_button.gif b/src/components/ui/form/images/loader_button.gif
similarity index 100%
rename from src/components/ui/images/loader_button.gif
rename to src/components/ui/form/images/loader_button.gif
diff --git a/src/components/ui/form/index.js b/src/components/ui/form/index.js
new file mode 100644
index 0000000..93cfaf5
--- /dev/null
+++ b/src/components/ui/form/index.js
@@ -0,0 +1,11 @@
+import Input from './Input';
+import Checkbox from './Checkbox';
+import Button from './Button';
+import Form from './Form';
+
+export {
+ Input,
+ Button,
+ Checkbox,
+ Form
+};