@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,15 +1,8 @@
1
1
  import { Button, Divider } from "@mui/material";
2
2
  import { useRouter } from "next/router";
3
3
  import React, { CSSProperties, forwardRef, Fragment, ReactNode } from "react";
4
- import {
5
- ElementAlignment,
6
- ELEMENT_ALIGNMENT,
7
- } from "../../../../../../../../common/entities";
8
- import {
9
- BREAKPOINT_FN_NAME,
10
- useBreakpointHelper,
11
- } from "../../../../../../../../hooks/useBreakpointHelper";
12
- import { DESKTOP_SM } from "../../../../../../../../theme/common/breakpoints";
4
+ import { useBreakpoint } from "../../../../../../../../hooks/useBreakpoint";
5
+ import { BreakpointKey } from "../../../../../../../../hooks/useBreakpointHelper";
13
6
  import { ANCHOR_TARGET } from "../../../../../../../Links/common/entities";
14
7
  import { isClientSideNavigation } from "../../../../../../../Links/common/utils";
15
8
  import { HeaderProps } from "../../../../header";
@@ -20,15 +13,15 @@ import { Navigation as Links } from "./navigation.styles";
20
13
 
21
14
  export interface NavLinkItem {
22
15
  divider?: boolean;
23
- flatten?: boolean;
16
+ flatten?: Partial<Record<BreakpointKey, boolean>>;
24
17
  label: ReactNode;
25
18
  menuItems?: MenuItem[];
26
19
  target?: ANCHOR_TARGET;
27
20
  url: string;
21
+ visible?: Partial<Record<BreakpointKey, boolean>>;
28
22
  }
29
23
 
