Skip to content

fix(bulma-ui): associate Autocomplete and Taginput labels with their inner inputs - #496

Merged
allxsmith merged 2 commits into
mainfrom
fix/493-autocomplete-taginput-label
Aug 8, 2026
Merged

allxsmith merged 2 commits into
mainfrom
fix/493-autocomplete-taginput-label

Conversation

@allxsmith

@allxsmith allxsmith commented Aug 8, 2026 •

Copy link
Copy Markdown
Owner

Closes #493. Second of three stacked label-association PRs following #492 (merge order: this one → #494's PR → #495's PR).

What

The convenience label prop on Autocomplete and Taginput rendered an unassociated Field label, and a user-supplied id landed on the wrapper <div> instead of the labellable inner <input>. Both now run through the useAutoLabelId hook from #492: the inner input gets your id (or a generated one), the label gets a matching for, and an explicit labelProps.htmlFor wins outright.

Behavior changes to review

  • id relocation: a user-supplied id now applies to the inner text input (the labellable control), not the wrapper div. Verified nothing in the repo, docs, stories, or skills relied on the old placement; anyone targeting the wrapper by #id in CSS/tests would need to adjust. Documented in the props tables.
  • Taginput naming: the hardcoded aria-label="Add tag" becomes a fallback — suppressed when the wired visible label names the input (aria-label would otherwise shadow it), kept when unlabeled or nested in an outer Field.
  • Taginput at maxTags: the text input isn't rendered, so the label deliberately renders without for instead of dangling.

Tests

