@djangocfg/ui-tools 2.1.287 → 2.1.289

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.
@@ -5,6 +5,7 @@ var chunk33AMWFBZ_cjs = require('./chunk-33AMWFBZ.cjs');
5
5
  require('./chunk-2SMCH62O.cjs');
6
6
  var chunkWGEGR3DF_cjs = require('./chunk-WGEGR3DF.cjs');
7
7
  var React6 = require('react');
8
+ var lodashEs = require('lodash-es');
8
9
  var components = require('@djangocfg/ui-core/components');
9
10
  var hooks = require('@djangocfg/ui-core/hooks');
10
11
  var consola = require('consola');
@@ -58,7 +59,7 @@ function exampleFromSchema(schema, depth = 0) {
58
59
  }
59
60
  chunkWGEGR3DF_cjs.__name(exampleFromSchema, "exampleFromSchema");
60
61
  var HTTP_METHODS = ["get", "post", "put", "patch", "delete"];
61
- var extractEndpoints = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((schema, baseUrl) => {
62
+ var extractEndpoints = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((schema, baseUrl, schemaId) => {
62
63
  const endpoints = [];
63
64
  if (!schema.paths) return [];
64
65
  for (const [path, methods] of Object.entries(schema.paths)) {
@@ -109,7 +110,8 @@ var extractEndpoints = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((schema, baseUrl
109
110
  category,
110
111
  parameters: parameters.length > 0 ? parameters : void 0,
111
112
  requestBody,
112
- responses: responses.length > 0 ? responses : void 0
113
+ responses: responses.length > 0 ? responses : void 0,
114
+ schemaId
113
115
  };
114
116
  endpoints.push(endpoint);
115
117
  }
@@ -135,7 +137,8 @@ var fetchSchema = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(async (url) => {
135
137
  function useOpenApiSchema({
136
138
  schemas,
137
139
  defaultSchemaId,
138
- baseUrl: configBaseUrl
140
+ baseUrl: configBaseUrl,
141
+ preloadAll = false
139
142
  }) {
140
143
  const [loading, setLoading] = React6.useState(true);
141
144
  const [error, setError] = React6.useState(null);
@@ -145,6 +148,7 @@ function useOpenApiSchema({
145
148
  const [loadedSchemas, setLoadedSchemas] = React6.useState(
146
149
  /* @__PURE__ */ new Map()
147
150
  );
151
+ const [loadStates, setLoadStates] = React6.useState(/* @__PURE__ */ new Map());
148
152
  const currentSchema = React6.useMemo(
149
153
  () => schemas.find((s) => s.id === currentSchemaId) || null,
150
154
  [schemas, currentSchemaId]
@@ -166,8 +170,8 @@ function useOpenApiSchema({
166
170
  [currentSchema?.baseUrl, configBaseUrl, currentOpenApiSchema]
167
171
  );
168
172
  const endpoints = React6.useMemo(
169
- () => dereferencedSchema ? extractEndpoints(dereferencedSchema, resolvedBaseUrl) : [],
170
- [dereferencedSchema, resolvedBaseUrl]
173
+ () => dereferencedSchema ? extractEndpoints(dereferencedSchema, resolvedBaseUrl, currentSchemaId) : [],
174
+ [dereferencedSchema, resolvedBaseUrl, currentSchemaId]
171
175
  );
172
176
  const categories = React6.useMemo(() => getCategories(endpoints), [endpoints]);
173
177
  const schemaInfo = React6.useMemo(() => {
@@ -181,6 +185,7 @@ function useOpenApiSchema({
181
185
  };
182
186
  }, [currentOpenApiSchema]);
183
187
  React6.useEffect(() => {
188
+ if (preloadAll) return;
184
189
  if (!currentSchema) return;
185
190
  if (loadedSchemas.has(currentSchema.id)) {
186
191
  setLoading(false);
@@ -197,7 +202,90 @@ function useOpenApiSchema({
197
202
  setError(err instanceof Error ? err.message : "Failed to load schema");
198
203
  setLoading(false);
199
204
  });
200
- }, [currentSchema, loadedSchemas]);
205
+ }, [currentSchema, loadedSchemas, preloadAll]);
206
+ React6.useEffect(() => {
207
+ if (!preloadAll) return;
208
+ if (schemas.length === 0) {
209
+ setLoading(false);
210
+ return;
211
+ }
212
+ let cancelled = false;
213
+ const pending = schemas.filter((s) => !loadedSchemas.has(s.id));
214
+ if (pending.length === 0) {
215
+ setLoading(false);
216
+ return;
217
+ }
218
+ setLoading(true);
219
+ setLoadStates((prev) => {
220
+ const next = new Map(prev);
221
+ for (const s of pending) next.set(s.id, { loading: true, error: null });
222
+ return next;
223
+ });
224
+ Promise.allSettled(
225
+ pending.map(
226
+ (s) => fetchSchema(s.url).then((schema) => ({ id: s.id, name: s.name, schema }))
227
+ )
228
+ ).then((results) => {
229
+ if (cancelled) return;
230
+ setLoadedSchemas((prev) => {
231
+ const next = new Map(prev);
232
+ for (const r of results) {
233
+ if (r.status === "fulfilled") {
234
+ next.set(r.value.id, r.value.schema);
235
+ consola__default.default.success(`Schema loaded: ${r.value.name}`);
236
+ }
237
+ }
238
+ return next;
239
+ });
240
+ setLoadStates((prev) => {
241
+ const next = new Map(prev);
242
+ results.forEach((r, i) => {
243
+ const src = pending[i];
244
+ if (r.status === "fulfilled") {
245
+ next.set(src.id, { loading: false, error: null });
246
+ } else {
247
+ const msg = r.reason instanceof Error ? r.reason.message : "Failed to load schema";
248
+ consola__default.default.error(`Error loading schema from ${src.url}:`, r.reason);
249
+ next.set(src.id, { loading: false, error: msg });
250
+ }
251
+ });
252
+ return next;
253
+ });
254
+ setLoading(false);
255
+ });
256
+ return () => {
257
+ cancelled = true;
258
+ };
259
+ }, [preloadAll, schemas, loadedSchemas]);
260
+ const schemasData = React6.useMemo(() => {
261
+ if (!preloadAll) return [];
262
+ return schemas.map((src) => {
263
+ const raw = loadedSchemas.get(src.id) ?? null;
264
+ const deref = raw ? chunkIULI4XII_cjs.dereferenceSchema(raw) : null;
265
+ const resolved = chunkIULI4XII_cjs.resolveBaseUrl({
266
+ schemaSource: src.baseUrl,
267
+ config: configBaseUrl,
268
+ fromServers: raw?.servers?.[0]?.url
269
+ });
270
+ const info = raw?.info ? {
271
+ title: raw.info.title,
272
+ version: raw.info.version,
273
+ description: raw.info.description,
274
+ servers: raw.servers
275
+ } : null;
276
+ const eps = deref ? extractEndpoints(deref, resolved, src.id) : [];
277
+ const state = loadStates.get(src.id) ?? { loading: !raw, error: null };
278
+ return {
279
+ source: src,
280
+ info,
281
+ rawSchema: raw,
282
+ endpoints: eps,
283
+ resolvedBaseUrl: resolved || void 0,
284
+ loading: state.loading,
285
+ error: state.error
286
+ };
287
+ });
288
+ }, [preloadAll, schemas, loadedSchemas, loadStates, configBaseUrl]);
201
289
  const setCurrentSchema = React6.useCallback((schemaId) => {
202
290
  setCurrentSchemaId(schemaId);
203
291
  }, []);
@@ -234,10 +322,75 @@ function useOpenApiSchema({
234
322
  // convention from the resolver into undefined at the API boundary.
235
323
  resolvedBaseUrl: resolvedBaseUrl || void 0,
236
324
  setCurrentSchema,
237
- refresh
325
+ refresh,
326
+ schemasData
238
327
  };
239
328
  }
240
329
  chunkWGEGR3DF_cjs.__name(useOpenApiSchema, "useOpenApiSchema");
330
+ function parseDocsHash(hash) {
331
+ const raw = hash.startsWith("#") ? hash.slice(1) : hash;
332
+ if (!raw) return { schemaId: null, anchor: null };
333
+ const [schemaId = null, ...rest] = raw.split("/");
334
+ const anchor = rest.length > 0 ? rest.join("/") : null;
335
+ return {
336
+ schemaId: schemaId || null,
337
+ anchor: anchor || null
338
+ };
339
+ }
340
+ chunkWGEGR3DF_cjs.__name(parseDocsHash, "parseDocsHash");
341
+ function buildDocsHash(schemaId, anchor) {
342
+ if (!schemaId && !anchor) return "";
343
+ if (schemaId && anchor) return `#${schemaId}/${anchor}`;
344
+ if (schemaId) return `#${schemaId}`;
345
+ return anchor ? `#${anchor}` : "";
346
+ }
347
+ chunkWGEGR3DF_cjs.__name(buildDocsHash, "buildDocsHash");
348
+ function useDocsUrlSync({
349
+ enabled,
350
+ currentSchemaId,
351
+ activeAnchor,
352
+ onHashTarget
353
+ }) {
354
+ const primedRef = React6.useRef(false);
355
+ const onHashTargetRef = React6.useRef(onHashTarget);
356
+ React6.useEffect(() => {
357
+ onHashTargetRef.current = onHashTarget;
358
+ }, [onHashTarget]);
359
+ React6.useEffect(() => {
360
+ if (!enabled || typeof window === "undefined") return;
361
+ const apply = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
362
+ onHashTargetRef.current(parseDocsHash(window.location.hash));
363
+ }, "apply");
364
+ apply();
365
+ primedRef.current = true;
366
+ window.addEventListener("hashchange", apply);
367
+ window.addEventListener("popstate", apply);
368
+ return () => {
369
+ window.removeEventListener("hashchange", apply);
370
+ window.removeEventListener("popstate", apply);
371
+ };
372
+ }, [enabled]);
373
+ React6.useEffect(() => {
374
+ if (!enabled || typeof window === "undefined") return;
375
+ if (!primedRef.current) return;
376
+ const next = buildDocsHash(currentSchemaId, activeAnchor);
377
+ const current = window.location.hash;
378
+ if (next === current) return;
379
+ const url = next ? `${window.location.pathname}${window.location.search}${next}` : `${window.location.pathname}${window.location.search}`;
380
+ window.history.replaceState(window.history.state, "", url);
381
+ }, [enabled, currentSchemaId, activeAnchor]);
382
+ const pushTarget = React6.useCallback(
383
+ (schemaId, anchor) => {
384
+ if (!enabled || typeof window === "undefined") return;
385
+ const next = buildDocsHash(schemaId, anchor);
386
+ const url = next ? `${window.location.pathname}${window.location.search}${next}` : `${window.location.pathname}${window.location.search}`;
387
+ window.history.pushState(window.history.state, "", url);
388
+ },
389
+ [enabled]
390
+ );
391
+ return { pushTarget };
392
+ }
393
+ chunkWGEGR3DF_cjs.__name(useDocsUrlSync, "useDocsUrlSync");
241
394
  var EMPTY_DRAFT = { parameters: {}, requestBody: "" };
242
395
  function storageKey(schemaId, ep) {
243
396
  if (!schemaId || !ep) return null;
@@ -368,6 +521,18 @@ function EndpointDraftSync({ schemaId }) {
368
521
  return null;
369
522
  }
370
523
  chunkWGEGR3DF_cjs.__name(EndpointDraftSync, "EndpointDraftSync");
524
+
525
+ // src/tools/OpenapiViewer/components/DocsLayout/anchor.ts
526
+ function endpointAnchor(ep, schemaId) {
527
+ const slug = ep.path.replace(/^https?:\/\/[^/]+/, "").replace(/[{}]/g, "").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
528
+ const schemaSlug = schemaId ? `${slugifySchemaId(schemaId)}-` : "";
529
+ return `ep-${schemaSlug}${ep.method.toLowerCase()}-${slug}`;
530
+ }
531
+ chunkWGEGR3DF_cjs.__name(endpointAnchor, "endpointAnchor");
532
+ function slugifySchemaId(id) {
533
+ return id.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
534
+ }
535
+ chunkWGEGR3DF_cjs.__name(slugifySchemaId, "slugifySchemaId");
371
536
  var METHOD_STYLES = {
372
537
  GET: "bg-emerald-500/10 text-emerald-600 dark:text-emerald-400 border-emerald-500/25",
373
538
  POST: "bg-blue-500/10 text-blue-600 dark:text-blue-400 border-blue-500/25",
@@ -463,13 +628,6 @@ function CollapsibleSection({
463
628
  }
464
629
  chunkWGEGR3DF_cjs.__name(CollapsibleSection, "CollapsibleSection");
465
630
 
466
- // src/tools/OpenapiViewer/components/DocsLayout/anchor.ts
467
- function endpointAnchor(ep) {
468
- const slug = ep.path.replace(/^https?:\/\/[^/]+/, "").replace(/[{}]/g, "").replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
469
- return `ep-${ep.method.toLowerCase()}-${slug}`;
470
- }
471
- chunkWGEGR3DF_cjs.__name(endpointAnchor, "endpointAnchor");
472
-
473
631
  // src/tools/OpenapiViewer/components/DocsLayout/sidebarLabel.ts
474
632
  function longestCommonPrefix(paths) {
475
633
  if (paths.length === 0) return "";
@@ -510,6 +668,8 @@ function sidebarTooltip(ep) {
510
668
  return `${ep.method} ${relativePath2(ep.path)}`;
511
669
  }
512
670
  chunkWGEGR3DF_cjs.__name(sidebarTooltip, "sidebarTooltip");
671
+
672
+ // src/tools/OpenapiViewer/components/DocsLayout/grouping.ts
513
673
  var METHOD_ORDER = {
514
674
  GET: 0,
515
675
  POST: 1,
@@ -517,138 +677,25 @@ var METHOD_ORDER = {
517
677
  PATCH: 3,
518
678
  DELETE: 4
519
679
  };
680
+ var methodRank = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((ep) => METHOD_ORDER[ep.method] ?? 99, "methodRank");
520
681
  function groupEndpoints(list) {
521
- const map = /* @__PURE__ */ new Map();
522
- for (const ep of list) {
523
- const arr = map.get(ep.category) ?? [];
524
- arr.push(ep);
525
- map.set(ep.category, arr);
526
- }
527
- const groups = Array.from(map.entries()).map(([category, endpoints]) => ({
682
+ const byCategory = lodashEs.groupBy(list, "category");
683
+ const all = Object.entries(byCategory).map(([category, endpoints]) => ({
528
684
  category,
529
- endpoints: [...endpoints].sort((a, b) => {
530
- const byPath = a.path.localeCompare(b.path);
531
- if (byPath !== 0) return byPath;
532
- return (METHOD_ORDER[a.method] ?? 99) - (METHOD_ORDER[b.method] ?? 99);
533
- }),
685
+ endpoints: lodashEs.orderBy(endpoints, ["path", methodRank], ["asc", "asc"]),
534
686
  commonPrefix: longestCommonPrefix(endpoints.map((e) => e.path))
535
687
  }));
536
- groups.sort((a, b) => {
537
- if (a.category === "Other") return 1;
538
- if (b.category === "Other") return -1;
539
- return a.category.localeCompare(b.category);
540
- });
541
- return groups;
688
+ const [other, named] = lodashEs.partition(all, (g) => g.category === "Other");
689
+ return [...lodashEs.sortBy(named, (g) => g.category.toLowerCase()), ...other];
542
690
  }
543
691
  chunkWGEGR3DF_cjs.__name(groupEndpoints, "groupEndpoints");
544
- function DocsSidebar({
545
- info,
546
- endpoints,
547
- schemas,
548
- currentSchemaId,
549
- onSchemaChange,
550
- activeEndpointId,
551
- selectedVersion,
552
- onNavigate
553
- }) {
554
- const [search, setSearch] = React6.useState("");
555
- const [debounced, setDebounced] = React6.useState("");
556
- React6.useEffect(() => {
557
- const id = setTimeout(() => setDebounced(search), 120);
558
- return () => clearTimeout(id);
559
- }, [search]);
560
- const filteredGroups = React6.useMemo(() => {
561
- let list = chunkIULI4XII_cjs.deduplicateEndpoints(endpoints, selectedVersion);
562
- if (debounced) {
563
- const q = debounced.toLowerCase();
564
- list = list.filter(
565
- (e) => e.summary.toLowerCase().includes(q) || e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q) || e.path.toLowerCase().includes(q)
566
- );
567
- }
568
- return groupEndpoints(list);
569
- }, [endpoints, debounced, selectedVersion]);
570
- const schemaOptions = React6.useMemo(
571
- () => schemas.map((s) => ({ value: s.id, label: s.name })),
572
- [schemas]
573
- );
574
- const hasMultipleSchemas = schemas.length > 1;
575
- const apiTitle = info?.title ?? "API Reference";
576
- return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "flex flex-col min-h-0 border-r bg-muted/10", children: [
577
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-4 h-12 flex items-center gap-2", children: [
578
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-semibold text-foreground truncate", children: apiTitle }),
579
- info?.version && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-[10px] text-muted-foreground/70 shrink-0", children: [
580
- "v",
581
- info.version
582
- ] })
583
- ] }),
584
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-3 py-3 space-y-2", children: [
585
- hasMultipleSchemas && /* @__PURE__ */ jsxRuntime.jsx(
586
- components.Combobox,
587
- {
588
- options: schemaOptions,
589
- value: currentSchemaId ?? "",
590
- onValueChange: (id) => id && onSchemaChange(id),
591
- placeholder: "Select API",
592
- searchPlaceholder: "Search APIs\u2026",
593
- emptyText: "No APIs found",
594
- className: "w-full h-8 text-xs"
595
- }
596
- ),
597
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
598
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" }),
599
- /* @__PURE__ */ jsxRuntime.jsx(
600
- components.Input,
601
- {
602
- placeholder: "Search endpoints\u2026",
603
- value: search,
604
- onChange: (e) => setSearch(e.target.value),
605
- className: "pl-8 h-8 text-xs"
606
- }
607
- )
608
- ] })
609
- ] }),
610
- /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { children: filteredGroups.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 px-4 text-center text-xs text-muted-foreground", children: debounced ? `No endpoints match "${debounced}"` : "No endpoints in this schema" }) : /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "py-2", children: filteredGroups.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 last:mb-2", children: [
611
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/50 select-none", children: group.category }),
612
- /* @__PURE__ */ jsxRuntime.jsx("div", { children: group.endpoints.map((ep) => {
613
- const anchor = endpointAnchor(ep);
614
- const isActive = activeEndpointId === anchor;
615
- const label = sidebarLabel(ep, group.commonPrefix);
616
- const tooltip = sidebarTooltip(ep);
617
- const useMono = !ep.summary;
618
- return /* @__PURE__ */ jsxRuntime.jsxs(components.Tooltip, { delayDuration: 350, children: [
619
- /* @__PURE__ */ jsxRuntime.jsx(components.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
620
- "button",
621
- {
622
- onClick: () => onNavigate(anchor),
623
- "aria-current": isActive ? "location" : void 0,
624
- className: lib.cn(
625
- "relative group w-full text-left flex items-center gap-2 pl-4 pr-3 py-1.5 transition-colors",
626
- isActive ? "bg-primary/10 text-foreground" : "hover:bg-muted/40 text-foreground/75 hover:text-foreground"
627
- ),
628
- children: [
629
- isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-0 top-1 bottom-1 w-0.5 rounded-r bg-primary" }),
630
- /* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: ep.method }),
631
- /* @__PURE__ */ jsxRuntime.jsx(
632
- "span",
633
- {
634
- className: lib.cn(
635
- "truncate leading-tight flex-1 min-w-0",
636
- useMono ? "font-mono text-[11px]" : "text-[12px]",
637
- isActive && "text-foreground font-medium"
638
- ),
639
- children: label
640
- }
641
- )
642
- ]
643
- }
644
- ) }),
645
- /* @__PURE__ */ jsxRuntime.jsx(components.TooltipContent, { side: "right", align: "center", className: "font-mono text-[11px]", children: tooltip })
646
- ] }, `${ep.method}-${ep.path}`);
647
- }) })
648
- ] }, group.category)) }) })
649
- ] });
692
+ function buildSchemaSections(sources, endpointsBySchema) {
693
+ return sources.map((source) => ({
694
+ source,
695
+ groups: groupEndpoints(endpointsBySchema[source.id] ?? [])
696
+ }));
650
697
  }
