diff --git a/packages/design-system/lib/components/JsonToHtml/jsontohtml.module.css b/packages/design-system/lib/components/JsonToHtml/jsontohtml.module.css index f9ae18a92..bd024eb86 100644 --- a/packages/design-system/lib/components/JsonToHtml/jsontohtml.module.css +++ b/packages/design-system/lib/components/JsonToHtml/jsontohtml.module.css @@ -60,11 +60,8 @@ .ul, .ol { - display: grid; - gap: var(--Space-x1); padding: 0; - margin-top: var(--Space-x2); - margin-bottom: var(--Space-x2); + margin: var(--Space-x2) 0; } .ol > li::marker { @@ -73,16 +70,7 @@ .li { margin-left: var(--Space-x3); -} - -.heart > .li::before, -.li:has(.heart)::before { - content: url('/_static/icons/heart.svg'); - position: relative; - height: 8px; - top: 3px; - margin-right: var(--Space-x1); - margin-left: calc(var(--Space-x3) * -1); + margin-bottom: var(--Space-x05); } .heart > .li, @@ -90,16 +78,27 @@ .li:has(.check), .li:has(.heart) { list-style: none; + margin-left: 0; +} + +.heart > .li::before, +.li:has(.heart)::before, +.check > .li::before, +.li:has(.check)::before { + position: relative; + height: 8px; + top: 3px; + margin-right: var(--Space-x1); } .check > .li::before, .li:has(.check)::before { content: url('/_static/icons/check-ring.svg'); - position: relative; - height: 8px; - top: 3px; - margin-right: var(--Space-x1); - margin-left: calc(var(--Space-x3) * -1); +} + +.heart > .li::before, +.li:has(.heart)::before { + content: url('/_static/icons/heart.svg'); } .li > p { @@ -127,17 +126,24 @@ } @media screen and (min-width: 768px) { - .ol:has(li:nth-last-child(n + 5)), - .ul:has(li:nth-last-child(n + 5)) { - grid-template-columns: 1fr 1fr; - grid-auto-flow: column; + .ol, + .ul { + &.two-column, + &.two-columns, + &:has(.two-column, .two-columns) { + column-count: 2; + column-gap: var(--Space-x3); + } } } @container sidebar (max-width: 360px) { .ol, .ul { - display: flex; - flex-direction: column; + &.two-column, + &.two-columns, + &:has(.two-column, .two-columns) { + column-count: 1; + } } } diff --git a/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx b/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx index be2ab06b9..9fb0408fa 100644 --- a/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx +++ b/packages/design-system/lib/components/JsonToHtml/renderOptions.tsx @@ -9,13 +9,13 @@ import Table from '../Table' import { Typography } from '../Typography' import { + extractAvailableListClassNames, hasAvailableParagraphFormat, - hasAvailableULFormat, - makeCssModuleCompatibleClassName, } from './utils' import styles from './jsontohtml.module.css' +import { insertResponseToImageVaultAsset } from './insertResponseToImageVaultAsset' import type { EmbedByUid } from './JsonToHtml' import type { Attributes, RTEImageVaultAttrs } from './types/rte/attrs' import { @@ -33,7 +33,6 @@ import { type RTETextNode, } from './types/rte/node' import type { RenderOptions } from './types/rte/option' -import { insertResponseToImageVaultAsset } from './insertResponseToImageVaultAsset' function noNestedLinksOrReferences(node: RTENode) { if ('type' in node) { @@ -255,15 +254,12 @@ export const renderOptions: RenderOptions = { fullRenderOptions: RenderOptions ) => { const { className, ...props } = extractPossibleAttributes(node.attrs) - const compatibleClassName = makeCssModuleCompatibleClassName( - className, - 'ul' - ) + const compatibleClassNames = extractAvailableListClassNames(className) return (
  • {next(node.children, embeds, fullRenderOptions)}
  • @@ -277,26 +273,11 @@ export const renderOptions: RenderOptions = { fullRenderOptions: RenderOptions ) => { const { className, ...props } = extractPossibleAttributes(node.attrs) - - // Set the number of rows dynamically to create even rows for each column. We want the li:s - // to flow with the column, so therefore this is needed. - let numberOfRows: number | undefined - if (node.children.length > 4) { - const half = node.children.length / 2 - numberOfRows = Math.ceil(half) - } + const compatibleClassNames = extractAvailableListClassNames(className) return ( -
      +
        {next(node.children, embeds, fullRenderOptions)}
      @@ -340,8 +321,9 @@ export const renderOptions: RenderOptions = { let propsClassName = className if (className) { - if (hasAvailableULFormat(className)) { - propsClassName = styles[className] + const availableClassNames = extractAvailableListClassNames(className) + if (availableClassNames.length) { + propsClassName = cx(availableClassNames) } } @@ -361,8 +343,9 @@ export const renderOptions: RenderOptions = { let propsClassName = className if (className) { - if (hasAvailableULFormat(className)) { - propsClassName = styles[className] + const availableClassNames = extractAvailableListClassNames(className) + if (availableClassNames.length) { + propsClassName = cx(availableClassNames) } } @@ -656,32 +639,11 @@ export const renderOptions: RenderOptions = { fullRenderOptions: RenderOptions ) => { const { className, ...props } = extractPossibleAttributes(node.attrs) - const compatibleClassName = makeCssModuleCompatibleClassName( - className, - 'ul' - ) - - // Set the number of rows dynamically to create even rows for each column. We want the li:s - // to flow with the column, so therefore this is needed. - let numberOfRows: number | undefined - if (node.children.length > 4) { - const half = node.children.length / 2 - numberOfRows = Math.ceil(half) - } + const compatibleClassNames = extractAvailableListClassNames(className) return ( -
        +
          {next(node.children, embeds, fullRenderOptions)}
        @@ -747,8 +709,9 @@ export const renderOptions: RenderOptions = { } if (className) { - if (hasAvailableULFormat(className)) { - propsClassName = styles[className] + const availableClassNames = extractAvailableListClassNames(className) + if (availableClassNames.length) { + propsClassName = cx(availableClassNames) } } diff --git a/packages/design-system/lib/components/JsonToHtml/types/rte/constants.ts b/packages/design-system/lib/components/JsonToHtml/types/rte/constants.ts new file mode 100644 index 000000000..591a809df --- /dev/null +++ b/packages/design-system/lib/components/JsonToHtml/types/rte/constants.ts @@ -0,0 +1,6 @@ +export const AVAILABLE_LIST_FORMATS = [ + 'heart', + 'check', + 'two-column', + 'two-columns', +] diff --git a/packages/design-system/lib/components/JsonToHtml/types/rte/enums.ts b/packages/design-system/lib/components/JsonToHtml/types/rte/enums.ts index 18df410aa..d498ac6b7 100644 --- a/packages/design-system/lib/components/JsonToHtml/types/rte/enums.ts +++ b/packages/design-system/lib/components/JsonToHtml/types/rte/enums.ts @@ -63,11 +63,6 @@ export enum AvailableParagraphFormatEnum { 'subtitle-2' = 'subtitle-2', } -export enum AvailableULFormatEnum { - 'heart' = 'heart', - 'check' = 'check', -} - export type ContentBlockType = | 'AccountPage' | 'CampaignOverviewPage' diff --git a/packages/design-system/lib/components/JsonToHtml/utils.tsx b/packages/design-system/lib/components/JsonToHtml/utils.tsx index f0b56728a..48910bf3b 100644 --- a/packages/design-system/lib/components/JsonToHtml/utils.tsx +++ b/packages/design-system/lib/components/JsonToHtml/utils.tsx @@ -4,13 +4,11 @@ import { renderOptions } from './renderOptions' import styles from './jsontohtml.module.css' -import type { Node, Embeds } from './JsonToHtml' +import type { Embeds, Node } from './JsonToHtml' -import { - AvailableParagraphFormatEnum, - AvailableULFormatEnum, - RTETypeEnum, -} from './types/rte/enums' +import { EmbedByUid } from './JsonToHtml' +import { AVAILABLE_LIST_FORMATS } from './types/rte/constants' +import { AvailableParagraphFormatEnum, RTETypeEnum } from './types/rte/enums' import { RTEMarkType, type RTENode, @@ -19,7 +17,6 @@ import { type RTETextNode, } from './types/rte/node' import type { RenderOptions } from './types/rte/option' -import { EmbedByUid } from './JsonToHtml' export function groupEmbedsByUid(embedsArray: Node[]) { const embedsByUid = embedsArray.reduce((acc, embed) => { @@ -109,11 +106,14 @@ export function hasAvailableParagraphFormat(className?: string) { return Object.keys(AvailableParagraphFormatEnum).includes(className) } -export function hasAvailableULFormat(className?: string) { +export function extractAvailableListClassNames(className?: string) { if (!className) { - return false + return [] } - return Object.keys(AvailableULFormatEnum).includes(className) + const classNames = className.split(' ') + return classNames + .filter((name) => AVAILABLE_LIST_FORMATS.includes(name)) + .map((item) => styles[item] || item) } export function nodeToHtml( @@ -165,20 +165,3 @@ export function nodesToHtml( ) }) } - -export function makeCssModuleCompatibleClassName( - className: string | undefined, - formatType: 'ul' -): string { - if (!className) return '' - - if (formatType === 'ul' && hasAvailableULFormat(className)) { - // TODO: REMOVE - // @ats-expect-error: We want to set css modules classNames even if it does not correspond - // to an existing class in the module style sheet. Due to our css modules plugin for - // typescript, we cannot do this without the ts-ignore - return styles[className] || className - } - - return className -}