diff --git a/src/@chakra-ui/gatsby-plugin/components/Button.ts b/src/@chakra-ui/gatsby-plugin/components/Button.ts
index fb9ca7f8a08..0e124f058cf 100644
--- a/src/@chakra-ui/gatsby-plugin/components/Button.ts
+++ b/src/@chakra-ui/gatsby-plugin/components/Button.ts
@@ -10,17 +10,15 @@ import { defineStyle, defineStyleConfig } from "@chakra-ui/react"
*/
const ICON_SELECTOR = "& svg"
-const getBaseColor = (isSecondary: boolean) =>
- !isSecondary ? "primary.base" : "body.base"
-
-const baseStyle = defineStyle((props) => ({
+const baseStyle = defineStyle({
borderRadius: "base",
border: "1px",
- color: getBaseColor(props.isSecondary),
+ color: "primary.base",
lineHeight: "1.6",
transitionProperty: "common",
transitionDuration: "normal",
whiteSpace: "normal",
+ p: "unset",
_focusVisible: {
outline: "4px solid",
outlineColor: "primary.hover",
@@ -33,7 +31,16 @@ const baseStyle = defineStyle((props) => ({
_hover: {
color: "primary.hover",
},
-}))
+ "&[data-secondary='true']": {
+ color: "body.base",
+ },
+ "&.chakra-link": {
+ textDecoration: "none",
+ _hover: {
+ textDecoration: "none",
+ },
+ },
+})
const variantSolid = defineStyle({
color: "background.base",
@@ -68,7 +75,6 @@ const variantGhost = {
const variantLink = defineStyle({
borderColor: "transparent",
- color: "primary.base",
fontWeight: 700,
textDecor: "underline",
py: 0,
@@ -78,39 +84,22 @@ const variantLink = defineStyle({
},
})
-/**
- * @deprecated This is no longer needed. Styling for just the icon is not
- * unique compared to the variants used for text (as of the new DS)
- */
-const variantIcon = defineStyle({
- appearance: "none",
- background: "inherit",
- padding: "initial",
- border: 0,
- color: "inherit",
- boxShadow: "none",
- _hover: {
- color: "primary.base",
- boxShadow: "none",
- },
-})
-
const sizes = {
- md: {
- py: "2 !important",
- px: "4 !important",
+ md: defineStyle({
+ py: "2",
+ px: "4",
[ICON_SELECTOR]: {
fontSize: "2xl",
},
- },
- sm: {
+ }),
+ sm: defineStyle({
fontSize: "xs",
- py: "1.5 !important",
- px: "2 !important",
+ py: "1.5",
+ px: "2",
[ICON_SELECTOR]: {
fontSize: "md",
},
- },
+ }),
}
const variants = {
@@ -118,7 +107,6 @@ const variants = {
outline: variantOutline,
ghost: variantGhost,
link: variantLink,
- icon: variantIcon,
}
export const Button = defineStyleConfig({
diff --git a/src/components/Button/Button.stories.tsx b/src/components/Button/Button.stories.tsx
index e5b41e303f7..b1a70d0e3df 100644
--- a/src/components/Button/Button.stories.tsx
+++ b/src/components/Button/Button.stories.tsx
@@ -1,10 +1,13 @@
import * as React from "react"
-import { HStack, IconButton, ThemingProps, VStack } from "@chakra-ui/react"
+import { HStack, ThemingProps, Text, VStack } from "@chakra-ui/react"
import { getThemingArgTypes } from "@chakra-ui/storybook-addon"
import { Meta, StoryObj } from "@storybook/react"
-import { MdExpandMore, MdChevronRight } from "react-icons/md"
-import Button from "."
+import { MdExpandMore, MdChevronRight, MdNightlight } from "react-icons/md"
import theme from "../../@chakra-ui/gatsby-plugin/theme"
+import ButtonLink from "../ButtonLink"
+import IconButton from "../IconButton"
+import Translation from "../Translation"
+import Button from "."
type ButtonType = typeof Button
@@ -45,15 +48,12 @@ export const StyleVariants: Story = {
},
render: (args) => (
- {variants.map((variant, idx) => {
- if (args.isSecondary && variant === "solid") return
- return (
-
-
-
-
- )
- })}
+ {variants.map((variant, idx) => (
+
+
+
+
+ ))}
),
}
@@ -118,3 +118,20 @@ export const MultiLineText: Story = {
),
}
+
+export const OverrideStyles: Story = {
+ render: () => (
+ <>
+
+ Show custom styling examples here for visual testing of overrides from
+ the theme config
+
+
+ } px="1.5" />
+
+
+
+
+ >
+ ),
+}
diff --git a/src/components/Button/index.tsx b/src/components/Button/index.tsx
index 1bf7c8a1107..b5720e47258 100644
--- a/src/components/Button/index.tsx
+++ b/src/components/Button/index.tsx
@@ -2,17 +2,42 @@ import React from "react"
import {
Button as ChakraButton,
ButtonProps,
- useStyleConfig,
+ forwardRef,
} from "@chakra-ui/react"
import { scrollIntoView } from "../../utils/scrollIntoView"
+export const checkIsSecondary = (props: {
+ variant?: string
+ isSecondary?: boolean
+}) => {
+ const { variant, isSecondary } = props
+ // These two variants do not have secondary styling, so prevent overrides
+ return {
+ "data-secondary":
+ !["solid", "link"].includes(variant || "solid") && isSecondary,
+ }
+}
+
export interface IProps extends ButtonProps {
+ /**
+ * Set string value that matches the `id` attribute value used
+ * on another element in a given page. Selecting the button will then
+ * trigger a scroll to that element.
+ */
toId?: string
+ /**
+ * Custom theme prop. If true, `body` color is used instead of
+ * `primary` color in the theming.
+ *
+ * `NOTE`: Does not apply to the `Solid` or `Link` variants
+ */
isSecondary?: boolean
}
-const Button: React.FC = ({ toId, isSecondary, onClick, ...props }) => {
+const Button = forwardRef((props, ref) => {
+ const { toId, onClick, isSecondary, ...rest } = props
+
const handleOnClick = (e: React.MouseEvent) => {
if (toId) {
scrollIntoView(toId)
@@ -21,14 +46,14 @@ const Button: React.FC = ({ toId, isSecondary, onClick, ...props }) => {
onClick?.(e)
}
- /**
- * Prevent React warning that does not recognize `isSecondary` on DOM
- * while still sending prop to the theme config
- */
- const styles = useStyleConfig("Button", { ...props, isSecondary })
-
- // `styles` object sent to `sx` prop per convention
- return
-}
+ return (
+
+ )
+})
export default Button
diff --git a/src/components/ButtonLink.tsx b/src/components/ButtonLink.tsx
index 7dd4caf9c6b..49c6e729d19 100644
--- a/src/components/ButtonLink.tsx
+++ b/src/components/ButtonLink.tsx
@@ -1,39 +1,13 @@
import React from "react"
-import { Button, ButtonProps, useStyleConfig } from "@chakra-ui/react"
+import type { IProps as IButtonProps } from "./Button"
import { BaseLink, IBaseProps as ILinkProps } from "./Link"
+import Button from "./Button"
-export interface IProps extends ILinkProps, ButtonProps {
- isSecondary?: boolean
-}
-
-const ButtonLink: React.FC = ({ children, isSecondary, ...props }) => {
- /**
- * Prevent React warning that does not recognize `isSecondary` on DOM
- * while still sending prop to the theme config
- */
- const styles = useStyleConfig("Button", {
- ...props,
- isSecondary,
- })
+export interface IProps extends ILinkProps, Omit {}
- return (
-
- )
+const ButtonLink: React.FC = (props) => {
+ return
}
export default ButtonLink
diff --git a/src/components/IconButton.tsx b/src/components/IconButton.tsx
new file mode 100644
index 00000000000..8a45f151124
--- /dev/null
+++ b/src/components/IconButton.tsx
@@ -0,0 +1,22 @@
+import * as React from "react"
+import {
+ IconButton as ChakraIconButton,
+ IconButtonProps as ChakraIconButtonProps,
+} from "@chakra-ui/react"
+import { checkIsSecondary, IProps as IButtonProps } from "./Button"
+
+interface IconButtonProps
+ extends Omit,
+ ChakraIconButtonProps {}
+
+const IconButton = (props: IconButtonProps) => {
+ const { isSecondary, ...rest } = props
+ return (
+
+ )
+}
+
+export default IconButton
diff --git a/src/components/Nav/Menu.tsx b/src/components/Nav/Menu.tsx
index 1091df2d8ef..e4259d20e56 100644
--- a/src/components/Nav/Menu.tsx
+++ b/src/components/Nav/Menu.tsx
@@ -1,6 +1,6 @@
import React from "react"
import { useI18next } from "gatsby-plugin-react-i18next"
-import { Flex, List } from "@chakra-ui/react"
+import { Flex, FlexProps, List } from "@chakra-ui/react"
import NavDropdown from "./Dropdown"
import { getDirection } from "../../utils/translations"
@@ -8,12 +8,12 @@ import { getDirection } from "../../utils/translations"
import { Lang } from "../../utils/languages"
import { ISections } from "./types"
-export interface IProps {
+export interface IProps extends FlexProps {
path: string
sections: ISections
}
-const Menu: React.FC = ({ path, sections }) => {
+const Menu: React.FC = ({ path, sections, ...props }) => {
const { language } = useI18next()
const direction = getDirection(language as Lang)
const shouldShowSubNav = path.includes("/developers/")
@@ -23,7 +23,13 @@ const Menu: React.FC = ({ path, sections }) => {
const [start, basics, protocol] = learn.items
return (
-
+
{useEthereum.items.map((item, index) => (
(
(props, ref) =>
@@ -104,7 +104,7 @@ const glyphPathVariants = {
},
}
-export interface IProps {
+export interface IProps extends ButtonProps {
isMenuOpen: boolean
isDarkTheme: boolean
toggleMenu: () => void
@@ -124,6 +124,7 @@ const MobileNavMenu: React.FC = ({
linkSections,
fromPageParameter,
drawerContainerRef,
+ ...props
}) => {
const { t } = useTranslation()
@@ -132,54 +133,45 @@ const MobileNavMenu: React.FC = ({
}
return (
-
-
- path": {
- stroke: "primary.base",
- },
- }}
- sx={{
- "& > path": {
- stroke: "text",
- fill: "none",
- },
- }}
- >
-
-
- }
+ <>
+
+ {...props}
+ >
+ path": {
+ stroke: "primary.base",
+ },
+ }}
+ sx={{
+ "& > path": {
+ stroke: "text",
+ fill: "none",
+ },
+ }}
+ >
+
+
+
= ({
-
+ >
)
}
diff --git a/src/components/Nav/index.tsx b/src/components/Nav/index.tsx
index 2efa95da733..da0e3db1fb9 100644
--- a/src/components/Nav/index.tsx
+++ b/src/components/Nav/index.tsx
@@ -1,5 +1,5 @@
import React, { FC, useRef } from "react"
-import { Icon, IconButton, Flex, Text, Box } from "@chakra-ui/react"
+import { Icon, Flex, Box, HStack, useDisclosure } from "@chakra-ui/react"
import { MdWbSunny, MdBrightness2, MdLanguage } from "react-icons/md"
import Menu from "./Menu"
@@ -7,6 +7,7 @@ import MobileNavMenu from "./Mobile"
import ButtonLink from "../ButtonLink"
import Link, { BaseLink } from "../Link"
import Search from "../Search"
+import IconButton from "../IconButton"
import { EthHomeIcon } from "../icons"
import { useNav } from "./useNav"
@@ -25,9 +26,9 @@ const Nav: FC = ({ path }) => {
t,
toggleColorMode,
linkSections,
- searchRef,
mobileNavProps,
} = useNav({ path })
+ const searchModalDisclosure = useDisclosure()
const navWrapperRef = useRef(null)
@@ -62,52 +63,49 @@ const Nav: FC = ({ path }) => {
{/* Desktop */}
-
+
-
- }
- variant="icon"
- size="sm"
- fontSize="2xl"
- ms={{ xl: 2 }}
- _hover={{ color: "primary.base" }}
- onClick={toggleColorMode}
+
+ {/* Mobile */}
+
-
-
-
-
- {t("languages")}
- {" "}
- {i18n.language.toUpperCase()}
-
-
+
+ : }
+ aria-label={
+ isDarkTheme
+ ? "Switch to Light Theme"
+ : "Switch to Dark Theme"
+ }
+ variant="ghost"
+ isSecondary
+ px={1.5}
+ onClick={toggleColorMode}
+ >
+ }
+ variant="ghost"
+ isSecondary
+ px={1.5}
+ >
+ {t("languages")} {i18n.language.toUpperCase()}
+
+
- {/* Mobile */}
-
{shouldShowSubNav && (
diff --git a/src/components/Nav/useNav.ts b/src/components/Nav/useNav.ts
index a6226f3e17a..2599316415a 100644
--- a/src/components/Nav/useNav.ts
+++ b/src/components/Nav/useNav.ts
@@ -278,11 +278,6 @@ export const useNav = ({ path }: { path: string }) => {
setIsMenuOpen((prev) => !prev)
}
- const searchRef = useRef(null)
-
- const toggleSearch = (): void => {
- searchRef.current?.click()
- }
const shouldShowSubNav = path.includes("/developers/")
const splitPath = path.split("/")
const fromPageParameter =
@@ -304,7 +299,6 @@ export const useNav = ({ path }: { path: string }) => {
isDarkTheme,
toggleMenu,
toggleTheme: changeColorMode,
- toggleSearch,
linkSections: mobileLinkSections,
fromPageParameter,
}
@@ -316,7 +310,6 @@ export const useNav = ({ path }: { path: string }) => {
isDarkTheme,
ednLinks,
linkSections,
- searchRef,
shouldShowSubNav,
fromPageParameter,
mobileNavProps,
diff --git a/src/components/Search/index.tsx b/src/components/Search/index.tsx
index e5d3ccb0090..a15afb7ac1c 100644
--- a/src/components/Search/index.tsx
+++ b/src/components/Search/index.tsx
@@ -3,10 +3,8 @@ import React from "react"
import { useTranslation, useI18next } from "gatsby-plugin-react-i18next"
import { MdSearch } from "react-icons/md"
import {
- IconButton,
forwardRef,
Portal,
- useDisclosure,
IconButtonProps,
useToken,
useMediaQuery,
@@ -14,6 +12,7 @@ import {
} from "@chakra-ui/react"
import { useDocSearchKeyboardEvents } from "@docsearch/react"
import { DocSearchHit } from "@docsearch/react/dist/esm/types"
+import Button from "../Button"
import SearchButton from "./SearchButton"
import SearchModal from "./SearchModal"
import { sanitizeHitUrl } from "../../utils/url"
@@ -27,142 +26,145 @@ import { trackCustomEvent } from "../../utils/matomo"
export const SearchIconButton = forwardRef(
(props, ref) => (
- }
- fontSize="2xl"
- variant="icon"
- _hover={{ svg: { fill: "primary.base" } }}
- {...props}
- />
+
)
)
-const Search = forwardRef<{}, "button">((_, ref) => {
- const searchButtonRef = React.useRef(null)
- const { isOpen, onClose, onOpen } = useDisclosure()
+interface IProps {
+ isOpen: boolean
+ onOpen: () => void
+ onClose: () => void
+}
- const mergedButtonRefs = useMergeRefs(ref, searchButtonRef)
+const Search = forwardRef(
+ ({ isOpen, onOpen, onClose }, ref) => {
+ const searchButtonRef = React.useRef(null)
- useDocSearchKeyboardEvents({
- isOpen,
- onOpen,
- onClose,
- searchButtonRef,
- })
- const { t } = useTranslation()
- const { language } = useI18next()
- const appId = process.env.GATSBY_ALGOLIA_APP_ID || ""
- const apiKey = process.env.GATSBY_ALGOLIA_SEARCH_KEY || ""
- const indexName =
- process.env.GATSBY_ALGOLIA_BASE_SEARCH_INDEX_NAME || "ethereumorg"
+ const mergedButtonRefs = useMergeRefs(ref, searchButtonRef)
- // Check for the breakpoint with theme token
- const xlBp = useToken("breakpoints", "xl")
- const [isLargerThanXl] = useMediaQuery(`(min-width: ${xlBp})`)
+ useDocSearchKeyboardEvents({
+ isOpen,
+ onOpen,
+ onClose,
+ searchButtonRef,
+ })
+ const { t } = useTranslation()
+ const { language } = useI18next()
+ const appId = process.env.GATSBY_ALGOLIA_APP_ID || ""
+ const apiKey = process.env.GATSBY_ALGOLIA_SEARCH_KEY || ""
+ const indexName =
+ process.env.GATSBY_ALGOLIA_BASE_SEARCH_INDEX_NAME || "ethereumorg"
- return (
- <>
- {isLargerThanXl ? (
- {
- onOpen()
- trackCustomEvent({
- eventCategory: "nav bar",
- eventAction: "click",
- eventName: "search open",
- })
- }}
- translations={{
- buttonText: t("search"),
- buttonAriaLabel: t("search"),
- }}
- />
- ) : (
- {
- onOpen()
- trackCustomEvent({
- eventCategory: "nav bar",
- eventAction: "click",
- eventName: "search open",
- })
- }}
- ref={mergedButtonRefs}
- aria-label={t("aria-toggle-search-button")}
- size="sm"
- />
- )}
-
- {isOpen && (
-
- items.map((item: DocSearchHit) => {
- const newItem: DocSearchHit = structuredClone(item)
- newItem.url = sanitizeHitUrl(item.url)
- newItem._highlightResult.hierarchy.lvl0.value =
- sanitizeHitTitle(item._highlightResult.hierarchy.lvl0.value)
- return newItem
+ // Check for the breakpoint with theme token
+ const xlBp = useToken("breakpoints", "xl")
+ const [isLargerThanXl] = useMediaQuery(`(min-width: ${xlBp})`)
+
+ return (
+ <>
+ {isLargerThanXl ? (
+ {
+ onOpen()
+ trackCustomEvent({
+ eventCategory: "nav bar",
+ eventAction: "click",
+ eventName: "search open",
})
- }
- placeholder={t("search-ethereum-org")}
+ }}
translations={{
- searchBox: {
- resetButtonTitle: t("clear"),
- resetButtonAriaLabel: t("clear"),
- cancelButtonText: t("close"),
- cancelButtonAriaLabel: t("close"),
- },
- footer: {
- selectText: t("docsearch-to-select"),
- selectKeyAriaLabel: t("docsearch-to-select"),
- navigateText: t("docsearch-to-navigate"),
- navigateUpKeyAriaLabel: t("up"),
- navigateDownKeyAriaLabel: t("down"),
- closeText: t("docsearch-to-close"),
- closeKeyAriaLabel: t("docsearch-to-close"),
- searchByText: t("docsearch-search-by"),
- },
- errorScreen: {
- titleText: t("docsearch-error-title"),
- helpText: t("docsearch-error-help"),
- },
- startScreen: {
- recentSearchesTitle: t("docsearch-start-recent-searches-title"),
- noRecentSearchesText: t("docsearch-start-no-recent-searches"),
- saveRecentSearchButtonTitle: t(
- "docsearch-start-save-recent-search"
- ),
- removeRecentSearchButtonTitle: t(
- "docsearch-start-remove-recent-search"
- ),
- favoriteSearchesTitle: t("docsearch-start-favorite-searches"),
- removeFavoriteSearchButtonTitle: t(
- "docsearch-start-remove-favorite-search"
- ),
- },
- noResultsScreen: {
- noResultsText: t("docsearch-no-results-text"),
- suggestedQueryText: t("docsearch-no-results-suggested-query"),
- reportMissingResultsText: t("docsearch-no-results-missing"),
- reportMissingResultsLinkText: t(
- "docsearch-no-results-missing-link"
- ),
- },
+ buttonText: t("search"),
+ buttonAriaLabel: t("search"),
+ }}
+ />
+ ) : (
+ {
+ onOpen()
+ trackCustomEvent({
+ eventCategory: "nav bar",
+ eventAction: "click",
+ eventName: "search open",
+ })
}}
+ ref={mergedButtonRefs}
+ aria-label={t("aria-toggle-search-button")}
/>
)}
-
- >
- )
-})
+
+ {isOpen && (
+
+ items.map((item: DocSearchHit) => {
+ const newItem: DocSearchHit = structuredClone(item)
+ newItem.url = sanitizeHitUrl(item.url)
+ newItem._highlightResult.hierarchy.lvl0.value =
+ sanitizeHitTitle(item._highlightResult.hierarchy.lvl0.value)
+ return newItem
+ })
+ }
+ placeholder={t("search-ethereum-org")}
+ translations={{
+ searchBox: {
+ resetButtonTitle: t("clear"),
+ resetButtonAriaLabel: t("clear"),
+ cancelButtonText: t("close"),
+ cancelButtonAriaLabel: t("close"),
+ },
+ footer: {
+ selectText: t("docsearch-to-select"),
+ selectKeyAriaLabel: t("docsearch-to-select"),
+ navigateText: t("docsearch-to-navigate"),
+ navigateUpKeyAriaLabel: t("up"),
+ navigateDownKeyAriaLabel: t("down"),
+ closeText: t("docsearch-to-close"),
+ closeKeyAriaLabel: t("docsearch-to-close"),
+ searchByText: t("docsearch-search-by"),
+ },
+ errorScreen: {
+ titleText: t("docsearch-error-title"),
+ helpText: t("docsearch-error-help"),
+ },
+ startScreen: {
+ recentSearchesTitle: t(
+ "docsearch-start-recent-searches-title"
+ ),
+ noRecentSearchesText: t("docsearch-start-no-recent-searches"),
+ saveRecentSearchButtonTitle: t(
+ "docsearch-start-save-recent-search"
+ ),
+ removeRecentSearchButtonTitle: t(
+ "docsearch-start-remove-recent-search"
+ ),
+ favoriteSearchesTitle: t("docsearch-start-favorite-searches"),
+ removeFavoriteSearchButtonTitle: t(
+ "docsearch-start-remove-favorite-search"
+ ),
+ },
+ noResultsScreen: {
+ noResultsText: t("docsearch-no-results-text"),
+ suggestedQueryText: t("docsearch-no-results-suggested-query"),
+ reportMissingResultsText: t("docsearch-no-results-missing"),
+ reportMissingResultsLinkText: t(
+ "docsearch-no-results-missing-link"
+ ),
+ },
+ }}
+ />
+ )}
+
+ >
+ )
+ }
+)
export default Search
diff --git a/src/pages/languages.tsx b/src/pages/languages.tsx
index d34f5af2bf8..39f00a7b274 100644
--- a/src/pages/languages.tsx
+++ b/src/pages/languages.tsx
@@ -105,7 +105,7 @@ const LanguagesPage = ({ location }: PageProps) => {
position="absolute"
insetInlineEnd={1}
aria-label={t("clear")}
- variant="icon"
+ variant="ghost"
_hover={{ svg: { fill: "primary" } }}
/>
)