Skip to content

Commit

Permalink
chore: Refactor drawer visibility callback
Browse files Browse the repository at this point in the history
  • Loading branch information
georgylobko committed Nov 15, 2024
1 parent 5343b83 commit a321b5f
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 22 deletions.
2 changes: 2 additions & 0 deletions pages/app-layout/runtime-drawers-persist-open-state.page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ awsuiPlugins.appLayout.registerDrawer({
<rect fill="currentColor" x="5" y="5" width="6" height="6" />
</svg>`,
},
// preserveInactiveContent: true,

ariaLabels: {
closeButton: 'Close button',
Expand All @@ -32,6 +33,7 @@ awsuiPlugins.appLayout.registerDrawer({
mountContent: (container, { onVisibilityChange }) => {
awsuiPlugins.appLayout.updateDrawer({ id: 'runtime-drawer-persist-open-state', defaultActive: true });
onVisibilityChange(isVisible => {
console.log('onVisibilityChange: ', isVisible);
awsuiPlugins.appLayout.updateDrawer({ id: 'runtime-drawer-persist-open-state', defaultActive: isVisible });
});
render(<Counter id="runtime-drawer-persist-open-state" />, container);
Expand Down
15 changes: 4 additions & 11 deletions src/app-layout/runtime-drawer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ export interface DrawersLayout {
localAfter: Array<AppLayoutProps.Drawer>;
}

type VisibilityCallback = (isVisible: boolean) => void;

interface RuntimeContentWrapperProps {
id?: string;
mountContent: RuntimeDrawerConfig['mountContent'];
Expand All @@ -26,28 +24,23 @@ interface RuntimeContentWrapperProps {

function RuntimeDrawerWrapper({ mountContent, unmountContent, id }: RuntimeContentWrapperProps) {
const ref = useRef<HTMLDivElement>(null);
const visibilityChangeCallback = useRef<VisibilityCallback | null>(null);
const activeDrawersIds = useContext(ActiveDrawersContext);
const isVisible = !!id && activeDrawersIds.includes(id);
const drawersVisibilityCallbackMap = useContext(ActiveDrawersContext);

useEffect(() => {
const container = ref.current!;
mountContent(container, {
onVisibilityChange: cb => {
visibilityChangeCallback.current = cb;
if (drawersVisibilityCallbackMap?.current && id) {
drawersVisibilityCallbackMap.current[id!] = cb;
}
},
});
return () => {
unmountContent(container);
visibilityChangeCallback.current = null;
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
visibilityChangeCallback.current?.(isVisible);
}, [isVisible]);

return <div ref={ref} className={styles['runtime-content-wrapper']}></div>;
}

Expand Down
10 changes: 10 additions & 0 deletions src/app-layout/utils/use-drawers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,13 @@ function applyToolsDrawer(toolsProps: ToolsProps, runtimeDrawers: DrawersLayout)

export const MIN_DRAWER_SIZE = 290;

type VisibilityCallback = (isVisible: boolean) => void;

type UseDrawersProps = Pick<AppLayoutProps, 'drawers' | 'activeDrawerId' | 'onDrawerChange'> & {
__disableRuntimeDrawers?: boolean;
onGlobalDrawerFocus?: (drawerId: string, open: boolean) => void;
onAddNewActiveDrawer?: (drawerId: string) => void;
visibilityCallbackMap?: Record<string, VisibilityCallback | null>;
};

export function useDrawers(
Expand All @@ -188,6 +191,7 @@ export function useDrawers(
onGlobalDrawerFocus,
onAddNewActiveDrawer,
__disableRuntimeDrawers: disableRuntimeDrawers,
visibilityCallbackMap,
}: UseDrawersProps,
ariaLabels: AppLayoutProps['ariaLabels'],
toolsProps: ToolsProps
Expand Down Expand Up @@ -234,11 +238,17 @@ export function useDrawers(
setActiveGlobalDrawersIds(currentState => currentState.filter(id => id !== drawerId));
onGlobalDrawerFocus?.(drawerId, false);
drawersOpenQueue.current = drawersOpenQueue.current.filter(id => id !== drawerId);
if (visibilityCallbackMap) {
visibilityCallbackMap[drawerId]?.(false);
}
} else if (drawerId) {
onAddNewActiveDrawer?.(drawerId);
setActiveGlobalDrawersIds(currentState => [drawerId, ...currentState].slice(0, DRAWERS_LIMIT!));
onGlobalDrawerFocus?.(drawerId, true);
drawersOpenQueue.current = [drawerId, ...drawersOpenQueue.current];
if (visibilityCallbackMap) {
visibilityCallbackMap[drawerId]?.(true);
}
}
}

Expand Down
8 changes: 6 additions & 2 deletions src/app-layout/utils/visibility-context.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { createContext } from 'react';
import React, { createContext } from 'react';

export const ActiveDrawersContext = createContext<ReadonlyArray<string>>([]);
type VisibilityCallback = (isVisible: boolean) => void;

export const ActiveDrawersContext = createContext<React.MutableRefObject<
Record<string, VisibilityCallback | null>
> | null>({ current: {} });
30 changes: 21 additions & 9 deletions src/app-layout/visual-refresh-toolbar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import React, { useEffect, useImperativeHandle, useState } from 'react';
import React, { useEffect, useImperativeHandle, useRef, useState } from 'react';

import { useStableCallback } from '@cloudscape-design/component-toolkit/internal';

Expand Down Expand Up @@ -34,6 +34,8 @@ import {
import { useMultiAppLayout } from './multi-layout';
import { SkeletonLayout } from './skeleton';

type VisibilityCallback = (isVisible: boolean) => void;

const AppLayoutVisualRefreshToolbar = React.forwardRef<AppLayoutProps.Ref, AppLayoutPropsWithDefaults>(
(
{
Expand Down Expand Up @@ -78,6 +80,7 @@ const AppLayoutVisualRefreshToolbar = React.forwardRef<AppLayoutProps.Ref, AppLa
const [notificationsHeight, setNotificationsHeight] = useState(0);
const [navigationAnimationDisabled, setNavigationAnimationDisabled] = useState(true);
const [splitPanelAnimationDisabled, setSplitPanelAnimationDisabled] = useState(true);
const drawersVisibilityCallbackMap = useRef<Record<string, VisibilityCallback | null>>({});

const [toolsOpen = false, setToolsOpen] = useControllable(controlledToolsOpen, onToolsChange, false, {
componentName: 'AppLayout',
Expand Down Expand Up @@ -141,14 +144,23 @@ const AppLayoutVisualRefreshToolbar = React.forwardRef<AppLayoutProps.Ref, AppLa
onActiveDrawerChange,
onActiveDrawerResize,
onActiveGlobalDrawersChange,
} = useDrawers({ ...rest, onGlobalDrawerFocus, onAddNewActiveDrawer }, ariaLabels, {
} = useDrawers(
{
...rest,
onGlobalDrawerFocus,
onAddNewActiveDrawer,
visibilityCallbackMap: drawersVisibilityCallbackMap.current,
},
ariaLabels,
toolsHide,
toolsOpen,
tools,
toolsWidth,
onToolsToggle,
});
{
ariaLabels,
toolsHide,
toolsOpen,
tools,
toolsWidth,
onToolsToggle,
}
);

const onActiveDrawerChangeHandler = (drawerId: string | null) => {
onActiveDrawerChange(drawerId);
Expand Down Expand Up @@ -459,7 +471,7 @@ const AppLayoutVisualRefreshToolbar = React.forwardRef<AppLayoutProps.Ref, AppLa
navigationAnimationDisabled={navigationAnimationDisabled}
tools={drawers && drawers.length > 0 && <AppLayoutDrawer appLayoutInternals={appLayoutInternals} />}
globalTools={
<ActiveDrawersContext.Provider value={activeGlobalDrawersIds}>
<ActiveDrawersContext.Provider value={drawersVisibilityCallbackMap}>
<AppLayoutGlobalDrawers appLayoutInternals={appLayoutInternals} />
</ActiveDrawersContext.Provider>
}
Expand Down

0 comments on commit a321b5f

Please sign in to comment.