Skip to content

Commit

Permalink
Merge pull request #309 from MetroStar/toast-update-placement
Browse files Browse the repository at this point in the history
Adding placement prop to toast with styles and keyframes.
  • Loading branch information
jbouder authored Dec 27, 2024
2 parents d7d23fa + 6248f68 commit 731974e
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 19 deletions.
26 changes: 14 additions & 12 deletions packages/comet-extras/src/components/toast/toast.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const meta: Meta<typeof Toast> = {
message: { control: 'text' },
duration: { control: 'number' },
type: { control: 'select', required: true },
placement: { control: 'select', required: true },
onClose: { action: 'close' },
allowClose: { control: 'boolean' },
className: { control: false },
Expand All @@ -34,6 +35,7 @@ const Template: StoryFn<typeof Toast> = (args: ToastProps) => {
id: `toast-${args.type}`,
message: `${!args.message ? 'Default toast notification for ' + args.type : args.message}`,
type: `${args.type}`,
placement: `${args.placement}`,
duration: `${!args.duration ? 3000 : args.duration}`,
allowClose: args.allowClose,
};
Expand All @@ -46,18 +48,17 @@ const Template: StoryFn<typeof Toast> = (args: ToastProps) => {
Send Toast
</Button>

<div>
{toasts.map((toast) => (
<Toast
key={toast.id}
id={toast.id}
message={toast.message}
type={toast.type}
duration={toast.duration}
allowClose={toast.allowClose}
/>
))}
</div>
{toasts.map((toast) => (
<Toast
key={toast.id}
id={toast.id}
message={toast.message}
type={toast.type}
placement={toast.placement}
duration={toast.duration}
allowClose={toast.allowClose}
/>
))}
</div>
);
};
Expand All @@ -67,6 +68,7 @@ Default.args = {
id: 'toast-info',
message: 'This is a toast notification',
type: 'info',
placement: 'topRight',
duration: 3000,
allowClose: true,
};
59 changes: 52 additions & 7 deletions packages/comet-extras/src/components/toast/toast.style.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,31 @@
padding: 12px 16px;
color: #1b1b1b;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
animation: slideIn 0.3s ease-out forwards;
position: fixed;
}

.toast--topLeft {
top: 20px;
left: 20px;
animation: slideInFromLeft 0.3s ease-out forwards;
}

.toast--topRight {
top: 20px;
right: 20px;
animation: slideInFromRight 0.3s ease-out forwards;
}

.toast--bottomLeft {
bottom: 20px;
left: 20px;
animation: slideInFromLeft 0.3s ease-out forwards;
}

.toast--bottomRight {
bottom: 20px;
right: 20px;
animation: slideInFromRight 0.3s ease-out forwards;
}

.toast--info {
Expand Down Expand Up @@ -59,11 +80,17 @@
transition: background-color 0.2s;
}

.toast--isLeaving {
animation: slideOut 0.3s ease-in forwards;
.toast--bottomRight.toast--isLeaving,
.toast--topRight.toast--isLeaving {
animation: slideOutToRight 0.3s ease-in forwards;
}

@keyframes slideIn {
.toast--bottomLeft.toast--isLeaving,
.toast--topLeft.toast--isLeaving {
animation: slideOutToLeft 0.3s ease-in forwards;
}

@keyframes slideInFromRight {
from {
transform: translateX(100%);
opacity: 0;
Expand All @@ -74,11 +101,18 @@
}
}

.toast--isLeaving {
animation: slideOut 0.3s ease-in forwards;
@keyframes slideInFromLeft {
from {
transform: translateX(-100%);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}

@keyframes slideOut {
@keyframes slideOutToRight {
from {
transform: translateX(0);
opacity: 1;
Expand All @@ -88,3 +122,14 @@
opacity: 0;
}
}

@keyframes slideOutToLeft {
from {
transform: translateX(0);
opacity: 1;
}
to {
transform: translateX(-100%);
opacity: 0;
}
}
26 changes: 26 additions & 0 deletions packages/comet-extras/src/components/toast/toast.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ describe('Toast Component Tests', () => {
expect(container.querySelector('#test-toast')).toHaveClass('toast--info');
});

test('should render a Toast notification from the top left', () => {
const { container } = render(
<Toast
id="test-toast"
placement="topLeft"
message="Testing message for notification"
type="info"
/>,
);
expect(container.querySelector('#test-toast')).toBeTruthy();
expect(container.querySelector('#test-toast')).toHaveClass('toast--topLeft');
});

test('should render a Toast notification from the bottom right', () => {
const { container } = render(
<Toast
id="test-toast"
placement="bottomRight"
message="Testing message for notification"
type="info"
/>,
);
expect(container.querySelector('#test-toast')).toBeTruthy();
expect(container.querySelector('#test-toast')).toHaveClass('toast--bottomRight');
});

test('should render a warning Toast notification', () => {
const { container } = render(
<Toast id="test-toast" message="Testing message for notification" type="warning" />,
Expand Down
6 changes: 6 additions & 0 deletions packages/comet-extras/src/components/toast/toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export interface ToastProps {
* The type of toast which determines its color scheme
* */
type?: 'success' | 'error' | 'warning' | 'info' | 'emergency';
/**
* The placement of toast which determines where it appears
* */
placement?: 'topRight' | 'bottomRight' | 'topLeft' | 'bottomLeft';
/**
* Callback function when toast is closed either manually or automatically
* */
Expand All @@ -39,6 +43,7 @@ export const Toast = ({
message = 'This is a toast notification',
duration = 3000,
type = 'info',
placement = 'topRight',
className = '',
onClose = () => {},
allowClose = true,
Expand All @@ -49,6 +54,7 @@ export const Toast = ({
const classes = classnames(
'toast',
`toast--${type}`,
`toast--${placement}`,
className,
`${isLeaving ? 'toast--isLeaving' : ''}`,
);
Expand Down

0 comments on commit 731974e

Please sign in to comment.