Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork2
ON-HOLD - Declarative UIs for .NET MAUI with F# and MVU, using Fabulous
License
fabulous-dev/Fabulous.Maui
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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)})}
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
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.
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.
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.
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
.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]
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
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Sponsor this project
Uh oh!
There was an error while loading.Please reload this page.
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Contributors2
Uh oh!
There was an error while loading.Please reload this page.