Skip to content

✨ feat(scroll-to-top): add new scroll to top component#392

Open
devpedromgoncalves wants to merge 2 commits intozard-ui:masterfrom
devpedromgoncalves:feat/#scroll-to-top
Open

✨ feat(scroll-to-top): add new scroll to top component#392
devpedromgoncalves wants to merge 2 commits intozard-ui:masterfrom
devpedromgoncalves:feat/#scroll-to-top

Conversation

@devpedromgoncalves
Copy link

@devpedromgoncalves devpedromgoncalves commented Jan 3, 2026

What was done? 📝

Added a new Scroll to Top component with the following features:

✨ Floating button that appears when scrolling down (configurable threshold);
🎨 Three visual variants: default, outline, subtle;
📏 Three size options: sm, md, lg;
🎯 Two scroll targets: window (global page scroll) or parent (container scroll);
♿ Full accessibility support with ARIA labels and keyboard navigation;
🌈 Theme-aware using semantic color tokens (works with all 5 ZardUI themes + light/dark modes);
📱 Responsive and smooth scroll behavior;
🧪 Complete test coverage (14 tests);

Screenshots or GIFs 📸

image image image image

Link to Issue 🔗

None - This is a new componente addition with no issues attached.

Type of change 🏗

  • New feature (non-breaking change that adds functionality)
  • Bug fix (non-breaking change that fixes an issue)
  • Refactor (non-breaking change that improves the code or technical debt)
  • Chore (none of the above, such as upgrading libraries)

Breaking change 🚨

None - This is a new component addition with no breaking changes.

Checklist 🧐

  • Tested on Chrome
  • Tested on Safari
  • Tested on Firefox
  • No errors in the console
  • Signal-based inputs
  • OnPush change detection strategy
  • CVA for variants
  • Standalone component
  • Full TypeScript type safety

Summary by CodeRabbit

Release Notes

  • New Features

    • Added Scroll To Top component with multiple size and style variants, supporting both window and parent container scrolling targets.
  • Documentation

    • Added API reference and overview documentation for the new Scroll To Top component.
  • Tests

    • Added comprehensive unit test coverage for the Scroll To Top component.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 3, 2026

Note

.coderabbit.yaml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'tools', 'path_instructions'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
📝 Walkthrough

Walkthrough

A new Scroll To Top component is introduced with three demo variants, comprehensive documentation, and unit tests. The component is integrated into the library's public API and demo registry, with barrel exports updated accordingly.

Changes

Cohort / File(s) Summary
Component Implementation
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
Standalone Angular component with scroll event detection, visibility toggling (200px threshold), configurable target (window/parent), smooth scrolling animation, and proper listener cleanup on destroy
Styling & Variants
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
CVA pattern definitions for variant (default/outline/subtle) and size (sm/md/lg) configurations with default variants
Demo Components
libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts, sizes.ts, variants.ts, scroll-to-top.ts
Three standalone demo components showcasing default behavior, size variants, and visual variants; metadata aggregation in scroll-to-top.ts
Documentation
libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md, api.md
Overview describing functionality and API reference with inputs, methods, and properties
Testing
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
Unit tests covering visibility toggling, scroll threshold behavior, smooth scrolling, variant/size class generation, icon sizing, and listener cleanup
Public API & Exports
libs/zard/src/index.ts, libs/zard/src/lib/shared/components/index.ts, libs/zard/src/lib/shared/components/scroll-to-top/index.ts
New barrel export consolidating scroll-to-top in component index and main library index
Demo & Routing Registration
apps/web/src/app/shared/constants/components.constant.ts, routes.constant.ts
SCROLL_TO_TOP added to demo component registry and routing with path /docs/components/scroll-to-top

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Component as ZardScrollToTopComponent
    participant ScrollTarget as Window/<br/>Parent Element
    participant UI as Button & DOM

    Note over Component: Component Init
    Component->>ScrollTarget: Attach scroll listener<br/>(constructor)
    
    rect rgb(200, 220, 255)
    Note over User,UI: Scroll Event Phase
    User->>ScrollTarget: Scroll down >200px
    ScrollTarget->>Component: Emit scroll event
    Component->>Component: Update _visible signal<br/>(true)
    Component->>UI: Re-render button<br/>(visible)
    end
    
    rect rgb(220, 240, 220)
    Note over User,UI: Click & Scroll Phase
    User->>UI: Click scroll-to-top button
    UI->>Component: Call scrollToTop()
    Component->>ScrollTarget: Execute smooth scroll<br/>(scrollY/scrollLeft = 0)
    ScrollTarget->>ScrollTarget: Animate to top
    end
    
    rect rgb(240, 220, 220)
    Note over Component: Cleanup Phase
    User->>Component: Destroy component
    Component->>ScrollTarget: Remove scroll listener<br/>(ngOnDestroy)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

The change introduces a complete new component with multiple files across different concerns (implementation, styling, demos, docs, tests). While individual files follow consistent patterns, the logic density in the component (scroll listener setup, visibility toggling, dual-target support, smooth scrolling) and spread across ~13 files requires careful verification of edge cases, browser compatibility handling, and integration correctness. The CVA pattern and demo components follow established conventions but need validation against existing component patterns.

Possibly related PRs

Suggested reviewers

  • Luizgomess
  • ribeiromatheuss
  • srizzon

Poem

🚀 A button floats in digital skies,
Watching scroll events with clever eyes,
When distances grow beyond 200,
It springs to life—smooth sailing, it's true!
Back to the top with a graceful glide. ✨

Note: Modern Angular best practices (v16+) recommend using signal-based input() instead of @Input() decorators for stronger reactivity and type safety. Consider this pattern for future component iterations.

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely describes the main change: adding a new Scroll to Top component. It is specific, clear, and follows conventional commit formatting with the component name.
Description check ✅ Passed The description comprehensively covers all template sections: what was done with detailed features, screenshots/GIFs, type of change (new feature selected), breaking changes (none), and completed checklist items. It follows the required template structure.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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: 8

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 184ffd6 and ba724fb.

⛔ Files ignored due to path filters (11)
  • .prettierrc is excluded by none and included by none
  • apps/web/public/components/scroll-to-top/demo/default.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/components/scroll-to-top/demo/sizes.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/components/scroll-to-top/demo/small.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/components/scroll-to-top/demo/subtle.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/components/scroll-to-top/demo/variants.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/components/scroll-to-top/doc/api.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/components/scroll-to-top/doc/overview.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/installation/cli/add-scroll-to-top.md is excluded by !apps/web/public/** and included by apps/**
  • apps/web/public/installation/manual/scroll-to-top.md is excluded by !apps/web/public/** and included by apps/**
  • package-lock.json is excluded by !**/package-lock.json and included by none
📒 Files selected for processing (14)
  • apps/web/src/app/shared/constants/components.constant.ts
  • apps/web/src/app/shared/constants/routes.constant.ts
  • libs/zard/src/index.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md
  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
🧰 Additional context used
📓 Path-based instructions (3)
libs/zard/**/*.{css,ts}

📄 CodeRabbit inference engine (CLAUDE.md)

Use CSS custom properties for design tokens and theming in the component library

Files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use path aliases @zard/* to map to libs/zard/src/lib/* in imports

Files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
  • apps/web/src/app/shared/constants/routes.constant.ts
**/*.spec.ts

📄 CodeRabbit inference engine (CONTRIBUTING.md)

Use Jest with @happy-dom/jest-environment and Angular TestBed utilities for testing

