From 39b9cf2412d0632c585db695586d9bcee6fdf916 Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Tue, 1 Oct 2024 15:19:22 -0700 Subject: [PATCH] Plumbing to get boxSizing prop to Yoga (#46766) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/46766 tsia! Changelog: [Internal] Reviewed By: rozele Differential Revision: D63430964 fbshipit-source-id: f57e9a51236cb4c7d4c284af6987f88f9c7597da --- .../View/ReactNativeStyleAttributes.js | 1 + .../NativeComponent/BaseViewConfig.android.js | 1 + .../NativeComponent/BaseViewConfig.ios.js | 1 + .../Libraries/StyleSheet/StyleSheetTypes.d.ts | 1 + .../Libraries/StyleSheet/StyleSheetTypes.js | 13 +++++++++++ .../__snapshots__/public-api-test.js.snap | 1 + .../components/view/YogaStylableProps.cpp | 7 ++++++ .../renderer/components/view/conversions.h | 22 +++++++++++++++++++ 8 files changed, 47 insertions(+) diff --git a/packages/react-native/Libraries/Components/View/ReactNativeStyleAttributes.js b/packages/react-native/Libraries/Components/View/ReactNativeStyleAttributes.js index 455bea39f42..428bca4a1fb 100644 --- a/packages/react-native/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/packages/react-native/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -36,6 +36,7 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = { borderRightWidth: true, borderStartWidth: true, borderTopWidth: true, + boxSizing: true, columnGap: true, borderWidth: true, bottom: true, diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js index 0c8635e1275..3c7aedb1948 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.android.js @@ -227,6 +227,7 @@ const validAttributesForNonEventProps = { justifyContent: true, overflow: true, display: true, + boxSizing: true, margin: true, marginBlock: true, diff --git a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js index bc6090d7788..40f1b1bed35 100644 --- a/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js +++ b/packages/react-native/Libraries/NativeComponent/BaseViewConfig.ios.js @@ -348,6 +348,7 @@ const validAttributesForNonEventProps = { alignContent: true, position: true, aspectRatio: true, + boxSizing: true, // Also declared as ViewProps // overflow: true, diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts index 9226d25e395..88f80f23a11 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.d.ts @@ -55,6 +55,7 @@ export interface FlexStyle { borderTopWidth?: number | undefined; borderWidth?: number | undefined; bottom?: DimensionValue | undefined; + boxSizing?: 'border-box' | 'content-box' | undefined; display?: 'none' | 'flex' | undefined; end?: DimensionValue | undefined; flex?: number | undefined; diff --git a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js index 0502ec6f1ab..d6902bc8bcd 100644 --- a/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js +++ b/packages/react-native/Libraries/StyleSheet/StyleSheetTypes.js @@ -612,6 +612,19 @@ type ____LayoutStyle_Internal = $ReadOnly<{ */ aspectRatio?: number | string, + /** + * Box sizing controls whether certain size properties apply to the node's + * content box or border box. The size properties in question include `width`, + * `height`, `minWidth`, `minHeight`, `maxWidth`, `maxHeight`, and `flexBasis`. + * + * e.g: Say a node has 10px of padding and 10px of borders on all + * sides and a defined `width` and `height` of 100px and 50px. Then the total + * size of the node (content area + padding + border) would be 100px by 50px + * under `boxSizing: border-box` and 120px by 70px under + * `boxSizing: content-box`. + */ + boxSizing?: 'border-box' | 'content-box', + /** `zIndex` controls which components display on top of others. * Normally, you don't use `zIndex`. Components render according to * their order in the document tree, so later components draw over diff --git a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap index 554b0a19eea..e19e61a528b 100644 --- a/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap +++ b/packages/react-native/Libraries/__tests__/__snapshots__/public-api-test.js.snap @@ -7999,6 +7999,7 @@ type ____LayoutStyle_Internal = $ReadOnly<{ flexShrink?: number, flexBasis?: number | string, aspectRatio?: number | string, + boxSizing?: \\"border-box\\" | \\"content-box\\", zIndex?: number, direction?: \\"inherit\\" | \\"ltr\\" | \\"rtl\\", rowGap?: number | string, diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp index 508e3aeb6ca..3a3f7ee8cba 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp +++ b/packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp @@ -533,6 +533,13 @@ YogaStylableProps::YogaStylableProps( sourceProps.yogaStyle.aspectRatio(), yogaStyle.aspectRatio())); + yogaStyle.setBoxSizing(convertRawProp( + context, + rawProps, + "boxSizing", + sourceProps.yogaStyle.boxSizing(), + yogaStyle.boxSizing())); + convertRawPropAliases(context, sourceProps, rawProps); }; diff --git a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h index 8f0bcbb33ea..b1b71c0ebbf 100644 --- a/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h +++ b/packages/react-native/ReactCommon/react/renderer/components/view/conversions.h @@ -226,6 +226,28 @@ inline void fromRawValue( LOG(ERROR) << "Could not parse yoga::FlexDirection: " << stringValue; } +inline void fromRawValue( + const PropsParserContext& /*context*/, + const RawValue& value, + yoga::BoxSizing& result) { + result = yoga::BoxSizing::BorderBox; + react_native_expect(value.hasType()); + if (!value.hasType()) { + return; + } + auto stringValue = (std::string)value; + if (stringValue == "border-box") { + result = yoga::BoxSizing::BorderBox; + return; + } + if (stringValue == "content-box") { + result = yoga::BoxSizing::ContentBox; + return; + } + + LOG(ERROR) << "Could not parse yoga::BoxSizing: " << stringValue; +} + inline void fromRawValue( const PropsParserContext& context, const RawValue& value,