Checkbox ui component reimplemented

This commit is contained in:
NikolaBorislavovHristov 2019-01-30 17:03:49 +02:00
parent 8bd6acf0c7
commit a450ffc25f
4 changed files with 78 additions and 65 deletions

View file

@ -1,18 +1,11 @@
import React, { Component } from 'react';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Icon from 'stremio-icons/dom';
import { withFocusable } from 'stremio-common';
import { Input } from 'stremio-common';
import styles from './styles';
class Checkbox extends Component {
shouldComponentUpdate(nextProps) {
return nextProps.focusable !== this.props.focusable ||
nextProps.checked !== this.props.checked ||
nextProps.disabled !== this.props.disabled ||
nextProps.className !== this.props.className;
}
class Checkbox extends PureComponent {
onClick = (event) => {
event.preventDefault();
if (typeof this.props.onClick === 'function') {
@ -20,32 +13,48 @@ class Checkbox extends Component {
}
}
onDrag = (event) => {
if (typeof this.props.onDrag === 'function') {
this.props.onDrag(event);
}
if (!event.defaultPrevented) {
this.props.forwardedRef.current.blur();
}
}
onMouseOut = (event) => {
if (typeof this.props.onMouseOut === 'function') {
this.props.onMouseOut(event);
}
if (!event.defaultPrevented) {
this.props.forwardedRef.current.blur();
}
}
render() {
return (
<div className={classnames(this.props.className, styles['checkbox-container'], { 'checked': this.props.checked }, { 'disabled': this.props.disabled })}>
<Icon
className={styles['icon']}
icon={this.props.checked ? 'ic_check' : 'ic_box_empty'}
/>
<input
<label className={classnames(this.props.className, styles['checkbox-container'], { 'checked': this.props.checked }, { 'disabled': this.props.disabled })} onClick={this.onClick} onDrag={this.onDrag} onMouseOut={this.onMouseOut}>
<Input
ref={this.props.forwardedRef}
className={styles['native-checkbox']}
type={'checkbox'}
tabIndex={this.props.focusable ? 0 : -1}
disabled={this.props.disabled}
defaultChecked={this.props.checked}
onClick={this.onClick}
/>
</div>
<div className={styles['icon-container']}>
<Icon className={styles['icon']} icon={this.props.checked ? 'ic_check' : 'ic_box_empty'} />
</div>
{React.Children.only(this.props.children)}
</label>
);
}
}
Checkbox.propTypes = {
className: PropTypes.string,
disabled: PropTypes.bool.isRequired,
checked: PropTypes.bool.isRequired,
onClick: PropTypes.func
checked: PropTypes.bool.isRequired
};
Checkbox.defaultProps = {
@ -53,12 +62,8 @@ Checkbox.defaultProps = {
checked: false
};
const CheckboxWithFocusable = withFocusable(Checkbox);
CheckboxWithFocusable.displayName = 'CheckboxWithFocusable';
const CheckboxWithForwardedRef = React.forwardRef((props, ref) => (
<CheckboxWithFocusable {...props} forwardedRef={ref} />
<Checkbox {...props} forwardedRef={ref} />
));
CheckboxWithForwardedRef.displayName = 'CheckboxWithForwardedRef';

View file

@ -1,28 +1,34 @@
.checkbox-container {
position: relative;
z-index: 0;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--background-color);
.icon {
height: 100%;
fill: var(--icon-color);
.icon-container {
width: var(--icon-size);
height: var(--icon-size);
.icon {
width: 100%;
height: 100%;
fill: var(--icon-color);
background-color: var(--icon-background-color);
}
}
.native-checkbox {
position: absolute;
opacity: 0;
height: 0;
width: 0;
top: 0;
left: 0;
width: 0;
height: 0;
opacity: 0;
z-index: -1;
}
&:global(.checked) {
.icon {
padding: 10%;
.icon-container {
.icon {
padding: 10%;
}
}
}
}

View file

@ -4,14 +4,17 @@ import classnames from 'classnames';
import { Checkbox } from 'stremio-common';
import styles from './styles';
const linkOnClick = (event) => {
event.stopPropagation();
};
const ConsentCheckbox = React.forwardRef(({ className, label, link, href, checked, onClick }, ref) => (
<label className={classnames(styles['consent-checkbox-container'], className)}>
<Checkbox ref={ref} className={styles['checkbox']} checked={checked} onClick={onClick} />
<Checkbox ref={ref} className={classnames(styles['consent-checkbox-container'], className)} checked={checked} onClick={onClick}>
<div className={styles['label']}>
{label}
{link && href ? <a className={styles['link']} href={href} target={'_blank'} tabIndex={'-1'}> {link}</a> : null}
{link && href ? <a className={styles['link']} href={href} target={'_blank'} tabIndex={'-1'} onClick={linkOnClick}> {link}</a> : null}
</div>
</label>
</Checkbox>
));
ConsentCheckbox.displayName = 'ConsentCheckbox';

View file

@ -1,42 +1,41 @@
.consent-checkbox-container {
--icon-size: 1.2em;
--icon-color: var(--color-surface);
--icon-background-color: transparent;
padding: calc(var(--spacing) * 0.5);
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
cursor: pointer;
.checkbox {
--icon-color: var(--color-surface);
margin-right: calc(var(--spacing) * 0.5);
width: 1.3em;
height: 1.3em;
.label {
flex: 1;
margin-left: calc(var(--spacing) * 0.5);
line-height: 1.2em;
color: var(--color-surface);
&:global(.checked) {
--icon-color: var(--color-surfacelight);
background-color: var(--color-primary);
.link {
line-height: 1.2em;
color: var(--color-surfacelight);
}
}
.label {
line-height: 1.2em;
color: var(--color-surface);
}
.link {
line-height: 1.2em;
color: var(--color-surfacelight);
&:global(.checked) {
--icon-color: var(--color-surfacelight);
--icon-background-color: var(--color-primary);
}
&:focus-within, &:hover {
.checkbox {
--icon-color: var(--color-surfacelighter);
}
--icon-color: var(--color-surfacelighter);
.label {
color: var(--color-surfacelight);
}
.link {
color: var(--color-surfacelighter);
.link {
color: var(--color-surfacelighter);
}
}
}
}