@yaakdoc/react 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,551 @@
1
+ import { C as useRequest, S as usePage, T as useThemeOptions, _ as useRunInYaak, a as SiteLinks, b as useDocument, c as Html, d as MethodBadge, f as RequestUrl, g as usePageActions, h as useComponents, i as RunInYaak, l as KeyValueTable, m as overridable, n as Footer, o as brandingCss, p as ComponentsProvider, r as Logo, s as AuthInfo, t as BrandingStyles, u as Markdown, v as toAbsoluteUrl, w as useSite, x as useFolder, y as YaakdocProvider } from "./site-DyK7ZcqQ.js";
2
+ import { m as createIsland, o as EnvironmentSwitcher } from "./run-in-yaak-CMMcDS7S.js";
3
+ import { a as CopyButton, c as TabList, d as tabPanelProps, l as tabElementIds, n as OpenInLink, p as visibleTabPanelSelector, t as LLM_PROVIDERS, u as tabGroupIds } from "./llm-Ddn5hWnS.js";
4
+ import { findFolderNode, formFieldValue, grpcMethodPath, methodLabel } from "@yaakdoc/core";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/primitives/environment.tsx
7
+ /**
8
+ * Renders environment-dependent content once per environment variant. With several variants, each
9
+ * is wrapped in `<div data-yd-env="<id>">` (only the default is visible until the reader switches).
10
+ */
11
+ function EnvironmentVariants({ variants, children }) {
12
+ if (variants.length <= 1) return /* @__PURE__ */ jsx(Fragment, { children: variants[0] ? children(variants[0], 0) : null });
13
+ return /* @__PURE__ */ jsx(Fragment, { children: variants.map((variant, index) => /* @__PURE__ */ jsx("div", {
14
+ "data-yd-env": variant.environmentId ?? "",
15
+ hidden: index !== 0,
16
+ children: children(variant, index)
17
+ }, variant.environmentId ?? "none")) });
18
+ }
19
+ /** Environment switcher for the current document (renders nothing without alternatives). */
20
+ const EnvironmentSelect = overridable("EnvironmentSelect", function EnvironmentSelect({ className }) {
21
+ const document = useDocument();
22
+ if (document.environments.length < 2) return null;
23
+ return /* @__PURE__ */ jsx(EnvironmentSwitcher, {
24
+ environments: document.environments,
25
+ defaultId: document.environments[0].id,
26
+ ...className ? { className } : {}
27
+ });
28
+ });
29
+ //#endregion
30
+ //#region src/primitives/code.tsx
31
+ const CodeBlock = overridable("CodeBlock", function CodeBlock({ html, id, language, title, copy = true, className }) {
32
+ return /* @__PURE__ */ jsxs("figure", {
33
+ "data-yd": "code-block",
34
+ "data-language": language,
35
+ className,
36
+ children: [title || copy ? /* @__PURE__ */ jsxs("figcaption", {
37
+ "data-yd": "code-block-header",
38
+ children: [title ? /* @__PURE__ */ jsx("span", {
39
+ "data-yd": "code-block-title",
40
+ children: title
41
+ }) : null, copy ? /* @__PURE__ */ jsx(CopyButton, {
42
+ target: `#${id} pre`,
43
+ label: "Copy"
44
+ }) : null]
45
+ }) : null, /* @__PURE__ */ jsx(Html, {
46
+ html,
47
+ id,
48
+ "data-yd": "code"
49
+ })]
50
+ });
51
+ });
52
+ /** Tabbed code examples. Panels are static HTML; only the tab list hydrates. */
53
+ const CodeExamples = overridable("CodeExamples", function CodeExamples({ request, className, title = "Example request" }) {
54
+ const examples = request.examples;
55
+ if (examples.length === 0) return null;
56
+ const group = tabGroupIds.examples(request.anchor);
57
+ return /* @__PURE__ */ jsxs("section", {
58
+ "data-yd": "code-examples",
59
+ "data-yd-tab-group": group,
60
+ className,
61
+ "aria-label": title,
62
+ children: [/* @__PURE__ */ jsxs("div", {
63
+ "data-yd": "code-examples-header",
64
+ children: [/* @__PURE__ */ jsx(TabList, {
65
+ group,
66
+ tabs: examples.map((example) => ({
67
+ id: example.id,
68
+ label: example.label
69
+ }))
70
+ }), /* @__PURE__ */ jsx(CopyButton, {
71
+ target: visibleTabPanelSelector(group),
72
+ label: "Copy"
73
+ })]
74
+ }), /* @__PURE__ */ jsx(EnvironmentVariants, {
75
+ variants: request.variants,
76
+ children: (variant, variantIndex) => variant.examples.map((example, index) => /* @__PURE__ */ jsx("div", {
77
+ ...tabPanelProps(group, example.id, {
78
+ selected: index === 0,
79
+ variant: variantIndex
80
+ }),
81
+ "data-language": example.language,
82
+ children: /* @__PURE__ */ jsx(Html, {
83
+ html: example.html,
84
+ "data-yd": "code"
85
+ })
86
+ }, example.id))
87
+ })]
88
+ });
89
+ });
90
+ /**
91
+ * Example responses (from ```response / ```response:<status> blocks in the description), tabbed by
92
+ * status. Tabs carry `data-status-class` (`2xx`, `4xx`, ...) for styling.
93
+ */
94
+ const ResponseExamples = overridable("ResponseExamples", function ResponseExamples({ request, className, title = "Example response" }) {
95
+ if (request.responses.length === 0) return null;
96
+ const group = tabGroupIds.responses(request.anchor);
97
+ return /* @__PURE__ */ jsxs("section", {
98
+ "data-yd": "response-examples",
99
+ "data-yd-tab-group": group,
100
+ className,
101
+ "aria-label": title,
102
+ children: [/* @__PURE__ */ jsxs("div", {
103
+ "data-yd": "response-examples-header",
104
+ children: [/* @__PURE__ */ jsx(TabList, {
105
+ group,
106
+ sync: false,
107
+ label: title,
108
+ tabs: request.responses.map((response, index) => ({
109
+ id: String(index),
110
+ label: response.label
111
+ }))
112
+ }), /* @__PURE__ */ jsx(CopyButton, {
113
+ target: visibleTabPanelSelector(group),
114
+ label: "Copy"
115
+ })]
116
+ }), request.responses.map((response, index) => /* @__PURE__ */ jsx("div", {
117
+ ...tabPanelProps(group, String(index), { selected: index === 0 }),
118
+ "data-status": response.status ?? void 0,
119
+ "data-status-class": statusClass(response.status),
120
+ children: response.empty ? /* @__PURE__ */ jsx("p", {
121
+ "data-yd": "empty-response",
122
+ children: "No response body"
123
+ }) : /* @__PURE__ */ jsx(Html, {
124
+ html: response.html,
125
+ "data-yd": "code"
126
+ })
127
+ }, String(index)))]
128
+ });
129
+ });
130
+ /** `2xx`, `4xx`, ... or `undefined` for responses without a status. */
131
+ const statusClass = (status) => status ? `${String(status)[0]}xx` : void 0;
132
+ //#endregion
133
+ //#region src/primitives/heading.tsx
134
+ /** Clamps any number to a valid heading level (1–6). */
135
+ const clampHeadingLevel = (level) => Math.min(Math.max(level, 1), 6);
136
+ /** `<h1>`–`<h6>` chosen by `level` (clamped), for headings whose depth depends on nesting. */
137
+ function Heading({ level, ...props }) {
138
+ const Tag = `h${clampHeadingLevel(level)}`;
139
+ return /* @__PURE__ */ jsx(Tag, { ...props });
140
+ }
141
+ //#endregion
142
+ //#region src/primitives/llm.tsx
143
+ /**
144
+ * "Copy page" actions: copy as Markdown, view as Markdown, open in ChatGPT/Claude. Uses a native
145
+ * `<details>` menu, so it works without JavaScript (except copying).
146
+ */
147
+ /** Label of a copy action for an item at heading `level`: the page itself (1) or a section. */
148
+ const copyActionLabel = (level) => level <= 1 ? "Copy page" : "Copy section";
149
+ const PageActions = overridable("PageActions", function PageActions({ markdownUrl, label = "Copy page", className }) {
150
+ const actions = usePageActions(markdownUrl);
151
+ if (!actions) return null;
152
+ const absolute = actions.absoluteUrl ?? actions.markdownUrl;
153
+ return /* @__PURE__ */ jsxs("div", {
154
+ "data-yd": "page-actions",
155
+ className,
156
+ children: [/* @__PURE__ */ jsx(CopyButton, {
157
+ url: actions.markdownUrl,
158
+ label,
159
+ copiedLabel: "Copied!"
160
+ }), /* @__PURE__ */ jsxs("details", {
161
+ "data-yd": "page-actions-menu",
162
+ children: [/* @__PURE__ */ jsx("summary", {
163
+ "aria-label": "More page actions",
164
+ children: "⋯"
165
+ }), /* @__PURE__ */ jsxs("ul", { children: [/* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", {
166
+ href: actions.markdownUrl,
167
+ target: "_blank",
168
+ rel: "noopener",
169
+ "data-yd": "view-markdown",
170
+ children: "View as Markdown"
171
+ }) }), actions.openIn.map((provider) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx(OpenInLink, {
172
+ provider,
173
+ markdownUrl: absolute,
174
+ label: `Open in ${LLM_PROVIDERS[provider].label}`
175
+ }) }, provider))] })]
176
+ })]
177
+ });
178
+ });
179
+ //#endregion
180
+ //#region src/primitives/request.tsx
181
+ const RequestBody = overridable("RequestBody", function RequestBody({ request, className }) {
182
+ if (request.kind !== "http") {
183
+ if (!request.bodyHtml) return null;
184
+ return /* @__PURE__ */ jsx(Html, {
185
+ html: request.bodyHtml,
186
+ "data-yd": "body",
187
+ "data-kind": "message",
188
+ className
189
+ });
190
+ }
191
+ const { body } = request;
192
+ switch (body.type) {
193
+ case "none": return null;
194
+ case "form-urlencoded":
195
+ case "multipart": return /* @__PURE__ */ jsx("div", {
196
+ "data-yd": "body",
197
+ "data-kind": body.type,
198
+ className,
199
+ children: /* @__PURE__ */ jsx(KeyValueTable, {
200
+ items: body.fields.map((field) => ({
201
+ ...field,
202
+ value: formFieldValue(field)
203
+ })),
204
+ columns: ["Field", "Value"]
205
+ })
206
+ });
207
+ case "binary": return /* @__PURE__ */ jsxs("p", {
208
+ "data-yd": "body",
209
+ "data-kind": "binary",
210
+ className,
211
+ children: ["Binary file", body.filePath ? /* @__PURE__ */ jsxs(Fragment, { children: [
212
+ " ",
213
+ "(",
214
+ /* @__PURE__ */ jsx("code", { children: body.filePath }),
215
+ ")"
216
+ ] }) : null]
217
+ });
218
+ default: return request.bodyHtml ? /* @__PURE__ */ jsxs("div", {
219
+ "data-yd": "body",
220
+ "data-kind": body.type,
221
+ className,
222
+ children: [
223
+ request.variablesHtml ? /* @__PURE__ */ jsx("span", {
224
+ "data-yd": "body-label",
225
+ children: "Query"
226
+ }) : null,
227
+ /* @__PURE__ */ jsx(Html, { html: request.bodyHtml }),
228
+ request.variablesHtml ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("span", {
229
+ "data-yd": "body-label",
230
+ children: "Variables"
231
+ }), /* @__PURE__ */ jsx(Html, {
232
+ html: request.variablesHtml ?? "",
233
+ "data-yd": "body-variables"
234
+ })] }) : null
235
+ ]
236
+ }) : null;
237
+ }
238
+ });
239
+ const bodyContentType = (request) => request.kind === "http" && request.body.type !== "none" ? request.body.contentType : null;
240
+ /**
241
+ * Complete documentation section for a request: title, method, URL, description, auth, parameters,
242
+ * headers, body and code examples. Each sub-part is overridable on its own.
243
+ */
244
+ const RequestDoc = overridable("RequestDoc", function RequestDoc({ request, level = 2, className, examples = true }) {
245
+ const sub = clampHeadingLevel(level + 1);
246
+ const headers = request.kind === "grpc" ? request.metadata : request.headers;
247
+ const contentType = bodyContentType(request);
248
+ return /* @__PURE__ */ jsxs("section", {
249
+ id: request.anchor,
250
+ "data-yd": "request",
251
+ "data-yd-section": true,
252
+ "data-kind": request.kind,
253
+ className,
254
+ children: [
255
+ /* @__PURE__ */ jsxs("header", {
256
+ "data-yd": "request-header",
257
+ children: [/* @__PURE__ */ jsx(Heading, {
258
+ level,
259
+ children: /* @__PURE__ */ jsx("a", {
260
+ href: `#${request.anchor}`,
261
+ "data-yd": "anchor",
262
+ children: request.name
263
+ })
264
+ }), /* @__PURE__ */ jsx(PageActions, {
265
+ markdownUrl: request.markdownUrl,
266
+ label: copyActionLabel(level)
267
+ })]
268
+ }),
269
+ /* @__PURE__ */ jsxs("div", {
270
+ "data-yd": "request-line",
271
+ children: [/* @__PURE__ */ jsx(MethodBadge, { request }), /* @__PURE__ */ jsx(EnvironmentVariants, {
272
+ variants: request.variants,
273
+ children: (variant) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(RequestUrl, { url: variant.url }), /* @__PURE__ */ jsx(CopyButton, {
274
+ text: variant.resolvedUrl,
275
+ label: "Copy URL"
276
+ })] })
277
+ })]
278
+ }),
279
+ request.kind === "grpc" && (request.service || request.method) ? /* @__PURE__ */ jsx("p", {
280
+ "data-yd": "grpc-method",
281
+ children: /* @__PURE__ */ jsx("code", { children: grpcMethodPath(request) })
282
+ }) : null,
283
+ /* @__PURE__ */ jsx(Markdown, { html: request.descriptionHtml }),
284
+ /* @__PURE__ */ jsx(Heading, {
285
+ level: sub,
286
+ children: "Authentication"
287
+ }),
288
+ /* @__PURE__ */ jsx(AuthInfo, { auth: request.auth }),
289
+ request.kind !== "grpc" && request.pathParameters.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Heading, {
290
+ level: sub,
291
+ children: "Path parameters"
292
+ }), /* @__PURE__ */ jsx(KeyValueTable, { items: request.pathParameters })] }) : null,
293
+ request.kind !== "grpc" && request.queryParameters.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Heading, {
294
+ level: sub,
295
+ children: "Query parameters"
296
+ }), /* @__PURE__ */ jsx(KeyValueTable, { items: request.queryParameters })] }) : null,
297
+ headers.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Heading, {
298
+ level: sub,
299
+ children: request.kind === "grpc" ? "Metadata" : "Headers"
300
+ }), /* @__PURE__ */ jsx(KeyValueTable, { items: headers })] }) : null,
301
+ request.bodyHtml || request.kind === "http" && request.body.type !== "none" ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(Heading, {
302
+ level: sub,
303
+ children: [request.kind === "http" ? "Body" : "Message", contentType ? /* @__PURE__ */ jsxs(Fragment, { children: [" ", /* @__PURE__ */ jsx("code", {
304
+ "data-yd": "content-type",
305
+ children: contentType
306
+ })] }) : null]
307
+ }), /* @__PURE__ */ jsx(RequestBody, { request })] }) : null,
308
+ examples ? /* @__PURE__ */ jsx(CodeExamples, { request }) : null,
309
+ examples ? /* @__PURE__ */ jsx(ResponseExamples, { request }) : null
310
+ ]
311
+ });
312
+ });
313
+ //#endregion
314
+ //#region src/primitives/content.tsx
315
+ /** A folder section: title, description, inherited auth, then (optionally) its contents. */
316
+ const FolderDoc = overridable("FolderDoc", function FolderDoc({ id, level = 2, nested = true, className }) {
317
+ const document = useDocument();
318
+ const folder = document.folders[id];
319
+ if (!folder) return null;
320
+ const node = findFolderNode(document.tree, id);
321
+ return /* @__PURE__ */ jsxs("section", {
322
+ id: folder.anchor,
323
+ "data-yd": "folder",
324
+ "data-yd-section": true,
325
+ className,
326
+ children: [
327
+ /* @__PURE__ */ jsxs("header", {
328
+ "data-yd": "folder-header",
329
+ children: [/* @__PURE__ */ jsx(Heading, {
330
+ level,
331
+ children: /* @__PURE__ */ jsx("a", {
332
+ href: `#${folder.anchor}`,
333
+ "data-yd": "anchor",
334
+ children: folder.name
335
+ })
336
+ }), /* @__PURE__ */ jsx(PageActions, {
337
+ markdownUrl: folder.markdownUrl,
338
+ label: copyActionLabel(level)
339
+ })]
340
+ }),
341
+ /* @__PURE__ */ jsx(Markdown, { html: folder.descriptionHtml }),
342
+ nested && node ? /* @__PURE__ */ jsx(TreeContent, {
343
+ nodes: node.children,
344
+ level: level + 1
345
+ }) : null
346
+ ]
347
+ });
348
+ });
349
+ /** Renders a list of tree nodes as documentation sections, recursively. */
350
+ const TreeContent = overridable("TreeContent", function TreeContent({ nodes, level = 2 }) {
351
+ const document = useDocument();
352
+ return /* @__PURE__ */ jsx(Fragment, { children: nodes.map((node) => node.type === "folder" ? /* @__PURE__ */ jsx(FolderDoc, {
353
+ id: node.id,
354
+ level
355
+ }, node.id) : document.requests[node.id] ? /* @__PURE__ */ jsx(RequestDoc, {
356
+ request: document.requests[node.id],
357
+ level: clampHeadingLevel(level)
358
+ }, node.id) : null) });
359
+ });
360
+ /** Overview of the workspace: description, authentication and variables. */
361
+ const Overview = overridable("Overview", function Overview({ className, level = 1 }) {
362
+ const document = useDocument();
363
+ const site = useSite();
364
+ const page = usePage();
365
+ return /* @__PURE__ */ jsxs("section", {
366
+ id: "overview",
367
+ "data-yd": "overview",
368
+ className,
369
+ children: [
370
+ /* @__PURE__ */ jsxs("header", {
371
+ "data-yd": "overview-header",
372
+ children: [
373
+ /* @__PURE__ */ jsx(Heading, {
374
+ level,
375
+ children: site.title
376
+ }),
377
+ /* @__PURE__ */ jsx(RunInYaak, {}),
378
+ /* @__PURE__ */ jsx(PageActions, { markdownUrl: page.kind === "index" ? page.markdownUrl : null })
379
+ ]
380
+ }),
381
+ /* @__PURE__ */ jsx(Markdown, { html: document.workspace.descriptionHtml }),
382
+ document.workspace.auth ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Heading, {
383
+ level: level + 1,
384
+ id: "authentication-overview",
385
+ children: "Authentication"
386
+ }), /* @__PURE__ */ jsx(AuthInfo, { auth: document.workspace.auth })] }) : null,
387
+ /* @__PURE__ */ jsx(Variables, { level: level + 1 })
388
+ ]
389
+ });
390
+ });
391
+ /** Environment variables table (secrets redacted). */
392
+ const Variables = overridable("Variables", function Variables({ level = 2, className }) {
393
+ const document = useDocument();
394
+ if (!useSite().showVariables || document.variables.length === 0) return null;
395
+ return /* @__PURE__ */ jsxs("div", {
396
+ "data-yd": "variables",
397
+ className,
398
+ children: [/* @__PURE__ */ jsxs(Heading, {
399
+ level,
400
+ id: "variables",
401
+ children: ["Variables", document.environments.length > 1 ? /* @__PURE__ */ jsxs(Fragment, { children: [" ", /* @__PURE__ */ jsx(EnvironmentSelect, {})] }) : document.environment ? /* @__PURE__ */ jsxs(Fragment, { children: [" ", /* @__PURE__ */ jsx("span", {
402
+ "data-yd": "environment",
403
+ style: document.environment.color ? { color: document.environment.color } : void 0,
404
+ children: document.environment.name
405
+ })] }) : null]
406
+ }), /* @__PURE__ */ jsx(EnvironmentVariants, {
407
+ variants: document.variableSets,
408
+ children: (set) => /* @__PURE__ */ jsx(KeyValueTable, { items: set.variables })
409
+ })]
410
+ });
411
+ });
412
+ /**
413
+ * The main content for the current page: everything (single-page mode), a folder, a request, or a
414
+ * not-found message. Themes can use this or compose the pieces themselves.
415
+ */
416
+ const Content = overridable("Content", function Content({ className }) {
417
+ const document = useDocument();
418
+ const site = useSite();
419
+ const page = usePage();
420
+ let content;
421
+ if (page.kind === "request" && page.id && document.requests[page.id]) content = /* @__PURE__ */ jsx(RequestDoc, {
422
+ request: document.requests[page.id],
423
+ level: 1
424
+ });
425
+ else if (page.kind === "folder" && page.id) {
426
+ content = /* @__PURE__ */ jsx(FolderDoc, {
427
+ id: page.id,
428
+ level: 1,
429
+ nested: false
430
+ });
431
+ const node = findFolderNode(document.tree, page.id);
432
+ content = /* @__PURE__ */ jsxs(Fragment, { children: [content, node ? /* @__PURE__ */ jsx(ChildLinks, { nodes: node.children }) : null] });
433
+ } else if (page.kind === "not-found") content = /* @__PURE__ */ jsx(NotFound, {});
434
+ else content = /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Overview, {}), site.pages === "single" ? /* @__PURE__ */ jsx(TreeContent, {
435
+ nodes: document.tree,
436
+ level: 2
437
+ }) : /* @__PURE__ */ jsx(ChildLinks, { nodes: document.tree })] });
438
+ return /* @__PURE__ */ jsx("main", {
439
+ id: "content",
440
+ "data-yd": "content",
441
+ "data-page": page.kind,
442
+ className,
443
+ children: content
444
+ });
445
+ });
446
+ /** Content of the 404 page. */
447
+ const NotFound = overridable("NotFound", function NotFound({ className }) {
448
+ const site = useSite();
449
+ return /* @__PURE__ */ jsxs("section", {
450
+ "data-yd": "not-found",
451
+ className,
452
+ children: [/* @__PURE__ */ jsx("h1", { children: "Page not found" }), /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("a", {
453
+ href: site.base,
454
+ children: "Back to the documentation"
455
+ }) })]
456
+ });
457
+ });
458
+ /** List of links to child folders/requests (per-request pages mode). */
459
+ const ChildLinks = overridable("ChildLinks", function ChildLinks({ nodes, className }) {
460
+ const document = useDocument();
461
+ return /* @__PURE__ */ jsx("ul", {
462
+ "data-yd": "child-links",
463
+ className,
464
+ children: nodes.map((node) => {
465
+ const item = node.type === "folder" ? document.folders[node.id] : document.requests[node.id];
466
+ if (!item) return null;
467
+ return /* @__PURE__ */ jsxs("li", {
468
+ "data-type": node.type,
469
+ children: [/* @__PURE__ */ jsx("a", {
470
+ href: item.href,
471
+ children: item.name
472
+ }), item.summary ? /* @__PURE__ */ jsx("p", { children: item.summary }) : null]
473
+ }, node.id);
474
+ })
475
+ });
476
+ });
477
+ //#endregion
478
+ //#region src/primitives/nav.tsx
479
+ /**
480
+ * Navigation tree. Folders use native `<details>` (collapsible without JavaScript). Items carry
481
+ * `data-yd-nav-item` / `data-yd-nav-folder` for the `NavFilter` island, and the current page link
482
+ * gets `aria-current="page"`.
483
+ */
484
+ const NavTree = overridable("NavTree", function NavTree({ nodes, className, openDepth = 1 }) {
485
+ const document = useDocument();
486
+ const page = usePage();
487
+ const activeAncestors = new Set(page.id ? (document.requests[page.id]?.breadcrumbs ?? document.folders[page.id]?.breadcrumbs ?? []).map((b) => b.id) : []);
488
+ if (page.id) activeAncestors.add(page.id);
489
+ const renderNodes = (items, depth) => /* @__PURE__ */ jsx("ul", {
490
+ "data-yd": "nav-list",
491
+ "data-depth": depth,
492
+ children: items.map((node) => {
493
+ if (node.type === "request") {
494
+ const request = document.requests[node.id];
495
+ if (!request) return null;
496
+ return /* @__PURE__ */ jsx("li", {
497
+ "data-yd-nav-item": true,
498
+ "data-yd-nav-label": request.name,
499
+ children: /* @__PURE__ */ jsxs("a", {
500
+ href: request.href,
501
+ "data-yd": "nav-link",
502
+ "aria-current": page.id === node.id ? "page" : void 0,
503
+ children: [/* @__PURE__ */ jsx(MethodBadge, { request }), /* @__PURE__ */ jsx("span", {
504
+ "data-yd": "nav-label",
505
+ children: request.name
506
+ })]
507
+ })
508
+ }, node.id);
509
+ }
510
+ const folder = document.folders[node.id];
511
+ if (!folder) return null;
512
+ return /* @__PURE__ */ jsx("li", {
513
+ "data-yd-nav-folder": true,
514
+ "data-yd-nav-label": folder.name,
515
+ children: /* @__PURE__ */ jsxs("details", {
516
+ open: depth < openDepth || activeAncestors.has(node.id) || void 0,
517
+ children: [/* @__PURE__ */ jsx("summary", {
518
+ "data-yd": "nav-folder",
519
+ children: /* @__PURE__ */ jsx("span", {
520
+ "data-yd": "nav-label",
521
+ children: folder.name
522
+ })
523
+ }), renderNodes(node.children, depth + 1)]
524
+ })
525
+ }, node.id);
526
+ })
527
+ });
528
+ return /* @__PURE__ */ jsx("nav", {
529
+ "data-yd": "nav",
530
+ "aria-label": "API reference",
531
+ className,
532
+ children: renderNodes(nodes ?? document.tree, 0)
533
+ });
534
+ });
535
+ /** Breadcrumb trail of the current request/folder. */
536
+ const Breadcrumbs = overridable("Breadcrumbs", function Breadcrumbs({ id, className }) {
537
+ const document = useDocument();
538
+ const item = document.requests[id] ?? document.folders[id];
539
+ if (!item || item.breadcrumbs.length === 0) return null;
540
+ return /* @__PURE__ */ jsx("nav", {
541
+ "aria-label": "Breadcrumb",
542
+ "data-yd": "breadcrumbs",
543
+ className,
544
+ children: /* @__PURE__ */ jsx("ol", { children: item.breadcrumbs.map((crumb) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", {
545
+ href: document.folders[crumb.id]?.href,
546
+ children: crumb.name
547
+ }) }, crumb.id)) })
548
+ });
549
+ });
550
+ //#endregion
551
+ export { AuthInfo, BrandingStyles, Breadcrumbs, ChildLinks, CodeBlock, CodeExamples, ComponentsProvider, Content, EnvironmentSelect, EnvironmentVariants, FolderDoc, Footer, Heading, Html, KeyValueTable, Logo, Markdown, MethodBadge, NavTree, NotFound, Overview, PageActions, RequestBody, RequestDoc, RequestUrl, ResponseExamples, RunInYaak, SiteLinks, TabList, TreeContent, Variables, YaakdocProvider, brandingCss, clampHeadingLevel, copyActionLabel, createIsland, methodLabel, overridable, statusClass, tabElementIds, tabGroupIds, tabPanelProps, toAbsoluteUrl, useComponents, useDocument, useFolder, usePage, usePageActions, useRequest, useRunInYaak, useSite, useThemeOptions, visibleTabPanelSelector };
@@ -0,0 +1,29 @@
1
+ import { ComponentType } from "react";
2
+ //#region src/island.d.ts
3
+ type IslandComponent<P extends object> = ComponentType<P> & {
4
+ /** Unique island name, used to find the component when hydrating. */
5
+ islandName: string;
6
+ /** The underlying component (rendered inside the island element). */
7
+ Component: ComponentType<P>;
8
+ };
9
+ declare module "react" {
10
+ namespace JSX {
11
+ interface IntrinsicElements {
12
+ "yd-island": React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
13
+ "data-island"?: string;
14
+ "data-props"?: string;
15
+ "data-prefix"?: string;
16
+ };
17
+ }
18
+ }
19
+ }
20
+ /**
21
+ * Turns a component into an island: it is rendered to HTML on the server like any other component,
22
+ * and hydrated on the client (only this component, not the whole page).
23
+ *
24
+ * Islands are hydrated in isolation: their props must be JSON-serializable and they cannot use
25
+ * yaakdoc context hooks. Register islands on the client with `hydrateIslands()`.
26
+ */
27
+ declare function createIsland<P extends object>(name: string, Component: ComponentType<P>): IslandComponent<P>;
28
+ //#endregion
29
+ export { createIsland as n, IslandComponent as t };