docs: improvements and fixes to components in API reference (#9410)
- Change layout of parameters for clearer display - Fix schema code blocks being longer than container - switch between showing required to showing optional indicator - Fixed code tabs not having copy / report buttons Closes DOCS-936 Preview: https://api-reference-v2-git-docs-api-ref-comp-improv-medusajs.vercel.app/v2/api/store
This commit is contained in:
@@ -67,6 +67,14 @@ const TagsOperationDescriptionSection = ({
|
||||
workflow={operation["x-workflow"]}
|
||||
/>
|
||||
)}
|
||||
{operation.externalDocs && (
|
||||
<>
|
||||
Related guide:{" "}
|
||||
<Link href={operation.externalDocs.url} target="_blank">
|
||||
{operation.externalDocs.description || "Read More"}
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
<Feedback
|
||||
event="survey_api-ref"
|
||||
extraData={{
|
||||
@@ -79,14 +87,6 @@ const TagsOperationDescriptionSection = ({
|
||||
vertical={true}
|
||||
question="Did this API Route run successfully?"
|
||||
/>
|
||||
{operation.externalDocs && (
|
||||
<>
|
||||
Related guide:{" "}
|
||||
<Link href={operation.externalDocs.url} target="_blank">
|
||||
{operation.externalDocs.description || "Read More"}
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
{operation.security && (
|
||||
<TagsOperationDescriptionSectionSecurity
|
||||
security={operation.security}
|
||||
|
||||
@@ -16,100 +16,37 @@ type TagOperationParametersDescriptionProps = {
|
||||
const TagOperationParametersDescription = ({
|
||||
schema,
|
||||
}: TagOperationParametersDescriptionProps) => {
|
||||
let typeDescription: React.ReactNode = <></>
|
||||
switch (true) {
|
||||
case schema.type === "object":
|
||||
typeDescription = (
|
||||
<>
|
||||
{schema.type} {schema.title ? `(${schema.title})` : ""}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case schema.type === "array":
|
||||
typeDescription = (
|
||||
<>
|
||||
{schema.type === "array" && formatArrayDescription(schema.items)}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case schema.anyOf !== undefined:
|
||||
case schema.allOf !== undefined:
|
||||
typeDescription = (
|
||||
<>
|
||||
{formatUnionDescription(schema.allOf)}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case schema.oneOf !== undefined:
|
||||
typeDescription = (
|
||||
<>
|
||||
{schema.oneOf?.map((item, index) => (
|
||||
<Fragment key={index}>
|
||||
{index !== 0 && <> or </>}
|
||||
{item.type !== "array" && <>{item.title || item.type}</>}
|
||||
{item.type === "array" && (
|
||||
<>array{item.items.type ? ` of ${item.items.type}s` : ""}</>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
default:
|
||||
typeDescription = (
|
||||
<>
|
||||
{!schema.type ? "any" : schema.type}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
{schema.format ? ` <${schema.format}>` : ""}
|
||||
</>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<div className={clsx("w-2/3 break-words pb-0.5")}>
|
||||
{typeDescription}
|
||||
<div className={clsx("pb-0.5 flex flex-col gap-0.25")}>
|
||||
{schema.default !== undefined && (
|
||||
<>
|
||||
<br />
|
||||
<span>
|
||||
Default:{" "}
|
||||
<InlineCode className="break-words">
|
||||
{JSON.stringify(schema.default)}
|
||||
</InlineCode>
|
||||
</span>
|
||||
</>
|
||||
<span>
|
||||
Default:{" "}
|
||||
<InlineCode className="break-words">
|
||||
{JSON.stringify(schema.default)}
|
||||
</InlineCode>
|
||||
</span>
|
||||
)}
|
||||
{schema.enum && (
|
||||
<>
|
||||
<br />
|
||||
<span>
|
||||
Enum:{" "}
|
||||
{schema.enum.map((value, index) => (
|
||||
<Fragment key={index}>
|
||||
{index !== 0 && <>, </>}
|
||||
<InlineCode key={index}>{JSON.stringify(value)}</InlineCode>
|
||||
</Fragment>
|
||||
))}
|
||||
</span>
|
||||
</>
|
||||
<span>
|
||||
Enum:{" "}
|
||||
{schema.enum.map((value, index) => (
|
||||
<Fragment key={index}>
|
||||
{index !== 0 && <>, </>}
|
||||
<InlineCode key={index}>{JSON.stringify(value)}</InlineCode>
|
||||
</Fragment>
|
||||
))}
|
||||
</span>
|
||||
)}
|
||||
{schema.example !== undefined && (
|
||||
<>
|
||||
<br />
|
||||
<span>
|
||||
Example:{" "}
|
||||
<InlineCode className="break-words">
|
||||
{JSON.stringify(schema.example)}
|
||||
</InlineCode>
|
||||
</span>
|
||||
</>
|
||||
<span>
|
||||
Example:{" "}
|
||||
<InlineCode className="break-words">
|
||||
{JSON.stringify(schema.example)}
|
||||
</InlineCode>
|
||||
</span>
|
||||
)}
|
||||
{schema.description && (
|
||||
<>
|
||||
<br />
|
||||
<MDXContentClient
|
||||
content={capitalize(schema.description)}
|
||||
className={clsx("!mb-0 [&>*]:!mb-0")}
|
||||
@@ -120,33 +57,15 @@ const TagOperationParametersDescription = ({
|
||||
</>
|
||||
)}
|
||||
{schema.externalDocs && (
|
||||
<>
|
||||
<span>
|
||||
Related guide:{" "}
|
||||
<Link href={schema.externalDocs.url} target="_blank">
|
||||
{schema.externalDocs.description || "Read More"}
|
||||
</Link>
|
||||
</>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default TagOperationParametersDescription
|
||||
|
||||
function formatArrayDescription(schema?: SchemaObject) {
|
||||
if (!schema) {
|
||||
return "Array"
|
||||
}
|
||||
|
||||
const type =
|
||||
schema.type === "object"
|
||||
? `objects ${schema.title ? `(${schema.title})` : ""}`
|
||||
: `${schema.type || "object"}s`
|
||||
|
||||
return `Array of ${type}`
|
||||
}
|
||||
|
||||
function formatUnionDescription(arr?: SchemaObject[]) {
|
||||
const types = [...new Set(arr?.map((type) => type.type || "object"))]
|
||||
return <>{types.join(" or ")}</>
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { SchemaObject } from "@/types/openapi"
|
||||
import { Badge, ExpandableNotice, FeatureFlagNotice } from "docs-ui"
|
||||
import { Fragment } from "react"
|
||||
|
||||
export type TagOperationParametersNameProps = {
|
||||
name: string
|
||||
@@ -12,39 +13,101 @@ const TagOperationParametersName = ({
|
||||
isRequired,
|
||||
schema,
|
||||
}: TagOperationParametersNameProps) => {
|
||||
let typeDescription: React.ReactNode = <></>
|
||||
switch (true) {
|
||||
case schema.type === "object":
|
||||
typeDescription = (
|
||||
<>
|
||||
{schema.type} {schema.title ? `(${schema.title})` : ""}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case schema.type === "array":
|
||||
typeDescription = (
|
||||
<>
|
||||
{schema.type === "array" && formatArrayDescription(schema.items)}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case schema.anyOf !== undefined:
|
||||
case schema.allOf !== undefined:
|
||||
typeDescription = (
|
||||
<>
|
||||
{formatUnionDescription(schema.allOf)}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
case schema.oneOf !== undefined:
|
||||
typeDescription = (
|
||||
<>
|
||||
{schema.oneOf?.map((item, index) => (
|
||||
<Fragment key={index}>
|
||||
{index !== 0 && <> or </>}
|
||||
{item.type !== "array" && <>{item.title || item.type}</>}
|
||||
{item.type === "array" && (
|
||||
<>array{item.items.type ? ` of ${item.items.type}s` : ""}</>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
</>
|
||||
)
|
||||
break
|
||||
default:
|
||||
typeDescription = (
|
||||
<>
|
||||
{!schema.type ? "any" : schema.type}
|
||||
{schema.nullable ? ` or null` : ""}
|
||||
{schema.format ? ` <${schema.format}>` : ""}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<span className="w-1/3 break-words pr-0.5">
|
||||
<span className="inline-flex gap-0.5 items-center">
|
||||
<span className="font-monospace">{name}</span>
|
||||
<span className="text-medusa-fg-muted text-compact-small">
|
||||
{typeDescription}
|
||||
</span>
|
||||
{schema.deprecated && (
|
||||
<Badge variant="orange" className="ml-1">
|
||||
deprecated
|
||||
</Badge>
|
||||
)}
|
||||
{schema["x-expandable"] && (
|
||||
<>
|
||||
<br />
|
||||
<ExpandableNotice type="request" link="#expanding-relations" />
|
||||
</>
|
||||
<ExpandableNotice type="request" link="#expanding-relations" />
|
||||
)}
|
||||
{schema["x-featureFlag"] && (
|
||||
<>
|
||||
<br />
|
||||
<FeatureFlagNotice
|
||||
featureFlag={schema["x-featureFlag"]}
|
||||
type="type"
|
||||
/>
|
||||
</>
|
||||
<FeatureFlagNotice featureFlag={schema["x-featureFlag"]} type="type" />
|
||||
)}
|
||||
{isRequired && (
|
||||
<>
|
||||
<br />
|
||||
<span className="text-medusa-tag-red-text text-compact-x-small">
|
||||
required
|
||||
</span>
|
||||
</>
|
||||
{!isRequired && (
|
||||
<span className="text-medusa-tag-blue-text text-compact-x-small">
|
||||
optional
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
export default TagOperationParametersName
|
||||
|
||||
function formatArrayDescription(schema?: SchemaObject) {
|
||||
if (!schema) {
|
||||
return "Array"
|
||||
}
|
||||
|
||||
const type =
|
||||
schema.type === "object"
|
||||
? `objects ${schema.title ? `(${schema.title})` : ""}`
|
||||
: `${schema.type || "object"}s`
|
||||
|
||||
return `Array of ${type}`
|
||||
}
|
||||
|
||||
function formatUnionDescription(arr?: SchemaObject[]) {
|
||||
const types = [...new Set(arr?.map((type) => type.type || "object"))]
|
||||
return <>{types.join(" or ")}</>
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ const TagOperationParametersDefault = ({
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"my-0.5 inline-flex justify-between",
|
||||
"my-0.5 inline-flex flex-col justify-between gap-0.25",
|
||||
expandable && "w-[calc(100%-16px)]",
|
||||
!expandable && "w-full pl-1",
|
||||
className
|
||||
|
||||
@@ -101,16 +101,20 @@ const TagOperationParametersObject = ({
|
||||
const content = (
|
||||
<>
|
||||
{sortedProperties.map((property, index) => (
|
||||
<TagOperationParameters
|
||||
schemaObject={{
|
||||
...properties[property],
|
||||
parameterName: property,
|
||||
}}
|
||||
key={index}
|
||||
isRequired={
|
||||
properties[property].isRequired || checkRequired(schema, property)
|
||||
}
|
||||
/>
|
||||
<>
|
||||
{index !== 0 && <hr className="bg-medusa-border-base my-0" />}
|
||||
<TagOperationParameters
|
||||
schemaObject={{
|
||||
...properties[property],
|
||||
parameterName: property,
|
||||
}}
|
||||
key={index}
|
||||
isRequired={
|
||||
properties[property].isRequired ||
|
||||
checkRequired(schema, property)
|
||||
}
|
||||
/>
|
||||
</>
|
||||
))}
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo } from "react"
|
||||
import { useEffect, useMemo, useRef, useState } from "react"
|
||||
import { SchemaObject } from "../../../../types/openapi"
|
||||
import TagOperationParameters from "../../Operation/Parameters"
|
||||
import {
|
||||
@@ -16,6 +16,8 @@ import useSchemaExample from "../../../../hooks/use-schema-example"
|
||||
import { InView } from "react-intersection-observer"
|
||||
import checkElementInViewport from "../../../../utils/check-element-in-viewport"
|
||||
import { singular } from "pluralize"
|
||||
import useResizeObserver from "@react-hook/resize-observer"
|
||||
import clsx from "clsx"
|
||||
|
||||
export type TagSectionSchemaProps = {
|
||||
schema: SchemaObject
|
||||
@@ -23,6 +25,8 @@ export type TagSectionSchemaProps = {
|
||||
}
|
||||
|
||||
const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
|
||||
const paramsRef = useRef<HTMLDivElement>(null)
|
||||
const [maxCodeHeight, setMaxCodeHeight] = useState(0)
|
||||
const { addItems, setActivePath, activePath } = useSidebar()
|
||||
const tagSlugName = useMemo(() => getSectionId([tagName]), [tagName])
|
||||
const formattedName = useMemo(
|
||||
@@ -39,6 +43,9 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
|
||||
skipNonRequired: false,
|
||||
},
|
||||
})
|
||||
useResizeObserver(paramsRef, () => {
|
||||
setMaxCodeHeight(paramsRef.current?.clientHeight || 0)
|
||||
})
|
||||
|
||||
const { scrollableElement, scrollToElement } = useScrollController()
|
||||
const root = useMemo(() => {
|
||||
@@ -106,7 +113,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
|
||||
>
|
||||
<DividedLayout
|
||||
mainContent={
|
||||
<SectionContainer>
|
||||
<SectionContainer ref={paramsRef}>
|
||||
<h2>{formattedName} Object</h2>
|
||||
<h4 className="border-medusa-border-base border-b py-1.5 mt-2">
|
||||
Fields
|
||||
@@ -121,6 +128,11 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
|
||||
source={examples[0].content}
|
||||
lang="json"
|
||||
title={`The ${formattedName} Object`}
|
||||
className={clsx(maxCodeHeight && "overflow-auto")}
|
||||
style={{
|
||||
// remove padding + extra space
|
||||
maxHeight: maxCodeHeight ? maxCodeHeight - 212 : "unset",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</SectionContainer>
|
||||
|
||||
@@ -74,7 +74,7 @@ const TagSection = ({ tag }: TagSectionProps) => {
|
||||
return isElmWindow(scrollableElement) ? document.body : scrollableElement
|
||||
}, [scrollableElement])
|
||||
const { ref } = useInView({
|
||||
threshold: 0.5,
|
||||
threshold: 0.8,
|
||||
rootMargin: `112px 0px 112px 0px`,
|
||||
root,
|
||||
onChange: (inView) => {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
"@medusajs/icons": "preview",
|
||||
"@medusajs/ui": "^3.0.0",
|
||||
"@next/mdx": "14.2.14",
|
||||
"@react-hook/resize-observer": "^2.0.2",
|
||||
"@readme/openapi-parser": "^2.5.0",
|
||||
"@types/mapbox__rehype-prism": "^0.8.0",
|
||||
"@types/mdx": "^2.0.5",
|
||||
|
||||
@@ -15,7 +15,7 @@ export type CodeBlockActionsProps = {
|
||||
inInnerCode?: boolean
|
||||
isCollapsed: boolean
|
||||
canShowApiTesting?: boolean
|
||||
onApiTesting: React.Dispatch<React.SetStateAction<boolean>>
|
||||
onApiTesting?: React.Dispatch<React.SetStateAction<boolean>>
|
||||
noReport?: boolean
|
||||
noCopy?: boolean
|
||||
}
|
||||
@@ -91,7 +91,7 @@ export const CodeBlockActions = ({
|
||||
inHeader && "p-[4.5px]",
|
||||
"cursor-pointer"
|
||||
)}
|
||||
onClick={() => onApiTesting(true)}
|
||||
onClick={() => onApiTesting?.(true)}
|
||||
>
|
||||
<PlaySolid className={clsx(iconClassName)} />
|
||||
</span>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import clsx from "clsx"
|
||||
import React, { useMemo } from "react"
|
||||
import { useColorMode } from "../../../../providers"
|
||||
import { CodeBlockStyle } from "../../../.."
|
||||
|
||||
type CodeBlockHeaderWrapperProps = {
|
||||
blockStyle?: CodeBlockStyle
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
export const CodeBlockHeaderWrapper = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
CodeBlockHeaderWrapperProps
|
||||
>(function CodeBlockHeaderWrapper({ children, blockStyle = "loud" }, ref) {
|
||||
const { colorMode } = useColorMode()
|
||||
|
||||
const bgColor = useMemo(
|
||||
() =>
|
||||
clsx(
|
||||
blockStyle === "loud" && "bg-medusa-contrast-bg-base",
|
||||
blockStyle === "subtle" && [
|
||||
colorMode === "light" && "bg-medusa-bg-component",
|
||||
colorMode === "dark" && "bg-medusa-code-bg-header",
|
||||
]
|
||||
),
|
||||
[blockStyle, colorMode]
|
||||
)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"py-docs_0.5 px-docs_1 mb-0",
|
||||
"rounded-t-docs_lg relative flex justify-between items-center",
|
||||
blockStyle === "subtle" && [
|
||||
"border border-solid border-b-0",
|
||||
colorMode === "light" && "border-medusa-border-base",
|
||||
colorMode === "dark" && "border-medusa-code-border",
|
||||
],
|
||||
bgColor
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
@@ -6,6 +6,7 @@ import { CodeBlockStyle } from ".."
|
||||
import { useColorMode } from "@/providers"
|
||||
import { Badge, BadgeVariant } from "@/components"
|
||||
import { CodeBlockActions, CodeBlockActionsProps } from "../Actions"
|
||||
import { CodeBlockHeaderWrapper } from "./Wrapper"
|
||||
|
||||
export type CodeBlockHeaderMeta = {
|
||||
badgeLabel?: string
|
||||
@@ -27,17 +28,6 @@ export const CodeBlockHeader = ({
|
||||
}: CodeBlockHeaderProps) => {
|
||||
const { colorMode } = useColorMode()
|
||||
|
||||
const bgColor = useMemo(
|
||||
() =>
|
||||
clsx(
|
||||
blockStyle === "loud" && "bg-medusa-contrast-bg-base",
|
||||
blockStyle === "subtle" && [
|
||||
colorMode === "light" && "bg-medusa-bg-component",
|
||||
colorMode === "dark" && "bg-medusa-code-bg-header",
|
||||
]
|
||||
),
|
||||
[blockStyle, colorMode]
|
||||
)
|
||||
const titleColor = useMemo(
|
||||
() =>
|
||||
clsx(
|
||||
@@ -51,18 +41,7 @@ export const CodeBlockHeader = ({
|
||||
)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
"py-docs_0.5 px-docs_1 mb-0",
|
||||
"rounded-t-docs_lg relative flex justify-between items-center",
|
||||
blockStyle === "subtle" && [
|
||||
"border border-solid border-b-0",
|
||||
colorMode === "light" && "border-medusa-border-base",
|
||||
colorMode === "dark" && "border-medusa-code-border",
|
||||
],
|
||||
bgColor
|
||||
)}
|
||||
>
|
||||
<CodeBlockHeaderWrapper blockStyle={blockStyle}>
|
||||
<div className={clsx("flex-1", "flex gap-docs_0.75 items-start")}>
|
||||
{badgeLabel && (
|
||||
<Badge variant={badgeColor || "code"} className="font-base">
|
||||
@@ -76,6 +55,6 @@ export const CodeBlockHeader = ({
|
||||
)}
|
||||
</div>
|
||||
<CodeBlockActions {...actionsProps} />
|
||||
</div>
|
||||
</CodeBlockHeaderWrapper>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ export type CodeBlockProps = {
|
||||
collapsed?: boolean
|
||||
blockStyle?: CodeBlockStyle
|
||||
children?: React.ReactNode
|
||||
style?: React.HTMLAttributes<HTMLDivElement>["style"]
|
||||
} & CodeBlockMetaFields &
|
||||
Omit<HighlightProps, "code" | "language" | "children">
|
||||
|
||||
@@ -71,6 +72,7 @@ export const CodeBlock = ({
|
||||
collapsibleLines,
|
||||
expandButtonLabel,
|
||||
isTerminal,
|
||||
style,
|
||||
...rest
|
||||
}: CodeBlockProps) => {
|
||||
if (!source && typeof children === "string") {
|
||||
@@ -92,10 +94,14 @@ export const CodeBlock = ({
|
||||
: isTerminal
|
||||
}, [isTerminal, lang])
|
||||
const codeTitle = useMemo(() => {
|
||||
if (title || hasTabs) {
|
||||
if (title) {
|
||||
return title
|
||||
}
|
||||
|
||||
if (hasTabs) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (isTerminalCode) {
|
||||
return "Terminal"
|
||||
}
|
||||
@@ -329,6 +335,7 @@ export const CodeBlock = ({
|
||||
!hasInnerCodeBlock && "rounded-docs_DEFAULT",
|
||||
className
|
||||
)}
|
||||
style={style}
|
||||
>
|
||||
<Highlight
|
||||
theme={codeTheme}
|
||||
@@ -370,9 +377,6 @@ export const CodeBlock = ({
|
||||
!hasInnerCodeBlock &&
|
||||
tokens.length <= 1 &&
|
||||
"px-docs_1 py-[6px]",
|
||||
!codeTitle.length &&
|
||||
(!noCopy || !noReport) &&
|
||||
"xs:max-w-[83%]",
|
||||
(noLineNumbers ||
|
||||
(tokens.length <= 1 && !isTerminalCode)) &&
|
||||
"pl-docs_1",
|
||||
|
||||
@@ -10,6 +10,8 @@ import {
|
||||
useTabs,
|
||||
} from "../.."
|
||||
import clsx from "clsx"
|
||||
import { CodeBlockActions, CodeBlockActionsProps } from "../CodeBlock/Actions"
|
||||
import { CodeBlockHeaderWrapper } from "../CodeBlock/Header/Wrapper"
|
||||
|
||||
type CodeTab = BaseTabType & {
|
||||
codeProps: CodeBlockProps
|
||||
@@ -132,6 +134,23 @@ export const CodeTabs = ({
|
||||
}
|
||||
}, [codeTabSelectorRef, tabRefs, changeTabSelectorCoordinates, selectedTab])
|
||||
|
||||
const actionsProps: CodeBlockActionsProps | undefined = useMemo(() => {
|
||||
if (!selectedTab) {
|
||||
return
|
||||
}
|
||||
|
||||
return {
|
||||
source: selectedTab?.codeProps.source,
|
||||
blockStyle,
|
||||
noReport: selectedTab?.codeProps.noReport,
|
||||
noCopy: selectedTab?.codeProps.noCopy,
|
||||
inInnerCode: true,
|
||||
showGradientBg: false,
|
||||
inHeader: true,
|
||||
isCollapsed: false,
|
||||
}
|
||||
}, [selectedTab])
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(
|
||||
@@ -142,16 +161,7 @@ export const CodeTabs = ({
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"flex gap-docs_0.75 relative",
|
||||
"pt-[10px] px-docs_1 pb-px",
|
||||
blockStyle === "loud" &&
|
||||
selectedTab?.codeProps.title &&
|
||||
"border border-solid border-b border-medusa-contrast-border-bot"
|
||||
)}
|
||||
ref={codeTabsWrapperRef}
|
||||
>
|
||||
<CodeBlockHeaderWrapper blockStyle={blockStyle} ref={codeTabsWrapperRef}>
|
||||
<span
|
||||
className={clsx(
|
||||
"xs:absolute xs:transition-all xs:duration-200 xs:ease-ease xs:bottom-0",
|
||||
@@ -198,7 +208,8 @@ export const CodeTabs = ({
|
||||
{selectedTab.codeProps.badgeLabel}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
{actionsProps && <CodeBlockActions {...actionsProps} />}
|
||||
</CodeBlockHeaderWrapper>
|
||||
{selectedTab?.codeBlock}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -3197,6 +3197,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-hook/resize-observer@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "@react-hook/resize-observer@npm:2.0.2"
|
||||
dependencies:
|
||||
"@react-hook/latest": ^1.0.2
|
||||
"@react-hook/passive-layout-effect": ^1.2.0
|
||||
peerDependencies:
|
||||
react: ">=18"
|
||||
checksum: a88f088bd5b87fea80daca391bdea9823dc38651bd112f0c607b057d9c8381f37395cf5a01a79ba7ab24369c4b48acf912cfef0244e6610d72ea3074415e9c32
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-stately/datepicker@npm:^3.5.0, @react-stately/datepicker@npm:^3.9.2":
|
||||
version: 3.9.2
|
||||
resolution: "@react-stately/datepicker@npm:3.9.2"
|
||||
@@ -5553,6 +5565,7 @@ __metadata:
|
||||
"@medusajs/ui": ^3.0.0
|
||||
"@next/bundle-analyzer": ^14.2.14
|
||||
"@next/mdx": 14.2.14
|
||||
"@react-hook/resize-observer": ^2.0.2
|
||||
"@readme/openapi-parser": ^2.5.0
|
||||
"@types/jsdom": ^21.1.1
|
||||
"@types/mapbox__rehype-prism": ^0.8.0
|
||||
|
||||
Reference in New Issue
Block a user