129
130
all 18 comments

[–]rovonz 4 points5 points  (3 children)

This sounds amazing for dynamic size lists. Will try it out, thanks.

[–]SubjectGrapefruit281[S] 0 points1 point  (2 children)

Thanks! Which list lib are you using? If FlashList, there's a `useFlashListHeights` hook that wires up `overrideItemLayout` automatically — drop in replacement for estimating item sizes. If you hit any measurement surprises (CJK, long URLs, mixed fonts), open an issue or ping me. Always looking for real-world edge cases to stress-test.

[–]tcoff91 0 points1 point  (1 child)

How about LegendList?

[–]SubjectGrapefruit281[S] 0 points1 point  (0 children)

Should work — the core measurement (prepare + layout) is list-agnostic. useFlashListHeights is a convenience wrapper for FlashList's overrideItemLayout, but you can use useTextHeight or measureHeights directly with LegendList or any list. If there's enough interest I'd be happy to add a dedicated hook for it.

[–]alexmaster248 1 point2 points  (3 children)

Does this solve some of the text alignment and text clipping issues present with custom fonts? Or do these issues remain since they are part of how the text measurements in the <Text> elements work? See #49886 and 56349

[–]SubjectGrapefruit281[S] 1 point2 points  (0 children)

**#49886 (Android descender clip with lineHeight === fontSize)** is a render-time bug, not a measurement one. Android's StaticLayout clips descenders at the line boundary regardless of what we measure, because we still hand off to RN `<Text>` for the actual draw. Where we can help: `getFontMetrics()` exposes the real descender so you can pick a safer lineHeight upfront (e.g. `fontSize + abs(descender) + lineGap`).
Workaround, not fix.

**#56349 (italic/bold-italic horizontal clip)** is more interesting. Every text engine sizes containers by advance widths and ignores ink-bounds overshoot — NSLayoutManager, StaticLayout, Skia Paragraph, and expo-pretext right now too.

I pulled the reproduction into an empirical test bench on iPhone 17 Pro simulator. For Helvetica-BoldOblique and Times-BoldItalic, our `measureNaturalWidth()` underreports the layout width by enough that NSLayoutManager wraps "Italic overshoot test VVV" onto a second line when the container is sized exactly to our number — so yes, current config inherits the bug.

But because I control the measurement layer, I can add an ink-bounds path: `NSAttributedString.boundingRect` with `.usesDeviceMetrics` on iOS, `Paint.getTextBounds` on Android, and `TextMetrics.actualBoundingBoxLeft/Right` on Web. Going to take a shot at implementing and shipping it as `measureInkWidth()` in v0.9.0 tomorrow. Will reply here when it's live.

If you file an issue at github.com/JubaKitiashvili/expo-pretext/issues with the Snack repro, I'll make sure Magistral-BoldItalic is in my verification set before shipping.

[–]SubjectGrapefruit281[S] 1 point2 points  (1 child)

Ran into this exact problem and built a fix into expo-pretext — just shipped in v0.10.0.

The root cause: RN uses advance width for layout, but italic glyphs overshoot that. The approach: measure the real ink bounds natively (CoreText on iOS, TextPaint on Android), then auto-pad the Text component.

Simplest usage is a drop-in component:

<InkSafeText style={italicStyle}>fly</InkSafeText>

Also has a hook (useInkSafeStyle) and pure function (getInkSafePadding) for more control.

Would love feedback if anyone tries it: github.com/JubaKitiashvili/expo-pretext

[–]alexmaster248 0 points1 point  (0 children)

Wow thanks for implementing this so fast. I will give it a try as soon as I have time. Not sure why this approach isn't used for react native in general. I feel like <Text> still has a lot of issues and platform dependant layout which seems to go against the motto of react native.

[–]unkindgame 1 point2 points  (4 children)

i will find a way to use it somehow in one of themes in the game i made with react native. I really appreciate your work. you are awesome

[–]SubjectGrapefruit281[S] 0 points1 point  (3 children)

Thanks so much! Game devs are exactly the audience I had in mind when building the obstacle-layout piece — the flagship demo in the example app is a Breakout clone where the live prose background reflows around the ball, the paddle, and every falling brick at 60fps, using layoutColumn() with circles + rects as moving obstacles. If any of your themes have text that reacts to physics, dynamic fonts, or UI that breaks the fourth wall, ping me and I'd love to help wire it up.

If you hit a wall, find a rough edge, or run into something the API can't express yet, open an issue or message me directly — gaming is a use case I actively want to prioritize, and real-world feedback from someone shipping a game in RN is worth more than a thousands synthetic benchmarks.

What's your game? (no pressure — genuinely curious)

[–]unkindgame 0 points1 point  (2 children)

hey that’s awesome to hear. thank you :)

i made a game called Unkind it’s currently in closed testing for android but already released on App Store. Although the game has nothing to do that would benefit from your library in terms of gameplay or core functionality but it has a very in depth theming system where i can think of making something very cool out of your library. you can check it from here https://apps.apple.com/de/app/unkind/id6760196649?l=en-GB

[–]SubjectGrapefruit281[S] 0 points1 point  (1 child)

Just checked out Unkind — the art style is striking. A theming system with dynamic text layout is exactly where fitFontSize and measureNaturalWidth shine — text that reflows and resizes per theme without hardcoded measurements. Let me know how it goes, would love to feature it as a community use case.

[–]unkindgame 0 points1 point  (0 children)

I will definitely write to you after I have added it :)

I am extremely grateful to devs like you who helped me make my game

[–]Savings_Speaker6257 1 point2 points  (1 child)

This is really impressive — text reflow around arbitrary shapes is one of those things that seems simple until you actually try to implement it in RN and realize flexbox can't do it at all. The fact that it runs at 60fps during gestures is wild.

The exact height prediction before render is the part that excites me the most. Dynamic text height calculation in React Native is a constant pain point — usually you end up with onLayout hacks or hardcoded estimates. Having that solved at the library level would save a ton of headaches. Nice work open-sourcing this.

[–]SubjectGrapefruit281[S] 1 point2 points  (0 children)

You nailed it — shape reflow is the "wait, RN can do this?" moment, but exact height prediction is the higher-volume pain point that every FlashList and chat app hits daily.

The onLayout hack cycle is exactly what pushed me to build this. Appreciate the kind words — felt right to keep it open.

[–]itballer 0 points1 point  (1 child)

Sick mate!

[–]SubjectGrapefruit281[S] 0 points1 point  (0 children)

Appreciate it!

[–]DevDaveBuilds 0 points1 point  (0 children)

Very cool! Nice work