Skip to content

fix: add missing mat-label to form fields and remove positive tabinde…#1609

Open
SIDHARTH20K4 wants to merge 4 commits into
Ride-The-Lightning:masterfrom
SIDHARTH20K4:fix/accessibility-form-labels
Open

fix: add missing mat-label to form fields and remove positive tabinde…#1609
SIDHARTH20K4 wants to merge 4 commits into
Ride-The-Lightning:masterfrom
SIDHARTH20K4:fix/accessibility-form-labels

Conversation

@SIDHARTH20K4

@SIDHARTH20K4 SIDHARTH20K4 commented Jun 9, 2026

Copy link
Copy Markdown

Fixes #1566
Several mat-form-field elements across the app were missing mat-label, which meant screen readers had no way to announce what each field was for. This makes the app harder to use for blind users.

Changes made:

-Added mat-label to all affected form fields with descriptive label text
-Removed positive tabindex values which cause unpredictable keyboard navigation

Testing:

-Verified the Settings page visually before and after (screenshots attached)
-Could not test invoice/send modals as they require a live Lightning node connection
-Remaining files were verified by code review

WhatsApp Image 2026-06-09 at 5 43 51 PM After WhatsApp Image 2026-06-09 at 5 47 57 PM Before

Copilot AI review requested due to automatic review settings June 9, 2026 12:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR improves Angular Material form UI consistency and accessibility by adding missing <mat-label> elements, wrapping some selects in <mat-form-field>, and removing explicit tabindex usage across several modals and components.

Changes:

  • Added <mat-label> to multiple mat-select / matInput controls for clearer field labeling.
  • Removed many explicit tabindex attributes, relying on natural DOM tab order.
  • Adjusted markup structure (e.g., mat-form-field wrapper around “Scroll Range” select) for consistent Material form-field presentation.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/app/shared/components/settings/app-settings/app-settings.component.html Adds a visible Material label for the default node selector and removes explicit tab order.
src/app/shared/components/horizontal-scroller/horizontal-scroller.component.html Wraps scroll-range select in mat-form-field, adds labels to selects/date inputs, removes tabindex.
src/app/shared/components/data-modal/show-pubkey/show-pubkey.component.html Adds a Material label to the info-type selector and removes tabindex.
src/app/lnd/transactions/create-invoice-modal/create-invoice.component.html Removes explicit tabindex from dialog controls and adds missing label for the Time Unit select.
src/app/lnd/peers-channels/channels/open-channel-modal/open-channel.component.html Adds label for Transaction Type select and removes explicit tabindex from inputs/toggles/buttons.
src/app/lnd/peers-channels/channels/close-channel-modal/close-channel.component.html Adds label for Transaction Type select and removes explicit tabindex across the form.
src/app/lnd/peers-channels/channels/bump-fee-modal/bump-fee.component.html Adds label for Transaction Type select and removes explicit tabindex across the form.
src/app/lnd/on-chain/on-chain-send-modal/on-chain-send-modal.component.html Adds labels for selects, removes explicit tabindex in both template-driven and reactive stepper flows.
src/app/eclair/transactions/create-invoice-modal/create-invoice.component.html Removes explicit tabindex and adds missing label for the Time Unit select.
src/app/eclair/on-chain/on-chain-send-modal/on-chain-send-modal.component.html Adds label for Amount Unit select and removes explicit tabindex usage.
src/app/cln/transactions/invoices/create-invoice-modal/create-invoice.component.html Removes explicit tabindex and adds missing label for the Time Unit select.
src/app/cln/on-chain/on-chain-send-modal/on-chain-send-modal.component.html Adds labels for selects and removes explicit tabindex across template-driven and stepper forms.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

