Skip to content

Commit a357bfa

Browse files
authored
fix: potential duplicate ids warning (#48)
1 parent 2eea2e5 commit a357bfa

File tree

4 files changed

+41
-16
lines changed

4 files changed

+41
-16
lines changed

.changeset/calm-fishes-count.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@alauda/doom": patch
3+
---
4+
5+
fix: potential duplicate ids warning

src/runtime/components/OpenAPIPath.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import openapisMap from 'doom-@api-openapisMap'
44
import virtual from 'doom-@api-virtual'
55
import BananaSlug from 'github-slugger'
66
import { OpenAPIV3, type OpenAPIV3_1 } from 'openapi-types'
7-
import { Fragment, useMemo, useState, type ReactNode } from 'react'
7+
import { Fragment, useId, useMemo, useState, type ReactNode } from 'react'
88

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

@@ -177,6 +177,8 @@ export const OpenAPIPath = ({
177177

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

180+
const uid = useId()
181+
180182
const slugger = useMemo(() => new BananaSlug(), [])
181183

182184
const [pathItem, openapi, openapiPath, refs] = useMemo(() => {
@@ -204,14 +206,14 @@ export const OpenAPIPath = ({
204206

205207
return (
206208
<>
207-
<HeadingTitle slugger={slugger} level={2}>
209+
<HeadingTitle slugger={slugger} uid={uid} level={2}>
208210
{pathPrefix}
209211
{path}
210212
</HeadingTitle>
211213

212214
{pathItem.parameters && (
213215
<>
214-
<HeadingTitle slugger={slugger} level={3}>
216+
<HeadingTitle slugger={slugger} uid={uid} level={3}>
215217
Common Parameters
216218
</HeadingTitle>
217219
<OpenAPIParameters
@@ -245,22 +247,22 @@ export const OpenAPIPath = ({
245247

246248
return (
247249
<Fragment key={method}>
248-
<HeadingTitle slugger={slugger} level={3}>
250+
<HeadingTitle slugger={slugger} uid={uid} level={3}>
249251
<code>{method}</code>
250252
{summary}
251253
</HeadingTitle>
252254
<Markdown>{description}</Markdown>
253255
{parameters && (
254256
<>
255-
<HeadingTitle slugger={slugger} level={4}>
257+
<HeadingTitle slugger={slugger} uid={uid} level={4}>
256258
Parameters
257259
</HeadingTitle>
258260
<OpenAPIParameters parameters={parameters} openapi={openapi} />
259261
</>
260262
)}
261263
{requestBodySchema && (
262264
<>
263-
<HeadingTitle slugger={slugger} level={4}>
265+
<HeadingTitle slugger={slugger} uid={uid} level={4}>
264266
Request Body
265267
</HeadingTitle>
266268
<X.p>
@@ -272,7 +274,7 @@ export const OpenAPIPath = ({
272274
{/* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition */}
273275
{responses && (
274276
<>
275-
<HeadingTitle slugger={slugger} level={4}>
277+
<HeadingTitle slugger={slugger} uid={uid} level={4}>
276278
Response
277279
</HeadingTitle>
278280
<OpenAPIResponses responses={responses} openapi={openapi} />
@@ -288,6 +290,7 @@ export const OpenAPIPath = ({
288290
key={ref}
289291
schema={ref}
290292
openapiPath={openapiPath}
293+
uid={uid}
291294
collectRefs={false}
292295
/>
293296
)

src/runtime/components/OpenAPIRef.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { usePageData } from '@rspress/core/runtime'
22
import { getCustomMDXComponent } from '@rspress/core/theme'
33
import openapisMap from 'doom-@api-openapisMap'
44
import type { OpenAPIV3_1 } from 'openapi-types'
5-
import { type ReactNode, useMemo, useState } from 'react'
5+
import { type ReactNode, useId, useMemo, useState } from 'react'
66

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

@@ -19,6 +19,7 @@ export interface OpenAPIRefProps {
1919
* The specific path to the OpenAPI schema, otherwise the first matched will be used.
2020
*/
2121
openapiPath?: string
22+
uid?: string
2223
collectRefs?: boolean
2324
}
2425

@@ -150,10 +151,17 @@ const getRefsForSchema = (
150151
export const OpenAPIRef = ({
151152
schema,
152153
openapiPath: openapiPath_,
154+
uid,
153155
collectRefs = true,
154156
}: OpenAPIRefProps) => {
155157
const { page } = usePageData()
156158

159+
const innerUid = useId()
160+
161+
if (uid == null) {
162+
uid = innerUid
163+
}
164+
157165
const [schemaItem, openapi, openapiPath] = useMemo(() => {
158166
for (const [pathname, openapi] of Object.entries(openapisMap)) {
159167
if (openapiPath_ && pathname !== openapiPath_) {
@@ -184,7 +192,7 @@ export const OpenAPIRef = ({
184192

185193
return (
186194
<>
187-
<HeadingTitle slug={schema} level={2}>
195+
<HeadingTitle uid={uid} slug={schema} level={2}>
188196
{modelName(schema)}
189197
</HeadingTitle>
190198
<Markdown>{schemaItem.description}</Markdown>
@@ -199,6 +207,7 @@ export const OpenAPIRef = ({
199207
key={schema}
200208
schema={schema}
201209
openapiPath={openapiPath}
210+
uid={uid}
202211
collectRefs={false}
203212
/>
204213
))}

src/runtime/components/_HeadingTitle.tsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@ import { Children, type ReactNode, useMemo, useState } from 'react'
55
export interface HeadingTitleProps {
66
slug?: string
77
slugger?: BananaSlug
8+
uid?: string
89
level: 1 | 2 | 3 | 4 | 5 | 6
910
children: ReactNode
1011
}
1112

13+
// TODO: use context to simplify the usage of `slugger` and `uid`
1214
export const HeadingTitle = ({
1315
slug,
1416
slugger,
17+
uid,
1518
level,
1619
children,
1720
}: HeadingTitleProps) => {
@@ -22,13 +25,18 @@ export const HeadingTitle = ({
2225
const HeadingComponent = HeadingComponents[level]
2326
const id = useMemo(
2427
() =>
25-
slug ||
26-
slugger?.slug(
27-
Children.toArray(children)
28-
.filter((it) => typeof it === 'string')
29-
.join(''),
30-
),
31-
[slug, children],
28+
[
29+
uid,
30+
slug ||
31+
slugger?.slug(
32+
Children.toArray(children)
33+
.filter((it) => typeof it === 'string')
34+
.join(''),
35+
),
36+
]
37+
.filter(Boolean)
38+
.join('-') || undefined,
39+
[slug, uid, children],
3240
)
3341
return (
3442
<HeadingComponent id={id}>

0 commit comments

Comments
 (0)