@@ -4,14 +4,29 @@ import { createMemo, createSignal, onMount, sharedConfig, splitProps, untrack }
44import { isServer } from "solid-js/web" ;
55
66/**
7+ * What a `clientOnly` loader can resolve to: a module with a default export,
8+ * or the component itself.
9+ */
10+ type ClientOnlyModule < T > = T | { default : T } ;
11+
12+ /**
13+ * Renders a component only on the client. The loader can resolve to a module
14+ * with a default export, or to the component itself, which also works for a
15+ * named export:
16+ *
17+ * ```tsx
18+ * const Map = clientOnly(() => import("./map"));
19+ * const Chart = clientOnly(() => import("./chart").then(({ Chart }) => Chart));
20+ * ```
21+ *
22+ * Destructuring the export inside the loader, as in the second example, lets
23+ * the bundler leave the module's other exports out of the chunk.
724 *
825 * Read more: https://docs.solidjs.com/solid-start/reference/client/client-only
926 */
1027// not using Suspense
1128export default function clientOnly < T extends Component < any > > (
12- fn : ( ) => Promise < {
13- default : T ;
14- } > ,
29+ fn : ( ) => Promise < ClientOnlyModule < T > > ,
1530 options : { lazy ?: boolean } = { }
1631) {
1732 if ( isServer ) return ( props : ComponentProps < T > & { fallback ?: JSX . Element } ) => props . fallback ;
@@ -34,11 +49,10 @@ export default function clientOnly<T extends Component<any>>(
3449 } ;
3550}
3651
37- function load < T > (
38- fn : ( ) => Promise < {
39- default : T ;
40- } > ,
41- setComp : Setter < T >
52+ function load < T extends Component < any > > (
53+ fn : ( ) => Promise < ClientOnlyModule < T > > ,
54+ setComp : Setter < T | undefined >
4255) {
43- fn ( ) . then ( m => setComp ( ( ) => m . default ) ) ;
56+ // A module namespace object is never a function, and a component always is.
57+ fn ( ) . then ( m => setComp ( ( ) => ( typeof m === "function" ? m : m . default ) ) ) ;
4458}
0 commit comments