Skip to content

Various components: Let UserAttributes override generated ARIA attributes - #13642

Merged
danielchalmers merged 1 commit into
MudBlazor:devfrom
danielchalmers:mask-input-aria-user-attributes-override
Aug 18, 2026
Merged

Various components: Let UserAttributes override generated ARIA attributes#13642
danielchalmers merged 1 commit into
MudBlazor:devfrom
danielchalmers:mask-input-aria-user-attributes-override

Conversation

@danielchalmers

@danielchalmers danielchalmers commented Aug 18, 2026

Copy link
Copy Markdown
Member

Follows #13613, which moved aria-describedby, aria-invalid and aria-required above the @attributes="UserAttributes" splat on MudInput so a caller can override them. Blazor resolves duplicate attributes last-write-wins, so a literal written after the splat silently discards the caller's value, and one written before it acts as a fallback.

Deliberately unchanged

  • required stays below the splat everywhere. It is native browser behaviour rather than an ARIA annotation, and it drives MudFormComponent validation and the label asterisk, not just the DOM. Keeping the pair separable is the point of the original change.
  • MudRangeInput's aria-label and id stay below. Their values differ per input ("Start"/"End", -start/-end), and one dictionary cannot express two values for one key — a caller value would be duplicated onto both halves, breaking the distinct accessible names and producing a duplicate DOM id. StartInputAriaLabel/EndInputAriaLabel remain the supported override path.
  • MudFileUpload's id stays below. The splat sits inside a @for, so a single caller id would land on every active input and break mudFileUpload.openFilePicker, which resolves by getElementById and no-ops silently on a miss.

Behaviour

before after
no caller-supplied value computed value rendered unchanged — the literal is still emitted, just earlier
caller supplies aria-required / aria-invalid / aria-describedby silently discarded caller's value wins
required attribute from Required unchanged

Checklist:

  • I've read the contribution guidelines
  • My code follows the style of this project
  • I've added or updated relevant unit tests

…tes override generated ARIA attributes

Follows PR MudBlazor#13613, which moved `aria-describedby`, `aria-invalid` and
`aria-required` above the `@attributes="UserAttributes"` splat on MudInput so a
caller can override them. Blazor resolves duplicate attributes last-write-wins,
so a literal after the splat silently discards the caller's value and one before
it acts as a fallback.

The same four components still write these annotations after their splat.

MudMask is the reason this matters most. MudTextField renders a MudMask instead
of a MudInput whenever `Mask` is set, and splats the same UserAttributes down, so
after MudBlazor#13613:

    <MudTextField aria-required="true" />              honours the caller
    <MudTextField Mask="@Mask" aria-required="true" /> silently discards it

One public component, two answers, keyed on an unrelated parameter.

MudRadioGroup has the strongest standalone case: a `<div role="radiogroup">`
cannot carry the native `required` attribute, and the child radios do not emit it
either, so `aria-required` is the widget's only required-ness signal. An app that
validates server-side currently has no way to state it.

Both MudRangeInput inputs move together. They share one UserAttributes
dictionary, so moving only one would leave the two halves of a single field
announcing different required-ness — worse than the current uniform discard.

Deliberately unchanged:

- `required` stays below the splat everywhere. It is native browser behaviour
  rather than an annotation, and it drives validation, not just the DOM.
- MudRangeInput's `aria-label` and `id` stay below. Their values differ per input
  ("Start"/"End", `-start`/`-end`), and one dictionary cannot express two values
  for one key. `StartInputAriaLabel`/`EndInputAriaLabel` remain the supported
  override path.
- MudFileUpload's `id` stays below. The splat sits inside a `@for`, so a single
  caller id would land on every active input and break the file-picker interop.

This is an ordering change only. No new code, nothing allocated per render, and
default rendering is byte-identical.
@danielchalmers danielchalmers changed the title MudMask, MudRangeInput, MudRadioGroup, MudFileUpload: Let UserAttributes override generated ARIA attributes Various components: Let UserAttributes override generated ARIA attributes Aug 18, 2026
@danielchalmers
danielchalmers merged commit 947d408 into MudBlazor:dev Aug 18, 2026
11 checks passed
@danielchalmers danielchalmers added the bug Unexpected behavior or functionality not working as intended label Aug 18, 2026
This was referenced Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Unexpected behavior or functionality not working as intended

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant