Skip to content

Commit d16c6be

Browse files
committed
type safety fixes
1 parent 4e8d2e1 commit d16c6be

File tree

13 files changed

+55
-24
lines changed

13 files changed

+55
-24
lines changed

src/app-layout/visual-refresh-toolbar/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
55
import ScreenreaderOnly from '../../internal/components/screenreader-only';
66
import { AppLayoutProps } from '../interfaces';
77
import { AppLayoutVisibilityContext } from './contexts';
8-
import { AppLayoutInternalProps, AppLayoutState } from './interfaces';
8+
import { AppLayoutInternalProps, AppLayoutPendingState } from './interfaces';
99
import { AppLayoutWidgetizedState } from './internal';
1010
import { SkeletonLayout } from './skeleton';
1111
import { SkeletonSlotsAttributes } from './skeleton/interfaces';
@@ -20,12 +20,12 @@ const AppLayoutStateProvider: React.FC<{
2020
stateManager: React.MutableRefObject<StateManager>;
2121
children: (
2222
registered: boolean,
23-
appLayoutState: AppLayoutState,
23+
appLayoutState: AppLayoutPendingState,
2424
toolbarProps: ToolbarProps | null,
2525
skeletonAttributes: SkeletonSlotsAttributes
2626
) => React.ReactNode;
2727
}> = ({ forceDeduplicationType, appLayoutProps, stateManager, children }) => {
28-
const [appLayoutState, setAppLayoutState] = useState<AppLayoutState>(() => ({ isIntersecting: true }));
28+
const [appLayoutState, setAppLayoutState] = useState<AppLayoutPendingState>(() => ({ isIntersecting: true }));
2929
const [skeletonAttributes, setSkeletonAttributes] = useState<SkeletonSlotsAttributes>(() => ({}));
3030
// use { fn: } object wrapper to avoid confusion with callback form of setState
3131
const [deduplicator, setDeduplicator] = useState({ fn: mergeProps });

src/app-layout/visual-refresh-toolbar/interfaces.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import React from 'react';
55

66
import { BreadcrumbGroupProps } from '../../breadcrumb-group/interfaces';
77
import { SplitPanelSideToggleProps } from '../../internal/context/split-panel-context';
8+
import { SomeOptional } from '../../internal/types';
89
import { AppLayoutProps, AppLayoutPropsWithDefaults } from '../interfaces';
910
import { SplitPanelProviderProps } from '../split-panel';
1011
import { OnChangeParams } from '../utils/use-drawers';
@@ -73,6 +74,7 @@ export interface AppLayoutInternals {
7374
interface AppLayoutWidgetizedState extends AppLayoutInternals {
7475
isNested: boolean;
7576
verticalOffsets: VerticalLayoutOutput;
77+
navigationAnimationDisabled: boolean;
7678
splitPanelOffsets: {
7779
stickyVerticalBottomOffset: number;
7880
mainContentPaddingBlockEnd: number | undefined;
@@ -81,11 +83,16 @@ interface AppLayoutWidgetizedState extends AppLayoutInternals {
8183

8284
// New widget interface
8385
export interface AppLayoutState {
84-
rootRef?: React.Ref<HTMLElement>;
86+
rootRef: React.Ref<HTMLElement>;
8587
isIntersecting: boolean;
8688
// new state management
87-
widgetizedState?: AppLayoutWidgetizedState;
89+
widgetizedState: AppLayoutWidgetizedState;
8890
// the old object shape for backward compatibility
89-
appLayoutInternals?: AppLayoutInternals;
90-
splitPanelInternals?: SplitPanelProviderProps;
91+
appLayoutInternals: AppLayoutInternals;
92+
splitPanelInternals: SplitPanelProviderProps;
9193
}
94+
95+
export type AppLayoutPendingState = SomeOptional<
96+
AppLayoutState,
97+
'appLayoutInternals' | 'splitPanelInternals' | 'widgetizedState' | 'rootRef'
98+
>;

src/app-layout/visual-refresh-toolbar/skeleton/index.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { getAnalyticsMetadataAttribute } from '@cloudscape-design/component-tool
88
import { GeneratedAnalyticsMetadataAppLayoutToolbarComponent } from '../../../app-layout-toolbar/analytics-metadata/interfaces';
99
import VisualContext from '../../../internal/components/visual-context';
1010
import customCssProps from '../../../internal/generated/custom-css-properties';
11-
import { AppLayoutInternalProps, AppLayoutState } from '../interfaces';
11+
import { AppLayoutInternalProps, AppLayoutPendingState } from '../interfaces';
1212
import {
1313
AppLayoutAfterMainSlot,
1414
AppLayoutBeforeMainSlot,
@@ -24,7 +24,7 @@ import styles from './styles.css.js';
2424
export interface SkeletonLayoutProps {
2525
registered: boolean;
2626
appLayoutProps: AppLayoutInternalProps;
27-
appLayoutState: AppLayoutState;
27+
appLayoutState: AppLayoutPendingState;
2828
toolbarProps: ToolbarProps | null;
2929
skeletonSlotsAttributes: SkeletonSlotsAttributes;
3030
}

src/app-layout/visual-refresh-toolbar/skeleton/interfaces.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
import React from 'react';
44

5-
import { AppLayoutInternalProps, AppLayoutState } from '../interfaces';
5+
import { AppLayoutInternalProps, AppLayoutPendingState } from '../interfaces';
66
import { ToolbarProps } from '../toolbar';
77

88
interface ElementAttributes {
@@ -21,5 +21,5 @@ export interface SkeletonSlotsAttributes {
2121
export interface SkeletonPartProps {
2222
appLayoutProps: AppLayoutInternalProps;
2323
toolbarProps: ToolbarProps | null;
24-
appLayoutState: AppLayoutState;
24+
appLayoutState: AppLayoutPendingState;
2525
}

src/app-layout/visual-refresh-toolbar/skeleton/skeleton-parts.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export const BeforeMainSlotSkeleton = React.forwardRef<HTMLElement, SkeletonPart
1919
<>
2020
{!!toolbarProps && (
2121
<ToolbarSlot ref={ref}>
22-
{/*TODO: consider discovered breadcrumbs? */}
2322
<BreadcrumbsSlot ownBreadcrumbs={appLayoutProps.breadcrumbs} />
2423
</ToolbarSlot>
2524
)}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
import { AppLayoutPendingState, AppLayoutState } from '../interfaces';
4+
5+
export function isWidgetReady(state: AppLayoutPendingState): state is AppLayoutState {
6+
return !!state.widgetizedState;
7+
}

src/app-layout/visual-refresh-toolbar/state/props-merger.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
import { warnOnce } from '@cloudscape-design/component-toolkit/internal';
44

5-
import { AppLayoutInternalProps, AppLayoutState } from '../interfaces';
5+
import { AppLayoutInternalProps, AppLayoutPendingState } from '../interfaces';
66
import { ToolbarProps } from '../toolbar';
77
import { MergeProps, SharedProps } from './interfaces';
88

@@ -65,7 +65,7 @@ export const mergeProps: MergeProps = (ownProps, additionalProps) => {
6565
return Object.keys(toolbar).filter(key => key !== 'ariaLabels').length > 0 ? toolbar : null;
6666
};
6767

68-
export const getPropsToMerge = (props: AppLayoutInternalProps, appLayoutState: AppLayoutState): SharedProps => {
68+
export const getPropsToMerge = (props: AppLayoutInternalProps, appLayoutState: AppLayoutPendingState): SharedProps => {
6969
const state = appLayoutState.widgetizedState;
7070
return {
7171
breadcrumbs: props.breadcrumbs,

src/app-layout/visual-refresh-toolbar/state/use-app-layout.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { AppLayoutProps } from '../../interfaces';
1515
import { SplitPanelProviderProps } from '../../split-panel';
1616
import { MIN_DRAWER_SIZE, OnChangeParams, useDrawers } from '../../utils/use-drawers';
1717
import { useAsyncFocusControl, useFocusControl, useMultipleFocusControl } from '../../utils/use-focus-control';
18+
import { useGlobalScrollPadding } from '../../utils/use-global-scroll-padding';
1819
import { useSplitPanelFocusControl } from '../../utils/use-split-panel-focus-control';
1920
import {
2021
computeHorizontalLayout,
@@ -24,7 +25,6 @@ import {
2425
} from '../compute-layout';
2526
import { AppLayoutState } from '../interfaces';
2627
import { AppLayoutInternalProps, AppLayoutInternals } from '../interfaces';
27-
import { useGlobalScrollPadding } from '../../utils/use-global-scroll-padding';
2828

2929
export const useAppLayout = (
3030
hasToolbar: boolean,
@@ -71,7 +71,6 @@ export const useAppLayout = (
7171
const onMountRootRef = useCallback(node => {
7272
setIsNested(getIsNestedInAppLayout(node));
7373
}, []);
74-
const rootRef = useMergeRefs(rootRefInternal, onMountRootRef);
7574

7675
const [toolsOpen = false, setToolsOpen] = useControllable(controlledToolsOpen, onToolsChange, false, {
7776
componentName: 'AppLayout',
@@ -265,6 +264,8 @@ export const useAppLayout = (
265264

266265
const { ref: intersectionObserverRef, isIntersecting } = useIntersectionObserver({ initialState: true });
267266

267+
const rootRef = useMergeRefs(rootRefInternal, intersectionObserverRef, onMountRootRef);
268+
268269
useGlobalScrollPadding(verticalOffsets.header ?? 0);
269270

270271
const appLayoutInternals: AppLayoutInternals = {
@@ -430,12 +431,14 @@ export const useAppLayout = (
430431
});
431432

432433
return {
434+
rootRef,
433435
isIntersecting,
434436
appLayoutInternals,
435437
splitPanelInternals,
436438
widgetizedState: {
437439
...appLayoutInternals,
438440
isNested,
441+
navigationAnimationDisabled,
439442
verticalOffsets,
440443
splitPanelOffsets,
441444
},

src/app-layout/visual-refresh-toolbar/widget-areas/after-main-slot.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ import {
1111
} from '../drawer';
1212
import { SkeletonPartProps } from '../skeleton/interfaces';
1313
import { AppLayoutSplitPanelDrawerSideImplementation as AppLayoutSplitPanelSide } from '../split-panel';
14+
import { isWidgetReady } from '../state/invariants';
1415

1516
import sharedStyles from '../../resize/styles.css.js';
1617
import styles from '../skeleton/styles.css.js';
1718

1819
export const AfterMainSlotImplementation = ({ appLayoutState, appLayoutProps }: SkeletonPartProps) => {
19-
if (!appLayoutState.appLayoutInternals || !appLayoutState.splitPanelInternals) {
20+
if (!isWidgetReady(appLayoutState)) {
2021
return null;
2122
}
2223
const {
@@ -27,7 +28,7 @@ export const AfterMainSlotImplementation = ({ appLayoutState, appLayoutProps }:
2728
splitPanelOpen,
2829
drawers,
2930
splitPanelPosition,
30-
} = appLayoutState.widgetizedState ?? {};
31+
} = appLayoutState.widgetizedState;
3132
const drawerExpandedMode = !!expandedDrawerId;
3233
const toolsOpen = !!activeDrawer;
3334
const globalToolsOpen = !!activeGlobalDrawersIds?.length;

src/app-layout/visual-refresh-toolbar/widget-areas/before-main-slot.tsx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,18 @@ import { createWidgetizedComponent } from '../../../internal/widgets';
77
import { AppLayoutNavigationImplementation as AppLayoutNavigation } from '../navigation';
88
import { SkeletonPartProps } from '../skeleton/interfaces';
99
import { BeforeMainSlotSkeleton } from '../skeleton/skeleton-parts';
10+
import { isWidgetReady } from '../state/invariants';
1011
import { AppLayoutToolbarImplementation as AppLayoutToolbar } from '../toolbar';
1112

13+
import sharedStyles from '../../resize/styles.css.js';
1214
import styles from '../skeleton/styles.css.js';
1315

1416
export const BeforeMainSlotImplementation = ({ toolbarProps, appLayoutState }: SkeletonPartProps) => {
15-
if (!appLayoutState.widgetizedState || !appLayoutState.appLayoutInternals) {
17+
if (!isWidgetReady(appLayoutState)) {
1618
return null;
1719
}
18-
const { activeDrawer, navigationOpen, navigation, expandedDrawerId } = appLayoutState.widgetizedState;
20+
const { activeDrawer, navigationOpen, navigation, expandedDrawerId, navigationAnimationDisabled } =
21+
appLayoutState.widgetizedState;
1922
const drawerExpandedMode = !!expandedDrawerId;
2023
const toolsOpen = !!activeDrawer;
2124
// Must use `toolbarProps` because all layouts have to apply this mode, not just the one with toolbar
@@ -31,8 +34,7 @@ export const BeforeMainSlotImplementation = ({ toolbarProps, appLayoutState }: S
3134
styles.navigation,
3235
!navigationOpen && styles['panel-hidden'],
3336
toolsOpen && styles['unfocusable-mobile'],
34-
// TODO recover
35-
// !navigationAnimationDisabled && sharedStyles['with-motion-horizontal'],
37+
!navigationAnimationDisabled && sharedStyles['with-motion-horizontal'],
3638
(drawerExpandedMode || drawerExpandedModeInChildLayout) && styles.hidden
3739
)}
3840
>

0 commit comments

Comments
 (0)