@@ -146,6 +146,147 @@ describe('ReactDOMComponent', () => {
146146 }
147147 } ) ;
148148
149+ fit ( 'should warn for conflicting CSS shorthand updates' , ( ) => {
150+ const container = document . createElement ( 'div' ) ;
151+ ReactDOM . render (
152+ < div style = { { font : 'foo' , fontStyle : 'bar' } } /> ,
153+ container ,
154+ ) ;
155+ expect ( ( ) =>
156+ ReactDOM . render ( < div style = { { font : 'foo' } } /> , container ) ,
157+ ) . toWarnDev (
158+ 'Warning: Removing a style property during rerender (fontStyle) ' +
159+ 'when a conflicting property is set (font) can lead to styling ' +
160+ "bugs. To avoid this, don't mix shorthand and non-shorthand " +
161+ 'properties for the same value; instead, replace the shorthand ' +
162+ 'with separate values.' +
163+ '\n in div (at **)' ,
164+ ) ;
165+
166+ // These updates are OK and don't warn:
167+ ReactDOM . render (
168+ < div style = { { font : 'qux' , fontStyle : 'bar' } } /> ,
169+ container ,
170+ ) ;
171+ ReactDOM . render (
172+ < div style = { { font : 'foo' , fontStyle : 'baz' } } /> ,
173+ container ,
174+ ) ;
175+
176+ expect ( ( ) =>
177+ ReactDOM . render (
178+ < div style = { { font : 'qux' , fontStyle : 'baz' } } /> ,
179+ container ,
180+ ) ,
181+ ) . toWarnDev (
182+ 'Warning: Updating a style property during rerender (font) when ' +
183+ 'a conflicting property is set (fontStyle) can lead to styling ' +
184+ "bugs. To avoid this, don't mix shorthand and non-shorthand " +
185+ 'properties for the same value; instead, replace the shorthand ' +
186+ 'with separate values.' +
187+ '\n in div (at **)' ,
188+ ) ;
189+ expect ( ( ) =>
190+ ReactDOM . render ( < div style = { { fontStyle : 'baz' } } /> , container ) ,
191+ ) . toWarnDev (
192+ 'Warning: Removing a style property during rerender (font) when ' +
193+ 'a conflicting property is set (fontStyle) can lead to styling ' +
194+ "bugs. To avoid this, don't mix shorthand and non-shorthand " +
195+ 'properties for the same value; instead, replace the shorthand ' +
196+ 'with separate values.' +
197+ '\n in div (at **)' ,
198+ ) ;
199+
200+ // A bit of a special case: backgroundPosition isn't technically longhand
201+ // (it expands to backgroundPosition{X,Y} but so does background)
202+ ReactDOM . render (
203+ < div style = { { background : 'yellow' , backgroundPosition : 'center' } } /> ,
204+ container ,
205+ ) ;
206+ expect ( ( ) =>
207+ ReactDOM . render ( < div style = { { background : 'yellow' } } /> , container ) ,
208+ ) . toWarnDev (
209+ 'Warning: Removing a style property during rerender ' +
210+ '(backgroundPosition) when a conflicting property is set ' +
211+ "(background) can lead to styling bugs. To avoid this, don't mix " +
212+ 'shorthand and non-shorthand properties for the same value; ' +
213+ 'instead, replace the shorthand with separate values.' +
214+ '\n in div (at **)' ,
215+ ) ;
216+ ReactDOM . render (
217+ < div style = { { background : 'yellow' , backgroundPosition : 'center' } } /> ,
218+ container ,
219+ ) ;
220+ // But setting them at the same time is OK:
221+ ReactDOM . render (
222+ < div style = { { background : 'green' , backgroundPosition : 'top' } } /> ,
223+ container ,
224+ ) ;
225+ expect ( ( ) =>
226+ ReactDOM . render (
227+ < div style = { { backgroundPosition : 'top' } } /> ,
228+ container ,
229+ ) ,
230+ ) . toWarnDev (
231+ 'Warning: Removing a style property during rerender (background) ' +
232+ 'when a conflicting property is set (backgroundPosition) can lead ' +
233+ "to styling bugs. To avoid this, don't mix shorthand and " +
234+ 'non-shorthand properties for the same value; instead, replace the ' +
235+ 'shorthand with separate values.' +
236+ '\n in div (at **)' ,
237+ ) ;
238+
239+ // A bit of an even more special case: borderLeft and borderStyle overlap.
240+ ReactDOM . render (
241+ < div style = { { borderStyle : 'dotted' , borderLeft : '1px solid red' } } /> ,
242+ container ,
243+ ) ;
244+ expect ( ( ) =>
245+ ReactDOM . render (
246+ < div style = { { borderLeft : '1px solid red' } } /> ,
247+ container ,
248+ ) ,
249+ ) . toWarnDev (
250+ 'Warning: Removing a style property during rerender (borderStyle) ' +
251+ 'when a conflicting property is set (borderLeft) can lead to ' +
252+ "styling bugs. To avoid this, don't mix shorthand and " +
253+ 'non-shorthand properties for the same value; instead, replace the ' +
254+ 'shorthand with separate values.' +
255+ '\n in div (at **)' ,
256+ ) ;
257+ expect ( ( ) =>
258+ ReactDOM . render (
259+ < div style = { { borderStyle : 'dashed' , borderLeft : '1px solid red' } } /> ,
260+ container ,
261+ ) ,
262+ ) . toWarnDev (
263+ 'Warning: Updating a style property during rerender (borderStyle) ' +
264+ 'when a conflicting property is set (borderLeft) can lead to ' +
265+ "styling bugs. To avoid this, don't mix shorthand and " +
266+ 'non-shorthand properties for the same value; instead, replace the ' +
267+ 'shorthand with separate values.' +
268+ '\n in div (at **)' ,
269+ ) ;
270+ // But setting them at the same time is OK:
271+ ReactDOM . render (
272+ < div style = { { borderStyle : 'dotted' , borderLeft : '2px solid red' } } /> ,
273+ container ,
274+ ) ;
275+ expect ( ( ) =>
276+ ReactDOM . render (
277+ < div style = { { borderStyle : 'dotted' } } /> ,
278+ container ,
279+ ) ,
280+ ) . toWarnDev (
281+ 'Warning: Removing a style property during rerender (borderLeft) ' +
282+ 'when a conflicting property is set (borderStyle) can lead to ' +
283+ "styling bugs. To avoid this, don't mix shorthand and " +
284+ 'non-shorthand properties for the same value; instead, replace the ' +
285+ 'shorthand with separate values.' +
286+ '\n in div (at **)' ,
287+ ) ;
288+ } ) ;
289+
149290 it ( 'should warn for unknown prop' , ( ) => {
150291 const container = document . createElement ( 'div' ) ;
151292 expect ( ( ) =>
0 commit comments