Preprocess certain CSS values before PDF rendering to fix html2canvas limitations

This commit is contained in:
Andrew Kingston 2025-04-01 20:06:44 +01:00
parent c8de60eb8e
commit 651ac10de3
No known key found for this signature in database
4 changed files with 43 additions and 23 deletions

View File

@ -57,12 +57,6 @@
let permissionError = false
let embedNoScreens = false
// Get theme class names, which is always lightest for LDFs
$: isPDFScreen = $screenStore.activeScreen?.variant === ScreenVariant.PDF
$: themeClassNames = isPDFScreen
? "spectrum--light"
: getThemeClassNames($themeStore.theme)
// Determine if we should show devtools or not
$: showDevTools = $devToolsEnabled && !$routeStore.queryParams?.peek
@ -164,7 +158,7 @@
id="spectrum-root"
lang="en"
dir="ltr"
class="spectrum spectrum--medium {themeClassNames}"
class="spectrum spectrum--medium {getThemeClassNames($themeStore.theme)}"
class:builder={$builderStore.inBuilder}
class:show={fontsLoaded && dataLoaded}
>

View File

@ -1,12 +1,18 @@
<script>
import { themeStore } from "@/stores"
import { setContext } from "svelte"
import { Context } from "@budibase/bbui"
import { Context, Helpers } from "@budibase/bbui"
setContext(Context.PopoverRoot, "#theme-root")
export let popoverRoot = true
const id = Helpers.uuid()
if (popoverRoot) {
setContext(Context.PopoverRoot, `#id`)
}
</script>
<div style={$themeStore.customThemeCss} id="theme-root">
<div style={$themeStore.customThemeCss} {id}>
<slot />
</div>

View File

@ -3,6 +3,7 @@
import { Heading, Button } from "@budibase/bbui"
import { htmlToPdf, pxToPt, A4HeightPx, type PDFOptions } from "./pdf"
import { GridRowHeight } from "@/constants"
import CustomThemeWrapper from "@/components/CustomThemeWrapper.svelte"
const component = getContext("component")
const { styleable, Block, BlockComponent } = getContext("sdk")
@ -30,6 +31,7 @@
const generatePDF = async () => {
rendering = true
await tick()
preprocessCSS()
try {
const opts: PDFOptions = {
fileName: safeName,
@ -43,6 +45,16 @@
rendering = false
}
const preprocessCSS = () => {
const els = document.getElementsByClassName(
"grid-child"
) as unknown as HTMLElement[]
for (let el of els) {
const styles = window.getComputedStyle(el)
el.style.setProperty("grid-column-end", styles.gridColumnEnd, "important")
}
}
const getDividerStyle = (idx: number) => {
const top = (idx + 1) * innerPageHeightPx + doubleMarginPx / 2
return `--idx:"${idx + 1}"; --top:${top}px;`
@ -90,19 +102,24 @@
/>
{/each}
{/if}
<div class="pageContent" bind:this={ref}>
<BlockComponent
type="container"
props={{ layout: "grid" }}
styles={{
normal: {
height: `${gridMinHeight}px`,
},
}}
context="grid"
>
<slot />
</BlockComponent>
<div
class="spectrum spectrum--medium spectrum--lightest pageContent"
bind:this={ref}
>
<CustomThemeWrapper popoverRoot={false}>
<BlockComponent
type="container"
props={{ layout: "grid" }}
styles={{
normal: {
height: `${gridMinHeight}px`,
},
}}
context="grid"
>
<slot />
</BlockComponent>
</CustomThemeWrapper>
</div>
</div>
</div>

View File

@ -116,6 +116,9 @@ export const gridLayout = (node: HTMLDivElement, metadata: GridMetadata) => {
return
}
// Add a unique class to elements we mutate so we can easily find them later
node.classList.add("grid-child")
// Callback to select the component when clicking on the wrapper
selectComponent = (e: Event) => {
e.stopPropagation()