Skip to content

fix(popover): errors following a full review of the component - #1942

Merged
lskramarov merged 6 commits into
mainfrom
review/popover
Sep 2, 2026
Merged

fix(popover): errors following a full review of the component#1942
lskramarov merged 6 commits into
mainfrom
review/popover

Conversation

@lskramarov

@lskramarov lskramarov commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Summary

The popover surface is rich, but the trigger layer leaked and mis-positioned under ordinary
conditions: a global ScrollDispatcher subscription with no teardown in the default configuration,
stickToWindow wiped by every CDK position re-apply, and a hover mode whose effective leave delay was
0ms — the panel closed before the pointer could cross the 8px gap to it. The confirm variant also
shipped its default strings hardcoded in Russian.

The second commit fixes the close button's RTL placement.

List of notable changes:

  • fixed the untorn-down ScrollDispatcher.scrolled() subscription that leaked the trigger's
    subscriber graph for the lifetime of the app and pinned CDK's global scroll listener
  • fixed stickToWindow being undone by the first ancestor scroll, window resize, or input update
    while the popover is open
  • fixed the hover leave delay: this.leaveDelay ?? 500 was dead because the base initialises the
    field to 0, so hover mode's interactive content was unreachable even for pointer users (WCAG 1.4.13)
    and the auto-hide watchdog burned CPU as an interval(0) the whole time the panel was open
  • fixed the standalone import crashing at DI because the scroll-strategy provider lived only in
    the NgModule
  • added an accessible name for the icon-only close button, and aria-expanded / aria-haspopup /
    aria-controls on the trigger — the default click flow was fully silent for screen-reader users
  • added locale support for KbqPopoverConfirmComponent, whose defaults were hardcoded Russian
    with no locale-service integration; new core/locales/popover-confirm.ts plus entries in all five
    locale files
  • fixed the header-less close button under dir="rtl": inset-inline-end mirrors but the
    physical translateX(50%) did not, so the button landed inside the panel on top of the content —
    the transform is now direction-flipped through the repo's own rtl() mixin
  • added the popover-leave-delay migration, which reports programmatic leaveDelay assignments
    (they no longer stick — the delay is re-derived from trigger unless kbqLeaveDelay was bound), the
    now-readonly onConfirm, and the narrowed placementChange payload

What should reviewers focus on?

  • packages/components/core/locales/popover-confirm.ts and the five locale files — new translated
    strings that need a native check, particularly tk-TM.
  • The leaveDelay input is now a write-only kbqLeaveDelay setter with a tracked "was it bound"
    flag, because TypeScript refuses to override the base class's plain field with an accessor (TS2611)
    and an explicit kbqLeaveDelay="0" has to stay distinguishable from an unbound one.
  • The RTL fix is compiled CSS only; the visual baselines regenerate on CI.

