Skip to content

Commit

Permalink
line break mode for ios
Browse files Browse the repository at this point in the history
Summary:
What do you think is ```lineBreakMode``` a good name? For android it is called ```ellipsize```.

<img src="https://cloud.githubusercontent.com/assets/1488195/15628555/7372f8d0-250c-11e6-8919-722f28a38d60.png"" width="300" />
Closes facebook#7819

Differential Revision: D3417256

fbshipit-source-id: 189441a23ff554bf7f6d67fa8510959351e9e5cc
  • Loading branch information
skv-headless authored and Facebook Github Bot 3 committed Jun 10, 2016
1 parent 33dfc9d commit c03b166
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 8 deletions.
11 changes: 11 additions & 0 deletions Examples/UIExplorer/TextExample.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,17 @@ var TextExample = React.createClass({
Demo text shadow
</Text>
</UIExplorerBlock>
<UIExplorerBlock title="Line break mode">
<Text numberOfLines={1}>
This very long text should be truncated with dots in the end.
</Text>
<Text lineBreakMode="middle" numberOfLines={1}>
This very long text should be truncated with dots in the middle.
</Text>
<Text lineBreakMode="head" numberOfLines={1}>
This very long text should be truncated with dots in the beginning.
</Text>
</UIExplorerBlock>
</UIExplorerPage>
);
}
Expand Down
20 changes: 20 additions & 0 deletions Examples/UIExplorer/TextExample.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,26 @@ exports.examples = [
</View>
);
},
}, {
title: 'Line break mode',
render: function() {
return (
<View>
<Text numberOfLines={1}>
This very long text should be truncated with dots in the end.
</Text>
<Text lineBreakMode="middle" numberOfLines={1}>
This very long text should be truncated with dots in the middle.
</Text>
<Text lineBreakMode="head" numberOfLines={1}>
This very long text should be truncated with dots in the beginning.
</Text>
<Text lineBreakMode="clip" numberOfLines={1}>
This very looooooooooooooooooooooooooooong text should be clipped.
</Text>
</View>
);
},
}];

