Skip to content

Commit

Permalink
refactor(Notification): set notification portal from the components l…
Browse files Browse the repository at this point in the history
…ifecycle: connectedCallback()
  • Loading branch information
dgonzalezr committed Aug 29, 2024
1 parent 838204a commit 341c6e3
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ const Template = (args: Args) => {
@bqShow=${args.bqShow}
@bqHide=${onToastHide}
>
${args.text}
${type === 'custom' ? html`<bq-icon slot="icon" size="24" weight="bold" name="star"></bq-icon>` : null}
${args.text} ${type === 'custom' ? html`<bq-icon slot="icon" size="24" name="star-bold"></bq-icon>` : null}
</bq-toast>
</div>
`,
Expand Down Expand Up @@ -96,7 +95,7 @@ const CustomIconTemplate = (args: Args) => {
@bqHide=${onToastHide}
>
${args.text}
<bq-icon slot="icon" size="24" weight="bold" name="star"></bq-icon>
<bq-icon slot="icon" size="24" name="star-bold"></bq-icon>
</bq-toast>
`;
};
Expand Down
64 changes: 34 additions & 30 deletions packages/beeq/src/components/toast/bq-toast.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { Component, Element, Event, EventEmitter, h, Host, Listen, Method, Prop, Watch } from '@stencil/core';
import { Component, Element, Event, EventEmitter, h, Host, Listen, Method, Prop, State, Watch } from '@stencil/core';

import { TOAST_PLACEMENT, TOAST_TYPE, TToastBorderRadius, TToastPlacement, TToastType } from './bq-toast.types';
import { debounce, TDebounce, validatePropValue } from '../../shared/utils';

const toastPortal = Object.assign(document.createElement('div'), { className: 'bq-toast-portal' });
const TOAST_PORTAL_SELECTOR = 'bq-toast-portal';

/**
* @part wrapper - The component's internal wrapper inside the shadow DOM.
* @part icon-info - The `<div>` container that holds the icon component.
* @part base - The `<div>` container of the internal bq-icon component.
* @part svg - The `<svg>` element of the internal bq-icon component.
*
* @slot - The content to be displayed in the toast component.
* @slot icon - The icon to be displayed in the toast component.
*/
@Component({
tag: 'bq-toast',
Expand All @@ -31,6 +34,8 @@ export class BqToast {
// Inlined decorator, alphabetical order
// =======================================

@State() private toastPortal = document.querySelector(`.${TOAST_PORTAL_SELECTOR}`);

// Public Property API
// ========================

Expand Down Expand Up @@ -61,8 +66,9 @@ export class BqToast {
validatePropValue(TOAST_TYPE, 'default', this.el, 'type');
validatePropValue(TOAST_PLACEMENT, 'bottom-center', this.el, 'placement');

toastPortal.classList.remove(...TOAST_PLACEMENT);
toastPortal.classList.add(this.placement);
const { toastPortal } = this;
toastPortal?.classList.remove(...TOAST_PLACEMENT);
toastPortal?.classList.add(this.placement);
}

@Watch('time')
Expand Down Expand Up @@ -99,6 +105,13 @@ export class BqToast {
// Ordered by their natural call order
// =====================================

connectedCallback() {
const { toastPortal } = this;
if (!toastPortal) {
this.toastPortal = Object.assign(document.createElement('div'), { className: TOAST_PORTAL_SELECTOR });
}
}

componentWillLoad() {
this.checkPropValues();
this.handleTimeChange();
Expand All @@ -115,10 +128,11 @@ export class BqToast {
@Listen('bqHide')
onNotificationHide() {
try {
toastPortal.removeChild(this.el);
const { toastPortal } = this;
toastPortal?.removeChild(this.el);
// Remove the toast portal from the DOM when there are no more toasts
if (toastPortal.querySelector('bq-toast') === null) {
toastPortal.remove();
if (toastPortal?.querySelector(this.el.tagName.toLowerCase()) === null) {
toastPortal?.remove();
}
} catch (error) {
/**
Expand Down Expand Up @@ -152,11 +166,12 @@ export class BqToast {
/** This method can be used to display toasts in a fixed-position element that allows for stacking multiple toasts vertically */
@Method()
async toast() {
if (toastPortal.parentElement === null) {
const { toastPortal } = this;
if (toastPortal?.parentElement === null) {
document.body.append(toastPortal);
}

toastPortal.appendChild(this.el);
toastPortal?.appendChild(this.el);

requestAnimationFrame(() => {
this.show();
Expand All @@ -183,26 +198,15 @@ export class BqToast {
};

private get iconName() {
switch (this.type) {
case 'success': {
return 'check-circle';
}
case 'error': {
return 'x-circle';
}
case 'loading': {
return 'spinner-gap';
}
case 'alert': {
return 'warning';
}
case 'info': {
return 'info';
}
default: {
return 'info';
}
}
const typeMap = {
success: 'check-circle-bold',
error: 'x-circle-bold',
loading: 'spinner-gap-bold',
alert: 'warning-bold',
info: 'info-bold',
};

return typeMap[this.type] || 'info-bold';
}

// render() function
Expand All @@ -225,7 +229,7 @@ export class BqToast {
<output class="bq-toast" part="wrapper">
<div class={{ [`bq-toast--icon ${this.type}`]: true, '!hidden': this.hideIcon }} part="icon">
<slot name="icon">
<bq-icon name={this.iconName} size="24" weight="bold" slot="icon" exportparts="base,svg"></bq-icon>
<bq-icon name={this.iconName} size="24" slot="icon" exportparts="base,svg" />
</slot>
</div>
<slot />
Expand Down
8 changes: 8 additions & 0 deletions packages/beeq/src/components/toast/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@ Type: `Promise<void>`



## Slots

| Slot | Description |
| -------- | --------------------------------------------------- |
| | The content to be displayed in the toast component. |
| `"icon"` | The icon to be displayed in the toast component. |


## Shadow Parts

| Part | Description |
Expand Down

0 comments on commit 341c6e3

Please sign in to comment.