New describe('label association (#493)') blocks in both suites: association via getByLabelText, id relocation locked (input has it, wrapper doesn't), labelProps.htmlFor override, no-label/no-id, inside-Field no injection, both aria-label fallback directions, and the maxTags unwired case. All React 18/19-safe (no id text asserted). pnpm all green.

Docs / skill

Accessibility sections updated on autocomplete.md and taginput.md; TSDoc shadow-redeclares drive the regenerated props tables; skills/bestax-form moves both components into the auto-wired list (remaining manual: Field-composed usage and the group inputs — #494 and #495 are next in the stack).

Summary by CodeRabbit

  • Accessibility Improvements

    • Autocomplete and Taginput now automatically associate labels with their inputs.
    • Added support for custom input IDs and label properties, including explicit association overrides.
    • Improved accessible-name handling when labels are absent or inputs are hidden.
  • Documentation

    • Updated component references and form guidance to explain label wiring, IDs, and edge cases.

…inner inputs

The label prop on both components rendered an unassociated Field label, and
a user-supplied id landed on the wrapper div instead of the labellable
input. Both now run through useAutoLabelId: the inner input gets your id or
a generated one, the label gets a matching htmlFor, and an explicit
labelProps.htmlFor still wins.

Behavior notes: a user id now applies to the inner text input rather than
the wrapper div (nothing in the repo or docs relied on the old placement);
Taginput's hardcoded aria-label="Add tag" becomes a fallback so a wired
visible label names the input, and at maxTags (no input rendered) the label
stays unwired rather than pointing at nothing.
Copilot AI balanced review requested due to automatic review settings August 8, 2026 00:01
@coderabbitai

coderabbitai Bot commented Aug 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@allxsmith, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 47981dd3-97b8-4501-b5e1-d60be626c497

📥 Commits

Reviewing files that changed from the base of the PR and between 384bd38 and ca5996a.

📒 Files selected for processing (5)
  • bulma-ui/src/form/Autocomplete.tsx
  • bulma-ui/src/form/Taginput.tsx
  • bulma-ui/src/form/__tests__/Taginput.test.tsx
  • docs/docs/api/form/autocomplete.md
  • docs/docs/api/form/taginput.md

Walkthrough

Autocomplete and Taginput now support automatic label-to-input association. They accept label, labelProps, and id, apply IDs to inner inputs, handle overrides and nested fields, and update accessibility tests and documentation.

Changes

Form label association

Layer / File(s) Summary
Autocomplete label wiring
bulma-ui/src/form/Autocomplete.tsx, bulma-ui/src/form/__tests__/Autocomplete.test.tsx, docs/docs/api/form/autocomplete.md
Autocomplete derives label properties and an ID for its inner input. Tests and documentation cover generated IDs, supplied IDs, overrides, and nested Field behavior.
Taginput label and accessible-name wiring
bulma-ui/src/form/Taginput.tsx, bulma-ui/src/form/__tests__/Taginput.test.tsx, docs/docs/api/form/taginput.md
Taginput wires labels to its text input when present. It conditionally keeps the fallback "Add tag" label and skips wiring when maxTags hides the input.
Form labeling guidance
bulma-ui/src/form/fieldProps.ts, skills/bestax-form/SKILL.md
Documentation distinguishes automatic wiring for Autocomplete and Taginput from manual wiring for composed and grouped inputs.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant FormConsumer
  participant AutocompleteOrTaginput
  participant useAutoLabelId
  participant Field
  participant InnerInput
  FormConsumer->>AutocompleteOrTaginput: provide label, labelProps, and optional id
  AutocompleteOrTaginput->>useAutoLabelId: derive control ID and label props
  AutocompleteOrTaginput->>Field: render computed label props
  AutocompleteOrTaginput->>InnerInput: render computed control ID
Loading

Possibly related PRs

  • allxsmith/bestax#492: Introduces the shared useAutoLabelId label-association pattern used by these form components.
  • allxsmith/bestax#365: Updates related label-to-input accessibility guidance in skills/bestax-form/SKILL.md.

Suggested labels: needs-human-review, claude-assisted

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the primary label-association fix for Autocomplete and Taginput.
Description check ✅ Passed The description explains the changes, affected components, issue, tests, documentation, and accessibility behavior in sufficient detail.
Linked Issues check ✅ Passed The changes satisfy issue #493 by wiring labels, moving ids to inner inputs, and preventing Taginput aria-label from overriding visible labels.
Out of Scope Changes check ✅ Passed The tests, documentation, generated props guidance, and skill updates directly support the label-association fix and are in scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/493-autocomplete-taginput-label

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Extends #492’s automatic label association to Autocomplete and Taginput.

Changes:

  • Moves supplied/generated IDs to inner text inputs and wires labels.
  • Refines Taginput accessible naming and maxTags behavior.
  • Adds tests, documentation, and skill guidance.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
bulma-ui/src/form/Autocomplete.tsx Wires labels to the inner input.
bulma-ui/src/form/Taginput.tsx Adds label wiring and accessible-name fallback logic.
bulma-ui/src/form/fieldProps.ts Updates association guidance.
bulma-ui/src/form/__tests__/Autocomplete.test.tsx Tests label and ID behavior.
bulma-ui/src/form/__tests__/Taginput.test.tsx Tests label, fallback, and limit behavior.
docs/docs/api/form/autocomplete.md Documents association and ID relocation.
docs/docs/api/form/taginput.md Documents accessibility behavior.
skills/bestax-form/SKILL.md Adds both components to auto-wired guidance.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread bulma-ui/src/form/Taginput.tsx Outdated
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://7b4e26a6.bestax.pages.dev

@coderabbitai coderabbitai 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.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@bulma-ui/src/form/Taginput.tsx`:
- Around line 652-654: Update the aria-label condition in Taginput so the
fallback “Add tag” is removed only when fieldLabelProps.htmlFor matches a
defined controlId; otherwise preserve it, including explicit non-matching
htmlFor values. Add a regression test covering labelProps={{ htmlFor: 'other' }}
without a matching id and verify the input retains its accessible name.

In `@docs/docs/api/form/autocomplete.md`:
- Line 474: Update the ref type documentation for the Autocomplete API at
docs/docs/api/form/autocomplete.md:474-474 and the TagInput API at
docs/docs/api/form/taginput.md:540-540 from React.Ref&lt;HTMLElement&gt; to
React.Ref&lt;HTMLInputElement&gt;, preserving the existing ref descriptions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 51ce0b1b-2d39-44ab-be9b-6075cc823a0f

📥 Commits

Reviewing files that changed from the base of the PR and between 4e33d72 and 384bd38.

📒 Files selected for processing (8)
  • bulma-ui/src/form/Autocomplete.tsx
  • bulma-ui/src/form/Taginput.tsx
  • bulma-ui/src/form/__tests__/Autocomplete.test.tsx
  • bulma-ui/src/form/__tests__/Taginput.test.tsx
  • bulma-ui/src/form/fieldProps.ts
  • docs/docs/api/form/autocomplete.md
  • docs/docs/api/form/taginput.md
  • skills/bestax-form/SKILL.md

Comment thread bulma-ui/src/form/Taginput.tsx Outdated
Comment thread docs/docs/api/form/autocomplete.md Outdated

@claude claude 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.

Deep review — 0 blocking · 1 advisory

# Severity Area Finding Location
1 🔵 Advisory Accessibility Taginput's aria-label="Add tag" fallback is suppressed whenever a label is rendered outside a Field, even when labelProps.htmlFor is overridden to a target other than this input — leaving the input with no id, no wired label, and no fallback name (a nameless control). bulma-ui/src/form/Taginput.tsx:654

Overall: The change is sound and does exactly what #493 asks: id is destructured out of the wrapper spread and threaded onto the inner labellable <input> in both components, the label is wired through the shared useAutoLabelId hook (generated id, user id, or labelProps.htmlFor override), and Taginput's hardcoded aria-label correctly becomes a fallback in the common cases. Tests (201 passing), docs, the fieldProps.ts neutrality comment, and the bestax-form skill were all updated consistently. The riskiest spot is Taginput's fallback-name heuristic (label && !insideField), which keys off "is a label rendered" rather than "does the wired label actually name this input" — a divergence that only surfaces under an unusual labelProps.htmlFor override; the human can decide whether to tighten it now or leave it documented.

Residual risk:

  • Nameless-input variants of the addressed class — the aria-label fallback misfires only when label is set AND labelProps.htmlFor is overridden to a non-matching id (no id prop given). In every normal path the label is wired (getByLabelText tests confirm) or the Add tag fallback is kept (unlabeled / inside-Field tests confirm). The id-without-label case correctly keeps Add tag because the heuristic keys off label, not controlId. Recorded as the advisory above rather than a blocker because it requires a deliberate, self-defeating override.
  • id relocation breaking internal wiring — refuted: neither component derives aria-controls/popover/aria-activedescendant from id; the relocated id feeds only the <input>, so no listbox/dropdown association is disturbed.
  • maxTags dangling for — refuted: at maxTags the input isn't rendered and rendersLabel is false, so useAutoLabelId injects no htmlFor; the label renders unwired (test-covered) rather than pointing at a missing control. Hooks stay unconditional (useId called every render), so the threshold toggle is hydration-safe.

🏄 Clean little set, dude — the id finally rides the real input instead of wiping out on the wrapper div, and the labels all link up nice. Only ripple is Taginput dropping its "Add tag" name if you paddle the htmlFor somewhere weird on purpose. Good to send it. 🌊

… its input

Review round on #496: the aria-label suppression keyed off "a label is
rendered" rather than "the wired label names this input", so label plus a
labelProps.htmlFor pointing elsewhere (with no id) produced a nameless
control. The condition now requires the rendered label's htmlFor to equal
the input's id. Also corrects the documented ref types to
React.Ref<HTMLInputElement>.
Copilot AI review requested due to automatic review settings August 8, 2026 00:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 8 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (1)

bulma-ui/src/form/Taginput.tsx:660

  • This can remove the input's only accessible name even though no label is rendered. For example, <Taginput id="tags" labelProps={{ htmlFor: 'tags' }} /> produces matching values here, but Field omits the absent label, so aria-label becomes undefined. Gate suppression on the convenience label actually being rendered and not being inside an outer Field.
                  controlId && fieldLabelProps?.htmlFor === controlId

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment

Preview URL: https://b2daa02b.bestax.pages.dev

@allxsmith
allxsmith merged commit 73cec33 into main Aug 8, 2026
23 checks passed
@allxsmith
allxsmith deleted the fix/493-autocomplete-taginput-label branch August 8, 2026 03:58
@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.8.3 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 5.9.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 4.0.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 1.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@bestax-release-bot

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

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.

[Bug] bulma-ui: Autocomplete and Taginput label prop stays unassociated; id lands on the wrapper div

2 participants