@openstack_dev/gatsby-theme-marketing-oif-core 1.0.11 → 1.0.13

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 (30) hide show
  1. package/.nvmrc +1 -1
  2. package/gatsby-config.js +8 -0
  3. package/gatsby-node.js +0 -3
  4. package/gatsby-ssr.js +0 -31
  5. package/package.json +1 -1
  6. package/plugins/gatsby-plugin-emotion-cache-provider/gatsby-browser.js +9 -0
  7. package/plugins/gatsby-plugin-emotion-cache-provider/gatsby-ssr.js +36 -0
  8. package/plugins/gatsby-plugin-emotion-cache-provider/get-emotion-cache.js +5 -0
  9. package/plugins/gatsby-plugin-emotion-cache-provider/package.json +3 -0
  10. package/plugins/gatsby-plugin-mui-theme-provider/gatsby-browser.js +3 -0
  11. package/plugins/gatsby-plugin-mui-theme-provider/gatsby-node.js +43 -0
  12. package/plugins/gatsby-plugin-mui-theme-provider/gatsby-ssr.js +3 -0
  13. package/plugins/gatsby-plugin-mui-theme-provider/package.json +3 -0
  14. package/plugins/gatsby-plugin-mui-theme-provider/wrapThemeProvider.js +13 -0
  15. package/src/components/Layout.js +11 -17
  16. package/src/components/Navbar/AuthUserSubNavBar/index.js +145 -0
  17. package/src/components/Navbar/LoginButton/index.js +29 -0
  18. package/src/components/Navbar/MobileMenu/index.js +34 -0
  19. package/src/components/Navbar/MobileMenu/index.module.scss +9 -0
  20. package/src/components/Navbar/NavBarDropDown/index.js +47 -0
  21. package/src/components/Navbar/NavBarHeader/index.js +28 -0
  22. package/src/components/Navbar/NavBarHeader/index.module.scss +55 -0
  23. package/src/components/Navbar/NavBarItem/index.js +92 -0
  24. package/src/components/Navbar/PublicUserSubNavBar/index.js +83 -0
  25. package/src/components/Navbar/SearchBar/index.js +108 -0
  26. package/src/components/Navbar/SearchBar/index.module.scss +43 -0
  27. package/src/components/Navbar/index.js +24 -465
  28. package/src/components/Navbar/index.module.scss +2 -105
  29. package/src/components/Navbar/template.js +157 -0
  30. package/src/content/site-settings/index.json +1 -1
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- 18.15.0
1
+ 18.20.2
package/gatsby-config.js CHANGED
@@ -40,6 +40,13 @@ const manifestPlugin = faviconAsset
40
40
  : [];
41
41
 
42
42
  const plugins = [
43
+ {
44
+ resolve: "gatsby-plugin-mui-theme-provider",
45
+ options: {
46
+ themePath: `${__dirname}/src/theme.js`,
47
+ },
48
+ },
49
+ "gatsby-plugin-emotion-cache-provider",
43
50
  ...manifestPlugin,
44
51
  {
45
52
  resolve: "gatsby-alias-imports",
@@ -47,6 +54,7 @@ const plugins = [
47
54
  aliases: {
48
55
  "@utils": `${__dirname}/src/utils`,
49
56
  "@cms": `${__dirname}/src/cms`,
57
+ "@content": `${__dirname}/src/content`,
50
58
  },
51
59
  },
52
60
  },
package/gatsby-node.js CHANGED
@@ -140,9 +140,6 @@ exports.onCreateWebpackConfig = ({ actions, plugins }) => {
140
140
  },
141
141
  // allows content and data imports to correctly resolve when theming
142
142
  modules: [path.resolve("src")],
143
- alias: {
144
- "@utils": path.resolve(__dirname, "src/utils/"),
145
- },
146
143
  },
147
144
  // devtool: "source-map",
