fix: drop style attribute when value normalises to empty

Previously the client kept an empty `style=""` for empty-string values
while SSR dropped the attribute, which is a hydration mismatch and now
also affects every object/array input that filters down to nothing
(`style={false}`, `style={{}}`, `style={[null, false]}`). Coerce empty
to `null` in `to_style` so client and SSR agree, matching what the
directive path already did and what `to_class` does for `class={''}`.

Two existing tests asserted `<div style="">` for `component.style = ''`
as an incidental side effect; updated to expect the attribute dropped.
pull/18176/head
Mathias Picker 4 months ago
parent cd5b9add37
commit b6b6d03869

@ -261,5 +261,7 @@ export function to_style(value, styles) {
return new_style === '' ? null : new_style; return new_style === '' ? null : new_style;
} }
return value == null ? null : String(value); // Empty results drop the attribute entirely so that client and SSR agree
// (the directive path above already returns `null` for empty output).
return value == null || value === '' ? null : String(value);
} }

@ -12,8 +12,8 @@ export default test({
` `
<button>fork</button> <button>fork</button>
<button>commit</button> <button>commit</button>
<p style="">foo</p> <p>foo</p>
<p style="">foo</p> <p>foo</p>
<p>foo</p> <p>foo</p>
` `
); );
@ -51,8 +51,8 @@ export default test({
` `
<button>fork</button> <button>fork</button>
<button>commit</button> <button>commit</button>
<p style="">foo</p> <p>foo</p>
<p style="">foo</p> <p>foo</p>
<p>foo</p> <p>foo</p>
` `
); );

@ -37,14 +37,16 @@ export default test({
component.style = ''; component.style = '';
flushSync(); flushSync();
// empty results drop the attribute on both client and SSR (was previously
// `<div style=""></div>` on the client only — a hydration mismatch)
assert.htmlEqual( assert.htmlEqual(
target.innerHTML, target.innerHTML,
` `
<div style=""></div> <div></div>
<div style=""></div> <div></div>
<custom-element style=""></custom-element> <custom-element></custom-element>
<custom-element style=""></custom-element> <custom-element></custom-element>
` `
); );

Loading…
Cancel
Save