Skip to content

Commit

Permalink
Merge pull request #3 from Hugos68/feat/active-element
Browse files Browse the repository at this point in the history
Feat: Active Element Hook
  • Loading branch information
TGlide authored Apr 13, 2024
2 parents a023765 + 0cc93a0 commit a627f93
Show file tree
Hide file tree
Showing 14 changed files with 390 additions and 5 deletions.
5 changes: 5 additions & 0 deletions .changeset/late-cameras-whisper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"runed": minor
---

add useActiveElement
6 changes: 5 additions & 1 deletion packages/runed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
"url": "https://github.com/svecosystem/runed",
"directory": "packages/runed"
},
"funding": ["https://github.com/sponsors/huntabyte", "https://github.com/sponsors/tglide"],
"funding": [
"https://github.com/sponsors/huntabyte",
"https://github.com/sponsors/tglide"
],
"scripts": {
"dev": "pnpm sync && pnpm watch",
"build": "pnpm package",
Expand Down Expand Up @@ -45,6 +48,7 @@
"@sveltejs/package": "^2.3.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"@types/node": "^20.10.6",
"jsdom": "^24.0.0",
"publint": "^0.1.9",
"svelte": "^5.0.0-next.75",
"svelte-check": "^3.6.0",
Expand Down
1 change: 1 addition & 0 deletions packages/runed/src/lib/functions/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./useActiveElement/index.js";
export * from "./useDebounce/index.js";
export * from "./useElementSize/index.js";
1 change: 1 addition & 0 deletions packages/runed/src/lib/functions/useActiveElement/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./useActiveElement.svelte.js";
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { documentDefined } from "../../internal/utils/defined.js";

export function useActiveElement(): { value: Readonly<Element | null> } {
const activeElement = $state({ value: documentDefined() ? document.activeElement : null });

function onFocusChange() {
activeElement.value = document.activeElement;
}

$effect(() => {
document.addEventListener("focusin", onFocusChange);
document.addEventListener("focusout", onFocusChange);

return () => {
document.removeEventListener("focusin", onFocusChange);
document.removeEventListener("focusout", onFocusChange);
};
});

return activeElement;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { describe, expect } from "vitest";
import { tick } from "svelte";
import { useActiveElement } from "./index.js";
import { testWithEffect } from "$lib/test/util.svelte.js";

describe("useActiveElement", () => {
testWithEffect("initializes with `document.activeElement`", () => {
const activeElement = useActiveElement();
expect(activeElement.value).toBe(document.activeElement);
});
testWithEffect(
"updates accordingly when `document.activeElement` element changes",
async () => {
const input = document.createElement("input");
document.body.appendChild(input);
input.focus();

const activeElement = useActiveElement();
await tick();
expect(document.activeElement).toBe(input);
expect(activeElement.value).toBe(input);
}
);
});
3 changes: 3 additions & 0 deletions packages/runed/src/lib/internal/utils/defined.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function documentDefined() {
return typeof document !== "undefined";
}
13 changes: 13 additions & 0 deletions packages/runed/src/lib/test/util.svelte.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { it } from "vitest";

export function testWithEffect(name: string, fn: () => void) {
it(name, async () => {
let promise: Promise<void> | void;
const cleanup = $effect.root(() => (promise = fn()));
try {
await promise!;
} finally {
cleanup();
}
});
}
3 changes: 2 additions & 1 deletion packages/runed/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { defineConfig } from "vitest/config";
export default defineConfig({
plugins: [sveltekit()],
test: {
include: ["src/**/*.{test,spec}.{js,ts}"],
include: ["src/**/*.{test,test.svelte,spec}.{js,ts}"],
environment: "jsdom",
},
});
Loading

0 comments on commit a627f93

Please sign in to comment.