Make dialog popup rendered by bootstrap overlay library
This makes it more dynamic and eases proper placement in case of vertical layout Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
parent
c9ddc2513b
commit
bf17a24704
|
@ -485,6 +485,12 @@ button {
|
|||
padding: 5px 5px 12px;
|
||||
position: relative;
|
||||
|
||||
&.horizontal {
|
||||
flex-direction: column;
|
||||
min-height: 50px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
> div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -571,67 +577,6 @@ button {
|
|||
}
|
||||
}
|
||||
|
||||
.overlayVariant {
|
||||
top: 24px;
|
||||
width: 140px;
|
||||
min-height: 40px;
|
||||
max-height: 320px;
|
||||
overflow-y: scroll;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
text-align: left;
|
||||
background-color: white;
|
||||
color: black;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
padding: 0.2rem 0;
|
||||
|
||||
p {
|
||||
font-size: .65rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0.1rem 0.2rem;
|
||||
font-size: 0.75rem;
|
||||
|
||||
input {
|
||||
padding: 0;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
.options-icon {
|
||||
display: inline;
|
||||
height: .875rem;
|
||||
margin-right: 0.2rem;
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check {
|
||||
min-height: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.overlay-smallcard {
|
||||
left: -38.5px; // (card width (63) - overlay width (140)) / 2
|
||||
|
||||
&.overlay-first {
|
||||
left: 0;
|
||||
}
|
||||
&.overlay-last {
|
||||
left: -67px;
|
||||
}
|
||||
}
|
||||
.overlay-bigcard {
|
||||
left: -7px; // (card width (126) - overlay width (140)) / 2
|
||||
}
|
||||
|
||||
.hovered {
|
||||
|
@ -778,3 +723,49 @@ button {
|
|||
}
|
||||
}
|
||||
|
||||
.overlayVariant {
|
||||
width: 140px;
|
||||
min-height: 40px;
|
||||
max-height: 320px;
|
||||
overflow-y: scroll;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
align-items: start;
|
||||
text-align: left;
|
||||
background-color: white;
|
||||
color: black;
|
||||
flex-direction: column;
|
||||
cursor: pointer;
|
||||
padding: 0.2rem 0;
|
||||
|
||||
p {
|
||||
font-size: .65rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div {
|
||||
margin: 0.1rem 0.2rem;
|
||||
font-size: 0.75rem;
|
||||
|
||||
input {
|
||||
padding: 0;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
.options-icon {
|
||||
display: inline;
|
||||
height: .875rem;
|
||||
margin-right: 0.2rem;
|
||||
margin-left: 0.2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.form-check {
|
||||
min-height: 1rem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,11 @@ import React from "react";
|
|||
import {useShopStore} from "./shop_store";
|
||||
import {SummaryPopup} from "./options/SummaryPopup";
|
||||
|
||||
export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
||||
export function OptionsDialogWrapper({crate_index, card_index, horizontal}) {
|
||||
const crate_id = useShopStore((state) => state.crates[crate_index].id);
|
||||
const use_options = useShopStore((state) => state.crateParams(state.crates[crate_index].crate_mode).options);
|
||||
const options = useShopStore((state) => state.crates[crate_index].items[card_index][use_options]);
|
||||
const options_data = useShopStore((state) => state.crates[crate_index].items[card_index].options_data);
|
||||
const card_size = useShopStore((state) => state.crates[crate_index].items[card_index].size);
|
||||
const card_id = useShopStore((state) => state.crates[crate_index].items[card_index].id);
|
||||
const options_class = useShopStore((state) => state.crates[crate_index].items[card_index].options_class);
|
||||
const sideMenuIsOpen = useShopStore((state) => state.sideMenuIsOpen);
|
||||
|
@ -27,12 +26,10 @@ export function OptionsDialogWrapper({crate_index, card_index, first, last}) {
|
|||
options_class={options_class}
|
||||
key={"popover" + crate_id +card_id}
|
||||
id={"popover"+ crate_id + card_id}
|
||||
big={card_size === "big"}
|
||||
first={first}
|
||||
last={last}
|
||||
sideMenuIsOpen={sideMenuIsOpen}
|
||||
onHideNotification={hideNotification}
|
||||
displayNotification={displayNotification}
|
||||
horizontal={horizontal}
|
||||
target={{
|
||||
construct: ((outvar, value) => {
|
||||
// #!options_log
|
||||
|
|
|
@ -1,46 +1,56 @@
|
|||
import React, {useState} from "react";
|
||||
import {useClickAway} from "./useClickAway";
|
||||
import React, {useRef, useState} from "react";
|
||||
import {ProcessOptions} from "./Options";
|
||||
import {Notification} from "./Notification";
|
||||
import {Overlay} from "react-bootstrap";
|
||||
|
||||
export function DialogPopup({options, data, target, id, big, first, last, options_class,
|
||||
sideMenuIsOpen, displayNotification, onHideNotification}) {
|
||||
export function DialogPopup({options, data, target, id, options_class,
|
||||
sideMenuIsOpen, displayNotification, onHideNotification, horizontal}) {
|
||||
const [show, setShow] = useState(false);
|
||||
const ref = useClickAway((e) => {
|
||||
if (e.type === "mousedown") // ignore touchstart
|
||||
setShow(false)
|
||||
}
|
||||
);
|
||||
const ref = useRef(null);
|
||||
|
||||
let div_classes = `overlayVariant border rounded ${options_class || ""}`;
|
||||
|
||||
let div_classes = `overlayVariant border rounded ${big ? "overlay-bigcard" : "overlay-smallcard"} ${(!big && first) ? "overlay-first" : ""} ${(!big && last && !first) ? "overlay-last" : ""} ${options_class || ""}`;
|
||||
const handleClick = (_event) => {
|
||||
setShow(!show);
|
||||
};
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<Notification
|
||||
id={"processed_options_notification" + id}
|
||||
tip="Customization options available"
|
||||
sideMenuIsOpen={sideMenuIsOpen}
|
||||
show={displayNotification}
|
||||
onHide={onHideNotification}
|
||||
content={
|
||||
<img className="alert-info"
|
||||
src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
|
||||
onClick={handleClick}/>
|
||||
}
|
||||
/>
|
||||
<div style={{'display': show ? 'flex' : 'none'}} className={div_classes}>
|
||||
<ProcessOptions
|
||||
options={options}
|
||||
data={data}
|
||||
key={"processed_options_" + id}
|
||||
id={"processed_options_" + id}
|
||||
target={target}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (<>
|
||||
<Notification
|
||||
id={"processed_options_notification" + id}
|
||||
tip="Customization options available"
|
||||
sideMenuIsOpen={sideMenuIsOpen}
|
||||
show={displayNotification}
|
||||
onHide={onHideNotification}
|
||||
content={
|
||||
<img className="alert-info" ref={ref}
|
||||
src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
|
||||
onClick={handleClick}/>
|
||||
}
|
||||
/>
|
||||
<Overlay target={ref.current}
|
||||
show={show}
|
||||
placement={horizontal ? "right" : "bottom"}
|
||||
onHide={() => setShow(false)}
|
||||
rootClose={true}>
|
||||
{({
|
||||
placement: _placement,
|
||||
arrowProps: _arrowProps,
|
||||
show: _show,
|
||||
popper: _popper,
|
||||
hasDoneInitialMeasure: _hasDoneInitialMeasure,
|
||||
...props
|
||||
}) => (
|
||||
<div style={{'display': show ? 'flex' : 'none', ...props.style}} {...props} className={div_classes}>
|
||||
<ProcessOptions
|
||||
options={options}
|
||||
data={data}
|
||||
key={"processed_options_" + id}
|
||||
id={"processed_options_" + id}
|
||||
target={target}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</Overlay>
|
||||
</>);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue