Skip to content

Commit

Permalink
feat: added line break strategy attribute and example
Browse files Browse the repository at this point in the history
  • Loading branch information
bang9 committed Jun 15, 2021
1 parent f78526c commit 86a6704
Show file tree
Hide file tree
Showing 11 changed files with 145 additions and 5 deletions.
1 change: 1 addition & 0 deletions Libraries/Components/TextInput/RCTTextInputViewConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ const RCTTextInputViewConfig = {
selectTextOnFocus: true,
text: true,
clearTextOnFocus: true,
ios_lineBreakStrategy: true,
},
};

Expand Down
6 changes: 6 additions & 0 deletions Libraries/Components/TextInput/TextInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,12 @@ type IOSProps = $ReadOnly<{|
* @platform ios
*/
textContentType?: ?TextContentType,

/**
* Set line break strategy on iOS.
* @platform ios
*/
ios_lineBreakStrategy?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
|}>;

type AndroidProps = $ReadOnly<{|
Expand Down
1 change: 1 addition & 0 deletions Libraries/Text/BaseText/RCTBaseTextViewManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ - (RCTShadowView *)shadowView
RCT_REMAP_SHADOW_PROPERTY(lineHeight, textAttributes.lineHeight, CGFloat)
RCT_REMAP_SHADOW_PROPERTY(textAlign, textAttributes.alignment, NSTextAlignment)
RCT_REMAP_SHADOW_PROPERTY(writingDirection, textAttributes.baseWritingDirection, NSWritingDirection)
RCT_REMAP_SHADOW_PROPERTY(ios_lineBreakStrategy, textAttributes.lineBreakStrategy, NSLineBreakStrategy)
// Decoration
RCT_REMAP_SHADOW_PROPERTY(textDecorationColor, textAttributes.textDecorationColor, UIColor)
RCT_REMAP_SHADOW_PROPERTY(textDecorationStyle, textAttributes.textDecorationStyle, NSUnderlineStyle)
Expand Down
1 change: 1 addition & 0 deletions Libraries/Text/RCTTextAttributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extern NSString *const RCTTextAttributesTagAttributeName;
@property (nonatomic, assign) CGFloat lineHeight;
@property (nonatomic, assign) NSTextAlignment alignment;
@property (nonatomic, assign) NSWritingDirection baseWritingDirection;
@property (nonatomic, assign) NSLineBreakStrategy lineBreakStrategy;
// Decoration
@property (nonatomic, strong, nullable) UIColor *textDecorationColor;
@property (nonatomic, assign) NSUnderlineStyle textDecorationStyle;
Expand Down
20 changes: 15 additions & 5 deletions Libraries/Text/RCTTextAttributes.m
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ - (instancetype)init
_maxFontSizeMultiplier = NAN;
_alignment = NSTextAlignmentNatural;
_baseWritingDirection = NSWritingDirectionNatural;
_lineBreakStrategy = NSLineBreakStrategyNone;
_textShadowRadius = NAN;
_opacity = NAN;
_textTransform = RCTTextTransformUndefined;
Expand Down Expand Up @@ -61,6 +62,7 @@ - (void)applyTextAttributes:(RCTTextAttributes *)textAttributes
_lineHeight = !isnan(textAttributes->_lineHeight) ? textAttributes->_lineHeight : _lineHeight;
_alignment = textAttributes->_alignment != NSTextAlignmentNatural ? textAttributes->_alignment : _alignment; // *
_baseWritingDirection = textAttributes->_baseWritingDirection != NSWritingDirectionNatural ? textAttributes->_baseWritingDirection : _baseWritingDirection; // *
_lineBreakStrategy = textAttributes->_lineBreakStrategy != NSLineBreakStrategyNone ? textAttributes->_lineBreakStrategy : _lineBreakStrategy;

// Decoration
_textDecorationColor = textAttributes->_textDecorationColor ?: _textDecorationColor;
Expand Down Expand Up @@ -93,27 +95,34 @@ - (NSParagraphStyle *)effectiveParagraphStyle
alignment = NSTextAlignmentRight;
}
}

paragraphStyle.alignment = alignment;
isParagraphStyleUsed = YES;
}

if (_baseWritingDirection != NSWritingDirectionNatural) {
paragraphStyle.baseWritingDirection = _baseWritingDirection;
isParagraphStyleUsed = YES;
}


if (_lineBreakStrategy != NSLineBreakStrategyNone) {
if (@available(iOS 14.0, *)) {
paragraphStyle.lineBreakStrategy = _lineBreakStrategy;
isParagraphStyleUsed = YES;
}
}

if (!isnan(_lineHeight)) {
CGFloat lineHeight = _lineHeight * self.effectiveFontSizeMultiplier;
paragraphStyle.minimumLineHeight = lineHeight;
paragraphStyle.maximumLineHeight = lineHeight;
isParagraphStyleUsed = YES;
}

if (isParagraphStyleUsed) {
return [paragraphStyle copy];
}

return nil;
}

