Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

revert: Revert "fix: Render Visual Refresh background height in sync with con… #1385

Merged
merged 1 commit into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

106 changes: 0 additions & 106 deletions src/app-layout/__tests__/dynamic-overlap.test.tsx

This file was deleted.

5 changes: 3 additions & 2 deletions src/app-layout/visual-refresh/background.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ import styles from './styles.css.js';
export default function Background() {
const {
breadcrumbs,
isDynamicOverlapSet,
contentHeader,
dynamicOverlapHeight,
hasNotificationsContent,
hasStickyBackground,
isMobile,
stickyNotifications,
} = useAppLayoutInternals();

if (!hasNotificationsContent && (!breadcrumbs || isMobile) && !isDynamicOverlapSet) {
if (!hasNotificationsContent && (!breadcrumbs || isMobile) && !contentHeader && dynamicOverlapHeight <= 0) {
return null;
}

Expand Down
46 changes: 4 additions & 42 deletions src/app-layout/visual-refresh/context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import { warnOnce } from '@cloudscape-design/component-toolkit/internal';
import useResize from '../utils/use-resize';
import styles from './styles.css.js';
import { useContainerQuery } from '@cloudscape-design/component-toolkit';
import customCssProps from '../../internal/generated/custom-css-properties';

interface AppLayoutInternals extends AppLayoutProps {
activeDrawerId?: string | null;
Expand All @@ -41,6 +40,7 @@ interface AppLayoutInternals extends AppLayoutProps {
drawerRef: React.Ref<HTMLElement>;
resizeHandle: React.ReactElement;
drawersTriggerCount: number;
dynamicOverlapHeight: number;
handleDrawersClick: (activeDrawerId: string | null, skipFocusControl?: boolean) => void;
handleSplitPanelClick: () => void;
handleNavigationClick: (isOpen: boolean) => void;
Expand All @@ -52,8 +52,6 @@ interface AppLayoutInternals extends AppLayoutProps {
hasNotificationsContent: boolean;
hasOpenDrawer?: boolean;
hasStickyBackground: boolean;
isDynamicOverlapDisabled: boolean;
isDynamicOverlapSet: boolean;
isMobile: boolean;
isNavigationOpen: boolean;
isSplitPanelForcedPosition: boolean;
Expand Down Expand Up @@ -138,8 +136,7 @@ export const AppLayoutInternalsProvider = React.forwardRef(
* If a child component utilizes a sticky header the hasStickyBackground property will determine
* if the background remains in the same vertical position.
*/
const [isDynamicOverlapSet, setIsDynamicOverlapSet] = useState(false);
const [isDynamicOverlapDisabled, setIsDynamicOverlapDisabled] = useState(true);
const [dynamicOverlapHeight, setDynamicOverlapHeight] = useState(0);
const [hasStickyBackground, setHasStickyBackground] = useState(false);

/**
Expand Down Expand Up @@ -490,40 +487,6 @@ export const AppLayoutInternalsProvider = React.forwardRef(
const mainElement = useRef<HTMLDivElement>(null);
const [mainOffsetLeft, setMainOffsetLeft] = useState(0);

const hasContentHeader = !!props.contentHeader;

const updateDynamicOverlapHeight = useCallback(
(height: number) => {
/**
* The disableContentHeaderOverlap property is absolute and will always disable the overlap
* if it is set to true. If there is no contentHeader then the overlap should be disabled
* unless there is a dynamicOverlapHeight. The dynamicOverlapHeight property is set by a
* component in the content slot that needs to manually control the overlap height.
*/
const isOverlapSet = hasContentHeader || height > 0;
const isOverlapDisabled = props.disableContentHeaderOverlap || !isOverlapSet;
setIsDynamicOverlapSet(isOverlapSet);
setIsDynamicOverlapDisabled(isOverlapDisabled);

/**
* React 18 will trigger a paint before the state is correctly updated
* (see https://github.com/facebook/react/issues/24331).
* To work around this, we bypass React state updates and imperatively update the custom property on the DOM.
* An alternative would be to use `queueMicrotask` and `flushSync` in the ResizeObserver callback,
* but that would have some performance impact as it would delay the render.
* Using React state for `isDynamicOverlapSet` and `isDynamicOverlapDisabled` is less problematic
* because they will rarely change within the lifecycle of an application.
*/
const element = typeof layoutElement !== 'function' && layoutElement?.current; // Layout component uses RefObject
if (isOverlapDisabled || height <= 0) {
element?.style.removeProperty(customCssProps.overlapHeight);
} else {
element?.style.setProperty(customCssProps.overlapHeight, `${height}px`);
}
},
[layoutElement, hasContentHeader, props.disableContentHeaderOverlap]
);

useLayoutEffect(
function handleMainOffsetLeft() {
setMainOffsetLeft(mainElement?.current?.offsetLeft ?? 0);
Expand Down Expand Up @@ -637,6 +600,7 @@ export const AppLayoutInternalsProvider = React.forwardRef(
drawerRef,
resizeHandle,
drawersTriggerCount,
dynamicOverlapHeight,
headerHeight,
footerHeight,
hasDefaultToolsWidth,
Expand All @@ -652,8 +616,6 @@ export const AppLayoutInternalsProvider = React.forwardRef(
hasStickyBackground,
isMobile,
isNavigationOpen: isNavigationOpen ?? false,
isDynamicOverlapDisabled,
isDynamicOverlapSet,
isSplitPanelForcedPosition,
isSplitPanelOpen,
isToolsOpen,
Expand Down Expand Up @@ -698,7 +660,7 @@ export const AppLayoutInternalsProvider = React.forwardRef(
setHasStickyBackground,
}}
>
<DynamicOverlapContext.Provider value={updateDynamicOverlapHeight}>{children}</DynamicOverlapContext.Provider>
<DynamicOverlapContext.Provider value={setDynamicOverlapHeight}>{children}</DynamicOverlapContext.Provider>
</AppLayoutContext.Provider>
</AppLayoutInternalsContext.Provider>
);
Expand Down
19 changes: 15 additions & 4 deletions src/app-layout/visual-refresh/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ export default function Layout({ children }: LayoutProps) {
contentHeader,
contentType,
disableBodyScroll,
disableContentHeaderOverlap,
disableContentPaddings,
drawersTriggerCount,
dynamicOverlapHeight,
footerHeight,
hasNotificationsContent,
hasStickyBackground,
hasOpenDrawer,
headerHeight,
isDynamicOverlapDisabled,
isMobile,
isNavigationOpen,
layoutElement,
Expand All @@ -52,6 +53,14 @@ export default function Layout({ children }: LayoutProps) {
const hasContentGapLeft = isNavigationOpen || navigationHide;
const hasContentGapRight = drawersTriggerCount <= 0 || hasOpenDrawer;

/**
* The disableContentHeaderOverlap property is absolute and will always disable the overlap
* if it is set to true. If there is no contentHeader then the overlap should be disabled
* unless there is a dynamicOverlapHeight. The dynamicOverlapHeight property is set by a
* component in the content slot that needs to manually control the overlap height.
*/
const isOverlapDisabled = disableContentHeaderOverlap || (!contentHeader && dynamicOverlapHeight <= 0);

return (
<main
className={clsx(
Expand All @@ -71,7 +80,7 @@ export default function Layout({ children }: LayoutProps) {
[styles['has-split-panel']]: splitPanelDisplayed,
[styles['has-sticky-background']]: hasStickyBackground,
[styles['has-sticky-notifications']]: stickyNotifications && hasNotificationsContent,
[styles['is-overlap-disabled']]: isDynamicOverlapDisabled,
[styles['is-overlap-disabled']]: isOverlapDisabled,
},
testutilStyles.root
)}
Expand All @@ -84,6 +93,8 @@ export default function Layout({ children }: LayoutProps) {
...(maxContentWidth && { [customCssProps.maxContentWidth]: `${maxContentWidth}px` }),
...(minContentWidth && { [customCssProps.minContentWidth]: `${minContentWidth}px` }),
[customCssProps.notificationsHeight]: `${notificationsHeight}px`,
...(!isOverlapDisabled &&
dynamicOverlapHeight > 0 && { [customCssProps.overlapHeight]: `${dynamicOverlapHeight}px` }),
}}
>
{children}
Expand All @@ -93,8 +104,8 @@ export default function Layout({ children }: LayoutProps) {

/*
The Notifications, Breadcrumbs, Header, and Main are all rendered in the center
column of the grid layout. Any of these could be the first child to render in the
content area if the previous siblings do not exist. The grid gap before the first
column of the grid layout. Any of these could be the first child to render in the
content area if the previous siblings do not exist. The grid gap before the first
child will be different to ensure vertical alignment with the trigger buttons.
*/
function getContentFirstChild(
Expand Down
11 changes: 10 additions & 1 deletion src/internal/hooks/container-queries/use-resize-observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { ResizeObserver, ResizeObserverEntry } from '@juggle/resize-observer';
import React, { useEffect, useLayoutEffect } from 'react';
import { useStableEventHandler } from '../use-stable-event-handler';
import { ContainerQueryEntry } from '@cloudscape-design/component-toolkit';
import { convertResizeObserverEntry } from './utils';

type ElementReference = (() => Element | null) | React.RefObject<Element>;

Expand Down Expand Up @@ -59,3 +58,13 @@ export function useResizeObserver(elementRef: ElementReference, onObserve: (entr
}
}, [elementRef, stableOnObserve]);
}

function convertResizeObserverEntry(entry: ResizeObserverEntry): ContainerQueryEntry {
return {
target: entry.target,
contentBoxWidth: entry.contentBoxSize[0].inlineSize,
contentBoxHeight: entry.contentBoxSize[0].blockSize,
borderBoxWidth: entry.borderBoxSize[0].inlineSize,
borderBoxHeight: entry.borderBoxSize[0].blockSize,
};
}
14 changes: 0 additions & 14 deletions src/internal/hooks/container-queries/utils.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { render, screen } from '@testing-library/react';
import { useDynamicOverlap } from '../../../../../lib/components/internal/hooks/use-dynamic-overlap';
import { DynamicOverlapContext } from '../../../../../lib/components/internal/context/dynamic-overlap-context';

jest.mock('../../../../../lib/components/internal/hooks/container-queries/utils', () => ({
...jest.requireActual('../../../../../lib/components/internal/hooks/container-queries/utils'),
convertResizeObserverEntry: () => ({ contentBoxHeight: 800 }),
jest.mock('@cloudscape-design/component-toolkit', () => ({
...jest.requireActual('@cloudscape-design/component-toolkit'),
useContainerQuery: () => [800, () => {}],
}));

function renderApp(children: React.ReactNode) {
Expand Down
Loading
Loading