Skip to content

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
Blankeos authored and github-actions[bot] committed Sep 28, 2024
1 parent f18ee92 commit 5b9e02a
Showing 1 changed file with 133 additions and 134 deletions.
267 changes: 133 additions & 134 deletions src/use-hotkeys/use-hotkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,149 +3,148 @@
// ===========================================================================

export type KeyboardModifiers = {
alt: boolean;
ctrl: boolean;
meta: boolean;
mod: boolean;
shift: boolean;
};

export type Hotkey = KeyboardModifiers & {
key?: string;
};

type CheckHotkeyMatch = (event: KeyboardEvent) => boolean;

export function parseHotkey(hotkey: string): Hotkey {
const keys = hotkey
.toLowerCase()
.split("+")
.map((part) => part.trim());

const modifiers: KeyboardModifiers = {
alt: keys.includes("alt"),
ctrl: keys.includes("ctrl"),
meta: keys.includes("meta"),
mod: keys.includes("mod"),
shift: keys.includes("shift"),
};

const reservedKeys = ["alt", "ctrl", "meta", "shift", "mod"];

const freeKey = keys.find((key) => !reservedKeys.includes(key));

return {
...modifiers,
key: freeKey,
};
alt: boolean
ctrl: boolean
meta: boolean
mod: boolean
shift: boolean
}

export type Hotkey = KeyboardModifiers & {
key?: string
}

type CheckHotkeyMatch = (event: KeyboardEvent) => boolean

export function parseHotkey(hotkey: string): Hotkey {
const keys = hotkey
.toLowerCase()
.split('+')
.map(part => part.trim())

const modifiers: KeyboardModifiers = {
alt: keys.includes('alt'),
ctrl: keys.includes('ctrl'),
meta: keys.includes('meta'),
mod: keys.includes('mod'),
shift: keys.includes('shift'),
}

function isExactHotkey(hotkey: Hotkey, event: KeyboardEvent): boolean {
const { alt, ctrl, meta, mod, shift, key } = hotkey;
const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey } = event;

if (alt !== altKey) {
return false;
}

if (mod) {
if (!ctrlKey && !metaKey) {
return false;
}
} else {
if (ctrl !== ctrlKey) {
return false;
}
if (meta !== metaKey) {
return false;
}

const reservedKeys = ['alt', 'ctrl', 'meta', 'shift', 'mod']

const freeKey = keys.find(key => !reservedKeys.includes(key))

return {
...modifiers,
key: freeKey,
}
}

function isExactHotkey(hotkey: Hotkey, event: KeyboardEvent): boolean {
const { alt, ctrl, meta, mod, shift, key } = hotkey
const { altKey, ctrlKey, metaKey, shiftKey, key: pressedKey } = event

if (alt !== altKey) {
return false
}

if (mod) {
if (!ctrlKey && !metaKey) {
return false
}
if (shift !== shiftKey) {
return false;
} else {
if (ctrl !== ctrlKey) {
return false
}

if (
key &&
(pressedKey.toLowerCase() === key.toLowerCase() ||
event.code.replace("Key", "").toLowerCase() === key.toLowerCase())
) {
return true;
if (meta !== metaKey) {
return false
}

return false;
}

export function getHotkeyMatcher(hotkey: string): CheckHotkeyMatch {
return (event) => isExactHotkey(parseHotkey(hotkey), event);
if (shift !== shiftKey) {
return false
}

export interface HotkeyItemOptions {
preventDefault?: boolean;

if (
key &&
(pressedKey.toLowerCase() === key.toLowerCase() ||
event.code.replace('Key', '').toLowerCase() === key.toLowerCase())
) {
return true
}

export function getHotkeyHandler(hotkeys: HotkeyItem[]) {
// TODO fix the any
return (event: any) => {
const _event = "nativeEvent" in event ? event.nativeEvent : event;
hotkeys.forEach(([hotkey, handler, options = { preventDefault: true }]) => {
if (getHotkeyMatcher(hotkey)(_event)) {
if (options.preventDefault) {
event.preventDefault();
}

handler(_event);

return false
}

export function getHotkeyMatcher(hotkey: string): CheckHotkeyMatch {
return event => isExactHotkey(parseHotkey(hotkey), event)
}

export interface HotkeyItemOptions {
preventDefault?: boolean
}

export function getHotkeyHandler(hotkeys: HotkeyItem[]) {
// TODO fix the any
return (event: any) => {
const _event = 'nativeEvent' in event ? event.nativeEvent : event
hotkeys.forEach(([hotkey, handler, options = { preventDefault: true }]) => {
if (getHotkeyMatcher(hotkey)(_event)) {
if (options.preventDefault) {
event.preventDefault()
}
});
};
}

// ===========================================================================
// The hook
// ===========================================================================
import { createEffect, onCleanup } from "solid-js";

export type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?];

function shouldFireEvent(
event: KeyboardEvent,
tagsToIgnore: string[],
triggerOnContentEditable = false
) {
if (event.target instanceof HTMLElement) {
if (triggerOnContentEditable) {
return !tagsToIgnore.includes(event.target.tagName);

handler(_event)
}

return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName);
})
}
}

// ===========================================================================
// The hook
// ===========================================================================
import { createEffect, onCleanup } from 'solid-js'

export type HotkeyItem = [string, (event: KeyboardEvent) => void, HotkeyItemOptions?]

function shouldFireEvent(
event: KeyboardEvent,
tagsToIgnore: string[],
triggerOnContentEditable = false,
) {
if (event.target instanceof HTMLElement) {
if (triggerOnContentEditable) {
return !tagsToIgnore.includes(event.target.tagName)
}
return true;

return !event.target.isContentEditable && !tagsToIgnore.includes(event.target.tagName)
}
export function useHotkeys(
hotkeys: HotkeyItem[],
tagsToIgnore: string[] = ["INPUT", "TEXTAREA", "SELECT"],
triggerOnContentEditable = false
) {
createEffect(() => {
const keydownListener = (event: KeyboardEvent) => {
hotkeys.forEach(([hotkey, handler, options = { preventDefault: true }]) => {
if (
getHotkeyMatcher(hotkey)(event) &&
shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)
) {
if (options.preventDefault) {
event.preventDefault();
}

handler(event);

return true
}

export function useHotkeys(
hotkeys: HotkeyItem[],
tagsToIgnore: string[] = ['INPUT', 'TEXTAREA', 'SELECT'],
triggerOnContentEditable = false,
) {
createEffect(() => {
const keydownListener = (event: KeyboardEvent) => {
hotkeys.forEach(([hotkey, handler, options = { preventDefault: true }]) => {
if (
getHotkeyMatcher(hotkey)(event) &&
shouldFireEvent(event, tagsToIgnore, triggerOnContentEditable)
) {
if (options.preventDefault) {
event.preventDefault()
}
});
};

document.documentElement.addEventListener("keydown", keydownListener);

onCleanup(() => document.documentElement.removeEventListener("keydown", keydownListener));
});
}


handler(event)
}
})
}

document.documentElement.addEventListener('keydown', keydownListener)

onCleanup(() => document.documentElement.removeEventListener('keydown', keydownListener))
})
}

0 comments on commit 5b9e02a

Please sign in to comment.