diff --git a/src/components/dropdown/dropdown.ts b/src/components/dropdown/dropdown.ts index 031e52be7..e55d9ea6c 100644 --- a/src/components/dropdown/dropdown.ts +++ b/src/components/dropdown/dropdown.ts @@ -116,14 +116,24 @@ export default class WaDropdown extends WebAwesomeElement { } } - firstUpdated() { + firstUpdated (changedProperties: PropertyValues) { + super.firstUpdated(changedProperties) this.panel.hidden = !this.open; + const initiallyOpen = this.open + this.open = false - // If the dropdown is visible on init, update its position - if (this.open) { - this.addOpenListeners(); - this.popup.active = true; - } + // With SSR timings, sometimes the popup animations never get a chance to end / cancel. + // This is a hacky workaround to "fix" those animation issues. + setTimeout(() => { + this.popup.popup.dispatchEvent(new Event("animationend")) + + // If the dropdown is visible on init, update its position + if (initiallyOpen) { + setTimeout(() => { + this.open = true + }) + } + }) } async updated(changeProperties: PropertyValues) { diff --git a/src/components/select/select.ts b/src/components/select/select.ts index 342c7fafe..c25503883 100644 --- a/src/components/select/select.ts +++ b/src/components/select/select.ts @@ -268,6 +268,15 @@ export default class WaSelect extends WebAwesomeFormAssociatedElement { this.open = false; } + firstUpdated (changedProperties: PropertyValues) { + super.firstUpdated(changedProperties) + // With SSR timings, sometimes the popup animations never get a chance to end / cancel. + // This is a hacky workaround to "fix" those animation issues. + setTimeout(() => { + this.popup.popup.dispatchEvent(new Event("animationend")) + }) + } + updated(changedProperties: PropertyValues) { if (changedProperties.has('disabled') && this.hasUpdated) { // Close the listbox when the control is disabled diff --git a/src/components/tooltip/tooltip.ts b/src/components/tooltip/tooltip.ts index 138886b76..e02615b13 100644 --- a/src/components/tooltip/tooltip.ts +++ b/src/components/tooltip/tooltip.ts @@ -141,14 +141,26 @@ export default class WaTooltip extends WebAwesomeElement { } } - firstUpdated() { + firstUpdated (changedProperties: PropertyValues) { + super.firstUpdated(changedProperties) this.body.hidden = !this.open; + // With SSR timings, sometimes the popup animations never get a chance to end / cancel. + // This is a hacky workaround to "fix" those animation issues. + setTimeout(() => { + this.popup.popup.dispatchEvent(new Event("animationend")) + + if (this.open) { + // This makes sure the "animationend" event has finished then it will show the tooltip in the "open" state. + setTimeout(() => { + this.body.hidden = false + this.popup.active = true; + this.popup.reposition(); + }) + } + }) + // If the tooltip is visible on init, update its position - if (this.open) { - this.popup.active = true; - this.popup.reposition(); - } } async updated(changedProperties: PropertyValues) { @@ -261,7 +273,6 @@ export default class WaTooltip extends WebAwesomeElement { this.popup.active = true; await animateWithClass(this.popup.popup, 'show-with-scale'); this.popup.reposition(); - this.dispatchEvent(new WaAfterShowEvent()); } else { // Hide @@ -275,10 +286,12 @@ export default class WaTooltip extends WebAwesomeElement { this.closeWatcher?.destroy(); document.removeEventListener('keydown', this.handleDocumentKeyDown); - await animateWithClass(this.popup.popup, 'hide-with-scale'); + if (this.hasUpdated) { + await animateWithClass(this.popup.popup, 'hide-with-scale'); + } + this.popup.active = false; this.body.hidden = true; - this.dispatchEvent(new WaAfterHideEvent()); } } diff --git a/src/internal/animate.ts b/src/internal/animate.ts index 3c08d9fbe..b9b865317 100644 --- a/src/internal/animate.ts +++ b/src/internal/animate.ts @@ -11,7 +11,13 @@ export async function animate(el: Element, keyframes: Keyframe[], options?: Keyf */ export function animateWithClass(el: Element, className: string) { return new Promise(resolve => { + if (!el) { + resolve() + return + } + el.classList.remove(className); + const controller = new AbortController(); const { signal } = controller;