cps-dialog: focus ring on the dialog frame covers the dialog and blocks all clicks inside it
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 72/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
- 技術スタック
- angular, css, playwright, scss, typescript
- 領域
- frontend
調査の方向性
projects/cps-ui-kit/styles/_mixins.scss の focus-ring ミックスインと、cps-dialog.component.scss の107行目付近にある :focus-visible ルールから始めます。再現手順は、ドラッグ可能なダイアログの例を開き、ヘッダーをクリックし、ArrowDown を押して、elementFromPoint がボタンではなくダイアログを返すことを確認するだけです。リングの疑似要素がクリックを奪わず、リングの見た目が変わらず、focus-ring のテストの隣に置いた Playwright スペックで「Close dialog」を正常にクリックできれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
When a cps-dialog has keyboard focus on its frame, the focus ring drawn around the dialog covers the whole dialog and takes every pointer event. Buttons, inputs and links inside the dialog stop responding to clicks until the focus moves elsewhere.
The state is easy to reach: click on the dialog's header, then press a key. The click focuses the dialog frame (div.cps-dialog[tabindex="-1"]), and the key press makes the browser treat that focus as keyboard focus (:focus-visible matches), which turns the ring on.
Environment
cps-ui-kit21.33.0. The source of 22.3.0 has the same CSS for this ring, but I did not run that version.- Reproduced in Chromium and WebKit (automated browsers).
- Reproduced on the kit's own documentation site, so it does not depend on any application code. I do not know which kit version the site is currently built with.
Steps to reproduce
- Open https://absaoss.github.io/cps-shared-ui/dialog/examples and click the Draggable dialog button.
- In the dialog, click Disable closing. This stops Esc from closing the dialog, which would otherwise hide the problem. (Skipping this step and pressing ArrowDown in step 4 gives the same result.)
- Click on the dialog's header, in a bare part of it.
- Press Esc (or ArrowDown).
- Click anything inside the dialog, for example the Close dialog button.
Expected
The dialog shows its focus ring, and everything inside it still responds to clicks.
Actual
The dialog shows its focus ring, but clicks on everything inside it do nothing. The cursor behaves as if the dialog were one inert block.
Observed in the browser after step 4:
document.activeElementisdiv.cps-dialog, and.matches(':focus-visible')istrue.document.elementFromPoint(...)at the centre of the Close dialog button returnsdiv.cps-dialog, not the button.getComputedStyle(dialog, '::before')iscontent: "",inset: -1px,border: 1px solid,pointer-events: auto.::afteris the same withinset: -2px.- Playwright's click on the button fails with:
<div role="dialog" tabindex="-1" data-testid="cps-dialog" ... class="cps-dialog ..."> intercepts pointer events.
Cause
The dialog frame's focus ring comes from the focus-ring mixin:
projects/cps-ui-kit/src/lib/services/cps-dialog/internal/components/cps-dialog/cps-dialog.component.scss, around line 107:&:focus-visible { @include focus-ring(0.0625rem, 0.125rem, inherit); }projects/cps-ui-kit/styles/_mixins.scss,@mixin focus-ring: it setsposition: relativeon the element and draws the ring with::beforeand::after, bothposition: absolutewith a negativeinsetand a border.
On a small control that is harmless. On the dialog frame the two pseudo-elements are as large as the whole dialog. They are positioned, so they paint above the dialog's non-positioned content, and because pointer-events is left at its default they become the hit-test target for every point inside the dialog.
Esc is only one way in. A dialog whose closeOnEscape is false (or disableClose is set) stays open after Esc, so it is the clearest repro, but any key press after the header click does it: ArrowDown works on the docs site in both browsers. In WebKit, Shift alone does not turn the ring on, but ArrowDown and Esc do.
Suggested fix
The ring is decorative, so it should never be a pointer target. The smallest change is in the mixin, which also protects every other component that uses it:
&::before,
&::after {
content: '';
position: absolute;
pointer-events: none; // the ring is decorative and must never take clicks
border-radius: $radius;
}
If changing the mixin is too broad, put the same pointer-events: none on the ring's pseudo-elements for the dialog frame only.
The ring must stay visible; only its pointer behaviour changes. Other uses of the mixin on large containers (for example the resizable handles in the same file, around lines 195 and 285) may be worth checking for the same effect. I did not test those.
Acceptance criteria
- After clicking the dialog header and pressing Esc (with
closeOnEscape: false) or ArrowDown, buttons and inputs inside the dialog can be clicked. - The focus ring is still drawn exactly as before.
- A Playwright test covers it, next to the existing focus-ring specs under
playwright/cps-ui-kit/components/: open the draggable dialog example, click the header, press ArrowDown, then click Close dialog and expect the dialog to close.
Workaround for applications
.cps-dialog:focus-visible::before,
.cps-dialog:focus-visible::after {
pointer-events: none;
}
- 主要言語
- TypeScript
- スター
- 9
- フォーク
- 8
- 平均マージ
- 1日 6時間
- マージ済み PR(30日)
- 25
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
AbsaOSS/cps-shared-ui のほかの issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
AbsaOSS/cps-shared-ui#875 ·
メンテナーはふだん 1 日以内に返信
-
InputComponent - expand type beyond text/number/password再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープンenhancement library
難易度 1/5 1時間未満 初心者へのやさしさ 85/100
AbsaOSS/cps-shared-ui#644 ·
メンテナーはふだん 1 日以内に返信
-
enhancement
難易度 3/5 1〜2日 初心者へのやさしさ 35/100
AbsaOSS/cps-shared-ui#951 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 62/100
AbsaOSS/cps-shared-ui#950 ·
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 半日 初心者へのやさしさ 55/100
AbsaOSS/cps-shared-ui#949 ·
メンテナーはふだん 1 日以内に返信
AbsaOSS/cps-shared-ui の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
vercel-labs/ui#540 ·
メンテナーはふだん 1 日以内に返信
-
accepted ai-dev ai-implementing
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
livesport/homer#218 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
normalizePropName strips `#` characters from Figma property names instead of only the `#id` suffixオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
figma/code-connect#419 ·
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
-
Negative values skip k/M abbreviation and medium decimal format on line, stacked-area, and tooltipオープン
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
britecharts/britecharts#1255 ·
メンテナーはふだん 1 日以内に返信