Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,7 @@
## 2026-06-08 - Badge Snippet Accessible Names
**Learning:** アイコンやコピーなどの汎用的なアクションを実行するボタンが複数リストされている場合、スクリーンリーダーユーザーがどの項目のアクションかを識別できるように、`aria-label` に具体的なコンテキスト(例: `Copy ${snippet.label}`)を含めることが重要です。同時に、表示されているテキスト(この場合は 'Copy')を `aria-label` に含めることで WCAG 2.5.3(Label in Name)に準拠します。
**Action:** 今後、リスト内やコンテキストが不明瞭なボタン(特に同じテキストラベルを持つ複数のボタン)を実装・改善する際は、必ず `aria-label` に詳細な説明を含めるようにします。また、以前試みた「文字数カウンターの aria-live 属性の削除」は、スクリーンリーダーユーザーへのフィードバックを完全に奪うことになりアクセシビリティを低下させる(リグレッション)ため、行わないよう注意します。

## 2025-06-19 - Markdown Editor Tab Accessible Names

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 エントリーの日付が 2025-06-19 になっていますが、正しくは 2026-06-19 と思われます。

Suggested change
## 2025-06-19 - Markdown Editor Tab Accessible Names
## 2026-06-19 - Markdown Editor Tab Accessible Names
Prompt To Fix With AI
This is a comment left during a code review.
Path: .Jules/palette.md
Line: 29

Comment:
エントリーの日付が `2025-06-19` になっていますが、正しくは `2026-06-19` と思われます。

```suggestion
## 2026-06-19 - Markdown Editor Tab Accessible Names
```

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

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

**Learning:** タブUI(例:Markdownエディタの「Write」と「Preview」)において、短い表示テキスト(「Write」や「Preview」)だけではスクリーンリーダーユーザーにとってコンテキストが不足する場合があります。しかし、`aria-label`を追加してコンテキストを補足する際(例:「Write: Edit Markdown」)、WCAG 2.5.3(Label in Name)に準拠するためには、画面に表示されているテキスト(「Write」)を`aria-label`の先頭に正確に含める必要があります。これにより、音声認識ユーザーも視覚的なテキストを使って正しく要素を操作できるようになります。
**Action:** 今後、短いテキストラベルを持つタブやボタンに対して、より詳細なコンテキストを提供するために`aria-label`を追加する際は、必ず表示されているテキストを`aria-label`の文字列(理想的には先頭)に含めるようにします。また、アクセシブルな名前を変更した場合は、関連するユニットテスト(`getByRole`での名前の指定など)も必ず更新してテストの失敗を防ぎます。
Comment on lines +29 to +31

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

Markdownエディタのタブにおける aria-label の追加を差し戻す場合、この学習履歴(Learning/Action)も削除するか、あるいは「tablist に適切なラベルがある場合は、翻訳ツールとの互換性やシンプルさを優先して aria-label による上書きを避けるべきである」という内容に更新することをお勧めします。

12 changes: 8 additions & 4 deletions apps/web/src/components/__tests__/markdown-editor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe("MarkdownEditor", () => {
render(<MarkdownEditor {...defaultProps} />);

// Write tab is selected
const writeTab = screen.getByRole("tab", { name: "Write" });
const writeTab = screen.getByRole("tab", { name: "Write: Edit Markdown" });

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

コンポーネント側で aria-label を削除する場合、テスト内のクエリも元の "Write" に戻す必要があります。

expect(writeTab).toHaveAttribute("aria-selected", "true");

// Textarea is displayed
Expand All @@ -50,7 +50,9 @@ describe("MarkdownEditor", () => {
render(<MarkdownEditor {...defaultProps} mode="preview" />);

// Preview tab is selected
const previewTab = screen.getByRole("tab", { name: "Preview" });
const previewTab = screen.getByRole("tab", {
name: "Preview: View Output",
});
expect(previewTab).toHaveAttribute("aria-selected", "true");

// Textarea is not displayed
Expand All @@ -75,7 +77,9 @@ describe("MarkdownEditor", () => {
it("calls onModeChange when clicking tabs", () => {
const { rerender } = render(<MarkdownEditor {...defaultProps} />);

const previewTab = screen.getByRole("tab", { name: "Preview" });
const previewTab = screen.getByRole("tab", {
name: "Preview: View Output",
});
fireEvent.click(previewTab);

expect(mockOnModeChange).toHaveBeenCalledTimes(1);
Expand All @@ -84,7 +88,7 @@ describe("MarkdownEditor", () => {
// Simulate re-render with new mode using rerender
rerender(<MarkdownEditor {...defaultProps} mode="preview" />);

const writeTab = screen.getByRole("tab", { name: "Write" });
const writeTab = screen.getByRole("tab", { name: "Write: Edit Markdown" });
fireEvent.click(writeTab);

expect(mockOnModeChange).toHaveBeenCalledTimes(2);
Expand Down
2 changes: 2 additions & 0 deletions apps/web/src/components/markdown-editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export function MarkdownEditor({
id={`${id}-tab-write`}
type="button"
role="tab"
aria-label="Write: Edit Markdown"

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

タブ要素(role="tab")に aria-label を追加してアクセシブルな名前を拡張していますが、親要素の tablist にすでに aria-label="Markdown editor mode" が指定されているため、スクリーンリーダーは「Markdown editor mode、Write、タブ」のようにコンテキストを伴って読み上げます。そのため、aria-label で表示テキストを上書きして拡張する必要性は低いです。また、aria-label を使用すると、ブラウザの翻訳機能(Google翻訳など)が適用された際に、表示テキスト(「Write」)は翻訳される一方で aria-label は翻訳されず、音声認識ユーザーが翻訳後のテキストで操作できなくなる(WCAG 2.5.3 Label in Name の不一致が発生する)リスクがあります。アクセシビリティと国際化(翻訳対応)の観点から、aria-label は追加せず、表示テキスト(「Write」および「Preview」)をそのままアクセシブルな名前として使用することを推奨します。

aria-selected={mode === "write"}
aria-controls={`${id}-panel-write`}
tabIndex={mode === "write" ? 0 : -1}
Expand All @@ -77,6 +78,7 @@ export function MarkdownEditor({
id={`${id}-tab-preview`}
type="button"
role="tab"
aria-label="Preview: View Output"

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

こちらも同様に、親の tablistaria-label="Markdown editor mode" があるため、aria-label による拡張は不要です。翻訳時の WCAG 2.5.3 準拠を維持するためにも、aria-label を削除し、表示テキスト「Preview」をそのまま使用することを推奨します。

aria-selected={mode === "preview"}
aria-controls={`${id}-panel-preview`}
tabIndex={mode === "preview" ? 0 : -1}
Expand Down
Loading