mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-08-16 11:33:48 +00:00
ColorInput implemented with Modal
This commit is contained in:
parent
41841fefaf
commit
645ae7931d
2 changed files with 97 additions and 64 deletions
|
|
@ -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
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue