docs: redesign API runner (#8688)
* fix up block style + plain theme color * initial redesign * docs: redesign API Runner * revert yarn.lock changes
This commit is contained in:
@@ -16,7 +16,7 @@ export const singlePathHighlights = [
|
||||
["11", "req.params.id", "Access the path parameter `id`"]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/[id]/route.ts" highlights={singlePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}" testApiMethod="GET" testPathParams={{ "id": "1" }}
|
||||
```ts title="src/api/store/hello-world/[id]/route.ts" highlights={singlePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}" testApiMethod="GET" testPathParams={{ "id": "" }}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -45,7 +45,7 @@ export const multiplePathHighlights = [
|
||||
["13", "req.params.name", "Access the path parameter `name`"]
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/[id]/name/[name]/route.ts" highlights={multiplePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}/name/{name}" testApiMethod="GET" testPathParams={{ "id": "1", "name": "John" }}
|
||||
```ts title="src/api/store/hello-world/[id]/name/[name]/route.ts" highlights={multiplePathHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world/{id}/name/{name}" testApiMethod="GET" testPathParams={{ "id": "", "name": "" }}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -77,7 +77,7 @@ export const queryHighlights = [
|
||||
["11", "req.query.name", "Access the query parameter `name`"],
|
||||
]
|
||||
|
||||
```ts title="src/api/store/hello-world/route.ts" highlights={queryHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="GET" testQueryParams={{ "name": "John" }}
|
||||
```ts title="src/api/store/hello-world/route.ts" highlights={queryHighlights} apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="GET" testQueryParams={{ "name": "" }}
|
||||
import type {
|
||||
MedusaRequest,
|
||||
MedusaResponse,
|
||||
@@ -130,7 +130,7 @@ In this example, you use the `name` request body parameter to create the message
|
||||
|
||||
To test it out, send the following request to your Medusa application:
|
||||
|
||||
```bash apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="POST" testBodyParams={{ "name": "John" }}
|
||||
```bash apiTesting testApiUrl="http://localhost:9000/store/hello-world" testApiMethod="POST" testBodyParams={{ "name": "" }}
|
||||
curl -X POST 'http://localhost:9000/store/hello-world' \
|
||||
-H 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import React from "react"
|
||||
|
||||
export const ApiRunnerFooterBackground = () => {
|
||||
return (
|
||||
<svg
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 641 44"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="absolute top-0 left-0"
|
||||
>
|
||||
<rect
|
||||
width="640"
|
||||
height="44"
|
||||
transform="translate(0.5)"
|
||||
fill="var(--docs-bg-component)"
|
||||
/>
|
||||
<rect
|
||||
width="640"
|
||||
height="44"
|
||||
transform="translate(0.5)"
|
||||
fill="url(#pattern0_10459_12087)"
|
||||
fillOpacity="0.04"
|
||||
/>
|
||||
<defs>
|
||||
<pattern
|
||||
id="pattern0_10459_12087"
|
||||
patternContentUnits="objectBoundingBox"
|
||||
width="0.009375"
|
||||
height="0.136364"
|
||||
>
|
||||
<use
|
||||
xlinkHref="#image0_10459_12087"
|
||||
transform="scale(0.0015625 0.0227273)"
|
||||
/>
|
||||
</pattern>
|
||||
<image
|
||||
id="image0_10459_12087"
|
||||
width="6"
|
||||
height="6"
|
||||
xlinkHref="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAZSURBVHgBxcghAQAAAIMw+pf+C+CZHLilebfsBfsvTewEAAAAAElFTkSuQmCC"
|
||||
/>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -97,6 +97,7 @@ export const ApiRunnerParamInput = ({
|
||||
? (paramValue as number)
|
||||
: `${paramValue}`
|
||||
}
|
||||
className="w-full"
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,11 +15,9 @@ export const ApiRunnerParamInputs = ({
|
||||
setValue,
|
||||
}: ApiRunnerParamInputsProps) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-docs_0.5">
|
||||
<span className="text-compact-medium-plus text-medusa-fg-base">
|
||||
{title}
|
||||
</span>
|
||||
<div className="flex gap-docs_0.5">
|
||||
<div className="flex flex-col gap-docs_0.25 w-full">
|
||||
<span className="txt-small-plus text-medusa-fg-subtle">{title}</span>
|
||||
<div className="flex flex-col gap-docs_0.5">
|
||||
{Object.keys(data).map((pathParam, index) => (
|
||||
<ApiRunnerParamInput
|
||||
paramName={pathParam}
|
||||
|
||||
@@ -4,10 +4,13 @@ import React from "react"
|
||||
import { useEffect, useMemo, useState } from "react"
|
||||
import { useRequestRunner } from "../../hooks"
|
||||
import { CodeBlock } from "../CodeBlock"
|
||||
import { Card } from "../Card"
|
||||
import { Button } from "../.."
|
||||
import { ApiMethod, ApiTestingOptions } from "types"
|
||||
import { ApiRunnerParamInputs } from "./ParamInputs"
|
||||
import clsx from "clsx"
|
||||
import { ArrowDownRightMini } from "@medusajs/icons"
|
||||
import { ArrowRightDownIcon } from "../Icons/ArrowRightDown"
|
||||
import { ApiRunnerFooterBackground } from "./FooterBackground"
|
||||
|
||||
type ApiRunnerProps = {
|
||||
apiMethod: ApiMethod
|
||||
@@ -71,54 +74,82 @@ export const ApiRunner = React.forwardRef<HTMLDivElement, ApiRunnerProps>(
|
||||
}, [isRunning, ran])
|
||||
|
||||
return (
|
||||
<div ref={ref}>
|
||||
<div className="mb-docs_1" ref={ref}>
|
||||
{manualTestTrigger && (
|
||||
<Card className="font-base mb-docs_1" contentClassName="gap-docs_0.5">
|
||||
{apiTestingOptions.pathData && (
|
||||
<ApiRunnerParamInputs
|
||||
data={apiTestingOptions.pathData}
|
||||
title="Path Parameters"
|
||||
baseObjPath="pathData"
|
||||
setValue={
|
||||
setApiTestingOptions as React.Dispatch<
|
||||
React.SetStateAction<unknown>
|
||||
>
|
||||
}
|
||||
/>
|
||||
<div
|
||||
className={clsx(
|
||||
"bg-medusa-bg-component rounded-docs_DEFAULT",
|
||||
"shadow-elevation-card-rest dark:shadow-elevation-card-rest-dark",
|
||||
"mb-docs_0.75"
|
||||
)}
|
||||
{apiTestingOptions.bodyData && (
|
||||
<ApiRunnerParamInputs
|
||||
data={apiTestingOptions.bodyData}
|
||||
title="Request Body Parameters"
|
||||
baseObjPath="bodyData"
|
||||
setValue={
|
||||
setApiTestingOptions as React.Dispatch<
|
||||
React.SetStateAction<unknown>
|
||||
>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{apiTestingOptions.queryData && (
|
||||
<ApiRunnerParamInputs
|
||||
data={apiTestingOptions.queryData}
|
||||
title="Request Query Parameters"
|
||||
baseObjPath="queryData"
|
||||
setValue={
|
||||
setApiTestingOptions as React.Dispatch<
|
||||
React.SetStateAction<unknown>
|
||||
>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => {
|
||||
setIsRunning(true)
|
||||
setRan(false)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
"flex items-center gap-docs_0.75",
|
||||
"px-docs_0.75 pb-docs_0.75 pt-docs_0.5"
|
||||
)}
|
||||
>
|
||||
Send Request
|
||||
</Button>
|
||||
</Card>
|
||||
<ArrowDownRightMini className="text-medusa-fg-muted" />
|
||||
<div className="flex-1 flex items-center gap-docs_0.75">
|
||||
{apiTestingOptions.pathData && (
|
||||
<ApiRunnerParamInputs
|
||||
data={apiTestingOptions.pathData}
|
||||
title="Path Parameters"
|
||||
baseObjPath="pathData"
|
||||
setValue={
|
||||
setApiTestingOptions as React.Dispatch<
|
||||
React.SetStateAction<unknown>
|
||||
>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{apiTestingOptions.bodyData && (
|
||||
<ApiRunnerParamInputs
|
||||
data={apiTestingOptions.bodyData}
|
||||
title="Request Body Parameters"
|
||||
baseObjPath="bodyData"
|
||||
setValue={
|
||||
setApiTestingOptions as React.Dispatch<
|
||||
React.SetStateAction<unknown>
|
||||
>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{apiTestingOptions.queryData && (
|
||||
<ApiRunnerParamInputs
|
||||
data={apiTestingOptions.queryData}
|
||||
title="Request Query Parameters"
|
||||
baseObjPath="queryData"
|
||||
setValue={
|
||||
setApiTestingOptions as React.Dispatch<
|
||||
React.SetStateAction<unknown>
|
||||
>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<ArrowRightDownIcon className="text-medusa-fg-muted" />
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
"border-t border-medusa-border-base",
|
||||
"py-docs_0.5 px-docs_0.75 relative",
|
||||
"flex justify-end items-center gap-docs_0.5"
|
||||
)}
|
||||
>
|
||||
<ApiRunnerFooterBackground />
|
||||
<Button
|
||||
onClick={() => {
|
||||
setIsRunning(true)
|
||||
setRan(false)
|
||||
}}
|
||||
className="relative"
|
||||
variant="secondary"
|
||||
>
|
||||
Send Request
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{(isRunning || ran) && (
|
||||
<CodeBlock
|
||||
@@ -126,12 +157,11 @@ export const ApiRunner = React.forwardRef<HTMLDivElement, ApiRunnerProps>(
|
||||
lang="json"
|
||||
title="Testing Result"
|
||||
collapsed={true}
|
||||
blockStyle="subtle"
|
||||
noReport={true}
|
||||
badgeLabel={responseCode}
|
||||
badgeLabel={responseCode || "Failed"}
|
||||
badgeColor={
|
||||
!responseCode
|
||||
? undefined
|
||||
? "red"
|
||||
: responseCode.startsWith("2")
|
||||
? "green"
|
||||
: "red"
|
||||
|
||||
@@ -28,7 +28,7 @@ export const Button = ({
|
||||
}: ButtonProps) => {
|
||||
const variantClasses = {
|
||||
primary: [
|
||||
"px-[10px] py-[6px] rounded-docs_sm cursor-pointer",
|
||||
"px-docs_0.5 py-docs_0.25 rounded-docs_sm cursor-pointer",
|
||||
"bg-medusa-button-inverted",
|
||||
"hover:bg-medusa-button-inverted-hover hover:no-underline",
|
||||
"active:bg-medusa-button-inverted-pressed",
|
||||
@@ -44,7 +44,7 @@ export const Button = ({
|
||||
"select-none",
|
||||
],
|
||||
secondary: [
|
||||
"px-[10px] py-[6px] rounded-docs_sm cursor-pointer",
|
||||
"px-docs_0.5 py-docs_0.25 rounded-docs_sm cursor-pointer",
|
||||
"bg-medusa-button-neutral",
|
||||
"hover:bg-medusa-button-neutral-hover hover:no-underline",
|
||||
"active:bg-medusa-button-neutral-pressed",
|
||||
@@ -58,7 +58,7 @@ export const Button = ({
|
||||
"select-none",
|
||||
],
|
||||
transparent: [
|
||||
"px-[10px] py-[6px] rounded-docs_sm cursor-pointer",
|
||||
"px-docs_0.5 py-docs_0.25 rounded-docs_sm cursor-pointer",
|
||||
"bg-transparent shadow-none border-0 outline-none",
|
||||
"text-compact-small-plus text-medusa-fg-base",
|
||||
"hover:bg-medusa-button-transparent-hover",
|
||||
@@ -68,7 +68,7 @@ export const Button = ({
|
||||
"disabled:cursor-not-allowed disabled:text-medusa-fg-disabled",
|
||||
],
|
||||
transparentClear: [
|
||||
"px-[10px] py-[6px] rounded-docs_sm cursor-pointer",
|
||||
"px-docs_0.5 py-docs_0.25 rounded-docs_sm cursor-pointer",
|
||||
"bg-transparent shadow-none border-0 outline-none",
|
||||
"text-compact-small-plus text-medusa-fg-muted",
|
||||
"hover:bg-medusa-button-transparent-hover",
|
||||
@@ -82,7 +82,7 @@ export const Button = ({
|
||||
return (
|
||||
<button
|
||||
className={clsx(
|
||||
"inline-flex flex-row justify-center items-center gap-[6px]",
|
||||
"inline-flex flex-row justify-center items-center gap-[6px] font-base",
|
||||
variant === "primary" && variantClasses.primary,
|
||||
variant === "secondary" && variantClasses.secondary,
|
||||
variant === "transparent" && variantClasses.transparent,
|
||||
|
||||
@@ -221,7 +221,7 @@ export const CodeBlockLine = ({
|
||||
key={tokenKey}
|
||||
className={clsx(
|
||||
tokenClassName,
|
||||
(isTerminal || isTokenHighlighted || isLineHighlighted) &&
|
||||
(isTokenHighlighted || isLineHighlighted) &&
|
||||
"!text-medusa-contrast-fg-primary"
|
||||
)}
|
||||
{...rest}
|
||||
|
||||
@@ -272,6 +272,24 @@ export const CodeBlock = ({
|
||||
]
|
||||
)
|
||||
|
||||
const codeTheme = useMemo(() => {
|
||||
const prismTheme =
|
||||
blockStyle === "loud" || colorMode === "dark"
|
||||
? themes.vsDark
|
||||
: themes.vsLight
|
||||
|
||||
return {
|
||||
...prismTheme,
|
||||
plain: {
|
||||
...prismTheme,
|
||||
color:
|
||||
colorMode === "light"
|
||||
? "rgba(255, 255, 255, 0.88)"
|
||||
: "rgba(250, 250, 250, 1)",
|
||||
},
|
||||
}
|
||||
}, [blockStyle, colorMode])
|
||||
|
||||
if (!source.length) {
|
||||
return <></>
|
||||
}
|
||||
@@ -314,11 +332,7 @@ export const CodeBlock = ({
|
||||
)}
|
||||
>
|
||||
<Highlight
|
||||
theme={
|
||||
blockStyle === "loud" || colorMode === "dark"
|
||||
? themes.vsDark
|
||||
: themes.vsLight
|
||||
}
|
||||
theme={codeTheme}
|
||||
code={source.trim()}
|
||||
language={language}
|
||||
{...rest}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import React from "react"
|
||||
import { IconProps } from "@medusajs/icons/dist/types"
|
||||
|
||||
export const ArrowRightDownIcon = (props: IconProps) => {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M8.66671 13.5558L8.66671 4.22242C8.66671 3.2402 7.87115 2.44464 6.88893 2.44464L3.33337 2.44464"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M4.88892 9.77802L8.66669 13.5558L12.4445 9.77802"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
@@ -20,18 +20,17 @@ export const InputText = ({
|
||||
<input
|
||||
{...props}
|
||||
className={clsx(
|
||||
"bg-medusa-bg-field shadow-border-base dark:shadow-border-base-dark",
|
||||
"border-medusa-border-base rounded-docs_sm border border-solid",
|
||||
"px-docs_0.75 py-[9px]",
|
||||
"hover:bg-medusa-bg-field-hover",
|
||||
addGroupStyling && "group-hover:bg-medusa-bg-field-hover",
|
||||
"bg-medusa-bg-field-component shadow-border-base dark:shadow-border-base-dark",
|
||||
"rounded-docs_sm px-docs_0.5",
|
||||
"hover:bg-medusa-bg-field-component-hover",
|
||||
addGroupStyling && "group-hover:bg-medusa-bg-field-component-hover",
|
||||
"focus:border-medusa-border-interactive",
|
||||
"active:border-medusa-border-interactive",
|
||||
"disabled:bg-medusa-bg-disabled",
|
||||
"disabled:border-medusa-border-base",
|
||||
"placeholder:text-medusa-fg-muted",
|
||||
"disabled:placeholder:text-medusa-fg-disabled",
|
||||
"text-compact-medium font-base",
|
||||
"text-compact-small font-base",
|
||||
className
|
||||
)}
|
||||
ref={passedRef}
|
||||
|
||||
Reference in New Issue
Block a user