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: Optional frontmatter logo for page #1888

Merged
merged 7 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions fern/apis/fdr/definition/docs/latest/frontmatter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ types:
docs: |
The subtitle of the page. This is a markdown string that is rendered below the title.
If `description` is not set, this will be used for the <meta name="description"> tag in the HTML.
logo:
type: optional<Logo>
docs: The logo for this page.
image:
type: optional<commons.FileIdOrUrl>
docs: The URL to this page's image. This is currently an alias for `og:image`, but its purpose may change to a be a cover-image (pre-title).
Expand Down Expand Up @@ -67,6 +70,21 @@ types:
type: optional<string>
docs: The canonical URL of the page. This is used for the <link rel="canonical"> tag in the HTML.

Logo:
discriminated: false
union:
- commons.FileIdOrUrl
- LogoConfiguration

LogoConfiguration:
properties:
light:
type: optional<commons.FileIdOrUrl>
docs: The URL to this page's light theme logo.
dark:
type: optional<commons.FileIdOrUrl>
docs: The URL to this page's dark theme logo.

Layout:
enum:
- value: guide
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/fdr-sdk/src/docs/frontmatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ export const EMPTY_FRONTMATTER: Frontmatter = {
nofollow: undefined,
"jsonld:breadcrumb": undefined,
keywords: undefined,
logo: undefined,
};

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/ui/app/src/atoms/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export const EMPTY_DOCS_STATE: DocsProps = {
hasAside: false,
apis: {},
endpointIdsToSlugs: {},
frontmatter: undefined,
},
featureFlags: DEFAULT_FEATURE_FLAGS,
apis: [],
Expand All @@ -73,6 +74,7 @@ export const EMPTY_DOCS_STATE: DocsProps = {
user: undefined,
defaultLang: "curl",
stylesheet: "",
frontmatterLogoOverride: undefined,
};

