diff --git a/packages/chronicle/src/server/App.module.css b/packages/chronicle/src/server/App.module.css new file mode 100644 index 0000000..0864892 --- /dev/null +++ b/packages/chronicle/src/server/App.module.css @@ -0,0 +1,4 @@ +.fallback { + padding: var(--rs-space-8); + width: 80%; +} diff --git a/packages/chronicle/src/server/App.tsx b/packages/chronicle/src/server/App.tsx index 16db22e..cfa7fc2 100644 --- a/packages/chronicle/src/server/App.tsx +++ b/packages/chronicle/src/server/App.tsx @@ -1,17 +1,20 @@ import '@raystack/apsara/normalize.css'; import '@raystack/apsara/style.css'; -import { ThemeProvider } from '@raystack/apsara'; +import { ThemeProvider, Skeleton, Flex } from '@raystack/apsara'; +import { lazy, Suspense } from 'react'; import { Navigate, useLocation } from 'react-router'; import { Head } from '@/lib/head'; import { usePageContext } from '@/lib/page-context'; import { resolveRoute, RouteType } from '@/lib/route-resolver'; -import { ApiLayout } from '@/pages/ApiLayout'; -import { ApiPage } from '@/pages/ApiPage'; -import { DocsLayout } from '@/pages/DocsLayout'; -import { DocsPage } from '@/pages/DocsPage'; -import { LandingPage } from '@/pages/LandingPage'; import type { ChronicleConfig } from '@/types'; import { getThemeConfig } from '@/themes/registry'; +import styles from './App.module.css'; + +const ApiLayout = lazy(() => import('@/pages/ApiLayout').then(m => ({ default: m.ApiLayout }))); +const ApiPage = lazy(() => import('@/pages/ApiPage').then(m => ({ default: m.ApiPage }))); +const DocsLayout = lazy(() => import('@/pages/DocsLayout').then(m => ({ default: m.DocsLayout }))); +const DocsPage = lazy(() => import('@/pages/DocsPage').then(m => ({ default: m.DocsPage }))); +const LandingPage = lazy(() => import('@/pages/LandingPage').then(m => ({ default: m.LandingPage }))); export function App() { const { pathname } = useLocation(); @@ -35,19 +38,33 @@ export function App() { forcedTheme={themeConfig.forcedTheme} > - {isApi ? ( - - - - ) : ( - - {isLanding ? : } - - )} + }> + {isApi ? ( + + + + ) : ( + + {isLanding ? : } + + )} + ); } +function PageFallback() { + return ( + + + + {[...new Array(12)].map((_, i) => ( + + ))} + + ); +} + function RootHead({ config }: { config: ChronicleConfig }) { return ( import('@/components/api/playground-dialog').then(m => ({ default: m.PlaygroundDialog }))); import { ClientThemeSwitcher } from '@/components/ui/client-theme-switcher'; import { Search } from '@/components/ui/search'; import { Breadcrumbs } from '@/components/ui/breadcrumbs'; @@ -144,7 +145,7 @@ export function Layout({ ))} {apiEntries.map(api => ( Test request - + {open && ( + + + + )} ); } diff --git a/packages/chronicle/src/themes/default/Page.tsx b/packages/chronicle/src/themes/default/Page.tsx index a1bbaad..a3d6918 100644 --- a/packages/chronicle/src/themes/default/Page.tsx +++ b/packages/chronicle/src/themes/default/Page.tsx @@ -1,9 +1,11 @@ 'use client'; import { Flex, Headline } from '@raystack/apsara'; +import { lazy, Suspense } from 'react'; import type { ThemePageProps } from '@/types'; import styles from './Page.module.css'; -import { Toc } from './Toc'; + +const Toc = lazy(() => import('./Toc').then(m => ({ default: m.Toc }))); export function Page({ page }: ThemePageProps) { return ( @@ -16,7 +18,9 @@ export function Page({ page }: ThemePageProps) { )}
{page.content}
- + + + ); }