feat(SW-214): Implement usp component
This commit is contained in:
35
components/Blocks/UspGrid/index.tsx
Normal file
35
components/Blocks/UspGrid/index.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { getIconByIconName } from "@/components/Icons/get-icon-by-icon-name"
|
||||
import JsonToHtml from "@/components/JsonToHtml"
|
||||
|
||||
import { renderOptions } from "./renderOptions"
|
||||
import { getUspIconName } from "./utils"
|
||||
|
||||
import styles from "./uspgrid.module.css"
|
||||
|
||||
import type { UspGridProps, UspIcon } from "@/types/components/blocks/uspGrid"
|
||||
|
||||
function UspIcon({ icon }: { icon: UspIcon }) {
|
||||
const iconName = getUspIconName(icon)
|
||||
const Icon = iconName ? getIconByIconName(iconName) : null
|
||||
return Icon ? <Icon color="red" /> : null
|
||||
}
|
||||
|
||||
export default function UspGrid({ usp_grid }: UspGridProps) {
|
||||
return (
|
||||
<div className={styles.grid}>
|
||||
{usp_grid.usp_card.map(
|
||||
(usp) =>
|
||||
usp.text.json && (
|
||||
<div key={usp.text.json.uid} className={styles.usp}>
|
||||
<UspIcon icon={usp.icon} />
|
||||
<JsonToHtml
|
||||
embeds={usp.text.embedded_itemsConnection?.edges}
|
||||
nodes={usp.text.json.children}
|
||||
renderOptions={{ ...renderOptions }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
73
components/Blocks/UspGrid/renderOptions.tsx
Normal file
73
components/Blocks/UspGrid/renderOptions.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import Link from "@/components/TempDesignSystem/Link"
|
||||
import { removeMultipleSlashes } from "@/utils/url"
|
||||
|
||||
import styles from "./uspgrid.module.css"
|
||||
|
||||
import { EmbedEnum } from "@/types/requests/utils/embeds"
|
||||
import type { EmbedByUid } from "@/types/transitionTypes/jsontohtml"
|
||||
import { RTEItemTypeEnum, RTETypeEnum } from "@/types/transitionTypes/rte/enums"
|
||||
import type {
|
||||
RTEDefaultNode,
|
||||
RTENext,
|
||||
RTENode,
|
||||
RTERegularNode,
|
||||
} from "@/types/transitionTypes/rte/node"
|
||||
import type { RenderOptions } from "@/types/transitionTypes/rte/option"
|
||||
|
||||
export const renderOptions: RenderOptions = {
|
||||
[RTETypeEnum.p]: (
|
||||
node: RTEDefaultNode,
|
||||
embeds: EmbedByUid,
|
||||
next: RTENext,
|
||||
fullRenderOptions: RenderOptions
|
||||
) => {
|
||||
return (
|
||||
<p key={node.uid} className={styles.p}>
|
||||
{next(node.children, embeds, fullRenderOptions)}
|
||||
</p>
|
||||
)
|
||||
},
|
||||
[RTETypeEnum.a]: (
|
||||
node: RTERegularNode,
|
||||
embeds: EmbedByUid,
|
||||
next: RTENext,
|
||||
fullRenderOptions: RenderOptions
|
||||
) => {
|
||||
if (node.attrs.url) {
|
||||
return (
|
||||
<a
|
||||
href={node.attrs.url}
|
||||
target={node.attrs.target ?? "_blank"}
|
||||
key={node.uid}
|
||||
className={styles.a}
|
||||
>
|
||||
{next(node.children, embeds, fullRenderOptions)}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
return null
|
||||
},
|
||||
[RTETypeEnum.reference]: (
|
||||
node: RTENode,
|
||||
embeds: EmbedByUid,
|
||||
next: RTENext,
|
||||
fullRenderOptions: RenderOptions
|
||||
) => {
|
||||
if ("attrs" in node) {
|
||||
const type = node.attrs.type
|
||||
if (type !== RTEItemTypeEnum.asset) {
|
||||
const href = node.attrs?.locale
|
||||
? `/${node.attrs.locale}${node.attrs.href}`
|
||||
: node.attrs.href
|
||||
|
||||
return (
|
||||
<Link href={href} key={node.uid} className={styles.a}>
|
||||
{next(node.children, embeds, fullRenderOptions)}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
},
|
||||
}
|
||||
28
components/Blocks/UspGrid/uspgrid.module.css
Normal file
28
components/Blocks/UspGrid/uspgrid.module.css
Normal file
@@ -0,0 +1,28 @@
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: var(--Spacing-x3);
|
||||
padding: var(--Spacing-x3) var(--Spacing-x4);
|
||||
}
|
||||
@media screen and (min-width: 767px) {
|
||||
.grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
.grid:has(.usp:nth-child(4)) {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
}
|
||||
.usp {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--Spacing-x3);
|
||||
}
|
||||
.p {
|
||||
margin: 0;
|
||||
font-size: var(--typography-Caption-Regular-fontSize);
|
||||
color: var(--UI-Text-Medium-contrast);
|
||||
line-height: 21px; /* Caption variable for line-height is 139.9999976158142%, but it set to 21px in design */
|
||||
}
|
||||
.a {
|
||||
font-size: var(--typography-Caption-Regular-fontSize);
|
||||
color: var(--Base-Text-High-contrast);
|
||||
}
|
||||
11
components/Blocks/UspGrid/utils.ts
Normal file
11
components/Blocks/UspGrid/utils.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { UspIcon } from "@/types/components/blocks/uspGrid"
|
||||
import { IconName } from "@/types/components/icon"
|
||||
|
||||
export function getUspIconName(icon?: UspIcon | null) {
|
||||
switch (icon) {
|
||||
case "Snowflake":
|
||||
return IconName.Snowflake
|
||||
default:
|
||||
return IconName.Snowflake
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user