651
- chunkWGEGR3DF_cjs.__name(DocsSidebar, "DocsSidebar");
698
+ chunkWGEGR3DF_cjs.__name(buildSchemaSections, "buildSchemaSections");
652
699
  var FLAVOUR_LABELS = {
653
700
  markdown: {
654
701
  title: "Markdown for LLM",
@@ -663,7 +710,7 @@ var FLAVOUR_LABELS = {
663
710
  hint: "Full OpenAPI document with $refs."
664
711
  }
665
712
  };
666
- function SchemaCopyMenu({ schema, endpoints, baseUrl }) {
713
+ function SchemaCopyMenu({ schema, endpoints, baseUrl, variant = "button" }) {
667
714
  const [sizeCache, setSizeCache] = React6.useState({});
668
715
  const [justCopied, setJustCopied] = React6.useState(null);
669
716
  const [open, setOpen] = React6.useState(false);
@@ -681,20 +728,36 @@ function SchemaCopyMenu({ schema, endpoints, baseUrl }) {
681
728
  async (flavour) => {
682
729
  if (!isReady) return;
683
730
  const text = build(flavour);
731
+ const label = FLAVOUR_LABELS[flavour].title;
684
732
  try {
685
733
  await navigator.clipboard.writeText(text);
686
- setSizeCache((prev) => ({ ...prev, [flavour]: chunkIULI4XII_cjs.formatBytes(text) }));
734
+ const size = chunkIULI4XII_cjs.formatBytes(text);
735
+ setSizeCache((prev) => ({ ...prev, [flavour]: size }));
687
736
  setJustCopied(flavour);
688
737
  setTimeout(() => setJustCopied(null), 1500);
689
738
  setOpen(false);
690
- } catch {
739
+ hooks.toast.success(`Copied ${label}`, { description: size });
740
+ } catch (err) {
741
+ const message = err instanceof Error ? err.message : "Clipboard permission denied";
742
+ hooks.toast.error("Copy failed", { description: message });
691
743
  }
692
744
  },
693
745
  [build, isReady]
694
746
  );
695
747
  const flavours = React6.useMemo(() => ["markdown", "compact", "raw"], []);
696
748
  return /* @__PURE__ */ jsxRuntime.jsxs(components.DropdownMenu, { open, onOpenChange: setOpen, children: [
697
- /* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(components.Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", disabled: !isReady, children: [
749
+ /* @__PURE__ */ jsxRuntime.jsx(components.DropdownMenuTrigger, { asChild: true, children: variant === "icon" ? /* @__PURE__ */ jsxRuntime.jsx(
750
+ components.Button,
751
+ {
752
+ variant: "ghost",
753
+ size: "icon",
754
+ className: "h-7 w-7 shrink-0",
755
+ disabled: !isReady,
756
+ title: "Copy schema for AI",
757
+ "aria-label": "Copy schema for AI",
758
+ children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3.5 w-3.5" })
759
+ }
760
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(components.Button, { variant: "outline", size: "sm", className: "h-8 gap-1.5 text-xs", disabled: !isReady, children: [
698
761
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Sparkles, { className: "h-3 w-3" }),
699
762
  "Copy for AI",
700
763
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronDown, { className: "h-3 w-3 opacity-60" })
@@ -732,6 +795,296 @@ function SchemaCopyMenu({ schema, endpoints, baseUrl }) {
732
795
  ] });
733
796
  }
734
797
  chunkWGEGR3DF_cjs.__name(SchemaCopyMenu, "SchemaCopyMenu");
798
+ var METHOD_FILTERS = ["ALL", "GET", "POST", "PUT", "PATCH", "DELETE"];
799
+ function filterEndpoints(list, query, method) {
800
+ let out = list;
801
+ if (method !== "ALL") {
802
+ out = out.filter((e) => e.method === method);
803
+ }
804
+ if (query) {
805
+ const q = query.toLowerCase();
806
+ out = out.filter(
807
+ (e) => e.summary.toLowerCase().includes(q) || e.name.toLowerCase().includes(q) || e.description.toLowerCase().includes(q) || e.path.toLowerCase().includes(q)
808
+ );
809
+ }
810
+ return out;
811
+ }
812
+ chunkWGEGR3DF_cjs.__name(filterEndpoints, "filterEndpoints");
813
+ function buildCategory(group, activeEndpointId, schemaId, keyPrefix) {
814
+ const rows = group.endpoints.map((ep) => {
815
+ const anchor = endpointAnchor(ep, schemaId ?? ep.schemaId ?? null);
816
+ return {
817
+ key: `${ep.method}-${ep.path}`,
818
+ anchor,
819
+ schemaId: schemaId ?? ep.schemaId ?? null,
820
+ label: sidebarLabel(ep, group.commonPrefix),
821
+ tooltip: sidebarTooltip(ep),
822
+ method: ep.method,
823
+ useMono: !ep.summary,
824
+ isActive: activeEndpointId === anchor
825
+ };
826
+ });
827
+ return {
828
+ key: `${keyPrefix}${group.category}`,
829
+ category: group.category,
830
+ rows
831
+ };
832
+ }
833
+ chunkWGEGR3DF_cjs.__name(buildCategory, "buildCategory");
834
+ var emptyTextFor = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((query, method, defaultText) => {
835
+ if (query && method !== "ALL") return `No ${method} endpoints match "${query}"`;
836
+ if (query) return `No endpoints match "${query}"`;
837
+ if (method !== "ALL") return `No ${method} endpoints`;
838
+ return defaultText;
839
+ }, "emptyTextFor");
840
+ function buildFlatVM(endpoints, selectedVersion, query, method, activeEndpointId) {
841
+ const filtered = filterEndpoints(chunkIULI4XII_cjs.deduplicateEndpoints(endpoints, selectedVersion), query, method);
842
+ const groups = groupEndpoints(filtered);
843
+ return {
844
+ kind: "flat",
845
+ categories: groups.map((g) => buildCategory(g, activeEndpointId, null, "")),
846
+ emptyText: emptyTextFor(query, method, "No endpoints in this schema")
847
+ };
848
+ }
849
+ chunkWGEGR3DF_cjs.__name(buildFlatVM, "buildFlatVM");
850
+ function buildSectionsVM(schemas, endpointsBySchema, selectedVersion, query, method, activeEndpointId) {
851
+ const filteredMap = {};
852
+ for (const src of schemas) {
853
+ const raw = endpointsBySchema[src.id] ?? [];
854
+ filteredMap[src.id] = filterEndpoints(chunkIULI4XII_cjs.deduplicateEndpoints(raw, selectedVersion), query, method);
855
+ }
856
+ const rawSections = buildSchemaSections(schemas, filteredMap);
857
+ const sections = rawSections.filter((s) => s.groups.length > 0).map((s) => ({
858
+ sourceId: s.source.id,
859
+ sourceName: s.source.name,
860
+ categories: s.groups.map((g) => buildCategory(g, activeEndpointId, s.source.id, `${s.source.id}-`))
861
+ }));
862
+ return {
863
+ kind: "sections",
864
+ sections,
865
+ emptyText: emptyTextFor(query, method, "No endpoints in any schema")
866
+ };
867
+ }
868
+ chunkWGEGR3DF_cjs.__name(buildSectionsVM, "buildSectionsVM");
869
+ function DocsSidebar({
870
+ info,
871
+ endpoints,
872
+ schemas,
873
+ currentSchemaId,
874
+ onSchemaChange,
875
+ activeEndpointId,
876
+ selectedVersion,
877
+ onNavigate,
878
+ grouping = "selector",
879
+ endpointsBySchema,
880
+ rawSchema,
881
+ resolvedBaseUrl
882
+ }) {
883
+ const [search, setSearch] = React6.useState("");
884
+ const [debounced, setDebounced] = React6.useState("");
885
+ const [methodFilter, setMethodFilter] = React6.useState("ALL");
886
+ React6.useEffect(() => {
887
+ const id = setTimeout(() => setDebounced(search), 120);
888
+ return () => clearTimeout(id);
889
+ }, [search]);
890
+ const body = React6.useMemo(() => {
891
+ if (grouping === "sections") {
892
+ return buildSectionsVM(
893
+ schemas,
894
+ endpointsBySchema ?? {},
895
+ selectedVersion,
896
+ debounced,
897
+ methodFilter,
898
+ activeEndpointId
899
+ );
900
+ }
901
+ return buildFlatVM(endpoints, selectedVersion, debounced, methodFilter, activeEndpointId);
902
+ }, [
903
+ grouping,
904
+ schemas,
905
+ endpointsBySchema,
906
+ endpoints,
907
+ selectedVersion,
908
+ debounced,
909
+ methodFilter,
910
+ activeEndpointId
911
+ ]);
912
+ const schemaOptions = React6.useMemo(
913
+ () => schemas.map((s) => ({ value: s.id, label: s.name })),
914
+ [schemas]
915
+ );
916
+ const hasMultipleSchemas = schemas.length > 1;
917
+ const apiTitle = info?.title ?? "API Reference";
918
+ const showCombobox = grouping === "selector" && hasMultipleSchemas;
919
+ const copyReady = rawSchema !== null && rawSchema !== void 0 && endpoints.length > 0;
920
+ return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "flex flex-col h-full min-h-0 border-r bg-muted/10", children: [
921
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-3 h-12 flex items-center gap-2", children: [
922
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
923
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[13px] font-semibold text-foreground truncate", children: apiTitle }),
924
+ info?.version && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-[10px] text-muted-foreground/70 shrink-0", children: [
925
+ "v",
926
+ info.version
927
+ ] })
928
+ ] }),
929
+ copyReady && /* @__PURE__ */ jsxRuntime.jsx(
930
+ SchemaCopyMenu,
931
+ {
932
+ schema: rawSchema ?? null,
933
+ endpoints,
934
+ baseUrl: resolvedBaseUrl,
935
+ variant: "icon"
936
+ }
937
+ )
938
+ ] }),
939
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "shrink-0 border-b px-3 py-3 space-y-2", children: [
940
+ showCombobox && /* @__PURE__ */ jsxRuntime.jsx(
941
+ components.Combobox,
942
+ {
943
+ options: schemaOptions,
944
+ value: currentSchemaId ?? "",
945
+ onValueChange: (id) => id && onSchemaChange(id),
946
+ placeholder: "Select API",
947
+ searchPlaceholder: "Search APIs\u2026",
948
+ emptyText: "No APIs found",
949
+ className: "w-full h-8 text-xs"
950
+ }
951
+ ),
952
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
953
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Search, { className: "absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground/50 pointer-events-none" }),
954
+ /* @__PURE__ */ jsxRuntime.jsx(
955
+ components.Input,
956
+ {
957
+ placeholder: "Search endpoints\u2026",
958
+ value: search,
959
+ onChange: (e) => setSearch(e.target.value),
960
+ className: "pl-8 h-8 text-xs"
961
+ }
962
+ )
963
+ ] }),
964
+ /* @__PURE__ */ jsxRuntime.jsx(MethodChips, { value: methodFilter, onChange: setMethodFilter })
965
+ ] }),
966
+ /* @__PURE__ */ jsxRuntime.jsx(ScrollArea, { children: /* @__PURE__ */ jsxRuntime.jsx(SidebarBody, { body, onNavigate }) })
967
+ ] });
968
+ }
969
+ chunkWGEGR3DF_cjs.__name(DocsSidebar, "DocsSidebar");
970
+ function MethodChips({
971
+ value,
972
+ onChange
973
+ }) {
974
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1 flex-wrap", children: METHOD_FILTERS.map((m) => {
975
+ const active = value === m;
976
+ return /* @__PURE__ */ jsxRuntime.jsx(
977
+ "button",
978
+ {
979
+ type: "button",
980
+ onClick: () => onChange(m),
981
+ "aria-pressed": active,
982
+ className: lib.cn(
983
+ "px-2 py-0.5 rounded font-mono text-[10px] font-semibold tracking-wide transition-colors border",
984
+ active ? "bg-primary/15 border-primary/40 text-foreground" : "bg-transparent border-border/40 text-muted-foreground hover:text-foreground hover:border-border"
985
+ ),
986
+ children: m
987
+ },
988
+ m
989
+ );
990
+ }) });
991
+ }
992
+ chunkWGEGR3DF_cjs.__name(MethodChips, "MethodChips");
993
+ function SidebarBody({ body, onNavigate }) {
994
+ if (body.kind === "flat") {
995
+ if (body.categories.length === 0) {
996
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 px-4 text-center text-xs text-muted-foreground", children: body.emptyText });
997
+ }
998
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "py-2", children: body.categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(CategoryBlock, { category: cat, onNavigate }, cat.key)) });
999
+ }
1000
+ if (body.sections.length === 0) {
1001
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-10 px-4 text-center text-xs text-muted-foreground", children: body.emptyText });
1002
+ }
1003
+ return /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "py-2", children: body.sections.map((section) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-5 last:mb-2", children: [
1004
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-2 sticky top-0 z-[1] bg-muted/30 backdrop-blur-[2px] border-b border-border/30", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] font-bold uppercase tracking-[0.12em] text-foreground/80", children: section.sourceName }) }),
1005
+ section.categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx(CategoryBlock, { category: cat, onNavigate }, cat.key))
1006
+ ] }, section.sourceId)) });
1007
+ }
1008
+ chunkWGEGR3DF_cjs.__name(SidebarBody, "SidebarBody");
1009
+ var CategoryBlock = React6__default.default.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function CategoryBlock2({
1010
+ category,
1011
+ onNavigate
1012
+ }) {
1013
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-4 last:mb-2", children: [
1014
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-4 py-1.5 text-[10px] font-semibold uppercase tracking-[0.14em] text-muted-foreground/50 select-none", children: category.category }),
1015
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children: category.rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(EndpointRow, { row, onNavigate }, row.key)) })
1016
+ ] });
1017
+ }, "CategoryBlock"));
1018
+ var EndpointRow = React6__default.default.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function EndpointRow2({
1019
+ row,
1020
+ onNavigate
1021
+ }) {
1022
+ return /* @__PURE__ */ jsxRuntime.jsxs(components.Tooltip, { delayDuration: 350, children: [
1023
+ /* @__PURE__ */ jsxRuntime.jsx(components.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1024
+ "button",
1025
+ {
1026
+ onClick: () => onNavigate(row.anchor, row.schemaId),
1027
+ "aria-current": row.isActive ? "location" : void 0,
1028
+ className: lib.cn(
1029
+ "relative group w-full text-left flex items-start gap-2 pl-4 pr-3 py-1.5 transition-colors",
1030
+ row.isActive ? "bg-primary/10 text-foreground" : "hover:bg-muted/40 text-foreground/75 hover:text-foreground"
1031
+ ),
1032
+ children: [
1033
+ row.isActive && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute left-0 top-1 bottom-1 w-0.5 rounded-r bg-primary" }),
1034
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 mt-[1px]", children: /* @__PURE__ */ jsxRuntime.jsx(MethodBadge, { method: row.method }) }),
1035
+ /* @__PURE__ */ jsxRuntime.jsx(
1036
+ "span",
1037
+ {
1038
+ className: lib.cn(
1039
+ "line-clamp-2 leading-snug flex-1 min-w-0",
1040
+ row.useMono ? "font-mono text-[11px] break-all" : "text-[12px]",
1041
+ row.isActive && "text-foreground font-medium"
1042
+ ),
1043
+ children: row.label
1044
+ }
1045
+ )
1046
+ ]
1047
+ }
1048
+ ) }),
1049
+ /* @__PURE__ */ jsxRuntime.jsx(components.TooltipContent, { side: "right", align: "center", className: "font-mono text-[11px]", children: row.tooltip })
1050
+ ] });
1051
+ }, "EndpointRow"));
1052
+
1053
+ // src/tools/OpenapiViewer/utils/scrollParent.ts
1054
+ function getScrollParent(el) {
1055
+ if (typeof window === "undefined") return null;
1056
+ if (!el) return window;
1057
+ let cur = el.parentElement;
1058
+ while (cur && cur !== document.body && cur !== document.documentElement) {
1059
+ const style = getComputedStyle(cur);
1060
+ const overflowY = style.overflowY;
1061
+ const canScroll = (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay") && cur.scrollHeight > cur.clientHeight;
1062
+ if (canScroll) return cur;
1063
+ cur = cur.parentElement;
1064
+ }
1065
+ return window;
1066
+ }
1067
+ chunkWGEGR3DF_cjs.__name(getScrollParent, "getScrollParent");
1068
+ function getScrollTop(target) {
1069
+ return target === window ? window.scrollY : target.scrollTop;
1070
+ }
1071
+ chunkWGEGR3DF_cjs.__name(getScrollTop, "getScrollTop");
1072
+ function getViewportHeight(target) {
1073
+ return target === window ? window.innerHeight : target.clientHeight;
1074
+ }
1075
+ chunkWGEGR3DF_cjs.__name(getViewportHeight, "getViewportHeight");
1076
+ function getTargetTop(target) {
1077
+ return target === window ? 0 : target.getBoundingClientRect().top;
1078
+ }
1079
+ chunkWGEGR3DF_cjs.__name(getTargetTop, "getTargetTop");
1080
+ function scrollTargetTo(target, top) {
1081
+ if (target === window) {
1082
+ window.scrollTo({ top, behavior: "smooth" });
1083
+ return;
1084
+ }
1085
+ target.scrollTop = top;
1086
+ }
1087
+ chunkWGEGR3DF_cjs.__name(scrollTargetTo, "scrollTargetTo");
735
1088
  function ApiIntroSection({ info, schema, endpoints, resolvedBaseUrl }) {
736
1089
  return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "pb-10 mb-10 border-b", children: [
737
1090
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4 flex-wrap", children: [
@@ -835,8 +1188,9 @@ function schemaToFields(schema, prefix = "", depth = 0) {
835
1188
  return rows;
836
1189
  }
837
1190
  chunkWGEGR3DF_cjs.__name(schemaToFields, "schemaToFields");
838
- function EndpointDoc({ endpoint, isLoadedInPlayground, onTryIt }) {
839
- const anchor = endpointAnchor(endpoint);
1191
+ function EndpointDoc({ endpoint, isLoadedInPlayground, onTryIt, schemaId }) {
1192
+ const scopedSchemaId = schemaId ?? endpoint.schemaId ?? null;
1193
+ const anchor = endpointAnchor(endpoint, scopedSchemaId);
840
1194
  const pathParams = endpoint.parameters?.filter((p) => endpoint.path.includes(`{${p.name}}`)) ?? [];
841
1195
  const queryParams = endpoint.parameters?.filter((p) => !endpoint.path.includes(`{${p.name}}`)) ?? [];
842
1196
  const [copied, setCopied] = React6.useState(false);
@@ -854,6 +1208,7 @@ function EndpointDoc({ endpoint, isLoadedInPlayground, onTryIt }) {
854
1208
  {
855
1209
  id: anchor,
856
1210
  "data-endpoint-anchor": anchor,
1211
+ "data-schema-id": scopedSchemaId ?? "",
857
1212
  className: "scroll-mt-24 py-10 first:pt-0",
858
1213
  children: [
859
1214
  /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "space-y-4", children: [
@@ -1014,52 +1369,103 @@ function StatusTag({ code }) {
1014
1369
  ), children: code });
1015
1370
  }
1016
1371
  chunkWGEGR3DF_cjs.__name(StatusTag, "StatusTag");
1017
- var DocsView = React6__default.default.forwardRef(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function DocsView2({
1018
- info,
1019
- rawSchema,
1020
- resolvedBaseUrl,
1021
- endpoints,
1022
- selectedVersion,
1023
- loadedEndpoint,
1024
- onTryEndpoint,
1025
- onActiveChange
1026
- }, ref) {
1372
+ var readNavbarOffset = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1373
+ if (typeof document === "undefined") return 0;
1374
+ const raw = getComputedStyle(document.documentElement).getPropertyValue("--navbar-height");
1375
+ const parsed = parseInt(raw || "", 10);
1376
+ return Number.isFinite(parsed) ? parsed : 0;
1377
+ }, "readNavbarOffset");
1378
+ var isSameEndpoint = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name((a, b) => a !== null && a.method === b.method && a.path === b.path, "isSameEndpoint");
1379
+ function buildEndpointRow(ep, loadedEndpoint, schemaId) {
1380
+ const keySchema = schemaId ? `${schemaId}-` : "";
1381
+ return {
1382
+ key: `${keySchema}${ep.method}-${ep.path}`,
1383
+ endpoint: ep,
1384
+ isLoaded: isSameEndpoint(loadedEndpoint, ep),
1385
+ schemaId
1386
+ };
1387
+ }
1388
+ chunkWGEGR3DF_cjs.__name(buildEndpointRow, "buildEndpointRow");
1389
+ function buildSchemaSectionVM(entry, selectedVersion, loadedEndpoint) {
1390
+ const title = entry.info?.title ?? entry.source.name;
1391
+ const version = entry.info?.version ?? null;
1392
+ const description = entry.info?.description ?? null;
1393
+ let state;
1394
+ if (entry.loading) {
1395
+ state = { kind: "loading" };
1396
+ } else if (entry.error) {
1397
+ state = { kind: "error", message: entry.error };
1398
+ } else {
1399
+ const visible = chunkIULI4XII_cjs.deduplicateEndpoints(entry.endpoints, selectedVersion);
1400
+ state = visible.length === 0 ? { kind: "empty" } : {
1401
+ kind: "ready",
1402
+ rows: visible.map((ep) => buildEndpointRow(ep, loadedEndpoint, entry.source.id))
1403
+ };
1404
+ }
1405
+ return {
1406
+ schemaId: entry.source.id,
1407
+ title,
1408
+ version,
1409
+ description,
1410
+ state,
1411
+ rawSchema: entry.rawSchema,
1412
+ baseUrl: entry.resolvedBaseUrl,
1413
+ allEndpoints: entry.endpoints
1414
+ };
1415
+ }
1416
+ chunkWGEGR3DF_cjs.__name(buildSchemaSectionVM, "buildSchemaSectionVM");
1417
+ var DocsView = React6__default.default.forwardRef(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function DocsView2(props, ref) {
1027
1418
  const scrollRef = React6.useRef(null);
1028
- const visibleEndpoints = React6.useMemo(
1029
- () => chunkIULI4XII_cjs.deduplicateEndpoints(endpoints, selectedVersion),
1030
- [endpoints, selectedVersion]
1031
- );
1032
- const scrollToAnchor = React6.useCallback((anchor) => {
1033
- const root = scrollRef.current;
1034
- if (!root) return;
1035
- const el = root.querySelector(`[data-endpoint-anchor="${anchor}"]`);
1036
- if (!el) return;
1037
- el.scrollIntoView({ behavior: "smooth", block: "start" });
1419
+ const scrollTargetRef = React6.useRef(null);
1420
+ const { onActiveChange } = props;
1421
+ const ensureScrollTarget = React6.useCallback(() => {
1422
+ if (scrollTargetRef.current) return scrollTargetRef.current;
1423
+ if (!scrollRef.current) return null;
1424
+ scrollTargetRef.current = getScrollParent(scrollRef.current);
1425
+ return scrollTargetRef.current;
1038
1426
  }, []);
1427
+ const scrollToAnchor = React6.useCallback(
1428
+ (anchor) => {
1429
+ const root = scrollRef.current;
1430
+ if (!root) return;
1431
+ const el = root.querySelector(`[data-endpoint-anchor="${anchor}"]`);
1432
+ if (!el) return;
1433
+ const target = ensureScrollTarget();
1434
+ if (!target) return;
1435
+ const navbar = readNavbarOffset();
1436
+ const top = el.getBoundingClientRect().top - getTargetTop(target) + getScrollTop(target) - navbar - 8;
1437
+ scrollTargetTo(target, top);
1438
+ },
1439
+ [ensureScrollTarget]
1440
+ );
1039
1441
  React6__default.default.useImperativeHandle(ref, () => ({ scrollToAnchor }), [scrollToAnchor]);
1040
1442
  React6.useEffect(() => {
1041
1443
  const root = scrollRef.current;
1042
1444
  if (!root) return;
1445
+ const target = ensureScrollTarget();
1446
+ if (!target) return;
1043
1447
  let rafId = 0;
1044
1448
  let lastActive = null;
1045
1449
  const compute = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1046
1450
  rafId = 0;
1047
1451
  const sections = root.querySelectorAll("[data-endpoint-anchor]");
1048
1452
  if (sections.length === 0) return;
1049
- const rootTop = root.getBoundingClientRect().top;
1050
- const threshold = rootTop + root.clientHeight * 0.25;
1453
+ const navbar = readNavbarOffset();
1454
+ const viewportTop = getTargetTop(target);
1455
+ const threshold = viewportTop + navbar + getViewportHeight(target) * 0.25;
1051
1456
  let active = null;
1052
1457
  for (const s of Array.from(sections)) {
1053
1458
  const top = s.getBoundingClientRect().top;
1054
1459
  if (top <= threshold) {
1055
- active = s.dataset.endpointAnchor ?? null;
1460
+ active = s;
1056
1461
  } else {
1057
1462
  break;
1058
1463
  }
1059
1464
  }
1060
- if (active !== lastActive) {
1061
- lastActive = active;
1062
- onActiveChange(active);
1465
+ const anchor = active?.dataset.endpointAnchor ?? null;
1466
+ if (anchor !== lastActive) {
1467
+ lastActive = anchor;
1468
+ onActiveChange(anchor, active?.dataset.schemaId || null);
1063
1469
  }
1064
1470
  }, "compute");
1065
1471
  const onScroll = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
@@ -1067,13 +1473,39 @@ var DocsView = React6__default.default.forwardRef(/* @__PURE__ */ chunkWGEGR3DF_
1067
1473
  rafId = requestAnimationFrame(compute);
1068
1474
  }, "onScroll");
1069
1475
  compute();
1070
- root.addEventListener("scroll", onScroll, { passive: true });
1476
+ target.addEventListener("scroll", onScroll, { passive: true });
1477
+ window.addEventListener("resize", onScroll, { passive: true });
1071
1478
  return () => {
1072
- root.removeEventListener("scroll", onScroll);
1479
+ target.removeEventListener("scroll", onScroll);
1480
+ window.removeEventListener("resize", onScroll);
1073
1481
  if (rafId) cancelAnimationFrame(rafId);
1074
1482
  };
1075
- }, [visibleEndpoints, onActiveChange]);
1076
- return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, className: "flex-1 overflow-y-auto min-h-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-[860px] px-6 md:px-10 lg:px-14 py-12", children: [
1483
+ }, [onActiveChange, ensureScrollTarget, props]);
1484
+ if (props.grouping === "sections") {
1485
+ return /* @__PURE__ */ jsxRuntime.jsx(SectionsBody, { scrollRef, ...props });
1486
+ }
1487
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectorBody, { scrollRef, ...props });
1488
+ }, "DocsView"));
1489
+ function SelectorBody({
1490
+ scrollRef,
1491
+ info,
1492
+ rawSchema,
1493
+ resolvedBaseUrl,
1494
+ endpoints,
1495
+ selectedVersion,
1496
+ loadedEndpoint,
1497
+ onTryEndpoint
1498
+ }) {
1499
+ const visibleEndpoints = React6.useMemo(
1500
+ () => chunkIULI4XII_cjs.deduplicateEndpoints(endpoints, selectedVersion),
1501
+ [endpoints, selectedVersion]
1502
+ );
1503
+ const rows = React6.useMemo(
1504
+ () => visibleEndpoints.map((ep) => buildEndpointRow(ep, loadedEndpoint, ep.schemaId ?? null)),
1505
+ [visibleEndpoints, loadedEndpoint]
1506
+ );
1507
+ const isEmpty = rows.length === 0;
1508
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mx-auto w-full max-w-[860px] px-6 md:px-10 lg:px-14 py-12", children: [
1077
1509
  info && /* @__PURE__ */ jsxRuntime.jsx(
1078
1510
  ApiIntroSection,
1079
1511
  {
@@ -1083,20 +1515,96 @@ var DocsView = React6__default.default.forwardRef(/* @__PURE__ */ chunkWGEGR3DF_
1083
1515
  resolvedBaseUrl
1084
1516
  }
1085
1517
  ),
1086
- visibleEndpoints.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-16 text-center text-sm text-muted-foreground", children: "No endpoints to display." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border/60", children: visibleEndpoints.map((ep) => {
1087
- const isLoaded = loadedEndpoint?.method === ep.method && loadedEndpoint?.path === ep.path;
1088
- return /* @__PURE__ */ jsxRuntime.jsx(
1518
+ isEmpty ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-16 text-center text-sm text-muted-foreground", children: "No endpoints to display." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border/60", children: rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
1519
+ EndpointDoc,
1520
+ {
1521
+ endpoint: row.endpoint,
1522
+ isLoadedInPlayground: row.isLoaded,
1523
+ onTryIt: () => onTryEndpoint(row.endpoint),
1524
+ schemaId: row.schemaId
1525
+ },
1526
+ row.key
1527
+ )) })
1528
+ ] }) });
1529
+ }
1530
+ chunkWGEGR3DF_cjs.__name(SelectorBody, "SelectorBody");
1531
+ function SectionsBody({
1532
+ scrollRef,
1533
+ schemasData,
1534
+ selectedVersion,
1535
+ loadedEndpoint,
1536
+ onTryEndpoint
1537
+ }) {
1538
+ const sections = React6.useMemo(
1539
+ () => schemasData.map((e) => buildSchemaSectionVM(e, selectedVersion, loadedEndpoint)),
1540
+ [schemasData, selectedVersion, loadedEndpoint]
1541
+ );
1542
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: scrollRef, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mx-auto w-full max-w-[860px] px-6 md:px-10 lg:px-14 py-12 space-y-16", children: sections.map((section) => /* @__PURE__ */ jsxRuntime.jsx(SchemaSectionView, { section, onTryEndpoint }, section.schemaId)) }) });
1543
+ }
1544
+ chunkWGEGR3DF_cjs.__name(SectionsBody, "SectionsBody");
1545
+ var SchemaSectionView = React6__default.default.memo(/* @__PURE__ */ chunkWGEGR3DF_cjs.__name(function SchemaSectionView2({
1546
+ section,
1547
+ onTryEndpoint
1548
+ }) {
1549
+ const canCopy = section.rawSchema !== null && section.allEndpoints.length > 0;
1550
+ return /* @__PURE__ */ jsxRuntime.jsxs("section", { "data-schema-anchor": section.schemaId, className: "scroll-mt-20", children: [
1551
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "mb-8 pb-4 border-b", children: [
1552
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between gap-4", children: [
1553
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-baseline gap-3 min-w-0", children: [
1554
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl font-semibold tracking-tight", children: section.title }),
1555
+ section.version && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-mono text-xs text-muted-foreground/70", children: [
1556
+ "v",
1557
+ section.version
1558
+ ] })
1559
+ ] }),
1560
+ canCopy && /* @__PURE__ */ jsxRuntime.jsx(
1561
+ SchemaCopyMenu,
1562
+ {
1563
+ schema: section.rawSchema,
1564
+ endpoints: section.allEndpoints,
1565
+ baseUrl: section.baseUrl
1566
+ }
1567
+ )
1568
+ ] }),
1569
+ section.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 text-sm text-muted-foreground whitespace-pre-wrap", children: section.description })
1570
+ ] }),
1571
+ /* @__PURE__ */ jsxRuntime.jsx(SchemaSectionStateView, { section, onTryEndpoint })
1572
+ ] });
1573
+ }, "SchemaSectionView"));
1574
+ function SchemaSectionStateView({
1575
+ section,
1576
+ onTryEndpoint
1577
+ }) {
1578
+ switch (section.state.kind) {
1579
+ case "loading":
1580
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-8 text-center text-sm text-muted-foreground", children: [
1581
+ "Loading ",
1582
+ section.title,
1583
+ "\u2026"
1584
+ ] });
1585
+ case "error":
1586
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "py-8 text-center text-sm text-destructive", children: [
1587
+ "Failed to load ",
1588
+ section.title,
1589
+ ": ",
1590
+ section.state.message
1591
+ ] });
1592
+ case "empty":
1593
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-8 text-center text-sm text-muted-foreground", children: "No endpoints in this schema." });
1594
+ case "ready":
1595
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "divide-y divide-border/60", children: section.state.rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
1089
1596
  EndpointDoc,
