@databiosphere/findable-ui 30.0.0 → 31.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 (89) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +13 -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/Outline/utils.d.ts +3 -2
  11. package/lib/components/DataDictionary/components/Table/hook.d.ts +3 -3
  12. package/lib/components/DataDictionary/components/Table/hook.js +3 -1
  13. package/lib/components/DataDictionary/components/Table/options/core/constants.d.ts +2 -3
  14. package/lib/components/DataDictionary/components/Table/options/hook.d.ts +2 -2
  15. package/lib/components/DataDictionary/components/Table/options/sorting/constants.d.ts +2 -3
  16. package/lib/components/DataDictionary/components/Table/table.d.ts +2 -1
  17. package/lib/components/DataDictionary/components/Table/table.js +1 -1
  18. package/lib/components/DataDictionary/components/Table/types.d.ts +3 -4
  19. package/lib/components/DataDictionary/dataDictionary.d.ts +3 -1
  20. package/lib/components/DataDictionary/hooks/UseDataDictionary/hook.d.ts +3 -1
  21. package/lib/components/DataDictionary/hooks/UseDataDictionary/types.d.ts +5 -5
  22. package/lib/components/MarkdownRenderer/components/Anchor/anchor.d.ts +19 -0
  23. package/lib/components/MarkdownRenderer/components/Anchor/anchor.js +21 -0
  24. package/lib/components/MarkdownRenderer/components/Table/table.d.ts +3 -0
  25. package/lib/components/MarkdownRenderer/components/Table/table.js +5 -0
  26. package/lib/components/MarkdownRenderer/components/Table/table.styles.d.ts +4 -0
  27. package/lib/components/MarkdownRenderer/components/Table/table.styles.js +40 -0
  28. package/lib/components/MarkdownRenderer/constants.d.ts +2 -0
  29. package/lib/components/MarkdownRenderer/constants.js +6 -0
  30. package/lib/components/MarkdownRenderer/markdownRenderer.d.ts +2 -0
  31. package/lib/components/MarkdownRenderer/markdownRenderer.js +45 -0
  32. package/lib/components/MarkdownRenderer/markdownRenderer.styles.d.ts +4 -0
  33. package/lib/components/MarkdownRenderer/markdownRenderer.styles.js +13 -0
  34. package/lib/components/MarkdownRenderer/types.d.ts +6 -0
  35. package/lib/components/MarkdownRenderer/types.js +1 -0
  36. package/lib/components/Table/components/TableCell/components/ChipCell/chipCell.d.ts +2 -1
  37. package/lib/components/Table/components/TableCell/components/ChipCell/chipCell.js +2 -2
  38. package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.d.ts +1 -1
  39. package/lib/components/Table/components/TableCell/components/LinkCell/linkCell.js +2 -2
  40. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.d.ts +4 -0
  41. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.js +13 -0
  42. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.styles.d.ts +3 -0
  43. package/lib/components/Table/components/TableCell/components/MarkdownCell/markdownCell.styles.js +30 -0
  44. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/args.d.ts +4 -0
  45. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/args.js +10 -0
  46. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/constants.d.ts +5 -0
  47. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/constants.js +9 -0
  48. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories.d.ts +7 -0
  49. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories.js +25 -0
  50. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/types.d.ts +3 -0
  51. package/lib/components/Table/components/TableCell/components/MarkdownCell/stories/types.js +1 -0
  52. package/lib/components/Table/components/TableCell/components/MarkdownCell/types.d.ts +3 -0
  53. package/lib/components/Table/components/TableCell/components/MarkdownCell/types.js +1 -0
  54. package/lib/styles/common/mui/typography.js +1 -0
  55. package/package.json +6 -1
  56. package/src/common/entities.ts +8 -31
  57. package/src/components/DataDictionary/components/Entities/entities.tsx +7 -5
  58. package/src/components/DataDictionary/components/Entities/types.ts +5 -9
  59. package/src/components/DataDictionary/components/Entity/entity.tsx +9 -7
  60. package/src/components/DataDictionary/components/Entity/types.ts +5 -9
  61. package/src/components/DataDictionary/components/Outline/utils.ts +5 -2
  62. package/src/components/DataDictionary/components/Table/hook.ts +16 -8
  63. package/src/components/DataDictionary/components/Table/options/core/constants.ts +2 -3
  64. package/src/components/DataDictionary/components/Table/options/hook.ts +3 -3
  65. package/src/components/DataDictionary/components/Table/options/sorting/constants.ts +2 -6
  66. package/src/components/DataDictionary/components/Table/table.tsx +4 -1
  67. package/src/components/DataDictionary/components/Table/types.ts +3 -4
  68. package/src/components/DataDictionary/dataDictionary.tsx +4 -2
  69. package/src/components/DataDictionary/hooks/UseDataDictionary/hook.ts +9 -2
  70. package/src/components/DataDictionary/hooks/UseDataDictionary/types.ts +5 -9
  71. package/src/components/MarkdownRenderer/components/Anchor/anchor.tsx +34 -0
  72. package/src/components/MarkdownRenderer/components/Table/table.styles.ts +41 -0
  73. package/src/components/MarkdownRenderer/components/Table/table.tsx +13 -0
  74. package/src/components/MarkdownRenderer/constants.ts +8 -0
  75. package/src/components/MarkdownRenderer/markdownRenderer.styles.ts +16 -0
  76. package/src/components/MarkdownRenderer/markdownRenderer.tsx +62 -0
  77. package/src/components/MarkdownRenderer/types.ts +7 -0
  78. package/src/components/Table/components/TableCell/components/ChipCell/chipCell.tsx +4 -2
  79. package/src/components/Table/components/TableCell/components/LinkCell/linkCell.tsx +1 -1
  80. package/src/components/Table/components/TableCell/components/MarkdownCell/markdownCell.styles.ts +31 -0
  81. package/src/components/Table/components/TableCell/components/MarkdownCell/markdownCell.tsx +29 -0
  82. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/args.ts +17 -0
  83. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/constants.ts +11 -0
  84. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories.tsx +37 -0
  85. package/src/components/Table/components/TableCell/components/MarkdownCell/stories/types.ts +4 -0
  86. package/src/components/Table/components/TableCell/components/MarkdownCell/types.ts +3 -0
  87. package/src/styles/common/mui/typography.ts +1 -0
  88. package/tests/markdownCell.test.tsx +53 -0
  89. package/types/data-explorer-ui.d.ts +2 -0
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "30.0.0"
2
+ ".": "31.0.0"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [31.0.0](https://github.com/DataBiosphere/findable-ui/compare/v30.0.0...v31.0.0) (2025-05-15)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * create data dictionary table cell for displaying markdown ([#453](https://github.com/DataBiosphere/findable-ui/issues/453)) (#480)
9
+ * make data dictionary config generic with attribute as default ([#476](https://github.com/DataBiosphere/findable-ui/issues/476)) (#477)
10
+
11
+ ### Features
12
+
13
+ * create data dictionary table cell for displaying markdown ([#453](https://github.com/DataBiosphere/findable-ui/issues/453)) ([#480](https://github.com/DataBiosphere/findable-ui/issues/480)) ([4ee16e7](https://github.com/DataBiosphere/findable-ui/commit/4ee16e75e66dd56d126ed01773364d6fe5a32ab7))
14
+ * make data dictionary config generic with attribute as default ([#476](https://github.com/DataBiosphere/findable-ui/issues/476)) ([#477](https://github.com/DataBiosphere/findable-ui/issues/477)) ([723585d](https://github.com/DataBiosphere/findable-ui/commit/723585de6e6380eccd5d39f72cbc0aa6db1fc398))
15
+
3
16
  ## [30.0.0](https://github.com/DataBiosphere/findable-ui/compare/v29.0.2...v30.0.0) (2025-05-13)
4
17
 
5
18
 
@@ -1,5 +1,4 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import { GridTrackSize } from "../config/entities";
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
3
2
  /**
4
3
  * Model of a value of a metadata class.
5
4
  */
@@ -17,10 +16,6 @@ export interface Attribute {
17
16
  title: string;
18
17
  values?: string;
19
18
  }
20
- /**
21
- * Model of attribute key types; used mostly when building data dictionary column definitions.
22
- */
23
- export type AttributeValueTypes<TValue = unknown> = TValue;
24
19
  /**
25
20
  * Filterable metadata keys.
26
21
  */
@@ -36,8 +31,8 @@ export interface CategoryTag {
36
31
  /**
37
32
  * Model of a metadata class, to be specified manually or built from LinkML schema.
38
33
  */
39
- export interface Class {
40
- attributes: Attribute[];
34
+ export interface Class<T extends RowData = Attribute> {
35
+ attributes: T[];
41
36
  description: string;
42
37
  name: string;
43
38
  title: string;
@@ -54,36 +49,23 @@ export type DataDictionaryPrefix = Record<string, string>;
54
49
  /**
55
50
  * Model of a metadata dictionary containing a set of classes and their definitions.
56
51
  */
57
- export interface DataDictionary {
52
+ export interface DataDictionary<T extends RowData = Attribute> {
58
53
  annotations?: {
59
54
  [key in keyof DataDictionaryPrefix]: string;
60
55
  };
61
- classes: Class[];
56
+ classes: Class<T>[];
62
57
  description?: string;
63
58
  name: string;
64
59
  prefixes?: DataDictionaryPrefix;
65
60
  title: string;
66
61
  }
67
- /**
68
- * Display model of a data dictionary column.
69
- */
70
- export interface DataDictionaryColumnDef {
71
- attributeAccessorFnName?: string;
72
- attributeCellName?: string;
73
- attributeDisplayName: string;
74
- attributeSlotName: string;
75
- width: Omit<GridTrackSize, "GridTrackMinMax"> | {
76
- max: string;
77
- min: string;
78
- };
79
- }
80
62
  /**
81
63
  * Configuration of data dictionary; contains schema definition (that is, the actual data
82
64
  * dictionary) as well as column def for displaying the data dictionary.
83
65
  */
84
- export interface DataDictionaryConfig {
85
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
86
- dataDictionary: DataDictionary;
66
+ export interface DataDictionaryConfig<T extends RowData = Attribute> {
67
+ columnDefs: ColumnDef<T, T[keyof T]>[];
68
+ dataDictionary: DataDictionary<T>;
87
69
  }
88
70
  /**
89
71
  * Label and description values from a data dictionary that are added to a site
@@ -1,2 +1,4 @@
1
+ import { RowData } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
1
3
  import { ClassesProps } from "./types";
2
- export declare const Entities: ({ classes, columnDefs, spacing, }: ClassesProps) => JSX.Element;
4
+ export declare const Entities: <T extends RowData = Attribute>({ classes, columnDefs, spacing, }: ClassesProps<T>) => JSX.Element;
@@ -3,5 +3,5 @@ import React from "react";
3
3
  import { Entity } from "../Entity/entity";
4
4
  import { GRID_PROPS } from "./constants";
5
5
  export const Entities = ({ classes, columnDefs, spacing, }) => {
6
- return (React.createElement(Grid, { ...GRID_PROPS }, classes.map((classData) => (React.createElement(Entity, { key: classData.name, class: classData, columnDefs: columnDefs, spacing: spacing })))));
6
+ return (React.createElement(Grid, { ...GRID_PROPS }, classes.map((cls) => (React.createElement(Entity, { key: cls.name, class: cls, columnDefs: columnDefs, spacing: spacing })))));
7
7
  };
@@ -1,8 +1,8 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import { Attribute, AttributeValueTypes, Class } from "../../../../common/entities";
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
- export interface ClassesProps {
5
- classes: Class[];
6
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
4
+ export interface ClassesProps<T extends RowData = Attribute> {
5
+ classes: Class<T>[];
6
+ columnDefs: ColumnDef<T, T[keyof T]>[];
7
7
  spacing?: LayoutSpacing;
8
8
  }
@@ -1,2 +1,4 @@
1
+ import { RowData } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
1
3
  import { EntityProps } from "./types";
2
- export declare const Entity: ({ class: classData, columnDefs, spacing, }: EntityProps) => JSX.Element;
4
+ export declare const Entity: <T extends RowData = Attribute>({ class: cls, columnDefs, spacing, }: EntityProps<T>) => JSX.Element;
@@ -6,14 +6,14 @@ import { useTable } from "../Table/hook";
6
6
  import { Table } from "../Table/table";
7
7
  import { GRID_PROPS } from "./constants";
8
8
  import { StyledTypography } from "./entity.styles";
9
- export const Entity = ({ class: classData, columnDefs, spacing, }) => {
10
- const table = useTable(classData.attributes, columnDefs);
9
+ export const Entity = ({ class: cls, columnDefs, spacing, }) => {
10
+ const table = useTable(cls.attributes, columnDefs);
11
11
  return (React.createElement(Grid, { ...GRID_PROPS, rowGap: 4 },
12
12
  React.createElement(Grid, { ...GRID_PROPS, rowGap: 1 },
13
- React.createElement(StyledTypography, { component: "h3", id: classData.name, variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_HEADING_SMALL, ...spacing },
14
- classData.title,
13
+ React.createElement(StyledTypography, { component: "h3", id: cls.name, variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_HEADING_SMALL, ...spacing },
14
+ cls.title,
15
15
  " ",
16
- React.createElement(AnchorLink, { anchorLink: classData.name })),
17
- React.createElement(Typography, { color: TYPOGRAPHY_PROPS.COLOR.INK_LIGHT, component: "div", variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_400_2_LINES }, classData.description)),
16
+ React.createElement(AnchorLink, { anchorLink: cls.name })),
17
+ React.createElement(Typography, { color: TYPOGRAPHY_PROPS.COLOR.INK_LIGHT, component: "div", variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_400_2_LINES }, cls.description)),
18
18
  React.createElement(Table, { table: table })));
19
19
  };
@@ -1,8 +1,8 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import { Attribute, AttributeValueTypes, Class } from "../../../../common/entities";
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
- export interface EntityProps {
5
- class: Class;
6
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
4
+ export interface EntityProps<T extends RowData = Attribute> {
5
+ class: Class<T>;
6
+ columnDefs: ColumnDef<T, T[keyof T]>[];
7
7
  spacing?: LayoutSpacing;
8
8
  }
@@ -1,8 +1,9 @@
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
  * Returns outline items from classes.
5
6
  * @param classes - Class entities.
6
7
  * @returns Outline items.
7
8
  */
8
- export declare function buildClassesOutline(classes: Class[]): OutlineItem[];
9
+ export declare function buildClassesOutline<T extends RowData = Attribute>(classes: Class<T>[]): OutlineItem[];
@@ -1,3 +1,3 @@
1
- import { ColumnDef, Table } from "@tanstack/react-table";
2
- import { Attribute, AttributeValueTypes } from "../../../../common/entities";
3
- export declare const useTable: (data: Attribute[], columnDefs: ColumnDef<Attribute, AttributeValueTypes>[]) => Table<Attribute>;
1
+ import { ColumnDef, RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
+ export declare const useTable: <T extends RowData = Attribute>(data: T[], columnDefs: ColumnDef<T, T[keyof T]>[]) => Table<T>;
@@ -1,7 +1,9 @@
1
- import { useReactTable } from "@tanstack/react-table";
1
+ import { useReactTable, } from "@tanstack/react-table";
2
2
  import { useTableOptions } from "./options/hook";
3
3
  export const useTable = (data, columnDefs) => {
4
+ // Table options.
4
5
  const tableOptions = useTableOptions();
6
+ // Table instance.
5
7
  return useReactTable({
6
8
  ...tableOptions,
7
9
  columns: columnDefs,
@@ -1,3 +1,2 @@
1
- import { CoreOptions } from "@tanstack/react-table";
2
- import { Attribute } from "../../../../../../common/entities";
3
- export declare const CORE_OPTIONS: Pick<CoreOptions<Attribute>, "_features" | "getCoreRowModel">;
1
+ import { CoreOptions, RowData } from "@tanstack/react-table";
2
+ export declare const CORE_OPTIONS: Pick<CoreOptions<RowData>, "_features" | "getCoreRowModel">;
@@ -1,3 +1,3 @@
1
- import { TableOptions } from "@tanstack/react-table";
1
+ import { RowData, TableOptions } from "@tanstack/react-table";
2
2
  import { Attribute } from "../../../../../common/entities";
3
- export declare const useTableOptions: () => Omit<TableOptions<Attribute>, "columns" | "data">;
3
+ export declare const useTableOptions: <T extends RowData = Attribute>() => Omit<TableOptions<T>, "columns" | "data">;
@@ -1,3 +1,2 @@
1
- import { SortingOptions } from "@tanstack/react-table";
2
- import { Attribute } from "../../../../../../common/entities";
3
- export declare const SORTING_OPTIONS: Pick<SortingOptions<Attribute>, "enableSorting">;
1
+ import { RowData, SortingOptions } from "@tanstack/react-table";
2
+ export declare const SORTING_OPTIONS: Pick<SortingOptions<RowData>, "enableSorting">;
@@ -1,2 +1,3 @@
1
+ import { RowData } from "@tanstack/react-table";
1
2
  import { TableProps } from "./types";
2
- export declare const Table: ({ table }: TableProps) => JSX.Element;
3
+ export declare const Table: <T extends RowData>({ table, }: TableProps<T>) => JSX.Element;
@@ -7,7 +7,7 @@ import { GridTable } from "../../../Table/table.styles";
7
7
  import { getColumnTrackSizing } from "../../../TableCreator/options/columnTrackSizing/utils";
8
8
  import { GridPaper } from "../../../common/Paper/paper.styles";
9
9
  import { StyledRoundedPaper } from "./table.styles";
10
- export const Table = ({ table }) => {
10
+ export const Table = ({ table, }) => {
11
11
  return (React.createElement(StyledRoundedPaper, { variant: "table" },
12
12
  React.createElement(GridPaper, null,
13
13
  React.createElement(TableContainer, null,
@@ -1,5 +1,4 @@
1
- import { Table } from "@tanstack/react-table";
2
- import { Attribute } from "../../../../common/entities";
3
- export interface TableProps {
4
- table: Table<Attribute>;
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ export interface TableProps<T extends RowData> {
3
+ table: Table<T>;
5
4
  }
@@ -1,2 +1,4 @@
1
+ import { RowData } from "@tanstack/react-table";
2
+ import { Attribute } from "../../common/entities";
1
3
  import { DataDictionaryProps } from "./types";
2
- export declare const DataDictionary: ({ className, EntitiesLayout, Outline, OutlineLayout, Title, TitleLayout, }: DataDictionaryProps) => JSX.Element;
4
+ export declare const DataDictionary: <T extends RowData = Attribute>({ className, EntitiesLayout, Outline, OutlineLayout, Title, TitleLayout, }: DataDictionaryProps) => JSX.Element;
@@ -1,2 +1,4 @@
1
+ import { RowData } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
1
3
  import { UseDataDictionary } from "./types";
2
- export declare const useDataDictionary: () => UseDataDictionary;
4
+ export declare const useDataDictionary: <T extends RowData = Attribute>() => UseDataDictionary<T>;
@@ -1,6 +1,6 @@
1
- import { ColumnDef } from "@tanstack/react-table";
2
- import { Attribute, AttributeValueTypes, Class } from "../../../../common/entities";
3
- export interface UseDataDictionary {
4
- classes: Class[];
5
- columnDefs: ColumnDef<Attribute, AttributeValueTypes>[];
1
+ import { ColumnDef, RowData } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
3
+ export interface UseDataDictionary<T extends RowData = Attribute> {
4
+ classes: Class<T>[];
5
+ columnDefs: ColumnDef<T, T[keyof T]>[];
6
6
  }
@@ -0,0 +1,19 @@
1
+ import { AnchorHTMLAttributes, ClassAttributes } from "react";
2
+ import { BaseComponentProps } from "../../../types";
3
+ /**
4
+ * rehype-sanitize's default schema allows only a limited set of attributes on <a> elements:
5
+ * - aria-*
6
+ * - className
7
+ * - data-footnote-backref
8
+ * - data-footnote-ref
9
+ * - href
10
+ *
11
+ * By default, attributes such as:
12
+ * - download
13
+ * - rel
14
+ * - target
15
+ * are not permitted and will be stripped from anchor tags during sanitization.
16
+ *
17
+ * Note: This component currently does not support these excluded attributes.
18
+ */
19
+ export declare const Anchor: (props: BaseComponentProps & ClassAttributes<HTMLAnchorElement> & AnchorHTMLAttributes<HTMLAnchorElement>) => JSX.Element;
@@ -0,0 +1,21 @@
1
+ import React from "react";
2
+ import { Link } from "../../../Links/components/Link/link";
3
+ /**
4
+ * rehype-sanitize's default schema allows only a limited set of attributes on <a> elements:
5
+ * - aria-*
6
+ * - className
7
+ * - data-footnote-backref
8
+ * - data-footnote-ref
9
+ * - href
10
+ *
11
+ * By default, attributes such as:
12
+ * - download
13
+ * - rel
14
+ * - target
15
+ * are not permitted and will be stripped from anchor tags during sanitization.
16
+ *
17
+ * Note: This component currently does not support these excluded attributes.
18
+ */
19
+ export const Anchor = (props) => {
20
+ return (React.createElement(Link, { className: props.className, label: props.children, url: props.href || "" }));
21
+ };
@@ -0,0 +1,3 @@
1
+ import { BaseComponentProps } from "components/types";
2
+ import { ClassAttributes, TableHTMLAttributes } from "react";
3
+ export declare const Table: (props: BaseComponentProps & ClassAttributes<HTMLTableElement> & TableHTMLAttributes<HTMLTableElement>) => JSX.Element;
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import { StyledTable } from "./table.styles";
3
+ export const Table = (props) => {
4
+ return (React.createElement(StyledTable, { className: props.className }, props.children));
5
+ };
@@ -0,0 +1,4 @@
1
+ export declare const StyledTable: import("@emotion/styled").StyledComponent<{
2
+ theme?: import("@emotion/react").Theme;
3
+ as?: import("react").ElementType;
4
+ }, import("react").DetailedHTMLProps<import("react").TableHTMLAttributes<HTMLTableElement>, HTMLTableElement>, {}>;
@@ -0,0 +1,40 @@
1
+ import styled from "@emotion/styled";
2
+ import { PALETTE } from "../../../../styles/common/constants/palette";
3
+ import { textBody500 } from "../../../../styles/common/mixins/fonts";
4
+ export const StyledTable = styled("table") `
5
+ border-collapse: collapse;
6
+ margin: 16px 0;
7
+ table-layout: fixed;
8
+ width: 100%;
9
+
10
+ thead {
11
+ all: unset;
12
+ display: table-header-group;
13
+ }
14
+
15
+ tbody {
16
+ all: unset;
17
+ display: table-row-group;
18
+ }
19
+
20
+ tr {
21
+ all: unset;
22
+ display: table-row;
23
+ }
24
+
25
+ td,
26
+ th {
27
+ display: table-cell;
28
+ padding: 2px 4px;
29
+ }
30
+
31
+ th {
32
+ ${textBody500}
33
+ border-bottom: 1px solid ${PALETTE.SMOKE_MAIN};
34
+ }
35
+
36
+ td {
37
+ font: inherit;
38
+ overflow-wrap: break-word;
39
+ }
40
+ `;
@@ -0,0 +1,2 @@
1
+ import { Components } from "rehype-react";
2
+ export declare const COMPONENTS: Partial<Components>;
@@ -0,0 +1,6 @@
1
+ import { Anchor } from "./components/Anchor/anchor";
2
+ import { Table } from "./components/Table/table";
3
+ export const COMPONENTS = {
4
+ a: Anchor,
5
+ table: Table,
6
+ };
@@ -0,0 +1,2 @@
1
+ import { MarkdownRendererProps } from "./types";
2
+ export declare const MarkdownRenderer: ({ className, components, value, }: MarkdownRendererProps) => JSX.Element;
@@ -0,0 +1,45 @@
1
+ import { Typography } from "@mui/material";
2
+ import React, { useEffect, useState } from "react";
3
+ import * as production from "react/jsx-runtime";
4
+ import rehypeRaw from "rehype-raw";
5
+ import rehypeReact from "rehype-react";
6
+ import rehypeSanitize, { defaultSchema } from "rehype-sanitize";
7
+ import remarkGfm from "remark-gfm";
8
+ import remarkParse from "remark-parse";
9
+ import remarkRehype from "remark-rehype";
10
+ import { unified } from "unified";
11
+ import { TYPOGRAPHY_PROPS } from "../../styles/common/mui/typography";
12
+ import { COMPONENTS } from "./constants";
13
+ import { StyledContainer } from "./markdownRenderer.styles";
14
+ export const MarkdownRenderer = ({ className, components = COMPONENTS, value, }) => {
15
+ const [element, setElement] = useState(null);
16
+ const [error, setError] = useState(null);
17
+ const [componentOptions] = useState(components);
18
+ useEffect(() => {
19
+ let cancelled = false;
20
+ setError(null);
21
+ const processor = unified()
22
+ .use(remarkParse)
23
+ .use(remarkGfm)
24
+ .use(remarkRehype, { allowDangerousHtml: true })
25
+ .use(rehypeRaw)
26
+ .use(rehypeSanitize, defaultSchema)
27
+ .use(rehypeReact, { ...production, components: componentOptions });
28
+ processor
29
+ .process(value)
30
+ .then((file) => {
31
+ if (!cancelled)
32
+ setElement(file?.result);
33
+ })
34
+ .catch((err) => {
35
+ if (!cancelled)
36
+ setError(err.message);
37
+ });
38
+ return () => {
39
+ cancelled = true;
40
+ };
41
+ }, [componentOptions, value]);
42
+ if (error)
43
+ return (React.createElement(Typography, { color: TYPOGRAPHY_PROPS.COLOR.ERROR, variant: TYPOGRAPHY_PROPS.VARIANT.TEXT_BODY_SMALL_400 }, error));
44
+ return React.createElement(StyledContainer, { className: className }, element);
45
+ };
@@ -0,0 +1,4 @@
1
+ export declare const StyledContainer: import("@emotion/styled").StyledComponent<{
2
+ theme?: import("@emotion/react").Theme;
3
+ as?: import("react").ElementType;
4
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
@@ -0,0 +1,13 @@
1
+ import styled from "@emotion/styled";
2
+ // See https://github.com/emotion-js/emotion/issues/1105.
3
+ // See https://github.com/emotion-js/emotion/releases/tag/%40emotion%2Fcache%4011.10.2.
4
+ const ignoreSsrWarning = "/* emotion-disable-server-rendering-unsafe-selector-warning-please-do-not-use-this-the-warning-exists-for-a-reason */";
5
+ export const StyledContainer = styled("div") `
6
+ > *:first-child:not(style)${ignoreSsrWarning} {
7
+ margin-top: 0;
8
+ }
9
+
10
+ > *:last-child:not(style)${ignoreSsrWarning} {
11
+ margin-bottom: 0;
12
+ }
13
+ `;
@@ -0,0 +1,6 @@
1
+ import { Components } from "rehype-react";
2
+ import { BaseComponentProps } from "../types";
3
+ export interface MarkdownRendererProps extends BaseComponentProps {
4
+ components?: Partial<Components>;
5
+ value: string;
6
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,3 +1,4 @@
1
1
  import { ChipProps } from "@mui/material";
2
2
  import { CellContext, RowData } from "@tanstack/react-table";
3
- export declare const ChipCell: <T extends RowData, TValue extends ChipProps = ChipProps>({ getValue, }: CellContext<T, TValue>) => JSX.Element | null;
3
+ import { BaseComponentProps } from "../../../../../types";
4
+ export declare const ChipCell: <T extends RowData, TValue extends ChipProps = ChipProps>({ className, getValue, }: BaseComponentProps & CellContext<T, TValue>) => JSX.Element | null;
@@ -1,8 +1,8 @@
1
1
  import { Chip } from "@mui/material";
2
2
  import React from "react";
3
- export const ChipCell = ({ getValue, }) => {
3
+ export const ChipCell = ({ className, getValue, }) => {
4
4
  const props = getValue();
5
5
  if (!props)
6
6
  return null;
7
- return React.createElement(Chip, { ...props });
7
+ return React.createElement(Chip, { className: className, ...props });
8
8
  };
@@ -1,4 +1,4 @@
1
1
  import { LinkProps } from "@mui/material";
2
2
  import { CellContext, RowData } from "@tanstack/react-table";
3
3
  import { BaseComponentProps } from "components/types";
4
- export declare const LinkCell: <T extends RowData, TValue extends LinkProps = LinkProps>({ getValue, }: BaseComponentProps & CellContext<T, TValue>) => JSX.Element | null;
4
+ export declare const LinkCell: <T extends RowData, TValue extends LinkProps = LinkProps>({ className, getValue, }: BaseComponentProps & CellContext<T, TValue>) => JSX.Element | null;
@@ -4,11 +4,11 @@ import { isValidUrl } from "../../../../../../common/utils";
4
4
  import { TYPOGRAPHY_PROPS } from "../../../../../../styles/common/mui/typography";
5
5
  import { isClientSideNavigation } from "../../../../../Links/common/utils";
6
6
  import { getComponent, getRelAttribute, getTargetAttribute } from "./utils";
7
- export const LinkCell = ({ getValue, }) => {
7
+ export const LinkCell = ({ className, getValue, }) => {
8
8
  const props = getValue();
9
9
  if (!props)
10
10
  return null;
11
- const { children, className, color, href = "", rel, target, underline, ...linkProps } = props;
11
+ const { children, color, href = "", rel, target, underline, ...linkProps } = props;
12
12
  // Determine if the href should use client-side navigation.
13
13
  const isClientSide = isClientSideNavigation(href);
14
14
  // Determine if the href is valid.
@@ -0,0 +1,4 @@
1
+ import { CellContext, RowData } from "@tanstack/react-table";
2
+ import { BaseComponentProps } from "components/types";
3
+ import { MarkdownCellProps } from "./types";
4
+ export declare const MarkdownCell: <T extends RowData, TValue extends MarkdownCellProps = MarkdownCellProps>({ className, column, getValue, }: BaseComponentProps & CellContext<T, TValue>) => JSX.Element | null;
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { COMPONENTS } from "../../../../../MarkdownRenderer/constants";
3
+ import { StyledMarkdownRenderer } from "./markdownCell.styles";
4
+ export const MarkdownCell = ({ className, column, getValue, }) => {
5
+ const props = getValue();
6
+ if (!props)
7
+ return null;
8
+ const { values } = props;
9
+ const columnDef = column?.columnDef;
10
+ const columnMeta = columnDef?.meta;
11
+ const components = columnMeta?.components;
12
+ return (React.createElement(StyledMarkdownRenderer, { className: className, components: { ...COMPONENTS, ...components }, value: values }));
13
+ };
@@ -0,0 +1,3 @@
1
+ export declare const StyledMarkdownRenderer: import("@emotion/styled").StyledComponent<import("../../../../../MarkdownRenderer/types").MarkdownRendererProps & {
2
+ theme?: import("@emotion/react").Theme;
3
+ }, {}, {}>;
@@ -0,0 +1,30 @@
1
+ import styled from "@emotion/styled";
2
+ import { PALETTE } from "../../../../../../styles/common/constants/palette";
3
+ import { MarkdownRenderer } from "../../../../../MarkdownRenderer/markdownRenderer";
4
+ export const StyledMarkdownRenderer = styled(MarkdownRenderer) `
5
+ align-self: flex-start;
6
+
7
+ code {
8
+ all: unset;
9
+ font: inherit;
10
+ font-family: Roboto Mono, monospace;
11
+ }
12
+
13
+ h2,
14
+ h3,
15
+ h4,
16
+ h5,
17
+ h6 {
18
+ margin: 8px 0;
19
+ }
20
+
21
+ hr {
22
+ border: none;
23
+ border-bottom: 1px solid ${PALETTE.SMOKE_MAIN};
24
+ margin: 16px 0;
25
+ }
26
+
27
+ p {
28
+ font: inherit;
29
+ }
30
+ `;
@@ -0,0 +1,4 @@
1
+ import { ComponentProps } from "react";
2
+ import { MarkdownCell } from "../markdownCell";
3
+ export declare const DEFAULT_ARGS: Partial<ComponentProps<typeof MarkdownCell>>;
4
+ export declare const WITH_HTML_ARGS: Partial<ComponentProps<typeof MarkdownCell>>;
@@ -0,0 +1,10 @@
1
+ export const DEFAULT_ARGS = {
2
+ getValue: (() => ({
3
+ values: '| 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`. |',
4
+ })),
5
+ };
6
+ export const WITH_HTML_ARGS = {
7
+ getValue: (() => ({
8
+ values: "Hello <br />World <a href='https://www.example.com'>example link</a>",
9
+ })),
10
+ };
@@ -0,0 +1,5 @@
1
+ import { Anchor } from "../../../../../../MarkdownRenderer/components/Anchor/anchor";
2
+ /**
3
+ * Styled anchor component for testing purposes.
4
+ */
5
+ export declare const STYLED_ANCHOR: typeof Anchor;
@@ -0,0 +1,9 @@
1
+ import styled from "@emotion/styled";
2
+ import { Anchor } from "../../../../../../MarkdownRenderer/components/Anchor/anchor";
3
+ /**
4
+ * Styled anchor component for testing purposes.
5
+ */
6
+ export const STYLED_ANCHOR = styled(Anchor) `
7
+ background-color: green;
8
+ color: white;
9
+ `;