Skip to content

Commit

Permalink
Merge pull request #56 from fawaz-ahmed/lib-update
Browse files Browse the repository at this point in the history
update lib to deal with nested View to 1 level, update readme, update…
  • Loading branch information
fawaz-ahmed authored Feb 21, 2022
2 parents 96b35ec + 248c49e commit 5c040f8
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 56 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@ export default Home;
| `onExpand` | `func` | no | optional callback executed when expanded
| `onCollapse` | `func` | no | optional callback executed when collapsed
| `onReady` | `func` | no | optional callback executed when see more placement measurements are completed
| `seeMoreContainerStyleSecondary` | `object` | no | Incase of text overlap, pass { position: 'relative' } see [issue](https://github.com/fawaz-ahmed/react-native-read-more/issues/52)
| `seeMoreContainerStyleSecondary` | `object` | no | Incase of text overlap, pass { position: 'relative' } see [issue](https://github.com/fawaz-ahmed/react-native-read-more/issues/52) (not recommended)

Any additional props are passed down to underlying `Text` component.

# Usage with HTML
HTML rendering is not part of this package, but can be done easily with the help of any custom html to text library. For sample code, refer to this [issue](https://github.com/fawaz-ahmed/react-native-read-more/issues/55#issuecomment-1046941770)

# Run example
```
git clone https://github.com/fawaz-ahmed/react-native-read-more.git
Expand All @@ -93,13 +96,14 @@ yarn android
```

# Why another library ?
This module will calculate where to position `See more` and `See less` within the same paragraph instead of occupying another line. It is a drop-in replacement for `Text` component and you can control when to apply the see more functionality by configuring the `numberOfLines` prop. Moreover, you can also pass your own custom implementation of `Text` component like `ParsedText` etc.
This module will calculate where to position `See more` and `See less` within the same paragraph instead of occupying another line. It is a drop-in replacement for `Text` component and you can control when to apply the see more functionality by configuring the `numberOfLines` prop. Moreover, you can also pass your own custom implementation of `Text` component like `ParsedText` ([sample code](https://github.com/fawaz-ahmed/react-native-read-more/issues/37#issuecomment-1047029209)) etc.

## Seeing issues or any feedback or feature suggest ?
Create an [issue](https://github.com/fawaz-ahmed/react-native-read-more/issues) with github.

## Troubleshooting
- If you observe `See more` shown always in android, pass prop `allowFontScaling={false}`, refer to this [issue](https://github.com/fawaz-ahmed/react-native-read-more/issues/17)
- If you have any nested components other than `Text`, refer to this [issue](https://github.com/fawaz-ahmed/react-native-read-more/issues/52)

### jest - running unit tests
This package is not transpiled. So inorder for your test cases to work, this package should be transpiled by babel. For this you need to add this path `!node_modules/@fawazahmed/react-native-read-more/` under `transformIgnorePatterns` option provided by `jest`. In your `package.json` you will see this `jest` config:
Expand Down
13 changes: 4 additions & 9 deletions example/src/ReadMore.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {
LayoutAnimation,
Platform,
UIManager,
TextPropTypes,
} from 'react-native';
import {getText, insertAt, linesToCharacters} from './helper';
import {getTextByChildren, insertAt, linesToCharacters} from './helper';

if (Platform.OS === 'android') {
if (UIManager.setLayoutAnimationEnabledExperimental) {
Expand Down Expand Up @@ -298,7 +299,7 @@ const ReadMore = ({
// go to this position and insert \n
let charactersToTraverse = textBreakPosition;
let nodeFound = false;
const modifiedChildrenObjects = getText(children, TextComponent, true)
const modifiedChildrenObjects = getTextByChildren(children, TextComponent)
?.map(_childObject => {
if (nodeFound) {
return _childObject;
Expand Down Expand Up @@ -671,12 +672,10 @@ const styles = StyleSheet.create({
});

ReadMore.propTypes = {
style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
...TextPropTypes,
seeMoreStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
seeLessStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
wrapperStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
children: PropTypes.any,
numberOfLines: PropTypes.number,
seeMoreText: PropTypes.string,
seeLessText: PropTypes.string,
animate: PropTypes.bool,
Expand All @@ -686,14 +685,11 @@ ReadMore.propTypes = {
PropTypes.elementType,
]),
ellipsis: PropTypes.string,
allowFontScaling: PropTypes.bool,
onExpand: PropTypes.func,
onCollapse: PropTypes.func,
expandOnly: PropTypes.bool,
seeMoreOverlapCount: PropTypes.number,
debounceSeeMoreCalc: PropTypes.number,
onLayout: PropTypes.func,
onTextLayout: PropTypes.func,
onReady: PropTypes.func,
seeMoreContainerStyleSecondary: PropTypes.object,
};
Expand All @@ -703,7 +699,6 @@ ReadMore.defaultProps = {
seeMoreStyle: StyleSheet.flatten([styles.defaultText, styles.seeMoreText]),
seeLessStyle: StyleSheet.flatten([styles.defaultText, styles.seeLessText]),
wrapperStyle: styles.container,
text: '',
numberOfLines: 3,
seeMoreText: 'See more',
seeLessText: 'See less',
Expand Down
53 changes: 17 additions & 36 deletions example/src/helper.js
Original file line number Diff line number Diff line change
@@ -1,70 +1,51 @@
import React from 'react';

const getStringChild = (child, preserveLinebreaks = false) => {
const content = preserveLinebreaks ? child : child?.split('\n').join(' ');
const getStringChild = child => {
return {
type: 'string',
content,
child: content,
content: child,
child,
};
};

const getTextChild = (child, preserveLinebreaks = false) => {
const content = preserveLinebreaks
? child.props.children
: child.props.children?.split('\n').join(' ');
const getTextChild = child => {
return {
type: child?.type?.displayName,
content,
child: React.cloneElement(child, child.props, content),
content: child.props.children,
child: React.cloneElement(child, child.props, child.props.children),
};
};

export const getText = (children, TextComponent, preserveLinebreaks) => {
export const getTextByChildren = (children, TextComponent) => {
if (typeof children === 'string') {
return [getStringChild(children, preserveLinebreaks)];
return [getStringChild(children)];
}

if (typeof children === 'object' && children.props?.children) {
return getTextByChildren(React.Children.toArray(children.props.children));
}

if (Array.isArray(children)) {
return children
.filter((_child) => {
.filter(_child => {
return (
typeof _child === 'string' ||
_child?.type?.displayName === TextComponent?.displayName
);
})
.map((_child) => {
.map(_child => {
if (typeof _child === 'string') {
return getStringChild(_child, preserveLinebreaks);
return getStringChild(_child);
}

return getTextChild(_child);
});
}

return null;
};

export const childrenToText = (children, TextComponent, preserveLinebreaks) => {
const _textChildren = getText(children, TextComponent, preserveLinebreaks);
return _textChildren.map((_t) => _t.content).join(' ');
};

export const childrenToTextChildren = (
children,
TextComponent,
preserveLinebreaks,
) => {
const _textChildren = getText(children, TextComponent, preserveLinebreaks);
return _textChildren.map((_t) => _t.child);
};

export const childrenObjectsToChildren = (childrenObjects) => {
return childrenObjects.map((_t) => _t.child);
};

export const linesToCharacters = (lines) => {
return lines.map((_line) => _line?.text || '').join('');
export const linesToCharacters = lines => {
return lines.map(_line => _line?.text || '').join('');
};

export const insertAt = (str, sub, pos) =>
Expand Down
10 changes: 2 additions & 8 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import React from 'react';
import { StyleProp, TextStyle, ViewStyle, LayoutChangeEvent, NativeSyntheticEvent, TextLayoutEventData } from 'react-native';
import { StyleProp, TextStyle, ViewStyle, TextProps } from 'react-native';

export interface ReadMoreProps {
style?: StyleProp<TextStyle>;
export interface ReadMoreProps extends TextProps {
seeMoreStyle?: StyleProp<TextStyle>;
seeLessStyle?: StyleProp<TextStyle>;
wrapperStyle?: StyleProp<ViewStyle>;
children?: React.ReactNode;
numberOfLines?: number;
seeMoreText?: string;
seeLessText?: string;
animate?: boolean;
customTextComponent?: React.ReactNode;
ellipsis?: string;
allowFontScaling?: boolean;
onExpand?: () => void;
onCollapse?: () => void;
expandOnly?: boolean;
seeMoreOverlapCount?: number;
debounceSeeMoreCalc?: number;
onLayout?: (event: LayoutChangeEvent) => void;
onTextLayout?: (event: NativeSyntheticEvent<TextLayoutEventData>) => void;
onReady?: () => void;
seeMoreContainerStyleSecondary: StyleProp<ViewStyle>;
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fawazahmed/react-native-read-more",
"version": "2.3.2",
"version": "2.3.3",
"description": "A simple react native library to show large blocks of text in a condensed manner with the ability to collapse and expand.",
"main": "index.js",
"types": "index.d.ts",
Expand Down

0 comments on commit 5c040f8

Please sign in to comment.