One of ten pull requests from a single review pass (review/*). Every branch carries two commits: the
fixes from the component review, and a second pass over the findings an independent verifier could not
confirm outright.

The branches share files, so they have to be merged one at a time with a rebase in between. Overlap:
packages/components/core/locales/* (7 branches), tools/public_api_guard/components/core.api.md (7),
tools/cspell-locales/*.json (6), packages/e2e/routes.ts (4) and
packages/schematics/src/{collection,migrations}.json (3).

@github-actions github-actions Bot added the bug Something isn't working label Aug 26, 2026
@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit 0e6f08d):

https://koobiq-next--prs-1942-3631iuvm.web.app

(expires Sat, 05 Sep 2026 14:27:32 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

@lskramarov lskramarov self-assigned this Aug 27, 2026
@lskramarov
lskramarov force-pushed the review/popover branch 3 times, most recently from aaae9dd to 8c23016 Compare August 28, 2026 09:07
The popover-leave-delay schematic shipped without a section in the upgrade guide, and
the hover-delay change it reports is the one that has no compile error behind it: a
programmatic leaveDelay assignment is now silently overwritten.
The snapshot came from upstream during the rebase, so it missed the one member the merge
changed. Regenerated from a fresh build.
@lskramarov
lskramarov marked this pull request as ready for review September 1, 2026 16:04
@lskramarov
lskramarov requested review from NikGurev and artembelik and a lite review from Copilot September 1, 2026 16:04

Copilot AI 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.

🟡 Changes recommended

There are a few concrete correctness/documentation issues (including a schematic warning message mismatch and guardrails in popover close paths) that should be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR addresses multiple correctness, accessibility, and i18n issues in the popover component family, plus adds a warn-only migration schematic to help consumers find impacted call sites.

Changes:

  • Fixes popover trigger behavior (scroll subscription teardown, stick-to-window persistence, hover leave-delay defaulting) and improves repositioning stability.
  • Improves accessibility (trigger ARIA attributes, close button accessible name, reduced-motion support, focus restoration behavior).
  • Adds locale-backed defaults for KbqPopoverConfirmComponent and wires them into core locale infrastructure and docs/migrations.
File summaries
File Description
tools/public_api_guard/components/popover.api.md Public API snapshot updates for popover exports and signature changes.
tools/public_api_guard/components/core.api.md Public API snapshot updates for new locale types/tokens/helpers.
tools/cspell-locales/ru.json Adds a new Russian word form for spellchecking.
packages/schematics/src/migrations/popover-leave-delay/schema.ts Migration schematic options interface.
packages/schematics/src/migrations/popover-leave-delay/schema.json JSON schema for the migration schematic.
packages/schematics/src/migrations/popover-leave-delay/README.md Migration documentation describing behavior changes and manual steps.
packages/schematics/src/migrations/popover-leave-delay/index.ts Warn-only schematic implementation that scans for affected call sites.
packages/schematics/src/migrations/popover-leave-delay/index.spec.ts Unit tests for the migration schematic reporting behavior.
packages/schematics/src/migrations/popover-leave-delay/data.ts Defines detection patterns and user-facing warning messages.
packages/schematics/src/migrations.json Registers the new migration for the target version.
packages/schematics/src/collection.json Adds schematic entry so it can be invoked/generated.
packages/docs-examples/components/popover/popover-width/popover-width-example.html Updates docs examples to new prefixed inputs.
packages/docs-examples/components/popover/popover-scroll/popover-scroll-example.ts Updates docs examples to new prefixed inputs.
packages/docs-examples/components/popover/popover-paddings/popover-paddings-example.html Updates docs examples to new prefixed inputs.
packages/docs-examples/components/popover/popover-header/popover-header-example.html Updates docs examples to new prefixed inputs.
packages/docs-examples/components/popover/popover-content/popover-content-example.html Updates docs examples to new prefixed inputs.
packages/docs-examples/components/popover/popover-close/popover-close-example.html Updates docs examples to new prefixed inputs.
packages/docs-examples/components/list/list-intermediate-state/list-intermediate-state-example.html Updates nested popover example to new prefixed inputs.
packages/components/popover/popover.spec.ts Expands unit tests for hover timing, closing behavior, leaks, a11y, and confirm locale behavior.
packages/components/popover/popover.scss Adjusts layering/z-index and fixes RTL close-button positioning.
packages/components/popover/popover.ru.md Updates RU docs for prefixed inputs, close-on-scroll behavior, confirm variant, a11y, and leave-delay semantics.
packages/components/popover/popover.module.ts Simplifies module wiring now that providers move off the NgModule.
packages/components/popover/popover.en.md Updates EN docs for prefixed inputs, confirm variant, a11y, and leave-delay semantics.
packages/components/popover/popover.component.ts Core behavioral fixes (leaveDelay derivation, scroll teardown, focus restore, aria wiring, reduced-motion).
packages/components/popover/popover.component.html Adds conditional dialog role/naming, scrollable region semantics, and refactors close button markup.
packages/components/popover/popover-confirm.component.ts Adds locale-driven defaults and ensures confirm wiring doesn’t stack on updates.
packages/components/popover/popover-confirm.component.html Aligns confirm template with new panel id/trap focus/arrow behavior and a11y labeling.
packages/components/popover/popover-animations.ts Updates animation curves/durations and documents reduced-motion opt-out.
packages/components/popover/e2e.ts Adjusts e2e setup for trigger querying and panel instantiation.
packages/components/popover/e2e.playwright-spec.ts Updates e2e assertion commentary for the hover gap behavior.
packages/components/core/locales/types.ts Adds KbqPopoverConfirmLocaleConfiguration and wires it into locale string data shape.
packages/components/core/locales/tk-TM.ts Adds popoverConfirm localized strings.
packages/components/core/locales/ru-RU.ts Adds popoverConfirm localized strings.
packages/components/core/locales/pt-BR.ts Adds popoverConfirm localized strings.
packages/components/core/locales/es-LA.ts Adds popoverConfirm localized strings.
packages/components/core/locales/en-US.ts Adds popoverConfirm localized strings.
packages/components/core/locales/popover-confirm.ts Implements token/provider/injector helper for confirm-popover locale section.
packages/components/core/locales/popover-confirm.spec.ts Tests locale fallback, locale switching, overrides, and section completeness per locale.
packages/components/core/locales/index.ts Exports the new popover-confirm locale API.
packages/components-dev/popover/template.html Updates dev-app template to new prefixed inputs.
docs/guides/migration.ru.md Documents popover-related migration notes for v20 update.
docs/guides/migration.en.md Documents popover-related migration notes for v20 update.
apps/docs/src/app/components/popover-example/popover-example.component.ts Updates docs app usage to the new prefixed hide-in-viewport input.
Review details

Suppressed comments (1)

packages/components/popover/popover.component.ts:221

  • onClose() calls this.trigger.close() unconditionally; if the component is used without a trigger, clicking the close button will throw. A safe fallback is to close the panel directly when trigger is unset.
    protected onClose(): void {
        this.trigger.close();
    }
  • Files reviewed: 43/43 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/components/popover/popover.component.ts
Comment thread packages/components/popover/popover.component.ts Outdated
Comment thread packages/schematics/src/migrations/popover-leave-delay/data.ts Outdated
`KbqPopoverComponent` is exported, so a consumer can render the panel on its own, and
`ngAfterViewInit` already allowed for a missing trigger — but Escape and the close button
reached through it unguarded. They now hide the panel directly when there is no trigger to
route through, which is also the only case where there is no `kbqPopoverPreventClose` to
honor and nothing to hand focus back to.

Two corrections to the review's own text. The size warning read "Will used default size".
And the `placementChange` note claimed the output emits `KbqPopUpPlacementValues` and that a
`(p: string)` handler stops matching; it emits `string` where it used to emit `any`, so such
a handler is unaffected and only a payload assigned to a non-string breaks. Fixed in the
schematic message and in both migration guides.
@lskramarov
lskramarov merged commit 5e7db14 into main Sep 2, 2026
14 checks passed
@lskramarov
lskramarov deleted the review/popover branch September 2, 2026 17:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants