diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
new file mode 100644
index 00000000..fc95bbb8
--- /dev/null
+++ b/.github/workflows/deploy.yml
@@ -0,0 +1,71 @@
+name: Deploy demo to static pages
+
+on:
+ push:
+ branches:
+ - master
+ - wasm-demo
+
+env:
+ PUBLISH_DIR: Material.Avalonia.Demo.Browser/bin/Release/net8.0/browser-wasm/AppBundle/
+
+jobs:
+ # Build job
+ build:
+ name: "Builds a Material.Avalonia.Demo.Browser"
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ - uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: 8
+ - name: 'Cache: .nuke/temp, ~/.nuget/packages'
+ uses: actions/cache@v3
+ with:
+ path: |
+ .nuke/temp
+ ~/.nuget/packages
+ key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
+ - name: 'Install workload: wasm-tools'
+ run: dotnet workload install wasm-tools
+ - name: 'Publish Material.Avalonia.Demo.Browser'
+ run: dotnet publish Material.Avalonia.Demo.Browser/Material.Avalonia.Demo.Browser.csproj -c Release
+ - name: Fix permissions
+ run: |
+ chmod -c -R +rX "${{ env.PUBLISH_DIR }}" | while read line; do
+ echo "::info title=Invalid file permissions automatically fixed::$line"
+ done
+ - name: Rewrite base href
+ uses: SteveSandersonMS/ghaction-rewrite-base-href@v1
+ with:
+ html_path: ${{ env.PUBLISH_DIR }}/index.html
+ base_href: /Material.Avalonia/
+ - name: Upload Pages artifact
+ uses: actions/upload-pages-artifact@v3
+ with:
+ path: ${{ env.PUBLISH_DIR }}
+
+ # Deploy job
+ deploy:
+ name: "Deploy Material.Avalonia.Demo.Browser to GitHub Pages"
+ # Add a dependency to the build job
+ needs: build
+
+ # Grant GITHUB_TOKEN the permissions required to make a Pages deployment
+ permissions:
+ pages: write # to deploy to Pages
+ id-token: write # to verify the deployment originates from an appropriate source
+
+ # Deploy to the github-pages environment
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+
+ # Specify runner + deployment step
+ runs-on: ubuntu-latest
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v4 # or specific "vX.X.X" version tag for this action
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index d687a597..70ffbe49 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -15,13 +15,15 @@
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/Material.Avalonia.Demo.Browser/AppBundle/Logo.svg b/Material.Avalonia.Demo.Browser/AppBundle/Logo.svg
new file mode 100644
index 00000000..9685a23a
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/AppBundle/Logo.svg
@@ -0,0 +1,5 @@
+
diff --git a/Material.Avalonia.Demo.Browser/AppBundle/app.css b/Material.Avalonia.Demo.Browser/AppBundle/app.css
new file mode 100644
index 00000000..a424538b
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/AppBundle/app.css
@@ -0,0 +1,74 @@
+:root {
+ --sat: env(safe-area-inset-top);
+ --sar: env(safe-area-inset-right);
+ --sab: env(safe-area-inset-bottom);
+ --sal: env(safe-area-inset-left);
+}
+
+/* HTML styles for the splash screen */
+
+.highlight {
+ color: white;
+ font-size: 2.5rem;
+ display: block;
+}
+
+.purple {
+ color: #8b44ac;
+}
+
+.icon {
+ opacity: 0.05;
+ height: 35%;
+ width: 35%;
+ position: absolute;
+ background-repeat: no-repeat;
+ right: 0px;
+ bottom: 0px;
+ margin-right: 3%;
+ margin-bottom: 5%;
+ z-index: 5000;
+ background-position: right bottom;
+ pointer-events: none;
+}
+
+#avalonia-splash a {
+ color: whitesmoke;
+ text-decoration: none;
+}
+
+.center {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ height: 100vh;
+}
+
+#avalonia-splash {
+ position: relative;
+ height: 100%;
+ width: 100%;
+ color: whitesmoke;
+ background: #1b2a4e;
+ font-family: 'Nunito', sans-serif;
+ background-position: center;
+ background-size: cover;
+ background-repeat: no-repeat;
+ justify-content: center;
+ align-items: center;
+}
+
+.splash-close {
+ animation: fadeout 0.25s linear forwards;
+}
+
+@keyframes fadeout {
+ 0% {
+ opacity: 100%;
+ }
+
+ 100% {
+ opacity: 0;
+ visibility: collapse;
+ }
+}
diff --git a/Material.Avalonia.Demo.Browser/AppBundle/favicon.ico b/Material.Avalonia.Demo.Browser/AppBundle/favicon.ico
new file mode 100644
index 00000000..da8d49ff
Binary files /dev/null and b/Material.Avalonia.Demo.Browser/AppBundle/favicon.ico differ
diff --git a/Material.Avalonia.Demo.Browser/AppBundle/index.html b/Material.Avalonia.Demo.Browser/AppBundle/index.html
new file mode 100644
index 00000000..87fec207
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/AppBundle/index.html
@@ -0,0 +1,30 @@
+
+
+
+
+ AvaloniaCrossPlatformSample.Browser
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Material.Avalonia.Demo.Browser/AppBundle/main.js b/Material.Avalonia.Demo.Browser/AppBundle/main.js
new file mode 100644
index 00000000..83bf6ec2
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/AppBundle/main.js
@@ -0,0 +1,13 @@
+import { dotnet } from './dotnet.js'
+
+const is_browser = typeof window != "undefined";
+if (!is_browser) throw new Error(`Expected to be running in a browser`);
+
+const dotnetRuntime = await dotnet
+ .withDiagnosticTracing(false)
+ .withApplicationArgumentsFromQuery()
+ .create();
+
+const config = dotnetRuntime.getConfig();
+
+await dotnetRuntime.runMain(config.mainAssemblyName, [window.location.search]);
\ No newline at end of file
diff --git a/Material.Avalonia.Demo.Browser/Material.Avalonia.Demo.Browser.csproj b/Material.Avalonia.Demo.Browser/Material.Avalonia.Demo.Browser.csproj
new file mode 100644
index 00000000..c40d87bb
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/Material.Avalonia.Demo.Browser.csproj
@@ -0,0 +1,27 @@
+
+
+ net8.0
+ browser-wasm
+ AppBundle\main.js
+ Exe
+ false
+ false
+
+ true
+ true
+
+ 11.0.9
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Material.Avalonia.Demo.Browser/Program.cs b/Material.Avalonia.Demo.Browser/Program.cs
new file mode 100644
index 00000000..6aedcc92
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/Program.cs
@@ -0,0 +1,18 @@
+using System.Runtime.Versioning;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.Browser;
+using Material.Avalonia.Demo;
+using ShowMeTheXaml;
+
+[assembly: SupportedOSPlatform("browser")]
+
+internal sealed partial class Program
+{
+ private static Task Main(string[] args) => BuildAvaloniaApp()
+ .StartBrowserAppAsync("out");
+
+ public static AppBuilder BuildAvaloniaApp()
+ => AppBuilder.Configure()
+ .UseXamlDisplay();
+}
\ No newline at end of file
diff --git a/Material.Avalonia.Demo.Browser/Properties/launchSettings.json b/Material.Avalonia.Demo.Browser/Properties/launchSettings.json
new file mode 100644
index 00000000..61c5fcfb
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+ "profiles": {
+ "AvaloniaCrossPlatformSample.Browser": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:5000",
+ "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/debug?browser={browserInspectUri}"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Material.Avalonia.Demo.Browser/runtimeconfig.template.json b/Material.Avalonia.Demo.Browser/runtimeconfig.template.json
new file mode 100644
index 00000000..c6990ba7
--- /dev/null
+++ b/Material.Avalonia.Demo.Browser/runtimeconfig.template.json
@@ -0,0 +1,11 @@
+{
+ "wasmHostProperties": {
+ "perHostConfig": [
+ {
+ "name": "browser",
+ "html-path": "index.html",
+ "Host": "browser"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/Material.Demo/Material.Demo.csproj b/Material.Avalonia.Demo.Desktop/Material.Avalonia.Demo.Desktop.csproj
similarity index 57%
rename from Material.Demo/Material.Demo.csproj
rename to Material.Avalonia.Demo.Desktop/Material.Avalonia.Demo.Desktop.csproj
index 371bef28..57654851 100644
--- a/Material.Demo/Material.Demo.csproj
+++ b/Material.Avalonia.Demo.Desktop/Material.Avalonia.Demo.Desktop.csproj
@@ -4,11 +4,9 @@
WinExe
net8.0
false
- 11.0.9
false
true
-
true
link
@@ -17,30 +15,15 @@
false
true
true
+
+ 11.0.9
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
diff --git a/Material.Demo/Program.cs b/Material.Avalonia.Demo.Desktop/Program.cs
similarity index 97%
rename from Material.Demo/Program.cs
rename to Material.Avalonia.Demo.Desktop/Program.cs
index 581c26a2..f5eef1d3 100644
--- a/Material.Demo/Program.cs
+++ b/Material.Avalonia.Demo.Desktop/Program.cs
@@ -1,5 +1,6 @@
using System;
using Avalonia;
+using Material.Avalonia.Demo;
using ShowMeTheXaml;
namespace Material.Demo {
diff --git a/Material.Demo/App.axaml b/Material.Avalonia.Demo/App.axaml
similarity index 98%
rename from Material.Demo/App.axaml
rename to Material.Avalonia.Demo/App.axaml
index bd450632..bf7eb596 100644
--- a/Material.Demo/App.axaml
+++ b/Material.Avalonia.Demo/App.axaml
@@ -6,7 +6,7 @@
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:grammars="clr-namespace:TextMateSharp.Grammars;assembly=TextMateSharp.Grammars"
xmlns:avaloniaEdit="clr-namespace:ShowMeTheXaml.Avalonia.AvaloniaEdit;assembly=ShowMeTheXaml.Avalonia.AvaloniaEdit"
- x:Class="Material.Demo.App">
+ x:Class="Material.Avalonia.Demo.App">
fonts:Inter#Inter, $Default
diff --git a/Material.Avalonia.Demo/App.axaml.cs b/Material.Avalonia.Demo/App.axaml.cs
new file mode 100644
index 00000000..0e94437a
--- /dev/null
+++ b/Material.Avalonia.Demo/App.axaml.cs
@@ -0,0 +1,22 @@
+using Avalonia;
+using Avalonia.Controls.ApplicationLifetimes;
+using Avalonia.Markup.Xaml;
+
+namespace Material.Avalonia.Demo;
+
+public class App : Application {
+ public override void Initialize() {
+ AvaloniaXamlLoader.Load(this);
+ }
+
+ public override void OnFrameworkInitializationCompleted() {
+ if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) {
+ desktop.MainWindow = new MainWindow();
+ }
+ else if (ApplicationLifetime is ISingleViewApplicationLifetime singleViewPlatform) {
+ singleViewPlatform.MainView = new MainView();
+ }
+
+ base.OnFrameworkInitializationCompleted();
+ }
+}
\ No newline at end of file
diff --git a/Material.Demo/Assets/FavIcon_128x.png b/Material.Avalonia.Demo/Assets/FavIcon_128x.png
similarity index 100%
rename from Material.Demo/Assets/FavIcon_128x.png
rename to Material.Avalonia.Demo/Assets/FavIcon_128x.png
diff --git a/Material.Demo/Assets/FavIcon_200x.png b/Material.Avalonia.Demo/Assets/FavIcon_200x.png
similarity index 100%
rename from Material.Demo/Assets/FavIcon_200x.png
rename to Material.Avalonia.Demo/Assets/FavIcon_200x.png
diff --git a/Material.Demo/Assets/avalonia-logo.png b/Material.Avalonia.Demo/Assets/avalonia-logo.png
similarity index 100%
rename from Material.Demo/Assets/avalonia-logo.png
rename to Material.Avalonia.Demo/Assets/avalonia-logo.png
diff --git a/Material.Demo/Assets/johannes-plenio-RwHv7LgeC7s-unsplash.jpg b/Material.Avalonia.Demo/Assets/johannes-plenio-RwHv7LgeC7s-unsplash.jpg
similarity index 100%
rename from Material.Demo/Assets/johannes-plenio-RwHv7LgeC7s-unsplash.jpg
rename to Material.Avalonia.Demo/Assets/johannes-plenio-RwHv7LgeC7s-unsplash.jpg
diff --git a/Material.Avalonia.Demo/Converters/StringJoinConverter.cs b/Material.Avalonia.Demo/Converters/StringJoinConverter.cs
new file mode 100644
index 00000000..585dd06e
--- /dev/null
+++ b/Material.Avalonia.Demo/Converters/StringJoinConverter.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections;
+using System.Globalization;
+using System.Linq;
+using Avalonia.Data.Converters;
+
+namespace Material.Avalonia.Demo.Converters;
+
+public sealed class StringJoinConverter : IValueConverter {
+ public string? Separator { get; set; }
+
+ public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) {
+ IEnumerable values = value as IEnumerable ?? Array.Empty