Fix dialog focus

This commit is contained in:
2026-03-23 03:51:51 +00:00
parent a28d43a68b
commit 7fd89c5663
18 changed files with 403 additions and 177 deletions

View File

@@ -4,9 +4,10 @@
*/
import React from 'react';
import { Box, Text, useApp, useInput } from 'ink';
import { Box, Text, useApp } from 'ink';
import { NavigationProvider, useNavigation } from './hooks/useNavigation.js';
import { AppProvider, useAppContext, useDialog, useStatus } from './hooks/useAppContext.js';
import { InputLayerProvider, useBlockableInput } from './hooks/useInputLayer.js';
import type { AppConfig } from '../app.js';
import { colors, logoSmall } from './theme.js';
@@ -78,27 +79,9 @@ function StatusBar(): React.ReactElement {
* Dialog overlay component for modals.
*/
function DialogOverlay(): React.ReactElement | null {
const { dialog, setDialog } = useDialog();
const { dialog } = useDialog();
// 'custom' dialogs are rendered and managed by the screen itself;
// we only handle input for the built-in dialog types.
const isBuiltInDialog = dialog?.visible === true && dialog.type !== 'custom';
useInput((input, key) => {
if (!isBuiltInDialog) return;
if (key.return || input === 'y' || input === 'Y') {
if (dialog.type === 'confirm' && dialog.onConfirm) {
dialog.onConfirm();
} else {
dialog.onCancel?.();
}
} else if (key.escape || input === 'n' || input === 'N') {
dialog.onCancel?.();
}
}, { isActive: isBuiltInDialog });
if (!isBuiltInDialog) return null;
if (!dialog?.visible) return null;
const borderColor = dialog.type === 'error' ? colors.error :
dialog.type === 'confirm' ? colors.warning :
@@ -132,20 +115,12 @@ function MainContent(): React.ReactElement {
const { exit } = useApp();
const { goBack, canGoBack } = useNavigation();
const { screen } = useNavigation();
const { dialog } = useDialog();
const appContext = useAppContext();
// Global keybindings (disabled when dialog is shown)
useInput((input, key) => {
// Don't handle global keys when dialog is shown
if (dialog?.visible) return;
// Quit on 'q' or Ctrl+C
if (
// Commenting out 'q'. Its annoying me - It activates in text inputs.
// input === 'q'
(key.ctrl && input === 'c')
) {
// Global keybindings — auto-blocked when any dialog/overlay is capturing input.
useBlockableInput((input, key) => {
// Quit on Ctrl+C
if (key.ctrl && input === 'c') {
appContext.exit();
exit();
}
@@ -197,9 +172,11 @@ export function App({ config }: AppProps): React.ReactElement {
config={config}
onExit={handleExit}
>
<NavigationProvider initialScreen="seed-input">
<MainContent />
</NavigationProvider>
<InputLayerProvider>
<NavigationProvider initialScreen="seed-input">
<MainContent />
</NavigationProvider>
</InputLayerProvider>
</AppProvider>
);
}