Skip to content

Commit c03b166

Browse files
skv-headlessFacebook Github Bot 3
authored andcommitted
line break mode for ios
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
1 parent 33dfc9d commit c03b166

File tree

9 files changed

+70
-8
lines changed

9 files changed

+70
-8
lines changed

Examples/UIExplorer/TextExample.android.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,17 @@ var TextExample = React.createClass({
388388
Demo text shadow
389389
</Text>
390390
</UIExplorerBlock>
391+
<UIExplorerBlock title="Line break mode">
392+
<Text numberOfLines={1}>
393+
This very long text should be truncated with dots in the end.
394+
</Text>
395+
<Text lineBreakMode="middle" numberOfLines={1}>
396+
This very long text should be truncated with dots in the middle.
397+
</Text>
398+
<Text lineBreakMode="head" numberOfLines={1}>
399+
This very long text should be truncated with dots in the beginning.
400+
</Text>
401+
</UIExplorerBlock>
391402
</UIExplorerPage>
392403
);
393404
}

Examples/UIExplorer/TextExample.ios.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,26 @@ exports.examples = [
444444
</View>
445445
);
446446
},
447+
}, {
448+
title: 'Line break mode',
449+
render: function() {
450+
return (
451+
<View>
452+
<Text numberOfLines={1}>
453+
This very long text should be truncated with dots in the end.
454+
</Text>
455+
<Text lineBreakMode="middle" numberOfLines={1}>
456+
This very long text should be truncated with dots in the middle.
457+
</Text>
458+
<Text lineBreakMode="head" numberOfLines={1}>
459+
This very long text should be truncated with dots in the beginning.
460+
</Text>
461+
<Text lineBreakMode="clip" numberOfLines={1}>
462+
This very looooooooooooooooooooooooooooong text should be clipped.
463+
</Text>
464+
</View>
465+
);
466+
},
447467
}];
448468

449469
var styles = StyleSheet.create({

Libraries/Text/RCTShadowText.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern NSString *const RCTReactTagAttributeName;
2424
@property (nonatomic, assign) CGFloat letterSpacing;
2525
@property (nonatomic, assign) CGFloat lineHeight;
2626
@property (nonatomic, assign) NSUInteger numberOfLines;
27+
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;
2728
@property (nonatomic, assign) CGSize shadowOffset;
2829
@property (nonatomic, assign) NSTextAlignment textAlign;
2930
@property (nonatomic, assign) NSWritingDirection writingDirection;

Libraries/Text/RCTShadowText.m

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#import "RCTShadowRawText.h"
1818
#import "RCTText.h"
1919
#import "RCTUtils.h"
20+
#import "RCTConvert.h"
2021

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

167168
NSTextContainer *textContainer = [NSTextContainer new];
168169
textContainer.lineFragmentPadding = 0.0;
169-
textContainer.lineBreakMode = _numberOfLines > 0 ? NSLineBreakByTruncatingTail : NSLineBreakByClipping;
170+
171+
if (_numberOfLines > 0) {
172+
textContainer.lineBreakMode = _lineBreakMode;
173+
} else {
174+
textContainer.lineBreakMode = NSLineBreakByClipping;
175+
}
176+
170177
textContainer.maximumNumberOfLines = _numberOfLines;
171178
textContainer.size = (CGSize){widthMode == CSS_MEASURE_MODE_UNDEFINED ? CGFLOAT_MAX : width, CGFLOAT_MAX};
172179

@@ -451,6 +458,7 @@ - (void)set##setProp:(type)value; \
451458
RCT_TEXT_PROPERTY(LetterSpacing, _letterSpacing, CGFloat)
452459
RCT_TEXT_PROPERTY(LineHeight, _lineHeight, CGFloat)
453460
RCT_TEXT_PROPERTY(NumberOfLines, _numberOfLines, NSUInteger)
461+
RCT_TEXT_PROPERTY(LineBreakMode, _lineBreakMode, NSLineBreakMode)
454462
RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment)
455463
RCT_TEXT_PROPERTY(TextDecorationColor, _textDecorationColor, UIColor *);
456464
RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationLineType);