</div>
<div class="mt-2" fxLayout="row">
<button mat-button color="primary" tabindex="3" type="default" (click)="onAuthenticate()">Confirm</button>
<button mat-button color="primary" type="default" (click)="onAuthenticate()">Confirm</button>
</div>
<div class="mt-2" fxLayout="row" fxLayoutAlign="start center" fxFlex="100">
<button mat-button color="primary" tabindex="8" type="default" matStepperNext>Next</button>
<button mat-button color="primary" type="default" matStepperNext>Next</button>
<span class="page-title">Create Invoice</span>
</div>
<button tabindex="8" fxFlex="5" fxLayoutAlign="center center" class="btn-close-x p-0" default mat-button [mat-dialog-close]="false">X</button>
<button fxFlex="5" fxLayoutAlign="center center" class="btn-close-x p-0" default mat-button [mat-dialog-close]="false">X</button>
<div *ngIf="information.uris && information.uris.length > 0" fxLayout="row">
<mat-form-field fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayoutAlign="start end">
<mat-select tabindex="1" [(value)]="selInfoType">
<mat-label>Info type</mat-label>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request cleans up form templates across multiple components by removing explicit tabindex attributes to allow natural DOM tab ordering, adding missing <mat-label> elements, and wrapping select inputs in <mat-form-field> containers. The review feedback highlights two instances of invalid type="default" attributes on buttons inside the CLN on-chain send modal that should be changed to type="button" to avoid unintended form submissions. Additionally, it is recommended to remove obsolete fxFlex layout attributes from the mat-select element in the horizontal scroller component now that it is properly wrapped in a form field.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

</div>
<div class="mt-2" fxLayout="row">
<button mat-button color="primary" tabindex="3" type="default" (click)="onAuthenticate()">Confirm</button>
<button mat-button color="primary" type="default" (click)="onAuthenticate()">Confirm</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The button has type="default", which is not a valid HTML button type. Valid values are submit, reset, or button. Since this button is inside a form, an invalid type defaults to submit in most browsers, which can cause unexpected form submissions. It should be changed to type="button".

Suggested change
<button mat-button color="primary" type="default" (click)="onAuthenticate()">Confirm</button>
<button mat-button color="primary" type="button" (click)="onAuthenticate()">Confirm</button>

</div>
<div class="mt-2" fxLayout="row" fxLayoutAlign="start center" fxFlex="100">
<button mat-button color="primary" tabindex="8" type="default" matStepperNext>Next</button>
<button mat-button color="primary" type="default" matStepperNext>Next</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The button has type="default", which is not a valid HTML button type. It should be changed to type="button" to prevent unexpected form submission behavior inside the stepper form.

Suggested change
<button mat-button color="primary" type="default" matStepperNext>Next</button>
<button mat-button color="primary" type="button" matStepperNext>Next</button>

</mat-select>
<mat-form-field fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayoutAlign="start end">
<mat-label>Scroll Range</mat-label>
<mat-select fxFlex="60" fxFlex.gt-md="30" name="selScrlRange" class="font-bold-700" [(ngModel)]="selScrollRange" (selectionChange)="onRangeChanged($event)">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Now that the mat-select is wrapped inside a mat-form-field, the fxFlex attributes (fxFlex="60" fxFlex.gt-md="30") should be removed from the mat-select itself. In Angular Material, the form control inside a mat-form-field should span the full width of its container, and any flex or sizing layout should be applied to the mat-form-field container instead.

        <mat-select name="selScrlRange" class="font-bold-700" [(ngModel)]="selScrollRange" (selectionChange)="onRangeChanged($event)">

@saubyk

saubyk commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

/rtl review

@rtlreview

rtlreview Bot commented Jun 10, 2026

Copy link
Copy Markdown

✅ Review posted: #1609 (review)

4 finding(s); 4 inline, 0 in body.

🔁 Need a re-review after pushing changes? Reply with /rtl re-review.
Maintainers can also /rtl dismiss <id> to silence specific findings, or anyone can /rtl explain <id> for elaboration.

@rtlreview rtlreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pure HTML-template accessibility pass: adds mat-label to mat-form-fields that lacked one and strips positive tabindex from form controls and buttons across the LND/CLN/Eclair on-chain-send and create-invoice modals, the LND peers-channels modals (bump-fee, close-channel, open-channel), and three shared components. The actual edits are consistent across the three implementation trees for the modals that were touched, and they don't change submit semantics, password attributes, or template bindings — no security regression.

The gap is scope, not correctness: in three of the shared components the PR explicitly edits (show-pubkey, horizontal-scroller, app-settings), the mat-label was added but additional positive-tabindex attributes on sibling buttons inside the same file were left in place — directly contradicting the second half of the PR description. And the channel modal accessibility work landed only on the LND tree; the CLN peers-channels siblings (which mirror this UX in RTL) are not in this PR, so they likely still carry the same anti-pattern. None of this blocks the change, but the description should match what's shipped.

