skip to Main Content

I want a wrapped text that ends with an image icon, and tried the following.

    <Text>
        <Text
            numberOfLines={2}
            ellipsizeMode="tail"
            >
            Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ab quasi in dolor dolore recusandae ullam numquam labore sunt illo. Repellat in sed sit, pariatur voluptate distinctio! Perspiciatis inventore pariatur incidunt.
        </Text>
        <Image source={source} />
    </Text>

The outer wrapper <Text /> is to ensure that the <Image /> icon stays inline with the text.

I was hoping it would look like below:

    Lorem, ipsum dolor sit amet consectetur adipisicing elit.
    Ab quasi in dolor dolore recusandae ullam... <Image />

However, adding the outer <Text /> seems to have removed the effect of numberOfLines and I get the full text instead:

    Lorem, ipsum dolor sit amet consectetur adipisicing elit.
    Ab quasi in dolor dolore recusandae ullam numquam labore
    sunt illo. Repellat in sed sit, pariatur voluptate
    distinctio! Perspiciatis inventore pariatur incidunt. <Image />

Is it possible to achieve both the truncation via numberOfLines and the inline <Image /> at the end?

Thanks,

2

Answers


  1. you can use view component in order to solve the issue

     <View style={{ flexDirection: 'row', alignItems: 'center' }}>
            <Text numberOfLines={2} ellipsizeMode="tail" style={{ flex: 1 }}>
              Lorem, ipsum dolor sit amet consectetur adipisicing elit. Ab quasi in
              dolor dolore recusandae ullam numquam labore sunt illo. Repellat in
              sed sit, pariatur voluptate distinctio! Perspiciatis inventore
              pariatur incidunt.
            </Text>
            <Image source={require('./assets/snack-icon.png')} />
          </View>
    
    Login or Signup to reply.
  2. I have created an example:

    import React, { useState } from 'react';
    import {
      TextLayoutLine,
      Text,
      TextStyle,
      StyleProp,
      TextProps,
      Platform,
    } from 'react-native';
    
    export interface IReadMoreTextProps extends TextProps {
      style?: StyleProp<TextStyle>;
      numberOfLines?: number;
      children: string;
      appendComponent?: JSX.Element;
    }
    
    interface TextProperties {
      length: number;
      isTruncatedText: boolean;
    }
    
    export function TextInlneImage({
      style,
      numberOfLines = 1,
      children,
      appendComponent,
      ...props
    }: IReadMoreTextProps) {
      const [text, setText] = useState<TextProperties>({
        length: 0,
        isTruncatedText: false,
      });
    
      function handleOnTextLayout(textLayoutLines: TextLayoutLine[]) {
        let textLength = 0;
        if (textLayoutLines.length > numberOfLines) {
          for (var line = 0; line < numberOfLines; line++) {
            textLength += textLayoutLines[line].text.length;
          }
          setText({ length: textLength, isTruncatedText: true });
          return;
        }
        setText({ length: children.length, isTruncatedText: false });
      }
    
      return (
        <>
          {/** 
            iOS requires element to be drawn for getting needed lines
           */}
          {Platform.OS === 'ios' && (
            <Text
              style={{ height: 0 }}
              onTextLayout={({ nativeEvent: { lines } }) => {
                if (text.length > 0) {
                  return;
                }
                handleOnTextLayout(lines);
              }}>
              {children}
            </Text>
          )}
          <Text
            style={style}
            numberOfLines={text.length === 0 ? numberOfLines : 0}
            onTextLayout={({ nativeEvent: { lines } }) => {
              if (text.length > 0) {
                return;
              }
              handleOnTextLayout(lines);
            }}
            {...props}>
            {text.isTruncatedText &&
            props.ellipsizeMode === 'tail' &&
            text.length !== 0
              ? `${children.slice(0, text.length - 20).trim()}...`
              : children}
            {text.isTruncatedText && <Text style={style}>{appendComponent}</Text>}
          </Text>
        </>
      );
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search