@sv-use/core
Version:
A collection of Svelte 5 utilities.
54 lines (53 loc) • 1.97 kB
JavaScript
import { handleEventListener } from '../handle-event-listener/index.svelte.js';
import { noop } from '../__internal__/utils.svelte.js';
import { defaultDocument } from '../__internal__/configurable.js';
/**
* Fires when users start typing on non-editable elements.
* @param callback The callback for when users start typing on non-editable elements.
* @param options Additional options to customize the behavior.
* @see https://svelte-librarian.github.io/sv-use/docs/core/on-start-typing
*/
export function onStartTyping(callback, options = {}) {
const { autoCleanup = true, document = defaultDocument } = options;
let cleanup = noop;
if (document) {
cleanup = handleEventListener(document, 'keydown', onKeydown, { autoCleanup, passive: true });
}
function onKeydown(event) {
if (!isFocusedElementEditable() && isTypedCharValid(event)) {
callback(event);
}
}
function isFocusedElementEditable() {
if (!document)
return;
if (!document.activeElement)
return false;
if (document.activeElement === document.body)
return false;
// Assume <input> and <textarea> elements are editable.
switch (document.activeElement.tagName) {
case 'INPUT':
case 'TEXTAREA':
return true;
}
// Check if any other focused element id editable.
return document.activeElement.hasAttribute('contenteditable');
}
function isTypedCharValid({ keyCode, metaKey, ctrlKey, altKey }) {
if (metaKey || ctrlKey || altKey)
return false;
// 0...9
if (keyCode >= 48 && keyCode <= 57)
return true;
// A...Z
if (keyCode >= 65 && keyCode <= 90)
return true;
// a...z
if (keyCode >= 97 && keyCode <= 122)
return true;
// All other keys.
return false;
}
return cleanup;
}