/* * Copyright (c) 2022 R3BL LLC. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { Box, render, Text, useInput } from "ink" import React, { FC, useState } from "react" import { createNewShortcutToActionMap, inkCLIAppMainFn, KeypressOption, LifecycleHelper, ShortcutToActionMap, StateHook, TTYSize, useClockWithLocalTimeFormat, useKeyboardBuilder, usePreventProcessExitDuringTesting, useTTYSize, _also } from "../../index" // Unique namespace ensures there will be no unintended collisions w/ other symbols of the codebase. export namespace keyboard_debug_ui { // eslint-disable-line //#region Hooks. interface RenderContext { ttySize: TTYSize inRawMode: boolean formattedTime: string name: string keyPress: KeypressOption } const runHooks = (name: MainParams): RenderContext => { usePreventProcessExitDuringTesting() // For testing using `npm run start-dev-watch`. const ttySize: TTYSize = useTTYSize() const { localeTimeString: formattedTime } = useClockWithLocalTimeFormat(3_000) const { keyPress, inRawMode } = useKeyboardBuilder({ type: name, args: { type: "map-cached", createShortcutsFn, options: { isActive: true } } }) return { name, ttySize, formattedTime, inRawMode, keyPress } } //#endregion //#region handleKeyboard. const createShortcutsFn = (): ShortcutToActionMap => _also( createNewShortcutToActionMap(), map => map .set("q", LifecycleHelper.fireExit) .set("ctrl+q", LifecycleHelper.fireExit) .set("escape", LifecycleHelper.fireExit) ) //#endregion //#region Function component. const App: FC<{ arg: MainParams }> = ({ arg }) => { const { keyPress, name, inRawMode, ttySize, formattedTime } = runHooks(arg) return ( Hello {name} {inRawMode ? inRawMode : !inRawMode } ttySize {ttySize.toString()} time {formattedTime} {keyPress.isSome() ? {keyPress.value.toString()} : !keyPress } ) } const UserInput: FC = () => { const [ input, setInput ]: StateHook = useState("") useInput((input, _) => setInput(input)) return useInput: {input} } //#endregion //#region main(). type MainParams = "node-keypress" | "ink-compat" export const main = (arg: MainParams) => { inkCLIAppMainFn( () => render(), "Exiting ink", "Problem w/ exiting ink" ).catch(console.error) } //#endregion }