Skip to content

Commit

Permalink
docs: fixes and refactoring for API reference
Browse files Browse the repository at this point in the history
  • Loading branch information
shahednasser committed Oct 22, 2024
1 parent a0668ad commit e101728
Show file tree
Hide file tree
Showing 17 changed files with 332 additions and 264 deletions.
35 changes: 24 additions & 11 deletions www/apps/api-reference/app/admin/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,35 @@ import AdminContent from "../_mdx/admin.mdx"
import Tags from "@/components/Tags"
import PageTitleProvider from "@/providers/page-title"
import { H1 } from "docs-ui"
import { getBaseSpecs } from "../../lib"
import BaseSpecsProvider from "../../providers/base-specs"
import clsx from "clsx"

const AdminPage = async () => {
const data = await getBaseSpecs("admin")

const ReferencePage = async () => {
return (
<AreaProvider area={"admin"}>
<PageTitleProvider>
<H1 className="!h2-docs scroll-m-56 lg:pl-4" id="introduction">
Medusa V2 Admin API Reference
</H1>
<AdminContent />
<Tags />
</PageTitleProvider>
</AreaProvider>
<BaseSpecsProvider baseSpecs={data}>
<AreaProvider area={"admin"}>
<PageTitleProvider>
<H1
className={clsx(
"!h2-docs lg:pl-4",
"scroll-m-[184px] lg:scroll-m-[264px]"
)}
id="introduction"
>
Medusa V2 Admin API Reference
</H1>
<AdminContent />
<Tags tags={data?.tags} />
</PageTitleProvider>
</AreaProvider>
</BaseSpecsProvider>
)
}

export default ReferencePage
export default AdminPage

export function generateMetadata() {
return {
Expand Down
35 changes: 24 additions & 11 deletions www/apps/api-reference/app/store/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,35 @@ import StoreContent from "../_mdx/store.mdx"
import Tags from "@/components/Tags"
import PageTitleProvider from "@/providers/page-title"
import { H1 } from "docs-ui"
import { getBaseSpecs } from "../../lib"
import BaseSpecsProvider from "../../providers/base-specs"
import clsx from "clsx"

const StorePage = async () => {
const data = await getBaseSpecs("store")

const ReferencePage = async () => {
return (
<AreaProvider area={"store"}>
<PageTitleProvider>
<H1 className="!h2-docs scroll-m-56 lg:pl-4" id="introduction">
Medusa V2 Store API Reference
</H1>
<StoreContent />
<Tags />
</PageTitleProvider>
</AreaProvider>
<BaseSpecsProvider baseSpecs={data}>
<AreaProvider area={"store"}>
<PageTitleProvider>
<H1
className={clsx(
"!h2-docs lg:pl-4",
"scroll-m-[184px] lg:scroll-m-[264px]"
)}
id="introduction"
>
Medusa V2 Store API Reference
</H1>
<StoreContent />
<Tags tags={data?.tags} />
</PageTitleProvider>
</AreaProvider>
</BaseSpecsProvider>
)
}

export default ReferencePage
export default StorePage

export function generateMetadata() {
return {
Expand Down
12 changes: 9 additions & 3 deletions www/apps/api-reference/components/MDXComponents/H2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
import { useScrollController, useSidebar, H2 as UiH2 } from "docs-ui"
import { useEffect, useMemo, useRef, useState } from "react"
import getSectionId from "../../../utils/get-section-id"
import { SidebarItem } from "types"

type H2Props = React.HTMLAttributes<HTMLHeadingElement>

const H2 = ({ children, ...props }: H2Props) => {
const headingRef = useRef<HTMLHeadingElement>(null)
const { activePath, addItems } = useSidebar()
const { activePath, addItems, removeItems } = useSidebar()
const { scrollableElement, scrollToElement } = useScrollController()
const [scrolledFirstTime, setScrolledFirstTime] = useState(false)

Expand All @@ -28,14 +29,19 @@ const H2 = ({ children, ...props }: H2Props) => {
}, [scrollableElement, headingRef, id])

useEffect(() => {
addItems([
const item: SidebarItem[] = [
{
type: "link",
path: `${id}`,
title: children as string,
loaded: true,
},
])
]
addItems(item)

return () => {
removeItems(item)
}
}, [id])

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { TagOperationParametersProps } from "../.."
import type { TagsOperationParametersNestedProps } from "../../Nested"
import checkRequired from "@/utils/check-required"
import { Loading, type DetailsProps } from "docs-ui"
import { useMemo } from "react"
import { Fragment, useMemo } from "react"

const TagOperationParameters = dynamic<TagOperationParametersProps>(
async () => import("../.."),
Expand Down Expand Up @@ -101,20 +101,19 @@ const TagOperationParametersObject = ({
const content = (
<>
{sortedProperties.map((property, index) => (
<>
<Fragment key={index}>
{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)
}
/>
</>
</Fragment>
))}
</>
)
Expand Down
20 changes: 17 additions & 3 deletions www/apps/api-reference/components/Tags/Operation/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ import getSectionId from "@/utils/get-section-id"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import dynamic from "next/dynamic"
import { useInView } from "react-intersection-observer"
import { isElmWindow, useScrollController, useSidebar } from "docs-ui"
import {
isElmWindow,
useIsBrowser,
useScrollController,
useSidebar,
} from "docs-ui"
import type { TagOperationCodeSectionProps } from "./CodeSection"
import TagsOperationDescriptionSection from "./DescriptionSection"
import DividedLayout from "@/layouts/Divided"
Expand Down Expand Up @@ -44,9 +49,14 @@ const TagOperation = ({
const nodeRef = useRef<Element | null>(null)
const { loading, removeLoading } = useLoading()
const { scrollableElement, scrollToTop } = useScrollController()
const { isBrowser } = useIsBrowser()
const root = useMemo(() => {
if (!isBrowser) {
return
}

return isElmWindow(scrollableElement) ? document.body : scrollableElement
}, [scrollableElement])
}, [isBrowser, scrollableElement])
const { ref } = useInView({
threshold: 0.3,
rootMargin: `112px 0px 112px 0px`,
Expand Down Expand Up @@ -83,6 +93,10 @@ const TagOperation = ({
)

const scrollIntoView = useCallback(() => {
if (!isBrowser) {
return
}

if (nodeRef.current && !checkElementInViewport(nodeRef.current, 0)) {
const elm = nodeRef.current as HTMLElement
scrollToTop(
Expand All @@ -91,7 +105,7 @@ const TagOperation = ({
)
}
setShow(true)
}, [scrollToTop, nodeRef])
}, [scrollToTop, nodeRef, isBrowser])

useEffect(() => {
if (nodeRef && nodeRef.current) {
Expand Down
36 changes: 4 additions & 32 deletions www/apps/api-reference/components/Tags/Paths/index.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,29 @@
"use client"

import getSectionId from "@/utils/get-section-id"
import type { OpenAPIV3 } from "openapi-types"
import useSWR from "swr"
import type { Operation, PathsObject } from "@/types/openapi"
import { useSidebar, swrFetcher } from "docs-ui"
import { Fragment, useEffect, useMemo } from "react"
import { useSidebar } from "docs-ui"
import { Fragment, useEffect } from "react"
import dynamic from "next/dynamic"
import type { TagOperationProps } from "../Operation"
import { useArea } from "@/providers/area"
import clsx from "clsx"
import { useBaseSpecs } from "@/providers/base-specs"
import getTagChildSidebarItems from "@/utils/get-tag-child-sidebar-items"
import { useLoading } from "@/providers/loading"
import DividedLoading from "@/components/DividedLoading"
import { SidebarItemSections, SidebarItem, SidebarItemCategory } from "types"
import basePathUrl from "../../../utils/base-path-url"

const TagOperation = dynamic<TagOperationProps>(
async () => import("../Operation")
) as React.FC<TagOperationProps>

export type TagPathsProps = {
tag: OpenAPIV3.TagObject
paths: PathsObject
} & React.HTMLAttributes<HTMLDivElement>

const TagPaths = ({ tag, className }: TagPathsProps) => {
const tagSlugName = useMemo(() => getSectionId([tag.name]), [tag])
const { area } = useArea()
const TagPaths = ({ tag, className, paths }: TagPathsProps) => {
const { items, addItems, findItemInSection } = useSidebar()
const { baseSpecs } = useBaseSpecs()
const { loading } = useLoading()
// if paths are already loaded since through
// the expanded field, they're loaded directly
// otherwise, they're loaded using the API route
let paths: PathsObject =
baseSpecs?.expandedTags &&
Object.hasOwn(baseSpecs.expandedTags, tagSlugName)
? baseSpecs.expandedTags[tagSlugName]
: {}
const { data } = useSWR<{
paths: PathsObject
}>(
!Object.keys(paths).length
? basePathUrl(`/api/tag?tagName=${tagSlugName}&area=${area}`)
: null,
swrFetcher,
{
errorRetryInterval: 2000,
}
)

paths = data?.paths || paths

useEffect(() => {
if (paths) {
Expand Down
34 changes: 22 additions & 12 deletions www/apps/api-reference/components/Tags/Section/Schema/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useEffect, useMemo, useRef, useState } from "react"
"use client"

import { useEffect, useMemo, useRef } from "react"
import { SchemaObject } from "../../../../types/openapi"
import TagOperationParameters from "../../Operation/Parameters"
import {
Badge,
CodeBlock,
isElmWindow,
useIsBrowser,
useScrollController,
useSidebar,
} from "docs-ui"
Expand All @@ -16,7 +19,6 @@ 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 = {
Expand All @@ -26,7 +28,6 @@ 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(
Expand All @@ -43,14 +44,16 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
skipNonRequired: false,
},
})
useResizeObserver(paramsRef, () => {
setMaxCodeHeight(paramsRef.current?.clientHeight || 0)
})
const { isBrowser } = useIsBrowser()

const { scrollableElement, scrollToElement } = useScrollController()
const root = useMemo(() => {
if (!isBrowser) {
return
}

return isElmWindow(scrollableElement) ? document.body : scrollableElement
}, [scrollableElement])
}, [isBrowser, scrollableElement])

useEffect(() => {
addItems(
Expand All @@ -77,18 +80,26 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
}, [formattedName])

useEffect(() => {
if (!isBrowser) {
return
}

if (schemaSlug === (activePath || location.hash.replace("#", ""))) {
const elm = document.getElementById(schemaSlug) as HTMLElement
if (!checkElementInViewport(elm, 0)) {
scrollToElement(elm)
}
}
}, [activePath, schemaSlug])
}, [activePath, schemaSlug, isBrowser])

const handleViewChange = (
inView: boolean,
entry: IntersectionObserverEntry
) => {
if (!isBrowser) {
return
}

const section = entry.target

if (
Expand All @@ -106,7 +117,7 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
<InView
as="div"
id={schemaSlug}
initialInView={false}
initialInView={true}
onChange={handleViewChange}
root={root}
threshold={0.1}
Expand All @@ -128,10 +139,9 @@ const TagSectionSchema = ({ schema, tagName }: TagSectionSchemaProps) => {
source={examples[0].content}
lang="json"
title={`The ${formattedName} Object`}
className={clsx(maxCodeHeight && "overflow-auto")}
className={clsx("overflow-auto")}
style={{
// remove padding + extra space
maxHeight: maxCodeHeight ? maxCodeHeight - 212 : "unset",
maxHeight: "100vh",
}}
/>
)}
Expand Down
Loading

0 comments on commit e101728

Please sign in to comment.