Skip to content

Commit 5f3cfee

Browse files
MillenniumFalconMechanicFran McDade
andauthored
feat: markdown in entity description #4170 (#4342)
Co-authored-by: Fran McDade <[email protected]>
1 parent 5860f5c commit 5f3cfee

File tree

10 files changed

+18305
-12629
lines changed

10 files changed

+18305
-12629
lines changed
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Link } from "../../../../../../Layout/components/Content/components/Link/link";
2+
import { Table } from "../../Table/table";
3+
import { H1, H2, H3, H4, P } from "./../description.styles";
4+
5+
/**
6+
* Components used when rendering MDX content in Description. Note when
7+
* generalizing this constant, description styles also need to be generalized.
8+
*/
9+
export const MDX_COMPONENTS = {
10+
a: Link,
11+
h1: H1,
12+
h2: H2,
13+
h3: H3,
14+
h4: H4,
15+
p: P,
16+
table: Table,
17+
};
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {
2+
textBodyLarge500,
3+
textHeadingLarge,
4+
textHeadingSmall,
5+
} from "@databiosphere/findable-ui/lib/styles/common/mixins/fonts";
6+
import styled from "@emotion/styled";
7+
8+
/**
9+
* H1 styled component. Matches H1 in the Portal.
10+
*/
11+
export const H1 = styled.h1`
12+
${textHeadingLarge};
13+
font-size: 30px;
14+
letter-spacing: -0.8px;
15+
line-height: 40px;
16+
margin: 0 0 16px; /* Matching margin-bottom of H1 in docs */
17+
`;
18+
19+
/**
20+
* H2 styled component. Removed textHeadingLarge mixin to prevent `font-size: 30px`
21+
* for tablet+ (to match H2's in the Portal).
22+
*/
23+
export const H2 = styled.h2`
24+
font-size: 24px;
25+
font-weight: 500;
26+
letter-spacing: -0.4px;
27+
line-height: 32px;
28+
margin: 32px 0 16px; /* Matching margin-bottom of H2 in docs */
29+
`;
30+
31+
/**
32+
* H3 styled component.
33+
*/
34+
export const H3 = styled.h3`
35+
${textHeadingSmall}
36+
margin: 40px 0 16px; /* Matching margin-bottom of H3 in docs */
37+
`;
38+
39+
/*
40+
* H4 styled component.
41+
*/
42+
export const H4 = styled.h4`
43+
${textBodyLarge500}
44+
margin: 16px 0; /* Matching margin-bottom of H4 in docs */
45+
`;
46+
47+
/**
48+
* P styled component.
49+
*/
50+
export const P = styled.p`
51+
margin: 0 0 16px; /* Matching margin-bottom of P in docs */
52+
`;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { CollapsableSection } from "@databiosphere/findable-ui/lib/components/common/Section/components/CollapsableSection/collapsableSection";
2+
import type { EvaluateOptions } from "@mdx-js/mdx";
3+
import { evaluate } from "@mdx-js/mdx";
4+
import type { MDXProps } from "mdx/types";
5+
import { ReactNode, useEffect, useState } from "react";
6+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7+
import remarkGfm from "remark-gfm";
8+
import { MDX_COMPONENTS } from "./common/constants";
9+
import { DescriptionProps } from "./types";
10+
11+
type ReactMDXContent = (props: MDXProps) => ReactNode;
12+
type Runtime = Pick<EvaluateOptions, "jsx" | "jsxs" | "Fragment">;
13+
14+
const runtime = { Fragment, jsx, jsxs } as Runtime;
15+
16+
export const Description = ({ content }: DescriptionProps): JSX.Element => {
17+
const [MdxContent, setMdxContent] = useState<ReactMDXContent>(
18+
() => (): null => null
19+
);
20+
21+
useEffect(() => {
22+
evaluate(content, { ...runtime, remarkPlugins: [remarkGfm] }).then((r) =>
23+
setMdxContent(() => r.default)
24+
);
25+
}, [content]);
26+
27+
// Wrapping <MdxContent> with <div> to force `display: block`
28+
return (
29+
<CollapsableSection collapsable={false} title="Description">
30+
<div>
31+
{MdxContent ? <MdxContent components={MDX_COMPONENTS} /> : null}
32+
</div>
33+
</CollapsableSection>
34+
);
35+
};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export interface DescriptionProps {
2+
content: string;
3+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { smokeMain } from "@databiosphere/findable-ui/lib/styles/common/mixins/colors";
2+
import {
3+
textBody400,
4+
textBody500,
5+
} from "@databiosphere/findable-ui/lib/styles/common/mixins/fonts";
6+
import styled from "@emotion/styled";
7+
import { TableContainer as MTableContainer } from "@mui/material";
8+
9+
/**
10+
* Table style component. TODO De-dupe with Table component in the Portal.
11+
*/
12+
export const TableContainer = styled(MTableContainer)`
13+
margin: 24px 0;
14+
15+
.MuiTable-root {
16+
min-width: calc(390px - 32px);
17+
18+
tr {
19+
td,
20+
th {
21+
border-bottom: 1px solid ${smokeMain};
22+
padding: 12px;
23+
text-align: left;
24+
25+
&:first-of-type {
26+
padding-left: 0;
27+
}
28+
29+
&:last-of-type {
30+
padding-right: 0;
31+
}
32+
}
33+
34+
th {
35+
${textBody500};
36+
37+
&:empty {
38+
padding: 0;
39+
}
40+
}
41+
42+
td {
43+
${textBody400};
44+
}
45+
}
46+
}
47+
`;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { Table as MTable } from "@mui/material";
2+
import { TableContainer } from "./table.styles";
3+
4+
export const Table = ({ ...props }): JSX.Element => {
5+
return (
6+
<TableContainer>
7+
<MTable>{props.children}</MTable>
8+
</TableContainer>
9+
);
10+
};

app/viewModelBuilders/azul/anvil-cmg/common/viewModelBuilders.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ import {
103103
} from "../../../../apis/azul/common/utils";
104104
import * as C from "../../../../components";
105105
import * as MDX from "../../../../components/common/MDXContent/anvil-cmg";
106+
import { Description } from "../../../../components/Detail/components/MDX/components/Description/description";
106107
import { ExportMethod } from "../../../../components/Export/components/AnVILExplorer/ExportMethod/exportMethod";
107108
import { METADATA_KEY } from "../../../../components/Index/common/entities";
108109
import { getPluralizedMetadataLabel } from "../../../../components/Index/common/indexTransformer";
@@ -318,13 +319,13 @@ export function buildDatasetAccessibilityBadge(
318319
}
319320

320321
/**
321-
* Build props for Markdown component from the given entity response.
322+
* Build props for Description component from the given entity response.
322323
* @param datasetsResponse - Response model return from datasets API.
323-
* @returns model to be used as props for the Markdown component.
324+
* @returns model to be used as props for the Description component.
324325
*/
325326
export const buildDatasetDescription = (
326327
datasetsResponse: DatasetsResponse
327-
): React.ComponentProps<typeof C.Markdown> => {
328+
): React.ComponentProps<typeof Description> => {
328329
return {
329330
content:
330331
processEntityValue(

0 commit comments

Comments
 (0)