30
24
  export interface NavigationProps {
31
- alignment?: ElementAlignment;
32
25
  className?: string;
33
26
  closeAncestor?: () => void;
34
27
  headerProps?: HeaderProps;
@@ -38,25 +31,13 @@ export interface NavigationProps {
38
31
 
39
32
  export const Navigation = forwardRef<HTMLDivElement, NavigationProps>(
40
33
  function Navigation(
41
- {
42
- alignment = ELEMENT_ALIGNMENT.LEFT,
43
- className,
44
- closeAncestor,
45
- headerProps,
46
- links,
47
- style,
48
- }: NavigationProps,
34
+ { className, closeAncestor, headerProps, links, style }: NavigationProps,
49
35
  ref
50
36
  ): JSX.Element {
51
- const smDesktop = useBreakpointHelper(BREAKPOINT_FN_NAME.UP, DESKTOP_SM);
37
+ const { mdUp } = useBreakpoint();
52
38
  const router = useRouter();
53
39
  return (
54
- <Links
55
- ref={ref}
56
- alignment={alignment}
57
- className={className}
58
- style={style}
59
- >
40
+ <Links ref={ref} className={className} style={style}>
60
41
  {links.map(
61
42
  (
62
43
  { divider, label, menuItems, target = ANCHOR_TARGET.SELF, url },
@@ -64,7 +45,7 @@ export const Navigation = forwardRef<HTMLDivElement, NavigationProps>(
64
45
  ) =>
65
46
  menuItems ? (
66
47
  <Fragment key={i}>
67
- {smDesktop ? (
48
+ {mdUp ? (
68
49
  <NavigationMenu
69
50
  closeAncestor={closeAncestor}
70
51
  menuItems={menuItems}
@@ -1,23 +1,17 @@
1
1
  import { Meta, StoryObj } from "@storybook/react";
2
2
  import React from "react";
3
- import { ELEMENT_ALIGNMENT } from "../../../../common/entities";
4
3
  import logo from "../../../../images/logo.svg";
5
4
  import { DiscourseIcon } from "../../../common/CustomIcon/components/DiscourseIcon/discourseIcon";
6
5
  import { GitHubIcon } from "../../../common/CustomIcon/components/GitHubIcon/gitHubIcon";
7
6
  import { XIcon } from "../../../common/CustomIcon/components/XIcon/xIcon";
8
7
  import { YouTubeIcon } from "../../../common/CustomIcon/components/YouTubeIcon/youTubeIcon";
9
- import { HEADER_NAVIGATION_LABEL } from "./common/constants";
10
8
  import { Logo } from "./components/Content/components/Logo/logo";
11
9
  import { Header } from "./header";
12
10
 
13
11
  export default {
14
12
  argTypes: {
15
- Logo: { control: { disable: true } },
16
13
  authenticationEnabled: { control: "boolean" },
17
- navAlignment: {
18
- control: "select",
19
- options: [ELEMENT_ALIGNMENT.LEFT, ELEMENT_ALIGNMENT.CENTER],
20
- },
14
+ logo: { control: { disable: true } },
21
15
  navLinks: { control: "array" },
22
16
  searchEnabled: { control: "boolean" },
23
17
  slogan: { control: "text" },
@@ -36,45 +30,48 @@ const url = "/";
36
30
 
37
31
  export const HeaderStory: Story = {
38
32
  args: {
39
- Logo: <Logo alt="Logo" height={40} link="/" src={logo} />,
40
33
  authenticationEnabled: false,
41
- navAlignment: ELEMENT_ALIGNMENT.CENTER,
42
- navLinks: [
43
- {
44
- label: "Overview",
45
- url,
46
- },
47
- {
48
- label: "Learn",
49
- url,
50
- },
51
- {
52
- label: "Datasets",
53
- url,
54
- },
55
- {
56
- label: "More",
57
- menuItems: [
58
- {
59
- label: "Team",
60
- url,
61
- },
62
- {
63
- label: "FAQ",
64
- url,
65
- },
66
- {
67
- label: "Help",
68
- url,
69
- },
70
- ],
71
- url: "",
72
- },
34
+ logo: <Logo alt="Logo" height={40} link="/" src={logo} />,
35
+ navigation: [
36
+ undefined,
37
+ [
38
+ {
39
+ label: "Overview",
40
+ url,
41
+ },
42
+ {
43
+ label: "Learn",
44
+ url,
45
+ },
46
+ {
47
+ label: "Datasets",
48
+ url,
49
+ },
50
+ {
51
+ label: "More",
52
+ menuItems: [
53
+ {
54
+ label: "Team",
55
+ url,
56
+ },
57
+ {
58
+ label: "FAQ",
59
+ url,
60
+ },
61
+ {
62
+ label: "Help",
63
+ url,
64
+ },
65
+ ],
66
+ url: "",
67
+ },
68
+ ],
69
+ undefined,
73
70
  ],
74
71
  searchEnabled: true,
75
72
  slogan: "Header Slogan",
76
73
  socialMedia: {
77
- label: HEADER_NAVIGATION_LABEL.SOCIALS,
74
+ label: "Follow Us",
78
75
  socials: [
79
76
  {
80
77
  Icon: XIcon,
@@ -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";
@@ -16,8 +17,30 @@ export const AppBar = styled(MAppBar)`
16
17
  }
17
18
  ` as typeof MAppBar;
18
19
 
19
- export const HeaderSmAppBar = styled(AppBar)`
20
- .MuiToolbar-root {
21
- gap: 8px;
20
+ const group = css`
21
+ align-items: center;
22
+ display: flex;
23
+ flex: 1;
24
+ `;
25
+
26
+ export const Left = styled.div`
27
+ ${group};
28
+ gap: 16px;
29
+ justify-content: flex-start;
30
+
31
+ .MuiButton-navPrimary {
32
+ &:first-of-type {
33
+ margin-left: 24px;
34
+ }
22
35
  }
23
- ` as typeof MAppBar;
36
+ `;
37
+
38
+ export const Center = styled.div`
39
+ ${group};
40
+ justify-content: center;
41
+ `;
42
+
43
+ export const Right = styled.div`
44
+ ${group};
45
+ justify-content: flex-end;
46
+ `;
@@ -1,50 +1,35 @@
1
1
  import { Fade, Toolbar } from "@mui/material";
2
- import React, {
3
- ReactNode,
4
- useCallback,
5
- useEffect,
6
- useRef,
7
- useState,
8
- } from "react";
2
+ import React, { ReactNode } from "react";
3
+ import { ComponentsConfig } from "../../../../config/entities";
4
+ import { useBreakpoint } from "../../../../hooks/useBreakpoint";
5
+ import { useMenu } from "../../../../hooks/useMenu";
9
6
  import {
10
- ElementAlignment,
11
- ELEMENT_ALIGNMENT,
12
- } from "../../../../common/entities";
13
- import {
14
- BREAKPOINT_FN_NAME,
15
- useBreakpointHelper,
16
- } from "../../../../hooks/useBreakpointHelper";
17
- import { useLayoutState } from "../../../../hooks/useLayoutState";
18
- import {
19
- getBorderBoxSizeHeight,
20
- useResizeObserver,
21
- } from "../../../../hooks/useResizeObserver";
22
- import { LayoutActionKind } from "../../../../providers/layoutState";
23
- import { DESKTOP, DESKTOP_SM } from "../../../../theme/common/breakpoints";
24
- import { FADE_TRANSITION_PROPS } from "./common/constants";
25
- import { SocialMedia } from "./common/entities";
26
- import { getHeaderNavigationLinks } from "./common/utils";
7
+ APP_BAR_PROPS,
8
+ FADE_TRANSITION_PROPS,
9
+ TOOLBAR_PROPS,
10
+ } from "./common/constants";
11
+ import { Navigation, SocialMedia } from "./common/entities";
12
+ import { getNavigationLinks } from "./common/utils";
13
+ import { Announcements } from "./components/Announcements/announcements";
27
14
  import { Actions } from "./components/Content/components/Actions/actions";
28
15
  import { Authentication } from "./components/Content/components/Actions/components/Authentication/authentication";
29
16
  import { Menu } from "./components/Content/components/Actions/components/Menu/menu";
30
17
  import { Search } from "./components/Content/components/Actions/components/Search/search";
31
- import {
32
- Navigation,
33
- NavLinkItem,
34
- } from "./components/Content/components/Navigation/navigation";
18
+ import { Navigation as DXNavigation } from "./components/Content/components/Navigation/navigation";
35
19
  import { Slogan } from "./components/Content/components/Slogan/slogan";
36
20
  import { Divider } from "./components/Content/components/Slogan/slogan.styles";
37
21
  import { Socials } from "./components/Content/components/Socials/socials.styles";
38
- import { AppBar as HeaderAppBar, HeaderSmAppBar } from "./header.styles";
22
+ import { AppBar, Center, Left, Right } from "./header.styles";
23
+ import { useHeaderVisibility } from "./hooks/useHeaderVisibility";
24
+ import { useMeasureHeader } from "./hooks/useMeasureHeader";
39
25
 
40
26
  export interface HeaderProps {
41
27
  actions?: ReactNode;
42
- Announcements?: ReactNode;
28
+ announcements?: ComponentsConfig;
43
29
  authenticationEnabled?: boolean;
44
30
  className?: string;
45
- Logo: ReactNode;
46
- navAlignment?: ElementAlignment;
47
- navLinks: NavLinkItem[];
31
+ logo: ReactNode;
32
+ navigation?: Navigation;
48
33
  searchEnabled?: boolean;
49
34
  searchURL?: string;
50
35
  slogan?: ReactNode;
@@ -52,126 +37,103 @@ export interface HeaderProps {
52
37
  }
53
38
 
54
39
  export const Header = ({ ...headerProps }: HeaderProps): JSX.Element => {
40
+ const { breakpoint } = useBreakpoint();
41
+ const { isIn } = useHeaderVisibility(headerProps);
42
+ const { headerRef } = useMeasureHeader();
43
+ const { onClose, onOpen, open } = useMenu();
55
44
  const {
56
- Announcements,
57
- authenticationEnabled,
58
45
  actions,
46
+ announcements,
47
+ authenticationEnabled,
59
48
  className,
60
- Logo,
61
- navAlignment = ELEMENT_ALIGNMENT.LEFT,
62
- navLinks,
49
+ logo,
50
+ navigation: [navItemsL, navItemsC, navItemsR] = [],
63
51
  searchEnabled,
64
52
  searchURL,
65
53
  slogan,
66
54
  socialMedia,
67
55
  } = headerProps;
68
- const { layoutDispatch } = useLayoutState();
69
- const headerRef = useRef<HTMLElement>(null);
70
- const { height } = useResizeObserver(headerRef, getBorderBoxSizeHeight) || {};
71
- const [menuOpen, setMenuOpen] = useState<boolean>(false);
72
- const onlySmDesktop = useBreakpointHelper(
73
- BREAKPOINT_FN_NAME.ONLY,
74
- DESKTOP_SM
75
- );
76
- const smDesktop = useBreakpointHelper(BREAKPOINT_FN_NAME.UP, DESKTOP_SM);
77
- const desktop = useBreakpointHelper(BREAKPOINT_FN_NAME.UP, DESKTOP);
78
- const AppBar =
79
- navAlignment === ELEMENT_ALIGNMENT.RIGHT ? HeaderSmAppBar : HeaderAppBar;
80
- const showActions = searchEnabled || authenticationEnabled || !smDesktop;
81
- const isNavigationIn = smDesktop;
82
- const isSloganIn = Boolean(slogan) && smDesktop;
83
- const isSocialsIn = Boolean(socialMedia) && desktop;
84
- const fadeProps = FADE_TRANSITION_PROPS;
85
-
86
- // Closes header menu.
87
- const closeMenu = useCallback((): void => {
88
- setMenuOpen(false);
89
- }, []);
90
-
91
- // Opens header menu.
92
- const openMenu = useCallback((): void => {
93
- setMenuOpen(true);
94
- }, []);
95
-
96
- // Updates layout state header height.
97
- useEffect(() => {
98
- if (!height) return;
99
- layoutDispatch({
100
- payload: height,
101
- type: LayoutActionKind.UpdateHeaderHeight,
102
- });
103
- }, [height, layoutDispatch]);
104
56
 
105
57
  return (
106
- <AppBar
107
- ref={headerRef}
108
- className={className}
109
- elevation={1}
110
- position="fixed"
111
- >
58
+ <AppBar {...APP_BAR_PROPS} ref={headerRef} className={className}>
112
59
  {/* Announcements */}
113
- {Announcements}
60
+ <Announcements announcements={announcements} />
114
61
  {/* Toolbar */}
115
- <Toolbar variant="dense">
116
- {/* Logo */}
117
- {Logo}
118
- {/* Divider */}
119
- <Fade
120
- in={isSloganIn}
121
- style={{ transitionDelay: isSloganIn ? "50ms" : "0ms" }}
122
- {...fadeProps}
123
- >
124
- <Divider orientation="vertical" />
62
+ <Toolbar {...TOOLBAR_PROPS}>
63
+ {/* Left group */}
64
+ <Fade {...FADE_TRANSITION_PROPS} in={isIn.isLeftGroupIn}>
65
+ <Left>
66
+ {/* Logo */}
67
+ {logo}
68
+ {/* Divider */}
69
+ {isIn.isSloganIn && <Divider flexItem orientation="vertical" />}
70
+ {/* Slogan */}
71
+ {isIn.isSloganIn && <Slogan slogan={slogan} />}
72
+ {/* Left navigation */}
73
+ {isIn.isLeftNavigationIn && (
74
+ <DXNavigation
75
+ headerProps={headerProps}
76
+ links={getNavigationLinks(navItemsL, breakpoint)}
77
+ />
78
+ )}
79
+ </Left>
125
80
  </Fade>
126
- {/* Slogan */}
127
- <Fade
128
- in={isSloganIn}
129
- style={{ transitionDelay: isSloganIn ? "50ms" : "0ms" }}
130
- {...fadeProps}
131
- >
132
- <Slogan slogan={slogan} />
81
+ {/* Center group */}
82
+ <Fade {...FADE_TRANSITION_PROPS} in={isIn.isCenterGroupIn}>
83
+ <Center>
84
+ {/* Center navigation */}
85
+ {isIn.isCenterNavigationIn && (
86
+ <DXNavigation
87
+ headerProps={headerProps}
88
+ links={getNavigationLinks(navItemsC, breakpoint)}
89
+ />
90
+ )}
91
+ </Center>
133
92
  </Fade>
134
- {/* Navigation */}
135
- <Fade in={isNavigationIn} {...fadeProps}>
136
- <Navigation
137
- alignment={navAlignment}
138
- headerProps={headerProps}
139
- links={getHeaderNavigationLinks(
140
- navLinks,
141
- socialMedia,
142
- onlySmDesktop
93
+ {/* Right group */}
94
+ <Fade {...FADE_TRANSITION_PROPS} in={isIn.isRightGroupIn}>
95
+ <Right>
96
+ {/* Navigation */}
97
+ {isIn.isRightNavigationIn && (
98
+ <DXNavigation
99
+ headerProps={headerProps}
100
+ links={getNavigationLinks(navItemsR)}
101
+ />
102
+ )}
103
+ {/* Socials */}
104
+ {isIn.isSocialsIn && (
105
+ <Socials
106
+ buttonSize="small"
107
+ socials={socialMedia?.socials || []}
108
+ />
109
+ )}
110
+ {/* Actions */}
111
+ {isIn.isActionsIn && (
112
+ <Actions>
113
+ {/* Search */}
114
+ <Search
115
+ closeMenu={onClose}
116
+ searchEnabled={searchEnabled}
117
+ searchURL={searchURL}
118
+ />
119
+ {/* Authentication */}
120
+ <Authentication
121
+ authenticationEnabled={authenticationEnabled}
122
+ closeMenu={onClose}
123
+ />
124
+ {/* Additional actions i.e. call-to-action button */}
125
+ {actions}
126
+ {/* Menu */}
127
+ <Menu
128
+ closeMenu={onClose}
129
+ headerProps={headerProps}
130
+ open={open}
131
+ openMenu={onOpen}
132
+ />
133
+ </Actions>
143
134
  )}
144
- />
135
+ </Right>
145
136
  </Fade>
146
- {/* Socials */}
147
- {socialMedia && (
148
- <Fade in={isSocialsIn} {...fadeProps}>
149
- <Socials buttonSize="small" socials={socialMedia.socials} />
150
- </Fade>
151
- )}
152
- {/* Actions */}
153
- <Actions showActions={showActions}>
154
- {/* Search */}
155
- <Search
156
- closeMenu={closeMenu}
157
- searchEnabled={searchEnabled}
158
- searchURL={searchURL}
159
- />
160
- {/* Authentication */}
161
- <Authentication
162
- authenticationEnabled={authenticationEnabled}
163
- closeMenu={closeMenu}
164
- />
165
- {/* Additional actions i.e. call-to-action button */}
166
- {actions}
167
- {/* Menu */}
168
- <Menu
169
- closeMenu={closeMenu}
170
- headerProps={headerProps}
171
- open={menuOpen}
172
- openMenu={openMenu}
173
- />
174
- </Actions>
175
137
  </Toolbar>
176
138
  </AppBar>
177
139
  );
@@ -0,0 +1,74 @@
1
+ import { useBreakpoint } from "../../../../../hooks/useBreakpoint";
2
+ import { HeaderProps } from "../header";
3
+
4
+ export interface UseHeaderVisibility {
5
+ isIn: {
6
+ isActionsIn: boolean;
7
+ isCenterGroupIn: boolean;
8
+ isCenterNavigationIn: boolean;
9
+ isLeftGroupIn: boolean;
10
+ isLeftNavigationIn: boolean;
11
+ isRightGroupIn: boolean;
12
+ isRightNavigationIn: boolean;
13
+ isSloganIn: boolean;
14
+ isSocialsIn: boolean;
15
+ };
16
+ }
17
+
18
+ /**
19
+ * Returns header component visibility for header related rendering logic.
20
+ * @param headerProps - Header component props.
21
+ * @returns header component visibility.
22
+ */
23
+ export const useHeaderVisibility = (
24
+ headerProps: HeaderProps
25
+ ): UseHeaderVisibility => {
26
+ const { lgUp, mdUp } = useBreakpoint();
27
+ // Header configuration.
28
+ const {
29
+ actions,
30
+ authenticationEnabled,
31
+ logo,
32
+ navigation: [navItemsL, navItemsC, navItemsR] = [],
33
+ searchEnabled,
34
+ slogan,
35
+ socialMedia,
36
+ } = headerProps;
37
+ // Header content.
38
+ const hasActions = Boolean(actions);
39
+ const hasLogo = Boolean(logo);
40
+ const hasMenu = !mdUp;
41
+ const hasNavItemsC = Boolean(navItemsC);
42
+ const hasNavItemsL = Boolean(navItemsL);
43
+ const hasNavItemsR = Boolean(navItemsR);
44
+ const hasSlogan = Boolean(slogan);
45
+ const hasSocials = Boolean(socialMedia);
46
+ // Determines header content visibility.
47
+ const isActionsIn =
48
+ hasActions || searchEnabled || authenticationEnabled || hasMenu;
49
+ const isNavigationIn = mdUp;
50
+ const isSloganIn = hasSlogan && mdUp;
51
+ const isSocialsIn = hasSocials && lgUp;
52
+ // Determines navigation visibility.
53
+ const isCenterNavigationIn = isNavigationIn && hasNavItemsC;
54
+ const isLeftNavigationIn = isNavigationIn && hasNavItemsL;
55
+ const isRightNavigationIn = isNavigationIn && hasNavItemsR;
56
+ // Determines group visibility.
57
+ const isLeftGroupIn = hasLogo || isSocialsIn || isLeftNavigationIn;
58
+ const isCenterGroupIn = isCenterNavigationIn;
59
+ const isRightGroupIn = isRightNavigationIn || isSocialsIn || isActionsIn;
60
+
61
+ return {
62
+ isIn: {
63
+ isActionsIn,
64
+ isCenterGroupIn,
65
+ isCenterNavigationIn,
66
+ isLeftGroupIn,
67
+ isLeftNavigationIn,
68
+ isRightGroupIn,
69
+ isRightNavigationIn,
70
+ isSloganIn,
71
+ isSocialsIn,
72
+ },
73
+ };
74
+ };
@@ -0,0 +1,28 @@
1
+ import { RefObject, useEffect, useRef } from "react";
2
+ import { useLayoutState } from "../../../../../hooks/useLayoutState";
3
+ import {
4
+ getBorderBoxSizeHeight,
5
+ useResizeObserver,
6
+ } from "../../../../../hooks/useResizeObserver";
7
+ import { LayoutActionKind } from "../../../../../providers/layoutState";
8
+
9
+ export interface UseMeasureHeader {
10
+ headerRef: RefObject<HTMLElement>;
11
+ }
12
+
13
+ export const useMeasureHeader = (): UseMeasureHeader => {
14
+ const { layoutDispatch } = useLayoutState();
15
+ const headerRef = useRef<HTMLElement>(null);
16
+ const { height } = useResizeObserver(headerRef, getBorderBoxSizeHeight) || {};
17
+
18
+ // Updates layout state header height.
19
+ useEffect(() => {
20
+ if (!height) return;
21
+ layoutDispatch({
22
+ payload: height,
23
+ type: LayoutActionKind.UpdateHeaderHeight,
24
+ });
25
+ }, [height, layoutDispatch]);
26
+
27
+ return { headerRef };
28
+ };
@@ -159,6 +159,7 @@ export interface EntityConfig<T = any, I = any> extends TabConfig {
159
159
  detail: BackPageConfig;
160
160
  entityMapper?: EntityMapper<T, I>;
161
161
  exploreMode: ExploreMode;
162
+ explorerTitle?: SiteConfig["explorerTitle"];
162
163
  getId?: GetIdFunction<T>;
163
164
  getTitle?: GetTitleFunction<T>;
164
165
  list: ListConfig;
@@ -262,6 +263,7 @@ export interface ListViewConfig {
262
263
  enableDownload?: boolean;
263
264
  enableRowPreview?: boolean;
264
265
  enableRowSelection?: boolean;
266
+ enableTab?: boolean;
265
267
  listHero?: ComponentsConfig;
266
268
  rowPreviewView?: ComponentsConfig; // Row preview view is expected to be a modal or drawer or similar.
267
269
  rowSelectionView?: ComponentsConfig;
@@ -23,8 +23,7 @@ export function getDefaultConfig(): SiteConfig {
23
23
  socials: [],
24
24
  },
25
25
  header: {
26
- Logo: null,
27
- navLinks: [],
26
+ logo: null,
28
27
  },
29
28
  },
30
29
  redirectRootToPath: "",
@@ -0,0 +1,54 @@
1
+ import {
2
+ UseCurrentBreakpoint,
3
+ useCurrentBreakpoint,
4
+ } from "./useCurrentBreakpoint";
5
+
6
+ export type UseBreakpoint = {
7
+ breakpoint?: UseCurrentBreakpoint; // current breakpoint.
8
+ lg: boolean; // desktop.
9
+ lgDown: boolean;
10
+ lgUp: boolean;
11
+ md: boolean; // small desktop.
12
+ mdDown: boolean;
13
+ mdUp: boolean;
14
+ sm: boolean; // tablet.
15
+ smDown: boolean;
16
+ smUp: boolean;
17
+ xs: boolean; // mobile.
18
+ xsDown: boolean;
19
+ xsUp: boolean;
20
+ };
21
+
22
+ export const useBreakpoint = (): UseBreakpoint => {
23
+ const breakpoint = useCurrentBreakpoint();
24
+ // Current breakpoint.
25
+ const xs = breakpoint === "xs";
26
+ const sm = breakpoint === "sm";
27
+ const md = breakpoint === "md";
28
+ const lg = breakpoint === "lg";
29
+ // Current breakpoint, down.
30
+ const xsDown = xs;
31
+ const smDown = xs || sm;
32
+ const mdDown = xs || sm || md;
33
+ const lgDown = xs || sm || md || lg;
34
+ // Current breakpoint, up.
35
+ const xsUp = xs || sm || md || lg;
36
+ const smUp = sm || md || lg;
37
+ const mdUp = md || lg;
38
+ const lgUp = lg;
39
+ return {
40
+ breakpoint,
41
+ lg,
42
+ lgDown,
43
+ lgUp,
44
+ md,
45
+ mdDown,
46
+ mdUp,
47
+ sm,
48
+ smDown,
49
+ smUp,
50
+ xs,
51
+ xsDown,
52
+ xsUp,
53
+ };
54
+ };