react-native-pdfrender 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +306 -0
- package/android/build.gradle +76 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/pdfrender/ComposeRenderer.kt +85 -0
- package/android/src/main/java/com/pdfrender/PdfCacheManager.kt +150 -0
- package/android/src/main/java/com/pdfrender/PdfConstants.kt +63 -0
- package/android/src/main/java/com/pdfrender/PdfIconComponents.kt +275 -0
- package/android/src/main/java/com/pdfrender/PdfRenderingLogic.kt +325 -0
- package/android/src/main/java/com/pdfrender/PdfUIComponents.kt +335 -0
- package/android/src/main/java/com/pdfrender/PdfViewPackage.kt +32 -0
- package/android/src/main/java/com/pdfrender/PdfViewerActivity.kt +3467 -0
- package/android/src/main/java/com/pdfrender/PdfViewerFabricManager.kt +244 -0
- package/android/src/main/java/com/pdfrender/PdfViewerFragment.kt +129 -0
- package/android/src/main/java/com/pdfrender/PdfViewerTurboModule.kt +158 -0
- package/android/src/main/java/com/pdfrender/events/FullScreenChangeEvent.kt +26 -0
- package/android/src/main/java/com/pdfrender/events/LeftScreenChangeEvent.kt +22 -0
- package/android/src/main/java/com/pdfrender/events/RightScreenChangeEvent.kt +22 -0
- package/android/src/main/java/com/pdfrender/events/ZoomChangeEvent.kt +22 -0
- package/ios/PdfCacheManager.swift +44 -0
- package/ios/PdfConstants.swift +38 -0
- package/ios/PdfPageView.swift +121 -0
- package/ios/PdfRenderingLogic.swift +107 -0
- package/ios/PdfToolbarView.swift +158 -0
- package/ios/PdfViewerComponentView.mm +194 -0
- package/ios/PdfViewerTurboModule.mm +186 -0
- package/ios/PdfViewerTurboModuleImpl.swift +141 -0
- package/ios/PdfViewerView.swift +268 -0
- package/ios/PdfViewerViewController.swift +109 -0
- package/lib/commonjs/PdfViewerView.js +105 -0
- package/lib/commonjs/PdfViewerView.js.map +1 -0
- package/lib/commonjs/index.js +28 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/specs/NativePdfViewerComponent.js +27 -0
- package/lib/commonjs/specs/NativePdfViewerComponent.js.map +1 -0
- package/lib/commonjs/specs/NativePdfViewerModule.js +21 -0
- package/lib/commonjs/specs/NativePdfViewerModule.js.map +1 -0
- package/lib/commonjs/usePdfViewer.js +65 -0
- package/lib/commonjs/usePdfViewer.js.map +1 -0
- package/lib/module/PdfViewerView.js +99 -0
- package/lib/module/PdfViewerView.js.map +1 -0
- package/lib/module/index.js +8 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/specs/NativePdfViewerComponent.js +26 -0
- package/lib/module/specs/NativePdfViewerComponent.js.map +1 -0
- package/lib/module/specs/NativePdfViewerModule.js +18 -0
- package/lib/module/specs/NativePdfViewerModule.js.map +1 -0
- package/lib/module/usePdfViewer.js +60 -0
- package/lib/module/usePdfViewer.js.map +1 -0
- package/lib/typescript/PdfViewerView.d.ts +58 -0
- package/lib/typescript/PdfViewerView.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +7 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/specs/NativePdfViewerComponent.d.ts +59 -0
- package/lib/typescript/specs/NativePdfViewerComponent.d.ts.map +1 -0
- package/lib/typescript/specs/NativePdfViewerModule.d.ts +47 -0
- package/lib/typescript/specs/NativePdfViewerModule.d.ts.map +1 -0
- package/lib/typescript/usePdfViewer.d.ts +45 -0
- package/lib/typescript/usePdfViewer.d.ts.map +1 -0
- package/package.json +109 -0
- package/react-native-pdfrender.podspec +35 -0
- package/react-native.config.js +11 -0
- package/src/PdfViewerView.tsx +159 -0
- package/src/index.tsx +10 -0
- package/src/specs/NativePdfViewerComponent.ts +94 -0
- package/src/specs/NativePdfViewerModule.ts +58 -0
- package/src/usePdfViewer.ts +102 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PdfViewerView — public React component for the embedded PDF viewer.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { PdfViewerView } from './PdfViewerView';
|
|
6
|
+
*
|
|
7
|
+
* <PdfViewerView
|
|
8
|
+
* uri="file:///path/to/book.pdf"
|
|
9
|
+
* initialPage={0}
|
|
10
|
+
* defaultZoom={1.5}
|
|
11
|
+
* style={{ flex: 1 }}
|
|
12
|
+
* onZoomChange={(pct) => console.log('zoom', pct)}
|
|
13
|
+
* onFullScreenChange={(fs) => setFullScreen(fs)}
|
|
14
|
+
* />
|
|
15
|
+
*/
|
|
16
|
+
import React from 'react';
|
|
17
|
+
import { type ViewStyle } from 'react-native';
|
|
18
|
+
export interface PdfViewerHandle {
|
|
19
|
+
}
|
|
20
|
+
export interface IconSet {
|
|
21
|
+
zoomIn?: number | string;
|
|
22
|
+
zoomOut?: number | string;
|
|
23
|
+
fullScreen?: number | string;
|
|
24
|
+
minimizeScreen?: number | string;
|
|
25
|
+
leftLayout?: number | string;
|
|
26
|
+
rightLayout?: number | string;
|
|
27
|
+
}
|
|
28
|
+
export interface PdfViewerProps {
|
|
29
|
+
/** PDF file URI — file:// or content:// */
|
|
30
|
+
uri: string;
|
|
31
|
+
/** 0-based page index to open (-1 = first page) */
|
|
32
|
+
initialPage?: number;
|
|
33
|
+
/** Initial (and minimum) zoom level. 1.0 = 100%, 1.5 = 150% */
|
|
34
|
+
defaultZoom?: number;
|
|
35
|
+
/** Whether the viewer fills the screen */
|
|
36
|
+
isFullScreen?: boolean;
|
|
37
|
+
/** PDF position in split-view: true = right side */
|
|
38
|
+
rightLayout?: boolean;
|
|
39
|
+
/** Max pixel width of the viewer container (used in split-view) */
|
|
40
|
+
maxWidth?: number;
|
|
41
|
+
/** Width percentage of the screen occupied by the viewer (0–100) */
|
|
42
|
+
screenWidthPercentage?: number;
|
|
43
|
+
/** Custom toolbar icon assets */
|
|
44
|
+
icons?: IconSet;
|
|
45
|
+
/** Icon size in logical pixels (default: 40) */
|
|
46
|
+
iconSize?: number;
|
|
47
|
+
/** Toolbar back-button text */
|
|
48
|
+
backButtonText?: string;
|
|
49
|
+
/** Toolbar header text */
|
|
50
|
+
headerText?: string;
|
|
51
|
+
style?: ViewStyle;
|
|
52
|
+
onFullScreenChange?: (isFullScreen: boolean) => void;
|
|
53
|
+
onLeftScreenChange?: (isLeftScreen: boolean) => void;
|
|
54
|
+
onRightScreenChange?: (isRightScreen: boolean) => void;
|
|
55
|
+
onZoomChange?: (zoomPercentage: number) => void;
|
|
56
|
+
}
|
|
57
|
+
export declare const PdfViewerView: React.ForwardRefExoticComponent<PdfViewerProps & React.RefAttributes<PdfViewerHandle>>;
|
|
58
|
+
//# sourceMappingURL=PdfViewerView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PdfViewerView.d.ts","sourceRoot":"","sources":["../../src/PdfViewerView.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AACxE,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAKjE,MAAM,WAAW,eAAe;CAG/B;AAID,MAAM,WAAW,OAAO;IACtB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC7B,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IAEZ,mDAAmD;IACnD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,0CAA0C;IAC1C,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oEAAoE;IACpE,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAE/B,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,+BAA+B;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,0BAA0B;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,kBAAkB,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACrD,mBAAmB,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,CAAC;IACvD,YAAY,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;CACjD;AAID,eAAO,MAAM,aAAa,wFAwEzB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { PdfViewerView } from './PdfViewerView';
|
|
2
|
+
export type { PdfViewerProps, PdfViewerHandle, IconSet } from './PdfViewerView';
|
|
3
|
+
export { usePdfViewer } from './usePdfViewer';
|
|
4
|
+
export type { UsePdfViewerOptions, UsePdfViewerReturn } from './usePdfViewer';
|
|
5
|
+
export { default as NativePdfViewerModule } from './specs/NativePdfViewerModule';
|
|
6
|
+
export type { PdfPage, PdfCreationResult } from './specs/NativePdfViewerModule';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEhF,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAE9E,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACjF,YAAY,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codegen spec for the embedded PDF viewer Fabric component.
|
|
3
|
+
*
|
|
4
|
+
* Codegen reads this file and generates the native component registration
|
|
5
|
+
* that allows <PdfViewerView /> to map to PdfViewerFabricManager on Android.
|
|
6
|
+
*
|
|
7
|
+
* Use DirectEventHandler (not BubblingEventHandler) for custom events — they
|
|
8
|
+
* are dispatched directly to the component's onXxx prop without bubbling.
|
|
9
|
+
*/
|
|
10
|
+
import type { HostComponent, ViewProps } from 'react-native';
|
|
11
|
+
import type { Float, Int32, WithDefault, DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';
|
|
12
|
+
interface FullScreenChangeEvent {
|
|
13
|
+
isFullScreen: boolean;
|
|
14
|
+
}
|
|
15
|
+
interface LeftScreenChangeEvent {
|
|
16
|
+
isLeftScreen: boolean;
|
|
17
|
+
}
|
|
18
|
+
interface RightScreenChangeEvent {
|
|
19
|
+
isRightScreen: boolean;
|
|
20
|
+
}
|
|
21
|
+
interface ZoomChangeEvent {
|
|
22
|
+
zoomPercentage: Float;
|
|
23
|
+
}
|
|
24
|
+
export interface NativePdfViewerProps extends ViewProps {
|
|
25
|
+
/** PDF file URI (file:// or content://) */
|
|
26
|
+
pdfUri?: string;
|
|
27
|
+
/** 0-based page to scroll to on open. -1 = first page. */
|
|
28
|
+
initialPageIndex?: WithDefault<Int32, -1>;
|
|
29
|
+
/** Max pixel width available to the viewer (used in split-view) */
|
|
30
|
+
maxWidth?: Float;
|
|
31
|
+
/** Percentage of screen width the viewer occupies (0–100) */
|
|
32
|
+
screenWidthPercentage?: WithDefault<Float, 100>;
|
|
33
|
+
/** Whether the viewer is in full-screen mode */
|
|
34
|
+
isFullScreen?: WithDefault<boolean, false>;
|
|
35
|
+
/** PDF position: true = right side, false = left side (split-view) */
|
|
36
|
+
rightLayout?: WithDefault<boolean, false>;
|
|
37
|
+
/** Initial and minimum zoom level (1.0 = 100%) */
|
|
38
|
+
defaultZoom?: WithDefault<Float, 1.5>;
|
|
39
|
+
/** Text for the back button in the toolbar */
|
|
40
|
+
backButtonText?: string;
|
|
41
|
+
/** Text for the header in the toolbar */
|
|
42
|
+
headerText?: string;
|
|
43
|
+
/** Icon URIs passed from JS (resolved asset URIs from Image.resolveAssetSource) */
|
|
44
|
+
iconZoomIn?: string;
|
|
45
|
+
iconZoomOut?: string;
|
|
46
|
+
iconFullScreen?: string;
|
|
47
|
+
iconMinimizeScreen?: string;
|
|
48
|
+
iconLeftLayout?: string;
|
|
49
|
+
iconRightLayout?: string;
|
|
50
|
+
/** Icon size in logical pixels */
|
|
51
|
+
iconSize?: WithDefault<Float, 40>;
|
|
52
|
+
onFullScreenChange?: DirectEventHandler<FullScreenChangeEvent>;
|
|
53
|
+
onLeftScreenChange?: DirectEventHandler<LeftScreenChangeEvent>;
|
|
54
|
+
onRightScreenChange?: DirectEventHandler<RightScreenChangeEvent>;
|
|
55
|
+
onZoomChange?: DirectEventHandler<ZoomChangeEvent>;
|
|
56
|
+
}
|
|
57
|
+
declare const _default: HostComponent<NativePdfViewerProps>;
|
|
58
|
+
export default _default;
|
|
59
|
+
//# sourceMappingURL=NativePdfViewerComponent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativePdfViewerComponent.d.ts","sourceRoot":"","sources":["../../../src/specs/NativePdfViewerComponent.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,KAAK,EACV,KAAK,EACL,KAAK,EACL,WAAW,EACX,kBAAkB,EACnB,MAAM,2CAA2C,CAAC;AAUnD,UAAU,qBAAqB;IAC7B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,qBAAqB;IAC7B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,sBAAsB;IAC9B,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,UAAU,eAAe;IACvB,cAAc,EAAE,KAAK,CAAC;CACvB;AAID,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,2CAA2C;IAC3C,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;IAE1C,mEAAmE;IACnE,QAAQ,CAAC,EAAE,KAAK,CAAC;IAEjB,6DAA6D;IAC7D,qBAAqB,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEhD,gDAAgD;IAChD,YAAY,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE3C,sEAAsE;IACtE,WAAW,CAAC,EAAE,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE1C,kDAAkD;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAEtC,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,kCAAkC;IAClC,QAAQ,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAGlC,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;IAC/D,kBAAkB,CAAC,EAAE,kBAAkB,CAAC,qBAAqB,CAAC,CAAC;IAC/D,mBAAmB,CAAC,EAAE,kBAAkB,CAAC,sBAAsB,CAAC,CAAC;IACjE,YAAY,CAAC,EAAE,kBAAkB,CAAC,eAAe,CAAC,CAAC;CACpD;wBAKI,aAAa,CAAC,oBAAoB,CAAC;AAFxC,wBAEyC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codegen spec for PdfViewerTurboModule.
|
|
3
|
+
*
|
|
4
|
+
* Codegen reads this file at build time and generates:
|
|
5
|
+
* Android: abstract Kotlin class `NativePdfViewerModuleSpec`
|
|
6
|
+
*
|
|
7
|
+
* The name passed to TurboModuleRegistry.getEnforcing() MUST match the
|
|
8
|
+
* string returned by PdfViewerTurboModule.getName() in Kotlin.
|
|
9
|
+
*
|
|
10
|
+
* Method signatures here are the source of truth — if the Kotlin
|
|
11
|
+
* implementation diverges, the build fails at compile time.
|
|
12
|
+
*/
|
|
13
|
+
import type { TurboModule } from 'react-native';
|
|
14
|
+
export interface PdfCreationResult {
|
|
15
|
+
base64: string;
|
|
16
|
+
path: string;
|
|
17
|
+
}
|
|
18
|
+
export interface PdfPage {
|
|
19
|
+
title: string;
|
|
20
|
+
body: string;
|
|
21
|
+
}
|
|
22
|
+
export interface Spec extends TurboModule {
|
|
23
|
+
/**
|
|
24
|
+
* Show the PDF viewer inside the host Activity's Fragment back-stack.
|
|
25
|
+
* No new Activity is started — uses PdfViewerFragment.
|
|
26
|
+
*
|
|
27
|
+
* @param uri PDF file URI (file:// or content://)
|
|
28
|
+
* @param pageIndex 0-based page to open on start (-1 = first page)
|
|
29
|
+
* @param defaultZoom Initial zoom level (1.0 = 100%, 1.5 = 150%)
|
|
30
|
+
*/
|
|
31
|
+
openPdfViewer(uri: string, pageIndex: number, defaultZoom: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* Dismiss the viewer Fragment if it is currently visible.
|
|
34
|
+
*/
|
|
35
|
+
dismissPdfViewer(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Async: returns total page count without rendering the PDF.
|
|
38
|
+
*/
|
|
39
|
+
getPdfPageCount(uri: string): Promise<number>;
|
|
40
|
+
/**
|
|
41
|
+
* Generate a multi-page PDF from structured content and return as Base64.
|
|
42
|
+
*/
|
|
43
|
+
createMultiPagePdfBase64(pages: ReadonlyArray<PdfPage>, widthPx: number, heightPx: number): Promise<PdfCreationResult>;
|
|
44
|
+
}
|
|
45
|
+
declare const _default: Spec;
|
|
46
|
+
export default _default;
|
|
47
|
+
//# sourceMappingURL=NativePdfViewerModule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativePdfViewerModule.d.ts","sourceRoot":"","sources":["../../../src/specs/NativePdfViewerModule.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGhD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,IAAK,SAAQ,WAAW;IACvC;;;;;;;OAOG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzE;;OAEG;IACH,gBAAgB,IAAI,IAAI,CAAC;IAEzB;;OAEG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE9C;;OAEG;IACH,wBAAwB,CACtB,KAAK,EAAE,aAAa,CAAC,OAAO,CAAC,EAC7B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,iBAAiB,CAAC,CAAC;CAC/B;;AAED,wBAA+E"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* usePdfViewer — programmatic (Fragment-based) PDF viewer hook.
|
|
3
|
+
*
|
|
4
|
+
* Use this when you want to open the PDF viewer imperatively (like a modal),
|
|
5
|
+
* without embedding a <PdfViewerView /> in the render tree.
|
|
6
|
+
*
|
|
7
|
+
* Under the hood it calls PdfViewerTurboModule.openPdfViewer(), which shows
|
|
8
|
+
* PdfViewerFragment inside the host Activity — no new Activity is started.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* const { open, dismiss, getPageCount } = usePdfViewer({
|
|
12
|
+
* onZoomChanged: (pct) => console.log('zoom', pct),
|
|
13
|
+
* onDismiss: () => console.log('closed'),
|
|
14
|
+
* });
|
|
15
|
+
*
|
|
16
|
+
* // Open the viewer
|
|
17
|
+
* open('file:///path/to/book.pdf', 0, 1.5);
|
|
18
|
+
*
|
|
19
|
+
* // Dismiss it programmatically
|
|
20
|
+
* dismiss();
|
|
21
|
+
*/
|
|
22
|
+
export interface UsePdfViewerOptions {
|
|
23
|
+
onFullScreenChanged?: (isFullScreen: boolean) => void;
|
|
24
|
+
onZoomChanged?: (zoomPercentage: number) => void;
|
|
25
|
+
onDismiss?: () => void;
|
|
26
|
+
onError?: (error: string) => void;
|
|
27
|
+
}
|
|
28
|
+
export interface UsePdfViewerReturn {
|
|
29
|
+
/** Open the PDF viewer inside the host Activity */
|
|
30
|
+
open: (uri: string, pageIndex?: number, defaultZoom?: number) => void;
|
|
31
|
+
/** Dismiss the viewer programmatically */
|
|
32
|
+
dismiss: () => void;
|
|
33
|
+
/** Get the total number of pages (async, no rendering) */
|
|
34
|
+
getPageCount: (uri: string) => Promise<number>;
|
|
35
|
+
/** Generate a multi-page PDF as Base64 */
|
|
36
|
+
createPdf: (pages: Array<{
|
|
37
|
+
title: string;
|
|
38
|
+
body: string;
|
|
39
|
+
}>, widthPx: number, heightPx: number) => Promise<{
|
|
40
|
+
base64: string;
|
|
41
|
+
path: string;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
export declare function usePdfViewer(options?: UsePdfViewerOptions): UsePdfViewerReturn;
|
|
45
|
+
//# sourceMappingURL=usePdfViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePdfViewer.d.ts","sourceRoot":"","sources":["../../src/usePdfViewer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAMH,MAAM,WAAW,mBAAmB;IAClC,mBAAmB,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACtD,aAAa,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACtE,0CAA0C;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,0DAA0D;IAC1D,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,0CAA0C;IAC1C,SAAS,EAAE,CACT,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,EAC7C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,KACb,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CAqDlF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "react-native-pdfrender",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React Native PDF rendering library with TurboModules and Fabric components",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"react-native": "src/index.tsx",
|
|
8
|
+
"types": "lib/typescript/index.d.ts",
|
|
9
|
+
"source": "src/index.tsx",
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"lib",
|
|
13
|
+
"android/src",
|
|
14
|
+
"android/build.gradle",
|
|
15
|
+
"ios",
|
|
16
|
+
"react-native-pdfrender.podspec",
|
|
17
|
+
"react-native.config.js",
|
|
18
|
+
"!**/__tests__",
|
|
19
|
+
"!**/__fixtures__",
|
|
20
|
+
"!**/__mocks__",
|
|
21
|
+
"!android/build",
|
|
22
|
+
"!android/.gradle",
|
|
23
|
+
"!ios/build",
|
|
24
|
+
"!lib/typescript/example"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"react-native",
|
|
28
|
+
"ios",
|
|
29
|
+
"android",
|
|
30
|
+
"pdf",
|
|
31
|
+
"pdf-viewer",
|
|
32
|
+
"pdf-renderer",
|
|
33
|
+
"turbomodule",
|
|
34
|
+
"fabric",
|
|
35
|
+
"new-architecture"
|
|
36
|
+
],
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/cosmiq-co/react-native-pdfrender.git"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/cosmiq-co/react-native-pdfrender#readme",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/cosmiq-co/react-native-pdfrender/issues"
|
|
44
|
+
},
|
|
45
|
+
"author": "Shubham Keshari <shubham.keshari@cosmiq.co.in>",
|
|
46
|
+
"license": "MIT",
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "bob build",
|
|
49
|
+
"prepare": "bob build",
|
|
50
|
+
"typecheck": "tsc --noEmit",
|
|
51
|
+
"lint": "eslint src/",
|
|
52
|
+
"test": "jest",
|
|
53
|
+
"example:android": "yarn --cwd example android",
|
|
54
|
+
"example:ios": "yarn --cwd example ios",
|
|
55
|
+
"example:start": "yarn --cwd example start"
|
|
56
|
+
},
|
|
57
|
+
"peerDependencies": {
|
|
58
|
+
"react": ">=18.0.0",
|
|
59
|
+
"react-native": ">=0.70.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@babel/core": "^7.25.2",
|
|
63
|
+
"@babel/preset-env": "^7.25.3",
|
|
64
|
+
"@babel/runtime": "^7.25.0",
|
|
65
|
+
"@react-native-community/cli": "20.1.0",
|
|
66
|
+
"@react-native-community/cli-platform-android": "20.1.0",
|
|
67
|
+
"@react-native-community/cli-platform-ios": "20.1.0",
|
|
68
|
+
"@react-native/babel-preset": "0.84.1",
|
|
69
|
+
"@react-native/eslint-config": "0.84.1",
|
|
70
|
+
"@react-native/metro-config": "0.84.1",
|
|
71
|
+
"@react-native/typescript-config": "0.84.1",
|
|
72
|
+
"@types/jest": "^29.5.13",
|
|
73
|
+
"@types/react": "^19.2.0",
|
|
74
|
+
"@types/react-test-renderer": "^19.1.0",
|
|
75
|
+
"eslint": "^8.19.0",
|
|
76
|
+
"jest": "^29.6.3",
|
|
77
|
+
"prettier": "2.8.8",
|
|
78
|
+
"react": "19.2.3",
|
|
79
|
+
"react-native": "0.84.1",
|
|
80
|
+
"react-native-builder-bob": "^0.35.3",
|
|
81
|
+
"react-test-renderer": "19.2.3",
|
|
82
|
+
"typescript": "^5.8.3"
|
|
83
|
+
},
|
|
84
|
+
"engines": {
|
|
85
|
+
"node": ">=18"
|
|
86
|
+
},
|
|
87
|
+
"codegenConfig": {
|
|
88
|
+
"name": "PdfViewerSpecs",
|
|
89
|
+
"type": "all",
|
|
90
|
+
"jsSrcsDir": "src/specs",
|
|
91
|
+
"android": {
|
|
92
|
+
"javaPackageName": "com.pdfrender"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"react-native-builder-bob": {
|
|
96
|
+
"source": "src",
|
|
97
|
+
"output": "lib",
|
|
98
|
+
"targets": [
|
|
99
|
+
"commonjs",
|
|
100
|
+
"module",
|
|
101
|
+
[
|
|
102
|
+
"typescript",
|
|
103
|
+
{
|
|
104
|
+
"project": "tsconfig.build.json"
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "react-native-pdfrender"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"] || "https://github.com/cosmiq-co/react-native-pdfrender"
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
s.platforms = { :ios => "13.0" }
|
|
13
|
+
|
|
14
|
+
s.source = { :git => "https://github.com/cosmiq-co/react-native-pdfrender.git",
|
|
15
|
+
:tag => "v#{s.version}" }
|
|
16
|
+
|
|
17
|
+
# All Swift and ObjC++ library sources live in ios/
|
|
18
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
19
|
+
|
|
20
|
+
# Swift/ObjC++ interop: the module map enables Swift-to-ObjC++ bridging inside the pod
|
|
21
|
+
s.pod_target_xcconfig = {
|
|
22
|
+
"SWIFT_OBJC_BRIDGING_HEADER" => "",
|
|
23
|
+
"DEFINES_MODULE" => "YES",
|
|
24
|
+
"SWIFT_COMPILATION_MODE" => "wholemodule",
|
|
25
|
+
"OTHER_SWIFT_FLAGS" => "$(inherited) -D RCT_NEW_ARCH_ENABLED",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
# Minimum iOS for PDFRenderer-compatible APIs
|
|
29
|
+
s.ios.deployment_target = "13.0"
|
|
30
|
+
|
|
31
|
+
# ── React Native dependency resolution ────────────────────────────────────────
|
|
32
|
+
# install_modules_dependencies handles both Old Arch and New Arch automatically.
|
|
33
|
+
# It adds React-Core, React-RCTFabric, ReactCodegen, etc. as needed.
|
|
34
|
+
install_modules_dependencies(s)
|
|
35
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PdfViewerView — public React component for the embedded PDF viewer.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* import { PdfViewerView } from './PdfViewerView';
|
|
6
|
+
*
|
|
7
|
+
* <PdfViewerView
|
|
8
|
+
* uri="file:///path/to/book.pdf"
|
|
9
|
+
* initialPage={0}
|
|
10
|
+
* defaultZoom={1.5}
|
|
11
|
+
* style={{ flex: 1 }}
|
|
12
|
+
* onZoomChange={(pct) => console.log('zoom', pct)}
|
|
13
|
+
* onFullScreenChange={(fs) => setFullScreen(fs)}
|
|
14
|
+
* />
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import React, { forwardRef, useImperativeHandle, useMemo } from 'react';
|
|
18
|
+
import { Image, StyleSheet, type ViewStyle } from 'react-native';
|
|
19
|
+
import NativePdfViewerComponent from './specs/NativePdfViewerComponent';
|
|
20
|
+
|
|
21
|
+
// ── Public handle (imperative API via ref) ────────────────────────────────────
|
|
22
|
+
|
|
23
|
+
export interface PdfViewerHandle {
|
|
24
|
+
// Future: goToPage(index: number), resetZoom(), etc.
|
|
25
|
+
// Kept as an empty interface now so host apps can forward refs safely.
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ── Public props ──────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
export interface IconSet {
|
|
31
|
+
zoomIn?: number | string; // require('./assets/zoom_in.png') or URI string
|
|
32
|
+
zoomOut?: number | string;
|
|
33
|
+
fullScreen?: number | string;
|
|
34
|
+
minimizeScreen?: number | string;
|
|
35
|
+
leftLayout?: number | string;
|
|
36
|
+
rightLayout?: number | string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface PdfViewerProps {
|
|
40
|
+
/** PDF file URI — file:// or content:// */
|
|
41
|
+
uri: string;
|
|
42
|
+
|
|
43
|
+
/** 0-based page index to open (-1 = first page) */
|
|
44
|
+
initialPage?: number;
|
|
45
|
+
|
|
46
|
+
/** Initial (and minimum) zoom level. 1.0 = 100%, 1.5 = 150% */
|
|
47
|
+
defaultZoom?: number;
|
|
48
|
+
|
|
49
|
+
/** Whether the viewer fills the screen */
|
|
50
|
+
isFullScreen?: boolean;
|
|
51
|
+
|
|
52
|
+
/** PDF position in split-view: true = right side */
|
|
53
|
+
rightLayout?: boolean;
|
|
54
|
+
|
|
55
|
+
/** Max pixel width of the viewer container (used in split-view) */
|
|
56
|
+
maxWidth?: number;
|
|
57
|
+
|
|
58
|
+
/** Width percentage of the screen occupied by the viewer (0–100) */
|
|
59
|
+
screenWidthPercentage?: number;
|
|
60
|
+
|
|
61
|
+
/** Custom toolbar icon assets */
|
|
62
|
+
icons?: IconSet;
|
|
63
|
+
|
|
64
|
+
/** Icon size in logical pixels (default: 40) */
|
|
65
|
+
iconSize?: number;
|
|
66
|
+
|
|
67
|
+
/** Toolbar back-button text */
|
|
68
|
+
backButtonText?: string;
|
|
69
|
+
|
|
70
|
+
/** Toolbar header text */
|
|
71
|
+
headerText?: string;
|
|
72
|
+
|
|
73
|
+
style?: ViewStyle;
|
|
74
|
+
|
|
75
|
+
onFullScreenChange?: (isFullScreen: boolean) => void;
|
|
76
|
+
onLeftScreenChange?: (isLeftScreen: boolean) => void;
|
|
77
|
+
onRightScreenChange?: (isRightScreen: boolean) => void;
|
|
78
|
+
onZoomChange?: (zoomPercentage: number) => void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// ── Component ─────────────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
export const PdfViewerView = forwardRef<PdfViewerHandle, PdfViewerProps>(
|
|
84
|
+
(
|
|
85
|
+
{
|
|
86
|
+
uri,
|
|
87
|
+
initialPage = -1,
|
|
88
|
+
defaultZoom = 1,
|
|
89
|
+
isFullScreen = false,
|
|
90
|
+
rightLayout = false,
|
|
91
|
+
maxWidth,
|
|
92
|
+
screenWidthPercentage = 100,
|
|
93
|
+
icons,
|
|
94
|
+
iconSize = 40,
|
|
95
|
+
backButtonText,
|
|
96
|
+
headerText,
|
|
97
|
+
style,
|
|
98
|
+
onFullScreenChange,
|
|
99
|
+
onLeftScreenChange,
|
|
100
|
+
onRightScreenChange,
|
|
101
|
+
onZoomChange,
|
|
102
|
+
},
|
|
103
|
+
ref
|
|
104
|
+
) => {
|
|
105
|
+
useImperativeHandle(ref, () => ({}));
|
|
106
|
+
|
|
107
|
+
// Resolve icon assets to URI strings the native layer can load.
|
|
108
|
+
// Image.resolveAssetSource handles both require() numbers and plain strings.
|
|
109
|
+
const resolvedIcons = useMemo(() => {
|
|
110
|
+
const resolve = (src?: number | string): string | undefined => {
|
|
111
|
+
if (src == null) return undefined;
|
|
112
|
+
if (typeof src === 'string') return src;
|
|
113
|
+
try {
|
|
114
|
+
return Image.resolveAssetSource(src).uri;
|
|
115
|
+
} catch {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
zoomIn: resolve(icons?.zoomIn),
|
|
121
|
+
zoomOut: resolve(icons?.zoomOut),
|
|
122
|
+
fullScreen: resolve(icons?.fullScreen),
|
|
123
|
+
minimizeScreen: resolve(icons?.minimizeScreen),
|
|
124
|
+
leftLayout: resolve(icons?.leftLayout),
|
|
125
|
+
rightLayout: resolve(icons?.rightLayout),
|
|
126
|
+
};
|
|
127
|
+
}, [icons]);
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<NativePdfViewerComponent
|
|
131
|
+
style={[styles.fill, style]}
|
|
132
|
+
pdfUri={uri}
|
|
133
|
+
initialPageIndex={initialPage}
|
|
134
|
+
defaultZoom={defaultZoom}
|
|
135
|
+
isFullScreen={isFullScreen}
|
|
136
|
+
rightLayout={rightLayout}
|
|
137
|
+
maxWidth={maxWidth}
|
|
138
|
+
screenWidthPercentage={screenWidthPercentage}
|
|
139
|
+
iconZoomIn={resolvedIcons.zoomIn}
|
|
140
|
+
iconZoomOut={resolvedIcons.zoomOut}
|
|
141
|
+
iconFullScreen={resolvedIcons.fullScreen}
|
|
142
|
+
iconMinimizeScreen={resolvedIcons.minimizeScreen}
|
|
143
|
+
iconLeftLayout={resolvedIcons.leftLayout}
|
|
144
|
+
iconRightLayout={resolvedIcons.rightLayout}
|
|
145
|
+
iconSize={iconSize}
|
|
146
|
+
backButtonText={backButtonText}
|
|
147
|
+
headerText={headerText}
|
|
148
|
+
onFullScreenChange={(e) => onFullScreenChange?.(e.nativeEvent.isFullScreen)}
|
|
149
|
+
onLeftScreenChange={(e) => onLeftScreenChange?.(e.nativeEvent.isLeftScreen)}
|
|
150
|
+
onRightScreenChange={(e) => onRightScreenChange?.(e.nativeEvent.isRightScreen)}
|
|
151
|
+
onZoomChange={(e) => onZoomChange?.(e.nativeEvent.zoomPercentage)}
|
|
152
|
+
/>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const styles = StyleSheet.create({
|
|
158
|
+
fill: { flex: 1 },
|
|
159
|
+
});
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// ── Public API ────────────────────────────────────────────────────────────────
|
|
2
|
+
|
|
3
|
+
export { PdfViewerView } from './PdfViewerView';
|
|
4
|
+
export type { PdfViewerProps, PdfViewerHandle, IconSet } from './PdfViewerView';
|
|
5
|
+
|
|
6
|
+
export { usePdfViewer } from './usePdfViewer';
|
|
7
|
+
export type { UsePdfViewerOptions, UsePdfViewerReturn } from './usePdfViewer';
|
|
8
|
+
|
|
9
|
+
export { default as NativePdfViewerModule } from './specs/NativePdfViewerModule';
|
|
10
|
+
export type { PdfPage, PdfCreationResult } from './specs/NativePdfViewerModule';
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codegen spec for the embedded PDF viewer Fabric component.
|
|
3
|
+
*
|
|
4
|
+
* Codegen reads this file and generates the native component registration
|
|
5
|
+
* that allows <PdfViewerView /> to map to PdfViewerFabricManager on Android.
|
|
6
|
+
*
|
|
7
|
+
* Use DirectEventHandler (not BubblingEventHandler) for custom events — they
|
|
8
|
+
* are dispatched directly to the component's onXxx prop without bubbling.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { HostComponent, ViewProps } from 'react-native';
|
|
12
|
+
import type {
|
|
13
|
+
Float,
|
|
14
|
+
Int32,
|
|
15
|
+
WithDefault,
|
|
16
|
+
DirectEventHandler,
|
|
17
|
+
} from 'react-native/Libraries/Types/CodegenTypes';
|
|
18
|
+
// The deep import below is intentional. Metro codegen identifies Fabric component
|
|
19
|
+
// specs by statically analysing this exact import path — switching to a public
|
|
20
|
+
// re-export or require() breaks spec detection. The runtime deprecation warning
|
|
21
|
+
// this produces is a known false positive for *spec* files and can be ignored.
|
|
22
|
+
// eslint-disable-next-line import/no-deprecated
|
|
23
|
+
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
|
24
|
+
|
|
25
|
+
// ── Event payload types ───────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
interface FullScreenChangeEvent {
|
|
28
|
+
isFullScreen: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface LeftScreenChangeEvent {
|
|
32
|
+
isLeftScreen: boolean;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
interface RightScreenChangeEvent {
|
|
36
|
+
isRightScreen: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface ZoomChangeEvent {
|
|
40
|
+
zoomPercentage: Float;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// ── Component props ───────────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
export interface NativePdfViewerProps extends ViewProps {
|
|
46
|
+
/** PDF file URI (file:// or content://) */
|
|
47
|
+
pdfUri?: string;
|
|
48
|
+
|
|
49
|
+
/** 0-based page to scroll to on open. -1 = first page. */
|
|
50
|
+
initialPageIndex?: WithDefault<Int32, -1>;
|
|
51
|
+
|
|
52
|
+
/** Max pixel width available to the viewer (used in split-view) */
|
|
53
|
+
maxWidth?: Float;
|
|
54
|
+
|
|
55
|
+
/** Percentage of screen width the viewer occupies (0–100) */
|
|
56
|
+
screenWidthPercentage?: WithDefault<Float, 100>;
|
|
57
|
+
|
|
58
|
+
/** Whether the viewer is in full-screen mode */
|
|
59
|
+
isFullScreen?: WithDefault<boolean, false>;
|
|
60
|
+
|
|
61
|
+
/** PDF position: true = right side, false = left side (split-view) */
|
|
62
|
+
rightLayout?: WithDefault<boolean, false>;
|
|
63
|
+
|
|
64
|
+
/** Initial and minimum zoom level (1.0 = 100%) */
|
|
65
|
+
defaultZoom?: WithDefault<Float, 1.5>;
|
|
66
|
+
|
|
67
|
+
/** Text for the back button in the toolbar */
|
|
68
|
+
backButtonText?: string;
|
|
69
|
+
|
|
70
|
+
/** Text for the header in the toolbar */
|
|
71
|
+
headerText?: string;
|
|
72
|
+
|
|
73
|
+
/** Icon URIs passed from JS (resolved asset URIs from Image.resolveAssetSource) */
|
|
74
|
+
iconZoomIn?: string;
|
|
75
|
+
iconZoomOut?: string;
|
|
76
|
+
iconFullScreen?: string;
|
|
77
|
+
iconMinimizeScreen?: string;
|
|
78
|
+
iconLeftLayout?: string;
|
|
79
|
+
iconRightLayout?: string;
|
|
80
|
+
|
|
81
|
+
/** Icon size in logical pixels */
|
|
82
|
+
iconSize?: WithDefault<Float, 40>;
|
|
83
|
+
|
|
84
|
+
// ── Events ────────────────────────────────────────────────────────────────
|
|
85
|
+
onFullScreenChange?: DirectEventHandler<FullScreenChangeEvent>;
|
|
86
|
+
onLeftScreenChange?: DirectEventHandler<LeftScreenChangeEvent>;
|
|
87
|
+
onRightScreenChange?: DirectEventHandler<RightScreenChangeEvent>;
|
|
88
|
+
onZoomChange?: DirectEventHandler<ZoomChangeEvent>;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// The string 'PdfViewerView' must match PdfViewerFabricManager.VIEW_NAME in Kotlin.
|
|
92
|
+
export default codegenNativeComponent<NativePdfViewerProps>(
|
|
93
|
+
'PdfViewerView'
|
|
94
|
+
) as HostComponent<NativePdfViewerProps>;
|