/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import { Box, Text } from 'ink'; import { Colors } from '../colors.js'; import { PrepareLabel } from './PrepareLabel.js'; import { isSlashCommand } from '../utils/commandUtils.js'; export interface Suggestion { label: string; value: string; description?: string; matchedIndex?: number; } interface SuggestionsDisplayProps { suggestions: Suggestion[]; activeIndex: number; isLoading: boolean; width: number; scrollOffset: number; userInput: string; } export const MAX_SUGGESTIONS_TO_SHOW = 8; export function SuggestionsDisplay({ suggestions, activeIndex, isLoading, width, scrollOffset, userInput, }: SuggestionsDisplayProps) { if (isLoading) { return ( Loading suggestions... ); } if (suggestions.length === 0) { return null; // Don't render anything if there are no suggestions } // Calculate the visible slice based on scrollOffset const startIndex = scrollOffset; const endIndex = Math.min( scrollOffset + MAX_SUGGESTIONS_TO_SHOW, suggestions.length, ); const visibleSuggestions = suggestions.slice(startIndex, endIndex); const isSlashCommandMode = isSlashCommand(userInput); let commandNameWidth = 0; if (isSlashCommandMode) { const maxLabelLength = visibleSuggestions.length ? Math.max(...visibleSuggestions.map((s) => s.label.length)) : 0; const maxAllowedWidth = Math.floor(width * 0.35); commandNameWidth = Math.max( 15, Math.min(maxLabelLength + 2, maxAllowedWidth), ); } return ( {scrollOffset > 0 && } {visibleSuggestions.map((suggestion, index) => { const originalIndex = startIndex + index; const isActive = originalIndex === activeIndex; const textColor = isActive ? Colors.AccentPurple : Colors.Gray; const labelElement = ( ); return ( {isSlashCommandMode ? ( <> {labelElement} {suggestion.description ? ( {suggestion.description} ) : null} ) : ( <> {labelElement} {suggestion.description ? ( {suggestion.description} ) : null} )} ); })} {endIndex < suggestions.length && } {suggestions.length > MAX_SUGGESTIONS_TO_SHOW && ( ({activeIndex + 1}/{suggestions.length}) )} ); }