|
1 | 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2 | 2 | // SPDX-License-Identifier: Apache-2.0
|
3 |
| -import React, { useEffect, useRef, useState } from 'react'; |
| 3 | +import React, { useEffect, useState } from 'react'; |
4 | 4 |
|
| 5 | +import { FunctionComponent } from '../../internal/widgets'; |
5 | 6 | import { isAppLayoutDelayedWidget } from '../utils/feature-flags';
|
6 | 7 | import { AppLayoutState as AppLayoutStateImplementation, createWidgetizedAppLayoutState } from './app-layout-state';
|
7 | 8 | import { createWidgetizedAppLayoutDrawer, createWidgetizedAppLayoutGlobalDrawers } from './drawer';
|
8 | 9 | import { createWidgetizedAppLayoutNavigation } from './navigation';
|
9 | 10 | import { createWidgetizedAppLayoutNotifications } from './notifications';
|
10 |
| -import { createWidgetizedAppLayoutBottomPageContentSlot } from './skeleton/widget-slots/bottom-page-content-slot'; |
11 |
| -import { createWidgetizedAppLayoutSidePageSlot } from './skeleton/widget-slots/side-page-slot'; |
12 |
| -import { createWidgetizedAppLayoutTopPageContentSlot } from './skeleton/widget-slots/top-page-content-slot'; |
13 |
| -import { createWidgetizedAppLayoutTopPageSlot, TopPageSlot } from './skeleton/widget-slots/top-page-slot'; |
| 11 | +import { |
| 12 | + AfterMainSlotImplementation, |
| 13 | + createWidgetizedAppLayoutAfterMainSlot, |
| 14 | +} from './skeleton/widget-slots/after-main-slot'; |
| 15 | +import { |
| 16 | + BeforeMainSlotImplementation, |
| 17 | + createWidgetizedAppLayoutBeforeMainSlot, |
| 18 | +} from './skeleton/widget-slots/before-main-slot'; |
| 19 | +import { |
| 20 | + BottomContentSlotImplementation, |
| 21 | + createWidgetizedAppLayoutBottomContentSlot, |
| 22 | +} from './skeleton/widget-slots/bottom-content-slot'; |
| 23 | +import { |
| 24 | + createWidgetizedAppLayoutTopContentSlot, |
| 25 | + TopContentSlotImplementation, |
| 26 | +} from './skeleton/widget-slots/top-content-slot'; |
14 | 27 | import {
|
15 | 28 | createWidgetizedAppLayoutSplitPanelDrawerBottom,
|
16 | 29 | createWidgetizedAppLayoutSplitPanelDrawerSide,
|
17 | 30 | } from './split-panel';
|
18 | 31 | import { createWidgetizedAppLayoutToolbar } from './toolbar';
|
19 | 32 |
|
| 33 | +const enableDelayedComponents = isAppLayoutDelayedWidget(); |
| 34 | + |
| 35 | +// Legacy widgetized parts |
20 | 36 | export const AppLayoutNavigation = createWidgetizedAppLayoutNavigation();
|
21 | 37 | export const AppLayoutDrawer = createWidgetizedAppLayoutDrawer();
|
22 | 38 | export const AppLayoutGlobalDrawers = createWidgetizedAppLayoutGlobalDrawers();
|
23 | 39 | export const AppLayoutNotifications = createWidgetizedAppLayoutNotifications();
|
24 | 40 | export const AppLayoutToolbar = createWidgetizedAppLayoutToolbar();
|
25 | 41 | export const AppLayoutSplitPanelBottom = createWidgetizedAppLayoutSplitPanelDrawerBottom();
|
26 | 42 | export const AppLayoutSplitPanelSide = createWidgetizedAppLayoutSplitPanelDrawerSide();
|
27 |
| -export const AppLayoutSkeletonTopSlot = createWidgetizedAppLayoutTopPageSlot( |
28 |
| - createAppLayoutPart({ Component: TopPageSlot }) |
| 43 | + |
| 44 | +// Refactored widgetized parts |
| 45 | +export const AppLayoutBeforeMainSlot = createWidgetizedAppLayoutBeforeMainSlot( |
| 46 | + createLoadableComponent(BeforeMainSlotImplementation) |
| 47 | +); |
| 48 | +export const AppLayoutAfterMainSlot = createWidgetizedAppLayoutAfterMainSlot( |
| 49 | + createLoadableComponent(AfterMainSlotImplementation) |
| 50 | +); |
| 51 | +export const AppLayoutTopContentSlot = createWidgetizedAppLayoutTopContentSlot( |
| 52 | + createLoadableComponent(TopContentSlotImplementation) |
| 53 | +); |
| 54 | +export const AppLayoutBottomContentSlot = createWidgetizedAppLayoutBottomContentSlot( |
| 55 | + createLoadableComponent(BottomContentSlotImplementation) |
29 | 56 | );
|
30 |
| -export const AppLayoutSkeletonSideSlot = createWidgetizedAppLayoutSidePageSlot(); |
31 |
| -export const AppLayoutSkeletonTopContentSlot = createWidgetizedAppLayoutTopPageContentSlot(); |
32 |
| -export const AppLayoutSkeletonBottomContentSlot = createWidgetizedAppLayoutBottomPageContentSlot(); |
33 | 57 | export const AppLayoutWidgetizedState = createWidgetizedAppLayoutState(
|
34 |
| - createAppLayoutPart({ Component: AppLayoutStateImplementation }) |
| 58 | + createLoadableComponent(AppLayoutStateImplementation) |
35 | 59 | );
|
36 | 60 |
|
37 |
| -const enableDelayedComponents = isAppLayoutDelayedWidget(); |
38 |
| - |
39 |
| -export function createAppLayoutPart({ Component }: { Component: React.JSXElementConstructor<any> }) { |
40 |
| - const AppLayoutPartLoader = ({ Skeleton, ...props }: any) => { |
41 |
| - const [mount, setMount] = useState(false); |
42 |
| - const ref = useRef<HTMLDivElement>(null); |
| 61 | +export function createLoadableComponent<Props extends Record<string, any>>(Component: FunctionComponent<Props>) { |
| 62 | + if (!enableDelayedComponents) { |
| 63 | + return; |
| 64 | + } |
| 65 | + return (props: Props) => { |
| 66 | + const [mounted, setMounted] = useState(false); |
43 | 67 |
|
44 | 68 | useEffect(() => {
|
45 |
| - const timeoutId = setTimeout(() => { |
46 |
| - setMount(true); |
47 |
| - }, 1000); |
48 |
| - |
| 69 | + const timeoutId = setTimeout(() => setMounted(true), 1000); |
49 | 70 | return () => clearTimeout(timeoutId);
|
50 | 71 | }, []);
|
51 | 72 |
|
52 |
| - if (!enableDelayedComponents || (mount && enableDelayedComponents)) { |
| 73 | + if (mounted) { |
53 | 74 | return <Component {...props} />;
|
54 | 75 | }
|
| 76 | + // this prop is injected in `createWidgetizedComponent` and is not a part of the component signature |
| 77 | + const { Skeleton } = props as any; |
55 | 78 |
|
56 |
| - if (Skeleton) { |
57 |
| - return <Skeleton ref={ref} {...props} />; |
58 |
| - } |
59 |
| - return <div ref={ref} />; |
| 79 | + return Skeleton ? <Skeleton {...props} /> : <div />; |
60 | 80 | };
|
61 |
| - return AppLayoutPartLoader; |
62 | 81 | }
|
0 commit comments