/* ============================================================================ * Copyright (c) Palo Alto Networks * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * ========================================================================== */ import React, { isValidElement, ReactNode } from "react"; import { CodeBlockProps } from "@docusaurus/theme-common/internal"; import useIsBrowser from "@docusaurus/useIsBrowser"; import ElementContent from "@theme/ApiExplorer/ApiCodeBlock/Content/Element"; import StringContent from "@theme/ApiExplorer/ApiCodeBlock/Content/String"; /** * Best attempt to make the children a plain string so it is copyable. If there * are react elements, we will not be able to copy the content, and it will * return `children` as-is; otherwise, it concatenates the string children * together. */ function maybeStringifyChildren(children: ReactNode): ReactNode { if (React.Children.toArray(children).some((el) => isValidElement(el))) { return children; } // The children is now guaranteed to be one/more plain strings return Array.isArray(children) ? children.join("") : (children as string); } export default function ApiCodeBlock({ children: rawChildren, ...props }: CodeBlockProps) { // The Prism theme on SSR is always the default theme but the site theme can // be in a different mode. React hydration doesn't update DOM styles that come // from SSR. Hence force a re-render after mounting to apply the current // relevant styles. const isBrowser = useIsBrowser(); const children = maybeStringifyChildren(rawChildren); const CodeBlockComp = typeof children === "string" ? StringContent : ElementContent; return ( {children as string} ); }