ColorInput implemented with Modal

This commit is contained in:
NikolaBorislavovHristov 2019-10-05 23:42:18 +03:00
parent 41841fefaf
commit 645ae7931d
2 changed files with 97 additions and 64 deletions

View file

@ -1,59 +1,75 @@
const React = require('react');
const PropTypes = require('prop-types');
const Icon = require('stremio-icons/dom');
const { Modal } = require('stremio-router');
const Button = require('stremio/common/Button');
const Popup = require('stremio/common/Popup');
const useBinaryState = require('stremio/common/useBinaryState');
const ColorPicker = require('./ColorPicker');
const styles = require('./styles');
const ColorInput = ({ className, id, value, onChange, ...props }) => {
const [popupOpen, openPopup, closePopup, togglePopup] = useBinaryState(false);
const [selectedColor, setSelectedColor] = React.useState(value);
const ColorInput = ({ className, value, onChange, ...props }) => {
const labelRef = React.useRef(null);
const [modalOpen, openModal, closeModal] = useBinaryState(false);
const [tempValue, setTempValue] = React.useState(value);
React.useEffect(() => {
setSelectedColor(value);
}, [value]);
const onSubmit = React.useCallback((event) => {
setTempValue(value);
}, [value, modalOpen]);
const modalContainerOnMouseDown = React.useCallback((event) => {
if (!event.nativeEvent.closeModalPrevented) {
closeModal();
}
}, []);
const modalContentOnMouseDown = React.useCallback((event) => {
event.nativeEvent.closeModalPrevented = true;
}, []);
const submitButtonOnClick = React.useCallback((event) => {
event.type = 'change';
event.currentTarget = labelRef.current;
event.currentTarget.value = tempValue;
if (typeof onChange === 'function') {
event.nativeEvent.value = selectedColor;
onChange(event);
}
closePopup();
}, [selectedColor, onChange]);
event.currentTarget.value = undefined;
if (!event.nativeEvent.closeModalPrevented) {
closeModal();
}
}, [tempValue, onChange]);
return (
<Popup
open={popupOpen}
menuModalClassName={styles['color-input-modal-container']}
menuRelativePosition={false}
renderLabel={(ref) => (
<Button
{...props}
ref={ref}
style={{ backgroundColor: value }}
className={className}
title={selectedColor}
onClick={togglePopup}
/>
)}
renderMenu={() => (
<div className={styles['color-input-container']}>
<Button className={styles['close-button-container']} onClick={closePopup}>
<Icon className={styles['icon']} icon={'ic_x'} />
</Button>
<div className={styles['title']}>Choose a color:</div>
<ColorPicker className={styles['color-picker']} value={selectedColor} onChange={setSelectedColor} />
<Button className={styles['submit-button-container']} data-id={id} onClick={onSubmit}>Select</Button>
</div>
)}
onCloseRequest={closePopup}
/>
<React.Fragment>
<Button
ref={labelRef}
title={value}
{...props}
className={className}
style={{ backgroundColor: value }}
onClick={openModal}
/>
{
modalOpen ?
<Modal className={styles['color-input-modal-container']} onMouseDown={modalContainerOnMouseDown}>
<div className={styles['color-input-container']} onMouseDown={modalContentOnMouseDown}>
<div className={styles['header-container']}>
<div className={styles['title']}>Choose a color:</div>
<Button className={styles['close-button-container']} title={'Close'} onClick={closeModal}>
<Icon className={styles['icon']} icon={'ic_x'} />
</Button>
</div>
<ColorPicker className={styles['color-picker']} value={tempValue} onChange={setTempValue} />
<Button className={styles['submit-button-container']} title={'Submit'} onClick={submitButtonOnClick}>
<div className={styles['label']}>Select</div>
</Button>
</div>
</Modal>
:
null
}
</React.Fragment>
);
};
ColorInput.propTypes = {
className: PropTypes.string,
id: PropTypes.string,
value: PropTypes.string,
onChange: PropTypes.func
};

View file

@ -1,6 +1,6 @@
.color-input-modal-container {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
justify-content: center;
pointer-events: auto;
@ -8,49 +8,60 @@
.color-input-container {
flex: none;
position: relative;
z-index: 0;
display: flex;
flex-direction: column;
align-items: center;
max-width: 25rem;
padding: 1rem;
background-color: var(--color-surfacelighter);
.close-button-container {
position: absolute;
top: 1rem;
right: 1rem;
width: 1.5rem;
height: 1.5rem;
padding: 0.25rem;
z-index: 1;
.header-container {
flex: none;
align-self: stretch;
display: flex;
flex-direction: row;
align-items: flex-start;
&:hover, &:focus {
background-color: var(--color-surfacedark20);
.title {
flex: 1;
margin-right: 1rem;
font-size: 1.2rem;
max-height: 2.4em;
}
&:focus {
outline-color: var(--color-surfacedarker);
}
.close-button-container {
flex: none;
width: 1.5rem;
height: 1.5rem;
padding: 0.25rem;
.icon {
display: block;
width: 100%;
height: 100%;
fill: var(--color-surfacedarker);
}
}
&:hover, &:focus {
background-color: var(--color-surfacedark20);
}
.title {
font-size: 1.2rem;
&:focus {
outline-color: var(--color-surfacedarker);
}
.icon {
display: block;
width: 100%;
height: 100%;
fill: var(--color-surfacedarker);
}
}
}
.color-picker {
flex: none;
margin: 1rem;
}
.submit-button-container {
flex: none;
align-self: stretch;
padding: 1rem;
text-align: center;
background-color: var(--color-signal5);
color: var(--color-surfacelighter);
&:hover, &:focus {
filter: brightness(1.2);
@ -59,6 +70,12 @@
&:focus {
outline-color: var(--color-surfacedarker);
}
.label {
max-height: 2.4em;
text-align: center;
color: var(--color-surfacelighter);
}
}
}
}