@databiosphere/findable-ui 33.0.0 → 34.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 (180) hide show
  1. package/.release-please-manifest.json +1 -1
  2. package/CHANGELOG.md +11 -0
  3. package/jest.config.js +4 -0
  4. package/lib/common/entities.d.ts +3 -1
  5. package/lib/components/DataDictionary/components/Entities/entities.d.ts +1 -1
  6. package/lib/components/DataDictionary/components/Entities/entities.js +3 -2
  7. package/lib/components/DataDictionary/components/Entities/types.d.ts +3 -4
  8. package/lib/components/DataDictionary/components/Entity/entity.d.ts +1 -1
  9. package/lib/components/DataDictionary/components/Entity/entity.js +12 -6
  10. package/lib/components/DataDictionary/components/Entity/entity.styles.js +7 -1
  11. package/lib/components/DataDictionary/components/Entity/types.d.ts +4 -4
  12. package/lib/components/DataDictionary/components/Entity/utils.d.ts +9 -0
  13. package/lib/components/DataDictionary/components/Entity/utils.js +18 -0
  14. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.d.ts +4 -0
  15. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.js +9 -0
  16. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/types.d.ts +5 -0
  17. package/lib/components/DataDictionary/components/Filters/components/ColumnFilters/types.js +1 -0
  18. package/lib/components/DataDictionary/components/Filters/filters.d.ts +4 -0
  19. package/lib/components/DataDictionary/components/Filters/filters.js +7 -0
  20. package/lib/components/DataDictionary/components/Filters/filters.styles.d.ts +7 -0
  21. package/lib/components/DataDictionary/components/Filters/filters.styles.js +13 -0
  22. package/lib/components/DataDictionary/components/Filters/stories/constants.d.ts +4 -0
  23. package/lib/components/DataDictionary/components/Filters/stories/constants.js +25 -0
  24. package/lib/components/DataDictionary/components/Filters/stories/filters.stories.d.ts +6 -0
  25. package/lib/components/DataDictionary/components/Filters/stories/filters.stories.js +31 -0
  26. package/lib/components/DataDictionary/components/Filters/stories/hook.d.ts +5 -0
  27. package/lib/components/DataDictionary/components/Filters/stories/hook.js +5 -0
  28. package/lib/components/DataDictionary/components/Filters/stories/types.d.ts +4 -0
  29. package/lib/components/DataDictionary/components/Filters/stories/types.js +1 -0
  30. package/lib/components/DataDictionary/components/Filters/types.d.ts +5 -0
  31. package/lib/components/DataDictionary/components/Filters/types.js +1 -0
  32. package/lib/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.js +3 -1
  33. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.d.ts +2 -0
  34. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.js +5 -0
  35. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.d.ts +5 -0
  36. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.js +24 -0
  37. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/types.d.ts +5 -0
  38. package/lib/components/DataDictionary/components/Layout/components/FiltersLayout/types.js +1 -0
  39. package/lib/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.js +1 -1
  40. package/lib/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.js +1 -0
  41. package/lib/components/DataDictionary/components/Layout/constants.d.ts +4 -0
  42. package/lib/components/DataDictionary/components/Layout/constants.js +4 -0
  43. package/lib/components/DataDictionary/components/Outline/utils.d.ts +5 -5
  44. package/lib/components/DataDictionary/components/Outline/utils.js +23 -6
  45. package/lib/components/DataDictionary/components/Table/hook.d.ts +3 -3
  46. package/lib/components/DataDictionary/components/Table/hook.js +11 -3
  47. package/lib/components/DataDictionary/components/Table/options/columnFilters/constants.d.ts +2 -0
  48. package/lib/components/DataDictionary/components/Table/options/columnFilters/constants.js +8 -0
  49. package/lib/components/DataDictionary/components/Table/options/columnFilters/hook.d.ts +6 -0
  50. package/lib/components/DataDictionary/components/Table/options/columnFilters/hook.js +14 -0
  51. package/lib/components/DataDictionary/components/Table/options/expanded/constants.d.ts +2 -0
  52. package/lib/components/DataDictionary/components/Table/options/expanded/constants.js +5 -0
  53. package/lib/components/DataDictionary/components/Table/options/faceted/constants.d.ts +2 -0
  54. package/lib/components/DataDictionary/components/Table/options/faceted/constants.js +6 -0
  55. package/lib/components/DataDictionary/components/Table/options/grouping/constants.d.ts +2 -0
  56. package/lib/components/DataDictionary/components/Table/options/grouping/constants.js +5 -0
  57. package/lib/components/DataDictionary/components/Table/options/hook.d.ts +1 -1
  58. package/lib/components/DataDictionary/components/Table/options/hook.js +17 -0
  59. package/lib/components/DataDictionary/components/Table/options/visibility/constants.d.ts +2 -0
  60. package/lib/components/DataDictionary/components/Table/options/visibility/constants.js +3 -0
  61. package/lib/components/DataDictionary/components/Table/table.d.ts +1 -1
  62. package/lib/components/DataDictionary/components/Table/table.js +2 -2
  63. package/lib/components/DataDictionary/components/Table/types.d.ts +4 -1
  64. package/lib/components/DataDictionary/components/Table/utils.d.ts +18 -0
  65. package/lib/components/DataDictionary/components/Table/utils.js +27 -0
  66. package/lib/components/DataDictionary/dataDictionary.d.ts +1 -1
  67. package/lib/components/DataDictionary/dataDictionary.js +8 -6
  68. package/lib/components/DataDictionary/hooks/UseDataDictionary/hook.js +16 -5
  69. package/lib/components/DataDictionary/hooks/UseDataDictionary/types.d.ts +5 -4
  70. package/lib/components/DataDictionary/types.d.ts +1 -0
  71. package/lib/components/Detail/components/Table/components/TableBody/tableBody.d.ts +8 -2
  72. package/lib/components/Detail/components/Table/components/TableBody/tableBody.js +2 -2
  73. package/lib/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.d.ts +8 -2
  74. package/lib/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.js +2 -2
  75. package/lib/components/Detail/components/Table/components/TableRows/tableRows.d.ts +8 -2
  76. package/lib/components/Detail/components/Table/components/TableRows/tableRows.js +2 -2
  77. package/lib/components/Filter/components/FilterLabel/filterLabel.styles.d.ts +1 -1
  78. package/lib/components/Filter/components/FilterList/filterList.styles.d.ts +2 -0
  79. package/lib/components/Filter/components/FilterList/filterList.styles.js +28 -15
  80. package/lib/components/Filter/components/SearchAllFiltersSearch/searchAllFiltersSearch.styles.d.ts +1 -1
  81. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/Button/button.styles.d.ts +1 -1
  82. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/Button/button.styles.d.ts +1 -1
  83. package/lib/components/Layout/components/Outline/components/ContentsTab/contentsTab.styles.d.ts +1 -1
  84. package/lib/components/Layout/components/Outline/outline.styles.d.ts +1 -1
  85. package/lib/components/Login/components/Button/button.styles.d.ts +1 -1
  86. package/lib/components/Table/common/utils.d.ts +6 -0
  87. package/lib/components/Table/common/utils.js +14 -0
  88. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.d.ts +7 -0
  89. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.js +33 -0
  90. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.d.ts +3 -0
  91. package/lib/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.js +19 -0
  92. package/lib/components/Table/components/TableFeatures/ColumnFilter/constants.d.ts +2 -0
  93. package/lib/components/Table/components/TableFeatures/ColumnFilter/constants.js +14 -0
  94. package/lib/components/Table/components/TableFeatures/ColumnFilter/types.d.ts +7 -0
  95. package/lib/components/Table/components/TableFeatures/ColumnFilter/types.js +1 -0
  96. package/lib/components/Table/components/TableFeatures/ColumnFilter/utils.d.ts +6 -0
  97. package/lib/components/Table/components/TableFeatures/ColumnFilter/utils.js +23 -0
  98. package/lib/components/Table/featureOptions/facetedColumn/utils.d.ts +6 -0
  99. package/lib/components/Table/featureOptions/facetedColumn/utils.js +9 -0
  100. package/lib/components/common/ButtonGroup/constants.d.ts +2 -0
  101. package/lib/components/common/ButtonGroup/constants.js +11 -0
  102. package/lib/components/common/Tabs/tabs.styles.d.ts +1 -1
  103. package/lib/mocks/@storybook/addon-actions.d.ts +9 -0
  104. package/lib/mocks/@storybook/addon-actions.js +9 -0
  105. package/lib/styles/common/mui/buttonGroup.d.ts +13 -0
  106. package/lib/styles/common/mui/buttonGroup.js +34 -0
  107. package/lib/styles/common/mui/typography.js +2 -0
  108. package/lib/tests/mui/constants.d.ts +1 -0
  109. package/lib/tests/mui/constants.js +1 -0
  110. package/lib/tests/utils.d.ts +6 -0
  111. package/lib/tests/utils.js +8 -0
  112. package/lib/theme/common/components.d.ts +0 -6
  113. package/lib/theme/common/components.js +17 -31
  114. package/lib/theme/components/index.d.ts +1 -0
  115. package/lib/theme/components/index.js +1 -0
  116. package/lib/theme/components/muiButtonGroup.d.ts +2 -0
  117. package/lib/theme/components/muiButtonGroup.js +76 -0
  118. package/lib/theme/theme.js +1 -1
  119. package/package.json +1 -1
  120. package/src/common/entities.ts +3 -1
  121. package/src/components/DataDictionary/components/Entities/entities.tsx +5 -9
  122. package/src/components/DataDictionary/components/Entities/types.ts +3 -4
  123. package/src/components/DataDictionary/components/Entity/entity.styles.ts +9 -1
  124. package/src/components/DataDictionary/components/Entity/entity.tsx +18 -8
  125. package/src/components/DataDictionary/components/Entity/types.ts +4 -4
  126. package/src/components/DataDictionary/components/Entity/utils.ts +25 -0
  127. package/src/components/DataDictionary/components/Filters/components/ColumnFilters/columnFilters.tsx +21 -0
  128. package/src/components/DataDictionary/components/Filters/components/ColumnFilters/types.ts +6 -0
  129. package/src/components/DataDictionary/components/Filters/filters.styles.ts +14 -0
  130. package/src/components/DataDictionary/components/Filters/filters.tsx +16 -0
  131. package/src/components/DataDictionary/components/Filters/stories/constants.ts +31 -0
  132. package/src/components/DataDictionary/components/Filters/stories/filters.stories.tsx +42 -0
  133. package/src/components/DataDictionary/components/Filters/stories/hook.ts +9 -0
  134. package/src/components/DataDictionary/components/Filters/stories/types.ts +3 -0
  135. package/src/components/DataDictionary/components/Filters/types.ts +6 -0
  136. package/src/components/DataDictionary/components/Layout/components/EntitiesLayout/entitiesLayout.styles.ts +4 -1
  137. package/src/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.styles.ts +27 -0
  138. package/src/components/DataDictionary/components/Layout/components/FiltersLayout/filtersLayout.tsx +10 -0
  139. package/src/components/DataDictionary/components/Layout/components/FiltersLayout/types.ts +6 -0
  140. package/src/components/DataDictionary/components/Layout/components/OutlineLayout/outlineLayout.styles.ts +1 -1
  141. package/src/components/DataDictionary/components/Layout/components/TitleLayout/titleLayout.styles.ts +1 -0
  142. package/src/components/DataDictionary/components/Layout/constants.ts +4 -0
  143. package/src/components/DataDictionary/components/Outline/utils.ts +35 -13
  144. package/src/components/DataDictionary/components/Table/hook.ts +17 -5
  145. package/src/components/DataDictionary/components/Table/options/columnFilters/constants.ts +16 -0
  146. package/src/components/DataDictionary/components/Table/options/columnFilters/hook.ts +32 -0
  147. package/src/components/DataDictionary/components/Table/options/expanded/constants.ts +13 -0
  148. package/src/components/DataDictionary/components/Table/options/faceted/constants.ts +14 -0
  149. package/src/components/DataDictionary/components/Table/options/grouping/constants.ts +9 -0
  150. package/src/components/DataDictionary/components/Table/options/hook.ts +26 -3
  151. package/src/components/DataDictionary/components/Table/options/visibility/constants.ts +5 -0
  152. package/src/components/DataDictionary/components/Table/table.tsx +2 -0
  153. package/src/components/DataDictionary/components/Table/types.ts +8 -1
  154. package/src/components/DataDictionary/components/Table/utils.ts +40 -0
  155. package/src/components/DataDictionary/dataDictionary.tsx +9 -5
  156. package/src/components/DataDictionary/hooks/UseDataDictionary/hook.ts +19 -5
  157. package/src/components/DataDictionary/hooks/UseDataDictionary/types.ts +5 -4
  158. package/src/components/DataDictionary/types.ts +1 -0
  159. package/src/components/Detail/components/Table/components/TableBody/tableBody.tsx +14 -3
  160. package/src/components/Detail/components/Table/components/TableRows/components/CollapsableRows/collapsableRows.tsx +9 -2
  161. package/src/components/Detail/components/Table/components/TableRows/tableRows.tsx +9 -2
  162. package/src/components/Filter/components/FilterList/filterList.styles.ts +34 -15
  163. package/src/components/Table/common/utils.ts +16 -0
  164. package/src/components/Table/components/TableFeatures/ColumnFilter/columnFilter.styles.ts +23 -0
  165. package/src/components/Table/components/TableFeatures/ColumnFilter/columnFilter.tsx +98 -0
  166. package/src/components/Table/components/TableFeatures/ColumnFilter/constants.ts +16 -0
  167. package/src/components/Table/components/TableFeatures/ColumnFilter/types.ts +10 -0
  168. package/src/components/Table/components/TableFeatures/ColumnFilter/utils.ts +27 -0
  169. package/src/components/Table/featureOptions/facetedColumn/utils.ts +14 -0
  170. package/src/components/common/ButtonGroup/constants.ts +13 -0
  171. package/src/mocks/@storybook/addon-actions.ts +10 -0
  172. package/src/styles/common/mui/buttonGroup.ts +46 -0
  173. package/src/styles/common/mui/typography.ts +2 -0
  174. package/src/tests/mui/constants.ts +1 -0
  175. package/src/tests/utils.ts +9 -0
  176. package/src/theme/common/components.ts +17 -32
  177. package/src/theme/components/index.ts +1 -0
  178. package/src/theme/components/muiButtonGroup.ts +79 -0
  179. package/src/theme/theme.ts +1 -1
  180. package/tests/dataDictionaryColumnFilters.test.tsx +101 -0
