@databiosphere/findable-ui 7.0.0 → 8.0.1

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 (90) hide show
  1. package/lib/common/entities.d.ts +0 -9
  2. package/lib/common/entities.js +1 -9
  3. package/lib/components/Filter/components/FilterLabel/filterLabel.styles.d.ts +1 -1
  4. package/lib/components/Index/components/Tabs/common/utils.d.ts +8 -0
  5. package/lib/components/Index/components/Tabs/common/utils.js +18 -0
  6. package/lib/components/Index/components/Tabs/tabs.d.ts +2 -0
  7. package/lib/components/Index/components/Tabs/tabs.js +20 -0
  8. package/lib/components/Layout/components/Header/common/constants.d.ts +4 -9
  9. package/lib/components/Layout/components/Header/common/constants.js +8 -9
  10. package/lib/components/Layout/components/Header/common/entities.d.ts +6 -0
  11. package/lib/components/Layout/components/Header/common/utils.d.ts +12 -17
  12. package/lib/components/Layout/components/Header/common/utils.js +77 -59
  13. package/lib/components/Layout/components/Header/components/Announcements/announcements.d.ts +6 -0
  14. package/lib/components/Layout/components/Header/components/Announcements/announcements.js +7 -0
  15. package/lib/components/Layout/components/Header/components/Content/components/Actions/actions.d.ts +1 -2
  16. package/lib/components/Layout/components/Header/components/Content/components/Actions/actions.js +2 -2
  17. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/RequestAuthentication/requestAuthentication.js +8 -15
  18. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/RequestAuthentication/requestAuthentication.styles.d.ts +1 -1
  19. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Content/components/Navigation/navigation.styles.js +2 -0
  20. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Toolbar/toolbar.d.ts +4 -3
  21. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Toolbar/toolbar.js +4 -3
  22. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/menu.d.ts +1 -0
  23. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Menu/menu.js +18 -20
  24. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchButton/searchButton.js +5 -12
  25. package/lib/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchButton/searchButton.styles.d.ts +1 -1
  26. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationDrawer/navigationDrawer.d.ts +2 -1
  27. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationDrawer/navigationDrawer.js +2 -2
  28. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.d.ts +2 -1
  29. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.js +5 -6
  30. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.styles.js +10 -4
  31. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenuItems/navigationMenuItems.d.ts +2 -1
  32. package/lib/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenuItems/navigationMenuItems.js +3 -3
  33. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.d.ts +4 -3
  34. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.js +6 -8
  35. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.d.ts +1 -6
  36. package/lib/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.js +5 -19
  37. package/lib/components/Layout/components/Header/header.d.ts +5 -7
  38. package/lib/components/Layout/components/Header/header.js +38 -59
  39. package/lib/components/Layout/components/Header/header.stories.js +38 -41
  40. package/lib/components/Layout/components/Header/header.styles.d.ts +13 -1
  41. package/lib/components/Layout/components/Header/header.styles.js +23 -3
  42. package/lib/components/Layout/components/Header/hooks/useHeaderVisibility.d.ts +20 -0
  43. package/lib/components/Layout/components/Header/hooks/useHeaderVisibility.js +46 -0
  44. package/lib/components/Layout/components/Header/hooks/useMeasureHeader.d.ts +5 -0
  45. package/lib/components/Layout/components/Header/hooks/useMeasureHeader.js +19 -0
  46. package/lib/config/entities.d.ts +2 -0
  47. package/lib/config/utils.js +1 -2
  48. package/lib/hooks/useBreakpoint.d.ts +17 -0
  49. package/lib/hooks/useBreakpoint.js +34 -0
  50. package/lib/hooks/useBreakpointHelper.d.ts +1 -1
  51. package/lib/hooks/useCurrentBreakpoint.d.ts +3 -0
  52. package/lib/hooks/useCurrentBreakpoint.js +11 -0
  53. package/lib/hooks/useMenu.d.ts +10 -0
  54. package/lib/hooks/useMenu.js +17 -0
  55. package/lib/theme/common/components.js +17 -0
  56. package/lib/views/ExploreView/exploreView.js +4 -29
  57. package/package.json +1 -1
  58. package/src/common/entities.ts +0 -11
  59. package/src/components/Index/components/Tabs/common/utils.ts +33 -0
  60. package/src/components/Index/components/Tabs/tabs.tsx +23 -0
  61. package/src/components/Layout/components/Header/common/constants.ts +14 -10
  62. package/src/components/Layout/components/Header/common/entities.ts +7 -0
  63. package/src/components/Layout/components/Header/common/utils.ts +89 -66
  64. package/src/components/Layout/components/Header/components/Announcements/announcements.tsx +14 -0
  65. package/src/components/Layout/components/Header/components/Content/components/Actions/actions.tsx +2 -6
  66. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Authentication/components/RequestAuthentication/requestAuthentication.tsx +21 -32
  67. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Content/components/Navigation/navigation.styles.ts +2 -0
  68. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Menu/components/Toolbar/toolbar.tsx +8 -6
  69. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Menu/menu.tsx +22 -27
  70. package/src/components/Layout/components/Header/components/Content/components/Actions/components/Search/components/SearchButton/searchButton.tsx +11 -22
  71. package/src/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationDrawer/navigationDrawer.tsx +3 -0
  72. package/src/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.styles.ts +15 -5
  73. package/src/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenu/navigationMenu.tsx +10 -8
  74. package/src/components/Layout/components/Header/components/Content/components/Navigation/components/NavigationMenuItems/navigationMenuItems.tsx +4 -0
  75. package/src/components/Layout/components/Header/components/Content/components/Navigation/navigation.styles.ts +6 -30
  76. package/src/components/Layout/components/Header/components/Content/components/Navigation/navigation.tsx +12 -21
  77. package/src/components/Layout/components/Header/header.stories.tsx +38 -41
  78. package/src/components/Layout/components/Header/header.styles.ts +27 -4
  79. package/src/components/Layout/components/Header/header.tsx +102 -137
  80. package/src/components/Layout/components/Header/hooks/useHeaderVisibility.ts +74 -0
  81. package/src/components/Layout/components/Header/hooks/useMeasureHeader.ts +28 -0
  82. package/src/config/entities.ts +2 -0
  83. package/src/config/utils.ts +1 -2
  84. package/src/hooks/useBreakpoint.ts +54 -0
  85. package/src/hooks/useBreakpointHelper.ts +1 -1
  86. package/src/hooks/useCurrentBreakpoint.ts +23 -0
  87. package/src/hooks/useMenu.ts +27 -0
  88. package/src/theme/common/components.ts +17 -0
  89. package/src/views/ExploreView/exploreView.tsx +5 -34
  90. package/types/data-explorer-ui.d.ts +1 -0
