diff --git a/.changeset/slot-mixin-reactivity-align.md b/.changeset/slot-mixin-reactivity-align.md new file mode 100644 index 000000000..18847ea8d --- /dev/null +++ b/.changeset/slot-mixin-reactivity-align.md @@ -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. diff --git a/docs/fundamentals/systems/core/SlotMixin.md b/docs/fundamentals/systems/core/SlotMixin.md index 4b77c00d2..3a445618f 100644 --- a/docs/fundamentals/systems/core/SlotMixin.md +++ b/docs/fundamentals/systems/core/SlotMixin.md @@ -74,7 +74,6 @@ class MyAccessibleControl extends SlotMixin(LitElement) { 'rerenderable-slot': () => { return { template: html`${this.litProperty}`, - afterRender: () => { /** sync some state */ }, } }, // undefined (conditional slot) @@ -104,15 +103,12 @@ A `SlotRerenderObject` looks like this: ```ts { - template: TemplateResult; - afterRender?: Function; -}; + template: TemplateResult; +} ``` -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 diff --git a/packages/ui/components/core/src/SlotMixin.js b/packages/ui/components/core/src/SlotMixin.js index c73cb8697..5c9bb6bf8 100644 --- a/packages/ui/components/core/src/SlotMixin.js +++ b/packages/ui/components/core/src/SlotMixin.js @@ -83,6 +83,7 @@ const SlotMixinImplementation = superclass => slotName, shouldRerender: true, }); + // TODO: this is deprecated, remove later slotFunctionResult.afterRender?.(); } diff --git a/packages/ui/components/core/test/SlotMixin.test.js b/packages/ui/components/core/test/SlotMixin.test.js index 414b46029..884077af5 100644 --- a/packages/ui/components/core/test/SlotMixin.test.js +++ b/packages/ui/components/core/test/SlotMixin.test.js @@ -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( diff --git a/packages/ui/components/core/types/SlotMixinTypes.ts b/packages/ui/components/core/types/SlotMixinTypes.ts index 8f16a25a6..3831d5ee9 100644 --- a/packages/ui/components/core/types/SlotMixinTypes.ts +++ b/packages/ui/components/core/types/SlotMixinTypes.ts @@ -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; }; diff --git a/packages/ui/components/input-tel-dropdown/src/LionInputTelDropdown.js b/packages/ui/components/input-tel-dropdown/src/LionInputTelDropdown.js index 75248a038..0100f9b6e 100644 --- a/packages/ui/components/input-tel-dropdown/src/LionInputTelDropdown.js +++ b/packages/ui/components/input-tel-dropdown/src/LionInputTelDropdown.js @@ -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(); - } + this.__syncRegionWithDropdown(); if (changedProperties.has('disabled') || changedProperties.has('readOnly')) { if (this.disabled || this.readOnly) {