Implement nested and non-nested Label support for DisplayName#64821
Implement nested and non-nested Label support for DisplayName#64821ilonatommy merged 13 commits intodotnet:mainfrom
Label support for DisplayName#64821Conversation
There was a problem hiding this comment.
Pull request overview
This PR implements a new Label<TValue> component for Blazor Forms that renders an HTML <label> element with display name extraction from [Display] or [DisplayName] attributes. The component uses a wrapping pattern where input components are nested inside the label element, providing implicit HTML label-input association without requiring for/id attribute matching.
Key Changes
- Added
Label<TValue>component that implementsIComponentfor rendering accessible form labels - Component extracts display names using the existing
ExpressionMemberAccessor.GetDisplayNameutility - Comprehensive unit test suite covering various scenarios including attribute precedence, nested properties, and child content rendering
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Components/Web/src/Forms/Label.cs | Implements the new Label<TValue> component with parameter handling, display name extraction, and render tree building |
| src/Components/Web/test/Forms/LabelTest.cs | Adds comprehensive unit tests covering display name extraction, attributes, child content, and error scenarios |
| src/Components/Web/src/PublicAPI.Unshipped.txt | Documents the new public API surface for Label<TValue> component |
|
There are two ways to use
Is there a reason why we chose to implement only 1? Should we be detecting either of by checking to see if the RenderFragment has a value and using a form or the other appropriately? |
Yes, breaking changes: |
|
@ilonatommy thanks for the additional details. I don't think the breaking change concern is a valid one for a couple of reasons:
|
We don't allow explicit |
We should allow passing (note that even though we set NameAttributeValue after AdditionalAttributes, we do check AdditionalAttributes on InputBase to account for its value). |
Thank you, existing way of working is a good argument to not to throw, I am convinced. The non-nested pattern is a bit more tricky, can we discuss it separately and if we find a consensus, add it in a follow up? |
We have The |
Label for DisplayNameLabel support for DisplayName
javiercn
left a comment
There was a problem hiding this comment.
Looks great, only a few lose ends to track down, but other than that, it's good to go after we figure out that bit.
| return Convert.ToString(idAttributeValue, CultureInfo.InvariantCulture) ?? string.Empty; | ||
| } | ||
|
|
||
| return FieldIdGenerator.SanitizeHtmlId(NameAttributeValue); |
There was a problem hiding this comment.
Sorry that I am asking here in the merged PR, I am just trying to borrow some of the code.. But how will "id" be generated here if NameAttributeValue is only set when _shouldGenerateFieldNames is true (SSR)?
There was a problem hiding this comment.
That's true, id should be generated regardless of interactivity settings. This needs a follow-up. Thanks!
Add Label component for Blazor Forms
Add Label component that renders accessible labels with support for both nested and non-nested patterns
Description
This PR adds a new
Label<TValue>component that renders an HTML<label>element with the display name extracted from[Display]or[DisplayName]attributes, falling back to the property name.Details in #64791 (comment), #64791 (comment).
Usage
Nested pattern (wrapping):
Renders:
Non-nested pattern (for/id):
Renders:
Design
Supports both patterns for label-input association:
for/idmatchingforattribute that references the input's auto-generatedidattributeChanges
Label<TValue>: New component that conditionally rendersforattribute when noChildContentis providedInputBase<TValue>.IdAttributeValue: New protected property that auto-generatesidfrom the bound expression (follows same pattern asNameAttributeValue)InputText,InputNumber,InputCheckbox,InputDate,InputSelect,InputTextArea,InputHidden): Now renderidattribute usingIdAttributeValueforandidattributes inAdditionalAttributestake precedence over auto-generated valuesAPI Changes
Fixes #64791