Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[dev-v5] Add FluentTextArea component #3341

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
ο»Ώ<FluentStack Orientation="Orientation.Vertical">
<FluentStack Orientation="Orientation.Horizontal">
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

<FluentSelect Label="Appareance"
Items="@(@Enum.GetValues(typeof(TextAreaAppearance)).Cast<TextAreaAppearance>())"
AClerbois marked this conversation as resolved.
Show resolved Hide resolved
@bind-Value="@appearance" />

<FluentSelect Label="Size"
Items="@(@Enum.GetValues(typeof(TextAreaSize)).Cast<TextAreaSize>())"
@bind-Value="@size" />

<FluentCheckbox Label="Display shadow" @bind-Value="displayShadown"></FluentCheckbox>
</FluentStack>

<FluentTextArea Appearance="@appearance"
Size="@size"
DisplayShadow="@displayShadown"
Label="@label"
dvoituron marked this conversation as resolved.
Show resolved Hide resolved
Placeholder="@label"
AClerbois marked this conversation as resolved.
Show resolved Hide resolved
@bind-Value="@value" />
</FluentStack>

<FluentLabel>Value = @value</FluentLabel>

@code
{
string value = "";
TextAreaAppearance appearance = TextAreaAppearance.Outline;
TextAreaSize size = TextAreaSize.Medium;
bool displayShadown = false;

string label => $"{appearance} {size} - Display shadow : {displayShadown}";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
ο»Ώ<FluentStack Orientation="Orientation.Vertical">
<FluentTextInput Appearance="@TextInputAppearance.Outline"
dvoituron marked this conversation as resolved.
Show resolved Hide resolved
Placeholder="Updated after 400ms"
@bind-Value="@value"
@bind-Value:after="@(() => Console.WriteLine($"TextInput updated to '{value}'.") )"
Immediate="true"
ImmediateDelay="400" />

<FluentLabel>Value = @value</FluentLabel>
</FluentStack>


@code
{
string value = "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
ο»Ώ<FluentStack Orientation="Orientation.Vertical">

<FluentSelect Label="Resize modes"
Items="@(@Enum.GetValues(typeof(TextAreaResize)).Cast<TextAreaResize>())"
@bind-Value="@resizeMode" />

<FluentTextArea Resize="@resizeMode"
Label="@resizeMode.ToString()"
AClerbois marked this conversation as resolved.
Show resolved Hide resolved
Placeholder="@resizeMode.ToString()"
@bind-Value="@value" />

</FluentStack>

@code
{
TextAreaResize resizeMode = TextAreaResize.None;
string value = "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
ο»Ώ<FluentStack HorizontalGap="20px">
<FluentTextArea Required="true" Label="Required" Placeholder="Required" @bind-Value="@Value" />
<FluentTextArea Disabled="true" Label="Disabled" Placeholder="Disabled" @bind-Value="@Value" />
<FluentTextArea ReadOnly="true" Label="ReadOnly" Placeholder="ReadOnly" @bind-Value="@Value" />
</FluentStack>

<FluentLabel>Value = @Value</FluentLabel>

@code
{
string Value = "";
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: TextArea
route: /TextArea
---

# TextArea

A **FluentTextArea** component enables a user to enter multiple lines of text.
The component is a wrapper around the FluentUI `TextArea` component.
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

## Appearance

The apparent style of a textarea can be changed by setting the `Appearance` property, but also by setting the `Size` property.
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

You can also add a label to the text input by setting the `Label` property and a placeholder by setting the `Placeholder` property.
The label will be automatically positioned above the text input, and the placeholder will be displayed inside the text input.

We recommand to use a spacing of 24px between text fields and other components.

{{ TextAreaAppearances }}

## Resize

The `Resize` property allows you to specify how the textarea can be resized by the user.

{{ TextAreaResizes }}

## Binding with ImmediateDelay

In some cases, you may want to bind the value of the text input to a property of a model
and update the model immediately after the user types a character. But you may also want to delay the update.
This can be achieved by setting the `Immediate` and the optional `ImmediateDelay` properties.
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

{{ TextAreaImmediate }}

## States

A text input can be in different states, such as `Disabled`, `ReadOnly`, and `Required`.

{{ TextAreaState }}

## Know restrictions

At this time, it's not possible to define the height and width of the component.

> This features are under investigation.
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

## API FluentTextArea

{{ API Type=FluentTextArea }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
title: Migrating FluentTextArea
route: /Migration/TextArea
hidden: true
---

### New properties

- `Autoresize`, sets the element’s height should be automatically changed based on the content.
AClerbois marked this conversation as resolved.
Show resolved Hide resolved
- `Block`, sets the element should be a block-level element.
AClerbois marked this conversation as resolved.
Show resolved Hide resolved
- `Resize`, sets the textarea resize mode. New value : `none`.
- `Size`, sets the textarea size. Values available : `small`, `medium`, `large`.

### Removed propertiesπŸ’₯

- `Cols`
- `Rows`
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ component changes (flagged with πŸ”ƒ) or Breaking Changes (flagged with πŸ’₯).

{{ INCLUDE MigrationFluentLabel }}

## FluentTextArea

{{ INCLUDE MigrationFluentTextArea }}

## FluentLayout and FluentMainLayout

{{ INCLUDE MigrationFluentLayout }}

## Migrate to v5 with help from GitHub Copilot chat

{{ INCLUDE CopilotInstructionsContent }}
{{ INCLUDE CopilotInstructionsContent }}
31 changes: 31 additions & 0 deletions src/Core/Components/TextArea/FluentTextArea.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
ο»Ώ@namespace Microsoft.FluentUI.AspNetCore.Components
@using Microsoft.FluentUI.AspNetCore.Components.Extensions
@inherits FluentInputImmediateBase<string?>

<FluentField InputComponent="@this" ForId="@Id" Class="@ClassValue" Style="@StyleValue">
<fluent-textarea @ref="@Element"
appearance="@Appearance.ToAttributeValue()"
autocomplete="@AutoComplete"
autofocus="@Autofocus"
auto-resize="@AutoResize"
aria-label="@AriaLabel"
disabled="@Disabled"
display-shadow="@DisplayShadow"
id="@Id"
maxlength="@MaxLength"
minlength="@MinLength"
name="@Name"
placeholder="@Placeholder"
readonly="@ReadOnly"
required="@Required"
size="@Size.ToAttributeValue()"
slot="input"
spellcheck="@Spellcheck"
resize="@Resize.ToAttributeValue()"
value="@CurrentValueAsString"
@onfocusout="@FocusOutHandlerAsync"
@onchange="@ChangeHandlerAsync"
@oninput="@InputHandlerAsync"
@attributes="AdditionalAttributes">
</fluent-textarea>
</FluentField>
135 changes: 135 additions & 0 deletions src/Core/Components/TextArea/FluentTextArea.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// ------------------------------------------------------------------------
// MIT License - Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Web;
using Microsoft.JSInterop;

namespace Microsoft.FluentUI.AspNetCore.Components;

/// <summary>
/// A textarea component that allows users to enter and edit a single line of text.
/// </summary>
public partial class FluentTextArea : FluentInputImmediateBase<string?>, IFluentComponentElementBase
{

/// <summary>
/// Initializes a new instance of the <see cref="FluentTextInput"/> class.
/// </summary>
public FluentTextArea()
{
// Default conditions for the message
MessageCondition = (field) =>
{
field.MessageIcon = FluentStatus.ErrorIcon;
field.Message = Localizer[Localization.LanguageResource.TextInput_RequiredMessage];

return FocusLost &&
(Required ?? false)
&& !(Disabled ?? false)
&& !ReadOnly
&& string.IsNullOrEmpty(CurrentValueAsString);
};
}

/// <inheritdoc cref="IFluentComponentElementBase.Element" />
[Parameter]
public ElementReference Element { get; set; }

/// <summary>
/// Gets or sets the visual appearance.
/// </summary>
[Parameter]
public TextAreaAppearance? Appearance { get; set; }

/// <summary>
/// Gets or sets the short hint displayed in the textarea before the user enters a value.
/// </summary>
[Parameter]
public string? Placeholder { get; set; }

/// <summary>
/// Gets or sets the maximum number of characters allowed in the textarea
/// </summary>
[Parameter]
public int? MaxLength { get; set; }

/// <summary>
/// Gets or sets the minimum number of characters allowed in the textarea
/// </summary>
[Parameter]
public int? MinLength { get; set; }

/// <summary>
/// Specifies whether a form or an textarea field should have autocomplete "on" or "off" or another value.
/// An Id value must be set to use this property.
/// </summary>
[Parameter]
public string? AutoComplete { get; set; }

/// <summary>
/// Whether the element’s height should be automatically changed based on the content.
/// </summary>
[Parameter]
public bool? AutoResize { get; set; }

/// <summary>
/// Whether the element displays a visual box shadow
/// </summary>
[Parameter]
public bool? DisplayShadow { get; set; }
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

/// <summary>
/// Gets or sets the size of the textarea. See <see cref="Components.TextAreaSize"/>
/// </summary>
[Parameter]
public TextAreaSize? Size { get; set; }

/// <summary>
/// Gets or sets the how resize the element. See <see cref="Components.TextAreaResize"/>
/// </summary>
[Parameter]
public TextAreaResize? Resize { get; set; }

/// <summary>
/// Gets or sets a value indicating whether spellcheck should be used.
/// </summary>
[Parameter]
public bool? Spellcheck { get; set; } // TODO: To verify if this is supported by the component
AClerbois marked this conversation as resolved.
Show resolved Hide resolved

/// <inheritdoc cref="ComponentBase.OnAfterRenderAsync(bool)" />
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeVoidAsync("Microsoft.FluentUI.Blazor.Utilities.Attributes.observeAttributeChange", Element, "value");
}
}

/// <summary>
/// Parses a string to create the <see cref="Microsoft.AspNetCore.Components.Forms.InputBase{TValue}.Value"/>.
/// </summary>
/// <param name="value">The string value to be parsed.</param>
/// <param name="result">The result to inject into the Value.</param>
/// <param name="validationErrorMessage">If the value could not be parsed, provides a validation error message.</param>
/// <returns>True if the value could be parsed; otherwise false.</returns>
protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out string? result, [NotNullWhen(false)] out string? validationErrorMessage)
{
result = value;
validationErrorMessage = null;
return true;
}

/// <summary>
/// Handler for the OnFocus event.
/// </summary>
/// <param name="e"></param>
/// <returns></returns>
protected virtual Task FocusOutHandlerAsync(FocusEventArgs e)
{
FocusLost = true;
return Task.CompletedTask;
}
}
31 changes: 31 additions & 0 deletions src/Core/Enums/TextAreaAppearance.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// ------------------------------------------------------------------------
// MIT License - Copyright (c) Microsoft Corporation. All rights reserved.
// ------------------------------------------------------------------------

using System.ComponentModel;

namespace Microsoft.FluentUI.AspNetCore.Components;

/// <summary>
/// The visual appearance of the <see cref="TextAreaAppearance" />.
/// </summary>
public enum TextAreaAppearance
{
/// <summary>
/// The default appearance.
/// </summary>
[Description("outline")]
Outline,

/// <summary>
/// The appearance where the borders are filled with a lighter color.
/// </summary>
[Description("filled-lighter")]
FilledLighter,

/// <summary>
/// The appearance where the borders are filled with a darker color.
/// </summary>
[Description("filled-darker")]
FilledDarker,
}
Loading