react-pdf
react-pdf copied to clipboard
RTL support
Hi Dear; When use this library and using Arabic or Persian language direction problem, Please add RTL support for text and style direction: "rtl"
Hi @hmz22 How did you get the text in the right Unicode with this library? I got something like:
Hi @hmz22 How did you get the text in the right Unicode with this library? I got something like:
It worked!
Just by adding format: "truetype"
in the font registration section, and giving it to the Page element in the StyleSheet section.
Font.register({
family: "iranyekan",
format: "truetype", // 1
src: iranyekanwebregularfanum,
fontStyle: "normal",
fontWeight: "normal",
});
then:
const styles = StyleSheet.create({
page: {
fontFamily: "iranyekan", // 2
}
});
then:
// component code
return (
<Document>
<Page size="A5" orientation="landscape" style={styles.page}> {/* 3 */}
</Page>
</Document>
);
when pdf downloaded the arabic shown as a numbers and squares what is the problem
Hi @hmz22, did you find a workaround for this issue?
Having the same issue here
Any updates? has anyone found a solution?
Any updates? has anyone found a solution?
Hi, I found a way Test the code below, it might work for you too
const [splitedText, setSplitedText] = useState([]) useEffect(()=>{ const _splitedText = text.split(" "); setSplitedText(_splitedText) },[])
store the list of words in the array
now we need styles to show the all word correctly inside a <View> tag
const styles = StyleSheet.create({ flexRowReverse: { flexDirection: "row-reverse" }, flexWrap: { flexWrap: "wrap" }, ml1: { marginLeft: "2pt" } })
then map splitedText inside View tag
<View style={[styles.flexRowReverse, styles.flexWrap]}> {splitedText.map((word, idx) => { return ( <Text style={styles.ml1} key={idx}> {word} </Text> ); })} </View>
Any updates? has anyone found a solution?
Hi, I found a way Test the code below, it might work for you too.
Store the list of words in the array
const [splitedText, setSplitedText] = useState([])
useEffect(()=>{
const _splitedText = text.split(" ");
setSplitedText(_splitedText)
},[])
now we need styles to show the all word correctly inside a <View> tag
const styles = StyleSheet.create({
flexRowReverse: {
flexDirection: "row-reverse"
},
flexWrap: {
flexWrap: "wrap"
},
ml1: {
marginLeft: "2pt"
}
})
then map splitedText inside View tag
<View style={[styles.flexRowReverse, styles.flexWrap]}>
{
splitedText.map((word, idx) => {
return (
<Text style={styles.ml1} key={idx}>
{word}
</Text>
);
})
}
</View>
Using @X3rom-S 's idea here I created a component for RTL Text:
- The idea: reverses the sentence (mainly) by using
flexDirection: "row-reverse"
- Takes new lines ("\n") into account
- Notice: style on the text is different bcos each word is a <Text> so I added supports for textAlign: "center" by passing textAlign="center"
import { Text, View } from '@react-pdf/renderer';
import { FC } from 'react';
interface RtlTextProps {
containerStyle?: any | any[];
textAlign?: "center";
children: string;
}
/**
* When using <Text> component and the text is longer than 1 line, the hebrew text (and arabic I THINK) is rendered wrong.
* This component fixes that.
*/
export const RtlText: FC<RtlTextProps> = ({ children: text, ...props }) => {
const { containerStyle: containerStyleProp, textAlign } = props;
const sentences = text.split("\n");
if (sentences.length > 1) {
// each "sentence" doesn't have "\n"s in it
return <>{sentences.map((sentence, i) => <RtlText key={i} {...props} >{sentence}</RtlText>)}</>
}
const words = text.split(" ");
const TextStyle: Record<string, any> = { marginLeft: "2pt" }; //! couldn't get the `style` interface! https://github.com/diegomura/react-pdf/issues/2291
const ContainerStyle = Array.isArray(containerStyleProp) ? containerStyleProp : [containerStyleProp]
ContainerStyle.push({ flexWrap: "wrap", flexDirection: "row-reverse" });
if (textAlign === "center") {
ContainerStyle.push({ justifyContent: "center" });
}
return (
<View style={ContainerStyle}>
{
words.map((word, index) => <Text style={TextStyle} key={index}>{word}</Text>)
}
</View>
);
};
Usage example:
<RtlText textAlign={"center"} >
{text}
</RtlText>
Related: #1394
<Text style={{ textAlign: "right" }}>اهلا انا عربي </Text>
worked fine with me despite the view this text was inside
Any plans to support this? It would be fantastic.