Merged in SW-3317-move-toast-to-design-system (pull request #2716)

SW-3317 move toast to design system

* chore: Move toast to design-system and add interaction tests

* Move toast to design-system and add storybook tests

* Merge branch 'master' of bitbucket.org:scandic-swap/web into SW-3317-move-toast-to-design-system

* merge

* move sonner dependency to @scandic-hotels/design-system


Approved-by: Anton Gunnarsson
This commit is contained in:
Joakim Jäderberg
2025-08-27 13:03:17 +00:00
parent 34135879a8
commit 72f4f72a17
40 changed files with 366 additions and 172 deletions
@@ -1,104 +0,0 @@
import { type ExternalToast, toast as sonnerToast, Toaster } from "sonner"
import Body from "@scandic-hotels/design-system/Body"
import {
MaterialIcon,
type MaterialIconSetIconProps,
} from "@scandic-hotels/design-system/Icons/MaterialIcon"
import { OldDSButton as Button } from "@scandic-hotels/design-system/OldDSButton"
import { toastVariants } from "./variants"
import styles from "./toasts.module.css"
import type { ToastsProps } from "./toasts"
export function ToastHandler() {
return <Toaster position="bottom-right" duration={5000} />
}
interface AlertIconProps {
variant: ToastsProps["variant"]
}
function AlertIcon({
variant,
...props
}: AlertIconProps & MaterialIconSetIconProps) {
switch (variant) {
case "error":
return <MaterialIcon icon="cancel" {...props} />
case "info":
return <MaterialIcon icon="info" {...props} />
case "success":
return <MaterialIcon icon="check_circle" {...props} />
case "warning":
return <MaterialIcon icon="warning" {...props} />
}
}
export function Toast({ children, message, onClose, variant }: ToastsProps) {
const className = toastVariants({ variant })
const Icon = <AlertIcon variant={variant} color="Icon/Inverted" />
return (
<div className={className}>
<div className={styles.iconContainer}>{Icon && Icon}</div>
{message ? (
<Body className={styles.message}>{message}</Body>
) : (
<div className={styles.content}>{children}</div>
)}
{onClose ? (
<Button onClick={onClose} variant="icon" intent="tertiary">
<MaterialIcon icon="close" />
</Button>
) : null}
</div>
)
}
export const toast = {
success: (message: React.ReactNode, options?: ExternalToast) =>
sonnerToast.custom(
(t) => (
<Toast
variant="success"
message={message}
onClose={() => sonnerToast.dismiss(t)}
/>
),
options
),
info: (message: React.ReactNode, options?: ExternalToast) =>
sonnerToast.custom(
(t) => (
<Toast
variant="info"
message={message}
onClose={() => sonnerToast.dismiss(t)}
/>
),
options
),
error: (message: React.ReactNode, options?: ExternalToast) =>
sonnerToast.custom(
(t) => (
<Toast
variant="error"
message={message}
onClose={() => sonnerToast.dismiss(t)}
/>
),
options
),
warning: (message: React.ReactNode, options?: ExternalToast) =>
sonnerToast.custom(
(t) => (
<Toast
variant="warning"
message={message}
onClose={() => sonnerToast.dismiss(t)}
/>
),
options
),
}
@@ -1,48 +0,0 @@
.toast {
display: grid;
grid-template-columns: auto 1fr auto;
border-radius: var(--Corner-radius-lg);
overflow: hidden;
background: var(--Base-Surface-Primary-light-Normal);
box-shadow: 0px 0px 8px 2px rgba(0, 0, 0, 0.08);
align-items: center;
}
.content {
padding: var(--Spacing-x-one-and-half) var(--Spacing-x3);
}
@media screen and (min-width: 768px) {
.toast {
width: var(--width);
}
}
.toast .message {
padding: var(--Spacing-x2) var(--Spacing-x-one-and-half);
}
.success {
--icon-background-color: var(--UI-Semantic-Success);
}
.error {
--icon-background-color: var(--UI-Semantic-Error);
}
.warning {
--icon-background-color: var(--UI-Semantic-Warning);
}
.info {
--icon-background-color: var(--UI-Semantic-Information);
}
.iconContainer {
display: flex;
align-items: center;
justify-content: center;
background-color: var(--icon-background-color);
padding: var(--Spacing-x2);
height: 100%;
}
@@ -1,17 +0,0 @@
import type { VariantProps } from "class-variance-authority"
import type { toastVariants } from "./variants"
export type ToastsProps = Omit<React.HTMLAttributes<HTMLDivElement>, "color"> &
VariantProps<typeof toastVariants> & {
onClose?: () => void
} & (
| {
children: React.ReactNode
message?: never
}
| {
children?: never
message: React.ReactNode
}
)
@@ -1,14 +0,0 @@
import { cva } from "class-variance-authority"
import styles from "./toasts.module.css"
export const toastVariants = cva(styles.toast, {
variants: {
variant: {
success: styles.success,
info: styles.info,
warning: styles.warning,
error: styles.error,
},
},
})