rapidoc 11.0.0 → 12.0.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.
Files changed (80) hide show
  1. package/README.md +46 -31
  2. package/dist/rapidoc-min.js +1424 -213
  3. package/dist/rapidoc-static-min.js +13542 -0
  4. package/package.json +48 -34
  5. package/src/components/api-request.ts +869 -0
  6. package/src/components/api-response.ts +509 -0
  7. package/src/components/json-tree.ts +171 -0
  8. package/src/components/schema-base-element.ts +315 -0
  9. package/src/components/schema-table.ts +430 -0
  10. package/src/components/schema-tree.ts +386 -0
  11. package/src/components/tag-input.ts +184 -0
  12. package/src/index.js +6 -0
  13. package/src/oauth-receiver.ts +29 -0
  14. package/src/rapidoc-mini.ts +582 -0
  15. package/src/rapidoc.ts +1808 -0
  16. package/src/static/index.d.ts +149 -0
  17. package/src/static/index.js +62 -0
  18. package/src/static/navigation.js +497 -0
  19. package/src/static/render.js +490 -0
  20. package/src/static/serializer.js +216 -0
  21. package/src/styles/auth-styles.js +318 -0
  22. package/src/styles/border-styles.js +24 -0
  23. package/src/styles/css-bundle.js +129 -0
  24. package/src/styles/custom-styles.js +8 -0
  25. package/src/styles/dialog-box-styles.js +102 -0
  26. package/src/styles/endpoint-styles.js +559 -0
  27. package/src/styles/flex-styles.js +16 -0
  28. package/src/styles/font-styles.js +432 -0
  29. package/src/styles/info-styles.js +36 -0
  30. package/src/styles/input-styles.js +555 -0
  31. package/src/styles/layout-styles.js +396 -0
  32. package/src/styles/microlighter-styles.js +99 -0
  33. package/src/styles/nav-styles.js +609 -0
  34. package/src/styles/param-list-styles.js +261 -0
  35. package/src/styles/schema-styles.js +288 -0
  36. package/src/styles/tab-styles.js +106 -0
  37. package/src/styles/theme-tokens.js +582 -0
  38. package/src/templates/advanced-search-dialog-template.js +94 -0
  39. package/src/templates/api-response-template.js +219 -0
  40. package/src/templates/callback-template.js +86 -0
  41. package/src/templates/code-samples-template.js +52 -0
  42. package/src/templates/components-template.js +86 -0
  43. package/src/templates/downloads-template.js +85 -0
  44. package/src/templates/endpoint-template.js +386 -0
  45. package/src/templates/expanded-endpoint-template.js +266 -0
  46. package/src/templates/focused-endpoint-template.js +145 -0
  47. package/src/templates/header-template.js +92 -0
  48. package/src/templates/logo-template.js +21 -0
  49. package/src/templates/main-body-template.js +102 -0
  50. package/src/templates/navbar-template.js +489 -0
  51. package/src/templates/overview-template.js +104 -0
  52. package/src/templates/request-body-template.js +651 -0
  53. package/src/templates/request-params-template.js +474 -0
  54. package/src/templates/security-scheme-template.js +1263 -0
  55. package/src/templates/server-template.js +152 -0
  56. package/src/utils/auto-color-scheme.js +99 -0
  57. package/src/utils/bind-navbar.js +175 -0
  58. package/src/utils/color-utils.js +59 -0
  59. package/src/utils/common-utils.js +191 -0
  60. package/src/utils/curl-utils.js +123 -0
  61. package/src/utils/highlighter.js +416 -0
  62. package/src/utils/markdown-utils.js +110 -0
  63. package/src/utils/mcp/common.js +467 -0
  64. package/src/utils/mcp/generators/csharp.js +242 -0
  65. package/src/utils/mcp/generators/go.js +298 -0
  66. package/src/utils/mcp/generators/java.js +330 -0
  67. package/src/utils/mcp/generators/python.js +248 -0
  68. package/src/utils/mcp/generators/rust.js +281 -0
  69. package/src/utils/mcp/generators/typescript.js +290 -0
  70. package/src/utils/mcp-generator.js +143 -0
  71. package/src/utils/mock-interceptor.js +508 -0
  72. package/src/utils/oauth-utils.js +87 -0
  73. package/src/utils/request-utils.js +203 -0
  74. package/src/utils/response-utils.js +203 -0
  75. package/src/utils/sanitize.js +57 -0
  76. package/src/utils/schema-utils.js +1927 -0
  77. package/src/utils/slugger.js +189 -0
  78. package/src/utils/spec-parser.js +915 -0
  79. package/src/utils/url-utils.js +211 -0
  80. package/src/utils/xml-utils.js +61 -0
