Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ON-HOLD - Declarative UIs for .NET MAUI with F# and MVU, using Fabulous

License

NotificationsYou must be signed in to change notification settings

fabulous-dev/Fabulous.Maui

Repository files navigation

buildNuGet versionNuGet downloadsDiscordTwitter Follow


⚠️⚠️⚠️ Project on-hold due to major blockers in Microsoft.Maui⚠️⚠️⚠️

This project tried to provide custom MVU-first implementation to the new control interfaces of Maui (ILabel,IButton, etc.), and not rely on the MVVM-focused controls fromMicrosoft.Maui.Controls. Unfortunately those interfaces are missing a lot of features, andMicrosoft.Maui.Core is lacking plenty of handlers (eg.NavigationView has no iOS implementation).

Since this will very likely be a multi-year effort from the Maui team, it means Fabulous.Maui can't provide a full MVU-first experience for the moment.

Instead, while waiting for the Maui team to fully migrate to the new architecture, we wanted to allow you to mix Fabulous and Microsoft.Maui.Controls-implemented widgets. But this approach is not going to work as any Microsoft.Maui.Controls widgets require child controls to be inherit from the MVVM Microsoft.Maui.Controls.View class, effectively preventing us to mix Fabulous & Maui widgets.

We might reconsider this library in the future.

In the meantime, please useFabulous.MauiControls


Fabulous.Maui brings the great development experience of Fabulous to .NET MAUI, allowing you to take advantage of the latest cross-platform UI framework from Microsoft with a tailored declarative UI DSL and clean architecture.

Deploy to any platform supported by .NET MAUI, such as Android, iOS, macOS, Windows, Linux and more!

/// A simple Counter apptypeModel={ Count:int}typeMsg=| Increment| Decrementletinit()={ Count=0}letupdate msg model=match msgwith| Increment->{ modelwith Count= model.Count+1}| Decrement->{ modelwith Count= model.Count-1}letview model=    Application(){        Window(            VStack(spacing=16.){                Image(Aspect.AspectFit,"fabulous.png")                Label($"Count is {model.Count}")                TextButton("Increment", Increment)                TextButton("Decrement", Decrement)})}

Getting Started

You can start your new Fabulous.Maui app in a matter of seconds using the dotnet CLI templates.
For a starter guide see ourGet Started with Fabulous.Maui.

dotnet new install Fabulous.Maui.Templatesdotnet new fabulous-maui -n MyApp

Documentation

The full documentation for Fabulous.Maui can be found atdocs.fabulous.dev/v2/maui.

Other useful links:

Additionally, we have theFabulous Discord server where you can ask any of your Fabulous related questions.

Supporting Fabulous

The simplest way to show us your support is by giving this project and theFabulous project a star.

You can also support us by becoming our sponsor on the GitHub Sponsors program.
This is a fantastic way to support all the efforts going into making Fabulous the best declarative UI framework for dotnet.

If you need support see Commercial Support section below.

Contributing

Have you found a bug or have a suggestion of how to enhance Fabulous? Open an issue and we will take a look at it as soon as possible.

Do you want to contribute with a PR? PRs are always welcome, just make sure to create it from the correct branch (main) and follow theContributor Guide.

For bigger changes, or if in doubt, make sure to talk about your contribution to the team. Either via an issue, GitHub discussion, or reach out to the team either using theDiscord server.

Commercial support

If you would like us to provide you with:

  • training and workshops,
  • support services,
  • and consulting services.

Feel free to contact us:support@fabulous.dev

Dev notes

.NET MAUI is still transitioning from the old architecture to the new one, so we need to use a hybrid approach to support both.

TheCore folder contains the widgets and modifiers targeting the new architecture.
TheCompatibility folder contains the widgets and modifiers targeting the old architecture.

When MAUI migrates a control to the new architecture, we will need to remove the old widget fromCompatibility and add the new one toCore.

To allow to use both old and new widgets in a same app, we rely on marker interfaces to ensure compatibility:

  • Microsoft.Maui.IButton are the marker interfaces from the new architecture in .NET MAUI. They are also the base marker interfaces for Core and Compatibility widgets.
  • Fabulous.Maui.IFabButton are marker interfaces for Core widgets.
  • Fabulous.Maui.Compatibility.IFabCompatButton are marker interfaces for Compatibility widgets.
graph LR;    A[Microsoft.Maui.IButton]-->B[Fabulous.Maui.Controls.IFabButton]    A-->C[Fabulous.Maui.Compatibility.IFabCompatTextButton]    B-->D[Fabulous.Maui.Controls.FabButton]    C-->E[Microsoft.Maui.Controls.Button]
Loading

You need to make sure to apply the right kind of marker interfaces to avoid casting errors.
All modifiers need to target only the corresponding marker interfaces as they directly cast to the underlying type, which will be different between old and new architecture.

On the other hand, to enable mixing old and new widgets in a same tree, all "children" modifiers (such asLayout.Children,ContentView.Content, etc) need to target the base marker interfaces (fromMicrosoft.Maui). e.g.

// Here, the children marker interface is Microsoft.Maui.IView// Like this, we can pass either a Core or Compatibility widget as a childstatic member inlineVStack<'msg>(?spacing:float)=    CollectionBuilder<'msg, IFabCompatVerticalStackLayout, IView>(VerticalStackLayout.WidgetKey, LayoutOfView.Children)// This textColor modifier actually relies on BindableProperty, so we need to make sure to target only the Compatibility marker interface Fabulous.Maui.Compatibility.IFabCompatButtonstatic member inlinetextColor(this:WidgetBuilder<'msg, #IFabCompatButton>,light:FabColor,?dark:FabColor)=    this.AddScalar(Button.TextColor.WithValue(AppTheme.create light dark))

About

ON-HOLD - Declarative UIs for .NET MAUI with F# and MVU, using Fabulous

Topics

Resources

License

Code of conduct

Stars

Watchers

Forks

Sponsor this project

  •  
  •  

Packages

 
 
 

Contributors2

  •  
  •  

[8]ページ先頭

©2009-2025 Movatter.jp