UNPKG

use-secret-code

Version:

Custom hook for adding cheat codes to your React app

157 lines (155 loc) 3.68 kB
// src/index.ts import * as React from "react"; import { assign, setup } from "xstate"; import { useMachine } from "@xstate/react"; // src/utils.ts function isEqual(array1, array2) { return JSON.stringify(array1) === JSON.stringify(array2); } function takeRight(array, n) { if (n < 1) return []; return array.slice(-1 * n); } // src/index.ts var initialContext = { cheatCodeKeys: void 0, typedKeys: [] }; var cheatCodeMachine = setup({ types: { // typegen: {}; context: {}, events: {}, input: {} }, actions: { record: assign({ typedKeys: ({ context, event }) => [...context.typedKeys, event.key] }), resetTypedKeys: assign({ typedKeys: initialContext.typedKeys }) }, delays: { doneTyping: 2e3 }, guards: { cheatCodeEntered: ({ context }) => { return Array.isArray(context.cheatCodeKeys) && isEqual( takeRight(context.typedKeys, context.cheatCodeKeys.length), context.cheatCodeKeys ); } } }).createMachine({ context: ({ input }) => ({ ...initialContext, ...input }), id: "cheatCodeMachine", initial: "disabled", states: { disabled: { initial: "idle", states: { idle: { always: { target: "#cheatCodeMachine.enabled", guard: "cheatCodeEntered", actions: "resetTypedKeys" }, on: { keydown: { target: "recording", actions: "record" } } }, recording: { after: { doneTyping: { target: "#cheatCodeMachine.disabled.idle", actions: ["resetTypedKeys"], reenter: true } }, always: { target: "#cheatCodeMachine.enabled", guard: "cheatCodeEntered", actions: "resetTypedKeys" }, on: { keydown: { target: "recording", actions: "record", reenter: true } } } } }, enabled: { initial: "idle", states: { idle: { always: { target: "#cheatCodeMachine.disabled", guard: "cheatCodeEntered", actions: "resetTypedKeys" }, on: { keydown: { target: "recording", actions: "record" } } }, recording: { after: { doneTyping: { target: "#cheatCodeMachine.enabled.idle", actions: ["resetTypedKeys"], reenter: true } }, always: { target: "#cheatCodeMachine.disabled", guard: "cheatCodeEntered", actions: "resetTypedKeys" }, on: { keydown: { target: "recording", actions: "record", reenter: true } } } } } } }); function useCheatCode(cheatCodeKeys) { const machineOpts = React.useMemo( () => ({ input: { cheatCodeKeys } }), [cheatCodeKeys] ); const [state, send] = useMachine(cheatCodeMachine, machineOpts); React.useEffect(() => { const handleKeydownEvent = (event) => { send(event); }; window.addEventListener("keydown", handleKeydownEvent); return () => { window.removeEventListener("keydown", handleKeydownEvent); }; }, [send]); return state.matches("enabled"); } var useSecretCode = ( /* c8 ignore next */ useCheatCode ); export { useCheatCode, useSecretCode }; //# sourceMappingURL=index.mjs.map