app/components/editor/typing.ts
25 lines and 5 functions in DrDustinEdwards/carrel, at commit d5d5e82 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| useTypingRecede | 7 to 27 | 1 | 100% | OkCRAP 1 | No data: mutation testing has not run on this repo yet |
| <anonymous:8> | 8 to 26 | 1 | 0% | OkCRAP 2 | No data: mutation testing has not run on this repo yet |
| settle | 10 to 12 | 2 | 0% | WatchCRAP 6 | No data: mutation testing has not run on this repo yet |
| type | 13 to 18 | 7 | 0% | CriticalCRAP 56 | No data: mutation testing has not run on this repo yet |
| <anonymous:21> | 21 to 25 | 1 | 0% | OkCRAP 2 | No data: mutation testing has not run on this repo yet |
Imports
It imports no other module of this repo. Imported by app/routes/book.file.tsx, app/routes/editor.tsx.
Source
// The editor's chrome steps back while someone types and returns on a mouse move or when focus enters
// it. Carrel's editor always did this for its own toolbar; it now covers the shell too, so the rail and
// the top bar fall quiet with the rest. The state is one attribute on the document, read by app.css.
import { useEffect } from "react";
export function useTypingRecede() {
useEffect(() => {
const root = document.documentElement;
const settle = () => {
if (root.hasAttribute("data-typing")) root.removeAttribute("data-typing");
};
const type = (event: KeyboardEvent) => {
if (event.metaKey || event.ctrlKey || event.altKey || event.key.length !== 1) return;
// Only typing in the editing surface counts; a character typed in a dialog's field does not.
const target = event.target;
if (target instanceof HTMLElement && target.closest(".cm-editor, .app-rich-surface")) root.setAttribute("data-typing", "");
};
window.addEventListener("keydown", type);
window.addEventListener("mousemove", settle);
return () => {
window.removeEventListener("keydown", type);
window.removeEventListener("mousemove", settle);
root.removeAttribute("data-typing");
};
}, []);
}