diff --git a/packages/docusaurus-theme/src/theme/Logo/index.tsx b/packages/docusaurus-theme/src/theme/Logo/index.tsx new file mode 100644 index 000000000000..3f64a7bd9513 --- /dev/null +++ b/packages/docusaurus-theme/src/theme/Logo/index.tsx @@ -0,0 +1,137 @@ +import React, { useContext } from 'react'; +import { css } from '@emotion/react'; +import Link from '@docusaurus/Link'; +import useBaseUrl from '@docusaurus/useBaseUrl'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import { + useColorMode, + useThemeConfig, + type NavbarLogo, +} from '@docusaurus/theme-common'; +import type { Props } from '@theme-original/Logo'; +import { + EuiImage, + euiTextTruncate, + useEuiMemoizedStyles, + UseEuiTheme, +} from '@elastic/eui'; +import { AppThemeContext } from '../../components/theme_context'; + +const getStyles = ({ euiTheme }: UseEuiTheme) => ({ + wrapper: css` + ${euiTextTruncate()} + // create space to prevent focus outline from being cut off + padding: ${euiTheme.size.xs}; + + @media (min-width: 997px) { + border-right: ${euiTheme.border.thin}; + } + + .navbar__brand { + display: flex; + align-items: center; + + margin-inline-end: ${euiTheme.size.m}; + + @media (min-width: 997px) { + margin-inline-end: ${euiTheme.size.l}; + } + } + + .navbar__logo { + height: 100%; + } + `, + imageWrapper: css` + margin-inline-end: ${euiTheme.size.m}; + `, + image: css` + position: relative; + block-size: ${euiTheme.size.l}; + inline-size: ${euiTheme.size.l}; + margin: 0; + `, +}); + +function LogoThemedImage({ + logo, + alt, + imageClassName, +}: { + logo: NavbarLogo; + alt: string; + imageClassName?: string; +}) { + const { theme } = useContext(AppThemeContext); + const isDarkMode = theme === 'dark'; + + const styles = useEuiMemoizedStyles(getStyles); + + const src = isDarkMode + ? useBaseUrl(logo.srcDark || logo.src) + : useBaseUrl(logo.src); + + const themedImage = ( + + ); + + // Is this extra div really necessary? + // introduced in https://github.com/facebook/docusaurus/pull/5666 + return imageClassName ? ( +
+ {themedImage} +
+ ) : ( + themedImage + ); +} + +export default function Logo(props: Props): JSX.Element { + const { + siteConfig: { title }, + } = useDocusaurusContext(); + const { + navbar: { title: navbarTitle, logo }, + } = useThemeConfig(); + + const { imageClassName, titleClassName, ...propsRest } = props; + const logoLink = useBaseUrl(logo?.href || '/'); + + const styles = useEuiMemoizedStyles(getStyles); + + // If visible title is shown, fallback alt text should be + // an empty string to mark the logo as decorative. + const fallbackAlt = navbarTitle ? '' : title; + + // Use logo alt text if provided (including empty string), + // and provide a sensible fallback otherwise. + const alt = logo?.alt ?? fallbackAlt; + + return ( +
+ + {logo && ( + + )} + {navbarTitle != null && {navbarTitle}} + +
+ ); +}