Skip to content

Commit

Permalink
✨ pix-ui : add pixToast component
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreiaPena committed Sep 30, 2024
1 parent 8ad77e7 commit b0c76c1
Show file tree
Hide file tree
Showing 12 changed files with 382 additions and 0 deletions.
9 changes: 9 additions & 0 deletions addon/components/pix-toast-container.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div class="pix-toast-container">
{{#if this.pixToast.content}}
<PixToast
@message={{this.pixToast.content.message}}
@ariaLabelForCloseButton={{this.pixToast.content.ariaLabel}}
@type={{this.pixToast.content.type}}
/>
{{/if}}
</div>
6 changes: 6 additions & 0 deletions addon/components/pix-toast-container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Component from '@glimmer/component';
import { service } from '@ember/service';

export default class PixToastContainer extends Component {
@service pixToast;
}
17 changes: 17 additions & 0 deletions addon/components/pix-toast.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class="pix-toast {{concat 'pix-toast--' this.type}}" ...attributes>
<div class="pix-toast__icon {{concat 'pix-toast__icon--' this.type}}">
<FaIcon @icon={{this.iconClass}} />
</div>
<p class="pix-toast__content">
{{@message}}
</p>
<div class="pix-toast__close-button-container">
<PixIconButton
@ariaLabel={{@ariaLabelForCloseButton}}
@icon="xmark"
@size="small"
@triggerAction={{this.removeNotification}}
class="{{concat 'pix-toast__close-button--' this.type}}"
/>
</div>
</div>
37 changes: 37 additions & 0 deletions addon/components/pix-toast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Component from '@glimmer/component';
import { service } from '@ember/service';
import { action } from '@ember/object';
import { warn } from '@ember/debug';
const TYPE_SUCCESS = 'success';
const TYPE_ERROR = 'error';
const TYPE_INFORMATION = 'information';
const TYPE_WARNING = 'warning';

export default class PixToast extends Component {
@service pixToast;

get type() {
const correctTypes = [TYPE_SUCCESS, TYPE_ERROR, TYPE_INFORMATION, TYPE_WARNING];
warn('PixToast: you need to provide a type', [correctTypes].includes(this.args.type), {
id: 'pix-ui.toast.type.not-provided',
});
return this.args.type ?? 'success';
}

get iconClass() {
const classes = {
[TYPE_SUCCESS]: 'circle-check',
[TYPE_ERROR]: 'circle-exclamation',
[TYPE_INFORMATION]: 'circle-info',
[TYPE_WARNING]: 'triangle-exclamation',
};
return classes[this.type];
}

@action
removeNotification(event) {
event.preventDefault();
event.stopPropagation();
this.pixToast.removeNotification(this.pixToast.content);
}
}
63 changes: 63 additions & 0 deletions addon/services/pix-toast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import Service from '@ember/service';
import EmberObject from '@ember/object';
import { tracked } from '@glimmer/tracking';

export default class ToastService extends Service {
@tracked content = undefined;

addNotification({ message, ariaLabel, type }) {
if (!message || !ariaLabel) {
throw new Error('Mandatory attributes are missing: message and ariaLabel');
}

const toast = EmberObject.create({
ariaLabel,
message,
type: type || 'success',
});

this.content = toast;

return toast;
}

sendErrorNotification({ message, ariaLabel }) {
return this.addNotification({
ariaLabel,
message,
type: 'error',
});
}

sendSuccessNotification({ message, ariaLabel }) {
return this.addNotification({
ariaLabel,
message,
type: 'success',
});
}

sendInformationNotification({ message, ariaLabel }) {
return this.addNotification({
ariaLabel,
message,
type: 'information',
});
}

sendWarningNotification({ message, ariaLabel }) {
return this.addNotification({
ariaLabel,
message,
type: 'warning',
});
}

removeNotification(toast) {
if (!toast) {
return;
}

this.content = undefined;
}
}
138 changes: 138 additions & 0 deletions addon/styles/_pix-toast.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
.pix-toast {
display: flex;
max-width: 400px;
margin: 0 auto;
border-radius: 5px;
transition: all 0.3s ease-in-out;

&--error {
color: var(--pix-error-700);
background-color: var(--pix-error-50);
border: 1.5px solid var(--pix-error-700);
}

&--success {
color: var(--pix-success-700);
background-color: var(--pix-success-50);
border: 1.5px solid var(--pix-success-700);
}

&--information {
color: var(--pix-info-700);
background-color: var(--pix-info-50);
border: 1.5px solid var(--pix-info-700);
}

&--warning {
color: var(--pix-warning-700);
background-color: var(--pix-warning-50);
border: 1.5px solid var(--pix-warning-700);
}

> div, p {
@extend %pix-body-m;

display: flex;
align-items: center;
justify-content: center;
}
}

.pix-toast__icon {
flex: none;
width: 40px;

&--error {
color: var(--pix-neutral-0);
background-color: var(--pix-error-700);
}

&--success {
color: var(--pix-neutral-0);
background-color: var(--pix-success-700);
}

&--information {
color: var(--pix-neutral-0);
background-color: var(--pix-info-700);
}

&--warning {
color: var(--pix-neutral-0);
background-color: var(--pix-warning-700);
}
}

.pix-toast__content {
padding: 8px 12px;
}

.pix-toast__close-button-container {
flex: none;
width: 40px;
}

.pix-toast__close-button {
&--error {
color: var(--pix-error-700);

&:hover:enabled,
&:active:enabled, {
color: var(--pix-neutral-0);
background-color: var(--pix-error-700);
}

&:focus:enabled {
background-color: var(--pix-error-900);
}
}

&--success {
color: var(--pix-success-700);

&:hover:enabled,
&:active:enabled, {
color: var(--pix-neutral-0);
background-color: var(--pix-success-700);
}

&:focus:enabled {
background-color: var(--pix-success-900);
}
}

&--information {
color: var(--pix-info-700);

&:hover:enabled,
&:active:enabled, {
color: var(--pix-neutral-0);
background-color: var(--pix-info-700);
}

&:focus:enabled {
background-color: var(--pix-info-900);
}
}

&--warning {
color: var(--pix-warning-700);

&:hover:enabled,
&:active:enabled, {
color: var(--pix-neutral-0);
background-color: var(--pix-warning-700);
}

&:focus:enabled {
background-color: var(--pix-warning-900);
}
}
}

.pix-toast-container {
position: fixed;
right: 12px;
bottom: 30px;
z-index: 1000;
}
1 change: 1 addition & 0 deletions addon/styles/addon.scss
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
@import 'pix-indicator-card';
@import 'trap-focus';
@import 'pix-search-input';
@import 'pix-toast';

// at the end so it can override it's children scss
@import 'pix-filterable-and-searchable-select';
Expand Down
1 change: 1 addition & 0 deletions app/components/pix-toast-container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@1024pix/pix-ui/components/pix-toast-container';
1 change: 1 addition & 0 deletions app/components/pix-toast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@1024pix/pix-ui/components/pix-toast';
1 change: 1 addition & 0 deletions app/services/pix-toast.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from '@1024pix/pix-ui/services/pix-toast';
47 changes: 47 additions & 0 deletions app/stories/pix-toast.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { Meta, Story, ArgTypes } from '@storybook/blocks';
import * as ComponentStories from './pix-toast.stories';

<Meta of={ComponentStories} />

# Pix Toast

Une notification avec icône et un bouton de fermeture.

## Success

La notification en cas de succès.

<Story of={ComponentStories.success} height={300} />

## Error

La notification en cas d'erreur.

<Story of={ComponentStories.error} height={300} />

## Information

La notification pour afficher une information.

<Story of={ComponentStories.information} height={300} />

## Warning

La notification pour afficher un avertissement.

<Story of={ComponentStories.warning} height={300} />


## Usage

```html
<PixToast
@type="success"
@message="Bonjour !"
@ariaLabelForCloseButton='Fermer la notification'
/>
```

## Arguments

<ArgTypes />
Loading

0 comments on commit b0c76c1

Please sign in to comment.