Skip to content

Commit

Permalink
feat: vike-react Loading config (#133)
Browse files Browse the repository at this point in the history
  • Loading branch information
nitedani authored Jul 16, 2024
1 parent fa812a0 commit 2737f03
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 16 deletions.
6 changes: 4 additions & 2 deletions packages/vike-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
".": "./dist/index.js",
"./config": "./dist/+config.js",
"./renderer/onRenderHtml": "./dist/renderer/onRenderHtml.js",
"./renderer/onRenderClient": "./dist/renderer/onRenderClient.js"
"./renderer/onRenderClient": "./dist/renderer/onRenderClient.js",
"./components/Loading": "./dist/components/Loading.js"
},
"scripts": {
"dev": "tsc --watch",
"build": "rimraf dist/ && tsc",
"build": "rimraf dist/ && tsc && pnpm run build:css",
"build:css": "cp src/renderer/styles.css dist/renderer/styles.css",
"release": "release-me patch",
"release:minor": "release-me minor",
"release:commit": "release-me commit"
Expand Down
5 changes: 5 additions & 0 deletions packages/vike-react/src/+config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export default {
vike: '>=0.4.178'
},

Loading: 'import:vike-react/components/Loading:default',

// https://vike.dev/onRenderHtml
onRenderHtml: 'import:vike-react/renderer/onRenderHtml:onRenderHtml',
// https://vike.dev/onRenderClient
Expand Down Expand Up @@ -73,6 +75,9 @@ export default {
},
reactStrictMode: {
env: { client: true, server: true }
},
Loading: {
env: { server: true, client: true }
}
}
} satisfies Config
22 changes: 22 additions & 0 deletions packages/vike-react/src/components/Loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react'

export default {
component: LoadingComponent
}

function LoadingComponent() {
return (
<div
style={{
width: '100%',
height: '100%',
maxHeight: '100%',
background: 'linear-gradient(110deg, #ececec 8%, #f5f5f5 18%, #ececec 33%)',
borderRadius: '5px',
backgroundSize: '200% 100%',
animation: '1.3s vike-react-shine linear infinite',
aspectRatio: '2.5/1'
}}
/>
)
}
18 changes: 14 additions & 4 deletions packages/vike-react/src/renderer/getPageElement.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
export { getPageElement }

import React from 'react'
import React, { Suspense } from 'react'
import type { PageContext } from 'vike/types'
import { PageContextProvider } from '../hooks/usePageContext.js'

function getPageElement(pageContext: PageContext): JSX.Element {
const { Page } = pageContext
const {
Page,
config: { Loading }
} = pageContext
let page = Page ? <Page /> : null

// Wrapping
const addSuspense = (el: React.JSX.Element | null) => {
if (!Loading?.layout) return el
return <Suspense fallback={<Loading.layout />}>{page}</Suspense>
}
page = addSuspense(page)
;[
// Inner wrapping
...(pageContext.config.Layout || []),
// Outer wrapping
...(pageContext.config.Wrapper || [])
].forEach((Wrapper) => {
page = <Wrapper>{page}</Wrapper>
].forEach((Wrap) => {
page = <Wrap>{page}</Wrap>
page = addSuspense(page)
})

page = <PageContextProvider pageContext={pageContext}>{page}</PageContextProvider>
if (pageContext.config.reactStrictMode !== false) {
page = <React.StrictMode>{page}</React.StrictMode>
Expand Down
1 change: 1 addition & 0 deletions packages/vike-react/src/renderer/onRenderClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import ReactDOM from 'react-dom/client'
import { getHeadSetting } from './getHeadSetting.js'
import type { OnRenderClientSync } from 'vike/types'
import { getPageElement } from './getPageElement.js'
import './styles.css'

let root: ReactDOM.Root
const onRenderClient: OnRenderClientSync = (pageContext): ReturnType<OnRenderClientSync> => {
Expand Down
23 changes: 13 additions & 10 deletions packages/vike-react/src/renderer/ssrEffect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@ import type { ConfigEffect } from 'vike/types'

function ssrEffect({ configDefinedAt, configValue }: Parameters<ConfigEffect>[0]): ReturnType<ConfigEffect> {
if (typeof configValue !== 'boolean') throw new Error(`${configDefinedAt} should be a boolean`)
const env = {
// Always load on the client-side.
client: true,
// When the SSR flag is false, we want to render the page only on the client-side.
// We achieve this by loading `Page` only on the client-side: when onRenderHtml()
// gets a `Page` value that is undefined it skip server-side rendering.
server: configValue !== false
}
return {
meta: {
Page: {
env: {
// Always load `Page` on the client-side.
client: true,
// When the SSR flag is false, we want to render the page only on the client-side.
// We achieve this by loading `Page` only on the client-side: when onRenderHtml()
// gets a `Page` value that is undefined it skip server-side rendering.
server: configValue !== false
}
}
Page: { env },
/* We don't do this to enable wraping <Head> with <Wrapper>
Wrapper: { env }, */
Layout: { env },
Loading: { env }
}
}
}
6 changes: 6 additions & 0 deletions packages/vike-react/src/renderer/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* For components/Loading.tsx */
@keyframes vike-react-shine {
to {
background-position-x: -200%;
}
}
2 changes: 2 additions & 0 deletions packages/vike-react/src/types/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ declare global {
* https://vike.dev/onAfterRenderClient
*/
onAfterRenderClient?: (pageContext: PageContextClient) => void
Loading?: Loading | ImportString
}
interface ConfigResolved {
Wrapper?: Wrapper[]
Expand All @@ -118,3 +119,4 @@ type PlainOrGetter<T> = T | ((pageContext: PageContext) => T)

type Wrapper = (props: { children: React.ReactNode }) => React.ReactNode
type Layout = Wrapper
type Loading = { component?: () => React.ReactNode; layout?: () => React.ReactNode }

0 comments on commit 2737f03

Please sign in to comment.