Skip to content

Commit 9669c10

Browse files
gabrieldonadelfacebook-github-bot
authored andcommitted
feat: Add Fabric implementation of inset logical properties (facebook#35692)
Summary: This PR implements `inset` logical properties as requested on facebook#34425. This implementation includes the addition of the following style properties - `inset`, equivalent to `top`, `bottom`, `right` and `left`. - `insetBlock`, equivalent to `top` and `bottom`. - `insetBlockEnd`, equivalent to `bottom`. - `insetBlockStart`, equivalent to `top`. - `insetInline`, equivalent to `right` and `left`. - `insetInlineEnd`, equivalent to `right` or `left`. - `insetInlineStart`, equivalent to `right` or `left`. ## Changelog [GENERAL] [ADDED] - Add Fabric implementation of inset logical properties Pull Request resolved: facebook#35692 Test Plan: 1. Open the RNTester app and navigate to the `View` page 2. Test the new style properties through the `Insets` section <table> <tr> <td>Android</td> <td>iOS</td> </tr> <tr> <td><img src="https://user-images.githubusercontent.com/11707729/208821212-fbbac6ed-09a4-43f4-ba98-dfd2cbabf044.png" alt="1" width="360px" /> </td> <td> <img src="https://user-images.githubusercontent.com/11707729/208816997-ef044140-8824-4b1b-a77b-085f18ea9e0e.png" alt="2" width="360px" /> </td> </tr> </table> Reviewed By: NickGerleman Differential Revision: D42193661 Pulled By: ryancat fbshipit-source-id: 3db8bcd2c4db0ef4886b9ec49a46424d57362620
1 parent 1542d71 commit 9669c10

File tree

9 files changed

+217
-0
lines changed

9 files changed

+217
-0
lines changed

Libraries/Components/View/ReactNativeStyleAttributes.js

+7
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,13 @@ const ReactNativeStyleAttributes: {[string]: AnyAttributeType, ...} = {
4646
flexWrap: true,
4747
gap: true,
4848
height: true,
49+
inset: true,
50+
insetBlock: true,
51+
insetBlockEnd: true,
52+
insetBlockStart: true,
53+
insetInline: true,
54+
insetInlineEnd: true,
55+
insetInlineStart: true,
4956
justifyContent: true,
5057
left: true,
5158
margin: true,

Libraries/NativeComponent/BaseViewConfig.android.js

+8
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,14 @@ const validAttributesForNonEventProps = {
258258
top: true,
259259
bottom: true,
260260

261+
inset: true,
262+
insetBlock: true,
263+
insetBlockEnd: true,
264+
insetBlockStart: true,
265+
insetInline: true,
266+
insetInlineEnd: true,
267+
insetInlineStart: true,
268+
261269
position: true,
262270

263271
style: ReactNativeStyleAttributes,

Libraries/NativeComponent/BaseViewConfig.ios.js

+8
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,14 @@ const validAttributesForNonEventProps = {
232232
bottom: true,
233233
left: true,
234234

235+
inset: true,
236+
insetBlock: true,
237+
insetBlockEnd: true,
238+
insetBlockStart: true,
239+
insetInline: true,
240+
insetInlineEnd: true,
241+
insetInlineStart: true,
242+
235243
width: true,
236244
height: true,
237245

Libraries/StyleSheet/StyleSheetTypes.d.ts

+7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ export interface FlexStyle {
5959
flexShrink?: number | undefined;
6060
flexWrap?: 'wrap' | 'nowrap' | 'wrap-reverse' | undefined;
6161
height?: number | string | undefined;
62+
inset?: number | string | undefined;
63+
insetBlock?: number | string | undefined;
64+
insetBlockEnd?: number | string | undefined;
65+
insetBlockStart?: number | string | undefined;
66+
insetInline?: number | string | undefined;
67+
insetInlineEnd?: number | string | undefined;
68+
insetInlineStart?: number | string | undefined;
6269
justifyContent?:
6370
| 'flex-start'
6471
| 'flex-end'

Libraries/StyleSheet/StyleSheetTypes.js

+16
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,22 @@ type ____LayoutStyle_Internal = $ReadOnly<{
132132
*/
133133
top?: DimensionValue,
134134

135+
/** `inset` is a shorthand that corresponds to the top, right, bottom, and/or left properties.
136+
*
137+
* It works similarly to `inset` in CSS, but in React Native you
138+
* must use points or percentages. Ems and other units are not supported.
139+
*
140+
* See https://developer.mozilla.org/en-US/docs/Web/CSS/inset
141+
* for more details of how `inset` affects layout.
142+
*/
143+
inset?: DimensionValue,
144+
insetBlock?: DimensionValue,
145+
insetBlockEnd?: DimensionValue,
146+
insetBlockStart?: DimensionValue,
147+
insetInline?: DimensionValue,
148+
insetInlineEnd?: DimensionValue,
149+
insetInlineStart?: DimensionValue,
150+
135151
/** `minWidth` is the minimum width for this component, in logical pixels.
136152
*
137153
* It works similarly to `min-width` in CSS, but in React Native you

ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,21 @@ void YogaLayoutableShadowNode::updateYogaProps() {
333333
YGStyle result{baseStyle};
334334

335335
// Aliases with precedence
336+
if (!props.inset.isUndefined()) {
337+
result.position()[YGEdgeAll] = props.inset;
338+
}
339+
if (!props.insetBlock.isUndefined()) {
340+
result.position()[YGEdgeVertical] = props.insetBlock;
341+
}
342+
if (!props.insetInline.isUndefined()) {
343+
result.position()[YGEdgeHorizontal] = props.insetInline;
344+
}
345+
if (!props.insetInlineEnd.isUndefined()) {
346+
result.position()[YGEdgeEnd] = props.insetInlineEnd;
347+
}
348+
if (!props.insetInlineStart.isUndefined()) {
349+
result.position()[YGEdgeStart] = props.insetInlineStart;
350+
}
336351
if (!props.marginInline.isUndefined()) {
337352
result.margin()[YGEdgeHorizontal] = props.marginInline;
338353
}
@@ -359,6 +374,12 @@ void YogaLayoutableShadowNode::updateYogaProps() {
359374
}
360375

361376
// Aliases without precedence
377+
if (CompactValue(result.position()[YGEdgeBottom]).isUndefined()) {
378+
result.position()[YGEdgeBottom] = props.insetBlockEnd;
379+
}
380+
if (CompactValue(result.position()[YGEdgeTop]).isUndefined()) {
381+
result.position()[YGEdgeTop] = props.insetBlockStart;
382+
}
362383
if (CompactValue(result.margin()[YGEdgeTop]).isUndefined()) {
363384
result.margin()[YGEdgeTop] = props.marginBlockStart;
364385
}

ReactCommon/react/renderer/components/view/YogaStylableProps.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ void YogaStylableProps::setProp(
134134
REBUILD_FIELD_YG_EDGES(border, "border", "Width");
135135

136136
// Aliases
137+
RAW_SET_PROP_SWITCH_CASE(inset, "inset", CompactValue::ofUndefined());
138+
RAW_SET_PROP_SWITCH_CASE(
139+
insetBlock, "insetBlock", CompactValue::ofUndefined());
140+
RAW_SET_PROP_SWITCH_CASE(
141+
insetBlockEnd, "insetBlockEnd", CompactValue::ofUndefined());
142+
RAW_SET_PROP_SWITCH_CASE(
143+
insetBlockStart, "insetBlockStart", CompactValue::ofUndefined());
144+
RAW_SET_PROP_SWITCH_CASE(
145+
insetInline, "insetInline", CompactValue::ofUndefined());
146+
RAW_SET_PROP_SWITCH_CASE(
147+
insetInlineEnd, "insetInlineEnd", CompactValue::ofUndefined());
148+
RAW_SET_PROP_SWITCH_CASE(
149+
insetInlineStart, "insetInlineStart", CompactValue::ofUndefined());
137150
RAW_SET_PROP_SWITCH_CASE(
138151
marginInline, "marginInline", CompactValue::ofUndefined());
139152
RAW_SET_PROP_SWITCH_CASE(
@@ -245,6 +258,48 @@ void YogaStylableProps::convertRawPropAliases(
245258
const PropsParserContext &context,
246259
YogaStylableProps const &sourceProps,
247260
RawProps const &rawProps) {
261+
inset = convertRawProp(
262+
context,
263+
rawProps,
264+
"inset",
265+
sourceProps.inset,
266+
CompactValue::ofUndefined());
267+
insetBlock = convertRawProp(
268+
context,
269+
rawProps,
270+
"insetBlock",
271+
sourceProps.insetBlock,
272+
CompactValue::ofUndefined());
273+
insetBlockEnd = convertRawProp(
274+
context,
275+
rawProps,
276+
"insetBlockEnd",
277+
sourceProps.insetBlockEnd,
278+
CompactValue::ofUndefined());
279+
insetBlockStart = convertRawProp(
280+
context,
281+
rawProps,
282+
"insetBlockStart",
283+
sourceProps.insetBlockStart,
284+
CompactValue::ofUndefined());
285+
insetInline = convertRawProp(
286+
context,
287+
rawProps,
288+
"insetInline",
289+
sourceProps.insetInline,
290+
CompactValue::ofUndefined());
291+
insetInlineEnd = convertRawProp(
292+
context,
293+
rawProps,
294+
"insetInlineEnd",
295+
sourceProps.insetInlineEnd,
296+
CompactValue::ofUndefined());
297+
insetInlineStart = convertRawProp(
298+
context,
299+
rawProps,
300+
"insetInlineStart",
301+
sourceProps.insetInlineStart,
302+
CompactValue::ofUndefined());
248303
marginInline = convertRawProp(
249304
context,
250305
rawProps,

ReactCommon/react/renderer/components/view/YogaStylableProps.h

+9
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ class YogaStylableProps : public Props {
4343

4444
// Duplicates of existing properties with different names, taking
4545
// precendence. E.g. "marginBlock" instead of "marginVertical"
46+
CompactValue inset;
47+
CompactValue insetInline;
48+
CompactValue insetInlineEnd;
49+
CompactValue insetInlineStart;
50+
4651
CompactValue marginInline;
4752
CompactValue marginInlineStart;
4853
CompactValue marginInlineEnd;
@@ -56,6 +61,10 @@ class YogaStylableProps : public Props {
5661
// BlockEnd/BlockStart map to top/bottom (no writing mode), but we preserve
5762
// Yoga's precedence and prefer specific edges (e.g. top) to ones which are
5863
// flow relative (e.g. blockStart).
64+
CompactValue insetBlock;
65+
CompactValue insetBlockEnd;
66+
CompactValue insetBlockStart;
67+
5968
CompactValue marginBlockStart;
6069
CompactValue marginBlockEnd;
6170

packages/rn-tester/js/examples/View/ViewExample.js

+86
Original file line numberDiff line numberDiff line change
@@ -652,4 +652,90 @@ exports.examples = [
652652
return <FlexGapExample />;
653653
},
654654
},
655+
{
656+
title: 'Insets',
657+
render(): React.Node {
658+
return (
659+
<View style={{rowGap: 10}}>
660+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
661+
<View
662+
style={{
663+
backgroundColor: '#527FE4',
664+
padding: 5,
665+
position: 'absolute',
666+
inset: 10,
667+
}}>
668+
<Text style={{fontSize: 11}}>inset 10</Text>
669+
</View>
670+
</View>
671+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
672+
<View
673+
style={{
674+
backgroundColor: '#527FE4',
675+
padding: 5,
676+
position: 'absolute',
677+
insetBlock: 5,
678+
}}>
679+
<Text style={{fontSize: 11}}>insetBlock 5</Text>
680+
</View>
681+
</View>
682+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
683+
<View
684+
style={{
685+
backgroundColor: '#527FE4',
686+
padding: 5,
687+
position: 'absolute',
688+
insetBlockEnd: 5,
689+
}}>
690+
<Text style={{fontSize: 11}}>insetBlockEnd 5</Text>
691+
</View>
692+
</View>
693+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
694+
<View
695+
style={{
696+
backgroundColor: '#527FE4',
697+
padding: 5,
698+
position: 'absolute',
699+
insetBlockStart: 5,
700+
}}>
701+
<Text style={{fontSize: 11}}>insetBlockStart 5</Text>
702+
</View>
703+
</View>
704+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
705+
<View
706+
style={{
707+
backgroundColor: '#527FE4',
708+
padding: 5,
709+
position: 'absolute',
710+
insetInline: 5,
711+
}}>
712+
<Text style={{fontSize: 11}}>insetInline 5</Text>
713+
</View>
714+
</View>
715+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
716+
<View
717+
style={{
718+
backgroundColor: '#527FE4',
719+
padding: 5,
720+
position: 'absolute',
721+
insetInlineEnd: 5,
722+
}}>
723+
<Text style={{fontSize: 11}}>insetInlineEnd 5</Text>
724+
</View>
725+
</View>
726+
<View style={{position: 'relative', height: 50, borderWidth: 1}}>
727+
<View
728+
style={{
729+
backgroundColor: '#527FE4',
730+
padding: 5,
731+
position: 'absolute',
732+
insetInlineStart: 5,
733+
}}>
734+
<Text style={{fontSize: 11}}>insetInlineStart 5</Text>
735+
</View>
736+
</View>
737+
</View>
738+
);
739+
},
740+
},
655741
];

0 commit comments

Comments
 (0)