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:
Egor Savkin 2023-08-23 16:58:02 +08:00
parent 0fe665c0ba
commit 8bdfedc4b8
2 changed files with 49 additions and 10 deletions

View File

@ -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) && (

View File

@ -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>);