Skip to content

🎨 Palette: Dynamic Form Validation Accessibility#1005

Open
is0692vs wants to merge 2 commits into
stagingfrom
palette-dynamic-form-a11y-11488140522204002012
Open

🎨 Palette: Dynamic Form Validation Accessibility#1005
is0692vs wants to merge 2 commits into
stagingfrom
palette-dynamic-form-a11y-11488140522204002012

Conversation

@is0692vs

@is0692vs is0692vs commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

💡 What: コレクション作成フォームにおいて、スラッグの動的バリデーション結果をスクリーンリーダーに通知するための aria-live="polite" と、フォーム送信エラーを即座に通知するための role="alert" を追加しました。
🎯 Why: スラッグが使用可能かどうか(「確認中...」「✓ 使用可能」など)や、フォーム送信時のエラーが視覚的にしか伝わっていなかったため、支援技術ユーザーにも適切に状態変化を伝えるため。
♿ Accessibility:

  • スラッグ入力フィールドに aria-describedby="slug-status" を追加
  • ステータスメッセージに id="slug-status"aria-live="polite" を追加
  • 動的に出現するエラーメッセージ要素に role="alert" を追加

PR created automatically by Jules for task 11488140522204002012 started by @is0692vs

Summary by CodeRabbit

  • Documentation

    • Added comprehensive accessibility guidelines and best practices for implementing dynamic form validation and error messaging systems.
  • Refactor

    • Improved form validation status announcements and feedback communication to ensure users with assistive technologies receive timely and clear information on validation state changes.
    • Enhanced form error message display and rendering for improved overall accessibility compliance.

Greptile Summary

コレクション作成フォームのスラッグ検証ステータスとフォーム送信エラーに対して、支援技術向けのアクセシビリティ属性を追加するPRです。

  • スラッグ入力フィールドに aria-describedby="slug-status" を追加し、ステータス <p>id="slug-status"aria-live="polite" を付与。ステータス要素は常にDOMに存在するため aria-live が正しく機能します。
  • 動的に出現するフォーム送信エラーメッセージに role="alert" を付与。マウント時にスクリーンリーダーへ即座にアナウンスされます。

Confidence Score: 4/5

アクセシビリティ属性の追加のみで、機能ロジックへの変更はなく安全にマージできます。

変更はスラッグ入力フィールドと送信エラー表示への aria-* 属性付与のみです。aria-live の対象要素が常にDOMに存在する設計になっており実装方針は正しいですが、スラッグが「使用済み」または「無効」な場合に aria-invalid が付与されていないため、スクリーンリーダーへのエラー状態通知が完全ではありません。

apps/web/src/app/collections/new/page.tsx — aria-invalid の追加を検討する価値があります。

Important Files Changed

Filename Overview
apps/web/src/app/collections/new/page.tsx スラッグ入力に aria-describedby/aria-live=polite、送信エラーに role=alert を追加。実装方針は正しいが、エラー状態で aria-invalid が付与されていない点が改善余地として残る。
.Jules/palette.md 今回の変更から得られたアクセシビリティの知見をログとして追記したドキュメント更新のみ。コードへの影響なし。

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant User as ユーザー
    participant Input as スラッグ入力
    participant Status as aria-live polite 要素
    participant SR as スクリーンリーダー
    participant ErrEl as role=alert 要素

    User->>Input: 文字入力
    Input->>Status: "slugStatus=checking"
    Status-->>SR: polite で読み上げ
    Status->>Status: "slugStatus=available"
    Status-->>SR: polite で読み上げ

    User->>Input: フォーム送信
    Input->>ErrEl: error が truthy になりDOM追加
    ErrEl-->>SR: alert で即座に読み上げ
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant User as ユーザー
    participant Input as スラッグ入力
    participant Status as aria-live polite 要素
    participant SR as スクリーンリーダー
    participant ErrEl as role=alert 要素

    User->>Input: 文字入力
    Input->>Status: "slugStatus=checking"
    Status-->>SR: polite で読み上げ
    Status->>Status: "slugStatus=available"
    Status-->>SR: polite で読み上げ

    User->>Input: フォーム送信
    Input->>ErrEl: error が truthy になりDOM追加
    ErrEl-->>SR: alert で即座に読み上げ
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
apps/web/src/app/collections/new/page.tsx:293-294
`aria-invalid` が未設定のため、スラッグが「使用済み」または「無効」な状態でも入力フィールドがエラー状態であることをスクリーンリーダーに伝えられていません。`aria-describedby` でステータスメッセージは読み上げられますが、`aria-invalid="true"` がないと一部のスクリーンリーダーはフィールドがエラー状態であることを明示的にアナウンスしません(WCAG 1.3.1 / 4.1.2)。

```suggestion
            aria-describedby="slug-status"
            aria-invalid={slugStatus === "taken" || slugStatus === "invalid"}
            className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"
```

Reviews (1): Last reviewed commit: "feat: add accessible attributes to dynam..." | Re-trigger Greptile

Greptile also left 1 inline comment on this PR.

is0692vs and others added 2 commits June 18, 2026 14:18
Release: staging -> main (2026-06-17 02:44)
Added `aria-describedby` to the slug input, linked it to an `id="slug-status"` element, and added `aria-live="polite"` so screen readers announce validation states. Added `role="alert"` to the error message container.

Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com>
@google-labs-jules

Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
open-shelf Ignored Ignored Jun 18, 2026 2:52pm

@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@dosubot dosubot Bot added the enhancement New feature or request label Jun 18, 2026
@coderabbitai

coderabbitai Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The PR adds ARIA accessibility attributes to the slug validation UI in NewCollectionPage: aria-describedby="slug-status" on the slug input, aria-live="polite" on the status paragraph, and role="alert" on the error paragraph. The same pattern is documented as a new entry in .Jules/palette.md.

Changes

Dynamic Form Validation Accessibility

Layer / File(s) Summary
Slug status and error ARIA attributes
apps/web/src/app/collections/new/page.tsx
Slug input gains aria-describedby="slug-status"; slug status <p> gains aria-live="polite"; error <p> gains role="alert".
Accessibility guidance in palette.md
.Jules/palette.md
Adds a 2026-06-18 entry documenting the aria-describedby + aria-live="polite" + role="alert" combination for async validation status and dynamic error messages.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~3 minutes

Possibly related PRs

  • Hiroki-org/OpenShelf#30: Initially implemented the /collections/new slug generation and status states that this PR's ARIA attributes are applied to.
  • Hiroki-org/OpenShelf#792: Also updates .Jules/palette.md accessibility guidance around aria-describedby linking inputs to announced status elements.
  • Hiroki-org/OpenShelf#926: Adds overlapping "dynamic form validation" guidance in .Jules/palette.md and implements aria-describedby/aria-live="polite" on the same slug status element.

Suggested labels

enhancement, javascript

Poem

🐇 Hop, hop — the form now speaks!
With aria-live the status leaks
through screen readers, loud and clear.
role="alert" makes errors near,
and aria-describedby ties the bow —
accessibility stole the show! 🎉

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'Palette: Dynamic Form Validation Accessibility' directly describes the main change—adding accessibility features to form validation as documented in .Jules/palette.md and implemented in the page component.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 palette-dynamic-form-a11y-11488140522204002012

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 and usage tips.

@github-actions github-actions Bot changed the base branch from main to staging June 18, 2026 14:52
@github-actions

Copy link
Copy Markdown

このリポジトリでは staging 先行フローを採用しています。PR のターゲットを staging に変更しました。staging で動作確認後、stagingmain の PR を作成してください。

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request improves form validation accessibility on the new collection page by adding aria-describedby and aria-live="polite" to the slug input and its status message, and role="alert" to the error message. It also documents these accessibility practices in .Jules/palette.md. The reviewer suggests further enhancing accessibility by dynamically applying the aria-invalid attribute to the slug input field when the slug is invalid or already taken.

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.

Comment on lines 292 to 294
maxLength={40}
aria-describedby="slug-status"
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"

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.

medium

スラッグのバリデーション状態(invalid または taken)に応じて、入力フィールドに aria-invalid 属性を動的に付与することをおすすめします。

これにより、スクリーンリーダーなどの支援技術が、入力フィールドが現在エラー状態であることをユーザーに即座に伝えることができるようになり、アクセシビリティがさらに向上します。

            maxLength={40}
            aria-describedby="slug-status"
            aria-invalid={slugStatus === "invalid" || slugStatus === "taken" ? "true" : undefined}
            className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"

@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

Comment on lines +293 to 294
aria-describedby="slug-status"
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"

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.

P2 aria-invalid が未設定のため、スラッグが「使用済み」または「無効」な状態でも入力フィールドがエラー状態であることをスクリーンリーダーに伝えられていません。aria-describedby でステータスメッセージは読み上げられますが、aria-invalid="true" がないと一部のスクリーンリーダーはフィールドがエラー状態であることを明示的にアナウンスしません(WCAG 1.3.1 / 4.1.2)。

Suggested change
aria-describedby="slug-status"
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"
aria-describedby="slug-status"
aria-invalid={slugStatus === "taken" || slugStatus === "invalid"}
className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"
Prompt To Fix With AI
This is a comment left during a code review.
Path: apps/web/src/app/collections/new/page.tsx
Line: 293-294

Comment:
`aria-invalid` が未設定のため、スラッグが「使用済み」または「無効」な状態でも入力フィールドがエラー状態であることをスクリーンリーダーに伝えられていません。`aria-describedby` でステータスメッセージは読み上げられますが、`aria-invalid="true"` がないと一部のスクリーンリーダーはフィールドがエラー状態であることを明示的にアナウンスしません(WCAG 1.3.1 / 4.1.2)。

```suggestion
            aria-describedby="slug-status"
            aria-invalid={slugStatus === "taken" || slugStatus === "invalid"}
            className="w-full rounded-md border border-gray-300 px-3 py-2 text-sm dark:border-gray-700 dark:bg-gray-900"
```

How can I resolve this? If you propose a fix, please make it concise.

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

Labels

enhancement New feature or request size/S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant