Add Dynamic Text support plus test page
This commit is contained in:
Родитель
ab720113d4
Коммит
c56ccdfa90
|
@ -36,6 +36,7 @@ RCT_REMAP_SHADOW_PROPERTY(fontWeight, textAttributes.fontWeight, NSString)
|
|||
RCT_REMAP_SHADOW_PROPERTY(fontStyle, textAttributes.fontStyle, NSString)
|
||||
RCT_REMAP_SHADOW_PROPERTY(fontVariant, textAttributes.fontVariant, NSArray)
|
||||
RCT_REMAP_SHADOW_PROPERTY(allowFontScaling, textAttributes.allowFontScaling, BOOL)
|
||||
RCT_REMAP_SHADOW_PROPERTY(fontScaleRamp, textAttributes.fontScaleRamp, RCTFontScaleRamp)
|
||||
RCT_REMAP_SHADOW_PROPERTY(maxFontSizeMultiplier, textAttributes.maxFontSizeMultiplier, CGFloat)
|
||||
RCT_REMAP_SHADOW_PROPERTY(letterSpacing, textAttributes.letterSpacing, CGFloat)
|
||||
RCT_REMAP_SHADOW_PROPERTY(apple_fontSmoothing, textAttributes.fontSmoothing, RCTFontSmoothing) // TODO(OSS Candidate ISS#2710739)
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#import <React/RCTUIKit.h> // TODO(macOS GH#774)
|
||||
|
||||
#import <React/RCTTextDecorationLineType.h>
|
||||
#import <React/RCTFontScaleRamp.h>
|
||||
#import <React/RCTFontSmoothing.h> // TODO(OSS Candidate ISS#2710739)
|
||||
|
||||
#import "RCTTextTransform.h"
|
||||
|
@ -38,6 +39,7 @@ extern NSString *const RCTTextAttributesTagAttributeName;
|
|||
@property (nonatomic, copy, nullable) NSString *fontStyle;
|
||||
@property (nonatomic, copy, nullable) NSArray<NSString *> *fontVariant;
|
||||
@property (nonatomic, assign) BOOL allowFontScaling;
|
||||
@property (nonatomic, assign) RCTFontScaleRamp fontScaleRamp;
|
||||
@property (nonatomic, assign) CGFloat letterSpacing;
|
||||
@property (nonatomic, assign) RCTFontSmoothing fontSmoothing; // TODO(OSS Candidate ISS#2710739)
|
||||
@property (class, nonatomic, assign) RCTFontSmoothing fontSmoothingDefault; // TODO(OSS Candidate ISS#2710739)
|
||||
|
|
|
@ -70,6 +70,7 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
|
|||
_fontStyle = textAttributes->_fontStyle ?: _fontStyle;
|
||||
_fontVariant = textAttributes->_fontVariant ?: _fontVariant;
|
||||
_allowFontScaling = textAttributes->_allowFontScaling || _allowFontScaling; // *
|
||||
_fontScaleRamp = textAttributes->_fontScaleRamp != RCTFontScaleRampUndefined ? textAttributes->_fontScaleRamp : _fontScaleRamp;
|
||||
_letterSpacing = !isnan(textAttributes->_letterSpacing) ? textAttributes->_letterSpacing : _letterSpacing;
|
||||
_fontSmoothing = textAttributes->_fontSmoothing != RCTFontSmoothingAuto ? textAttributes->_fontSmoothing : _fontSmoothing; // TODO(OSS Candidate ISS#2710739)
|
||||
|
||||
|
@ -230,6 +231,13 @@ NSString *const RCTTextAttributesTagAttributeName = @"RCTTextAttributesTagAttrib
|
|||
|
||||
if (fontScalingEnabled) {
|
||||
CGFloat fontSizeMultiplier = !isnan(_fontSizeMultiplier) ? _fontSizeMultiplier : 1.0;
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
if (_fontScaleRamp != RCTFontScaleRampUndefined) {
|
||||
UIFontMetrics *fontMetrics = RCTUIFontMetricsForFontScaleRamp(_fontScaleRamp);
|
||||
CGFloat baseSize = RCTUIBaseSizeForFontScaleRamp(_fontScaleRamp);
|
||||
fontSizeMultiplier = [fontMetrics scaledValueForValue:baseSize] / baseSize;
|
||||
}
|
||||
#endif // ]TODO(macOS GH#774)
|
||||
CGFloat maxFontSizeMultiplier = !isnan(_maxFontSizeMultiplier) ? _maxFontSizeMultiplier : 0.0;
|
||||
return maxFontSizeMultiplier >= 1.0 ? fminf(maxFontSizeMultiplier, fontSizeMultiplier) : fontSizeMultiplier;
|
||||
} else {
|
||||
|
@ -328,6 +336,7 @@ static NSString *capitalizeText(NSString *text)
|
|||
RCTTextAttributesCompareObjects(_fontStyle) &&
|
||||
RCTTextAttributesCompareObjects(_fontVariant) &&
|
||||
RCTTextAttributesCompareOthers(_allowFontScaling) &&
|
||||
RCTTextAttributesCompareOthers(_fontScaleRamp) &&
|
||||
RCTTextAttributesCompareFloats(_letterSpacing) &&
|
||||
RCTTextAttributesCompareOthers(_fontSmoothing) && // TODO(OSS Candidate ISS#2710739)
|
||||
// Paragraph Styles
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
typedef NS_ENUM(NSInteger, RCTFontScaleRamp) {
|
||||
RCTFontScaleRampUndefined,
|
||||
RCTFontScaleRampCaption2,
|
||||
RCTFontScaleRampCaption1,
|
||||
RCTFontScaleRampFootnote,
|
||||
RCTFontScaleRampSubhead,
|
||||
RCTFontScaleRampCallout,
|
||||
RCTFontScaleRampBody,
|
||||
RCTFontScaleRampHeadline,
|
||||
RCTFontScaleRampTitle3,
|
||||
RCTFontScaleRampTitle2,
|
||||
RCTFontScaleRampTitle1,
|
||||
RCTFontScaleRampLargeTitle
|
||||
};
|
||||
|
||||
@interface RCTConvert (FontScaleRamp)
|
||||
|
||||
+ (RCTFontScaleRamp)RCTFontScaleRamp:(nullable id)json;
|
||||
|
||||
@end
|
||||
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
/// Generates a `UIFontMetrics` instance representing a particular font scale ramp.
|
||||
UIFontMetrics * _Nonnull RCTUIFontMetricsForFontScaleRamp(RCTFontScaleRamp fontScaleRamp);
|
||||
/// The "reference" size for a particular font scale ramp, equal to a text element's size under default text size settings.
|
||||
CGFloat RCTUIBaseSizeForFontScaleRamp(RCTFontScaleRamp fontScaleRamp);
|
||||
#endif // ]TODO(macOS GH#774)
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTFontScaleRamp.h>
|
||||
|
||||
@implementation RCTConvert (FontScaleRamp)
|
||||
|
||||
RCT_ENUM_CONVERTER(RCTFontScaleRamp, (@{
|
||||
@"caption2": @(RCTFontScaleRampCaption2),
|
||||
@"caption1": @(RCTFontScaleRampCaption1),
|
||||
@"footnote": @(RCTFontScaleRampFootnote),
|
||||
@"subhead": @(RCTFontScaleRampSubhead),
|
||||
@"callout": @(RCTFontScaleRampCallout),
|
||||
@"body": @(RCTFontScaleRampBody),
|
||||
@"headline": @(RCTFontScaleRampHeadline),
|
||||
@"title3": @(RCTFontScaleRampTitle3),
|
||||
@"title2": @(RCTFontScaleRampTitle2),
|
||||
@"title1": @(RCTFontScaleRampTitle1),
|
||||
@"largeTitle": @(RCTFontScaleRampLargeTitle),
|
||||
}), RCTFontScaleRampUndefined, integerValue)
|
||||
|
||||
@end
|
||||
|
||||
#if !TARGET_OS_OSX // [TODO(macOS GH#774)
|
||||
UIFontMetrics *RCTUIFontMetricsForFontScaleRamp(RCTFontScaleRamp fontScaleRamp) {
|
||||
static NSDictionary<NSNumber *, UIFontTextStyle> *mapping;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
mapping = @{
|
||||
@(RCTFontScaleRampCaption2): UIFontTextStyleCaption2,
|
||||
@(RCTFontScaleRampCaption1): UIFontTextStyleCaption1,
|
||||
@(RCTFontScaleRampFootnote): UIFontTextStyleFootnote,
|
||||
@(RCTFontScaleRampSubhead): UIFontTextStyleSubheadline,
|
||||
@(RCTFontScaleRampCallout): UIFontTextStyleCallout,
|
||||
@(RCTFontScaleRampBody): UIFontTextStyleBody,
|
||||
@(RCTFontScaleRampHeadline): UIFontTextStyleHeadline,
|
||||
@(RCTFontScaleRampTitle3): UIFontTextStyleTitle3,
|
||||
@(RCTFontScaleRampTitle2): UIFontTextStyleTitle2,
|
||||
@(RCTFontScaleRampTitle1): UIFontTextStyleTitle1,
|
||||
@(RCTFontScaleRampLargeTitle): UIFontTextStyleLargeTitle,
|
||||
};
|
||||
});
|
||||
|
||||
id textStyle = mapping[@(fontScaleRamp)] ?: UIFontTextStyleBody; // Default to body if we don't recognize the specified ramp
|
||||
return [UIFontMetrics metricsForTextStyle:textStyle];
|
||||
}
|
||||
|
||||
CGFloat RCTUIBaseSizeForFontScaleRamp(RCTFontScaleRamp fontScaleRamp) {
|
||||
static NSDictionary<NSNumber *, NSNumber *> *mapping;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
// Values taken from https://developer.apple.com/design/human-interface-guidelines/foundations/typography/
|
||||
mapping = @{
|
||||
@(RCTFontScaleRampCaption2): @11,
|
||||
@(RCTFontScaleRampCaption1): @12,
|
||||
@(RCTFontScaleRampFootnote): @13,
|
||||
@(RCTFontScaleRampSubhead): @15,
|
||||
@(RCTFontScaleRampCallout): @16,
|
||||
@(RCTFontScaleRampBody): @17,
|
||||
@(RCTFontScaleRampHeadline): @17,
|
||||
@(RCTFontScaleRampTitle3): @20,
|
||||
@(RCTFontScaleRampTitle2): @22,
|
||||
@(RCTFontScaleRampTitle1): @28,
|
||||
@(RCTFontScaleRampLargeTitle): @34,
|
||||
};
|
||||
});
|
||||
|
||||
NSNumber *baseSize = mapping[@(fontScaleRamp)] ?: @17; // Default to body size if we don't recognize the specified ramp
|
||||
return CGFLOAT_IS_DOUBLE ? [baseSize doubleValue] : [baseSize floatValue];
|
||||
}
|
||||
#endif // ]TODO(macOS GH#774)
|
|
@ -34,6 +34,7 @@ export const NativeText: HostComponent<NativeTextProps> =
|
|||
numberOfLines: true,
|
||||
ellipsizeMode: true,
|
||||
allowFontScaling: true,
|
||||
fontScaleRamp: true,
|
||||
maxFontSizeMultiplier: true,
|
||||
disabled: true,
|
||||
selectable: true,
|
||||
|
|
|
@ -186,6 +186,23 @@ export type TextProps = $ReadOnly<{|
|
|||
*/
|
||||
adjustsFontSizeToFit?: ?boolean,
|
||||
|
||||
/**
|
||||
* The Dynamic Text scale ramp to apply to this element on iOS.
|
||||
*/
|
||||
fontScaleRamp?: ?(
|
||||
| 'caption2'
|
||||
| 'caption1'
|
||||
| 'footnote'
|
||||
| 'subhead'
|
||||
| 'callout'
|
||||
| 'body'
|
||||
| 'headline'
|
||||
| 'title3'
|
||||
| 'title2'
|
||||
| 'title1'
|
||||
| 'largeTitle'
|
||||
),
|
||||
|
||||
/**
|
||||
* Smallest possible scale a font can reach.
|
||||
*
|
||||
|
|
|
@ -563,8 +563,8 @@ SPEC CHECKSUMS:
|
|||
boost: 613e39eac4239cc72b15421247b5ab05361266a2
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
DoubleConversion: ed15e075aa758ac0e4c1f8b830bd4e4d40d669e8
|
||||
FBLazyVector: 8c015ab0962fa7ca8b83a2f85486553ee12fa2c3
|
||||
FBReactNativeSpec: d5e0e1eab0166d3998da480c3277a4fc9d5beef9
|
||||
FBLazyVector: e80429cc05cff5705af0a97a22a0f1be1d87ebf3
|
||||
FBReactNativeSpec: edc16f1d57552d580d21fe5a640c0ad76c6a1b91
|
||||
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
|
||||
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
|
||||
Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c
|
||||
|
@ -580,37 +580,37 @@ SPEC CHECKSUMS:
|
|||
OCMock: 9491e4bec59e0b267d52a9184ff5605995e74be8
|
||||
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
|
||||
RCT-Folly: 24c6da766832002a4a2aac5f79ee0ca50fbe8507
|
||||
RCTRequired: 1efc34e0e287a4e1b514fcc9e163651c44c3dd9d
|
||||
RCTTypeSafety: 239fff897dcb1fe657556057955c7e571d201d94
|
||||
React: 0bb0907e6c1cd7ab1d1944c513fb8a278724135d
|
||||
React-callinvoker: d982ccf1b8ac51b93deee087cb8ca5af41269e70
|
||||
RCTRequired: d464086ee8d610689a8968ebb940815916685a97
|
||||
RCTTypeSafety: a25d8ad134c389a662ce207d09c33ae2e6f31f59
|
||||
React: eee389898adae6450c1bb131b0bdd1a6fe5e596f
|
||||
React-callinvoker: ef69b20aa08b4c7051a8a72b276954818145d491
|
||||
React-Codegen: b3fbef96f960cb15fc61250078b0700cfd4cd8a1
|
||||
React-Core: 7388e919ba68e29e2068bb2dc4c83ee0e176c277
|
||||
React-CoreModules: 7424cb36a2e91d9af6b01d1b20c9701a2fcdc322
|
||||
React-cxxreact: d7be72a8ac63c058dff0da14a2340e461dee5a06
|
||||
React-jsi: 6679d5fd952443b2945ad502f8f592f5a61916db
|
||||
React-jsiexecutor: 8a92c56f39dbbaaf23b834b78a4aa950ac61f1f3
|
||||
React-jsinspector: f5d9b01ea66dd10e25ed711a73e7b370c5f6a00b
|
||||
React-logger: a87dbd13ef3409c729c9900954d19b3f0af0c57d
|
||||
React-perflogger: 63baa12c036f63a56a591806089cba2178bfa5ce
|
||||
React-RCTActionSheet: 657e35f1549f792ff8cb2175165a2e34eacc405e
|
||||
React-RCTAnimation: 661b7b7d6b9244103f34a691a2a17cf08b870cda
|
||||
React-RCTBlob: d033f8473850f445c0043bd17a53ac768d8ae003
|
||||
React-RCTImage: f0ec96d288e9a97bdad40a91aa9371e5859db561
|
||||
React-RCTLinking: 245902d2b32f1934b776add9af6fa6d13418b036
|
||||
React-RCTNetwork: 51aba5631b28b959225ff1cc7e270975e571f1c6
|
||||
React-RCTPushNotification: 0ce584762d852b8e7fb4ab76d531e2ce13ff2ca3
|
||||
React-RCTSettings: d2c584eedf27f3e127e7c4e4ab8628e58b615782
|
||||
React-RCTTest: 8e9fdc24c24ece07e0e5b3c3e1424c160025d194
|
||||
React-RCTText: 9f60e6cc120fff66ebed92077d076210d203ffb1
|
||||
React-RCTVibration: cd53df9d069038a6caa7274481f9cd94d0ea53f3
|
||||
React-runtimeexecutor: 792724a76f30693d1db43dd2f5e96d7858adbf36
|
||||
React-Core: 2d3e7572b473f30852352af25b2fe1cc1373fab9
|
||||
React-CoreModules: 7e96d2339cdc1222bb881b84f1cf11cc43d009fb
|
||||
React-cxxreact: e281966e72e33658d0be065c6e853cd59a019913
|
||||
React-jsi: 4d8dfc08118d65560e3996d7221bab7ecb3993b6
|
||||
React-jsiexecutor: d85100b9a614856b90ab1c362fe3f33465c9cc7f
|
||||
React-jsinspector: b529c56a8b51ad33c1397b12045f5d0a119ed1a6
|
||||
React-logger: d30a666bca9e66b34d4d8716891b1e061601833a
|
||||
React-perflogger: 92cee36035743d30b9e6d96fd86b94a2a0008bd2
|
||||
React-RCTActionSheet: 9a910651201dd3fad1b151e152caf06467e132ba
|
||||
React-RCTAnimation: 7f76001c7252d19ed71b7774a16517e5ea48db4e
|
||||
React-RCTBlob: 20bba1a828491a4ee59e5e059ec4c8e788f54309
|
||||
React-RCTImage: b5cd9667278a9ffd9f6c31eb52d62798a34367f9
|
||||
React-RCTLinking: 55d89d2a268b5f84938738d69aa893e899ea2cf2
|
||||
React-RCTNetwork: 264a2b8c75c35250757aa7da3bf4fc1827ca9b54
|
||||
React-RCTPushNotification: 54964d39a88b62ae2ebc7aafb12b42871d956bee
|
||||
React-RCTSettings: efcdbb2e10d28f960f6778c8d256aa13b5a07722
|
||||
React-RCTTest: 1b7527ab6b372b88dbaac17b80e4d0555fca7c1f
|
||||
React-RCTText: 06274ceb822c0650544ad15b136c446d5293371a
|
||||
React-RCTVibration: 0c4b247824ccef25d8596bbf7d8d57a89ecba77a
|
||||
React-runtimeexecutor: 32b822f26f10d85676b747f9ce62145c99ed82a5
|
||||
React-TurboModuleCxx-RNW: 881411415eafe818f9cc3c4016167cc3d219402b
|
||||
React-TurboModuleCxx-WinRTPort: 50cd9648f6b21aab53d1c62c466dc6567263a983
|
||||
ReactCommon: cbfca257bdf2378d6036321c28ad21765b833f3a
|
||||
ScreenshotManager: b378292226c78474e70b139ba2e19f584836c520
|
||||
React-TurboModuleCxx-WinRTPort: d998841ac172264f9d54f8726546d4a72634dc78
|
||||
ReactCommon: 68700e9db52849dc55ec5d379450c5518b0d4feb
|
||||
ScreenshotManager: 1d5d672b71a31623453916311ff5656e0a6d4cfd
|
||||
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
|
||||
Yoga: ddfd728ee27a2b67dfdd249da09a6393d6d5514d
|
||||
Yoga: f3fcf7a3bf93229ebd30a0cfb19bf8caa088eb46
|
||||
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
|
||||
|
||||
PODFILE CHECKSUM: cbf4f9be33910397d5f84dd4fcbe56d3d61d42fa
|
||||
|
|
|
@ -1245,4 +1245,49 @@ exports.examples = [
|
|||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Dynamic Text sizing (iOS only)',
|
||||
render: function (): React.Node {
|
||||
const boldStyle = {fontWeight: 'bold'};
|
||||
const boxStyle = {
|
||||
borderWidth: 1,
|
||||
padding: 8,
|
||||
margin: 8,
|
||||
};
|
||||
return (
|
||||
<View style={{marginTop: 10, marginBottom: 10}}>
|
||||
<Text>
|
||||
Adjust text size in Accessibility settings and watch how the font
|
||||
sizes change relative to each other.
|
||||
</Text>
|
||||
<View style={boxStyle}>
|
||||
<Text style={boldStyle}>With `fontScaleRamp`:</Text>
|
||||
<Text style={{fontSize: 34}} fontScaleRamp="largeTitle">
|
||||
Large Title
|
||||
</Text>
|
||||
<Text style={{fontSize: 28}} fontScaleRamp="title1">
|
||||
Title
|
||||
</Text>
|
||||
<Text style={{fontSize: 22}} fontScaleRamp="title2">
|
||||
Title 2
|
||||
</Text>
|
||||
<Text style={{fontSize: 20}} fontScaleRamp="title3">
|
||||
Title 3
|
||||
</Text>
|
||||
<Text style={{fontSize: 17}} fontScaleRamp="body">
|
||||
Body
|
||||
</Text>
|
||||
</View>
|
||||
<View style={boxStyle}>
|
||||
<Text style={boldStyle}>Without `fontScaleRamp`:</Text>
|
||||
<Text style={{fontSize: 34}}>Large Title</Text>
|
||||
<Text style={{fontSize: 28}}>Title</Text>
|
||||
<Text style={{fontSize: 22}}>Title 2</Text>
|
||||
<Text style={{fontSize: 20}}>Title 3</Text>
|
||||
<Text style={{fontSize: 17}}>Body</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
Загрузка…
Ссылка в новой задаче