[Proposal] Add `.Text()` and `.TextColor()` Extension Methods
brminnick opened this issue · 4 comments
Add .Text()
+ .TextColor()
Extension Methods
- Proposed
- Prototype
- Implementation
- iOS Support
- Android Support
- macOS Support
- Windows Support
- Unit Tests
- Sample
- Documentation
Link to Discussion
Summary
This Proposal adds extension methods for IText.Text
and ITextStyle.TextColor
.
Motivation
Currently, the only way to set Text
and TextColor
properties on an element that implements IText
is to set the properties directly. Here is an example from CommunityToolkit.Maui.Markup.Sample.Pages.SettingsPage
:
new Label { Text = "Top Stories To Fetch", TextColor = ColorConstants.PrimaryTextColor }
.LayoutFlags(AbsoluteLayoutFlags.XProportional | AbsoluteLayoutFlags.WidthProportional)
.LayoutBounds(0, 0, 1, 40)
.TextCenterHorizontal()
.TextBottom(),
This Proposal will allow devs to use fluent extension methods to set both Text
and TextColor
.
Detailed Design
/// <summary>
/// Sets <see cref="ITextStyle.TextColor"/> Property
/// </summary>
/// <typeparam name="TBindable"><see cref="BindableObject"/></typeparam>
/// <param name="bindable">Element</param>
/// <param name="textColor">Text <see cref="Color"/></param>
/// <returns></returns>
public static TBindable TextColor<TBindable>(this TBindable bindable, Color? textColor) where TBindable : BindableObject, ITextStyle
{
bindable.SetValue(TextElement.TextColorProperty, textColor);
return bindable;
}
/// <summary>
/// Sets <see cref="IText.Text"/> Property
/// </summary>
/// <typeparam name="TBindable"><see cref="BindableObject"/></typeparam>
/// <param name="bindable">Element</param>
/// <param name="text"></param>
/// <returns></returns>
public static TBindable Text<TBindable>(this TBindable bindable, string? text) where TBindable : BindableObject, IText
{
bindable.SetValue(ITextElement.TextProperty, text);
return bindable;
}
/// <summary>
/// Sets <see cref="IText.Text"/> Property
/// </summary>
/// <typeparam name="TBindable"><see cref="BindableObject"/></typeparam>
/// <param name="bindable">Element</param>
/// <param name="text"></param>
/// <param name="textColor">Text <see cref="Color"/></param>
public static TBindable Text<TBindable>(this TBindable bindable, string? text, Color? textColor) where TBindable : BindableObject, IText
{
return bindable.Text(text).TextColor(textColor);
}
Usage Syntax
C# Usage
Content = new VerticalStackLayout
{
Children =
{
new Label()
.Text("Hello World", Colors.Blue),
new Label()
.TextColor(Colors.Green)
.Bind(Label.TextProperty, nameof(ViewModel.LabelText);
}
}
Drawbacks
Currently, TextElement
does not have a TextProperty
static property, i.e. TextElelement.TextProperty
does not yet exist.
We can workaround this by doing the following. This is a proven and common workaround in Xamarin.CommunityToolkit.Markup.
using ITextElement = Microsoft.Maui.Controls.Label; // ToDo Remove this once TextElement.TextProperty is added
public static class ElementExtensions
{
public static TBindable Text<TBindable>(this TBindable bindable, string? text) where TBindable : BindableObject, IText
{
bindable.SetValue(ITextElement.TextProperty, text);
return bindable;
}
}
Alternatives
Currently, the only alternative is to initialize the properties like so:
new Label { Text = "Top Stories To Fetch", TextColor = ColorConstants.PrimaryTextColor }
Unresolved Questions
Should we support null
inputs? The default value of Color
and Text
is null
and I imagine the number of use cases where developer would use this .Text()
to revert the values of Color
and Text
back to null
may be minimal.
gets my vote!
I vote to approve it!
I vote to approve ✅
Reopening Proposal.
Only Proposals moved to the Closed
Project Column and Completed
Project Column can be closed.