Skip to content

Commit

Permalink
Merge pull request #16 from tutkli/bug/dismissible
Browse files Browse the repository at this point in the history
fix: prevent toasts to be swiped out when not dismissible
  • Loading branch information
tutkli committed Apr 16, 2024
2 parents cbf2a10 + 8e30c20 commit 6cd1e93
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 13 deletions.
6 changes: 3 additions & 3 deletions libs/ngx-sonner/src/lib/state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function createToastState() {
? data.id
: toastsCounter++;

const dismissable = data.dismissable ?? true;
const dismissible = data.dismissible ?? true;
const type = data.type ?? 'default';

const alreadyExists = toasts().find(toast => toast.id === id);
Expand All @@ -45,15 +45,15 @@ function createToastState() {
...data,
id,
title: message,
dismissable,
dismissible,
type,
updated: true,
};
} else return { ...toast, updated: false };
})
);
} else {
addToast({ ...rest, id, title: message, dismissable, type });
addToast({ ...rest, id, title: message, dismissible: dismissible, type });
}

return id;
Expand Down
14 changes: 8 additions & 6 deletions libs/ngx-sonner/src/lib/toast.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const defaultClasses: ToastClassnames = {
[attr.data-index]="index()"
[attr.data-front]="isFront()"
[attr.data-swiping]="swiping()"
[attr.data-dismissible]="toast().dismissible"
[attr.data-type]="toastType()"
[attr.data-invert]="invert()"
[attr.data-swipe-out]="swipeOut()"
Expand All @@ -78,7 +79,7 @@ const defaultClasses: ToastClassnames = {
(pointerdown)="onPointerDown($event)"
(pointerup)="onPointerUp()"
(pointermove)="onPointerMove($event)">
@if (toast().dismissable && closeButton() && !toast().component) {
@if (toast().dismissible && closeButton() && !toast().component) {
<button
aria-label="Close toast"
[attr.data-disabled]="disabled()"
Expand Down Expand Up @@ -389,7 +390,7 @@ export class ToastComponent implements AfterViewInit, OnDestroy {
}

onPointerDown(event: PointerEvent) {
if (this.disabled()) return;
if (this.disabled() || !this.toast().dismissible) return;

this.offsetBeforeRemove.set(this.offset());
const target = event.target as HTMLElement;
Expand All @@ -403,7 +404,7 @@ export class ToastComponent implements AfterViewInit, OnDestroy {
}

onPointerUp() {
if (this.swipeOut()) return;
if (this.swipeOut() || !this.toast().dismissible) return;

this.pointerStartRef = null;
const swipeAmount = Number(
Expand All @@ -426,7 +427,7 @@ export class ToastComponent implements AfterViewInit, OnDestroy {
}

onPointerMove(event: PointerEvent) {
if (!this.pointerStartRef) return;
if (!this.pointerStartRef || !this.toast().dismissible) return;

const yPosition = event.clientY - this.pointerStartRef.y;
const xPosition = event.clientX - this.pointerStartRef.x;
Expand All @@ -449,14 +450,15 @@ export class ToastComponent implements AfterViewInit, OnDestroy {
}

onCloseButtonClick() {
if (this.disabled()) return;
if (this.disabled() || !this.toast().dismissible) return;
this.deleteToast();
this.toast().onDismiss?.(this.toast());
}

onCancelClick() {
this.deleteToast();
const toast = this.toast();
if (!toast.dismissible) return;
this.deleteToast();
if (toast.cancel?.onClick) {
toast.cancel.onClick();
}
Expand Down
17 changes: 16 additions & 1 deletion libs/ngx-sonner/src/lib/toaster.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ const GAP = 14;
(mouseenter)="expanded.set(true)"
(mousemove)="expanded.set(true)"
(mouseleave)="handleMouseLeave()"
(pointerdown)="interacting.set(true)"
(pointerdown)="handlePointerDown($event)"
(pointerup)="interacting.set(false)"
[style]="toasterStyles()">
@for (
Expand Down Expand Up @@ -225,12 +225,27 @@ export class NgxSonnerToaster implements OnDestroy {
}

handleFocus(event: FocusEvent) {
const isNotDismissible =
event.target instanceof HTMLElement &&
event.target.dataset['dismissible'] === 'false';

if (isNotDismissible) return;

if (!this.isFocusWithinRef()) {
this.isFocusWithinRef.set(true);
this.lastFocusedElementRef.set(event.relatedTarget as HTMLElement);
}
}

handlePointerDown(event: MouseEvent) {
const isNotDismissible =
event.target instanceof HTMLElement &&
event.target.dataset['dismissible'] === 'false';

if (isNotDismissible) return;
this.interacting.set(true);
}

handleMouseLeave() {
if (!this.interacting()) {
this.expanded.set(false);
Expand Down
2 changes: 1 addition & 1 deletion libs/ngx-sonner/src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export type ToastT = {
};
onDismiss?: (toast: ToastT) => void;
onAutoClose?: (toast: ToastT) => void;
dismissable?: boolean;
dismissible?: boolean;
promise?: PromiseT;
style?: Record<string, unknown>;
class?: string;
Expand Down
4 changes: 2 additions & 2 deletions libs/ngx-sonner/src/tests/toaster.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -263,9 +263,9 @@ describe('Toaster', () => {
expect(closeButton).not.toBeNull();
});

it('should not show close button if the toast is not dismissable', async () => {
it('should not show close button if the toast is not dismissible', async () => {
const { user, trigger, container } = await setup({
callback: toast => toast('Hello world', { dismissable: false }),
callback: toast => toast('Hello world', { dismissible: false }),
closeButton: true,
});

Expand Down

0 comments on commit 6cd1e93

Please sign in to comment.