diff options
| author | Oliver <oliver@mohlin.dev> | 2025-10-03 07:30:18 +0200 |
|---|---|---|
| committer | Tobias Järvelöv <tobias.jarvelov@mullvad.net> | 2025-10-10 13:36:21 +0200 |
| commit | 7cce7234a7571cb0f020a9b9e93b94fdffa5a250 (patch) | |
| tree | 8cfb0861264eb94b3aae18134dfb347972fbc9ae | |
| parent | ebcb6cb4c20e4798e97f7ad24eb97eb69837bd9c (diff) | |
| download | mullvadvpn-7cce7234a7571cb0f020a9b9e93b94fdffa5a250.tar.xz mullvadvpn-7cce7234a7571cb0f020a9b9e93b94fdffa5a250.zip | |
Add support for em tag in formatHtml
| -rw-r--r-- | desktop/packages/mullvad-vpn/src/renderer/lib/html-formatter.tsx | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/html-formatter.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/html-formatter.tsx index 452b7fb1e8..6fd98272d2 100644 --- a/desktop/packages/mullvad-vpn/src/renderer/lib/html-formatter.tsx +++ b/desktop/packages/mullvad-vpn/src/renderer/lib/html-formatter.tsx @@ -1,18 +1,63 @@ -import React from 'react'; +import React, { JSX } from 'react'; import styled from 'styled-components'; -const boldSyntax = /(<b>.*?<\/b>)/g; +import { colors } from './foundations'; + const Bold = styled.span({ fontWeight: 700 }); +const Emphasis = styled.em({ color: colors.white }); + +// When a new tag is added here, it must also be added to allowed tags in +// our verify translations script. +const testMap: Partial< + Record< + keyof JSX.IntrinsicElements, + { + test: RegExp; + replace: RegExp; + } + > +> = { + b: { + test: /(<b>.*?<\/b>)/g, + replace: /<b>|<\/b>/g, + }, + em: { + test: /(<em>.*?<\/em>)/g, + replace: /<em>|<\/em>/g, + }, +} as const; + +const componentMap: Partial< + Record<keyof JSX.IntrinsicElements, React.ComponentType<{ children: React.ReactNode }>> +> = { + b: Bold, + em: Emphasis, +} as const; export function formatHtml(inputString: string): React.ReactElement { - const formattedString = inputString.split(boldSyntax).map((value, index) => { - if (boldSyntax.test(value)) { - const valueWithoutTags = value.replaceAll(/<b>|<\/b>/g, ''); - return <Bold key={index}>{valueWithoutTags}</Bold>; - } else { - return <React.Fragment key={index}>{value}</React.Fragment>; + const formattedString: JSX.Element[] = []; + + Object.entries(testMap).forEach(([key, { test, replace }]) => { + const parts = inputString.split(test).filter((part) => part !== ''); + if (parts.length <= 1) { + return; } + + parts.map((value, index) => { + if (test.test(value)) { + const Component = componentMap[key as keyof typeof componentMap]!; + const valueWithoutTags = value.replaceAll(replace, ''); + + formattedString.push(<Component key={index}>{valueWithoutTags}</Component>); + } else { + formattedString.push(<React.Fragment key={index}>{value}</React.Fragment>); + } + }); }); + if (formattedString.length === 0) { + formattedString.push(<>{inputString}</>); + } + return <>{formattedString}</>; } |
