Skip to content

Commit

Permalink
Callback for clicking on annotations #76
Browse files Browse the repository at this point in the history
  • Loading branch information
t29mato committed Dec 3, 2024
1 parent 8634000 commit ccde4c1
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
12 changes: 10 additions & 2 deletions streamlit_pdf_viewer/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import base64
import os
from pathlib import Path
from typing import Union, List, Optional
from typing import Union, List, Optional, Callable

import streamlit.components.v1 as components
import json
Expand Down Expand Up @@ -39,7 +39,8 @@ def pdf_viewer(
resolution_boost: int = 1,
scroll_to_page: int = None,
scroll_to_annotation: int = None,
):
on_annotation_click: Optional[Callable[[dict], None]] = None,
):
"""
pdf_viewer function to display a PDF file in a Streamlit app.
Expand All @@ -59,6 +60,7 @@ def pdf_viewer(
:param resolution_boost: Boost the resolution by a factor from 2 to 10. Defaults to 1.
:param scroll_to_page: Scroll to a specific page in the PDF. The parameter is an integer, which represent the positional value of the page. E.g. 1, will be the first page. Defaults to None.
:param scroll_to_annotation: Scroll to a specific annotation in the PDF. The parameter is an integer, which represent the positional value of the annotation. E.g. 1, will be the first annotation. Defaults to None.
:param on_annotation_click: A callback function that will be called when an annotation is clicked. The function should accept a single argument, which is the annotation that was clicked. Defaults to None.
The function reads the PDF file (from a file path, URL, or binary data), encodes it in base64,
and uses a Streamlit component to render it in the app. It supports optional annotations and adjustable margins.
Expand Down Expand Up @@ -118,6 +120,12 @@ def pdf_viewer(
scroll_to_page=scroll_to_page,
scroll_to_annotation=scroll_to_annotation
)

# Execute the custom callback function
if component_value and 'clicked_annotation' in component_value:
clicked_annotation = component_value['clicked_annotation']
if on_annotation_click is not None and callable(on_annotation_click):
on_annotation_click(clicked_annotation)
return component_value


Expand Down
27 changes: 23 additions & 4 deletions streamlit_pdf_viewer/frontend/src/PdfViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
<div id="pdfContainer" :style="pdfContainerStyle">
<div v-if="args.rendering==='unwrap'">
<div id="pdfViewer" :style="pdfViewerStyle">
<div id="pdfAnnotations" v-if="args.annotations">
<div v-for="(annotation, index) in filteredAnnotations" :key="index" :style="getPageStyle">
<div :style="getAnnotationStyle(annotation, index)" :id="`annotation-${index}`"></div>
<div id="pdfAnnotations" v-if="args.annotations">
<div
v-for="(annotation, index) in filteredAnnotations"
:key="index"
:style="getPageStyle"
@click="handleAnnotationClick(annotation, index)"
>
<div
:style="getAnnotationStyle(annotation, index)"
:id="`annotation-${index}`"
></div>
</div>
</div>
</div>
</div>
</div>
<div v-else-if="args.rendering==='legacy_embed'">
<embed :src="`data:application/pdf;base64,${args.binary}`" :width="`${args.width}`" :height="`${args.height}`" type="application/pdf"/>
Expand Down Expand Up @@ -55,6 +63,16 @@ export default {
})
});
const handleAnnotationClick = (annotation, index) => {
// Convert the Proxy object to a plain object
const serializedAnnotation = JSON.parse(JSON.stringify(annotation));
// Send data to Streamlit
Streamlit.setComponentValue({
clicked_annotation: { index, ...serializedAnnotation },
});
};
const renderText = props.args.render_text === true
const pdfContainerStyle = computed(() => ({
Expand Down Expand Up @@ -355,6 +373,7 @@ export default {
return {
filteredAnnotations,
handleAnnotationClick,
getAnnotationStyle,
pdfContainerStyle,
pdfViewerStyle,
Expand Down

0 comments on commit ccde4c1

Please sign in to comment.