modules/core/Invoke-TuiMenu.ps1
|
function Invoke-TuiMenu { param( [string]$Title, [string[]]$Options, [int]$SelectedIndex = 0 ) [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 $originalColor = $host.UI.RawUI.ForegroundColor $cursorVisible = $host.UI.RawUI.CursorSize -ne 0 if ($cursorVisible) { $host.UI.RawUI.CursorSize = 0 } # Hide cursor $currentSelection = $SelectedIndex $running = $true function Render { param($selection) # Clear menu area (assuming max 10 options for simplicity) Write-Host "`r" -NoNewline Write-Host " $Title" -ForegroundColor White for ($i = 0; $i -lt $Options.Length; $i++) { if ($i -eq $selection) { Write-Host " > " -NoNewline -ForegroundColor Cyan Write-Host $Options[$i] -ForegroundColor Cyan } else { Write-Host " " -NoNewline Write-Host $Options[$i] -ForegroundColor Gray } } } # Initial Render Write-Host "" Render $currentSelection while ($running) { if ($host.UI.RawUI.KeyAvailable) { $key = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") switch ($key.VirtualKeyCode) { 38 { # Up Arrow $currentSelection = if ($currentSelection -gt 0) { $currentSelection - 1 } else { $Options.Length - 1 } # Move cursor up to redraw [Console]::SetCursorPosition(0, [Console]::CursorTop - ($Options.Length + 1)) Render $currentSelection } 40 { # Down Arrow $currentSelection = if ($currentSelection -lt $Options.Length - 1) { $currentSelection + 1 } else { 0 } [Console]::SetCursorPosition(0, [Console]::CursorTop - ($Options.Length + 1)) Render $currentSelection } 13 { # Enter $running = $false } 27 { # Escape if ($cursorVisible) { $host.UI.RawUI.CursorSize = 25 } exit 1 } } } Start-Sleep -Milliseconds 50 } if ($cursorVisible) { $host.UI.RawUI.CursorSize = 25 } # Restore cursor Write-Host "" return $currentSelection } if ($MyInvocation.InvocationName -ne '.') { Export-ModuleMember -Function Invoke-TuiMenu } |