From 8605b124f8f18cc96d245c98051bbce8ac706d77 Mon Sep 17 00:00:00 2001 From: Sami Belkadi <33563876+sbelkadi@users.noreply.github.com> Date: Thu, 12 Dec 2024 22:22:50 -0500 Subject: [PATCH] feat: Optional frontmatter logo for page (#1888) Co-authored-by: Sami Belkadi Co-authored-by: Andrew Jiang --- .../definition/docs/latest/frontmatter.yml | 18 ++++ .../frontmatter/types/Frontmatter.ts | 2 + .../resources/frontmatter/types/Logo.ts | 7 ++ .../frontmatter/types/LogoConfiguration.ts | 12 +++ .../resources/frontmatter/types/index.ts | 2 + packages/fdr-sdk/src/docs/frontmatter.ts | 1 + .../frontmatter/types/Frontmatter.ts | 2 + .../resources/frontmatter/types/Logo.ts | 7 ++ .../frontmatter/types/LogoConfiguration.ts | 12 +++ .../resources/frontmatter/types/index.ts | 2 + packages/ui/app/src/atoms/files.ts | 12 ++- packages/ui/app/src/atoms/logo.ts | 48 ++++++++++ .../ui/app/src/header/HeaderLogoImage.tsx | 93 ++++++++++--------- .../frontmatter/types/Frontmatter.d.ts | 2 + .../resources/frontmatter/types/Logo.d.ts | 5 + .../resources/frontmatter/types/Logo.js | 4 + .../frontmatter/types/LogoConfiguration.d.ts | 10 ++ .../frontmatter/types/LogoConfiguration.js | 4 + .../resources/frontmatter/types/index.d.ts | 2 + .../resources/frontmatter/types/index.js | 2 + 20 files changed, 202 insertions(+), 45 deletions(-) create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts create mode 100644 packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts create mode 100644 packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts create mode 100644 servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.js create mode 100644 servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.js diff --git a/fern/apis/fdr/definition/docs/latest/frontmatter.yml b/fern/apis/fdr/definition/docs/latest/frontmatter.yml index c218ab5bcc..24880a768e 100644 --- a/fern/apis/fdr/definition/docs/latest/frontmatter.yml +++ b/fern/apis/fdr/definition/docs/latest/frontmatter.yml @@ -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 tag in the HTML. + logo: + type: optional + docs: The logo for this page. image: type: optional 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). @@ -67,6 +70,21 @@ types: type: optional docs: The canonical URL of the page. This is used for the tag in the HTML. + Logo: + discriminated: false + union: + - commons.FileIdOrUrl + - LogoConfiguration + + LogoConfiguration: + properties: + light: + type: optional + docs: The URL to this page's light theme logo. + dark: + type: optional + docs: The URL to this page's dark theme logo. + Layout: enum: - value: guide diff --git a/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts index 0d0e6886c6..2869a98451 100644 --- a/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts +++ b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts @@ -25,6 +25,8 @@ export interface Frontmatter * If `description` is not set, this will be used for the tag in the HTML. */ subtitle: string | undefined; + /** The logo for this page. */ + logo: FernRegistry.docs.latest.Logo | undefined; /** 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). */ image: FernRegistry.docs.latest.FileIdOrUrl | undefined; /** Reners an "Edit this page" link at the bottom of the page. */ diff --git a/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts new file mode 100644 index 0000000000..7bd855c8ae --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../../../../../index"; + +export type Logo = FernRegistry.docs.latest.FileIdOrUrl | FernRegistry.docs.latest.LogoConfiguration; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts new file mode 100644 index 0000000000..a75cc8633b --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../../../../../index"; + +export interface LogoConfiguration { + /** The URL to this page's light theme logo. */ + light: FernRegistry.docs.latest.FileIdOrUrl | undefined; + /** The URL to this page's dark theme logo. */ + dark: FernRegistry.docs.latest.FileIdOrUrl | undefined; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts index bffeeeef11..27614c9bb0 100644 --- a/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts +++ b/packages/fdr-sdk/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts @@ -1,2 +1,4 @@ export * from "./Frontmatter"; +export * from "./Logo"; +export * from "./LogoConfiguration"; export * from "./Layout"; diff --git a/packages/fdr-sdk/src/docs/frontmatter.ts b/packages/fdr-sdk/src/docs/frontmatter.ts index 32c80554b9..7ac307c641 100644 --- a/packages/fdr-sdk/src/docs/frontmatter.ts +++ b/packages/fdr-sdk/src/docs/frontmatter.ts @@ -37,4 +37,5 @@ export const EMPTY_FRONTMATTER: Frontmatter = { nofollow: undefined, "jsonld:breadcrumb": undefined, keywords: undefined, + logo: undefined, }; diff --git a/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts index 0d0e6886c6..2869a98451 100644 --- a/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts +++ b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.ts @@ -25,6 +25,8 @@ export interface Frontmatter * If `description` is not set, this will be used for the tag in the HTML. */ subtitle: string | undefined; + /** The logo for this page. */ + logo: FernRegistry.docs.latest.Logo | undefined; /** 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). */ image: FernRegistry.docs.latest.FileIdOrUrl | undefined; /** Reners an "Edit this page" link at the bottom of the page. */ diff --git a/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts new file mode 100644 index 0000000000..7bd855c8ae --- /dev/null +++ b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../../../../../index"; + +export type Logo = FernRegistry.docs.latest.FileIdOrUrl | FernRegistry.docs.latest.LogoConfiguration; diff --git a/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts new file mode 100644 index 0000000000..a75cc8633b --- /dev/null +++ b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../../../../../index"; + +export interface LogoConfiguration { + /** The URL to this page's light theme logo. */ + light: FernRegistry.docs.latest.FileIdOrUrl | undefined; + /** The URL to this page's dark theme logo. */ + dark: FernRegistry.docs.latest.FileIdOrUrl | undefined; +} diff --git a/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts index bffeeeef11..27614c9bb0 100644 --- a/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts +++ b/packages/parsers/src/client/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.ts @@ -1,2 +1,4 @@ export * from "./Frontmatter"; +export * from "./Logo"; +export * from "./LogoConfiguration"; export * from "./Layout"; diff --git a/packages/ui/app/src/atoms/files.ts b/packages/ui/app/src/atoms/files.ts index e127611586..9a4099b836 100644 --- a/packages/ui/app/src/atoms/files.ts +++ b/packages/ui/app/src/atoms/files.ts @@ -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"; @@ -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], + ), + ); } diff --git a/packages/ui/app/src/atoms/logo.ts b/packages/ui/app/src/atoms/logo.ts index 830b7059ea..3b4d5a6856 100644 --- a/packages/ui/app/src/atoms/logo.ts +++ b/packages/ui/app/src/atoms/logo.ts @@ -1,3 +1,4 @@ +import { EMPTY_FRONTMATTER, 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"; @@ -17,3 +18,50 @@ LOGO_HEIGHT_ATOM.debugLabel = "LOGO_HEIGHT_ATOM"; 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_IMAGE_ATOM = atom((get) => { + const { content, colors } = get(DOCS_ATOM); + const markdownText = + content.type === "markdown-page" + ? content.content + : content.type === "changelog" && content.node.overviewPageId != null + ? content.pages[content.node.overviewPageId] + : content.type === "changelog-entry" + ? content.page + : undefined; + + const { logo } = typeof markdownText === "object" ? markdownText.frontmatter : EMPTY_FRONTMATTER; + + 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 }; + } + } + + const light = colors.light?.logo != null ? { type: "fileId" as const, value: colors.light.logo } : undefined; + const dark = colors.dark?.logo != null ? { type: "fileId" as const, value: colors.dark.logo } : undefined; + + return { light: light ?? dark, dark: dark ?? light }; +}); diff --git a/packages/ui/app/src/header/HeaderLogoImage.tsx b/packages/ui/app/src/header/HeaderLogoImage.tsx index d76f551666..f080e1391d 100644 --- a/packages/ui/app/src/header/HeaderLogoImage.tsx +++ b/packages/ui/app/src/header/HeaderLogoImage.tsx @@ -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_IMAGE_ATOM, useFile, useLogoHeight } from "../atoms"; import { FernImage } from "../components/FernImage"; function FernFileImage({ @@ -11,57 +11,64 @@ function FernFileImage({ return ; } +function FernFileOrUrlImage({ + fileIdOrUrl, + ...props +}: Omit & { fileIdOrUrl: DocsV1Read.FileIdOrUrl }): ReactElement { + if (fileIdOrUrl.type === "fileId") { + return ; + } + return ; +} + export function HeaderLogoImage(): ReactElement | null { - const colors = useColors(); const logoImageHeight = useLogoHeight(); const title = useAtomValue(DOCS_ATOM).title ?? "Logo"; + const { light, dark } = useAtomValue(LOGO_IMAGE_ATOM); - if (colors.dark != null && colors.light != null) { + if (light != null && dark != null) { return ( <> - {colors.light.logo != null && ( - - )} - {colors.dark.logo != null && ( - - )} + + ); - } else { - const logoFile = colors.light?.logo ?? colors.dark?.logo; + } - if (logoFile == null) { - return null; - } + const logoFile = light ?? dark; - return ( - - ); + if (logoFile == null) { + return null; } + + return ( + + ); } diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.d.ts b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.d.ts index c78075ee2b..18de449e91 100644 --- a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.d.ts +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Frontmatter.d.ts @@ -21,6 +21,8 @@ export interface Frontmatter extends FernRegistry.docs.latest.WithMetadataConfig * If `description` is not set, this will be used for the tag in the HTML. */ subtitle: string | undefined; + /** The logo for this page. */ + logo: FernRegistry.docs.latest.Logo | undefined; /** 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). */ image: FernRegistry.docs.latest.FileIdOrUrl | undefined; /** Reners an "Edit this page" link at the bottom of the page. */ diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.d.ts b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.d.ts new file mode 100644 index 0000000000..c049aa8b80 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.d.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../../../../../index"; +export declare type Logo = FernRegistry.docs.latest.FileIdOrUrl | FernRegistry.docs.latest.LogoConfiguration; diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.js b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/Logo.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.d.ts b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.d.ts new file mode 100644 index 0000000000..7ea1f0b7f0 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.d.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../../../../../index"; +export interface LogoConfiguration { + /** The URL to this page's light theme logo. */ + light: FernRegistry.docs.latest.FileIdOrUrl | undefined; + /** The URL to this page's dark theme logo. */ + dark: FernRegistry.docs.latest.FileIdOrUrl | undefined; +} diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.js b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/LogoConfiguration.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.d.ts b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.d.ts index bffeeeef11..27614c9bb0 100644 --- a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.d.ts +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.d.ts @@ -1,2 +1,4 @@ export * from "./Frontmatter"; +export * from "./Logo"; +export * from "./LogoConfiguration"; export * from "./Layout"; diff --git a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.js b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.js index bffeeeef11..27614c9bb0 100644 --- a/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.js +++ b/servers/fdr/src/api/generated/api/resources/docs/resources/latest/resources/frontmatter/types/index.js @@ -1,2 +1,4 @@ export * from "./Frontmatter"; +export * from "./Logo"; +export * from "./LogoConfiguration"; export * from "./Layout";