@openstack_dev/gatsby-theme-marketing-oif-core 1.0.12 → 1.0.14

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.
@@ -0,0 +1,47 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import Box from "@mui/material/Box";
4
+ import Button from "@mui/material/Button";
5
+
6
+ import styles from "../index.module.scss";
7
+
8
+ function NavBarDropDown({ isMobile, items, handleNavigation }) {
9
+ return (
10
+ <Box className={isMobile ? styles.mobileDropdownMenu : styles.dropDownMenu}>
11
+ {items.map((subItem) => (!subItem.title && !subItem.link ? (
12
+ <div className={styles.divider} key={subItem.title} />
13
+ ) : (
14
+ <Button
15
+ className={
16
+ isMobile ? styles.mobileDropdownOption : styles.dropdownMenuOption
17
+ }
18
+ key={isMobile ? `${subItem.title}-mobile` : subItem.title}
19
+ onClick={(ev) => handleNavigation(ev, subItem.link)}
20
+ sx={{ display: "block" }}
21
+ disableRipple
22
+ >
23
+ {subItem.title}
24
+ </Button>
25
+ )))}
26
+ </Box>
27
+ );
28
+ }
29
+
30
+ NavBarDropDown.propTypes = {
31
+ isMobile: PropTypes.bool,
32
+ items: PropTypes.arrayOf(
33
+ PropTypes.shape({
34
+ link: PropTypes.string,
35
+ title: PropTypes.string,
36
+ display: PropTypes.bool,
37
+ requiresAuth: PropTypes.bool,
38
+ }),
39
+ ).isRequired,
40
+ handleNavigation: PropTypes.func.isRequired,
41
+ };
42
+
43
+ NavBarDropDown.defaultProps = {
44
+ isMobile: false,
45
+ };
46
+
47
+ export default NavBarDropDown;
@@ -0,0 +1,28 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import Box from "@mui/material/Box";
4
+
5
+ import styles from "./index.module.scss";
6
+ import SearchBar from "../SearchBar";
7
+
8
+ function NavBarHeader({ setIsSearchBarOpen }) {
9
+ return (
10
+ <Box className={styles.navbarHeader}>
11
+ <div className={styles.brandWrapper}>
12
+ <a
13
+ className={styles.navbarBrand}
14
+ href="/"
15
+ alt="Openstack logo"
16
+ aria-label="Go to homepage"
17
+ />
18
+ </div>
19
+ <SearchBar onSearchBarOpen={(value) => setIsSearchBarOpen(value)} />
20
+ </Box>
21
+ );
22
+ }
23
+
24
+ NavBarHeader.propTypes = {
25
+ setIsSearchBarOpen: PropTypes.func.isRequired,
26
+ };
27
+
28
+ export default NavBarHeader;
@@ -0,0 +1,55 @@
1
+ .navbarHeader {
2
+ .brandWrapper {
3
+ margin: 10px 0;
4
+ padding-right: 20px;
5
+ float: left;
6
+ border-right: 1px solid #eee;
7
+ min-width: 135px;
8
+ a.navbarBrand {
9
+ background: url("../../../images/openstack-logo-full.svg") left no-repeat;
10
+ height: 35px;
11
+ width: 135px;
12
+ color: #777;
13
+ padding: 15px 15px;
14
+ font-size: 18px;
15
+ line-height: 20px;
16
+ display: block;
17
+ }
18
+ }
19
+ .navbarToggle {
20
+ appearance: button;
21
+ cursor: pointer;
22
+ position: relative;
23
+ float: right;
24
+ padding: 9px 10px;
25
+ margin-top: 8px;
26
+ margin-bottom: 8px;
27
+ background: transparent;
28
+ border: none;
29
+ .iconBar {
30
+ background-color: #5a5a5a;
31
+ height: 3px;
32
+ border-radius: 3px;
33
+ display: block;
34
+ width: 22px;
35
+ margin-top: 4px;
36
+ }
37
+ @media (min-width: 768px) {
38
+ display: none;
39
+ }
40
+ }
41
+ @media (min-width: 768px) and (max-width: 1310px) {
42
+ .brandWrapper {
43
+ width: 75px;
44
+ min-width: 75px;
45
+ margin-top: 0;
46
+ a.navbarBrand {
47
+ background: url("../../../images/openstack-logo-vert.svg") left
48
+ no-repeat;
49
+ margin-left: 0px !important;
50
+ height: 54px;
51
+ width: 59px;
52
+ }
53
+ }
54
+ }
55
+ }
@@ -0,0 +1,92 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import Button from "@mui/material/Button";
4
+ import AddIcon from "@mui/icons-material/Add";
5
+ import RemoveIcon from "@mui/icons-material/Remove";
6
+ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
7
+ import NavBarDropDown from "../NavBarDropDown";
8
+ import Link from "../../Link";
9
+
10
+ import styles from "../index.module.scss";
11
+
12
+ function NavBarItem({
13
+ isMobile,
14
+ item,
15
+ navbarMenu,
16
+ setActiveMenu,
17
+ handleNavigation,
18
+ }) {
19
+ return isMobile ? (
20
+ <>
21
+ <Button
22
+ disableRipple
23
+ className={styles.mobileOption}
24
+ key={`${item.title}-mobile`}
25
+ onClick={() => setActiveMenu(item.title)}
26
+ >
27
+ {item.title}
28
+ {item.items?.length > 0
29
+ && (item.title === navbarMenu ? (
30
+ <RemoveIcon aria-hidden="true" />
31
+ ) : (
32
+ <AddIcon aria-hidden="true" />
33
+ ))}
34
+ </Button>
35
+ {item.items?.length > 0 && item.title === navbarMenu && (
36
+ <NavBarDropDown
37
+ items={item.items}
38
+ handleNavigation={handleNavigation}
39
+ isMobile
40
+ />
41
+ )}
42
+ </>
43
+ ) : (
44
+ <Link
45
+ className={styles.navbarOption}
46
+ key={item.title}
47
+ sx={{ my: 2, display: "block" }}
48
+ href={item.link}
49
+ >
50
+ {item.items?.length > 0 ? (
51
+ <>
52
+ {item.title}
53
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
54
+ <NavBarDropDown
55
+ items={item.items}
56
+ handleNavigation={handleNavigation}
57
+ />
58
+ </>
59
+ ) : (
60
+ item.title
61
+ )}
62
+ </Link>
63
+ );
64
+ }
65
+
66
+ NavBarItem.propTypes = {
67
+ isMobile: PropTypes.bool,
68
+ item: PropTypes.shape({
69
+ title: PropTypes.string,
70
+ link: PropTypes.string,
71
+ display: PropTypes.bool,
72
+ requiresAuth: PropTypes.bool,
73
+ items: PropTypes.arrayOf(
74
+ PropTypes.shape({
75
+ link: PropTypes.string,
76
+ title: PropTypes.string,
77
+ display: PropTypes.bool,
78
+ requiresAuth: PropTypes.bool,
79
+ }),
80
+ ),
81
+ }),
82
+ navbarMenu: PropTypes.string.isRequired,
83
+ setActiveMenu: PropTypes.func,
84
+ handleNavigation: PropTypes.func.isRequired,
85
+ };
86
+
87
+ NavBarItem.defaultProps = {
88
+ isMobile: false,
89
+ setActiveMenu: (option) => console.log(option),
90
+ };
91
+
92
+ export default NavBarItem;
@@ -0,0 +1,83 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import Box from "@mui/material/Box";
4
+ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
5
+ import LoginButton from "../LoginButton";
6
+ import NavBarDropDown from "../NavBarDropDown";
7
+
8
+ import styles from "../index.module.scss";
9
+
10
+ function PublicUserSubNavBar({ isSearchBarOpen, isDesktop, handleNavigation }) {
11
+ const publicNavbarMenu = [
12
+ {
13
+ link: "https://openinfra.dev/join",
14
+ title: "Sign up for Foundation Membership",
15
+ display: true,
16
+ requiresAuth: false,
17
+ },
18
+ {
19
+ link: "https://openinfra.dev/join",
20
+ title: "Sponsor the Foundation",
21
+ display: true,
22
+ requiresAuth: false,
23
+ },
24
+ {
25
+ link: "https://openinfra.dev",
26
+ title: "More about the Foundation",
27
+ display: true,
28
+ requiresAuth: false,
29
+ },
30
+ ];
31
+
32
+ const getBackURL = () => {
33
+ let backUrl = "/";
34
+ if (window && typeof window !== "undefined") {
35
+ backUrl = window.location.pathname;
36
+ }
37
+ return backUrl;
38
+ };
39
+
40
+ return (
41
+ <Box
42
+ maxWidth={isDesktop ? "15%" : "100px"}
43
+ sx={
44
+ isDesktop
45
+ ? {
46
+ display: {
47
+ xs: "none",
48
+ md: isSearchBarOpen ? "none" : "flex",
49
+ },
50
+ justifyContent: "flex-end",
51
+ marginLeft: "auto",
52
+ }
53
+ : {}
54
+ }
55
+ >
56
+ <Box
57
+ className={`${styles.navbarOption} ${styles.join}`}
58
+ sx={{ my: 2, display: "block" }}
59
+ >
60
+ Join
61
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
62
+ <NavBarDropDown
63
+ items={publicNavbarMenu}
64
+ handleNavigation={handleNavigation}
65
+ />
66
+ </Box>
67
+ <LoginButton backUrl={getBackURL()} />
68
+ </Box>
69
+ );
70
+ }
71
+
72
+ PublicUserSubNavBar.propTypes = {
73
+ isSearchBarOpen: PropTypes.bool,
74
+ isDesktop: PropTypes.bool,
75
+ handleNavigation: PropTypes.func.isRequired,
76
+ };
77
+
78
+ PublicUserSubNavBar.defaultProps = {
79
+ isSearchBarOpen: false,
80
+ isDesktop: false,
81
+ };
82
+
83
+ export default PublicUserSubNavBar;
@@ -0,0 +1,108 @@
1
+ import * as React from "react";
2
+ import { Script } from "gatsby";
3
+ import PropTypes from "prop-types";
4
+ import Box from "@mui/material/Box";
5
+ import SearchIcon from "@mui/icons-material/Search";
6
+
7
+ import {
8
+ SEARCH_WIDGET_BASE_URL,
9
+ getEnvVariable,
10
+ } from "../../../utils/envVariables";
11
+
12
+ import styles from "./index.module.scss";
13
+
14
+ function SearchBar({ isMobile, isMobileMenuOpen, onSearchBarOpen }) {
15
+ const [isSearchBarOpen, setIsSearchBarOpen] = React.useState(false);
16
+
17
+ const handleSearchBarOpenClose = (value) => {
18
+ onSearchBarOpen(value);
19
+ setIsSearchBarOpen(value);
20
+ };
21
+
22
+ const handleCloseSearchBar = (event) => {
23
+ if (event?.target.matches(".ossw-search-bar-close")) {
24
+ handleSearchBarOpenClose(false);
25
+ }
26
+ };
27
+
28
+ React.useEffect(() => {
29
+ document.addEventListener("click", handleCloseSearchBar);
30
+ return () => {
31
+ document.removeEventListener("click", handleCloseSearchBar);
32
+ };
33
+ }, []);
34
+
35
+ React.useEffect(() => {
36
+ if (isSearchBarOpen) {
37
+ const inputElement = document.getElementById("search-bar-input");
38
+ if (inputElement) {
39
+ inputElement.focus();
40
+ }
41
+ }
42
+ }, [isSearchBarOpen]);
43
+
44
+ return (
45
+ <>
46
+ <Script
47
+ src={`${getEnvVariable(SEARCH_WIDGET_BASE_URL)}/widget/embed.min.js`}
48
+ />
49
+ {isMobile ? (
50
+ <Box
51
+ className={`${styles.openstackSearchBarMobile} openstack-search-bar ossw-mobile`}
52
+ sx={{
53
+ visibility: {
54
+ xs: isMobileMenuOpen ? "visible" : "hidden",
55
+ md: "hidden",
56
+ },
57
+ opacity: { xs: isMobileMenuOpen ? "1" : "0", md: "0" },
58
+ height: { xs: isMobileMenuOpen ? "auto" : 0, md: 0 },
59
+ color: "#8a959e",
60
+ }}
61
+ data-baseurl={getEnvVariable(SEARCH_WIDGET_BASE_URL)}
62
+ data-context="www-openstack"
63
+ />
64
+ ) : (
65
+ <Box
66
+ className={styles.searchWrapper}
67
+ sx={{ display: { xs: "none", md: "flex" } }}
68
+ >
69
+ <div
70
+ role="button"
71
+ tabIndex={0}
72
+ onKeyDown={(event) => {
73
+ if (event.key === "Enter" || event.key === " ") handleSearchBarOpenClose(true);
74
+ }}
75
+ onClick={() => handleSearchBarOpenClose(true)}
76
+ className={styles.searchComponent}
77
+ >
78
+ <SearchIcon className={styles.searchIcon} />
79
+ <span className={styles.headerSearchText}>Search</span>
80
+ </div>
81
+ <Box
82
+ className={`openstack-search-bar ${styles.openstackSearchBar}`}
83
+ style={{
84
+ visibility: isSearchBarOpen ? "visible" : "hidden",
85
+ opacity: isSearchBarOpen ? "1" : "0",
86
+ }}
87
+ data-baseurl={getEnvVariable(SEARCH_WIDGET_BASE_URL)}
88
+ data-context="www-openstack"
89
+ />
90
+ </Box>
91
+ )}
92
+ </>
93
+ );
94
+ }
95
+
96
+ SearchBar.propTypes = {
97
+ isMobile: PropTypes.bool,
98
+ isMobileMenuOpen: PropTypes.bool,
99
+ onSearchBarOpen: PropTypes.func,
100
+ };
101
+
102
+ SearchBar.defaultProps = {
103
+ isMobile: false,
104
+ isMobileMenuOpen: false,
105
+ onSearchBarOpen: () => null,
106
+ };
107
+
108
+ export default SearchBar;
@@ -0,0 +1,43 @@
1
+ .searchWrapper {
2
+ padding: 20px 0px 15px 20px;
3
+ float: left;
4
+ text-transform: uppercase;
5
+ color: #8a959e;
6
+ font-size: 12px;
7
+ font-weight: 400;
8
+ line-height: 17.15px;
9
+ .searchComponent {
10
+ cursor: pointer;
11
+ z-index: 5;
12
+ position: relative;
13
+ .searchIcon {
14
+ width: 12px;
15
+ height: 12px;
16
+ line-height: 12px;
17
+ margin-right: 5px;
18
+ }
19
+ }
20
+ .openstackSearchBar {
21
+ width: 100%;
22
+ position: absolute;
23
+ top: 0;
24
+ z-index: 100;
25
+ height: 70px;
26
+ padding-top: 10px;
27
+ padding-right: 12%;
28
+ background-color: #fff;
29
+ opacity: 0;
30
+ transition: opacity 0.3s ease;
31
+ }
32
+ @media (max-width: 768px) {
33
+ display: none;
34
+ }
35
+ @media (max-width: 1160px) {
36
+ .headerSearchText {
37
+ display: none;
38
+ }
39
+ }
40
+ @media (min-width: 768px) and (max-width: 1310px) {
41
+ padding: 25px 0px 15px 20px;
42
+ }
43
+ }