diff --git a/components/Current/Aside/Puff/index.tsx b/components/Current/Aside/Puff/index.tsx
index f435c442d..a08f99605 100644
--- a/components/Current/Aside/Puff/index.tsx
+++ b/components/Current/Aside/Puff/index.tsx
@@ -6,6 +6,7 @@ import { Button } from "@scandic-hotels/design-system/current"
import Image from "@/components/Image"
import JsonToHtml from "@/components/JsonToHtml"
+import { renderOptions as currentRenderOption } from "./../../currentRenderOptions"
import { renderOptions } from "./renderOptions"
import styles from "./puff.module.css"
@@ -44,7 +45,7 @@ export default function Puff({
diff --git a/components/Current/Blocks/Text.tsx b/components/Current/Blocks/Text.tsx
index d79bf1518..4d20bd1fc 100644
--- a/components/Current/Blocks/Text.tsx
+++ b/components/Current/Blocks/Text.tsx
@@ -1,5 +1,7 @@
import JsonToHtml from "@/components/JsonToHtml"
+import { renderOptions } from "./../currentRenderOptions"
+
import type { TextProps } from "@/types/components/current/blocks/text"
export default function Text({ text }: TextProps) {
@@ -7,6 +9,7 @@ export default function Text({ text }: TextProps) {
)
}
diff --git a/components/Current/Preamble/index.tsx b/components/Current/Preamble/index.tsx
index d615a6da6..ef0dc682a 100644
--- a/components/Current/Preamble/index.tsx
+++ b/components/Current/Preamble/index.tsx
@@ -1,5 +1,6 @@
import JsonToHtml from "@/components/JsonToHtml"
+import { renderOptions as currentRenderOption } from "./../currentRenderOptions"
import Breadcrumbs from "./Breadcrumbs"
import { renderOptions } from "./renderOptions"
@@ -27,7 +28,7 @@ export default function Preamble({
) : null}
diff --git a/components/Current/currentRenderOptions.module.css b/components/Current/currentRenderOptions.module.css
new file mode 100644
index 000000000..2e564ffac
--- /dev/null
+++ b/components/Current/currentRenderOptions.module.css
@@ -0,0 +1,6 @@
+.image {
+ height: auto;
+ margin-bottom: var(--Spacing-x2);
+ max-width: 100%;
+ object-fit: cover;
+}
diff --git a/components/Current/currentRenderOptions.tsx b/components/Current/currentRenderOptions.tsx
new file mode 100644
index 000000000..ae8c465be
--- /dev/null
+++ b/components/Current/currentRenderOptions.tsx
@@ -0,0 +1,474 @@
+import Image from "@/components/Image"
+import Link from "@/components/TempDesignSystem/Link"
+
+import styles from "./currentRenderOptions.module.css"
+
+import type { EmbedByUid } from "@/types/components/jsontohtml"
+import { EmbedEnum } from "@/types/requests/utils/embeds"
+import type { Attributes } from "@/types/rte/attrs"
+import { RTEItemTypeEnum, RTETypeEnum } from "@/types/rte/enums"
+import type {
+ RTEDefaultNode,
+ RTENext,
+ RTENode,
+ RTERegularNode,
+} from "@/types/rte/node"
+import { RTEMarkType } from "@/types/rte/node"
+import type { RenderOptions } from "@/types/rte/option"
+
+function extractPossibleAttributes(attrs: Attributes | undefined) {
+ if (!attrs) return {}
+ const props: Record
= {}
+ if (attrs.id) {
+ props.id = attrs.id
+ }
+
+ if (attrs.class) {
+ props.className = attrs.class
+ } else if (attrs["class-name"]) {
+ props.className = attrs["class-name"]
+ } else if (attrs.classname) {
+ props.className = attrs.classname
+ } else if (attrs?.style?.["text-align"]) {
+ props.style = {
+ textAlign: attrs?.style?.["text-align"],
+ }
+ }
+
+ return props
+}
+
+export const renderOptions: RenderOptions = {
+ [RTETypeEnum.a]: (
+ node: RTERegularNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ if (node.attrs.url) {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ }
+ return null
+ },
+
+ [RTETypeEnum.blockquote]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.code]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.embed]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ if (node.attrs.src) {
+ props.src = node.attrs.src
+ }
+ if (node.attrs.url) {
+ props.src = node.attrs.url
+ }
+ if (!props.src) {
+ return null
+ }
+ return (
+
+ )
+ },
+
+ [RTETypeEnum.h1]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.h2]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.h3]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.h4]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.h5]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.h6]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.hr]: () => {
+ return
+ },
+
+ [RTETypeEnum.li]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.ol]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.p]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.reference]: (
+ node: RTENode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ if ("attrs" in node) {
+ const type = node.attrs.type
+ if (type === RTEItemTypeEnum.asset) {
+ const image = embeds?.[node?.attrs?.["asset-uid"]]
+ if (image?.node.__typename === EmbedEnum.SysAsset) {
+ const alt = image?.node?.title ?? node.attrs.alt
+ const alignment = node.attrs?.style?.["text-align"]
+ ? {
+ alignSelf: node.attrs?.style?.["text-align"],
+ }
+ : {}
+ return (
+
+ )
+ }
+ } else {
+ const props = extractPossibleAttributes(node.attrs)
+ const href = node.attrs?.locale
+ ? `/${node.attrs.locale}${node.attrs.href}`
+ : node.attrs.href
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ }
+ }
+
+ return null
+ },
+
+ [RTETypeEnum.table]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.thead]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.tbody]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.tfoot]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.tr]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ [RTETypeEnum.th]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+ |
+ )
+ },
+
+ [RTETypeEnum.td]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+ |
+ )
+ },
+
+ [RTETypeEnum.ul]: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ const props = extractPossibleAttributes(node.attrs)
+ return (
+
+ {next(node.children, embeds, fullRenderOptions)}
+
+ )
+ },
+
+ /** TextNode wrappers */
+ [RTEMarkType.bold]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.italic]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.underline]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.strikethrough]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.inlineCode]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.subscript]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.superscript]: (children: React.ReactNode) => {
+ return {children}
+ },
+
+ [RTEMarkType.break]: (children: React.ReactNode) => {
+ return (
+ <>
+
+ {children}
+ >
+ )
+ },
+
+ [RTEMarkType.classnameOrId]: (
+ children: React.ReactNode,
+ className?: string,
+ id?: string
+ ) => {
+ let props = {
+ className,
+ id,
+ }
+ if (!className) {
+ delete props.className
+ }
+ if (!id) {
+ delete props.id
+ }
+ return (
+
+ {children}
+
+ )
+ },
+
+ /**
+ * Contentstack can return something called `default` as seen here in their
+ * own SDK (https://github.com/contentstack/contentstack-utils-javascript/blob/master/src/options/default-node-options.ts#L89)
+ */
+ default: (
+ node: RTEDefaultNode,
+ embeds: EmbedByUid,
+ next: RTENext,
+ fullRenderOptions: RenderOptions
+ ) => {
+ return next(node.children, embeds, fullRenderOptions)
+ },
+}
diff --git a/components/JsonToHtml/index.tsx b/components/JsonToHtml/index.tsx
index 9beebccae..689bd0460 100644
--- a/components/JsonToHtml/index.tsx
+++ b/components/JsonToHtml/index.tsx
@@ -10,5 +10,10 @@ export default function JsonToHtml({
if (!Array.isArray(nodes) || !nodes.length) {
return null
}
- return <>{nodesToHtml(nodes, embeds, renderOptions).filter(Boolean)}>
+ console.log({ nodes })
+ return (
+
+ {nodesToHtml(nodes, embeds, renderOptions).filter(Boolean)}
+
+ )
}
diff --git a/components/JsonToHtml/jsontohtml.module.css b/components/JsonToHtml/jsontohtml.module.css
index 2e564ffac..178802905 100644
--- a/components/JsonToHtml/jsontohtml.module.css
+++ b/components/JsonToHtml/jsontohtml.module.css
@@ -1,6 +1,8 @@
.image {
- height: auto;
- margin-bottom: var(--Spacing-x2);
max-width: 100%;
+ width: 100%;
+ height: 365px;
object-fit: cover;
+ border-radius: var(--Corner-radius-Medium);
+ padding: var(--Spacing-x1) var(--Spacing-x0);
}
diff --git a/components/JsonToHtml/renderOptions.tsx b/components/JsonToHtml/renderOptions.tsx
index 1b745815e..cd748e58e 100644
--- a/components/JsonToHtml/renderOptions.tsx
+++ b/components/JsonToHtml/renderOptions.tsx
@@ -1,14 +1,23 @@
import Image from "@/components/Image"
import Link from "@/components/TempDesignSystem/Link"
+import { insertResponseToImageVaultAsset } from "@/utils/imageVault"
+
+import Divider from "../TempDesignSystem/Divider"
+import BiroScript from "../TempDesignSystem/Text/BiroScript"
+import Body from "../TempDesignSystem/Text/Body"
+import Caption from "../TempDesignSystem/Text/Caption"
+import Subtitle from "../TempDesignSystem/Text/Subtitle"
+import Title from "../TempDesignSystem/Text/Title"
import styles from "./jsontohtml.module.css"
import type { EmbedByUid } from "@/types/components/jsontohtml"
import { EmbedEnum } from "@/types/requests/utils/embeds"
-import type { Attributes } from "@/types/rte/attrs"
+import type { Attributes, RTEImageVaultAttrs } from "@/types/rte/attrs"
import { RTEItemTypeEnum, RTETypeEnum } from "@/types/rte/enums"
import type {
RTEDefaultNode,
+ RTEImageNode,
RTENext,
RTENode,
RTERegularNode,
@@ -69,9 +78,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -120,9 +129,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -134,9 +143,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -148,9 +157,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -162,9 +171,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -176,9 +185,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -190,14 +199,14 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
- {next(node.children, embeds, fullRenderOptions)}
-
+
+ {next(node.children, embeds, fullRenderOptions)}
+
)
},
[RTETypeEnum.hr]: () => {
- return
+ return
},
[RTETypeEnum.li]: (
@@ -236,9 +245,9 @@ export const renderOptions: RenderOptions = {
) => {
const props = extractPossibleAttributes(node.attrs)
return (
-
+
{next(node.children, embeds, fullRenderOptions)}
-
+
)
},
@@ -254,11 +263,7 @@ export const renderOptions: RenderOptions = {
const image = embeds?.[node?.attrs?.["asset-uid"]]
if (image?.node.__typename === EmbedEnum.SysAsset) {
const alt = image?.node?.title ?? node.attrs.alt
- const alignment = node.attrs?.style?.["text-align"]
- ? {
- alignSelf: node.attrs?.style?.["text-align"],
- }
- : {}
+ const props = extractPossibleAttributes(node.attrs)
return (
)
}
@@ -287,6 +292,36 @@ export const renderOptions: RenderOptions = {
return null
},
+ [RTETypeEnum.ImageVault]: (node: RTEImageNode) => {
+ if ("attrs" in node) {
+ const type = node.type
+ if (type === RTETypeEnum.ImageVault) {
+ const attrs = node.attrs as RTEImageVaultAttrs
+ const image = insertResponseToImageVaultAsset(attrs)
+ const alt = image.meta.alt ?? image.title
+
+ const height = parseInt(attrs.height.replaceAll("px", ""))
+ const width = parseInt(attrs.width.replaceAll("px", ""))
+ const props = extractPossibleAttributes(attrs)
+ return (
+
+
+ {image.meta.caption}
+
+ )
+ }
+ }
+
+ return null
+ },
+
[RTETypeEnum.table]: (
node: RTEDefaultNode,
embeds: EmbedByUid,
diff --git a/types/rte/attrs.ts b/types/rte/attrs.ts
index f8bb36e30..dd658872d 100644
--- a/types/rte/attrs.ts
+++ b/types/rte/attrs.ts
@@ -1,6 +1,8 @@
+import { InsertResponse } from "../components/imageVaultImage"
import { RTEItemTypeEnum } from "./enums"
-import type { EmbedTypesEnum, RTEItemType } from "./enums"
+
import type { Lang } from "@/constants/languages"
+import type { EmbedTypesEnum, RTEItemType } from "./enums"
export interface Attributes {
[key: string]: any
@@ -36,3 +38,9 @@ export interface RTELinkAttrs extends Attributes {
target: HTMLAnchorElement["target"]
type: RTEItemTypeEnum.entry
}
+
+export interface RTEImageVaultAttrs extends Attributes, InsertResponse {
+ height: string
+ width: string
+ style: string[]
+}
diff --git a/types/rte/enums.ts b/types/rte/enums.ts
index b5eb2a6a1..271c800aa 100644
--- a/types/rte/enums.ts
+++ b/types/rte/enums.ts
@@ -36,6 +36,7 @@ export enum RTETypeEnum {
thead = "thead",
tr = "tr",
ul = "ul",
+ ImageVault = "ImageVault",
}
export type RTEType = keyof typeof RTETypeEnum
diff --git a/types/rte/node.ts b/types/rte/node.ts
index c762f33bb..dca0f9281 100644
--- a/types/rte/node.ts
+++ b/types/rte/node.ts
@@ -5,6 +5,7 @@ import type {
Attributes,
RTEAnchorAttrs,
RTEAssetAttrs,
+ RTEImageVaultAttrs,
RTELinkAttrs,
} from "./attrs"
import type { RenderOptions } from "./option"
@@ -36,6 +37,11 @@ export interface RTEReferenceLinkNode extends RTEDefaultNode {
attrs: RTELinkAttrs
}
+export interface RTEImageVaultNode extends RTEDefaultNode {
+ attrs: RTEImageVaultAttrs
+ type: RTETypeEnum.ImageVault
+}
+
export enum RTEMarkType {
bold = "bold",
break = "break",
@@ -58,9 +64,11 @@ export type RTETextNode = RTETextNodeOptionalKeys & {
text: string
}
-export type RTERegularNode = RTEDefaultNode | RTEAnchorNode
+export type RTERegularNode = RTEDefaultNode | RTEAnchorNode | RTEImageVaultNode
-export type RTEReferenceNode = RTEDefaultNode | RTEAnchorNode
+export type RTEImageNode = RTEDefaultNode | RTEImageVaultNode
+
+export type RTEReferenceNode = RTEAnchorNode
export type RTENode = RTERegularNode | RTEReferenceNode | RTETextNode