Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Debt] Updates Toast component and react-toastify #12426

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/toast/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"react-toastify": "^10.0.6"
"react-toastify": "^11.0.2"
},
"devDependencies": {
"@faker-js/faker": "^9.3.0",
"@gc-digital-talent/eslint-config": "workspace:*",
"@gc-digital-talent/storybook-helpers": "workspace:*",
"@gc-digital-talent/ui": "workspace:*",
"@storybook/react": "^8.4.7",
"@types/react": "^18.3.13",
"eslint": "^8.57.0",
Expand Down
75 changes: 44 additions & 31 deletions packages/toast/src/components/Toast/Toast.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,56 @@
import type { StoryFn, Meta } from "@storybook/react";
import { faker } from "@faker-js/faker/locale/en";
import { useEffect } from "react";
import type { Meta, StoryObj } from "@storybook/react";

import { OverlayOrDialogDecorator } from "@gc-digital-talent/storybook-helpers";
import {
allModes,
OverlayOrDialogDecorator,
} from "@gc-digital-talent/storybook-helpers";

import toast from "../../toast";
import Toast from "./Toast";
import "./toast.css";

interface StoryArgs {
text: string;
longText: string;
}

faker.seed(0);

export default {
const meta = {
component: Toast,
argTypes: {
disableTransition: { control: "boolean" },
autoClose: { control: "boolean" },
},
args: {
text: "Toast text",
longText: faker.lorem.sentences(3),
disableTransition: true,
autoClose: false,
},
decorators: [OverlayOrDialogDecorator],
} as Meta;

const Template: StoryFn<StoryArgs> = (args) => {
const { text, longText } = args;

toast.info(text);
toast.info(longText);
toast.success(text);
toast.warning(text);
toast.error(text);

// avoid animations with Chromatic snapshots
return (
<div>
<Toast disableTransition autoClose={false} />
</div>
);
parameters: {
chromatic: {
modes: {
light: allModes.light,
dark: allModes.dark,
},
delay: 1500,
},
},
} satisfies Meta<typeof Toast>;
export default meta;

type Story = StoryObj<typeof Toast>;

const Template = () => {
useEffect(() => {
setTimeout(() => {
toast.info("Toast info text", { autoClose: false });
toast.info(
"Toast info with three sentences. Text sentence two. Toast text sentence three.",
{ autoClose: false },
);
toast.success("Toast success text", { autoClose: false });
toast.warning("Toast warning text", { autoClose: false });
toast.error("Toast error text", { autoClose: false });
}, 100);
}, []);
return <Toast />;
};

export const Default = Template.bind({});
export const Default: Story = {
render: () => <Template />,
};
2 changes: 1 addition & 1 deletion packages/toast/src/components/Toast/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import XCircleIcon from "@heroicons/react/24/solid/XCircleIcon";

import closeButtonStyles from "./styles";

import "react-toastify/dist/ReactToastify.minimal.css";
import "./toast.css";

type CloseButtonProps = ComponentPropsWithoutRef<
Expand Down Expand Up @@ -52,6 +51,7 @@ const Toast = ({ disableTransition, autoClose = 5000 }: ToastProps) => (
closeButton={CloseButton}
icon={false}
autoClose={autoClose}
aria-label={undefined}
/>
);

Expand Down
192 changes: 16 additions & 176 deletions packages/toast/src/components/Toast/toast.css
Original file line number Diff line number Diff line change
@@ -1,191 +1,31 @@
:root {
--toast-space: calc(var(--h2-base-whitespace) * 1rem);
--toastify-toast-width: calc(100vw - calc(2 * var(--toast-space)));
--toastify-toast-offset: 16px;
--toastify-toast-padding: 0;
--toastify-text-color-light: rgba(var(--h2-color-black), 1);
--toastify-font-family: inherit;
}

/** Used to define container behavior: width, position: fixed etc... **/
.Toastify__toast-container {
position: fixed;
width: calc(100vw - calc(2 * var(--toast-space)));
z-index: 999999; /* Display over everything else */
}

@media screen and (min-width: 48rem) {
.Toastify__toast-container {
width: 40vw;
}
}

/** Used to define the position of the ToastContainer **/
.Toastify__toast-container--top-left {
top: var(--toast-space);
left: var(--toast-space);
}

.Toastify__toast-container--top-center {
top: var(--toast-space);
left: 50%;
transform: translateX(-50%);
}

.Toastify__toast-container--top-right {
top: var(--toast-space);
right: var(--toast-space);
}

.Toastify__toast-container--bottom-left {
bottom: var(--toast-space);
left: var(--toast-space);
}

.Toastify__toast-container--bottom-center {
bottom: var(--toast-space);
left: 50%;
transform: translateX(-50%);
.Toastify__toast {
display: block;
}

.Toastify__toast-container--bottom-right {
z-index: 999999; /* Display over everything else */
left: auto;
bottom: var(--toast-space);
right: var(--toast-space);
}

/** Classes for the displayed toast **/
.Toastify__toast {
background-color: rgba(var(--h2-color-foreground), 1);
box-sizing: border-box;
position: relative;
margin-bottom: calc((var(--h2-base-whitespace) * 0.5) * 1rem);
border: 3px solid;
border-radius: var(--h2-radius-rounded);
box-shadow: var(--h2-shadow-largest);
display: flex;
overflow: hidden;
justify-content: space-between;
z-index: 0;
}

.Toastify__toast-body {
align-items: center;
display: flex;
margin: auto 0;
flex: 1 1 auto;
}

.Toastify__toast-body > div:nth-child(2) {
padding-right: calc((var(--h2-base-whitespace) * 2) * 1rem);
}

.Toastify__toast--default {
border-color: rgba(var(--h2-color-black), 1);
}

.Toastify__toast--info {
border-color: rgba(var(--h2-color-secondary-darker), 1);
}

.Toastify__toast--success {
border-color: rgba(var(--h2-color-success-darker), 1);
}

.Toastify__toast--warning {
border-color: rgba(var(--h2-color-warning-darker), 1);
}

.Toastify__toast--error {
border-color: rgba(var(--h2-color-error-darker), 1);
}

.Toastify__toast-icon {
display: flex;
align-items: flex-start;
align-self: stretch;
padding: calc(var(--h2-base-whitespace) * 0.5rem)
calc(var(--h2-base-whitespace) * 1rem);
position: relative;
}

.Toastify__toast--info .Toastify__toast-icon {
background-color: rgba(var(--h2-color-secondary-lightest-locked), 1);
color: rgba(var(--h2-color-secondary-darker-locked), 1);
}

.Toastify__toast--success .Toastify__toast-icon {
background-color: rgba(var(--h2-color-success-lightest-locked), 1);
color: rgba(var(--h2-color-success-darker-locked), 1);
}

.Toastify__toast--warning .Toastify__toast-icon {
background-color: rgba(var(--h2-color-warning-lightest-locked), 1);
color: rgba(var(--h2-color-warning-darker-locked), 1);
}

.Toastify__toast--error .Toastify__toast-icon {
background-color: rgba(var(--h2-color-error-lightest-locked), 1);
color: rgba(var(--h2-color-error-darker-locked), 1);
right: 0.25rem;
}

.Toastify__toast-icon:after {
border-style: solid;
border-width: 10px 0 10px 10px;
bottom: auto;
content: "";
height: 0;
left: 100%;
position: absolute;
top: calc((1 * var(--h2-base-whitespace)) * 1.1rem);
transform: translate(0);
width: 0;
}

.Toastify__toast--info .Toastify__toast-icon:after {
border-color: transparent transparent transparent
rgba(var(--h2-color-secondary-lightest-locked), 1);
}
.Toastify__toast--success .Toastify__toast-icon:after {
border-color: transparent transparent transparent
rgba(var(--h2-color-success-lightest-locked), 1);
}
.Toastify__toast--warning .Toastify__toast-icon:after {
border-color: transparent transparent transparent
rgba(var(--h2-color-warning-lightest-locked), 1);
}
.Toastify__toast--error .Toastify__toast-icon:after {
border-color: transparent transparent transparent
rgba(var(--h2-color-error-lightest-locked), 1);
}

.Toastify--animate {
animation-fill-mode: both;
animation-duration: 0.7s;
}

@keyframes Toastify__slideInUp {
from {
transform: translateY(110%);
opacity: 0;
visibility: visible;
}
to {
transform: translateY(0);
opacity: 1;
@media screen and (min-width: 48rem) {
:root {
--toastify-toast-width: 40vw;
}
}

@keyframes Toastify__slideOutRight {
from {
opacity: 1;
transform: translateX(0);
@media only screen and (max-width: 480px) {
.Toastify__toast {
--toastify-toast-width: calc(100vw - calc(2 * var(--toast-space)));
}
to {
visibility: hidden;
transform: translateX(200%);
opacity: 0;
}
}

.Toastify__slide-enter--bottom-right {
animation-name: Toastify__slideInUp;
}

.Toastify__slide-exit--bottom-right {
animation-name: Toastify__slideOutRight;
}
14 changes: 14 additions & 0 deletions packages/toast/src/components/ToastAlert/ToastAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Alert, AlertProps } from "@gc-digital-talent/ui";

const ToastAlert = ({ type, children }: AlertProps) => (
<Alert.Root live={false} type={type} data-h2-margin="base(0)" tabIndex={0}>
<div
data-h2-padding-right="p-tablet(x2)"
data-h2-line-height="base(var(--h2-base-line-height))"
>
{children}
</div>
</Alert.Root>
);

export default ToastAlert;
16 changes: 0 additions & 16 deletions packages/toast/src/components/ToastMessage/ToastMessage.tsx

This file was deleted.

Loading
Loading