Skip to content

Commit

Permalink
feat: upgrade clientOnly helper
Browse files Browse the repository at this point in the history
  • Loading branch information
magne4000 committed Oct 21, 2024
1 parent 58ad664 commit d739a23
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions packages/vike-solid/helpers/clientOnly.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
type Component,
type ComponentProps,
type JSX,
type Setter,
createMemo,
createSignal,
onMount,
Expand All @@ -16,22 +17,34 @@ import { isServer } from "solid-js/web";
* Load and render a component only on the client-side.
* @see {@link https://vike.dev/clientOnly}
*/
export function clientOnly<T extends Component<any>>(fn: () => Promise<{ default: T } | T>) {
export function clientOnly<T extends Component<any>>(
fn: () => Promise<{ default: T } | T>,
options: { lazy?: boolean } = {},
) {
if (isServer) return (props: ComponentProps<T> & { fallback?: JSX.Element }) => <>{props.fallback}</>;

const [comp, setComp] = createSignal<T>();
fn().then((m) => setComp(() => ("default" in m ? m.default : m)));
if (!options.lazy) {
load(fn, setComp);
}
// eslint-disable-next-line solid/reactivity
return (props: ComponentProps<T>) => {
let Comp: T | undefined;
let m: boolean;
const [, rest] = splitProps(props, ["fallback"]);
if (options.lazy) {
load(fn, setComp);
}
if ((Comp = comp()) && !sharedConfig.context) return Comp(rest);
const [mounted, setMounted] = createSignal(!sharedConfig.context);
onMount(() => setMounted(true));
// eslint-disable-next-line solid/reactivity
return createMemo(
() => ((Comp = comp()), (m = mounted()), untrack(() => (Comp && m ? Comp(rest) : props.fallback))),
);
) as unknown as JSX.Element;
};
}

function load<T>(fn: () => Promise<{ default: T } | T>, setComp: Setter<T>) {
fn().then((m) => setComp(() => ("default" in (m as object) ? (m as any).default : m)));
}

0 comments on commit d739a23

Please sign in to comment.