Libraries/Text/RCTTextManager.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ - (RCTShadowView *)shadowView
6464
RCT_EXPORT_SHADOW_PROPERTY(letterSpacing, CGFloat)
6565
RCT_EXPORT_SHADOW_PROPERTY(lineHeight, CGFloat)
6666
RCT_EXPORT_SHADOW_PROPERTY(numberOfLines, NSUInteger)
67+
RCT_EXPORT_SHADOW_PROPERTY(lineBreakMode, NSLineBreakMode)
6768
RCT_EXPORT_SHADOW_PROPERTY(textAlign, NSTextAlignment)
6869
RCT_EXPORT_SHADOW_PROPERTY(textDecorationStyle, NSUnderlineStyle)
6970
RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, UIColor)

Libraries/Text/Text.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const viewConfig = {
2929
validAttributes: merge(ReactNativeViewAttributes.UIView, {
3030
isHighlighted: true,
3131
numberOfLines: true,
32+
lineBreakMode: true,
3233
allowFontScaling: true,
3334
}),
3435
uiViewClassName: 'RCTText',
@@ -69,6 +70,11 @@ const viewConfig = {
6970

7071
const Text = React.createClass({
7172
propTypes: {
73+
/**
74+
* Line Break mode. Works only with numberOfLines.
75+
* clip is working only for iOS
76+
*/
77+
lineBreakMode: React.PropTypes.oneOf(['head', 'middle', 'tail', 'clip']),
7278
/**
7379
* Used to truncate the text with an ellipsis after computing the text
7480
* layout, including line wrapping, such that the total number of lines
@@ -110,6 +116,7 @@ const Text = React.createClass({
110116
return {
111117
accessible: true,
112118
allowFontScaling: true,
119+
lineBreakMode: 'tail',
113120
};
114121
},
115122
getInitialState: function(): Object {

React/Base/RCTConvert.m

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -248,13 +248,11 @@ + (NSDate *)NSDate:(id)json
248248
}
249249

250250
RCT_ENUM_CONVERTER(NSLineBreakMode, (@{
251-
@"wordWrapping": @(NSLineBreakByWordWrapping),
252-
@"charWrapping": @(NSLineBreakByCharWrapping),
253-
@"clipping": @(NSLineBreakByClipping),
254-
@"truncatingHead": @(NSLineBreakByTruncatingHead),
255-
@"truncatingTail": @(NSLineBreakByTruncatingTail),
256-
@"truncatingMiddle": @(NSLineBreakByTruncatingMiddle),
257-
}), NSLineBreakByWordWrapping, integerValue)
251+
@"clip": @(NSLineBreakByClipping),
252+
@"head": @(NSLineBreakByTruncatingHead),
253+
@"tail": @(NSLineBreakByTruncatingTail),
254+
@"middle": @(NSLineBreakByTruncatingMiddle),
255+
}), NSLineBreakByTruncatingTail, integerValue)
258256

259257
RCT_ENUM_CONVERTER(NSTextAlignment, (@{
260258
@"auto": @(NSTextAlignmentNatural),

ReactAndroid/src/main/java/com/facebook/react/uimanager/ViewProps.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ public class ViewProps {
6767
public static final String LINE_HEIGHT = "lineHeight";
6868
public static final String NEEDS_OFFSCREEN_ALPHA_COMPOSITING = "needsOffscreenAlphaCompositing";
6969
public static final String NUMBER_OF_LINES = "numberOfLines";
70+
public static final String LINE_BREAK_MODE = "lineBreakMode";
7071
public static final String ON = "on";
7172
public static final String RESIZE_MODE = "resizeMode";
7273
public static final String TEXT_ALIGN = "textAlign";

ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextViewManager.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ public void setTextAlign(ReactTextView view, @Nullable String textAlign) {
7373
}
7474
}
7575

76+
@ReactProp(name = ViewProps.LINE_BREAK_MODE)
77+
public void setLineBreakMode(ReactTextView view, @Nullable String lineBreakMode) {
78+
if(lineBreakMode == null) {
79+
return;
80+
}
81+
82+
if (lineBreakMode.equals("head")) {
83+
view.setEllipsize(TextUtils.TruncateAt.START);
84+
} else if (lineBreakMode.equals("middle")) {
85+
view.setEllipsize(TextUtils.TruncateAt.MIDDLE);
86+
} else if (lineBreakMode.equals("tail")) {
87+
view.setEllipsize(TextUtils.TruncateAt.END);
88+
}
89+
}
90+
7691
@ReactProp(name = ViewProps.TEXT_ALIGN_VERTICAL)
7792
public void setTextAlignVertical(ReactTextView view, @Nullable String textAlignVertical) {
7893
if (textAlignVertical == null || "auto".equals(textAlignVertical)) {

0 commit comments

Comments
 (0)