Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme-classic): themeConfig navbar/footer logos accept className/style + update Meta Open-Source Logo #7643

Merged
merged 11 commits into from Jun 23, 2022
Expand Up @@ -148,7 +148,7 @@ const config = {
alt: 'Meta Open Source Logo',
// This default includes a positive & negative version, allowing for
// appropriate use depending on your site's style.
src: 'img/meta_opensource_logo_negative.png',
src: '/img/meta_opensource_logo_negative.svg',
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this leading slash?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no :D

With/without it's the same afaik, and historically many config elements don't have one

But I'd prefer to always have one in the future to make it more explicit it's not a relative path. Does it make sense?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Absolute paths, IMO, are always relative to the domain. The fact that we automatically prepend the base URL is quite magical. But I'm fine with either since it's not strictly a relative path either.

Copy link
Collaborator Author

@slorber slorber Jun 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes 🤪 I know, no ideal choice there. I'd prefer to have leading / everywhere, but this is just my personal opinion, and Docusaurus v1 did not have any leading / in docs/configs either so 🤷‍♂️ . I can revert it if needed.

@yangshun you remember why historically we usually don't have any leading /?

href: 'https://opensource.fb.com',
},
// Please do not remove the credits, help to publicize Docusaurus :)
Expand Down
Expand Up @@ -68,6 +68,11 @@ describe('themeConfig', () => {
alt: 'Docusaurus Logo',
src: 'img/docusaurus.svg',
srcDark: 'img/docusaurus_keytar.svg',
target: '_self',
className: 'navbar__logo__custom',
style: {
maxWidth: 42,
},
},
items: [
{
Expand Down Expand Up @@ -99,10 +104,14 @@ describe('themeConfig', () => {
},
],
logo: {
alt: 'Facebook Open Source Logo',
src: 'img/oss_logo.png',
alt: 'Meta Open Source Logo',
src: 'img/footer_logo.png',
href: 'https://opensource.facebook.com',
target: '_self',
className: 'footer__logo__custom',
style: {
maxWidth: 42,
},
},
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc. Built with Docusaurus.`,
},
Expand Down
Expand Up @@ -6,6 +6,7 @@
*/

import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import {useBaseUrlUtils} from '@docusaurus/useBaseUrl';
import ThemedImage from '@theme/ThemedImage';
Expand All @@ -21,11 +22,12 @@ function LogoImage({logo}: Props) {
};
return (
<ThemedImage
className="footer__logo"
className={clsx('footer__logo', logo.className)}
alt={logo.alt}
sources={sources}
width={logo.width}
height={logo.height}
style={logo.style}
/>
);
}
Expand Down
69 changes: 45 additions & 24 deletions packages/docusaurus-theme-classic/src/theme/Logo/index.tsx
Expand Up @@ -9,53 +9,74 @@ import React from 'react';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import {useThemeConfig} from '@docusaurus/theme-common';
import {useThemeConfig, type NavbarLogo} from '@docusaurus/theme-common';
import ThemedImage from '@theme/ThemedImage';
import type {Props} from '@theme/Logo';

function LogoThemedImage({
logo,
alt,
imageClassName,
}: {
logo: NavbarLogo;
alt: string;
imageClassName?: string;
}) {
const sources = {
light: useBaseUrl(logo.src),
dark: useBaseUrl(logo.srcDark || logo.src),
};
const themedImage = (
<ThemedImage
className={logo.className}
sources={sources}
height={logo.height}
width={logo.width}
alt={alt}
style={logo.style}
/>
);

// Is this extra div really necessary?
// introduced in https://github.com/facebook/docusaurus/pull/5666
return imageClassName ? (
<div className={imageClassName}>{themedImage}</div>
) : (
themedImage
);
}

export default function Logo(props: Props): JSX.Element {
const {
siteConfig: {title},
} = useDocusaurusContext();
const {
navbar: {title: navbarTitle, logo = {src: ''}},
navbar: {title: navbarTitle, logo},
} = useThemeConfig();

const {imageClassName, titleClassName, ...propsRest} = props;
const logoLink = useBaseUrl(logo.href || '/');
const sources = {
light: useBaseUrl(logo.src),
dark: useBaseUrl(logo.srcDark || logo.src),
};
const logoLink = useBaseUrl(logo?.href || '/');

// 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;

const themedImage = (
<ThemedImage
sources={sources}
height={logo.height}
width={logo.width}
alt={alt}
/>
);
const alt = logo?.alt ?? fallbackAlt;

return (
<Link
to={logoLink}
{...propsRest}
{...(logo.target && {target: logo.target})}>
{logo.src &&
(imageClassName ? (
<div className={imageClassName}>{themedImage}</div>
) : (
themedImage
))}
{...(logo?.target && {target: logo.target})}>
{logo && (
<LogoThemedImage
logo={logo}
alt={alt}
imageClassName={imageClassName}
/>
)}
{navbarTitle != null && <b className={titleClassName}>{navbarTitle}</b>}
</Link>
);
Expand Down
33 changes: 14 additions & 19 deletions packages/docusaurus-theme-classic/src/validateThemeConfig.ts
Expand Up @@ -300,6 +300,18 @@ const CustomCssSchema = Joi.alternatives()
.try(Joi.array().items(Joi.string().required()), Joi.string().required())
.optional();

const LogoSchema = Joi.object({
alt: Joi.string().allow(''),
src: Joi.string().required(),
srcDark: Joi.string(),
width: Joi.alternatives().try(Joi.string(), Joi.number()),
height: Joi.alternatives().try(Joi.string(), Joi.number()),
href: Joi.string(),
target: Joi.string(),
style: Joi.object(),
slorber marked this conversation as resolved.
Show resolved Hide resolved
className: Joi.string(),
});

export const ThemeConfigSchema = Joi.object<ThemeConfig>({
// TODO temporary (@alpha-58)
// @ts-expect-error: forbidden
Expand Down Expand Up @@ -344,28 +356,11 @@ export const ThemeConfigSchema = Joi.object<ThemeConfig>({
.items(NavbarItemSchema)
.default(DEFAULT_CONFIG.navbar.items),
title: Joi.string().allow('', null),
logo: Joi.object({
alt: Joi.string().allow(''),
src: Joi.string().required(),
srcDark: Joi.string(),
width: Joi.alternatives().try(Joi.string(), Joi.number()),
height: Joi.alternatives().try(Joi.string(), Joi.number()),
href: Joi.string(),
target: Joi.string(),
}),
logo: LogoSchema,
}).default(DEFAULT_CONFIG.navbar),
footer: Joi.object({
style: Joi.string().equal('dark', 'light').default('light'),
logo: Joi.object({
alt: Joi.string().allow(''),
src: Joi.string().required(),
srcDark: Joi.string(),
// TODO infer this from reading the image
width: Joi.alternatives().try(Joi.string(), Joi.number()),
height: Joi.alternatives().try(Joi.string(), Joi.number()),
href: Joi.string(),
target: Joi.string(),
}),
logo: LogoSchema,
copyright: Joi.string(),
links: Joi.alternatives(
Joi.array().items(
Expand Down
20 changes: 8 additions & 12 deletions packages/docusaurus-theme-common/src/utils/useThemeConfig.ts
Expand Up @@ -20,16 +20,20 @@ export type NavbarItem = {
position?: 'left' | 'right';
} & {[key: string]: unknown};

export type NavbarLogo = {
type BaseLogo = {
alt?: string;
src: string;
srcDark?: string;
href?: string;
width?: string | number;
height?: string | number;
href?: string;
target?: string;
alt?: string;
style?: object;
className?: string;
};

export type NavbarLogo = BaseLogo;

// TODO improve
export type Navbar = {
style?: 'dark' | 'primary';
Expand Down Expand Up @@ -69,15 +73,7 @@ export type FooterLinkItem = {
prependBaseUrlToHref?: string;
} & {[key: string]: unknown};

export type FooterLogo = {
alt?: string;
src: string;
srcDark?: string;
width?: string | number;
height?: string | number;
target?: string;
href?: string;
};
export type FooterLogo = BaseLogo;

export type FooterBase = {
style: 'light' | 'dark';
Expand Down
5 changes: 3 additions & 2 deletions website/docs/api/docusaurus.config.js.md
Expand Up @@ -334,8 +334,9 @@ module.exports = {
// ... other links
],
logo: {
alt: 'Facebook Open Source Logo',
src: 'https://docusaurus.io/img/oss_logo.png',
alt: 'Meta Open Source Logo',
src: 'img/meta_oss_logo.png',
href: 'https://opensource.fb.com',
width: 160,
height: 51,
},
Expand Down
10 changes: 7 additions & 3 deletions website/docs/api/themes/theme-configuration.md
Expand Up @@ -199,6 +199,8 @@ Accepted fields:
| `width` | <code>string \| number</code> | `undefined` | Specifies the `width` attribute. |
| `height` | <code>string \| number</code> | `undefined` | Specifies the `height` attribute. |
| `target` | `string` | Calculated based on `href` (external links will open in a new tab, all others in the current one). | The `target` attribute of the link; controls whether the link is opened in a new tab, the current one, or otherwise. |
| `className` | `string` | `undefined` | CSS class applied to the image. |
| `style` | `object` | `undefined` | CSS inline style object. React/JSX flavor, using camelCase properties. |

```mdx-code-block
</APITable>
Expand All @@ -220,6 +222,8 @@ module.exports = {
target: '_self',
width: 32,
height: 32,
className: 'custom-navbar-logo-class',
style: {border: 'solid red'},
},
// highlight-end
},
Expand Down Expand Up @@ -858,9 +862,9 @@ module.exports = {
// highlight-start
footer: {
logo: {
alt: 'Facebook Open Source Logo',
src: 'img/oss_logo.png',
href: 'https://opensource.facebook.com',
alt: 'Meta Open Source Logo',
src: 'img/meta_oss_logo.png',
href: 'https://opensource.fb.com',
width: 160,
height: 51,
},
Expand Down
8 changes: 4 additions & 4 deletions website/docs/migration/migration-manual.md
Expand Up @@ -223,8 +223,8 @@ module.exports = {
themeConfig: {
footer: {
logo: {
alt: 'Facebook Open Source Logo',
src: 'https://docusaurus.io/img/oss_logo.png',
alt: 'Meta Open Source Logo',
src: '/img/meta_oss_logo.png',
href: 'https://opensource.facebook.com/',
},
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc.`, // You can also put own HTML here.
Expand Down Expand Up @@ -507,8 +507,8 @@ module.exports = {
themeConfig: {
footer: {
logo: {
alt: 'Facebook Open Source Logo',
src: 'img/oss_logo.png',
alt: 'Meta Open Source Logo',
src: '/img/meta_oss_logo.png',
href: 'https://opensource.facebook.com',
},
},
Expand Down
9 changes: 0 additions & 9 deletions website/docusaurus.config-blog-only.js
Expand Up @@ -57,14 +57,5 @@ module.exports = {
srcDark: 'img/docusaurus_keytar.svg',
},
},
footer: {
style: 'dark',
logo: {
alt: 'Facebook Open Source Logo',
src: 'img/oss_logo.png',
href: 'https://opensource.facebook.com',
},
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc. Built with Docusaurus.`,
},
},
};
10 changes: 4 additions & 6 deletions website/docusaurus.config.js
Expand Up @@ -589,13 +589,11 @@ const config = {
},
],
logo: {
alt: 'Facebook Open Source Logo',
src: 'img/oss_logo.png',
width: 160,
height: 51,
href: 'https://opensource.facebook.com',
alt: 'Meta Open Source Logo',
src: '/img/meta_opensource_logo_negative.svg',
href: 'https://opensource.fb.com',
},
copyright: `Copyright © ${new Date().getFullYear()} Facebook, Inc. Built with Docusaurus.`,
copyright: `Copyright © ${new Date().getFullYear()} Meta Platforms, Inc. Built with Docusaurus.`,
},
}),
};
Expand Down