feat(SW-498): Added Alert component

This commit is contained in:
Erik Tiekstra
2024-10-16 15:18:43 +02:00
parent bcee55c359
commit e41bf86993
6 changed files with 229 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
.alert {
display: flex;
gap: var(--Spacing-x2);
overflow: hidden;
}
.iconWrapper {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.content {
display: flex;
justify-content: space-between;
align-items: center;
gap: var(--Spacing-x2);
padding: var(--Spacing-x-one-and-half) var(--Spacing-x2)
var(--Spacing-x-one-and-half) 0;
flex-grow: 1;
}
.textWrapper {
display: grid;
gap: var(--Spacing-x-half);
padding: var(--Spacing-x1) 0;
}
.sidepeekCta {
flex-shrink: 0;
}
.closeButton {
border-width: 0;
padding: 0;
margin: 0;
background-color: transparent;
display: flex;
align-items: center;
flex-shrink: 0;
cursor: pointer;
}
/* Intent: inline */
.inline {
border-radius: var(--Corner-radius-Large);
border: 1px solid var(--Base-Border-Subtle);
background-color: var(--Base-Surface-Primary-light-Normal);
}
.inline .iconWrapper {
padding: var(--Spacing-x-one-and-half);
}
.inline.alarm .iconWrapper {
background-color: var(--Main-Red-70);
}
.inline.warning .iconWrapper {
background-color: var(--Main-Yellow-60);
}
.inline.info .iconWrapper {
background-color: var(--Scandic-Blue-70);
}
.inline .icon,
.inline .icon * {
fill: var(--Base-Surface-Primary-light-Normal);
}
.inline .closeButton {
border-left: 1px solid var(--Base-Border-Subtle);
padding: var(--Spacing-x-one-and-half);
}
/* Intent: banner */
.banner {
padding: 0 var(--Spacing-x5);
border-left-width: 6px;
border-left-style: solid;
}
.banner.alarm {
border-left-color: var(--Main-Red-70);
background-color: var(--Main-Red-00);
}
.banner.warning {
border-left-color: var(--Main-Yellow-60);
background-color: var(--Main-Yellow-00);
}
.banner.info {
border-left-color: var(--Scandic-Blue-70);
background-color: var(--Scandic-Blue-00);
}
.banner.alarm .icon,
.banner.alarm .icon * {
fill: var(--Main-Red-70);
}
.banner.warning .icon,
.banner.warning .icon * {
fill: var(--Main-Yellow-60);
}
.banner.info .icon,
.banner.info .icon * {
fill: var(--Scandic-Blue-70);
}
.banner .closeButton {
align-self: center;
padding-left: var(--Spacing-x-one-and-half);
}

View File

@@ -0,0 +1,16 @@
import { alertVariants } from "./variants"
import type { VariantProps } from "class-variance-authority"
import { AlertTypeEnum } from "@/types/enums/alert"
import type { SidepeekContent } from "@/types/trpc/routers/contentstack/siteConfig"
export interface AlertProps extends VariantProps<typeof alertVariants> {
className?: string
type: AlertTypeEnum
closeable?: boolean
heading?: string
text: string
sidepeekContent?: SidepeekContent | null
sidePeekCtaText?: string | null
}

View File

@@ -0,0 +1,69 @@
import { ChevronRightIcon, CloseLargeIcon } from "@/components/Icons"
import Button from "@/components/TempDesignSystem/Button"
import Body from "@/components/TempDesignSystem/Text/Body"
import { getIntl } from "@/i18n"
import { AlertProps } from "./alert"
import { getIconByAlertType } from "./utils"
import { alertVariants } from "./variants"
import styles from "./alert.module.css"
export default async function Alert({
className,
variant,
type,
heading,
text,
sidePeekCtaText,
sidepeekContent,
closeable = false,
}: AlertProps) {
const classNames = alertVariants({
className,
variant,
type,
})
const intl = await getIntl()
const Icon = getIconByAlertType(type)
return (
<div className={classNames}>
<span className={styles.iconWrapper}>
<Icon className={styles.icon} width={24} height={24} />
</span>
<div className={styles.content}>
<div className={styles.textWrapper}>
{heading ? (
<Body className={styles.heading} textTransform="bold" asChild>
<h2>{heading}</h2>
</Body>
) : null}
<Body className={styles.text}>{text}</Body>
</div>
{sidePeekCtaText ? (
<Button
theme="base"
variant="icon"
intent="text"
size="small"
wrapping
className={styles.sidepeekCta}
>
{sidePeekCtaText}
<ChevronRightIcon />
</Button>
) : null}
</div>
{closeable ? (
<button
className={styles.closeButton}
aria-label={intl.formatMessage({ id: "Close" })}
>
<CloseLargeIcon />
</button>
) : null}
</div>
)
}

View File

@@ -0,0 +1,17 @@
import { InfoCircleIcon } from "@/components/Icons"
import CrossCircleIcon from "@/components/Icons/CrossCircle"
import WarningTriangleIcon from "@/components/Icons/WarningTriangle"
import { AlertTypeEnum } from "@/types/enums/alert"
export function getIconByAlertType(alertType: AlertTypeEnum) {
switch (alertType) {
case AlertTypeEnum.Alarm:
return CrossCircleIcon
case AlertTypeEnum.Warning:
return WarningTriangleIcon
case AlertTypeEnum.Info:
default:
return InfoCircleIcon
}
}

View File

@@ -0,0 +1,20 @@
import { cva } from "class-variance-authority"
import styles from "./alert.module.css"
import { AlertTypeEnum } from "@/types/enums/alert"
export const alertVariants = cva(styles.alert, {
variants: {
variant: {
inline: styles.inline,
banner: styles.banner,
},
type: {
[AlertTypeEnum.Info]: styles.info,
[AlertTypeEnum.Warning]: styles.warning,
[AlertTypeEnum.Alarm]: styles.alarm,
},
},
defaultVariants: {},
})

View File

@@ -12,3 +12,4 @@ export type GetSiteConfigData = z.input<typeof siteConfigSchema>
export type SiteConfig = z.output<typeof siteConfigSchema>
export type Alert = z.output<typeof alertSchema>
export type SidepeekContent = Alert["sidepeekContent"]