Skip to content

Commit

Permalink
Merge pull request #1491 from TouK/NU-1746-fix-window-position
Browse files Browse the repository at this point in the history
Nu 1746 fix window position
  • Loading branch information
JulianWielga authored Jul 19, 2024
2 parents a35c999 + 6683e24 commit a219b17
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 27 deletions.
10 changes: 10 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
"@types/lodash": "4.17.1",
"@types/node": "20.12.12",
"@types/react": "18.3.2",
"@types/react-transition-group": "4.4.10",
"@typescript-eslint/eslint-plugin": "7.9.0",
"@typescript-eslint/parser": "7.9.0",
"babel-loader": "9.1.3",
Expand Down
10 changes: 6 additions & 4 deletions src/components/ModalMask.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { css, cx } from "@emotion/css";
import React from "react";
import React, { forwardRef, RefObject } from "react";
import { rgba } from "../rgba";
import { useModalMaskTheme } from "../themeHooks";

export function ModalMask({ zIndex }: { zIndex?: number }): JSX.Element {
export const ModalMask = forwardRef(({ zIndex }: { zIndex?: number }, ref: RefObject<HTMLDivElement>): JSX.Element => {
const modalMaskTheme = useModalMaskTheme();
const modalMaskClass = css({
top: 0,
Expand All @@ -13,5 +13,7 @@ export function ModalMask({ zIndex }: { zIndex?: number }): JSX.Element {
position: "fixed",
background: rgba("black", 0.6),
});
return <div className={cx(modalMaskClass, modalMaskTheme)} style={{ zIndex }} />;
}
return <div ref={ref} className={cx(modalMaskClass, modalMaskTheme)} style={{ zIndex }} />;
});

ModalMask.displayName = "ModalMask";
13 changes: 8 additions & 5 deletions src/components/WindowsContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { flatMap } from "lodash";
import React from "react";
import React, { useRef } from "react";
import { createPortal } from "react-dom";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import { useWindowManager } from "../hooks";
Expand All @@ -18,16 +18,19 @@ interface WindowsContainerProps {

export function WindowsContainer({ container = document.body, contentGetter }: WindowsContainerProps): JSX.Element {
const { windows } = useWindowManager();
const modalMaskRef = useRef<HTMLDivElement>();
const windowRef = useRef<HTMLDivElement>();

return createPortal(
<TransitionGroup component={WindowsViewport}>
{flatMap(windows, (d, index) => [
d.isModal && (
<CSSTransition key={`${d.id}/mask`} timeout={250} classNames={fadeInAnimation}>
<ModalMask key={`${d.id}/mask`} zIndex={index} />
<CSSTransition nodeRef={modalMaskRef} key={`${d.id}/mask`} timeout={250} classNames={fadeInAnimation}>
<ModalMask ref={modalMaskRef} key={`${d.id}/mask`} zIndex={index} />
</CSSTransition>
),
<CSSTransition key={d.id} timeout={250} classNames={fadeInAnimation}>
<Window data={d} contentGetter={contentGetter} />
<CSSTransition nodeRef={windowRef} key={d.id} timeout={250} classNames={fadeInAnimation}>
<Window ref={windowRef} data={d} contentGetter={contentGetter} />
</CSSTransition>,
]).filter(Boolean)}
</TransitionGroup>,
Expand Down
9 changes: 6 additions & 3 deletions src/components/window/Window.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useCallback } from "react";
import React, { forwardRef, RefObject, useCallback } from "react";
import { useWindowManager, useWindowZoom } from "../../hooks";
import { WindowWithOrder } from "../../types";
import { ContentGetter, WindowContent } from "./WindowContent";
Expand All @@ -9,7 +9,7 @@ export interface WindowProps {
contentGetter: ContentGetter;
}

export function Window({ data, contentGetter }: WindowProps): JSX.Element {
export const Window = forwardRef(({ data, contentGetter }: WindowProps, ref: RefObject<HTMLDivElement>): JSX.Element => {
const { isResizable, isStatic, focusParent, id, order, shouldCloseOnEsc } = data;

const { focus: onFocus, close: onClose } = useWindowManager(id);
Expand All @@ -31,8 +31,11 @@ export function Window({ data, contentGetter }: WindowProps): JSX.Element {
height={data.height}
minWidth={data.minWidth}
minHeight={data.minHeight}
ref={ref}
>
<WindowContent contentGetter={contentGetter} data={data} close={onClose} zoom={onToggleZoom} isMaximized={zoom} />
</WindowFrame>
);
}
});

Window.displayName = "Window";
24 changes: 9 additions & 15 deletions src/components/window/WindowFrame.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { css, cx } from "@emotion/css";
import { isEqual } from "lodash";
import { mapValues } from "lodash/fp";
import React, { PropsWithChildren, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import React, { forwardRef, PropsWithChildren, RefObject, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import FocusLock from "react-focus-lock";
import { Position, Rnd } from "react-rnd";
import { CSSTransition } from "react-transition-group";
Expand Down Expand Up @@ -96,7 +96,7 @@ const windowClass = css({
willChange: "transform, top, left, minWidth, minHeight, width, height",
});

export function WindowFrame(props: PropsWithChildren<WindowFrameProps>): JSX.Element {
export const WindowFrame = forwardRef((props: PropsWithChildren<WindowFrameProps>, windowRef: RefObject<HTMLDivElement>): JSX.Element => {
const {
focusGroup,
zIndex,
Expand Down Expand Up @@ -143,17 +143,9 @@ export function WindowFrame(props: PropsWithChildren<WindowFrameProps>): JSX.Ele

const contentAvailable = useContentVisibility(ref, onContentChanged);

// set initial position
useEffect(() => {
if (dragging.current) return;
if (contentAvailable && !position) {
forceCenterWindow();
}
}, [contentAvailable, maximized, position, forceCenterWindow]);

const wasMaximized = usePreviousDifferent(maximized);

// setup position correction for screen egdes
// setup position correction for screen edges
const calcEdgePosition = useCallback(
(viewport, box: Box = ref.current.getBoundingClientRect()) => {
const width = size?.width || box?.width || 0;
Expand Down Expand Up @@ -286,7 +278,7 @@ export function WindowFrame(props: PropsWithChildren<WindowFrameProps>): JSX.Ele
useScrollFix(ref.current);

return (
<>
<div ref={windowRef}>
{/*fallback animation for lazy loaded content*/}
<CSSTransition nodeRef={nodeRef} in={contentAvailable} timeout={250} classNames={fadeInAnimation}>
<CSSTransition in={maximized} timeout={250} classNames={zoomAnimation} onEnter={onEnter} onExited={onExited}>
Expand All @@ -313,7 +305,7 @@ export function WindowFrame(props: PropsWithChildren<WindowFrameProps>): JSX.Ele
data-testid="window-frame"
>
{/* trap keyboard focus within group (windows opened since last modal) */}
<FocusLock ref={nodeRef} className={css({ flex: 1 })} group={focusGroup} disabled={!focusGroup} returnFocus autoFocus>
<FocusLock className={css({ flex: 1 })} group={focusGroup} disabled={!focusGroup} returnFocus autoFocus>
<div
ref={ref}
onFocus={focus}
Expand All @@ -333,6 +325,8 @@ export function WindowFrame(props: PropsWithChildren<WindowFrameProps>): JSX.Ele
</CSSTransition>
</CSSTransition>
<SnapMask previewBox={snapPreviewBox} />
</>
</div>
);
}
});

WindowFrame.displayName = "WindowFrame";

0 comments on commit a219b17

Please sign in to comment.