@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.
@@ -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
@@ -0,0 +1,4 @@
1
+ import ExpoPdfReaderView from './ExpoPdfReaderView';
2
+ import { ExpoPdfReaderViewProps } from './ExpoPdfReader.types';
3
+
4
+ export { ExpoPdfReaderView, ExpoPdfReaderViewProps };
package/tsconfig.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "extends": "./node_modules/expo-module-scripts/tsconfig.base",
3
+ "compilerOptions": {
4
+ "outDir": "build",
5
+ "rootDir": "src"
6
+ },
7
+ "include": ["src/**/*"],
8
+ "exclude": ["**/__tests__/*", "example/**/*"]
9
+ }