docs: DX improvements to a workflow / step reference page (#10906)
This commit is contained in:
37
www/packages/docs-ui/src/components/SourceCodeLink/index.tsx
Normal file
37
www/packages/docs-ui/src/components/SourceCodeLink/index.tsx
Normal file
@@ -0,0 +1,37 @@
|
||||
import React from "react"
|
||||
import { Link } from "../Link"
|
||||
import { Badge } from "../Badge"
|
||||
import { Github } from "@medusajs/icons"
|
||||
import clsx from "clsx"
|
||||
|
||||
type SourceCodeLinkProps = {
|
||||
link: string
|
||||
text?: string
|
||||
icon?: React.ReactNode
|
||||
className?: string
|
||||
}
|
||||
|
||||
export const SourceCodeLink = ({
|
||||
link,
|
||||
text,
|
||||
icon,
|
||||
className,
|
||||
}: SourceCodeLinkProps) => {
|
||||
return (
|
||||
<Link
|
||||
href={link}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className={clsx("my-docs_0.5 align-middle inline-block", className)}
|
||||
>
|
||||
<Badge
|
||||
variant="neutral"
|
||||
className="inline-flex hover:bg-medusa-tag-neutral-bg-hover cursor-pointer"
|
||||
childrenWrapperClassName="inline-flex flex-row gap-[3px] items-center"
|
||||
>
|
||||
{icon || <Github />}
|
||||
<span>{text || "Source Code"}</span>
|
||||
</Badge>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client"
|
||||
|
||||
import React, { useId } from "react"
|
||||
import React, { forwardRef, useId } from "react"
|
||||
import { Tooltip as ReactTooltip } from "react-tooltip"
|
||||
import type { ITooltip } from "react-tooltip"
|
||||
import clsx from "clsx"
|
||||
@@ -15,47 +15,52 @@ export type TooltipProps = {
|
||||
} & React.HTMLAttributes<HTMLSpanElement> &
|
||||
ITooltip
|
||||
|
||||
export const Tooltip = ({
|
||||
text = "",
|
||||
tooltipClassName = "",
|
||||
children,
|
||||
html = "",
|
||||
tooltipChildren,
|
||||
className,
|
||||
innerClassName,
|
||||
...tooltipProps
|
||||
}: TooltipProps) => {
|
||||
const elementId = useId()
|
||||
export const Tooltip = forwardRef<HTMLSpanElement, TooltipProps>(
|
||||
function Tooltip(
|
||||
{
|
||||
text = "",
|
||||
tooltipClassName = "",
|
||||
children,
|
||||
html = "",
|
||||
tooltipChildren,
|
||||
className,
|
||||
innerClassName,
|
||||
...tooltipProps
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const elementId = useId()
|
||||
|
||||
return (
|
||||
<span className={clsx(className, "notranslate")} translate="no">
|
||||
<span
|
||||
id={elementId}
|
||||
data-tooltip-content={text}
|
||||
data-tooltip-html={html}
|
||||
data-tooltip-id={elementId}
|
||||
className={innerClassName}
|
||||
>
|
||||
{children}
|
||||
return (
|
||||
<span className={clsx(className, "notranslate")} translate="no" ref={ref}>
|
||||
<span
|
||||
id={elementId}
|
||||
data-tooltip-content={text}
|
||||
data-tooltip-html={html}
|
||||
data-tooltip-id={elementId}
|
||||
className={innerClassName}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
<ReactTooltip
|
||||
anchorId={elementId}
|
||||
// anchorSelect={elementId ? `#${elementId}` : undefined}
|
||||
className={clsx(
|
||||
"!text-compact-x-small !shadow-elevation-tooltip dark:!shadow-elevation-tooltip-dark !rounded-docs_DEFAULT",
|
||||
"!py-docs_0.25 !z-[399] hidden !px-docs_0.5 lg:block",
|
||||
"!bg-medusa-bg-component",
|
||||
"!text-medusa-fg-base text-center",
|
||||
tooltipClassName
|
||||
)}
|
||||
wrapper="span"
|
||||
noArrow={true}
|
||||
positionStrategy={"fixed"}
|
||||
opacity={1}
|
||||
{...tooltipProps}
|
||||
>
|
||||
{tooltipChildren}
|
||||
</ReactTooltip>
|
||||
</span>
|
||||
<ReactTooltip
|
||||
anchorId={elementId}
|
||||
// anchorSelect={elementId ? `#${elementId}` : undefined}
|
||||
className={clsx(
|
||||
"!text-compact-x-small !shadow-elevation-tooltip dark:!shadow-elevation-tooltip-dark !rounded-docs_DEFAULT",
|
||||
"!py-docs_0.25 !z-[399] hidden !px-docs_0.5 lg:block",
|
||||
"!bg-medusa-bg-component",
|
||||
"!text-medusa-fg-base text-center",
|
||||
tooltipClassName
|
||||
)}
|
||||
wrapper="span"
|
||||
noArrow={true}
|
||||
positionStrategy={"fixed"}
|
||||
opacity={1}
|
||||
{...tooltipProps}
|
||||
>
|
||||
{tooltipChildren}
|
||||
</ReactTooltip>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -41,6 +41,7 @@ const TypeListItem = ({
|
||||
elementKey,
|
||||
sectionTitle,
|
||||
referenceType = "method",
|
||||
openedLevel = 0,
|
||||
}: TypeListItemProps) => {
|
||||
const { isBrowser } = useIsBrowser()
|
||||
const pathname = usePathname()
|
||||
@@ -249,6 +250,7 @@ const TypeListItem = ({
|
||||
className={clsx(getItemClassNames())}
|
||||
heightAnimation={true}
|
||||
id={typeId ? typeId : ""}
|
||||
openInitial={openedLevel >= level}
|
||||
>
|
||||
{typeItem.children && (
|
||||
<TypeListItems
|
||||
|
||||
@@ -5,6 +5,7 @@ import { Loading } from "@/components"
|
||||
export type CommonProps = {
|
||||
expandUrl?: string
|
||||
sectionTitle?: string
|
||||
openedLevel?: number
|
||||
}
|
||||
|
||||
export type Type = {
|
||||
@@ -31,6 +32,7 @@ export const TypeList = ({
|
||||
className,
|
||||
sectionTitle,
|
||||
expandUrl,
|
||||
openedLevel,
|
||||
...props
|
||||
}: ParameterTypesType) => {
|
||||
return (
|
||||
@@ -47,6 +49,7 @@ export const TypeList = ({
|
||||
types={types}
|
||||
expandUrl={expandUrl}
|
||||
sectionTitle={sectionTitle}
|
||||
openedLevel={openedLevel}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import React from "react"
|
||||
import { InlineCode } from "../../../InlineCode"
|
||||
import { Text } from "@medusajs/ui"
|
||||
import { Bolt, InformationCircle } from "@medusajs/icons"
|
||||
|
||||
export const WorkflowDiagramLegend = () => {
|
||||
return (
|
||||
<div className="flex gap-docs_0.5 mt-1">
|
||||
<div className="flex items-center gap-docs_0.5">
|
||||
<div className="flex size-[20px] items-center justify-center text-medusa-tag-orange-icon">
|
||||
<Bolt />
|
||||
</div>
|
||||
<Text
|
||||
size="xsmall"
|
||||
leading="compact"
|
||||
weight="plus"
|
||||
className="select-none"
|
||||
>
|
||||
Workflow Hook
|
||||
</Text>
|
||||
</div>
|
||||
<div className="flex items-center gap-docs_0.5">
|
||||
<div className="flex size-[20px] items-center justify-center text-medusa-tag-green-icon">
|
||||
<InformationCircle />
|
||||
</div>
|
||||
<Text
|
||||
size="xsmall"
|
||||
leading="compact"
|
||||
weight="plus"
|
||||
className="select-none"
|
||||
>
|
||||
Step conditioned by <InlineCode>when</InlineCode>
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
import { Text } from "@medusajs/ui"
|
||||
import clsx from "clsx"
|
||||
import Link from "next/link"
|
||||
import React, { useMemo } from "react"
|
||||
import React, { useEffect, useMemo, useRef, useState } from "react"
|
||||
import { WorkflowStepUi } from "types"
|
||||
import { InlineCode, MarkdownContent, Tooltip } from "../../.."
|
||||
import { Bolt, InformationCircle } from "@medusajs/icons"
|
||||
@@ -14,11 +14,34 @@ export type WorkflowDiagramNodeProps = {
|
||||
|
||||
export const WorkflowDiagramStepNode = ({ step }: WorkflowDiagramNodeProps) => {
|
||||
const stepId = step.name.split(".").pop()
|
||||
const [offset, setOffset] = useState<number | undefined>(undefined)
|
||||
const ref = useRef<HTMLSpanElement>(null)
|
||||
|
||||
const description = useMemo(() => {
|
||||
return step.description?.replaceAll(/:::[a-z]*/g, "") || ""
|
||||
}, [step.description])
|
||||
|
||||
useEffect(() => {
|
||||
if (!ref.current) {
|
||||
return
|
||||
}
|
||||
|
||||
// find parent
|
||||
const diagramParent = ref.current.closest(".workflow-list-diagram")
|
||||
const nodeParent = ref.current.closest(".workflow-node-group")
|
||||
|
||||
if (!diagramParent || !nodeParent) {
|
||||
return
|
||||
}
|
||||
|
||||
const nodeBoundingRect = nodeParent.getBoundingClientRect()
|
||||
const diagramBoundingRect = diagramParent.getBoundingClientRect()
|
||||
|
||||
setOffset(
|
||||
Math.max(diagramBoundingRect.width - nodeBoundingRect.width + 10, 10)
|
||||
)
|
||||
}, [ref.current])
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
tooltipClassName="!text-left max-w-[300px] text-pretty overflow-scroll"
|
||||
@@ -43,6 +66,8 @@ export const WorkflowDiagramStepNode = ({ step }: WorkflowDiagramNodeProps) => {
|
||||
}
|
||||
clickable={true}
|
||||
place="right"
|
||||
offset={offset}
|
||||
ref={ref}
|
||||
>
|
||||
<Link
|
||||
href={step.link || `#${step.name}`}
|
||||
|
||||
@@ -14,7 +14,7 @@ export const WorkflowDiagramListDepth = ({
|
||||
cluster,
|
||||
}: WorkflowDiagramListDepthProps) => {
|
||||
return (
|
||||
<div className="flex items-start">
|
||||
<div className="flex items-start workflow-node-group w-fit">
|
||||
<WorkflowDiagramLine step={cluster} />
|
||||
<div className="flex flex-col justify-center gap-y-docs_0.5">
|
||||
{cluster.map((step, index) => (
|
||||
|
||||
@@ -4,6 +4,7 @@ import React from "react"
|
||||
import { createNodeClusters, getNextCluster } from "../../../utils"
|
||||
import { WorkflowDiagramCommonProps } from "../../.."
|
||||
import { WorkflowDiagramListDepth } from "./Depth"
|
||||
import { WorkflowDiagramLegend } from "../Common/Legend"
|
||||
|
||||
export const WorkflowDiagramList = ({
|
||||
workflow,
|
||||
@@ -11,7 +12,7 @@ export const WorkflowDiagramList = ({
|
||||
const clusters = createNodeClusters(workflow.steps)
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-docs_0.5 my-docs_1">
|
||||
<div className="flex flex-col gap-docs_0.5 my-docs_1 workflow-list-diagram w-fit">
|
||||
{Object.entries(clusters).map(([depth, cluster]) => {
|
||||
const next = getNextCluster(clusters, Number(depth))
|
||||
|
||||
@@ -19,6 +20,7 @@ export const WorkflowDiagramList = ({
|
||||
<WorkflowDiagramListDepth cluster={cluster} next={next} key={depth} />
|
||||
)
|
||||
})}
|
||||
<WorkflowDiagramLegend />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ export * from "./Search/Suggestions/Item"
|
||||
export * from "./Select"
|
||||
export * from "./Sidebar"
|
||||
export * from "./Sidebar/Item"
|
||||
export * from "./SourceCodeLink"
|
||||
export * from "./Table"
|
||||
export * from "./Tabs"
|
||||
export * from "./TextArea"
|
||||
|
||||
Reference in New Issue
Block a user