Examples/Invoke-LayoutDemo.ps1
|
Import-Module "$PSScriptRoot/../Elm.psd1" -Force # --------------------------------------------------------------------------- # Multi-pane layout demo # Left panel: navigation menu (arrow keys + enter to switch) # Right panel: content for the selected page # Demonstrates: New-ElmRow, percentage widths, conditional view rendering # --------------------------------------------------------------------------- $pages = @( [PSCustomObject]@{ Title = 'Welcome' Content = @( 'This demo shows a two-pane layout.' '' 'The left panel is a nav menu.' 'The right panel renders content' 'based on the selected page.' '' 'Arrow keys move the selection.' 'Enter confirms.' ) } [PSCustomObject]@{ Title = 'Layout' Content = @( 'New-ElmRow arranges children' 'horizontally.' '' 'New-ElmBox arranges children' 'vertically (the default).' '' 'Width can be: Auto, Fill,' 'an integer, or a percentage.' ) } [PSCustomObject]@{ Title = 'Style' Content = @( 'New-ElmStyle properties:' '' ' -Foreground / -Background' ' -Bold / -Italic' ' -Underline / -Strikethrough' ' -Border (None/Normal/Rounded' ' /Thick/Double)' ' -Padding / -Margin' ) } [PSCustomObject]@{ Title = 'TEA' Content = @( 'The Elm Architecture:' '' ' Init -> initial model' ' Update -> msg + model' ' -> new model' ' View -> model -> tree' '' 'Pure scriptblocks. No side' 'effects in Update or View.' ) } ) # --------------------------------------------------------------------------- # Init # --------------------------------------------------------------------------- $init = { [PSCustomObject]@{ Model = [PSCustomObject]@{ Pages = $pages Selected = 0 } Cmd = $null } } # --------------------------------------------------------------------------- # Update # --------------------------------------------------------------------------- $update = { param($msg, $model) $selected = $model.Selected $count = $model.Pages.Count switch ($msg.Key) { 'UpArrow' { $selected = if ($selected -gt 0) { $selected - 1 } else { $count - 1 } } 'DownArrow' { $selected = if ($selected -lt $count - 1) { $selected + 1 } else { 0 } } 'Q' { return [PSCustomObject]@{ Model = $model Cmd = [PSCustomObject]@{ Type = 'Quit' } } } } [PSCustomObject]@{ Model = [PSCustomObject]@{ Pages = $model.Pages; Selected = $selected } Cmd = $null } } # --------------------------------------------------------------------------- # View # --------------------------------------------------------------------------- $view = { param($model) $navActiveStyle = New-ElmStyle -Foreground 'BrightWhite' -Background 'Blue' -Bold $navNormalStyle = New-ElmStyle -Foreground 'White' $headingStyle = New-ElmStyle -Bold -Foreground 'BrightCyan' $contentStyle = New-ElmStyle -Foreground 'White' $hintStyle = New-ElmStyle -Foreground 'BrightBlack' $navPanelStyle = New-ElmStyle -Border 'Normal' -Padding @(1, 1) -Width 18 $contentPanStyle = New-ElmStyle -Border 'Normal' -Padding @(1, 2) -Width 36 # Left: nav menu $navItems = for ($i = 0; $i -lt $model.Pages.Count; $i++) { $page = $model.Pages[$i] $label = if ($i -eq $model.Selected) { "> $($page.Title)" } else { " $($page.Title)" } $style = if ($i -eq $model.Selected) { $navActiveStyle } else { $navNormalStyle } New-ElmText -Content $label -Style $style } $navItems += New-ElmText -Content '' $navItems += New-ElmText -Content '[q] quit' -Style $hintStyle $navPanel = New-ElmBox -Style $navPanelStyle -Children $navItems # Right: content for selected page $page = $model.Pages[$model.Selected] $content = @(New-ElmText -Content $page.Title -Style $headingStyle) $content += New-ElmText -Content '' foreach ($line in $page.Content) { $content += New-ElmText -Content $line -Style $contentStyle } $contentPanel = New-ElmBox -Style $contentPanStyle -Children $content New-ElmRow -Children @($navPanel, $contentPanel) } # --------------------------------------------------------------------------- # Run # --------------------------------------------------------------------------- Start-ElmProgram -InitFn $init -UpdateFn $update -ViewFn $view |