Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Accessibility] Dynamic Type support in iOS #519

Open
amgleitman opened this issue Sep 30, 2022 · 1 comment
Open

[Accessibility] Dynamic Type support in iOS #519

amgleitman opened this issue Sep 30, 2022 · 1 comment

Comments

@amgleitman
Copy link

amgleitman commented Sep 30, 2022

Introduction

One of iOS's accessibility features is to increase text size. However, iOS uses different font ramps for different kinds of text styles as described on Apple's typography page. This is known as Dynamic Type, and we would like to bring this functionality to React Native.

Details

For native iOS apps, the preferred way to distinguish between different kinds of text (e.g., titles, body text, captions, etc.) is to adopt different font styles. These font styles automatically grow and shrink according to specific scales as outlined on Apple's typography page. For example:

Text style Large (default) xxxLarge AX5
Large Title 34 40 60
Body 17 23 53

This concept doesn't exist on React Native as it currently stands. Different text styles are solely determined by what values to pass into a Text element's style prop, but there is nothing inherently baked into RN like there is HTML with h1, h2, etc. Since developers are in theory able to define whatever typography specs they want for their apps, we can't really infer text styles with 100% accuracy from text style alone.

RN's current strategy is to scale all text according to the "body" font ramp. The relevant ratios are hard-coded in three different locations within the RN codebase. This appears to be similar to Android's approach to larger text sizes, since Android uses scalable pixels for all of its font styles as per its typography page.

What I propose is a new iOS-only prop for Text elements that indicates which font ramp we should apply. We can then use UIFontMetrics to scale our fonts appropriately. This would be an opt-in feature in order to maintain backwards compatibility. Android will ignore this prop because all of its text styles use the same linear font ramp as explained in the previous paragraph.

At the moment, react-native-macos is planning on implementing this feature with the intention of upstreaming it to react-native, so it'll probably be easier to discuss finer implementation details once we have a working example.

@amgleitman amgleitman changed the title [Accessibility] Dynamic Text support in iOS [Accessibility] Dynamic Type support in iOS Oct 1, 2022
@amgleitman
Copy link
Author

A proposed implementation in react-native-macos can be found here: microsoft/react-native-macos#1445

facebook-github-bot pushed a commit to facebook/react-native that referenced this issue Nov 16, 2022
Summary:
This adds Dynamic Type support in iOS as described [here](react-native-community/discussions-and-proposals#519).

`Text` elements have a new prop, `dynamicTypeRamp`, that allows users to specify which font ramp a particular `Text` element should take on as the OS's accessibility setting for text size. The different types line up with different values of `UIFontTextStyle`. If not specified, we default to the current behavior.

~~For the moment, this change is only for Paper. I tried applying a corresponding change to Fabric by adding an additional field to [`facebook::react::TextAttributes`](https://github.com/facebook/react-native/blob/main/ReactCommon/react/renderer/attributedstring/TextAttributes.h) and changing [`RCTEffectiveFontSizeMultiplierFromTextAttributes`](https://github.com/facebook/react-native/blob/afb124dcf0cdf0db525acc7cfd2cea2742c64068/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm#L79-L84) to use that new field, but in the process I discovered that this function doesn't seem to ever get called, hence [this bug](#34990

## Changelog

[iOS] [Added] - Dynamic Type support

Pull Request resolved: #35017

Test Plan:
Validated with a test page in RNTester. Screenshots follow:

A) Default text size
B) Largest non-accessibility text size
C) Largest accessibility text size, split across two screenshots due to size

| A | B | C |
|-|-|-|
| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 08](https://user-images.githubusercontent.com/717674/196562746-c8bbf53d-3c70-4e55-8600-0cfed8aacf5d.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 55](https://user-images.githubusercontent.com/717674/196563051-68bb0e34-c573-47ed-8c19-58ae45a7ce2b.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 33](https://user-images.githubusercontent.com/717674/196563185-61ede5ee-e79e-4af5-84a7-8f1e230a25f8.png) |
||| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 42](https://user-images.githubusercontent.com/717674/196563208-2242efa2-5f24-466d-80f5-eb57a7678a67.png) |

Reviewed By: sammy-SC

Differential Revision: D40779346

Pulled By: NickGerleman

fbshipit-source-id: efc7a8e9810a93afc82c5def97af15a2e8453d90
kelset pushed a commit to facebook/react-native that referenced this issue Nov 22, 2022
Summary:
This adds Dynamic Type support in iOS as described [here](react-native-community/discussions-and-proposals#519).

`Text` elements have a new prop, `dynamicTypeRamp`, that allows users to specify which font ramp a particular `Text` element should take on as the OS's accessibility setting for text size. The different types line up with different values of `UIFontTextStyle`. If not specified, we default to the current behavior.

~~For the moment, this change is only for Paper. I tried applying a corresponding change to Fabric by adding an additional field to [`facebook::react::TextAttributes`](https://github.com/facebook/react-native/blob/main/ReactCommon/react/renderer/attributedstring/TextAttributes.h) and changing [`RCTEffectiveFontSizeMultiplierFromTextAttributes`](https://github.com/facebook/react-native/blob/afb124dcf0cdf0db525acc7cfd2cea2742c64068/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm#L79-L84) to use that new field, but in the process I discovered that this function doesn't seem to ever get called, hence [this bug](#34990

## Changelog

[iOS] [Added] - Dynamic Type support

Pull Request resolved: #35017

Test Plan:
Validated with a test page in RNTester. Screenshots follow:

A) Default text size
B) Largest non-accessibility text size
C) Largest accessibility text size, split across two screenshots due to size

| A | B | C |
|-|-|-|
| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 08](https://user-images.githubusercontent.com/717674/196562746-c8bbf53d-3c70-4e55-8600-0cfed8aacf5d.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 55](https://user-images.githubusercontent.com/717674/196563051-68bb0e34-c573-47ed-8c19-58ae45a7ce2b.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 33](https://user-images.githubusercontent.com/717674/196563185-61ede5ee-e79e-4af5-84a7-8f1e230a25f8.png) |
||| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 42](https://user-images.githubusercontent.com/717674/196563208-2242efa2-5f24-466d-80f5-eb57a7678a67.png) |

Reviewed By: sammy-SC

Differential Revision: D40779346

Pulled By: NickGerleman

fbshipit-source-id: efc7a8e9810a93afc82c5def97af15a2e8453d90

# Conflicts:
#	packages/rn-tester/Podfile.lock
OlimpiaZurek pushed a commit to OlimpiaZurek/react-native that referenced this issue May 22, 2023
Summary:
This adds Dynamic Type support in iOS as described [here](react-native-community/discussions-and-proposals#519).

`Text` elements have a new prop, `dynamicTypeRamp`, that allows users to specify which font ramp a particular `Text` element should take on as the OS's accessibility setting for text size. The different types line up with different values of `UIFontTextStyle`. If not specified, we default to the current behavior.

~~For the moment, this change is only for Paper. I tried applying a corresponding change to Fabric by adding an additional field to [`facebook::react::TextAttributes`](https://github.com/facebook/react-native/blob/main/ReactCommon/react/renderer/attributedstring/TextAttributes.h) and changing [`RCTEffectiveFontSizeMultiplierFromTextAttributes`](https://github.com/facebook/react-native/blob/afb124dcf0cdf0db525acc7cfd2cea2742c64068/ReactCommon/react/renderer/textlayoutmanager/platform/ios/RCTAttributedTextUtils.mm#L79-L84) to use that new field, but in the process I discovered that this function doesn't seem to ever get called, hence [this bug](facebook#34990

## Changelog

[iOS] [Added] - Dynamic Type support

Pull Request resolved: facebook#35017

Test Plan:
Validated with a test page in RNTester. Screenshots follow:

A) Default text size
B) Largest non-accessibility text size
C) Largest accessibility text size, split across two screenshots due to size

| A | B | C |
|-|-|-|
| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 08](https://user-images.githubusercontent.com/717674/196562746-c8bbf53d-3c70-4e55-8600-0cfed8aacf5d.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 17 55](https://user-images.githubusercontent.com/717674/196563051-68bb0e34-c573-47ed-8c19-58ae45a7ce2b.png) | ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 33](https://user-images.githubusercontent.com/717674/196563185-61ede5ee-e79e-4af5-84a7-8f1e230a25f8.png) |
||| ![Simulator Screen Shot - iPad (9th generation) - 2022-10-18 at 16 18 42](https://user-images.githubusercontent.com/717674/196563208-2242efa2-5f24-466d-80f5-eb57a7678a67.png) |

Reviewed By: sammy-SC

Differential Revision: D40779346

Pulled By: NickGerleman

fbshipit-source-id: efc7a8e9810a93afc82c5def97af15a2e8453d90
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant