Skip to content

Make ShrinkLabel configurable on MudBlazor field components #177

Closed

Description

@phmatray

Problem / motivation

Reported by @bdsoko in #146 after .WithVariant(...) shipped in v3.1.0:

While using, I set the variant to 'Text' and noticed that the label does not float. I believe it's because ShrinkLabel property is hardcoded to 'true'. Any chance this can be customizable as well.

Confirmed. ShrinkLabel="true" is hardcoded at 12 sites across FormCraft.ForMudBlazor, with no way for a consumer to override it:

File Line
Fields/TextField/MudBlazorTextFieldComponent.razor 25
Fields/NumericField/MudBlazorNumericFieldComponent.razor 22
Fields/NumericField/MudBlazorNullableNumericFieldComponent.razor 22
Fields/SelectField/MudBlazorSelectFieldComponent.razor 18
Fields/SelectField/MudBlazorMultiSelectFieldComponent.razor 18
Fields/DateTimeField/MudBlazorDateTimeFieldComponent.razor 16
Fields/DateTimeField/MudBlazorDateOnlyFieldComponent.razor 15
Fields/DateTimeField/MudBlazorTimeOnlyFieldComponent.razor 15
Fields/AutocompleteField/MudBlazorAutocompleteFieldComponent.razor 18
Fields/LookupField/MudBlazorLookupFieldComponent.razor 16
Features/CustomFields/MudBlazorColorPickerComponent.razor 15
Features/CollectionField/CollectionFieldComponent.razor.cs (AddCommonFieldAttributes) 271

ShrinkLabel="true" permanently pins the label above the input. That reads correctly for Variant.Outlined (the default, where the label sits in the notch of the border) and acceptably for Variant.Filled. For Variant.Text it removes the one affordance the variant relies on: the label is meant to sit inside the input as a placeholder and float up on focus/value. The result is a floating label over an input that has no border to anchor it — visually orphaned, and exactly what @bdsoko is seeing.

This makes the v3.1.0 Variant feature only two-thirds useful: Variant.Text is selectable but not presentable.

Proposed solution

Make ShrinkLabel configurable through the same channel Variant already uses — a field-level builder extension plus a form-level default, resolved through AdditionalAttributes. The v3.1.0 work built exactly this plumbing (MudBlazorFieldComponentBase.EffectiveVariant, FormCraftCascadingValues.DefaultVariant, FormCraftComponent.DefaultVariant); this rides it rather than inventing a second mechanism.

New public surface, all in FormCraft.ForMudBlazor:

// Field-level (FieldBuilderExtensions) — sibling of WithVariant
.AddField(x => x.Name, field => field
    .WithLabel("Name")
    .WithVariant(Variant.Text)
    .WithShrinkLabel(false))          // label floats on focus/value

// Form-level (FormCraftComponent<TModel>) — sibling of DefaultVariant
<FormCraftComponent TModel="MyModel"
                    Model="@model"
                    Configuration="@config"
                    DefaultVariant="Variant.Text"
                    DefaultShrinkLabel="false" />

Precedence mirrors Variant exactly: field-level wins over form-level, form-level over the built-in default, and the built-in default stays true so no existing form changes appearance.

Alternatives considered

  • Derive ShrinkLabel from the variant (ShrinkLabel = variant != Variant.Text) — zero new API and it fixes the reported symptom with no consumer action. Rejected: it is unoverridable magic, it silently changes rendering for anyone already on Variant.Text who wanted the pinned label, and it couples two independent MudBlazor properties forever.
  • Form-level parameter only, no field-level extension — smaller surface, but breaks the symmetry with Variant/MinDate/MaxDate and can't express a single field that differs from the form.
  • Expose the raw ShrinkLabel attribute via .WithAttribute("ShrinkLabel", false) — already technically possible for renderers reading AdditionalAttributes, but it is undiscoverable, untyped, and today no component reads that key.

Area

FormCraft.ForMudBlazor — field rendering


Related: #146 (the Variant request this follows up on, shipped in v3.1.0), #148 (render-pipeline consolidation that made this well-contained)

🧠 Brainstorm

Problem / context

ShrinkLabel is a MudBlazor MudBaseInput property. When true, the label is permanently rendered in its shrunk position (above the input); when false, MudBlazor animates it from inside the input to above it on focus or when a value is present.

FormCraft hardcodes it to true in 12 places. That choice predates configurable variants — when every field was Variant.Outlined, a pinned label was the only correct rendering, so the constant was invisible. v3.1.0 (#146) let consumers pick Variant.Text and Variant.Filled, and the constant became a visible defect: Variant.Text renders a floating label with no border to anchor it.

Prior art in this very repo is decisive. The v3.1.0 change already established the mechanism for "a MudBlazor presentation property, configurable per field with a form-level default":

  • FormCraftCascadingValues.DefaultVariant — the cascading-value name (FormCraft.ForMudBlazor/Fields/MudBlazorFieldComponentBase.cs:17)
  • MudBlazorFieldComponentBase<TModel,TValue>.FormDefaultVariant — [CascadingParameter] (:34)
  • MudBlazorFieldComponentBase.EffectiveVariant — the three-tier resolver (:42)
  • FormCraftComponent<TModel>.DefaultVariant — [Parameter], defaults Variant.Outlined (Features/FormContainer/FormCraftComponent.razor.cs:53)
  • The <CascadingValue TValue="Variant?" …> wrapper (Features/FormContainer/FormCraftComponent.razor:12)
  • FieldBuilderExtensions.WithVariant — one line, builder.WithAttribute("Variant", variant) (Extensions/FieldBuilderExtensions.cs:133)
  • CollectionFieldComponent.GetItemFieldVariant — the RenderTreeBuilder path's own resolver (Features/CollectionField/CollectionFieldComponent.razor.cs:278)

So the question isn't how to plumb this. It's what shape the fix should take.

Approaches

A. Mirror Variant exactly — .WithShrinkLabel(bool) + DefaultShrinkLabel.
Add EffectiveShrinkLabel to MudBlazorFieldComponentBase, a second cascading value, a form parameter, and a one-line builder extension; swap the 12 constants for @EffectiveShrinkLabel.
Pros: the API a FormCraft user already knows — they learned it three weeks ago from WithVariant; explicit, typed, discoverable via IntelliSense; per-field granularity; default true means byte-identical rendering for every existing form. The 12 call sites are already the exact sites that were touched for Variant, so the diff is mechanical and reviewable.
Cons: ~6 files of plumbing for one boolean, and the consumer must set two things (DefaultVariant="Variant.Text" and DefaultShrinkLabel="false") to get the look they want.

B. Derive it from the variant — ShrinkLabel = EffectiveVariant != Variant.Text.
One expression on the base class, zero public API.
Pros: smallest possible change; @bdsoko's case is fixed with no code on their side; arguably "the right default" for all three variants.
Cons: unoverridable — the next issue is "I want Variant.Text with a pinned label" and there's no answer; it silently changes rendering for anyone who already adopted Variant.Text in v3.1.0; it welds two independent MudBlazor properties together, so MudBlazor's own semantics and FormCraft's diverge. It also answers a question nobody asked: the request is "can this be customizable as well", not "please guess for me".

C. Form-level parameter only.
DefaultShrinkLabel on FormCraftComponent, no field extension.
Pros: half the plumbing; covers the reported case, which is form-wide.
Cons: asymmetric with Variant for no principled reason, and unable to express a mixed form — which is precisely the scenario .WithVariant was added to support (a Variant.Text search box among outlined fields).

Recommendation

A, with true as the resolved default.

The deciding argument is consistency of the mental model. A consumer who has learned "field-level .WithX(...) beats form-level DefaultX, and the built-in default preserves v3.0 rendering" should be able to apply that rule to any MudBlazor presentation property FormCraft exposes. B and C each break that rule in a different direction — B by making the property non-configurable after having just made its sibling configurable, C by dropping a tier. A costs about 6 small files and buys a surface that needs no explaining.

B's appeal — "it should just look right" — is better served by documentation than by hidden coupling: the README bullet and the XML docs should say plainly that Variant.Text usually wants ShrinkLabel="false", and show the two-line snippet. That teaches the pairing without welding it.

Worth folding in while here: Fields/LovField/MudBlazorLovFieldComponent.razor honors EffectiveVariant (line 17) but is the only one of the 13 variant-aware components that never sets ShrinkLabel at all — so it silently renders with MudBlazor's false today while its 12 siblings pin the label. That asymmetry is a latent bug regardless of this feature; see Task 5, which flags it as a deliberate decision rather than folding it in silently.

📋 Spec

Goal

Let consumers control MudBlazor's ShrinkLabel per field and per form, with the current behavior (true) as the resolved default, so Variant.Text can render with a properly floating label.

Scope

  • A field-level .WithShrinkLabel(bool shrinkLabel = true) extension in FormCraft.ForMudBlazor.
  • A form-level DefaultShrinkLabel parameter on FormCraftComponent<TModel>, cascaded.
  • EffectiveShrinkLabel on MudBlazorFieldComponentBase<TModel, TValue> resolving the three tiers.
  • All 12 hardcoded sites switched to the resolved value.
  • The RenderTreeBuilder path in CollectionFieldComponent (item fields inside collections).
  • XML docs on every new member; a README feature bullet documenting the Variant.Text pairing.

Non-goals

  • Changing the default rendering of any existing form. ShrinkLabel resolves to true when unconfigured; the two existing parity assertions (RenderPipelineParityTests.cs:237 and :257, both ShrinkLabel.ShouldBeTrue()) stay green untouched and serve as the back-compat guard.
  • Auto-deriving ShrinkLabel from Variant (rejected approach B).
  • Exposing other MudBaseInput styling properties (Margin, Immediate, Typo) — same pattern would apply, but each deserves its own issue and its own default-preservation argument.
  • The two file-upload components (MudBlazorFileUploadFieldComponent, MudBlazorMultipleFileUploadComponent): they render MudButton/MudFileUpload, which have no ShrinkLabel.

Public surface

namespace FormCraft.ForMudBlazor;

public static class FormCraftCascadingValues
{
    public const string DefaultVariant = "FormCraftDefaultVariant";
    // new
    public const string DefaultShrinkLabel = "FormCraftDefaultShrinkLabel";
}

public abstract class MudBlazorFieldComponentBase<TModel, TValue> : FieldComponentBase<TModel, TValue>
{
    [CascadingParameter(Name = FormCraftCascadingValues.DefaultVariant)]
    public Variant? FormDefaultVariant { get; set; }

    // new
    [CascadingParameter(Name = FormCraftCascadingValues.DefaultShrinkLabel)]
    public bool? FormDefaultShrinkLabel { get; set; }

    protected Variant EffectiveVariant =>
        GetAttribute<Variant?>("Variant") ?? FormDefaultVariant ?? Variant.Outlined;

    // new
    protected bool EffectiveShrinkLabel =>
        GetAttribute<bool?>("ShrinkLabel") ?? FormDefaultShrinkLabel ?? true;
}

public static class FieldBuilderExtensions
{
    // new
    public static FieldBuilder<TModel, TValue> WithShrinkLabel<TModel, TValue>(
        this FieldBuilder<TModel, TValue> builder,
        bool shrinkLabel = true)
        where TModel : new()
        => builder.WithAttribute("ShrinkLabel", shrinkLabel);
}

public partial class FormCraftComponent<TModel>
{
    [Parameter] public Variant DefaultVariant { get; set; } = Variant.Outlined;
    // new
    [Parameter] public bool DefaultShrinkLabel { get; set; } = true;
}

Resolution

flowchart TD
    A["MudBlazor input needs ShrinkLabel"] --> B{"field's AdditionalAttributes<br/>contains 'ShrinkLabel'?<br/><i>.WithShrinkLabel(...)</i>"}
    B -->|yes| C["use that value<br/><b>field-level wins</b>"]
    B -->|no| D{"cascaded FormDefaultShrinkLabel<br/>has a value?<br/><i>DefaultShrinkLabel param</i>"}
    D -->|yes| E["use the form-level default"]
    D -->|no| F["use <b>true</b><br/>preserves v3.0/v3.1 rendering"]
Loading

GetAttribute<bool?>("ShrinkLabel") unboxes a stored bool into bool? correctly — the same mechanism GetAttribute<Variant?>("Variant") already relies on in production (FieldComponentBase.GetAttribute<T> at FormCraft/Components/FieldComponentBase.cs:163 uses value is T typedValue, and a boxed value type satisfies an is T? check).

Files

Modify (core plumbing)

  • FormCraft.ForMudBlazor/Fields/MudBlazorFieldComponentBase.cs — cascading-value name, [CascadingParameter], EffectiveShrinkLabel
  • FormCraft.ForMudBlazor/Extensions/FieldBuilderExtensions.cs — WithShrinkLabel, placed next to WithVariant (currently line 133)
  • FormCraft.ForMudBlazor/Features/FormContainer/FormCraftComponent.razor.cs — DefaultShrinkLabel parameter
  • FormCraft.ForMudBlazor/Features/FormContainer/FormCraftComponent.razor — nested <CascadingValue TValue="bool?" …> around the existing Variant cascade

Modify (the 12 hardcoded sites) — ShrinkLabel="true" → ShrinkLabel="@EffectiveShrinkLabel" in the 11 .razor files listed in Problem / motivation, and builder.AddAttribute(startIndex, "ShrinkLabel", true) → the resolved value in CollectionFieldComponent.razor.cs:271, via a GetItemFieldShrinkLabel(field) helper mirroring GetItemFieldVariant (:278).

Create (tests)

  • FormCraft.ForMudBlazor.UnitTests/Fields/ShrinkLabelConfigurationTests.cs — modeled on VariantConfigurationTests.cs, reusing its RenderForm + MudPopoverProvider helper for picker components

Validation rules

  • Unconfigured field, unconfigured form → ShrinkLabel == true (every component type).
  • .WithShrinkLabel(false) → false on that field only; siblings stay true.
  • DefaultShrinkLabel="false" → false on all fields lacking their own setting.
  • Field-level beats form-level in both directions (.WithShrinkLabel(true) on a DefaultShrinkLabel="false" form, and vice versa).
  • Collection item fields honor both tiers through the RenderTreeBuilder path.

Edge cases

  • .WithShrinkLabel() with no argument — defaults to true, matching AsPassword(enableVisibilityToggle: true)'s convention in the same file.
  • Non-bool value under the "ShrinkLabel" key (a consumer having used .WithAttribute("ShrinkLabel", "true")) — value is bool? fails, so it falls through to the form default. Silent, and correct: no throw on a presentation attribute.
  • A consumer already calling .WithAttribute("ShrinkLabel", false) — starts being honored by this change. That is the intended fix, not a regression, but it is a behavior change for anyone who wrote that line speculatively; worth a release-note line.
  • Variant.Text + ShrinkLabel="true" — stays reachable, and remains the default. Anyone who adopted Variant.Text in v3.1.0 sees no change unless they opt in.
  • LOV field — see Task 5; it is the one component whose current ShrinkLabel is effectively false, so aligning it is a visual change, not a no-op.

Assumptions

  • No issue form template exists in this repo (.github/ISSUE_TEMPLATE/ is absent — .github/ holds only banner.png and 4 workflows), so the fields above follow the conventional feature-request shape rather than a live YAML form.
  • Target release is v3.1.x / v3.2.0 (additive, no breaking change). Latest tag is v3.1.0; base branch is dev.
  • The MudBlazor version in use exposes ShrinkLabel on every component touched here (MudBaseInput descendants + the pickers), which the 12 existing hardcoded usages already prove.

🛠️ Implementation plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: make MudBlazor's ShrinkLabel configurable per field and per form, resolving to true when unset, so Variant.Text can render a floating label (follow-up to #146).

Architecture: FormCraft core stays UI-framework-agnostic — every change in this plan lands in FormCraft.ForMudBlazor or its test project; nothing in FormCraft/ is touched. Configuration flows one way: FieldBuilder → IFieldConfiguration.AdditionalAttributes → renderer component. The form-level default travels by cascading value, never by service or static state.

Tech stack: .NET 8 / 9 / 10 multi-target, Blazor, MudBlazor, xUnit + bUnit + Shouldly (MudBlazorTestBase).

Global constraints:

  • Base branch dev; commit as Philippe Matray <phmatray@gmail.com>; conventional commits (feat:, test:, docs:).
  • Default rendering must not change. RenderPipelineParityTests.cs:237 and :257 assert ShrinkLabel.ShouldBeTrue() — they must stay green unmodified. Editing them to accommodate the change means the change is wrong.
  • Additive only: no existing public member is renamed, removed, or has its default altered.
  • Mirror Variant naming exactly (WithShrinkLabel / DefaultShrinkLabel / FormDefaultShrinkLabel / EffectiveShrinkLabel) — a reader who knows one must be able to predict the other.
  • Suite: dotnet test FormCraft.ForMudBlazor.UnitTests/FormCraft.ForMudBlazor.UnitTests.csproj; single class via --filter "FullyQualifiedName~ShrinkLabelConfigurationTests".
  • Full dotnet build + dotnet test green before the final commit.

Task 1: Field-level .WithShrinkLabel(...), honored by the text field

Proves the whole chain end-to-end on one component before rolling out.

Files: modify FormCraft.ForMudBlazor/Fields/MudBlazorFieldComponentBase.cs, FormCraft.ForMudBlazor/Extensions/FieldBuilderExtensions.cs, FormCraft.ForMudBlazor/Fields/TextField/MudBlazorTextFieldComponent.razor (line 25); create FormCraft.ForMudBlazor.UnitTests/Fields/ShrinkLabelConfigurationTests.cs.

Interfaces: MudBlazorFieldComponentBase<TModel,TValue>.EffectiveShrinkLabel => GetAttribute<bool?>("ShrinkLabel") ?? FormDefaultShrinkLabel ?? true; FieldBuilderExtensions.WithShrinkLabel<TModel,TValue>(this FieldBuilder<TModel,TValue>, bool shrinkLabel = true).

  • Step 1: Write the failing tests in ShrinkLabelConfigurationTests.cs (copy VariantConfigurationTests.cs's class shape and its RenderForm helper): TextField_Should_Default_To_ShrinkLabel_True and WithShrinkLabel_False_Should_Apply_To_TextField, asserting component.FindComponent<MudTextField<string>>().Instance.ShrinkLabel.
  • Step 2: Run dotnet test FormCraft.ForMudBlazor.UnitTests/FormCraft.ForMudBlazor.UnitTests.csproj --filter "FullyQualifiedName~ShrinkLabelConfigurationTests" → FAIL (WithShrinkLabel does not exist).
  • Step 3: Add FormCraftCascadingValues.DefaultShrinkLabel = "FormCraftDefaultShrinkLabel", the [CascadingParameter(Name = …)] public bool? FormDefaultShrinkLabel, and EffectiveShrinkLabel to MudBlazorFieldComponentBase.cs — XML docs mirroring the Variant members directly above.
  • Step 4: Add WithShrinkLabel to FieldBuilderExtensions.cs immediately after WithVariant (line 139), with XML docs whose <example> shows the Variant.Text pairing.
  • Step 5: In MudBlazorTextFieldComponent.razor, change ShrinkLabel="true" (line 25) to ShrinkLabel="@EffectiveShrinkLabel".
  • Step 6: Re-run the filtered suite → PASS.
  • Step 7: Run the full FormCraft.ForMudBlazor.UnitTests suite → PASS, confirming RenderPipelineParityTests is still green with no edits.
  • Step 8: Commit: feat(mudblazor): add .WithShrinkLabel field extension honored by text field.

Task 2: Form-level DefaultShrinkLabel + precedence

Files: modify FormCraft.ForMudBlazor/Features/FormContainer/FormCraftComponent.razor.cs (near DefaultVariant, line 53), FormCraft.ForMudBlazor/Features/FormContainer/FormCraftComponent.razor (the cascade at line 12); modify ShrinkLabelConfigurationTests.cs.

Interfaces: FormCraftComponent<TModel>.DefaultShrinkLabel — [Parameter] public bool, default true; cascaded as TValue="bool?" under FormCraftCascadingValues.DefaultShrinkLabel.

  • Step 1: Write failing tests: DefaultShrinkLabel_False_Should_Apply_To_Fields_Without_Explicit_Setting, FieldLevel_WithShrinkLabel_Should_Override_FormLevel_DefaultShrinkLabel (field true over form false, and field false over form true).
  • Step 2: Run the filtered suite → FAIL (no DefaultShrinkLabel parameter).
  • Step 3: Add the DefaultShrinkLabel [Parameter] to FormCraftComponent.razor.cs with XML docs pointing at .WithShrinkLabel(...).
  • Step 4: In FormCraftComponent.razor, nest a <CascadingValue TValue="bool?" Name="@FormCraftCascadingValues.DefaultShrinkLabel" Value="@DefaultShrinkLabel"> around the existing Variant cascade — and add the matching closing tag at the end of the markup.
  • Step 5: Re-run the filtered suite → PASS.
  • Step 6: Commit: feat(mudblazor): add form-level DefaultShrinkLabel parameter.

Task 3: Roll out to the remaining 10 .razor components

Files: modify Fields/NumericField/MudBlazorNumericFieldComponent.razor (22), Fields/NumericField/MudBlazorNullableNumericFieldComponent.razor (22), Fields/SelectField/MudBlazorSelectFieldComponent.razor (18), Fields/SelectField/MudBlazorMultiSelectFieldComponent.razor (18), Fields/DateTimeField/MudBlazorDateTimeFieldComponent.razor (16), Fields/DateTimeField/MudBlazorDateOnlyFieldComponent.razor (15), Fields/DateTimeField/MudBlazorTimeOnlyFieldComponent.razor (15), Fields/AutocompleteField/MudBlazorAutocompleteFieldComponent.razor (18), Fields/LookupField/MudBlazorLookupFieldComponent.razor (16), Features/CustomFields/MudBlazorColorPickerComponent.razor (15); modify ShrinkLabelConfigurationTests.cs.

Interfaces: none new — each site swaps the literal for @EffectiveShrinkLabel.

  • Step 1: Write failing per-component tests covering numeric, nullable-numeric, select, multi-select, date-time, date-only, time-only, autocomplete, lookup and color-picker — each asserting default true and .WithShrinkLabel(false) → false. Use the MudPopoverProvider render helper for the picker-backed ones.
  • Step 2: Run the filtered suite → FAIL on every component not yet converted.
  • Step 3: Replace ShrinkLabel="true" with ShrinkLabel="@EffectiveShrinkLabel" in all 10 files.
  • Step 4: Verify none were missed: grep -rn 'ShrinkLabel="true"' FormCraft.ForMudBlazor/ returns nothing.
  • Step 5: Re-run the filtered suite → PASS, then the full suite → PASS.
  • Step 6: Commit: feat(mudblazor): honor configurable ShrinkLabel in all input components.

Task 4: Collection item fields (RenderTreeBuilder path)

The collection renderer builds its inputs imperatively and resolves Variant through its own helper; ShrinkLabel needs the parallel treatment.

Files: modify FormCraft.ForMudBlazor/Features/CollectionField/CollectionFieldComponent.razor.cs (AddCommonFieldAttributes line 271; add helper next to GetItemFieldVariant line 278); modify ShrinkLabelConfigurationTests.cs.

Interfaces: private bool GetItemFieldShrinkLabel(IFieldConfiguration<TItem, object> field) — reads field.AdditionalAttributes["ShrinkLabel"] as bool, else FormDefaultShrinkLabel ?? true; plus a [CascadingParameter(Name = FormCraftCascadingValues.DefaultShrinkLabel)] public bool? FormDefaultShrinkLabel alongside the existing FormDefaultVariant (line 40).

  • Step 1: Write failing tests for a collection field: item inputs default to ShrinkLabel == true, honor a per-item-field .WithShrinkLabel(false), and honor the form-level DefaultShrinkLabel="false".
  • Step 2: Run the filtered suite → FAIL.
  • Step 3: Add the FormDefaultShrinkLabel cascading parameter and GetItemFieldShrinkLabel, mirroring GetItemFieldVariant's structure exactly; change line 271 to pass the resolved value.
  • Step 4: Re-run the filtered suite → PASS, then the full suite → PASS.
  • Step 5: Commit: feat(mudblazor): honor ShrinkLabel for collection item fields.

Task 5: Decide the LOV field's ShrinkLabel (flagged — behavior change)

Fields/LovField/MudBlazorLovFieldComponent.razor honors EffectiveVariant (line 17) but is the only variant-aware component that never sets ShrinkLabel, so it renders with MudBlazor's false while its 12 siblings pin the label. Adding ShrinkLabel="@EffectiveShrinkLabel" aligns it — and changes how LOV fields look today (label starts pinned instead of floating).

  • Step 1: Confirm the asymmetry: grep -n 'ShrinkLabel\|EffectiveVariant' FormCraft.ForMudBlazor/Fields/LovField/MudBlazorLovFieldComponent.razor.
  • Step 2: Take the call and record it in the PR description — recommended: align it (the input is ReadOnly="true" with a value-or-placeholder always shown, so a pinned label is the right rendering, and consistency across the field family is the point of this issue). If instead LOV is left alone, say so explicitly and add a code comment so the next reader doesn't "fix" it silently.
  • Step 3: If aligning: write a failing test (LovField_Should_Honor_ShrinkLabel) asserting default true and .WithShrinkLabel(false) → false; run → FAIL.
  • Step 4: If aligning: add ShrinkLabel="@EffectiveShrinkLabel" to the MudTextField at line 9-23; re-run → PASS; full suite → PASS.
  • Step 5: Commit: fix(mudblazor): align LOV field ShrinkLabel with the other input components (or, if not aligning, docs(mudblazor): note why the LOV field leaves ShrinkLabel unset).

Task 6: Documentation

Files: modify README.md (the v3.1.0 feature bullet at line 65).

  • Step 1: Add a feature bullet next to the existing Configurable MudBlazor Variant one, documenting .WithShrinkLabel(false) and DefaultShrinkLabel, and stating plainly that Variant.Text usually wants ShrinkLabel="false" so the label floats — with the two-line snippet.
  • Step 2: Re-read the XML docs added in Tasks 1-2 and confirm each <example> compiles as written (correct namespaces, real member names).
  • Step 3: Run the full solution build and test suite one final time: dotnet build then dotnet test → both green.
  • Step 4: Commit: docs: document configurable ShrinkLabel and the Variant.Text pairing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    priority:mediumFix when possiblestatus:triagedClassified and ready for analysis/worktype:featureNew feature or enhancement request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions