Skip to content

Conversation

@PieterjanDeClippel
Copy link
Member

Summary

  • update the carousel template to use the ViewChild swipe container when reading slide height and index state
  • ensure the vertical bindings no longer reference an undefined template variable

Testing

  • CI=1 npx nx build mintplayer-ng-bootstrap

https://chatgpt.com/codex/tasks/task_e_690113aa332c8323a48356c8bcdd2689

@gemini-code-assist
Copy link

Summary of Changes

Hello @PieterjanDeClippel, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical bug in the carousel component where template variables for slide height and index state were not correctly bound to the ViewChild swipe container. In addition to this fix, it introduces a significant new feature: full support for vertical carousel orientation. This enhancement involves comprehensive updates across the component's template, styling, and core swipe logic, providing a more flexible and robust carousel implementation.

Highlights

  • Carousel Template Fixes: Corrected template references to the swipeContainer for accurate slide height and index state readings, resolving potential undefined variable issues.
  • Vertical Orientation Support: Introduced a new orientation input for the carousel, enabling vertical scrolling and display, complete with corresponding CSS styling and layout adjustments.
  • Enhanced Navigation: Implemented orientation-aware keyboard navigation, allowing ArrowUp/ArrowDown for vertical carousels and ArrowLeft/ArrowRight for horizontal ones.
  • Swipe Logic Adaptation: Updated the underlying BsSwipeContainerDirective to dynamically calculate swipe offsets, animation properties, and slide dimensions based on the carousel's orientation.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for vertical orientation in the carousel component and fixes an issue with template variable scope. The changes are well-structured, particularly the refactoring in BsSwipeContainerDirective to handle both horizontal and vertical orientations. I've identified a bug in the fade animation mode where the container height isn't correctly handled for vertical orientation. I've also suggested a couple of improvements for code clarity and to better align with Angular best practices, such as using the @let block in the template and removing a potentially redundant change detection call.

Comment on lines +85 to +86
<div class="carousel-indicators" [class.carousel-indicators-vertical]="orientation === 'vertical'"
[style.height.px]="orientation === 'vertical' ? (swipeContainer?.currentSlideHeight$ | async) : null">

Choose a reason for hiding this comment

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

high

In fade animation mode, the swipeContainer is not available, as it's only defined within the slide animation block. Consequently, swipeContainer?.currentSlideHeight$ | async will always evaluate to null. This means that for a vertically oriented carousel with fade animation, the height of the indicators container will not be set, which could lead to layout issues. You should consider a different way to determine the height in fade mode, perhaps by creating a mechanism to measure slide heights that is independent of the swipe container.

Comment on lines +40 to 51
<div class="carousel slide mx-auto" [class.carousel-vertical]="orientation === 'vertical'"
[style.height.px]="orientation === 'vertical' ? (swipeContainer?.currentSlideHeight$ | async) : null">
@if (indicators) {
<div class="carousel-indicators">
<div class="carousel-indicators" [class.carousel-indicators-vertical]="orientation === 'vertical'"
[style.height.px]="orientation === 'vertical' ? (swipeContainer?.currentSlideHeight$ | async) : null">
@for (image of (images$ | async); track image.id; let i = $index) {
<button type="button" (click)="container.goto(i)"
[class.active]="(container.imageIndex$ | async) === i" data-bs-target
[attr.aria-current]="(container.imageIndex$ | async) === i ? true : null"
<button type="button" (click)="swipeContainer?.goto(i)"
[class.active]="(swipeContainer?.imageIndex$ | async) === i" data-bs-target
[attr.aria-current]="(swipeContainer?.imageIndex$ | async) === i ? true : null"
[attr.aria-label]="'Slide ' + i"></button>
}
</div>

Choose a reason for hiding this comment

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

medium

To improve readability and performance by reducing the number of async pipe subscriptions, you can use the @let syntax to create template variables for the resolved values of your observables. This also makes the template cleaner.

 @let slideHeight = swipeContainer?.currentSlideHeight$ | async; @let imageIndex = swipeContainer?.imageIndex$ | async; <div class="carousel slide mx-auto" [class.carousel-vertical]="orientation === 'vertical'" [style.height.px]="orientation === 'vertical' ? slideHeight : null"> @if (indicators) { <div class="carousel-indicators" [class.carousel-indicators-vertical]="orientation === 'vertical'" [style.height.px]="orientation === 'vertical' ? slideHeight : null"> @for (image of (images$ | async); track image.id; let i = $index) { <button type="button" (click)="swipeContainer?.goto(i)" [class.active]="imageIndex === i" data-bs-target [attr.aria-current]="imageIndex === i ? true : null" [attr.aria-label]="'Slide ' + i"></button> } </div> 
Comment on lines +60 to +63
@Input() public set orientation(value: 'horizontal' | 'vertical') {
this._orientation = value ?? 'horizontal';
this.cdRef.detectChanges();
}

Choose a reason for hiding this comment

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

medium

The explicit call to this.cdRef.detectChanges() within the setter for the orientation input is likely unnecessary. Angular's change detection mechanism automatically handles updates to the view when an @Input() property changes. Removing this call can simplify the code and rely on the framework's standard behavior. You should verify that the component continues to function as expected after its removal.

 @Input() public set orientation(value: 'horizontal' | 'vertical') { this._orientation = value ?? 'horizontal'; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2 participants