public/New-UDThemePicker.ps1
|
function New-UDThemePicker { <# .SYNOPSIS Creates a theme picker that switches the app theme at runtime. .DESCRIPTION Lets users choose between themes. The selection is applied with Set-UDTheme for the user's connection, keeps their light/dark mode, and is remembered in the browser. .PARAMETER Id Component ID. .PARAMETER Themes Themes to offer. Accepts any mix of: - Built-in theme names (strings from Get-UDTheme) - Get-UDChameleonTheme results - Hashtables/objects with Name and Theme (and optional Description, Colors) - A single hashtable of name = theme pairs .PARAMETER Variant menu (dropdown button, good for -HeaderContent), grid (swatch cards) or select (native dropdown). .PARAMETER Label Button/select label shown when no theme is selected. .PARAMETER HideReset Hides the "Default" option that restores the app's configured theme. .PARAMETER StorageKey Browser storage key used to remember the selection. Defaults to the app's base URL segment. .PARAMETER OnChange Called after a theme is applied. $EventData is the selected theme name ('' for Default). .EXAMPLE New-UDApp -Title 'My App' -HeaderContent { New-UDThemePicker -Themes 'Dracula', 'nord', 'Github' } -Content { } .EXAMPLE $Picker = @{ Themes = Get-UDChameleonTheme Variant = 'grid' OnChange = { Show-UDToast -Message "Theme: $EventData" } } New-UDThemePicker @Picker #> [CmdletBinding()] param( [Parameter()] [string]$Id = (New-Guid).ToString(), [Parameter(Mandatory)] [AllowEmptyCollection()] [object[]]$Themes, [Parameter()] [ValidateSet('menu', 'grid', 'select')] [string]$Variant = 'menu', [Parameter()] [string]$Label = 'Theme', [Parameter()] [switch]$HideReset, [Parameter()] [string]$StorageKey, [Parameter()] [Endpoint]$OnChange ) $Items = @( if ($Themes.Count -eq 1 -and $Themes[0] -is [System.Collections.IDictionary] -and -not $Themes[0].Contains('Name')) { foreach ($Key in $Themes[0].Keys) { @{ Name = [string]$Key; Theme = $Themes[0][$Key] } } } else { $Themes } ) $BuiltIn = $null $Options = foreach ($Item in $Items) { if ($null -eq $Item) { continue } if ($Item -is [string]) { if ($null -eq $BuiltIn) { $BuiltIn = @(Get-ChameleonBuiltInName) + @(Get-UDTheme) } if ($Item -cnotin $BuiltIn) { Write-Warning "Skipping unknown built-in theme '$Item'." continue } @{ name = $Item builtin = $true colors = @(Get-ChameleonSwatch -Theme (Get-UDTheme -Name $Item)) } continue } $Record = if ($Item -is [System.Collections.IDictionary]) { $Item } else { ConvertTo-UDChameleonHashtable -InputObject $Item } $ThemeName = $Record['Name'] if (-not $ThemeName) { Write-Warning 'Skipping theme without a Name.' continue } $Hashtable = ConvertTo-UDChameleonHashtable -InputObject $Record['Theme'] @{ name = [string]$ThemeName description = $Record['Description'] theme = $Hashtable colors = if ($Record['Colors']) { @($Record['Colors']) } else { @(Get-ChameleonSwatch -Theme $Hashtable) } } } $Apply = [Endpoint]::new({ $Data = ConvertTo-UDChameleonHashtable -InputObject $EventData if ($Data.builtin) { Set-UDChameleonTheme -Name $Data.name -Variant $Data.variant } else { Set-UDChameleonTheme -Theme $Data.theme -Variant $Data.variant } }) $Apply.Register($Id + 'onApply', $PSCmdlet) $Reset = [Endpoint]::new({ Reset-UDTheme }) $Reset.Register($Id + 'onReset', $PSCmdlet) if ($OnChange) { $OnChange.Register($Id + 'onChange', $PSCmdlet) } @{ assetId = $Script:AssetId isPlugin = $true type = 'ud-theme-picker' id = $Id themes = @($Options) variant = $Variant label = $Label showReset = -not $HideReset storageKey = $StorageKey onApply = $Apply onReset = $Reset onChange = $OnChange } } |