Files
vue-tui/packages/runtime-tests/integration/pty/fixtures/use-input.tsx
T
Yunfei He bfd680490f refactor(runtime)!: rename useAppContext() to useApp() (full Ink alignment) (#73)
#69 added `useAppContext()` as a Vue-native rename of Ink's `useApp()`,
qualified to avoid reading as the Vue application instance. On reflection the
"Context" suffix borrowed the name of an internal grab-bag context and slightly
mislabels the hook — it returns app lifecycle controls, not that context. The
collision worry doesn't hold up: Vue has no `useApp()`, the returned
`{ exit, waitUntilRenderFlush }` is clearly not the Vue app instance, and "App"
in vue-tui already means the `TuiApp` from `createApp()`.

Rename to `useApp()` for full Ink fidelity (same name + same shape), and drop
the now-defunct "App composable" entry from ink-divergences.md — it ceases to
be a divergence.

Internal context cleanup (the grab-bag `AppContext` + the `StdinContext`
duplication) is intentionally out of scope here, tracked separately.

BREAKING CHANGE: `useAppContext()` is renamed to `useApp()`. Replace
`const { exit } = useAppContext()` with `const { exit } = useApp()`.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 23:32:22 +08:00

242 lines
5.4 KiB
TypeScript

import process from "node:process";
import { createApp, useInput, useApp } from "@vue-tui/runtime";
import { defineComponent, onMounted } from "vue";
const UserInput = defineComponent({
props: {
test: { type: String, default: undefined },
},
setup(props) {
const { exit } = useApp();
let rapidDownArrowCount = 0;
let rapidTimeout: ReturnType<typeof setTimeout> | undefined;
onMounted(() => {
if (props.test === "rapidArrowsEnter") {
rapidTimeout = setTimeout(() => {
throw new Error(
`Expected 3 down arrows and enter, received ${rapidDownArrowCount} down arrow events`,
);
}, 6000);
}
process.stdout.write("__READY__");
});
useInput((input, key) => {
if (props.test === "rapidArrowsEnter") {
if (key.downArrow) {
rapidDownArrowCount++;
return;
}
if (key.return) {
if (rapidDownArrowCount === 3) {
clearTimeout(rapidTimeout);
exit();
return;
}
throw new Error(`Expected enter after 3 down arrows, received ${rapidDownArrowCount}`);
}
throw new Error("Expected only down arrows and enter");
}
if (props.test === "lowercase" && input === "q") {
exit();
return;
}
if (props.test === "uppercase" && input === "Q" && key.shift) {
exit();
return;
}
if (props.test === "uppercase" && input === "\r" && !key.shift) {
exit();
return;
}
if (props.test === "pastedCarriageReturn" && input === "\rtest") {
exit();
return;
}
if (props.test === "pastedTab" && input === "\ttest") {
exit();
return;
}
if (props.test === "bracketedPaste" && input === "hello") {
exit();
return;
}
if (props.test === "escape" && key.escape) {
exit();
return;
}
if (props.test === "escapeNoMeta" && key.escape && !key.meta) {
exit();
return;
}
if (props.test === "ctrl" && input === "f" && key.ctrl) {
exit();
return;
}
if (props.test === "meta" && input === "m" && key.meta) {
exit();
return;
}
if (props.test === "metaBackspace" && input === "" && key.meta && key.backspace) {
exit();
return;
}
if (props.test === "escapeBracketPrefix" && input === "[" && !key.meta) {
exit();
return;
}
if (props.test === "metaUpperO" && input === "O" && key.meta) {
exit();
return;
}
if (props.test === "upArrow" && key.upArrow && !key.meta) {
exit();
return;
}
if (props.test === "downArrow" && key.downArrow && !key.meta) {
exit();
return;
}
if (props.test === "leftArrow" && key.leftArrow && !key.meta) {
exit();
return;
}
if (props.test === "rightArrow" && key.rightArrow && !key.meta) {
exit();
return;
}
if (props.test === "upArrowMeta" && key.upArrow && key.meta) {
exit();
return;
}
if (props.test === "downArrowMeta" && key.downArrow && key.meta) {
exit();
return;
}
if (props.test === "leftArrowMeta" && key.leftArrow && key.meta) {
exit();
return;
}
if (props.test === "rightArrowMeta" && key.rightArrow && key.meta) {
exit();
return;
}
if (props.test === "upArrowCtrl" && key.upArrow && key.ctrl) {
exit();
return;
}
if (props.test === "downArrowCtrl" && key.downArrow && key.ctrl) {
exit();
return;
}
if (props.test === "leftArrowCtrl" && key.leftArrow && key.ctrl) {
exit();
return;
}
if (props.test === "rightArrowCtrl" && key.rightArrow && key.ctrl) {
exit();
return;
}
if (props.test === "pageDown" && key.pageDown && !key.meta) {
exit();
return;
}
if (props.test === "pageUp" && key.pageUp && !key.meta) {
exit();
return;
}
if (props.test === "home" && key.home && !key.meta) {
exit();
return;
}
if (props.test === "end" && key.end && !key.meta) {
exit();
return;
}
if (props.test === "tab" && input === "" && key.tab && !key.ctrl) {
exit();
return;
}
if (props.test === "shiftTab" && input === "" && key.tab && key.shift) {
exit();
return;
}
if (props.test === "backspace" && input === "" && key.backspace) {
exit();
return;
}
if (props.test === "delete" && input === "" && key.delete) {
exit();
return;
}
if (props.test === "remove" && input === "" && key.delete) {
exit();
return;
}
if (props.test === "returnMeta" && key.return && key.meta) {
exit();
return;
}
if (props.test === "ctrlF1" && input === "" && key.ctrl) {
exit();
return;
}
if (props.test === "unmappedCtrlSequence" && input === "" && key.ctrl) {
exit();
return;
}
throw new Error("Crash");
});
return () => null;
},
});
const app = createApp(UserInput, { test: process.argv[2] });
app.mount();
await app.waitUntilExit();
console.log("exited");