@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,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;
@@ -0,0 +1,37 @@
1
+ import { Box } from "@mui/material";
2
+ import { Meta, StoryObj } from "@storybook/react";
3
+ import React from "react";
4
+ import { PALETTE } from "../../../../../../../styles/common/constants/palette";
5
+ import { MarkdownCell } from "../markdownCell";
6
+ import { DEFAULT_ARGS, WITH_HTML_ARGS } from "./args";
7
+
8
+ const meta: Meta<typeof MarkdownCell> = {
9
+ component: MarkdownCell,
10
+ decorators: [
11
+ (Story): JSX.Element => (
12
+ <Box
13
+ sx={{
14
+ backgroundColor: PALETTE.COMMON_WHITE,
15
+ fontSize: "14px",
16
+ lineHeight: "20px",
17
+ padding: 3,
18
+ width: 480,
19
+ }}
20
+ >
21
+ <Story />
22
+ </Box>
23
+ ),
24
+ ],
25
+ };
26
+
27
+ export default meta;
28
+
29
+ type Story = StoryObj<typeof meta>;
30
+
31
+ export const Default: Story = {
32
+ args: DEFAULT_ARGS,
33
+ };
34
+
35
+ export const WithHtml: Story = {
36
+ args: WITH_HTML_ARGS,
37
+ };
@@ -0,0 +1,4 @@
1
+ import { CellContext, RowData } from "@tanstack/react-table";
2
+ import { MarkdownCellProps } from "../types";
3
+
4
+ export type GetValue = CellContext<RowData, MarkdownCellProps>["getValue"];
@@ -0,0 +1,3 @@
1
+ export type MarkdownCellProps = {
2
+ values: string;
3
+ };
@@ -6,6 +6,7 @@ type TypographyPropsOptions = {
6
6
  };
7
7
 
8
8
  const COLOR: Record<string, TypographyOwnProps["color"]> = {
9
+ ERROR: "error",
9
10
  INHERIT: "inherit",
10
11
  INK_LIGHT: "ink.light",
11
12
  INK_MAIN: "ink.main",
@@ -0,0 +1,53 @@
1
+ import { matchers } from "@emotion/jest";
2
+ import { composeStories } from "@storybook/react";
3
+ import { Column } from "@tanstack/react-table";
4
+ import "@testing-library/jest-dom";
5
+ import { render, screen } from "@testing-library/react";
6
+ import React from "react";
7
+ import {
8
+ ANCHOR_TARGET,
9
+ REL_ATTRIBUTE,
10
+ } from "../src/components/Links/common/entities";
11
+ import { STYLED_ANCHOR } from "../src/components/Table/components/TableCell/components/MarkdownCell/stories/constants";
12
+ import * as stories from "../src/components/Table/components/TableCell/components/MarkdownCell/stories/markdownCell.stories";
13
+ import { MarkdownCellProps } from "../src/components/Table/components/TableCell/components/MarkdownCell/types";
14
+
15
+ expect.extend(matchers);
16
+
17
+ const { Default, WithHtml } = composeStories(stories);
18
+
19
+ describe("MarkdownCell", () => {
20
+ it("renders the markdown content", async () => {
21
+ render(<Default />);
22
+ expect(await screen.findByText("UBERON:0000955")).toBeInTheDocument();
23
+ });
24
+
25
+ it("renders HTML and anchor elements", async () => {
26
+ render(<WithHtml />);
27
+ const anchorEl = await screen.findByText("example link");
28
+ expect(anchorEl).toBeInTheDocument();
29
+ expect(anchorEl.getAttribute("href")).toBe("https://www.example.com");
30
+ expect(anchorEl.getAttribute("target")).toBe(ANCHOR_TARGET.BLANK);
31
+ expect(anchorEl.getAttribute("rel")).toBe(
32
+ REL_ATTRIBUTE.NO_OPENER_NO_REFERRER
33
+ );
34
+ expect(anchorEl).toHaveClass("MuiLink-root");
35
+ });
36
+
37
+ it("applies the correct className and component", async () => {
38
+ render(
39
+ <WithHtml
40
+ className="css-pygqsj"
41
+ column={
42
+ {
43
+ columnDef: { meta: { components: { a: STYLED_ANCHOR } } },
44
+ } as unknown as Column<unknown, MarkdownCellProps>
45
+ }
46
+ />
47
+ );
48
+ const anchorEl = await screen.findByText("example link");
49
+ expect(anchorEl).toHaveStyleRule("background-color", "green");
50
+ expect(anchorEl).toHaveStyleRule("color", "white");
51
+ expect(anchorEl.closest(".css-pygqsj")).toBeInTheDocument();
52
+ });
53
+ });
@@ -19,6 +19,7 @@ import type {} from "@mui/material/Toolbar";
19
19
  import type {} from "@mui/material/Typography";
20
20
  import type {} from "@tanstack/react-table";
21
21
  import { RowData } from "@tanstack/react-table";
22
+ import { Components } from "rehype-react";
22
23
  import { DataLayer } from "../src/common/analytics/entities";
23
24
  import { DataDictionaryAnnotation } from "../src/common/entities";
24
25
  import {
@@ -230,6 +231,7 @@ declare module "@tanstack/react-table" {
230
231
  align?: TableCellProps["align"];
231
232
  annotation?: DataDictionaryAnnotation;
232
233
  columnPinned?: boolean;
234
+ components?: Partial<Components>; // For `MarkdownRendererCell` component.
233
235
  header?: string;
234
236
  width?: GridTrackSize;
235
237
  }