<span class="page-title">{{alertTitle}}</span>
</div>
<button tabindex="8" fxFlex="5" fxLayoutAlign="center center" class="btn-close-x p-0" mat-button (click)="onClose()">X</button>
<button fxFlex="5" fxLayoutAlign="center center" class="btn-close-x p-0" mat-button (click)="onClose()">X</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 F1 (minor): [Multi-impl parity per rules/rtl-multi-impl-parity.md] The channel-modal accessibility fix is applied LND-only — this PR touches src/app/lnd/peers-channels/channels/{open-channel-modal,close-channel-modal,bump-fee-modal}/*.component.html but no file under src/app/cln/peers-channels/. CLN exposes equivalent open-channel / close-channel modals in RTL's standard mirrored layout and the same mat-label-missing + positive-tabindex pattern almost certainly lives there too. The CLN sibling files are not in this PR's file_contents[], so this is unverified rather than asserted drift — worth a human spot-check before merge to decide whether to widen scope or follow up. Bump-fee is LND-only (RBF surface) so that file is not a parity concern; Eclair's channel UX is different so not flagged either. Raised by: parity-checker.

<div *ngIf="information.uris && information.uris.length > 0" fxLayout="row">
<mat-form-field fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayoutAlign="start end">
<mat-select tabindex="1" [(value)]="selInfoType">
<mat-label>Info type</mat-label>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 F2 (minor): The PR adds <mat-label>Info type</mat-label> to the info-type select but leaves two other positive-tabindex attributes in the same file untouched: the close <button tabindex="3" ...>X</button> at line 11, and the copy <button ... tabindex="2" type="submit" ...> at line 36. The PR body says positive tabindex is being removed because it causes unpredictable keyboard navigation — leaving them in a file the PR otherwise edits leaves the dialog's tab order still broken (the X jumps over the form), and a reviewer trusting the description would not notice. Either drop the two tabindex values here or narrow the PR description to call out which leftover values are intentionally out of scope. Minor labeling nit: the rest of the codebase capitalises every mat-label word (e.g. "Amount Unit", "Time Unit", "Transaction Type"); "Info type" is the only lowercase one — make it "Info Type" for consistency with the surrounding labels. Raised by: code-reviewer.

{{scrollRange | titlecase}}
</mat-option>
</mat-select>
<mat-form-field fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayoutAlign="start end">

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 F3 (minor): The PR wraps the scroll-range mat-select in a mat-form-field with a <mat-label> and adds labels to the two datepicker inputs — good. But the four navigation buttons at lines 3–6 (FIRST / PREVIOUS / NEXT / LAST mat-icon-buttons) still carry tabindex="1", tabindex="2", tabindex="5", tabindex="6". Those are positive tabindex values on the file's most-used focus path, and the PR description explicitly says these are being removed. Since this is a shared component used across every implementation, the inconsistency is more visible than in any single modal. Drop them or note the exception in the description. Raised by: code-reviewer.

<div fxLayout="row" fxLayoutAlign="start start">
<mat-form-field fxLayout="column" fxLayoutAlign="start start">
<mat-select autoFocus tabindex="1" name="defaultNode" [(ngModel)]="appConfig.defaultNodeIndex">
<mat-label>Default Node</mat-label>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 F4 (minor): The PR strips tabindex="1" from the Default Node mat-select and adds its mat-label — but the Reset (tabindex="2") and Update (tabindex="3") buttons immediately below (lines 19–20 in the post-change file) still carry positive tabindex values. The Settings page is the only one the author manually verified per the PR body, so the missed half is conspicuous: with the mat-select no longer pinned to tabindex="1", the natural DOM order now puts the buttons before the select via the explicit tabs, which is exactly the unpredictable keyboard navigation the PR set out to fix. Either remove these two tabindex values for a consistent fix here, or update the description. Raised by: code-reviewer.

@rtlreview rtlreview Bot added the rtl-active label Jun 10, 2026
@rtlreview

rtlreview Bot commented Jun 10, 2026

Copy link
Copy Markdown

🤖 rtlreviewbot audit metadata for this PR — auto-generated, please don't edit.

@SIDHARTH20K4

Copy link
Copy Markdown
Author

@saubyk
could you review this when you get time?!
Thanks!

@saubyk

saubyk commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

/rtl re-review

@rtlreview

rtlreview Bot commented Jun 11, 2026

Copy link
Copy Markdown

✅ Re-review posted: #1609 (review)

Prior findings: 2 addressed, 2 still unresolved, 0 withdrawn.
New findings: 0.
Total inline: 2; in body: 0.

🔁 Need another re-review after pushing changes? Reply with /rtl re-review.
Maintainers can also /rtl dismiss <id> to silence specific findings, or anyone can /rtl explain <id> for elaboration.

@rtlreview rtlreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Substantial response since the last review: CLN siblings for open-channel, bump-fee, create-invoice, and on-chain-send are now included, Eclair siblings for on-chain-send and create-invoice are in, and every leftover positive tabindex in the three shared components (show-pubkey, horizontal-scroller, app-settings) has been stripped. F3 and F4 are fully fixed, F1 is largely resolved bar a residual close-channel parity question, and F2 is fixed except for a one-word capitalization nit.

No new defects emerged: pure {{...}} interpolations, no unsafe template binding, no auth-gate change. A few touched files lost their trailing newline and one type="button " attribute has a trailing space, but neither rises to a finding.


Status of prior findings

  • F3 addressed: Fixed — all four navigation mat-icon-buttons in src/app/shared/components/horizontal-scroller/horizontal-scroller.component.html (FIRST/PREVIOUS/NEXT/LAST, formerly tabindex="1|2|5|6") now carry no positive tabindex. The scroll-range mat-select was additionally wrapped in a mat-form-field with a Scroll Range label, and the monthly / yearly datepicker inputs received Monthly Date / Yearly Date labels.
  • F4 addressed: Fixed — tabindex="2" on the Reset button and tabindex="3" on the Update button in src/app/shared/components/settings/app-settings/app-settings.component.html are both removed; the Default Node mat-select now has its Default Node label and natural DOM focus order is restored.

<span class="page-title">{{channelToClose.active ? 'Close Channel' : 'Force Close Channel'}}</span>
</div>
<button tabindex="8" fxFlex="5" fxLayoutAlign="center center" class="btn-close-x p-0" mat-button (click)="onClose()">X</button>
<button fxFlex="5" fxLayoutAlign="center center" class="btn-close-x p-0" mat-button (click)="onClose()">X</button>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 F1 (minor) — partially_addressed: CLN open-channel-modal and bump-fee siblings are now in the PR (src/app/cln/peers-channels/channels/open-channel-modal/open-channel.component.html and .../bump-fee-modal/bump-fee.component.html), and on-chain-send / create-invoice are mirrored across CLN and Eclair too — the bulk of the parity gap is closed. What remains unresolved is the close-channel surface: LND's close-channel-modal got mat-label additions and tabindex stripping, but no CLN/Eclair sibling appears in files[]. Channel close in CLN/Eclair may be implemented as an inline confirmation rather than a dedicated modal with mat-form-field controls, so this is plausibly LND-only and not an actual drift; the sibling paths are not in file_contents[] so this is unverified rather than asserted. Worth a quick author confirmation that CLN/Eclair expose no equivalent mat-form-field close-channel UI that should receive the same fix. Raised by: parity-checker.

<div *ngIf="information.uris && information.uris.length > 0" fxLayout="row">
<mat-form-field fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayoutAlign="start end">
<mat-select tabindex="1" [(value)]="selInfoType">
<mat-label>Info type</mat-label>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 F2 (minor) — partially_addressed: Both leftover positive tabindex values flagged previously are removed — the X close button no longer carries tabindex="3" (line 11 in post-change) and the Copy button no longer carries tabindex="2" (line 34 in post-change). What remains is the labeling nit: the newly added <mat-label>Info type</mat-label> uses sentence case while every other label added in this PR uses Title Case (Bitcoin Address, Amount Unit, Default Node, Scroll Range, Time Unit, Transaction Type, Number of Blocks). Prefer Info Type for visual consistency. Raised by: code-reviewer.

@saubyk

saubyk commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

@SIDHARTH20K4 can you look at the F1 and F2 findings which the bot is flagging as partially addressed?

Also wondering about the feedback posted by Gemini and Copilot? Worth addressing?

@SIDHARTH20K4

SIDHARTH20K4 commented Jun 12, 2026

Copy link
Copy Markdown
Author

@saubyk
I checked these two folders:
src/app/cln/peers-channels/channels/
src/app/eclair/peers-channels/channels/

Neither has a close-channel-modal. CLN has bump-fee and open-channel modals, Eclair has open-channel only... looks like channel close works differently in those implementations.

Also fixed F2... "Info Type" is now Title Case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[A11Y] [High] Form fields missing visible labels for screen readers

3 participants