Skip to content

fix(ios/fabric): stop overriding JS width in Yoga layout#1036

Open
Scr3nt wants to merge 2 commits intoreact-native-datetimepicker:masterfrom
Scr3nt:fix/fabric-width-override-ios
Open

fix(ios/fabric): stop overriding JS width in Yoga layout#1036
Scr3nt wants to merge 2 commits intoreact-native-datetimepicker:masterfrom
Scr3nt:fix/fabric-width-override-ios

Conversation

@Scr3nt
Copy link

@Scr3nt Scr3nt commented Feb 16, 2026

Summary

The adopt method in ComponentDescriptors.h calls setSize() with both width and height from sizeThatFits:UILayoutFittingCompressedSize. Because UIDatePicker has a native minimum width of 280pt, this forces a fixed width on the Yoga node, overriding any JS style such as width: "100%".

This PR changes the native layout code to only set the height from the native measurement, letting the JS side control the width through regular Yoga styles.

Changes

  • ShadowNodes.h: Add setMeasuredHeight(float) method that only sets yoga::Dimension::Height on the Yoga node style, leaving the width untouched
  • ComponentDescriptors.h: Replace setSize() call with setMeasuredHeight() in the adopt method

Before / After

Simulator Screenshot - iPhone 17 Pro - 2026-02-16 at 11 05 49 Simulator Screenshot - iPhone 17 Pro - 2026-02-16 at 11 17 29

Fixes #1014

The `adopt` method in `ComponentDescriptors.h` called `setSize()` with
both width and height from `sizeThatFits:UILayoutFittingCompressedSize`.
Because `UIDatePicker` has a native minimum width of 280pt, this forced
a fixed width on the Yoga node, overriding any JS style such as
`width: "100%"`.

Only set the **height** from the native measurement and let the JS side
control the width through regular Yoga styles.

Adds `setMeasuredHeight()` to `RNDateTimePickerShadowNode` which sets
only `yoga::Dimension::Height` on the Yoga node style, leaving the
width dimension untouched.

Fixes react-native-datetimepicker#1014
@camcam-lemon
Copy link

Thank you so much for this PR. I have been struggling with this issue for a long time.

While testing my product, I found an additional issue: when using mode="datetime" with display="inline" on iOS, the time picker row
is cut off because sizeThatFits:UILayoutFittingCompressedSize does not include the time picker row height in its
measurement.

I was able to fix this by adding the following to updateMeasurements in RNDateTimePickerComponentView.mm:

if (@available(iOS 14.0, *)) {
  if (_dummyPicker.datePickerMode == UIDatePickerModeDateAndTime &&
    _dummyPicker.preferredDatePickerStyle == UIDatePickerStyleInline) {
    UIDatePicker *timePicker = [UIDatePicker new];
    timePicker.datePickerMode = UIDatePickerModeTime;
    timePicker.preferredDatePickerStyle = UIDatePickerStyleInline;
    CGSize timeSize = [timePicker sizeThatFits:UILayoutFittingCompressedSize];
    size.height += timeSize.height;
  }
}

This measures the height of a time-only picker separately and adds it to the total height. With this change, the datetime nline picker displays correctly including the time picker row.

before after
スクリーンショット 2026-02-18 2 05 10 スクリーンショット 2026-02-18 2 05 31

Note: I have only verified this fix with mode="datetime" + display="inline". I have not yet tested whether it affects
other mode/display combinations, so further testing may be needed.
sorry

@Scr3nt
Copy link
Author

Scr3nt commented Feb 17, 2026

I made the fix and tested all modes.
Thanks!

@camcam-lemon
Copy link

Thank you fix!!

@vonovak
Copy link
Member

vonovak commented Mar 6, 2026

Hello and thanks for the PR,
I have a few questions:

  1. can you update the screenshot so it's clear what the difference is? I may be blind but I don't see it.
  2. if the width isn't set from the layout measurement now, who does set the width? Is this breaking? Can we make it so that by default the width is measured as before, and we only use custom width when it's set?
    Thank you 🙂

@Scr3nt
Copy link
Author

Scr3nt commented Mar 7, 2026

Hello and thanks for the PR, I have a few questions:

  1. can you update the screenshot so it's clear what the difference is? I may be blind but I don't see it.
  2. if the width isn't set from the layout measurement now, who does set the width? Is this breaking? Can we make it so that by default the width is measured as before, and we only use custom width when it's set?
    Thank you 🙂

Thanks for the review!

About the screenshots: the first one shows the picker constrained to ~280pt (the native minimum width forced by setSize()), while the second one shows it properly filling the available width as expected from the JS layout.

About the width question:

Previously, ComponentDescriptors.h called setSize() which set both width and height on the Yoga node style, effectively hardcoding the native measurement (minimum ~280pt) and overriding any JS style like width: "100%" or flex: 1.

Now, only the height is set from the native side (via the new setMeasuredHeight()). The width is handled by standard Yoga layout just like most other React Native components. This means:

If the user sets width: "100%" or flex: 1, it works as expected.
If no explicit width is set, Yoga's default behavior applies (alignItems: 'stretch' from the parent will stretch it to fill available width, which is the default).
So in practice, this is not breaking the previous behavior (picker stuck at ~280pt regardless of JS styles) was actually the bug (#1014). The new behavior aligns with how every other React Native component handles width: the JS side controls it through normal layout props.

Making it opt-in (measure width by default, skip only when a custom width is set) would require inspecting the Yoga node's style to check if a width was explicitly set by the user, which adds complexity for no real benefit. The standard RN pattern is to let Yoga handle width from the JS side.

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

Successfully merging this pull request may close these issues.

iOS DatePicker Width Issue

3 participants