@@ -1,50 +1,36 @@
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 { usePathname } from "next/navigation";
3
+ import React, { ReactNode } from "react";
4
+ import { ComponentsConfig } from "../../../../config/entities";
5
+ import { useBreakpoint } from "../../../../hooks/useBreakpoint";
6
+ import { useMenu } from "../../../../hooks/useMenu";
9
7
  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";
8
+ APP_BAR_PROPS,
9
+ FADE_TRANSITION_PROPS,
10
+ TOOLBAR_PROPS,
11
+ } from "./common/constants";
12
+ import { Navigation, SocialMedia } from "./common/entities";
13
+ import { getNavigationLinks } from "./common/utils";
14
+ import { Announcements } from "./components/Announcements/announcements";
27
15
  import { Actions } from "./components/Content/components/Actions/actions";
28
16
  import { Authentication } from "./components/Content/components/Actions/components/Authentication/authentication";
29
17
  import { Menu } from "./components/Content/components/Actions/components/Menu/menu";
30
18
  import { Search } from "./components/Content/components/Actions/components/Search/search";
31
- import {
32
- Navigation,
33
- NavLinkItem,
34
- } from "./components/Content/components/Navigation/navigation";
19
+ import { Navigation as DXNavigation } from "./components/Content/components/Navigation/navigation";
35
20
  import { Slogan } from "./components/Content/components/Slogan/slogan";
36
21
  import { Divider } from "./components/Content/components/Slogan/slogan.styles";
37
22
  import { Socials } from "./components/Content/components/Socials/socials.styles";
38
- import { AppBar as HeaderAppBar, HeaderSmAppBar } from "./header.styles";
23
+ import { AppBar, Center, Left, Right } from "./header.styles";
24
+ import { useHeaderVisibility } from "./hooks/useHeaderVisibility";
25
+ import { useMeasureHeader } from "./hooks/useMeasureHeader";
39
26
 
