@databiosphere/findable-ui 30.0.0 → 32.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +24 -0
  3. package/lib/common/entities.d.ts +8 -26
  4. package/lib/components/DataDictionary/components/Entities/entities.d.ts +3 -1
  5. package/lib/components/DataDictionary/components/Entities/entities.js +1 -1
  6. package/lib/components/DataDictionary/components/Entities/types.d.ts +5 -5
  7. package/lib/components/DataDictionary/components/Entity/entity.d.ts +3 -1
  8. package/lib/components/DataDictionary/components/Entity/entity.js +6 -6
  9. package/lib/components/DataDictionary/components/Entity/types.d.ts +5 -5
  10. package/lib/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.d.ts +1 -1
  11. package/lib/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.d.ts +2 -2
  12. package/lib/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.d.ts +1 -1
  13. package/lib/components/DataDictionary/components/Outline/utils.d.ts +3 -2
  14. package/lib/components/DataDictionary/components/Table/components/BasicCell/basicCell.d.ts +2 -2
  15. package/lib/components/DataDictionary/components/Table/hook.d.ts +3 -3
  16. package/lib/components/DataDictionary/components/Table/hook.js +3 -1
  17. package/lib/components/DataDictionary/components/Table/options/core/constants.d.ts +2 -3
  18. package/lib/components/DataDictionary/components/Table/options/hook.d.ts +2 -2
  19. package/lib/components/DataDictionary/components/Table/options/sorting/constants.d.ts +2 -3
  20. package/lib/components/DataDictionary/components/Table/table.d.ts +2 -1
  21. package/lib/components/DataDictionary/components/Table/table.js +1 -1
  22. package/lib/components/DataDictionary/components/Table/types.d.ts +3 -4
  23. package/lib/components/DataDictionary/dataDictionary.d.ts +3 -1
  24. package/lib/components/DataDictionary/dataDictionary.styles.d.ts +1 -1
  25. package/lib/components/DataDictionary/hooks/UseDataDictionary/hook.d.ts +3 -1
  26. package/lib/components/DataDictionary/hooks/UseDataDictionary/types.d.ts +5 -5
  27. package/lib/components/Error/error.styles.d.ts +1 -1
  28. package/lib/components/Export/components/ExportToTerra/components/TerraSetUpForm/components/FormStep/formStep.styles.d.ts +1 -1
  29. package/lib/components/Export/components/ExportToTerra/components/TerraSetUpForm/terraSetUpForm.styles.d.ts +4 -4
  30. package/lib/components/Export/components/ManifestDownload/components/ManifestDownloadEntity/manifestDownloadEntity.styles.d.ts +1 -1
  31. package/lib/components/Filter/components/FilterRange/filterRange.styles.d.ts +1 -1
  32. package/lib/components/Filter/components/Filters/filters.styles.d.ts +2 -2
  33. package/lib/components/Filter/components/VariableSizeList/VariableSizeList.d.ts +1 -1
  34. package/lib/components/Filter/components/VariableSizeList/VariableSizeList.js +1 -1
  35. package/lib/components/Index/components/EntitiesView/components/ChartView/chartView.styles.d.ts +1 -1
  36. package/lib/components/Index/index.styles.d.ts +1 -1
  37. package/lib/components/Layout/components/ContentLayout/contentLayout.styles.d.ts +1 -1
  38. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/AuthenticationMenu/authenticationMenu.styles.d.ts +1 -1
  39. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.d.ts +1 -1
  40. package/lib/components/Layout/components/Main/main.styles.d.ts +2 -2
  41. package/lib/components/Layout/components/Sidebar/components/SidebarPositioner/sidebarPositioner.styles.d.ts +1 -1
  42. package/lib/components/Login/components/Section/components/Consent/consent.styles.d.ts +1 -1
  43. package/lib/components/MarkdownRenderer/components/Anchor/anchor.d.ts +19 -0
  44. package/lib/components/MarkdownRenderer/components/Anchor/anchor.js +21 -0
  45. package/lib/components/MarkdownRenderer/components/Table/table.d.ts +3 -0
  46. package/lib/components/MarkdownRenderer/components/Table/table.js +5 -0
  47. package/lib/components/MarkdownRenderer/components/Table/table.styles.d.ts +4 -0
  48. package/lib/components/MarkdownRenderer/components/Table/table.styles.js +40 -0
  49. package/lib/components/MarkdownRenderer/constants.d.ts +2 -0
  50. package/lib/components/MarkdownRenderer/constants.js +6 -0
  51. package/lib/components/MarkdownRenderer/markdownRenderer.d.ts +14 -0
  52. package/lib/components/MarkdownRenderer/markdownRenderer.js +56 -0
  53. package/lib/components/MarkdownRenderer/markdownRenderer.styles.d.ts +4 -0
  54. package/lib/components/MarkdownRenderer/markdownRenderer.styles.js +13 -0
  55. package/lib/components/MarkdownRenderer/types.d.ts +7 -0
  56. package/lib/components/MarkdownRenderer/types.js +1 -0
  57. package/lib/components/Stepper/components/Step/components/StepIcon/components/CompletedIcon/completedIcon.styles.d.ts +1 -1
  58. package/lib/components/Stepper/components/Step/components/StepLabel/components/Label/label.styles.d.ts +1 -1
  59. package/lib/components/Support/components/ViewSupport/viewSupport.styles.d.ts +1 -1
  60. package/lib/components/Table/components/TableCell/components/ChipCell/chipCell.d.ts +2 -1
  61. package/lib/components/Table/components/TableCell/components/ChipCell/chipCell.js +2 -2
  62. package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.d.ts +1 -1
  63. package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.js +2 -2
  64. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.d.ts +4 -0
  65. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.js +13 -0
  66. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.styles.d.ts +3 -0
  67. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.styles.js +30 -0
  68. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/args.d.ts +4 -0
  69. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/args.js +10 -0
  70. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/constants.d.ts +5 -0
  71. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/constants.js +9 -0
  72. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories.d.ts +7 -0
  73. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories.js +25 -0
  74. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/types.d.ts +3 -0
  75. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/types.js +1 -0
  76. package/lib/components/Table/components/TableCell/components/MarkdownCell/types.d.ts +3 -0
  77. package/lib/components/Table/components/TableCell/components/MarkdownCell/types.js +1 -0
  78. package/lib/components/common/AnchorLink/anchorLink.styles.d.ts +7 -7
  79. package/lib/components/common/Card/components/CardSecondaryTitle/cardSecondaryTitle.styles.d.ts +1 -1
  80. package/lib/components/common/Code/code.styles.d.ts +1 -1
  81. package/lib/components/common/Dot/dot.styles.d.ts +1 -1
  82. package/lib/components/common/EllipsisContent/ellipsisContent.styles.d.ts +1 -1
  83. package/lib/components/common/Progress/components/CircularProgress/circularProgress.d.ts +1 -1
  84. package/lib/components/common/Progress/components/CircularProgress/circularProgress.js +1 -1
  85. package/lib/components/common/Stack/stack.d.ts +1 -1
  86. package/lib/components/common/Stack/stack.js +1 -1
  87. package/lib/components/common/ToggleButtonGroup/hooks/UseToggleButtonGroup/hook.d.ts +1 -1
  88. package/lib/styles/common/mui/typography.js +1 -0
  89. package/package.json +8 -1
  90. package/src/common/entities.ts +8 -31
  91. package/src/components/DataDictionary/components/Entities/entities.tsx +7 -5
  92. package/src/components/DataDictionary/components/Entities/types.ts +5 -9
  93. package/src/components/DataDictionary/components/Entity/entity.tsx +9 -7
  94. package/src/components/DataDictionary/components/Entity/types.ts +5 -9
  95. package/src/components/DataDictionary/components/Outline/utils.ts +5 -2
  96. package/src/components/DataDictionary/components/Table/hook.ts +16 -8
  97. package/src/components/DataDictionary/components/Table/options/core/constants.ts +2 -3
  98. package/src/components/DataDictionary/components/Table/options/hook.ts +3 -3
  99. package/src/components/DataDictionary/components/Table/options/sorting/constants.ts +2 -6
  100. package/src/components/DataDictionary/components/Table/table.tsx +4 -1
  101. package/src/components/DataDictionary/components/Table/types.ts +3 -4
  102. package/src/components/DataDictionary/dataDictionary.tsx +4 -2
  103. package/src/components/DataDictionary/hooks/UseDataDictionary/hook.ts +9 -2
  104. package/src/components/DataDictionary/hooks/UseDataDictionary/types.ts +5 -9
  105. package/src/components/Filter/components/VariableSizeList/VariableSizeList.tsx +1 -1
  106. package/src/components/MarkdownRenderer/components/Anchor/anchor.tsx +34 -0
  107. package/src/components/MarkdownRenderer/components/Table/table.styles.ts +41 -0
  108. package/src/components/MarkdownRenderer/components/Table/table.tsx +13 -0
  109. package/src/components/MarkdownRenderer/constants.ts +8 -0
  110. package/src/components/MarkdownRenderer/markdownRenderer.styles.ts +16 -0
  111. package/src/components/MarkdownRenderer/markdownRenderer.tsx +74 -0
  112. package/src/components/MarkdownRenderer/types.ts +10 -0
  113. package/src/components/Table/components/TableCell/components/ChipCell/chipCell.tsx +4 -2
  114. package/src/components/Table/components/TableCell/components/LinkCell/linkCell.tsx +1 -1
  115. package/src/components/Table/components/TableCell/components/MarkdownCell/markdownCell.styles.ts +31 -0
  116. package/src/components/Table/components/TableCell/components/MarkdownCell/markdownCell.tsx +29 -0
  117. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/args.ts +17 -0
  118. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/constants.ts +11 -0
  119. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories.tsx +37 -0
  120. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/types.ts +4 -0
  121. package/src/components/Table/components/TableCell/components/MarkdownCell/types.ts +3 -0
  122. package/src/components/common/Progress/components/CircularProgress/circularProgress.tsx +1 -1
  123. package/src/components/common/Stack/stack.tsx +2 -2
  124. package/src/styles/common/mui/typography.ts +1 -0
  125. package/tests/markdownCell.test.tsx +53 -0
  126. package/tests/useRequestManifest.test.ts +1 -1
  127. package/types/data-explorer-ui.d.ts +2 -0