1090
1597
  {
1091
- endpoint: ep,
1092
- isLoadedInPlayground: isLoaded,
1093
- onTryIt: () => onTryEndpoint(ep)
1598
+ endpoint: row.endpoint,
1599
+ isLoadedInPlayground: row.isLoaded,
1600
+ onTryIt: () => onTryEndpoint(row.endpoint),
1601
+ schemaId: row.schemaId
1094
1602
  },
1095
- `${ep.method}-${ep.path}`
1096
- );
1097
- }) })
1098
- ] }) });
1099
- }, "DocsView"));
1603
+ row.key
1604
+ )) });
1605
+ }
1606
+ }
1607
+ chunkWGEGR3DF_cjs.__name(SchemaSectionStateView, "SchemaSectionStateView");
1100
1608
  var MAX_DEPTH2 = 6;
1101
1609
  function defaultForSchema(schema) {
1102
1610
  if (!schema) return null;
@@ -1889,6 +2397,9 @@ var DocsLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1889
2397
  const { state, config, setSelectedEndpoint } = chunkIULI4XII_cjs.usePlaygroundContext();
1890
2398
  const isDesktop = hooks.useMediaQuery("(min-width: 1024px)");
1891
2399
  const isMobile = !isDesktop;
2400
+ const grouping = config.schemaGrouping ?? "selector";
2401
+ const preloadAll = grouping === "sections";
2402
+ const urlSyncEnabled = typeof config.urlSync === "boolean" ? config.urlSync : Boolean(config.urlSync?.enabled);
1892
2403
  const {
1893
2404
  endpoints,
1894
2405
  schemaInfo,
@@ -1898,16 +2409,26 @@ var DocsLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1898
2409
  error,
1899
2410
  schemas,
1900
2411
  currentSchema,
1901
- setCurrentSchema
2412
+ setCurrentSchema,
2413
+ schemasData
1902
2414
  } = useOpenApiSchema({
1903
2415
  schemas: config.schemas,
1904
2416
  defaultSchemaId: config.defaultSchemaId,
1905
- baseUrl: config.baseUrl
2417
+ baseUrl: config.baseUrl,
2418
+ preloadAll
1906
2419
  });
1907
2420
  const [activeAnchor, setActiveAnchor] = React6.useState(null);
2421
+ const [activeSchemaId, setActiveSchemaId] = React6.useState(null);
1908
2422
  const [sheetOpen, setSheetOpen] = React6.useState(false);
1909
2423
  const docsRef = React6.useRef(null);
1910
2424
  const slideOpen = !isMobile && state.selectedEndpoint !== null;
2425
+ const endpointsBySchema = React6.useMemo(() => {
2426
+ if (grouping !== "sections") return {};
2427
+ const byId = lodashEs.keyBy(schemasData, (e) => e.source.id);
2428
+ const out = {};
2429
+ for (const src of schemas) out[src.id] = byId[src.id]?.endpoints ?? [];
2430
+ return out;
2431
+ }, [grouping, schemasData, schemas]);
1911
2432
  const handleTry = React6.useCallback(
1912
2433
  (ep) => {
1913
2434
  setSelectedEndpoint(ep);
@@ -1918,29 +2439,71 @@ var DocsLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1918
2439
  const handleCloseSlide = React6.useCallback(() => {
1919
2440
  setSelectedEndpoint(null);
1920
2441
  }, [setSelectedEndpoint]);
1921
- const handleNavigate = React6.useCallback((anchor) => {
1922
- docsRef.current?.scrollToAnchor(anchor);
2442
+ const handleNavigate = React6.useCallback(
2443
+ (anchor, schemaId) => {
2444
+ if (schemaId && schemaId !== currentSchema?.id && grouping === "selector") {
2445
+ setCurrentSchema(schemaId);
2446
+ requestAnimationFrame(() => {
2447
+ docsRef.current?.scrollToAnchor(anchor);
2448
+ });
2449
+ return;
2450
+ }
2451
+ docsRef.current?.scrollToAnchor(anchor);
2452
+ },
2453
+ [currentSchema?.id, grouping, setCurrentSchema]
2454
+ );
2455
+ const handleActiveChange = React6.useCallback((anchor, schemaId) => {
2456
+ setActiveAnchor(anchor);
2457
+ setActiveSchemaId(schemaId);
1923
2458
  }, []);
1924
- if (loading) {
1925
- return /* @__PURE__ */ jsxRuntime.jsxs(
1926
- "div",
1927
- {
1928
- className: "grid grid-cols-[260px_1fr] min-h-0 overflow-hidden",
1929
- style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
1930
- children: [
1931
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-r p-3 space-y-1.5", children: Array.from({ length: 12 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-full rounded" }, i)) }),
1932
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-8 space-y-4", children: [
1933
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-1/2" }),
1934
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-full" }),
1935
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-3/4" }),
1936
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 space-y-6", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1937
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-6 w-1/3" }),
1938
- /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-20 w-full" })
1939
- ] }, i)) })
1940
- ] })
1941
- ]
2459
+ const effectiveSchemaId = grouping === "sections" ? activeSchemaId : currentSchema?.id ?? null;
2460
+ const handleHashTarget = React6.useCallback(
2461
+ (target) => {
2462
+ if (!target.schemaId && !target.anchor) return;
2463
+ const matched = target.schemaId ? schemas.find((s) => s.id === target.schemaId || slugifySchemaId(s.id) === target.schemaId) : null;
2464
+ const needsSchemaSwitch = matched && grouping === "selector" && matched.id !== currentSchema?.id;
2465
+ if (needsSchemaSwitch) {
2466
+ setCurrentSchema(matched.id);
1942
2467
  }
1943
- );
2468
+ if (target.anchor) {
2469
+ const anchor = target.anchor;
2470
+ if (needsSchemaSwitch) {
2471
+ requestAnimationFrame(() => {
2472
+ docsRef.current?.scrollToAnchor(anchor);
2473
+ });
2474
+ } else {
2475
+ docsRef.current?.scrollToAnchor(anchor);
2476
+ }
2477
+ }
2478
+ },
2479
+ [schemas, grouping, currentSchema?.id, setCurrentSchema]
2480
+ );
2481
+ useDocsUrlSync({
2482
+ enabled: urlSyncEnabled,
2483
+ currentSchemaId: effectiveSchemaId,
2484
+ activeAnchor,
2485
+ onHashTarget: handleHashTarget
2486
+ });
2487
+ if (loading) {
2488
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[260px_1fr] items-start", children: [
2489
+ /* @__PURE__ */ jsxRuntime.jsx(
2490
+ "div",
2491
+ {
2492
+ className: "sticky top-[var(--navbar-height,64px)] border-r p-3 space-y-1.5 overflow-y-auto",
2493
+ style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
2494
+ children: Array.from({ length: 12 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-full rounded" }, i))
2495
+ }
2496
+ ),
2497
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-8 space-y-4", children: [
2498
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-8 w-1/2" }),
2499
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-full" }),
2500
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-4 w-3/4" }),
2501
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-8 space-y-6", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
2502
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-6 w-1/3" }),
2503
+ /* @__PURE__ */ jsxRuntime.jsx(components.Skeleton, { className: "h-20 w-full" })
2504
+ ] }, i)) })
2505
+ ] })
2506
+ ] });
1944
2507
  }