@@ -0,0 +1,7 @@
1
+ import { Button, MenuProps } from "@mui/material";
2
+ import { Column, RowData } from "@tanstack/react-table";
3
+ import { BaseComponentProps } from "../../../../types";
4
+ export interface ColumnFilterProps<T extends RowData> extends BaseComponentProps, Omit<MenuProps, "anchorEl" | "onClose" | "open"> {
5
+ Button?: typeof Button;
6
+ column: Column<T>;
7
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Returns an updater function for column filter.
3
+ * @param value - Value.
4
+ * @returns An updater function that returns the new filter value.
5
+ */
6
+ export declare function updater(value: unknown): (old: unknown[] | undefined) => unknown[] | undefined;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Returns an updater function for column filter.
3
+ * @param value - Value.
4
+ * @returns An updater function that returns the new filter value.
5
+ */
6
+ export function updater(value) {
7
+ return (old) => {
8
+ // If no old value, return new value.
9
+ if (!old)
10
+ return [value];
11
+ // If value already exists, remove it.
12
+ if (old.includes(value)) {
13
+ // Filter out the value.
14
+ const next = old.filter((v) => v !== value);
15
+ // If no values remain, return undefined.
16
+ if (next.length === 0)
17
+ return undefined;
18
+ return next;
19
+ }
20
+ // Otherwise, add the value.
21
+ return [...old, value];
22
+ };
23
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Sorts Map entries by key.
3
+ * @param facetedValues - Map of faceted values.
4
+ * @returns Sorted array of [key, value] entries.
5
+ */
6
+ export declare function getSortedFacetedValues(facetedValues: Map<unknown, number>): [unknown, number][];
@@ -0,0 +1,9 @@
1
+ import { COLLATOR_CASE_INSENSITIVE } from "../../../../common/constants";
2
+ /**
3
+ * Sorts Map entries by key.
4
+ * @param facetedValues - Map of faceted values.
5
+ * @returns Sorted array of [key, value] entries.
6
+ */
7
+ export function getSortedFacetedValues(facetedValues) {
8
+ return [...facetedValues].sort((a, b) => COLLATOR_CASE_INSENSITIVE.compare(String(a), String(b)));
9
+ }
@@ -0,0 +1,2 @@
1
+ import { ButtonGroupProps } from "@mui/material";
2
+ export declare const BUTTON_GROUP_PROPS: Record<string, Partial<ButtonGroupProps>>;
@@ -0,0 +1,11 @@
1
+ import { BUTTON_GROUP_PROPS as MUI_BUTTON_GROUP_PROPS } from "../../../styles/common/mui/buttonGroup";
2
+ export const BUTTON_GROUP_PROPS = {
3
+ PRIMARY_CONTAINED: {
4
+ color: MUI_BUTTON_GROUP_PROPS.COLOR.PRIMARY,
5
+ variant: MUI_BUTTON_GROUP_PROPS.VARIANT.CONTAINED,
6
+ },
7
+ SECONDARY_OUTLINED: {
8
+ color: MUI_BUTTON_GROUP_PROPS.COLOR.SECONDARY,
9
+ variant: MUI_BUTTON_GROUP_PROPS.VARIANT.OUTLINED,
10
+ },
11
+ };
@@ -9,7 +9,7 @@ export declare const TabScrollFuzz: import("@emotion/styled").StyledComponent<{
9
9
  } & Props, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>, {}>;
10
10
  export declare const Tab: import("@emotion/styled").StyledComponent<import("@mui/material").TabOwnProps & Omit<import("@mui/material").ButtonBaseOwnProps, "classes"> & import("@mui/material/OverridableComponent").CommonProps & Omit<Omit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
11
11
  ref?: ((instance: HTMLDivElement | null) => void | import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import("react").DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import("react").RefObject<HTMLDivElement> | null | undefined;
12
- }, "label" | "style" | "className" | "classes" | "tabIndex" | "children" | "sx" | "disabled" | "value" | "action" | "icon" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "wrapped" | "iconPosition"> & {
12
+ }, "label" | "style" | "className" | "classes" | "tabIndex" | "children" | "sx" | "disabled" | "value" | "action" | "centerRipple" | "disableRipple" | "disableTouchRipple" | "focusRipple" | "focusVisibleClassName" | "LinkComponent" | "onFocusVisible" | "TouchRippleProps" | "touchRippleRef" | "disableFocusRipple" | "icon" | "wrapped" | "iconPosition"> & {
13
13
  theme?: import("@emotion/react").Theme;
14
14
  }, {}, {}>;
15
15
  export {};
@@ -0,0 +1,9 @@
1
+ import { jest } from "@jest/globals";
2
+ /**
3
+ * Mock for Storybook's @storybook/addon-actions function.
4
+ * The mock keeps the same function signature as the real Storybook action,
5
+ * does not trigger any Storybook logic, and simply returns a Jest mock function
6
+ * for use in tests.
7
+ * @returns A Jest mock function.
8
+ */
9
+ export declare const action: () => jest.Mock;
@@ -0,0 +1,9 @@
1
+ import { jest } from "@jest/globals";
2
+ /**
3
+ * Mock for Storybook's @storybook/addon-actions function.
4
+ * The mock keeps the same function signature as the real Storybook action,
5
+ * does not trigger any Storybook logic, and simply returns a Jest mock function
6
+ * for use in tests.
7
+ * @returns A Jest mock function.
8
+ */
9
+ export const action = () => jest.fn();
@@ -0,0 +1,13 @@
1
+ import { ButtonGroupProps } from "@mui/material";
2
+ type ButtonGroupPropsOptions = {
3
+ CLASSES: typeof CLASSES;
4
+ COLOR: typeof COLOR;
5
+ SIZE: typeof SIZE;
6
+ VARIANT: typeof VARIANT;
7
+ };
8
+ declare const CLASSES: Record<string, ButtonGroupProps["classes"]>;
9
+ declare const COLOR: Record<string, ButtonGroupProps["color"]>;
10
+ declare const SIZE: Record<string, ButtonGroupProps["size"]>;
11
+ declare const VARIANT: Record<string, ButtonGroupProps["variant"]>;
12
+ export declare const BUTTON_GROUP_PROPS: ButtonGroupPropsOptions;
13
+ export {};
@@ -0,0 +1,34 @@
1
+ import { buttonGroupClasses } from "@mui/material";
2
+ const CLASSES = {
3
+ COLOR_PRIMARY: buttonGroupClasses.colorPrimary,
4
+ COLOR_SECONDARY: buttonGroupClasses.colorSecondary,
5
+ CONTAINED: buttonGroupClasses.contained,
6
+ GROUPED: buttonGroupClasses.grouped,
7
+ OUTLINED: buttonGroupClasses.outlined,
8
+ ROOT: buttonGroupClasses.root,
9
+ };
10
+ const COLOR = {
11
+ ERROR: "error",
12
+ INFO: "info",
13
+ INHERIT: "inherit",
14
+ PRIMARY: "primary",
15
+ SECONDARY: "secondary",
16
+ SUCCESS: "success",
17
+ WARNING: "warning",
18
+ };
19
+ const SIZE = {
20
+ LARGE: "large",
21
+ MEDIUM: "medium",
22
+ SMALL: "small",
23
+ };
24
+ const VARIANT = {
25
+ CONTAINED: "contained",
26
+ OUTLINED: "outlined",
27
+ TEXT: "text",
28
+ };
29
+ export const BUTTON_GROUP_PROPS = {
30
+ CLASSES,
31
+ COLOR,
32
+ SIZE,
33
+ VARIANT,
34
+ };
@@ -3,11 +3,13 @@ const COLOR = {
3
3
  INHERIT: "inherit",
4
4
  INK_LIGHT: "ink.light",
5
5
  INK_MAIN: "ink.main",
6
+ PRIMARY: "primary",
6
7
  };
7
8
  const VARIANT = {
8
9
  INHERIT: "inherit",
9
10
  TEXT_BODY_400: "text-body-400",
10
11
  TEXT_BODY_400_2_LINES: "text-body-400-2lines",
12
+ TEXT_BODY_500: "text-body-500",
11
13
  TEXT_BODY_SMALL_400: "text-body-small-400",
12
14
  TEXT_HEADING_LARGE: "text-heading-large",
13
15
  TEXT_HEADING_SMALL: "text-heading-small",
@@ -1,5 +1,6 @@
1
1
  export declare const MUI_CLASSES: {
2
2
  ACTIVE: string;
3
3
  COMPLETED: string;
4
+ DISABLED: string;
4
5
  SELECTED: string;
5
6
  };
@@ -1,5 +1,6 @@
1
1
  export const MUI_CLASSES = {
2
2
  ACTIVE: "Mui-active",
3
3
  COMPLETED: "Mui-completed",
4
+ DISABLED: "Mui-disabled",
4
5
  SELECTED: "Mui-selected",
5
6
  };
@@ -16,6 +16,12 @@ export declare function getLabelText<T extends HTMLElement = HTMLElement>(text:
16
16
  * @returns RegExp.
17
17
  */
18
18
  export declare function getStartsWithRegex(text: string): RegExp;
19
+ /**
20
+ * Retrieves an element by its role.
21
+ * @param role - The role of the element.
22
+ * @returns The element.
23
+ */
24
+ export declare function getRole<T extends HTMLElement = HTMLElement>(role: string): T;
19
25
  /**
20
26
  * Retrieves an element by its text content.
21
27
  * @param text - The text content of the element.
@@ -24,6 +24,14 @@ export function getLabelText(text) {
24
24
  export function getStartsWithRegex(text) {
25
25
  return new RegExp(`^${escapeRegExp(text)}`);
26
26
  }
27
+ /**
28
+ * Retrieves an element by its role.
29
+ * @param role - The role of the element.
30
+ * @returns The element.
31
+ */
32
+ export function getRole(role) {
33
+ return screen.getByRole(role);
34
+ }
27
35
  /**
28
36
  * Retrieves an element by its text content.
29
37
  * @param text - The text content of the element.
@@ -40,12 +40,6 @@ export declare const MuiButton: (theme: Theme) => Components["MuiButton"];
40
40
  * @returns MuiButtonBase component theme styles.
41
41
  */
42
42
  export declare const MuiButtonBase: (theme: Theme) => Components["MuiButtonBase"];
43
- /**
44
- * MuiButtonGroup Component
45
- * @param theme - Theme.
46
- * @returns MuiButtonGroup component theme styles.
47
- */
48
- export declare const MuiButtonGroup: (theme: Theme) => Components["MuiButtonGroup"];
49
43
  /**
50
44
  * MuiCard Component
51
45
  */
@@ -2,6 +2,7 @@ import { DropDownIcon } from "../../components/common/Form/components/Select/com
2
2
  import { COLOR_MIXES } from "../../styles/common/constants/colorMixes";
3
3
  import { PALETTE } from "../../styles/common/constants/palette";
4
4
  import { SHADOWS } from "../../styles/common/constants/shadows";
5
+ import { BUTTON_PROPS } from "../../styles/common/mui/button";
5
6
  import { CHIP_PROPS } from "../../styles/common/mui/chip";
6
7
  import { desktopUp, mobileUp, tabletUp } from "./breakpoints";
7
8
  import { TEXT_BODY_400, TEXT_BODY_400_2_LINES, TEXT_BODY_500, TEXT_BODY_SMALL_400, TEXT_BODY_SMALL_500, TEXT_HEADING, TEXT_HEADING_SMALL, } from "./typography";
@@ -183,6 +184,22 @@ export const MuiButton = (theme) => {
183
184
  },
184
185
  endIcon: {
185
186
  margin: 0,
187
+ variants: [
188
+ {
189
+ props: { size: BUTTON_PROPS.SIZE.MEDIUM },
190
+ style: {
191
+ marginLeft: -6,
192
+ marginRight: -6,
193
+ },
194
+ },
195
+ {
196
+ props: { size: BUTTON_PROPS.SIZE.SMALL },
197
+ style: {
198
+ marginLeft: -6,
199
+ marginRight: -6,
200
+ },
201
+ },
202
+ ],
186
203
  },
187
204
  outlinedSecondary: {
188
205
  backgroundColor: "transparent",
@@ -298,37 +315,6 @@ export const MuiButtonBase = (theme) => {
298
315
  },
299
316
  };
300
317
  };
301
- /**
302
- * MuiButtonGroup Component
303
- * @param theme - Theme.
304
- * @returns MuiButtonGroup component theme styles.
305
- */
306
- export const MuiButtonGroup = (theme) => {
307
- return {
308
- defaultProps: {
309
- disableElevation: true,
310
- disableRipple: true,
311
- },
312
- styleOverrides: {
313
- grouped: {
314
- minWidth: 0,
315
- padding: "6px 8px",
316
- },
317
- groupedContainedPrimary: {
318
- borderColor: theme.palette.primary.dark,
319
- boxShadow: `0 1px 0 0 ${theme.palette.primary.dark}`,
320
- // eslint-disable-next-line sort-keys -- disabling key order for readability
321
- "&:hover": {
322
- boxShadow: `0 1px 0 0 ${theme.palette.primary.dark}`,
323
- },
324
- // eslint-disable-next-line sort-keys -- disabling key order for readability
325
- "&:active": {
326
- boxShadow: "none",
327
- },
328
- },
329
- },
330
- };
331
- };
332
318
  /**
333
319
  * MuiCard Component
334
320
  */
@@ -1,3 +1,4 @@
1
1
  export { MuiAlert } from "./muiAlert";
2
2
  export { MuiAlertTitle } from "./muiAlertTitle";
3
+ export { MuiButtonGroup } from "./muiButtonGroup";
3
4
  export { MuiTableCell } from "./muiTableCell";
@@ -1,3 +1,4 @@
1
1
  export { MuiAlert } from "./muiAlert";
2
2
  export { MuiAlertTitle } from "./muiAlertTitle";
3
+ export { MuiButtonGroup } from "./muiButtonGroup";
3
4
  export { MuiTableCell } from "./muiTableCell";
@@ -0,0 +1,2 @@
1
+ import { Components } from "@mui/material";
2
+ export declare const MuiButtonGroup: Components["MuiButtonGroup"];
@@ -0,0 +1,76 @@
1
+ import { COLOR_MIXES } from "../../styles/common/constants/colorMixes";
2
+ import { PALETTE } from "../../styles/common/constants/palette";
3
+ import { BUTTON_GROUP_PROPS } from "../../styles/common/mui/buttonGroup";
4
+ const SELECTORS = {
5
+ GROUPED: `.${BUTTON_GROUP_PROPS.CLASSES.GROUPED}`,
6
+ };
7
+ export const MuiButtonGroup = {
8
+ defaultProps: {
9
+ disableElevation: true,
10
+ disableRipple: true,
11
+ },
12
+ styleOverrides: {
13
+ root: {
14
+ variants: [
15
+ /* PRIMARY CONTAINED */
16
+ {
17
+ props: {
18
+ color: BUTTON_GROUP_PROPS.COLOR.PRIMARY,
19
+ variant: BUTTON_GROUP_PROPS.VARIANT.CONTAINED,
20
+ },
21
+ style: {
22
+ [SELECTORS.GROUPED]: {
23
+ borderColor: PALETTE.PRIMARY_DARK,
24
+ boxShadow: `0 1px 0 0 ${PALETTE.PRIMARY_DARK}`,
25
+ minWidth: 0,
26
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
27
+ "&:hover": {
28
+ boxShadow: `0 1px 0 0 ${PALETTE.PRIMARY_DARK}`,
29
+ },
30
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
31
+ "&:active": {
32
+ boxShadow: "none",
33
+ },
34
+ },
35
+ },
36
+ },
37
+ /* SECONDARY OUTLINED */
38
+ {
39
+ props: {
40
+ color: BUTTON_GROUP_PROPS.COLOR.SECONDARY,
41
+ variant: BUTTON_GROUP_PROPS.VARIANT.OUTLINED,
42
+ },
43
+ style: {
44
+ [SELECTORS.GROUPED]: {
45
+ backgroundColor: PALETTE.COMMON_WHITE,
46
+ boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}, 0 1px 0 0 ${COLOR_MIXES.COMMON_BLACK_08}`,
47
+ color: PALETTE.INK_MAIN,
48
+ minWidth: 0,
49
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
50
+ "&:hover": {
51
+ backgroundColor: PALETTE.SMOKE_LIGHTEST,
52
+ boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}, 0 1px 0 0 ${COLOR_MIXES.COMMON_BLACK_08}`,
53
+ },
54
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
55
+ "&:active": {
56
+ backgroundColor: PALETTE.SMOKE_LIGHTEST,
57
+ boxShadow: `inset 0 0 0 1px ${PALETTE.SMOKE_DARK}`,
58
+ },
59
+ },
60
+ },
61
+ },
62
+ /* SMALL */
63
+ {
64
+ props: {
65
+ size: BUTTON_GROUP_PROPS.SIZE.SMALL,
66
+ },
67
+ style: {
68
+ [SELECTORS.GROUPED]: {
69
+ padding: "6px 8px",
70
+ },
71
+ },
72
+ },
73
+ ],
74
+ },
75
+ },
76
+ };
@@ -69,7 +69,7 @@ export function createAppTheme(customOptions = {}) {
69
69
  MuiBreadcrumbs: C.MuiBreadcrumbs(theme),
70
70
  MuiButton: C.MuiButton(theme),
71
71
  MuiButtonBase: C.MuiButtonBase(theme),
72
- MuiButtonGroup: C.MuiButtonGroup(theme),
72
+ MuiButtonGroup: M.MuiButtonGroup,
73
73
  MuiCard: C.MuiCard,
74
74
  MuiCheckbox: C.MuiCheckbox(theme),
75
75
  MuiChip: C.MuiChip(theme),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "33.0.0",
3
+ "version": "34.0.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
@@ -1,4 +1,4 @@
1
- import { ColumnDef, RowData } from "@tanstack/react-table";
1
+ import { ColumnDef, RowData, TableOptions } from "@tanstack/react-table";
2
2
 
3
3
  /**
4
4
  * Model of a value of a metadata class.
@@ -6,6 +6,7 @@ import { ColumnDef, RowData } from "@tanstack/react-table";
6
6
  export interface Attribute {
7
7
  // Prefix to fragment mapping, e.g. cxg: "batch_condition", or, general tags e.g. tier: "Tier 1" and bionetwork: ["gut"]
8
8
  annotations?: Record<string, string | string[] | undefined>; // 'undefined' allows for mix of keys across attributes e.g. tier, or tier and cxg, or cxg
9
+ classKey?: string; // Programmatic class name or key (e.g. cell, sample) the attribute belongs to.
9
10
  description: string;
10
11
  example?: string; // Free text example of attribute
11
12
  multivalued: boolean; // True if attribute can have multiple values
@@ -73,6 +74,7 @@ export interface DataDictionary<T extends RowData = Attribute> {
73
74
  export interface DataDictionaryConfig<T extends RowData = Attribute> {
74
75
  columnDefs: ColumnDef<T, T[keyof T]>[];
75
76
  dataDictionary: DataDictionary<T>;
77
+ tableOptions?: Omit<TableOptions<T>, "columns" | "data" | "getCoreRowModel">;
76
78
  }
77
79
 
78
80
  /**
@@ -7,19 +7,15 @@ import { GRID_PROPS } from "./constants";
7
7
  import { ClassesProps } from "./types";
8
8
 
9
9
  export const Entities = <T extends RowData = Attribute>({
10
- classes,
11
- columnDefs,
12
10
  spacing,
11
+ table,
13
12
  }: ClassesProps<T>): JSX.Element => {
13
+ const { getGroupedRowModel } = table;
14
14
  return (
15
15
  <Grid {...GRID_PROPS}>
16
- {classes.map((cls) => (
17
- <Entity
18
- key={cls.name}
19
- class={cls}
20
- columnDefs={columnDefs}
21
- spacing={spacing}
22
- />
16
+ {/* Render grouped rows where each "group" is a class e.g. "donor" */}
17
+ {getGroupedRowModel().rows.map((row) => (
18
+ <Entity key={row.id} row={row} spacing={spacing} table={table} />
23
19
  ))}
24
20
  </Grid>
25
21
  );
@@ -1,9 +1,8 @@
1
- import { ColumnDef, RowData } from "@tanstack/react-table";
2
- import { Attribute, Class } from "../../../../common/entities";
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
4
 
5
5
  export interface ClassesProps<T extends RowData = Attribute> {
6
- classes: Class<T>[];
7
- columnDefs: ColumnDef<T, T[keyof T]>[];
8
6
  spacing?: LayoutSpacing;
7
+ table: Table<T>;
9
8
  }
@@ -2,9 +2,17 @@ import styled from "@emotion/styled";
2
2
  import { Typography } from "@mui/material";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
4
  import { ENTITIES_ROW_GAP } from "../Entities/constants";
5
+ import { LAYOUT_SPACING } from "../Layout/constants";
6
+
7
+ const TOP =
8
+ ENTITIES_ROW_GAP +
9
+ LAYOUT_SPACING.TITLE_HEIGHT +
10
+ LAYOUT_SPACING.FILTERS_HEIGHT +
11
+ LAYOUT_SPACING.FILTERS_PADDING_TOP +
12
+ LAYOUT_SPACING.CONTENT_PADDING_TOP;
5
13
 
6
14
  export const StyledTypography = styled(Typography)<Partial<LayoutSpacing>>`
7
- scroll-margin-top: ${({ top = 0 }) => top + ENTITIES_ROW_GAP}px;
15
+ scroll-margin-top: ${({ top = 0 }) => top + TOP}px;
8
16
 
9
17
  &:hover a {
10
18
  opacity: 1;
@@ -4,28 +4,37 @@ import React from "react";
4
4
  import { Attribute } from "../../../../common/entities";
5
5
  import { TYPOGRAPHY_PROPS } from "../../../../styles/common/mui/typography";
6
6
  import { AnchorLink } from "../../../common/AnchorLink/anchorLink";
7
- import { useTable } from "../Table/hook";
8
7
  import { Table } from "../Table/table";
9
8
  import { GRID_PROPS } from "./constants";
10
9
  import { StyledTypography } from "./entity.styles";
11
10
  import { EntityProps } from "./types";
11
+ import { getClassMeta } from "./utils";
12
12
 
13
13
  export const Entity = <T extends RowData = Attribute>({
14
- class: cls,
15
- columnDefs,
14
+ row,
16
15
  spacing,
17
- }: EntityProps<T>): JSX.Element => {
18
- const table = useTable<T>(cls.attributes, columnDefs);
16
+ table,
17
+ }: EntityProps<T>): JSX.Element | null => {
18
+ // Get class key from row.
19
+ const classKey = row.getValue<string>("classKey");
20
+
21
+ // Get class metadata from table options.
22
+ const cls = getClassMeta<T>(classKey, table);
23
+
24
+ // Class not found in table meta - return null.
25
+ if (!cls) return null;
26
+
19
27
  return (
20
28
  <Grid {...GRID_PROPS} rowGap={4}>
29
+ {/* Class title and description */}
21
30
  <Grid {...GRID_PROPS} rowGap={1}>
22
31
  <StyledTypography
23
32
  component="h3"
24
- id={cls.name}
33
+ id={classKey}
25
34
  variant={TYPOGRAPHY_PROPS.VARIANT.TEXT_HEADING_SMALL}
26
35
  {...spacing}
27
36
  >
28
- {cls.title} <AnchorLink anchorLink={cls.name} />
37
+ {cls.title} <AnchorLink anchorLink={classKey} />
29
38
  </StyledTypography>
30
39
  <Typography
31
40
  color={TYPOGRAPHY_PROPS.COLOR.INK_LIGHT}
@@ -35,7 +44,8 @@ export const Entity = <T extends RowData = Attribute>({
35
44
  {cls.description}
36
45
  </Typography>
37
46
  </Grid>
38
- <Table table={table} />
47
+ {/* Class attributes table */}
48
+ <Table row={row} table={table} />
39
49
  </Grid>
40
50
  );
41
51
  };
@@ -1,9 +1,9 @@
1
- import { ColumnDef, RowData } from "@tanstack/react-table";
2
- import { Attribute, Class } from "../../../../common/entities";
1
+ import { Row, RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../common/entities";
3
3
  import { LayoutSpacing } from "../../hooks/UseLayoutSpacing/types";
4
4
 
5
5
  export interface EntityProps<T extends RowData = Attribute> {
6
- class: Class<T>;
7
- columnDefs: ColumnDef<T, T[keyof T]>[];
6
+ row: Row<T>;
8
7
  spacing?: LayoutSpacing;
8
+ table: Table<T>;
9
9
  }
@@ -0,0 +1,25 @@
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute, Class } from "../../../../common/entities";
3
+ import { ClassMeta } from "../Table/types";
4
+
5
+ /**
6
+ * Retrieves class metadata from the table options meta.
7
+ * @param classKey - Class key.
8
+ * @param table - Table instance.
9
+ * @returns Class metadata or undefined.
10
+ */
11
+ export function getClassMeta<T extends RowData = Attribute>(
12
+ classKey: string | undefined,
13
+ table: Table<T>
14
+ ): Pick<Class<T>, "description" | "title"> | undefined {
15
+ if (!classKey) return;
16
+
17
+ // Grab the table meta and return if not defined.
18
+ const meta = table.options.meta;
19
+ if (!meta) return;
20
+
21
+ // Return class metadata if defined.
22
+ if ("classMeta" in meta) {
23
+ return (meta.classMeta as ClassMeta)?.[classKey];
24
+ }
25
+ }
@@ -0,0 +1,21 @@
1
+ import { ButtonGroup } from "@mui/material";
2
+ import { RowData } from "@tanstack/react-table";
3
+ import React from "react";
4
+ import { Attribute } from "../../../../../../common/entities";
5
+ import { BUTTON_GROUP_PROPS } from "../../../../../common/ButtonGroup/constants";
6
+ import { ColumnFilter } from "../../../../../Table/components/TableFeatures/ColumnFilter/columnFilter";
7
+ import { ColumnFiltersProps } from "./types";
8
+
9
+ export const ColumnFilters = <T extends RowData = Attribute>({
10
+ table,
11
+ }: ColumnFiltersProps<T>): JSX.Element => {
12
+ const columns = table.getAllColumns();
13
+ const columnFilters = columns.filter((column) => column.getCanFilter());
14
+ return (
15
+ <ButtonGroup {...BUTTON_GROUP_PROPS.SECONDARY_OUTLINED}>
16
+ {columnFilters.map((column) => (
17
+ <ColumnFilter key={column.id} column={column} />
18
+ ))}
19
+ </ButtonGroup>
20
+ );
21
+ };
@@ -0,0 +1,6 @@
1
+ import { RowData, Table } from "@tanstack/react-table";
2
+ import { Attribute } from "../../../../../../common/entities";
3
+
4
+ export interface ColumnFiltersProps<T extends RowData = Attribute> {
5
+ table: Table<T>;
6
+ }
@@ -0,0 +1,14 @@
1
+ import styled from "@emotion/styled";
2
+ import { Grid } from "@mui/material";
3
+ import { BUTTON_GROUP_PROPS } from "../../../../styles/common/mui/buttonGroup";
4
+
5
+ export const StyledGrid = styled(Grid)`
6
+ align-items: center;
7
+ display: grid;
8
+ gap: 16px;
9
+ grid-template-columns: 1fr auto;
10
+
11
+ .${BUTTON_GROUP_PROPS.CLASSES.ROOT} {
12
+ grid-column: 2;
13
+ }
14
+ `;