nova_forms/components/
preview.rs

1use leptos::*;
2use leptos_meta::*;
3
4use crate::{FormContext, PRINT_CSS};
5
6use super::AppContext;
7
8pub fn start_preview(form_id: &str) {
9    let base_context = expect_context::<AppContext>();
10
11    js_sys::eval(&format!(r#"
12            startPreview("{}", "{}", `@scope (#preview) {{ {} }}`);
13        "#,
14        form_id,
15        base_context.resolve_path("print.css"),
16        PRINT_CSS
17    )).ok();
18}
19
20pub fn stop_preview(_form_id: &str) {
21    js_sys::eval(&format!(r#"
22        stopPreview();
23    "#)).ok();
24}
25
26#[component]
27pub fn Preview() -> impl IntoView {
28    let nova_form_context = expect_context::<FormContext>();
29
30    view! {
31        <Script>r#"
32            window.styles = [];
33
34            function resizePreview() {
35                const preview = document.getElementById("preview");
36                let scaleFactor =  Math.min(1, (preview.parentElement.offsetWidth / preview.scrollWidth));
37                if (scaleFactor < 1) {
38                    preview.style.position = "absolute";
39                    preview.style.width = "210mm";
40                    preview.style.transformOrigin = "top left";
41                    preview.style.transform = "scale(" + scaleFactor + ")";
42                    preview.style.marginRight = -210 * (1 - scaleFactor) + "mm";
43                    preview.style.marginBottom = -preview.scrollHeight * (1 - scaleFactor) + "px";
44                    preview.parentElement.style.height = preview.scrollHeight * scaleFactor + "px";
45                } else {
46                    preview.removeAttribute("style");
47                    preview.parentElement.removeAttribute("style");
48                }
49            }
50
51            async function startPreview(formId, printCss, baseCss) {
52                if (document.getElementById("preview-wrapper").classList.contains("visible")) {
53                    var url = URL.createObjectURL(new Blob([baseCss], {type: "text/css"}));
54                    var preview = document.getElementById("preview");
55                    preview.innerHTML = "";
56                    var paged = new window.Paged.Previewer();
57                    window.previewer = paged;
58                    await paged.preview(
59                        document.getElementById(formId).innerHTML,
60                        [printCss, url],
61                        preview
62                    );
63                    resizePreview();
64                }
65            }
66
67            async function stopPreview() {
68                var preview = document.getElementById("preview");
69                preview.removeAttribute("style");
70                preview.parentElement.removeAttribute("style");
71                window.previewer.removeStyles(preview);
72            }
73
74            window.PagedConfig = {
75                auto: false
76            };
77
78            /*window.addEventListener("DOMContentLoaded", function() {
79                const previewObserver = new MutationObserver(function(mutations) {
80                    mutations.forEach(function(mutation) {
81                        resizePreview();
82                    });
83                });
84                
85                previewObserver.observe(document.getElementById("preview"), {
86                    childList: true,
87                    subtree: true
88                });
89            });*/
90            
91            window.addEventListener("resize", resizePreview);
92        "#</Script>
93        <Script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></Script>
94
95        <div
96            id="preview-wrapper"
97            class:hidden=move || !nova_form_context.is_preview_mode()
98            class:visible=move || nova_form_context.is_preview_mode()
99        >
100            <div
101                id="preview"
102            ></div>
103        </div>
104    }
105}