40
27
  export interface HeaderProps {
41
28
  actions?: ReactNode;
42
- Announcements?: ReactNode;
29
+ announcements?: ComponentsConfig;
43
30
  authenticationEnabled?: boolean;
44
31
  className?: string;
45
- Logo: ReactNode;
46
- navAlignment?: ElementAlignment;
47
- navLinks: NavLinkItem[];
32
+ logo: ReactNode;
33
+ navigation?: Navigation;
48
34
  searchEnabled?: boolean;
49
35
  searchURL?: string;
50
36
  slogan?: ReactNode;
@@ -52,126 +38,105 @@ export interface HeaderProps {
52
38
  }
53
39
 
54
40
  export const Header = ({ ...headerProps }: HeaderProps): JSX.Element => {
41
+ const { breakpoint } = useBreakpoint();
42
+ const { isIn } = useHeaderVisibility(headerProps);
43
+ const { headerRef } = useMeasureHeader();
44
+ const { onClose, onOpen, open } = useMenu();
45
+ const pathname = usePathname();
55
46
  const {
56
- Announcements,
57
- authenticationEnabled,
58
47
  actions,
48
+ announcements,
49
+ authenticationEnabled,
59
50
  className,
60
- Logo,
61
- navAlignment = ELEMENT_ALIGNMENT.LEFT,
62
- navLinks,
51
+ logo,
52
+ navigation: [navItemsL, navItemsC, navItemsR] = [],
63
53
  searchEnabled,
64
54
  searchURL,
65
55
  slogan,
66
56
  socialMedia,
67
57
  } = 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]);
58
+ const navigationProps = { headerProps, pathname };
104
59
 
105
60
  return (
106
- <AppBar
107
- ref={headerRef}
108
- className={className}
109
- elevation={1}
110
- position="fixed"
111
- >
61
+ <AppBar {...APP_BAR_PROPS} ref={headerRef} className={className}>
112
62
  {/* Announcements */}
113
- {Announcements}
63
+ <Announcements announcements={announcements} />
114
64
  {/* 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" />
65
+ <Toolbar {...TOOLBAR_PROPS}>
66
+ {/* Left group */}
67
+ <Fade {...FADE_TRANSITION_PROPS} in={isIn.isLeftGroupIn}>
68
+ <Left>
69
+ {/* Logo */}
70
+ {logo}
71
+ {/* Divider */}
72
+ {isIn.isSloganIn && <Divider flexItem orientation="vertical" />}
73
+ {/* Slogan */}
74
+ {isIn.isSloganIn && <Slogan slogan={slogan} />}
75
+ {/* Left navigation */}
76
+ {isIn.isLeftNavigationIn && (
77
+ <DXNavigation
78
+ {...navigationProps}
79
+ links={getNavigationLinks(navItemsL, breakpoint)}
80
+ />
81
+ )}
82
+ </Left>
125
83
  </Fade>
126
- {/* Slogan */}
127
- <Fade
128
- in={isSloganIn}
129
- style={{ transitionDelay: isSloganIn ? "50ms" : "0ms" }}
130
- {...fadeProps}
131
- >
132
- <Slogan slogan={slogan} />
84
+ {/* Center group */}
85
+ <Fade {...FADE_TRANSITION_PROPS} in={isIn.isCenterGroupIn}>
86
+ <Center>
87
+ {/* Center navigation */}
88
+ {isIn.isCenterNavigationIn && (
89
+ <DXNavigation
90
+ {...navigationProps}
91
+ links={getNavigationLinks(navItemsC, breakpoint)}
92
+ />
93
+ )}
94
+ </Center>
133
95
  </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
96
+ {/* Right group */}
97
+ <Fade {...FADE_TRANSITION_PROPS} in={isIn.isRightGroupIn}>
98
+ <Right>
99
+ {/* Navigation */}
100
+ {isIn.isRightNavigationIn && (
101
+ <DXNavigation
102
+ {...navigationProps}
103
+ links={getNavigationLinks(navItemsR)}
104
+ />
105
+ )}
106
+ {/* Socials */}
107
+ {isIn.isSocialsIn && (
108
+ <Socials
109
+ buttonSize="small"
110
+ socials={socialMedia?.socials || []}
111
+ />
112
+ )}
113
+ {/* Actions */}
114
+ {isIn.isActionsIn && (
115
+ <Actions>
116
+ {/* Search */}
117
+ <Search
118
+ closeMenu={onClose}
119
+ searchEnabled={searchEnabled}
120
+ searchURL={searchURL}
121
+ />
122
+ {/* Authentication */}
123
+ <Authentication
124
+ authenticationEnabled={authenticationEnabled}
125
+ closeMenu={onClose}
126
+ />
127
+ {/* Additional actions i.e. call-to-action button */}
128
+ {actions}
129
+ {/* Menu */}
130
+ <Menu
131
+ {...navigationProps}
132
+ closeMenu={onClose}
133
+ open={open}
134
+ openMenu={onOpen}
135
+ />
136
+ </Actions>
143
137
  )}
144
- />
138
+ </Right>
145
139
  </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
140
  </Toolbar>
176
141
  </AppBar>
177
142
  );