Files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
🧠 Learnings (45)
📓 Common learnings
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Keep commit messages in present tense, single line format with scope and description (e.g., '✨ feat(popover): add popover component')
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Add barrel exports for all new components in libs/zard/src/lib/components/components.ts
Learnt from: mikij
Repo: zard-ui/zardui PR: 352
File: apps/web/src/app/domain/components/sidebar/scroll-on-active.directive.ts:23-27
Timestamp: 2025-11-30T19:07:11.572Z
Learning: In apps/web/src/app/domain/components/sidebar/scroll-on-active.directive.ts, the guard checking if scrollIntoView exists before calling it is necessary due to mobile browser compatibility issues. Physical testing on mobile devices shows scrollIntoView may not be present or functional. This defensive pattern should be kept despite scrollIntoView being part of the standard DOM API.
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/demo/**/*.ts : Create demo components in the `demo/` folder with a main export, default example, and variant examples
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/*/demo/*.ts : Create demo examples in the demo/ folder with structured exports containing name, code, and component properties
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Export all components in `libs/zard/src/lib/components/components.ts` for public API

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/components.ts : Add barrel exports for all new components in libs/zard/src/lib/components/components.ts

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md
  • libs/zard/src/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
  • apps/web/src/app/shared/constants/routes.constant.ts
📚 Learning: 2025-11-30T13:27:41.206Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 348
File: libs/zard/src/lib/components/popover/popover.component.ts:28-29
Timestamp: 2025-11-30T13:27:41.206Z
Learning: In libs/zard/src/lib/components/core/**/*.ts files (core utilities, plugins, and providers), use relative imports for intra-core dependencies because the ZardUI CLI performs path transformations during component installation. The CLI expects specific relative path patterns and transforms them to the target project structure. For all other component imports and application code, use zard/* path aliases.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/index.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/demo/**/*.ts : Create demo components in the `demo/` folder with a main export, default example, and variant examples

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/index.ts
📚 Learning: 2025-12-15T11:43:06.831Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 373
File: libs/zard/src/lib/shared/components/select/select.component.ts:33-33
Timestamp: 2025-12-15T11:43:06.831Z
Learning: In files under libs/zard/src/lib/**/*.{ts,tsx,js}, prefer the @/ path alias for imports that map to libs/zard/src/lib/* directories. For example, write import { mergeClasses } from '@/shared/utils/merge-classes' instead of using the 'zard/' alias. This improves path readability and aligns with the project's alias configuration.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use mergeClasses utility from zard/shared/utils for combining CVA variants with custom classes

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-11-30T08:50:23.436Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 348
File: libs/zard/src/lib/components/core/providezard.ts:0-0
Timestamp: 2025-11-30T08:50:23.436Z
Learning: In libs/zard/src/lib/components/core/providezard.ts, the import paths `../core/event-manager-plugins/...` are intentionally structured this way because the ZardUI CLI transforms them to 'shared/components/core/event-manager-plugins/...' format. Other relative path combinations don't work with the current CLI implementation. This path pattern should not be simplified until the CLI transformation logic is updated.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/index.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/*/demo/*.ts : Create demo examples in the demo/ folder with structured exports containing name, code, and component properties

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/index.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Ensure components are standalone Angular components

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Create components as standalone components with `standalone: true` in Angular

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.variants.ts : Use CVA (Class Variance Authority) for type-safe styling variants in components

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.variants.ts : Use CVA (Class Variance Authority) for typed variants in component styling

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
📚 Learning: 2025-12-13T11:50:50.088Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 372
File: libs/zard/src/lib/shared/components/card/card.component.spec.ts:86-88
Timestamp: 2025-12-13T11:50:50.088Z
Learning: Do not flag or require removing standalone: true for test components (*.spec.ts) and demo components (demo/*.ts) within libs/zard/src/lib/shared/components/**.ts. In these contexts, an explicit standalone: true flag is acceptable; apply this exclusion when reviewing files under this path.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-21T21:17:39.497Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 383
File: libs/zard/src/lib/shared/components/carousel/carousel.component.ts:114-115
Timestamp: 2025-12-21T21:17:39.497Z
Learning: In Angular components that use signal inputs (Input()) with types from external libraries (e.g., Embla Carousel), add explicit type annotations to prevent TypeScript IDE errors about inferred types referencing non-portable node_modules paths. For example, declare a readonly typed input like: readonly zOptions: InputSignal<EmblaOptionsType> = input<EmblaOptionsType>(...). This explicit annotation helps avoid the error cannot be named without a reference to node_modules. Apply this pattern to components in the shared carousel area (and similar components) whenever an external library type is used in an InputSignal to ensure type safety and IDE compatibility.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.spec.ts : Use Angular TestBed and ComponentFixture utilities for testing components

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.spec.ts : Place tests co-located with components using the .spec.ts naming convention

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.spec.ts : Co-locate test files with components using `.spec.ts` suffix next to component files

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
📚 Learning: 2025-11-26T11:20:45.264Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 348
File: libs/zard/src/lib/components/select/select.component.spec.ts:79-88
Timestamp: 2025-11-26T11:20:45.264Z
Learning: In ZardUI select component tests (libs/zard/src/lib/components/select/select.component.spec.ts), use fakeAsync() with flush() instead of setTimeout because the component uses setTimeout(..., 0) for focus management, which requires advancing macrotasks in tests.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
📚 Learning: 2025-11-30T19:07:11.572Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 352
File: apps/web/src/app/domain/components/sidebar/scroll-on-active.directive.ts:23-27
Timestamp: 2025-11-30T19:07:11.572Z
Learning: In apps/web/src/app/domain/components/sidebar/scroll-on-active.directive.ts, the guard checking if scrollIntoView exists before calling it is necessary due to mobile browser compatibility issues. Physical testing on mobile devices shows scrollIntoView may not be present or functional. This defensive pattern should be kept despite scrollIntoView being part of the standard DOM API.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to **/*.spec.ts : Use Jest with happy-dom/jest-environment and Angular TestBed utilities for testing

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use OnPush change detection strategy in Angular components: `changeDetection: ChangeDetectionStrategy.OnPush`

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Use Jest with `happy-dom/jest-environment` for testing Angular components

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
📚 Learning: 2025-11-14T22:52:09.135Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 326
File: libs/zard/src/lib/components/input/float.label.component.ts:71-0
Timestamp: 2025-11-14T22:52:09.135Z
Learning: In libs/zard/src/lib/components/*/*.component.ts files, move HostListener and HostBinding to the Component decorator's host property instead of using decorators on class members (e.g., host: { '(input)': 'onInput()' }).

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Implement TailwindCSS v4 with PostCSS for styling and use class merging with tailwind-merge to resolve conflicts

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use `mergeClasses()` utility with `clsx` and `tailwind-merge` to resolve class conflicts in component styling

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/**/*.{css,ts} : Use CSS custom properties for design tokens and theming in the component library

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts
📚 Learning: 2025-12-21T00:12:01.342Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-12-21T00:12:01.342Z
Learning: Applies to libs/blocks/src/lib/**/*.component.ts : Block component files must use the .component.ts extension and should be standalone Angular components with explicit imports from ReactiveFormsModule and ZardUI components

Applied to files:

  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use ChangeDetectionStrategy.OnPush for performance optimization in components

Applied to files:

  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-13T11:50:56.310Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 372
File: libs/zard/src/lib/shared/components/card/card.component.spec.ts:86-88
Timestamp: 2025-12-13T11:50:56.310Z
Learning: Do not flag or suggest removing `standalone: true` from test components (*.spec.ts files) or demo components (demo/*.ts files) in libs/zard/src/lib/shared/components/**/*.ts, as it is not a significant concern and the explicit flag is acceptable in these contexts.

Applied to files:

  • apps/web/src/app/shared/constants/components.constant.ts
📚 Learning: 2025-11-04T20:46:01.373Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 309
File: libs/zard/src/lib/components/select/demo/multi-select.ts:23-27
Timestamp: 2025-11-04T20:46:01.373Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, console.log statements are acceptable and often intentional to demonstrate reactivity and help users understand how the component works.

Applied to files:

  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
📚 Learning: 2025-12-08T17:34:37.975Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 367
File: libs/zard/src/lib/components/progress-bar/demo/shape.ts:9-11
Timestamp: 2025-12-08T17:34:37.975Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally mixing different variants (e.g., zType and zShape in a shape demo) is acceptable when done to showcase additional features that might not be demonstrated elsewhere.

Applied to files:

  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
📚 Learning: 2025-11-10T21:46:33.213Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 318
File: libs/zard/src/lib/components/select/demo/default.ts:21-21
Timestamp: 2025-11-10T21:46:33.213Z
Learning: In demo files under libs/zard/src/lib/components/**/demo/*.ts, intentionally showing different patterns (e.g., primitive values vs signals) across different demos is valuable for demonstrating the flexibility of Angular features like two-way binding.

Applied to files:

  • apps/web/src/app/shared/constants/components.constant.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts
  • libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts
📚 Learning: 2025-12-21T00:12:01.342Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: libs/blocks/README.md:0-0
Timestamp: 2025-12-21T00:12:01.342Z
Learning: Applies to libs/blocks/src/index.ts : All new blocks must be exported in the library's index file (libs/blocks/src/index.ts) with both component and block metadata exports

Applied to files:

  • libs/zard/src/lib/shared/components/index.ts
  • libs/zard/src/index.ts
📚 Learning: 2025-12-21T00:12:15.315Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: packages/cli/README.md:0-0
Timestamp: 2025-12-21T00:12:15.315Z
Learning: Applies to packages/cli/**/*.{ts,tsx} : Components should be modular and self-contained, allowing users to add only the components they need

Applied to files:

  • libs/zard/src/lib/shared/components/index.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/*/doc/*.md : Write component documentation with overview.md for use cases and basic examples, and api.md for complete API reference

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/doc/**/*.md : Write component documentation in `doc/overview.md` and `doc/api.md` files

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md
  • libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md
📚 Learning: 2025-10-31T10:03:18.563Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 299
File: libs/zard/src/lib/components/select/select.component.ts:34-38
Timestamp: 2025-10-31T10:03:18.563Z
Learning: In Angular 19+ (including Angular 20 used in this project), components are standalone by default. The `standalone: true` flag is redundant and should be omitted unless explicitly setting `standalone: false` to opt out.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts
📚 Learning: 2025-11-04T10:18:55.477Z
Learnt from: mihajm
Repo: zard-ui/zardui PR: 308
File: libs/zard/src/lib/components/button-group/doc/overview.md:1-3
Timestamp: 2025-11-04T10:18:55.477Z
Learning: In zardui repo, doc/overview.md files for components should contain only a brief overview description. Examples are provided through separate demo files and the api.md documentation, not in overview.md.

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md
📚 Learning: 2025-12-15T11:43:10.889Z
Learnt from: mikij
Repo: zard-ui/zardui PR: 373
File: libs/zard/src/lib/shared/components/select/select.component.ts:33-33
Timestamp: 2025-12-15T11:43:10.889Z
Learning: For files in libs/zard/src/lib/**/*.{ts,tsx,js}, use the `@/` path alias for imports mapping to libs/zard/src/lib/* directories. For example, use `import { mergeClasses } from '@/shared/utils/merge-classes'` instead of `import { mergeClasses } from 'zard/shared/utils/merge-classes'`.

Applied to files:

  • libs/zard/src/index.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to **/*.{ts,tsx,js,jsx} : Use path aliases zard/* to map to libs/zard/src/lib/* in imports

Applied to files:

  • libs/zard/src/index.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Use path aliases `zard/*` pointing to `libs/zard/src/lib/*` for component imports

Applied to files:

  • libs/zard/src/index.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use Signal-based inputs with the `input()` function instead of Input decorators in Angular components

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-12-21T00:11:39.450Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs with `input()` in Angular components

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
📚 Learning: 2025-11-25T18:54:01.560Z
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use computed properties in Angular components for reactive class calculations: `protected readonly classes = computed(() => ...)`

Applied to files:

  • libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
🧬 Code graph analysis (4)
apps/web/src/app/shared/constants/components.constant.ts (1)
libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts (1)
  • SCROLL_TO_TOP (5-23)
libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts (3)
libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts (1)
  • Component (5-37)
libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts (1)
  • Component (5-39)
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts (1)
  • Component (17-98)
libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts (3)
libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts (1)
  • Component (5-39)
libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts (1)
  • Component (5-39)
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts (1)
  • Component (17-98)
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts (2)
libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts (3)
  • ScrollToTopVariants (44-44)
  • scrollToTopVariants (3-29)
  • scrollToTopIconVariants (31-42)
libs/zard/src/lib/shared/utils/merge-classes.ts (1)
  • mergeClasses (6-8)
🪛 markdownlint-cli2 (0.18.1)
libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md

8-8: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


8-8: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


8-8: Multiple headings with the same content

(MD024, no-duplicate-heading)


9-9: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)

🔇 Additional comments (25)
libs/zard/src/lib/shared/components/scroll-to-top/doc/overview.md (1)

1-3: LGTM!

The overview is concise and clearly describes the component's purpose and behavior, following the established documentation pattern.

libs/zard/src/lib/shared/components/scroll-to-top/index.ts (1)

1-2: LGTM!

Barrel exports follow the established pattern, properly consolidating the component and variants for the public API surface.

apps/web/src/app/shared/constants/routes.constant.ts (1)

110-110: LGTM!

Route entry follows the established pattern, correctly integrating the Scroll To Top component into the documentation navigation with proper sorting.

libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md (1)

10-34: LGTM!

The API documentation is comprehensive and well-structured, properly documenting the component selector, inputs, methods, and properties with accurate type information.

libs/zard/src/index.ts (1)

46-46: LGTM!

The public API export follows the established pattern, properly exposing the Scroll To Top component to library consumers.

apps/web/src/app/shared/constants/components.constant.ts (2)

35-35: LGTM!

The import follows the established pattern and uses the correct @Zard path alias.


101-101: LGTM!

The component is correctly registered and alphabetically ordered in the COMPONENTS array.

libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts (1)

5-39: LGTM!

The demo component follows Angular best practices with standalone components and native control flow (@for). The template effectively showcases the three visual variants.

libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts (1)

5-39: LGTM!

The demo component follows Angular best practices with standalone components and native control flow (@for). The template effectively showcases the three size variants.

libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts (3)

1-31: LGTM!

The test setup correctly mocks window.scrollTo and follows standard Jest/TestBed patterns with proper cleanup in afterEach.


53-56: LGTM!

The test correctly verifies that the scrollToTop method calls window.scrollTo with smooth scrolling behavior.


58-101: LGTM!

The tests comprehensively cover all variants (default, outline, subtle) and sizes (sm, md, lg), correctly using componentRef.setInput() for signal inputs.

libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts (1)

5-37: LGTM!

The demo component follows the established patterns for ZardUI demo files, with clear structure, appropriate use of target="parent" for the scrollable container, and good visual indicators (bouncing chevron) to guide users.

libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.variants.ts (3)

3-29: LGTM! Proper use of semantic color tokens.

The CVA variants correctly leverage semantic tokens (bg-primary, text-primary-foreground, bg-background, border-input, etc.) which map to CSS custom properties for theme support. Good accessibility with focus-visible states and clear size tiers.


31-42: LGTM!

Clean icon sizing variants that maintain consistency with the button size options.


44-44: LGTM!

Proper type extraction from CVA variants for type-safe component inputs.

libs/zard/src/lib/shared/components/scroll-to-top/demo/scroll-to-top.ts (1)

5-23: LGTM!

Demo aggregation follows the established pattern with clear examples structure. The ordering (default → variants → sizes) provides a logical learning progression.

libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts (8)

1-15: LGTM! Proper import patterns.

Correctly uses @/ path alias for shared utilities and relative imports for co-located files. Good use of type-only import for OnDestroy.


21-31: LGTM! Well-structured template.

Excellent use of native control flow (@if), proper accessibility (aria-label, aria-hidden), and flexible customization via <ng-content> with a sensible SVG default.


34-43: LGTM! Proper signal patterns.

Excellent use of inject(), signal-based inputs with proper typing from CVA variants, and the private writable / public readonly signal pattern for visible.


45-59: LGTM! Reactive class computation.

Proper use of computed() with mergeClasses() for conflict-free Tailwind class merging. Good separation of button and icon sizing concerns.


77-81: LGTM! Proper cleanup.

Correct implementation of ngOnDestroy() with defensive checks and proper event listener removal to prevent memory leaks.


83-89: LGTM! Proper scroll handling.

Correct use of arrow function for event listener context preservation. The dual path for window vs. parent scrolling is well-structured with appropriate type guards.


91-97: LGTM! Clean scroll-to-top implementation.

Public method with proper dual-path logic for window vs. parent targets. The behavior: 'smooth' provides good UX and degrades gracefully in unsupported browsers.


61-75: Consider moving initialization to AfterViewInit.

Reading signal inputs (this.target()) in the constructor may be unreliable since input signals are not guaranteed to be resolved during construction. Consider implementing AfterViewInit and moving the scroll listener setup to ngAfterViewInit() for more predictable behavior.

🔎 Suggested refactoring approach
-import {
-  Component,
-  ChangeDetectionStrategy,
-  computed,
-  input,
-  signal,
-  ElementRef,
-  inject,
-  type OnDestroy,
-} from '@angular/core';
+import {
+  Component,
+  ChangeDetectionStrategy,
+  computed,
+  input,
+  signal,
+  ElementRef,
+  inject,
+  type OnDestroy,
+  type AfterViewInit,
+} from '@angular/core';

-export class ZardScrollToTopComponent implements OnDestroy {
+export class ZardScrollToTopComponent implements AfterViewInit, OnDestroy {

-  constructor() {
+  ngAfterViewInit() {
     if (typeof window !== 'undefined') {
-      setTimeout(() => {
-        if (this.target() === 'parent') {
-          this.scrollElement = this.elementRef.nativeElement.parentElement;
-          if (this.scrollElement) {
-            this.scrollElement.addEventListener('scroll', this.onScroll, { passive: true });
-          }
-        } else {
-          this.scrollElement = window;
-          window.addEventListener('scroll', this.onScroll, { passive: true });
-        }
-      });
+      if (this.target() === 'parent') {
+        this.scrollElement = this.elementRef.nativeElement.parentElement;
+        if (this.scrollElement) {
+          this.scrollElement.addEventListener('scroll', this.onScroll, { passive: true });
+        }
+      } else {
+        this.scrollElement = window;
+        window.addEventListener('scroll', this.onScroll, { passive: true });
+      }
     }
   }
⛔ Skipped due to learnings
Learnt from: mikij
Repo: zard-ui/zardui PR: 352
File: apps/web/src/app/domain/components/sidebar/scroll-on-active.directive.ts:23-27
Timestamp: 2025-11-30T19:07:11.572Z
Learning: In apps/web/src/app/domain/components/sidebar/scroll-on-active.directive.ts, the guard checking if scrollIntoView exists before calling it is necessary due to mobile browser compatibility issues. Physical testing on mobile devices shows scrollIntoView may not be present or functional. This defensive pattern should be kept despite scrollIntoView being part of the standard DOM API.
Learnt from: mikij
Repo: zard-ui/zardui PR: 326
File: libs/zard/src/lib/components/input/float.label.component.ts:71-0
Timestamp: 2025-11-14T22:52:09.135Z
Learning: In libs/zard/src/lib/components/*/*.component.ts files, move HostListener and HostBinding to the Component decorator's host property instead of using decorators on class members (e.g., host: { '(input)': 'onInput()' }).
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T18:54:01.560Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use Signal-based inputs with the `input()` function instead of Input decorators in Angular components
Learnt from: CR
Repo: zard-ui/zardui PR: 0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-12-21T00:11:39.450Z
Learning: Applies to libs/zard/src/lib/components/**/*.component.ts : Use signal-based inputs with `input()` in Angular components

export * from './toggle';
export * from './toggle-group';
export * from './tooltip';
export * from './scroll-to-top';
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider maintaining alphabetical order for better maintainability.

The scroll-to-top export is placed at the end, but for consistency with the rest of the file, it should be positioned alphabetically between resizable (line 32) and segmented (line 33).

🔎 Proposed refactor

Move line 45 to be between lines 32 and 33:

 export * from './radio';
 export * from './resizable';
+export * from './scroll-to-top';
 export * from './segmented';
 export * from './select';
 export * from './sheet';
 export * from './skeleton';
 export * from './slider';
 export * from './switch';
 export * from './table';
 export * from './tabs';
 export * from './toast';
 export * from './toggle';
 export * from './toggle-group';
 export * from './tooltip';
-export * from './scroll-to-top';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export * from './scroll-to-top';
export * from './radio';
export * from './resizable';
export * from './scroll-to-top';
export * from './segmented';
export * from './select';
export * from './sheet';
export * from './skeleton';
export * from './slider';
export * from './switch';
export * from './table';
export * from './tabs';
export * from './toast';
export * from './toggle';
export * from './toggle-group';
export * from './tooltip';
🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/index.ts around line 45, the export
"export * from './scroll-to-top';" breaks the file's alphabetical ordering; move
that line so it appears between the current `resizable` export (line ~32) and
the `segmented` export (line ~33) to restore consistent alphabetical ordering
across the exports.

@@ -0,0 +1,37 @@
import { Component } from '@angular/core';

import { ZardScrollToTopComponent } from '../scroll-to-top.component';
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Use @/ path alias for imports.

Per project conventions, prefer the @/ path alias over relative imports for files mapping to libs/zard/src/lib/* directories.

🔎 Suggested change
-import { ZardScrollToTopComponent } from '../scroll-to-top.component';
+import { ZardScrollToTopComponent } from '@/shared/components/scroll-to-top/scroll-to-top.component';

Based on learnings and coding guidelines.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { ZardScrollToTopComponent } from '../scroll-to-top.component';
import { ZardScrollToTopComponent } from '@/shared/components/scroll-to-top/scroll-to-top.component';
🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/demo/default.ts line 3, the
import uses a relative path; replace it with the project "@/..." path alias
(e.g. import from "@/shared/components/scroll-to-top/scroll-to-top.component")
so it resolves via the libs/zard/src/lib/* mapping; update the import statement
accordingly and run a quick build/TS check to ensure the alias is correct in
tsconfig/paths.

@@ -0,0 +1,39 @@
import { Component } from '@angular/core';

import { ZardScrollToTopComponent } from '../scroll-to-top.component';
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using the @/ path alias for consistency.

For better path readability and alignment with the project's alias configuration, prefer the @/ alias over relative imports.

🔎 Proposed refactor
-import { ZardScrollToTopComponent } from '../scroll-to-top.component';
+import { ZardScrollToTopComponent } from '@/shared/components/scroll-to-top/scroll-to-top.component';

Based on learnings, in files under libs/zard/src/lib/**/*.{ts,tsx,js}, prefer the @/ path alias for imports that map to libs/zard/src/lib/* directories.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { ZardScrollToTopComponent } from '../scroll-to-top.component';
import { ZardScrollToTopComponent } from '@/shared/components/scroll-to-top/scroll-to-top.component';
🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/demo/sizes.ts around line
3, the import uses a relative path to pull ZardScrollToTopComponent; update the
import to use the project path alias (e.g.
'@/lib/shared/components/scroll-to-top/scroll-to-top.component') so it
consistently follows the @/ alias convention; modify the import statement
accordingly and run TypeScript/tsconfig path validation to ensure the alias
resolves.

@@ -0,0 +1,39 @@
import { Component } from '@angular/core';

import { ZardScrollToTopComponent } from '../scroll-to-top.component';
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using the @/ path alias for consistency.

For better path readability and alignment with the project's alias configuration, prefer the @/ alias over relative imports.

🔎 Proposed refactor
-import { ZardScrollToTopComponent } from '../scroll-to-top.component';
+import { ZardScrollToTopComponent } from '@/shared/components/scroll-to-top/scroll-to-top.component';

Based on learnings, in files under libs/zard/src/lib/**/*.{ts,tsx,js}, prefer the @/ path alias for imports that map to libs/zard/src/lib/* directories.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { ZardScrollToTopComponent } from '../scroll-to-top.component';
import { ZardScrollToTopComponent } from '@/shared/components/scroll-to-top/scroll-to-top.component';
🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/demo/variants.ts around
line 3, the file uses a relative import for ZardScrollToTopComponent; replace
"import { ZardScrollToTopComponent } from '../scroll-to-top.component';" with
the project path-alias import using the @/ alias that maps to libs/zard/src/lib
(e.g. import from '@/shared/components/scroll-to-top/scroll-to-top.component'),
and ensure the path matches the component's location and your tsconfig/paths so
the alias resolves correctly.

Comment on lines +3 to +9
##

## ZardScrollToTopComponent

A floating button component that scrolls to the top of the page.
##
### Selector
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix markdown formatting issues.

The documentation contains empty headings and missing blank lines that violate markdown best practices:

  • Lines 3 and 8: Empty ## headings should be removed
  • Line 9: Missing blank line above the ### Selector heading
🔎 Proposed fix
 # API Reference
 
-##
-
 ## ZardScrollToTopComponent
 
 A floating button component that scrolls to the top of the page.
-##
+
 ### Selector
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
##
## ZardScrollToTopComponent
A floating button component that scrolls to the top of the page.
##
### Selector
# API Reference
## ZardScrollToTopComponent
A floating button component that scrolls to the top of the page.
### Selector
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

8-8: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)


8-8: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


8-8: Multiple headings with the same content

(MD024, no-duplicate-heading)


9-9: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Above

(MD022, blanks-around-headings)

🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/doc/api.md around lines 3
to 9, remove the two empty "##" headings at lines 3 and 8 and ensure there is a
blank line inserted above the "### Selector" heading on line 9 so headings
follow proper Markdown spacing and structure.

@Component({
selector: 'z-scroll-to-top, [z-scroll-to-top]',
imports: [CommonModule],
standalone: true,
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Remove redundant standalone: true flag.

In Angular 19+ (including Angular 20 used in this project), components are standalone by default. The explicit standalone: true flag is redundant and should be omitted.

🔎 Suggested change
  selector: 'z-scroll-to-top, [z-scroll-to-top]',
  imports: [CommonModule],
-  standalone: true,
  template: `
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
standalone: true,
selector: 'z-scroll-to-top, [z-scroll-to-top]',
imports: [CommonModule],
template: `
🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.component.ts
around line 20, remove the redundant `standalone: true` property from the
component decorator; edit the decorator to omit that key entirely so the
component relies on Angular 19+/20 default standalone behavior and run
lint/tests to confirm no other changes are needed.

Comment on lines +37 to +51
it('should show when scrollY > 200', async () => {
Object.defineProperty(window, 'scrollY', { value: 300, configurable: true });
// Wait for setTimeout in constructor
await new Promise(resolve => setTimeout(resolve, 10));
component['onScroll']();
expect(component.visible()).toBe(true);
});

it('should hide when scrollY <= 200', async () => {
Object.defineProperty(window, 'scrollY', { value: 100, configurable: true });
// Wait for setTimeout in constructor
await new Promise(resolve => setTimeout(resolve, 10));
component['onScroll']();
expect(component.visible()).toBe(false);
});
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider using fakeAsync/tick for more reliable async testing.

The current tests use setTimeout with Promise to wait for the constructor's async initialization. Using Angular's fakeAsync and tick utilities provides better control over timing and makes tests more deterministic.

🔎 Proposed refactor
+import { fakeAsync, tick } from '@angular/core/testing';
+
-  it('should show when scrollY > 200', async () => {
+  it('should show when scrollY > 200', fakeAsync(() => {
     Object.defineProperty(window, 'scrollY', { value: 300, configurable: true });
-    // Wait for setTimeout in constructor
-    await new Promise(resolve => setTimeout(resolve, 10));
+    tick(10); // Advance timers for constructor setTimeout
     component['onScroll']();
     expect(component.visible()).toBe(true);
-  });
+  }));

-  it('should hide when scrollY <= 200', async () => {
+  it('should hide when scrollY <= 200', fakeAsync(() => {
     Object.defineProperty(window, 'scrollY', { value: 100, configurable: true });
-    // Wait for setTimeout in constructor
-    await new Promise(resolve => setTimeout(resolve, 10));
+    tick(10); // Advance timers for constructor setTimeout
     component['onScroll']();
     expect(component.visible()).toBe(false);
-  });
+  }));

Based on learnings, use fakeAsync() with tick() instead of setTimeout for testing components that use setTimeout, as it provides better control over macrotasks in tests.

🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
around lines 37 to 51, the tests rely on awaiting a Promise that wraps
setTimeout to wait for the component constructor's async setTimeout; replace
these fragile waits with Angular's fakeAsync and tick utilities for
deterministic timing: change each `async` test to use `fakeAsync(() => { ...
})`, remove the Promise/await setTimeout, call `tick(10)` (or the exact timeout
duration used in the component) before invoking `component['onScroll']()`, and
import `fakeAsync` and `tick` from '@angular/core/testing'; this ensures the
macrotask is flushed deterministically and the visibility assertions remain the
same.

Comment on lines +119 to +125
it('should cleanup event listener on destroy', async () => {
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
// Wait for setTimeout in constructor to attach listener
await new Promise(resolve => setTimeout(resolve, 10));
component.ngOnDestroy();
expect(removeEventListenerSpy).toHaveBeenCalled();
});
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Apply the fakeAsync pattern here as well.

This test also uses the setTimeout pattern. Consider applying the same fakeAsync/tick refactor suggested earlier for consistency.

🔎 Proposed refactor
-  it('should cleanup event listener on destroy', async () => {
+  it('should cleanup event listener on destroy', fakeAsync(() => {
     const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
-    // Wait for setTimeout in constructor to attach listener
-    await new Promise(resolve => setTimeout(resolve, 10));
+    tick(10); // Advance timers for constructor setTimeout
     component.ngOnDestroy();
     expect(removeEventListenerSpy).toHaveBeenCalled();
-  });
+  }));
🤖 Prompt for AI Agents
In libs/zard/src/lib/shared/components/scroll-to-top/scroll-to-top.spec.ts
around lines 119 to 125, the test uses a real setTimeout to wait for the
component constructor to attach an event listener; replace this with Angular's
fakeAsync/tick pattern for consistency and determinism: wrap the test body with
fakeAsync, remove the Promise/setTimeout, call tick(10) (or appropriate tick
duration) to advance timers so the listener is attached, then call
component.ngOnDestroy() and assert removeEventListener was called; ensure the
test imports fakeAsync and tick from @angular/core/testing and remove use of
async/await in this test.

standalone: true,
template: `
@if (visible()) {
<button type="button" aria-label="Scroll to top" (click)="scrollToTop()" [class]="classes()">
Copy link
Contributor

@mikij mikij Jan 5, 2026

Choose a reason for hiding this comment

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

We should avoid code duplication whenever it is possible. In this case, that is certainly possible using z-button with zShape set to 'circle' and using z-icon as content (chevron-up) instead of svg. I suspect your variant file is just copy of button variant file here. At least most of it.

Copy link
Author

Choose a reason for hiding this comment

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

Hi, @mikij.

Understood and agreed. Should I update the PR fixing what you mentioned and also what CodeRabbit alerted?

Thanks in advance.

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah I think you should address both. Though not sure if we want to go as directive with this then you don't need to do what I suggested

Copy link
Contributor

Choose a reason for hiding this comment

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

let's wait a little about decision how to work on this

Copy link
Author

Choose a reason for hiding this comment

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

Ok, no prob.
Thanks

@mikij
Copy link
Contributor

mikij commented Jan 5, 2026

I see this functionality more like directive that can be applied to a button than as a separate component. But not sure yet what is the best approach.

@devpedromgoncalves
Copy link
Author

devpedromgoncalves commented Jan 5, 2026

That's interesting... so you would use the normal button and add only the necessary functions to it as a directive, that's it?

Let me know what you decide after.

Thanks for helping.

@mikij
Copy link
Contributor

mikij commented Jan 5, 2026

Not sure yet. Is this what you have in mind with this component https://primeng.org/scrolltop?

@devpedromgoncalves
Copy link
Author

Not sure yet. Is this what you have in mind with this component https://primeng.org/scrolltop?

Yes, exactly.

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.

2 participants