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(react-uploader): added ConditionalSuspense for SSR #29

Merged
merged 1 commit into from
May 27, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React, { FC, Suspense } from 'react';

export type TProps = {
fallback?: React.ReactChild | React.ReactFragment | React.ReactPortal | null;
condition: boolean;
children: React.ReactNode;
};

export const ConditionalSuspense: FC<TProps> = ({ condition, fallback, children, ...rest }) => {
return condition ? (
<Suspense fallback={fallback} {...rest}>
{children}
</Suspense>
) : (
<>{fallback}</>
);
};
2 changes: 2 additions & 0 deletions packages/react-uploader/src/SSR/ConditionalSuspense/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { ConditionalSuspense, type TProps } from './ConditionalSuspense';
export { useIsBrowser } from './useIsBrowser';
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { useState, useEffect } from 'react';

export const useIsBrowser = () => {
const [isBrowser, setIsBrowser] = useState(false);

useEffect(() => {
if (typeof window !== 'undefined') {
setIsBrowser(true);
}
}, []);

return isBrowser;
};
30 changes: 18 additions & 12 deletions packages/react-uploader/src/Uploader/Inline/FileUploaderInline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AdapterUploadCtxProvider } from "../core/AdapterUploadCtxProvider";
import type { TProps } from "../types";
import { getCalcPropertyOfProps } from "../../utils/getCalcPropertyOfProps";
import { getUserAgentIntegration } from "../../utils/getUserAgentIntegration";
import { ConditionalSuspense, useIsBrowser } from "../../SSR/ConditionalSuspense";

LR.registerBlocks(LR);

