feat(SW-498): Added Alert component
This commit is contained in:
106
components/TempDesignSystem/Alert/alert.module.css
Normal file
106
components/TempDesignSystem/Alert/alert.module.css
Normal 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);
|
||||
}
|
||||
16
components/TempDesignSystem/Alert/alert.ts
Normal file
16
components/TempDesignSystem/Alert/alert.ts
Normal 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
|
||||
}
|
||||
69
components/TempDesignSystem/Alert/index.tsx
Normal file
69
components/TempDesignSystem/Alert/index.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
17
components/TempDesignSystem/Alert/utils.ts
Normal file
17
components/TempDesignSystem/Alert/utils.ts
Normal 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
|
||||
}
|
||||
}
|
||||
20
components/TempDesignSystem/Alert/variants.ts
Normal file
20
components/TempDesignSystem/Alert/variants.ts
Normal 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: {},
|
||||
})
|
||||
@@ -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"]
|
||||
|
||||
Reference in New Issue
Block a user