- {typeDescription}
+
{schema.default !== undefined && (
- <>
-
-
- Default:{" "}
-
- {JSON.stringify(schema.default)}
-
-
- >
+
+ Default:{" "}
+
+ {JSON.stringify(schema.default)}
+
+
)}
{schema.enum && (
- <>
-
-
- Enum:{" "}
- {schema.enum.map((value, index) => (
-
- {index !== 0 && <>, >}
- {JSON.stringify(value)}
-
- ))}
-
- >
+
+ Enum:{" "}
+ {schema.enum.map((value, index) => (
+
+ {index !== 0 && <>, >}
+ {JSON.stringify(value)}
+
+ ))}
+
)}
{schema.example !== undefined && (
- <>
-
-
- Example:{" "}
-
- {JSON.stringify(schema.example)}
-
-
- >
+
+ Example:{" "}
+
+ {JSON.stringify(schema.example)}
+
+
)}
{schema.description && (
<>
-
*]:!mb-0")}
@@ -120,33 +57,15 @@ const TagOperationParametersDescription = ({
>
)}
{schema.externalDocs && (
- <>
+
Related guide:{" "}
{schema.externalDocs.description || "Read More"}
- >
+
)}
)
}
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 ")}>
-}
diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx
index 465b5e8c31..c42e065301 100644
--- a/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx
+++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Name/index.tsx
@@ -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) => (
+
+ {index !== 0 && <> or >}
+ {item.type !== "array" && <>{item.title || item.type}>}
+ {item.type === "array" && (
+ <>array{item.items.type ? ` of ${item.items.type}s` : ""}>
+ )}
+
+ ))}
+ {schema.nullable ? ` or null` : ""}
+ >
+ )
+ break
+ default:
+ typeDescription = (
+ <>
+ {!schema.type ? "any" : schema.type}
+ {schema.nullable ? ` or null` : ""}
+ {schema.format ? ` <${schema.format}>` : ""}
+ >
+ )
+ }
+
return (
-
+
{name}
+
+ {typeDescription}
+
{schema.deprecated && (
deprecated
)}
{schema["x-expandable"] && (
- <>
-
-
- >
+
)}
{schema["x-featureFlag"] && (
- <>
-
-
- >
+
)}
- {isRequired && (
- <>
-
-
- required
-
- >
+ {!isRequired && (
+
+ optional
+
)}
)
}
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 ")}>
+}
diff --git a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx
index 6102282e4b..96b443e0d4 100644
--- a/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx
+++ b/www/apps/api-reference/components/Tags/Operation/Parameters/Types/Default/index.tsx
@@ -21,7 +21,7 @@ const TagOperationParametersDefault = ({
return (
{sortedProperties.map((property, index) => (
-
+ <>
+ {index !== 0 &&
}
+
+ >
))}
>
)
diff --git a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx
index 0801d54630..c542fe2db9 100644
--- a/www/apps/api-reference/components/Tags/Section/Schema/index.tsx
+++ b/www/apps/api-reference/components/Tags/Section/Schema/index.tsx
@@ -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
(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) => {
>
+
{formattedName} Object
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",
+ }}
/>
)}
diff --git a/www/apps/api-reference/components/Tags/Section/index.tsx b/www/apps/api-reference/components/Tags/Section/index.tsx
index 42527c0860..2c318afc62 100644
--- a/www/apps/api-reference/components/Tags/Section/index.tsx
+++ b/www/apps/api-reference/components/Tags/Section/index.tsx
@@ -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) => {
diff --git a/www/apps/api-reference/package.json b/www/apps/api-reference/package.json
index 1d6b2d3c92..40cbd473f3 100644
--- a/www/apps/api-reference/package.json
+++ b/www/apps/api-reference/package.json
@@ -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",
diff --git a/www/packages/docs-ui/src/components/CodeBlock/Actions/index.tsx b/www/packages/docs-ui/src/components/CodeBlock/Actions/index.tsx
index 7544ac1685..7deb8bc8fe 100644
--- a/www/packages/docs-ui/src/components/CodeBlock/Actions/index.tsx
+++ b/www/packages/docs-ui/src/components/CodeBlock/Actions/index.tsx
@@ -15,7 +15,7 @@ export type CodeBlockActionsProps = {
inInnerCode?: boolean
isCollapsed: boolean
canShowApiTesting?: boolean
- onApiTesting: React.Dispatch>
+ onApiTesting?: React.Dispatch>
noReport?: boolean
noCopy?: boolean
}
@@ -91,7 +91,7 @@ export const CodeBlockActions = ({
inHeader && "p-[4.5px]",
"cursor-pointer"
)}
- onClick={() => onApiTesting(true)}
+ onClick={() => onApiTesting?.(true)}
>
diff --git a/www/packages/docs-ui/src/components/CodeBlock/Header/Wrapper/index.tsx b/www/packages/docs-ui/src/components/CodeBlock/Header/Wrapper/index.tsx
new file mode 100644
index 0000000000..5f7b1d9549
--- /dev/null
+++ b/www/packages/docs-ui/src/components/CodeBlock/Header/Wrapper/index.tsx
@@ -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 (
+
+ {children}
+
+ )
+})
diff --git a/www/packages/docs-ui/src/components/CodeBlock/Header/index.tsx b/www/packages/docs-ui/src/components/CodeBlock/Header/index.tsx
index 19fa820836..b6be62c9d8 100644
--- a/www/packages/docs-ui/src/components/CodeBlock/Header/index.tsx
+++ b/www/packages/docs-ui/src/components/CodeBlock/Header/index.tsx
@@ -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 (
-
+
{badgeLabel && (
@@ -76,6 +55,6 @@ export const CodeBlockHeader = ({
)}
-
+
)
}
diff --git a/www/packages/docs-ui/src/components/CodeBlock/index.tsx b/www/packages/docs-ui/src/components/CodeBlock/index.tsx
index 541215447e..7f3392efef 100644
--- a/www/packages/docs-ui/src/components/CodeBlock/index.tsx
+++ b/www/packages/docs-ui/src/components/CodeBlock/index.tsx
@@ -51,6 +51,7 @@ export type CodeBlockProps = {
collapsed?: boolean
blockStyle?: CodeBlockStyle
children?: React.ReactNode
+ style?: React.HTMLAttributes["style"]
} & CodeBlockMetaFields &
Omit
@@ -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}
>
{
+ 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 (
-
+
)}
-
+ {actionsProps &&
}
+
{selectedTab?.codeBlock}
)
diff --git a/www/yarn.lock b/www/yarn.lock
index 836b0527fe..8d62faaf16 100644
--- a/www/yarn.lock
+++ b/www/yarn.lock
@@ -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