Expand Down Expand Up @@ -294,6 +303,7 @@ - (BOOL)isEqual:(RCTTextAttributes *)textAttributes
RCTTextAttributesCompareFloats(_lineHeight) &&
RCTTextAttributesCompareFloats(_alignment) &&
RCTTextAttributesCompareOthers(_baseWritingDirection) &&
RCTTextAttributesCompareOthers(_lineBreakStrategy) &&
// Decoration
RCTTextAttributesCompareObjects(_textDecorationColor) &&
RCTTextAttributesCompareOthers(_textDecorationStyle) &&
Expand Down
1 change: 1 addition & 0 deletions Libraries/Text/TextNativeComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const NativeText: HostComponent<NativeTextProps> = (createReactNativeComp
onInlineViewLayout: true,
dataDetectorType: true,
android_hyphenationFrequency: true,
ios_lineBreakStrategy: true,
},
directEventTypes: {
topTextLayout: {
Expand Down
7 changes: 7 additions & 0 deletions Libraries/Text/TextProps.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,11 @@ export type TextProps = $ReadOnly<{|
* See https://reactnative.dev/docs/text.html#supperhighlighting
*/
suppressHighlighting?: ?boolean,

/**
* Set line break strategy on iOS.
*
* See https://reactnative.dev/docs/text.html#ios_linebreakstrategy
*/
ios_lineBreakStrategy?: ?('none' | 'standard' | 'hangul-word' | 'push-out'),
|}>;
1 change: 1 addition & 0 deletions React/Base/RCTConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef NSURL RCTFileURL;
+ (NSTextAlignment)NSTextAlignment:(id)json;
+ (NSUnderlineStyle)NSUnderlineStyle:(id)json;
+ (NSWritingDirection)NSWritingDirection:(id)json;
+ (NSLineBreakStrategy)NSLineBreakStrategy:(id)json;
+ (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json;
+ (UITextFieldViewMode)UITextFieldViewMode:(id)json;
+ (UIKeyboardType)UIKeyboardType:(id)json;
Expand Down
32 changes: 32 additions & 0 deletions React/Base/RCTConvert.m
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,38 @@ + (NSLocale *)NSLocale:(id)json
NSWritingDirectionNatural,
integerValue)

+ (NSLineBreakStrategy)NSLineBreakStrategy:(id)json RCT_DYNAMIC
{
static NSDictionary *mapping;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
if (@available(iOS 14.0, *)) {
mapping = @{
@"none" : @(NSLineBreakStrategyNone),
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
@"standard" : @(NSLineBreakStrategyStandard),
@"hangul-word" : @(NSLineBreakStrategyHangulWordPriority),
@"push-out": @(NSLineBreakStrategyPushOut)
#else
@"standard" : @(NSLineBreakStrategyNone),
@"hangul-word" : @(NSLineBreakStrategyNone),
@"push-out": @(NSLineBreakStrategyNone)
#endif
};
} else {
mapping = @{
@"none" : @(NSLineBreakStrategyNone),
@"standard" : @(NSLineBreakStrategyNone),
@"hangul-word" : @(NSLineBreakStrategyNone),
@"push-out": @(NSLineBreakStrategyNone)
};
}
});

NSLineBreakStrategy type = RCTConvertEnumValue("NSLineBreakStrategy", mapping, @(NSLineBreakStrategyNone), json).integerValue;
return type;
}

RCT_ENUM_CONVERTER(
UITextAutocapitalizationType,
(@{
Expand Down
39 changes: 39 additions & 0 deletions packages/rn-tester/js/examples/Text/TextExample.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -1148,4 +1148,43 @@ exports.examples = [
);
},
},
{
title: 'Line Break Strategy',
render: function(): React.Node {
const lineBreakStrategy = ['none', 'standard', 'hangul-word', 'push-out'];
const textByCode = {
en:
'lineBreakStrategy lineBreakStrategy lineBreakStrategy lineBreakStrategy',
ko:
'한글개행 한글개행 한글개행 한글개행 한글개행 한글개행 한글개행 한글개행',
ja: 'かいぎょう かいぎょう かいぎょう かいぎょう かいぎょう かいぎょう',
cn: '改行 改行 改行 改行 改行 改行 改行 改行 改行 改行 改行 改行',
};

return (
<View>
{lineBreakStrategy.map(strategy => {
return (
<View key={strategy} style={{marginBottom: 12}}>
<Text
style={{
backgroundColor: 'lightgrey',
}}>{`Strategy: ${strategy}`}</Text>
{Object.keys(textByCode).map(code => {
return (
<View key={code}>
<Text style={{fontWeight: 'bold'}}>{`[${code}]`}</Text>
<Text ios_lineBreakStrategy={strategy}>
{textByCode[code]}
</Text>
</View>
);
})}
</View>
);
})}
</View>
);
},
},
];
41 changes: 41 additions & 0 deletions packages/rn-tester/js/examples/TextInput/TextInputExample.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -816,4 +816,45 @@ exports.examples = ([
);
},
},
{
title: 'Line Break Strategy',
render: function(): React.Node {
const lineBreakStrategy = ['none', 'standard', 'hangul-word', 'push-out'];
const textByCode = {
en:
'lineBreakStrategy lineBreakStrategy lineBreakStrategy lineBreakStrategy',
ko:
'한글개행한글개행 한글개행한글개행 한글개행한글개행 한글개행한글개행 한글개행한글개행 한글개행한글개행',
ja: 'かいぎょう かいぎょう かいぎょう かいぎょう かいぎょう かいぎょう',
cn: '改行 改行 改行 改行 改行 改行 改行 改行 改行 改行 改行 改行',
};
return (
<View>
{lineBreakStrategy.map(strategy => {
return (
<View key={strategy} style={{marginBottom: 12}}>
<Text
style={{
backgroundColor: 'lightgrey',
}}>{`Strategy: ${strategy}`}</Text>
{Object.keys(textByCode).map(code => {
return (
<View key={code}>
<Text style={{fontWeight: 'bold'}}>{`[${code}]`}</Text>
<TextInput
multiline
ios_lineBreakStrategy={strategy}
style={styles.default}
defaultValue={textByCode[code]}
/>
</View>
);
})}
</View>
);
})}
</View>
);
},
},
]: Array<RNTesterExampleModuleItem>);

0 comments on commit 86a6704

Please sign in to comment.