fix: buttons and actions no longer getting stuck

fix: context menu resizes if accordion is opened
feat: added expanding descriptions for context actions
This commit is contained in:
Davide Passoni
2024-12-11 18:06:59 +01:00
parent e9896963ca
commit 7fe9b0d19f
16 changed files with 145 additions and 64 deletions

View File

@@ -9,7 +9,7 @@ export function OlStateButton(props: {
buttonColor?: string | null;
checked: boolean;
icon?: IconProp;
tooltip?: string | JSX.Element | JSX.Element[];
tooltip?: string | (() => JSX.Element | JSX.Element[]);
tooltipPosition?: string;
onClick: () => void;
onMouseUp?: () => void;
@@ -64,7 +64,7 @@ export function OlStateButton(props: {
{props.children}
</div>
</button>
{hover && props.tooltip && <OlTooltip buttonRef={buttonRef} content={props.tooltip} position={props.tooltipPosition}/>}
{hover && props.tooltip && <OlTooltip buttonRef={buttonRef} content={typeof(props.tooltip) === "string" ? props.tooltip: props.tooltip()} position={props.tooltipPosition}/>}
</>
);
}

View File

@@ -72,6 +72,12 @@ export function OlTooltip(props: { content: string | JSX.Element | JSX.Element[]
const button = props.buttonRef.current as HTMLButtonElement;
setPosition(content, button);
const resizeObserver = new ResizeObserver(() => {
setPosition(content, button);
});
resizeObserver.observe(content);
return () => resizeObserver.disconnect(); // clean up
}
});

View File

@@ -26,6 +26,7 @@ export function MapContextMenu(props: {}) {
const [latLng, setLatLng] = useState(null as null | LatLng);
const [unit, setUnit] = useState(null as null | Unit);
const [selectedUnits, setSelectedUnits] = useState([] as Unit[]);
const [height, setHeight] = useState(0);
var contentRef = useRef(null);
@@ -68,6 +69,14 @@ export function MapContextMenu(props: {}) {
content.style.left = `${newXPosition}px`;
content.style.top = `${newYposition}px`;
setHeight(content.clientHeight);
const resizeObserver = new ResizeObserver(() => {
setHeight(content.clientHeight);
});
resizeObserver.observe(content);
return () => resizeObserver.disconnect(); // clean up
}
});

View File

@@ -62,6 +62,7 @@ export function SpawnContextMenu(props: {}) {
const [showCost, setShowCost] = useState(false);
const [spawnCoalition, setSpawnCoalition] = useState("blue" as Coalition);
const [showMore, setShowMore] = useState(false);
const [height, setHeight] = useState(0);
useEffect(() => {
if (selectedRole) setBlueprints(getApp()?.getUnitsManager().getDatabase().getByRole(selectedRole));
@@ -152,17 +153,24 @@ export function SpawnContextMenu(props: {}) {
content.style.left = `${newXPosition}px`;
content.style.top = `${newYposition}px`;
const resizeObserver = new ResizeObserver(() => {
setHeight(content.clientHeight);
});
resizeObserver.observe(content);
return () => resizeObserver.disconnect(); // clean up
}
});
// TODO fix button being moved if overflowing
return (
<>
<div
ref={contentRef}
data-hidden={appState !== OlympusState.SPAWN_CONTEXT}
className={`
absolute flex w-[395px] data- flex-wrap gap-2 rounded-md
bg-olympus-800
absolute flex w-[395px] data- max-h-[800px] flex-wrap gap-2
overflow-auto rounded-md bg-olympus-800
data-[hidden=true]:hidden
`}
>

View File

@@ -152,26 +152,28 @@ export function MapToolBar(props: {}) {
key={"select"}
checked={selectionEnabled}
icon={faObjectGroup}
tooltip={
<div className="flex content-center gap-2">
{shortcutCombination(shortcuts["toggleSelectionEnabled"]?.getOptions())}
<div className="my-auto">Box selection</div>
tooltip={() => (
<div
className="overflow-hidden"
style={{ animationName: "fadeIn", animationDuration: "1s", animationFillMode: "forwards", height: "25px" }}
>
<div className="flex content-center gap-2">
{shortcutCombination(shortcuts["toggleSelectionEnabled"]?.getOptions())}
<div className="my-auto">Box selection</div>
</div>
</div>
}
)}
tooltipPosition="side"
onClick={() => {
getApp().getMap().setSelectionEnabled(!selectionEnabled);
if (!selectionEnabled) {
getApp()
.getMap()
.getContainer()
.addEventListener(
"mouseup",
() => {
getApp().getMap().setSelectionEnabled(false);
},
{ once: true, signal: controller.signal }
);
window.addEventListener(
"mouseup",
() => {
getApp().getMap().setSelectionEnabled(false);
},
{ once: true, signal: controller.signal }
);
} else {
controller.abort();
}
@@ -184,12 +186,12 @@ export function MapToolBar(props: {}) {
key={"copy"}
checked={false}
icon={faCopy}
tooltip={
tooltip={() => (
<div className="flex content-center gap-2">
{shortcutCombination(shortcuts["copyUnits"]?.getOptions())}
<div className="my-auto">Copy selected units</div>
</div>
}
)}
tooltipPosition="side"
onClick={() => {
getApp().getUnitsManager().copy(selectedUnits);
@@ -199,14 +201,21 @@ export function MapToolBar(props: {}) {
)}
{copiedUnitsData.length > 0 && (
<div className="flex flex-col gap-1">
<OlStateButton key={"paste"} checked={pasteEnabled} icon={faPaste} tooltip={
<OlStateButton
key={"paste"}
checked={pasteEnabled}
icon={faPaste}
tooltip={() => (
<div className="flex content-center gap-2">
{shortcutCombination(shortcuts["pasteUnits"]?.getOptions())}
<div className="my-auto">Paste copied units</div>
</div>
} tooltipPosition="side" onClick={() => {
getApp().getMap().setPasteEnabled(!pasteEnabled)
}} />
)}
tooltipPosition="side"
onClick={() => {
getApp().getMap().setPasteEnabled(!pasteEnabled);
}}
/>
</div>
)}
</>
@@ -218,12 +227,18 @@ export function MapToolBar(props: {}) {
key={contextActionIt.getId()}
checked={contextActionIt === contextAction}
icon={contextActionIt.getIcon()}
tooltip={
tooltip={() => (
<div
className="overflow-hidden"
style={{ animationName: "tooltipFadeInHeight", animationDuration: "1s", animationFillMode: "forwards", height: "25px" }}
>
<div className="flex content-center gap-2">
{shortcutCombination(contextActionIt.getOptions())}
<div className="my-auto">{contextActionIt.getLabel()}</div>
</div>
}
<div className={"max-w-[200px] text-wrap"} style={{ animationName: "tooltipFadeInWidth", animationDuration: "1s", animationFillMode: "forwards", width: "1px" }}>{contextActionIt.getDescription()}</div>
</div>
)}
tooltipPosition="side"
buttonColor={CONTEXT_ACTION_COLORS[contextActionIt.getOptions().type ?? 0]}
onClick={() => {

View File

@@ -103,4 +103,22 @@ input[type="range"]:focus::-moz-range-thumb {
.no-scrollbar {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
@keyframes tooltipFadeInHeight {
99% {
height: 25px;
}
100% {
height: fit-content;
}
}
@keyframes tooltipFadeInWidth {
99% {
width: 0px;
}
100% {
width: 200px;
}
}