mirror of
https://github.com/documenso/documenso.git
synced 2025-11-23 05:01:54 +10:00
chore: dependency updates (#2229)
This commit is contained in:
@ -1,11 +1,10 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useHydrated } from '../lib/use-hydrated';
|
||||
|
||||
export const ClientOnly = async ({ children }: { children: React.ReactNode }) => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
return mounted ? children : null;
|
||||
type ClientOnlyProps = {
|
||||
children: () => React.ReactNode;
|
||||
fallback?: React.ReactNode;
|
||||
};
|
||||
|
||||
export const ClientOnly = ({ children, fallback = null }: ClientOnlyProps) => {
|
||||
return useHydrated() ? <>{children()}</> : <>{fallback}</>;
|
||||
};
|
||||
|
||||
@ -19,19 +19,19 @@ export type LoadedPDFDocument = PDFDocumentProxy;
|
||||
* This imports the worker from the `pdfjs-dist` package.
|
||||
*/
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.js',
|
||||
'pdfjs-dist/legacy/build/pdf.worker.min.mjs',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
|
||||
const pdfViewerOptions = {
|
||||
cMapUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/static/cmaps`,
|
||||
cMapUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/static/cmaps/`,
|
||||
};
|
||||
|
||||
const PDFLoader = () => (
|
||||
<>
|
||||
<Loader className="text-documenso h-12 w-12 animate-spin" />
|
||||
<Loader className="h-12 w-12 animate-spin text-documenso" />
|
||||
|
||||
<p className="text-muted-foreground mt-4">
|
||||
<p className="mt-4 text-muted-foreground">
|
||||
<Trans>Loading document...</Trans>
|
||||
</p>
|
||||
</>
|
||||
@ -145,9 +145,9 @@ export const PdfViewerKonva = ({
|
||||
}}
|
||||
externalLinkTarget="_blank"
|
||||
loading={
|
||||
<div className="dark:bg-background flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50">
|
||||
<div className="flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50 dark:bg-background">
|
||||
{pdfError ? (
|
||||
<div className="text-muted-foreground text-center">
|
||||
<div className="text-center text-muted-foreground">
|
||||
<p>
|
||||
<Trans>Something went wrong while loading the document.</Trans>
|
||||
</p>
|
||||
@ -161,8 +161,8 @@ export const PdfViewerKonva = ({
|
||||
</div>
|
||||
}
|
||||
error={
|
||||
<div className="dark:bg-background flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50">
|
||||
<div className="text-muted-foreground text-center">
|
||||
<div className="flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50 dark:bg-background">
|
||||
<div className="text-center text-muted-foreground">
|
||||
<p>
|
||||
<Trans>Something went wrong while loading the document.</Trans>
|
||||
</p>
|
||||
@ -172,13 +172,13 @@ export const PdfViewerKonva = ({
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
// options={pdfViewerOptions}
|
||||
options={pdfViewerOptions}
|
||||
>
|
||||
{Array(numPages)
|
||||
.fill(null)
|
||||
.map((_, i) => (
|
||||
<div key={i} className="last:-mb-2">
|
||||
<div className="border-border rounded border will-change-transform">
|
||||
<div className="rounded border border-border will-change-transform">
|
||||
<PDFPage
|
||||
pageNumber={i + 1}
|
||||
width={width}
|
||||
@ -189,7 +189,7 @@ export const PdfViewerKonva = ({
|
||||
customRenderer={customPageRenderer}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-muted-foreground/80 my-2 text-center text-[11px]">
|
||||
<p className="my-2 text-center text-[11px] text-muted-foreground/80">
|
||||
<Trans>
|
||||
Page {i + 1} of {numPages}
|
||||
</Trans>
|
||||
|
||||
13
packages/ui/lib/use-hydrated.ts
Normal file
13
packages/ui/lib/use-hydrated.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { useSyncExternalStore } from 'react';
|
||||
|
||||
const subscribe = () => {
|
||||
return () => {};
|
||||
};
|
||||
|
||||
export const useHydrated = () => {
|
||||
return useSyncExternalStore(
|
||||
subscribe,
|
||||
() => true,
|
||||
() => false,
|
||||
);
|
||||
};
|
||||
@ -19,8 +19,8 @@
|
||||
"devDependencies": {
|
||||
"@documenso/tailwind-config": "*",
|
||||
"@documenso/tsconfig": "*",
|
||||
"@types/luxon": "^3.3.2",
|
||||
"@types/react": "^18",
|
||||
"@types/luxon": "^3.7.1",
|
||||
"@types/react": "18.3.27",
|
||||
"@types/react-dom": "^18",
|
||||
"react": "^18",
|
||||
"typescript": "5.6.2"
|
||||
@ -28,56 +28,57 @@
|
||||
"dependencies": {
|
||||
"@documenso/lib": "*",
|
||||
"@hello-pangea/dnd": "^16.6.0",
|
||||
"@hookform/resolvers": "^3.3.0",
|
||||
"@lingui/macro": "^5.2.0",
|
||||
"@lingui/react": "^5.2.0",
|
||||
"@radix-ui/react-accordion": "^1.1.1",
|
||||
"@radix-ui/react-alert-dialog": "^1.0.3",
|
||||
"@radix-ui/react-aspect-ratio": "^1.0.2",
|
||||
"@radix-ui/react-avatar": "^1.0.2",
|
||||
"@radix-ui/react-checkbox": "^1.0.3",
|
||||
"@radix-ui/react-collapsible": "^1.0.2",
|
||||
"@radix-ui/react-context-menu": "^2.1.3",
|
||||
"@radix-ui/react-dialog": "^1.0.5",
|
||||
"@radix-ui/react-dropdown-menu": "^2.0.4",
|
||||
"@radix-ui/react-hover-card": "^1.0.5",
|
||||
"@radix-ui/react-label": "^2.0.1",
|
||||
"@radix-ui/react-menubar": "^1.0.2",
|
||||
"@radix-ui/react-navigation-menu": "^1.1.2",
|
||||
"@radix-ui/react-popover": "^1.0.5",
|
||||
"@radix-ui/react-progress": "^1.0.2",
|
||||
"@radix-ui/react-radio-group": "^1.1.2",
|
||||
"@radix-ui/react-scroll-area": "^1.0.3",
|
||||
"@radix-ui/react-select": "^2.0.0",
|
||||
"@radix-ui/react-separator": "^1.0.2",
|
||||
"@radix-ui/react-slider": "^1.1.1",
|
||||
"@radix-ui/react-slot": "^1.0.2",
|
||||
"@radix-ui/react-switch": "^1.0.2",
|
||||
"@radix-ui/react-tabs": "^1.0.3",
|
||||
"@radix-ui/react-toast": "^1.1.3",
|
||||
"@radix-ui/react-toggle": "^1.0.2",
|
||||
"@radix-ui/react-toggle-group": "^1.0.4",
|
||||
"@radix-ui/react-tooltip": "^1.0.6",
|
||||
"@tanstack/react-table": "^8.9.1",
|
||||
"class-variance-authority": "^0.6.0",
|
||||
"@hookform/resolvers": "^3",
|
||||
"@lingui/macro": "^5.6.0",
|
||||
"@lingui/react": "^5.6.0",
|
||||
"@radix-ui/react-accordion": "^1.2.12",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-aspect-ratio": "^1.1.8",
|
||||
"@radix-ui/react-avatar": "^1.1.11",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
"@radix-ui/react-context-menu": "^2.2.16",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
"@radix-ui/react-hover-card": "^1.1.15",
|
||||
"@radix-ui/react-label": "^2.1.8",
|
||||
"@radix-ui/react-menubar": "^1.1.16",
|
||||
"@radix-ui/react-navigation-menu": "^1.2.14",
|
||||
"@radix-ui/react-popover": "^1.1.15",
|
||||
"@radix-ui/react-progress": "^1.1.8",
|
||||
"@radix-ui/react-radio-group": "^1.3.8",
|
||||
"@radix-ui/react-scroll-area": "^1.2.10",
|
||||
"@radix-ui/react-select": "^2.2.6",
|
||||
"@radix-ui/react-separator": "^1.1.8",
|
||||
"@radix-ui/react-slider": "^1.3.6",
|
||||
"@radix-ui/react-slot": "^1.2.4",
|
||||
"@radix-ui/react-switch": "^1.2.6",
|
||||
"@radix-ui/react-tabs": "^1.1.13",
|
||||
"@radix-ui/react-toast": "^1.2.15",
|
||||
"@radix-ui/react-toggle": "^1.1.10",
|
||||
"@radix-ui/react-toggle-group": "^1.1.11",
|
||||
"@radix-ui/react-tooltip": "^1.2.8",
|
||||
"@scure/base": "^1.2.6",
|
||||
"@tanstack/react-table": "^8.21.3",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^1.2.1",
|
||||
"cmdk": "^0.2.0",
|
||||
"framer-motion": "^10.12.8",
|
||||
"lucide-react": "^0.279.0",
|
||||
"luxon": "^3.4.2",
|
||||
"perfect-freehand": "^1.2.0",
|
||||
"pdfjs-dist": "3.11.174",
|
||||
"cmdk": "^0.2.1",
|
||||
"framer-motion": "^12.23.24",
|
||||
"lucide-react": "^0.554.0",
|
||||
"luxon": "^3.7.2",
|
||||
"perfect-freehand": "^1.2.2",
|
||||
"pdfjs-dist": "5.4.296",
|
||||
"react": "^18",
|
||||
"react-colorful": "^5.6.1",
|
||||
"react-day-picker": "^8.7.1",
|
||||
"react-day-picker": "^8.10.1",
|
||||
"react-dom": "^18",
|
||||
"react-hook-form": "^7.45.4",
|
||||
"react-pdf": "7.7.3",
|
||||
"react-rnd": "^10.4.1",
|
||||
"remeda": "^2.17.3",
|
||||
"tailwind-merge": "^1.12.0",
|
||||
"tailwindcss-animate": "^1.0.5",
|
||||
"ts-pattern": "^5.0.5",
|
||||
"react-hook-form": "^7.66.1",
|
||||
"react-pdf": "^10.2.0",
|
||||
"react-rnd": "^10.5.2",
|
||||
"remeda": "^2.32.0",
|
||||
"tailwind-merge": "^1.14.0",
|
||||
"tailwindcss-animate": "^1.0.7",
|
||||
"ts-pattern": "^5.9.0",
|
||||
"zod": "^3.25.76"
|
||||
}
|
||||
}
|
||||
10
packages/ui/primitives/pdf-viewer/base.client.tsx
Normal file
10
packages/ui/primitives/pdf-viewer/base.client.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import {
|
||||
type LoadedPDFDocument,
|
||||
type OnPDFViewerPageClick,
|
||||
PDFViewer,
|
||||
type PDFViewerProps,
|
||||
} from './base';
|
||||
|
||||
export { PDFViewer, type LoadedPDFDocument, type OnPDFViewerPageClick, type PDFViewerProps };
|
||||
|
||||
export default PDFViewer;
|
||||
@ -1,4 +1,4 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { useLingui } from '@lingui/react';
|
||||
@ -10,26 +10,27 @@ import { type PDFDocumentProxy } from 'pdfjs-dist';
|
||||
import { Document as PDFDocument, Page as PDFPage, pdfjs } from 'react-pdf';
|
||||
|
||||
import { NEXT_PUBLIC_WEBAPP_URL } from '@documenso/lib/constants/app';
|
||||
// import 'react-pdf/dist/esm/Page/AnnotationLayer.css';
|
||||
// import 'react-pdf/dist/esm/Page/TextLayer.css';
|
||||
import { PDF_VIEWER_PAGE_SELECTOR } from '@documenso/lib/constants/pdf-viewer';
|
||||
import { getEnvelopeItemPdfUrl } from '@documenso/lib/utils/envelope-download';
|
||||
|
||||
import { cn } from '../lib/utils';
|
||||
import { useToast } from './use-toast';
|
||||
import { cn } from '../../lib/utils';
|
||||
import { useToast } from '../use-toast';
|
||||
|
||||
export type LoadedPDFDocument = PDFDocumentProxy;
|
||||
|
||||
/**
|
||||
* This imports the worker from the `pdfjs-dist` package.
|
||||
* Wrapped in typeof window check to prevent SSR evaluation.
|
||||
*/
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.js',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
if (typeof window !== 'undefined') {
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/legacy/build/pdf.worker.min.mjs',
|
||||
import.meta.url,
|
||||
).toString();
|
||||
}
|
||||
|
||||
const pdfViewerOptions = {
|
||||
cMapUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/static/cmaps`,
|
||||
cMapUrl: `${NEXT_PUBLIC_WEBAPP_URL()}/static/cmaps/`,
|
||||
};
|
||||
|
||||
export type OnPDFViewerPageClick = (_event: {
|
||||
@ -44,9 +45,9 @@ export type OnPDFViewerPageClick = (_event: {
|
||||
|
||||
const PDFLoader = () => (
|
||||
<>
|
||||
<Loader className="text-documenso h-12 w-12 animate-spin" />
|
||||
<Loader className="h-12 w-12 animate-spin text-documenso" />
|
||||
|
||||
<p className="text-muted-foreground mt-4">
|
||||
<p className="mt-4 text-muted-foreground">
|
||||
<Trans>Loading document...</Trans>
|
||||
</p>
|
||||
</>
|
||||
@ -61,6 +62,7 @@ export type PDFViewerProps = {
|
||||
onDocumentLoad?: (_doc: LoadedPDFDocument) => void;
|
||||
onPageClick?: OnPDFViewerPageClick;
|
||||
overrideData?: string;
|
||||
customPageRenderer?: React.FunctionComponent;
|
||||
[key: string]: unknown;
|
||||
} & Omit<React.HTMLAttributes<HTMLDivElement>, 'onPageClick'>;
|
||||
|
||||
@ -73,6 +75,7 @@ export const PDFViewer = ({
|
||||
onDocumentLoad,
|
||||
onPageClick,
|
||||
overrideData,
|
||||
customPageRenderer,
|
||||
...props
|
||||
}: PDFViewerProps) => {
|
||||
const { _ } = useLingui();
|
||||
@ -91,6 +94,16 @@ export const PDFViewer = ({
|
||||
|
||||
const isLoading = isDocumentBytesLoading || !documentBytes;
|
||||
|
||||
const envelopeItemFile = useMemo(() => {
|
||||
if (!documentBytes) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
data: documentBytes,
|
||||
};
|
||||
}, [documentBytes]);
|
||||
|
||||
const onDocumentLoaded = (doc: LoadedPDFDocument) => {
|
||||
setNumPages(doc.numPages);
|
||||
onDocumentLoad?.(doc);
|
||||
@ -203,7 +216,7 @@ export const PDFViewer = ({
|
||||
) : (
|
||||
<>
|
||||
<PDFDocument
|
||||
file={documentBytes.buffer}
|
||||
file={envelopeItemFile}
|
||||
className={cn('w-full overflow-hidden rounded', {
|
||||
'h-[80vh] max-h-[60rem]': numPages === 0,
|
||||
})}
|
||||
@ -215,9 +228,9 @@ export const PDFViewer = ({
|
||||
}}
|
||||
externalLinkTarget="_blank"
|
||||
loading={
|
||||
<div className="dark:bg-background flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50">
|
||||
<div className="flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50 dark:bg-background">
|
||||
{pdfError ? (
|
||||
<div className="text-muted-foreground text-center">
|
||||
<div className="text-center text-muted-foreground">
|
||||
<p>
|
||||
<Trans>Something went wrong while loading the document.</Trans>
|
||||
</p>
|
||||
@ -231,8 +244,8 @@ export const PDFViewer = ({
|
||||
</div>
|
||||
}
|
||||
error={
|
||||
<div className="dark:bg-background flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50">
|
||||
<div className="text-muted-foreground text-center">
|
||||
<div className="flex h-[80vh] max-h-[60rem] flex-col items-center justify-center bg-white/50 dark:bg-background">
|
||||
<div className="text-center text-muted-foreground">
|
||||
<p>
|
||||
<Trans>Something went wrong while loading the document.</Trans>
|
||||
</p>
|
||||
@ -242,23 +255,25 @@ export const PDFViewer = ({
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
// options={pdfViewerOptions}
|
||||
options={pdfViewerOptions}
|
||||
>
|
||||
{Array(numPages)
|
||||
.fill(null)
|
||||
.map((_, i) => (
|
||||
<div key={i} className="last:-mb-2">
|
||||
<div className="border-border overflow-hidden rounded border will-change-transform">
|
||||
<div className="overflow-hidden rounded border border-border will-change-transform">
|
||||
<PDFPage
|
||||
pageNumber={i + 1}
|
||||
width={width}
|
||||
renderAnnotationLayer={false}
|
||||
renderTextLayer={false}
|
||||
loading={() => ''}
|
||||
renderMode={customPageRenderer ? 'custom' : 'canvas'}
|
||||
customRenderer={customPageRenderer}
|
||||
onClick={(e) => onDocumentPageClick(e, i + 1)}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-muted-foreground/80 my-2 text-center text-[11px]">
|
||||
<p className="my-2 text-center text-[11px] text-muted-foreground/80">
|
||||
<Trans>
|
||||
Page {i + 1} of {numPages}
|
||||
</Trans>
|
||||
1
packages/ui/primitives/pdf-viewer/index.ts
Normal file
1
packages/ui/primitives/pdf-viewer/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './base';
|
||||
7
packages/ui/primitives/pdf-viewer/lazy.tsx
Normal file
7
packages/ui/primitives/pdf-viewer/lazy.tsx
Normal file
@ -0,0 +1,7 @@
|
||||
import { ClientOnly } from '../../components/client-only';
|
||||
|
||||
import { PDFViewer, type PDFViewerProps } from './base.client';
|
||||
|
||||
export const PDFViewerLazy = (props: PDFViewerProps) => {
|
||||
return <ClientOnly fallback={<div>Loading...</div>}>{() => <PDFViewer {...props} />}</ClientOnly>;
|
||||
};
|
||||
Reference in New Issue
Block a user