Skip to content

Commit

Permalink
Support system font families on iOS (facebook#47544)
Browse files Browse the repository at this point in the history
Summary:
Apple introduced system font families

```
font-family: system-ui;
font-family: ui-sans-serif;
font-family: ui-serif;
font-family: ui-monospace;
font-family: ui-rounded;
```

for Safari at 2020 (see https://developer.apple.com/videos/play/wwdc2020/10663/?time=872).

This PR implementation supports above font families on iOS.

bypass-github-export-checks

## Changelog:

[IOS] [ADDED] - Support system font families (system-ui, ui-sans-serif, ui-serif, ui-monospace, and ui-rounded) on iOS

Pull Request resolved: facebook#47544

Test Plan: Run `RNTester` and view the `Text` component where shows the usage for those font families.

Reviewed By: NickGerleman

Differential Revision: D65761307

Pulled By: cipolleschi

fbshipit-source-id: 18628160b7753b314389e887cddfe9d0ec96ee1d
  • Loading branch information
cxa authored and facebook-github-bot committed Dec 12, 2024
1 parent 61e876e commit 1763321
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,19 @@ static RCTFontStyle RCTGetFontStyle(UIFont *font)
return font;
}

static UIFontDescriptorSystemDesign RCTGetFontDescriptorSystemDesign(NSString *family)
{
static NSDictionary<NSString *, NSString *> *systemDesigns = @{
@"system-ui" : UIFontDescriptorSystemDesignDefault,
@"ui-sans-serif" : UIFontDescriptorSystemDesignDefault,
@"ui-serif" : UIFontDescriptorSystemDesignSerif,
@"ui-rounded" : UIFontDescriptorSystemDesignRounded,
@"ui-monospace" : UIFontDescriptorSystemDesignMonospaced
};

return systemDesigns[family];
}

UIFont *RCTFontWithFontProperties(RCTFontProperties fontProperties)
{
RCTFontProperties defaultFontProperties = RCTDefaultFontProperties();
Expand All @@ -154,7 +167,16 @@ static RCTFontStyle RCTGetFontStyle(UIFont *font)
assert(!isnan(fontProperties.sizeMultiplier));
CGFloat effectiveFontSize = fontProperties.sizeMultiplier * fontProperties.size;
UIFont *font;
if ([fontProperties.family isEqualToString:defaultFontProperties.family]) {
UIFontDescriptorSystemDesign design = RCTGetFontDescriptorSystemDesign([fontProperties.family lowercaseString]);
if (design) {
// Create a system font which `-fontDescriptorWithDesign:` asks for
// (see:
// https://developer.apple.com/documentation/uikit/uifontdescriptor/3151797-fontdescriptorwithdesign?language=objc)
// It's OK to use `RCTDefaultFontWithFontProperties` which creates a system font
font = RCTDefaultFontWithFontProperties(fontProperties);
UIFontDescriptor *descriptor = [font.fontDescriptor fontDescriptorWithDesign:design];
font = [UIFont fontWithDescriptor:descriptor size:effectiveFontSize];
} else if ([fontProperties.family isEqualToString:defaultFontProperties.family]) {
// Handle system font as special case. This ensures that we preserve
// the specific metrics of the standard system font as closely as possible.
font = RCTDefaultFontWithFontProperties(fontProperties);
Expand Down
47 changes: 47 additions & 0 deletions packages/rn-tester/js/examples/Text/TextExample.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,53 @@ class TextWithCapBaseBox extends React.Component<
}

const examples = [
{
title: 'iOS System Font Families (iOS only)',
name: 'iOSSystemFontFamilies',
description:
('Shows system font families including system-ui/ui-sans-serif, ui-serif, ui-monospace, and ui-rounded': string),
render: function (): React.Node {
return (
<View testID={'ios-font-families'}>
<Text
style={{
fontFamily: 'system-ui',
fontSize: 32,
marginBottom: 20,
}}>
`fontFamily: system-ui` (same as `ui-sans-serif`)
</Text>
<Text
style={{
fontFamily: 'ui-sans-serif',
fontSize: 32,
marginBottom: 20,
}}>
`fontFamily: ui-sans-serif` (same as `system-ui`)
</Text>
<Text
style={{fontFamily: 'ui-serif', fontSize: 32, marginBottom: 20}}>
`fontFamily: ui-serif`
</Text>
<Text
style={{
fontFamily: 'ui-monospace',
fontSize: 32,
marginBottom: 20,
}}>
`fontFamily: ui-monospace`
</Text>
<Text
style={{
fontFamily: 'ui-rounded',
fontSize: 32,
}}>
`fontFamily: ui-rounded`
</Text>
</View>
);
},
},
{
title: 'Wrap',
render: function (): React.Node {
Expand Down

0 comments on commit 1763321

Please sign in to comment.