Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(Android)!: overflowing text in native header (software-mansion#2325)
## Description > [!caution] This PR includes **BREAKING CHANGES** Corresponding PR in `react-navigation`: * react-navigation/react-navigation#12125 Fixes software-mansion#1946 This PR refactors the header config component to use flex-box model instead of absolute positioning in Yoga layer. This is required so that the Yoga layouts children of header config with respect to one another (not absolutely), so that the title can be properly truncated. In the end, the subviews are laid out by system anyway, thus we send additional information, such as padding / margins from native side to the shadow tree, so that we can adjust for these in Yoga layout. > [!important] This PR introduces a bug in very first few frames - before the information from HostTree is propagated to ShadowTree the header title might not be truncated properly. This is known issue and based on the same mechanism and "jumping content" due to not including header dimensions in first Yoga layout. <!-- ### Before / After `headerTitleAlign: 'left'`, long title as string ⬇️ | Before ✅ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/ec7dd405-7244-4c18-b96d-5ffd79be78b8"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/7b0086b5-3554-4b76-99d5-302d03cab96e"></img> | | Works fine, cause `title` is passed as regular string to native side, where it is simply assigned to `toolbar.title` & `AppCompatTextView` is used by Android. `headerTitleAlign: 'left'`, `headerLeft`, long title as string ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/228f64b9-4ca8-4c65-8128-a5097bbae595"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/e1426702-a020-4113-a271-588c62e385db"></img> | | Title despite being a plain string is wrapped inside `HeaderTitle` component & rendered as a `Text` inside `SubviewLeft` together with `HeaderLeft`. The text overflows, because subview is positioned as `absolute`: it does not respect native toolbar's content inset (left padding), as Yoga has no information of it & the text view does measure itself with width of whole containing box (which is the `HeaderConfig` which has width of full screen). What's also important to notice is that in this configuration `backButtonIcon` is disabled. `headerTitleAlign: 'left'`, `headerRight`, long title as string ⬇️ | Before ✅ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/2af7a845-4c7c-419a-a9bc-5e44525fb935"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/7afaa643-7a00-42a4-8cb2-3d4fa9a9781b"></img> | | Works ok, because text is assigned to `toolbar.title`, thus `AppCompatTextView` is in use & native layout takes care of truncating the text & respecting the `HeaderRight`. We good here. `headerTitleAlign: 'left'`, `headerLeft`, `headerRight`, long title as string ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/186b8534-00e0-4dc6-b4b0-45a12e9a84c5"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/3bfc1bd6-3e9f-4ede-a375-7fa329e6a4f0"></img> | | Text is put together with `HeaderLeft` into `SubviewLeft` & rendered inside `Text`. Subviews are positioned as `absolute` & Yoga measures text with full width of the screen & does not take into account `absolute` siblings. Notice that in the second row of screenshots `backButtonIcon` is also not present. `headerTitleAlign: 'left'`, long title as `Text` ⬇️ | Before ✅ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/ec7dd405-7244-4c18-b96d-5ffd79be78b8"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/7b0086b5-3554-4b76-99d5-302d03cab96e"></img> | | `headerTitleAlign: 'left'`, `headerLeft`, long title as `Text` ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/34046637-886e-44e7-8588-2143cc5ec7bc"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/b57d9beb-0c5e-405d-b920-393bee801a07"></img> | | `headerTitleAlign: 'left'`, `headerRight`, long title as `Text` ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/83afc32a-b8f5-4ffc-9570-8b9034e4abb9"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/04d58470-53c3-45bb-a335-f6265b34c1e6"></img> | | `headerTitleAlign: 'left'`, `headerLeft`, `headerRight`, long title as `Text` ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/30dcc02e-4fa4-4a89-9add-b925e1290bb2"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/716de207-aeec-4766-8cab-09f535f2fac2"></img> | | `headerTitleAlign: 'center'`, long title as string ⬇️ | Before ✅ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/58194a20-9373-4352-a2b6-ada2982c2646"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/6c31121d-09d9-40f5-8bf8-688cd4d1a28e"></img> | | `headerTitleAlign: 'center'`, `headerLeft`, long title as string ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/c8c2507a-fb23-4265-b257-e2a469e0cbae"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/cdc6efaa-83f8-4e7d-9aba-68ad0b276bbb"></img> | | `headerTitleAlign: 'center'`, `headerRight`, long title as string ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/c83cf46a-0b5a-49cf-96b2-c602df090a83"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/e33623ae-0a32-46d6-9355-2ce353c60a66"></img> | | `headerTitleAlign: 'center'`, `headerLeft`, `headerRight`, long title as string ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/a8c626b8-7b9d-4b91-b2f9-4a94ae10fd4a"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/90dc5994-2aca-4ce2-8360-4baea67734be"></img> | | `headerTitleAlign: 'center'`, long title as `Text` ⬇️ | Before ✅ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/b119f64a-4638-4e28-abf8-33b23290d195"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/0f0a92e4-305e-429a-b852-623dc06f43f8"></img> | | `headerTitleAlign: 'center'`, `headerLeft`, long title as `Text` ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/1966cca9-1cce-47f7-8a87-a0b687edfe7a"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/5ea1bb3a-1926-4abf-839c-3ddac73c74aa"></img> | | `headerTitleAlign: 'center'`, `headerRight`, long title as `Text` ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/c2801a4d-7f63-4e67-acb3-0ce55e09e937"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/789de0b6-f703-45dd-aeb0-8e3082bbf267"></img> | | `headerTitleAlign: 'center'`, `headerLeft`, `headerRight`, long title as `Text` ⬇️ | Before ❌ | After ❓| |--------|--------| | <img width="480" height="200" src="https://github.com/user-attachments/assets/9159990b-845f-4d26-b103-d1a5ecdec656"></img> | | | <img width="480" height="200" src="https://github.com/user-attachments/assets/07cdf821-9503-4f68-a87f-9dc7a96ea032"></img> | | --> ## Changes <!-- Please describe things you've changed here, make a **high level** overview, if change is simple you can omit this section. For example: - Updated `about.md` docs --> <!-- ## Screenshots / GIFs Here you can add screenshots / GIFs documenting your change. You can add before / after section if you're changing some behavior. ### Before ### After --> ## Test code and steps to reproduce I've tried to test these changes carefully, however there still might be some bugs. It would be nice if we could get rid of them during beta-phase of 4.0. Below I paste my test matrix I conducted on `Test1649` on both platforms and architectures. ![image](https://github.com/user-attachments/assets/504fad12-dbd4-4648-871d-3c65215758ce) ## Checklist - [x] Included code example that can be used to test this change - [ ] Ensured that CI passes
- Loading branch information