SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer
0.0.3
See the version list below for details.
dotnet tool install --global SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer --version 0.0.3
dotnet new tool-manifest # if you are setting up this repo dotnet tool install --local SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer --version 0.0.3
#tool dotnet:?package=SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer&version=0.0.3
nuke :add-package SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer --version 0.0.3
Avalonia.FuncUI.LiveView
Live fs/fsx previewer for Avalonia.FuncUI.
What is this ?
Avalonia.FuncUI.LiveView is an experimental FsAutoComplete extension that aims to provide a real-time preview of the UI of Avalonia.FuncUI. Analyzers.SDK, it displays a real-time preview of the content of the F# file you are editing in the editor. No need to save the file to update the preview.
How to use
Warning Avalonia.FuncUI.LiveView is incomplete. It has not been fully tested and is not intended for use in a production environment. Please use this tool at your own risk.
The following is a case of using VScode and Paket.
Preliminary Preparation
Network
Use localhost:8080
for communication between Analyzer and LivePreview.
Communication method will be improved in the future.
VScode
Install Ionide.Ionide-fsharp in VScode.
FuncUI Setup
Create a working directory and launch VScode.
mkdir YourFuncUIApp
cd YourFuncUIApp
code .
Create a project.
dotnet new tool-manifest
dotnet new gitignore
dotnet new sln
dotnet new console -o ./src/YourFuncUIApp -lang f#
dotnet sln add ./src/YourFuncUIApp/YourFuncUIApp.fsproj
Setup F# formatter
dotnet tool install fantomas
Create .editorconfig
. The contents are as follows:
root = true
[*]
indent_style=space
indent_size=4
charset=utf-8
trim_trailing_whitespace=true
insert_final_newline=false
[*.{fs,fsx}]
fsharp_experimental_elmish=true
Paket Setup
dotnet tool install paket
Create paket.dependencies
. The contents are as follows:
source https://api.nuget.org/v3/index.json
storage: none
nuget FSharp.Core content: none
nuget Avalonia.FuncUI 1.0.1
nuget Avalonia.Desktop 11.0.3
nuget Avalonia.Themes.Fluent 11.0.3
nuget SilkyFowl.Avalonia.FuncUI.LiveView 0.0.3
dotnet paket convert-from-nuget --force --no-install --no-auto-restore
dotnet paket add -p ./src/YourFuncUIApp/YourFuncUIApp.fsproj Avalonia.FuncUI --no-install
dotnet paket add -p ./src/YourFuncUIApp/YourFuncUIApp.fsproj Avalonia.Desktop --no-install
dotnet paket add -p ./src/YourFuncUIApp/YourFuncUIApp.fsproj Avalonia.Themes.Fluent --no-install
dotnet paket add -p ./src/YourFuncUIApp/YourFuncUIApp.fsproj SilkyFowl.Avalonia.FuncUI.LiveView --no-install
dotnet paket install
Without Paket
Add a dependency to YourFuncUIApp.fsproj
as follows:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Desktop" Version="11.0.3" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.3" />
<PackageReference Include="Avalonia.FuncUI" Version="1.0.1" />
<PackageReference Include="SilkyFowl.Avalonia.FuncUI.LiveView" Version="0.0.3" />
</ItemGroup>
</Project>
dotnet restore
Write code
Rewrite Program.fs
as follows:
namespace CounterApp
open Avalonia
open Avalonia.Controls.ApplicationLifetimes
open Avalonia.Themes.Fluent
open Avalonia.FuncUI.Hosts
open Avalonia.Controls
open Avalonia.FuncUI
open Avalonia.FuncUI.DSL
open Avalonia.Layout
open Avalonia.FuncUI.LiveView
open Avalonia.FuncUI.LiveView.Core.Types
module Main =
[<LivePreview>]
let view () =
Component(fun ctx ->
let state = ctx.useState 0
DockPanel.create [
DockPanel.children [
Button.create [
Button.dock Dock.Bottom
Button.onClick (fun _ -> state.Set(state.Current - 1))
Button.content "-"
Button.horizontalAlignment HorizontalAlignment.Stretch
Button.horizontalContentAlignment HorizontalAlignment.Center
]
Button.create [
Button.dock Dock.Bottom
Button.onClick (fun _ -> state.Set(state.Current + 1))
Button.content "+"
Button.horizontalAlignment HorizontalAlignment.Stretch
Button.horizontalContentAlignment HorizontalAlignment.Center
]
TextBlock.create [
TextBlock.dock Dock.Top
TextBlock.fontSize 48.0
TextBlock.verticalAlignment VerticalAlignment.Center
TextBlock.horizontalAlignment HorizontalAlignment.Center
TextBlock.text (string state.Current)
]
]
])
type MainWindow() =
inherit HostWindow()
do
base.Title <- "Counter Example"
base.Content <- Main.view ()
module LiveView =
let enabled =
match System.Environment.GetEnvironmentVariable("FUNCUI_LIVEPREVIEW") with
| null -> false
| "1" -> true
| _ -> false
type App() =
inherit Application()
override this.Initialize() =
this.Styles.Add(FluentTheme())
this.RequestedThemeVariant <- Styling.ThemeVariant.Dark
override this.OnFrameworkInitializationCompleted() =
match this.ApplicationLifetime with
| :? IClassicDesktopStyleApplicationLifetime as desktopLifetime ->
desktopLifetime.MainWindow <-
if LiveView.enabled then
LiveViewWindow() :> Window
else
MainWindow()
| _ -> ()
#if DEBUG
this.AttachDevTools()
#endif
module Program =
[<EntryPoint>]
let main (args: string[]) =
AppBuilder
.Configure<App>()
.UsePlatformDetect()
.UseSkia()
.StartWithClassicDesktopLifetime(args)
Start the program and check if it works.
dotnet run --project ./src/YourFuncUIApp/YourFuncUIApp.fsproj
vscode settings
- .vscode/launch.json
{
"configurations": [
{
"name": "FuncUI Launch",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/YourFuncUIApp/bin/Debug/net7.0/YourFuncUIApp.dll",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": "FuncUI Launch (Preview)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/src/YourFuncUIApp/bin/Debug/net7.0/YourFuncUIApp.dll",
"args": [],
"env": {
"FUNCUI_LIVEPREVIEW": "1"
},
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
}
]
}
- .vscode/tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"command": "dotnet",
"type": "shell",
"args": [
"build",
],
"problemMatcher": [
"$msCompile"
],
"group": "build"
},
]
}
- .vscode/settings.json
{
"FSharp.enableAnalyzers": true
}
Now start the debugger and make sure it works.
When launched, proceed to the next step.
Setting up FuncUI Analyzer
Install Analyzer.
Warning Installation of SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer has changed since v0.0.3.
dotnet tool install SilkyFowl.Avalonia.FuncUI.LiveView.Analyzer --version 0.0.3 --tool-path analyzers
Check if FuncUI Analyzer works
FSharp.enableAnalyzers
is true- Analyzer Dll exists in
FSharp.analyzersPath
.
With these conditions, editing the F# code recognized in the Solution Explorer
of Ionide for F# will start the FuncUi Analyzer
.
Warning You can analyze
fsx
scripts, etc. that are not recognized by theSolution Explorer
, but you cannot start theFuncUi Analyzer
.
Launch LivePreview
When using debugger
Change the debugger setting to FuncUI Launch(Live Preview)
and start it.
When not using debugger
Set environment variables.
bash
export FUNCUI_LIVEPREVIEW=1
cmd
set FUNCUI_LIVEPREVIEW=1
powershell
$env:FUNCUI_LIVEPREVIEW = 1
Note Without the debugger, response to code changes is improved.
dotnet build -c Release
dotnet ./src/YourFuncUIApp/bin/Release/net7.0/YourFuncUIApp.dll
Known Issues, Limitations
- Write quickly.
If there is a DU in the file that consists entirely of valued case labels, it cannot be previewed
workaround
Make it a DU that includes one or more cases with no value
DU are defined in a separate file
// TypesDefinition.fs
module ElmishModule =
type State = { watermark: string }
let init = { watermark = "" }
type Msg =
| SetWatermark of string
let update msg state =
match msg with
| SetWatermark test -> { state with watermark = test }
// OtherFile.fs
open Sample.ElmishModule
let view (state:State) dispatch =
StackPanel.create [
StackPanel.spacing 10.0
StackPanel.children [
TextBox.create [
TextBox.watermark state.watermark
TextBox.horizontalAlignment HorizontalAlignment.Stretch
]
Button.create [
Button.background "DarkBlue"
Button.content "Set Watermark"
Button.onClick (fun _ -> SetWatermark "test" |> dispatch)
Button.horizontalAlignment HorizontalAlignment.Stretch
]
Button.create [
Button.content "Unset Watermark"
Button.onClick (fun _ -> SetWatermark "" |> dispatch)
Button.horizontalAlignment HorizontalAlignment.Stretch
]
]
]
type Host() as this =
inherit Hosts.HostControl()
do
Elmish.Program.mkSimple (fun () -> init) update view
|> Program.withHost this
|> Elmish.Program.run
[<LivePreview>]
let preview () = ViewBuilder.Create<Host> []
mechanism
- Write quickly.
Plan
→ SilkyFowl/Avalonia.FuncUI.LiveView#4
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
This package has no dependencies.
Version | Downloads | Last updated |
---|---|---|
0.0.4-preview06 | 78 | 5/25/2024 |
0.0.4-preview05 | 262 | 3/10/2024 |
0.0.4-preview04 | 170 | 2/17/2024 |
0.0.4-preview03 | 213 | 2/12/2024 |
0.0.4-preview02 | 313 | 12/20/2023 |
0.0.4-preview01 | 520 | 11/3/2023 |
0.0.3 | 751 | 8/28/2023 |
0.0.3-preview01 | 592 | 8/28/2023 |
0.0.2-preview03 | 383 | 5/6/2023 |
0.0.2-preview02 | 389 | 5/6/2023 |
0.0.2-preview01 | 384 | 5/5/2023 |
0.0.1.1 | 464 | 8/14/2023 |
0.0.1 | 437 | 5/5/2023 |
0.0.1-alpha4 | 470 | 6/22/2022 |
0.0.1-alpha3 | 558 | 6/22/2022 |
0.0.1-alpha2 | 477 | 6/15/2022 |
0.0.1-alpha | 419 | 6/14/2022 |
* Stable release.