Skip to content

feat(core): add overflow shadow directives (#DS-3478)#1633

Open
lskramarov wants to merge 5 commits into
mainfrom
feat/DS-3478
Open

feat(core): add overflow shadow directives (#DS-3478)#1633
lskramarov wants to merge 5 commits into
mainfrom
feat/DS-3478

Conversation

@lskramarov

Copy link
Copy Markdown
Contributor

No description provided.

@lskramarov lskramarov self-assigned this Jun 11, 2026
@lskramarov lskramarov added the enhancement New feature or request label Jun 11, 2026
@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown

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

https://koobiq-next--prs-1633-ov2qkikl.web.app

(expires Sat, 20 Jun 2026 15:59:06 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@koobiq koobiq deleted a comment from github-actions Bot Jun 15, 2026
@github-actions

Copy link
Copy Markdown

🚨 Failed to update snapshots.

@github-actions

Copy link
Copy Markdown

🚨 E2E tests failed

Review the report for details.


💡 Comment /approve-snapshots to approve snapshot changes.

@lskramarov

Copy link
Copy Markdown
Contributor Author

/approve-snapshots

@github-actions

Copy link
Copy Markdown

🔄 Updating snapshots.

@github-actions

Copy link
Copy Markdown

✅ Snapshots updated!

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.

Pull request overview

This PR introduces a shared overflow shadow mechanism in @koobiq/components/core (container + top/bottom marker directives + optional scroll-source DI token), and migrates multiple scrollable components (sidepanel, popover, modal, notification-center, content-panel) to use it instead of bespoke overflow checks and CSS class toggles.

Changes:

  • Added KbqOverflowShadowContainer, KbqOverflowShadowTop, KbqOverflowShadowBottom, KbqOverflowShadowState, and KBQ_OVERFLOW_SHADOW_SOURCE to core.
  • Updated KbqScrollbar to implement/provide KbqOverflowShadowSource so overflow shadows can follow the real scroll viewport.
  • Reworked component styles/templates/e2e tests to rely on box-shadow (via the directives) rather than overflow CSS classes.

Reviewed changes

Copilot reviewed 33 out of 34 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/public_api_guard/components/sidepanel.api.md Public API snapshot updates for sidepanel overflow-shadow integration/types.
tools/public_api_guard/components/scrollbar.api.md Public API snapshot updates for KbqScrollbar implementing KbqOverflowShadowSource.
tools/public_api_guard/components/popover.api.md Public API snapshot updates for popover removing old overflow fields and exposing overflow container ref.
tools/public_api_guard/components/notification-center.api.md Public API snapshot updates reflecting removal of old overflow fields.
tools/public_api_guard/components/modal.api.md Public API snapshot updates reflecting removal of old overflow fields/methods.
tools/public_api_guard/components/core.api.md Public API snapshot adds overflow-shadow directives/interfaces/token.
tools/public_api_guard/components/content-panel.api.md Public API snapshot updates for content-panel overflow state and container ref.
packages/e2e/utils/overflow-shadow.ts New Playwright helper to assert overflow shadow presence via computed box-shadow.
packages/e2e/utils/index.ts Re-export the new overflow shadow e2e helper.
packages/components/sidepanel/sidepanel.scss Removes class-based overflow shadow styling (now applied inline by directives/bindings).
packages/components/sidepanel/sidepanel-ref.ts Types bodyOverflow as KbqOverflowShadowState.
packages/components/sidepanel/sidepanel-directives.ts Uses KbqOverflowShadowContainer + signal/effect wiring; header/footer now bind inline box-shadow.
packages/components/sidepanel/e2e.playwright-spec.ts Updates assertions to check computed shadow rather than CSS classes.
packages/components/scrollbar/scrollbar.component.ts Provides KBQ_OVERFLOW_SHADOW_SOURCE and adds getScrollElement() for overflow-shadow container.
packages/components/popover/popover.scss Simplifies header/footer overflow styling (inline shadow now).
packages/components/popover/popover.component.ts Removes manual overflow tracking logic; uses overflow-shadow directives instead.
packages/components/popover/popover.component.html Adds kbqOverflowShadowContainer + top/bottom marker directives; triggers manual checkOverflow() on content mutation.
packages/components/popover/e2e.playwright-spec.ts Updates assertions to check computed shadow rather than CSS classes.
packages/components/notification-center/notification-center.ts Removes manual overflow tracking; imports overflow-shadow directives.
packages/components/notification-center/notification-center.scss Removes class-based overflow shadow styling (inline shadow now).
packages/components/notification-center/notification-center.html Adds overflow-shadow container + markers; customizes bottom shadow token via [shadow].
packages/components/modal/modal.component.ts Removes manual overflow tracking logic; imports overflow-shadow directives.
packages/components/modal/modal.component.html Adds overflow-shadow container + top/bottom markers around modal body.
packages/components/modal/e2e.playwright-spec.ts Updates assertions to check computed shadow rather than CSS classes.
packages/components/modal/_modal-theme.scss Removes class-based overflow shadow styling (inline shadow now).
packages/components/core/public-api.ts Exports the new overflow-shadow entrypoint.
packages/components/core/overflow-shadow/public-api.ts New barrel for overflow-shadow public surface.
packages/components/core/overflow-shadow/overflow-shadow.ts New overflow shadow directives + token/source abstraction.
packages/components/core/overflow-shadow/overflow-shadow.spec.ts Unit tests for container + marker directives and external scroll source behavior.
packages/components/core/overflow-shadow/index.ts New index barrel for overflow-shadow.
packages/components/content-panel/e2e.playwright-spec.ts Updates assertions to check computed shadow rather than CSS classes.
packages/components/content-panel/content-panel.ts Replaces class toggling logic with computed overflow state from KbqOverflowShadowContainer.
packages/components/content-panel/content-panel.scss Removes class-based overflow shadow styling (inline shadow now).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 121 to 123
constructor() {
afterNextRender(() => {
this.checkOverflow();
});
}

/** @docs-private */
protected checkOverflow() {
const nativeElement = this.elementRef.nativeElement;

if (!isHtmlElement(nativeElement)) return;

const { scrollTop, offsetHeight, scrollHeight } = nativeElement;

this.sidepanelRef.bodyOverflow.set({
top: scrollTop > 0,
bottom: scrollTop + offsetHeight < scrollHeight
});
effect(() => this.sidepanelRef.bodyOverflow.set(this.overflowContainer.overflow()));
}
Comment on lines +52 to +54
* In addition to scroll events, the directive observes scroll source size changes via
* `ResizeObserver` — this covers cases where layout changes without a scroll (modal open
* animation, dynamic content load, window resize).
this.destroyRef.onDestroy(() => this.resizeObserver?.disconnect());
}

ngOnInit(): void {

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.

лучше использовать afterNextRender чтобы это точно работало в ssr

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

в конструкторе afterNextRender, а тут только подписки на события..


if (!source) return;

this.resizeObserver = new ResizeObserver(() => this.checkOverflow());

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.

у cdk есть SharedResizeObserver, кажется что лучше его использовать, он удобен тем что возвращает готовый Observable

import { SharedResizeObserver } from '@angular/cdk/observers/private';

Comment thread packages/components/notification-center/notification-center.html Outdated
export class KbqContentPanelFooter {}
export class KbqContentPanelFooter {
/** @docs-private */
protected readonly contentPanel = inject(KbqContentPanel, { optional: true });

@artembelik artembelik Jun 15, 2026

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.

KbqContentPanelFooter и KbqContentPanelHeader не могут быть использованы без KbqContentPanel

Suggested change
protected readonly contentPanel = inject(KbqContentPanel, { optional: true });
protected readonly contentPanel = inject(KbqContentPanel);

@artembelik

Copy link
Copy Markdown
Contributor

тень в шапке еще есть у code-block:
https://github.com/koobiq/angular-components/blob/main/packages/components/code-block/code-block.ts#L488

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants