mirror of
https://github.com/discourse/discourse.git
synced 2025-02-16 18:24:52 -06:00
UX: Allow opening user-menu tabs in new tab/window (#20792)
This commit turns the new user menu tabs into `<a href` elements. This means that the tab's associated URL is shown on mouseover, and also allows the browser to handle navigation when a modifier key is pressed (e.g. ctrl, shift, mod).
This commit is contained in:
parent
ed6f7b1e6d
commit
d2617c4904
@ -1,5 +1,4 @@
|
||||
<button
|
||||
type="button"
|
||||
<a
|
||||
role="tab"
|
||||
class={{this.classNames}}
|
||||
id={{this.id}}
|
||||
@ -8,12 +7,12 @@
|
||||
aria-selected={{if this.isActive "true" "false"}}
|
||||
aria-controls={{this.ariaControls}}
|
||||
data-tab-number={{@tab.position}}
|
||||
href={{@tab.linkWhenActive}}
|
||||
{{on "click" @onTabClick}}
|
||||
{{! template-lint-disable require-context-role }}
|
||||
>
|
||||
{{d-icon @tab.icon}}
|
||||
{{#if @tab.count}}
|
||||
<span aria-hidden="true" class="badge-notification">{{@tab.count}}</span>
|
||||
{{/if}}
|
||||
{{yield}}
|
||||
</button>
|
||||
</a>
|
@ -5,7 +5,7 @@ import { NO_REMINDER_ICON } from "discourse/models/bookmark";
|
||||
import UserMenuTab, { CUSTOM_TABS_CLASSES } from "discourse/lib/user-menu/tab";
|
||||
import { inject as service } from "@ember/service";
|
||||
import getUrl from "discourse-common/lib/get-url";
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import { wantsNewWindow } from "discourse/lib/intercept-click";
|
||||
|
||||
const DEFAULT_TAB_ID = "all-notifications";
|
||||
const DEFAULT_PANEL_COMPONENT = "user-menu/notifications-list";
|
||||
@ -314,14 +314,17 @@ export default class UserMenu extends Component {
|
||||
}
|
||||
|
||||
@action
|
||||
handleTabClick(tab) {
|
||||
if (this.currentTabId !== tab.id) {
|
||||
this.currentTabId = tab.id;
|
||||
this.currentPanelComponent = tab.panelComponent;
|
||||
this.currentNotificationTypes = tab.notificationTypes;
|
||||
} else if (tab.linkWhenActive) {
|
||||
DiscourseURL.routeTo(tab.linkWhenActive);
|
||||
handleTabClick(tab, event) {
|
||||
if (wantsNewWindow(event) || this.currentTabId === tab.id) {
|
||||
// Allow normal navigation to href
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
this.currentTabId = tab.id;
|
||||
this.currentPanelComponent = tab.panelComponent;
|
||||
this.currentNotificationTypes = tab.notificationTypes;
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -748,6 +748,34 @@ acceptance("User menu", function (needs) {
|
||||
await click("#site-logo");
|
||||
}
|
||||
});
|
||||
|
||||
test("tabs have hrefs and can be opened in new window/tab", async function (assert) {
|
||||
await visit("/");
|
||||
await click(".d-header-icons .current-user");
|
||||
|
||||
assert
|
||||
.dom("#user-menu-button-replies")
|
||||
.hasAttribute("href", "/u/eviltrout/notifications/responses");
|
||||
|
||||
// Add a top-level click listener to stub attempts to open a new window/tab
|
||||
const newWindowOpenedAssertion = assert.async();
|
||||
const interceptor = (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
newWindowOpenedAssertion();
|
||||
const target = event.target;
|
||||
assert.strictEqual(target.tagName, "A");
|
||||
assert.true(target.href.endsWith("/u/eviltrout/notifications/responses"));
|
||||
};
|
||||
|
||||
window.addEventListener("click", interceptor);
|
||||
|
||||
try {
|
||||
await click("#user-menu-button-replies", { shiftKey: true });
|
||||
} finally {
|
||||
window.removeEventListener("click", interceptor);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
acceptance("User menu - Dismiss button", function (needs) {
|
||||
|
Loading…
Reference in New Issue
Block a user