-
Notifications
You must be signed in to change notification settings - Fork 143
Description
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.