diff --git a/package-lock.json b/package-lock.json index ad854a733e7..cea0eee1f25 100644 --- a/package-lock.json +++ b/package-lock.json @@ -32,7 +32,7 @@ "@openzeppelin/contracts": "^4.9.6", "astro": "^5.7.12", "bignumber.js": "^9.3.0", - "chainlink-algolia-search": "^0.8.7", + "chainlink-algolia-search": "^0.11.0-alpha.13", "clipboard": "^2.0.11", "dotenv": "^16.5.0", "ethers": "^6.14.0", @@ -13628,7 +13628,6 @@ "version": "1.26.5", "resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.26.5.tgz", "integrity": "sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==", - "dev": true, "license": "MIT" }, "node_modules/@types/qs": { @@ -16241,11 +16240,16 @@ } }, "node_modules/chainlink-algolia-search": { - "version": "0.8.7", - "resolved": "https://registry.npmjs.org/chainlink-algolia-search/-/chainlink-algolia-search-0.8.7.tgz", - "integrity": "sha512-lXPILOHiqwh1EQabWOYbSYvZ4VIbqnACOgolL7I5EGIUsjdmuzQsrnz1DjCgDOjHBXA7HzjEZ+qfjEiObplc+A==", + "version": "0.11.0-alpha.14", + "resolved": "https://registry.npmjs.org/chainlink-algolia-search/-/chainlink-algolia-search-0.11.0-alpha.14.tgz", + "integrity": "sha512-NaNYPUiF2lnKKKfU8YOXQAnNjCyCZ0N+CDWLGuPcbDLq4mf26M+iSNkBirbBa4XSBI31+1EiB8B01kzXaVATug==", "dependencies": { - "@algolia/client-search": "^5.17.1" + "@algolia/client-search": "^5.17.1", + "react-markdown": "^10.1.0", + "rehype-autolink-headings": "^7.1.0", + "rehype-prism-plus": "^2.0.0", + "rehype-slug": "^6.0.0", + "remark-gfm": "^4.0.1" }, "peerDependencies": { "react": ">=18.0.0", @@ -22588,6 +22592,15 @@ "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", "license": "MIT" }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/html-void-elements": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", @@ -28834,6 +28847,11 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/parse-numeric-range": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz", + "integrity": "sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==" + }, "node_modules/parse5": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", @@ -30091,6 +30109,32 @@ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==", "license": "MIT" }, + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } + }, "node_modules/react-modal": { "version": "3.16.1", "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz", @@ -30840,6 +30884,84 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/rehype-prism-plus": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/rehype-prism-plus/-/rehype-prism-plus-2.0.1.tgz", + "integrity": "sha512-Wglct0OW12tksTUseAPyWPo3srjBOY7xKlql/DPKi7HbsdZTyaLCAoO58QBKSczFQxElTsQlOY3JDOFzB/K++Q==", + "dependencies": { + "hast-util-to-string": "^3.0.0", + "parse-numeric-range": "^1.3.0", + "refractor": "^4.8.0", + "rehype-parse": "^9.0.0", + "unist-util-filter": "^5.0.0", + "unist-util-visit": "^5.0.0" + } + }, + "node_modules/rehype-prism-plus/node_modules/@types/hast": { + "version": "2.3.10", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.10.tgz", + "integrity": "sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==", + "dependencies": { + "@types/unist": "^2" + } + }, + "node_modules/rehype-prism-plus/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" + }, + "node_modules/rehype-prism-plus/node_modules/hast-util-parse-selector": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-prism-plus/node_modules/hastscript": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", + "dependencies": { + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-prism-plus/node_modules/property-information": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/rehype-prism-plus/node_modules/refractor": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/refractor/-/refractor-4.9.0.tgz", + "integrity": "sha512-nEG1SPXFoGGx+dcjftjv8cAjEusIh6ED1xhf5DG3C0x/k+rmZ2duKnc3QLpt6qeHv5fPb8uwN3VWN2BT7fr3Og==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/prismjs": "^1.0.0", + "hastscript": "^7.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/rehype-raw": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", @@ -35173,6 +35295,16 @@ "ohash": "^2.0.0" } }, + "node_modules/unist-util-filter": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/unist-util-filter/-/unist-util-filter-5.0.1.tgz", + "integrity": "sha512-pHx7D4Zt6+TsfwylH9+lYhBhzyhEnCXs/lbq/Hstxno5z4gVdyc2WEW0asfjGKPyG4pEKrnBv5hdkO6+aRnQJw==", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + } + }, "node_modules/unist-util-find-after": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", diff --git a/package.json b/package.json index 1638ee332f9..7cb6a855df4 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,7 @@ "@openzeppelin/contracts": "^4.9.6", "astro": "^5.7.12", "bignumber.js": "^9.3.0", - "chainlink-algolia-search": "^0.8.7", + "chainlink-algolia-search": "^0.11.0-alpha.13", "clipboard": "^2.0.11", "dotenv": "^16.5.0", "ethers": "^6.14.0", diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index a21efde3792..28884aa3558 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -8,8 +8,19 @@ const { productsNav, subProductsNav } = getNavigationProps() const path = Astro.url.pathname const algoliaVars = { algoliaAppId: import.meta.env.PUBLIC_ALGOLIA_SEARCH_APP_ID || "", - algoliaPublicApiKey: import.meta.env.PUBLIC_ALGOLIA_SEARCH_PUBLIC_API_KEY || "", + algoliaPublicApiKey: import.meta.env.ALGOLIA_PUBLIC_SEARCH_PUBLIC_API_KEY || "", } + +const categoryOrder = ["Documentation"] + +const popularCards = [ + { + url: "https://dev.chain.link/resources/quickstarts", + imgSrc: "/images/algolia/quick-start.png", + label: "Quickstarts", + }, + { url: "https://dev.chain.link/tools", imgSrc: "/images/algolia/tools.png", label: "Tools" }, +] --- @@ -19,6 +30,14 @@ const algoliaVars = { width="0" style="display:none;visibility:hidden"> - + diff --git a/src/components/Header/Nav/NavBar.tsx b/src/components/Header/Nav/NavBar.tsx index e84b22c948a..3b2422983f1 100644 --- a/src/components/Header/Nav/NavBar.tsx +++ b/src/components/Header/Nav/NavBar.tsx @@ -7,11 +7,15 @@ import { useScrollPosition } from "./useScrollPosition.tsx" import { ProductNavigation } from "./ProductNavigation/ProductNavigation.tsx" import { useHideHeader } from "./useHideHeader.tsx" import ProductChainTable from "../../QuickLinks/sections/ProductChainTable.tsx" +import AlgoliaSearch from "../aiSearch/Search.tsx" export type SearchTrigger = React.ReactNode export type NavBarProps = { - searchTrigger?: SearchTrigger + showSearch: boolean + algoliaVars: { algoliaAppId: string; algoliaPublicApiKey: string } + categoryOrder: string[] + popularCards: Array<{ url: string; imgSrc: string; label: string }> path: string onHideChange?: (hidden: boolean) => void productsNav: ProductsNav @@ -23,7 +27,9 @@ export const navBarHeight = 64 export const NavBar = ({ path, - searchTrigger, + algoliaVars, + categoryOrder, + popularCards, onHideChange, productsNav, subProductsNav, @@ -76,7 +82,6 @@ export const NavBar = ({
- {searchTrigger &&
{searchTrigger}
} +
diff --git a/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx b/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx index c0c079c5c3a..e8e018de5b4 100644 --- a/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx +++ b/src/components/Header/Nav/ProductNavigation/ProductNavigation.tsx @@ -1,11 +1,9 @@ import { SubProductsNav, ProductsNav } from "../config.tsx" -import { SearchTrigger } from "../NavBar.tsx" import { ProductNavigation as Desktop } from "./Desktop/ProductNavigation.tsx" import { ProductNavigation as Mobile } from "./Mobile/ProductNavigation.tsx" type Props = { path: string - searchTrigger?: SearchTrigger setNavMenuOpen: (navMenuOpen: boolean) => void productsNav: ProductsNav subProductsNav?: SubProductsNav diff --git a/src/components/Header/NavBar.tsx b/src/components/Header/NavBar.tsx index a6eaf00cd2e..e5d31e686aa 100644 --- a/src/components/Header/NavBar.tsx +++ b/src/components/Header/NavBar.tsx @@ -1,6 +1,5 @@ import React from "react" import { NavBar as Nav } from "./Nav/index.ts" -import { Search } from "./aiSearch/Search.tsx" import { useNavBar } from "./useNavBar/useNavBar.ts" import styles from "./scroll.module.css" import { ProductsNav, SubProductsNav } from "./Nav/config.tsx" @@ -11,12 +10,16 @@ export const NavBar = ({ path, showSearch = true, algoliaVars, + categoryOrder, + popularCards, }: { productsNav: ProductsNav subProductsNav: SubProductsNav path: string showSearch?: boolean algoliaVars: { algoliaAppId: string; algoliaPublicApiKey: string } + categoryOrder: string[] + popularCards: Array<{ url: string; imgSrc: string; label: string }> }) => { const navRef = React.useRef(null) @@ -60,7 +63,10 @@ export const NavBar = ({ productsNav={productsNav} subProductsNav={subProductsNav} path={path} - searchTrigger={showSearch ? : undefined} + showSearch={showSearch} + algoliaVars={algoliaVars} + categoryOrder={categoryOrder} + popularCards={popularCards} onHideChange={onHideChange} doubleNavbar={doubleNavbar()} /> diff --git a/src/components/Header/aiSearch/Search.tsx b/src/components/Header/aiSearch/Search.tsx index e8d7e58dfc0..8d2f14163cf 100644 --- a/src/components/Header/aiSearch/Search.tsx +++ b/src/components/Header/aiSearch/Search.tsx @@ -1,23 +1,33 @@ -import { SearchButton } from "chainlink-algolia-search" +// src/components/Header/aiSearch/SearchReact.tsx +import React, { useEffect, useState, ComponentType } from "react" +import { SearchButtonProps } from "chainlink-algolia-search" import "chainlink-algolia-search/dist/index.css" -export const Search = ({ - algoliaVars: { algoliaAppId, algoliaPublicApiKey }, -}: { - algoliaVars: { algoliaAppId: string; algoliaPublicApiKey: string } -}) => { +function AlgoliaSearch({ algoliaVars, categoryOrder, popularCards }) { + // Only render the component on the client side + const [isClient, setIsClient] = useState(false) + const [SearchButtonComponent, setSearchButtonComponent] = useState | null>(null) + + useEffect(() => { + setIsClient(true) + import("chainlink-algolia-search").then((module) => { + setSearchButtonComponent(() => module.SearchButton) + }) + }, []) + + // Return null during server-side rendering + if (!isClient || !SearchButtonComponent) { + return
+ } + return ( - ) } + +export default AlgoliaSearch