6

I'm working on a React Native app where I show some text inside boxes. Sometimes the individual words in the boxes are too long to fit on one line so RN just breaks the word off when it would get too long and continues the text on the next line. This unfortunately leads to poor hyphenation of the words (see the left box in the image). I'm trying to find a solution to improve this such that in this example the result would be like the box on the right where the word is hyphenated at a reasonable point. I know there are javascript libraries that deal with hyphenation. This for example breaks words into their hyphens in an array. I'm stuck here because I have no idea how to actually figure out if I need to hyphenate the word or not. Any ideas?

Poor hyphenation on the left, better on the right

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
user3346601
  • 1,019
  • 1
  • 11
  • 18
  • Add a space between "t" and "N". A lower letter followed by a capital one seems to be the only rule you could apply here. Find all those cases in the string and prepend a space before the capital letter. – Sergiu Paraschiv Apr 27 '16 at 15:57
  • This is just an example. What if the word was "Stackoverflow" - a long word without upper case letters in it – user3346601 Apr 27 '16 at 16:01
  • Then there is no programatic rule to split it where a human would. – Sergiu Paraschiv Apr 27 '16 at 16:06
  • I think some additional left-right padding is all you need then. – Sergiu Paraschiv Apr 27 '16 at 16:06
  • 3
    of course there are rules - I've linked to a javascript library that does splits word into their hypens - I just dont know what to do with it – user3346601 Apr 27 '16 at 16:11
  • 2
    OK, that could work. Only one big issue I can see. What happens with "analbum"? Solutions like this almost always have strange edge cases that you maybe can't ignore. – Sergiu Paraschiv Apr 27 '16 at 16:24
  • when I've had to do this for the web, I would create a hidden div element with the text, measure the width of it, decide whether or not to split the real text, and then delete the hidden div. I think you could do all of that with a Text element when the component is mounting – Garrett McCullough Oct 11 '16 at 20:51
  • @GarrettMcCullough what does that look like? – shmuli May 18 '17 at 20:16
  • @shmuli here's an example of how it is done on the web https://stackoverflow.com/questions/118241/calculate-text-width-with-javascript What you would probably end up doing is running the text through the hypher.js library and then adding each token one at a time to your invisible text tag and checking the length. If the length is less than the desired width, you'd add the next the next token. If it's greater, then you'd subtract that token and put in your hyphen. We had a design that was causing a similar problem with hyphenated words. We ended up just re-doing the design – Garrett McCullough May 24 '17 at 15:30

2 Answers2

5

use C/C++/Java Encoding:

text = 'React\u00ADNative'
<Text>{text}</Text>
peni4142
  • 426
  • 1
  • 7
  • 26
  • Soft hyphens work on iOS but not on Android. https://stackoverflow.com/q/58376106 :( – Sampo Apr 02 '20 at 09:56
  • Since react-native soft hyphens work on Android if you set android_hyphenationFrequency="full" on the text component. – hontas Nov 30 '21 at 14:15
1

Actually, I used peni4142's answer to make a function to return a string that is able to be hyphenated:

const hyphenatedText = (text: string): string => 
  text
    .split(' ')
    .map((word) => word.split('').join('\u00AD'))
    .join(' ');

Now, if your hyphenatedText would be in a React Native Text component it would be hyphenated wrapped automatically.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154