Functions/Public/Write-InfoBox.ps1
|
<#
================================================================================ ORION DESIGN - POWERSHELL UI FRAMEWORK | Write-InfoBox Function ================================================================================ Author: Sune Alexandersen Narud Date: August 22, 2025 Module: OrionDesign v1.6.0 Category: Information Display Dependencies: OrionDesign Theme System FUNCTION PURPOSE: Creates bordered information boxes with titles and multiple styling options. Versatile information display component providing highlighted content areas with automatic width calculation and various visual styles. HLD INTEGRATION: ┌─ INFORMATION ─┐ ┌─ BOX STYLES ─┐ ┌─ OUTPUT ─┐ │ Write-InfoBox │◄──►│ Classic/Modern│───►│ Bordered │ │ • Title/Content│ │ Simple/Accent │ │ Info │ │ • Auto Width │ │ Icon Support │ │ Content │ │ • Safety Checks│ │ Width Control │ │ Safe │ └────────────────┘ └───────────────┘ └──────────┘ ================================================================================ #> <# .SYNOPSIS Displays formatted information in styled boxes or panels. .DESCRIPTION The Write-InfoBox function creates visually appealing information displays with titles, key-value pairs, and different styling options. .PARAMETER Title The title of the information box. .PARAMETER Content Hashtable of key-value pairs to display, or array of strings. .PARAMETER Style The visual style of the box. Available styles: • Classic: Traditional box with decorative borders and formal presentation • Modern: Contemporary flat design with clean lines and subtle shadows • Simple: Minimal styling with basic borders and understated formatting • Accent: Highlighted presentation using theme accent colors for emphasis Valid values: Classic, Modern, Simple, Accent .PARAMETER Width Width of the information box (default: auto-calculate). .EXAMPLE Write-InfoBox -Title "System Information" -Content @{ "Server" = "SQL-01" "Database" = "Production" "Version" = "2019 SP3" } Displays system information in a formatted box. .EXAMPLE Write-InfoBox -Title "Configuration" -Content @("Setting 1: Enabled", "Setting 2: Disabled") -Style Modern Displays configuration information in modern style. #> function Write-InfoBox { [CmdletBinding(DefaultParameterSetName = 'Default')] param( [Parameter(Mandatory, ParameterSetName = 'Default', Position = 0)][string]$Title, [Parameter(Mandatory, ParameterSetName = 'Default', Position = 1)]$Content, [ValidateSet('Classic', 'Modern', 'Simple', 'Accent')] [string]$Style = 'Classic', [int]$Width = 0, [switch]$WrapContent, [Parameter(Mandatory, ParameterSetName = 'Demo')] [switch]$Demo ) if ($Demo) { $renderCodeBlock = { param([string[]]$Lines) $innerWidth = ($Lines | Measure-Object -Property Length -Maximum).Maximum + 4 $bar = '─' * $innerWidth Write-Host ' # Code' -ForegroundColor DarkGray Write-Host " ┌$bar┐" -ForegroundColor DarkGray foreach ($line in $Lines) { $padded = (" $line").PadRight($innerWidth) Write-Host " │" -ForegroundColor DarkGray -NoNewline Write-Host $padded -ForegroundColor Green -NoNewline Write-Host '│' -ForegroundColor DarkGray } Write-Host " └$bar┘" -ForegroundColor DarkGray Write-Host '' } Write-Host '' Write-Host ' Write-InfoBox Demo' -ForegroundColor Cyan Write-Host ' ==================' -ForegroundColor DarkGray Write-Host '' foreach ($style in @('Classic', 'Modern', 'Simple', 'Accent')) { Write-Host " [Style: $style]" -ForegroundColor Yellow Write-Host '' & $renderCodeBlock @( "Write-InfoBox -Title 'Server Info' -Content @{Server='SQL-01'; DB='Production'; Status='Online'} -Style $style" ) Write-InfoBox -Title 'Server Info' -Content @{Server='SQL-01'; DB='Production'; Status='Online'} -Style $style Write-Host '' } return } # Helper function for word wrapping function Wrap-Text { param([string]$Text, [int]$MaxWidth) if ($Text.Length -le $MaxWidth -or $MaxWidth -le 0) { return @($Text) } $words = $Text -split '\s+' $lines = @() $currentLine = "" foreach ($word in $words) { $testLine = if ($currentLine) { "$currentLine $word" } else { $word } if ($testLine.Length -le $MaxWidth) { $currentLine = $testLine } else { if ($currentLine) { $lines += $currentLine } $currentLine = $word } } if ($currentLine) { $lines += $currentLine } return $lines } # Default theme if (-not $script:Theme) { $script:Theme = @{ Accent = 'Cyan' Success = 'Green' Warning = 'Yellow' Error = 'Red' Text = 'White' Muted = 'DarkGray' Divider = '─' UseAnsi = $true } if ($psISE) { $script:Theme.UseAnsi = $false } } # Calculate width with proper content analysis $maxKeyLength = 0 $maxValueLength = 0 $maxContentWidth = 0 $contentLines = @() if ($Content -is [hashtable]) { foreach ($key in $Content.Keys) { $value = $Content[$key] $contentLines += "$key`: $value" if ($key.Length -gt $maxKeyLength) { $maxKeyLength = $key.Length } if ($value.ToString().Length -gt $maxValueLength) { $maxValueLength = $value.ToString().Length } # Calculate total line width for hashtable content $totalLineWidth = $key.Length + 3 + $value.ToString().Length # key + " : " + value if ($totalLineWidth -gt $maxContentWidth) { $maxContentWidth = $totalLineWidth } } } else { $contentLines = $Content foreach ($line in $contentLines) { if ($line.Length -gt $maxValueLength) { $maxValueLength = $line.Length } # For simple content, the line length IS the content width if ($line.Length -gt $maxContentWidth) { $maxContentWidth = $line.Length } } } if ($Width -eq 0) { # Use global max width if available $globalWidth = if ($script:OrionMaxWidth) { $script:OrionMaxWidth } else { 80 } # Calculate minimum width based on actual content requirements $titleWidthReq = $Title.Length + 10 # Title + decorative elements $contentWidthReq = $maxContentWidth + 4 # Content + border chars (│ + space + content + space + │) $minWidth = [Math]::Max($titleWidthReq, $contentWidthReq) # Respect global width while ensuring content fits $Width = [Math]::Max(40, [Math]::Min($globalWidth, $minWidth)) # If content still doesn't fit within global limit, expand to accommodate it if ($minWidth -gt $globalWidth) { $Width = $minWidth Write-Verbose "Content width ($minWidth) exceeds global limit ($globalWidth), expanding to fit content" } } # Ensure minimum width to prevent negative values $Width = [Math]::Max($Width, $Title.Length + 6) Write-Host switch ($Style) { 'Classic' { # Top border - ensure non-negative width Write-Host "┌─ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $Title -ForegroundColor $script:Theme.Text -NoNewline $borderLength = [Math]::Max(0, $Width - $Title.Length - 5) Write-Host (" " + "─" * $borderLength + "┐") -ForegroundColor $script:Theme.Accent # Content foreach ($line in $contentLines) { if ($Content -is [hashtable] -and $line -match '^([^:]+): (.+)$') { $key = $matches[1] $value = $matches[2] if ($WrapContent -and $value.Length -gt ($Width - $maxKeyLength - 8)) { # Wrap long values $maxValueWidth = $Width - $maxKeyLength - 8 $wrappedLines = Wrap-Text -Text $value -MaxWidth $maxValueWidth # First line with key Write-Host "│ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $key.PadRight($maxKeyLength) -ForegroundColor $script:Theme.Accent -NoNewline Write-Host " : " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host $wrappedLines[0] -ForegroundColor $script:Theme.Text -NoNewline $contentLength = 2 + $maxKeyLength + 3 + $wrappedLines[0].Length + 1 $padding = [Math]::Max(0, $Width - $contentLength) Write-Host (" " * $padding + "│") -ForegroundColor $script:Theme.Accent # Additional wrapped lines for ($i = 1; $i -lt $wrappedLines.Count; $i++) { Write-Host "│ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host (" " * ($maxKeyLength + 3)) -NoNewline Write-Host $wrappedLines[$i] -ForegroundColor $script:Theme.Text -NoNewline $contentLength = 2 + $maxKeyLength + 3 + $wrappedLines[$i].Length + 1 $padding = [Math]::Max(0, $Width - $contentLength) Write-Host (" " * $padding + "│") -ForegroundColor $script:Theme.Accent } } else { # Normal single-line display Write-Host "│ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $key.PadRight($maxKeyLength) -ForegroundColor $script:Theme.Accent -NoNewline Write-Host " : " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host $value -ForegroundColor $script:Theme.Text -NoNewline $contentLength = 2 + $maxKeyLength + 3 + $value.Length + 1 $padding = [Math]::Max(0, $Width - $contentLength) Write-Host (" " * $padding + "│") -ForegroundColor $script:Theme.Accent } } else { if ($WrapContent -and $line.Length -gt ($Width - 4)) { # Wrap long simple content $wrappedLines = Wrap-Text -Text $line -MaxWidth ($Width - 4) foreach ($wrappedLine in $wrappedLines) { Write-Host "│ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $wrappedLine -ForegroundColor $script:Theme.Text -NoNewline $contentLength = 2 + $wrappedLine.Length + 1 $padding = [Math]::Max(0, $Width - $contentLength) Write-Host (" " * $padding + "│") -ForegroundColor $script:Theme.Accent } } else { # Normal single-line display Write-Host "│ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $line -ForegroundColor $script:Theme.Text -NoNewline $contentLength = 2 + $line.Length + 1 $padding = [Math]::Max(0, $Width - $contentLength) Write-Host (" " * $padding + "│") -ForegroundColor $script:Theme.Accent } } } # Bottom border $bottomBorderLength = [Math]::Max(0, $Width - 2) Write-Host ("└" + "─" * $bottomBorderLength + "┘") -ForegroundColor $script:Theme.Accent } 'Modern' { # Title with modern styling Write-Host "▌" -ForegroundColor $script:Theme.Accent -NoNewline Write-Host " $Title" -ForegroundColor $script:Theme.Text $modernBorderLength = [Math]::Max(0, $Width - 1) Write-Host ("▌" + "─" * $modernBorderLength) -ForegroundColor $script:Theme.Accent # Content foreach ($line in $contentLines) { if ($Content -is [hashtable] -and $line -match '^([^:]+): (.+)$') { $key = $matches[1] $value = $matches[2] Write-Host "▌ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host "● " -ForegroundColor $script:Theme.Success -NoNewline Write-Host $key -ForegroundColor $script:Theme.Accent -NoNewline Write-Host ": " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host $value -ForegroundColor $script:Theme.Text } else { Write-Host "▌ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host "● " -ForegroundColor $script:Theme.Success -NoNewline Write-Host $line -ForegroundColor $script:Theme.Text } } } 'Simple' { # Simple title Write-Host $Title -ForegroundColor $script:Theme.Accent Write-Host ("-" * $Title.Length) -ForegroundColor $script:Theme.Muted # Content foreach ($line in $contentLines) { if ($Content -is [hashtable] -and $line -match '^([^:]+): (.+)$') { $key = $matches[1] $value = $matches[2] Write-Host " $key" -ForegroundColor $script:Theme.Muted -NoNewline Write-Host ": " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host $value -ForegroundColor $script:Theme.Text } else { Write-Host " $line" -ForegroundColor $script:Theme.Text } } } 'Accent' { # Accent title - highlight only the title text, not full width Write-Host " " -NoNewline Write-Host $Title -BackgroundColor $script:Theme.Accent -ForegroundColor Black -NoNewline Write-Host " " # Just a space after the title # Content with accent bullets foreach ($line in $contentLines) { if ($Content -is [hashtable] -and $line -match '^([^:]+): (.+)$') { $key = $matches[1] $value = $matches[2] Write-Host " ◆ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $key -ForegroundColor $script:Theme.Accent -NoNewline Write-Host ": " -ForegroundColor $script:Theme.Muted -NoNewline Write-Host $value -ForegroundColor $script:Theme.Text } else { Write-Host " ◆ " -ForegroundColor $script:Theme.Accent -NoNewline Write-Host $line -ForegroundColor $script:Theme.Text } } } } Write-Host } |