browsertrix/frontend/src/controllers/navigate.ts
sua yoo 901f1435d7
Refactor LiteElement into reactive controllers (#1423)
- Copies navigation and notification utility methods into separate
controllers
- Adds deprecation notice to `LitElement` methods
- Default type import start to inline
2023-12-05 15:30:10 -08:00

76 lines
1.7 KiB
TypeScript

import type { ReactiveController, ReactiveControllerHost } from "lit";
import appState from "@/utils/state";
const NAVIGATE_EVENT_NAME = "navigate";
export interface NavigateEvent extends CustomEvent {
detail: {
url: string;
state?: object;
};
}
/**
* Manage app navigation
*/
export class NavigateController implements ReactiveController {
private host: ReactiveControllerHost & EventTarget;
get orgBasePath() {
const slug = appState.orgSlug;
if (slug) {
return `/orgs/${slug}`;
}
return "/";
}
constructor(host: NavigateController["host"]) {
this.host = host;
host.addController(this);
}
hostConnected() {}
hostDisconnected() {}
to(url: string, state?: object): void {
const evt: NavigateEvent = new CustomEvent(NAVIGATE_EVENT_NAME, {
detail: { url, state },
bubbles: true,
composed: true,
});
this.host.dispatchEvent(evt);
}
/**
* Bind to anchor tag to prevent full page navigation
* @example
* ```ts
* <a href="/" @click=${this.navigate.link}>go</a>
* ```
* @param event Click event
*/
link(event: MouseEvent, _href?: string): void {
if (
// Detect keypress for opening in a new tab
event.ctrlKey ||
event.shiftKey ||
event.metaKey ||
(event.button && event.button == 1) ||
// Account for event prevented on anchor tag
event.defaultPrevented
) {
return;
}
event.preventDefault();
const evt: NavigateEvent = new CustomEvent(NAVIGATE_EVENT_NAME, {
detail: { url: (event.currentTarget as HTMLAnchorElement).href },
bubbles: true,
composed: true,
});
this.host.dispatchEvent(evt);
}
}