CLARIN-DSpace v9/Restore the dropped accessibility labels on the suggestion inputs and reject reason (X1 sweep, X-02a part C) - #1517
Open
milanmajchrak wants to merge 1 commit into
Conversation
milanmajchrak
force-pushed
the
ufal/port-x02a-suggestion-labels-9-base
branch
from
September 10, 2026 17:47
857e188 to
bf6773d
Compare
…tion inputs, reject reason and banner Card X-02a, part C of three. Seven templates the v9 upgrade took wholesale from vanilla 9.3, so the remaining accessibility hunks of 5a92fdf were never applied. The five autocomplete inputs (input-suggestions and its dso, validation, person and org-unit variants) carried a placeholder and nothing else: a placeholder is not a label, so a screen reader announced them as an unnamed edit field. Each input now gets [id]="name + '-input'" and a visually-hidden <label> bound to the same expression. The workflow reject-reason textarea had the same problem and now has id="reason" and a label carrying the reason placeholder key. The dspace theme's home banner image gets the translated [alt] the fork added. Fork mistakes ported fixed rather than literally: 1. class="sr-only" does not exist in Bootstrap 5 and 9-base defines it nowhere (git grep -nE '^[[:space:]]*\.sr-only' -- src => 0 hits, "bootstrap": "^5.3"); a literal port would render a visible label above every autocomplete. visually-hidden is used, defined at src/styles/_global-styles.scss:280. 2. <label for="name + '-input'"> is a static attribute, not a binding - it emits those 15 characters literally and pairs with nothing. It is ported as [attr.for]="name + '-input'", matching the input's [id] expression, so the association is real. The banner [alt] needs one file the card did not list: src/themes/dspace/app/home-page/home-news/ home-news.component.ts. That themed component declares no imports[] at all, because its template was pure static HTML until now, so the first use of the translate pipe fails the production build with NG8004 "No pipe found with name 'translate'". TranslateModule is added to its imports[]. The file has no fork delta and is claimed by no other card. 3. validation-suggestions also carried a static id="name" on the same input as the fork's new [id] binding. Leaving both would keep a second element answering to id="name" in the submission form, so the static one is removed and only the per-instance binding remains. The five suggestion templates keep their existing <button class="sr-only" type="submit">: that is pre-existing vanilla markup on 9-base (29 files use the class), out of scope here, and touching it would mix an unrelated Bootstrap-5 migration into an accessibility port. Tests: 5a92fdf ships none. input-suggestions.component.spec.ts gains cases asserting the label resolves to the input it names (label.htmlFor === input.id, id non-empty and derived from the name input) rather than asserting that a string is present in the template. Proven load-bearing with negative controls - see the PR description. Source: 5a92fdf (dtq-dev PR #1084), partial - the search boxes from the same commit are in the sibling PR for card X-02a part B. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
milanmajchrak
force-pushed
the
ufal/port-x02a-suggestion-labels-9-base
branch
from
September 10, 2026 17:59
bf6773d to
cb7c40a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Re-applies the remaining accessibility hunks of
dataquest-dev/dspace-angular#1084(
5a92fdfa89) ondtq-dev-9-base. Sync card X-02a, part C of three.Seven templates the v9 upgrade took wholesale from vanilla 9.3. The five autocomplete inputs
(
input-suggestionsand itsdso,validation,personandorg-unitvariants) carried aplaceholderand nothing else — a placeholder is not a label, so a screen reader announces them as anunnamed edit field. The workflow reject-reason
<textarea>had the same problem. Thedspacetheme'shome banner image had
alt="".Changes
shared/input-suggestions/input-suggestions.component.html[id]="name + '-input'"+visually-hiddenlabel bound with[attr.for]shared/input-suggestions/dso-input-suggestions/…htmlshared/input-suggestions/validation-suggestions/…htmlid="name"removedentity-groups/…/person-suggestions/person-input-suggestions.component.htmlentity-groups/…/org-unit-suggestions/org-unit-input-suggestions.component.htmlshared/mydspace-actions/claimed-task/reject/…htmlid="reason"on the textarea + a label carrying the reason keythemes/dspace/app/home-page/home-news/home-news.component.htmlalt=""→[alt]="'home.news.image.banner' | translate"shared/input-suggestions/input-suggestions.component.spec.tsNo i18n key is added, removed or renamed —
home.news.image.banneralready exists inen.json5andcs.json5with zero references, which is the symptom of the dropped hunk.Three fork mistakes ported fixed, not literally
class="sr-only"does not exist in Bootstrap 5 and this branch defines it nowhere(
"bootstrap": "^5.3";git grep -nE '^[[:space:]]*\.sr-only' -- src→ 0 hits;.visually-hiddenis atsrc/styles/_global-styles.scss:280). A literal port would render avisible label above every autocomplete.
<label for="name + '-input'">is a static attribute, not a binding — Angular emits those 15characters literally and the label pairs with nothing. Ported as
[attr.for]="name + '-input'",matching the input's
[id]expression, so the association is real and per-instance.validation-suggestionsalso carried a staticid="name"on the same input the fork gave a[id]binding. Keeping both would leave a second element answering toid="name"in thesubmission form, so the static one is removed and only the per-instance binding remains.
Deliberately not touched
The five suggestion templates keep their existing
<button class="sr-only" type="submit">. That ispre-existing vanilla markup on this branch (29 files still use the class), it is not part of these
hunks, and rewriting it would fold an unrelated Bootstrap-5 migration into an accessibility port.
Flagged for a separate card rather than smuggled in here.
validation-suggestionsalso carries a pre-existingattr.aria-labelledby="fieldName"writtenwithout brackets — a literal attribute named
attr.aria-labelledby, not an aria binding. It isvanilla, out of scope, and left alone; the new
<label>is what actually names the field.No aria attribute is added that the fork did not have. The additions are
<label>elements,id/[id], and[alt]on an<img>— no role forbids any of them.Tests added beyond the source commit
5a92fdfa89ships no spec.input-suggestions.component.spec.tsgains two cases that assert theassociation, not the presence of a string:
should label the input with a label that resolves to itname='author',placeholder='Search for an author': the input has a non-empty id, a<label>exists,label.htmlFor === input.id, the label text is the placeholder, and the label carriesvisually-hiddenshould derive the id from the name input so two instances do not collidenamefromauthortosubjectchanges the input id, and the label follows it (label.htmlFor === input.idagain)The second case is what makes this per-instance rather than "an id exists".
Negative controls — each new case proven load-bearing
Applied on top of the commit, so
git checkout HEAD -- <path>restores the ported file. Reverts andrestores are proved with
git diff HEAD --stat, not the bare form (git checkout <ref> -- <path>stages what it writes, so the bare
git diffis empty even when the revert landed).NC-1 — revert
input-suggestions.component.htmlto the base → 2 FAILED, 36 SUCCESSNC-2 — write the label exactly the way the fork did (
[attr.for]="name + '-input'"→for="name + '-input'") → 2 FAILED, 36 SUCCESSThis is fork mistake Test first touch #2 proved at runtime rather than by reading the template. The rendered
label.htmlForis the literal 15-character stringname + '-input'— the label pairs with nothing,on all five suggestion inputs. Porting that hunk verbatim would have shipped five labels that name
no control, and a grep-style test ("does the template contain
<label") would have called it a pass.NC-3 — keep the label, drop the input's
[id]binding → 2 FAILED, 36 SUCCESSThe label now points at an id nothing carries — the mirror image of NC-2, and the reason both halves
(
[id]on the input and[attr.for]on the label) are asserted together.Testing
Every subject spec is run, not only the extended one — the specs on this branch still assert vanilla
behaviour of these templates, so they are the real regression gate.
person-input-suggestionsand thethemed
home-newshave no spec file on 9-base (checked withgit ls-tree, not assumed).npm run build:prodis the CIRun buildstep (build.yml:110-111) and runs on this PR.Card X-02a is split into three PRs by theme with disjoint file sets; this is part C. Part A (#1515)
carries the
6628aaf493(#1221) unique DOM ids, part B the search boxes.Source:
5a92fdfa89(dtq-dev PR #1084), partial. Sync card: X-02a.🤖 Generated with Claude Code