lbry-desktop/ui/js/component/form.js

199 lines
4.3 KiB
JavaScript
Raw Normal View History

2017-06-06 23:19:12 +02:00
import React from "react";
import FormField from "component/formField";
import { Icon } from "component/common.js";
2016-11-22 21:19:08 +01:00
let formFieldCounter = 0;
2016-11-22 21:19:08 +01:00
export const formFieldNestedLabelTypes = ["radio", "checkbox"];
2017-06-06 06:21:55 +02:00
export function formFieldId() {
return "form-field-" + ++formFieldCounter;
2017-05-17 10:10:25 +02:00
}
2016-11-22 21:19:08 +01:00
export class Form extends React.PureComponent {
2017-09-19 00:16:00 +02:00
static propTypes = {
onSubmit: React.PropTypes.func.isRequired,
};
constructor(props) {
super(props);
}
handleSubmit(event) {
event.preventDefault();
this.props.onSubmit();
}
render() {
return (
<form onSubmit={event => this.handleSubmit(event)}>
{this.props.children}
</form>
);
}
}
2017-06-08 06:42:19 +02:00
export class FormRow extends React.PureComponent {
2017-05-17 10:10:25 +02:00
static propTypes = {
2017-06-06 23:19:12 +02:00
label: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.element,
]),
2017-07-19 01:00:13 +02:00
errorMessage: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.object,
]),
2017-04-10 14:32:40 +02:00
// helper: React.PropTypes.html,
2017-06-06 23:19:12 +02:00
};
2017-05-17 10:10:25 +02:00
2017-10-15 00:03:05 +02:00
static defaultProps = {
isFocus: false,
};
2017-05-17 10:10:25 +02:00
constructor(props) {
super(props);
this._field = null;
2017-06-06 23:19:12 +02:00
this._fieldRequiredText = __("This field is required");
2017-05-17 10:10:25 +02:00
2017-06-08 23:15:34 +02:00
this.state = this.getStateFromProps(props);
}
componentWillReceiveProps(nextProps) {
this.setState(this.getStateFromProps(nextProps));
}
getStateFromProps(props) {
return {
isError: !!props.errorMessage,
2017-06-08 23:15:34 +02:00
errorMessage: typeof props.errorMessage === "string"
? props.errorMessage
2017-07-19 01:00:13 +02:00
: props.errorMessage instanceof Error
? props.errorMessage.toString()
: "",
2017-05-17 10:10:25 +02:00
};
}
showError(text) {
2017-04-10 14:32:40 +02:00
this.setState({
isError: true,
errorMessage: text,
});
2017-05-17 10:10:25 +02:00
}
showRequiredError() {
2017-04-12 16:55:19 +02:00
this.showError(this._fieldRequiredText);
2017-05-17 10:10:25 +02:00
}
clearError(text) {
2017-04-12 16:55:19 +02:00
this.setState({
isError: false,
2017-06-06 23:19:12 +02:00
errorMessage: "",
2017-04-12 16:55:19 +02:00
});
2017-05-17 10:10:25 +02:00
}
getValue() {
return this._field.getValue();
2017-05-17 10:10:25 +02:00
}
getSelectedElement() {
return this._field.getSelectedElement();
2017-05-17 10:10:25 +02:00
}
2017-06-15 21:30:56 +02:00
getOptions() {
return this._field.getOptions();
2017-06-15 21:30:56 +02:00
}
2017-10-15 22:39:19 +02:00
focus() {
this._field.focus();
}
2017-10-15 00:03:05 +02:00
onFocus() {
this.setState({ isFocus: true });
}
onBlur() {
this.setState({ isFocus: false });
2017-05-17 10:10:25 +02:00
}
render() {
2017-04-10 14:32:40 +02:00
const fieldProps = Object.assign({}, this.props),
2017-06-06 23:19:12 +02:00
elementId = formFieldId(),
renderLabelInFormField = formFieldNestedLabelTypes.includes(
this.props.type
);
2017-04-10 14:32:40 +02:00
if (!renderLabelInFormField) {
delete fieldProps.label;
}
delete fieldProps.helper;
delete fieldProps.errorMessage;
2017-10-15 00:03:05 +02:00
delete fieldProps.isFocus;
2017-04-10 14:32:40 +02:00
2017-06-06 23:19:12 +02:00
return (
2017-10-15 21:50:13 +02:00
<div
className={"form-row" + (this.state.isFocus ? " form-row--focus" : "")}
>
2017-06-06 23:19:12 +02:00
{this.props.label && !renderLabelInFormField
? <div
className={
"form-row__label-row " +
2017-10-15 21:50:13 +02:00
(this.props.labelPrefix ? "form-row__label-row--prefix" : "")
2017-06-06 23:19:12 +02:00
}
>
<label
htmlFor={elementId}
className={
"form-field__label " +
2017-10-15 21:50:13 +02:00
(this.state.isError ? "form-field__label--error" : " ")
2017-06-06 23:19:12 +02:00
}
>
{this.props.label}
</label>
</div>
: ""}
<FormField
ref={ref => {
this._field = ref ? ref.getWrappedInstance() : null;
}}
hasError={this.state.isError}
2017-10-15 00:03:05 +02:00
onFocus={this.onFocus.bind(this)}
onBlur={this.onBlur.bind(this)}
{...fieldProps}
/>
2017-06-06 23:19:12 +02:00
{!this.state.isError && this.props.helper
? <div className="form-field__helper">{this.props.helper}</div>
: ""}
{this.state.isError
? <div className="form-field__error">{this.state.errorMessage}</div>
: ""}
</div>
);
2017-04-10 14:32:40 +02:00
}
2017-05-17 10:10:25 +02:00
}
export const Submit = props => {
const { title, label, icon, disabled } = props;
const className =
"button-block" +
" button-primary" +
" button-set-item" +
" button--submit" +
(disabled ? " disabled" : "");
const content = (
<span className="button__content">
{"icon" in props ? <Icon icon={icon} fixed={true} /> : null}
{label ? <span className="button-label">{label}</span> : null}
</span>
);
return (
<button type="submit" className={className} title={title}>
{content}
</button>
);
};