FIX: allows modals to disable swipe to close (#26460)
Prior to this fix the `swipe` modifier could not be disabled and we were not using the `this.dimissable` property to apply/not apply it. This commit adds a new `enabled` param to the `swipe` modifier, which is used in modals with the value of `this.dismissable`. Note this commit also adds tests for this modifier.
This commit is contained in:
parent
9182501366
commit
defd63d20b
|
@ -302,9 +302,9 @@ export default class DModal extends Component {
|
|||
<div
|
||||
class={{concatClass "d-modal__header" @headerClass}}
|
||||
{{swipe
|
||||
didStartSwipe=this.handleSwipeStarted
|
||||
didSwipe=this.handleSwipe
|
||||
didEndSwipe=this.handleSwipeEnded
|
||||
enabled=this.dismissable
|
||||
}}
|
||||
>
|
||||
{{yield to="headerAboveTitle"}}
|
||||
|
@ -396,9 +396,9 @@ export default class DModal extends Component {
|
|||
<div
|
||||
class="d-modal__backdrop"
|
||||
{{swipe
|
||||
didStartSwipe=this.handleSwipeStarted
|
||||
didSwipe=this.handleSwipe
|
||||
didEndSwipe=this.handleSwipeEnded
|
||||
enabled=this.dismissable
|
||||
}}
|
||||
{{on "click" this.handleWrapperClick}}
|
||||
></div>
|
||||
|
|
|
@ -26,10 +26,11 @@ export default class SwipeModifier extends Modifier {
|
|||
* @type {Element}
|
||||
*/
|
||||
element;
|
||||
enabled = true;
|
||||
|
||||
constructor(owner, args) {
|
||||
super(owner, args);
|
||||
registerDestructor(this, (instance) => instance.cleanup(instance.element));
|
||||
registerDestructor(this, (instance) => instance.cleanup());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -41,8 +42,14 @@ export default class SwipeModifier extends Modifier {
|
|||
* @param {Function} options.didStartSwipe Callback to be executed when a swipe starts.
|
||||
* @param {Function} options.didSwipe Callback to be executed when a swipe moves.
|
||||
* @param {Function} options.didEndSwipe Callback to be executed when a swipe ends.
|
||||
* @param {Boolean} options.enabled Enable or disable the swipe modifier.
|
||||
*/
|
||||
modify(element, _, { didStartSwipe, didSwipe, didEndSwipe }) {
|
||||
modify(element, _, { didStartSwipe, didSwipe, didEndSwipe, enabled }) {
|
||||
if (enabled === false) {
|
||||
this.enabled = enabled;
|
||||
return;
|
||||
}
|
||||
|
||||
this.element = element;
|
||||
this.didSwipeCallback = didSwipe;
|
||||
this.didStartSwipeCallback = didStartSwipe;
|
||||
|
@ -121,12 +128,14 @@ export default class SwipeModifier extends Modifier {
|
|||
|
||||
/**
|
||||
* Cleans up the modifier by removing event listeners from the element.
|
||||
*
|
||||
* @param {Element} element The DOM element from which to remove event listeners.
|
||||
*/
|
||||
cleanup(element) {
|
||||
element.removeEventListener("touchstart", this.handleTouchStart);
|
||||
element.removeEventListener("touchmove", this.handleTouchMove);
|
||||
element.removeEventListener("touchend", this.handleTouchEnd);
|
||||
cleanup() {
|
||||
if (!this.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.element?.removeEventListener("touchstart", this.handleTouchStart);
|
||||
this.element?.removeEventListener("touchmove", this.handleTouchMove);
|
||||
this.element?.removeEventListener("touchend", this.handleTouchEnd);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
import { render, triggerEvent } from "@ember/test-helpers";
|
||||
import { setupRenderingTest } from "ember-qunit";
|
||||
import hbs from "htmlbars-inline-precompile";
|
||||
import { module, test } from "qunit";
|
||||
|
||||
module("Integration | Modifier | swipe", function (hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test("it calls didStartSwipe on touchstart", async function (assert) {
|
||||
this.didStartSwipe = (state) => {
|
||||
assert.ok(state, "didStartSwipe called with state");
|
||||
};
|
||||
|
||||
await render(hbs`<div {{swipe didStartSwipe=this.didStartSwipe}}></div>`);
|
||||
|
||||
await triggerEvent("div", "touchstart", {
|
||||
touches: [{ clientX: 0, clientY: 0 }],
|
||||
});
|
||||
});
|
||||
|
||||
test("it calls didSwipe on touchmove", async function (assert) {
|
||||
this.didSwipe = (state) => {
|
||||
assert.ok(state, "didSwipe called with state");
|
||||
};
|
||||
|
||||
await render(hbs`<div {{swipe didSwipe=this.didSwipe}}></div>`);
|
||||
|
||||
await triggerEvent("div", "touchstart", {
|
||||
touches: [{ clientX: 0, clientY: 0 }],
|
||||
changedTouches: [{ clientX: 0, clientY: 0 }],
|
||||
});
|
||||
|
||||
await triggerEvent("div", "touchmove", {
|
||||
touches: [{ clientX: 5, clientY: 5 }],
|
||||
});
|
||||
});
|
||||
|
||||
test("it calls didEndSwipe on touchend", async function (assert) {
|
||||
this.didEndSwipe = (state) => {
|
||||
assert.ok(state, "didEndSwipe called with state");
|
||||
};
|
||||
|
||||
await render(hbs`<div {{swipe didEndSwipe=this.didEndSwipe}}></div>`);
|
||||
|
||||
await triggerEvent("div", "touchstart", {
|
||||
touches: [{ clientX: 0, clientY: 0 }],
|
||||
changedTouches: [{ clientX: 0, clientY: 0 }],
|
||||
});
|
||||
|
||||
await triggerEvent("div", "touchmove", {
|
||||
touches: [{ clientX: 10, clientY: 0 }],
|
||||
changedTouches: [{ clientX: 10, clientY: 0 }],
|
||||
});
|
||||
|
||||
await triggerEvent("div", "touchend", {
|
||||
changedTouches: [{ clientX: 10, clientY: 0 }],
|
||||
});
|
||||
});
|
||||
|
||||
test("it does not trigger when disabled", async function (assert) {
|
||||
let calls = 0;
|
||||
|
||||
this.didStartSwipe = () => {
|
||||
calls++;
|
||||
};
|
||||
|
||||
this.set("isEnabled", false);
|
||||
|
||||
await render(
|
||||
hbs`<div {{swipe didStartSwipe=this.didStartSwipe enabled=this.isEnabled}}></div>`
|
||||
);
|
||||
|
||||
await triggerEvent("div", "touchstart", {
|
||||
touches: [{ clientX: 0, clientY: 0 }],
|
||||
});
|
||||
|
||||
this.set("isEnabled", true);
|
||||
|
||||
await triggerEvent("div", "touchstart", {
|
||||
touches: [{ clientX: 0, clientY: 0 }],
|
||||
});
|
||||
|
||||
assert.deepEqual(calls, 1, "didStartSwipe should be called once");
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue