<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Aqeel Ahmad</title>
    <description>The latest articles on DEV Community by Aqeel Ahmad (@aqeel_ahmad_331bef29ba12a).</description>
    <link>https://dev.to/aqeel_ahmad_331bef29ba12a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4173371%2Fd3370a21-0a63-4069-8737-214b4d134355.jpg</url>
      <title>DEV Community: Aqeel Ahmad</title>
      <link>https://dev.to/aqeel_ahmad_331bef29ba12a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aqeel_ahmad_331bef29ba12a"/>
    <language>en</language>
    <item>
      <title>Instagram story text in React Native: rounded highlighted text that you can edit</title>
      <dc:creator>Aqeel Ahmad</dc:creator>
      <pubDate>Fri, 09 Oct 2026 12:07:20 +0000</pubDate>
      <link>https://dev.to/aqeel_ahmad_331bef29ba12a/instagram-story-text-in-react-native-rounded-highlighted-text-that-you-can-edit-15cl</link>
      <guid>https://dev.to/aqeel_ahmad_331bef29ba12a/instagram-story-text-in-react-native-rounded-highlighted-text-that-you-can-edit-15cl</guid>
      <description>&lt;p&gt;If you have ever tried to build an Instagram or TikTok style story editor in React Native, you probably started the same way I did.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;backgroundColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FF3D7F&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;white&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  golden hour in lisbon
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you got a flat pink rectangle. No rounded corners, no padding around each line, and when the text wrapped to a second line, the box just grew into one big block. That is not the story look. The story look is a rounded background that hugs every line separately, with a little breathing room around the glyphs, and it grows line by line while you type.&lt;/p&gt;

&lt;p&gt;I needed exactly that in an app I was building and could not find a library that did it well on both platforms. So I built one, &lt;code&gt;react-native-highlight-text-view&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnyje5jrmw3abq2wp36q5.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnyje5jrmw3abq2wp36q5.gif" alt="Typing story text on iOS: the rounded highlight grows line by line" width="340" height="739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why plain backgroundColor cannot do this
&lt;/h2&gt;

&lt;p&gt;The usual tricks all break somewhere.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;backgroundColor&lt;/code&gt; on &lt;code&gt;&amp;lt;Text&amp;gt;&lt;/code&gt;&lt;/strong&gt; paints the whole text box. You get one rectangle, and &lt;code&gt;borderRadius&lt;/code&gt; rounds that rectangle, not each line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nested &lt;code&gt;&amp;lt;Text&amp;gt;&lt;/code&gt; with a background&lt;/strong&gt; paints behind the glyphs of each run, but you cannot add padding to an inline span, and the corners stay square. The background also stops tight at the glyph edges, so lines look cramped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Splitting the text into one &lt;code&gt;&amp;lt;Text&amp;gt;&lt;/code&gt; per line&lt;/strong&gt; works for a fixed caption, but you have to guess where the line breaks are. The moment the font, size or screen width changes, your breaks are wrong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editing&lt;/strong&gt; makes all of this worse. A &lt;code&gt;TextInput&lt;/code&gt; does its own line wrapping on the native side, and you only learn about it after the fact. Trying to mirror the layout in JS on every keystroke leads to flicker and backgrounds that lag a frame behind the cursor.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The real problem is that the line breaks are only known inside the native text layout engine. So that is where the background has to be drawn.&lt;/p&gt;

&lt;h2&gt;
  
  
  The approach: draw it in the native text layout
&lt;/h2&gt;

&lt;p&gt;The library is a Fabric component (New Architecture) with a native implementation on each platform.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;iOS:&lt;/strong&gt; the view wraps a &lt;code&gt;UITextView&lt;/code&gt; whose layout manager is a custom &lt;code&gt;NSLayoutManager&lt;/code&gt; subclass. It overrides &lt;code&gt;drawBackgroundForGlyphRange:atPoint:&lt;/code&gt;, so after the system has laid out and wrapped the text, it draws rounded, padded backgrounds for the glyphs that are actually on each line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Android:&lt;/strong&gt; the view is a custom &lt;code&gt;EditText&lt;/code&gt; that draws the rounded highlights itself in &lt;code&gt;onDraw()&lt;/code&gt;, using the &lt;code&gt;Layout&lt;/code&gt; the system already computed, and then lets &lt;code&gt;EditText&lt;/code&gt; draw the text, cursor and selection on top. Neighbouring character backgrounds are filled as one shape, so a line reads as one continuous rounded block instead of separate boxes per word.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because both sides read the platform's own line layout, the highlight follows wrapping automatically, redraws as you type, and keeps working when you change the font, size, colors or alignment at runtime without remounting. As of 1.1.0, Android uses the same units as iOS (points), so values you tune on one platform give the same result on the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;react-native-highlight-text-view
&lt;span class="c"&gt;# or&lt;/span&gt;
yarn add react-native-highlight-text-view
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the React Native CLI on iOS, run &lt;code&gt;cd ios &amp;amp;&amp;amp; pod install&lt;/code&gt; afterwards.&lt;/p&gt;