@@ -1,20 +1,22 @@
1
1
  import { Grid } from "@mui/material";
2
+ import { RowData } from "@tanstack/react-table";
2
3
  import React from "react";
4
+ import { Attribute } from "../../../../common/entities";
3
5
  import { Entity } from "../Entity/entity";
4
6
  import { GRID_PROPS } from "./constants";
5
7
  import { ClassesProps } from "./types";
6
8
 
7
- export const Entities = ({
9
+ export const Entities = <T extends RowData = Attribute>({
8
10
  classes,
9
11
  columnDefs,
10
12
  spacing,
11
- }: ClassesProps): JSX.Element => {
13
+ }: ClassesProps<T>): JSX.Element => {
12
14
  return (
13
15
  <Grid {...GRID_PROPS}>
14
- {classes.map((classData) => (
16
+ {classes.map((cls) => (
15
17
  <Entity
16
- key={classData.name}
17
- class={classData}
18
+ key={cls.name}
19
+ class={cls}
18
20
  columnDefs={columnDefs}
19
21
  spacing={spacing}
20
22
  />
@@ -1,13 +1,9 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import {
3
- Attribute,
4
- AttributeValueTypes,
5
- Class,
6
- } from "../../../../common/entities";
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
7
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
8
4
 
9
- export interface ClassesProps {
10
- classes: Class[];
11
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
5
+ export interface ClassesProps<T extends RowData = Attribute> {
6
+ classes: Class<T>[];
7
+ columnDefs: ColumnDef<T, T[keyof T]>[];
12
8
  spacing?: LayoutSpacing;
13
9
  }
@@ -1,5 +1,7 @@
1
1
  import { Grid, Typography } from "@mui/material";
2
+ import { RowData } from "@tanstack/react-table";
2
3
  import React from "react";
4
+ import { Attribute } from "../../../../common/entities";
3
5
  import { TYPOGRAPHY_PROPS } from "../../../../styles/common/mui/typography";
4
6
  import { AnchorLink } from "../../../common/AnchorLink/anchorLink";
5
7
  import { useTable } from "../Table/hook";
@@ -8,29 +10,29 @@ import { GRID_PROPS } from "./constants";
8
10
  import { StyledTypography } from "./entity.styles";
9
11
  import { EntityProps } from "./types";
10
12
 
11
- export const Entity = ({
12
- class: classData,
13
+ export const Entity = <T extends RowData = Attribute>({
14
+ class: cls,
13
15
  columnDefs,
14
16
  spacing,
15
- }: EntityProps): JSX.Element => {
16
- const table = useTable(classData.attributes, columnDefs);
17
+ }: EntityProps<T>): JSX.Element => {
18
+ const table = useTable<T>(cls.attributes, columnDefs);
17
19
  return (
18
20
  <Grid {...GRID_PROPS} rowGap={4}>
19
21
  <Grid {...GRID_PROPS} rowGap={1}>
20
22
  <StyledTypography
21
23
  component="h3"
22
- id={classData.name}
24
+ id={cls.name}
23
25
  variant={TYPOGRAPHY_PROPS.VARIANT.TEXT_HEADING_SMALL}
24
26
  {...spacing}
25
27
  >
26
- {classData.title} <AnchorLink anchorLink={classData.name} />
28
+ {cls.title} <AnchorLink anchorLink={cls.name} />
27
29
  </StyledTypography>
28
30
  <Typography
29
31
  color={TYPOGRAPHY_PROPS.COLOR.INK_LIGHT}
30
32
  component="div"
31
33
  variant={TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_400_2_LINES}
32
34
  >
33
- {classData.description}
35
+ {cls.description}
34
36
  </Typography>
35
37
  </Grid>
36
38
  <Table table={table} />
@@ -1,13 +1,9 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import {
3
- Attribute,
4
- AttributeValueTypes,
5
- Class,
6
- } from "../../../../common/entities";
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
7
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
8
4
 
9
- export interface EntityProps {
10
- class: Class;
11
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
5
+ export interface EntityProps<T extends RowData = Attribute> {
6
+ class: Class<T>;
7
+ columnDefs: ColumnDef<T, T[keyof T]>[];
12
8
  spacing?: LayoutSpacing;
13
9
  }
@@ -1,4 +1,5 @@
1
- import { Class } from "../../../../common/entities";
1
+ import { RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
2
3
  import { OutlineItem } from "../../../Layout/components/Outline/types";
3
4
 
4
5
  /**
@@ -6,7 +7,9 @@ import { OutlineItem } from "../../../Layout/components/Outline/types";
6
7
  * @param classes - Class entities.
7
8
  * @returns Outline items.
8
9
  */
9
- export function buildClassesOutline(classes: Class[]): OutlineItem[] {
10
+ export function buildClassesOutline<T extends RowData = Attribute>(
11
+ classes: Class<T>[]
12
+ ): OutlineItem[] {
10
13
  return classes.map(({ name, title }) => {
11
14
  return {
12
15
  depth: 2,
@@ -1,13 +1,21 @@
1
- import { ColumnDef, Table, useReactTable } from "@tanstack/react-table";
2
- import { Attribute, AttributeValueTypes } from "../../../../common/entities";
1
+ import {
2
+ ColumnDef,
3
+ RowData,
4
+ Table,
5
+ useReactTable,
6
+ } from "@tanstack/react-table";
7
+ import { Attribute } from "../../../../common/entities";
3
8
  import { useTableOptions } from "./options/hook";
4
9
 
5
- export const useTable = (
6
- data: Attribute[],
7
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[]
8
- ): Table<Attribute> => {
9
- const tableOptions = useTableOptions();
10
- return useReactTable<Attribute>({
10
+ export const useTable = <T extends RowData = Attribute>(
11
+ data: T[],
12
+ columnDefs: ColumnDef<T, T[keyof T]>[]
13
+ ): Table<T> => {
14
+ // Table options.
15
+ const tableOptions = useTableOptions<T>();
16
+
17
+ // Table instance.
18
+ return useReactTable<T>({
11
19
  ...tableOptions,
12
20
  columns: columnDefs,
13
21
  data,
@@ -1,10 +1,9 @@
1
- import { CoreOptions, getCoreRowModel } from "@tanstack/react-table";
2
- import { Attribute } from "../../../../../../common/entities";
1
+ import { CoreOptions, getCoreRowModel, RowData } from "@tanstack/react-table";
3
2
  import { ROW_POSITION } from "../../../../../Table/features/RowPosition/constants";
4
3
  import { ROW_PREVIEW } from "../../../../../Table/features/RowPreview/constants";
5
4
 
6
5
  export const CORE_OPTIONS: Pick<
7
- CoreOptions<Attribute>,
6
+ CoreOptions<RowData>,
8
7
  "_features" | "getCoreRowModel"
9
8
  > = {
10
9
  _features: [ROW_POSITION, ROW_PREVIEW],
@@ -1,10 +1,10 @@
1
- import { TableOptions } from "@tanstack/react-table";
1
+ import { RowData, TableOptions } from "@tanstack/react-table";
2
2
  import { Attribute } from "../../../../../common/entities";
3
3
  import { CORE_OPTIONS } from "./core/constants";
4
4
  import { SORTING_OPTIONS } from "./sorting/constants";
5
5
 
6
- export const useTableOptions = (): Omit<
7
- TableOptions<Attribute>,
6
+ export const useTableOptions = <T extends RowData = Attribute>(): Omit<
7
+ TableOptions<T>,
8
8
  "columns" | "data"
9
9
  > => {
10
10
  return {
@@ -1,9 +1,5 @@
1
- import { SortingOptions } from "@tanstack/react-table";
2
- import { Attribute } from "../../../../../../common/entities";
1
+ import { RowData, SortingOptions } from "@tanstack/react-table";
3
2
 
4
- export const SORTING_OPTIONS: Pick<
5
- SortingOptions<Attribute>,
6
- "enableSorting"
7
- > = {
3
+ export const SORTING_OPTIONS: Pick<SortingOptions<RowData>, "enableSorting"> = {
8
4
  enableSorting: false,
9
5
  };
@@ -1,4 +1,5 @@
1
1
  import { TableContainer } from "@mui/material";
2
+ import { RowData } from "@tanstack/react-table";
2
3
  import React from "react";
3
4
  import { TableBody } from "../../../Detail/components/Table/components/TableBody/tableBody";
4
5
  import { ROW_DIRECTION } from "../../../Table/common/entities";
@@ -9,7 +10,9 @@ import { GridPaper } from "../../../common/Paper/paper.styles";
9
10
  import { StyledRoundedPaper } from "./table.styles";
10
11
  import { TableProps } from "./types";
11
12
 
12
- export const Table = ({ table }: TableProps): JSX.Element => {
13
+ export const Table = <T extends RowData>({
14
+ table,
15
+ }: TableProps<T>): JSX.Element => {
13
16
  return (
14
17
  <StyledRoundedPaper variant="table">
15
18
  <GridPaper>
@@ -1,6 +1,5 @@
1
- import { Table } from "@tanstack/react-table";
2
- import { Attribute } from "../../../../common/entities";
1
+ import { RowData, Table } from "@tanstack/react-table";
3
2
 
4
- export interface TableProps {
5
- table: Table<Attribute>;
3
+ export interface TableProps<T extends RowData> {
4
+ table: Table<T>;
6
5
  }
@@ -1,4 +1,6 @@
1
+ import { RowData } from "@tanstack/react-table";
1
2
  import React, { useMemo } from "react";
3
+ import { Attribute } from "../../common/entities";
2
4
  import { Entities } from "./components/Entities/entities";
3
5
  import { EntitiesLayout as DefaultEntitiesLayout } from "./components/Layout/components/EntitiesLayout/entitiesLayout";
4
6
  import { OutlineLayout as DefaultOutlineLayout } from "./components/Layout/components/OutlineLayout/outlineLayout";
@@ -11,7 +13,7 @@ import { useDataDictionary } from "./hooks/UseDataDictionary/hook";
11
13
  import { useLayoutSpacing } from "./hooks/UseLayoutSpacing/hook";
12
14
  import { DataDictionaryProps } from "./types";
13
15
 
14
- export const DataDictionary = ({
16
+ export const DataDictionary = <T extends RowData = Attribute>({
15
17
  className,
16
18
  EntitiesLayout = DefaultEntitiesLayout,
17
19
  Outline = DefaultOutline,
@@ -19,7 +21,7 @@ export const DataDictionary = ({
19
21
  Title = DefaultTitle,
20
22
  TitleLayout = DefaultTitleLayout,
21
23
  }: DataDictionaryProps): JSX.Element => {
22
- const { classes, columnDefs } = useDataDictionary();
24
+ const { classes, columnDefs } = useDataDictionary<T>();
23
25
  const { spacing } = useLayoutSpacing();
24
26
  const outline = useMemo(() => buildClassesOutline(classes), [classes]);
25
27
  return (
@@ -1,13 +1,20 @@
1
+ import { RowData } from "@tanstack/react-table";
1
2
  import { useMemo } from "react";
3
+ import { Attribute, DataDictionaryConfig } from "../../../../common/entities";
2
4
  import { useConfig } from "../../../../hooks/useConfig";
3
5
  import { UseDataDictionary } from "./types";
4
6
 
5
- export const useDataDictionary = (): UseDataDictionary => {
7
+ export const useDataDictionary = <
8
+ T extends RowData = Attribute
9
+ >(): UseDataDictionary<T> => {
6
10
  const {
7
11
  config: { dataDictionaries: dataDictionaryConfigs },
8
12
  } = useConfig();
9
13
 
10
- const dataDictionaryConfig = dataDictionaryConfigs?.[0]; // TODO: Handle multiple data dictionaries
14
+ const dataDictionaryConfig = dataDictionaryConfigs?.[0] as
15
+ | DataDictionaryConfig<T>
16
+ | undefined; // TODO: Handle multiple data dictionaries
17
+
11
18
  return useMemo(() => {
12
19
  const classes = dataDictionaryConfig?.dataDictionary?.classes || [];
13
20
  const columnDefs = dataDictionaryConfig?.columnDefs || [];
@@ -1,11 +1,7 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import {
3
- Attribute,
4
- AttributeValueTypes,
5
- Class,
6
- } from "../../../../common/entities";
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
7
3
 
8
- export interface UseDataDictionary {
9
- classes: Class[];
10
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
4
+ export interface UseDataDictionary<T extends RowData = Attribute> {
5
+ classes: Class<T>[];
6
+ columnDefs: ColumnDef<T, T[keyof T]>[];
11
7
  }
@@ -63,9 +63,9 @@ export const VariableSizeList = ({
63
63
  height: initHeight = MAX_LIST_HEIGHT_PX,
64
64
  isFilterDrawer,
65
65
  itemSize = LIST_ITEM_HEIGHT,
66
+ matchedItems,
66
67
  onFilter,
67
68
  overscanCount = MAX_DISPLAYABLE_LIST_ITEMS * 2,
68
- matchedItems,
69
69
  width = "100%",
70
70
  }: VariableSizeListProps): JSX.Element => {
71
71
  const { height: windowHeight } = useWindowResize();
@@ -0,0 +1,34 @@
1
+ import React, { AnchorHTMLAttributes, ClassAttributes } from "react";
2
+ import { Link } from "../../../Links/components/Link/link";
3
+ import { BaseComponentProps } from "../../../types";
4
+
5
+ /**
6
+ * rehype-sanitize's default schema allows only a limited set of attributes on <a> elements:
7
+ * - aria-*
8
+ * - className
9
+ * - data-footnote-backref
10
+ * - data-footnote-ref
11
+ * - href
12
+ *
13
+ * By default, attributes such as:
14
+ * - download
15
+ * - rel
16
+ * - target
17
+ * are not permitted and will be stripped from anchor tags during sanitization.
18
+ *
19
+ * Note: This component currently does not support these excluded attributes.
20
+ */
21
+
22
+ export const Anchor = (
23
+ props: BaseComponentProps &
24
+ ClassAttributes<HTMLAnchorElement> &
25
+ AnchorHTMLAttributes<HTMLAnchorElement>
26
+ ): JSX.Element => {
27
+ return (
28
+ <Link
29
+ className={props.className}
30
+ label={props.children}
31
+ url={props.href || ""}
32
+ />
33
+ );
34
+ };
@@ -0,0 +1,41 @@
1
+ import styled from "@emotion/styled";
2
+ import { PALETTE } from "../../../../styles/common/constants/palette";
3
+ import { textBody500 } from "../../../../styles/common/mixins/fonts";
4
+
5
+ export const StyledTable = styled("table")`
6
+ border-collapse: collapse;
7
+ margin: 16px 0;
8
+ table-layout: fixed;
9
+ width: 100%;
10
+
11
+ thead {
12
+ all: unset;
13
+ display: table-header-group;
14
+ }
15
+
16
+ tbody {
17
+ all: unset;
18
+ display: table-row-group;
19
+ }
20
+
21
+ tr {
22
+ all: unset;
23
+ display: table-row;
24
+ }
25
+
26
+ td,
27
+ th {
28
+ display: table-cell;
29
+ padding: 2px 4px;
30
+ }
31
+
32
+ th {
33
+ ${textBody500}
34
+ border-bottom: 1px solid ${PALETTE.SMOKE_MAIN};
35
+ }
36
+
37
+ td {
38
+ font: inherit;
39
+ overflow-wrap: break-word;
40
+ }
41
+ `;
@@ -0,0 +1,13 @@
1
+ import { BaseComponentProps } from "components/types";
2
+ import React, { ClassAttributes, TableHTMLAttributes } from "react";
3
+ import { StyledTable } from "./table.styles";
4
+
5
+ export const Table = (
6
+ props: BaseComponentProps &
7
+ ClassAttributes<HTMLTableElement> &
8
+ TableHTMLAttributes<HTMLTableElement>
9
+ ): JSX.Element => {
10
+ return (
11
+ <StyledTable className={props.className}>{props.children}</StyledTable>
12
+ );
13
+ };
@@ -0,0 +1,8 @@
1
+ import { Anchor } from "./components/Anchor/anchor";
2
+ import { Table } from "./components/Table/table";
3
+ import { MarkdownRendererComponents } from "./types";
4
+
5
+ export const COMPONENTS: MarkdownRendererComponents = {
6
+ a: Anchor,
7
+ table: Table,
8
+ };
@@ -0,0 +1,16 @@
1
+ import styled from "@emotion/styled";
2
+
3
+ // See https://github.com/emotion-js/emotion/issues/1105.
4
+ // See https://github.com/emotion-js/emotion/releases/tag/%40emotion%2Fcache%4011.10.2.
5
+ const ignoreSsrWarning =
6
+ "/* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */";
7
+
8
+ export const StyledContainer = styled("div")`
9
+ > *:first-child:not(style)${ignoreSsrWarning} {
10
+ margin-top: 0;
11
+ }
12
+
13
+ > *:last-child:not(style)${ignoreSsrWarning} {
14
+ margin-bottom: 0;
15
+ }
16
+ `;
@@ -0,0 +1,74 @@
1
+ import { Typography } from "@mui/material";
2
+ import React, { Fragment, createElement, useEffect, useState } from "react";
3
+ import rehypeRaw from "rehype-raw";
4
+ import rehypeReact from "rehype-react";
5
+ import rehypeSanitize from "rehype-sanitize";
6
+ import remarkGfm from "remark-gfm";
7
+ import remarkParse from "remark-parse";
8
+ import remarkRehype from "remark-rehype";
9
+ import { unified } from "unified";
10
+ import { TYPOGRAPHY_PROPS } from "../../styles/common/mui/typography";
11
+ import { COMPONENTS } from "./constants";
12
+ import { StyledContainer } from "./markdownRenderer.styles";
13
+ import { MarkdownRendererComponents, MarkdownRendererProps } from "./types";
14
+
15
+ /**
16
+ * Markdown Rendering - Pipeline Version Constraints
17
+ *
18
+ * next-mdx-remote and @next/mdx currently embed MDX v3. MDX v3 is compiled
19
+ * for the "Unified 10" tool-chain and therefore only functions with unified
20
+ * 10.x, remark-parse 10.x, remark-rehype 10.x and, critically, remark-gfm 3.x.
21
+ *
22
+ * Because remark-gfm 3.x is required, migrating to Unified 11 is not yet possible.
23
+ *
24
+ * rehype plug-ins are chosen from versions that still target Unified 10:
25
+ * rehype-raw 7.x, rehype-sanitize 5.x and rehype-react 7.x.
26
+ */
27
+
28
+ export const MarkdownRenderer = ({
29
+ className,
30
+ components: componentOptions = COMPONENTS,
31
+ value,
32
+ }: MarkdownRendererProps): JSX.Element => {
33
+ const [element, setElement] = useState<JSX.Element | null>(null);
34
+ const [error, setError] = useState<string | null>(null);
35
+ const [components] = useState<MarkdownRendererComponents>(componentOptions);
36
+
37
+ useEffect(() => {
38
+ let cancelled = false;
39
+ setError(null);
40
+
41
+ const processor = unified()
42
+ .use(remarkParse)
43
+ .use(remarkGfm)
44
+ .use(remarkRehype, { allowDangerousHtml: true })
45
+ .use(rehypeRaw)
46
+ .use(rehypeSanitize)
47
+ .use(rehypeReact, { Fragment, components, createElement });
48
+
49
+ processor
50
+ .process(value)
51
+ .then(({ result }) => {
52
+ if (!cancelled) setElement(result);
53
+ })
54
+ .catch((err) => {
55
+ if (!cancelled) setError(err.message);
56
+ });
57
+
58
+ return (): void => {
59
+ cancelled = true;
60
+ };
61
+ }, [components, value]);
62
+
63
+ if (error)
64
+ return (
65
+ <Typography
66
+ color={TYPOGRAPHY_PROPS.COLOR.ERROR}
67
+ variant={TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_SMALL_400}
68
+ >
69
+ {error}
70
+ </Typography>
71
+ );
72
+
73
+ return <StyledContainer className={className}>{element}</StyledContainer>;
74
+ };
@@ -0,0 +1,10 @@
1
+ import { ComponentType } from "react";
2
+ import { BaseComponentProps } from "../types";
3
+
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- rehype-react passes arbitrary HTML attributes to components when rendering markdown elements
5
+ export type MarkdownRendererComponents = Record<string, ComponentType<any>>;
6
+
7
+ export interface MarkdownRendererProps extends BaseComponentProps {
8
+ components?: MarkdownRendererComponents;
9
+ value: string;
10
+ }
@@ -1,14 +1,16 @@
1
1
  import { Chip, ChipProps } from "@mui/material";
2
2
  import { CellContext, RowData } from "@tanstack/react-table";
3
3
  import React from "react";
4
+ import { BaseComponentProps } from "../../../../../types";
4
5
 
5
6
  export const ChipCell = <
6
7
  T extends RowData,
7
8
  TValue extends ChipProps = ChipProps
8
9
  >({
10
+ className,
9
11
  getValue,
10
- }: CellContext<T, TValue>): JSX.Element | null => {
12
+ }: BaseComponentProps & CellContext<T, TValue>): JSX.Element | null => {
11
13
  const props = getValue();
12
14
  if (!props) return null;
13
- return <Chip {...props} />;
15
+ return <Chip className={className} {...props} />;
14
16
  };
@@ -11,13 +11,13 @@ export const LinkCell = <
11
11
  T extends RowData,
12
12
  TValue extends LinkProps = LinkProps
13
13
  >({
14
+ className,
14
15
  getValue,
15
16
  }: BaseComponentProps & CellContext<T, TValue>): JSX.Element | null => {
16
17
  const props = getValue();
17
18
  if (!props) return null;
18
19
  const {
19
20
  children,
20
- className,
21
21
  color,
22
22
  href = "",
23
23
  rel,
@@ -0,0 +1,31 @@
1
+ import styled from "@emotion/styled";
2
+ import { PALETTE } from "../../../../../../styles/common/constants/palette";
3
+ import { MarkdownRenderer } from "../../../../../MarkdownRenderer/markdownRenderer";
4
+
5
+ export const StyledMarkdownRenderer = styled(MarkdownRenderer)`
6
+ align-self: flex-start;
7
+
8
+ code {
9
+ all: unset;
10
+ font: inherit;
11
+ font-family: Roboto Mono, monospace;
12
+ }
13
+
14
+ h2,
15
+ h3,
16
+ h4,
17
+ h5,
18
+ h6 {
19
+ margin: 8px 0;
20
+ }
21
+
22
+ hr {
23
+ border: none;
24
+ border-bottom: 1px solid ${PALETTE.SMOKE_MAIN};
25
+ margin: 16px 0;
26
+ }
27
+
28
+ p {
29
+ font: inherit;
30
+ }
31
+ `;
@@ -0,0 +1,29 @@
1
+ import { CellContext, RowData } from "@tanstack/react-table";
2
+ import { BaseComponentProps } from "components/types";
3
+ import React from "react";
4
+ import { COMPONENTS } from "../../../../../MarkdownRenderer/constants";
5
+ import { StyledMarkdownRenderer } from "./markdownCell.styles";
6
+ import { MarkdownCellProps } from "./types";
7
+
8
+ export const MarkdownCell = <
9
+ T extends RowData,
10
+ TValue extends MarkdownCellProps = MarkdownCellProps
11
+ >({
12
+ className,
13
+ column,
14
+ getValue,
15
+ }: BaseComponentProps & CellContext<T, TValue>): JSX.Element | null => {
16
+ const props = getValue();
17
+ if (!props) return null;
18
+ const { values } = props;
19
+ const columnDef = column?.columnDef;
20
+ const columnMeta = columnDef?.meta;
21
+ const components = columnMeta?.components;
22
+ return (
23
+ <StyledMarkdownRenderer
24
+ className={className}
25
+ components={{ ...COMPONENTS, ...components }}
26
+ value={values}
27
+ />
28
+ );
29
+ };
@@ -0,0 +1,17 @@
1
+ import { ComponentProps } from "react";
2
+ import { MarkdownCell } from "../markdownCell";
3
+ import { GetValue } from "./types";
4
+
5
+ export const DEFAULT_ARGS: Partial<ComponentProps<typeof MarkdownCell>> = {
6
+ getValue: (() => ({
7
+ values:
8
+ '| Key | Annotator | Value |\n| --- | --- | --- |\n| `tissue_ontology_term_id` | Curator | categorical with `str` categories. This **MUST** be the UBERON or CL term that best describes the tissue the cell was derived from, depending on the sample type. |\n\n**Mapping guidance**\n\n| For | Use |\n| --- | --- |\n| Tissue | STRONGLY RECOMMENDED to be an UBERON term&nbsp;<br />(e.g. [`UBERON:0008930`](http://purl.obolibrary.org/obo/UBERON_0008930) for a *somatosensory cortex* tissue sample) |\n| Cell culture | MUST be a CL term appended with \\" (cell culture)\\"&nbsp;<br />(e.g. [`CL:0000057`](http://purl.obolibrary.org/obo/CL_0000057) **(cell culture)** for the *WTC-11* cell line) |\n| Organoid | MUST be an UBERON term appended with \\" (organoid)\\"&nbsp;<br />(e.g. [`UBERON:0000955`](http://purl.obolibrary.org/obo/UBERON_0000955) **(organoid)** for a *brain organoid*) |\n| Enriched / sorted / isolated cells from a tissue | MUST be an UBERON or CL term and **SHOULD NOT** use terms that do not capture the tissue of origin.<br /><br />• *CD3+ kidney cells* → [`UBERON:0002113`](https://www.ebi.ac.uk/ols/ontologies/uberon/terms?iri=http://purl.obolibrary.org/obo/UBERON_0002113) (*kidney*) instead of [`CL:000084`](https://www.ebi.ac.uk/ols/ontologies/cl/terms?iri=http://purl.obolibrary.org/obo/CL_0000084) (*T cell*).<br />• *EPCAM+ cervical cells* → [`CL:0000066`](https://www.ebi.ac.uk/ols/ontologies/cl/terms?iri=http://purl.obolibrary.org/obo/CL_0000066) (*epithelial cell* of the cervix). |\n\n---\n\nWhen a dataset is uploaded, the **cellxgene Data Portal** MUST automatically add the matching human-readable name for the corresponding ontology term to the `obs` dataframe. Curators **MUST NOT** annotate the following columns.\n\n### `assay`\n\n| Key | Annotator | Value |\n| --- | --- | --- |\n| `assay` | Data Portal | categorical with `str` categories. This **MUST** be the human-readable name assigned to the value of `assay_ontology_term_id`. |',
9
+ })) as GetValue,
10
+ };
11
+
12
+ export const WITH_HTML_ARGS: Partial<ComponentProps<typeof MarkdownCell>> = {
13
+ getValue: (() => ({
14
+ values:
15
+ "Hello <br />World <a href='https://www.example.com'>example link</a>",
16
+ })) as GetValue,
17
+ };
@@ -0,0 +1,11 @@
1
+ import styled from "@emotion/styled";
2
+ import { Anchor } from "../../../../../../MarkdownRenderer/components/Anchor/anchor";
3
+
4
+ /**
5
+ * Styled anchor component for testing purposes.
6
+ */
7
+
8
+ export const STYLED_ANCHOR = styled(Anchor)`
9
+ background-color: green;
10
+ color: white;
11
+ ` as typeof Anchor;