var styles = StyleSheet.create({
Expand Down
1 change: 1 addition & 0 deletions Libraries/Text/RCTShadowText.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ extern NSString *const RCTReactTagAttributeName;
@property (nonatomic, assign) CGFloat letterSpacing;
@property (nonatomic, assign) CGFloat lineHeight;
@property (nonatomic, assign) NSUInteger numberOfLines;
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;
@property (nonatomic, assign) CGSize shadowOffset;
@property (nonatomic, assign) NSTextAlignment textAlign;
@property (nonatomic, assign) NSWritingDirection writingDirection;
Expand Down
10 changes: 9 additions & 1 deletion Libraries/Text/RCTShadowText.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#import "RCTShadowRawText.h"
#import "RCTText.h"
#import "RCTUtils.h"
#import "RCTConvert.h"

NSString *const RCTShadowViewAttributeName = @"RCTShadowViewAttributeName";
NSString *const RCTIsHighlightedAttributeName = @"IsHighlightedAttributeName";
Expand Down Expand Up @@ -166,7 +167,13 @@ - (NSTextStorage *)buildTextStorageForWidth:(CGFloat)width widthMode:(css_measur

NSTextContainer *textContainer = [NSTextContainer new];
textContainer.lineFragmentPadding = 0.0;
textContainer.lineBreakMode = _numberOfLines > 0 ? NSLineBreakByTruncatingTail : NSLineBreakByClipping;

if (_numberOfLines > 0) {
textContainer.lineBreakMode = _lineBreakMode;
} else {
textContainer.lineBreakMode = NSLineBreakByClipping;
}

textContainer.maximumNumberOfLines = _numberOfLines;
textContainer.size = (CGSize){widthMode == CSS_MEASURE_MODE_UNDEFINED ? CGFLOAT_MAX : width, CGFLOAT_MAX};

Expand Down Expand Up @@ -451,6 +458,7 @@ - (void)set##setProp:(type)value; \
RCT_TEXT_PROPERTY(LetterSpacing, _letterSpacing, CGFloat)
RCT_TEXT_PROPERTY(LineHeight, _lineHeight, CGFloat)
RCT_TEXT_PROPERTY(NumberOfLines, _numberOfLines, NSUInteger)
RCT_TEXT_PROPERTY(LineBreakMode, _lineBreakMode, NSLineBreakMode)
RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment)
RCT_TEXT_PROPERTY(TextDecorationColor, _textDecorationColor, UIColor *);
RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationLineType);
Expand Down
1 change: 1 addition & 0 deletions Libraries/Text/RCTTextManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ - (RCTShadowView *)shadowView
RCT_EXPORT_SHADOW_PROPERTY(letterSpacing, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(lineHeight, CGFloat)
RCT_EXPORT_SHADOW_PROPERTY(numberOfLines, NSUInteger)
RCT_EXPORT_SHADOW_PROPERTY(lineBreakMode, NSLineBreakMode)
RCT_EXPORT_SHADOW_PROPERTY(textAlign, NSTextAlignment)
RCT_EXPORT_SHADOW_PROPERTY(textDecorationStyle, NSUnderlineStyle)
RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, UIColor)
Expand Down
7 changes: 7 additions & 0 deletions Libraries/Text/Text.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const viewConfig = {
validAttributes: merge(ReactNativeViewAttributes.UIView, {
isHighlighted: true,
numberOfLines: true,
lineBreakMode: true,
allowFontScaling: true,
}),
uiViewClassName: 'RCTText',
Expand Down Expand Up @@ -69,6 +70,11 @@ const viewConfig = {

const Text = React.createClass({
propTypes: {
/**
* Line Break mode. Works only with numberOfLines.
* clip is working only for iOS
*/
lineBreakMode: React.PropTypes.oneOf(['head', 'middle', 'tail', 'clip']),
/**
* Used to truncate the text with an ellipsis after computing the text
* layout, including line wrapping, such that the total number of lines
Expand Down Expand Up @@ -110,6 +116,7 @@ const Text = React.createClass({
return {
accessible: true,
allowFontScaling: true,
lineBreakMode: 'tail',
};
},
getInitialState: function(): Object {
Expand Down
12 changes: 5 additions & 7 deletions React/Base/RCTConvert.m
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,11 @@ + (NSDate *)NSDate:(id)json
}

RCT_ENUM_CONVERTER(NSLineBreakMode, (@{
@"wordWrapping": @(NSLineBreakByWordWrapping),
@"charWrapping": @(NSLineBreakByCharWrapping),
@"clipping": @(NSLineBreakByClipping),
@"truncatingHead": @(NSLineBreakByTruncatingHead),
@"truncatingTail": @(NSLineBreakByTruncatingTail),
@"truncatingMiddle": @(NSLineBreakByTruncatingMiddle),
}), NSLineBreakByWordWrapping, integerValue)
@"clip": @(NSLineBreakByClipping),
@"head": @(NSLineBreakByTruncatingHead),
@"tail": @(NSLineBreakByTruncatingTail),
@"middle": @(NSLineBreakByTruncatingMiddle),
}), NSLineBreakByTruncatingTail, integerValue)

RCT_ENUM_CONVERTER(NSTextAlignment, (@{
@"auto": @(NSTextAlignmentNatural),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class ViewProps {
public static final String LINE_HEIGHT = "lineHeight";
public static final String NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
public static final String NUMBER_OF_LINES = "numberOfLines";
public static final String LINE_BREAK_MODE = "lineBreakMode";
public static final String ON = "on";
public static final String RESIZE_MODE = "resizeMode";
public static final String TEXT_ALIGN = "textAlign";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,21 @@ public void setTextAlign(ReactTextView view, @Nullable String textAlign) {
}
}

@ReactProp(name = ViewProps.LINE_BREAK_MODE)
public void setLineBreakMode(ReactTextView view, @Nullable String lineBreakMode) {
if(lineBreakMode == null) {
return;
}

if (lineBreakMode.equals("head")) {
view.setEllipsize(TextUtils.TruncateAt.START);
} else if (lineBreakMode.equals("middle")) {
view.setEllipsize(TextUtils.TruncateAt.MIDDLE);
} else if (lineBreakMode.equals("tail")) {
view.setEllipsize(TextUtils.TruncateAt.END);
}
}

@ReactProp(name = ViewProps.TEXT_ALIGN_VERTICAL)
public void setTextAlignVertical(ReactTextView view, @Nullable String textAlignVertical) {
if (textAlignVertical == null || "auto".equals(textAlignVertical)) {
Expand Down

0 comments on commit c03b166

Please sign in to comment.