Skip to content

Commit ca4e3a9

Browse files
authored
[material-ui] Update mergeSlotProps to merge style (#44959)
1 parent 0221d17 commit ca4e3a9

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

docs/data/material/guides/composition/composition.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ If you added another `className` via the `slotProps` prop on the Custom Tooltip
6565
The popper slot in the original example would now have both classes applied to it, in addition to any others that may be present: `"[…] custom-tooltip-popper foo"`.
6666
:::
6767
68+
:::info
69+
`style` object are shallow merged rather than replacing one another. The style keys from the first argument have higher priority.
70+
:::
71+
6872
## Component prop
6973
7074
Material UI allows you to change the root element that will be rendered via a prop called `component`.

packages/mui-material/src/utils/mergeSlotProps.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import * as React from 'react';
12
import { expect } from 'chai';
23

34
import mergeSlotProps from './mergeSlotProps';
45

56
type OwnerState = {
67
className: string;
78
'aria-label'?: string;
9+
style?: React.CSSProperties;
810
};
911

1012
describe('utils/index.js', () => {
@@ -21,6 +23,27 @@ describe('utils/index.js', () => {
2123
});
2224
});
2325

26+
it('merge styles', () => {
27+
expect(
28+
mergeSlotProps<{ style: React.CSSProperties }>(
29+
{ style: { color: 'red' } },
30+
{ style: { backgroundColor: 'blue' } },
31+
),
32+
).to.deep.equal({
33+
style: { color: 'red', backgroundColor: 'blue' },
34+
});
35+
36+
// external styles should override
37+
expect(
38+
mergeSlotProps<{ style: React.CSSProperties }>(
39+
{ style: { backgroundColor: 'red' } },
40+
{ style: { backgroundColor: 'blue' } },
41+
),
42+
).to.deep.equal({
43+
style: { backgroundColor: 'red' },
44+
});
45+
});
46+
2447
it('external slot props should override', () => {
2548
expect(
2649
mergeSlotProps<OwnerState>(
@@ -78,6 +101,35 @@ describe('utils/index.js', () => {
78101
});
79102
});
80103

104+
it('merge styles for callbacks', () => {
105+
expect(
106+
mergeSlotProps(
107+
() => ({
108+
style: { color: 'red' },
109+
}),
110+
() => ({
111+
style: { backgroundColor: 'blue' },
112+
}),
113+
)(),
114+
).to.deep.equal({
115+
style: { color: 'red', backgroundColor: 'blue' },
116+
});
117+
118+
// external styles should override
119+
expect(
120+
mergeSlotProps(
121+
() => ({
122+
style: { backgroundColor: 'red' },
123+
}),
124+
() => ({
125+
style: { backgroundColor: 'blue' },
126+
}),
127+
)(),
128+
).to.deep.equal({
129+
style: { backgroundColor: 'red' },
130+
});
131+
});
132+
81133
it('external callback should be called with default slot props', () => {
82134
expect(
83135
mergeSlotProps<(ownerState: OwnerState) => OwnerState>(

packages/mui-material/src/utils/mergeSlotProps.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ export default function mergeSlotProps<
2828
...defaultSlotPropsValue,
2929
...externalSlotPropsValue,
3030
...(!!className && { className }),
31+
...(defaultSlotPropsValue?.style &&
32+
externalSlotPropsValue?.style && {
33+
style: { ...defaultSlotPropsValue.style, ...externalSlotPropsValue.style },
34+
}),
3135
};
3236
}) as U;
3337
}
@@ -39,5 +43,9 @@ export default function mergeSlotProps<
3943
...defaultSlotProps,
4044
...externalSlotProps,
4145
...(!!className && { className }),
46+
...((defaultSlotProps as Record<string, any>)?.style &&
47+
externalSlotProps?.style && {
48+
style: { ...(defaultSlotProps as Record<string, any>).style, ...externalSlotProps.style },
49+
}),
4250
} as U;
4351
}

0 commit comments

Comments
 (0)