Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/calm-fishes-count.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@alauda/doom": patch
---

fix: potential duplicate ids warning
17 changes: 10 additions & 7 deletions src/runtime/components/OpenAPIPath.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import openapisMap from 'doom-@api-openapisMap'
import virtual from 'doom-@api-virtual'
import BananaSlug from 'github-slugger'
import { OpenAPIV3, type OpenAPIV3_1 } from 'openapi-types'
import { Fragment, useMemo, type ReactNode } from 'react'
import { Fragment, useId, useMemo, type ReactNode } from 'react'

import { omitRoutePathRefs, resolveRef } from '../utils.js'

Expand Down Expand Up @@ -175,6 +175,8 @@ export const OpenAPIPath = ({

const pathPrefix = pathPrefix_ ?? (virtual.pathPrefix || '')

const uid = useId()

const slugger = useMemo(() => new BananaSlug(), [])

const [pathItem, openapi, openapiPath, refs] = useMemo(() => {
Expand Down Expand Up @@ -202,14 +204,14 @@ export const OpenAPIPath = ({

return (
<>
<HeadingTitle slugger={slugger} level={2}>
<HeadingTitle slugger={slugger} uid={uid} level={2}>
{pathPrefix}
{path}
</HeadingTitle>

{pathItem.parameters && (
<>
<HeadingTitle slugger={slugger} level={3}>
<HeadingTitle slugger={slugger} uid={uid} level={3}>
Common Parameters
</HeadingTitle>
<OpenAPIParameters
Expand Down Expand Up @@ -243,22 +245,22 @@ export const OpenAPIPath = ({

return (
<Fragment key={method}>
<HeadingTitle slugger={slugger} level={3}>
<HeadingTitle slugger={slugger} uid={uid} level={3}>
<code>{method}</code>
{summary}
</HeadingTitle>
<Markdown>{description}</Markdown>
{parameters && (
<>
<HeadingTitle slugger={slugger} level={4}>
<HeadingTitle slugger={slugger} uid={uid} level={4}>
Parameters
</HeadingTitle>
<OpenAPIParameters parameters={parameters} openapi={openapi} />
</>
)}
{requestBodySchema && (
<>
<HeadingTitle slugger={slugger} level={4}>
<HeadingTitle slugger={slugger} uid={uid} level={4}>
Request Body
</HeadingTitle>
<X.p>
Expand All @@ -270,7 +272,7 @@ export const OpenAPIPath = ({
{/* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition */}
{responses && (
<>
<HeadingTitle slugger={slugger} level={4}>
<HeadingTitle slugger={slugger} uid={uid} level={4}>
Response
</HeadingTitle>
<OpenAPIResponses responses={responses} openapi={openapi} />
Expand All @@ -286,6 +288,7 @@ export const OpenAPIPath = ({
key={ref}
schema={ref}
openapiPath={openapiPath}
uid={uid}
collectRefs={false}
/>
)
Expand Down
13 changes: 11 additions & 2 deletions src/runtime/components/OpenAPIRef.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { usePageData } from '@rspress/core/runtime'
import openapisMap from 'doom-@api-openapisMap'
import type { OpenAPIV3_1 } from 'openapi-types'
import { type ReactNode, useMemo } from 'react'
import { type ReactNode, useId, useMemo } from 'react'

import { modelName, omitRoutePathRefs, resolveRef } from '../utils.js'

Expand All @@ -19,6 +19,7 @@ export interface OpenAPIRefProps {
* The specific path to the OpenAPI schema, otherwise the first matched will be used.
*/
openapiPath?: string
uid?: string
collectRefs?: boolean
}

Expand Down Expand Up @@ -149,10 +150,17 @@ const getRefsForSchema = (
export const OpenAPIRef = ({
schema,
openapiPath: openapiPath_,
uid,
collectRefs = true,
}: OpenAPIRefProps) => {
const { page } = usePageData()

const innerUid = useId()

if (uid == null) {
uid = innerUid
}

const [schemaItem, openapi, openapiPath] = useMemo(() => {
for (const [pathname, openapi] of Object.entries(openapisMap)) {
if (openapiPath_ && pathname !== openapiPath_) {
Expand Down Expand Up @@ -183,7 +191,7 @@ export const OpenAPIRef = ({

return (
<>
<HeadingTitle slug={schema} level={2}>
<HeadingTitle uid={uid} slug={schema} level={2}>
{modelName(schema)}
</HeadingTitle>
<Markdown>{schemaItem.description}</Markdown>
Expand All @@ -198,6 +206,7 @@ export const OpenAPIRef = ({
key={schema}
schema={schema}
openapiPath={openapiPath}
uid={uid}
collectRefs={false}
/>
))}
Expand Down
22 changes: 15 additions & 7 deletions src/runtime/components/_HeadingTitle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@ import { X } from './_X.js'
export interface HeadingTitleProps {
slug?: string
slugger?: BananaSlug
uid?: string
level: 1 | 2 | 3 | 4 | 5 | 6
children: ReactNode
}

// TODO: use context to simplify the usage of `slugger` and `uid`
export const HeadingTitle = ({
slug,
slugger,
uid,
level,
children,
}: HeadingTitleProps) => {
Expand All @@ -22,13 +25,18 @@ export const HeadingTitle = ({
const HeadingComponent = HeadingComponents[level]
const id = useMemo(
() =>
slug ||
slugger?.slug(
Children.toArray(children)
.filter((it) => typeof it === 'string')
.join(''),
),
[slug, children],
[
uid,
slug ||
slugger?.slug(
Children.toArray(children)
.filter((it) => typeof it === 'string')
.join(''),
),
]
.filter(Boolean)
.join('-') || undefined,
[slug, uid, children],
)
return (
<HeadingComponent id={id}>
Expand Down
21 changes: 9 additions & 12 deletions src/runtime/components/_Markdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ import remarkGfm from 'remark-gfm'

import { X } from './_X.js'

export const Markdown = ({ children }: { children?: string }) => {
return (
children && (
<ReactMarkdown
remarkPlugins={[[remarkGfm]]}
components={X as Record<string, ElementType>}
skipHtml={true}
>
{children}
</ReactMarkdown>
)
export const Markdown = ({ children }: { children?: string }) =>
children && (
<ReactMarkdown
remarkPlugins={[[remarkGfm]]}
components={X as Record<string, ElementType>}
skipHtml={true}
>
{children}
</ReactMarkdown>
)
}