Skip to content

Commit 1ae4668

Browse files
authored
Used new markdown library (#693)
Moved to use a pure js library instead of a React library to simplify some packaging and transpiling issues. This also created a new Markdown component to be used separately. Although this is not exported directly yet.
1 parent c4188e4 commit 1ae4668

File tree

8 files changed

+177
-184
lines changed

8 files changed

+177
-184
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"classnames": "^2.3.2",
2626
"geojson": "^0.5.0",
2727
"luxon": "^3.3.0",
28-
"markdown-to-jsx": "^7.7.13",
28+
"marked": "^16.2.1",
2929
"react": "^18.2.0",
3030
"react-dom": "^18.2.0",
3131
"react-intersection-observer": "^9.5.2",

src/components/Markdown/index.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React, { useCallback, useEffect, useState } from 'react';
2+
3+
import { marked } from 'marked';
4+
5+
import './styles.scss';
6+
7+
export type MarkdownProps = {
8+
value: string;
9+
};
10+
11+
const Markdown = ({ value }: MarkdownProps): JSX.Element => {
12+
const [html, setHtml] = useState<string>();
13+
14+
const parseValue = useCallback(async (_value: string) => {
15+
const _html = await marked.parse(_value);
16+
setHtml(_html);
17+
}, []);
18+
19+
useEffect(() => {
20+
void parseValue(value);
21+
}, [value]);
22+
23+
return <div className='markdown' dangerouslySetInnerHTML={{ __html: html ?? '' }} />;
24+
};
25+
26+
export default Markdown;
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
@use 'sass:math';
2+
3+
@import '../../style-dictionary-dist/terraware.scss';
4+
5+
@font-face {
6+
font-family: 'Inter';
7+
src: local('Inter'), url(../../fonts/Inter.ttf) format('truetype');
8+
}
9+
10+
.markdown {
11+
display: flex;
12+
flex-flow: column;
13+
font-family: $tw-fnt-frm-fld-text-value-font-family;
14+
color: $tw-clr-txt;
15+
padding: $tw-spc-base-x-small 0;
16+
margin: 0;
17+
18+
h1 {
19+
font-size: $tw-fnt-base-headline-01-semi-bold-font-size;
20+
font-weight: $tw-fnt-base-headline-01-semi-bold-font-weight;
21+
line-height: $tw-fnt-base-headline-01-semi-bold-line-height;
22+
padding: 0;
23+
margin: 0;
24+
}
25+
h2 {
26+
font-size: $tw-fnt-base-headline-02-semi-bold-font-size;
27+
font-weight: $tw-fnt-base-headline-02-semi-bold-font-weight;
28+
line-height: $tw-fnt-base-headline-02-semi-bold-line-height;
29+
padding: 0;
30+
margin: 0;
31+
}
32+
h3 {
33+
font-size: $tw-fnt-base-headline-03-semi-bold-font-size;
34+
font-weight: $tw-fnt-base-headline-03-semi-bold-font-weight;
35+
line-height: $tw-fnt-base-headline-03-semi-bold-line-height;
36+
padding: 0;
37+
margin: 0;
38+
}
39+
h4 {
40+
font-size: $tw-fnt-base-headline-04-semi-bold-font-size;
41+
font-weight: $tw-fnt-base-headline-04-semi-bold-font-weight;
42+
line-height: $tw-fnt-base-headline-04-semi-bold-line-height;
43+
padding: 0;
44+
margin: 0;
45+
}
46+
h5 {
47+
font-size: $tw-fnt-base-headline-05-semi-bold-font-size;
48+
font-weight: $tw-fnt-base-headline-05-semi-bold-font-weight;
49+
line-height: $tw-fnt-base-headline-05-semi-bold-line-height;
50+
padding: 0;
51+
margin: 0;
52+
}
53+
h6 {
54+
font-size: $tw-fnt-base-headline-06-semi-bold-font-size;
55+
font-weight: $tw-fnt-base-headline-06-semi-bold-font-weight;
56+
line-height: $tw-fnt-base-headline-06-semi-bold-line-height;
57+
padding: 0;
58+
margin: 0;
59+
}
60+
61+
p {
62+
font-size: $tw-fnt-frm-fld-text-value-font-size;
63+
font-weight: $tw-fnt-frm-fld-text-value-font-weight;
64+
line-height: $tw-fnt-frm-fld-text-value-line-height;
65+
padding: 0;
66+
margin: 0;
67+
}
68+
69+
a {
70+
color: $tw-clr-txt-brand;
71+
text-decoration: underline;
72+
&:hover {
73+
color: $tw-clr-txt-brand;
74+
}
75+
}
76+
77+
code {
78+
font-family: 'Fira Code', monospace;
79+
background: $tw-clr-bg-secondary;
80+
color: $tw-clr-txt-secondary;
81+
}
82+
83+
pre code {
84+
display: block;
85+
padding: 4px;
86+
overflow-x: auto;
87+
background: $tw-clr-bg-secondary;
88+
color: $tw-clr-txt-secondary;
89+
border-color: $tw-clr-brdr-secondary;
90+
border-radius: 8px;
91+
}
92+
93+
table {
94+
width: 100%;
95+
border-collapse: collapse;
96+
}
97+
98+
th,
99+
td {
100+
border: none;
101+
padding: 4px 8px;
102+
text-align: left;
103+
}
104+
105+
thead {
106+
tr {
107+
background-color: $tw-clr-base-gray-050;
108+
}
109+
}
110+
111+
tbody {
112+
tr {
113+
&:nth-child(odd) {
114+
background-color: $tw-clr-base-white;
115+
}
116+
117+
&:nth-child(even) {
118+
background-color: $tw-clr-base-gray-050;
119+
}
120+
}
121+
}
122+
123+
blockquote {
124+
border-left: 4px solid $tw-clr-brdr-brand;
125+
padding-left: 1em;
126+
margin: 1em 0;
127+
color: $tw-clr-txt-secondary;
128+
}
129+
}

src/components/Textfield/Textfield.tsx

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import React, { useMemo } from 'react';
22

33
import { Box, SxProps, TooltipProps } from '@mui/material';
44
import classNames from 'classnames';
5-
import Markdown from 'markdown-to-jsx';
65

76
import { isWhitespaces } from '../../utils';
87
import Icon from '../Icon/Icon';
98
import { IconName } from '../Icon/icons';
109
import IconTooltip from '../IconTooltip';
10+
import Markdown from '../Markdown';
1111
import TruncatedTextArea from './TruncatedTextArea';
1212
import './styles.scss';
1313

@@ -20,7 +20,6 @@ export interface TruncateConfig {
2020
showMoreText: string;
2121
showLessText: string;
2222
showTextStyle?: Record<string, any>;
23-
valueTextStyle?: Record<string, any>;
2423
alignment?: 'left' | 'right';
2524
}
2625

@@ -150,32 +149,21 @@ export default function TextField(props: Props): JSX.Element {
150149
}
151150

152151
const displayComponent = useMemo(() => {
153-
if (!display) {
152+
if (!display || value === undefined) {
154153
return null;
155154
}
156155

157-
if (type === 'textarea' && truncateConfig) {
158-
return (
159-
<TruncatedTextArea
160-
markdown={markdown}
161-
preserveNewlines={preserveNewlines}
162-
truncateConfig={truncateConfig}
163-
value={value}
164-
/>
165-
);
166-
}
156+
const component = markdown ? (
157+
<Markdown value={value.toString()} />
158+
) : (
159+
<p className={`textfield-value--display${preserveNewlines ? ' preserve-newlines' : ''}`}>{value}</p>
160+
);
167161

168-
if (markdown) {
169-
return (
170-
value !== undefined && (
171-
<div className='textfield-display-markdown'>
172-
<Markdown>{value.toString()}</Markdown>
173-
</div>
174-
)
175-
);
162+
if (type === 'textarea' && truncateConfig) {
163+
return <TruncatedTextArea truncateConfig={truncateConfig}>{component}</TruncatedTextArea>;
164+
} else {
165+
return component;
176166
}
177-
178-
return <p className={`textfield-value--display${preserveNewlines ? ' preserve-newlines' : ''}`}>{value}</p>;
179167
}, [display, markdown, preserveNewlines, truncateConfig, type, value]);
180168

181169
return (

src/components/Textfield/TruncatedTextArea.tsx

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,17 @@
1-
import React, { useEffect, useRef, useState } from 'react';
1+
import React, { ReactNode, useEffect, useRef, useState } from 'react';
22

33
import { Link, Typography, useTheme } from '@mui/material';
4-
import Markdown from 'markdown-to-jsx';
54

65
import { TruncateConfig } from './Textfield';
76
import './styles.scss';
87

98
interface TruncatedTextAreaProps {
10-
markdown?: boolean;
11-
preserveNewlines?: boolean;
129
truncateConfig: TruncateConfig;
13-
value?: string | number;
10+
children: ReactNode;
1411
}
1512

16-
const TruncatedTextArea = ({ markdown, preserveNewlines, truncateConfig, value }: TruncatedTextAreaProps) => {
17-
const { maxHeight, showLessText, showMoreText, showTextStyle, valueTextStyle, alignment = 'left' } = truncateConfig;
13+
const TruncatedTextArea = ({ truncateConfig, children }: TruncatedTextAreaProps) => {
14+
const { maxHeight, showLessText, showMoreText, showTextStyle, alignment = 'left' } = truncateConfig;
1815

1916
const theme = useTheme();
2017
const [showAll, setShowAll] = useState(false);
@@ -45,17 +42,8 @@ const TruncatedTextArea = ({ markdown, preserveNewlines, truncateConfig, value }
4542

4643
return (
4744
<>
48-
<div ref={ref} style={divStyle} className={markdown ? 'textfield-display-markdown' : undefined}>
49-
{markdown ? (
50-
value !== undefined && <Markdown>{value.toString()}</Markdown>
51-
) : (
52-
<p
53-
className={`textfield-value--display${preserveNewlines ? ' preserve-newlines' : ''}`}
54-
style={valueTextStyle}
55-
>
56-
{value}
57-
</p>
58-
)}
45+
<div ref={ref} style={divStyle}>
46+
{children}
5947
</div>
6048

6149
{needsTruncating && (

src/components/Textfield/styles.scss

Lines changed: 0 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -269,122 +269,3 @@
269269
}
270270
}
271271
}
272-
273-
.textfield-display-markdown {
274-
font-family: $tw-fnt-base-body-01-regular-font-family;
275-
font-size: $tw-fnt-frm-fld-text-value-font-size;
276-
font-weight: $tw-fnt-frm-fld-text-value-font-weight;
277-
line-height: $tw-fnt-frm-fld-text-value-line-height;
278-
color: $tw-clr-txt;
279-
padding: $tw-spc-base-x-small 0;
280-
margin: 0;
281-
282-
h1,
283-
h2,
284-
h3,
285-
h4,
286-
h5,
287-
h6 {
288-
font-weight: 600;
289-
margin: 1.5em 0 0.75em;
290-
line-height: 1.25;
291-
}
292-
293-
h1 {
294-
font-size: $tw-fnt-base-headline-01-semi-bold-font-size;
295-
font-weight: $tw-fnt-base-headline-01-semi-bold-font-weight;
296-
line-height: $tw-fnt-base-headline-01-semi-bold-line-height;
297-
}
298-
h2 {
299-
font-size: $tw-fnt-base-headline-02-semi-bold-font-size;
300-
font-weight: $tw-fnt-base-headline-02-semi-bold-font-weight;
301-
line-height: $tw-fnt-base-headline-02-semi-bold-line-height;
302-
}
303-
h3 {
304-
font-size: $tw-fnt-base-headline-03-semi-bold-font-size;
305-
font-weight: $tw-fnt-base-headline-03-semi-bold-font-weight;
306-
line-height: $tw-fnt-base-headline-03-semi-bold-line-height;
307-
}
308-
h4 {
309-
font-size: $tw-fnt-base-headline-04-semi-bold-font-size;
310-
font-weight: $tw-fnt-base-headline-04-semi-bold-font-weight;
311-
line-height: $tw-fnt-base-headline-04-semi-bold-line-height;
312-
}
313-
h5 {
314-
font-size: $tw-fnt-base-headline-05-semi-bold-font-size;
315-
font-weight: $tw-fnt-base-headline-05-semi-bold-font-weight;
316-
line-height: $tw-fnt-base-headline-05-semi-bold-line-height;
317-
}
318-
h6 {
319-
font-size: $tw-fnt-base-headline-06-semi-bold-font-size;
320-
font-weight: $tw-fnt-base-headline-06-semi-bold-font-weight;
321-
line-height: $tw-fnt-base-headline-06-semi-bold-line-height;
322-
}
323-
324-
p {
325-
font-size: $tw-fnt-frm-fld-text-value-font-size;
326-
font-weight: $tw-fnt-frm-fld-text-value-font-weight;
327-
line-height: $tw-fnt-frm-fld-text-value-line-height;
328-
}
329-
330-
a {
331-
color: $tw-clr-txt-brand;
332-
text-decoration: underline;
333-
&:hover {
334-
color: $tw-clr-txt-brand;
335-
}
336-
}
337-
338-
code {
339-
font-family: 'Fira Code', monospace;
340-
background: $tw-clr-bg-secondary;
341-
color: $tw-clr-txt-secondary;
342-
}
343-
344-
pre code {
345-
display: block;
346-
padding: 4px;
347-
overflow-x: auto;
348-
background: $tw-clr-bg-secondary;
349-
color: $tw-clr-txt-secondary;
350-
border-color: $tw-clr-brdr-secondary;
351-
border-radius: 8px;
352-
}
353-
354-
table {
355-
width: 100%;
356-
border-collapse: collapse;
357-
}
358-
359-
th,
360-
td {
361-
border: none;
362-
padding: 4px;
363-
text-align: left;
364-
}
365-
366-
thead {
367-
tr {
368-
background-color: $tw-clr-base-gray-050;
369-
}
370-
}
371-
372-
tbody {
373-
tr {
374-
&:nth-child(odd) {
375-
background-color: $tw-clr-base-white;
376-
}
377-
378-
&:nth-child(even) {
379-
background-color: $tw-clr-base-gray-050;
380-
}
381-
}
382-
}
383-
384-
blockquote {
385-
border-left: 4px solid $tw-clr-brdr-brand;
386-
padding-left: 1em;
387-
margin: 1em 0;
388-
color: $tw-clr-txt-secondary;
389-
}
390-
}

0 commit comments

Comments
 (0)