-
Notifications
You must be signed in to change notification settings - Fork 401
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement AppThemeColor, AppThemeObject, and AppThemeResource (#1264)
* Implement AppThemeColor and AppThemeResource * Undo AvatarView sample changes * Add XML docs and use .shared. filename convention * Add samples * Split AppThemeObject<T>, Resource and Color * Apply suggestions from code review Co-authored-by: Pedro Jesus <[email protected]> * Update AppThemeObjectOfT.shared.cs * Moving some things around * Add namespaces to URL namespace + fix sample * `dotnet format` * Update docs * Enable string interpolation * Remove unnecessary changes * Use `static` class for improved performance * Use real variable names * Remove unnecessary `pragma`, add non-nullable default values * Remove unnecessary condition * Update AppThemeViewModel.cs * Add theme toggle to sample * Use ArgumentNullException.ThrowIfNull * AppThemeExtension -> ThemeResourceExtension * Update Description * `dotnet format` * AppTheme => Theme * AppTheme => Theme * Revert "AppTheme => Theme" This reverts commit 7d77d02. * Revert "AppTheme => Theme" This reverts commit 1f46a73. * Rename `ThemeResourceExtension` -> `AppThemeResourceExtension` * Revert "Rename `ThemeResourceExtension` -> `AppThemeResourceExtension`" This reverts commit 3b3d472. * Rename `ThemeResourceExtension` -> `AppThemeResourceExtension` and `AppThemeResource` -> `AppThemeObject` * Update AppThemeObjectExtensions.shared.cs --------- Co-authored-by: Pedro Jesus <[email protected]> Co-authored-by: Brandon Minnick <[email protected]>
- Loading branch information
1 parent
1bb29e0
commit c04539c
Showing
13 changed files
with
415 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
samples/CommunityToolkit.Maui.Sample/Pages/Essentials/AppThemePage.xaml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
<?xml version="1.0" encoding="utf-8" ?> | ||
<pages:BasePage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" | ||
xmlns:pages="clr-namespace:CommunityToolkit.Maui.Sample.Pages" | ||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||
x:Class="CommunityToolkit.Maui.Sample.Pages.Essentials.AppThemePage" | ||
xmlns:mct="http://schemas.microsoft.com/dotnet/2022/maui/toolkit" | ||
xmlns:vm="clr-namespace:CommunityToolkit.Maui.Sample.ViewModels.Essentials" | ||
x:TypeArguments="vm:AppThemeViewModel" | ||
x:DataType="vm:AppThemeViewModel" | ||
Title="AppTheme"> | ||
<pages:BasePage.Resources> | ||
<mct:AppThemeColor Light="Green" Dark="Red" x:Key="LabelTextColor" /> | ||
<mct:AppThemeObject Light="dotnet_bot.png" Dark="avatar_icon.png" x:Key="ImageSource" /> | ||
|
||
<Style x:Key="Headline" TargetType="Label"> | ||
<Setter Property="FontFamily" Value="Segoe UI" /> | ||
<Setter Property="FontSize" Value="10" /> | ||
<Setter Property="TextColor" Value="{mct:AppThemeResource LabelTextColor}" /> | ||
</Style> | ||
</pages:BasePage.Resources> | ||
|
||
<VerticalStackLayout Spacing="14"> | ||
|
||
<Label Text="AppTheme provides extension methods and markup extensions that make it easy to assign Light Theme, Dark Theme and Default Theme" | ||
HorizontalTextAlignment="Center" | ||
VerticalOptions="Center"/> | ||
|
||
<Label | ||
Text="This color comes from the resource dictionary!" | ||
FontSize="20" | ||
VerticalOptions="Center" | ||
HorizontalOptions="Center" | ||
TextColor="{mct:AppThemeResource LabelTextColor}"/> | ||
|
||
<Label | ||
Text="The below image comes from the resource dictionary!" | ||
VerticalOptions="Center" | ||
HorizontalOptions="Center"/> | ||
|
||
<Image | ||
WidthRequest="100" | ||
HeightRequest="100" | ||
VerticalOptions="Center" | ||
HorizontalOptions="Center" | ||
Source="{mct:AppThemeResource ImageSource}"/> | ||
|
||
<Label | ||
Text="This color comes from a style!" | ||
VerticalOptions="Center" | ||
HorizontalOptions="Center" | ||
Style="{StaticResource Headline}"/> | ||
|
||
<HorizontalStackLayout Spacing="5" HorizontalOptions="Center" Margin="0,0,0,20"> | ||
<Switch x:Name="themeToggle" Toggled="Switch_Toggled" /> | ||
<Label Text="Toggle Dark/Light Theme" VerticalOptions="Center" /> | ||
</HorizontalStackLayout> | ||
</VerticalStackLayout> | ||
</pages:BasePage> |
21 changes: 21 additions & 0 deletions
21
samples/CommunityToolkit.Maui.Sample/Pages/Essentials/AppThemePage.xaml.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
using CommunityToolkit.Maui.Sample.ViewModels.Essentials; | ||
|
||
namespace CommunityToolkit.Maui.Sample.Pages.Essentials; | ||
|
||
public partial class AppThemePage : BasePage<AppThemeViewModel> | ||
{ | ||
public AppThemePage(AppThemeViewModel viewModel) : base(viewModel) | ||
{ | ||
InitializeComponent(); | ||
} | ||
|
||
void Switch_Toggled(object sender, ToggledEventArgs e) | ||
{ | ||
if (Application.Current is not null) | ||
{ | ||
Application.Current.UserAppTheme = Application.Current.RequestedTheme is AppTheme.Dark | ||
? AppTheme.Light | ||
: AppTheme.Dark; | ||
} | ||
} | ||
} |
8 changes: 8 additions & 0 deletions
8
samples/CommunityToolkit.Maui.Sample/ViewModels/Essentials/AppThemeViewModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace CommunityToolkit.Maui.Sample.ViewModels.Essentials; | ||
|
||
public class AppThemeViewModel : BaseViewModel | ||
{ | ||
public AppThemeViewModel() : base() | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
119 changes: 119 additions & 0 deletions
119
src/CommunityToolkit.Maui.UnitTests/Essentials/AppThemeTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
using CommunityToolkit.Maui.Extensions; | ||
using CommunityToolkit.Maui.UnitTests.Mocks; | ||
using Xunit; | ||
|
||
namespace CommunityToolkit.Maui.UnitTests.Essentials; | ||
|
||
public class AppThemeTests : BaseTest | ||
{ | ||
readonly MockAppInfo mockAppInfo; | ||
readonly Application app; | ||
|
||
public AppThemeTests() | ||
{ | ||
AppInfo.SetCurrent(mockAppInfo = new() { RequestedTheme = AppTheme.Light }); | ||
Application.Current = app = new Application(); | ||
} | ||
|
||
[Fact] | ||
public void AppThemeColorUsesCorrectColorForTheme() | ||
{ | ||
AppThemeColor color = new() | ||
{ | ||
Light = Colors.Green, | ||
Dark = Colors.Red | ||
}; | ||
|
||
Label label = new() | ||
{ | ||
Text = "Green on Light, Red on Dark" | ||
}; | ||
|
||
label.SetAppThemeColor(Label.TextColorProperty, color); | ||
|
||
Application.Current = null; | ||
|
||
Assert.Equal(Colors.Green, label.TextColor); | ||
|
||
SetAppTheme(AppTheme.Dark); | ||
|
||
Assert.Equal(Colors.Red, label.TextColor); | ||
} | ||
|
||
[Fact] | ||
public void AppThemeColorUsesDefaultColorWhenDarkColorNotSet() | ||
{ | ||
AppThemeColor color = new() | ||
{ | ||
Light = Colors.Green, | ||
Default = Colors.Blue | ||
}; | ||
|
||
Label label = new() | ||
{ | ||
Text = "Green on Light, Red on Dark" | ||
}; | ||
|
||
label.SetAppThemeColor(Label.TextColorProperty, color); | ||
|
||
Application.Current = null; | ||
|
||
Assert.Equal(Colors.Green, label.TextColor); | ||
|
||
SetAppTheme(AppTheme.Dark); | ||
|
||
Assert.Equal(Colors.Blue, label.TextColor); | ||
} | ||
|
||
[Fact] | ||
public void AppThemeColorUsesDefaultColorWhenLightColorNotSet() | ||
{ | ||
AppThemeColor color = new() | ||
{ | ||
Default = Colors.Blue, | ||
Dark = Colors.Red | ||
}; | ||
|
||
Label label = new() | ||
{ | ||
Text = "Green on Light, Red on Dark" | ||
}; | ||
|
||
label.SetAppThemeColor(Label.TextColorProperty, color); | ||
|
||
Application.Current = null; | ||
|
||
Assert.Equal(Colors.Blue, label.TextColor); | ||
|
||
SetAppTheme(AppTheme.Dark); | ||
|
||
Assert.Equal(Colors.Red, label.TextColor); | ||
} | ||
|
||
[Fact] | ||
public void AppThemeResourceUpdatesLabelText() | ||
{ | ||
Label label = new(); | ||
|
||
AppThemeObject resource = new() | ||
{ | ||
Light = "Light Theme", | ||
Dark = "Dark Theme" | ||
}; | ||
|
||
label.SetAppTheme(Label.TextProperty, resource); | ||
|
||
Application.Current = null; | ||
Assert.Equal("Light Theme", label.Text); | ||
|
||
SetAppTheme(AppTheme.Dark); | ||
|
||
Assert.Equal("Dark Theme", label.Text); | ||
} | ||
|
||
void SetAppTheme(AppTheme theme) | ||
{ | ||
mockAppInfo.RequestedTheme = theme; | ||
((IApplication)app).ThemeChanged(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
namespace CommunityToolkit.Maui.UnitTests.Mocks; | ||
|
||
class MockAppInfo : IAppInfo | ||
{ | ||
public string PackageName { get; set; } = string.Empty; | ||
|
||
public string Name { get; set; } = string.Empty; | ||
|
||
public string VersionString { get; set; } = string.Empty; | ||
|
||
public string BuildString { get; set; } = string.Empty; | ||
|
||
public Version Version { get; set; } = new Version(1, 0); | ||
|
||
public LayoutDirection RequestedLayoutDirection { get; set; } | ||
|
||
public AppTheme RequestedTheme { get; set; } | ||
|
||
public AppPackagingModel PackagingModel { get; set; } | ||
|
||
public void ShowSettingsUI() | ||
{ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/CommunityToolkit.Maui/Essentials/AppTheme/AppThemeColor.shared.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace CommunityToolkit.Maui; | ||
|
||
/// <summary> | ||
/// Represents a color that is aware of the operating system theme. | ||
/// </summary> | ||
public sealed class AppThemeColor : AppThemeObject<Color> | ||
{ | ||
} |
56 changes: 56 additions & 0 deletions
56
src/CommunityToolkit.Maui/Essentials/AppTheme/AppThemeObject.shared.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
namespace CommunityToolkit.Maui; | ||
|
||
/// <summary> | ||
/// Represents a resource that is aware of the operating system theme. | ||
/// </summary> | ||
public sealed class AppThemeObject : AppThemeObject<object> | ||
{ | ||
} | ||
|
||
/// <summary> | ||
/// Represents an object that is aware of the operating system theme. | ||
/// </summary> | ||
public abstract class AppThemeObject<T> | ||
{ | ||
/// <summary> | ||
/// The <see cref="object"/> that is used when the operating system uses light theme. | ||
/// </summary> | ||
public T? Light { get; set; } | ||
|
||
/// <summary> | ||
/// The <see cref="object"/> that is used when the operating system uses dark theme. | ||
/// </summary> | ||
public T? Dark { get; set; } | ||
|
||
/// <summary> | ||
/// The <see cref="object"/> that is used when the current theme is unspecified or | ||
/// when a value is not provided for <see cref="Light"/> or <see cref="Dark"/>. | ||
/// </summary> | ||
public T? Default { get; set; } | ||
|
||
/// <summary> | ||
/// Gets a bindable object which holds the diffent values for each operating system theme. | ||
/// </summary> | ||
/// <returns>A <see cref="AppThemeBinding"/> instance with the respective theme values.</returns> | ||
public virtual BindingBase GetBinding() | ||
{ | ||
var binding = new AppThemeBinding(); | ||
|
||
if (Light is not null) | ||
{ | ||
binding.Light = Light; | ||
} | ||
|
||
if (Dark is not null) | ||
{ | ||
binding.Dark = Dark; | ||
} | ||
|
||
if (Default is not null) | ||
{ | ||
binding.Default = Default; | ||
} | ||
|
||
return binding; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
src/CommunityToolkit.Maui/Extensions/AppThemeObjectExtensions.shared.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace CommunityToolkit.Maui.Extensions; | ||
|
||
/// <summary> | ||
/// This class contains static extension methods for use with <see cref="BindableObject"/> objects. | ||
/// </summary> | ||
public static class AppThemeObjectExtensions | ||
{ | ||
/// <summary> | ||
/// Sets the <see cref="AppThemeColor"/> to the provided <see cref="BindableProperty"/> of the given <see cref="BindableObject"/>. | ||
/// </summary> | ||
/// <param name="self">The <see cref="BindableObject"/> on which the <paramref name="appThemeColor"/> will be applied to the provided property in <paramref name="targetProperty"/>.</param> | ||
/// <param name="targetProperty">The <see cref="BindableProperty"/> on which to set the <paramref name="appThemeColor"/>.</param> | ||
/// <param name="appThemeColor">The <see cref="AppThemeColor"/> to apply to <paramref name="targetProperty"/>.</param> | ||
public static void SetAppThemeColor(this BindableObject self, BindableProperty targetProperty, AppThemeColor appThemeColor) => | ||
self.SetBinding(targetProperty, appThemeColor.GetBinding()); | ||
|
||
/// <summary> | ||
/// Sets the <see cref="AppThemeObject"/> to the provided <see cref="BindableProperty"/> of the given <see cref="BindableObject"/>. | ||
/// </summary> | ||
/// <param name="self">The <see cref="BindableObject"/> on which the <paramref name="appThemeResource"/> will be applied to the provided property in <paramref name="targetProperty"/>.</param> | ||
/// <param name="targetProperty">The <see cref="BindableProperty"/> on which to set the <paramref name="appThemeResource"/>.</param> | ||
/// <param name="appThemeResource">The <see cref="AppThemeObject"/> to apply to <paramref name="targetProperty"/>.</param> | ||
public static void SetAppTheme<T>(this BindableObject self, BindableProperty targetProperty, AppThemeObject<T> appThemeResource) => | ||
self.SetBinding(targetProperty, appThemeResource.GetBinding()); | ||
} |
Oops, something went wrong.