refactor(cli): fully remove React anti patterns, improve type safety and fix UX oversights in SettingsDialog.tsx (#18963)

Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
Pyush Sinha
2026-03-02 13:30:58 -08:00
committed by GitHub
parent 18d0375a7f
commit 8133d63ac6
14 changed files with 589 additions and 1390 deletions

View File

@@ -531,6 +531,37 @@ describe('BaseSettingsDialog', () => {
});
describe('edit mode', () => {
it('should prioritize editValue over rawValue stringification', async () => {
const objectItem: SettingsDialogItem = {
key: 'object-setting',
label: 'Object Setting',
description: 'A complex object setting',
displayValue: '{"foo":"bar"}',
type: 'object',
rawValue: { foo: 'bar' },
editValue: '{"foo":"bar"}',
};
const { stdin } = await renderDialog({
items: [objectItem],
});
// Enter edit mode and immediately commit
await act(async () => {
stdin.write(TerminalKeys.ENTER);
});
await act(async () => {
stdin.write(TerminalKeys.ENTER);
});
await waitFor(() => {
expect(mockOnEditCommit).toHaveBeenCalledWith(
'object-setting',
'{"foo":"bar"}',
expect.objectContaining({ type: 'object' }),
);
});
});
it('should commit edit on Enter', async () => {
const items = createMockItems(4);
const stringItem = items.find((i) => i.type === 'string')!;

View File

@@ -9,6 +9,10 @@ import { Box, Text } from 'ink';
import chalk from 'chalk';
import { theme } from '../../semantic-colors.js';
import type { LoadableSettingScope } from '../../../config/settings.js';
import type {
SettingsType,
SettingsValue,
} from '../../../config/settingsSchema.js';
import { getScopeItems } from '../../../utils/dialogScopeUtils.js';
import { RadioButtonSelect } from './RadioButtonSelect.js';
import { TextInput } from './TextInput.js';
@@ -33,7 +37,7 @@ export interface SettingsDialogItem {
/** Optional description below label */
description?: string;
/** Item type for determining interaction behavior */
type: 'boolean' | 'number' | 'string' | 'enum';
type: SettingsType;
/** Pre-formatted display value (with * if modified) */
displayValue: string;
/** Grey out value (at default) */
@@ -41,7 +45,9 @@ export interface SettingsDialogItem {
/** Scope message e.g., "(Modified in Workspace)" */
scopeMessage?: string;
/** Raw value for edit mode initialization */
rawValue?: string | number | boolean;
rawValue?: SettingsValue;
/** Optional pre-formatted edit buffer value for complex types */
editValue?: string;
}
/**
@@ -381,9 +387,11 @@ export function BaseSettingsDialog({
if (currentItem.type === 'boolean' || currentItem.type === 'enum') {
onItemToggle(currentItem.key, currentItem);
} else {
// Start editing for string/number
// Start editing for string/number/array/object
const rawVal = currentItem.rawValue;
const initialValue = rawVal !== undefined ? String(rawVal) : '';
const initialValue =
currentItem.editValue ??
(rawVal !== undefined ? String(rawVal) : '');
startEditing(currentItem.key, initialValue);
}
return true;