From 8d289ca91ce3978d5c2788d7973c2bcf8bdce109 Mon Sep 17 00:00:00 2001 From: masuP9 Date: Thu, 14 May 2026 01:23:01 +0900 Subject: [PATCH 1/2] =?UTF-8?q?refactor(styles):=20:focus=20/=20:focus-vis?= =?UTF-8?q?ible=20=E3=82=92=E6=A8=99=E6=BA=96=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 通常 CSS のフォーカスインジケーターを `:focus { outline: none } + :focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }` のパターン A に統一。 色を `var(--ring)` に一本化し、`var(--primary)` は selected / pressed などの 状態色専用にする。 - CODING_RULES.md: 規約 2 行追記(focus-visible / var(--ring) の標準) - 通常 CSS で var(--primary) を focus 色として使っていた箇所を var(--ring) に置換 - :focus + :focus-visible の冗長な併用を `outline: none` + `:focus-visible` に整理 - :focus-visible 未使用の landmarks に規約適用 - data-grid / grid / treegrid の `--focus-color, #3b82f6` を var(--ring) に統合、 dark mode の `--focus-color: #60a5fa` 定義を削除(テーマ層 --ring が吸収) - grid 系セルは :focus 維持(キーボード/マウス両方でセルハイライトが必要なため) - tree-view の treeitem も box-shadow を var(--ring) ベースに統一 - menubar の trigger / menuitem / submenu-trigger は :focus と :focus-visible を 分離(background は :focus、outline は :focus-visible) - tabs.css の重複 :focus-visible (line 135 と 229) を統合 - forced-colors: active 内のセレクタは既存 :focus を維持 (マウスクリック後の現在位置表示を保つため) Co-Authored-By: Claude Opus 4.7 (1M context) --- CODING_RULES.md | 2 ++ src/patterns/menubar/menubar.css | 24 ++++++++++++++++++++++-- src/styles/patterns/accordion.css | 15 +++++++++------ src/styles/patterns/alert-dialog.css | 19 ++++++++++--------- src/styles/patterns/button.css | 2 +- src/styles/patterns/carousel.css | 15 ++++++--------- src/styles/patterns/checkbox.css | 2 +- src/styles/patterns/combobox.css | 15 ++++++--------- src/styles/patterns/data-grid.css | 18 ++++++++---------- src/styles/patterns/dialog.css | 10 ++++------ src/styles/patterns/disclosure.css | 6 +++++- src/styles/patterns/feed.css | 12 ++++++++++++ src/styles/patterns/grid.css | 7 +++---- src/styles/patterns/landmarks.css | 16 ++++++++++++++++ src/styles/patterns/link.css | 2 +- src/styles/patterns/listbox.css | 9 ++++----- src/styles/patterns/menu-button.css | 12 +++++------- src/styles/patterns/radio-group.css | 2 +- src/styles/patterns/switch.css | 2 +- src/styles/patterns/tabs.css | 18 ++++++++++-------- src/styles/patterns/toggle-button.css | 2 +- src/styles/patterns/toolbar.css | 2 +- src/styles/patterns/tree-view.css | 6 +----- src/styles/patterns/treegrid.css | 7 +++---- 24 files changed, 133 insertions(+), 92 deletions(-) diff --git a/CODING_RULES.md b/CODING_RULES.md index a1fde1bc..808831c2 100644 --- a/CODING_RULES.md +++ b/CODING_RULES.md @@ -476,3 +476,5 @@ const config = thirdPartyLib.getConfig() as Config; // TODO: 型定義改善待 - キーボードナビゲーション対応必須 - スクリーンリーダー対応 - `prefers-contrast` メディアクエリの値は `more` / `less` / `no-preference` / `custom` を使う(`high` / `low` は仕様にない値) +- フォーカスインジケーターの標準: `:focus-visible` に `outline: 2px solid var(--ring); outline-offset: 2px;`(内側に出したい場合のみ `outline-offset: -2px`)。クリック時の outline 残りを抑えるため `:focus { outline: none; }` を明示する。セル系(grid 等)で outline が扱いづらいときに限り `box-shadow: inset 0 0 0 2px var(--ring);` を許可 +- フォーカス色は `var(--ring)` に統一。`var(--primary)` は selected / pressed / expanded などの状態色専用で focus 表示には使わない diff --git a/src/patterns/menubar/menubar.css b/src/patterns/menubar/menubar.css index cd35496a..ef7afb6b 100644 --- a/src/patterns/menubar/menubar.css +++ b/src/patterns/menubar/menubar.css @@ -92,6 +92,11 @@ .apg-menubar-trigger:focus, .apg-menubar [data-menubar-trigger]:focus { + outline: none; +} + +.apg-menubar-trigger:focus-visible, +.apg-menubar [data-menubar-trigger]:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; } @@ -236,9 +241,19 @@ .apg-menubar [data-menubar-menu] [role='menuitem']:focus, .apg-menubar [data-menubar-menu] [role='menuitemcheckbox']:focus, .apg-menubar [data-menubar-menu] [role='menuitemradio']:focus { + outline: none; + background-color: oklch(0.95 0 0); +} + +.apg-menubar-menuitem:focus-visible, +.apg-menubar-menu [role='menuitem']:focus-visible, +.apg-menubar-menu [role='menuitemcheckbox']:focus-visible, +.apg-menubar-menu [role='menuitemradio']:focus-visible, +.apg-menubar [data-menubar-menu] [role='menuitem']:focus-visible, +.apg-menubar [data-menubar-menu] [role='menuitemcheckbox']:focus-visible, +.apg-menubar [data-menubar-menu] [role='menuitemradio']:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; - background-color: oklch(0.95 0 0); } /* Active state - pressed */ @@ -325,9 +340,14 @@ .apg-menubar-submenu-trigger:focus, .apg-menubar [data-submenu-trigger]:focus { + outline: none; + background-color: oklch(0.95 0 0); +} + +.apg-menubar-submenu-trigger:focus-visible, +.apg-menubar [data-submenu-trigger]:focus-visible { outline: 2px solid var(--ring); outline-offset: -2px; - background-color: oklch(0.95 0 0); } /* Active state - pressed or submenu open */ diff --git a/src/styles/patterns/accordion.css b/src/styles/patterns/accordion.css index e824f60d..7795bd8a 100644 --- a/src/styles/patterns/accordion.css +++ b/src/styles/patterns/accordion.css @@ -65,15 +65,14 @@ } .apg-accordion-trigger:focus { - outline: 2px solid var(--primary); - outline-offset: -2px; - z-index: 1; - position: relative; + outline: none; } .apg-accordion-trigger:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; + z-index: 1; + position: relative; } .apg-accordion-trigger:disabled { @@ -135,7 +134,11 @@ } .apg-accordion-panel:focus { - outline: 2px solid var(--primary); + outline: none; +} + +.apg-accordion-panel:focus-visible { + outline: 2px solid var(--ring); outline-offset: -2px; } diff --git a/src/styles/patterns/alert-dialog.css b/src/styles/patterns/alert-dialog.css index ef052626..2abcd8ee 100644 --- a/src/styles/patterns/alert-dialog.css +++ b/src/styles/patterns/alert-dialog.css @@ -115,12 +115,11 @@ body:has(dialog.apg-alert-dialog[open]) { } .apg-alert-dialog-cancel:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-alert-dialog-cancel:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } @@ -137,12 +136,11 @@ body:has(dialog.apg-alert-dialog[open]) { } .apg-alert-dialog-confirm:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-alert-dialog-confirm:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } @@ -159,6 +157,10 @@ body:has(dialog.apg-alert-dialog[open]) { } .apg-alert-dialog-confirm--danger:focus { + outline: none; +} + +.apg-alert-dialog-confirm--danger:focus-visible { outline: 2px solid var(--destructive); outline-offset: 2px; } @@ -169,12 +171,11 @@ body:has(dialog.apg-alert-dialog[open]) { } .apg-alert-dialog-trigger:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-alert-dialog-trigger:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/button.css b/src/styles/patterns/button.css index 604fade3..40b71e22 100644 --- a/src/styles/patterns/button.css +++ b/src/styles/patterns/button.css @@ -35,7 +35,7 @@ } .apg-button:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/carousel.css b/src/styles/patterns/carousel.css index 79f5e8aa..6e17bfb1 100644 --- a/src/styles/patterns/carousel.css +++ b/src/styles/patterns/carousel.css @@ -201,8 +201,7 @@ } .apg-carousel-play-pause:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-carousel-play-pause[data-playing='true'] { @@ -237,9 +236,7 @@ } .apg-carousel-tab:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; - border-radius: 50%; + outline: none; } /* Tab Indicator (Visual Dot) */ @@ -298,8 +295,7 @@ .apg-carousel-prev:focus, .apg-carousel-next:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-carousel-prev:active, @@ -336,14 +332,15 @@ /* Focus Enhancement for Keyboard Users */ .apg-carousel-tab:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; + border-radius: 50%; } .apg-carousel-play-pause:focus-visible, .apg-carousel-prev:focus-visible, .apg-carousel-next:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/checkbox.css b/src/styles/patterns/checkbox.css index 76428f47..1013fb10 100644 --- a/src/styles/patterns/checkbox.css +++ b/src/styles/patterns/checkbox.css @@ -48,7 +48,7 @@ apg-checkbox { /* Focus state */ .apg-checkbox-input:focus-visible + .apg-checkbox-control { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/combobox.css b/src/styles/patterns/combobox.css index 40372b24..b48c4539 100644 --- a/src/styles/patterns/combobox.css +++ b/src/styles/patterns/combobox.css @@ -51,8 +51,12 @@ .apg-combobox-input:focus { outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 20%, transparent); +} + +.apg-combobox-input:focus-visible { + outline: none; + border-color: var(--ring); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--ring) 30%, transparent); } .apg-combobox-input:disabled { @@ -198,13 +202,6 @@ } } -/* Focus Enhancement for Keyboard Users */ -.apg-combobox-input:focus-visible { - outline: none; - border-color: var(--primary); - box-shadow: 0 0 0 2px color-mix(in srgb, var(--primary) 20%, transparent); -} - /* Windows High Contrast Mode */ @media (forced-colors: active) { .apg-combobox-input { diff --git a/src/styles/patterns/data-grid.css b/src/styles/patterns/data-grid.css index c7245ce4..be48bb9e 100644 --- a/src/styles/patterns/data-grid.css +++ b/src/styles/patterns/data-grid.css @@ -59,34 +59,34 @@ } .apg-data-grid-header.sortable:focus { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--header-focus-bg, #e0f2fe); } .apg-data-grid:focus-within .apg-data-grid-header.sortable.focused { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--header-focus-bg, #e0f2fe); } /* Header checkbox cell focus style */ .apg-data-grid-header.apg-data-grid-checkbox-cell:focus { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--header-focus-bg, #e0f2fe); } .apg-data-grid:focus-within .apg-data-grid-header.apg-data-grid-checkbox-cell.focused { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--header-focus-bg, #e0f2fe); } /* Data row checkbox cell focus style (match header checkbox cell) */ .apg-data-grid-cell.apg-data-grid-checkbox-cell:focus { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--header-focus-bg, #e0f2fe); } .apg-data-grid:focus-within .apg-data-grid-cell.apg-data-grid-checkbox-cell.focused { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--header-focus-bg, #e0f2fe); } @@ -144,12 +144,12 @@ /* Focus state */ .apg-data-grid-cell:focus { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--focus-bg, #eff6ff); } .apg-data-grid:focus-within .apg-data-grid-cell.focused { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--focus-bg, #eff6ff); } @@ -424,7 +424,6 @@ --header-hover-bg: #374151; --header-focus-bg: #1e3a5f; --row-header-bg: #1f2937; - --focus-color: #60a5fa; --focus-bg: #1e3a5f; --selected-bg: #1e3a5f; --selected-focus-bg: #1e4a7f; @@ -455,7 +454,6 @@ --header-hover-bg: #374151; --header-focus-bg: #1e3a5f; --row-header-bg: #1f2937; - --focus-color: #60a5fa; --focus-bg: #1e3a5f; --selected-bg: #1e3a5f; --selected-focus-bg: #1e4a7f; diff --git a/src/styles/patterns/dialog.css b/src/styles/patterns/dialog.css index 63afcce7..d4134725 100644 --- a/src/styles/patterns/dialog.css +++ b/src/styles/patterns/dialog.css @@ -104,12 +104,11 @@ dialog.apg-dialog:not([open]) { } .apg-dialog-close:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-dialog-close:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } @@ -133,12 +132,11 @@ dialog.apg-dialog:not([open]) { } .apg-dialog-trigger:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-dialog-trigger:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/disclosure.css b/src/styles/patterns/disclosure.css index ff15e17a..4cf6060a 100644 --- a/src/styles/patterns/disclosure.css +++ b/src/styles/patterns/disclosure.css @@ -37,8 +37,12 @@ background: color-mix(in srgb, var(--background) 90%, var(--foreground)); } +.apg-disclosure-trigger:focus { + outline: none; +} + .apg-disclosure-trigger:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; z-index: 1; position: relative; diff --git a/src/styles/patterns/feed.css b/src/styles/patterns/feed.css index 97bfa87c..66d71a97 100644 --- a/src/styles/patterns/feed.css +++ b/src/styles/patterns/feed.css @@ -78,6 +78,10 @@ } .apg-feed-article-link:focus { + outline: none; +} + +.apg-feed-article-link:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; border-radius: 0.25rem; @@ -138,6 +142,10 @@ } .apg-feed-demo-button:focus { + outline: none; +} + +.apg-feed-demo-button:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } @@ -166,6 +174,10 @@ } .apg-feed-search-input:focus { + outline: none; +} + +.apg-feed-search-input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; border-color: var(--ring); diff --git a/src/styles/patterns/grid.css b/src/styles/patterns/grid.css index 5d572695..76ab82b5 100644 --- a/src/styles/patterns/grid.css +++ b/src/styles/patterns/grid.css @@ -72,13 +72,14 @@ /* Focus state - only show when cell actually has focus */ .apg-grid-cell:focus { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + outline: none; + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--focus-bg, #eff6ff); } /* Show focused class styling only when grid has focus */ .apg-grid:focus-within .apg-grid-cell.focused { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--focus-bg, #eff6ff); } @@ -152,7 +153,6 @@ --border-color: #374151; --header-bg: #1f2937; --row-header-bg: #1f2937; - --focus-color: #60a5fa; --focus-bg: #1e3a5f; --selected-bg: #1e3a5f; --selected-focus-bg: #1e4a7f; @@ -167,7 +167,6 @@ --border-color: #374151; --header-bg: #1f2937; --row-header-bg: #1f2937; - --focus-color: #60a5fa; --focus-bg: #1e3a5f; --selected-bg: #1e3a5f; --selected-focus-bg: #1e4a7f; diff --git a/src/styles/patterns/landmarks.css b/src/styles/patterns/landmarks.css index 303758d7..7abb51ca 100644 --- a/src/styles/patterns/landmarks.css +++ b/src/styles/patterns/landmarks.css @@ -259,6 +259,10 @@ } .apg-landmark-search-input:focus { + outline: none; +} + +.apg-landmark-search-input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } @@ -278,6 +282,10 @@ } .apg-landmark-search-button:focus { + outline: none; +} + +.apg-landmark-search-button:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } @@ -310,6 +318,10 @@ } .apg-landmark-input:focus { + outline: none; +} + +.apg-landmark-input:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } @@ -330,6 +342,10 @@ } .apg-landmark-submit:focus { + outline: none; +} + +.apg-landmark-submit:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/link.css b/src/styles/patterns/link.css index b98ad369..69dc62cd 100644 --- a/src/styles/patterns/link.css +++ b/src/styles/patterns/link.css @@ -20,7 +20,7 @@ } .apg-link:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; border-radius: 2px; } diff --git a/src/styles/patterns/listbox.css b/src/styles/patterns/listbox.css index 79e446eb..ac3bd7c8 100644 --- a/src/styles/patterns/listbox.css +++ b/src/styles/patterns/listbox.css @@ -89,9 +89,7 @@ } .apg-listbox-option:focus { - outline: 2px solid var(--primary); - outline-offset: -2px; - z-index: 1; + outline: none; } .apg-listbox-option[aria-selected='true'] { @@ -121,8 +119,9 @@ /* Focus Enhancement for Keyboard Users */ .apg-listbox-option:focus-visible { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: 2px solid var(--ring); + outline-offset: -2px; + z-index: 1; } /* Windows High Contrast Mode */ diff --git a/src/styles/patterns/menu-button.css b/src/styles/patterns/menu-button.css index eac723b7..2b78bb6f 100644 --- a/src/styles/patterns/menu-button.css +++ b/src/styles/patterns/menu-button.css @@ -52,8 +52,7 @@ } .apg-menu-button-trigger:focus { - outline: 2px solid var(--primary); - outline-offset: 2px; + outline: none; } .apg-menu-button-trigger:active { @@ -107,9 +106,7 @@ } .apg-menu-button-item:focus { - outline: 2px solid var(--primary); - outline-offset: -2px; - z-index: 1; + outline: none; background: color-mix(in srgb, var(--primary) 10%, transparent); } @@ -138,13 +135,14 @@ /* Focus Enhancement for Keyboard Users */ .apg-menu-button-trigger:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } .apg-menu-button-item:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: -2px; + z-index: 1; } /* Windows High Contrast Mode */ diff --git a/src/styles/patterns/radio-group.css b/src/styles/patterns/radio-group.css index 3b518fe4..ac5c89df 100644 --- a/src/styles/patterns/radio-group.css +++ b/src/styles/patterns/radio-group.css @@ -60,7 +60,7 @@ apg-radio-group { /* Focus state */ .apg-radio:focus-visible .apg-radio-control { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/switch.css b/src/styles/patterns/switch.css index d3eb9e0d..68f53875 100644 --- a/src/styles/patterns/switch.css +++ b/src/styles/patterns/switch.css @@ -21,7 +21,7 @@ apg-switch { } .apg-switch:focus-visible .apg-switch-track { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/tabs.css b/src/styles/patterns/tabs.css index 9808f39b..a36101fb 100644 --- a/src/styles/patterns/tabs.css +++ b/src/styles/patterns/tabs.css @@ -132,8 +132,12 @@ color: var(--foreground); } +.apg-tab:focus { + outline: none; +} + .apg-tab:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: -2px; z-index: 1; } @@ -201,8 +205,12 @@ min-height: 200px; } +.apg-tabpanel:focus { + outline: none; +} + .apg-tabpanel:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: -2px; } @@ -225,12 +233,6 @@ } } -/* Focus Enhancement for Keyboard Users */ -.apg-tab:focus-visible { - outline: 2px solid var(--primary); - outline-offset: 2px; -} - /* Windows High Contrast Mode */ @media (forced-colors: active) { .apg-tabs { diff --git a/src/styles/patterns/toggle-button.css b/src/styles/patterns/toggle-button.css index 3ff031f7..67a39232 100644 --- a/src/styles/patterns/toggle-button.css +++ b/src/styles/patterns/toggle-button.css @@ -25,7 +25,7 @@ outline: none; box-shadow: 0 0 0 2px var(--background), - 0 0 0 4px var(--primary); + 0 0 0 4px var(--ring); } .apg-toggle-button:disabled { diff --git a/src/styles/patterns/toolbar.css b/src/styles/patterns/toolbar.css index 3b2669d9..5a3fb73e 100644 --- a/src/styles/patterns/toolbar.css +++ b/src/styles/patterns/toolbar.css @@ -45,7 +45,7 @@ } .apg-toolbar-button:focus-visible { - outline: 2px solid var(--primary); + outline: 2px solid var(--ring); outline-offset: 2px; } diff --git a/src/styles/patterns/tree-view.css b/src/styles/patterns/tree-view.css index b5a447be..0e2a4089 100644 --- a/src/styles/patterns/tree-view.css +++ b/src/styles/patterns/tree-view.css @@ -117,10 +117,6 @@ outline: none; } -.apg-treeview-item:focus > .apg-treeview-item-content { - box-shadow: inset 0 0 0 2px var(--primary); -} - /* Selected state */ .apg-treeview-item[aria-selected='true'] > .apg-treeview-item-content { background: color-mix(in srgb, var(--primary) 10%, transparent); @@ -160,7 +156,7 @@ /* Focus Enhancement for Keyboard Users */ .apg-treeview-item:focus-visible > .apg-treeview-item-content { - box-shadow: inset 0 0 0 2px var(--primary); + box-shadow: inset 0 0 0 2px var(--ring); } /* Windows High Contrast Mode */ diff --git a/src/styles/patterns/treegrid.css b/src/styles/patterns/treegrid.css index 047e7c6f..a7b349a6 100644 --- a/src/styles/patterns/treegrid.css +++ b/src/styles/patterns/treegrid.css @@ -118,13 +118,14 @@ /* Focus state - only show when cell actually has focus */ .apg-treegrid-cell:focus { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + outline: none; + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--focus-bg, #eff6ff); } /* Show focused class styling only when treegrid has focus */ .apg-treegrid:focus-within .apg-treegrid-cell.focused { - box-shadow: inset 0 0 0 2px var(--focus-color, #3b82f6); + box-shadow: inset 0 0 0 2px var(--ring); background-color: var(--focus-bg, #eff6ff); } @@ -212,7 +213,6 @@ --border-color: #374151; --header-bg: #1f2937; --row-header-bg: #1f2937; - --focus-color: #60a5fa; --focus-bg: #1e3a5f; --selected-bg: #1e3a5f; --selected-focus-bg: #1e4a7f; @@ -228,7 +228,6 @@ --border-color: #374151; --header-bg: #1f2937; --row-header-bg: #1f2937; - --focus-color: #60a5fa; --focus-bg: #1e3a5f; --selected-bg: #1e3a5f; --selected-focus-bg: #1e4a7f; From 254544d41196549633876df5ddbcd50fd071e263 Mon Sep 17 00:00:00 2001 From: masuP9 Date: Thu, 14 May 2026 01:23:01 +0900 Subject: [PATCH 2/2] chore: bump version to 0.3.7 Co-Authored-By: Claude Opus 4.7 (1M context) --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index b917bb98..a5f52250 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "apg-patterns-examples", - "version": "0.3.3", + "version": "0.3.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "apg-patterns-examples", - "version": "0.3.3", + "version": "0.3.7", "license": "MIT", "dependencies": { "@astrojs/compiler-rs": "^0.1.10", diff --git a/package.json b/package.json index 30a5a515..af0e0d50 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "apg-patterns-examples", "type": "module", - "version": "0.3.6", + "version": "0.3.7", "private": false, "description": "Accessible UI components following WAI-ARIA APG patterns. Multi-framework implementations in React, Vue, Svelte, and Astro with documentation and tests.", "author": "masuP9",