Skip to content

Commit

Permalink
prevent clicks while dragging; fixes #2196 (#2259)
Browse files Browse the repository at this point in the history
  • Loading branch information
claviska authored Nov 5, 2024
1 parent 569acdb commit 8db6580
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/pages/resources/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti
- Fixed a bug in `<sl-carousel>` that caused the navigation icons to be reversed
- Fixed a bug in `<sl-select>` that prevented label changes in `<sl-option>` from updating the controller [#1971]
- Fixed a bug in `<sl-textarea>` that caused a console warning in Firefox when typing [#2107]
- Fixed a bug in `<sl-carousel>` that caused interactive elements to be activated when dragging [#2196]
- Improved performance of `<sl-range>` by skipping positioning logic when tooltip isn't shown [#2064]

## 2.18.0
Expand Down
18 changes: 18 additions & 0 deletions src/components/carousel/carousel.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export default class SlCarousel extends ShoelaceElement {
@state() dragging = false;

private autoplayController = new AutoplayController(this, () => this.next());
private dragStartPosition: [number, number] = [-1, -1];
private readonly localize = new LocalizeController(this);
private mutationObserver: MutationObserver;
private pendingSlideChange = false;
Expand Down Expand Up @@ -151,6 +152,20 @@ export default class SlCarousel extends ShoelaceElement {
) as SlCarouselItem[];
}

private handleClick(event: MouseEvent) {
if (this.dragging && this.dragStartPosition[0] > 0 && this.dragStartPosition[1] > 0) {
const deltaX = Math.abs(this.dragStartPosition[0] - event.clientX);
const deltaY = Math.abs(this.dragStartPosition[1] - event.clientY);
const delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY);

// Prevents clicks on interactive elements while dragging if the click is within a small range. This prevents
// accidental drags from interfering with intentional clicks.
if (delta >= 10) {
event.preventDefault();
}
}
}

private handleKeyDown(event: KeyboardEvent) {
if (['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'Home', 'End'].includes(event.key)) {
const target = event.target as HTMLElement;
Expand Down Expand Up @@ -208,6 +223,7 @@ export default class SlCarousel extends ShoelaceElement {
// Start dragging if it hasn't yet
this.scrollContainer.style.setProperty('scroll-snap-type', 'none');
this.dragging = true;
this.dragStartPosition = [event.clientX, event.clientY];
}

this.scrollContainer.scrollBy({
Expand Down Expand Up @@ -255,6 +271,7 @@ export default class SlCarousel extends ShoelaceElement {
scrollContainer.style.removeProperty('scroll-snap-type');

this.dragging = false;
this.dragStartPosition = [-1, -1];
this.handleScrollEnd();
});
};
Expand Down Expand Up @@ -533,6 +550,7 @@ export default class SlCarousel extends ShoelaceElement {
@mousedown="${this.handleMouseDragStart}"
@scroll="${this.handleScroll}"
@scrollend=${this.handleScrollEnd}
@click=${this.handleClick}
>
<slot></slot>
</div>
Expand Down

0 comments on commit 8db6580

Please sign in to comment.