lwc
lwc copied to clipboard
Move HTML/ARIA property/attribute reflection from `ssr-compiler` to `ssr-runtime`
Right now the property/attribute reflection in the ssr- packages is a bit hairy. I don't think that we need to sniff at runtime which props are present in the component (title, ariaLabel, etc.) – we can just move the known lists of global HTML props / ARIA props to ssr-runtime and put them all on a shared prototype (or similar mechanism). This will simplify the SSR compiler code quite a bit.
Another small bug: calling
this.ariaLabel = undefined
this.title = undefined
(etc)
should result in the corresponding attributes being removed, same as setting null. This is just how HTML IDL attribute reflection works. Currently this is busted for ARIA properties because @lwc/aria-reflection doesn't handle undefined correctly for backwards compat.
This issue has been linked to a new work item: W-16985169
Interestingly, null / undefined remove ARIA attributes, but not global HTML attributes.
const div = document.createElement('div')
// <div></div>
div.ariaLabel = div.title = 'foo'
// <div aria-label="foo" title="foo"></div>
div.ariaLabel = div.title = null
// <div title="null"></div>
I think it varies from attribute to attribute. E.g. setting tabIndex to undefined actually gives you tabindex="0". There are also inconsistencies between browsers:
https://github.com/salesforce/lwc/blob/6d0296bbca3073022ee23ef37c69e95aab3c36ab/packages/%40lwc/integration-karma/test/component/html-properties/index.spec.js#L133-L136
I think it varies from attribute to attribute. E.g. setting
tabIndexto undefined actually gives youtabindex="0". There are also inconsistencies between browsers:
That's variation on the value, not variation on removal.
const div = document.createElement('div')
// <div></div>
div.ariaLabel = div.title = div.spellcheck = div.tabIndex = 'foo'
// <div aria-label="foo" title="foo" spellcheck="true" tabindex="0"></div>
div.ariaLabel = div.title = div.spellcheck = div.tabIndex = null
div.hasAttribute('aria-label') // false
div.hasAttribute('title') // true
div.hasAttribute('spellcheck') // true
div.hasAttribute('tabindex') // true
We had to shuffle things around quite a bit, but I think we've finally got the correct implementation.