@june24/expo-pdf-reader 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 +50 -0
- package/android/build.gradle +23 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/expo/modules/pdfreader/ExpoPdfReaderModule.kt +202 -0
- package/android/src/main/java/expo/modules/pdfreader/ExpoPdfReaderView.kt +934 -0
- package/build/ExpoPdfReader.types.d.ts +85 -0
- package/build/ExpoPdfReader.types.d.ts.map +1 -0
- package/build/ExpoPdfReader.types.js +2 -0
- package/build/ExpoPdfReader.types.js.map +1 -0
- package/build/ExpoPdfReaderView.d.ts +28 -0
- package/build/ExpoPdfReaderView.d.ts.map +1 -0
- package/build/ExpoPdfReaderView.js +107 -0
- package/build/ExpoPdfReaderView.js.map +1 -0
- package/build/index.d.ts +4 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +3 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +16 -0
- package/ios/ExpoPdfReader.podspec +27 -0
- package/ios/ExpoPdfReaderModule.swift +170 -0
- package/ios/ExpoPdfReaderView.swift +675 -0
- package/package.json +37 -0
- package/src/ExpoPdfReader.types.ts +99 -0
- package/src/ExpoPdfReaderView.tsx +137 -0
- package/src/index.ts +4 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ViewProps, StyleProp, ViewStyle } from 'react-native';
|
|
2
|
+
|
|
3
|
+
export type AnnotationTool = 'none' | 'pen' | 'highlighter' | 'text' | 'note' | 'eraser';
|
|
4
|
+
|
|
5
|
+
export type DisplayMode = 'single' | 'continuous' | 'twoUp' | 'twoUpContinuous';
|
|
6
|
+
|
|
7
|
+
export type Point = { x: number; y: number };
|
|
8
|
+
|
|
9
|
+
export type Annotation = {
|
|
10
|
+
type: 'pen' | 'highlighter' | 'text';
|
|
11
|
+
color: string;
|
|
12
|
+
page?: number;
|
|
13
|
+
points?: Point[][]; // For pen/highlighter
|
|
14
|
+
width?: number; // Stroke width or font size for text? Let's use fontSize for text explicitly
|
|
15
|
+
text?: string; // For text
|
|
16
|
+
fontSize?: number; // For text
|
|
17
|
+
x?: number; // For text
|
|
18
|
+
y?: number; // For text
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export type AnnotationChangeEvent = {
|
|
22
|
+
nativeEvent: {
|
|
23
|
+
annotations: Annotation[];
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type PageChangeEvent = {
|
|
28
|
+
nativeEvent: {
|
|
29
|
+
page: number;
|
|
30
|
+
total: number;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type ScrollEvent = {
|
|
35
|
+
nativeEvent: {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
contentWidth: number;
|
|
39
|
+
contentHeight: number;
|
|
40
|
+
layoutWidth: number;
|
|
41
|
+
layoutHeight: number;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export type SearchResult = {
|
|
46
|
+
page: number;
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
textSnippet?: string;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Public API: group drawing configuration into a single object
|
|
55
|
+
export type AnnotationOptions = {
|
|
56
|
+
tool?: AnnotationTool;
|
|
57
|
+
color?: string; // Hex color
|
|
58
|
+
fontSize?: number;
|
|
59
|
+
text?: string;
|
|
60
|
+
strokeWidth?: number; // line thickness for pen/highlighter
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Props exposed to JS users of the component
|
|
64
|
+
export type ExpoPdfReaderViewProps = ViewProps & {
|
|
65
|
+
url: string;
|
|
66
|
+
style?: StyleProp<ViewStyle>;
|
|
67
|
+
displayMode?: DisplayMode; // 'single' | 'continuous' | 'twoUp' | 'twoUpContinuous'
|
|
68
|
+
initialPage?: number; // starting page index (0-based)
|
|
69
|
+
minZoom?: number;
|
|
70
|
+
maxZoom?: number;
|
|
71
|
+
annotationOptions?: AnnotationOptions;
|
|
72
|
+
initialAnnotations?: Annotation[];
|
|
73
|
+
onAnnotationChange?: (event: AnnotationChangeEvent) => void;
|
|
74
|
+
onPageChange?: (event: PageChangeEvent) => void;
|
|
75
|
+
onScroll?: (event: ScrollEvent) => void;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Internal props that the native view actually receives.
|
|
79
|
+
// This keeps backwards-compat with the native module while giving
|
|
80
|
+
// JS a cleaner grouped API via `annotationOptions`.
|
|
81
|
+
export type NativeExpoPdfReaderViewProps = ViewProps & {
|
|
82
|
+
url: string;
|
|
83
|
+
style?: StyleProp<ViewStyle>;
|
|
84
|
+
displayMode?: DisplayMode;
|
|
85
|
+
initialPage?: number;
|
|
86
|
+
minZoom?: number;
|
|
87
|
+
maxZoom?: number;
|
|
88
|
+
annotationTool?: AnnotationTool;
|
|
89
|
+
annotationColor?: string; // Hex color
|
|
90
|
+
annotationFontSize?: number;
|
|
91
|
+
annotationText?: string; // Default text to place
|
|
92
|
+
// Native-only props derived from AnnotationOptions
|
|
93
|
+
annotationStrokeWidth?: number;
|
|
94
|
+
initialAnnotations?: Annotation[];
|
|
95
|
+
onAnnotationChange?: (event: AnnotationChangeEvent) => void;
|
|
96
|
+
onPageChange?: (event: PageChangeEvent) => void;
|
|
97
|
+
onScroll?: (event: ScrollEvent) => void;
|
|
98
|
+
};
|
|
99
|
+
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { requireNativeModule } from 'expo-modules-core';
|
|
2
|
+
import { requireNativeViewManager } from 'expo-modules-core';
|
|
3
|
+
import * as React from 'react';
|
|
4
|
+
import { findNodeHandle } from 'react-native';
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ExpoPdfReaderViewProps,
|
|
8
|
+
NativeExpoPdfReaderViewProps,
|
|
9
|
+
Annotation,
|
|
10
|
+
SearchResult,
|
|
11
|
+
} from './ExpoPdfReader.types';
|
|
12
|
+
|
|
13
|
+
const NativeView: React.ComponentType<
|
|
14
|
+
NativeExpoPdfReaderViewProps & { ref?: React.Ref<any> }
|
|
15
|
+
> = requireNativeViewManager('ExpoPdfReader');
|
|
16
|
+
|
|
17
|
+
const NativeModule = requireNativeModule('ExpoPdfReader');
|
|
18
|
+
|
|
19
|
+
export type ExpoPdfReaderRef = {
|
|
20
|
+
save: () => Promise<string>;
|
|
21
|
+
getAnnotations: () => Promise<Annotation[]>;
|
|
22
|
+
searchText: (text: string) => Promise<SearchResult[]>;
|
|
23
|
+
goToPage: (page: number) => Promise<void>;
|
|
24
|
+
undo: () => Promise<boolean>;
|
|
25
|
+
redo: () => Promise<boolean>;
|
|
26
|
+
zoomIn: () => Promise<boolean>;
|
|
27
|
+
zoomOut: () => Promise<boolean>;
|
|
28
|
+
renderThumbnail: (page: number, width: number) => Promise<string>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const ExpoPdfReaderView = React.forwardRef<ExpoPdfReaderRef, ExpoPdfReaderViewProps>(
|
|
32
|
+
(props, ref) => {
|
|
33
|
+
const nativeRef = React.useRef<any>(null);
|
|
34
|
+
|
|
35
|
+
React.useImperativeHandle(ref, () => ({
|
|
36
|
+
save: async () => {
|
|
37
|
+
if (nativeRef.current) {
|
|
38
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
39
|
+
if (viewTag && NativeModule && NativeModule.save) {
|
|
40
|
+
return await NativeModule.save(viewTag);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
throw new Error('Cannot save: Native view not found');
|
|
44
|
+
},
|
|
45
|
+
getAnnotations: async () => {
|
|
46
|
+
if (nativeRef.current) {
|
|
47
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
48
|
+
if (viewTag && NativeModule && NativeModule.getAnnotations) {
|
|
49
|
+
return await NativeModule.getAnnotations(viewTag);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return [];
|
|
53
|
+
},
|
|
54
|
+
searchText: async (text: string) => {
|
|
55
|
+
if (nativeRef.current) {
|
|
56
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
57
|
+
if (viewTag && NativeModule && NativeModule.searchText) {
|
|
58
|
+
return await NativeModule.searchText(viewTag, text);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return [];
|
|
62
|
+
},
|
|
63
|
+
goToPage: async (page: number) => {
|
|
64
|
+
if (nativeRef.current) {
|
|
65
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
66
|
+
if (viewTag && NativeModule && NativeModule.goToPage) {
|
|
67
|
+
return await NativeModule.goToPage(viewTag, page);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
undo: async () => {
|
|
72
|
+
if (nativeRef.current) {
|
|
73
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
74
|
+
if (viewTag && NativeModule && NativeModule.undo) {
|
|
75
|
+
return await NativeModule.undo(viewTag);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
},
|
|
80
|
+
redo: async () => {
|
|
81
|
+
if (nativeRef.current) {
|
|
82
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
83
|
+
if (viewTag && NativeModule && NativeModule.redo) {
|
|
84
|
+
return await NativeModule.redo(viewTag);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return false;
|
|
88
|
+
},
|
|
89
|
+
zoomIn: async () => {
|
|
90
|
+
if (nativeRef.current) {
|
|
91
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
92
|
+
if (viewTag && NativeModule && NativeModule.zoomIn) {
|
|
93
|
+
return await NativeModule.zoomIn(viewTag);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
},
|
|
98
|
+
zoomOut: async () => {
|
|
99
|
+
if (nativeRef.current) {
|
|
100
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
101
|
+
if (viewTag && NativeModule && NativeModule.zoomOut) {
|
|
102
|
+
return await NativeModule.zoomOut(viewTag);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return false;
|
|
106
|
+
},
|
|
107
|
+
renderThumbnail: async (page: number, width: number) => {
|
|
108
|
+
if (nativeRef.current) {
|
|
109
|
+
const viewTag = findNodeHandle(nativeRef.current);
|
|
110
|
+
if (viewTag && NativeModule && NativeModule.renderThumbnail) {
|
|
111
|
+
return await NativeModule.renderThumbnail(viewTag, page, width);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return '';
|
|
115
|
+
},
|
|
116
|
+
}));
|
|
117
|
+
|
|
118
|
+
const { annotationOptions, ...restProps } = props;
|
|
119
|
+
|
|
120
|
+
const nativeProps: NativeExpoPdfReaderViewProps = {
|
|
121
|
+
...(restProps as NativeExpoPdfReaderViewProps),
|
|
122
|
+
displayMode: props.displayMode,
|
|
123
|
+
initialPage: props.initialPage,
|
|
124
|
+
minZoom: props.minZoom,
|
|
125
|
+
maxZoom: props.maxZoom,
|
|
126
|
+
annotationTool: annotationOptions?.tool,
|
|
127
|
+
annotationColor: annotationOptions?.color,
|
|
128
|
+
annotationFontSize: annotationOptions?.fontSize,
|
|
129
|
+
annotationText: annotationOptions?.text,
|
|
130
|
+
annotationStrokeWidth: annotationOptions?.strokeWidth,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
return <NativeView ref={nativeRef} {...nativeProps} />;
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
export default ExpoPdfReaderView;
|
package/src/index.ts
ADDED