common: add Checkbox, Switch, FieldSet components

This commit is contained in:
David Sevilla Martin 2020-01-31 17:51:11 -05:00
parent dfedd585f5
commit 220a36c2e4
No known key found for this signature in database
GPG Key ID: F764F1417E16B15F
3 changed files with 110 additions and 0 deletions

View File

@ -0,0 +1,67 @@
import Component, { ComponentProps } from '../Component';
import LoadingIndicator from './LoadingIndicator';
import icon from '../helpers/icon';
export interface CheckboxProps extends ComponentProps {
/**
* Whether or not the checkbox is checked
*/
state: boolean;
/**
* Whether or not the checkbox is disabled.
*/
disabled: boolean;
/**
* A callback to run when the checkbox is checked/unchecked.
*/
onchange?: Function;
}
/**
* The `Checkbox` component defines a checkbox input.
*/
export default class Checkbox<T extends CheckboxProps = CheckboxProps> extends Component<CheckboxProps> {
/**
* Whether or not the checkbox's value is in the process of being saved.
*/
loading = false;
view() {
const className = classNames(
'Checkbox',
this.props.className,
this.props.state ? 'on' : 'off',
this.loading && 'loading',
this.props.disabled && 'disabled'
);
return (
<label className={className}>
<input
type="checkbox"
checked={this.props.state}
disabled={this.props.disabled}
onchange={m.withAttr('checked', this.onchange.bind(this))}
/>
<div className="Checkbox-display">{this.getDisplay()}</div>
{this.props.children}
</label>
);
}
/**
* Get the template for the checkbox's display (tick/cross icon).
*/
protected getDisplay() {
return this.loading ? LoadingIndicator.component({ size: 'tiny' }) : icon(this.props.state ? 'fas fa-check' : 'fas fa-times');
}
/**
* Run a callback when the state of the checkbox is changed.
*/
protected onchange(checked: boolean) {
if (this.props.onchange) this.props.onchange(checked, this);
}
}

View File

@ -0,0 +1,26 @@
import Component, { ComponentProps } from '../Component';
import listItems from '../helpers/listItems';
export interface FieldSetProps extends ComponentProps {
/**
* The title of this group of fields
*/
label: string;
}
/**
* The `FieldSet` component defines a collection of fields, displayed in a list
* underneath a title.
*
* The children should be an array of items to show in the fieldset.
*/
export default class FieldSet extends Component<FieldSetProps> {
view() {
return (
<fieldset className={this.props.className}>
<legend>{this.props.label}</legend>
<ul>{listItems(this.props.children)}</ul>
</fieldset>
);
}
}

View File

@ -0,0 +1,17 @@
import Checkbox from './Checkbox';
/**
* The `Switch` component is a `Checkbox`, but with a switch display instead of
* a tick/cross one.
*/
export default class Switch extends Checkbox {
static initProps(props) {
super.initProps(props);
props.className = `${props.className || ''} Checkbox--switch`;
}
getDisplay() {
return this.loading ? super.getDisplay() : '';
}
}