public/controls/New-UiRadioGroup.ps1
|
function New-UiRadioGroup { <# .SYNOPSIS Creates a group of mutually exclusive radio button options. .DESCRIPTION Creates a labeled panel containing radio buttons where only one option can be selected at a time. The selected value is available as a hydrated variable in -Action blocks. .PARAMETER Label Label text displayed above the radio button group. .PARAMETER Variable Variable name to store the selected value. .PARAMETER Items Array of option labels for the radio buttons. .PARAMETER Default Initially selected option. If not specified, the first item is selected. .PARAMETER Orientation Layout orientation for the radio buttons. 'Vertical' (default) or 'Horizontal'. .PARAMETER FullWidth Stretches the control to fill available width instead of fixed sizing. .PARAMETER WPFProperties Hashtable of additional WPF properties to set on the container control. .EXAMPLE New-UiRadioGroup -Label "Priority" -Variable "priority" -Items @('Low', 'Medium', 'High') -Default 'Medium' .EXAMPLE New-UiRadioGroup -Label "Size" -Variable "size" -Items @('S', 'M', 'L', 'XL') -Orientation Horizontal #> [CmdletBinding()] param( [Parameter(Mandatory)] [string]$Label, [Parameter(Mandatory)] [string]$Variable, [Parameter(Mandatory)] [string[]]$Items, [string]$Default, [ValidateSet('Vertical', 'Horizontal')] [string]$Orientation = 'Vertical', [switch]$FullWidth, [Parameter()] [hashtable]$WPFProperties ) $session = Assert-UiSession -CallerName 'New-UiRadioGroup' Write-Debug "Creating radio group '$Variable' with $($Items.Count) items" $colors = Get-ThemeColors $parent = $session.CurrentParent $outerStack = [System.Windows.Controls.StackPanel]@{ Margin = [System.Windows.Thickness]::new(4, 4, 4, 8) } $labelBlock = [System.Windows.Controls.TextBlock]@{ Text = $Label FontSize = 12 Foreground = ConvertTo-UiBrush $colors.ControlFg Margin = [System.Windows.Thickness]::new(0, 0, 0, 6) Tag = 'ControlFgBrush' } [PsUi.ThemeEngine]::RegisterElement($labelBlock) [void]$outerStack.Children.Add($labelBlock) $radioPanel = [System.Windows.Controls.StackPanel]@{ Orientation = if ($Orientation -eq 'Horizontal') { [System.Windows.Controls.Orientation]::Horizontal } else { [System.Windows.Controls.Orientation]::Vertical } } # Unique group name so only one radio button can be selected at a time $groupName = "RadioGroup_${Variable}_$(Get-Random)" # Track which item should be selected by default $defaultItem = if ($Default -and $Items -contains $Default) { $Default } else { $Items[0] } Write-Debug "Default selection: $defaultItem" $radioButtons = @{} foreach ($item in $Items) { $radio = [System.Windows.Controls.RadioButton]@{ Content = $item GroupName = $groupName IsChecked = ($item -eq $defaultItem) Margin = if ($Orientation -eq 'Horizontal') { [System.Windows.Thickness]::new(0, 2, 12, 2) } else { [System.Windows.Thickness]::new(0, 2, 0, 2) } Tag = $item # Store the value in Tag for easy retrieval } Set-RadioButtonStyle -RadioButton $radio $radioButtons[$item] = $radio [void]$radioPanel.Children.Add($radio) } [void]$outerStack.Children.Add($radioPanel) # Tag wrapper for FormLayout unwrapping in New-UiGrid Set-UiFormControlTag -Wrapper $outerStack -Label $labelBlock -Control $radioPanel # FullWidth in WrapPanel contexts Set-FullWidthConstraint -Control $outerStack -Parent $parent -FullWidth:$FullWidth # Apply custom WPF properties if specified if ($WPFProperties) { Set-UiProperties -Control $outerStack -Properties $WPFProperties } Write-Debug "Adding to parent and registering as '$Variable'" [void]$parent.Children.Add($outerStack) # Store the panel and mark it so hydration knows how to extract the value $radioPanel.Tag = @{ ControlType = 'RadioGroup' GroupName = $groupName } # Register control with session using AddControlSafe for thread-safe access $session.AddControlSafe($Variable, $radioPanel) } |