import { WebComponent, html } from 'web-component-base' /** * Boolean props reflect as **bare attributes**: `true` sets the attribute with * no value, `false` removes it entirely — exactly how native `disabled` and * `required` behave. * * Two things that silently broke under the old string reflection now work: * * - `el.toggleAttribute(name, force)` only ever adds/removes an attribute, * it never rewrites a value. With `flag="false"` sitting there, forcing * `true` changed nothing — no attributeChangedCallback, no re-render. * - `[flag]` CSS selectors match on *presence*, so a stamped `flag="false"` * matched too and painted the "on" style onto an element whose prop was * false. */ class FlagBox extends WebComponent { static props = { flag: false } static shadowRootInit = { mode: 'open' } static styles = ` :host { display: block; padding: 0.8em 1em; border: 2px solid #8884; border-radius: 8px; font-family: system-ui, sans-serif; } /* presence selector: matches only while the prop is actually true */ :host([flag]) { border-color: #c2410c; background: #c2410c22; } .state { font-weight: 600; } ` get template() { return html`
${this.props.log}
The last button is the migration trap:
any present value is true, so writing the string
"false" turns the flag on — just like native
disabled="false" is still disabled. Check the console for
the warning wcb logs. Use
toggleAttribute(name, bool) instead.