Reposition summary popup relative to icon respective to window width, hide on scroll
Signed-off-by: Egor Savkin <es@m-labs.hk>
This commit is contained in:
parent
0fe665c0ba
commit
8bdfedc4b8
|
@ -6,7 +6,7 @@ import { createRoot } from "react-dom/client";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { CustomizeButton, CustomizeData } from "./shop_components.jsx";import { OverlayTrigger } from "react-bootstrap";
|
import { OptionsDialogPopup, OptionsSummaryPopup } from "./shop_components.jsx";import { OverlayTrigger } from "react-bootstrap";
|
||||||
|
|
||||||
const data = window.shop_data;
|
const data = window.shop_data;
|
||||||
const itemsUnfoldedList = Array.from(data.columns.backlog.categories.map(groupId => groupId.itemIds).flat());
|
const itemsUnfoldedList = Array.from(data.columns.backlog.categories.map(groupId => groupId.itemIds).flat());
|
||||||
|
@ -697,7 +697,7 @@ class ProductCartItem extends React.PureComponent {
|
||||||
|
|
||||||
{warning ? (
|
{warning ? (
|
||||||
<img className="alert-warning" src={`/images${warning.icon}`} />
|
<img className="alert-warning" src={`/images${warning.icon}`} />
|
||||||
) : (options ? (<CustomizeButton
|
) : (options ? (<OptionsDialogPopup
|
||||||
options={options}
|
options={options}
|
||||||
data={options_data}
|
data={options_data}
|
||||||
key={"popover" + index}
|
key={"popover" + index}
|
||||||
|
@ -1460,7 +1460,7 @@ class OrderSumary extends React.PureComponent {
|
||||||
src={`/images/${warning.icon}`}
|
src={`/images/${warning.icon}`}
|
||||||
/>
|
/>
|
||||||
) : ( (options && options_data) ?
|
) : ( (options && options_data) ?
|
||||||
( <CustomizeData id={item.id + "options"} data={options_data} /> ) : null
|
( <OptionsSummaryPopup id={item.id + "options"} data={options_data} /> ) : null
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{(!warning && !options) && (
|
{(!warning && !options) && (
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import React, {Component} from "react";
|
import React, {Component} from "react";
|
||||||
import jsonLogic from 'json-logic-js';
|
import jsonLogic from 'json-logic-js';
|
||||||
import {useState} from 'react';
|
import {useState, useEffect} from 'react';
|
||||||
import {useClickAway} from "@uidotdev/usehooks";
|
import {useClickAway} from "@uidotdev/usehooks";
|
||||||
|
|
||||||
// https://stackoverflow.com/a/70511311
|
// https://stackoverflow.com/a/70511311
|
||||||
|
@ -268,7 +268,7 @@ export function ProcessOptions({options, data, target, id}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomizeButton({options, data, target, id, big}) {
|
export function OptionsDialogPopup({options, data, target, id, big}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
const ref = useClickAway(() => setShow(false));
|
const ref = useClickAway(() => setShow(false));
|
||||||
|
|
||||||
|
@ -294,14 +294,51 @@ export function CustomizeButton({options, data, target, id, big}) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function CustomizeData({id, data}) {
|
export function OptionsSummaryPopup({id, data}) {
|
||||||
const [show, setShow] = useState(false);
|
const [show, setShow] = useState(false);
|
||||||
const [position, setPosition] = useState({x: 0, y: 0});
|
const [position, setPosition] = useState({x: 0, y: 0});
|
||||||
const ref = useClickAway(() => setShow(false));
|
const [size, setSize] = useState({w: 0, h: 0});
|
||||||
|
const close = () => {
|
||||||
|
setShow(false);
|
||||||
|
document.removeEventListener("scroll", close, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
const ref = useClickAway(close);
|
||||||
|
|
||||||
|
const reposition = () => {
|
||||||
|
let popup_button = document.getElementById(id + "img");
|
||||||
|
let rect = popup_button.getBoundingClientRect()
|
||||||
|
let pos_x = (rect.left + rect.right) / 2;
|
||||||
|
let pos_y = (rect.top + rect.bottom) / 2;
|
||||||
|
if (pos_x + size.w > window.innerWidth) {
|
||||||
|
setPosition({x: pos_x - size.w - 20, y: pos_y - size.h / 2});
|
||||||
|
} else {
|
||||||
|
setPosition({x: pos_x - size.w / 2, y: pos_y - size.h - 20});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (show) {
|
||||||
|
let popup = document.getElementById(id);
|
||||||
|
let width = popup.offsetWidth;
|
||||||
|
let height = popup.offsetHeight;
|
||||||
|
setSize({w: width, h: height});
|
||||||
|
reposition()
|
||||||
|
}
|
||||||
|
}, [show])
|
||||||
|
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (show) {
|
||||||
|
reposition();
|
||||||
|
}
|
||||||
|
}, [show, size])
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
setPosition({x: event.clientX, y: event.clientY});
|
|
||||||
setShow(!show);
|
setShow(!show);
|
||||||
|
if (!show) {
|
||||||
|
document.addEventListener("scroll", close, true);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const stringify = (value) => {
|
const stringify = (value) => {
|
||||||
|
@ -322,9 +359,11 @@ export function CustomizeData({id, data}) {
|
||||||
<div ref={ref}>
|
<div ref={ref}>
|
||||||
<img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
|
<img className="alert-info" src={show ? "/images/shop/icon-close.svg" : "/images/shop/icon-customize.svg"}
|
||||||
style={{'marginLeft': '10px'}}
|
style={{'marginLeft': '10px'}}
|
||||||
|
id={id + "img"}
|
||||||
onClick={handleClick}/>
|
onClick={handleClick}/>
|
||||||
<div style={{'display': show ? 'flex' : 'none', 'top': position.y - 170, 'left': position.x - 66}}
|
<div style={{'display': show ? 'flex' : 'none', 'top': position.y, 'left': position.x}}
|
||||||
className="overlayVariant card border rounded">
|
className="overlayVariant card border rounded"
|
||||||
|
id={id}>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{Array.from(Object.entries(data).map(([key, value], _) => {
|
{Array.from(Object.entries(data).map(([key, value], _) => {
|
||||||
return (<p className="card-text" key={id + key}><i>{key}</i>: {stringify(value)}</p>);
|
return (<p className="card-text" key={id + key}><i>{key}</i>: {stringify(value)}</p>);
|
||||||
|
|
Loading…
Reference in New Issue