UNPKG

bits-ui

Version:

The headless components for Svelte.

52 lines (51 loc) 1.89 kB
import { executeCallbacks } from "svelte-toolbelt"; import { on } from "svelte/events"; // Using global state to avoid multiple listeners. let isUsingKeyboard = $state(false); /** * Detects whether the user is currently using the keyboard * or not by listening to keyboard and pointer events. Uses shared global * state to avoid listener duplication. */ export class IsUsingKeyboard { static _refs = 0; // Reference counting to avoid multiple listeners. static _cleanup; constructor() { $effect(() => { if (IsUsingKeyboard._refs === 0) { IsUsingKeyboard._cleanup = $effect.root(() => { const callbacksToDispose = []; const handlePointer = (_) => { isUsingKeyboard = false; }; const handleKeydown = (_) => { isUsingKeyboard = true; }; callbacksToDispose.push(on(document, "pointerdown", handlePointer, { capture: true, }), on(document, "pointermove", handlePointer, { capture: true, }), on(document, "keydown", handleKeydown, { capture: true, })); // Don't forget to spread and call twice. return executeCallbacks(...callbacksToDispose); }); } IsUsingKeyboard._refs++; return () => { IsUsingKeyboard._refs--; if (IsUsingKeyboard._refs === 0) { isUsingKeyboard = false; IsUsingKeyboard._cleanup?.(); } }; }); } get current() { return isUsingKeyboard; } set current(value) { isUsingKeyboard = value; } }