diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js
index 06f1d6df54ef6f..8b93bb79072e60 100644
--- a/Libraries/Components/View/ReactNativeStyleAttributes.js
+++ b/Libraries/Components/View/ReactNativeStyleAttributes.js
@@ -46,6 +46,13 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
flexWrap: true,
gap: true,
height: true,
+ inset: true,
+ insetBlock: true,
+ insetBlockEnd: true,
+ insetBlockStart: true,
+ insetInline: true,
+ insetInlineEnd: true,
+ insetInlineStart: true,
justifyContent: true,
left: true,
margin: true,
diff --git a/Libraries/NativeComponent/BaseViewConfig.android.js b/Libraries/NativeComponent/BaseViewConfig.android.js
index b394cf551bd6be..b25e9ed0dce6b0 100644
--- a/Libraries/NativeComponent/BaseViewConfig.android.js
+++ b/Libraries/NativeComponent/BaseViewConfig.android.js
@@ -258,6 +258,14 @@ const validAttributesForNonEventProps = {
top: true,
bottom: true,
+ inset: true,
+ insetBlock: true,
+ insetBlockEnd: true,
+ insetBlockStart: true,
+ insetInline: true,
+ insetInlineEnd: true,
+ insetInlineStart: true,
+
position: true,
style: ReactNativeStyleAttributes,
diff --git a/Libraries/NativeComponent/BaseViewConfig.ios.js b/Libraries/NativeComponent/BaseViewConfig.ios.js
index 8d371596dba5d6..52897e611d5fd5 100644
--- a/Libraries/NativeComponent/BaseViewConfig.ios.js
+++ b/Libraries/NativeComponent/BaseViewConfig.ios.js
@@ -232,6 +232,14 @@ const validAttributesForNonEventProps = {
bottom: true,
left: true,
+ inset: true,
+ insetBlock: true,
+ insetBlockEnd: true,
+ insetBlockStart: true,
+ insetInline: true,
+ insetInlineEnd: true,
+ insetInlineStart: true,
+
width: true,
height: true,
diff --git a/Libraries/StyleSheet/StyleSheetTypes.d.ts b/Libraries/StyleSheet/StyleSheetTypes.d.ts
index 427265e580885a..4a77bada47948f 100644
--- a/Libraries/StyleSheet/StyleSheetTypes.d.ts
+++ b/Libraries/StyleSheet/StyleSheetTypes.d.ts
@@ -59,6 +59,13 @@ export interface FlexStyle {
flexShrink?: number | undefined;
flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse' | undefined;
height?: number | string | undefined;
+ inset?: number | string | undefined;
+ insetBlock?: number | string | undefined;
+ insetBlockEnd?: number | string | undefined;
+ insetBlockStart?: number | string | undefined;
+ insetInline?: number | string | undefined;
+ insetInlineEnd?: number | string | undefined;
+ insetInlineStart?: number | string | undefined;
justifyContent?:
| 'flex-start'
| 'flex-end'
diff --git a/Libraries/StyleSheet/StyleSheetTypes.js b/Libraries/StyleSheet/StyleSheetTypes.js
index d2f18a74024cc9..34ba38b3804a9c 100644
--- a/Libraries/StyleSheet/StyleSheetTypes.js
+++ b/Libraries/StyleSheet/StyleSheetTypes.js
@@ -132,6 +132,22 @@ type ____LayoutStyle_Internal = $ReadOnly<{
*/
top?: DimensionValue,
+ /** `inset` is a shorthand that corresponds to the top, right, bottom, and/or left properties.
+ *
+ * It works similarly to `inset` in CSS, but in React Native you
+ * must use points or percentages. Ems and other units are not supported.
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/CSS/inset
+ * for more details of how `inset` affects layout.
+ */
+ inset?: DimensionValue,
+ insetBlock?: DimensionValue,
+ insetBlockEnd?: DimensionValue,
+ insetBlockStart?: DimensionValue,
+ insetInline?: DimensionValue,
+ insetInlineEnd?: DimensionValue,
+ insetInlineStart?: DimensionValue,
+
/** `minWidth` is the minimum width for this component, in logical pixels.
*
* It works similarly to `min-width` in CSS, but in React Native you
diff --git a/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp
index 4bc5bac4a971b0..93c3b543f10b5a 100644
--- a/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp
+++ b/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp
@@ -333,6 +333,21 @@ void YogaLayoutableShadowNode::updateYogaProps() {
YGStyle result{baseStyle};
// Aliases with precedence
+ if (!props.inset.isUndefined()) {
+ result.position()[YGEdgeAll] = props.inset;
+ }
+ if (!props.insetBlock.isUndefined()) {
+ result.position()[YGEdgeVertical] = props.insetBlock;
+ }
+ if (!props.insetInline.isUndefined()) {
+ result.position()[YGEdgeHorizontal] = props.insetInline;
+ }
+ if (!props.insetInlineEnd.isUndefined()) {
+ result.position()[YGEdgeEnd] = props.insetInlineEnd;
+ }
+ if (!props.insetInlineStart.isUndefined()) {
+ result.position()[YGEdgeStart] = props.insetInlineStart;
+ }
if (!props.marginInline.isUndefined()) {
result.margin()[YGEdgeHorizontal] = props.marginInline;
}
@@ -359,6 +374,12 @@ void YogaLayoutableShadowNode::updateYogaProps() {
}
// Aliases without precedence
+ if (CompactValue(result.position()[YGEdgeBottom]).isUndefined()) {
+ result.position()[YGEdgeBottom] = props.insetBlockEnd;
+ }
+ if (CompactValue(result.position()[YGEdgeTop]).isUndefined()) {
+ result.position()[YGEdgeTop] = props.insetBlockStart;
+ }
if (CompactValue(result.margin()[YGEdgeTop]).isUndefined()) {
result.margin()[YGEdgeTop] = props.marginBlockStart;
}
diff --git a/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp b/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp
index 614da3b2fbef88..17e342dd6ee14c 100644
--- a/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp
+++ b/ReactCommon/react/renderer/components/view/YogaStylableProps.cpp
@@ -134,6 +134,19 @@ void YogaStylableProps::setProp(
REBUILD_FIELD_YG_EDGES(border, "border", "Width");
// Aliases
+ RAW_SET_PROP_SWITCH_CASE(inset, "inset", CompactValue::ofUndefined());
+ RAW_SET_PROP_SWITCH_CASE(
+ insetBlock, "insetBlock", CompactValue::ofUndefined());
+ RAW_SET_PROP_SWITCH_CASE(
+ insetBlockEnd, "insetBlockEnd", CompactValue::ofUndefined());
+ RAW_SET_PROP_SWITCH_CASE(
+ insetBlockStart, "insetBlockStart", CompactValue::ofUndefined());
+ RAW_SET_PROP_SWITCH_CASE(
+ insetInline, "insetInline", CompactValue::ofUndefined());
+ RAW_SET_PROP_SWITCH_CASE(
+ insetInlineEnd, "insetInlineEnd", CompactValue::ofUndefined());
+ RAW_SET_PROP_SWITCH_CASE(
+ insetInlineStart, "insetInlineStart", CompactValue::ofUndefined());
RAW_SET_PROP_SWITCH_CASE(
marginInline, "marginInline", CompactValue::ofUndefined());
RAW_SET_PROP_SWITCH_CASE(
@@ -245,6 +258,48 @@ void YogaStylableProps::convertRawPropAliases(
const PropsParserContext &context,
YogaStylableProps const &sourceProps,
RawProps const &rawProps) {
+ inset = convertRawProp(
+ context,
+ rawProps,
+ "inset",
+ sourceProps.inset,
+ CompactValue::ofUndefined());
+ insetBlock = convertRawProp(
+ context,
+ rawProps,
+ "insetBlock",
+ sourceProps.insetBlock,
+ CompactValue::ofUndefined());
+ insetBlockEnd = convertRawProp(
+ context,
+ rawProps,
+ "insetBlockEnd",
+ sourceProps.insetBlockEnd,
+ CompactValue::ofUndefined());
+ insetBlockStart = convertRawProp(
+ context,
+ rawProps,
+ "insetBlockStart",
+ sourceProps.insetBlockStart,
+ CompactValue::ofUndefined());
+ insetInline = convertRawProp(
+ context,
+ rawProps,
+ "insetInline",
+ sourceProps.insetInline,
+ CompactValue::ofUndefined());
+ insetInlineEnd = convertRawProp(
+ context,
+ rawProps,
+ "insetInlineEnd",
+ sourceProps.insetInlineEnd,
+ CompactValue::ofUndefined());
+ insetInlineStart = convertRawProp(
+ context,
+ rawProps,
+ "insetInlineStart",
+ sourceProps.insetInlineStart,
+ CompactValue::ofUndefined());
marginInline = convertRawProp(
context,
rawProps,
diff --git a/ReactCommon/react/renderer/components/view/YogaStylableProps.h b/ReactCommon/react/renderer/components/view/YogaStylableProps.h
index 8891436cdb0364..4a25898f70d80c 100644
--- a/ReactCommon/react/renderer/components/view/YogaStylableProps.h
+++ b/ReactCommon/react/renderer/components/view/YogaStylableProps.h
@@ -43,6 +43,11 @@ class YogaStylableProps : public Props {
// Duplicates of existing properties with different names, taking
// precendence. E.g. "marginBlock" instead of "marginVertical"
+ CompactValue inset;
+ CompactValue insetInline;
+ CompactValue insetInlineEnd;
+ CompactValue insetInlineStart;
+
CompactValue marginInline;
CompactValue marginInlineStart;
CompactValue marginInlineEnd;
@@ -56,6 +61,10 @@ class YogaStylableProps : public Props {
// BlockEnd/BlockStart map to top/bottom (no writing mode), but we preserve
// Yoga's precedence and prefer specific edges (e.g. top) to ones which are
// flow relative (e.g. blockStart).
+ CompactValue insetBlock;
+ CompactValue insetBlockEnd;
+ CompactValue insetBlockStart;
+
CompactValue marginBlockStart;
CompactValue marginBlockEnd;
diff --git a/packages/rn-tester/js/examples/View/ViewExample.js b/packages/rn-tester/js/examples/View/ViewExample.js
index 7a073a3a491697..de2e04acc1aec4 100644
--- a/packages/rn-tester/js/examples/View/ViewExample.js
+++ b/packages/rn-tester/js/examples/View/ViewExample.js
@@ -652,4 +652,90 @@ exports.examples = [
return ;
},
},
+ {
+ title: 'Insets',
+ render(): React.Node {
+ return (
+
+
+
+ inset 10
+
+
+
+
+ insetBlock 5
+
+
+
+
+ insetBlockEnd 5
+
+
+
+
+ insetBlockStart 5
+
+
+
+
+ insetInline 5
+
+
+
+
+ insetInlineEnd 5
+
+
+
+
+ insetInlineStart 5
+
+
+
+ );
+ },
+ },
];