refactor(cli): better react patterns for BaseSettingsDialog (#21206)

This commit is contained in:
Pyush Sinha
2026-03-09 11:35:08 -07:00
committed by GitHub
parent 4c9f9bb3e2
commit b68d7bc0f9
10 changed files with 834 additions and 282 deletions

View File

@@ -346,94 +346,9 @@ export function SettingsDialog({
[showRestartPrompt, onRestartRequest],
);
// Calculate effective max items and scope visibility based on terminal height
const { effectiveMaxItemsToShow, showScopeSelection, showSearch } =
useMemo(() => {
// Only show scope selector if we have a workspace
const hasWorkspace = settings.workspace.path !== undefined;
// Search box is hidden when restart prompt is shown to save space and avoid key conflicts
const shouldShowSearch = !showRestartPrompt;
if (!availableTerminalHeight) {
return {
effectiveMaxItemsToShow: Math.min(MAX_ITEMS_TO_SHOW, items.length),
showScopeSelection: hasWorkspace,
showSearch: shouldShowSearch,
};
}
// Layout constants based on BaseSettingsDialog structure:
// 4 for border (2) and padding (2)
const DIALOG_PADDING = 4;
const SETTINGS_TITLE_HEIGHT = 1;
// 3 for box + 1 for marginTop + 1 for spacing after
const SEARCH_SECTION_HEIGHT = shouldShowSearch ? 5 : 0;
const SCROLL_ARROWS_HEIGHT = 2;
const ITEMS_SPACING_AFTER = 1;
// 1 for Label + 3 for Scope items + 1 for spacing after
const SCOPE_SECTION_HEIGHT = hasWorkspace ? 5 : 0;
const HELP_TEXT_HEIGHT = 1;
const RESTART_PROMPT_HEIGHT = showRestartPrompt ? 1 : 0;
const ITEM_HEIGHT = 3; // Label + description + spacing
const currentAvailableHeight = availableTerminalHeight - DIALOG_PADDING;
const baseFixedHeight =
SETTINGS_TITLE_HEIGHT +
SEARCH_SECTION_HEIGHT +
SCROLL_ARROWS_HEIGHT +
ITEMS_SPACING_AFTER +
HELP_TEXT_HEIGHT +
RESTART_PROMPT_HEIGHT;
// Calculate max items with scope selector
const heightWithScope = baseFixedHeight + SCOPE_SECTION_HEIGHT;
const availableForItemsWithScope =
currentAvailableHeight - heightWithScope;
const maxItemsWithScope = Math.max(
1,
Math.floor(availableForItemsWithScope / ITEM_HEIGHT),
);
// Calculate max items without scope selector
const availableForItemsWithoutScope =
currentAvailableHeight - baseFixedHeight;
const maxItemsWithoutScope = Math.max(
1,
Math.floor(availableForItemsWithoutScope / ITEM_HEIGHT),
);
// In small terminals, hide scope selector if it would allow more items to show
let shouldShowScope = hasWorkspace;
let maxItems = maxItemsWithScope;
if (hasWorkspace && availableTerminalHeight < 25) {
// Hide scope selector if it gains us more than 1 extra item
if (maxItemsWithoutScope > maxItemsWithScope + 1) {
shouldShowScope = false;
maxItems = maxItemsWithoutScope;
}
}
return {
effectiveMaxItemsToShow: Math.min(maxItems, items.length),
showScopeSelection: shouldShowScope,
showSearch: shouldShowSearch,
};
}, [
availableTerminalHeight,
items.length,
settings.workspace.path,
showRestartPrompt,
]);
const footerContent = showRestartPrompt ? (
<Text color={theme.status.warning}>
Changes that require a restart have been modified. Press r to exit and
apply changes now.
</Text>
) : null;
// Decisions on what features to enable
const hasWorkspace = settings.workspace.path !== undefined;
const showSearch = !showRestartPrompt;
return (
<BaseSettingsDialog
@@ -442,17 +357,30 @@ export function SettingsDialog({
searchEnabled={showSearch}
searchBuffer={searchBuffer}
items={items}
showScopeSelector={showScopeSelection}
showScopeSelector={hasWorkspace}
selectedScope={selectedScope}
onScopeChange={handleScopeChange}
maxItemsToShow={effectiveMaxItemsToShow}
maxItemsToShow={MAX_ITEMS_TO_SHOW}
availableHeight={availableTerminalHeight}
maxLabelWidth={maxLabelOrDescriptionWidth}
onItemToggle={handleItemToggle}
onEditCommit={handleEditCommit}
onItemClear={handleItemClear}
onClose={handleClose}
onKeyPress={handleKeyPress}
footerContent={footerContent}
footer={
showRestartPrompt
? {
content: (
<Text color={theme.status.warning}>
Changes that require a restart have been modified. Press r to
exit and apply changes now.
</Text>
),
height: 1,
}
: undefined
}
/>
);
}