diff --git a/Examples/UIExplorer/TextExample.ios.js b/Examples/UIExplorer/TextExample.ios.js index 5abfae323f6964..4aff00e73fa351 100644 --- a/Examples/UIExplorer/TextExample.ios.js +++ b/Examples/UIExplorer/TextExample.ios.js @@ -185,6 +185,44 @@ exports.examples = [ ); }, +}, { + title: 'Text Decoration', + render: function() { + return ( + + + Solid underline + + + Double underline with custom color + + + Dashed underline with custom color + + + Dotted underline with custom color + + + None textDecoration + + + Solid line-through + + + Double line-through with custom color + + + Dashed line-through with custom color + + + Dotted line-through with custom color + + + Both underline and line-through + + + ); + }, }, { title: 'Nested', description: 'Nested text components will inherit the styles of their ' + diff --git a/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp.ios/testTextExampleSnapshot_1@2x.png b/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp.ios/testTextExampleSnapshot_1@2x.png index 3ac73f3ad3d13c..e613b91441c041 100644 Binary files a/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp.ios/testTextExampleSnapshot_1@2x.png and b/Examples/UIExplorer/UIExplorerIntegrationTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp.ios/testTextExampleSnapshot_1@2x.png differ diff --git a/Libraries/Text/RCTShadowText.h b/Libraries/Text/RCTShadowText.h index 4343110bf5e41f..da2a0315624fce 100644 --- a/Libraries/Text/RCTShadowText.h +++ b/Libraries/Text/RCTShadowText.h @@ -8,6 +8,7 @@ */ #import "RCTShadowView.h" +#import "RCTTextDecorationType.h" extern NSString *const RCTIsHighlightedAttributeName; extern NSString *const RCTReactTagAttributeName; @@ -26,6 +27,9 @@ extern NSString *const RCTReactTagAttributeName; @property (nonatomic, assign) CGSize shadowOffset; @property (nonatomic, assign) NSTextAlignment textAlign; @property (nonatomic, assign) NSWritingDirection writingDirection; +@property (nonatomic, strong) UIColor *textDecorationColor; +@property (nonatomic, assign) NSUnderlineStyle textDecorationStyle; +@property (nonatomic, assign) RCTTextDecorationType textDecorationLine; - (void)recomputeText; diff --git a/Libraries/Text/RCTShadowText.m b/Libraries/Text/RCTShadowText.m index e970249287982d..c100cc783a490d 100644 --- a/Libraries/Text/RCTShadowText.m +++ b/Libraries/Text/RCTShadowText.m @@ -252,6 +252,22 @@ - (void)_setParagraphStyleOnAttributedString:(NSMutableAttributedString *)attrib value:paragraphStyle range:(NSRange){0, attributedString.length}]; } + + + //underline and line-through + _textDecorationStyle = _textDecorationStyle ? : NSUnderlineStyleSingle; + if(_textDecorationLine == RCTTextDecorationTypeUnderline || _textDecorationLine == RCTTextDecorationTypeUnderlineStrikethrough) { + [self _addAttribute: NSUnderlineStyleAttributeName withValue:[NSNumber numberWithInt:_textDecorationStyle] toAttributedString:attributedString]; + } + if(_textDecorationLine == RCTTextDecorationTypeStrikethrough || _textDecorationLine == RCTTextDecorationTypeUnderlineStrikethrough){ + [self _addAttribute: NSStrikethroughStyleAttributeName withValue:[NSNumber numberWithInt:_textDecorationStyle] toAttributedString:attributedString]; + } + + if(_textDecorationColor) { + [self _addAttribute: NSStrikethroughColorAttributeName withValue: _textDecorationColor toAttributedString:attributedString]; + [self _addAttribute: NSUnderlineColorAttributeName withValue: _textDecorationColor toAttributedString:attributedString]; + } + } - (void)fillCSSNode:(css_node_t *)node @@ -298,5 +314,8 @@ - (void)set##setProp:(type)value; \ RCT_TEXT_PROPERTY(ShadowOffset, _shadowOffset, CGSize) RCT_TEXT_PROPERTY(TextAlign, _textAlign, NSTextAlignment) RCT_TEXT_PROPERTY(WritingDirection, _writingDirection, NSWritingDirection) +RCT_TEXT_PROPERTY(TextDecorationStyle, _textDecorationStyle, NSUnderlineStyle); +RCT_TEXT_PROPERTY(TextDecorationColor, _textDecorationColor, UIColor *); +RCT_TEXT_PROPERTY(TextDecorationLine, _textDecorationLine, RCTTextDecorationType); @end diff --git a/Libraries/Text/RCTTextManager.m b/Libraries/Text/RCTTextManager.m index 3d2c737598de17..aec021df0ff914 100644 --- a/Libraries/Text/RCTTextManager.m +++ b/Libraries/Text/RCTTextManager.m @@ -35,6 +35,9 @@ - (RCTShadowView *)shadowView #pragma mark - Shadow properties RCT_EXPORT_SHADOW_PROPERTY(writingDirection, NSWritingDirection) +RCT_EXPORT_SHADOW_PROPERTY(textDecorationStyle, NSUnderlineStyle) +RCT_EXPORT_SHADOW_PROPERTY(textDecorationColor, UIColor) +RCT_EXPORT_SHADOW_PROPERTY(textDecorationLine, RCTTextDecorationType) RCT_EXPORT_SHADOW_PROPERTY(color, UIColor) RCT_EXPORT_SHADOW_PROPERTY(fontFamily, NSString) RCT_EXPORT_SHADOW_PROPERTY(fontSize, CGFloat) diff --git a/Libraries/Text/TextStylePropTypes.js b/Libraries/Text/TextStylePropTypes.js index b903675093c89b..041a0d3e0b1ecf 100644 --- a/Libraries/Text/TextStylePropTypes.js +++ b/Libraries/Text/TextStylePropTypes.js @@ -33,6 +33,13 @@ var TextStylePropTypes = Object.assign(Object.create(ViewStylePropTypes), { ['auto' /*default*/, 'ltr', 'rtl'] ), letterSpacing: ReactPropTypes.number, + textDecorationLine:ReactPropTypes.oneOf( + ['none' /*default*/, 'underline', 'line-through', 'underline line-through'] + ), + textDecorationStyle:ReactPropTypes.oneOf( + ['solid' /*default*/, 'double', 'dotted','dashed'] + ), + textDecorationColor: ReactPropTypes.string, }); // Text doesn't support padding correctly (#4841912) diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index e96e4562d3cc61..6a45e06f309ca0 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -12,10 +12,12 @@ #import "Layout.h" #import "RCTAnimationType.h" +#import "RCTTextDecorationType.h" #import "RCTDefines.h" #import "RCTLog.h" #import "RCTPointerEvents.h" + /** * This class provides a collection of conversion functions for mapping * JSON objects to native types and classes. These are useful when writing @@ -54,6 +56,7 @@ typedef NSURL RCTFileURL; + (NSTimeInterval)NSTimeInterval:(id)json; + (NSTextAlignment)NSTextAlignment:(id)json; ++ (NSUnderlineStyle)NSUnderlineStyle:(id)json; + (NSWritingDirection)NSWritingDirection:(id)json; + (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json; + (UITextFieldViewMode)UITextFieldViewMode:(id)json; @@ -126,6 +129,7 @@ typedef BOOL css_clip_t; + (RCTPointerEvents)RCTPointerEvents:(id)json; + (RCTAnimationType)RCTAnimationType:(id)json; ++ (RCTTextDecorationType)RCTTextDecorationType:(id)json; @end diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 6347bcc01bc94d..84c0f66c464d95 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -216,6 +216,20 @@ + (NSDate *)NSDate:(id)json @"justify": @(NSTextAlignmentJustified), }), NSTextAlignmentNatural, integerValue) +RCT_ENUM_CONVERTER(NSUnderlineStyle, (@{ + @"solid": @(NSUnderlineStyleSingle), + @"double": @(NSUnderlineStyleDouble), + @"dotted": @(NSUnderlinePatternDot | NSUnderlineStyleSingle), + @"dashed": @(NSUnderlinePatternDash | NSUnderlineStyleSingle), +}), NSUnderlineStyleSingle, integerValue) + +RCT_ENUM_CONVERTER(RCTTextDecorationType, (@{ + @"none": @(RCTTextDecorationTypeNone), + @"underline": @(RCTTextDecorationTypeUnderline), + @"line-through": @(RCTTextDecorationTypeStrikethrough), + @"underline line-through": @(RCTTextDecorationTypeUnderlineStrikethrough), +}), RCTTextDecorationTypeNone, integerValue) + RCT_ENUM_CONVERTER(NSWritingDirection, (@{ @"auto": @(NSWritingDirectionNatural), @"ltr": @(NSWritingDirectionLeftToRight), diff --git a/React/React.xcodeproj/project.pbxproj b/React/React.xcodeproj/project.pbxproj index 54261357db451e..3391ad8cf5e5fd 100644 --- a/React/React.xcodeproj/project.pbxproj +++ b/React/React.xcodeproj/project.pbxproj @@ -241,6 +241,7 @@ 83CBBA971A6020BB00E9B192 /* RCTTouchHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTouchHandler.m; sourceTree = ""; }; 83CBBACA1A6023D300E9B192 /* RCTConvert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTConvert.h; sourceTree = ""; }; 83CBBACB1A6023D300E9B192 /* RCTConvert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTConvert.m; sourceTree = ""; }; + E3BBC8EB1ADE6F47001BBD81 /* RCTTextDecorationType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RCTTextDecorationType.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -378,6 +379,7 @@ 13B080241A694A8400A75B9A /* RCTWrapperViewController.m */, 13E067531A70F44B002CDEE1 /* UIView+React.h */, 13E067541A70F44B002CDEE1 /* UIView+React.m */, + E3BBC8EB1ADE6F47001BBD81 /* RCTTextDecorationType.h */, ); path = Views; sourceTree = ""; diff --git a/React/Views/RCTTextDecorationType.h b/React/Views/RCTTextDecorationType.h new file mode 100644 index 00000000000000..ba10eb99e1a5fe --- /dev/null +++ b/React/Views/RCTTextDecorationType.h @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +typedef NS_ENUM(NSInteger, RCTTextDecorationType) { + RCTTextDecorationTypeNone = 0, + RCTTextDecorationTypeUnderline, + RCTTextDecorationTypeStrikethrough, + RCTTextDecorationTypeUnderlineStrikethrough, +};