UX: allows to close popover on escape (#16698)
This commit is contained in:
parent
5fb6dd5664
commit
142ae3b5e5
|
@ -4,6 +4,7 @@ import tippy from "tippy.js";
|
||||||
import { guidFor } from "@ember/object/internals";
|
import { guidFor } from "@ember/object/internals";
|
||||||
import { action } from "@ember/object";
|
import { action } from "@ember/object";
|
||||||
import { next } from "@ember/runloop";
|
import { next } from "@ember/runloop";
|
||||||
|
import { hideOnEscapePlugin } from "discourse/lib/d-popover";
|
||||||
|
|
||||||
export default class DiscoursePopover extends Component {
|
export default class DiscoursePopover extends Component {
|
||||||
tagName = "";
|
tagName = "";
|
||||||
|
@ -50,6 +51,7 @@ export default class DiscoursePopover extends Component {
|
||||||
allowHTML: false,
|
allowHTML: false,
|
||||||
appendTo: "parent",
|
appendTo: "parent",
|
||||||
hideOnClick: true,
|
hideOnClick: true,
|
||||||
|
plugins: [hideOnEscapePlugin],
|
||||||
content:
|
content:
|
||||||
this.options?.content ||
|
this.options?.content ||
|
||||||
document
|
document
|
||||||
|
|
|
@ -3,6 +3,29 @@ import { run } from "@ember/runloop";
|
||||||
import tippy from "tippy.js";
|
import tippy from "tippy.js";
|
||||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||||
|
|
||||||
|
export const hideOnEscapePlugin = {
|
||||||
|
name: "hideOnEscape",
|
||||||
|
|
||||||
|
defaultValue: true,
|
||||||
|
|
||||||
|
fn({ hide }) {
|
||||||
|
function onKeyDown(event) {
|
||||||
|
if (event.keyCode === 27) {
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
onShow() {
|
||||||
|
document.addEventListener("keydown", onKeyDown);
|
||||||
|
},
|
||||||
|
onHide() {
|
||||||
|
document.removeEventListener("keydown", onKeyDown);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export function hidePopover(event) {
|
export function hidePopover(event) {
|
||||||
if (event?.target?._tippy) {
|
if (event?.target?._tippy) {
|
||||||
showPopover(event);
|
showPopover(event);
|
||||||
|
@ -20,6 +43,7 @@ export function showPopover(event, options = {}) {
|
||||||
trigger: "mouseenter click",
|
trigger: "mouseenter click",
|
||||||
hideOnClick: true,
|
hideOnClick: true,
|
||||||
zIndex: 1400,
|
zIndex: 1400,
|
||||||
|
plugins: [hideOnEscapePlugin],
|
||||||
},
|
},
|
||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
} from "discourse/tests/helpers/qunit-helpers";
|
} from "discourse/tests/helpers/qunit-helpers";
|
||||||
import hbs from "htmlbars-inline-precompile";
|
import hbs from "htmlbars-inline-precompile";
|
||||||
import { showPopover } from "discourse/lib/d-popover";
|
import { showPopover } from "discourse/lib/d-popover";
|
||||||
import { click } from "@ember/test-helpers";
|
import { click, triggerKeyEvent } from "@ember/test-helpers";
|
||||||
|
|
||||||
discourseModule("Integration | Component | d-popover", function (hooks) {
|
discourseModule("Integration | Component | d-popover", function (hooks) {
|
||||||
setupRenderingTest(hooks);
|
setupRenderingTest(hooks);
|
||||||
|
@ -85,4 +85,18 @@ discourseModule("Integration | Component | d-popover", function (hooks) {
|
||||||
assert.ok(exists(".d-popover.foo"));
|
assert.ok(exists(".d-popover.foo"));
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
componentTest("d-popover component closes on escape key", {
|
||||||
|
template: hbs`{{#d-popover as |state|}}{{d-button icon=(if state.isExpanded "chevron-up" "chevron-down")}}{{/d-popover}}`,
|
||||||
|
|
||||||
|
async test(assert) {
|
||||||
|
await click(".btn");
|
||||||
|
|
||||||
|
assert.ok(exists(".d-popover.is-expanded"));
|
||||||
|
|
||||||
|
await triggerKeyEvent(document, "keydown", 27);
|
||||||
|
|
||||||
|
assert.notOk(exists(".d-popover.is-expanded"));
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue