ReactorUI
  • What's ReactorUI for Xamarin
  • Guide
    • Setting up
    • Hello World Sample
    • Components
      • Component Lifecycle
      • Component Properties
      • Component with children
      • Navigation
      • Component Context
      • Reference to native controls
      • Animation
  • Native Tree and Visual Tree
    • Custom visual nodes
    • Custom Pages
  • Migrating from MVVM model
  • Integrating DI Containers
  • Hot reload troubleshooting
  • Styling and theming
  • Sample with SkiaSharp
Powered by GitBook
On this page

Was this helpful?

Styling and theming

Styling with RxTheme is no more relevant in MauiReactor where the reccomended way is using standard .NET classes and XAML resources

You can style components or widgets directly in C#, for example creating a library of reusable custom widgets as classes or functions. The below code uses a static function to return a customized button:

public static RxButton PrimaryButton(string text)
    => new RxButton(text)
        .BackgroundColor(ThemeColor.CommunicationCommunicationPrimary)
        .TextColor(ThemeColor.NeutralWhite)
        .BorderWidth(0)
        .CornerRadius(2)
        .Padding(5, 0);

NOTE: Styling thru XAML (Resources) is not currently supported

Theming

Another powerful way to style an entire page is using an RxTheme object. A theme provides an efficient way to style every control present in a page. For example consider we want to style an application with a Dark and Light theme, we could create 2 RxTheme:

public static class Theme
{
    public static RxTheme Light()
        => new RxTheme()
            .StyleFor<RxLabel>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(0, 10);
            })
            .StyleFor<RxEntry>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(0, 10);
                _.BackgroundColor(Color.White);
            })
            .StyleFor<RxButton>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(10);
                _.BackgroundColor(Color.DarkGray);
            })
            .StyleFor<RxNavigationPage>(_ =>
            {
                _.BarBackgroundColor((Color)NavigationPage.BarBackgroundColorProperty.DefaultValue);
                _.BarTextColor((Color)NavigationPage.BarTextColorProperty.DefaultValue);
            })
            .StyleFor<RxContentPage>(_ =>
            {
                _.BackgroundColor((Color)ContentPage.BackgroundColorProperty.DefaultValue);
                _.Padding(10);
            });

    public static RxTheme Dark()
        => new RxTheme()
            .StyleFor<RxLabel>(_ =>
            {
                _.TextColor(Color.White);
                _.Margin(0, 10);
            })
            .StyleFor<RxEntry>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(0, 10);
                _.BackgroundColor(Color.LightGray);
            })
            .StyleFor<RxButton>(_ =>
            {
                _.TextColor(Color.Black);
                _.Margin(10);
                _.BackgroundColor(Color.LightGray);
            })
            .StyleFor<RxNavigationPage>(_ =>
            {
                _.BarBackgroundColor(Color.DarkGray);
                _.BarTextColor(Color.White);
            })
            .StyleFor<RxContentPage>(_ =>
            {
                _.BackgroundColor(Color.Black);
                _.Padding(10);
            });
}

Now we can wrap any component/visual with these themes to automatically change its style:

public enum ThemeColor
{ 
    Dark,

    Light
}

public class MainPageState : IState
{
    public ThemeColor ThemeColor { get; set; } = ThemeColor.Light;
}

public class MainPage : RxComponent<MainPageState>
{
    public override VisualNode Render()
    {
        return new RxNavigationPage()
        {
            new RxContentPage()
            { 
                new RxStackLayout()
                { 
                    new RxLabel("Label"),
                    new RxEntry(),
                    new RxButton("Toggle Theme")
                        .OnClick(()=> SetState(s => s.ThemeColor = (s.ThemeColor == ThemeColor.Dark ? ThemeColor.Light : ThemeColor.Dark)))
                }
            }
            .Title("Theming")
        }
        .UseTheme(State.ThemeColor == ThemeColor.Dark ? Theme.Dark() : Theme.Light());
    }
}

This should be the final effect:

PreviousHot reload troubleshootingNextSample with SkiaSharp

Last updated 2 years ago

Was this helpful?

Dynamically change page theme