Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support width in percentage #30 #39

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ In the following table the list of parameters that can be provided to the `pdf_v
| name | description |
|-------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| input | The source of the PDF file. Accepts a file path, URL, or binary data. |
| width | Width of the PDF viewer in pixels. It defaults to 700 pixels. |
| width | The width of the PDF viewer defaults to 100% of the layout. Specify in pixels with a numeric value, or as a percentage for relative sizing. |
| height | Height of the PDF viewer in pixels. If not provided, the viewer shows the whole content. |
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about having height = 100% by default too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tried it and pushed it here 5443edb
But, it's outer height not inner height. The custom javascript returned 0 as value when I retrieve inner height because of iframe problem
ref: https://developer.mozilla.org/en-US/docs/Web/API/Window/outerHeight

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK forget about it, we can address the height-related issue in #41

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, do you think I should revert it? Because I've already pushed the code which supports outerHeight.

| annotations | A list of annotations to be overlaid on the PDF. Format is described here. |
| pages_vertical_spacing | The vertical space (in pixels) between each page of the PDF. Defaults to 2 pixels. |
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
streamlit
bump-my-version
bump-my-version
lfoppiano marked this conversation as resolved.
Show resolved Hide resolved
streamlit_js_eval
38 changes: 33 additions & 5 deletions streamlit_pdf_viewer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Union, List, Optional

import streamlit.components.v1 as components
from streamlit_js_eval import streamlit_js_eval
import json

_RELEASE = True
Expand All @@ -21,8 +22,23 @@
path=build_dir
)

def get_screen_size():
"""
Returns the inner width and outer height of a window.
Ideally, it should return the inner height, but JavaScript couldn't retrieve the height in an iframe.
"""
async_js_code = """
new Promise(resolve => {
if (document.readyState === "complete") {
resolve([window.innerWidth, window.outerHeight]);
} else {
window.addEventListener("load", () => resolve([window.innerWidth, window.outerHeight]));
}
})
"""
return streamlit_js_eval(js_expressions=async_js_code)

def pdf_viewer(input: Union[str, Path, bytes], width: int = 700, height: int = None, key=None,
def pdf_viewer(input: Union[str, Path, bytes], width: Union[str, int] = "100%", height: Union[str, int] = "100%", key=None,
annotations: list = (),
pages_vertical_spacing: int = 2,
annotation_outline_size: int = 1,
Expand All @@ -33,7 +49,7 @@ def pdf_viewer(input: Union[str, Path, bytes], width: int = 700, height: int = N
pdf_viewer function to display a PDF file in a Streamlit app.

:param input: The source of the PDF file. Accepts a file path, URL, or binary data.
:param width: Width of the PDF viewer in pixels. Defaults to 700 pixels.
:param width: The width of the PDF viewer defaults to 100% of the layout. Specify in pixels with a numeric value, or as a percentage for relative sizing.
:param height: Height of the PDF viewer in pixels. If not provided, the viewer show the whole content.
:param key: An optional key that uniquely identifies this component. Used to preserve state in Streamlit apps.
:param annotations: A list of annotations to be overlaid on the PDF. Each annotation should be a dictionary.
Expand All @@ -51,9 +67,21 @@ def pdf_viewer(input: Union[str, Path, bytes], width: int = 700, height: int = N
Returns the value of the selected component (if any).
"""

# Validate width and height parameters
if not isinstance(width, int):
raise TypeError("Width must be an integer")
screen_width, screen_height = get_screen_size()

if isinstance(width, str) and width.endswith('%'):
percentage_width = float(width[:-1]) / 100
width = int(screen_width * percentage_width)
elif not isinstance(width, int):
raise TypeError("Width must be an integer or a percentage string (e.g., '70%' or 700)")

if isinstance(height, str) and height.endswith('%'):
percentage_height = float(height[:-1]) / 100
height = int(screen_height * percentage_height)
elif height is not None and not isinstance(height, int):
raise TypeError("Height must be an integer, a percentage string (e.g., '70%'), or None")


if height is not None and not isinstance(height, int):
raise TypeError("Height must be an integer or None")
if not all(isinstance(page, int) for page in pages_to_render):
Expand Down
Loading