@@ -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
+ };
@@ -12,7 +12,7 @@ export enum BREAKPOINT_FN_NAME {
12
12
  }
13
13
 
14
14
  type BreakpointFnName = BREAKPOINT_FN_NAME;
15
- type BreakpointKey = Breakpoint;
15
+ export type BreakpointKey = Breakpoint;
16
16
 
17
17
  export const useBreakpointHelper = (
18
18
  fnName: BreakpointFnName,
@@ -0,0 +1,23 @@
1
+ import { Breakpoint } from "@mui/material";
2
+ import { useMemo } from "react";
3
+ import {
4
+ BreakpointKey,
5
+ BREAKPOINT_FN_NAME,
6
+ useBreakpointHelper,
7
+ } from "./useBreakpointHelper";
8
+
9
+ export type UseCurrentBreakpoint = BreakpointKey | undefined;
10
+
11
+ const breakpointKeys: BreakpointKey[] = ["xs", "sm", "md", "lg"];
12
+
13
+ export const useCurrentBreakpoint = (): UseCurrentBreakpoint => {
14
+ const xs = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "xs");
15
+ const sm = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "sm");
16
+ const md = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "md");
17
+ const lg = useBreakpointHelper(BREAKPOINT_FN_NAME.ONLY, "lg");
18
+ const breakpoints: Record<Breakpoint, boolean> = useMemo(
19
+ () => ({ lg, md, sm, xs }),
20
+ [lg, md, sm, xs]
21
+ );
22
+ return breakpointKeys.find((key) => breakpoints[key]);
23
+ };
@@ -0,0 +1,27 @@
1
+ import { useCallback, useState } from "react";
2
+
3
+ export interface UseMenu {
4
+ onClose: () => void;
5
+ onOpen: () => void;
6
+ open: boolean;
7
+ }
8
+
9
+ /**
10
+ * Menu functionality for menu dropdown.
11
+ * @returns menu functionality.
12
+ */
13
+ export const useMenu = (): UseMenu => {
14
+ const [open, setOpen] = useState<boolean>(false);
15
+
16
+ // Closes header menu.
17
+ const onClose = useCallback((): void => {
18
+ setOpen(false);
19
+ }, []);
20
+
21
+ // Opens header menu.
22
+ const onOpen = useCallback((): void => {
23
+ setOpen(true);
24
+ }, []);
25
+
26
+ return { onClose, onOpen, open };
27
+ };
@@ -410,6 +410,23 @@ export const MuiButton = (theme: Theme): Components["MuiButton"] => {
410
410
  },
411
411
  },