&lt;p&gt;On Expo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx expo &lt;span class="nb"&gt;install &lt;/span&gt;react-native-highlight-text-view
npx expo prebuild   &lt;span class="c"&gt;# or build with EAS&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This package contains native code, so it works in Expo development builds and EAS builds, but &lt;strong&gt;not in Expo Go&lt;/strong&gt;. No config plugin is needed.&lt;/p&gt;

&lt;p&gt;Requirements: React Native 0.76 or newer with the New Architecture (it is a Fabric only component), or Expo SDK 52 or newer in a dev build. Android minSdk is 24.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

&lt;p&gt;Here is a controlled story input. It behaves like a regular &lt;code&gt;TextInput&lt;/code&gt;: &lt;code&gt;text&lt;/code&gt; plus &lt;code&gt;onChange&lt;/code&gt;, a &lt;code&gt;placeholder&lt;/code&gt;, keyboard props, and a ref with &lt;code&gt;focus()&lt;/code&gt;, &lt;code&gt;blur()&lt;/code&gt;, &lt;code&gt;clear()&lt;/code&gt; and &lt;code&gt;setText()&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;HighlightTextView&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;HighlightTextViewRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-native-highlight-text-view&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;StoryText&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HighlightTextViewRef&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HighlightTextView&lt;/span&gt;
      &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;onChange&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Tap to type"&lt;/span&gt;
      &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#FF3D7F"&lt;/span&gt;
      &lt;span class="na"&gt;textColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"white"&lt;/span&gt;
      &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"800"&lt;/span&gt;
      &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
      &lt;span class="na"&gt;verticalAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
      &lt;span class="na"&gt;paddingLeft&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;paddingRight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;paddingBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;highlightBorderRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;returnKeyType&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"done"&lt;/span&gt;
      &lt;span class="na"&gt;onSubmitEditing&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;blur&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;240&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few things worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;color&lt;/code&gt; is the highlight background and &lt;code&gt;textColor&lt;/code&gt; is the text. Both accept any React Native color string, like &lt;code&gt;"#FF3D7F"&lt;/code&gt;, &lt;code&gt;"rgb(255, 204, 0)"&lt;/code&gt;, &lt;code&gt;"hsl(158, 64%, 52%)"&lt;/code&gt; or &lt;code&gt;"teal"&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Numeric props take numbers (&lt;code&gt;fontSize={32}&lt;/code&gt;) or strings (&lt;code&gt;fontSize="32"&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The view is sized by its &lt;code&gt;style&lt;/code&gt;, like a &lt;code&gt;TextInput&lt;/code&gt;. The highlight is drawn only behind the text inside it.&lt;/li&gt;
&lt;li&gt;Setting &lt;code&gt;returnKeyType&lt;/code&gt; to anything other than &lt;code&gt;'default'&lt;/code&gt; makes Return fire &lt;code&gt;onSubmitEditing&lt;/code&gt; instead of inserting a new line. Leave it unset if you want multi-line typing.&lt;/li&gt;
&lt;li&gt;With no &lt;code&gt;verticalAlign&lt;/code&gt;, iOS draws the text at the top and Android centers it. Set &lt;code&gt;verticalAlign&lt;/code&gt; to get the same result on both.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Three recipes
&lt;/h2&gt;

&lt;p&gt;The example app in the repo has a story editor (live typing, color swatches, alignment, font size, ref methods) and a recipes screen. Here are three of them. Read-only views just use &lt;code&gt;editable={false}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw3nr0jx4fgz65jgcfr7h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fw3nr0jx4fgz65jgcfr7h.png" alt="Recipes on iOS and Android: story text, marker, tag chips and a quote" width="744" height="680"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Story text
&lt;/h3&gt;

&lt;p&gt;The classic look. A &lt;code&gt;\n&lt;/code&gt; in the text gives you a manual break, and long lines wrap on their own.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HighlightTextView&lt;/span&gt;
  &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;golden hour&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s1"&gt;in lisbon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#FF3D7F"&lt;/span&gt;
  &lt;span class="na"&gt;textColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#FFFFFF"&lt;/span&gt;
  &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"800"&lt;/span&gt;
  &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
  &lt;span class="na"&gt;verticalAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
  &lt;span class="na"&gt;paddingLeft&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingRight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;highlightBorderRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;130&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Marker highlight
&lt;/h3&gt;

&lt;p&gt;A soft color plus a large &lt;code&gt;backgroundInsetTop&lt;/code&gt; paints only the lower part of each line, like a highlighter pen across a note.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HighlightTextView&lt;/span&gt;
  &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Ship the demo before Friday"&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#FFE066"&lt;/span&gt;
  &lt;span class="na"&gt;textColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#1D1D1F"&lt;/span&gt;
  &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"600"&lt;/span&gt;
  &lt;span class="na"&gt;paddingLeft&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingRight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;backgroundInsetTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;highlightBorderRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;verticalAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;92&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Tag chips
&lt;/h3&gt;

&lt;p&gt;One small read-only view per tag. Give each chip a width. The example app measures the label with a hidden &lt;code&gt;&amp;lt;Text&amp;gt;&lt;/code&gt; and uses that.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HighlightTextView&lt;/span&gt;
  &lt;span class="na"&gt;editable&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#reactnative"&lt;/span&gt;
  &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#E0F2FE"&lt;/span&gt;
  &lt;span class="na"&gt;textColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#075985"&lt;/span&gt;
  &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;fontWeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"700"&lt;/span&gt;
  &lt;span class="na"&gt;textAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
  &lt;span class="na"&gt;verticalAlign&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"center"&lt;/span&gt;
  &lt;span class="na"&gt;paddingLeft&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingRight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;highlightBorderRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Tips from tuning it
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Padding grows the background, insets shrink it.&lt;/strong&gt; The &lt;code&gt;padding&lt;/code&gt; props (&lt;code&gt;padding&lt;/code&gt;, which defaults to &lt;code&gt;4&lt;/code&gt;, plus &lt;code&gt;paddingTop&lt;/code&gt;, &lt;code&gt;paddingBottom&lt;/code&gt;, &lt;code&gt;paddingLeft&lt;/code&gt;, &lt;code&gt;paddingRight&lt;/code&gt;) expand the colored area outward from the text. The &lt;code&gt;backgroundInset&lt;/code&gt; props (&lt;code&gt;backgroundInsetTop&lt;/code&gt;, &lt;code&gt;backgroundInsetBottom&lt;/code&gt;, &lt;code&gt;backgroundInsetLeft&lt;/code&gt;, &lt;code&gt;backgroundInsetRight&lt;/code&gt;, all default &lt;code&gt;0&lt;/code&gt;) pull it inward from the font's line box. Some fonts, like Eczar or Georgia, have tall built-in ascenders and descenders, so the highlight looks too tall. Insets fix that without touching the font size.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HighlightTextView&lt;/span&gt;
  &lt;span class="na"&gt;fontFamily&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Eczar"&lt;/span&gt;
  &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingLeft&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingRight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;backgroundInsetTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;backgroundInsetBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Tight Background"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Touching line backgrounds.&lt;/strong&gt; If you want the lines to join into one smooth vertical shape, combine &lt;code&gt;lineHeight&lt;/code&gt; with insets. Start with &lt;code&gt;lineHeight&lt;/code&gt; around &lt;code&gt;fontSize + 4&lt;/code&gt; to &lt;code&gt;fontSize + 8&lt;/code&gt;, then raise &lt;code&gt;backgroundInsetTop&lt;/code&gt; and &lt;code&gt;backgroundInsetBottom&lt;/code&gt; until the backgrounds touch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;HighlightTextView&lt;/span&gt;
  &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;lineHeight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingLeft&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingRight&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;paddingBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;backgroundInsetTop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;backgroundInsetBottom&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;highlightBorderRadius&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Multiple lines with touching backgrounds create smooth vertical flow"&lt;/span&gt;
&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Change fonts freely.&lt;/strong&gt; &lt;code&gt;fontFamily&lt;/code&gt;, &lt;code&gt;fontSize&lt;/code&gt; and &lt;code&gt;fontWeight&lt;/code&gt; can change at any time. The view re-measures and redraws the highlight. The old &lt;code&gt;key={fontFamily}&lt;/code&gt; remount trick from before 1.0 is no longer needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Open the keyboard on mount&lt;/strong&gt; with &lt;code&gt;autoFocus&lt;/code&gt;, which is handy for a "create story" screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/aqeelkhokhar/react-native-highlight-text" rel="noopener noreferrer"&gt;https://github.com/aqeelkhokhar/react-native-highlight-text&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;npm: &lt;a href="https://www.npmjs.com/package/react-native-highlight-text-view" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/react-native-highlight-text-view&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current version is 1.1.0, fully typed, MIT licensed. Clone the repo and run &lt;code&gt;yarn&lt;/code&gt; then &lt;code&gt;yarn example ios&lt;/code&gt; (or &lt;code&gt;yarn example android&lt;/code&gt;) to play with the story editor.&lt;/p&gt;

&lt;p&gt;If it saves you a weekend of fighting &lt;code&gt;backgroundColor&lt;/code&gt;, a star on GitHub helps other developers find it. And if something renders differently from what you expect on a font or device, open an issue with a screenshot. That kind of report is how the Android and iOS output got matched in 1.1.0.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>react</category>
      <category>mobile</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
