How to implement text-shadow with @react-pdf/renderer in such a way that you can center align the text?

Viewed 331

I'm using @react-pdf/renderer to generate PDF on the frontend. I've to implement titles with "text borders" and shadows. Since the library doesn't support the text-shadow CSS property, I've implemented the following workaround using the position property:

import React from 'react'
import { StyleSheet, Text, View } from '@react-pdf/renderer'

const BaseStyles = {
  FakeShadowProvider: {
    position: "relative",
  },
  FakeBorderTop: {
    position: "absolute",
    top: "-1pt",
    left: 0,
    color: "black",
  },
  FakeBorderRight: {
    position: "absolute",
    top: 0,
    left: "1pt",
    color: "black",
  },
  FakeBorderBottom: {
    position: "absolute",
    top: "-1pt",
    left: 0,
    color: "black",
  },
  FakeBorderLeft: {
    position: "absolute",
    top: 0,
    left: "-1pt",
    color: "black",
  },
  FakeShadow: {
    position: "absolute",
    top: "1pt",
    left: "3pt",
    color: "black",
  },
}

const PDFTextWithShadow = ({
  value,
  textAlign = "left",
  fontSize,
  color,
}) => {
  const styles = StyleSheet.create({
    FakeShadowProvider: {
      ...BaseStyles.FakeShadowProvider,
      textAlign,
      fontSize,
    },
    FakeShadow: {
      ...BaseStyles.FakeShadow,
    },
    FakeBorderTop: {
      ...BaseStyles.FakeBorderTop,
    },
    FakeBorderRight: {
      ...BaseStyles.FakeBorderRight,
    },
    FakeBorderBottom: {
      ...BaseStyles.FakeBorderBottom,
    },
    FakeBorderLeft: {
      ...BaseStyles.FakeBorderLeft,
    },
    Text: {
      color,
    }
  })

  return (
    <View style={styles.FakeShadowProvider}>
      <Text style={styles.FakeShadow}>
        {value}
      </Text>
      <Text style={styles.FakeBorderTop}>
        {value}
      </Text>
      <Text style={styles.FakeBorderRight}>
        {value}
      </Text>
      <Text style={styles.FakeBorderBottom}>
        {value}
      </Text>
      <Text style={styles.FakeBorderLeft}>
        {value}
      </Text>
      <Text style={styles.Text}>
        {value}
      </Text>
    </View>
  )
}

export default PDFTextWithShadow

This allowed me to implement the shadows as you can see here.

My problem is that my workaround doesn't support center-aligning the texts with their shadows. If I tried several things:

  1. To just use textAlign: "center". That doens't work because the shadows use position. The outcome to that is this
  2. To find a way to get the width of the <Text /> components at runtime (because right now it says "NICO" but that text is variable). If I had it, given the fixed width of the container then I could simply calculate a corresponding left value that would get the job done. But this library doesn't expose any way for doing this.

So, how can I center align texts with @react-pdf/renderer while also implementing the "text-shadows" feature?

0 Answers
Related