148
145
  plugins: [
package/gatsby-ssr.js CHANGED
@@ -1,12 +1,7 @@
1
- import * as React from "react";
2
1
  import { JSDOM } from "jsdom";
3
2
  import { XMLHttpRequest } from "xmlhttprequest";
4
- import { renderToString } from "react-dom/server";
5
- import { CacheProvider } from "@emotion/react";
6
- import createEmotionServer from "@emotion/server/create-instance";
7
3
  import { ReduxWrapper } from "./src/state/ReduxWrapper";
8
4
  import { HeadComponents } from "./src/components/head-components";
9
- import createEmotionCache from "./src/utils/createEmotionCache";
10
5
 
11
6
  export const onRenderBody = ({ setHeadComponents }) => {
12
7
  if (process.env.NODE_ENV === "production") {
@@ -14,32 +9,6 @@ export const onRenderBody = ({ setHeadComponents }) => {
14
9
  }
15
10
  };
16
11
 
17
- export const replaceRenderer = ({
18
- bodyComponent,
19
- setHeadComponents,
20
- replaceBodyHTMLString,
21
- }) => {
22
- const cache = createEmotionCache();
23
- const { extractCriticalToChunks } = createEmotionServer(cache);
24
-
25
- const emotionStyles = extractCriticalToChunks(
26
- renderToString(<CacheProvider value={cache}>{bodyComponent}</CacheProvider>),
27
- );
28
-
29
- setHeadComponents(
30
- emotionStyles.styles.map((style) => (
31
- <style
32
- data-emotion={`${style.key} ${style.ids.join(" ")}`}
33
- key={style.key}
34
- dangerouslySetInnerHTML={{ __html: style.css }}
35
- />
36
- )),
37
- );
38
-
39
- // render the result from `extractCritical`
40
- replaceBodyHTMLString(emotionStyles.html);
41
- };
42
-
43
12
  export const wrapRootElement = ReduxWrapper;
44
13
 
45
14
  // build enabler polyfills
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openstack_dev/gatsby-theme-marketing-oif-core",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Base theme for Marketing Sites",
5
5
  "author": "smarcet",
6
6
  "keywords": [
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { CacheProvider } from "@emotion/react";
3
+ import getEmotionCache from "./get-emotion-cache";
4
+
5
+ const cache = getEmotionCache();
6
+
7
+ export const wrapRootElement = ({ element }) => (
8
+ <CacheProvider value={cache}>{element}</CacheProvider>
9
+ );
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+ import { CacheProvider } from "@emotion/react";
3
+ import createEmotionServer from "@emotion/server/create-instance";
4
+ import { renderToString } from "react-dom/server";
5
+
6
+ import getEmotionCache from "./get-emotion-cache";
7
+
8
+ export const replaceRenderer = ({
9
+ bodyComponent,
10
+ setHeadComponents,
11
+ replaceBodyHTMLString,
12
+ }) => {
13
+ // see https://mui.com/material-ui/guides/server-rendering/
14
+ const cache = getEmotionCache();
15
+ const { extractCritical } = createEmotionServer(cache);
16
+
17
+ const initialHTML = renderToString(
18
+ <CacheProvider value={cache}>{bodyComponent}</CacheProvider>,
19
+ );
20
+
21
+ // see https://emotion.sh/docs/ssr#extractcritical
22
+ const { html, css, ids } = extractCritical(initialHTML);
23
+
24
+ const style = (
25
+ <style
26
+ key="theme-styles"
27
+ data-emotion={`css ${ids.join(" ")}`}
28
+ dangerouslySetInnerHTML={{ __html: css }}
29
+ />
30
+ );
31
+
32
+ setHeadComponents([style]);
33
+
34
+ // render the result from `extractCritical`
35
+ replaceBodyHTMLString(html);
36
+ };
@@ -0,0 +1,5 @@
1
+ import createCache from "@emotion/cache";
2
+
3
+ export default function getEmotionCache(props) {
4
+ return createCache(props ?? { key: "css" });
5
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "gatsby-plugin-emotion-cache-provider"
3
+ }
@@ -0,0 +1,3 @@
1
+ import wrapThemeProvider from "./wrapThemeProvider";
2
+ // see https://galenwong.github.io/blog/2020-02-27-mui-jss-rendering/
3
+ export const wrapRootElement = wrapThemeProvider;
@@ -0,0 +1,43 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ // Copy and past from https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-typography
5
+ exports.onPreBootstrap = ({ cache }, pluginOptions) => {
6
+ let data = "";
7
+ console.log(
8
+ "gatsby-plugin-mui-theme-provider::onPreBootstrap",
9
+ pluginOptions,
10
+ );
11
+ if (pluginOptions.themePath) {
12
+ console.log(
13
+ `gatsby-plugin-mui-theme-provider::onPreBootstrap loading file ${pluginOptions.themePath}`,
14
+ );
15
+ data = fs.readFileSync(pluginOptions.themePath, {
16
+ encoding: "utf8",
17
+ flag: "r",
18
+ });
19
+ }
20
+
21
+ const dir = cache.directory;
22
+
23
+ if (!fs.existsSync(dir)) {
24
+ fs.mkdirSync(dir);
25
+ }
26
+
27
+ fs.writeFileSync(path.join(dir, "custom-theme.js"), data);
28
+ };
29
+
30
+ exports.onCreateWebpackConfig = ({ actions, cache }) => {
31
+ const themeFile = path.join(cache.directory, "custom-theme.js");
32
+ console.log(
33
+ `gatsby-plugin-mui-theme-provider::onCreateWebpackConfig ${themeFile}`,
34
+ );
35
+ const { setWebpackConfig } = actions;
36
+ setWebpackConfig({
37
+ resolve: {
38
+ alias: {
39
+ "custom-theme": themeFile,
40
+ },
41
+ },
42
+ });
43
+ };
@@ -0,0 +1,3 @@
1
+ import wrapThemeProvider from "./wrapThemeProvider";
2
+ // see https://galenwong.github.io/blog/2020-02-27-mui-jss-rendering/
3
+ export const wrapRootElement = wrapThemeProvider;
@@ -0,0 +1,3 @@
1
+ {
2
+ "name": "gatsby-plugin-mui-theme-provider"
3
+ }
@@ -0,0 +1,13 @@
1
+ import * as React from "react";
2
+ import { ThemeProvider } from "@mui/material/styles";
3
+ import CssBaseline from "@mui/material/CssBaseline";
4
+ import theme from "custom-theme";
5
+ // see https://galenwong.github.io/blog/2020-02-27-mui-jss-rendering/
6
+ const wrapThemeProvider = ({ element }) => (
7
+ <ThemeProvider theme={theme}>
8
+ <CssBaseline />
9
+ {element}
10
+ </ThemeProvider>
11
+ );
12
+
13
+ export default wrapThemeProvider;
@@ -1,14 +1,11 @@
1
1
  import React from "react";
2
2
  import PropTypes from "prop-types";
3
- import CssBaseline from "@mui/material/CssBaseline";
4
- import { ThemeProvider } from "@mui/material/styles";
5
3
  import loadable from "@loadable/component";
6
4
  import Footer from "./Footer";
7
5
  import SponsoredProjectsNav from "./SponsoredProjectsNav";
8
6
  import SubscribeForm from "./SubscribeForm";
9
7
  import AnnouncementBanner from "./AnnouncementBanner";
10
8
  import Header from "./Header";
11
- import theme from "../theme";
12
9
  import NavBarPlaceholder from "./Navbar/placeholder";
13
10
 
14
11
  const Navbar = loadable(() => import("./Navbar"), {
@@ -18,22 +15,19 @@ const Navbar = loadable(() => import("./Navbar"), {
18
15
 
19
16
  function Layout({ children }) {
20
17
  return (
21
- <ThemeProvider theme={theme}>
22
- <CssBaseline />
18
+ <div>
19
+ <SponsoredProjectsNav />
20
+ <Navbar />
23
21
  <div>
24
- <SponsoredProjectsNav />
25
- <Navbar />
26
- <div>
27
- <Header />
28
- <AnnouncementBanner />
29
- <main id="content-wrapper">
30
- {children}
31
- <SubscribeForm />
32
- </main>
33
- <Footer />
34
- </div>
22
+ <Header />
23
+ <AnnouncementBanner />
24
+ <main id="content-wrapper">
25
+ {children}
26
+ <SubscribeForm />
27
+ </main>
28
+ <Footer />
35
29
  </div>
36
- </ThemeProvider>
30
+ </div>
37
31
  );
38
32
  }
39
33
 
@@ -0,0 +1,145 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { navigate } from "gatsby";
4
+ import Box from "@mui/material/Box";
5
+ import Button from "@mui/material/Button";
6
+ import AddIcon from "@mui/icons-material/Add";
7
+ import RemoveIcon from "@mui/icons-material/Remove";
8
+ import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
9
+
10
+ import styles from "../index.module.scss";
11
+
12
+ function AuthUserSubNavBar({
13
+ member,
14
+ isMobile,
15
+ navbarMenu,
16
+ setActiveMenu,
17
+ isSearchBarOpen,
18
+ handleNavigation,
19
+ }) {
20
+ const onClickLogout = () => {
21
+ navigate("/auth/logout", {
22
+ state: {
23
+ backUrl: window.location.pathname,
24
+ },
25
+ });
26
+ };
27
+
28
+ return isMobile ? (
29
+ <>
30
+ <Button
31
+ className={styles.mobileOption}
32
+ onClick={() => setActiveMenu("My Account")}
33
+ disableRipple
34
+ >
35
+ My Account
36
+ {navbarMenu === "My Account" ? (
37
+ <RemoveIcon aria-hidden="true" />
38
+ ) : (
39
+ <AddIcon aria-hidden="true" />
40
+ )}
41
+ </Button>
42
+ {navbarMenu === "My Account" && (
43
+ <Box className={styles.mobileDropdownMenu}>
44
+ <Button
45
+ className={styles.mobileDropdownOption}
46
+ onClick={() => handleNavigation("/profile/")}
47
+ sx={{ display: "block" }}
48
+ disableRipple
49
+ >
50
+ Edit Profile
51
+ </Button>
52
+ <Button
53
+ className={styles.mobileDropdownOption}
54
+ onClick={() => handleNavigation(
55
+ `/community/members/profile/${
56
+ member.id
57
+ }/${`${member.first_name.toLowerCase()}-${member.last_name.toLowerCase()}`}`,
58
+ )}
59
+ sx={{ display: "block" }}
60
+ disableRipple
61
+ >
62
+ View Public Profile
63
+ </Button>
64
+ <div className={styles.divider} />
65
+ <Button
66
+ className={styles.mobileDropdownOption}
67
+ sx={{ display: "block" }}
68
+ onClick={onClickLogout}
69
+ disableRipple
70
+ >
71
+ Log out
72
+ </Button>
73
+ </Box>
74
+ )}
75
+ </>
76
+ ) : (
77
+ <Box
78
+ maxWidth="15%"
79
+ sx={{
80
+ display: {
81
+ xs: "none",
82
+ md: isSearchBarOpen ? "none" : "flex",
83
+ },
84
+ justifyContent: "flex-end",
85
+ marginLeft: "auto",
86
+ }}
87
+ >
88
+ <Box
89
+ className={`${styles.navbarOption}`}
90
+ sx={{ my: 2, display: "block" }}
91
+ >
92
+ My Account
93
+ <ArrowDropDownIcon className={styles.arrowDownIcon} />
94
+ <Box className={styles.dropDownMenu}>
95
+ <Button
96
+ className={styles.dropdownMenuOption}
97
+ onClick={() => handleNavigation("/profile/")}
98
+ sx={{ display: "block" }}
99
+ disableRipple
100
+ >
101
+ Edit Profile
102
+ </Button>
103
+ <Button
104
+ className={styles.dropdownMenuOption}
105
+ onClick={() => handleNavigation(
106
+ `/community/members/profile/${
107
+ member.id
108
+ }/${`${member.first_name.toLowerCase()}-${member.last_name.toLowerCase()}`}`,
109
+ )}
110
+ sx={{ display: "block" }}
111
+ disableRipple
112
+ >
113
+ View Public Profile
114
+ </Button>
115
+ <div className={styles.divider} />
116
+ <Button
117
+ className={styles.dropdownMenuOption}
118
+ sx={{ display: "block" }}
119
+ onClick={onClickLogout}
120
+ disableRipple
121
+ >
122
+ Log out
123
+ </Button>
124
+ </Box>
125
+ </Box>
126
+ </Box>
127
+ );
128
+ }
129
+
130
+ AuthUserSubNavBar.propTypes = {
131
+ member: PropTypes.oneOfType([PropTypes.object, PropTypes.oneOf([null])]),
132
+ isMobile: PropTypes.bool.isRequired,
133
+ navbarMenu: PropTypes.string.isRequired,
134
+ setActiveMenu: PropTypes.func,
135
+ isSearchBarOpen: PropTypes.bool,
136
+ handleNavigation: PropTypes.func.isRequired,
137
+ };
138
+
139
+ AuthUserSubNavBar.defaultProps = {
140
+ member: null,
141
+ isSearchBarOpen: false,
142
+ setActiveMenu: (option) => console.log(option),
143
+ };
144
+
145
+ export default AuthUserSubNavBar;
@@ -0,0 +1,29 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import { doLogin } from "openstack-uicore-foundation/lib/security/methods";
4
+ import Button from "@mui/material/Button";
5
+
6
+ import styles from "../index.module.scss";
7
+
8
+ function LoginButton({ backUrl }) {
9
+ return (
10
+ <Button
11
+ className={`${styles.navbarOption} ${styles.login}`}
12
+ onClick={() => doLogin(backUrl)}
13
+ sx={{ my: 2, display: "block" }}
14
+ disableRipple
15
+ >
16
+ Log in
17
+ </Button>
18
+ );
19
+ }
20
+
21
+ LoginButton.propTypes = {
22
+ backUrl: PropTypes.string,
23
+ };
24
+
25
+ LoginButton.defaultProps = {
26
+ backUrl: "/",
27
+ };
28
+
29
+ export default LoginButton;
@@ -0,0 +1,34 @@
1
+ import * as React from "react";
2
+ import PropTypes from "prop-types";
3
+ import Box from "@mui/material/Box";
4
+ import IconButton from "@mui/material/IconButton";
5
+ import MenuIcon from "@mui/icons-material/Menu";
6
+
7
+ import styles from "./index.module.scss";
8
+
9
+ function MobileMenu({ handleMobileMenuToggle }) {
10
+ return (
11
+ <Box
12
+ className={styles.mobileMenuWrapper}
13
+ sx={{ flexGrow: 1, display: { xs: "flex", md: "none" } }}
14
+ >
15
+ <IconButton
16
+ className={styles.toggleIcon}
17
+ size="large"
18
+ aria-label="account of current user"
19
+ aria-controls="menu-appbar"
20
+ aria-haspopup="true"
21
+ onClick={() => handleMobileMenuToggle()}
22
+ color="inherit"
23
+ >
24
+ <MenuIcon />
25
+ </IconButton>
26
+ </Box>
27
+ );
28
+ }
29
+
30
+ MobileMenu.propTypes = {
31
+ handleMobileMenuToggle: PropTypes.func.isRequired,
32
+ };
33
+
34
+ export default MobileMenu;
@@ -0,0 +1,9 @@
1
+ .mobileMenuWrapper {
2
+ .toggleIcon {
3
+ color: #5a5a5a;
4
+ margin-left: auto;
5
+ &:hover {
6
+ background-color: transparent;
7
+ }
8
+ }
9
+ }
@@ -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
+ }