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 + + + + + + + + + + +
+
+
+

+ Powered by + Avalonia UI +

+
+ Avalonia Logo +
+
+ + + + \ 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(); + return string.Join(Separator ?? "", values.OfType()); + } + + public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) { + throw new NotSupportedException(); + } +} \ No newline at end of file diff --git a/Material.Demo/Extensions/PrimaryColorExt.cs b/Material.Avalonia.Demo/Extensions/PrimaryColorExt.cs similarity index 91% rename from Material.Demo/Extensions/PrimaryColorExt.cs rename to Material.Avalonia.Demo/Extensions/PrimaryColorExt.cs index d4f89c42..5c8ceca9 100644 --- a/Material.Demo/Extensions/PrimaryColorExt.cs +++ b/Material.Avalonia.Demo/Extensions/PrimaryColorExt.cs @@ -3,7 +3,7 @@ using Avalonia.Media; using Material.Colors; -namespace Material.Demo.Extensions; +namespace Material.Avalonia.Demo.Extensions; public class PrimaryColorExt : MarkupExtension { diff --git a/Material.Demo/Extensions/SecondaryColorExt.cs b/Material.Avalonia.Demo/Extensions/SecondaryColorExt.cs similarity index 91% rename from Material.Demo/Extensions/SecondaryColorExt.cs rename to Material.Avalonia.Demo/Extensions/SecondaryColorExt.cs index 6c1a38f3..33b4c55c 100644 --- a/Material.Demo/Extensions/SecondaryColorExt.cs +++ b/Material.Avalonia.Demo/Extensions/SecondaryColorExt.cs @@ -3,7 +3,7 @@ using Avalonia.Media; using Material.Colors; -namespace Material.Demo.Extensions; +namespace Material.Avalonia.Demo.Extensions; public class SecondaryColorExt : MarkupExtension { diff --git a/Material.Avalonia.Demo/GlobalCommand.cs b/Material.Avalonia.Demo/GlobalCommand.cs new file mode 100644 index 00000000..54cf9724 --- /dev/null +++ b/Material.Avalonia.Demo/GlobalCommand.cs @@ -0,0 +1,36 @@ +using System.Diagnostics; +using Avalonia; +using Material.Styles.Themes; +using Material.Styles.Themes.Base; + +namespace Material.Avalonia.Demo; + +public static class GlobalCommand +{ + private static readonly MaterialTheme MaterialThemeStyles = + Application.Current!.LocateMaterialTheme(); + + public static void UseMaterialUIDarkTheme() + { + MaterialThemeStyles.BaseTheme = BaseThemeMode.Dark; + } + + public static void UseMaterialUILightTheme() + { + MaterialThemeStyles.BaseTheme = BaseThemeMode.Light; + } + + public static void OpenProjectRepoLink() => + OpenBrowserForVisitSite("https://github.com/AvaloniaUtils/material.avalonia"); + + public static void OpenBrowserForVisitSite(string link) + { + var param = new ProcessStartInfo + { + FileName = link, + UseShellExecute = true, + Verb = "open" + }; + Process.Start(param); + } +} \ No newline at end of file diff --git a/Material.Demo/Icons/FavIcon_128x.png b/Material.Avalonia.Demo/Icons/FavIcon_128x.png similarity index 100% rename from Material.Demo/Icons/FavIcon_128x.png rename to Material.Avalonia.Demo/Icons/FavIcon_128x.png diff --git a/Material.Demo/Icons/FavIcon_16x.png b/Material.Avalonia.Demo/Icons/FavIcon_16x.png similarity index 100% rename from Material.Demo/Icons/FavIcon_16x.png rename to Material.Avalonia.Demo/Icons/FavIcon_16x.png diff --git a/Material.Demo/Icons/FavIcon_256x.png b/Material.Avalonia.Demo/Icons/FavIcon_256x.png similarity index 100% rename from Material.Demo/Icons/FavIcon_256x.png rename to Material.Avalonia.Demo/Icons/FavIcon_256x.png diff --git a/Material.Demo/Icons/FavIcon_32x.png b/Material.Avalonia.Demo/Icons/FavIcon_32x.png similarity index 100% rename from Material.Demo/Icons/FavIcon_32x.png rename to Material.Avalonia.Demo/Icons/FavIcon_32x.png diff --git a/Material.Demo/Icons/FavIcon_48x.png b/Material.Avalonia.Demo/Icons/FavIcon_48x.png similarity index 100% rename from Material.Demo/Icons/FavIcon_48x.png rename to Material.Avalonia.Demo/Icons/FavIcon_48x.png diff --git a/Material.Demo/Icons/FavIcon_64x.png b/Material.Avalonia.Demo/Icons/FavIcon_64x.png similarity index 100% rename from Material.Demo/Icons/FavIcon_64x.png rename to Material.Avalonia.Demo/Icons/FavIcon_64x.png diff --git a/Material.Demo/Icons/icon.ico b/Material.Avalonia.Demo/Icons/icon.ico similarity index 100% rename from Material.Demo/Icons/icon.ico rename to Material.Avalonia.Demo/Icons/icon.ico diff --git a/Material.Demo/MainWindow.axaml b/Material.Avalonia.Demo/MainView.axaml similarity index 88% rename from Material.Demo/MainWindow.axaml rename to Material.Avalonia.Demo/MainView.axaml index e1d7dc52..090374a9 100644 --- a/Material.Demo/MainWindow.axaml +++ b/Material.Avalonia.Demo/MainView.axaml @@ -1,18 +1,16 @@ - - + + @@ -23,8 +21,8 @@ - - + + Your lucky number: @@ -37,7 +35,7 @@ - + @@ -50,7 +48,7 @@ @@ -192,7 +190,7 @@ - + @@ -224,4 +222,4 @@ - + diff --git a/Material.Avalonia.Demo/MainView.axaml.cs b/Material.Avalonia.Demo/MainView.axaml.cs new file mode 100644 index 00000000..f2e96865 --- /dev/null +++ b/Material.Avalonia.Demo/MainView.axaml.cs @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Input; +using Avalonia.Interactivity; +using Avalonia.Markup.Xaml; +using Avalonia.Threading; +using Material.Styles.Controls; +using Material.Styles.Models; +using Material.Styles.Themes; +using Material.Styles.Themes.Base; + +namespace Material.Avalonia.Demo; + +public partial class MainView : UserControl { + private readonly List helloSnackBars = new(); + + public MainView() { + InitializeComponent(); + DrawerList.PointerReleased += DrawerSelectionChanged; + DrawerList.KeyUp += DrawerList_KeyUp; + } + + private void DrawerList_KeyUp(object? sender, KeyEventArgs e) { + if (e.Key == Key.Space || e.Key == Key.Enter) + DrawerSelectionChanged(sender, null); + } + + public void DrawerSelectionChanged(object? sender, RoutedEventArgs? args) { + if (sender is not ListBox listBox) + return; + + if (!listBox.IsFocused && !listBox.IsKeyboardFocusWithin) + return; + try { + PageCarousel.SelectedIndex = listBox.SelectedIndex; + mainScroller.Offset = Vector.Zero; + mainScroller.VerticalScrollBarVisibility = + listBox.SelectedIndex == 5 ? ScrollBarVisibility.Disabled : ScrollBarVisibility.Auto; + } + catch { + // ignored + } + + LeftDrawer.OptionalCloseLeftDrawer(); + } + + private void TemplatedControl_OnTemplateApplied(object? sender, TemplateAppliedEventArgs e) { + SnackbarHost.Post("Welcome to demo of Material.Avalonia!", null, DispatcherPriority.Normal); + } + + /// + /// This method is used for showcase of snackbar. + /// + private void HelloButtonMenuItem_OnClick(object? sender, RoutedEventArgs e) { + // According to guidelines of Material design, 'endless' snackbar is not recommended. + // They should dismiss after 4 - 10 seconds. + // https://m2.material.io/components/snackbars#behavior + var helloSnackBar = new SnackbarModel("Hello, user!", TimeSpan.FromSeconds(5)); + SnackbarHost.Post(helloSnackBar, null, DispatcherPriority.Normal); + } + + /// + /// This method is used for showcase of snackbar. + /// + private void GoodbyeButtonMenuItem_OnClick(object? sender, RoutedEventArgs e) { + SnackbarHost.Post("See ya next time, user!", null, DispatcherPriority.Normal); + } + + /// + /// This method is used for showcase of snackbar. + /// + private void ConnectToNetworkMenuItem_OnClick(object? sender, RoutedEventArgs e) { + void Retry() { + SnackbarHost.Post( + new SnackbarModel("Connected to network.", TimeSpan.FromSeconds(5)), + null, DispatcherPriority.Normal); + } + + SnackbarHost.Post( + new SnackbarModel("Unable to connect network. Please check everything is fine.", + TimeSpan.FromSeconds(10), + new SnackbarButtonModel { + Text = "Retry", + Action = Retry + }), null, DispatcherPriority.Normal); + } + + private void MaterialIcon_OnPointerPressed(object? sender, PointerPressedEventArgs e) { + var materialTheme = Application.Current!.LocateMaterialTheme(); + materialTheme.BaseTheme = + materialTheme.BaseTheme == BaseThemeMode.Light ? BaseThemeMode.Dark : BaseThemeMode.Light; + } +} \ No newline at end of file diff --git a/Material.Avalonia.Demo/MainWindow.axaml b/Material.Avalonia.Demo/MainWindow.axaml new file mode 100644 index 00000000..eefe8f18 --- /dev/null +++ b/Material.Avalonia.Demo/MainWindow.axaml @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/Material.Avalonia.Demo/MainWindow.axaml.cs b/Material.Avalonia.Demo/MainWindow.axaml.cs new file mode 100644 index 00000000..07ac8d10 --- /dev/null +++ b/Material.Avalonia.Demo/MainWindow.axaml.cs @@ -0,0 +1,9 @@ +using Avalonia.Controls; + +namespace Material.Avalonia.Demo; + +public partial class MainWindow : Window { + public MainWindow() { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/Material.Avalonia.Demo/Material.Avalonia.Demo.csproj b/Material.Avalonia.Demo/Material.Avalonia.Demo.csproj new file mode 100644 index 00000000..1da93eb1 --- /dev/null +++ b/Material.Avalonia.Demo/Material.Avalonia.Demo.csproj @@ -0,0 +1,31 @@ + + + net8.0 + false + false + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Material.Avalonia.Demo/Models/FeatureStatusModels.cs b/Material.Avalonia.Demo/Models/FeatureStatusModels.cs new file mode 100644 index 00000000..d7edcc05 --- /dev/null +++ b/Material.Avalonia.Demo/Models/FeatureStatusModels.cs @@ -0,0 +1,16 @@ +using System.ComponentModel; + +namespace Material.Avalonia.Demo.Models; + +public enum StatusEnum { + Yes, + No, + [Description("N/A")] NA, + [Description("Not Fully")] NotFully +} + +public class FeatureStatusModels { + public required string FeatureName { get; init; } + public StatusEnum IsReady { get; init; } + public StatusEnum IsAnimated { get; init; } +} \ No newline at end of file diff --git a/Material.Avalonia.Demo/Models/PackIconKindGroup.cs b/Material.Avalonia.Demo/Models/PackIconKindGroup.cs new file mode 100644 index 00000000..9bd7b1b5 --- /dev/null +++ b/Material.Avalonia.Demo/Models/PackIconKindGroup.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Material.Avalonia.Demo.ViewModels; +using Material.Icons; + +namespace Material.Avalonia.Demo.Models; + +public class MaterialIconKindGroup +{ + private readonly IconsDemoViewModel _parent; + + public MaterialIconKindGroup(IconsDemoViewModel parent, IEnumerable kinds) + { + _parent = parent; + + if (kinds is null) throw new ArgumentNullException(nameof(kinds)); + var allValues = kinds.ToList(); + if (!allValues.Any()) throw new ArgumentException($"{nameof(kinds)} must contain at least one value"); + Kind = allValues.First(); + KindValue = Enum.Parse(Kind); + Aliases = allValues + .OrderBy(x => x, StringComparer.InvariantCultureIgnoreCase) + .ToArray(); + } + + public IconsDemoViewModel Parent => _parent; + + public string Kind { get; } + public string KindToCopy => $""; + public MaterialIconKind KindValue { get; } + public string[] Aliases { get; } +} \ No newline at end of file diff --git a/Material.Avalonia.Demo/Models/Sample2Model.cs b/Material.Avalonia.Demo/Models/Sample2Model.cs new file mode 100644 index 00000000..0267373a --- /dev/null +++ b/Material.Avalonia.Demo/Models/Sample2Model.cs @@ -0,0 +1,11 @@ +namespace Material.Avalonia.Demo.Models; + +public class Sample2Model +{ + public Sample2Model(int number) + { + Number = number; + } + + public int Number { get; set; } +} \ No newline at end of file diff --git a/Material.Avalonia.Demo/Models/SideSheetDemoViewModel.cs b/Material.Avalonia.Demo/Models/SideSheetDemoViewModel.cs new file mode 100644 index 00000000..5d66e775 --- /dev/null +++ b/Material.Avalonia.Demo/Models/SideSheetDemoViewModel.cs @@ -0,0 +1,30 @@ +using Material.Avalonia.Demo.ViewModels; + +namespace Material.Avalonia.Demo.Models; + +// Data context for sidesheet +public class SideSheetData : ViewModelBase { + private readonly string _header = "SideSheet"; + public string Header => _header; + + public string ContentHeader { get; set; } = "What is Lorem Ipsum?"; + + public string ImportantInfos { get; set; } = + "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."; +} + +// Data context for SideSheet demo page +public class SideSheetDemoViewModel : ViewModelBase { + private readonly SideSheetData _information = new(); + + private bool _sideInfoOpened; + public SideSheetData Information => _information; + + public bool SideInfoOpened { + get => _sideInfoOpened; + set { + _sideInfoOpened = value; + OnPropertyChanged(); + } + } +} \ No newline at end of file diff --git a/Material.Demo/Pages/ButtonsDemo.axaml b/Material.Avalonia.Demo/Pages/ButtonsDemo.axaml similarity index 99% rename from Material.Demo/Pages/ButtonsDemo.axaml rename to Material.Avalonia.Demo/Pages/ButtonsDemo.axaml index 34b100b3..6ca2ed94 100644 --- a/Material.Demo/Pages/ButtonsDemo.axaml +++ b/Material.Avalonia.Demo/Pages/ButtonsDemo.axaml @@ -6,7 +6,7 @@ xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia" xmlns:controls="clr-namespace:Material.Styles.Controls;assembly=Material.Styles" xmlns:showMeTheXaml="clr-namespace:ShowMeTheXaml;assembly=ShowMeTheXaml.Avalonia" - x:Class="Material.Demo.Pages.ButtonsDemo"> + x:Class="Material.Avalonia.Demo.Pages.ButtonsDemo"> - - - - - + + diff --git a/Material.Avalonia.Demo/Pages/IconsDemo.axaml.cs b/Material.Avalonia.Demo/Pages/IconsDemo.axaml.cs new file mode 100644 index 00000000..b62809ce --- /dev/null +++ b/Material.Avalonia.Demo/Pages/IconsDemo.axaml.cs @@ -0,0 +1,25 @@ +using Avalonia.Controls; +using Avalonia.Input; +using Avalonia.Threading; +using Material.Avalonia.Demo.ViewModels; + +namespace Material.Avalonia.Demo.Pages; + +public partial class IconsDemo : UserControl { + public IconsDemo() { + InitializeComponent(); + + DataContext = new IconsDemoViewModel(); + } + + private void Search_OnKeyDown(object? sender, KeyEventArgs e) { + var textBox = (TextBox)sender!; + if (e.Key == Key.Enter) + this.Get