Skip to content

Commit

Permalink
Toaster: Add methods to close individual or all toasts (#5537)
Browse files Browse the repository at this point in the history
  • Loading branch information
deleonio committed Nov 9, 2023
2 parents c1fa739 + 3dbf399 commit 5305eb7
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 45 deletions.
3 changes: 2 additions & 1 deletion packages/components/src/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2470,7 +2470,8 @@ export namespace Components {
"_value"?: string;
}
interface KolToastContainer {
"enqueue": (toast: Toast) => Promise<void>;
"closeAll": () => Promise<void>;
"enqueue": (toast: Toast) => Promise<() => void>;
}
interface KolTooltipWc {
/**
Expand Down
26 changes: 20 additions & 6 deletions packages/components/src/components/toaster/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class KolToastContainer implements API {
// Stencil requires async function:
// eslint-disable-next-line @typescript-eslint/require-await
@Method()
async enqueue(toast: Toast) {
public async enqueue(toast: Toast) {
const newToastState: ToastState = {
toast,
status: 'adding',
Expand All @@ -37,7 +37,7 @@ export class KolToastContainer implements API {
this.state = {
...this.state,
_toastStates: this.state._toastStates.map((localToastState) =>
localToastState === newToastState
localToastState.id === newToastState.id
? {
...localToastState,
status: 'settled',
Expand All @@ -46,13 +46,17 @@ export class KolToastContainer implements API {
),
};
}, TRANSITION_TIMEOUT);

return () => {
this.handleClose(newToastState);
};
}

private handleClose(toastState: ToastState) {
this.state = {
...this.state,
_toastStates: this.state._toastStates.map((localToastState) => {
if (localToastState === toastState) {
if (localToastState.id === toastState.id) {
localToastState.status = 'removing';
}
return localToastState;
Expand All @@ -62,12 +66,14 @@ export class KolToastContainer implements API {
setTimeout(() => {
this.state = {
...this.state,
_toastStates: this.state._toastStates.filter((localToastState) => localToastState !== toastState),
_toastStates: this.state._toastStates.filter((localToastState) => localToastState.id !== toastState.id),
};
}, TRANSITION_TIMEOUT);
}

private handleCloseAllClick() {
// eslint-disable-next-line @typescript-eslint/require-await
@Method()
public async closeAll() {
this.state = {
...this.state,
_toastStates: this.state._toastStates.map((localToastState) => ({
Expand All @@ -88,7 +94,15 @@ export class KolToastContainer implements API {
return (
<>
{this.state._toastStates.length > 1 && (
<kol-button _label={translate('kol-toast-close-all')} class="close-all" _on={{ onClick: this.handleCloseAllClick.bind(this) }}></kol-button>
<kol-button
_label={translate('kol-toast-close-all')}
class="close-all"
_on={{
onClick: () => {
void this.closeAll();
},
}}
></kol-button>
)}
{this.state._toastStates.map((toastState) => (
<InternalToast toastState={toastState} onClose={() => this.handleClose(toastState)} key={toastState.id} />
Expand Down
17 changes: 15 additions & 2 deletions packages/components/src/components/toaster/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ toaster.enqueue({
});
```

### Weitere Service-Methoden

- `closeAll`: Schließt alle Toasts
- `dispose`: Entfernt den Toast Container. Die Toaster-Instanz kann nicht weiter genutzt werden.

## Verwendung

### Überschrift
Expand All @@ -37,7 +42,7 @@ Alternativ zur statischen Description können Sie über das Attribut **`_render`
HTMLElement der Toast-Komponente aufgerufen. Zudem wird auch ein Objekt übergeben, das eine `close`-Funktion zum Schließen des Toasts bereitstellt.

```ts
void toaster.enqueue({
const closeToast = toaster.enqueue({
render: (element: HTMLElement, { close }) => {
element.textContent = 'Mein Inhalt';
const customCloseButton = document.createElement('button');
Expand All @@ -46,6 +51,8 @@ void toaster.enqueue({
customCloseButton.addEventListener('click', close, { once: true });
},
});

/* Optional: Toast wieder schließen mit `closeToast()` */
```

### Anzeigetyp des Toast
Expand All @@ -62,12 +69,18 @@ Verwenden Sie das Attribut **`_type`**, um den Typ des Toasts festzulegen. Mögl

## Methods

### `enqueue(toast: Toast) => Promise<void>`
### `closeAll() => Promise<void>`

#### Returns

Type: `Promise<void>`

### `enqueue(toast: Toast) => Promise<() => void>`

#### Returns

Type: `Promise<() => void>`

## Dependencies

### Depends on
Expand Down
10 changes: 8 additions & 2 deletions packages/components/src/components/toaster/toaster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,19 @@ export class ToasterService {
}
}

public async enqueue(toast: Toast) {
public enqueue(toast: Toast): Promise<() => void> | undefined {
/**
* We need this condition for SSR. The toast container is not rendered on the server,
* so we can't enqueue toasts.
*/
if (this.toastContainerElement && typeof this.toastContainerElement.enqueue === 'function') {
await this.toastContainerElement.enqueue(toast);
return this.toastContainerElement.enqueue(toast);
}
}

public closeAll(): void {
if (this.toastContainerElement && typeof this.toastContainerElement.closeAll === 'function') {
void this.toastContainerElement.closeAll();
}
}
}
92 changes: 58 additions & 34 deletions packages/samples/react/src/components/toast/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,63 @@ import { getRoot } from '../../shares/react-roots';

const toaster = ToasterService.getInstance(document);

const handleButtonClickSimple = () => {
void toaster.enqueue({
description: 'Toasty',
label: `Initial Toast`,
type: 'warning',
});
};
export const ToastBasic: FC = () => {
const handleButtonClickSimple = () => {
void toaster.enqueue({
description: 'Toasty',
label: `Initial Toast`,
type: 'warning',
});
};

const handleButtonClickComplex = () => {
void toaster.enqueue({
render: (element: HTMLElement, { close }) => {
getRoot(element).render(
<>
<KolButton
_label={'Hello World from Toast!'}
_on={{
onClick: () => {
console.log('Toast Button clicked!');
close();
},
}}
/>
</>,
);
},
label: `Initial Toast`,
type: 'warning',
});
};
const handleButtonClickComplex = () => {
void toaster.enqueue({
render: (element: HTMLElement, { close }) => {
getRoot(element).render(
<>
<KolButton
_label={'Hello World from Toast!'}
_on={{
onClick: () => {
console.log('Toast Button clicked!');
close();
},
}}
/>
</>,
);
},
label: `Initial Toast`,
type: 'warning',
});
};

const handleButtonClickOpenAndClose = async () => {
const close = await toaster.enqueue({
description: 'I will disappear in two seconds...',
label: `Good Bye`,
type: 'warning',
});

export const ToastBasic: FC = () => (
<div>
<KolButton _label="Show simple toast" _on={{ onClick: handleButtonClickSimple }}></KolButton>
<KolButton _label="Show complex toast" _on={{ onClick: handleButtonClickComplex }}></KolButton>
</div>
);
if (close) {
setTimeout(close, 2000);
}
};

const closeAll = () => {
toaster.closeAll();
};

return (
<div>
<KolButton _label="Show simple toast" _on={{ onClick: handleButtonClickSimple }}></KolButton>
<KolButton _label="Show complex toast" _on={{ onClick: handleButtonClickComplex }}></KolButton>
<br />
<br />
<KolButton _label="Show toast and close after 2 seconds" _on={{ onClick: () => void handleButtonClickOpenAndClose() }}></KolButton>
<br />
<br />
<KolButton _label="Close all toasts" _on={{ onClick: closeAll }}></KolButton>
</div>
);
};
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5305eb7

Please sign in to comment.