412
412
  variants: [
413
+ {
414
+ props: {
415
+ variant: "activeNav", // associated with "nav" variant.
416
+ },
417
+ style: {
418
+ ...theme.typography[TEXT_BODY_500],
419
+ backgroundColor: theme.palette.smoke.light,
420
+ color: theme.palette.ink.main,
421
+ minWidth: 0,
422
+ textTransform: "capitalize",
423
+ whiteSpace: "nowrap",
424
+ // eslint-disable-next-line sort-keys -- disabling key order for readability
425
+ "&:hover": {
426
+ backgroundColor: theme.palette.smoke.light,
427
+ },
428
+ },
429
+ },
413
430
  {
414
431
  props: {
415
432
  variant: "nav",
@@ -1,4 +1,3 @@
1
- import { useRouter } from "next/router";
2
1
  import React, { useEffect, useMemo, useState } from "react";
3
2
  import {
4
3
  AzulEntitiesStaticResponse,
@@ -11,7 +10,6 @@ import {
11
10
  CategoryValueKey,
12
11
  SelectCategoryView,
13
12
  } from "../../common/entities";
14
- import { Tab, Tabs, TabValue } from "../../components/common/Tabs/tabs";
15
13
  import { ComponentCreator } from "../../components/ComponentCreator/ComponentCreator";
16
14
  import { ClearAllFilters } from "../../components/Filter/components/ClearAllFilters/clearAllFilters";
17
15
  import {
@@ -19,6 +17,7 @@ import {
19
17
  Filters,
20
18
  } from "../../components/Filter/components/Filters/filters";
21
19
  import { SearchAllFilters } from "../../components/Filter/components/SearchAllFilters/searchAllFilters";
20
+ import { Tabs } from "../../components/Index/components/Tabs/tabs";
22
21
  import { Index as IndexView } from "../../components/Index/index";
23
22
  import { SidebarButton } from "../../components/Layout/components/Sidebar/components/SidebarButton/sidebarButton";
24
23
  import { SidebarLabel } from "../../components/Layout/components/Sidebar/components/SidebarLabel/sidebarLabel";
@@ -47,33 +46,15 @@ export interface ExploreViewProps extends AzulEntitiesStaticResponse {
47
46
  className?: string;
48
47
  }
49
48
 
50
- /**
51
- * Returns tabs to be used as a prop for the Tabs component.
52
- * @param entities - Entities config.
53
- * @returns tabs list.
54
- */
55
- function getTabs(entities: EntityConfig[]): Tab[] {
56
- return entities.map(
57
- ({ label, route, tabIcon: icon, tabIconPosition: iconPosition }) => ({
58
- icon,
59
- iconPosition,
60
- label,
61
- value: route,
62
- })
63
- );
64
- }
65
-
66
49
  export const ExploreView = (props: ExploreViewProps): JSX.Element => {
67
50
  const [isDrawerOpen, setIsDrawerOpen] = useState<boolean>(false);
68
51
  const tabletDown = useBreakpointHelper(BREAKPOINT_FN_NAME.DOWN, DESKTOP_SM);
69
52
  const { config, entityConfig } = useConfig(); // Get app level config.
70
53
  const { exploreDispatch, exploreState } = useExploreState(); // Get the useReducer state and dispatch for "Explore".
71
- const { entities, explorerTitle, summaryConfig, trackingConfig } = config;
54
+ const { explorerTitle, summaryConfig, trackingConfig } = config;
72
55
  const { listView } = entityConfig;
73
56
  const { listHero, subTitleHero } = listView || {};
74
- const { categoryGroups, categoryViews, filterCount, tabValue } = exploreState;
75
- const { push } = useRouter();
76
- const tabs = getTabs(entities);
57
+ const { categoryGroups, categoryViews, filterCount } = exploreState;
77
58
  const { response: summaryResponse } = useSummary(); // Fetch summary.
78
59
  useEntityList(props); // Fetch entities.
79
60
  const { entityListType } = props;
@@ -145,16 +126,6 @@ export const ExploreView = (props: ExploreViewProps): JSX.Element => {
145
126
  setIsDrawerOpen(true);
146
127
  };
147
128
 
148
- /**
149
- * Callback fired when selected tab value changes.
150
- * - Sets state tabsValue to selected tab value.
151
- * - Executes a pushState and resets pagination.
152
- * @param tabValue - Selected tab value.
153
- */
154
- const onTabChange = (tabValue: TabValue): void => {
155
- push(`/${tabValue}`);
156
- };
157
-
158
129
  /**
159
130
  * Dispatch a SelectedEntityType action when entityListType changes.
160
131
  */
@@ -206,8 +177,8 @@ export const ExploreView = (props: ExploreViewProps): JSX.Element => {
206
177
  }
207
178
  SubTitleHero={renderComponent(subTitleHero)}
208
179
  Summaries={renderSummary(summaryConfig, summaryResponse)}
209
- Tabs={<Tabs onTabChange={onTabChange} tabs={tabs} value={tabValue} />}
210
- title={explorerTitle}
180
+ Tabs={<Tabs />}
181
+ title={entityConfig.explorerTitle || explorerTitle}
211
182
  />
212
183
  </>
213
184
  );
@@ -59,6 +59,7 @@ declare module "@mui/material/styles" {
59
59
  */
60
60
  declare module "@mui/material/Button" {
61
61
  interface ButtonPropsVariantOverrides {
62
+ activeNav: true;
62
63
  nav: true;
63
64
  }
64
65
  }