@@ -0,0 +1,489 @@
1
+ /**
2
+ * Renders the sidebar navigation panel with search filter, tag groupings, method badges, and link routing.
3
+ */
4
+ import { html, nothing } from "lit";
5
+ import Slugger from "github-slugger";
6
+ import { getMatchedPaths, isInternalOrHidden } from "~/utils/common-utils";
7
+
8
+ export function expandCollapseNavBarTag(navLinkEl, action = "toggle") {
9
+ const tagAndPathEl = navLinkEl?.closest(".nav-bar-tag-and-paths");
10
+ const pathsUnderTagEl = tagAndPathEl?.querySelector(".nav-bar-paths-under-tag");
11
+ if (tagAndPathEl) {
12
+ const isExpanded = tagAndPathEl.classList.contains("expanded");
13
+ if (isExpanded && (action === "toggle" || action === "collapse")) {
14
+ if (pathsUnderTagEl) pathsUnderTagEl.style.maxHeight = 0;
15
+ tagAndPathEl.classList.replace("expanded", "collapsed");
16
+ tagAndPathEl.querySelector(".nav-bar-tag")?.setAttribute("aria-expanded", "false");
17
+ } else if (!isExpanded && (action === "toggle" || action === "expand")) {
18
+ tagAndPathEl.classList.replace("collapsed", "expanded");
19
+ if (pathsUnderTagEl)
20
+ pathsUnderTagEl.style.maxHeight = pathsUnderTagEl.scrollHeight
21
+ ? `${pathsUnderTagEl.scrollHeight}px`
22
+ : null;
23
+ tagAndPathEl.querySelector(".nav-bar-tag")?.setAttribute("aria-expanded", "true");
24
+ }
25
+ }
26
+ }
27
+
28
+ export function expandCollapseNavBarTagGroup(navLinkEl, action = "toggle") {
29
+ const tagGroupEl = navLinkEl?.closest(".nav-bar-tag-group");
30
+ if (tagGroupEl) {
31
+ const isExpanded = tagGroupEl.classList.contains("expanded");
32
+ if (isExpanded && (action === "toggle" || action === "collapse")) {
33
+ tagGroupEl.classList.replace("expanded", "collapsed");
34
+ tagGroupEl.querySelector(".nav-bar-tag-group-header")?.setAttribute("aria-expanded", "false");
35
+ } else if (!isExpanded && (action === "toggle" || action === "expand")) {
36
+ tagGroupEl.classList.replace("collapsed", "expanded");
37
+ tagGroupEl.querySelector(".nav-bar-tag-group-header")?.setAttribute("aria-expanded", "true");
38
+ }
39
+ }
40
+ }
41
+
42
+ export function expandParentNavContainers(navLinkEl) {
43
+ if (!navLinkEl) return;
44
+ expandCollapseNavBarTagGroup(navLinkEl, "expand");
45
+ expandCollapseNavBarTag(navLinkEl, "expand");
46
+ }
47
+
48
+ export { isInternalOrHidden };
49
+
50
+ export function isNavPathVisible(path, searchVal, tagName) {
51
+ if (isInternalOrHidden(path)) {
52
+ return false;
53
+ }
54
+ if (searchVal) {
55
+ return getMatchedPaths(searchVal, path, tagName);
56
+ }
57
+ return true;
58
+ }
59
+
60
+ export function isNavTagVisible(tag, searchVal) {
61
+ if (isInternalOrHidden(tag)) {
62
+ return false;
63
+ }
64
+ return (tag.paths || []).some((path) => isNavPathVisible(path, searchVal, tag.name));
65
+ }
66
+
67
+ export function isNavTagGroupVisible(group, searchVal) {
68
+ if (isInternalOrHidden(group)) {
69
+ return false;
70
+ }
71
+ return (group.tags || []).some((tag) => isNavTagVisible(tag, searchVal));
72
+ }
73
+
74
+ export function expandCollapseAll(event, action = "expand-all") {
75
+ if (!(event.type === "click" || (event.type === "keyup" && event.keyCode === 13))) {
76
+ return;
77
+ }
78
+ const navEl = event.target.closest(".nav-scroll");
79
+ const groupList = [...navEl.querySelectorAll(".nav-bar-tag-group")];
80
+ if (action === "expand-all") {
81
+ groupList.forEach((el) => {
82
+ el.classList.replace("collapsed", "expanded");
83
+ el.querySelector(".nav-bar-tag-group-header")?.setAttribute("aria-expanded", "true");
84
+ });
85
+ } else {
86
+ groupList.forEach((el) => {
87
+ el.classList.replace("expanded", "collapsed");
88
+ el.querySelector(".nav-bar-tag-group-header")?.setAttribute("aria-expanded", "false");
89
+ });
90
+ }
91
+ const elList = [...navEl.querySelectorAll(".nav-bar-tag-and-paths")];
92
+ if (action === "expand-all") {
93
+ elList.forEach((el) => {
94
+ const navBarPathsUnderTagEl = el.querySelector(".nav-bar-paths-under-tag");
95
+ el.classList.replace("collapsed", "expanded");
96
+ if (navBarPathsUnderTagEl) {
97
+ navBarPathsUnderTagEl.style.maxHeight = `${navBarPathsUnderTagEl?.scrollHeight}px`;
98
+ }
99
+ });
100
+ } else {
101
+ elList.forEach((el) => {
102
+ el.classList.replace("expanded", "collapsed");
103
+ // el.querySelector('.nav-bar-paths-under-tag').style.maxHeight = 0;
104
+ });
105
+ }
106
+ }
107
+
108
+ export function navBarClickAndEnterHandler(event) {
109
+ if (!(event.type === "click" || (event.type === "keyup" && event.keyCode === 13))) {
110
+ return;
111
+ }
112
+ const navEl = event.target.closest("[data-action]") || event.target;
113
+ // Ignore clicks or enter inside the search / filter controls or logo slot
114
+ if (
115
+ navEl.closest("#nav-bar-search") ||
116
+ navEl.closest("#advanced-search-btn") ||
117
+ navEl.closest('[part~="btn-clear-filter"]') ||
118
+ navEl.closest('slot[name="nav-logo"]')
119
+ ) {
120
+ return;
121
+ }
122
+ event.stopPropagation();
123
+ if (navEl.dataset?.action === "navigate") {
124
+ this.scrollToEventTarget(event, false);
125
+ const navBarEl = event.currentTarget.closest("#nav-bar");
126
+ // hide the navigation bar incase of floating navigation
127
+ if (navBarEl.classList.contains("floating-nav")) {
128
+ navBarEl.classList.remove("floating-nav");
129
+ }
130
+ } else if (navEl.dataset?.action === "expand-all" || navEl.dataset?.action === "collapse-all") {
131
+ expandCollapseAll(event, navEl.dataset.action);
132
+ } else if (navEl.dataset?.action === "expand-collapse-tag-group") {
133
+ expandCollapseNavBarTagGroup(navEl, "toggle");
134
+ } else if (navEl.dataset?.action === "expand-collapse-tag") {
135
+ expandCollapseNavBarTag(navEl, "toggle");
136
+ }
137
+ }
138
+
139
+ export default function navbarTemplate() {
140
+ const slugger = new Slugger();
141
+ let isFirstNavItem = true;
142
+ function checkFirstNav() {
143
+ if (isFirstNavItem) {
144
+ isFirstNavItem = false;
145
+ return true;
146
+ }
147
+ return false;
148
+ }
149
+ if (!this.resolvedSpec || this.resolvedSpec.specLoadError) {
150
+ return html`<nav class="nav-bar" part="section-navbar">
151
+ <div class="nav-bar-header" part="section-navbar-header">
152
+ <slot name="nav-logo" class="logo" part="section-navbar-logo"></slot>
153
+ </div>
154
+ </nav>`;
155
+ }
156
+ return html`
157
+ <button id="nav-bar-btn" part="btn-navbar" class="btn" @click="${this.onOpenNavBarToggle}">☰</button>
158
+ <nav id="nav-bar" class="nav-bar ${this.renderStyle} overflow-${this.navItemOverflow || "ellipsis"}" part="section-navbar">
159
+ <div
160
+ class="nav-scroll"
161
+ tabindex="-1"
162
+ part="section-navbar-scroll"
163
+ @click="${(e) => navBarClickAndEnterHandler.call(this, e)}"
164
+ @keyup="${(e) => navBarClickAndEnterHandler.call(this, e)}"
165
+ >
166
+ <div class="nav-bar-header" part="section-navbar-header">
167
+ <slot name="nav-logo" class="logo" part="section-navbar-logo"></slot>
168
+ ${
169
+ this.allowSearch === "false" && this.allowAdvancedSearch === "false"
170
+ ? ""
171
+ : html`
172
+ <div
173
+ class="nav-bar-search-container ${this.allowAdvancedSearch === "false" ? "has-bottom-border" : ""}"
174
+ part="section-navbar-search"
175
+ >
176
+ ${
177
+ this.allowSearch === "false"
178
+ ? ""
179
+ : html`
180
+ <div class="nav-bar-search-input-wrapper">
181
+ <input
182
+ id="nav-bar-search"
183
+ part="textbox textbox-nav-filter"
184
+ class="nav-bar-search-input"
185
+ type="text"
186
+ placeholder="Filter"
187
+ @change="${this.onSearchChange}"
188
+ spellcheck="false"
189
+ />
190
+ <div class="nav-bar-search-icon" @click="${this.onSearchChange}">&#x21a9;</div>
191
+ </div>
192
+ ${
193
+ this.searchVal
194
+ ? html` <button
195
+ @click="${this.onClearSearch}"
196
+ class="btn btn-outline btn-clear-filter"
197
+ part="btn btn-outline btn-clear-filter"
198
+ >
199
+ CLEAR
200
+ </button>`
201
+ : ""
202
+ }
203
+ `
204
+ }
205
+ ${
206
+ this.allowAdvancedSearch === "false" || this.searchVal
207
+ ? ""
208
+ : html`
209
+ <button
210
+ id="advanced-search-btn"
211
+ class="btn btn-primary"
212
+ part="btn btn-fill btn-search"
213
+ @click="${this.onShowAdvancedSearchClicked}"
214
+ >
215
+ SEARCH
216
+ </button>
217
+ `
218
+ }
219
+ </div>
220
+ `
221
+ }
222
+ </div>
223
+ ${
224
+ this.showInfo === "false" || !this.resolvedSpec.info
225
+ ? ""
226
+ : html`
227
+ ${
228
+ this.infoDescriptionHeadingsInNavBar === "true"
229
+ ? html`
230
+ ${
231
+ this.resolvedSpec.infoDescriptionHeaders.length > 0
232
+ ? (() => {
233
+ const isFirst = checkFirstNav();
234
+ return html`<div
235
+ class="nav-bar-info${isFirst ? " first-nav-item" : ""}"
236
+ id="link-overview"
237
+ data-content-id="overview"
238
+ data-action="navigate"
239
+ data-first-nav-item="${isFirst ? "true" : nothing}"
240
+ tabindex="0"
241
+ part="section-navbar-item section-navbar-overview"
242
+ >
243
+ ${this.resolvedSpec.info?.title?.trim() || "Overview"}
244
+ </div>`;
245
+ })()
246
+ : ""
247
+ }
248
+ <div class="overview-headers">
249
+ ${this.resolvedSpec.infoDescriptionHeaders.map((header) => {
250
+ const headerElId = slugger.slug(header.text);
251
+ return html`<div
252
+ class="nav-bar-h${header.depth}"
253
+ id="link-overview--${headerElId}"
254
+ data-action="navigate"
255
+ data-content-id="overview--${headerElId}"
256
+ >
257
+ ${header.text}
258
+ </div>`;
259
+ })}
260
+ </div>
261
+ ${
262
+ this.resolvedSpec.infoDescriptionHeaders.length > 0
263
+ ? html`<hr style="border-top: 1px solid var(--muted); border-width:1px 0 0 0; margin: 15px 0 0 0" />`
264
+ : ""
265
+ }
266
+ `
267
+ : (() => {
268
+ const isFirst = checkFirstNav();
269
+ return html`<div
270
+ class="nav-bar-info${isFirst ? " first-nav-item" : ""}"
271
+ id="link-overview"
272
+ data-action="navigate"
273
+ data-content-id="overview"
274
+ data-first-nav-item="${isFirst ? "true" : nothing}"
275
+ tabindex="0"
276
+ >
277
+ ${this.resolvedSpec.info?.title?.trim() || "Overview"}
278
+ </div>`;
279
+ })()
280
+ }
281
+ `
282
+ }
283
+ ${
284
+ this.allowServerSelection === "false"
285
+ ? ""
286
+ : (() => {
287
+ const isFirst = checkFirstNav();
288
+ return html`<div
289
+ class="nav-bar-info${isFirst ? " first-nav-item" : ""}"
290
+ id="link-servers"
291
+ data-action="navigate"
292
+ data-content-id="servers"
293
+ data-first-nav-item="${isFirst ? "true" : nothing}"
294
+ tabindex="0"
295
+ part="section-navbar-item section-navbar-servers"
296
+ >
297
+ API Servers
298
+ </div>`;
299
+ })()
300
+ }
301
+ ${
302
+ this.allowAuthentication === "false" || !this.resolvedSpec.securitySchemes
303
+ ? ""
304
+ : (() => {
305
+ const isFirst = checkFirstNav();
306
+ return html`<div
307
+ class="nav-bar-info${isFirst ? " first-nav-item" : ""}"
308
+ id="link-auth"
309
+ data-action="navigate"
310
+ data-content-id="auth"
311
+ data-first-nav-item="${isFirst ? "true" : nothing}"
312
+ tabindex="0"
313
+ part="section-navbar-item section-navbar-auth"
314
+ >
315
+ Authentication
316
+ </div>`;
317
+ })()
318
+ }
319
+
320
+ <div
321
+ id="link-operations-top"
322
+ class="nav-bar-section operations"
323
+ data-action="navigate"
324
+ data-content-id="${this.renderStyle === "focused" ? "" : "operations-top"}"
325
+ part="section-navbar-item section-navbar-operations-top"
326
+ >
327
+ <div style="font-size:16px; display:flex; margin-left:10px;">
328
+ ${
329
+ this.renderStyle === "focused"
330
+ ? html`<div class="nav-bar-expand-all" data-action="expand-all" tabindex="0" title="Expand all">▸</div>
331
+ <div class="nav-bar-collapse-all" data-action="collapse-all" tabindex="0" title="Collapse all">▸</div>`
332
+ : ""
333
+ }
334
+ </div>
335
+ <div class="nav-bar-section-title">OPERATIONS</div>
336
+ </div>
337
+
338
+ <!-- TAGS AND PATHS (3-tier if tagGroups exist, else 2-tier) -->
339
+ ${(() => {
340
+ const renderNavTagItem = (tag) => {
341
+ const visiblePaths = (tag.paths || []).filter((p) =>
342
+ isNavPathVisible(p, this.searchVal, tag.name),
343
+ );
344
+ if (visiblePaths.length === 0) return "";
345
+ const firstPathId = visiblePaths[0].elementId;
346
+
347
+ return html` <div class="nav-bar-tag-and-paths ${tag.expanded ? "expanded" : "collapsed"}">
348
+ <div
349
+ class="nav-bar-tag"
350
+ part="section-navbar-item section-navbar-tag"
351
+ id="link-${tag.elementId}"
352
+ data-action="expand-collapse-tag"
353
+ data-first-path-id="${firstPathId}"
354
+ tabindex="0"
355
+ role="button"
356
+ aria-expanded="${tag.expanded ? "true" : "false"}"
357
+ >
358
+ <div class="nav-bar-tag-title">${tag.displayName || tag.name}</div>
359
+ <div class="nav-bar-tag-icon" tabindex="0" data-action="expand-collapse-tag"></div>
360
+ </div>
361
+ ${
362
+ this.infoDescriptionHeadingsInNavBar === "true"
363
+ ? html` <div class="tag-headers">
364
+ ${(() => {
365
+ const tagSlugger = new Slugger();
366
+ return tag.headers.map((header) => {
367
+ const headerElId = tagSlugger.slug(header.text);
368
+ return html` <div
369
+ class="nav-bar-h${header.depth}"
370
+ part="section-navbar-item section-navbar-h${header.depth}"
371
+ id="link-${tag.elementId}--${headerElId}"
372
+ data-action="navigate"
373
+ data-content-id="${tag.elementId}--${headerElId}"
374
+ tabindex="0"
375
+ >
376
+ ${header.text}
377
+ </div>`;
378
+ });
379
+ })()}
380
+ </div>`
381
+ : ""
382
+ }
383
+ <div class="nav-bar-paths-under-tag">
384
+ <!-- Paths in each tag (endpoints) -->
385
+ ${visiblePaths.map((p) => {
386
+ const isFirst = checkFirstNav();
387
+ return html` <div
388
+ class="nav-bar-path${isFirst ? " first-nav-item" : ""}"
389
+ style="${p.deprecated ? "filter:opacity(0.5);" : ""}"
390
+ part="section-navbar-item section-navbar-path"
391
+ data-action="navigate"
392
+ data-content-id="${p.elementId}"
393
+ data-first-nav-item="${isFirst ? "true" : nothing}"
394
+ id="link-${p.elementId}"
395
+ tabindex="0"
396
+ >
397
+ <span class="nav-bar-path-label">
398
+ ${p.isWebhook ? html`<span class="nav-bar-webhook">WEBHOOK</span>` : ""}
399
+ ${this.usePathInNavBar === "true" ? html`<span class="mono-font">${p.path}</span>` : p.summary || p.shortSummary}
400
+ </span>
401
+ ${html`<span class="nav-method ${this.showMethodInNavBar} ${p.method}">
402
+ ${this.showMethodInNavBar === "as-colored-block" ? p.method.substring(0, 3).toUpperCase() : p.method.toUpperCase()}
403
+ </span>`}
404
+ </div>`;
405
+ })}
406
+ </div>
407
+ </div>`;
408
+ };
409
+
410
+ if (this.resolvedSpec.tagGroups && this.resolvedSpec.tagGroups.length > 0) {
411
+ const assignedTagNames = new Set();
412
+ this.resolvedSpec.tagGroups.forEach((group) => {
413
+ (group.tags || []).forEach((tag) => {
414
+ assignedTagNames.add(tag.name.toLowerCase());
415
+ });
416
+ });
417
+
418
+ const renderedGroups = this.resolvedSpec.tagGroups
419
+ .filter((group) => isNavTagGroupVisible(group, this.searchVal))
420
+ .map((group) => {
421
+ const groupTags = group.tags.filter((tag) => isNavTagVisible(tag, this.searchVal));
422
+ if (groupTags.length === 0) return "";
423
+ return html`
424
+ <div class="nav-bar-tag-group ${group.expanded ? "expanded" : "collapsed"}" id="link-${group.elementId}">
425
+ <div
426
+ class="nav-bar-tag-group-header"
427
+ part="section-navbar-item section-navbar-tag-group"
428
+ data-action="expand-collapse-tag-group"
429
+ tabindex="0"
430
+ role="button"
431
+ aria-expanded="${group.expanded ? "true" : "false"}"
432
+ >
433
+ <div class="nav-bar-tag-group-title">${group.displayName || group.name}</div>
434
+ <div class="nav-bar-tag-group-icon" tabindex="0" data-action="expand-collapse-tag-group"></div>
435
+ </div>
436
+ <div class="nav-bar-tags-under-group">${groupTags.map((tag) => renderNavTagItem(tag))}</div>
437
+ </div>
438
+ `;
439
+ });
440
+
441
+ const remainingTags = (this.resolvedSpec.tags || [])
442
+ .filter(
443
+ (tag) =>
444
+ !assignedTagNames.has(tag.name.toLowerCase()) &&
445
+ isNavTagVisible(tag, this.searchVal),
446
+ )
447
+ .map((tag) => renderNavTagItem(tag));
448
+
449
+ return html`${renderedGroups}${remainingTags}`;
450
+ }
451
+
452
+ return (this.resolvedSpec.tags || [])
453
+ .filter((tag) => isNavTagVisible(tag, this.searchVal))
454
+ .map((tag) => renderNavTagItem(tag));
455
+ })()}
456
+
457
+ <!-- COMPONENTS -->
458
+ ${
459
+ this.resolvedSpec.components && this.showComponents === "true"
460
+ ? html` <div id="link-components" class="nav-bar-section components">
461
+ <div class="nav-bar-section-title">COMPONENTS</div>
462
+ </div>
463
+ ${this.resolvedSpec.components.map((component) =>
464
+ component.subComponents.length
465
+ ? html` <div
466
+ class="nav-bar-tag"
467
+ part="section-navbar-item section-navbar-tag"
468
+ data-action="navigate"
469
+ data-content-id="cmp--${component.name.toLowerCase()}"
470
+ id="link-cmp--${component.name.toLowerCase()}"
471
+ >
472
+ ${component.name}
473
+ </div>
474
+ ${component.subComponents
475
+ .filter((p) => p.expanded !== false)
476
+ .map(
477
+ (p) =>
478
+ html` <div class="nav-bar-path" data-action="navigate" data-content-id="cmp--${p.id}" id="link-cmp--${p.id}">
479
+ <span style="pointer-events: none;"> ${p.name} </span>
480
+ </div>`,
481
+ )}`
482
+ : "",
483
+ )}`
484
+ : ""
485
+ }
486
+ </div>
487
+ </nav>
488
+ `;
489
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Renders the API specification overview header with metadata, description markdown, contact, license, and download links.
3
+ */
4
+ import { fixRenderedAnchorLinks } from "~/utils/markdown-utils";
5
+ import { html } from "lit";
6
+ import { unsafeHTML } from "lit/directives/unsafe-html.js";
7
+ import { sanitizeHTML } from "../utils/sanitize.js";
8
+ import Slugger from "github-slugger";
9
+ import { marked } from "marked";
10
+
11
+ function headingRenderer() {
12
+ const slugger = new Slugger();
13
+ const renderer = new marked.Renderer();
14
+ // renderer.heading = (text, level, raw, slugger) => `<h${level} class="observe-me" id="overview--${slugger.slug(raw)}">${text}</h${level}>`;
15
+ renderer.heading = ({ text, depth }) =>
16
+ `<h${depth} class="observe-me" id="overview--${slugger.slug(text)}">${text}</h${depth}>`;
17
+ fixRenderedAnchorLinks(renderer);
18
+ return renderer;
19
+ }
20
+
21
+ export default function overviewTemplate() {
22
+ return html`
23
+ <section
24
+ id="overview"
25
+ part="section-overview"
26
+ class="observe-me ${this.renderStyle === "view" ? "section-gap" : "section-gap--read-mode"}"
27
+ >
28
+ ${
29
+ this.resolvedSpec?.info
30
+ ? html`
31
+ <h1 id="api-title" class="rapidoc-heading" part="section-overview-title heading heading-1">
32
+ ${this.resolvedSpec.info.title}
33
+ ${
34
+ !this.resolvedSpec.info.version
35
+ ? ""
36
+ : html`<span class="version" part="label-overview-version">${this.resolvedSpec.info.version}</span>`
37
+ }
38
+ </h1>
39
+ <div id="api-info">
40
+ ${
41
+ this.resolvedSpec.info.contact?.email
42
+ ? html`<span
43
+ >${this.resolvedSpec.info.contact.name || "Email"}:
44
+ <a href="mailto:${this.resolvedSpec.info.contact.email}" part="anchor anchor-overview"
45
+ >${this.resolvedSpec.info.contact.email}</a
46
+ >
47
+ </span>`
48
+ : ""
49
+ }
50
+ ${
51
+ this.resolvedSpec.info.contact?.url
52
+ ? html`<span
53
+ >URL:
54
+ <a href="${this.resolvedSpec.info.contact.url}" part="anchor anchor-overview"
55
+ >${this.resolvedSpec.info.contact.url}</a
56
+ ></span
57
+ >`
58
+ : ""
59
+ }
60
+ ${
61
+ this.resolvedSpec.info.license
62
+ ? html`<span
63
+ >License:
64
+ ${
65
+ this.resolvedSpec.info.license.url
66
+ ? html`<a href="${this.resolvedSpec.info.license.url}" part="anchor anchor-overview"
67
+ >${this.resolvedSpec.info.license.name}</a
68
+ >`
69
+ : this.resolvedSpec.info.license.name
70
+ }
71
+ </span>`
72
+ : ""
73
+ }
74
+ ${
75
+ this.resolvedSpec.info.termsOfService
76
+ ? html`<span
77
+ ><a href="${this.resolvedSpec.info.termsOfService}" part="anchor anchor-overview">Terms of Service</a></span
78
+ >`
79
+ : ""
80
+ }
81
+ </div>
82
+ <slot name="overview"></slot>
83
+ ${
84
+ this.resolvedSpec.info.description
85
+ ? html`<div id="api-description" class="m-markdown regular-font">
86
+ ${unsafeHTML(
87
+ sanitizeHTML(
88
+ marked(
89
+ this.resolvedSpec.info.description,
90
+ this.infoDescriptionHeadingsInNavBar === "true"
91
+ ? { renderer: headingRenderer() }
92
+ : undefined,
93
+ ),
94
+ ),
95
+ )}
96
+ </div>`
97
+ : ""
98
+ }
99
+ `
100
+ : ""
101
+ }
102
+ </section>
103
+ `;
104
+ }