1945
2508
  if (error) {
1946
2509
  return /* @__PURE__ */ jsxRuntime.jsx(
@@ -1956,40 +2519,44 @@ var DocsLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1956
2519
  );
1957
2520
  }
1958
2521
  if (isMobile) {
1959
- return /* @__PURE__ */ jsxRuntime.jsxs(
2522
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col", children: [
2523
+ /* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
2524
+ grouping === "sections" ? /* @__PURE__ */ jsxRuntime.jsx(
2525
+ DocsView,
2526
+ {
2527
+ ref: docsRef,
2528
+ grouping: "sections",
2529
+ schemasData,
2530
+ selectedVersion: state.selectedVersion,
2531
+ loadedEndpoint: state.selectedEndpoint,
2532
+ onTryEndpoint: handleTry,
2533
+ onActiveChange: handleActiveChange
2534
+ }
2535
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2536
+ DocsView,
2537
+ {
2538
+ ref: docsRef,
2539
+ info: schemaInfo,
2540
+ rawSchema,
2541
+ resolvedBaseUrl,
2542
+ endpoints,
2543
+ selectedVersion: state.selectedVersion,
2544
+ loadedEndpoint: state.selectedEndpoint,
2545
+ onTryEndpoint: handleTry,
2546
+ onActiveChange: handleActiveChange
2547
+ }
2548
+ ),
2549
+ /* @__PURE__ */ jsxRuntime.jsx(TryItSheet, { open: sheetOpen, onOpenChange: setSheetOpen })
2550
+ ] });
2551
+ }
2552
+ return /* @__PURE__ */ jsxRuntime.jsx(components.TooltipProvider, { delayDuration: 350, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-[260px_minmax(0,1fr)] items-start", children: [
2553
+ /* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
2554
+ /* @__PURE__ */ jsxRuntime.jsx(
1960
2555
  "div",
1961
2556
  {
1962
- className: "flex flex-col overflow-hidden",
2557
+ className: "sticky top-[var(--navbar-height,64px)]",
1963
2558
  style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
1964
- children: [
1965
- /* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
1966
- /* @__PURE__ */ jsxRuntime.jsx(
1967
- DocsView,
1968
- {
1969
- ref: docsRef,
1970
- info: schemaInfo,
1971
- rawSchema,
1972
- resolvedBaseUrl,
1973
- endpoints,
1974
- selectedVersion: state.selectedVersion,
1975
- loadedEndpoint: state.selectedEndpoint,
1976
- onTryEndpoint: handleTry,
1977
- onActiveChange: setActiveAnchor
1978
- }
1979
- ),
1980
- /* @__PURE__ */ jsxRuntime.jsx(TryItSheet, { open: sheetOpen, onOpenChange: setSheetOpen })
1981
- ]
1982
- }
1983
- );
1984
- }
1985
- return /* @__PURE__ */ jsxRuntime.jsx(components.TooltipProvider, { delayDuration: 350, children: /* @__PURE__ */ jsxRuntime.jsxs(
1986
- "div",
1987
- {
1988
- className: "grid grid-cols-[260px_minmax(0,1fr)] min-h-0 overflow-hidden",
1989
- style: { height: "calc(100dvh - var(--navbar-height, 64px))" },
1990
- children: [
1991
- /* @__PURE__ */ jsxRuntime.jsx(EndpointDraftSync, { schemaId: currentSchema?.id ?? null }),
1992
- /* @__PURE__ */ jsxRuntime.jsx(
2559
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1993
2560
  DocsSidebar,
1994
2561
  {
1995
2562
  info: schemaInfo,
@@ -1999,29 +2566,44 @@ var DocsLayout = /* @__PURE__ */ chunkWGEGR3DF_cjs.__name(() => {
1999
2566
  onSchemaChange: setCurrentSchema,
2000
2567
  activeEndpointId: activeAnchor,
2001
2568
  selectedVersion: state.selectedVersion,
2002
- onNavigate: handleNavigate
2003
- }
2004
- ),
2005
- /* @__PURE__ */ jsxRuntime.jsx(
2006
- DocsView,
2007
- {
2008
- ref: docsRef,
2009
- info: schemaInfo,
2569
+ onNavigate: handleNavigate,
2570
+ grouping,
2571
+ endpointsBySchema,
2010
2572
  rawSchema,
2011
- resolvedBaseUrl,
2012
- endpoints,
2013
- selectedVersion: state.selectedVersion,
2014
- loadedEndpoint: state.selectedEndpoint,
2015
- onTryEndpoint: handleTry,
2016
- onActiveChange: setActiveAnchor
2573
+ resolvedBaseUrl
2017
2574
  }
2018
- ),
2019
- /* @__PURE__ */ jsxRuntime.jsx(SlideInPlayground, { open: slideOpen, onClose: handleCloseSlide })
2020
- ]
2021
- }
2022
- ) });
2575
+ )
2576
+ }
2577
+ ),
2578
+ grouping === "sections" ? /* @__PURE__ */ jsxRuntime.jsx(
2579
+ DocsView,
2580
+ {
2581
+ ref: docsRef,
2582
+ grouping: "sections",
2583
+ schemasData,
2584
+ selectedVersion: state.selectedVersion,
2585
+ loadedEndpoint: state.selectedEndpoint,
2586
+ onTryEndpoint: handleTry,
2587
+ onActiveChange: handleActiveChange
2588
+ }
2589
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
2590
+ DocsView,
2591
+ {
2592
+ ref: docsRef,
2593
+ info: schemaInfo,
2594
+ rawSchema,
2595
+ resolvedBaseUrl,
2596
+ endpoints,
2597
+ selectedVersion: state.selectedVersion,
2598
+ loadedEndpoint: state.selectedEndpoint,
2599
+ onTryEndpoint: handleTry,
2600
+ onActiveChange: handleActiveChange
2601
+ }
2602
+ ),
2603
+ /* @__PURE__ */ jsxRuntime.jsx(SlideInPlayground, { open: slideOpen, onClose: handleCloseSlide })
2604
+ ] }) });
2023
2605
  }, "DocsLayout");
2024
2606
 
2025
2607
  exports.DocsLayout = DocsLayout;
2026
- //# sourceMappingURL=DocsLayout-BCVU6TTX.cjs.map
2027
- //# sourceMappingURL=DocsLayout-BCVU6TTX.cjs.map
2608
+ //# sourceMappingURL=DocsLayout-YDR7DSMM.cjs.map
2609
+ //# sourceMappingURL=DocsLayout-YDR7DSMM.cjs.map