Skip to content

ヘルプサイドバー改善: 頂点削除の説明追加 + 使い方タブの視認性向上#54

Merged
sugama-satsuki merged 3 commits intomainfrom
feature/improve-help-sidebar
Mar 17, 2026
Merged

ヘルプサイドバー改善: 頂点削除の説明追加 + 使い方タブの視認性向上#54
sugama-satsuki merged 3 commits intomainfrom
feature/improve-help-sidebar

Conversation

@sugama-satsuki
Copy link
Collaborator

@sugama-satsuki sugama-satsuki commented Mar 2, 2026

Summary

  • 「選択・編集」セクションに「頂点の削除」「描画中ポイントの削除」の操作説明を追加
    • 右クリックメニューからの頂点削除、Deleteキーでの削除、描画途中のポイント削除について記載
  • 使い方タブ(左下固定)の視認性を改善
    • アイコン: 16px → 20px
    • フォントサイズ: 13px → 14px
    • パディング: 8px 14px → 10px 16px
    • テキスト色: グレー(#374151) → ブルー(var(--color-blue))
    • 初回表示時にパルスアニメーションで注目を引く
  • ユニットテストに新規ヘルプ項目の検証を追加

レビュー対応(CodeRabbit指摘)

  • パルスアニメーションを localStorage フラグで初回表示のみに制限(useRef + help-tab--pulse 条件クラス)
  • prefers-reduced-motion メディアクエリでアニメーション無効化に対応(アクセシビリティ)
  • テストに description の内容検証を追加し回帰耐性を向上

変更ファイル

  • src/lib/help-content.ts — 頂点削除・描画中ポイント削除の説明を追加
  • src/lib/__tests__/help-content.test.ts — テスト追加(description検証強化)
  • src/components/HelpSidebar.css — タブの視認性改善(サイズ・色・アニメーション・prefers-reduced-motion対応)
  • src/components/HelpSidebar.tsx — localStorage による初回パルスアニメーション制御

Test plan

  • ユニットテスト: 99件パス
  • E2E テスト: 60シナリオ / 401ステップ パス(mainマージ後)
  • ビルド成功
  • 目視確認: 左下「使い方」タブが大きく、青色で目立つ
  • 目視確認: パルスアニメーションが初回のみ再生される
  • 目視確認: prefers-reduced-motion 設定時にアニメーションが無効化される
  • 目視確認: サイドバーの「選択・編集」セクションに「頂点の削除」「描画中ポイントの削除」が表示される

Summary by CodeRabbit

リリースノート

  • 新機能

    • ヘルプタブに一度だけ表示されるパルス表示を追加しました(初回表示後は消えます)。
    • ヘルプセクションに「頂点の削除」「描画中ポイントの削除」の説明を追加しました。
  • スタイル

    • ヘルプサイドバーのパディング・フォント・アイコンサイズを調整し、パルスアニメーションを導入しました。
  • テスト

    • 追加したヘルプ項目を検証するテストを追加しました。

- 「選択・編集」セクションに「頂点の削除」「描画中ポイントの削除」の説明を追加
- 使い方タブのサイズ拡大(アイコン20px、フォント14px、パディング増)
- タブの文字色をブルーに変更し視認性向上
- 初回表示時のパルスアニメーションを追加
- ユニットテストに新規項目の検証を追加
@sugama-satsuki
Copy link
Collaborator Author

テスト結果

ユニットテスト

✓ src/lib/__tests__/help-content.test.ts (11 tests)
... 全9ファイル

Test Files  9 passed (9)
Tests       99 passed (99)

E2E テスト

59 scenarios (59 passed)
389 steps (389 passed)
2m15.666s

ビルド

✓ built in 2.82s
dist/assets/index-DBSvRGT-.css     24.04 kB │ gzip:   4.55 kB
dist/assets/index-Cq27HUVx.js   1,326.91 kB │ gzip: 374.84 kB

@coderabbitai
Copy link

coderabbitai bot commented Mar 2, 2026

📝 Walkthrough

Walkthrough

ヘルプサイドバーにパルス表示を導入・スタイル調整し、ヘルプの「選択・編集」セクションへ「頂点の削除」と「描画中ポイントの削除」を追加、対応するテストを実装。UI状態はlocalStorageで一度だけ記録される仕組みを追加。

Changes

Cohort / File(s) Summary
ヘルプサイドバーのスタイル
src/components/HelpSidebar.css
ヘルプタブのパディングとフォントサイズを拡大、フォント色をCSS変数へ変更。ヘルプタブ用のパルスアニメーション(help-tab-pulse)と関連のキーフレームを追加。アイコンサイズも拡大。
ヘルプタブの表示ロジック
src/components/HelpSidebar.tsx
localStorageキー(HELP_TAB_SEEN_KEY)を利用して一度だけ表示するパルス状態を導入。初回レンダー時にキーを書き込むEffectを追加し、条件でhelp-tab--pulseクラスを付与。
ヘルプ内容の拡張
src/lib/help-content.ts
「選択・編集」セクションに「頂点の削除」と「描画中ポイントの削除」の2項目を追加(右クリック・Deleteキーに関する説明を含む)。
テスト追加
src/lib/__tests__/help-content.test.ts
新規追加項目を検証するテストを追加。セクションタイトルで該当セクションを特定し、各項目ラベルと説明文の存在をアサート。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰 タブがぽん、と光る朝、
ぴょんと見つけた新しい説明、
右クリックで消える頂点の舞、
パルスひとつで目を引いて、
地図の旅路、軽やかに続く。

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed プルリクエストのタイトルは、ヘルプサイドバーの改善に関する2つの主な変更(頂点削除の説明追加と使い方タブの視認性向上)を明確に要約しており、実装された変更内容と完全に一致しています。

✏️ 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 feature/improve-help-sidebar
📝 Coding Plan
  • Generate coding plan for human review comments

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/lib/__tests__/help-content.test.ts (1)

25-31: ラベルに加えて説明文の要点も検証すると、回帰に強くなります。

現状はラベル一致のみのため、説明文が意図せず変わってもテストが通ってしまいます。

💡 提案差分
   it('「選択・編集」セクションに頂点削除の説明が含まれる', () => {
     const section = HELP_SECTIONS.find((s) => s.title === '選択・編集')
     expect(section).toBeDefined()
-    const labels = section!.items.map((i) => i.label)
-    expect(labels).toContain('頂点の削除')
-    expect(labels).toContain('描画中ポイントの削除')
+    expect(section!.items).toEqual(
+      expect.arrayContaining([
+        expect.objectContaining({
+          label: '頂点の削除',
+          description: expect.stringContaining('Delete キー'),
+        }),
+        expect.objectContaining({
+          label: '描画中ポイントの削除',
+          description: expect.stringContaining('右クリック'),
+        }),
+      ]),
+    )
   })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/help-content.test.ts` around lines 25 - 31, The test
currently only asserts labels in HELP_SECTIONS; update it to also verify the
corresponding item descriptions so changes to text will fail tests. Locate
HELP_SECTIONS and the found section ('選択・編集'), then for each target label
('頂点の削除', '描画中ポイントの削除') find the item by label in section.items and assert the
item's description (e.g., item.description or item.text) matches the expected
summary strings; keep the label assertions and add these description assertions
using the same section variable to make the test regression-resistant.
src/components/HelpSidebar.css (1)

57-68: モーション低減設定への対応を追加してください。

prefers-reduced-motion でパルスを無効化すると、アクセシビリティが改善します。

💡 提案差分
 .help-tab {
   position: fixed;
@@
   animation: help-tab-pulse 2s ease-in-out 1;
   cursor: pointer;
@@
 }
 
+@media (prefers-reduced-motion: reduce) {
+  .help-tab {
+    animation: none;
+  }
+}
+
 `@keyframes` help-tab-pulse {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HelpSidebar.css` around lines 57 - 68,
このアニメーションはアクセシビリティ設定で無効化すべきなので、@keyframes help-tab-pulse を使っている要素に対して
prefers-reduced-motion: reduce
のメディアクエリを追加してアニメーションと関連するトランジション/ボックスシャドウ効果を無効化してください(例: `@media`
(prefers-reduced-motion: reduce) { .help-tab, .help-tab--pulse { animation: none
!important; transition: none !important; box-shadow: none !important; }
})。対象セレクタは実際に help-tab-pulse を割り当てているクラス(例: .help-tab や
.help-tab--pulse)を使って置き換えてください。
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/components/HelpSidebar.css`:
- Around line 28-29: The pulse animation in HelpSidebar.css on the .help-tab is
replaying every time the sidebar closes because the DOM node is recreated;
update the HelpSidebar React component (the isOpen-controlled rendering of the
help-tab button) to track a "hasSeenHelpTab" flag (stored in localStorage or in
persistent React state) and conditionally add an animation class (e.g.,
help-tab--pulse) only when the flag is false, set the flag true immediately
after the first render/animation start, and remove the unconditional animation
declaration from .help-tab in HelpSidebar.css so the animation only runs when
the conditional help-tab--pulse class is present.

---

Nitpick comments:
In `@src/components/HelpSidebar.css`:
- Around line 57-68: このアニメーションはアクセシビリティ設定で無効化すべきなので、@keyframes help-tab-pulse
を使っている要素に対して prefers-reduced-motion: reduce
のメディアクエリを追加してアニメーションと関連するトランジション/ボックスシャドウ効果を無効化してください(例: `@media`
(prefers-reduced-motion: reduce) { .help-tab, .help-tab--pulse { animation: none
!important; transition: none !important; box-shadow: none !important; }
})。対象セレクタは実際に help-tab-pulse を割り当てているクラス(例: .help-tab や
.help-tab--pulse)を使って置き換えてください。

In `@src/lib/__tests__/help-content.test.ts`:
- Around line 25-31: The test currently only asserts labels in HELP_SECTIONS;
update it to also verify the corresponding item descriptions so changes to text
will fail tests. Locate HELP_SECTIONS and the found section ('選択・編集'), then for
each target label ('頂点の削除', '描画中ポイントの削除') find the item by label in
section.items and assert the item's description (e.g., item.description or
item.text) matches the expected summary strings; keep the label assertions and
add these description assertions using the same section variable to make the
test regression-resistant.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 629a551 and 4e3640b.

📒 Files selected for processing (3)
  • src/components/HelpSidebar.css
  • src/lib/__tests__/help-content.test.ts
  • src/lib/help-content.ts

- パルスアニメーションをlocalStorageフラグで初回表示のみに制限(useRefで不要な再レンダリングを回避)
- prefers-reduced-motionメディアクエリでアニメーション無効化に対応
- テストにdescription検証を追加し回帰耐性を向上
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
src/components/HelpSidebar.tsx (1)

17-23: ⚠️ Potential issue | 🟠 Major

パルスが「初回のみ」にならず再表示時に再生されます。

Line 17 の useRef(...).current が固定値のため、Line 56 の help-tab--pulse が同一マウント中ずっと有効です。!isOpen でボタンが再 mount されるたびにアニメーションが再実行されます。

🔧 修正案(初回消費後に確実に無効化)
-import { useEffect, useRef } from 'react'
+import { useEffect, useRef, useState } from 'react'
@@
-  const showPulse = useRef(!localStorage.getItem(HELP_TAB_SEEN_KEY)).current
+  const [showPulse, setShowPulse] = useState(() => !localStorage.getItem(HELP_TAB_SEEN_KEY))
@@
-  useEffect(() => {
-    if (showPulse) {
-      localStorage.setItem(HELP_TAB_SEEN_KEY, '1')
-    }
-  }, [showPulse])
+  const consumePulse = () => {
+    if (!showPulse) return
+    localStorage.setItem(HELP_TAB_SEEN_KEY, '1')
+    setShowPulse(false)
+  }
@@
-          onClick={onOpen}
+          onAnimationEnd={consumePulse}
+          onClick={() => {
+            consumePulse()
+            onOpen()
+          }}
#!/bin/bash
# showPulse が固定値かつ setter 不在であることを静的確認
rg -n -C3 'HELP_TAB_SEEN_KEY|showPulse|help-tab--pulse|useRef\(|useState\(' src/components/HelpSidebar.tsx

Also applies to: 56-57

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/components/HelpSidebar.tsx` around lines 17 - 23, showPulse is created
from useRef(...).current so it never updates, causing help-tab--pulse to re-run
whenever the button remounts; replace the ref with a stateful flag initialized
from localStorage (e.g., useState(() =>
!localStorage.getItem(HELP_TAB_SEEN_KEY))) and update localStorage and clear the
state (setShowPulse(false)) inside the useEffect (or on animation end) so the
pulse is consumed once; update references to showPulse, HELP_TAB_SEEN_KEY, and
the useEffect that currently writes localStorage so the class help-tab--pulse
only applies on the true state once.
🧹 Nitpick comments (1)
src/lib/__tests__/help-content.test.ts (1)

25-40: 「頂点の削除」の説明検証をもう1点追加してください。

Line 32 は Delete キー のみを検証しており、右クリック が欠けても通過します。ここは両方を検証すると回帰に強くなります。

✅ 追加例
         expect.objectContaining({
           label: '頂点の削除',
-          description: expect.stringContaining('Delete キー'),
+          description: expect.stringMatching(/(Delete キー.*右クリック|右クリック.*Delete キー)/),
         }),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/__tests__/help-content.test.ts` around lines 25 - 40, Update the test
that inspects HELP_SECTIONS for the '選択・編集' section so the assertion for the
item with label '頂点の削除' checks that its description contains both 'Delete キー'
and '右クリック' (not just one). Locate the test in help-content.test.ts that finds
HELP_SECTIONS and the expect.objectContaining for label '頂点の削除', and change the
description expectation to require both substrings (e.g., assert description
contains 'Delete キー' AND contains '右クリック') to make the test stricter and prevent
regressions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/components/HelpSidebar.tsx`:
- Around line 17-23: showPulse is created from useRef(...).current so it never
updates, causing help-tab--pulse to re-run whenever the button remounts; replace
the ref with a stateful flag initialized from localStorage (e.g., useState(() =>
!localStorage.getItem(HELP_TAB_SEEN_KEY))) and update localStorage and clear the
state (setShowPulse(false)) inside the useEffect (or on animation end) so the
pulse is consumed once; update references to showPulse, HELP_TAB_SEEN_KEY, and
the useEffect that currently writes localStorage so the class help-tab--pulse
only applies on the true state once.

---

Nitpick comments:
In `@src/lib/__tests__/help-content.test.ts`:
- Around line 25-40: Update the test that inspects HELP_SECTIONS for the '選択・編集'
section so the assertion for the item with label '頂点の削除' checks that its
description contains both 'Delete キー' and '右クリック' (not just one). Locate the
test in help-content.test.ts that finds HELP_SECTIONS and the
expect.objectContaining for label '頂点の削除', and change the description
expectation to require both substrings (e.g., assert description contains
'Delete キー' AND contains '右クリック') to make the test stricter and prevent
regressions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d76d48a0-87c7-476f-9742-26b85e1f1059

📥 Commits

Reviewing files that changed from the base of the PR and between 4e3640b and 85f8266.

📒 Files selected for processing (3)
  • src/components/HelpSidebar.css
  • src/components/HelpSidebar.tsx
  • src/lib/__tests__/help-content.test.ts

@sugama-satsuki sugama-satsuki merged commit f5ebeff into main Mar 17, 2026
2 checks passed
@sugama-satsuki sugama-satsuki deleted the feature/improve-help-sidebar branch March 17, 2026 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant