@databiosphere/findable-ui 7.0.0 → 8.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 (72) hide show
  1. package/lib/common/entities.d.ts +0 -9
  2. package/lib/common/entities.js +1 -9
  3. package/lib/components/Index/components/Tabs/common/utils.d.ts +8 -0
  4. package/lib/components/Index/components/Tabs/common/utils.js +18 -0
  5. package/lib/components/Index/components/Tabs/tabs.d.ts +2 -0
  6. package/lib/components/Index/components/Tabs/tabs.js +20 -0
  7. package/lib/components/Layout/components/Header/common/constants.d.ts +4 -9
  8. package/lib/components/Layout/components/Header/common/constants.js +8 -9
  9. package/lib/components/Layout/components/Header/common/entities.d.ts +6 -0
  10. package/lib/components/Layout/components/Header/common/utils.d.ts +12 -17
  11. package/lib/components/Layout/components/Header/common/utils.js +77 -59
  12. package/lib/components/Layout/components/Header/components/Announcements/announcements.d.ts +6 -0
  13. package/lib/components/Layout/components/Header/components/Announcements/announcements.js +7 -0
  14. package/lib/components/Layout/components/Header/components/Content/components/Actions/actions.d.ts +1 -2
  15. package/lib/components/Layout/components/Header/components/Content/components/Actions/actions.js +2 -2
  16. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/RequestAuthentication/requestAuthentication.js +8 -15
  17. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Toolbar/toolbar.d.ts +4 -3
  18. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Toolbar/toolbar.js +4 -3
  19. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/menu.js +17 -19
  20. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchButton/searchButton.js +5 -12
  21. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.js +3 -4
  22. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.d.ts +3 -3
  23. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.js +5 -7
  24. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.d.ts +1 -6
  25. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.js +4 -19
  26. package/lib/components/Layout/components/Header/header.d.ts +5 -7
  27. package/lib/components/Layout/components/Header/header.js +35 -59
  28. package/lib/components/Layout/components/Header/header.stories.js +38 -41
  29. package/lib/components/Layout/components/Header/header.styles.d.ts +13 -1
  30. package/lib/components/Layout/components/Header/header.styles.js +23 -3
  31. package/lib/components/Layout/components/Header/hooks/useHeaderVisibility.d.ts +20 -0
  32. package/lib/components/Layout/components/Header/hooks/useHeaderVisibility.js +46 -0
  33. package/lib/components/Layout/components/Header/hooks/useMeasureHeader.d.ts +5 -0
  34. package/lib/components/Layout/components/Header/hooks/useMeasureHeader.js +19 -0
  35. package/lib/config/entities.d.ts +2 -0
  36. package/lib/config/utils.js +1 -2
  37. package/lib/hooks/useBreakpoint.d.ts +17 -0
  38. package/lib/hooks/useBreakpoint.js +34 -0
  39. package/lib/hooks/useBreakpointHelper.d.ts +1 -1
  40. package/lib/hooks/useCurrentBreakpoint.d.ts +3 -0
  41. package/lib/hooks/useCurrentBreakpoint.js +11 -0
  42. package/lib/hooks/useMenu.d.ts +10 -0
  43. package/lib/hooks/useMenu.js +17 -0
  44. package/lib/views/ExploreView/exploreView.js +4 -29
  45. package/package.json +1 -1
  46. package/src/common/entities.ts +0 -11
  47. package/src/components/Index/components/Tabs/common/utils.ts +33 -0
  48. package/src/components/Index/components/Tabs/tabs.tsx +23 -0
  49. package/src/components/Layout/components/Header/common/constants.ts +14 -10
  50. package/src/components/Layout/components/Header/common/entities.ts +7 -0
  51. package/src/components/Layout/components/Header/common/utils.ts +89 -66
  52. package/src/components/Layout/components/Header/components/Announcements/announcements.tsx +14 -0
  53. package/src/components/Layout/components/Header/components/Content/components/Actions/actions.tsx +2 -6
  54. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/RequestAuthentication/requestAuthentication.tsx +21 -32
  55. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Toolbar/toolbar.tsx +8 -6
  56. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Menu/menu.tsx +19 -26
  57. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchButton/searchButton.tsx +11 -22
  58. package/src/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.tsx +3 -7
  59. package/src/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.ts +5 -30
  60. package/src/components/Layout/components/Header/components/Content/components/Navigation/navigation.tsx +8 -27
  61. package/src/components/Layout/components/Header/header.stories.tsx +38 -41
  62. package/src/components/Layout/components/Header/header.styles.ts +27 -4
  63. package/src/components/Layout/components/Header/header.tsx +99 -137
  64. package/src/components/Layout/components/Header/hooks/useHeaderVisibility.ts +74 -0
  65. package/src/components/Layout/components/Header/hooks/useMeasureHeader.ts +28 -0
  66. package/src/config/entities.ts +2 -0
  67. package/src/config/utils.ts +1 -2
  68. package/src/hooks/useBreakpoint.ts +54 -0
  69. package/src/hooks/useBreakpointHelper.ts +1 -1
  70. package/src/hooks/useCurrentBreakpoint.ts +23 -0
  71. package/src/hooks/useMenu.ts +27 -0
  72. package/src/views/ExploreView/exploreView.tsx +5 -34
@@ -1,6 +1,4 @@
1
- import { css } from "@emotion/react";
2
1
  import styled from "@emotion/styled";
3
- import { ELEMENT_ALIGNMENT, } from "../../../../../../../../common/entities";
4
2
  import { mediaDesktopSmallUp } from "../../../../../../../../styles/common/mixins/breakpoints";
5
3
  import { textBody500 } from "../../../../../../../../styles/common/mixins/fonts";
6
4
  export const Navigation = styled("div") `
@@ -10,23 +8,10 @@ export const Navigation = styled("div") `
10
8
  gap: 8px;
11
9
  justify-content: flex-start;
12
10
 
13
- // Left alignment.
14
- ${({ alignment }) => alignment === ELEMENT_ALIGNMENT.LEFT &&
15
- css `
16
- margin-left: 24px;
17
- `};
18
-
19
- // Center alignment.
20
- ${({ alignment }) => alignment === ELEMENT_ALIGNMENT.CENTER &&
21
- css `
22
- justify-content: center;
23
- `};
24
-
25
- // Right alignment.
26
- ${({ alignment }) => alignment === ELEMENT_ALIGNMENT.RIGHT &&
27
- css `
28
- justify-content: flex-end;
29
- `};
11
+ ${mediaDesktopSmallUp} {
12
+ flex: unset;
13
+ justify-content: inherit;
14
+ }
30
15
 
31
16
  .MuiButton-nav {
32
17
  ${textBody500};
@@ -1,15 +1,13 @@
1
1
  import { ReactNode } from "react";
2
- import { ElementAlignment } from "../../../../common/entities";
3
- import { SocialMedia } from "./common/entities";
4
- import { NavLinkItem } from "./components/Content/components/Navigation/navigation";
2
+ import { ComponentsConfig } from "../../../../config/entities";
3
+ import { Navigation, SocialMedia } from "./common/entities";
5
4
  export interface HeaderProps {
6
5
  actions?: ReactNode;
7
- Announcements?: ReactNode;
6
+ announcements?: ComponentsConfig;
8
7
  authenticationEnabled?: boolean;
9
8
  className?: string;
10
- Logo: ReactNode;
11
- navAlignment?: ElementAlignment;
12
- navLinks: NavLinkItem[];
9
+ logo: ReactNode;
10
+ navigation?: Navigation;
13
11
  searchEnabled?: boolean;
14
12
  searchURL?: string;
15
13
  slogan?: ReactNode;
@@ -1,69 +1,45 @@
1
1
  import { Fade, Toolbar } from "@mui/material";
2
- import React, { useCallback, useEffect, useRef, useState, } from "react";
3
- import { ELEMENT_ALIGNMENT, } from "../../../../common/entities";
4
- import { BREAKPOINT_FN_NAME, useBreakpointHelper, } from "../../../../hooks/useBreakpointHelper";
5
- import { useLayoutState } from "../../../../hooks/useLayoutState";
6
- import { getBorderBoxSizeHeight, useResizeObserver, } from "../../../../hooks/useResizeObserver";
7
- import { LayoutActionKind } from "../../../../providers/layoutState";
8
- import { DESKTOP, DESKTOP_SM } from "../../../../theme/common/breakpoints";
9
- import { FADE_TRANSITION_PROPS } from "./common/constants";
10
- import { getHeaderNavigationLinks } from "./common/utils";
2
+ import React from "react";
3
+ import { useBreakpoint } from "../../../../hooks/useBreakpoint";
4
+ import { useMenu } from "../../../../hooks/useMenu";
5
+ import { APP_BAR_PROPS, FADE_TRANSITION_PROPS, TOOLBAR_PROPS, } from "./common/constants";
6
+ import { getNavigationLinks } from "./common/utils";
7
+ import { Announcements } from "./components/Announcements/announcements";
11
8
  import { Actions } from "./components/Content/components/Actions/actions";
12
9
  import { Authentication } from "./components/Content/components/Actions/components/Authentication/authentication";
13
10
  import { Menu } from "./components/Content/components/Actions/components/Menu/menu";
14
11
  import { Search } from "./components/Content/components/Actions/components/Search/search";
15
- import { Navigation, } from "./components/Content/components/Navigation/navigation";
12
+ import { Navigation as DXNavigation } from "./components/Content/components/Navigation/navigation";
16
13
  import { Slogan } from "./components/Content/components/Slogan/slogan";
17
14
  import { Divider } from "./components/Content/components/Slogan/slogan.styles";
18
15
  import { Socials } from "./components/Content/components/Socials/socials.styles";
19
- import { AppBar as HeaderAppBar, HeaderSmAppBar } from "./header.styles";
16
+ import { AppBar, Center, Left, Right } from "./header.styles";
17
+ import { useHeaderVisibility } from "./hooks/useHeaderVisibility";
18
+ import { useMeasureHeader } from "./hooks/useMeasureHeader";
20
19
  export const Header = ({ ...headerProps }) => {
21
- const { Announcements, authenticationEnabled, actions, className, Logo, navAlignment = ELEMENT_ALIGNMENT.LEFT, navLinks, searchEnabled, searchURL, slogan, socialMedia, } = headerProps;
22
- const { layoutDispatch } = useLayoutState();
23
- const headerRef = useRef(null);
24
- const { height } = useResizeObserver(headerRef, getBorderBoxSizeHeight) || {};
25
- const [menuOpen, setMenuOpen] = useState(false);
26
- const onlySmDesktop = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, DESKTOP_SM);
27
- const smDesktop = useBreakpointHelper(BREAKPOINT_FN_NAME.UP, DESKTOP_SM);
28
- const desktop = useBreakpointHelper(BREAKPOINT_FN_NAME.UP, DESKTOP);
29
- const AppBar = navAlignment === ELEMENT_ALIGNMENT.RIGHT ? HeaderSmAppBar : HeaderAppBar;
30
- const showActions = searchEnabled || authenticationEnabled || !smDesktop;
31
- const isNavigationIn = smDesktop;
32
- const isSloganIn = Boolean(slogan) && smDesktop;
33
- const isSocialsIn = Boolean(socialMedia) && desktop;
34
- const fadeProps = FADE_TRANSITION_PROPS;
35
- // Closes header menu.
36
- const closeMenu = useCallback(() => {
37
- setMenuOpen(false);
38
- }, []);
39
- // Opens header menu.
40
- const openMenu = useCallback(() => {
41
- setMenuOpen(true);
42
- }, []);
43
- // Updates layout state header height.
44
- useEffect(() => {
45
- if (!height)
46
- return;
47
- layoutDispatch({
48
- payload: height,
49
- type: LayoutActionKind.UpdateHeaderHeight,
50
- });
51
- }, [height, layoutDispatch]);
52
- return (React.createElement(AppBar, { ref: headerRef, className: className, elevation: 1, position: "fixed" },
53
- Announcements,
54
- React.createElement(Toolbar, { variant: "dense" },
55
- Logo,
56
- React.createElement(Fade, { in: isSloganIn, style: { transitionDelay: isSloganIn ? "50ms" : "0ms" }, ...fadeProps },
57
- React.createElement(Divider, { orientation: "vertical" })),
58
- React.createElement(Fade, { in: isSloganIn, style: { transitionDelay: isSloganIn ? "50ms" : "0ms" }, ...fadeProps },
59
- React.createElement(Slogan, { slogan: slogan })),
60
- React.createElement(Fade, { in: isNavigationIn, ...fadeProps },
61
- React.createElement(Navigation, { alignment: navAlignment, headerProps: headerProps, links: getHeaderNavigationLinks(navLinks, socialMedia, onlySmDesktop) })),
62
- socialMedia && (React.createElement(Fade, { in: isSocialsIn, ...fadeProps },
63
- React.createElement(Socials, { buttonSize: "small", socials: socialMedia.socials }))),
64
- React.createElement(Actions, { showActions: showActions },
65
- React.createElement(Search, { closeMenu: closeMenu, searchEnabled: searchEnabled, searchURL: searchURL }),
66
- React.createElement(Authentication, { authenticationEnabled: authenticationEnabled, closeMenu: closeMenu }),
67
- actions,
68
- React.createElement(Menu, { closeMenu: closeMenu, headerProps: headerProps, open: menuOpen, openMenu: openMenu })))));
20
+ const { breakpoint } = useBreakpoint();
21
+ const { isIn } = useHeaderVisibility(headerProps);
22
+ const { headerRef } = useMeasureHeader();
23
+ const { onClose, onOpen, open } = useMenu();
24
+ const { actions, announcements, authenticationEnabled, className, logo, navigation: [navItemsL, navItemsC, navItemsR] = [], searchEnabled, searchURL, slogan, socialMedia, } = headerProps;
25
+ return (React.createElement(AppBar, { ...APP_BAR_PROPS, ref: headerRef, className: className },
26
+ React.createElement(Announcements, { announcements: announcements }),
27
+ React.createElement(Toolbar, { ...TOOLBAR_PROPS },
28
+ React.createElement(Fade, { ...FADE_TRANSITION_PROPS, in: isIn.isLeftGroupIn },
29
+ React.createElement(Left, null,
30
+ logo,
31
+ isIn.isSloganIn && React.createElement(Divider, { flexItem: true, orientation: "vertical" }),
32
+ isIn.isSloganIn && React.createElement(Slogan, { slogan: slogan }),
33
+ isIn.isLeftNavigationIn && (React.createElement(DXNavigation, { headerProps: headerProps, links: getNavigationLinks(navItemsL, breakpoint) })))),
34
+ React.createElement(Fade, { ...FADE_TRANSITION_PROPS, in: isIn.isCenterGroupIn },
35
+ React.createElement(Center, null, isIn.isCenterNavigationIn && (React.createElement(DXNavigation, { headerProps: headerProps, links: getNavigationLinks(navItemsC, breakpoint) })))),
36
+ React.createElement(Fade, { ...FADE_TRANSITION_PROPS, in: isIn.isRightGroupIn },
37
+ React.createElement(Right, null,
38
+ isIn.isRightNavigationIn && (React.createElement(DXNavigation, { headerProps: headerProps, links: getNavigationLinks(navItemsR) })),
39
+ isIn.isSocialsIn && (React.createElement(Socials, { buttonSize: "small", socials: socialMedia?.socials || [] })),
40
+ isIn.isActionsIn && (React.createElement(Actions, null,
41
+ React.createElement(Search, { closeMenu: onClose, searchEnabled: searchEnabled, searchURL: searchURL }),
42
+ React.createElement(Authentication, { authenticationEnabled: authenticationEnabled, closeMenu: onClose }),
43
+ actions,
44
+ React.createElement(Menu, { closeMenu: onClose, headerProps: headerProps, open: open, openMenu: onOpen }))))))));
69
45
  };
@@ -1,21 +1,15 @@
1
1
  import React from "react";
2
- import { ELEMENT_ALIGNMENT } from "../../../../common/entities";
3
2
  import logo from "../../../../images/logo.svg";
4
3
  import { DiscourseIcon } from "../../../common/CustomIcon/components/DiscourseIcon/discourseIcon";
5
4
  import { GitHubIcon } from "../../../common/CustomIcon/components/GitHubIcon/gitHubIcon";
6
5
  import { XIcon } from "../../../common/CustomIcon/components/XIcon/xIcon";
7
6
  import { YouTubeIcon } from "../../../common/CustomIcon/components/YouTubeIcon/youTubeIcon";
8
- import { HEADER_NAVIGATION_LABEL } from "./common/constants";
9
7
  import { Logo } from "./components/Content/components/Logo/logo";
10
8
  import { Header } from "./header";
11
9
  export default {
12
10
  argTypes: {
13
- Logo: { control: { disable: true } },
14
11
  authenticationEnabled: { control: "boolean" },
15
- navAlignment: {
16
- control: "select",
17
- options: [ELEMENT_ALIGNMENT.LEFT, ELEMENT_ALIGNMENT.CENTER],
18
- },
12
+ logo: { control: { disable: true } },
19
13
  navLinks: { control: "array" },
20
14
  searchEnabled: { control: "boolean" },
21
15
  slogan: { control: "text" },
@@ -30,45 +24,48 @@ export default {
30
24
  const url = "/";
31
25
  export const HeaderStory = {
32
26
  args: {
33
- Logo: React.createElement(Logo, { alt: "Logo", height: 40, link: "/", src: logo }),
34
27
  authenticationEnabled: false,
35
- navAlignment: ELEMENT_ALIGNMENT.CENTER,
36
- navLinks: [
37
- {
38
- label: "Overview",
39
- url,
40
- },
41
- {
42
- label: "Learn",
43
- url,
44
- },
45
- {
46
- label: "Datasets",
47
- url,
48
- },
49
- {
50
- label: "More",
51
- menuItems: [
52
- {
53
- label: "Team",
54
- url,
55
- },
56
- {
57
- label: "FAQ",
58
- url,
59
- },
60
- {
61
- label: "Help",
62
- url,
63
- },
64
- ],
65
- url: "",
66
- },
28
+ logo: React.createElement(Logo, { alt: "Logo", height: 40, link: "/", src: logo }),
29
+ navigation: [
30
+ undefined,
31
+ [
32
+ {
33
+ label: "Overview",
34
+ url,
35
+ },
36
+ {
37
+ label: "Learn",
38
+ url,
39
+ },
40
+ {
41
+ label: "Datasets",
42
+ url,
43
+ },
44
+ {
45
+ label: "More",
46
+ menuItems: [
47
+ {
48
+ label: "Team",
49
+ url,
50
+ },
51
+ {
52
+ label: "FAQ",
53
+ url,
54
+ },
55
+ {
56
+ label: "Help",
57
+ url,
58
+ },
59
+ ],
60
+ url: "",
61
+ },
62
+ ],
63
+ undefined,
67
64
  ],
68
65
  searchEnabled: true,
69
66
  slogan: "Header Slogan",
70
67
  socialMedia: {
71
- label: HEADER_NAVIGATION_LABEL.SOCIALS,
68
+ label: "Follow Us",
72
69
  socials: [
73
70
  {
74
71
  Icon: XIcon,
@@ -1,2 +1,14 @@
1
+ /// <reference types="react" />
1
2
  export declare const AppBar: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").AppBarTypeMap<{}, "header">>;
2
- export declare const HeaderSmAppBar: import("@mui/material/OverridableComponent").OverridableComponent<import("@mui/material").AppBarTypeMap<{}, "header">>;
3
+ export declare const Left: import("@emotion/styled").StyledComponent<{
4
+ theme?: import("@emotion/react").Theme | undefined;
5
+ as?: import("react").ElementType<any> | undefined;
6
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
7
+ export declare const Center: import("@emotion/styled").StyledComponent<{
8
+ theme?: import("@emotion/react").Theme | undefined;
9
+ as?: import("react").ElementType<any> | undefined;
10
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
11
+ export declare const Right: import("@emotion/styled").StyledComponent<{
12
+ theme?: import("@emotion/react").Theme | undefined;
13
+ as?: import("react").ElementType<any> | undefined;
14
+ }, import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
@@ -1,3 +1,4 @@
1
+ import { css } from "@emotion/react";
1
2
  import styled from "@emotion/styled";
2
3
  import { AppBar as MAppBar } from "@mui/material";
3
4
  import { HEADER_HEIGHT } from "./common/constants";
@@ -14,8 +15,27 @@ export const AppBar = styled(MAppBar) `
14
15
  min-height: unset;
15
16
  }
16
17
  `;
17
- export const HeaderSmAppBar = styled(AppBar) `
18
- .MuiToolbar-root {
19
- gap: 8px;
18
+ const group = css `
19
+ align-items: center;
20
+ display: flex;
21
+ flex: 1;
22
+ `;
23
+ export const Left = styled.div `
24
+ ${group};
25
+ gap: 16px;
26
+ justify-content: flex-start;
27
+
28
+ .MuiButton-navPrimary {
29
+ &:first-of-type {
30
+ margin-left: 24px;
31
+ }
20
32
  }
21
33
  `;
34
+ export const Center = styled.div `
35
+ ${group};
36
+ justify-content: center;
37
+ `;
38
+ export const Right = styled.div `
39
+ ${group};
40
+ justify-content: flex-end;
41
+ `;
@@ -0,0 +1,20 @@
1
+ import { HeaderProps } from "../header";
2
+ export interface UseHeaderVisibility {
3
+ isIn: {
4
+ isActionsIn: boolean;
5
+ isCenterGroupIn: boolean;
6
+ isCenterNavigationIn: boolean;
7
+ isLeftGroupIn: boolean;
8
+ isLeftNavigationIn: boolean;
9
+ isRightGroupIn: boolean;
10
+ isRightNavigationIn: boolean;
11
+ isSloganIn: boolean;
12
+ isSocialsIn: boolean;
13
+ };
14
+ }
15
+ /**
16
+ * Returns header component visibility for header related rendering logic.
17
+ * @param headerProps - Header component props.
18
+ * @returns header component visibility.
19
+ */
20
+ export declare const useHeaderVisibility: (headerProps: HeaderProps) => UseHeaderVisibility;
@@ -0,0 +1,46 @@
1
+ import { useBreakpoint } from "../../../../../hooks/useBreakpoint";
2
+ /**
3
+ * Returns header component visibility for header related rendering logic.
4
+ * @param headerProps - Header component props.
5
+ * @returns header component visibility.
6
+ */
7
+ export const useHeaderVisibility = (headerProps) => {
8
+ const { lgUp, mdUp } = useBreakpoint();
9
+ // Header configuration.
10
+ const { actions, authenticationEnabled, logo, navigation: [navItemsL, navItemsC, navItemsR] = [], searchEnabled, slogan, socialMedia, } = headerProps;
11
+ // Header content.
12
+ const hasActions = Boolean(actions);
13
+ const hasLogo = Boolean(logo);
14
+ const hasMenu = !mdUp;
15
+ const hasNavItemsC = Boolean(navItemsC);
16
+ const hasNavItemsL = Boolean(navItemsL);
17
+ const hasNavItemsR = Boolean(navItemsR);
18
+ const hasSlogan = Boolean(slogan);
19
+ const hasSocials = Boolean(socialMedia);
20
+ // Determines header content visibility.
21
+ const isActionsIn = hasActions || searchEnabled || authenticationEnabled || hasMenu;
22
+ const isNavigationIn = mdUp;
23
+ const isSloganIn = hasSlogan && mdUp;
24
+ const isSocialsIn = hasSocials && lgUp;
25
+ // Determines navigation visibility.
26
+ const isCenterNavigationIn = isNavigationIn && hasNavItemsC;
27
+ const isLeftNavigationIn = isNavigationIn && hasNavItemsL;
28
+ const isRightNavigationIn = isNavigationIn && hasNavItemsR;
29
+ // Determines group visibility.
30
+ const isLeftGroupIn = hasLogo || isSocialsIn || isLeftNavigationIn;
31
+ const isCenterGroupIn = isCenterNavigationIn;
32
+ const isRightGroupIn = isRightNavigationIn || isSocialsIn || isActionsIn;
33
+ return {
34
+ isIn: {
35
+ isActionsIn,
36
+ isCenterGroupIn,
37
+ isCenterNavigationIn,
38
+ isLeftGroupIn,
39
+ isLeftNavigationIn,
40
+ isRightGroupIn,
41
+ isRightNavigationIn,
42
+ isSloganIn,
43
+ isSocialsIn,
44
+ },
45
+ };
46
+ };
@@ -0,0 +1,5 @@
1
+ import { RefObject } from "react";
2
+ export interface UseMeasureHeader {
3
+ headerRef: RefObject<HTMLElement>;
4
+ }
5
+ export declare const useMeasureHeader: () => UseMeasureHeader;
@@ -0,0 +1,19 @@
1
+ import { useEffect, useRef } from "react";
2
+ import { useLayoutState } from "../../../../../hooks/useLayoutState";
3
+ import { getBorderBoxSizeHeight, useResizeObserver, } from "../../../../../hooks/useResizeObserver";
4
+ import { LayoutActionKind } from "../../../../../providers/layoutState";
5
+ export const useMeasureHeader = () => {
6
+ const { layoutDispatch } = useLayoutState();
7
+ const headerRef = useRef(null);
8
+ const { height } = useResizeObserver(headerRef, getBorderBoxSizeHeight) || {};
9
+ // Updates layout state header height.
10
+ useEffect(() => {
11
+ if (!height)
12
+ return;
13
+ layoutDispatch({
14
+ payload: height,
15
+ type: LayoutActionKind.UpdateHeaderHeight,
16
+ });
17
+ }, [height, layoutDispatch]);
18
+ return { headerRef };
19
+ };
@@ -128,6 +128,7 @@ export interface EntityConfig<T = any, I = any> extends TabConfig {
128
128
  detail: BackPageConfig;
129
129
  entityMapper?: EntityMapper<T, I>;
130
130
  exploreMode: ExploreMode;
131
+ explorerTitle?: SiteConfig["explorerTitle"];
131
132
  getId?: GetIdFunction<T>;
132
133
  getTitle?: GetTitleFunction<T>;
133
134
  list: ListConfig;
@@ -212,6 +213,7 @@ export interface ListViewConfig {
212
213
  enableDownload?: boolean;
213
214
  enableRowPreview?: boolean;
214
215
  enableRowSelection?: boolean;
216
+ enableTab?: boolean;
215
217
  listHero?: ComponentsConfig;
216
218
  rowPreviewView?: ComponentsConfig;
217
219
  rowSelectionView?: ComponentsConfig;
@@ -20,8 +20,7 @@ export function getDefaultConfig() {
20
20
  socials: [],
21
21
  },
22
22
  header: {
23
- Logo: null,
24
- navLinks: [],
23
+ logo: null,
25
24
  },
26
25
  },
27
26
  redirectRootToPath: "",
@@ -0,0 +1,17 @@
1
+ import { UseCurrentBreakpoint } from "./useCurrentBreakpoint";
2
+ export declare type UseBreakpoint = {
3
+ breakpoint?: UseCurrentBreakpoint;
4
+ lg: boolean;
5
+ lgDown: boolean;
6
+ lgUp: boolean;
7
+ md: boolean;
8
+ mdDown: boolean;
9
+ mdUp: boolean;
10
+ sm: boolean;
11
+ smDown: boolean;
12
+ smUp: boolean;
13
+ xs: boolean;
14
+ xsDown: boolean;
15
+ xsUp: boolean;
16
+ };
17
+ export declare const useBreakpoint: () => UseBreakpoint;
@@ -0,0 +1,34 @@
1
+ import { useCurrentBreakpoint, } from "./useCurrentBreakpoint";
2
+ export const useBreakpoint = () => {
3
+ const breakpoint = useCurrentBreakpoint();
4
+ // Current breakpoint.
5
+ const xs = breakpoint === "xs";
6
+ const sm = breakpoint === "sm";
7
+ const md = breakpoint === "md";
8
+ const lg = breakpoint === "lg";
9
+ // Current breakpoint, down.
10
+ const xsDown = xs;
11
+ const smDown = xs || sm;
12
+ const mdDown = xs || sm || md;
13
+ const lgDown = xs || sm || md || lg;
14
+ // Current breakpoint, up.
15
+ const xsUp = xs || sm || md || lg;
16
+ const smUp = sm || md || lg;
17
+ const mdUp = md || lg;
18
+ const lgUp = lg;
19
+ return {
20
+ breakpoint,
21
+ lg,
22
+ lgDown,
23
+ lgUp,
24
+ md,
25
+ mdDown,
26
+ mdUp,
27
+ sm,
28
+ smDown,
29
+ smUp,
30
+ xs,
31
+ xsDown,
32
+ xsUp,
33
+ };
34
+ };
@@ -9,6 +9,6 @@ export declare enum BREAKPOINT_FN_NAME {
9
9
  UP = "up"
10
10
  }
11
11
  declare type BreakpointFnName = BREAKPOINT_FN_NAME;
12
- declare type BreakpointKey = Breakpoint;
12
+ export declare type BreakpointKey = Breakpoint;
13
13
  export declare const useBreakpointHelper: (fnName: BreakpointFnName, breakpointKey: BreakpointKey) => boolean;
14
14
  export {};
@@ -0,0 +1,3 @@
1
+ import { BreakpointKey } from "./useBreakpointHelper";
2
+ export declare type UseCurrentBreakpoint = BreakpointKey | undefined;
3
+ export declare const useCurrentBreakpoint: () => UseCurrentBreakpoint;
@@ -0,0 +1,11 @@
1
+ import { useMemo } from "react";
2
+ import { BREAKPOINT_FN_NAME, useBreakpointHelper, } from "./useBreakpointHelper";
3
+ const breakpointKeys = ["xs", "sm", "md", "lg"];
4
+ export const useCurrentBreakpoint = () => {
5
+ const xs = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "xs");
6
+ const sm = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "sm");
7
+ const md = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "md");
8
+ const lg = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "lg");
9
+ const breakpoints = useMemo(() => ({ lg, md, sm, xs }), [lg, md, sm, xs]);
10
+ return breakpointKeys.find((key) => breakpoints[key]);
11
+ };
@@ -0,0 +1,10 @@
1
+ export interface UseMenu {
2
+ onClose: () => void;
3
+ onOpen: () => void;
4
+ open: boolean;
5
+ }
6
+ /**
7
+ * Menu functionality for menu dropdown.
8
+ * @returns menu functionality.
9
+ */
10
+ export declare const useMenu: () => UseMenu;
@@ -0,0 +1,17 @@
1
+ import { useCallback, useState } from "react";
2
+ /**
3
+ * Menu functionality for menu dropdown.
4
+ * @returns menu functionality.
5
+ */
6
+ export const useMenu = () => {
7
+ const [open, setOpen] = useState(false);
8
+ // Closes header menu.
9
+ const onClose = useCallback(() => {
10
+ setOpen(false);
11
+ }, []);
12
+ // Opens header menu.
13
+ const onOpen = useCallback(() => {
14
+ setOpen(true);
15
+ }, []);
16
+ return { onClose, onOpen, open };
17
+ };
@@ -1,12 +1,11 @@
1
- import { useRouter } from "next/router";
2
1
  import React, { useEffect, useMemo, useState } from "react";
3
2
  import { track } from "../../common/analytics/analytics";
4
3
  import { EVENT_NAME, EVENT_PARAM } from "../../common/analytics/entities";
5
- import { Tabs } from "../../components/common/Tabs/tabs";
6
4
  import { ComponentCreator } from "../../components/ComponentCreator/ComponentCreator";
7
5
  import { ClearAllFilters } from "../../components/Filter/components/ClearAllFilters/clearAllFilters";
8
6
  import { Filters, } from "../../components/Filter/components/Filters/filters";
9
7
  import { SearchAllFilters } from "../../components/Filter/components/SearchAllFilters/searchAllFilters";
8
+ import { Tabs } from "../../components/Index/components/Tabs/tabs";
10
9
  import { Index as IndexView } from "../../components/Index/index";
11
10
  import { SidebarButton } from "../../components/Layout/components/Sidebar/components/SidebarButton/sidebarButton";
12
11
  import { SidebarLabel } from "../../components/Layout/components/Sidebar/components/SidebarLabel/sidebarLabel";
@@ -21,30 +20,15 @@ import { useSummary } from "../../hooks/useSummary";
21
20
  import { ExploreActionKind } from "../../providers/exploreState";
22
21
  import { SELECT_CATEGORY_KEY } from "../../providers/exploreState/constants";
23
22
  import { DESKTOP_SM } from "../../theme/common/breakpoints";
24
- /**
25
- * Returns tabs to be used as a prop for the Tabs component.
26
- * @param entities - Entities config.
27
- * @returns tabs list.
28
- */
29
- function getTabs(entities) {
30
- return entities.map(({ label, route, tabIcon: icon, tabIconPosition: iconPosition }) => ({
31
- icon,
32
- iconPosition,
33
- label,
34
- value: route,
35
- }));
36
- }
37
23
  export const ExploreView = (props) => {
38
24
  const [isDrawerOpen, setIsDrawerOpen] = useState(false);
39
25
  const tabletDown = useBreakpointHelper(BREAKPOINT_FN_NAME.DOWN, DESKTOP_SM);
40
26
  const { config, entityConfig } = useConfig(); // Get app level config.
41
27
  const { exploreDispatch, exploreState } = useExploreState(); // Get the useReducer state and dispatch for "Explore".
42
- const { entities, explorerTitle, summaryConfig, trackingConfig } = config;
28
+ const { explorerTitle, summaryConfig, trackingConfig } = config;
43
29
  const { listView } = entityConfig;
44
30
  const { listHero, subTitleHero } = listView || {};
45
- const { categoryGroups, categoryViews, filterCount, tabValue } = exploreState;
46
- const { push } = useRouter();
47
- const tabs = getTabs(entities);
31
+ const { categoryGroups, categoryViews, filterCount } = exploreState;
48
32
  const { response: summaryResponse } = useSummary(); // Fetch summary.
49
33
  useEntityList(props); // Fetch entities.
50
34
  const { entityListType } = props;
@@ -98,15 +82,6 @@ export const ExploreView = (props) => {
98
82
  const onOpenDrawer = () => {
99
83
  setIsDrawerOpen(true);
100
84
  };
101
- /**
102
- * Callback fired when selected tab value changes.
103
- * - Sets state tabsValue to selected tab value.
104
- * - Executes a pushState and resets pagination.
105
- * @param tabValue - Selected tab value.
106
- */
107
- const onTabChange = (tabValue) => {
108
- push(`/${tabValue}`);
109
- };
110
85
  /**
111
86
  * Dispatch a SelectedEntityType action when entityListType changes.
112
87
  */
@@ -128,7 +103,7 @@ export const ExploreView = (props) => {
128
103
  React.createElement(ClearAllFilters, null),
129
104
  React.createElement(SearchAllFilters, { categoryViews: categoryViews, drawerOpen: isDrawerOpen, onFilter: onFilterChange.bind(null, true) })),
130
105
  React.createElement(Filters, { categoryFilters: categoryFilters, closeAncestor: onCloseDrawer, onFilter: onFilterChange.bind(null, false), trackFilterOpened: trackingConfig?.trackFilterOpened }))),
131
- React.createElement(IndexView, { className: props.className, List: renderList(exploreState, entityConfig, entityListType), ListHero: renderComponent(listHero), SideBarButton: tabletDown ? (React.createElement(SidebarButton, { count: filterCount, label: "Filter", onClick: onOpenDrawer })) : undefined, SubTitleHero: renderComponent(subTitleHero), Summaries: renderSummary(summaryConfig, summaryResponse), Tabs: React.createElement(Tabs, { onTabChange: onTabChange, tabs: tabs, value: tabValue }), title: explorerTitle })));
106
+ React.createElement(IndexView, { className: props.className, List: renderList(exploreState, entityConfig, entityListType), ListHero: renderComponent(listHero), SideBarButton: tabletDown ? (React.createElement(SidebarButton, { count: filterCount, label: "Filter", onClick: onOpenDrawer })) : undefined, SubTitleHero: renderComponent(subTitleHero), Summaries: renderSummary(summaryConfig, summaryResponse), Tabs: React.createElement(Tabs, null), title: entityConfig.explorerTitle || explorerTitle })));
132
107
  };
133
108
  /**
134
109
  * Builds the category views into category views grouped by the given category group configuration.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@databiosphere/findable-ui",
3
- "version": "7.0.0",
3
+ "version": "8.0.0",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "jest",