diff --git a/.changeset/nice-peas-begin.md b/.changeset/nice-peas-begin.md new file mode 100644 index 00000000..c090f941 --- /dev/null +++ b/.changeset/nice-peas-begin.md @@ -0,0 +1,5 @@ +--- +"runed": minor +--- + +add PressedKeys utility diff --git a/logo.svg b/logo.svg new file mode 100644 index 00000000..a432cbfe --- /dev/null +++ b/logo.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + diff --git a/packages/runed/src/lib/utilities/ElementSize/ElementSize.svelte.ts b/packages/runed/src/lib/utilities/ElementSize/ElementSize.svelte.ts index d8d58d95..a0bd737f 100644 --- a/packages/runed/src/lib/utilities/ElementSize/ElementSize.svelte.ts +++ b/packages/runed/src/lib/utilities/ElementSize/ElementSize.svelte.ts @@ -18,7 +18,7 @@ export type ElementSizeOptions = { * * @returns an object with `width` and `height` properties. * - * @see {@link https://runed.dev/docs/utilities/use-element-size} + * @see {@link https://runed.dev/docs/utilities/element-size} */ export class ElementSize { #size = $state({ diff --git a/packages/runed/src/lib/utilities/IsMounted/IsMounted.svelte.ts b/packages/runed/src/lib/utilities/IsMounted/IsMounted.svelte.ts index abbef5db..72e25327 100644 --- a/packages/runed/src/lib/utilities/IsMounted/IsMounted.svelte.ts +++ b/packages/runed/src/lib/utilities/IsMounted/IsMounted.svelte.ts @@ -4,7 +4,7 @@ import { untrack } from "svelte"; * Returns an object with the mounted state of the component * that invokes this function. * - * @see {@link https://runed.dev/docs/utilities/use-mounted} + * @see {@link https://runed.dev/docs/utilities/is-mounted} */ export class IsMounted { #isMounted = $state(false); diff --git a/packages/runed/src/lib/utilities/IsSupported/IsSupported.ts b/packages/runed/src/lib/utilities/IsSupported/IsSupported.ts index 0e31862e..6f27e0f1 100644 --- a/packages/runed/src/lib/utilities/IsSupported/IsSupported.ts +++ b/packages/runed/src/lib/utilities/IsSupported/IsSupported.ts @@ -3,7 +3,7 @@ * * Useful for checking if a browser API is supported before attempting to use it. * - * @see {@link https://runed.dev/docs/utilities/use-supported} + * @see {@link https://runed.dev/docs/utilities/supported} */ export class IsSupported { #current = $state(false); diff --git a/packages/runed/src/lib/utilities/PressedKeys/PressedKeys.svelte.ts b/packages/runed/src/lib/utilities/PressedKeys/PressedKeys.svelte.ts new file mode 100644 index 00000000..e1973eab --- /dev/null +++ b/packages/runed/src/lib/utilities/PressedKeys/PressedKeys.svelte.ts @@ -0,0 +1,43 @@ +import { addEventListener } from "$lib/internal/utils/event.js"; + +/** + * Tracks which keys are currently pressed. + * + * @see {@link https://runed.dev/docs/utilities/pressed-keys} + */ +export class PressedKeys { + #pressedKeys = $state>([]); + + constructor() { + $effect(() => { + const callbacks: VoidFunction[] = []; + + callbacks.push( + addEventListener(window, "keydown", (e) => { + const key = e.key.toLowerCase(); + if (!this.#pressedKeys.includes(key)) { + this.#pressedKeys.push(key); + } + }) + ); + + callbacks.push( + addEventListener(window, "keyup", (e) => { + const key = e.key.toLowerCase(); + this.#pressedKeys = this.#pressedKeys.filter((k) => k !== key); + }) + ); + + return () => callbacks.forEach((c) => c()); + }); + } + + has(...keys: string[]) { + const normalizedKeys = keys.map((key) => key.toLowerCase()); + return normalizedKeys.every((key) => this.#pressedKeys.includes(key)); + } + + get all() { + return this.#pressedKeys; + } +} diff --git a/packages/runed/src/lib/utilities/PressedKeys/index.ts b/packages/runed/src/lib/utilities/PressedKeys/index.ts new file mode 100644 index 00000000..390fb310 --- /dev/null +++ b/packages/runed/src/lib/utilities/PressedKeys/index.ts @@ -0,0 +1 @@ +export { PressedKeys } from "./PressedKeys.svelte.js"; diff --git a/packages/runed/src/lib/utilities/Previous/Previous.svelte.ts b/packages/runed/src/lib/utilities/Previous/Previous.svelte.ts index fc5dc0c7..0bbbdf1d 100644 --- a/packages/runed/src/lib/utilities/Previous/Previous.svelte.ts +++ b/packages/runed/src/lib/utilities/Previous/Previous.svelte.ts @@ -3,7 +3,7 @@ import type { Getter } from "$lib/internal/types.js"; /** * Holds the previous value of a getter. * - * @see {@link https://runed.dev/docs/utilities/use-previous} + * @see {@link https://runed.dev/docs/utilities/previous} */ export class Previous { #previous = $state(undefined); diff --git a/packages/runed/src/lib/utilities/StateHistory/StateHistory.svelte.ts b/packages/runed/src/lib/utilities/StateHistory/StateHistory.svelte.ts index bf40054b..18e483db 100644 --- a/packages/runed/src/lib/utilities/StateHistory/StateHistory.svelte.ts +++ b/packages/runed/src/lib/utilities/StateHistory/StateHistory.svelte.ts @@ -14,7 +14,7 @@ type StateHistoryOptions = { /** * Tracks the change history of a value, providing undo and redo capabilities. * - * @see {@link https://runed.dev/docs/utilities/use-state-history} + * @see {@link https://runed.dev/docs/utilities/state-history} */ export class StateHistory { #redoStack = $state[]>([]); diff --git a/packages/runed/src/lib/utilities/activeElement/activeElement.svelte.ts b/packages/runed/src/lib/utilities/activeElement/activeElement.svelte.ts index 993dd257..ad44d94c 100644 --- a/packages/runed/src/lib/utilities/activeElement/activeElement.svelte.ts +++ b/packages/runed/src/lib/utilities/activeElement/activeElement.svelte.ts @@ -4,7 +4,7 @@ import { Readable } from "../Readable/readable.svelte.js"; * An object holding a reactive value that is equal to `document.activeElement`. * It automatically listens for changes, keeping the reference up to date. * - * @see {@link https://runed.dev/docs/utilities/use-active-element} + * @see {@link https://runed.dev/docs/utilities/active-element} */ export const activeElement = new Readable(null, (set, insideEffect) => { function update() { diff --git a/packages/runed/src/lib/utilities/index.ts b/packages/runed/src/lib/utilities/index.ts index b9efbbbc..90db8bf1 100644 --- a/packages/runed/src/lib/utilities/index.ts +++ b/packages/runed/src/lib/utilities/index.ts @@ -9,3 +9,4 @@ export * from "./Previous/index.js"; export * from "./watch/index.js"; export * from "./Readable/index.js"; export * from "./Debounced/index.js"; +export * from "./PressedKeys/index.js"; diff --git a/sites/docs/content/utilities/pressed-keys.md b/sites/docs/content/utilities/pressed-keys.md new file mode 100644 index 00000000..e15482cd --- /dev/null +++ b/sites/docs/content/utilities/pressed-keys.md @@ -0,0 +1,31 @@ +--- +title: PressedKeys +description: Tracks which keys are currently pressed +category: Browser +--- + + + +## Demo + + + +## Usage + +With an instance of `PressedKeys`, you can use the `has` method. + +```ts +const keys = new PressedKeys(); + +const isArrowDownPressed = $derived(keys.has("ArrowDown")); +const isCtrlAPressed = $derived(keys.has("Control", "a")); +``` + +Or get all of the currently pressed keys: + +```ts +const keys = new PressedKeys(); +console.log(keys.all()); +``` diff --git a/sites/docs/src/lib/components/demos/pressed-keys.svelte b/sites/docs/src/lib/components/demos/pressed-keys.svelte new file mode 100644 index 00000000..e298a1e1 --- /dev/null +++ b/sites/docs/src/lib/components/demos/pressed-keys.svelte @@ -0,0 +1,68 @@ + + +
+
+ {#if allPressed} +
+ +
+ {/if} + {#each toPress as key} + +
(triedInputting = true)} + > + {#if keys.has(key)} + + {key} + + {/if} +
+ {/each} +
+

{guessedCorrectly ? "You did it! 🎉" : "Try and guess the password 👀"}

+ + {#if !guessedCorrectly && triedInputting} +

+ Press any key to start, no need to select anything +

+ {/if} +
diff --git a/sites/docs/src/lib/components/logos/index.ts b/sites/docs/src/lib/components/logos/index.ts deleted file mode 100644 index d3e4c548..00000000 --- a/sites/docs/src/lib/components/logos/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { default as SvecosystemDark } from "./svecosystem-dark.svelte"; -export { default as SvecosystemLight } from "./svecosystem-light.svelte"; -export { default as WithRunesDark } from "./runed-dark.svelte"; -export { default as WithRunesLight } from "./runed-light.svelte"; diff --git a/sites/docs/src/lib/components/logos/runed-icon.svelte b/sites/docs/src/lib/components/logos/runed-icon.svelte new file mode 100644 index 00000000..f90846ec --- /dev/null +++ b/sites/docs/src/lib/components/logos/runed-icon.svelte @@ -0,0 +1,34 @@ + + + + + + + + + +