import mitt, { Emitter } from "mitt";
import { ref } from "vue";
export interface KeyDetails {
[key: string | symbol]: Pick<
KeyboardEvent,
| "key"
| "ctrlKey"
| "shiftKey"
| "altKey"
| "charCode"
| "code"
| "keyCode"
| "metaKey"
| "preventDefault"
>;
}
export const keyEmitter: Emitter<KeyDetails> = mitt<KeyDetails>();
// Make sure we don't start the emitter more than once.
// This happens often when developing the system and causes redundant keydown evs
let keyEmitterStarted = false;
export const startKeyEmitter = (document: Document) => {
if (keyEmitterStarted) return;
keyEmitterStarted = true;
document.addEventListener("keydown", (event: KeyboardEvent) => {
const fromInput = ["INPUT", "TEXTAREA", "SELECT"].includes(
(event.target as HTMLBodyElement)?.tagName,
);
if (!fromInput) {
// letter keys should be case insensitive
const isUpperCaseLetter = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".includes(
event.key,
);
keyEmitter.emit(
isUpperCaseLetter ? event.key.toLowerCase() : event.key,
event,
);
}
});
};
type AttributeDetails = {
selectedPath: { path: string; name: string };
selectedDocs: { docs: string; link: string } | null;
};
export const attributeEmitter: Emitter<AttributeDetails> =
mitt<AttributeDetails>();
export const windowWidthReactive = ref<number>(window.innerWidth);
export const windowHeightReactive = ref<number>(window.innerHeight);
export interface ResizeDetails {
[resize: string | symbol]: Pick<Event, "preventDefault" | "target">;
}
export const windowResizeEmitter: Emitter<ResizeDetails> =
mitt<ResizeDetails>();
let windowResizeEmitterStarted = false;
const onResize = (event: Event) => {
windowWidthReactive.value = window.innerWidth;
windowHeightReactive.value = window.innerHeight;
windowResizeEmitter.emit("resize", event);
};
export const startWindowResizeEmitter = (window: Window) => {
if (windowResizeEmitterStarted) return;
windowResizeEmitterStarted = true;
window.addEventListener("resize", onResize);
};
export interface MouseDetails {
[key: string | symbol]: Pick<
MouseEvent,
| "button"
| "clientX"
| "clientY"
| "altKey"
| "ctrlKey"
| "metaKey"
| "shiftKey"
| "preventDefault"
| "target"
>;
}
const onClick = (event: MouseEvent) => {
mouseEmitter.emit("click", event);
};
const onMouseDown = (event: MouseEvent) => {
mouseEmitter.emit("mousedown", event);
};
export const mouseEmitter: Emitter<MouseDetails> = mitt<MouseDetails>();
let mouseEmitterStarted = false;
export const startMouseEmitters = (window: Window) => {
if (mouseEmitterStarted) return;
mouseEmitterStarted = true;
window.addEventListener("click", onClick);
window.addEventListener("mousedown", onMouseDown);
};