mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 23:12:13 +00:00
Popup/Multiselect api changed
This commit is contained in:
parent
acd75db430
commit
f20d04d5ee
8 changed files with 197 additions and 241 deletions
|
|
@ -1,3 +0,0 @@
|
||||||
const Dropdown = require('./Dropdown');
|
|
||||||
|
|
||||||
module.exports = Dropdown;
|
|
||||||
|
|
@ -1,74 +0,0 @@
|
||||||
.dropdown-label-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 1rem;
|
|
||||||
background-color: var(--color-backgroundlighter);
|
|
||||||
|
|
||||||
&:hover, &:focus {
|
|
||||||
filter: brightness(1.2);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:global(.active) {
|
|
||||||
background-color: var(--color-surfacelight);
|
|
||||||
|
|
||||||
.label {
|
|
||||||
color: var(--color-backgrounddarker);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
fill: var(--color-backgrounddarker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
flex: 1;
|
|
||||||
max-height: 2.4em;
|
|
||||||
color: var(--color-surfacelighter);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
flex: none;
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
margin-left: 1rem;
|
|
||||||
fill: var(--color-surfacelighter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-menu-container {
|
|
||||||
.dropdown-option-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
padding: 1rem;
|
|
||||||
background-color: var(--color-backgroundlighter);
|
|
||||||
|
|
||||||
&:global(.selected) {
|
|
||||||
background-color: var(--color-surfacedarker);
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover, &:focus {
|
|
||||||
background-color: var(--color-surfacedark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
flex: 1;
|
|
||||||
max-height: 4.8em;
|
|
||||||
color: var(--color-surfacelighter);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
flex: none;
|
|
||||||
display: none;
|
|
||||||
width: 1rem;
|
|
||||||
height: 1rem;
|
|
||||||
margin-left: 1rem;
|
|
||||||
fill: var(--color-surfacelighter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -7,9 +7,24 @@ const Popup = require('stremio/common/Popup');
|
||||||
const useBinaryState = require('stremio/common/useBinaryState');
|
const useBinaryState = require('stremio/common/useBinaryState');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
// TODO rename to multiselect
|
const Multiselect = ({ className, direction, title, renderLabelContent, options, selected, onOpen, onClose, onSelect, ...props }) => {
|
||||||
const Dropdown = ({ className, menuClassName, menuMatchLabelWidth, renderLabel, name, selected, options, tabIndex, onOpen, onClose, onSelect }) => {
|
options = Array.isArray(options) ?
|
||||||
|
options.filter(option => option && typeof option.value === 'string')
|
||||||
|
:
|
||||||
|
[];
|
||||||
|
selected = Array.isArray(selected) ?
|
||||||
|
selected.filter(value => typeof value === 'string')
|
||||||
|
:
|
||||||
|
[];
|
||||||
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
|
const [menuOpen, openMenu, closeMenu, toggleMenu] = useBinaryState(false);
|
||||||
|
const popupLabelOnClick = React.useCallback((event) => {
|
||||||
|
if (!event.nativeEvent.togglePopupPrevented) {
|
||||||
|
toggleMenu();
|
||||||
|
}
|
||||||
|
}, [toggleMenu]);
|
||||||
|
const popupMenuOnClick = React.useCallback((event) => {
|
||||||
|
event.nativeEvent.togglePopupPrevented = true;
|
||||||
|
}, []);
|
||||||
const optionOnClick = React.useCallback((event) => {
|
const optionOnClick = React.useCallback((event) => {
|
||||||
if (typeof onSelect === 'function') {
|
if (typeof onSelect === 'function') {
|
||||||
onSelect(event);
|
onSelect(event);
|
||||||
|
|
@ -29,72 +44,66 @@ const Dropdown = ({ className, menuClassName, menuMatchLabelWidth, renderLabel,
|
||||||
onClose();
|
onClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [menuOpen, onOpen, onClose]);
|
}, [menuOpen]);
|
||||||
return (
|
return (
|
||||||
<Popup
|
<Popup
|
||||||
open={menuOpen}
|
open={menuOpen}
|
||||||
menuMatchLabelWidth={typeof menuMatchLabelWidth === 'boolean' ? menuMatchLabelWidth : true}
|
direction={direction}
|
||||||
onCloseRequest={closeMenu}
|
onCloseRequest={closeMenu}
|
||||||
renderLabel={(ref) => (
|
renderLabel={({ ref, className: popupLabelClassName, children }) => (
|
||||||
<Button ref={ref} className={classnames(className, styles['dropdown-label-container'], { 'active': menuOpen })} title={name} tabIndex={tabIndex} onClick={toggleMenu}>
|
<Button {...props} ref={ref} className={classnames(className, popupLabelClassName, styles['label-container'], { 'active': menuOpen })} title={title} onClick={popupLabelOnClick}>
|
||||||
{
|
{
|
||||||
typeof renderLabel === 'function' ?
|
typeof renderLabelContent === 'function' ?
|
||||||
renderLabel()
|
renderLabelContent()
|
||||||
:
|
:
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<div className={styles['label']}>
|
<div className={styles['label']}>
|
||||||
{
|
{
|
||||||
Array.isArray(selected) && selected.length > 0 ?
|
selected.length > 0 ?
|
||||||
options.reduce((labels, { label, value }) => {
|
options.reduce((labels, { label, value }) => {
|
||||||
if (selected.includes(value)) {
|
if (selected.includes(value)) {
|
||||||
labels.push(label);
|
labels.push(typeof label === 'string' ? label : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return labels;
|
return labels;
|
||||||
}, []).join(', ')
|
}, []).join(', ')
|
||||||
:
|
:
|
||||||
name
|
title
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<Icon className={styles['icon']} icon={'ic_arrow_down'} />
|
<Icon className={styles['icon']} icon={'ic_arrow_down'} />
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
}
|
}
|
||||||
|
{children}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
renderMenu={() => (
|
renderMenu={() => (
|
||||||
<div className={classnames(menuClassName, styles['dropdown-menu-container'])}>
|
<div className={styles['menu-container']} onClick={popupMenuOnClick}>
|
||||||
{
|
{options.map(({ label, value }) => (
|
||||||
Array.isArray(options) && options.length > 0 ?
|
<Button key={value} className={classnames(styles['option-container'], { 'selected': selected.includes(value) })} title={typeof label === 'string' ? label : value} data-value={value} onClick={optionOnClick}>
|
||||||
options.map(({ label, value }) => (
|
<div className={styles['label']}>{typeof label === 'string' ? label : value}</div>
|
||||||
<Button key={value} className={classnames(styles['dropdown-option-container'], { 'selected': Array.isArray(selected) && selected.includes(value) })} title={label} data-name={name} data-value={value} onClick={optionOnClick}>
|
<Icon className={styles['icon']} icon={'ic_check'} />
|
||||||
<div className={styles['label']}>{label}</div>
|
</Button>
|
||||||
<Icon className={styles['icon']} icon={'ic_check'} />
|
))}
|
||||||
</Button>
|
|
||||||
))
|
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Dropdown.propTypes = {
|
Multiselect.propTypes = {
|
||||||
className: PropTypes.string,
|
className: PropTypes.string,
|
||||||
menuClassName: PropTypes.string,
|
direction: PropTypes.any,
|
||||||
menuMatchLabelWidth: PropTypes.bool,
|
title: PropTypes.string,
|
||||||
renderLabel: PropTypes.func,
|
renderLabelContent: PropTypes.func,
|
||||||
name: PropTypes.string,
|
|
||||||
selected: PropTypes.arrayOf(PropTypes.string),
|
|
||||||
options: PropTypes.arrayOf(PropTypes.shape({
|
options: PropTypes.arrayOf(PropTypes.shape({
|
||||||
label: PropTypes.string.isRequired,
|
value: PropTypes.string.isRequired,
|
||||||
value: PropTypes.string.isRequired
|
label: PropTypes.string
|
||||||
})),
|
})),
|
||||||
tabIndex: PropTypes.number,
|
selected: PropTypes.arrayOf(PropTypes.string),
|
||||||
onOpen: PropTypes.func,
|
onOpen: PropTypes.func,
|
||||||
onClose: PropTypes.func,
|
onClose: PropTypes.func,
|
||||||
onSelect: PropTypes.func
|
onSelect: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Dropdown;
|
module.exports = Multiselect;
|
||||||
3
src/common/Multiselect/index.js
Normal file
3
src/common/Multiselect/index.js
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
const Multiselect = require('./Multiselect');
|
||||||
|
|
||||||
|
module.exports = Multiselect;
|
||||||
78
src/common/Multiselect/styles.less
Normal file
78
src/common/Multiselect/styles.less
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
:import('~stremio/common/Popup/styles.less') {
|
||||||
|
popup-menu-container: menu-container;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 1rem;
|
||||||
|
background-color: var(--color-backgroundlighter);
|
||||||
|
|
||||||
|
&:global(.active) {
|
||||||
|
background-color: var(--color-surfacelight);
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: var(--color-backgrounddarker);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--color-backgrounddarker);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex: 1;
|
||||||
|
max-height: 2.4em;
|
||||||
|
margin-right: 1rem;
|
||||||
|
color: var(--color-surfacelighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
flex: none;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
fill: var(--color-surfacelighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-menu-container {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.menu-container {
|
||||||
|
.option-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: var(--color-backgroundlighter);
|
||||||
|
|
||||||
|
&:global(.selected) {
|
||||||
|
background-color: var(--color-surfacedarker);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover, &:focus {
|
||||||
|
background-color: var(--color-surfacedark);
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex: 1;
|
||||||
|
max-height: 4.8em;
|
||||||
|
margin-right: 1rem;
|
||||||
|
color: var(--color-surfacelighter);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
flex: none;
|
||||||
|
display: none;
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
fill: var(--color-surfacelighter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,147 +1,78 @@
|
||||||
const React = require('react');
|
const React = require('react');
|
||||||
const PropTypes = require('prop-types');
|
const PropTypes = require('prop-types');
|
||||||
const classnames = require('classnames');
|
const classnames = require('classnames');
|
||||||
const { Modal } = require('stremio-router');
|
const FocusLock = require('react-focus-lock').default;
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
// TODO rename to Popover
|
const Popup = ({ open, direction, renderLabel, renderMenu, onCloseRequest }) => {
|
||||||
const Popup = ({ open, menuModalClassName, menuRelativePosition, menuMatchLabelWidth, renderLabel, renderMenu, onCloseRequest }) => {
|
|
||||||
const labelRef = React.useRef(null);
|
const labelRef = React.useRef(null);
|
||||||
const menuRef = React.useRef(null);
|
const [autoDirection, setAutoDirection] = React.useState(null);
|
||||||
const [menuStyles, setMenuStyles] = React.useState({});
|
|
||||||
React.useEffect(() => {
|
|
||||||
const checkCloseEvent = (event) => {
|
|
||||||
switch (event.type) {
|
|
||||||
case 'resize':
|
|
||||||
onCloseRequest(event);
|
|
||||||
break;
|
|
||||||
case 'keydown':
|
|
||||||
if (event.key === 'Escape') {
|
|
||||||
onCloseRequest(event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'mousedown':
|
|
||||||
if (event.target !== document &&
|
|
||||||
event.target !== document.documentElement &&
|
|
||||||
!event.closePopupPrevented) {
|
|
||||||
onCloseRequest(event);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'react-scroll':
|
|
||||||
if (!event.nativeEvent.closePopupPrevented) {
|
|
||||||
onCloseRequest(event.nativeEvent);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (open) {
|
|
||||||
window.addEventListener('react-scroll', checkCloseEvent);
|
|
||||||
window.addEventListener('mousedown', checkCloseEvent);
|
|
||||||
window.addEventListener('keydown', checkCloseEvent);
|
|
||||||
window.addEventListener('resize', checkCloseEvent);
|
|
||||||
}
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('react-scroll', checkCloseEvent);
|
|
||||||
window.removeEventListener('mousedown', checkCloseEvent);
|
|
||||||
window.removeEventListener('keydown', checkCloseEvent);
|
|
||||||
window.removeEventListener('resize', checkCloseEvent);
|
|
||||||
};
|
|
||||||
}, [open, onCloseRequest]);
|
|
||||||
const menuOnMouseDown = React.useCallback((event) => {
|
const menuOnMouseDown = React.useCallback((event) => {
|
||||||
event.nativeEvent.closePopupPrevented = true;
|
event.nativeEvent.closePopupPrevented = true;
|
||||||
}, []);
|
}, []);
|
||||||
const menuOnScroll = React.useCallback((event) => {
|
|
||||||
event.nativeEvent.closePopupPrevented = true;
|
|
||||||
}, []);
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let menuStyles = {};
|
const checkCloseEvent = (event) => {
|
||||||
|
if (typeof onCloseRequest === 'function') {
|
||||||
|
switch (event.type) {
|
||||||
|
case 'resize':
|
||||||
|
onCloseRequest(event);
|
||||||
|
break;
|
||||||
|
case 'keydown':
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
onCloseRequest(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'mousedown':
|
||||||
|
if (event.target !== document.documentElement &&
|
||||||
|
!labelRef.current.contains(event.target) &&
|
||||||
|
!event.closePopupPrevented) {
|
||||||
|
onCloseRequest(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
if (open) {
|
if (open) {
|
||||||
if (menuRelativePosition !== false) {
|
window.addEventListener('resize', checkCloseEvent);
|
||||||
const documentRect = document.documentElement.getBoundingClientRect();
|
window.addEventListener('keydown', checkCloseEvent);
|
||||||
const labelRect = labelRef.current.getBoundingClientRect();
|
window.addEventListener('mousedown', checkCloseEvent);
|
||||||
const menuRect = menuRef.current.getBoundingClientRect();
|
}
|
||||||
const labelPosition = {
|
return () => {
|
||||||
left: labelRect.left - documentRect.left,
|
window.removeEventListener('resize', checkCloseEvent);
|
||||||
top: labelRect.top - documentRect.top,
|
window.removeEventListener('keydown', checkCloseEvent);
|
||||||
right: (documentRect.width + documentRect.left) - (labelRect.left + labelRect.width),
|
window.removeEventListener('mousedown', checkCloseEvent);
|
||||||
bottom: (documentRect.height + documentRect.top) - (labelRect.top + labelRect.height)
|
};
|
||||||
};
|
}, [open, onCloseRequest]);
|
||||||
const matchLabelWidthMenuStyles = {
|
React.useLayoutEffect(() => {
|
||||||
width: `${labelRect.width}px`,
|
if (open) {
|
||||||
maxWidth: `${labelRect.width}px`
|
const documentRect = document.documentElement.getBoundingClientRect();
|
||||||
};
|
const labelRect = labelRef.current.getBoundingClientRect();
|
||||||
const bottomMenuStyles = {
|
const labelOffsetTop = labelRect.top - documentRect.top;
|
||||||
top: `${labelPosition.top + labelRect.height}px`,
|
const labelOffsetBottom = (documentRect.height + documentRect.top) - (labelRect.top + labelRect.height);
|
||||||
maxHeight: `${labelPosition.bottom}px`
|
const autoDirection = labelOffsetBottom >= labelOffsetTop ? 'bottom' : 'top';
|
||||||
};
|
setAutoDirection(autoDirection);
|
||||||
const topMenuStyles = {
|
} else {
|
||||||
bottom: `${labelPosition.bottom + labelRect.height}px`,
|
setAutoDirection(null);
|
||||||
maxHeight: `${labelPosition.top}px`
|
|
||||||
};
|
|
||||||
const rightMenuStyles = {
|
|
||||||
left: `${labelPosition.left}px`,
|
|
||||||
maxWidth: `${labelPosition.right + labelRect.width}px`
|
|
||||||
};
|
|
||||||
const leftMenuStyles = {
|
|
||||||
right: `${labelPosition.right}px`,
|
|
||||||
maxWidth: `${labelPosition.left + labelRect.width}px`
|
|
||||||
};
|
|
||||||
|
|
||||||
if (menuRect.height <= labelPosition.bottom) {
|
|
||||||
menuStyles = { ...menuStyles, ...bottomMenuStyles };
|
|
||||||
} else if (menuRect.height <= labelPosition.top) {
|
|
||||||
menuStyles = { ...menuStyles, ...topMenuStyles };
|
|
||||||
} else if (labelPosition.bottom >= labelPosition.top) {
|
|
||||||
menuStyles = { ...menuStyles, ...bottomMenuStyles };
|
|
||||||
} else {
|
|
||||||
menuStyles = { ...menuStyles, ...topMenuStyles };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menuRect.width <= (labelPosition.right + labelRect.width)) {
|
|
||||||
menuStyles = { ...menuStyles, ...rightMenuStyles };
|
|
||||||
} else if (menuRect.width <= (labelPosition.left + labelRect.width)) {
|
|
||||||
menuStyles = { ...menuStyles, ...leftMenuStyles };
|
|
||||||
} else if (labelPosition.right > labelPosition.left) {
|
|
||||||
menuStyles = { ...menuStyles, ...rightMenuStyles };
|
|
||||||
} else {
|
|
||||||
menuStyles = { ...menuStyles, ...leftMenuStyles };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (menuMatchLabelWidth) {
|
|
||||||
menuStyles = { ...menuStyles, ...matchLabelWidthMenuStyles };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
menuStyles = { ...menuStyles, visibility: 'visible' };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setMenuStyles(menuStyles);
|
|
||||||
}, [open]);
|
}, [open]);
|
||||||
return (
|
return renderLabel({
|
||||||
<React.Fragment>
|
ref: labelRef,
|
||||||
{renderLabel(labelRef)}
|
className: styles['label-container'],
|
||||||
{
|
children: open ?
|
||||||
open ?
|
<FocusLock className={classnames(styles['menu-container'], styles[`menu-direction-${typeof direction === 'string' ? direction : autoDirection}`])} autoFocus={false} lockProps={{ onMouseDown: menuOnMouseDown }}>
|
||||||
<Modal className={classnames(styles['menu-modal-container'], menuModalClassName)}>
|
{renderMenu()}
|
||||||
<div ref={menuRef} style={menuStyles} className={styles['menu-container']} onMouseDown={menuOnMouseDown} onScroll={menuOnScroll}>
|
</FocusLock>
|
||||||
{renderMenu()}
|
:
|
||||||
</div>
|
null
|
||||||
</Modal>
|
});
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</React.Fragment>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Popup.propTypes = {
|
Popup.propTypes = {
|
||||||
open: PropTypes.bool,
|
open: PropTypes.bool,
|
||||||
menuModalClassName: PropTypes.string,
|
direction: PropTypes.oneOf(['top', 'bottom']),
|
||||||
menuRelativePosition: PropTypes.bool,
|
|
||||||
menuMatchLabelWidth: PropTypes.bool,
|
|
||||||
renderLabel: PropTypes.func.isRequired,
|
renderLabel: PropTypes.func.isRequired,
|
||||||
renderMenu: PropTypes.func.isRequired,
|
renderMenu: PropTypes.func.isRequired,
|
||||||
onCloseRequest: PropTypes.func.isRequired
|
onCloseRequest: PropTypes.func
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = Popup;
|
module.exports = Popup;
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,24 @@
|
||||||
.menu-modal-container {
|
.label-container {
|
||||||
pointer-events: none;
|
position: relative;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
.menu-container {
|
.menu-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: auto;
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
overflow: visible;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
overflow: auto;
|
|
||||||
box-shadow: 0 1.35rem 2.7rem var(--color-backgrounddarker40),
|
box-shadow: 0 1.35rem 2.7rem var(--color-backgrounddarker40),
|
||||||
0 1.1rem 0.85rem var(--color-backgrounddarker20);
|
0 1.1rem 0.85rem var(--color-backgrounddarker20);
|
||||||
|
|
||||||
|
&.menu-direction-bottom {
|
||||||
|
top: 100%;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.menu-direction-top {
|
||||||
|
bottom: 100%;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
const Button = require('./Button');
|
const Button = require('./Button');
|
||||||
const Checkbox = require('./Checkbox');
|
const Checkbox = require('./Checkbox');
|
||||||
const ColorInput = require('./ColorInput');
|
const ColorInput = require('./ColorInput');
|
||||||
const Dropdown = require('./Dropdown');
|
const Multiselect = require('./Multiselect');
|
||||||
const Image = require('./Image');
|
const Image = require('./Image');
|
||||||
const MainNavBar = require('./MainNavBar');
|
const MainNavBar = require('./MainNavBar');
|
||||||
const MetaItem = require('./MetaItem');
|
const MetaItem = require('./MetaItem');
|
||||||
|
|
@ -29,7 +29,7 @@ module.exports = {
|
||||||
Button,
|
Button,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
ColorInput,
|
ColorInput,
|
||||||
Dropdown,
|
Multiselect,
|
||||||
Image,
|
Image,
|
||||||
MainNavBar,
|
MainNavBar,
|
||||||
MetaItem,
|
MetaItem,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue