Implementing inline display in React Native emulator

React Native does not support the CSS display property, so all elements default to using display: flex (without inline-flex support either). While most non-flex layouts can be mimicked with flex properties, working with inline text can be tricky.

In my app, I have a container that holds multiple words of text, some of which require special formatting. This means I have to use spans for styling purposes. If I want the spans to wrap properly, I can try setting the container's flex-wrap: wrap, but this only allows wrapping at the end of a span instead of the traditional behavior of wrapping at word breaks.

Here is a visual representation of the problem (spans highlighted in yellow):

https://i.sstatic.net/CgR94.png

(source: http://codepen.io/anon/pen/GoWmdm?editors=110)

Is there a way to achieve proper wrapping and true inline simulation using flex properties?

Answer №1

To achieve this desired effect, you can create nested text elements similar to how you would nest a span within a div or another element:

<View>
  <Text><Text>This content will occupy most of the container</Text><Text>This content will also occupy most of the container</Text></Text>       
</View>

Another method to obtain this effect is by setting the parent's flexDirection to 'row' and flexWrap to 'wrap'. This will cause the children to display in-line:

<View style={{flexDirection:'row', flexWrap:'wrap'}}>
  <Text>one</Text><Text>two</Text><Text>Three</Text><Text>Four</Text><Text>Five</Text>
</View>

Take a look at an example here.

For more information, visit .

Answer №2

To achieve the desired effect, you can nest text nodes without relying on flex properties. For example, check out this link: https://facebook.github.io/react-native/docs/text

<Text style={{fontWeight: 'bold'}}>
  I am bold
  <Text style={{color: 'red'}}>
    and red
  </Text>
</Text>

Answer №3

Struggling to seamlessly integrate text blocks with other content? Our makeshift solution involves breaking down each word in a text string into individual blocks to ensure proper wrapping with flexWrap.

Answer №4

Give this a try for a simple and polished look.

<Text style={{ fontFamily: 'CUSTOM_FONT', ... }}>
   <Text>Lorem ipsum</Text>
   <Text style={{ color: "red" }}>&nbsp;dolor sit amet.</Text>
</Text>

Outcome:

Lorem ipsum dolor sit amet.

Answer №5

My use case was quite specific:

I required a text element that could wrap with varying sizes, and within this text, I needed to emphasize certain words by underlining them (to signify that they are clickable).

The solution seemed simple at first, except for the fact that I couldn't control the underline's appearance in any way (distance from the text, color, etc.). This prompted me to dive deep into finding a solution, which eventually led to the idea of splitting each word, wrapping it in separate Text components, enclosed within View elements.

Here is the simplified code snippet:



import React from 'react';
import { StyleSheet, View, TouchableOpacity, Text } from 'react-native';
import Colors from '../../styles/Colors';
import Fonts from '../../styles/Fonts';

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
});

export default class SaltText extends React.Component {

  getTheme (type) {

    if (type === 'robomonoregular10gray') {
      return {
          fontSize: Fonts.SIZES.TEN,
          fontFamily: Fonts.ROBOTOMONO_REGULAR,
          color: Colors.getColorOpacity(Colors.GRAY, 70),
          lineHeight: Fonts.SIZES.TEN + 10
      };
    }

    throw new Error('not supported');
  }

  splitText (text) {
    const parts = [];
    const maps = [];

    let currentPart = '';
    let matchIndex = 0;

    for (const letter of text) {

      const isOpening = letter === '[';
      const isClosing = letter === ']';

      if (!isOpening && !isClosing) {
        currentPart += letter;
        continue;
      }

      if (isOpening) {
        parts.push(currentPart);
        currentPart = '';
      }

      if (isClosing) {
        parts.push(`[${matchIndex}]`);
        maps.push(currentPart);
        currentPart = '';
        matchIndex++;
      }
    }

    const partsModified = [];
    for (const part of parts) {
      const splitted = part
        .split(' ')
        .filter(f => f.length);

      partsModified.push(...splitted);
    }

    return { parts: partsModified, maps };
  }

  render () {

    const textProps = this.getTheme(this.props.type);
    const children = this.props.children;

    const getTextStyle = () => {
      return {
        ...textProps,
      };
    };

    const getTextUnderlineStyle = () => {
      return {
        ...textProps,
        borderBottomWidth: 1,
        borderColor: textProps.color
      };
    };

    const getViewStyle = () => {
      return {
        flexDirection: 'row',
        flexWrap: 'wrap',
      };
    };

    const { parts, maps } = this.splitText(children);

    return (
      <View style={getViewStyle()}>
        {parts.map((part, index) => {

          const key = `${part}_${index}`;
          const isLast = parts.length === index + 1;

          if (part[0] === '[') {
            const mapIndex = part.substring(1, part.length - 1);
            const val = maps[mapIndex];
            const onPressHandler = () => {
              this.props.onPress(parseInt(mapIndex, 10));
            };
            return (
              <View key={key} style={getTextUnderlineStyle()}>
                <Text style={getTextStyle()} onPress={() => onPressHandler()}>
                  {val}{isLast ? '' : ' '}
                </Text>
              </View>
            );
          }

          return (
            <Text key={key} style={getTextStyle()}>
              {part}{isLast ? '' : ' '}
            </Text>
          );
        })}
      </View>
    );
  }
}

And here is an example of how you can use this component:

  renderPrivacy () {

    const openTermsOfService = () => {
      Linking.openURL('https://myterms.com');
    };

    const openPrivacyPolicy = () => {
      Linking.openURL('https://mypolicy.com');
    };

    const onUrlClick = (index) => {
      if (index === 0) {
        openTermsOfService();
      }

      if (index === 1) {
        openPrivacyPolicy();
      }
    };

    return (
      <SaltText type="robomonoregular10gray" onPress={(index) => onUrlClick(index)}>
        By tapping "Create an account" or "Continue", I agree to [Terms of Service] and [Privacy Policy]
      </SaltText>
    );
  }

This implementation results in the following output:

https://i.sstatic.net/CWDIb.png

Answer №6

If you have a large amount of text to display (as I do), you can try approaching it like this. It may not be the most aesthetically pleasing solution, but it gets the job done.

  const words =  text.split(' ');
  return (
    <React.Fragment>
      {words.map((word) => (
        <Text key={word} className="pr-1">
          {word}
        </Text>
      ))}
    </React.Fragment>
  );

I'm utilizing nativewind for styling purposes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using ReactJS, Document.ready functions are essential for initializing the application

Exploring ReactJS for the first time, working on a project and encountering a challenge. I've created an app with a user authentication feature. Once the user logs in, they should be able to access a slide-up navigation menu that is controlled by ex ...

Is there a way to change the color of a Material-UI snackbar without creating a new one for each color?

Is there a way to change the color of a snackbar in material-ui without creating a new one for each color? It seems that the example sandbox only has one color, while the others are static. ...

Guide to running several versions of a single Next JS application with distinct configurations simultaneously on a shared server

My goal is to run 2 instances of the NextJS app on the same machine with different configurations and ports. The first instance runs on port 3000, while the second runs on port 3001, and this setup functions correctly with the commands: next dev next de ...

The div element on my website spans the entire width, yet it appears slightly narrower than the body

My website features a scrolling div element that spans 100% of the screen, but I am encountering an issue with slight horizontal scrolling and the background image extending beyond the visible area. I am striving to adjust the width of the div so that it ...

Using React-Native for FTP Integration

Has anyone successfully managed to download/upload files and folders from FTP servers using react native? I tried using the react-native-ftp package but it doesn't seem to work. If you've faced a similar scenario, please share your insights! ...

It seems that you're facing an issue with the react-native-git-upgrade tool. The error message

I encountered issues while attempting to upgrade using react-native-git-upgrade. One of the first problems I faced was similar to what was described in https://github.com/facebook/react-native/issues/11578. Unfortunately, none of the solutions mentioned i ...

Alter the color of a hyperlink when it is hovered over

Looking to create a menu with links and descriptive paragraphs that change color when hovered over. Preferably done with CSS only, without the use of JS or jQuery. For example: <a class="title" href="page1.html">Page 1</a> <hr/> & ...

Using CSS to duplicate images in multiple repetitions horizontally

In the process of developing a UHD project that involves showcasing large images, I have encountered limitations with iOS and certain mobile browsers. While stationary browsers pose no issue, iOS only supports PNG images up to 5 megapixels in resolution, w ...

Error: The function `setSate` is not defined. Should I use `bind(this)` or another method? If using `bind(this)`, where should it

Every time the hamburger button is clicked, a function is executed to open a side drawer. "TypeError: this.setSate is not a function." It seems like this error may be related to an update that requires binding 'this', but I'm uncertain. I h ...

Does the useEffect function run before the component is rendered?

export default function ExampleComponent() { useEffect(()=>{ console.log('DOM has not rendered anything yet') }); return ( <div> Hello </div> ); } After analyzing the above code, ...

The command "npm start" fails to execute on Windows operating systems

After using npx create-react-app to create my application, I encountered an issue where running npm start would do nothing and exit with code 0. When I try to run the npm start command, I receive the following message: C:\projects\novo-curricul ...

Tips for decreasing the placeholder font size within a mobile media query

I'm encountering a strange issue. I successfully managed to decrease the font size of the placeholder text for my desktop design, but it's not working for my mobile phone media query. I started with the desktop version and used a max width of 480 ...

How to align content within a FormControlLabel using Material UI

My goal is to line up the label and radio button inside a FormControlLabel component so that the label occupies the same width regardless of its content. The current appearance can be seen below: https://i.stack.imgur.com/GhXed.png Below is the code I am ...

Sub-menu disappears upon resizing the screen

Currently, I am working on creating a unique responsive navigation system that transforms into a 100% width pulldown menu for mobile devices. To achieve this functionality, I have implemented some JavaScript code that hides any open sub-menu items when the ...

Unique text: "Transformative custom checkboxes featuring checkboxes placed underneath descriptive

I am attempting to create custom inline checkboxes where the text is aligned above the checkbox. The goal is to have the checkbox horizontally centered compared to the text, resembling this example: https://i.sstatic.net/GkYVI.png My initial approach inv ...

aligning divs in a horizontal distribution is ineffective when the divs become fixed in place

When distributing divs horizontally equally, issues arise when these elements are attached without spaces in between (particularly in Chrome and Firefox). For instance: http://jsfiddle.net/pdelorme/au9ouko0/ HTML : <div class="ul"> <div class=" ...

Updating static files in Django seems to be a bit tricky since clearing the browser cache does not seem to have any effect

I encountered an issue with my Django & React application. While trying to update the appearance of a component, I noticed that Django did not reflect the changes upon refreshing. I attempted to force refresh the page and clear the browser cache without s ...

What is the best way to adjust the height and width of a div when it comes into view through scrolling?

How can I automatically and frequently change the size of my div when it is scrolled into view? HTML <div id="contact" class="fadeInBlock"> <div class="map"> <div class="pointer"> <div class="dot"></div& ...

Ways to address the issue with the Promise object showing as <pending>

I recently started using next JS and I'm facing an issue where my data is not getting displayed on a specific route. Can someone please help me understand why this is happening? Feel free to ask if you have any questions about my query. https://i.sst ...

Tips for maintaining the footer at the bottom of the page regardless of the screen size

In my current project, I am dealing with several web pages. For each page, I have arranged three div tags: Header Body (content) Footer The issue arises when it comes to the body div tag, which houses the main content of a page such as forms and descrip ...