From 4cf86e0d8a13535bccb75201f58bc50a5c706a29 Mon Sep 17 00:00:00 2001 From: Simone Cuomo Date: Thu, 11 Jul 2024 16:33:55 +0100 Subject: [PATCH 01/41] feat: Docs Product Switcher (#2) * feat: Docs Product Switcher * feat: finish the product switcher * fix: style * fix: hover effect * fix: variables feat: new homepage design (#3) * feat: new homepage design * fix: comments feat: Header (#4) * feat: Header * feat: Megamenu * feat: Megamenu hover state * feat: Megamenu bottom links * feat: mobile megamenu * feat: search button mobile * fix: remove unused files * fix: rename megamenu file * fix: megaMenu css file name * fix: - Megamenu hover stuck issue - Resources link accessibility - Resources link triangle * Fix some accessibility --------- Co-authored-by: Simone Cuomo Update navigation Nav updates --- public/assets/icons/close.svg | 6 +- public/chainlink-docs.svg | 94 +------- public/images/quick-start.png | Bin 0 -> 59891 bytes public/images/tabler_arrow-up.svg | 3 + .../product-logos/data-resources-logo.svg | 13 ++ src/components/DocsSwitcher/DocsPicker.tsx | 46 ++++ .../DocsSwitcher/docsPicker.module.css | 100 +++++++++ src/components/Footer/NewsletterCTA.css | 4 + src/components/Footer/NewsletterCTA.tsx | 4 +- src/components/Header/Nav/NavBar.tsx | 27 ++- .../Nav/ProductNavigation/CaretIcon.tsx | 2 +- .../ProductNavigation/Desktop/MegaMenu.tsx | 204 ++++++++++++++++++ .../Desktop/ProductNavigation.tsx | 88 ++++---- .../Desktop/megaMenu.module.css | 132 ++++++++++++ .../Desktop/productNavigation.module.css | 125 +++++++++++ .../Header/Nav/ProductNavigation/MenuIcon.tsx | 12 ++ .../Mobile/BackArrowIcon.tsx | 5 +- .../ProductNavigation/Mobile/BottomBar.tsx | 31 --- .../Nav/ProductNavigation/Mobile/MegaMenu.tsx | 92 ++++++++ .../Mobile/ProductNavigation.tsx | 93 ++++---- .../Mobile/SubProductContent.tsx | 65 ------ .../Mobile/bottomBar.module.css | 39 ---- .../Mobile/megaMenu.module.css | 142 ++++++++++++ .../Mobile/productNavigation.module.css | 43 +++- .../Mobile/subProductContent.module.css | 22 -- .../ProductNavigation/ProductNavigation.tsx | 3 + src/components/Header/Nav/navBar.module.css | 21 +- src/components/Header/NavBar.tsx | 8 +- src/components/Header/aiSearch/Search.tsx | 2 +- .../Header/aiSearch/SearchButton.tsx | 14 +- .../Header/aiSearch/searchButton.module.css | 15 +- src/components/LeftSidebar/LeftSidebar.astro | 94 ++++---- .../QuickLinks/assets/search-icon.svg | 10 + .../landing/components/ProductCard.module.css | 53 ++--- .../landing/components/ProductCard.tsx | 38 ++-- src/features/landing/sections/HeroCTA.astro | 66 ------ .../notifications/components/HeaderBanner.tsx | 3 - src/layouts/DocsLayout.astro | 2 +- src/pages/index.astro | 170 +++++++++++++-- 39 files changed, 1346 insertions(+), 545 deletions(-) create mode 100644 public/images/quick-start.png create mode 100644 public/images/tabler_arrow-up.svg create mode 100644 src/assets/product-logos/data-resources-logo.svg create mode 100644 src/components/DocsSwitcher/DocsPicker.tsx create mode 100644 src/components/DocsSwitcher/docsPicker.module.css create mode 100644 src/components/Header/Nav/ProductNavigation/Desktop/MegaMenu.tsx create mode 100644 src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css create mode 100644 src/components/Header/Nav/ProductNavigation/MenuIcon.tsx delete mode 100644 src/components/Header/Nav/ProductNavigation/Mobile/BottomBar.tsx create mode 100644 src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx delete mode 100644 src/components/Header/Nav/ProductNavigation/Mobile/SubProductContent.tsx delete mode 100644 src/components/Header/Nav/ProductNavigation/Mobile/bottomBar.module.css create mode 100644 src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css delete mode 100644 src/components/Header/Nav/ProductNavigation/Mobile/subProductContent.module.css create mode 100644 src/components/QuickLinks/assets/search-icon.svg delete mode 100644 src/features/landing/sections/HeroCTA.astro diff --git a/public/assets/icons/close.svg b/public/assets/icons/close.svg index 57805cb4307..1cca4227259 100644 --- a/public/assets/icons/close.svg +++ b/public/assets/icons/close.svg @@ -1,5 +1,3 @@ - - - - + + diff --git a/public/chainlink-docs.svg b/public/chainlink-docs.svg index 95745e05904..a97cd591a30 100644 --- a/public/chainlink-docs.svg +++ b/public/chainlink-docs.svg @@ -1,91 +1,5 @@ - - - - - - - - - - - - - - - - - - + + + + diff --git a/public/images/quick-start.png b/public/images/quick-start.png new file mode 100644 index 0000000000000000000000000000000000000000..98fcfcf1e1818c40bea2fe8cecba3c24476be14d GIT binary patch literal 59891 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 M07*qoM6N<$g36iMaR2}S literal 0 HcmV?d00001 diff --git a/public/images/tabler_arrow-up.svg b/public/images/tabler_arrow-up.svg new file mode 100644 index 00000000000..6857ba992c3 --- /dev/null +++ b/public/images/tabler_arrow-up.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/product-logos/data-resources-logo.svg b/src/assets/product-logos/data-resources-logo.svg new file mode 100644 index 00000000000..b103a7372e8 --- /dev/null +++ b/src/assets/product-logos/data-resources-logo.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/src/components/DocsSwitcher/DocsPicker.tsx b/src/components/DocsSwitcher/DocsPicker.tsx new file mode 100644 index 00000000000..4d6f28ae06d --- /dev/null +++ b/src/components/DocsSwitcher/DocsPicker.tsx @@ -0,0 +1,46 @@ +import { useState } from "react" +import { isMatchedPath } from "../Header/Nav/isMatchedPath" +import { getNavigationProps } from "../Header/getNavigationProps" +import styles from "./docsPicker.module.css" +import { clsx } from "../Header/Nav/utils" + +function DocsPicker({ pathname }: { pathname: string }) { + const [productMenuOpen, setProductMenuOpen] = useState(false) + const { subProductsNav } = getNavigationProps("/data-feeds") + const subProductTrigger = subProductsNav?.find(({ href }) => isMatchedPath(pathname, href)) + + const label = subProductTrigger?.label || "Resources" + const icon = subProductTrigger?.label ? subProductTrigger.icon : undefined + + // MENU + return ( +
setProductMenuOpen(true)} + onMouseLeave={() => setProductMenuOpen(false)} + > + {label} +
+ +
+ {productMenuOpen && ( +
+
    + {subProductsNav + .filter((item) => !item.hideFromDropdown) + .map((item) => ( +
  • + + + {item.label} + +
  • + ))} +
+
+ )} +
+ ) +} + +export default DocsPicker diff --git a/src/components/DocsSwitcher/docsPicker.module.css b/src/components/DocsSwitcher/docsPicker.module.css new file mode 100644 index 00000000000..f60dd6c0fb4 --- /dev/null +++ b/src/components/DocsSwitcher/docsPicker.module.css @@ -0,0 +1,100 @@ +.container { + box-sizing: border-box; + display: flex; + align-items: center; + padding: var(--space-3x) var(--space-4x); + gap: var(--space-3x); + isolation: isolate; + z-index: 100; + margin-bottom: var(--space-5x); + position: relative; + background: var(--blue-100); + border: 1px solid var(--blue-200); + color: var(--blue-800); + border-radius: var(--space-2x); + flex: none; + font-size: 19px; + font-weight: var(--font-weight-medium); + order: 0; + flex-grow: 0; + cursor: pointer; + transition: all 0.2s ease; + width: 100%; +} + +.logo { + width: var(--space-8x); + height: var(--space-8x); +} + +.caret { + width: var(--space-4x); + height: var(--space-4x); + background: white; + border: 1px solid var(--blue-600); + border-radius: 50%; + position: absolute; + right: var(--space-4x); + display: flex; + align-items: center; + justify-content: center; +} + +.caret span { + width: var(--space-1x); + height: var(--space-1x); + border-right: 1px solid var(--blue-600); + border-bottom: 1px solid var(--blue-600); + transform: rotate(45deg); + transition: transform 0.2s ease; + margin-bottom: 1px; +} + +.container:hover { + border-color: var(--blue-300); +} + +.container:hover .caret span { + transform: rotate(-135deg); + margin-bottom: -1px; +} + +.menu { + position: absolute; + top: 100%; + left: 0; + width: 100%; + background: #ffffff; + border: 1px solid var(--blue-200); + border-radius: var(--space-2x); + box-shadow: var(--space-0x) var(--space-1x) var(--space-2x) rgba(0, 0, 0, 0.1); + z-index: 100; + transition: all 0.2s ease; + padding: var(--space-2x) var(--space-3x); +} + +.icon { + width: var(--space-5x); + height: var(--space-5x); +} + +.menu ul { + list-style: none; + padding: var(--space-2x); + margin: 0; + display: flex; + flex-direction: column; +} + +.link { + display: flex; + align-items: center; + font-size: var(--space-4x); + color: var(--blue-800); + padding: var(--space-3x) var(--space-2x); + gap: var(--space-2x); +} + +.link:hover { + color: var(--blue-600); +} diff --git a/src/components/Footer/NewsletterCTA.css b/src/components/Footer/NewsletterCTA.css index 7d33d8056b0..bf25fd36df4 100644 --- a/src/components/Footer/NewsletterCTA.css +++ b/src/components/Footer/NewsletterCTA.css @@ -17,6 +17,10 @@ white-space: nowrap; } +.cta-subscribe-h1 { + text-align: center; +} + .newsletter-cta :is(h2) { margin-bottom: var(--space-12x); } diff --git a/src/components/Footer/NewsletterCTA.tsx b/src/components/Footer/NewsletterCTA.tsx index 0ac627c0b36..ca72081f120 100644 --- a/src/components/Footer/NewsletterCTA.tsx +++ b/src/components/Footer/NewsletterCTA.tsx @@ -6,7 +6,9 @@ import { NewsletterSignupForm } from "./NewsletterSignupForm" export type NewsletterCTAProps = { title?: string } -export const NewsletterCTA = ({ title = "Stay updated on the latest Chainlink news" }: NewsletterCTAProps) => { +export const NewsletterCTA = ({ + title = "Get the latest Chainlink content straight to your inbox.", +}: NewsletterCTAProps) => { return (

{title}

diff --git a/src/components/Header/Nav/NavBar.tsx b/src/components/Header/Nav/NavBar.tsx index 90768aed403..8a296cc0b59 100644 --- a/src/components/Header/Nav/NavBar.tsx +++ b/src/components/Header/Nav/NavBar.tsx @@ -8,6 +8,7 @@ import { ProductNavigation } from "./ProductNavigation/ProductNavigation" import { useHideHeader } from "./useHideHeader" import ProductChainTable from "../../QuickLinks/sections/ProductChainTable" import QuickLinksIcon from "../../QuickLinks/assets/quick-links-icon.svg" +import { Search } from "../aiSearch/Search" declare const Weglot: any @@ -19,11 +20,25 @@ export type NavBarProps = { onHideChange?: (hidden: boolean) => void productsNav: ProductsNav subProductsNav: SubProductsNav + showMegaMenu: () => void + isMegamenuOpen: boolean + exitMegamenu: () => void } export const navBarHeight = 64 -export const NavBar = ({ path, searchTrigger, onHideChange, productsNav, subProductsNav }: NavBarProps) => { +const SearchButton = + +export const NavBar = ({ + path, + searchTrigger, + onHideChange, + productsNav, + subProductsNav, + showMegaMenu, + isMegamenuOpen, + exitMegamenu, +}: NavBarProps) => { const [isMenuOpen, setIsMenuOpen] = useState(false) const [isModalOpen, setIsModalOpen] = useState(false) const navRef = useRef(null) @@ -82,7 +97,7 @@ export const NavBar = ({ path, searchTrigger, onHideChange, productsNav, subProd
-
+ -
+
{searchTrigger &&
{searchTrigger}
}
+ ( - + void +} + +export const megaMenuSections = [ + { + title: "Cross Chain", + items: [ + { + ...(evmProducts.find((product) => product.title === "CCIP") || {}), + links: [ + { + label: "Docs", + href: "/ccip/getting-started", + }, + { + label: "Learn", + href: (evmProducts.find((product) => product.title === "CCIP") || {})?.learnMorelink, + }, + ], + }, + ], + bottomLinks: [ + { + label: "View all resources", + href: "/cross-chain", + }, + { + label: "Learn about Chainlink", + href: "#", + }, + ], + }, + { + title: "Data Feeds", + items: [ + { + ...evmProducts.find((product) => product.title === "Data Feeds"), + title: "Feeds", + docs: "/data-feeds/getting-started", + links: [ + { + label: "Docs", + href: "/data-feeds/getting-started", + }, + { + label: "Learn", + href: (evmProducts.find((product) => product.title === "Data Feeds") || {})?.learnMorelink, + }, + ], + }, + + { + ...evmProducts.find((product) => product.title === "Data Streams"), + title: "Streams", + docs: "/data-feeds/getting-started", + links: [ + { + label: "Docs", + href: "/data-feeds/getting-started", + }, + { + label: "Learn", + href: (evmProducts.find((product) => product.title === "Data Streams") || {})?.learnMorelink, + }, + ], + }, + + { + title: "Data resources", + image: resourcesLogo, + description: "Global standard for building secure cross-chain applications.", + learnMorelink: "data-feeds", + links: [ + { + label: "Learn", + href: "/data-feeds", + }, + ], + }, + ], + }, + { + title: "Compute", + items: [ + { + ...evmProducts.find((product) => product.title === "Automation"), + links: [ + { + label: "Docs", + href: "/chainlink-automation/getting-started", + }, + { + label: "Learn", + href: (evmProducts.find((product) => product.title === "Automation") || {})?.learnMorelink, + }, + ], + }, + { + ...evmProducts.find((product) => product.title === "Functions"), + links: [ + { + label: "Docs", + href: "/chainlink-functions/getting-started", + }, + { + label: "Learn", + href: (evmProducts.find((product) => product.title === "Functions") || {})?.learnMorelink, + }, + ], + }, + { + ...evmProducts.find((product) => product.title === "VRF"), + links: [ + { + label: "Docs", + href: "/vrf", + }, + { + label: "Learn", + href: (evmProducts.find((product) => product.title === "VRF") || {})?.learnMorelink, + }, + ], + }, + ], + }, +] + +function MegaMenu({ cancel }: MegaMenuProps) { + useEffect(() => { + const onESC = (ev: KeyboardEvent) => { + if (ev.key === "Escape") { + cancel() + } + } + window.addEventListener("keyup", onESC, false) + return () => { + window.addEventListener("keyup", onESC, false) + } + }, []) + + return ( + + ) +} + +export default MegaMenu diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx b/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx index 881ebdd83e6..ce7d0b33dd6 100644 --- a/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx +++ b/src/components/Header/Nav/ProductNavigation/Desktop/ProductNavigation.tsx @@ -1,75 +1,83 @@ import * as NavigationMenu from "@radix-ui/react-navigation-menu" import React from "react" -import { ProductsNav, SubProductsNav } from "../../config" -import { Divider } from "../../Divider" -import { isMatchedPath } from "../../isMatchedPath" +import { SubProductsNav } from "../../config" import { clsx } from "../../utils" import { extendRadixComponent } from "../extendRadixComponent" import styles from "./productNavigation.module.css" -import { SubProductContent } from "./SubProductContent" -import { Trigger } from "./Trigger" -import externalArrow from "../../../../../assets/icons/external-arrow.svg" +import { CaretIcon } from "../CaretIcon" type Props = { - path: string setNavMenuOpen: (navMenuOpen: boolean) => void - productsNav: ProductsNav subProductsNav?: SubProductsNav + showMegaMenu: () => void + isMegamenuOpen: boolean + exitMegamenu: () => void } const Root = extendRadixComponent(NavigationMenu.Root) const List = extendRadixComponent(NavigationMenu.List) -const Indicator = extendRadixComponent(NavigationMenu.Indicator) const Item = extendRadixComponent(NavigationMenu.Item) -const Viewport = extendRadixComponent(NavigationMenu.Viewport) -const RadixTrigger = extendRadixComponent(NavigationMenu.Trigger) -const RadixContent = extendRadixComponent(NavigationMenu.Content) -export const ProductNavigation = ({ path, setNavMenuOpen, productsNav, subProductsNav }: Props) => { +export const ProductNavigation = ({ setNavMenuOpen, showMegaMenu, isMegamenuOpen, exitMegamenu }: Props) => { const productMenuRef = React.useRef(null) const productMenuDataset = productMenuRef.current?.dataset ?? {} const productMenuOpen = React.useMemo(() => productMenuDataset.state === "open", [productMenuDataset.state]) const subProductMenuRef = React.useRef(null) const subProductMenuDataset = subProductMenuRef.current?.dataset ?? {} const subProductMenuOpen = React.useMemo(() => subProductMenuDataset.state === "open", [subProductMenuDataset.state]) + const handleKeyDown = (event: React.KeyboardEvent) => { + if (event.key === "Enter" || event.key === " ") { + if (isMegamenuOpen) { + exitMegamenu() + } else { + showMegaMenu() + } + } + } React.useEffect(() => setNavMenuOpen(productMenuOpen || subProductMenuOpen), [productMenuOpen, subProductMenuOpen]) - const subProductTrigger = subProductsNav?.find(({ href }) => isMatchedPath(path, href)) - - const label = subProductTrigger?.label || "Resources" - const icon = subProductTrigger?.label ? subProductTrigger.icon : undefined - return ( <> - - - - {(subProductTrigger || label === "Resources") && subProductsNav && ( - - - - )} + + Resources + + + + + Docs + + + + + Demos + + + + + Tools + + + + + ChainLog + - -
- - -
- -
- - - Developer Hub -
- -
-
+ {/* */} ) } diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css b/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css new file mode 100644 index 00000000000..a362c262da8 --- /dev/null +++ b/src/components/Header/Nav/ProductNavigation/Desktop/megaMenu.module.css @@ -0,0 +1,132 @@ +.megaMenuContainer { + z-index: 9999; + position: fixed; + top: 60px; + bottom: 0; + left: 0; + right: 0; + display: none; + justify-content: center; +} + +.wrapper { + max-width: 1360px; + width: 100%; + background-color: white; + height: fit-content; + border-radius: 0.5rem; + display: grid; + grid-template-columns: 3fr 1fr; + overflow: hidden; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); +} + +.wrapper h2 { + font-size: var(--space-3x); + font-weight: var(--font-weight-medium); + padding-bottom: var(--space-3x); + color: var(--gray-500); + text-transform: uppercase; + border-bottom: 1px solid var(--gray-200); +} + +.wrapper h3 { + font-family: var(--font-family-text); + font-weight: var(--font-weight-medium); + font-size: var(--space-4x); + line-height: 20px; + color: var(--gray-800); +} + +.wrapper p { + font-family: var(--font-family-text); + font-size: var(--space-3x); + color: var(--gray-800); + margin: var(--space-2x) 0; +} + +.resourcesMenuContentMain { + padding-top: var(--space-16x); + padding-left: var(--space-16x); + padding-bottom: var(--space-16x); + padding-right: var(--space-8x); + display: grid; + grid-template-columns: 1fr 1fr 1fr; + gap: var(--space-16x); +} + +.resourcesMenuContentRow { + display: flex; + flex-direction: column; +} + +.verticalDivider { + border-left: 1px solid var(--gray-300); + margin: 0 var(--space-3x); +} + +.links { + margin-bottom: var(--space-10x); +} + +.resourcesMenuContentFeatured { + padding-top: var(--space-16x); + padding-left: var(--space-8x); + padding-bottom: var(--space-16x); + padding-right: var(--space-16x); + background-color: var(--gray-100); +} + +.megaMenuLink { + display: flex; + align-items: center; + gap: var(--space-2x); +} + +.megaMenuLink h3 { + margin-bottom: 0; +} + +.megaMenuLink img { + width: var(--space-5x); + height: var(--space-5x); +} + +.featuredImage { + width: 100%; +} + +.divider { + border-bottom: 1px solid var(--gray-200); + margin: var(--space-8x) auto; +} + +.bottomLinks { + margin-top: auto; + display: flex; + flex-direction: column; + gap: var(--space-3x); +} + +.bottomLink { + display: flex; + align-items: center; + gap: var(--space-2x); + font-weight: var(--font-weight-medium); + color: var(--gray-800); + font-size: 15px; +} + +.bottomLink a { + color: var(--gray-800); +} + +.bottomLink a:hover { + color: var(--blue-500); +} + +@media screen and (min-width: 768px) { + .megaMenuContainer { + display: flex; + } +} diff --git a/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css b/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css index b1bc93d81ce..7f98ed0bdcb 100644 --- a/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css +++ b/src/components/Header/Nav/ProductNavigation/Desktop/productNavigation.module.css @@ -9,6 +9,73 @@ display: none; } +.navLink { + color: var(--gray-600); + font-size: var(--space-4x); + font-weight: var(--font-weight-medium); + padding: 0px 16px; + height: 100%; + position: relative; + transition: all 200ms ease-in-out; + user-select: none; + cursor: pointer; + display: flex; + align-items: center; + gap: var(--space-1x); +} + +.navLink:hover { + color: var(--blue-800); +} + +.navLink::before { + position: absolute; + content: ""; + width: var(--space-4x); + height: var(--space-4x); + background-color: var(--blue-500); + top: calc(-1 * var(--space-8x)); + left: 50%; + transform: translateX(-50%) rotate(45deg); + opacity: 0; + transition: all 200ms ease-in-out; +} + +.navLink:hover::before { + opacity: 1; +} + +.active { + color: var(--blue-800); +} + +.active::before { + position: absolute; + content: ""; + width: var(--space-4x); + height: var(--space-4x); + background-color: var(--blue-500); + top: calc(-1 * var(--space-8x)); + left: 50%; + transform: translateX(-50%) rotate(45deg); + opacity: 1; + transition: all 200ms ease-in-out; +} + +.active::after { + content: ""; + position: absolute; + bottom: -35px; + right: 35%; + transform: translateX(-50%) rotate(45deg); + width: 20px; + height: 20px; + z-index: -1; + box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1); + background-color: white; + padding: var(--space-2x); +} + @media screen and (min-width: 768px) { .root { display: flex; @@ -130,6 +197,64 @@ animation: scaleOut 200ms ease; } +.resourcesMenuContent { + position: absolute; + display: grid; + grid-template-columns: 3fr 1fr; + background-color: white; + border-radius: var(--border-radius-secondary); + box-shadow: 0px 4px 25px 0px rgba(0, 0, 0, 0.15); + top: 60px; + left: 20px; + right: 20px; + transform: translateX(-50%); +} + +.resourcesMenuContent::before { + content: ""; + position: absolute; + top: -5px; + left: 50%; + transform: translateX(-50%) rotate(45deg); + width: 10px; + height: 10px; + background-color: white; + box-shadow: 0px 4px 25px 0px rgba(0, 0, 0, 0.15); +} + +.resourcesMenuContent h2 { + font-size: var(--space-3x); + font-weight: var(--font-weight-medium); + padding-bottom: var(--space-3x); + color: var(--gray-500); + text-transform: uppercase; + border-bottom: 1px solid var(--gray-200); +} + +.resourcesMenuContentMain { + padding: var(--space-16x); +} + +.resourcesMenuContentFeatured { + padding: var(--space-8x); + background-color: var(--gray-100); +} + +.featuredImage { + width: 260px !important; +} + +.trigger span { + position: relative; + color: var(--gray-600) !important; + font-size: var(--space-4x); + font-weight: var(--font-weight-medium); +} + +.trigger:hover span { + color: var(--blue-800) !important; +} + .arrow { position: absolute; top: 70%; diff --git a/src/components/Header/Nav/ProductNavigation/MenuIcon.tsx b/src/components/Header/Nav/ProductNavigation/MenuIcon.tsx new file mode 100644 index 00000000000..399bdccae5a --- /dev/null +++ b/src/components/Header/Nav/ProductNavigation/MenuIcon.tsx @@ -0,0 +1,12 @@ +import React from "react" + +export const MenuIcon = () => ( + + + +) diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/BackArrowIcon.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/BackArrowIcon.tsx index 63717b8f48e..e63b6bf2588 100644 --- a/src/components/Header/Nav/ProductNavigation/Mobile/BackArrowIcon.tsx +++ b/src/components/Header/Nav/ProductNavigation/Mobile/BackArrowIcon.tsx @@ -1,9 +1,10 @@ export const BackArrowIcon = () => ( - + ) diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/BottomBar.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/BottomBar.tsx deleted file mode 100644 index 9663fd36f22..00000000000 --- a/src/components/Header/Nav/ProductNavigation/Mobile/BottomBar.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import styles from "./bottomBar.module.css" -import { ResourcesIcon } from "./ResourcesIcon" -import { Search } from "../../../aiSearch/Search" - -const ResourcesButton = () => ( - - - GitHub - -) - -const SearchButton = () => - -const DeveloperHubButton = () => ( - - Developer Hub - -) - -export const BottomBar = () => { - const buttons = [, , ] - return ( -
-
- {buttons.map((ButtonComponent, index) => ( -
{ButtonComponent}
- ))} -
-
- ) -} diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx new file mode 100644 index 00000000000..a9dd4ade6db --- /dev/null +++ b/src/components/Header/Nav/ProductNavigation/Mobile/MegaMenu.tsx @@ -0,0 +1,92 @@ +import styles from "./megaMenu.module.css" +import { Fragment } from "react/jsx-runtime" +import { megaMenuSections } from "../Desktop/MegaMenu" +import { useState } from "react" + +function MegaMenu() { + return ( +
+
+ {megaMenuSections.map((section) => ( +
+

{section.title}

+ {section.items.map((item, index) => ( + + ))} +
+ ))} + + +
+
+

Featured

+ +
+ +

Blockchain 101

+
+ Docs + + SDK +
+
+
+ ) +} + +function MegaMenuItem({ + image, + title, + description, + links, +}: { + image: string + title: string + description: string + links: { href: string; label: string }[] +}) { + const [open, setOpen] = useState(false) + return ( + <> + + {open && ( +
+

{description}

+ {links.map((link, index) => ( + + {link.label} + {index < links.length - 1 && } + + ))} +
+ )} + + ) +} + +export default MegaMenu diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx index 4a12e347a16..8d9ac9702f1 100644 --- a/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx +++ b/src/components/Header/Nav/ProductNavigation/Mobile/ProductNavigation.tsx @@ -4,12 +4,13 @@ import { ProductsNav, SubProducts } from "../../config" import { SearchTrigger } from "../../NavBar" import { isMatchedPath } from "../../isMatchedPath" import { clsx } from "../../utils" -import { CaretIcon } from "../CaretIcon" import { extendRadixComponent } from "../extendRadixComponent" -import { BottomBar } from "./BottomBar" import { ProductContent } from "./ProductContent" -import { SubProductContent } from "./SubProductContent" import styles from "./productNavigation.module.css" +import { MenuIcon } from "./MenuIcon" +import { BackArrowIcon } from "./BackArrowIcon" +import { CaretRightIcon } from "./CaretRightIcon" +import MegaMenu from "./MegaMenu" type Props = { searchTrigger?: SearchTrigger @@ -22,9 +23,8 @@ const Close = extendRadixComponent(Dialog.Close) const Portal = extendRadixComponent(Dialog.Portal) const Root = extendRadixComponent(Dialog.Root) -export function ProductNavigation({ productsNav, path }: Props) { +export function ProductNavigation({ productsNav, path, searchTrigger }: Props) { const [open, setOpen] = React.useState(false) - const [subProducts, setSubProducts] = React.useState(undefined) const [showSearch, setShowSearch] = React.useState(false) const [productsSlidePosition, setProductsSlidePosition] = React.useState<"main" | "submenu">("main") const closeButtonRef = React.useRef(null) @@ -53,30 +53,16 @@ export function ProductNavigation({ productsNav, path }: Props) { items, } - setSubProducts(safeSubProducts) setProductsSlidePosition("submenu") } - } else { - setSubProducts(undefined) } }, [path, productsNav]) - const onProductClick = React.useCallback((subProducts: SubProducts) => { - setSubProducts(subProducts) - setProductsSlidePosition("submenu") - }, []) - - const onSubproductClick = () => { - setProductsSlidePosition("main") - setSubProducts(undefined) - } - const handleOpenChange = (newOpenState: boolean) => { setOpen(newOpenState) if (!newOpenState) { setProductsSlidePosition("main") setShowSearch(false) - setSubProducts(undefined) } } @@ -90,17 +76,12 @@ export function ProductNavigation({ productsNav, path }: Props) { src="/chainlink-docs.svg" height={30} /> - + - +
-
    - -
-
- +
+
+ Documentation Home + + + +
+ +
+
+
+ + Resources + {/* Spacer */} +
+
+ +
- - - - diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/SubProductContent.tsx b/src/components/Header/Nav/ProductNavigation/Mobile/SubProductContent.tsx deleted file mode 100644 index 30e056076d6..00000000000 --- a/src/components/Header/Nav/ProductNavigation/Mobile/SubProductContent.tsx +++ /dev/null @@ -1,65 +0,0 @@ -import React, { useEffect, useRef } from "react" -import { BackArrowIcon } from "./BackArrowIcon" -import { Page } from "../../config" -import styles from "./subProductContent.module.css" - -type Props = { - onSubproductClick: () => void - subProducts?: { - label: string - items: { label: string; icon?: string; href: string; pages?: Page[] }[] - } - currentPath: string -} - -const renderPages = (pages: Page[], currentPath: string, indent: boolean) => { - return pages.map(({ label, href, children }) => { - const adjustedHref = "/" + href - const isActive = currentPath.replace(/\/$/, "") === adjustedHref.replace(/\/$/, "") - - const linkRef = useRef(null) - - useEffect(() => { - if (isActive && linkRef.current) { - linkRef.current.scrollIntoView({ behavior: "smooth", block: "center" }) - } - }, [isActive]) - - const linkStyle = { - backgroundColor: isActive ? "var(--blue-100)" : "transparent", - color: isActive ? "var(--blue-600)" : "inherit", - fontWeight: isActive ? "500" : "normal", - marginLeft: indent ? "20px" : "0", - } - - return ( - - - {label} - - {children && renderPages(children, currentPath, true)} - - ) - }) -} - -export const SubProductContent = ({ subProducts, onSubproductClick, currentPath }: Props) => { - if (!subProducts) { - return null - } - - return ( - <> - - {subProducts.items.map(({ label, pages }) => ( -
-

{label}

- {pages && renderPages(pages, currentPath, false)} -
- ))} - - ) -} diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/bottomBar.module.css b/src/components/Header/Nav/ProductNavigation/Mobile/bottomBar.module.css deleted file mode 100644 index 430763fce0f..00000000000 --- a/src/components/Header/Nav/ProductNavigation/Mobile/bottomBar.module.css +++ /dev/null @@ -1,39 +0,0 @@ -.bottomBar { - position: absolute; - bottom: 0; - left: 0; - height: 56px; - width: 100%; - background-color: var(--color-background-secondary); - color: var(--color-text-secondary); - display: flex; - align-items: center; - justify-content: center; - padding: 0 var(--space-8x); -} - -.bottomBar > div { - display: flex; - justify-content: space-between; - align-items: center; - gap: var(--space-2x); - width: calc(100% - 2 * var(--space-2x)); -} - -.bottomBar :is(button, a) { - display: flex; - justify-content: center; - align-items: center; - gap: var(--space-2x); - height: 100%; - width: 100%; - position: relative; -} - -.back { - color: var(--color-text-link); -} - -.back svg { - fill: var(--color-text-link); -} diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css b/src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css new file mode 100644 index 00000000000..87796ba5adb --- /dev/null +++ b/src/components/Header/Nav/ProductNavigation/Mobile/megaMenu.module.css @@ -0,0 +1,142 @@ +.wrapper { + width: 100%; + border-radius: 0.5rem; + display: flex; + flex-direction: column; + max-height: calc(100vh - 68px); +} + +.wrapper h2 { + font-size: var(--space-3x); + font-weight: var(--font-weight-medium); + padding-bottom: var(--space-3x); + color: var(--gray-400); + letter-spacing: 8%; + text-transform: uppercase; + border-bottom: 1px solid var(--gray-200); +} + +.wrapper h3 { + font-family: var(--font-family-text); + font-weight: var(--font-weight-medium); + font-size: var(--space-4x); + line-height: 20px; + color: var(--gray-800); +} + +.wrapper p { + font-family: var(--font-family-text); + font-size: var(--space-3x); + color: var(--gray-800); + margin: var(--space-2x) 0; +} + +.resourcesMenuContentMain { + padding: var(--space-6x) var(--space-8x) var(--space-4x) var(--space-8x); + display: flex; + flex-direction: column; + gap: var(--space-6x); +} + +.resourcesMenuContentRow { + display: flex; + flex-direction: column; +} + +.verticalDivider { + border-left: 1px solid var(--gray-300); + margin: 0 var(--space-3x); +} + +.links { + margin-bottom: var(--space-6x); +} + +.resourcesMenuContentFeatured { + padding-top: var(--space-16x); + padding-left: var(--space-8x); + padding-bottom: var(--space-16x); + padding-right: var(--space-16x); + background-color: var(--gray-100); +} + +.megaMenuButton { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-4x) var(--space-1x); + cursor: pointer; +} + +.megaMenuButton span { + font-size: var(--space-6x); + font-weight: var(--font-weight-medium); + color: var(--gray-500); +} + +.megaMenuLink { + display: flex; + align-items: center; + gap: var(--space-2x); +} + +.megaMenuLink h3 { + margin-bottom: 0; +} + +.megaMenuLink img { + width: var(--space-5x); + height: var(--space-5x); +} + +.featuredImage { + width: 100%; +} + +.divider { + border-bottom: 1px solid var(--gray-200); + margin: var(--space-8x) auto; +} + +.bottomLinks { + padding: var(--space-6x) 0; + display: flex; + flex-direction: column; + gap: var(--space-8x); + border-top: 1px solid var(--gray-200); +} + +.bottomLink { + display: flex; + align-items: center; + gap: var(--space-2x); + font-weight: var(--font-weight-medium); + color: var(--gray-800); + font-size: 15px; +} + +.bottomLink a { + color: var(--gray-800); +} + +.bottomLink a:hover { + color: var(--blue-500); +} + +@media screen and (min-width: 768px) { + .megaMenuContainer { + display: flex; + } +} + +@media screen and (min-width: 1280px) { + .wrapper::before { + left: 31%; + } +} + +@media screen and (min-width: 1565px) { + .wrapper::before { + left: 35%; + } +} diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css b/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css index 078661f7e41..f050592b418 100644 --- a/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css +++ b/src/components/Header/Nav/ProductNavigation/Mobile/productNavigation.module.css @@ -16,10 +16,20 @@ width: 100vw; width: 100dvw; display: flex; + flex-direction: column; overflow: hidden; z-index: 11; } +.header { + display: flex; + justify-content: space-between; + align-items: center; + padding: var(--space-6x) var(--space-8x); + /* border-bottom: 1px solid var(--gray-200); */ + box-shadow: 0px 4px 12px 0px #0000000f; +} + .content { width: 200vw; display: flex; @@ -34,17 +44,31 @@ transform: translateX(-100vw); } -.closeButton { - position: absolute; - top: var(--space-6x); - right: var(--space-8x); - z-index: 12; +.productContent { + display: flex; + flex-direction: column; + gap: var(--space-4x); + padding: var(--space-6x) var(--space-8x); +} + +.productContentLink { + font-size: var(--font-size-4x); + font-weight: var(--font-weight-medium); + color: var(--gray-600); + margin-right: var(--space-5x); + padding: var(--space-2x) 0; + font-size: var(--font-size-4x); + display: flex; + justify-content: space-between; +} + +.subProductContentPage { + overflow: scroll; } .productContent, .subProductContent { overflow: scroll; - padding: var(--space-6x) var(--space-8x); list-style: none; width: 100vw; padding-bottom: 56px; @@ -54,6 +78,13 @@ flex-direction: column; } +.subProductContentTitle { + font-size: var(--font-size-4x); + font-weight: var(--font-weight-medium); + color: var(--blue-800); + margin-right: var(--space-5x); +} + @keyframes slideFromLeft { from { transform: translateX(-100%); diff --git a/src/components/Header/Nav/ProductNavigation/Mobile/subProductContent.module.css b/src/components/Header/Nav/ProductNavigation/Mobile/subProductContent.module.css deleted file mode 100644 index 825edfb433f..00000000000 --- a/src/components/Header/Nav/ProductNavigation/Mobile/subProductContent.module.css +++ /dev/null @@ -1,22 +0,0 @@ -.back { - color: var(--color-text-link); - font-weight: var(--font-weight-bold); - display: flex; - align-items: center; - gap: var(--space-2x); - padding: var(--space-1x) 0 var(--space-3x); -} - -.back svg { - fill: var(--color-text-link); -} - -.section { - padding-top: var(--space-4x); - composes: text-400 from global; -} - -.link { - display: block; - padding: var(--space-2x) 0 var(--space-2x) var(--space-5x); -} diff --git a/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx b/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx index e6ef3a5c8f1..363a757f41d 100644 --- a/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx +++ b/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx @@ -9,6 +9,9 @@ type Props = { setNavMenuOpen: (navMenuOpen: boolean) => void productsNav: ProductsNav subProductsNav?: SubProductsNav + showMegaMenu: () => void + isMegamenuOpen: boolean + exitMegamenu: () => void } export const ProductNavigation = (props: Props) => ( diff --git a/src/components/Header/Nav/navBar.module.css b/src/components/Header/Nav/navBar.module.css index b2764fa7a88..d508594e119 100644 --- a/src/components/Header/Nav/navBar.module.css +++ b/src/components/Header/Nav/navBar.module.css @@ -20,10 +20,9 @@ position: relative; display: flex; justify-content: space-between; - padding-block: var(--space-4x); + padding-block: var(--space-0x); + width: auto; height: var(--space-16x); - /* max-width: var(--fullwidth-max-width); - margin: 0 auto; */ gap: var(--space-3x); } @@ -131,7 +130,7 @@ } .quickLinksButton { - display: inline; + display: none; background: none; border: var(--border-width-primary) solid transparent; cursor: pointer; @@ -254,6 +253,12 @@ color: var(--blue-600); } +@media screen and (min-width: 768px) { + .quickLinksButton { + display: inline; + } +} + @media screen and (min-width: 768px) { :is(.button) { display: flex; @@ -288,6 +293,7 @@ .rightSection { flex-direction: row; + justify-content: flex-end; } .quickLinksTooltip { @@ -305,6 +311,13 @@ } } +/* For fixing the layout shifts caused by the search widget */ +@media screen and (min-width: 995px) { + .rightSection { + width: 340px; + } +} + @media screen and (max-width: 768px) { .container { position: relative; diff --git a/src/components/Header/NavBar.tsx b/src/components/Header/NavBar.tsx index 9090af025c9..4cfd40709d0 100644 --- a/src/components/Header/NavBar.tsx +++ b/src/components/Header/NavBar.tsx @@ -1,14 +1,16 @@ -import React from "react" +import React, { useState } from "react" import { NavBar as Nav } from "./Nav" import { Search } from "./aiSearch/Search" import { getNavigationProps } from "./getNavigationProps" import { useNavBar } from "./useNavBar/useNavBar" import styles from "./scroll.module.css" +import MegaMenu from "./Nav/ProductNavigation/Desktop/MegaMenu" declare const Weglot: any export const NavBar = ({ path, showSearch = true }: { path: string; showSearch?: boolean }) => { const navRef = React.useRef(null) + const [showMegaMenu, setShowMegaMenu] = useState(false) const { setNavBarInfo } = useNavBar() @@ -68,7 +70,11 @@ export const NavBar = ({ path, showSearch = true }: { path: string; showSearch?: path={path} searchTrigger={showSearch ? : undefined} onHideChange={onHideChange} + isMegamenuOpen={showMegaMenu} + showMegaMenu={() => setShowMegaMenu(true)} + exitMegamenu={() => setShowMegaMenu(false)} /> + {showMegaMenu && setShowMegaMenu(false)} />} ) } diff --git a/src/components/Header/aiSearch/Search.tsx b/src/components/Header/aiSearch/Search.tsx index af545dab41e..f17c6fd2d68 100644 --- a/src/components/Header/aiSearch/Search.tsx +++ b/src/components/Header/aiSearch/Search.tsx @@ -1,7 +1,7 @@ import { SearchButton } from "./SearchButton" import { SearchModal } from "./SearchModal" -export const Search = ({ variant = "default" }: { variant?: "default" | "bottomBar" }) => { +export const Search = ({ variant = "default" }: { variant?: "default" | "mobile" }) => { return ( <> diff --git a/src/components/Header/aiSearch/SearchButton.tsx b/src/components/Header/aiSearch/SearchButton.tsx index 04cbcd401cf..096724f16e4 100644 --- a/src/components/Header/aiSearch/SearchButton.tsx +++ b/src/components/Header/aiSearch/SearchButton.tsx @@ -1,6 +1,7 @@ import { clsx } from "~/lib" import styles from "./searchButton.module.css" import { useEffect, useState } from "react" +import SearchIcon from "../../QuickLinks/assets/search-icon.svg" const searchIcon = ( ) -export const SearchButton = ({ variant }: { variant: "default" | "bottomBar" }) => { +export const SearchButton = ({ variant }: { variant: "default" | "mobile" }) => { const [isMac, setIsMac] = useState(false) useEffect(() => { const checkIsMac = typeof navigator !== "undefined" ? navigator.userAgent.toUpperCase().indexOf("MAC") >= 0 : false @@ -58,15 +59,8 @@ export const SearchButton = ({ variant }: { variant: "default" | "bottomBar" })
{isMac ? "⌘" : "Ctrl+"}K
) : ( - ) } diff --git a/src/components/Header/aiSearch/searchButton.module.css b/src/components/Header/aiSearch/searchButton.module.css index a3b439cea00..019efdaae35 100644 --- a/src/components/Header/aiSearch/searchButton.module.css +++ b/src/components/Header/aiSearch/searchButton.module.css @@ -12,6 +12,10 @@ gap: vaR(--space-2x); } +.mobile { + display: inline; +} + .default .icon { min-width: var(--space-4x); height: var(--space-4x); @@ -32,6 +36,12 @@ display: none; } +@media screen and (min-width: 768px) { + .mobile { + display: none; + } +} + @media screen and (min-width: 996px) { .default { max-width: 160px; /* Initial width */ @@ -67,8 +77,3 @@ color: #6d7380; } } - -.bottomBar { - width: full; - display: flex; -} diff --git a/src/components/LeftSidebar/LeftSidebar.astro b/src/components/LeftSidebar/LeftSidebar.astro index cd68f10ec93..c1d1f9fd01c 100644 --- a/src/components/LeftSidebar/LeftSidebar.astro +++ b/src/components/LeftSidebar/LeftSidebar.astro @@ -3,6 +3,7 @@ import { Sections } from "~/content/config" import { SIDEBAR, MENU, SectionContent } from "../../config" import { flattenChildren } from "../../scripts/flatten-children" import ActiveIcon from "./ActiveIcon.astro" +import DocsPicker from "../DocsSwitcher/DocsPicker" export type Props = { currentPage: string section?: Sections @@ -54,49 +55,54 @@ const isCurrentPageMatch = (sectionUrl: string, currentPage: string): boolean => --- diff --git a/src/features/notifications/components/HeaderBanner.tsx b/src/features/notifications/components/HeaderBanner.tsx index 0b74d373c20..4ee0ff0ca78 100644 --- a/src/features/notifications/components/HeaderBanner.tsx +++ b/src/features/notifications/components/HeaderBanner.tsx @@ -36,9 +36,6 @@ export const HeaderBanner: React.FC<{ bannerContent?: BannerContent }> = ({ bann if (!bannerContent) return null return (
-
- {bannerTypes[bannerContent.type].alertText} -

{bannerContent.description}{" "} {bannerContent.linkUrl && ( diff --git a/src/layouts/DocsLayout.astro b/src/layouts/DocsLayout.astro index 7ddc686b0a7..df3f7f730bf 100644 --- a/src/layouts/DocsLayout.astro +++ b/src/layouts/DocsLayout.astro @@ -133,7 +133,7 @@ const includeLinkToWalletScript = !!Astro.props.frontmatter.metadata?.linkToWall } #grid-left { - width: 285px; + width: 376px; padding-left: var(--space-16x); } } diff --git a/src/pages/index.astro b/src/pages/index.astro index 403b536ac75..a2b4c739906 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -2,28 +2,44 @@ import ProductTabs from "../features/landing/sections/ProductTabs.astro" import LandingLayout from "../layouts/LandingLayout.astro" import HeroCTA from "../features/landing/sections/HeroCTA.astro" +import BaseLayout from "~/layouts/BaseLayout.astro" + +import * as CONFIG from "../config" + +const formattedContentTitle = `${CONFIG.PAGE.titleFallback} | ${CONFIG.SITE.title}` --- - - -

- -
- + +
+
+
+

What are you
building?

+ +
+
+ +
+
From a7e54bbac1b04f483fe1b248eab74c98f8423a4b Mon Sep 17 00:00:00 2001 From: "Mark S. Shenouda" <49324987+markshenouda@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:08:28 +0300 Subject: [PATCH 02/41] update: homepage metadata (#5) fix: remove unused code Co-authored-by: Simone Cuomo --- public/images/og.png | Bin 0 -> 27498 bytes src/layouts/LandingLayout.astro | 13 +++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 public/images/og.png diff --git a/public/images/og.png b/public/images/og.png new file mode 100644 index 0000000000000000000000000000000000000000..5c3057ab3146c19241252ed2905f90f4d9a31eda GIT binary patch literal 27498 zcmZs@c|4Ts|35xNi59XXg;F77twgfrMA=2mkX>Y{5F*>iQdy#sCD~f6Gj_6MOQe*2 zOF~hNU6`>9W`3`G>MZZi_xHznoO8_F_kG>h^;)0L=WD_Z^v-T)iM`|i5r3Q}=c`e{>zV^i5@TFT9M>KfF&s=#9sML> z#!#L!${A%*`Kmwmikn=(WZH@O_zv`v*a4T~ur86Sho2~7URCIxGZ}x$UASDTzvub= zEu;4p?3lQZ)?0RPSF_3ZsK@%!lvNaeN*|T>XnTCD&ZBM0%cA*PyZp!1l-0#kbF2Qt zb?&=syjz}ZMYTPfY1!Kqrd9s%`-v z-qJWmJ2pVP?%IA3{=2_nH4-BnWO76CRGL$xM}xNrinrnE?w7>!iT*FCJmMA!OG=B_ z&x31N#!0kVIvnBa?+L-6e{mr5OaNDvM>2ZX%_Lp@o&XT$BCJ1-92sUPTtFW z=m2R}p^Bsv9yUqW?J)`@Tm8vlAJ;c|Y>cR$hbXonj+65(s!NwBsnvpL-!l;%G0d%p z`j|)h%M@$k!`|MU8^kM@!!ct~7Y>;`es7OS4$Qd7x& z%nT^!GjNoN;rsD^V@fxXHxxLvkQ^w^XLymvOr70t{hhb|ouUE??`Bl?VFn(QU4FHo z%j+($RkLry!_B+6EN-?N>zGeeGNO3-VLhzRk&pSONOtG3MUtP~hb$%*VAn_5ΜO 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 +
From 77fc4a1517e988ce514524aabbac4b4d608c55c1 Mon Sep 17 00:00:00 2001 From: "Mark S. Shenouda" <49324987+markshenouda@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:14:49 +0300 Subject: [PATCH 03/41] feat: New Header Banner (#6) * feat: New Header Banner * fix: notification versions --- .../notifications/components/CloseIcon.tsx | 13 +++++++ .../notifications/components/HeaderBanner.tsx | 38 +++++++++++++------ .../components/NotificationBanner.astro | 2 +- .../components/headerBanner.module.css | 31 +++++++++++++++ 4 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 src/features/notifications/components/CloseIcon.tsx create mode 100644 src/features/notifications/components/headerBanner.module.css diff --git a/src/features/notifications/components/CloseIcon.tsx b/src/features/notifications/components/CloseIcon.tsx new file mode 100644 index 00000000000..e63ceb0315e --- /dev/null +++ b/src/features/notifications/components/CloseIcon.tsx @@ -0,0 +1,13 @@ +import React from "react" + +type Props = { + style?: React.CSSProperties +} + +export const CloseIcon = ({ style }: Props) => ( + + + + + +) diff --git a/src/features/notifications/components/HeaderBanner.tsx b/src/features/notifications/components/HeaderBanner.tsx index 4ee0ff0ca78..5276c18a8e2 100644 --- a/src/features/notifications/components/HeaderBanner.tsx +++ b/src/features/notifications/components/HeaderBanner.tsx @@ -1,5 +1,8 @@ -import React from "react" +import React, { useState, useEffect } from "react" import headerbanner from "@chainlink/design-system/headerbanner.module.css" +import headerbannerCustom from "./headerBanner.module.css" +import { clsx } from "~/lib" +import { CloseIcon } from "./CloseIcon" type BannerType = "info" | "success" | "warning" | "danger" export type BannerContent = { @@ -9,33 +12,35 @@ export type BannerContent = { linkUrl?: string } -const bannerTypes: Record = { +const bannerTypes: Record = { info: { primaryColour: "var(--blue-800)", - alertColour: "var(--blue-600)", - alertText: "NEW", }, success: { primaryColour: "var(--green-600)", - alertColour: "var(--green-400)", - alertText: "NEW", }, warning: { primaryColour: "var(--yellow-400)", - alertColour: "var(--yellow-300)", - alertText: "ALERT", }, danger: { primaryColour: "var(--red-600)", - alertColour: "var(--red-400)", - alertText: "ALERT", }, } export const HeaderBanner: React.FC<{ bannerContent?: BannerContent }> = ({ bannerContent }) => { - if (!bannerContent) return null + const [isDismissed, setIsDismissed] = useState(true) // Change to false to show banner later to prevent flasing on page load for users who have already dismissed it + useEffect(() => { + const isDismissedLocalStorage = localStorage.getItem("headerBannerDismissed") + if (!isDismissedLocalStorage || isDismissedLocalStorage !== bannerContent?.description) { + setIsDismissed(false) + } + }, [isDismissed]) + if (!bannerContent || isDismissed) return null return ( -
+

{bannerContent.description}{" "} {bannerContent.linkUrl && ( @@ -44,6 +49,15 @@ export const HeaderBanner: React.FC<{ bannerContent?: BannerContent }> = ({ bann )}

+
) as React.ReactElement // Explicitly assigning to ReactElement cause TS is confused otherwise } diff --git a/src/features/notifications/components/NotificationBanner.astro b/src/features/notifications/components/NotificationBanner.astro index f5fd36e0376..78717449627 100644 --- a/src/features/notifications/components/NotificationBanner.astro +++ b/src/features/notifications/components/NotificationBanner.astro @@ -3,4 +3,4 @@ import { NotificationData } from "../data" import { HeaderBanner } from "./HeaderBanner" --- - + diff --git a/src/features/notifications/components/headerBanner.module.css b/src/features/notifications/components/headerBanner.module.css new file mode 100644 index 00000000000..d58aa5a7db3 --- /dev/null +++ b/src/features/notifications/components/headerBanner.module.css @@ -0,0 +1,31 @@ +.container { + position: relative; +} + +.dismiss { + position: absolute; + right: var(--space-24x); + top: 50%; + transform: translateY(-50%); + display: flex; + justify-content: center; + align-items: center; + font-size: var(--space-4x); + cursor: pointer; + background: white; + border-radius: 50%; + color: var(--color-primary); +} + +@media (max-width: 768px) { + .container { + justify-content: start; + } + + .container p { + padding-right: var(--space-6x); + } + .dismiss { + right: var(--space-6x); + } +} From b3359e0a84f1fc4bc278932b04053dc75dd74a86 Mon Sep 17 00:00:00 2001 From: "Mark S. Shenouda" <49324987+markshenouda@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:43:39 +0300 Subject: [PATCH 04/41] feat: Docs Navigation for Desktop (#7) * feat: Docs Navigation for Desktop * fix: remove unused comments * fix: quicklinks * fix: left side nav --- public/assets/icons/github-blue.svg | 10 ++ public/assets/icons/quick-links.svg | 11 +++ .../DocsNavigation/DocsNavigationDesktop.tsx | 42 +++++++++ .../DocsNavigation/DocsPickerDesktop.tsx | 45 +++++++++ .../docsNavigationDesktop.module.css | 49 ++++++++++ .../docsPickerDesktop.module.css | 94 +++++++++++++++++++ src/components/DocsNavigation/index.tsx | 11 +++ src/components/Header/Nav/QuickLinksModal.tsx | 26 +++++ src/components/Header/Nav/navBar.module.css | 8 ++ src/components/LeftSidebar/LeftSidebar.astro | 4 +- src/layouts/DocsLayout.astro | 2 + 11 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 public/assets/icons/github-blue.svg create mode 100644 public/assets/icons/quick-links.svg create mode 100644 src/components/DocsNavigation/DocsNavigationDesktop.tsx create mode 100644 src/components/DocsNavigation/DocsPickerDesktop.tsx create mode 100644 src/components/DocsNavigation/docsNavigationDesktop.module.css create mode 100644 src/components/DocsNavigation/docsPickerDesktop.module.css create mode 100644 src/components/DocsNavigation/index.tsx create mode 100644 src/components/Header/Nav/QuickLinksModal.tsx diff --git a/public/assets/icons/github-blue.svg b/public/assets/icons/github-blue.svg new file mode 100644 index 00000000000..fe9cec74f42 --- /dev/null +++ b/public/assets/icons/github-blue.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/assets/icons/quick-links.svg b/public/assets/icons/quick-links.svg new file mode 100644 index 00000000000..ca4bf545bb4 --- /dev/null +++ b/public/assets/icons/quick-links.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/components/DocsNavigation/DocsNavigationDesktop.tsx b/src/components/DocsNavigation/DocsNavigationDesktop.tsx new file mode 100644 index 00000000000..fda88c77446 --- /dev/null +++ b/src/components/DocsNavigation/DocsNavigationDesktop.tsx @@ -0,0 +1,42 @@ +import { clsx } from "~/lib" +import { useNavBar } from "../Header/useNavBar/useNavBar" +import DocsPickerDesktop from "./DocsPickerDesktop" +import styles from "./docsNavigationDesktop.module.css" +import QuickLinksModal from "../Header/Nav/QuickLinksModal" +import { useState } from "react" + +function DocsNavigationDesktop({ pathname }: { pathname: string }) { + const { $navBarInfo } = useNavBar() + const [isModalOpen, setIsModalOpen] = useState(false) + return ( + <> + + {isModalOpen && setIsModalOpen((state) => !state)} />} + + ) +} + +export default DocsNavigationDesktop diff --git a/src/components/DocsNavigation/DocsPickerDesktop.tsx b/src/components/DocsNavigation/DocsPickerDesktop.tsx new file mode 100644 index 00000000000..3c05e17f86f --- /dev/null +++ b/src/components/DocsNavigation/DocsPickerDesktop.tsx @@ -0,0 +1,45 @@ +import { useState } from "react" +import { isMatchedPath } from "../Header/Nav/isMatchedPath" +import { getNavigationProps } from "../Header/getNavigationProps" +import styles from "./docsPickerDesktop.module.css" +import { clsx } from "../Header/Nav/utils" + +function DocsPickerDesktop({ pathname }: { pathname: string }) { + const [productMenuOpen, setProductMenuOpen] = useState(false) + const { subProductsNav } = getNavigationProps(pathname) + const subProductTrigger = subProductsNav?.find(({ href }) => isMatchedPath(pathname, href)) + + const label = subProductTrigger?.label || "Resources" + const icon = subProductTrigger?.label ? subProductTrigger.icon : undefined + + return ( +
setProductMenuOpen(true)} + onMouseLeave={() => setProductMenuOpen(false)} + > + {label} +
+ +
+ {productMenuOpen && ( +
+
    + {subProductsNav + .filter((item) => !item.hideFromDropdown) + .map((item) => ( +
  • + + + {item.label} + +
  • + ))} +
+
+ )} +
+ ) +} + +export default DocsPickerDesktop diff --git a/src/components/DocsNavigation/docsNavigationDesktop.module.css b/src/components/DocsNavigation/docsNavigationDesktop.module.css new file mode 100644 index 00000000000..0e9ee11c245 --- /dev/null +++ b/src/components/DocsNavigation/docsNavigationDesktop.module.css @@ -0,0 +1,49 @@ +.nav { + position: sticky; + display: none; + top: var(--space-16x); + background-color: var(--gray-100); + height: var(--space-16x); + box-shadow: var(--space-0x) var(--space-1x) var(--space-3x) var(--space-0x) #0000000f; + z-index: 9; + transition: top 0.5s ease; +} + +.hidden { + top: 0 !important; +} + +.container { + display: flex; + justify-content: space-between; + align-items: center; + margin: auto; + max-width: min(calc(1440px - 2 * var(--space-16x)), calc(100% - 2 * var(--space-16x))); +} + +.links { + display: flex; + gap: var(--space-4x); +} + +.link { + transition: color 0.2s ease; + font-size: var(--space-4x); + color: var(--gray-600); + display: flex; + justify-content: center; + align-items: center; + padding: var(--space-0x) var(--space-0x) var(--space-0x) var(--space-2x); + gap: var(--space-2x); + font-weight: var(--font-weight-medium); +} + +.link:hover { + color: var(--blue-600); +} + +@media screen and (min-width: 992px) { + .nav { + display: block; + } +} diff --git a/src/components/DocsNavigation/docsPickerDesktop.module.css b/src/components/DocsNavigation/docsPickerDesktop.module.css new file mode 100644 index 00000000000..1fc50624103 --- /dev/null +++ b/src/components/DocsNavigation/docsPickerDesktop.module.css @@ -0,0 +1,94 @@ +.container { + display: flex; + align-items: center; + padding: var(--space-3x) var(--space-4x); + padding-right: var(--space-16x); + gap: var(--space-3x); + isolation: isolate; + z-index: 100; + position: relative; + color: var(--blue-800); + flex: none; + font-size: 18px; + font-weight: var(--font-weight-medium); + order: 0; + flex-grow: 0; + cursor: pointer; + transition: all 0.2s ease; + width: 235px; +} + +.logo { + width: var(--space-8x); + height: var(--space-8x); +} + +.caret { + width: var(--space-4x); + height: var(--space-4x); + border-radius: 50%; + position: absolute; + right: var(--space-4x); + display: flex; + align-items: center; + justify-content: center; +} + +.caret span { + width: var(--space-2x); + height: var(--space-2x); + border-right: 2px solid var(--gray-600); + border-bottom: 2px solid var(--gray-600); + transform: rotate(45deg); + transition: transform 0.2s ease; + margin-bottom: 1px; +} + +.container:hover { + border-color: var(--blue-300); +} + +.container:hover .caret span { + transform: rotate(-135deg); + margin-bottom: -1px; +} + +.menu { + position: absolute; + top: 100%; + left: 0; + width: 100%; + background: #ffffff; + border: 1px solid var(--blue-200); + border-radius: var(--space-2x); + box-shadow: var(--space-0x) var(--space-1x) var(--space-2x) rgba(0, 0, 0, 0.1); + z-index: 100; + transition: all 0.2s ease; + padding: var(--space-2x) var(--space-3x); +} + +.icon { + width: var(--space-5x); + height: var(--space-5x); +} + +.menu ul { + list-style: none; + padding: var(--space-2x); + margin: 0; + display: flex; + flex-direction: column; +} + +.link { + display: flex; + align-items: center; + font-size: var(--space-4x); + color: var(--blue-800); + padding: var(--space-3x) var(--space-2x); + gap: var(--space-2x); +} + +.link:hover { + color: var(--blue-600); +} diff --git a/src/components/DocsNavigation/index.tsx b/src/components/DocsNavigation/index.tsx new file mode 100644 index 00000000000..b72752f90f6 --- /dev/null +++ b/src/components/DocsNavigation/index.tsx @@ -0,0 +1,11 @@ +import DocsNavigationDesktop from "./DocsNavigationDesktop" + +function DocsNavigation({ pathname }: { pathname: string }) { + return ( + <> + + + ) +} + +export default DocsNavigation diff --git a/src/components/Header/Nav/QuickLinksModal.tsx b/src/components/Header/Nav/QuickLinksModal.tsx new file mode 100644 index 00000000000..38fa672fc4c --- /dev/null +++ b/src/components/Header/Nav/QuickLinksModal.tsx @@ -0,0 +1,26 @@ +import ProductChainTable from "~/components/QuickLinks/sections/ProductChainTable" +import styles from "./navBar.module.css" + +function QuickLinksModal({ toggleModal }: { toggleModal: () => void }) { + return ( +
+
e.stopPropagation()}> + +
+

+ Quick links for Builders +

+

+ Find all the supported networks at a glance, and the network-specific information you need to build your + project. +

+ +
+
+
+ ) +} + +export default QuickLinksModal diff --git a/src/components/Header/Nav/navBar.module.css b/src/components/Header/Nav/navBar.module.css index d508594e119..e0d37aebbf5 100644 --- a/src/components/Header/Nav/navBar.module.css +++ b/src/components/Header/Nav/navBar.module.css @@ -309,6 +309,14 @@ .modalContentWrapper { width: 80%; } + + .button { + display: none; + } + + .quickLinksWrapper { + display: none; + } } /* For fixing the layout shifts caused by the search widget */ diff --git a/src/components/LeftSidebar/LeftSidebar.astro b/src/components/LeftSidebar/LeftSidebar.astro index c1d1f9fd01c..29ba433d289 100644 --- a/src/components/LeftSidebar/LeftSidebar.astro +++ b/src/components/LeftSidebar/LeftSidebar.astro @@ -1,9 +1,8 @@ --- import { Sections } from "~/content/config" -import { SIDEBAR, MENU, SectionContent } from "../../config" +import { SIDEBAR, SectionContent } from "../../config" import { flattenChildren } from "../../scripts/flatten-children" import ActiveIcon from "./ActiveIcon.astro" -import DocsPicker from "../DocsSwitcher/DocsPicker" export type Props = { currentPage: string section?: Sections @@ -56,7 +55,6 @@ const isCurrentPageMatch = (sectionUrl: string, currentPage: string): boolean => diff --git a/src/components/DocsNavigation/DocsNavigationMobile/DocsPickerMobile.tsx b/src/components/DocsNavigation/DocsNavigationMobile/DocsPickerMobile.tsx index fe4ac4c62ee..5ae4d99c842 100644 --- a/src/components/DocsNavigation/DocsNavigationMobile/DocsPickerMobile.tsx +++ b/src/components/DocsNavigation/DocsNavigationMobile/DocsPickerMobile.tsx @@ -109,7 +109,7 @@ export function ProductNavigation({ path }: Props) { >
    - +
void productsNav: ProductsNav + currentPath: string } -export const ProductContent = ({ onProductClick, productsNav }: Props) => { +export const ProductContent = ({ onProductClick, productsNav, currentPath }: Props) => { return ( <> {productsNav.categories.map(({ label, items }) => ( - + ))} ) diff --git a/src/components/DocsNavigation/DocsNavigationMobile/category.module.css b/src/components/DocsNavigation/DocsNavigationMobile/category.module.css index 0276902b18a..4bbabd052b0 100644 --- a/src/components/DocsNavigation/DocsNavigationMobile/category.module.css +++ b/src/components/DocsNavigation/DocsNavigationMobile/category.module.css @@ -8,6 +8,11 @@ width: 100%; } +.link:hover, +.active { + color: var(--blue-600); +} + .label { composes: paragraph-100 from global; display: block; diff --git a/src/components/DocsNavigation/DocsNavigationMobile/docsNavigationMobile.module.css b/src/components/DocsNavigation/DocsNavigationMobile/docsNavigationMobile.module.css index 510ae29bfa5..dddb0f3166d 100644 --- a/src/components/DocsNavigation/DocsNavigationMobile/docsNavigationMobile.module.css +++ b/src/components/DocsNavigation/DocsNavigationMobile/docsNavigationMobile.module.css @@ -1,8 +1,8 @@ .nav { - position: sticky; top: var(--space-16x); background-color: var(--gray-100); - height: var(--space-16x); + padding-top: var(--space-4x); + padding-bottom: var(--space-4x); box-shadow: var(--space-0x) var(--space-1x) var(--space-3x) var(--space-0x) #0000000f; z-index: 8; transition: top 0.5s ease; @@ -12,12 +12,13 @@ top: 0 !important; } -.container { +.DocsPickerContainer { display: flex; justify-content: space-between; align-items: center; margin: auto; max-width: calc(100% - 2 * var(--space-6x)); + height: var(--space-6x); } .links { diff --git a/src/components/DocsNavigation/DocsNavigationMobile/docsPickerMobile.module.css b/src/components/DocsNavigation/DocsNavigationMobile/docsPickerMobile.module.css index b4af7dbb5f2..3f0439073b0 100644 --- a/src/components/DocsNavigation/DocsNavigationMobile/docsPickerMobile.module.css +++ b/src/components/DocsNavigation/DocsNavigationMobile/docsPickerMobile.module.css @@ -1,7 +1,6 @@ .container { display: flex; align-items: center; - padding: var(--space-4x) var(--space-0x); padding-right: var(--space-16x); gap: var(--space-2x); isolation: isolate; @@ -15,11 +14,12 @@ flex-grow: 0; cursor: pointer; transition: all 0.2s ease; + height: var(--space-6x); } .logo { - width: var(--space-8x); - height: var(--space-8x); + width: var(--space-5x); + height: var(--space-5x); } .caret { diff --git a/src/components/DocsNavigation/DocsNavigationMobile/productNavigation.module.css b/src/components/DocsNavigation/DocsNavigationMobile/productNavigation.module.css index 18410af1d16..e3a0bd84385 100644 --- a/src/components/DocsNavigation/DocsNavigationMobile/productNavigation.module.css +++ b/src/components/DocsNavigation/DocsNavigationMobile/productNavigation.module.css @@ -4,8 +4,8 @@ .logo { margin-right: var(--space-2x); - width: var(--space-8x); - height: var(--space-8x); + width: var(--space-5x); + height: var(--space-5x); } .icon { @@ -115,7 +115,6 @@ .trigger { display: flex; align-items: center; - padding: var(--space-4x) var(--space-0x); padding-right: var(--space-16x); gap: var(--space-2x); isolation: isolate; diff --git a/src/components/HeadCommon.astro b/src/components/HeadCommon.astro index 6cfe10de0f5..aff2315d557 100644 --- a/src/components/HeadCommon.astro +++ b/src/components/HeadCommon.astro @@ -17,15 +17,8 @@ const { title } = Astro.props - - + + diff --git a/src/components/HeadSEO.astro b/src/components/HeadSEO.astro index 7d5e2acf4ae..c7753c3518a 100644 --- a/src/components/HeadSEO.astro +++ b/src/components/HeadSEO.astro @@ -48,15 +48,8 @@ if (metadata?.image) { - - + + - - + +