Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@fawazahmed/react-native-read-more

Package Overview
Dependencies
Maintainers
1
Versions
38
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@fawazahmed/react-native-read-more - npm Package Compare versions

Comparing version 2.0.3 to 2.1.0

524

example/src/ReadMore.js

@@ -11,9 +11,3 @@ import React, {memo, useState, useEffect, useCallback} from 'react';

} from 'react-native';
import {
childrenToTextChildren,
getText,
insertAt,
linesToCharacters,
childrenObjectsToChildren,
} from './helper';
import {getText, insertAt, linesToCharacters} from './helper';

@@ -42,3 +36,2 @@ if (Platform.OS === 'android') {

animate,
backgroundColor,
customTextComponent: TextComponent,

@@ -52,36 +45,28 @@ ellipsis,

debounceSeeMoreCalc,
preserveLinebreaks,
...restProps
}) => {
const [additionalProps, setAdditionalProps] = useState({});
// hiddenTextHeightOne comes from hidden component one
const [hiddenTextHeightOne, setHiddenTextHeightOne] = useState(0);
// hiddenTextHeightWithSeeLess comes from hidden component two
const [
hiddenTextHeightWithSeeLess,
setHiddenTextHeightWithSeeLess,
] = useState(0);
// hiddenTextLinesWithSeeLess comes from hidden component two
const [hiddenTextLinesWithSeeLess, setHiddenTextLinesWithSeeLess] = useState(
[],
);
// textHeight and textWidth comes from hidden component three
const [textHeight, setTextHeight] = useState(0);
const [textWidth, setTextWidth] = useState(0);
// lineOfImpact comes from hidden component four
const [lineOfImpact, setLineOfImpact] = useState({});
// const [lineOfImpact, setLineOfImpact] = useState({});
const [truncatedLineOfImpact, setTruncatedLineOfImpact] = useState('');
const [truncatedLineOfImpactWidth, setTruncatedLineOfImpactWidth] = useState(
0,
);
const [lines, setLines] = useState([]);
const [truncatedLineOfImpact, setTruncatedLineOfImpact] = useState('');
// eslint-disable-next-line prettier/prettier
const [truncatedLineOfImpactWidth, setTruncatedLineOfImpactWidth] = useState(0);
const [reconciledLineOfImpact, setReconciledLineOfImpact] = useState('');
// eslint-disable-next-line prettier/prettier
const [reconciledLineOfImpactWidth, setReconciledLineOfImpactWidth] = useState(0);
const [collapsedLines, setCollapsedLines] = useState([]);
const [seeMoreRightPadding, setSeeMoreRightPadding] = useState(0);
// mount or unmount hidden components
const [mountHiddenTextOne, setMountHiddenTextOne] = useState(true);
const [mountHiddenTextTwo, setMountHiddenTextTwo] = useState(true);
const [mountHiddenTextThree, setMountHiddenTextThree] = useState(true);
const [mountHiddenTextFour, setMountHiddenTextFour] = useState(true);
const [mountHiddenTextFive, setMountHiddenTextFive] = useState(false);
const [mountHiddenTextOne, setMountHiddenTextOne] = useState(false);
const [mountHiddenTextTwo, setMountHiddenTextTwo] = useState(false);
const [mountHiddenTextThree, setMountHiddenTextThree] = useState(false);
const [mountHiddenTextFour, setMountHiddenTextFour] = useState(false);
const [mountHiddenTextSix, setMountHiddenTextSix] = useState(false);
const [mountHiddenTextSeven, setMountHiddenTextSeven] = useState(false);
// initial measurement is in progress
const [isMeasuring, setIsMeasuring] = useState(true);
const [isMeasured, setIsMeasured] = useState(false);

@@ -93,10 +78,9 @@ // logic decisioning params

// copy of children with only text
const [collapsedChildren, setCollapsedChildren] = useState(
childrenToTextChildren(children, TextComponent, preserveLinebreaks),
);
const [measuredCollapsedChildren, setMeasuredCollapsedChildren] = useState(
null,
);
const [collapsedChildren, setCollapsedChildren] = useState(null);
const [reconciledLineOfImpact, setReconciledLineOfImpact] = useState('');
// eslint-disable-next-line prettier/prettier
const [reconciledLineOfImpactWidth, setReconciledLineOfImpactWidth] = useState(0);
// width of see more component
const [seeMoreWidth, setSeeMoreWidth] = useState(0);
const [hideEllipsis, setHideEllipsis] = useState(false);

@@ -114,27 +98,21 @@ const onSeeMoreViewLayout = useCallback(

const onLayoutHiddenTextSeven = useCallback(
({
nativeEvent: {
layout: {width},
},
}) => {
setMountHiddenTextSeven(false);
setReconciledLineOfImpactWidth(width);
const onTextLayoutOne = useCallback(
({nativeEvent: {lines: _lines}}) => {
setLines(_lines);
setMountHiddenTextOne(false);
setMountHiddenTextTwo(true);
},
[setReconciledLineOfImpactWidth, setMountHiddenTextSeven],
[setLines, setMountHiddenTextOne],
);
const onLayoutHiddenTextSix = useCallback(() => {
setMountHiddenTextSix(false);
}, [setMountHiddenTextSix]);
const onTextLayoutHiddenTextSix = useCallback(
const onTextLayoutTwo = useCallback(
({nativeEvent: {lines: _lines}}) => {
const _lineOfImpact = _lines[numberOfLines - 1];
setReconciledLineOfImpact(_lineOfImpact?.text || '');
setHiddenTextLinesWithSeeLess(_lines);
setMountHiddenTextTwo(false);
setMountHiddenTextFour(true);
},
[numberOfLines, setReconciledLineOfImpact],
[setHiddenTextLinesWithSeeLess, setMountHiddenTextTwo],
);
const onLayoutHiddenTextFive = useCallback(
const onLayoutActualTextComponent = useCallback(
({

@@ -145,56 +123,57 @@ nativeEvent: {

}) => {
setMountHiddenTextFive(false);
setTruncatedLineOfImpactWidth(width);
setTextWidth(width);
setMountHiddenTextFour(false);
if (Platform.OS === 'android') {
setMountHiddenTextSix(true);
}
},
[setTruncatedLineOfImpactWidth, setMountHiddenTextFive],
[setTextWidth],
);
const onTextLayoutHiddenTextFour = useCallback(
const onTextLayoutActualTextComponent = useCallback(
({nativeEvent: {lines: _lines}}) => {
const _lineOfImpact = _lines[numberOfLines - 1];
setLineOfImpact(_lineOfImpact);
setLines(_lines);
if (!collapsed) {
return;
}
setCollapsedLines(_lines);
},
[numberOfLines, setLineOfImpact, setLines],
[setCollapsedLines, collapsed],
);
const onLayoutHiddenTextFour = useCallback(() => {
setMountHiddenTextFour(false);
}, [setMountHiddenTextFour]);
const onLayoutHiddenTextThree = useCallback(
const onLayoutThree = useCallback(
({
nativeEvent: {
layout: {height, width},
layout: {width},
},
}) => {
setTextHeight(height);
setTextWidth(width);
setTruncatedLineOfImpactWidth(width);
setMountHiddenTextThree(false);
},
[setTextHeight, setTextWidth, setMountHiddenTextThree],
[setTruncatedLineOfImpactWidth, setMountHiddenTextThree],
);
const onHiddenTextLayoutOne = useCallback(
({
nativeEvent: {
layout: {height},
},
}) => {
setHiddenTextHeightOne(height);
setMountHiddenTextOne(false);
const onLayoutHiddenTextSix = useCallback(() => {
setMountHiddenTextSix(false);
setMountHiddenTextSeven(true);
}, [setMountHiddenTextSix, setMountHiddenTextSeven]);
const onTextLayoutHiddenTextSix = useCallback(
({nativeEvent: {lines: _lines}}) => {
const _lineOfImpact = _lines[numberOfLines - 1];
setReconciledLineOfImpact(_lineOfImpact?.text || '');
},
[setHiddenTextHeightOne, setMountHiddenTextOne],
[numberOfLines, setReconciledLineOfImpact],
);
const onHiddenSeeLessTextLayoutTwo = useCallback(
const onLayoutHiddenTextSeven = useCallback(
({
nativeEvent: {
layout: {height},
layout: {width},
},
}) => {
setHiddenTextHeightWithSeeLess(height);
setMountHiddenTextTwo(false);
setMountHiddenTextSeven(false);
setReconciledLineOfImpactWidth(width);
},
[setHiddenTextHeightWithSeeLess, setMountHiddenTextTwo],
[setReconciledLineOfImpactWidth, setMountHiddenTextSeven],
);

@@ -208,90 +187,146 @@

if (
!seeMore ||
!textWidth ||
!numberOfLines ||
!seeMoreWidth ||
!lineOfImpact?.text
numberOfLines < 1 ||
!lines.length ||
!collapsedLines.length ||
!seeMore
) {
setTruncatedLineOfImpact('');
setTruncatedLineOfImpactWidth(0);
return setMeasuredCollapsedChildren(null);
return;
}
// if line of impact
// use number fo lines - 1 lines with wrap text and clip ellipsis
// another text component with line of impact
// width will be total width - see more width
// show this ^^ on collapsed state
const linesTillImpact = Array(numberOfLines)
.fill({})
.map((_e, index) => lines[index]);
const charactersBeforeSeeMore = linesToCharacters(linesTillImpact);
const charactersLengthTillSeeMore = charactersBeforeSeeMore.trim().length;
const seeMoreTextLength =
`${ellipsis} ${seeMoreText}`.length + seeMoreOverlapCount;
// text break position for collapsed text
const textBreakPosition = charactersLengthTillSeeMore - seeMoreTextLength;
const trimmedLineOfImpact = lineOfImpact.text.trim();
const _truncatedLineOfImpact = trimmedLineOfImpact.substring(
0,
trimmedLineOfImpact.length - seeMoreTextLength,
);
setTruncatedLineOfImpact(_truncatedLineOfImpact);
// go to this position and insert a line break
let charactersToTraverse = textBreakPosition;
let nodeFound = false;
const modifiedChildrenObjects = getText(
children,
TextComponent,
preserveLinebreaks,
).map((_childObject) => {
if (nodeFound) {
return _childObject;
if (!lines[numberOfLines - 1] || !collapsedLines[numberOfLines - 1]) {
return;
}
// find line of impact
let _lineOfImpact = lines[numberOfLines - 1];
_lineOfImpact.index = numberOfLines - 1;
if (Platform.OS === 'ios') {
const modifiedIndex = lines.findIndex((_line, index) => {
if (index + 1 < numberOfLines - 1) {
return false;
}
return collapsedLines[numberOfLines - 1].text.includes(_line.text);
});
_lineOfImpact = lines[modifiedIndex];
_lineOfImpact.index = modifiedIndex;
}
const availableWidth = textWidth - seeMoreWidth;
// calculate how many characters to cut off if any
// trim right before -> spaces and \n
// width from line, textWidth, seeMoreWidth
// if no text after right trim
// hide ellipsis
// move see more to beginning
if (_lineOfImpact.text.trim().length === 0) {
_lineOfImpact.width = 0;
_lineOfImpact.text = '';
setHideEllipsis(true);
} else {
setHideEllipsis(false);
}
// todo
// right trim and width adjustment
// setLineOfImpact(_lineOfImpact);
if (_lineOfImpact.width < availableWidth) {
// if no need to cutoff, simply calculate see more right padding
const _seeMoreRightPadding =
textWidth - _lineOfImpact.width - seeMoreWidth;
if (_seeMoreRightPadding > 0) {
setTruncatedLineOfImpact('');
setTruncatedLineOfImpactWidth(0);
setReconciledLineOfImpact('');
setReconciledLineOfImpactWidth(0);
setSeeMoreRightPadding(_seeMoreRightPadding);
// todo: remove this
if (animate) {
LayoutAnimation.configureNext(readmoreAnimation);
}
}
if (_childObject.content.length > charactersToTraverse) {
// this node is the one
nodeFound = true;
const childContent = insertAt(
_childObject.content,
'\n',
charactersToTraverse,
);
return {
type: _childObject?.type,
content: childContent,
child:
_childObject?.type === 'string'
? childContent
: React.cloneElement(
_childObject,
_childObject.props,
childContent,
),
};
} else {
// todo
// determine point, traverse through nodes
// create collapsed children with spaces at the point
const seeMoreTextLength =
`${ellipsis} ${seeMoreText}`.length + seeMoreOverlapCount;
const linesTillImpact = Array(_lineOfImpact.index + 1)
.fill({})
.map((_e, index) => lines[index]);
const charactersBeforeSeeMore = linesToCharacters(linesTillImpact);
const charactersLengthTillSeeMore = charactersBeforeSeeMore.length;
// text break position for collapsed text
const textBreakPosition = charactersLengthTillSeeMore - seeMoreTextLength;
const _truncatedText = _lineOfImpact.text.substr(
0,
_lineOfImpact.text.length - seeMoreTextLength,
);
if (truncatedLineOfImpact !== _truncatedText) {
setTruncatedLineOfImpact(_truncatedText);
}
charactersToTraverse = charactersToTraverse - _childObject.content.length;
return _childObject;
});
// go to this position and insert spaces
let charactersToTraverse = textBreakPosition;
let nodeFound = false;
const modifiedChildrenObjects = getText(children, TextComponent, true)
?.map((_childObject) => {
if (nodeFound) {
return _childObject;
}
if (_childObject.content.length > charactersToTraverse) {
// this node is the one
nodeFound = true;
const childContent = insertAt(
_childObject.content,
'\n',
charactersToTraverse,
);
return {
type: _childObject?.type,
content: childContent,
child:
_childObject?.type === 'string'
? childContent
: React.cloneElement(
_childObject,
_childObject.props,
childContent,
),
};
}
charactersToTraverse =
charactersToTraverse - _childObject.content.length;
if (nodeFound) {
return setMeasuredCollapsedChildren(
childrenObjectsToChildren(modifiedChildrenObjects),
);
return _childObject;
})
?.map((_updatedObjects) => {
return _updatedObjects.child;
});
if (nodeFound) {
setCollapsedChildren(modifiedChildrenObjects);
}
}
return setMeasuredCollapsedChildren(null);
setIsMeasured(true);
}, [
children,
TextComponent,
textWidth,
numberOfLines,
lines,
collapsedLines,
seeMore,
textWidth,
seeMoreWidth,
lineOfImpact,
lines,
animate,
ellipsis,
seeMoreText,
seeMoreOverlapCount,
preserveLinebreaks,
truncatedLineOfImpact,
children,
TextComponent,
]);

@@ -322,8 +357,10 @@

const seeMoreBackgroundStyle =
isMeasuring || lineOfImpact?.text ? {} : {backgroundColor};
const seeMoreTextHidingStyle = isMeasured ? {} : {color: 'transparent'};
// use after measured here
const seeMoreTextHidingStyle = !isMeasured
? {color: 'transparent'}
: {
backgroundColor: 'transparent',
};
const seeMoreContainerStyle = [
styles.seeMoreContainer,
seeMoreBackgroundStyle,
{

@@ -335,9 +372,5 @@ marginRight: seeMoreRightPadding,

useEffect(() => {
if (!hiddenTextHeightOne || !textHeight) {
return;
}
setSeeMore(lines.length > numberOfLines);
}, [numberOfLines, lines]);
setSeeMore(hiddenTextHeightOne > textHeight);
}, [textHeight, hiddenTextHeightOne]);
useEffect(() => {

@@ -361,5 +394,2 @@ if (collapsed === afterCollapsed) {

setMountHiddenTextOne(true);
setMountHiddenTextTwo(true);
setMountHiddenTextThree(true);
setMountHiddenTextFour(true);
}, debounceSeeMoreCalc);

@@ -382,27 +412,2 @@ return () => clearTimeout(handle);

useEffect(() => {
const checkIfStillMeasuring = () => {
if (
!mountHiddenTextOne &&
!mountHiddenTextTwo &&
!mountHiddenTextThree &&
!mountHiddenTextFour
) {
setIsMeasuring(false);
if (animate) {
LayoutAnimation.configureNext(readmoreAnimation);
}
}
};
const handler = setTimeout(checkIfStillMeasuring, debounceSeeMoreCalc);
return () => clearTimeout(handler);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
mountHiddenTextOne,
mountHiddenTextTwo,
mountHiddenTextThree,
mountHiddenTextFour,
]);
// a map of additional props to be passed down

@@ -423,18 +428,19 @@ // in hidden text components other than style

useEffect(() => {
if (mountHiddenTextOne || mountHiddenTextTwo || mountHiddenTextFour) {
return;
}
const handle = setTimeout(measureSeeMoreLine, debounceSeeMoreCalc);
return () => clearTimeout(handle);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [measureSeeMoreLine]);
}, [
lines,
numberOfLines,
collapsedLines,
seeMore,
mountHiddenTextOne,
mountHiddenTextTwo,
mountHiddenTextFour,
]);
useEffect(() => {
const _textChildren = childrenToTextChildren(
children,
TextComponent,
preserveLinebreaks,
);
setCollapsedChildren(_textChildren);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [children]);
useEffect(() => {
if (!truncatedLineOfImpact) {

@@ -444,39 +450,16 @@ return;

setMountHiddenTextFive(true);
setMountHiddenTextThree(true);
}, [truncatedLineOfImpact]);
useEffect(() => {
if (!truncatedLineOfImpactWidth || !seeMoreWidth || !textWidth) {
setSeeMoreRightPadding(0);
if (!truncatedLineOfImpactWidth) {
return;
}
const _seeMoreRightPadding =
textWidth - truncatedLineOfImpactWidth - seeMoreWidth;
if (_seeMoreRightPadding > 0) {
setSeeMoreRightPadding(_seeMoreRightPadding);
if (animate) {
LayoutAnimation.configureNext(readmoreAnimation);
}
}
const padding = textWidth - truncatedLineOfImpactWidth - seeMoreWidth;
setSeeMoreRightPadding(padding);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [truncatedLineOfImpactWidth, seeMoreWidth, textWidth]);
}, [truncatedLineOfImpactWidth]);
useEffect(() => {
if (!measuredCollapsedChildren) {
return;
}
// start reconciliation
setMountHiddenTextSix(true);
}, [measuredCollapsedChildren]);
useEffect(() => {
if (!reconciledLineOfImpact) {
return;
}
setMountHiddenTextSeven(true);
}, [reconciledLineOfImpact]);
useEffect(() => {
if (!reconciledLineOfImpactWidth || !seeMoreWidth || !textWidth) {

@@ -497,33 +480,17 @@ // setSeeMoreRightPadding(0);

useEffect(() => {
if (isMeasuring) {
return;
}
const handle = setTimeout(() => {
setIsMeasured(!isMeasuring);
if (animate) {
LayoutAnimation.configureNext(readmoreAnimation);
}
}, debounceSeeMoreCalc);
return () => clearTimeout(handle);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isMeasuring]);
return (
<View style={wrapperStyle}>
{/* text component to measure see if see more is applicable and get height */}
{/* text component to measure see if see more is applicable and get lines */}
{mountHiddenTextOne && (
<TextComponent
{...commonHiddenComponentProps}
ellipsizeMode={'clip'}
onLayout={onHiddenTextLayoutOne}>
onTextLayout={onTextLayoutOne}>
{children || ''}
</TextComponent>
)}
{/* text component to measure height with see less */}
{/* text component to measure lines with see less */}
{mountHiddenTextTwo && (
<TextComponent
{...commonHiddenComponentProps}
onLayout={onHiddenSeeLessTextLayoutTwo}>
onTextLayout={onTextLayoutTwo}>
{children || ''}

@@ -534,31 +501,20 @@ {/* 3 spaces before see less are intentional */}

)}
{/* to remove all flickers add another hidden component with collapsed children to get seeMore and all hidden components to use collapsed children only */}
{/* extract width of line of impact without see more line */}
{mountHiddenTextThree && (
<TextComponent
{...commonHiddenComponentProps}
numberOfLines={numberOfLines}
onLayout={onLayoutHiddenTextThree}>
{collapsedChildren || ''}
{/* no see less here since it's in collapsed state replicating original component */}
{...hiddenComponentPropsLineOfImpact}
onLayout={onLayoutThree}>
{truncatedLineOfImpact}
</TextComponent>
)}
{/* extract line of impact -> see more line */}
{mountHiddenTextFour && (
<TextComponent
{...commonHiddenComponentProps}
numberOfLines={numberOfLines + 1}
onLayout={onLayoutHiddenTextFour}
onTextLayout={onTextLayoutHiddenTextFour}>
{collapsedChildren || ''}
{/* no see less here since it's in collapsed state replicating original component */}
numberOfLines={numberOfLines}
ellipsizeMode={'clip'}
onLayout={onLayoutActualTextComponent}
onTextLayout={onTextLayoutActualTextComponent}>
{children || ''}
</TextComponent>
)}
{/* extract width of line of impact without see more line */}
{mountHiddenTextFive && (
<TextComponent
{...hiddenComponentPropsLineOfImpact}
onLayout={onLayoutHiddenTextFive}>
{truncatedLineOfImpact}
</TextComponent>
)}
{/* extract line of impact with measured children */}

@@ -571,3 +527,3 @@ {mountHiddenTextSix && (

onTextLayout={onTextLayoutHiddenTextSix}>
{measuredCollapsedChildren || ''}
{collapsedChildren || ''}
{/* no see less here since it's in collapsed state replicating original component */}

@@ -590,4 +546,4 @@ </TextComponent>

{...textProps}>
{isMeasuring || (seeMore && collapsed)
? measuredCollapsedChildren || collapsedChildren || ''
{seeMore && collapsed
? collapsedChildren || children || ''
: children || ''}

@@ -600,3 +556,3 @@ {seeMore && !collapsed && !expandOnly && (

style={seeLessStyle}>
{hiddenTextHeightWithSeeLess > hiddenTextHeightOne ? '\n' : ' '}
{hiddenTextLinesWithSeeLess.length > lines.length ? '\n' : ' '}
{seeLessText}

@@ -610,7 +566,8 @@ </TextComponent>

<TextComponent
key={`${isMeasured}`}
{...additionalProps}
{...restProps}
onPress={toggle}
style={style}>
{`${ellipsis}`}
style={[style, seeMoreTextHidingStyle]}>
{`${hideEllipsis ? '' : ellipsis}`}
</TextComponent>

@@ -623,2 +580,3 @@ <TextComponent

{` ${seeMoreText}`}
{hideEllipsis ? ' ' : ''}
</TextComponent>

@@ -681,3 +639,2 @@ </View>

animate: PropTypes.bool,
backgroundColor: PropTypes.string,
customTextComponent: PropTypes.oneOfType([

@@ -695,3 +652,2 @@ PropTypes.node,

debounceSeeMoreCalc: PropTypes.number,
preserveLinebreaks: PropTypes.bool,
};

@@ -709,3 +665,2 @@

animate: true,
backgroundColor: 'white',
customTextComponent: Text,

@@ -718,3 +673,2 @@ ellipsis: '...',

debounceSeeMoreCalc: 300,
preserveLinebreaks: false,
allowFontScaling: Platform.select({

@@ -721,0 +675,0 @@ android: false,

{
"name": "@fawazahmed/react-native-read-more",
"version": "2.0.3",
"version": "2.1.0",
"description": "A simple react native library to show large blocks of text in a condensed manner with the ability to collapse and expand.",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -73,3 +73,3 @@ ![NPM Downloads](https://img.shields.io/npm/dw/@fawazahmed/react-native-read-more) ![NPM License](https://img.shields.io/npm/l/@fawazahmed/react-native-read-more) ![NPM Version](https://img.shields.io/npm/v/@fawazahmed/react-native-read-more)

| `animate` | `bool` | no | defaults to `true` => applies a subtle animation to see more and see less text, not the complete text itself
| `backgroundColor` | `string` | no | defaults to `white` => supply `backgroundColor` if your background color is something other than white
| `backgroundColor` | `string` | no | (deprecated) defaults to `white` => supply `backgroundColor` if your background color is something other than white
| `customTextComponent` | `React component` | no | defaults to `Text`

@@ -79,3 +79,3 @@ | `expandOnly` | `bool` | no | defaults to `false` => hide see less option similar to a linkedIn post

| `onCollapse` | `func` | no | optional callback executed when collapsed
| `preserveLinebreaks` | `bool` | no | defaults to `false` => preserves `\n` in the content while in the collapsed state. This prop is in experimental stage.
| `preserveLinebreaks` | `bool` | no | (deprecated) defaults to `false` => preserves `\n` in the content while in the collapsed state. This prop is in experimental stage.

@@ -82,0 +82,0 @@ Any additional props are passed down to underlying `Text` component.

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc