Skip to content

Commit

Permalink
fix: hide close button on non dimissable toasts (#12)
Browse files Browse the repository at this point in the history
* fix: hide close button on non dimissable toasts

* tests: add close button tests
  • Loading branch information
tutkli authored Apr 11, 2024
1 parent ef76ad8 commit 3d1b31a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 18 deletions.
2 changes: 1 addition & 1 deletion libs/ngx-sonner/src/lib/toast.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const defaultClasses: ToastClassnames = {
(pointerdown)="onPointerDown($event)"
(pointerup)="onPointerUp()"
(pointermove)="onPointerMove($event)">
@if (closeButton() && !toast().component) {
@if (toast().dismissable && closeButton() && !toast().component) {
<button
aria-label="Close toast"
[attr.data-disabled]="disabled()"
Expand Down
15 changes: 10 additions & 5 deletions libs/ngx-sonner/src/tests/toaster-test.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,32 @@ import { NgxSonnerToaster, ToasterProps, toast } from 'ngx-sonner';
type ToastFn = (t: typeof toast) => void;

export type ToastTestInputs = {
cb: ToastFn;
callback: ToastFn;
dir?: ToasterProps['dir'];
theme?: ToasterProps['theme'];
closeButton?: ToasterProps['closeButton'];
};

@Component({
selector: 'ngx-sonner-test',
standalone: true,
imports: [NgxSonnerToaster],
template: `
<ngx-sonner-toaster [dir]="dir()" [theme]="theme()" />
<ngx-sonner-toaster
[dir]="dir()"
[theme]="theme()"
[closeButton]="closeButton()" />
<button data-testid="trigger" (click)="onClick()">Trigger</button>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ToasterTestComponent {
cb = input.required<ToastTestInputs['cb']>();
dir = input<ToasterProps['dir']>();
callback = input.required<ToastTestInputs['callback']>();
dir = input<ToasterProps['dir']>('auto');
theme = input<ToasterProps['theme']>('light');
closeButton = input<ToasterProps['closeButton']>(false);

onClick() {
this.cb()(toast);
this.callback()(toast);
}
}
46 changes: 34 additions & 12 deletions libs/ngx-sonner/src/tests/toaster.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ describe('Toaster', () => {

it('should render a toast', async () => {
const { user, trigger, container, getByText } = await setup({
cb: toast => toast('Hello world'),
callback: toast => toast('Hello world'),
});

await user.click(trigger);
Expand All @@ -44,7 +44,7 @@ describe('Toaster', () => {

it('should show a toast with custom duration', async () => {
const { user, trigger, queryByText, detectChanges } = await setup({
cb: toast => toast('Custom duration', { duration: 300 }),
callback: toast => toast('Custom duration', { duration: 300 }),
});

expect(queryByText('Custom duration')).toBeNull();
Expand All @@ -60,7 +60,7 @@ describe('Toaster', () => {
it('should reset duration on a toast update', async () => {
const { user, trigger, getByText, queryByText, detectChanges } =
await setup({
cb: toast => {
callback: toast => {
const id = toast('Loading', { duration: 2000 });

setTimeout(() => {
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('Toaster', () => {
it('should allow duration updates on toast update', async () => {
const { user, trigger, getByText, queryByText, detectChanges } =
await setup({
cb: toast => {
callback: toast => {
const id = toast('Loading', { duration: 2000 });

setTimeout(() => {
Expand All @@ -113,7 +113,7 @@ describe('Toaster', () => {
it('should show correct toast content based on promise state', async () => {
const { user, trigger, queryByText, getByText, detectChanges } =
await setup({
cb: toast =>
callback: toast =>
toast.promise<string>(
() =>
new Promise(resolve =>
Expand All @@ -139,7 +139,7 @@ describe('Toaster', () => {

it('should focus the toast when hotkey is pressed', async () => {
const { user, trigger, getByText } = await setup({
cb: toast => toast('Hello world', { duration: 5000 }),
callback: toast => toast('Hello world', { duration: 5000 }),
});

await user.click(trigger);
Expand All @@ -153,7 +153,7 @@ describe('Toaster', () => {
it('should not immediately close the toast when reset', async () => {
const { user, trigger, getByText, queryByText, detectChanges } =
await setup({
cb: toast => {
callback: toast => {
const id = toast('Loading', { duration: 4000 });

setTimeout(() => {
Expand All @@ -175,7 +175,7 @@ describe('Toaster', () => {

it('should render toast with custom class', async () => {
const { user, trigger, container } = await setup({
cb: toast =>
callback: toast =>
toast('Hello world', {
classes: {
toast: 'test-class',
Expand All @@ -191,7 +191,7 @@ describe('Toaster', () => {

it('should render cancel button custom styles', async () => {
const { user, trigger, container } = await setup({
cb: toast =>
callback: toast =>
toast('Hello world', {
cancel: {
label: 'Cancel',
Expand All @@ -210,7 +210,7 @@ describe('Toaster', () => {

it('should render action button custom styles', async () => {
const { user, trigger, container } = await setup({
cb: toast =>
callback: toast =>
toast('Hello world', {
action: {
label: 'Do something',
Expand All @@ -230,7 +230,7 @@ describe('Toaster', () => {

it('should reflect toaster dir correctly', async () => {
const { user, trigger, container } = await setup({
cb: toast => toast('Hello world'),
callback: toast => toast('Hello world'),
dir: 'rtl',
});

Expand All @@ -242,7 +242,7 @@ describe('Toaster', () => {

it('should reflect toaster dark theme correctly', async () => {
const { user, trigger, container } = await setup({
cb: toast => toast('Hello world'),
callback: toast => toast('Hello world'),
theme: 'dark',
});

Expand All @@ -251,4 +251,26 @@ describe('Toaster', () => {
expect(toaster).not.toBeNull();
expect(toaster as Element).toHaveAttribute('data-theme', 'dark');
});

it('should show close button correctly', async () => {
const { user, trigger, container } = await setup({
callback: toast => toast('Hello world'),
closeButton: true,
});

await user.click(trigger);
const closeButton = container.querySelector('[data-close-button]');
expect(closeButton).not.toBeNull();
});

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

await user.click(trigger);
const closeButton = container.querySelector('[data-close-button]');
expect(closeButton).toBeNull();
});
});

0 comments on commit 3d1b31a

Please sign in to comment.