Skip to content

Commit e16695d

Browse files
committed
feat: optional mergePros
1 parent 45290ca commit e16695d

File tree

2 files changed

+21
-10
lines changed

2 files changed

+21
-10
lines changed

packages/babel-plugin-jsx/src/buildProps.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,18 @@ const getJSXAttributeValue = (
4646
const transformJSXSpreadAttribute = (
4747
nodePath: NodePath,
4848
path: NodePath<t.JSXSpreadAttribute>,
49-
mergeArgs: (t.ObjectProperty | t.Expression)[],
49+
mergeProps: boolean,
50+
args: (t.ObjectProperty | t.Expression | t.SpreadElement)[],
5051
) => {
5152
const argument = path.get('argument') as NodePath<t.ObjectExpression>;
5253
const { properties } = argument.node;
5354
if (!properties) {
5455
if (argument.isIdentifier()) {
5556
walksScope(nodePath, (argument.node as t.Identifier).name, SlotFlags.DYNAMIC);
5657
}
57-
mergeArgs.push(argument.node);
58+
args.push(mergeProps ? argument.node : t.spreadElement(argument.node));
5859
} else {
59-
mergeArgs.push(t.objectExpression(properties));
60+
args.push(t.objectExpression(properties));
6061
}
6162
};
6263

@@ -71,7 +72,10 @@ const mergeAsArray = (existing: t.ObjectProperty, incoming: t.ObjectProperty) =>
7172
}
7273
};
7374

74-
const dedupeProperties = (properties: t.ObjectProperty[] = []) => {
75+
const dedupeProperties = (properties: t.ObjectProperty[] = [], mergeProps?: boolean) => {
76+
if (!mergeProps) {
77+
return properties;
78+
}
7579
const knownProps = new Map<string, t.ObjectProperty>();
7680
const deduped: t.ObjectProperty[] = [];
7781
properties.forEach((prop) => {
@@ -146,6 +150,7 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
146150
let hasDynamicKeys = false;
147151

148152
const mergeArgs: (t.CallExpression | t.ObjectExpression | t.Identifier)[] = [];
153+
const { mergeProps = true } = state.opts;
149154
props
150155
.forEach((prop) => {
151156
if (prop.isJSXAttribute()) {
@@ -273,8 +278,8 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
273278
));
274279
}
275280
} else {
276-
if (properties.length) {
277-
mergeArgs.push(t.objectExpression(dedupeProperties(properties)));
281+
if (properties.length && mergeProps) {
282+
mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
278283
properties = [];
279284
}
280285

@@ -283,7 +288,8 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
283288
transformJSXSpreadAttribute(
284289
path as NodePath,
285290
prop as NodePath<t.JSXSpreadAttribute>,
286-
mergeArgs,
291+
mergeProps,
292+
mergeProps ? mergeArgs : properties,
287293
);
288294
}
289295
});
@@ -314,10 +320,9 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
314320
}
315321

316322
let propsExpression: t.Expression | t.ObjectProperty | t.Literal = t.nullLiteral();
317-
318323
if (mergeArgs.length) {
319324
if (properties.length) {
320-
mergeArgs.push(t.objectExpression(dedupeProperties(properties)));
325+
mergeArgs.push(t.objectExpression(dedupeProperties(properties, mergeProps)));
321326
}
322327
if (mergeArgs.length > 1) {
323328
propsExpression = t.callExpression(
@@ -329,7 +334,12 @@ const buildProps = (path: NodePath<t.JSXElement>, state: State) => {
329334
propsExpression = mergeArgs[0];
330335
}
331336
} else if (properties.length) {
332-
propsExpression = t.objectExpression(dedupeProperties(properties));
337+
// single no need for spread
338+
if (properties.length === 1 && t.isSpreadElement(properties[0])) {
339+
propsExpression = (properties[0] as unknown as t.SpreadElement).argument;
340+
} else {
341+
propsExpression = t.objectExpression(dedupeProperties(properties, mergeProps));
342+
}
333343
}
334344

335345
return {

packages/babel-plugin-jsx/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export type State = {
1414
interface Opts {
1515
transformOn?: boolean;
1616
optimize?: boolean;
17+
mergeProps?: boolean;
1718
isCustomElement?: (tag: string) => boolean;
1819
}
1920

0 commit comments

Comments
 (0)