Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: vike-react Loading config #133

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 }