From 12b3bef02f930e3d90c3be7a37930ea446477e2a Mon Sep 17 00:00:00 2001 From: Joe Vilches Date: Thu, 3 Oct 2024 14:12:57 -0700 Subject: [PATCH] Plumbing to get boxSizing prop to Yoga round 2 Summary: Relanding this as we had to unship due to some issues, which are fixed in the previous diff Changelog: [Internal] Differential Revision: D63844167 --- .../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 455bea39f42b95..428bca4a1fbba7 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 0c8635e12759f5..3c7aedb1948900 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 bc6090d77881d2..40f1b1bed35176 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 9226d25e395fcb..88f80f23a11ff8 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 0502ec6f1ab564..d6902bc8bcd3d2 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 2bceffd5851558..8d2e1f4cc2c15d 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 @@ -8003,6 +8003,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 508e3aeb6cac0a..3a3f7ee8cba3a6 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 8f0bcbb33ea11d..b1b71c0ebbf777 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,