Merge remote-tracking branch 'origin/main' into simulation
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import React, { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { Widget } from "../../../store/useWidgetStore";
|
||||
import { MoveArrowLeft, MoveArrowRight } from "../../icons/SimulationIcons";
|
||||
import { InfoIcon } from "../../icons/ExportCommonIcons";
|
||||
|
||||
// Define the type for `Side`
|
||||
type Side = "top" | "bottom" | "left" | "right";
|
||||
@@ -60,138 +62,135 @@ const DisplayZone: React.FC<DisplayZoneProps> = ({
|
||||
// Ref for the container element
|
||||
const containerRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
// Example state for selectedOption and options (adjust based on your actual use case)
|
||||
const [selectedOption, setSelectedOption] = React.useState<string | null>(
|
||||
null
|
||||
);
|
||||
// console.log('setSelectedOption: ', setSelectedOption);
|
||||
const [options, setOptions] = React.useState<string[]>([]);
|
||||
// console.log('setOptions: ', setOptions);
|
||||
// State to track overflow visibility
|
||||
const [showLeftArrow, setShowLeftArrow] = useState(false);
|
||||
const [showRightArrow, setShowRightArrow] = useState(false);
|
||||
|
||||
// Scroll to the selected option when it changes
|
||||
useEffect(() => {
|
||||
// Function to calculate overflow state
|
||||
const updateOverflowState = useCallback(() => {
|
||||
const container = containerRef.current;
|
||||
|
||||
if (container && selectedOption) {
|
||||
// Handle scrolling to the selected option
|
||||
const index = options.findIndex((option) => {
|
||||
const formattedOption = formatOptionName(option);
|
||||
const selectedFormattedOption =
|
||||
selectedOption?.split("_")[1] || selectedOption;
|
||||
return formattedOption === selectedFormattedOption;
|
||||
});
|
||||
|
||||
if (index !== -1) {
|
||||
const optionElement = container.children[index] as HTMLElement;
|
||||
if (optionElement) {
|
||||
optionElement.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "nearest",
|
||||
inline: "center",
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [selectedOption, options]);
|
||||
|
||||
useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
|
||||
const handleWheel = (event: WheelEvent) => {
|
||||
event.preventDefault();
|
||||
if (container) {
|
||||
container.scrollBy({
|
||||
left: event.deltaY * 2, // Adjust the multiplier for faster scrolling
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
let isDragging = false;
|
||||
let startX: number;
|
||||
let scrollLeft: number;
|
||||
|
||||
const handleMouseDown = (event: MouseEvent) => {
|
||||
isDragging = true;
|
||||
startX = event.pageX - (container?.offsetLeft || 0);
|
||||
scrollLeft = container?.scrollLeft || 0;
|
||||
};
|
||||
|
||||
const handleMouseMove = (event: MouseEvent) => {
|
||||
if (!isDragging || !container) return;
|
||||
event.preventDefault();
|
||||
const x = event.pageX - (container.offsetLeft || 0);
|
||||
const walk = (x - startX) * 2; // Adjust the multiplier for faster dragging
|
||||
container.scrollLeft = scrollLeft - walk;
|
||||
};
|
||||
|
||||
const handleMouseUp = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
const handleMouseLeave = () => {
|
||||
isDragging = false;
|
||||
};
|
||||
|
||||
if (container) {
|
||||
container.addEventListener("wheel", handleWheel, { passive: false });
|
||||
container.addEventListener("mousedown", handleMouseDown);
|
||||
container.addEventListener("mousemove", handleMouseMove);
|
||||
container.addEventListener("mouseup", handleMouseUp);
|
||||
container.addEventListener("mouseleave", handleMouseLeave);
|
||||
}
|
||||
const isOverflowing = container.scrollWidth > container.clientWidth;
|
||||
const canScrollLeft = container.scrollLeft > 0;
|
||||
const canScrollRight =
|
||||
container.scrollLeft + container.clientWidth < container.scrollWidth;
|
||||
|
||||
return () => {
|
||||
if (container) {
|
||||
container.removeEventListener("wheel", handleWheel);
|
||||
container.removeEventListener("mousedown", handleMouseDown);
|
||||
container.removeEventListener("mousemove", handleMouseMove);
|
||||
container.removeEventListener("mouseup", handleMouseUp);
|
||||
container.removeEventListener("mouseleave", handleMouseLeave);
|
||||
}
|
||||
};
|
||||
setShowLeftArrow(isOverflowing && canScrollLeft);
|
||||
setShowRightArrow(isOverflowing && canScrollRight);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Helper function to format option names (customize as needed)
|
||||
const formatOptionName = (option: string): string => {
|
||||
// Replace underscores with spaces and capitalize the first letter
|
||||
return option.replace(/_/g, " ").replace(/^\w/, (c) => c.toUpperCase());
|
||||
useEffect(() => {
|
||||
const container = containerRef.current;
|
||||
|
||||
if (container) {
|
||||
// Initial calculation after the DOM has been rendered
|
||||
const handleInitialRender = () => {
|
||||
requestAnimationFrame(updateOverflowState);
|
||||
};
|
||||
|
||||
handleInitialRender();
|
||||
|
||||
// Update on window resize or scroll
|
||||
const handleResize = () => updateOverflowState();
|
||||
const handleScroll = () => updateOverflowState();
|
||||
|
||||
// Add mouse wheel listener for horizontal scrolling
|
||||
const handleWheel = (event: WheelEvent) => {
|
||||
event.preventDefault(); // Prevent default vertical scrolling
|
||||
if (container) {
|
||||
container.scrollBy({
|
||||
left: event.deltaY * 2, // Translate vertical scroll to horizontal scroll
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
container.addEventListener("scroll", handleScroll);
|
||||
window.addEventListener("resize", handleResize);
|
||||
container.addEventListener("wheel", handleWheel, { passive: false });
|
||||
|
||||
return () => {
|
||||
container.removeEventListener("scroll", handleScroll);
|
||||
window.removeEventListener("resize", handleResize);
|
||||
container.removeEventListener("wheel", handleWheel);
|
||||
};
|
||||
}
|
||||
}, [updateOverflowState]);
|
||||
|
||||
// Handle scrolling with navigation arrows
|
||||
const handleScrollLeft = () => {
|
||||
const container = containerRef.current;
|
||||
if (container) {
|
||||
container.scrollBy({
|
||||
left: -200, // Scroll left by 200px
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleScrollRight = () => {
|
||||
const container = containerRef.current;
|
||||
if (container) {
|
||||
container.scrollBy({
|
||||
left: 200, // Scroll right by 200px
|
||||
behavior: "smooth",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className={`zoon-wrapper ${selectedZone?.activeSides?.includes("bottom") && "bottom"
|
||||
}`}
|
||||
>
|
||||
{Object.keys(zonesData).map((zoneName, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`zone ${selectedZone.zoneName === zoneName ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
<div className="zone-wrapper">
|
||||
{/* Left Arrow */}
|
||||
{showLeftArrow && (
|
||||
<button className="arrow left-arrow" onClick={handleScrollLeft}>
|
||||
<MoveArrowLeft />
|
||||
</button>
|
||||
)}
|
||||
|
||||
|
||||
setSelectedZone({
|
||||
zoneName,
|
||||
activeSides: zonesData[zoneName].activeSides || [],
|
||||
panelOrder: zonesData[zoneName].panelOrder || [],
|
||||
lockedPanels: zonesData[zoneName].lockedPanels || [],
|
||||
widgets: zonesData[zoneName].widgets || [],
|
||||
zoneId: zonesData[zoneName]?.zoneId || "",
|
||||
zoneViewPortTarget: zonesData[zoneName].zoneViewPortTarget || [],
|
||||
zoneViewPortPosition:
|
||||
zonesData[zoneName].zoneViewPortPosition || [],
|
||||
});
|
||||
// setSelectedZone({
|
||||
// zoneName,
|
||||
// ...zonesData[zoneName],
|
||||
// });
|
||||
}}
|
||||
>
|
||||
{zoneName}
|
||||
{/* Zones Wrapper */}
|
||||
{Object.keys(zonesData).length !== 0 ? (
|
||||
<div ref={containerRef} className="zones-wrapper">
|
||||
{Object.keys(zonesData).map((zoneName, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={`zone ${
|
||||
selectedZone.zoneName === zoneName ? "active" : ""
|
||||
}`}
|
||||
onClick={() => {
|
||||
console.log("zoneName: ", zoneName);
|
||||
setSelectedZone({
|
||||
zoneName,
|
||||
activeSides: zonesData[zoneName].activeSides || [],
|
||||
panelOrder: zonesData[zoneName].panelOrder || [],
|
||||
lockedPanels: zonesData[zoneName].lockedPanels || [],
|
||||
widgets: zonesData[zoneName].widgets || [],
|
||||
zoneId: zonesData[zoneName]?.zoneId || "",
|
||||
zoneViewPortTarget:
|
||||
zonesData[zoneName].zoneViewPortTarget || [],
|
||||
zoneViewPortPosition:
|
||||
zonesData[zoneName].zoneViewPortPosition || [],
|
||||
});
|
||||
}}
|
||||
>
|
||||
{zoneName}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
) : (
|
||||
<div className="no-zone">
|
||||
<InfoIcon />
|
||||
No zones? Create one!
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Right Arrow */}
|
||||
{showRightArrow && (
|
||||
<button className="arrow right-arrow" onClick={handleScrollRight}>
|
||||
<MoveArrowRight />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user