export const DOCS_ATOM = atomWithReducer<DocsProps, DocsProps>(EMPTY_DOCS_STATE, (_, next) => {
Expand Down
12 changes: 10 additions & 2 deletions packages/ui/app/src/atoms/files.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { DocsV1Read } from "@fern-api/fdr-sdk/client/types";
import { DocsV1Read } from "@fern-api/fdr-sdk/client/types";
import { isEqual } from "es-toolkit/predicate";
import { atom, useAtomValue } from "jotai";
import { selectAtom } from "jotai/utils";
Expand All @@ -9,5 +9,13 @@ export const FILES_ATOM = selectAtom(DOCS_ATOM, (docs) => docs.files, isEqual);
FILES_ATOM.debugLabel = "FILES_ATOM";

export function useFile(fileId: DocsV1Read.FileId): DocsV1Read.File_ | undefined {
return useAtomValue(useMemoOne(() => atom((get) => get(FILES_ATOM)[fileId]), [fileId]));
return useAtomValue(
useMemoOne(
() =>
atom(
(get) => get(FILES_ATOM)[DocsV1Read.FileId(fileId.startsWith("file:") ? fileId.slice(5) : fileId)],
),
[fileId],
),
);
}
35 changes: 35 additions & 0 deletions packages/ui/app/src/atoms/logo.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { FileIdOrUrl, Logo, LogoConfiguration } from "@fern-api/fdr-sdk/docs";
import { atom, useAtomValue } from "jotai";
import { DOCS_ATOM } from "./docs";
import { FEATURE_FLAGS_ATOM } from "./flags";
Expand All @@ -17,3 +18,37 @@
export function useLogoHeight(): number {
return useAtomValue(LOGO_HEIGHT_ATOM);
}

function isFileIdOrUrl(logo: Logo | undefined): logo is FileIdOrUrl {
if (logo == null) {
return false;
}
if (typeof logo !== "object") {
return false;
}
if (!("type" in logo && "value" in logo)) {
return false;
}
return logo.type === "fileId" || logo.type === "url";
}

export const LOGO_OVERRIDE_ATOM = atom<LogoConfiguration | undefined>((get) => {
const logo = get(DOCS_ATOM).frontmatterLogoOverride ?? undefined;
console.log("frontmatter logo", logo);

Check failure on line 37 in packages/ui/app/src/atoms/logo.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

if (logo != null && typeof logo === "object") {
if ("light" in logo && "dark" in logo && isFileIdOrUrl(logo.light) && isFileIdOrUrl(logo.dark)) {
return { light: logo.light, dark: logo.dark };
}
if ("light" in logo && isFileIdOrUrl(logo.light)) {
return { light: logo.light, dark: logo.light };
}
if ("dark" in logo && isFileIdOrUrl(logo.dark)) {
return { light: logo.dark, dark: logo.dark };
}
if (isFileIdOrUrl(logo)) {
return { light: logo, dark: logo };
}
}
return undefined;
});
1 change: 1 addition & 0 deletions packages/ui/app/src/atoms/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export interface DocsProps {
navbarLinks: NavbarLink[];
logoHeight: DocsV1Read.Height | undefined;
logoHref: DocsV1Read.Url | undefined;
frontmatterLogoOverride: FernDocs.Frontmatter["logo"] | undefined;
files: Record<DocsV1Read.FileId, DocsV1Read.File_>;
content: DocsContent;
featureFlags: FeatureFlags;
Expand Down
48 changes: 46 additions & 2 deletions packages/ui/app/src/header/HeaderLogoImage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DocsV1Read } from "@fern-api/fdr-sdk";
import { useAtomValue } from "jotai";
import { ReactElement } from "react";
import { DOCS_ATOM, useColors, useFile, useLogoHeight } from "../atoms";
import { DOCS_ATOM, LOGO_OVERRIDE_ATOM, useColors, useFile, useLogoHeight } from "../atoms";
import { FernImage } from "../components/FernImage";

function FernFileImage({
Expand All @@ -11,12 +11,56 @@
return <FernImage src={useFile(fileId)} {...props} />;
}

function FernFileOrUrlImage({
fileIdOrUrl,
...props
}: Omit<FernImage.Props, "src"> & { fileIdOrUrl: DocsV1Read.FileIdOrUrl }): ReactElement {
if (fileIdOrUrl.type === "fileId") {
return <FernFileImage fileId={fileIdOrUrl.value} {...props} />;
}
return <FernImage src={{ type: "url", url: fileIdOrUrl.value }} {...props} />;
}

export function HeaderLogoImage(): ReactElement | null {
const colors = useColors();
const logoImageHeight = useLogoHeight();
const title = useAtomValue(DOCS_ATOM).title ?? "Logo";
const logoConfiguration = useAtomValue(LOGO_OVERRIDE_ATOM);
console.log("logoConfiguration", logoConfiguration);

Check failure on line 29 in packages/ui/app/src/header/HeaderLogoImage.tsx

View workflow job for this annotation

GitHub Actions / lint

Unexpected console statement

if (colors.dark != null && colors.light != null) {
if (logoConfiguration != null) {
const lightLogo = logoConfiguration.light;
const darkLogo = logoConfiguration.dark;

return (
<>
{lightLogo != null && (
<FernFileOrUrlImage
alt={title}
fileIdOrUrl={lightLogo}
className="fern-logo-light"
height={logoImageHeight}
style={{ height: logoImageHeight }}
priority={true}
loading="eager"
quality={100}
/>
)}
{darkLogo != null && (
<FernFileOrUrlImage
alt={title}
fileIdOrUrl={darkLogo}
className="fern-logo-dark"
height={logoImageHeight}
style={{ height: logoImageHeight }}
priority={true}
loading="eager"
quality={100}
/>
)}
</>
);
} else if (colors.dark != null && colors.light != null) {
return (
<>
{colors.light.logo != null && (
Expand Down
1 change: 1 addition & 0 deletions packages/ui/app/src/resolver/DocsContent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export declare namespace DocsContent {
* The Request / Response snippets will use this to link back to the endpoint reference page.
*/
endpointIdsToSlugs: Record<FernNavigation.EndpointId, FernNavigation.Slug>;
frontmatter: FernDocs.Frontmatter | undefined;
}

interface ApiEndpointPage {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/app/src/resolver/resolveMarkdownPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,6 @@ export async function resolveMarkdownPageWithoutApiRefs({
breadcrumb,
neighbors,
hasAside,
frontmatter,
};
}
1 change: 1 addition & 0 deletions packages/ui/docs-bundle/src/server/withInitialProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,7 @@ export async function withInitialProps({
docs.definition.filesV2,
found.tabs.length > 0,
),
frontmatterLogoOverride: content?.type === "markdown-page" ? content.frontmatter?.logo : undefined,
};

// if the user specifies a github navbar link, grab the repo info from it and save it as an SWR fallback
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading