From a02debc53b5ded56c0d7a53034c0148fe37fa636 Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:06:30 +1300 Subject: [PATCH 1/7] chore(test app autofocus input): replace render modifier --- tests/dummy/app/components/autofocus-input.js | 5 +++-- tests/dummy/app/templates/components/autofocus-input.hbs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/dummy/app/components/autofocus-input.js b/tests/dummy/app/components/autofocus-input.js index 24283d08..839fc3f2 100644 --- a/tests/dummy/app/components/autofocus-input.js +++ b/tests/dummy/app/components/autofocus-input.js @@ -1,7 +1,8 @@ import Component from '@glimmer/component'; +import { modifier } from 'ember-modifier'; export default class extends Component { - focusInput(input) { + focusInput = modifier((input) => { input.focus(); - } + }); } diff --git a/tests/dummy/app/templates/components/autofocus-input.hbs b/tests/dummy/app/templates/components/autofocus-input.hbs index 85964995..024d9f59 100644 --- a/tests/dummy/app/templates/components/autofocus-input.hbs +++ b/tests/dummy/app/templates/components/autofocus-input.hbs @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From cb95ba5ea02bd220bd9a29fd13881ceb5e40c80f Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:13:43 +1300 Subject: [PATCH 2/7] refactor(basic-dropdown-content): migrate animation render modifiers to a plain modifier --- addon/components/basic-dropdown-content.hbs | 3 +- addon/components/basic-dropdown-content.ts | 50 ++++++++++----------- 2 files changed, 25 insertions(+), 28 deletions(-) diff --git a/addon/components/basic-dropdown-content.hbs b/addon/components/basic-dropdown-content.hbs index 141dd9b5..973e6ceb 100644 --- a/addon/components/basic-dropdown-content.hbs +++ b/addon/components/basic-dropdown-content.hbs @@ -25,9 +25,8 @@ {{did-insert this.setup}} {{did-insert @dropdown.actions.reposition}} {{did-insert this.setupMutationObserver}} - {{did-insert this.animateIn}} + {{this.animateInAndOut}} {{will-destroy this.teardownMutationObserver}} - {{will-destroy this.animateOut}} {{will-destroy this.teardown}} {{on 'focusin' (fn (or @onFocusIn this.noop) @dropdown)}} {{on 'focusout' (fn (or @onFocusOut this.noop) @dropdown)}} diff --git a/addon/components/basic-dropdown-content.ts b/addon/components/basic-dropdown-content.ts index 400350d8..36e421f9 100644 --- a/addon/components/basic-dropdown-content.ts +++ b/addon/components/basic-dropdown-content.ts @@ -11,6 +11,7 @@ import { import hasMoved from '../utils/has-moved'; import { Dropdown } from './basic-dropdown'; import { isTesting } from '@embroider/macros'; +import { modifier } from 'ember-modifier'; interface Args { animationEnabled?: boolean; @@ -66,7 +67,7 @@ export default class BasicDropdownContent extends Component { return animationEnabledArg && !isTesting(); } - + get positionStyles(): Record { const style: Record = {}; if (this.args.top !== undefined) { @@ -161,34 +162,31 @@ export default class BasicDropdownContent extends Component { } } - @action - animateIn(dropdownElement: Element): void { - if (!this.animationEnabled) return; + animateInAndOut = modifier((dropdownElement: Element): () => void => { + if (!this.animationEnabled) return () => {}; waitForAnimations(dropdownElement, () => { this.animationClass = this.transitionedInClass; }); - } - - @action - animateOut(dropdownElement: Element): void { - if (!this.animationEnabled) return; - let parentElement = - dropdownElement.parentElement ?? this.destinationElement; - if (parentElement === null) return; - if (this.args.renderInPlace) { - parentElement = parentElement.parentElement; - } - if (parentElement === null) return; - let clone = dropdownElement.cloneNode(true) as Element; - clone.id = `${clone.id}--clone`; - clone.classList.remove(...this.transitioningInClass.split(' ')); - clone.classList.add(...this.transitioningOutClass.split(' ')); - parentElement.appendChild(clone); - this.animationClass = this.transitioningInClass; - waitForAnimations(clone, function () { - (parentElement as HTMLElement).removeChild(clone); - }); - } + return () => { + if (!this.animationEnabled) return; + let parentElement = + dropdownElement.parentElement ?? this.destinationElement; + if (parentElement === null) return; + if (this.args.renderInPlace) { + parentElement = parentElement.parentElement; + } + if (parentElement === null) return; + let clone = dropdownElement.cloneNode(true) as Element; + clone.id = `${clone.id}--clone`; + clone.classList.remove(...this.transitioningInClass.split(' ')); + clone.classList.add(...this.transitioningOutClass.split(' ')); + parentElement.appendChild(clone); + this.animationClass = this.transitioningInClass; + waitForAnimations(clone, function () { + (parentElement as HTMLElement).removeChild(clone); + }); + }; + }); @action setupMutationObserver(dropdownElement: Element): void { From 8c1d230554ff6ef8ac9e1e0717d088c088e27f6b Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:16:44 +1300 Subject: [PATCH 3/7] refactor(basic-dropdown-content): migrate mutation observer render modifiers to a plain modifier --- addon/components/basic-dropdown-content.hbs | 3 +-- addon/components/basic-dropdown-content.ts | 17 +++++++---------- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/addon/components/basic-dropdown-content.hbs b/addon/components/basic-dropdown-content.hbs index 973e6ceb..8c930a7a 100644 --- a/addon/components/basic-dropdown-content.hbs +++ b/addon/components/basic-dropdown-content.hbs @@ -24,9 +24,8 @@ }} {{did-insert this.setup}} {{did-insert @dropdown.actions.reposition}} - {{did-insert this.setupMutationObserver}} + {{this.observeMutations}} {{this.animateInAndOut}} - {{will-destroy this.teardownMutationObserver}} {{will-destroy this.teardown}} {{on 'focusin' (fn (or @onFocusIn this.noop) @dropdown)}} {{on 'focusout' (fn (or @onFocusOut this.noop) @dropdown)}} diff --git a/addon/components/basic-dropdown-content.ts b/addon/components/basic-dropdown-content.ts index 36e421f9..395c74e5 100644 --- a/addon/components/basic-dropdown-content.ts +++ b/addon/components/basic-dropdown-content.ts @@ -188,8 +188,7 @@ export default class BasicDropdownContent extends Component { }; }); - @action - setupMutationObserver(dropdownElement: Element): void { + observeMutations = modifier((dropdownElement: Element): () => void => { this.mutationObserver = new MutationObserver((mutations) => { let shouldReposition = mutations.some( (record: MutationRecord) => @@ -212,15 +211,13 @@ export default class BasicDropdownContent extends Component { childList: true, subtree: true, }); - } - - @action - teardownMutationObserver(): void { - if (this.mutationObserver !== undefined) { - this.mutationObserver.disconnect(); - this.mutationObserver = undefined; + return () => { + if (this.mutationObserver !== undefined) { + this.mutationObserver.disconnect(); + this.mutationObserver = undefined; + } } - } + }); @action touchStartHandler(): void { From 80320526337dbf38a668b98590215de92d4ca3cc Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:25:19 +1300 Subject: [PATCH 4/7] refactor(basic-dropdown-content): migrate event binding render modifiers to a plain modifier --- addon/components/basic-dropdown-content.hbs | 3 +- addon/components/basic-dropdown-content.ts | 35 ++++++++++----------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/addon/components/basic-dropdown-content.hbs b/addon/components/basic-dropdown-content.hbs index 8c930a7a..c6b43720 100644 --- a/addon/components/basic-dropdown-content.hbs +++ b/addon/components/basic-dropdown-content.hbs @@ -22,11 +22,10 @@ @otherStyles this.positionStyles }} - {{did-insert this.setup}} + {{this.respondToEvents}} {{did-insert @dropdown.actions.reposition}} {{this.observeMutations}} {{this.animateInAndOut}} - {{will-destroy this.teardown}} {{on 'focusin' (fn (or @onFocusIn this.noop) @dropdown)}} {{on 'focusout' (fn (or @onFocusOut this.noop) @dropdown)}} {{on 'mouseenter' (fn (or @onMouseEnter this.noop) @dropdown)}} diff --git a/addon/components/basic-dropdown-content.ts b/addon/components/basic-dropdown-content.ts index 395c74e5..395e89a1 100644 --- a/addon/components/basic-dropdown-content.ts +++ b/addon/components/basic-dropdown-content.ts @@ -98,8 +98,7 @@ export default class BasicDropdownContent extends Component { */ noop(): void {} - @action - setup(dropdownElement: Element): void { + respondToEvents = modifier((dropdownElement: Element): () => void => { let triggerElement = document.querySelector( `[data-ebd-id=${this.args.dropdown.uniqueId}-trigger]` ); @@ -138,29 +137,27 @@ export default class BasicDropdownContent extends Component { this.scrollableAncestors = getScrollableAncestors(triggerElement); } this.addScrollHandling(dropdownElement); - } - - @action - teardown(): void { - this.removeGlobalEvents(); - this.removeScrollHandling(); - this.scrollableAncestors = []; - - document.removeEventListener( - this.args.rootEventType, - this.handleRootMouseDown as RootMouseDownHandler, - true - ); + return () => { + this.removeGlobalEvents(); + this.removeScrollHandling(); + this.scrollableAncestors = []; - if (this.isTouchDevice) { - document.removeEventListener('touchstart', this.touchStartHandler, true); document.removeEventListener( - 'touchend', + this.args.rootEventType, this.handleRootMouseDown as RootMouseDownHandler, true ); + + if (this.isTouchDevice) { + document.removeEventListener('touchstart', this.touchStartHandler, true); + document.removeEventListener( + 'touchend', + this.handleRootMouseDown as RootMouseDownHandler, + true + ); + } } - } + }); animateInAndOut = modifier((dropdownElement: Element): () => void => { if (!this.animationEnabled) return () => {}; From 4a5af2e2504094b3e98f129f6d8d5f85b17eb297 Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:42:33 +1300 Subject: [PATCH 5/7] refactor(basic-dropdown-content): migrate initial reposition render modifier to a plain modifier --- addon/components/basic-dropdown-content.hbs | 2 +- addon/components/basic-dropdown-content.ts | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/addon/components/basic-dropdown-content.hbs b/addon/components/basic-dropdown-content.hbs index c6b43720..f61be26f 100644 --- a/addon/components/basic-dropdown-content.hbs +++ b/addon/components/basic-dropdown-content.hbs @@ -23,7 +23,7 @@ this.positionStyles }} {{this.respondToEvents}} - {{did-insert @dropdown.actions.reposition}} + {{this.initiallyReposition}} {{this.observeMutations}} {{this.animateInAndOut}} {{on 'focusin' (fn (or @onFocusIn this.noop) @dropdown)}} diff --git a/addon/components/basic-dropdown-content.ts b/addon/components/basic-dropdown-content.ts index 395e89a1..962b27f2 100644 --- a/addon/components/basic-dropdown-content.ts +++ b/addon/components/basic-dropdown-content.ts @@ -159,6 +159,13 @@ export default class BasicDropdownContent extends Component { } }); + initiallyReposition = modifier(() => { + // Escape autotracking frame and avoid backtracking re-render + Promise.resolve().then(() => { + this.args.dropdown.actions.reposition() + }); + }); + animateInAndOut = modifier((dropdownElement: Element): () => void => { if (!this.animationEnabled) return () => {}; waitForAnimations(dropdownElement, () => { From e2c323b352ebe8990f3fa499634ac30e65b59646 Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:45:10 +1300 Subject: [PATCH 6/7] chore(deps): drop dependency on @ember/render-modifiers --- package-lock.json | 5 ++++- package.json | 1 - 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index cb71bffd..f166c794 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "7.2.2", "license": "MIT", "dependencies": { - "@ember/render-modifiers": "^2.0.5", "@embroider/macros": "^1.12.0", "@embroider/util": "^1.11.0", "@glimmer/component": "^1.1.2", @@ -2000,6 +1999,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/@ember/render-modifiers/-/render-modifiers-2.1.0.tgz", "integrity": "sha512-LruhfoDv2itpk0fA0IC76Sxjcnq/7BC6txpQo40hOko8Dn6OxwQfxkPIbZGV0Cz7df+iX+VJrcYzNIvlc3w2EQ==", + "dev": true, "dependencies": { "@embroider/macros": "^1.0.0", "ember-cli-babel": "^7.26.11", @@ -12480,6 +12480,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/ember-modifier-manager-polyfill/-/ember-modifier-manager-polyfill-1.2.0.tgz", "integrity": "sha512-bnaKF1LLKMkBNeDoetvIJ4vhwRPKIIumWr6dbVuW6W6p4QV8ZiO+GdF8J7mxDNlog9CeL9Z/7wam4YS86G8BYA==", + "dev": true, "dependencies": { "ember-cli-babel": "^7.10.0", "ember-cli-version-checker": "^2.1.2", @@ -12493,6 +12494,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz", "integrity": "sha512-G+KtYIVlSOWGcNaTFHk76xR4GdzDLzAS4uxZUKdASuFX0KJE43C6DaqL+y3VTpUFLI2FIkAS6HZ4I1YBi+S3hg==", + "dev": true, "dependencies": { "resolve": "^1.3.3", "semver": "^5.3.0" @@ -12505,6 +12507,7 @@ "version": "5.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, "bin": { "semver": "bin/semver" } diff --git a/package.json b/package.json index ffa49c4b..558b24de 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,6 @@ "test": "tests" }, "dependencies": { - "@ember/render-modifiers": "^2.0.5", "@embroider/macros": "^1.12.0", "@embroider/util": "^1.11.0", "@glimmer/component": "^1.1.2", From 0f895896765c54efe5f954141f47489b9c31aeb8 Mon Sep 17 00:00:00 2001 From: Giles Thompson Date: Mon, 23 Oct 2023 12:49:38 +1300 Subject: [PATCH 7/7] chore(basic dropdown content): add eager declarations for ember-modifer 3.2.x compat --- addon/components/basic-dropdown-content.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/addon/components/basic-dropdown-content.ts b/addon/components/basic-dropdown-content.ts index 962b27f2..9666c3df 100644 --- a/addon/components/basic-dropdown-content.ts +++ b/addon/components/basic-dropdown-content.ts @@ -157,14 +157,16 @@ export default class BasicDropdownContent extends Component { ); } } - }); + // @ts-ignore + }, { eager: false }); initiallyReposition = modifier(() => { // Escape autotracking frame and avoid backtracking re-render Promise.resolve().then(() => { this.args.dropdown.actions.reposition() }); - }); + // @ts-ignore + }, { eager: false }); animateInAndOut = modifier((dropdownElement: Element): () => void => { if (!this.animationEnabled) return () => {}; @@ -190,7 +192,8 @@ export default class BasicDropdownContent extends Component { (parentElement as HTMLElement).removeChild(clone); }); }; - }); + // @ts-ignore + }, { eager: false }); observeMutations = modifier((dropdownElement: Element): () => void => { this.mutationObserver = new MutationObserver((mutations) => { @@ -221,7 +224,8 @@ export default class BasicDropdownContent extends Component { this.mutationObserver = undefined; } } - }); + // @ts-ignore + }, { eager: false }); @action touchStartHandler(): void {