Expand All @@ -21,6 +22,7 @@ export const FileUploaderInline: FC<TProps> = ({
className,
classNameUploader,
apiRef,
fallback,
...props
}) => {
const CTX_NAME = useMemo(() => ctxName ?? LR.UID.generate(), [ctxName]);
Expand All @@ -30,19 +32,23 @@ export const FileUploaderInline: FC<TProps> = ({
[props],
);

const isBrowser = useIsBrowser();

return (
<div className={className}>
{/* @ts-ignore */}
<AdapterConfig userAgentIntegration={getUserAgentIntegration()} ctx-name={CTX_NAME} {...config} />
{/* @ts-ignore */}
<AdapterUploadCtxProvider
ref={apiRef}
ctx-name={CTX_NAME}
{...eventHandlers}
/>
<ConditionalSuspense condition={isBrowser} fallback={fallback} >
<div className={className}>
{/* @ts-ignore */}
<AdapterConfig userAgentIntegration={getUserAgentIntegration()} ctx-name={CTX_NAME} {...config} />
{/* @ts-ignore */}
<AdapterUploadCtxProvider
ref={apiRef}
ctx-name={CTX_NAME}
{...eventHandlers}
/>

{/* @ts-ignore */}
<AdapterFileUploaderInline class={classNameUploader} ctx-name={CTX_NAME} />
</div>
{/* @ts-ignore */}
<AdapterFileUploaderInline class={classNameUploader} ctx-name={CTX_NAME} />
</div>
</ConditionalSuspense>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AdapterUploadCtxProvider } from "../core/AdapterUploadCtxProvider";
import type { TProps } from "../types";
import { getCalcPropertyOfProps } from "../../utils/getCalcPropertyOfProps";
import { getUserAgentIntegration } from "../../utils/getUserAgentIntegration";
import { ConditionalSuspense, useIsBrowser } from "../../SSR/ConditionalSuspense";

LR.registerBlocks(LR);

Expand All @@ -22,6 +23,7 @@ export const FileUploaderMinimal: FC<TProps> = ({
className,
classNameUploader,
apiRef,
fallback,
...props
}) => {
const CTX_NAME = useMemo(() => ctxName ?? LR.UID.generate(), [ctxName]);
Expand All @@ -31,18 +33,22 @@ export const FileUploaderMinimal: FC<TProps> = ({
[props],
);

const isBrowser = useIsBrowser();

return (
<div className={className}>
{/* @ts-ignore */}
<AdapterConfig userAgentIntegration={getUserAgentIntegration()} ctx-name={CTX_NAME} {...config} />
{/* @ts-ignore */}
<AdapterUploadCtxProvider
ref={apiRef}
ctx-name={CTX_NAME}
{...eventHandlers}
/>
{/* @ts-ignore */}
<AdapterFileUploaderMinimal class={classNameUploader} ctx-name={CTX_NAME} />
</div>
<ConditionalSuspense condition={isBrowser} fallback={fallback} >
<div className={className}>
{/* @ts-ignore */}
<AdapterConfig userAgentIntegration={getUserAgentIntegration()} ctx-name={CTX_NAME} {...config} />
{/* @ts-ignore */}
<AdapterUploadCtxProvider
ref={apiRef}
ctx-name={CTX_NAME}
{...eventHandlers}
/>
{/* @ts-ignore */}
<AdapterFileUploaderMinimal class={classNameUploader} ctx-name={CTX_NAME} />
</div>
</ConditionalSuspense>
);
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import React, { type FC, useMemo } from "react";
import * as LR from "@uploadcare/blocks";
import "@uploadcare/blocks/web/lr-file-uploader-regular.min.css";
import { customElementToReactComponent } from "@uploadcare/react-adapter";
import { AdapterConfig } from "../core/AdapterConfig";
import { AdapterUploadCtxProvider } from "../core/AdapterUploadCtxProvider";
import type { TProps } from "../types";

import { getCalcPropertyOfProps } from "../../utils/getCalcPropertyOfProps";
import { getUserAgentIntegration } from "../../utils/getUserAgentIntegration";
import { ConditionalSuspense, useIsBrowser } from "../../SSR/ConditionalSuspense";

LR.registerBlocks(LR);

Expand All @@ -21,6 +23,7 @@ export const FileUploaderRegular: FC<TProps> = ({
className,
classNameUploader,
apiRef,
fallback,
...props
}) => {
const CTX_NAME = useMemo(() => ctxName ?? LR.UID.generate(), [ctxName]);
Expand All @@ -30,18 +33,22 @@ export const FileUploaderRegular: FC<TProps> = ({
[props],
);

const isBrowser = useIsBrowser();

return (
<div className={className}>
{/* @ts-ignore */}
<AdapterConfig userAgentIntegration={getUserAgentIntegration()} ctx-name={CTX_NAME} {...config} />
{/* @ts-ignore */}
<AdapterUploadCtxProvider
ref={apiRef}
ctx-name={CTX_NAME}
{...eventHandlers}
/>
{/* @ts-ignore */}
<AdapterFileUploaderRegular class={classNameUploader} ctx-name={CTX_NAME} />
</div>
<ConditionalSuspense condition={isBrowser} fallback={fallback}>
<div className={className}>
{/* @ts-ignore */}
<AdapterConfig userAgentIntegration={getUserAgentIntegration()} ctx-name={CTX_NAME} {...config} />
{/* @ts-ignore */}
<AdapterUploadCtxProvider
ref={apiRef}
ctx-name={CTX_NAME}
{...eventHandlers}
/>
{/* @ts-ignore */}
<AdapterFileUploaderRegular class={classNameUploader} ctx-name={CTX_NAME} />
</div>
</ConditionalSuspense >
);
};
6 changes: 5 additions & 1 deletion packages/react-uploader/src/Uploader/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@

import type { Ref } from "react";
import type {
ConfigType,
UploadCtxProvider,
EventMap,
} from "@uploadcare/blocks";
import type {
TProps as TPropsConditionalSuspense
} from "../SSR/ConditionalSuspense"

type TToCamelCase<S extends string> = S extends `${infer Head}-${infer Tail}`
? `${Lowercase<Head>}${Capitalize<TToCamelCase<Tail>>}`
Expand Down Expand Up @@ -31,7 +35,7 @@ type TDefaultProps = {
className?: string;
classNameUploader?: string;
ctxName?: string;
};
} & Pick<TPropsConditionalSuspense, "fallback">;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we expose fallback prop to the user? Looks strange


export type TProps = TDefaultProps &
TRefUploadCtxProvider &
Expand Down
2 changes: 1 addition & 1 deletion packages/react-uploader/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export default defineConfig({
fileName: "react-uploader",
},
rollupOptions: {
external: ["react"],
external: ["react", "@uploadcare/blocks"],
output: {
globals: {
react: "React",
Expand Down