Skip to content

Commit c6c47fd

Browse files
committed
feat: add disableViewFlattening
1 parent 37fe875 commit c6c47fd

4 files changed

Lines changed: 53 additions & 1 deletion

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { PluginObj, types as BabelTypes, NodePath } from '@babel/core';
2+
3+
const collapsiblePlugin = ({
4+
types: t,
5+
}: typeof import('@babel/core')): PluginObj => {
6+
return {
7+
name: 'react-native-harness-collapsible-plugin',
8+
visitor: {
9+
JSXOpeningElement(path: NodePath<BabelTypes.JSXOpeningElement>) {
10+
const { node } = path;
11+
12+
// 1. Check if the tag is named "View"
13+
if (t.isJSXIdentifier(node.name) && node.name.name === 'View') {
14+
// 2. Check if 'collapsable' is already defined to avoid overriding explicit props
15+
const hasCollapsable = node.attributes.some(
16+
(attr) =>
17+
t.isJSXAttribute(attr) &&
18+
t.isJSXIdentifier(attr.name) &&
19+
attr.name.name === 'collapsable'
20+
);
21+
22+
if (!hasCollapsable) {
23+
// 3. Inject collapsable={true}
24+
node.attributes.push(
25+
t.jsxAttribute(
26+
t.jsxIdentifier('collapsable'),
27+
t.jsxExpressionContainer(t.booleanLiteral(true))
28+
)
29+
);
30+
}
31+
}
32+
},
33+
},
34+
};
35+
};
36+
37+
export default collapsiblePlugin;

packages/babel-preset/src/preset.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import resolveWeakPlugin from './resolve-weak-plugin';
2+
import collapsiblePlugin from './collapsible-plugin';
23
import path from 'path';
34

45
const getIstanbulPlugin = (): string | [string, object] | null => {
@@ -20,6 +21,7 @@ const getIstanbulPlugin = (): string | [string, object] | null => {
2021
export const rnHarnessPlugins = [
2122
'@babel/plugin-transform-class-static-block',
2223
resolveWeakPlugin,
24+
process.env.RN_HARNESS_VIEW_FLATTENING === 'false' ? collapsiblePlugin : null,
2325
getIstanbulPlugin(),
2426
].filter((plugin) => plugin !== null);
2527

packages/config/src/types.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ export const ConfigSchema = z
4646
.min(100, 'Crash detection interval must be at least 100ms')
4747
.default(500),
4848

49+
disableViewFlattening: z
50+
.boolean()
51+
.optional()
52+
.default(false)
53+
.describe(
54+
'Disable view flattening in React Native. This will set collapsable={true} for all View components ' +
55+
'to ensure they are not flattened by the native layout engine.'
56+
),
57+
4958
coverage: z
5059
.object({
5160
root: z
@@ -55,7 +64,7 @@ export const ConfigSchema = z
5564
'Root directory for coverage instrumentation in monorepo setups. ' +
5665
'Specifies the directory from which coverage data should be collected. ' +
5766
'Use ".." for create-react-native-library projects where tests run from example/ ' +
58-
'but source files are in parent directory. Passed to babel-plugin-istanbul\'s cwd option.'
67+
"but source files are in parent directory. Passed to babel-plugin-istanbul's cwd option."
5968
),
6069
})
6170
.optional(),

packages/jest/src/setup.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ export const setup = async (globalConfig: JestConfig.GlobalConfig) => {
7474
}
7575
}
7676

77+
if (harnessConfig.disableViewFlattening) {
78+
process.env.RN_HARNESS_VIEW_FLATTENING = 'false';
79+
}
80+
7781
logTestRunHeader(selectedRunner);
7882
const harness = await getHarness(
7983
harnessConfig,

0 commit comments

Comments
 (0)