chore: SlotRerenderObject aligned with reactive cycle (docs + changelog) (#1999)

This commit is contained in:
Thijs Louisse 2023-06-07 09:16:28 +02:00 committed by GitHub
parent d2de984f0b
commit 6893421779
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 18 additions and 14 deletions

View file

@ -0,0 +1,7 @@
---
'@lion/ui': minor
---
fix(ui): align light dom with internal [reactivity cycle of LitElement/ReactiveElement](https://lit.dev/docs/components/lifecycle/#reactive-update-cycle).
Since light dom render is now aligned inside `update` instead of `updated` (like it already was for shadow dom),
we can rely on the fact that all dom (light and shadow) has rendered inside our `updated` loop.

View file

@ -74,7 +74,6 @@ class MyAccessibleControl extends SlotMixin(LitElement) {
'rerenderable-slot': () => {
return {
template: html`<w-c>${this.litProperty}</w-c>`,
afterRender: () => { /** sync some state */ },
}
},
// undefined (conditional slot)
@ -105,14 +104,11 @@ A `SlotRerenderObject` looks like this:
```ts
{
template: TemplateResult;
afterRender?: Function;
};
}
```
It is meant for complex templates that need rerenders. Normally - when rendering into shadow dom via `LitElement.render` - we get rerenders
"for free" via [property effects](https://lit.dev/docs/components/properties/#when-properties-change).
When we configure `SlotFunctionResult` to return a `SlotRerenderObject`, we get the same behavior for light dom.
For this rerendering to work predictably (no focus and other interaction issues), the slot will be created with a wrapper div.
It is meant for complex templates that need rerenders and are bound to the [reactive update cycle](https://lit.dev/docs/components/lifecycle/#reactive-update-cycle). The same lifecycle hooks (for instance `updated`) can be used as with templates rendered to the shadow root (via the regular render function).
For rerendering to work predictably (no focus and other interaction issues), the slot will be created within a wrapper div.
### Undefined

View file

@ -83,6 +83,7 @@ const SlotMixinImplementation = superclass =>
slotName,
shouldRerender: true,
});
// TODO: this is deprecated, remove later
slotFunctionResult.afterRender?.();
}

View file

@ -383,7 +383,7 @@ describe('SlotMixin', () => {
expect(slot.tagName).to.equal('SPAN');
});
it('supports afterRender logic (type "{ template:TemplateResults; afterRender: Function}" )', async () => {
it('supports (deprecated) afterRender logic (type "{ template:TemplateResults; afterRender: Function}" )', async () => {
let varThatProvesAfterRenderIsCalled = 'not called';
const tag = defineCE(

View file

@ -6,7 +6,10 @@ import { TemplateResult, LitElement } from 'lit';
*/
export type SlotRerenderObject = {
template: TemplateResult;
/* Add logic that will be performed after the render */
/**
* Add logic that will be performed after the render
* @deprecated
*/
afterRender?: Function;
};

View file

@ -180,7 +180,6 @@ export class LionInputTelDropdown extends LionInputTel {
return {
template: templates.dropdown(this._templateDataDropdown),
afterRender: this.__syncRegionWithDropdown,
};
},
};
@ -274,9 +273,7 @@ export class LionInputTelDropdown extends LionInputTel {
updated(changedProperties) {
super.updated(changedProperties);
if (changedProperties.has('activeRegion')) {
this.__syncRegionWithDropdown();
}
if (changedProperties.has('disabled') || changedProperties.has('readOnly')) {
if (this.disabled || this.readOnly) {