From 71f3ccf4e23c59ec1e465797eb79ea91d2d6fd8e Mon Sep 17 00:00:00 2001
From: Gabe Koscky <68292774+gkoscky@users.noreply.github.com>
Date: Fri, 1 Dec 2023 09:56:07 -0500
Subject: [PATCH] Add new Banner module (#481)
* Add SASS/SCSS support
* Add new Banner module
To allow us to create promotional banners more quickly and easily than before.
* Fix module reference
---
docusaurus.config.js | 1 +
package.json | 2 +
.../Banner/Banner.custom.module.scss | 21 +++++
src/components/Banner/Banner.module.scss | 12 +++
src/components/Banner/Banner.tsx | 82 ++++++++++++++++
src/components/Banner/_base.scss | 19 ++++
src/components/Banner/banner.config.tsx | 93 +++++++++++++++++++
src/theme/Navbar/index.js | 13 +++
src/theme/Navbar/navbar.module.css | 5 +
yarn.lock | 41 +++++++-
10 files changed, 287 insertions(+), 2 deletions(-)
create mode 100644 src/components/Banner/Banner.custom.module.scss
create mode 100644 src/components/Banner/Banner.module.scss
create mode 100644 src/components/Banner/Banner.tsx
create mode 100644 src/components/Banner/_base.scss
create mode 100644 src/components/Banner/banner.config.tsx
create mode 100644 src/theme/Navbar/index.js
create mode 100644 src/theme/Navbar/navbar.module.css
diff --git a/docusaurus.config.js b/docusaurus.config.js
index 71707f07..ce9a953d 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -102,6 +102,7 @@ module.exports = async function createConfigAsync() {
},
};
},
+ 'docusaurus-plugin-sass'
],
}
}
diff --git a/package.json b/package.json
index 5a02eb68..3b5773ae 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
"axios": "^1.4.0",
"change-case": "^5.1.2",
"clsx": "^1.1.1",
+ "docusaurus-plugin-sass": "^0.2.5",
"dotenv": "^8.2.0",
"ethers": "^6.7.1",
"postcss": "^8.4.31",
@@ -46,6 +47,7 @@
"react-loadable": "^5.5.0",
"rehype-katex": "^6.0.3",
"remark-math": "^5.1.1",
+ "sass": "^1.69.5",
"search-insights": "^2.8.3",
"tailwindcss": "^3.3.3",
"webpack": "^5.88.1"
diff --git a/src/components/Banner/Banner.custom.module.scss b/src/components/Banner/Banner.custom.module.scss
new file mode 100644
index 00000000..712a63ac
--- /dev/null
+++ b/src/components/Banner/Banner.custom.module.scss
@@ -0,0 +1,21 @@
+@use '_base';
+
+/*
+Add custom CSS styling for your banner here
+
+You can add any classes you'd like based on the markup for your banner
+The .banner class is already provided and apply to the parent element of
+the banner.
+
+The '@extend %banner-structure' defines the structural properties for the
+banner and should not be removed.
+*/
+
+.banner {
+ @extend %banner-structure; // Do not remove
+}
+
+
+[data-theme=dark] .banner {
+ @extend %banner-structure; // Do not remove
+}
diff --git a/src/components/Banner/Banner.module.scss b/src/components/Banner/Banner.module.scss
new file mode 100644
index 00000000..fb95fa28
--- /dev/null
+++ b/src/components/Banner/Banner.module.scss
@@ -0,0 +1,12 @@
+@use 'base';
+
+.banner {
+ @extend %banner-structure;
+
+ background-color: var(--banner-background-color, var(--ifm-navbar-background-color));
+ color: var(--banner-text-color, var(--ifm-font-color-base));
+
+ a {
+ color: var(--banner-text-color , var(--ifm-font-color-base));
+ }
+}
diff --git a/src/components/Banner/Banner.tsx b/src/components/Banner/Banner.tsx
new file mode 100644
index 00000000..ae51c7f1
--- /dev/null
+++ b/src/components/Banner/Banner.tsx
@@ -0,0 +1,82 @@
+/* Custom Banner Module
+Use it to quickly deploy a simple banner to the Flashbots homepage
+
+To add a new banner all you need to do is edit the ./banner.config.tsx
+file and set the applicable properties. No other work is necessary.
+
+You'll find more in-depth documentation there.
+*/
+
+import React from 'react'
+import clsx from 'clsx'
+import bannerConfig from './banner.config'
+import customStyles from './Banner.custom.module.scss'
+import bannerStyles from './Banner.module.scss'
+
+export interface BannerOptions {
+ bannerContent?: JSX.Element | string | null
+ backgroundColor: string
+ textColor: string
+ startDate: string | null
+ endDate: string | null
+ customBannerCSS: boolean
+}
+
+class BannerConfigs {
+ options: BannerOptions
+
+ constructor(options: BannerOptions) {
+ this.options = options
+ }
+
+ // Sets the appropriate CSS rules for the element
+ // based on the `customCSS` option
+ getBannerStyle(): React.CSSProperties | null {
+ return !this.options.customBannerCSS
+ ? {
+ "--banner-text-color": this.options.textColor,
+ "--banner-background-color": this.options.backgroundColor
+ }
+ : null
+ }
+
+ // Sets the appropriate class name for the element
+ // based on the `customCSS` option
+ getBannerClass(): string {
+ const styles = this.options.customBannerCSS ? customStyles : bannerStyles
+
+ return clsx(styles.banner)
+ }
+
+ // Determines whether the banner should appear based on:
+ // 1. Whether there is content to be shown
+ // 2. The start and end dates exist and are valid
+ shouldShowBanner(): boolean {
+ if (!this.options.bannerContent) {
+ return false
+ }
+
+ const parsedStart = Date.parse(this.options.startDate)
+ const parsedEnd = Date.parse(this.options.endDate)
+ const currentDate = Date.now()
+
+ return (
+ (isNaN(parsedStart) || parsedStart <= currentDate) &&
+ (isNaN(parsedEnd) || parsedEnd >= currentDate)
+ )
+ }
+}
+
+export default function Banner(): JSX.Element {
+ const configs = new BannerConfigs(bannerConfig)
+
+ if (!configs.shouldShowBanner()) {
+ return null
+ }
+
+ return (
+
+ {configs.options.bannerContent}
+
+ )
+}
diff --git a/src/components/Banner/_base.scss b/src/components/Banner/_base.scss
new file mode 100644
index 00000000..615f14e8
--- /dev/null
+++ b/src/components/Banner/_base.scss
@@ -0,0 +1,19 @@
+%banner-structure {
+ height: fit-content;
+ padding: 0.5rem 2rem;
+ text-align: center;
+ line-height: 1.25;
+
+ a{
+ cursor: pointer;
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+ @media (max-width: 720px){
+ padding: 0.5rem 2rem;
+ }
+}
diff --git a/src/components/Banner/banner.config.tsx b/src/components/Banner/banner.config.tsx
new file mode 100644
index 00000000..7ace62ee
--- /dev/null
+++ b/src/components/Banner/banner.config.tsx
@@ -0,0 +1,93 @@
+/* Custom Banner Module
+Use it to quickly deploy a simple banner to the Flashbots homepage
+
+To add a new banner all you need to do is edit the properties below and set them
+to your desired values.
+
+For simple banners with just a couple of colors - for copy and background - you
+can use the properties here. But if the banner requires more sophisticated styling
+you can override the color options by setting `customCSS: true` and adding your CSS
+rules to ./Banner.custom.module.scss.
+
+There are detailed explanations for each property below, but here's a quick guide:
+ - bannerContent: What should appear inside the banner
+ - backgroundColor: Solid, single color for the banner
+ - textColor: Solid, single color for all the copy inside the banner
+ - startDate: When should the banner start appearing on the site
+ - endDate: When should the banner stop appearing on the site
+ - customCSS: Whether the banner should make use of custom CSS rules loaded from ./Banner.custom.module.scss
+*/
+
+import React from 'react'
+import BannerOptions from './Banner'
+
+export const bannerConfig: BannerOptions = {
+ /*
+ bannerContent: The pure text or HTML markup to appear in the banner
+ - Banner won't appear when set to null
+
+ Examples:
+ - bannerContent: null
+ - bannerContent: "Banner content!"
+ - bannerContent: (Banner content! Link)
+ */
+ bannerContent: null,
+
+ /*
+ backgroundColor: Single, solid background color for the banner
+ - Will default to the site's background when set to null
+ - Has no effect if customCSS is true
+
+ Examples:
+ - backgroundColor: null
+ - backgroundColor: "#023047"
+ */
+ backgroundColor: null,
+
+ /*
+ textColor: Single, solid text color for the banner
+ - Will default to the site's text color when set to null
+ - Has no effect if customCSS is true
+
+ Examples:
+ - textColor: null
+ - textColor: "#ffb703"
+ */
+ textColor: null,
+
+ /*
+ startDate: Date and time (UTC) when the banner should start appearing on the website
+ - When set to null a banner will always appear, provided there is content to be shown
+ and the endDate, if there is one, hasn't been reached
+ Format: "YYYY-MM-DD HH:mmZ"
+
+ Examples:
+ - startDate: null
+ - startDate: "2001-09-14 16:00Z"
+ */
+ startDate: null,
+
+ /*
+ endDate: Date and time (UTC) when the banner should stop appearing on the website
+ - When set to null a banner will always appear, provided there is content to be shown
+ and the startDate, if there is one, has been reached
+ Format: "YYYY-MM-DD HH:mmZ"
+
+ Examples:
+ - endDate: null
+ - endDate: "2007-02-01 00:00Z"
+ */
+ endDate: null,
+
+ /*
+ customCSS: Determines whether to use a custom CSS instead instead of the color options
+ - Custom CSS must be set in ./Banner.custom.module.scss
+ - Will completely bypass backgroundColor and textColor if set to true
+
+ Examples:
+ - customCSS: true
+ */
+ customBannerCSS: false
+}
+
+export default bannerConfig
diff --git a/src/theme/Navbar/index.js b/src/theme/Navbar/index.js
new file mode 100644
index 00000000..ae6f2678
--- /dev/null
+++ b/src/theme/Navbar/index.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import Navbar from '@theme-original/Navbar';
+import Banner from '../../components/Banner/Banner'
+import styles from './navbar.module.css'
+
+export default function NavbarWrapper(props) {
+ return (
+
+
+
+
+ );
+}
diff --git a/src/theme/Navbar/navbar.module.css b/src/theme/Navbar/navbar.module.css
new file mode 100644
index 00000000..06368759
--- /dev/null
+++ b/src/theme/Navbar/navbar.module.css
@@ -0,0 +1,5 @@
+.combinedNavigation {
+ position: sticky;
+ top: 0px;
+ z-index: var(--ifm-z-index-fixed);
+}
diff --git a/yarn.lock b/yarn.lock
index c06eb2c0..11a3ba69 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4342,7 +4342,7 @@ cheerio@^1.0.0-rc.12:
parse5 "^7.0.0"
parse5-htmlparser2-tree-adapter "^7.0.0"
-chokidar@3.5.3, chokidar@^3.4.2, chokidar@^3.5.3:
+chokidar@3.5.3, "chokidar@>=3.0.0 <4.0.0", chokidar@^3.4.2, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
@@ -5292,6 +5292,13 @@ doctrine@^3.0.0:
dependencies:
esutils "^2.0.2"
+docusaurus-plugin-sass@^0.2.5:
+ version "0.2.5"
+ resolved "https://registry.yarnpkg.com/docusaurus-plugin-sass/-/docusaurus-plugin-sass-0.2.5.tgz#6bfb8a227ac6265be685dcbc24ba1989e27b8005"
+ integrity sha512-Z+D0fLFUKcFpM+bqSUmqKIU+vO+YF1xoEQh5hoFreg2eMf722+siwXDD+sqtwU8E4MvVpuvsQfaHwODNlxJAEg==
+ dependencies:
+ sass-loader "^10.1.1"
+
dom-converter@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768"
@@ -7255,6 +7262,11 @@ immer@^9.0.7:
resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176"
integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==
+immutable@^4.0.0:
+ version "4.3.4"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f"
+ integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==
+
import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
@@ -7979,6 +7991,11 @@ kleur@^4.0.3:
resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
+klona@^2.0.4:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22"
+ integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==
+
known-css-properties@^0.26.0:
version "0.26.0"
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.26.0.tgz#008295115abddc045a9f4ed7e2a84dc8b3a77649"
@@ -11065,6 +11082,26 @@ safe-regex-test@^1.0.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
+sass-loader@^10.1.1:
+ version "10.4.1"
+ resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.4.1.tgz#bea4e173ddf512c9d7f53e9ec686186146807cbf"
+ integrity sha512-aX/iJZTTpNUNx/OSYzo2KsjIUQHqvWsAhhUijFjAPdZTEhstjZI9zTNvkTTwsx+uNUJqUwOw5gacxQMx4hJxGQ==
+ dependencies:
+ klona "^2.0.4"
+ loader-utils "^2.0.0"
+ neo-async "^2.6.2"
+ schema-utils "^3.0.0"
+ semver "^7.3.2"
+
+sass@^1.69.5:
+ version "1.69.5"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde"
+ integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ==
+ dependencies:
+ chokidar ">=3.0.0 <4.0.0"
+ immutable "^4.0.0"
+ source-map-js ">=0.6.2 <2.0.0"
+
sax@^1.2.4:
version "1.3.0"
resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0"
@@ -11406,7 +11443,7 @@ sort-css-media-queries@2.1.0:
resolved "https://registry.yarnpkg.com/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz#7c85e06f79826baabb232f5560e9745d7a78c4ce"
integrity sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==
-source-map-js@^1.0.2:
+"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==