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:
@@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user