@ng-doc/app 22.0.0 → 22.2.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 (173) hide show
  1. package/LICENSE +21 -0
  2. package/fesm2022/ng-doc-app-classes-content-controller.mjs +22 -4
  3. package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -1
  4. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +36 -12
  5. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
  6. package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
  7. package/fesm2022/ng-doc-app-components-api-list.mjs +7 -5
  8. package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
  9. package/fesm2022/ng-doc-app-components-breadcrumb.mjs +5 -3
  10. package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
  11. package/fesm2022/ng-doc-app-components-code.mjs +6 -4
  12. package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
  13. package/fesm2022/ng-doc-app-components-command-palette.mjs +35 -27
  14. package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -1
  15. package/fesm2022/ng-doc-app-components-copy-button.mjs +6 -4
  16. package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
  17. package/fesm2022/ng-doc-app-components-demo-displayer.mjs +19 -4
  18. package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
  19. package/fesm2022/ng-doc-app-components-demo-frame.mjs +279 -0
  20. package/fesm2022/ng-doc-app-components-demo-frame.mjs.map +1 -0
  21. package/fesm2022/ng-doc-app-components-demo-pane.mjs +2 -2
  22. package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
  23. package/fesm2022/ng-doc-app-components-demo.mjs +97 -14
  24. package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
  25. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +5 -3
  26. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
  27. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +4 -2
  28. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -1
  29. package/fesm2022/ng-doc-app-components-heading-anchor.mjs +5 -3
  30. package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
  31. package/fesm2022/ng-doc-app-components-image-viewer.mjs +5 -3
  32. package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
  33. package/fesm2022/ng-doc-app-components-navbar.mjs +4 -2
  34. package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
  35. package/fesm2022/ng-doc-app-components-page-navigation.mjs +5 -3
  36. package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
  37. package/fesm2022/ng-doc-app-components-page-wrapper.mjs +2 -2
  38. package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
  39. package/fesm2022/ng-doc-app-components-page.mjs +83 -16
  40. package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
  41. package/fesm2022/ng-doc-app-components-playground.mjs +838 -141
  42. package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
  43. package/fesm2022/ng-doc-app-components-root.mjs +51 -4
  44. package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
  45. package/fesm2022/ng-doc-app-components-search-result.mjs +8 -6
  46. package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
  47. package/fesm2022/ng-doc-app-components-search.mjs +7 -5
  48. package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
  49. package/fesm2022/ng-doc-app-components-sidebar.mjs +4 -3
  50. package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
  51. package/fesm2022/ng-doc-app-components-tabs.mjs +21 -3
  52. package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
  53. package/fesm2022/ng-doc-app-components-theme-toggle.mjs +7 -5
  54. package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
  55. package/fesm2022/ng-doc-app-components-toc.mjs +4 -2
  56. package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
  57. package/fesm2022/ng-doc-app-components.mjs +1 -0
  58. package/fesm2022/ng-doc-app-components.mjs.map +1 -1
  59. package/fesm2022/ng-doc-app-constants.mjs +11 -1
  60. package/fesm2022/ng-doc-app-constants.mjs.map +1 -1
  61. package/fesm2022/ng-doc-app-demo-app.mjs +779 -0
  62. package/fesm2022/ng-doc-app-demo-app.mjs.map +1 -0
  63. package/fesm2022/ng-doc-app-helpers.mjs +147 -7
  64. package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
  65. package/fesm2022/ng-doc-app-processors-processors.mjs +30 -9
  66. package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
  67. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +29 -18
  68. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
  69. package/fesm2022/ng-doc-app-providers-texts.mjs +53 -0
  70. package/fesm2022/ng-doc-app-providers-texts.mjs.map +1 -0
  71. package/fesm2022/ng-doc-app-providers-title.mjs +129 -0
  72. package/fesm2022/ng-doc-app-providers-title.mjs.map +1 -0
  73. package/fesm2022/ng-doc-app-providers.mjs +2 -0
  74. package/fesm2022/ng-doc-app-providers.mjs.map +1 -1
  75. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +27 -2
  76. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -1
  77. package/fesm2022/ng-doc-app-services-highlighter.mjs +23 -16
  78. package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
  79. package/fesm2022/ng-doc-app-services-route-preloader.mjs +34 -10
  80. package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -1
  81. package/fesm2022/ng-doc-app-services-shortcuts.mjs +38 -4
  82. package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -1
  83. package/fesm2022/ng-doc-app-texts-ar.mjs +238 -0
  84. package/fesm2022/ng-doc-app-texts-ar.mjs.map +1 -0
  85. package/fesm2022/ng-doc-app-texts-de.mjs +205 -0
  86. package/fesm2022/ng-doc-app-texts-de.mjs.map +1 -0
  87. package/fesm2022/ng-doc-app-texts-es.mjs +205 -0
  88. package/fesm2022/ng-doc-app-texts-es.mjs.map +1 -0
  89. package/fesm2022/ng-doc-app-texts-fr.mjs +205 -0
  90. package/fesm2022/ng-doc-app-texts-fr.mjs.map +1 -0
  91. package/fesm2022/ng-doc-app-texts-hi.mjs +219 -0
  92. package/fesm2022/ng-doc-app-texts-hi.mjs.map +1 -0
  93. package/fesm2022/ng-doc-app-texts-ja.mjs +205 -0
  94. package/fesm2022/ng-doc-app-texts-ja.mjs.map +1 -0
  95. package/fesm2022/ng-doc-app-texts-ko.mjs +205 -0
  96. package/fesm2022/ng-doc-app-texts-ko.mjs.map +1 -0
  97. package/fesm2022/ng-doc-app-texts-pt-br.mjs +205 -0
  98. package/fesm2022/ng-doc-app-texts-pt-br.mjs.map +1 -0
  99. package/fesm2022/ng-doc-app-texts-ru.mjs +231 -0
  100. package/fesm2022/ng-doc-app-texts-ru.mjs.map +1 -0
  101. package/fesm2022/ng-doc-app-texts-uk.mjs +231 -0
  102. package/fesm2022/ng-doc-app-texts-uk.mjs.map +1 -0
  103. package/fesm2022/ng-doc-app-texts-zh.mjs +205 -0
  104. package/fesm2022/ng-doc-app-texts-zh.mjs.map +1 -0
  105. package/fesm2022/ng-doc-app-tokens.mjs +214 -1
  106. package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
  107. package/fesm2022/ng-doc-app-type-controls-json-control.mjs +90 -0
  108. package/fesm2022/ng-doc-app-type-controls-json-control.mjs.map +1 -0
  109. package/fesm2022/ng-doc-app-type-controls-list-control.mjs +792 -0
  110. package/fesm2022/ng-doc-app-type-controls-list-control.mjs.map +1 -0
  111. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +45 -8
  112. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
  113. package/fesm2022/ng-doc-app-type-controls.mjs +2 -0
  114. package/fesm2022/ng-doc-app-type-controls.mjs.map +1 -1
  115. package/package.json +73 -4
  116. package/styles/global.css +4 -0
  117. package/styles/main.css +4 -0
  118. package/styles/themes/dark.css +10 -0
  119. package/types/ng-doc-app-classes-default-search-engine.d.ts +11 -0
  120. package/types/ng-doc-app-classes-root-page.d.ts +13 -0
  121. package/types/ng-doc-app-components-api-list.d.ts +3 -1
  122. package/types/ng-doc-app-components-breadcrumb.d.ts +2 -1
  123. package/types/ng-doc-app-components-code.d.ts +2 -0
  124. package/types/ng-doc-app-components-command-palette.d.ts +3 -1
  125. package/types/ng-doc-app-components-copy-button.d.ts +3 -1
  126. package/types/ng-doc-app-components-demo-displayer.d.ts +13 -1
  127. package/types/ng-doc-app-components-demo-frame.d.ts +107 -0
  128. package/types/ng-doc-app-components-demo.d.ts +47 -10
  129. package/types/ng-doc-app-components-fullscreen-button.d.ts +2 -0
  130. package/types/ng-doc-app-components-fullscreen-toggle.d.ts +2 -0
  131. package/types/ng-doc-app-components-heading-anchor.d.ts +2 -0
  132. package/types/ng-doc-app-components-image-viewer.d.ts +2 -0
  133. package/types/ng-doc-app-components-navbar.d.ts +2 -0
  134. package/types/ng-doc-app-components-page-navigation.d.ts +2 -1
  135. package/types/ng-doc-app-components-page.d.ts +10 -1
  136. package/types/ng-doc-app-components-playground.d.ts +260 -42
  137. package/types/ng-doc-app-components-root.d.ts +18 -0
  138. package/types/ng-doc-app-components-search-result.d.ts +2 -0
  139. package/types/ng-doc-app-components-search.d.ts +2 -0
  140. package/types/ng-doc-app-components-sidebar.d.ts +2 -1
  141. package/types/ng-doc-app-components-tabs.d.ts +13 -3
  142. package/types/ng-doc-app-components-theme-toggle.d.ts +4 -1
  143. package/types/ng-doc-app-components-toc.d.ts +2 -1
  144. package/types/ng-doc-app-components.d.ts +1 -0
  145. package/types/ng-doc-app-constants.d.ts +11 -1
  146. package/types/ng-doc-app-demo-app.d.ts +297 -0
  147. package/types/ng-doc-app-helpers.d.ts +75 -4
  148. package/types/ng-doc-app-interfaces.d.ts +635 -6
  149. package/types/ng-doc-app-processors-processors.d.ts +5 -0
  150. package/types/ng-doc-app-providers-ng-doc-app.d.ts +7 -1
  151. package/types/ng-doc-app-providers-texts.d.ts +28 -0
  152. package/types/ng-doc-app-providers-title.d.ts +59 -0
  153. package/types/ng-doc-app-providers.d.ts +2 -0
  154. package/types/ng-doc-app-services-content-scroll-intent.d.ts +11 -1
  155. package/types/ng-doc-app-services-highlighter.d.ts +15 -6
  156. package/types/ng-doc-app-services-route-preloader.d.ts +13 -1
  157. package/types/ng-doc-app-services-shortcuts.d.ts +16 -0
  158. package/types/ng-doc-app-texts-ar.d.ts +13 -0
  159. package/types/ng-doc-app-texts-de.d.ts +12 -0
  160. package/types/ng-doc-app-texts-es.d.ts +12 -0
  161. package/types/ng-doc-app-texts-fr.d.ts +12 -0
  162. package/types/ng-doc-app-texts-hi.d.ts +12 -0
  163. package/types/ng-doc-app-texts-ja.d.ts +12 -0
  164. package/types/ng-doc-app-texts-ko.d.ts +12 -0
  165. package/types/ng-doc-app-texts-pt-br.d.ts +12 -0
  166. package/types/ng-doc-app-texts-ru.d.ts +12 -0
  167. package/types/ng-doc-app-texts-uk.d.ts +12 -0
  168. package/types/ng-doc-app-texts-zh.d.ts +12 -0
  169. package/types/ng-doc-app-tokens.d.ts +21 -2
  170. package/types/ng-doc-app-type-controls-json-control.d.ts +38 -0
  171. package/types/ng-doc-app-type-controls-list-control.d.ts +313 -0
  172. package/types/ng-doc-app-type-controls-type-alias-control.d.ts +28 -5
  173. package/types/ng-doc-app-type-controls.d.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-heading-anchor.mjs","sources":["../../../../libs/app/components/heading-anchor/heading-anchor.component.ts","../../../../libs/app/components/heading-anchor/ng-doc-app-components-heading-anchor.ts"],"sourcesContent":["import { LocationStrategy } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n OnInit,\n Renderer2,\n} from '@angular/core';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { ɵngDocPageUrl } from '@ng-doc/app/helpers';\nimport { NgDocIconComponent } from '@ng-doc/ui-kit';\nimport { WA_LOCATION } from '@ng-web-apis/common';\n\n/**\n * Button next to a heading that copies the link to the heading.\n */\n@Component({\n selector: 'ng-doc-heading-anchor',\n imports: [NgDocIconComponent, NgDocCopyButtonComponent],\n template: `\n <ng-doc-copy-button [text]=\"href\" label=\"Copy link to section\">\n <ng-doc-icon icon=\"link-2\"></ng-doc-icon>\n </ng-doc-copy-button>\n `,\n styles: ``,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'classes()',\n },\n})\nexport class NgDocHeadingAnchorComponent implements OnInit {\n /** Id of the heading. */\n readonly anchor = input.required<string>();\n\n /** Classes of the host element. */\n readonly classes = input<string[]>([]);\n\n protected readonly location = inject(WA_LOCATION);\n\n private readonly locationStrategy = inject(LocationStrategy);\n private readonly host: HTMLElement = inject(ElementRef).nativeElement;\n private readonly renderer = inject(Renderer2);\n\n // Read when the button is pressed: the location is not a signal, and the link must use the\n // route the reader is on, in the form the location strategy shows it.\n protected readonly href = (): string =>\n ɵngDocPageUrl(this.locationStrategy, this.location, this.anchor());\n\n /**\n * Names the heading after its own text: the anchor sits inside the heading, so the button's\n * label would otherwise end the heading's accessible name (\"Installation Copy link to\n * section\"). The heading's other content moves into a span that the heading is labelled by, so\n * the name follows that content and leaves out whatever it hides from assistive technology.\n * The processors insert the anchor before its first change detection, on the server as in the\n * browser, so the heading is its parent here.\n * @internal\n */\n ngOnInit(): void {\n const heading = this.host.parentElement;\n\n if (\n !heading ||\n !/^H[1-6]$/.test(heading.tagName) ||\n heading.hasAttribute('aria-label') ||\n heading.hasAttribute('aria-labelledby')\n )\n return;\n\n const id = `ng-doc-heading-label-${heading.id || this.anchor()}`;\n const label: HTMLElement = this.renderer.createElement('span');\n\n this.renderer.setAttribute(label, 'id', id);\n this.renderer.setAttribute(label, 'class', 'ng-doc-heading-label');\n for (const node of Array.from(heading.childNodes)) {\n if (node !== this.host) this.renderer.appendChild(label, node);\n }\n this.renderer.insertBefore(heading, label, this.host);\n this.renderer.setAttribute(heading, 'aria-labelledby', id);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵngDocPageUrl"],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-heading-anchor.mjs","sources":["../../../../libs/app/components/heading-anchor/heading-anchor.component.ts","../../../../libs/app/components/heading-anchor/ng-doc-app-components-heading-anchor.ts"],"sourcesContent":["import { LocationStrategy } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n OnInit,\n Renderer2,\n} from '@angular/core';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { ɵngDocPageUrl } from '@ng-doc/app/helpers';\nimport type { NgDocCopyTexts } from '@ng-doc/app/interfaces';\nimport { NG_DOC_TEXTS } from '@ng-doc/app/tokens';\nimport { NgDocIconComponent } from '@ng-doc/ui-kit';\nimport { WA_LOCATION } from '@ng-web-apis/common';\n\n/**\n * Button next to a heading that copies the link to the heading.\n */\n@Component({\n selector: 'ng-doc-heading-anchor',\n imports: [NgDocIconComponent, NgDocCopyButtonComponent],\n template: `\n <ng-doc-copy-button [text]=\"href\" [label]=\"texts.copyLinkToSection\">\n <ng-doc-icon icon=\"link-2\"></ng-doc-icon>\n </ng-doc-copy-button>\n `,\n styles: ``,\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[class]': 'classes()',\n },\n})\nexport class NgDocHeadingAnchorComponent implements OnInit {\n protected readonly texts: NgDocCopyTexts = inject(NG_DOC_TEXTS).copy;\n\n /** Id of the heading. */\n readonly anchor = input.required<string>();\n\n /** Classes of the host element. */\n readonly classes = input<string[]>([]);\n\n protected readonly location = inject(WA_LOCATION);\n\n private readonly locationStrategy = inject(LocationStrategy);\n private readonly host: HTMLElement = inject(ElementRef).nativeElement;\n private readonly renderer = inject(Renderer2);\n\n // Read when the button is pressed: the location is not a signal, and the link must use the\n // route the reader is on, in the form the location strategy shows it.\n protected readonly href = (): string =>\n ɵngDocPageUrl(this.locationStrategy, this.location, this.anchor());\n\n /**\n * Names the heading after its own text: the anchor sits inside the heading, so the button's\n * label would otherwise end the heading's accessible name (\"Installation Copy link to\n * section\"). The heading's other content moves into a span that the heading is labelled by, so\n * the name follows that content and leaves out whatever it hides from assistive technology.\n * The processors insert the anchor before its first change detection, on the server as in the\n * browser, so the heading is its parent here.\n * @internal\n */\n ngOnInit(): void {\n const heading = this.host.parentElement;\n\n if (\n !heading ||\n !/^H[1-6]$/.test(heading.tagName) ||\n heading.hasAttribute('aria-label') ||\n heading.hasAttribute('aria-labelledby')\n )\n return;\n\n const id = `ng-doc-heading-label-${heading.id || this.anchor()}`;\n const label: HTMLElement = this.renderer.createElement('span');\n\n this.renderer.setAttribute(label, 'id', id);\n this.renderer.setAttribute(label, 'class', 'ng-doc-heading-label');\n for (const node of Array.from(heading.childNodes)) {\n if (node !== this.host) this.renderer.appendChild(label, node);\n }\n this.renderer.insertBefore(heading, label, this.host);\n this.renderer.setAttribute(heading, 'aria-labelledby', id);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵngDocPageUrl"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, viewChild, TemplateRef, inject, ElementRef, DOCUMENT, signal, DestroyRef, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, input, viewChild, TemplateRef, ElementRef, DOCUMENT, signal, DestroyRef, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { NG_DOC_TEXTS } from '@ng-doc/app/tokens';
3
4
  import { NgDocOverlayService, NgDocOverlayContainerComponent } from '@ng-doc/ui-kit';
4
5
 
5
6
  /** Easing of the zoom: fast at first, settling into the final size. */
@@ -13,6 +14,7 @@ const ZOOM_EASING = 'cubic-bezier(0.2, 0, 0, 1)';
13
14
  */
14
15
  class NgDocImageViewerComponent {
15
16
  constructor() {
17
+ this.texts = inject(NG_DOC_TEXTS).content;
16
18
  /** Source of the image. */
17
19
  this.src = input.required(/* @ts-ignore */
18
20
  ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
@@ -195,14 +197,14 @@ class NgDocImageViewerComponent {
195
197
  return { transformOrigin: '0 0', transform: `translate(${x}px, ${y}px) scale(${scale})` };
196
198
  }
197
199
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocImageViewerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
198
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.2.1", type: NgDocImageViewerComponent, isStandalone: true, selector: "ng-doc-image-viewer", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "clickEvent()", "keydown.enter": "clickEvent()", "keydown.space": "onSpace($event)" }, properties: { "attr.role": "isInteractive() ? \"button\" : null", "attr.tabindex": "isInteractive() ? 0 : null", "attr.aria-label": "isInteractive() ? \"Open image: \" + alt() : null", "attr.data-interactive": "isInteractive()", "attr.data-opened": "opened()" } }, viewQueries: [{ propertyName: "image", first: true, predicate: ["image"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\n\n<ng-template #image>\n <div\n class=\"ng-doc-image-container\"\n [style.width.px]=\"size().width\"\n [style.height.px]=\"size().height\"\n (click)=\"overlayRef?.close()\">\n <img class=\"ng-doc-scaled-image\" [src]=\"src()\" [alt]=\"alt()\" />\n </div>\n</ng-template>\n", styles: [":host{display:inline-block}:host[data-interactive=true]{cursor:zoom-in}:host{transition:var(--ng-doc-transition);border-radius:var(--ng-doc-radius-lg)}:host:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}:host[data-opened=true]>::ng-deep img{opacity:0}:host>::ng-deep img{max-width:100%;vertical-align:middle;border-radius:var(--ng-doc-radius-lg);overflow:hidden}.ng-doc-image-container{display:block}.ng-doc-image-container .ng-doc-scaled-image{display:block;width:100%;height:100%;object-fit:contain;border-radius:var(--ng-doc-radius-lg);cursor:zoom-out}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
200
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.2.1", type: NgDocImageViewerComponent, isStandalone: true, selector: "ng-doc-image-viewer", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, alt: { classPropertyName: "alt", publicName: "alt", isSignal: true, isRequired: true, transformFunction: null } }, host: { listeners: { "click": "clickEvent()", "keydown.enter": "clickEvent()", "keydown.space": "onSpace($event)" }, properties: { "attr.role": "isInteractive() ? \"button\" : null", "attr.tabindex": "isInteractive() ? 0 : null", "attr.aria-label": "isInteractive() ? texts.openImage({ alt: alt() }) : null", "attr.data-interactive": "isInteractive()", "attr.data-opened": "opened()" } }, viewQueries: [{ propertyName: "image", first: true, predicate: ["image"], descendants: true, read: TemplateRef, isSignal: true }], ngImport: i0, template: "<ng-content></ng-content>\n\n<ng-template #image>\n <div\n class=\"ng-doc-image-container\"\n [style.width.px]=\"size().width\"\n [style.height.px]=\"size().height\"\n (click)=\"overlayRef?.close()\">\n <img class=\"ng-doc-scaled-image\" [src]=\"src()\" [alt]=\"alt()\" />\n </div>\n</ng-template>\n", styles: [":host{display:inline-block}:host[data-interactive=true]{cursor:zoom-in}:host{transition:var(--ng-doc-transition);border-radius:var(--ng-doc-radius-lg)}:host:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}:host[data-opened=true]>::ng-deep img{opacity:0}:host>::ng-deep img{max-width:100%;vertical-align:middle;border-radius:var(--ng-doc-radius-lg);overflow:hidden}.ng-doc-image-container{display:block}.ng-doc-image-container .ng-doc-scaled-image{display:block;width:100%;height:100%;object-fit:contain;border-radius:var(--ng-doc-radius-lg);cursor:zoom-out}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
199
201
  }
200
202
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocImageViewerComponent, decorators: [{
201
203
  type: Component,
202
204
  args: [{ selector: 'ng-doc-image-viewer', imports: [], changeDetection: ChangeDetectionStrategy.OnPush, host: {
203
205
  '[attr.role]': 'isInteractive() ? "button" : null',
204
206
  '[attr.tabindex]': 'isInteractive() ? 0 : null',
205
- '[attr.aria-label]': 'isInteractive() ? "Open image: " + alt() : null',
207
+ '[attr.aria-label]': 'isInteractive() ? texts.openImage({ alt: alt() }) : null',
206
208
  '[attr.data-interactive]': 'isInteractive()',
207
209
  '[attr.data-opened]': 'opened()',
208
210
  '(click)': 'clickEvent()',
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-image-viewer.mjs","sources":["../../../../libs/app/components/image-viewer/image-viewer.component.ts","../../../../libs/app/components/image-viewer/image-viewer.component.html","../../../../libs/app/components/image-viewer/ng-doc-app-components-image-viewer.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n DOCUMENT,\n ElementRef,\n inject,\n input,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { NgDocOverlayContainerComponent, NgDocOverlayService } from '@ng-doc/ui-kit';\nimport { NgDocOverlayRef } from '@ng-doc/ui-kit/classes';\n\n/** The size of the opened image, in CSS pixels. */\ninterface ZoomSize {\n width: number;\n height: number;\n}\n\n/** Easing of the zoom: fast at first, settling into the final size. */\nconst ZOOM_EASING: string = 'cubic-bezier(0.2, 0, 0, 1)';\n\n/**\n * Wraps an image of the page: clicking it, or pressing Enter or Space on it, opens the image at\n * its natural size, scaled down to fit the window.\n *\n * An image inside a link keeps the link's behaviour, and an image with an empty `alt` is\n * decorative: neither becomes a button.\n */\n@Component({\n selector: 'ng-doc-image-viewer',\n imports: [],\n templateUrl: './image-viewer.component.html',\n styleUrl: './image-viewer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.role]': 'isInteractive() ? \"button\" : null',\n '[attr.tabindex]': 'isInteractive() ? 0 : null',\n '[attr.aria-label]': 'isInteractive() ? \"Open image: \" + alt() : null',\n '[attr.data-interactive]': 'isInteractive()',\n '[attr.data-opened]': 'opened()',\n '(click)': 'clickEvent()',\n '(keydown.enter)': 'clickEvent()',\n '(keydown.space)': 'onSpace($event)',\n },\n})\nexport class NgDocImageViewerComponent {\n /** Source of the image. */\n readonly src = input.required<string>();\n\n /** Alternative text of the image. */\n readonly alt = input.required<string>();\n\n protected readonly image = viewChild.required('image', { read: TemplateRef });\n protected readonly overlay = inject(NgDocOverlayService);\n protected readonly element: HTMLElement = inject(ElementRef<HTMLElement>).nativeElement;\n protected readonly window: Window | null = inject(DOCUMENT).defaultView;\n\n /** Whether the scaled image is open. */\n protected readonly opened = signal<boolean>(false);\n\n /** The size of the opened image. */\n protected readonly size = signal<ZoomSize>({ width: 0, height: 0 });\n\n protected overlayRef?: NgDocOverlayRef;\n\n private attempt: number = 0;\n private destroyed: boolean = false;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.destroyed = true;\n this.overlayRef?.close();\n });\n }\n\n /**\n * Opens the image at its natural size, scaled down to fit the window, unless the image is not\n * interactive. The image grows from its place on the page.\n */\n clickEvent(): void {\n untracked(() => {\n if (this.isInteractive()) {\n void this.open();\n }\n });\n }\n\n /**\n * Whether the image opens: it has a text alternative and is not inside a link. The page\n * processor moves the host into place before change detection, so the check reads the DOM\n * where the image ends up.\n */\n protected isInteractive(): boolean {\n return !!this.alt().trim() && !this.element.parentElement?.closest('a');\n }\n\n /**\n * Opens the image on Space without scrolling the page.\n * @param event - The key press.\n */\n protected onSpace(event: Event): void {\n if (this.isInteractive()) {\n event.preventDefault();\n this.clickEvent();\n }\n }\n\n private async open(): Promise<void> {\n this.overlayRef?.close();\n\n const attempt: number = ++this.attempt;\n const thumbnail: HTMLImageElement | null = this.element.querySelector('img');\n\n await this.decode(thumbnail);\n\n // The reader may have opened the image again, pressed Escape or left the page while it\n // decoded.\n if (attempt !== this.attempt || this.destroyed) {\n return;\n }\n\n // The size is known before anything moves, so the image grows straight to it.\n const source: ZoomSize = this.sourceSize(thumbnail);\n const size: ZoomSize = this.fit(source);\n const zoomedFrame: Keyframe = { transformOrigin: '0 0', transform: 'none' };\n // The close animation reads its keyframes when it runs; a refit updates them in place.\n const closeFrames: Keyframe[] = [zoomedFrame, this.thumbnailFrame(thumbnail, size)];\n const animate: boolean = !this.window?.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n\n this.size.set(size);\n\n const overlayRef: NgDocOverlayRef = this.overlay.open(this.image(), {\n overlayContainer: NgDocOverlayContainerComponent,\n positionStrategy: this.overlay\n .globalPositionStrategy()\n .centerHorizontally()\n .centerVertically(),\n scrollStrategy: this.overlay.scrollStrategy().block(),\n hasBackdrop: true,\n backdropClass: 'ng-doc-blur-backdrop',\n width: `${size.width}px`,\n height: `${size.height}px`,\n openAnimation: animate\n ? [[closeFrames[1], zoomedFrame], { duration: 300, easing: ZOOM_EASING }]\n : undefined,\n closeAnimation: animate\n ? [closeFrames, { duration: 200, easing: ZOOM_EASING, fill: 'forwards' }]\n : undefined,\n });\n const listeners: AbortController = new AbortController();\n // A resized or rotated window fits the image again.\n const refit = (): void => {\n const fitted: ZoomSize = this.fit(source);\n\n this.size.set(fitted);\n overlayRef.overlayRef.updateSize({\n width: `${fitted.width}px`,\n height: `${fitted.height}px`,\n });\n closeFrames[1] = this.thumbnailFrame(thumbnail, fitted);\n };\n\n this.window?.addEventListener('resize', refit, { signal: listeners.signal });\n this.window?.addEventListener('orientationchange', refit, { signal: listeners.signal });\n\n this.overlayRef = overlayRef;\n this.opened.set(true);\n\n overlayRef.afterClose().subscribe(() => {\n listeners.abort();\n\n if (this.overlayRef === overlayRef) {\n this.overlayRef = undefined;\n this.opened.set(false);\n this.element.focus();\n }\n });\n }\n\n /**\n * Waits until the image is decoded, so its natural size is known. Escape cancels the open\n * meanwhile, as it closes the opened image. A failed decode (a broken or not yet available\n * image) leaves the sizes that are known.\n * @param thumbnail - The image on the page.\n */\n private async decode(thumbnail: HTMLImageElement | null): Promise<void> {\n const listeners: AbortController = new AbortController();\n\n this.window?.document.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.attempt++;\n }\n },\n { capture: true, signal: listeners.signal },\n );\n\n try {\n await thumbnail?.decode?.().catch(() => undefined);\n } finally {\n listeners.abort();\n }\n }\n\n /**\n * The size to scale: the natural size of the image, or the size of the thumbnail for an image\n * without one (an SVG without dimensions), which may then grow to fill the window.\n * @param thumbnail - The image on the page.\n */\n private sourceSize(thumbnail: HTMLImageElement | null): ZoomSize & { natural: boolean } {\n const naturalWidth: number = thumbnail?.naturalWidth ?? 0;\n const naturalHeight: number = thumbnail?.naturalHeight ?? 0;\n\n if (naturalWidth > 0 && naturalHeight > 0) {\n return { width: naturalWidth, height: naturalHeight, natural: true };\n }\n\n const rect: DOMRect = (thumbnail ?? this.element).getBoundingClientRect();\n\n return { width: rect.width, height: rect.height, natural: false };\n }\n\n /**\n * The size the image opens at: its natural size, scaled down to fit the viewport with a margin\n * and never scaled up. An image without a natural size fills the available space with the\n * proportions of its thumbnail.\n * @param source - The size to scale.\n */\n private fit(source: ZoomSize & { natural?: boolean }): ZoomSize {\n const viewport: HTMLElement | undefined = this.window?.document.documentElement;\n const viewportWidth: number = viewport?.clientWidth || this.window?.innerWidth || 0;\n const viewportHeight: number = viewport?.clientHeight || this.window?.innerHeight || 0;\n const margin: number = viewportWidth <= 640 ? 16 : 48;\n const maxWidth: number = Math.max(viewportWidth - margin * 2, 1);\n const maxHeight: number = Math.max(viewportHeight - margin * 2, 1);\n const width: number = source.width || maxWidth;\n const height: number = source.height || maxHeight;\n const scale: number = Math.min(\n source.natural ? 1 : Number.POSITIVE_INFINITY,\n maxWidth / width,\n maxHeight / height,\n );\n\n return { width: Math.round(width * scale), height: Math.round(height * scale) };\n }\n\n /**\n * The keyframe that puts the opened image over its thumbnail. The overlay centres the image in\n * the viewport; the frame scales it uniformly to fit the thumbnail's box and centres it there,\n * so an image whose proportions differ from its box's is not distorted.\n * @param thumbnail - The image on the page.\n * @param size - The size of the opened image.\n */\n private thumbnailFrame(thumbnail: HTMLImageElement | null, size: ZoomSize): Keyframe {\n const from: DOMRect = (thumbnail ?? this.element).getBoundingClientRect();\n const viewport: HTMLElement | undefined = this.window?.document.documentElement;\n const left: number = ((viewport?.clientWidth ?? size.width) - size.width) / 2;\n const top: number = ((viewport?.clientHeight ?? size.height) - size.height) / 2;\n const scale: number = Math.min(from.width / size.width, from.height / size.height) || 0;\n const x: number = from.left + (from.width - size.width * scale) / 2 - left;\n const y: number = from.top + (from.height - size.height * scale) / 2 - top;\n\n return { transformOrigin: '0 0', transform: `translate(${x}px, ${y}px) scale(${scale})` };\n }\n}\n","<ng-content></ng-content>\n\n<ng-template #image>\n <div\n class=\"ng-doc-image-container\"\n [style.width.px]=\"size().width\"\n [style.height.px]=\"size().height\"\n (click)=\"overlayRef?.close()\">\n <img class=\"ng-doc-scaled-image\" [src]=\"src()\" [alt]=\"alt()\" />\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-image-viewer.mjs","sources":["../../../../libs/app/components/image-viewer/image-viewer.component.ts","../../../../libs/app/components/image-viewer/image-viewer.component.html","../../../../libs/app/components/image-viewer/ng-doc-app-components-image-viewer.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n DOCUMENT,\n ElementRef,\n inject,\n input,\n signal,\n TemplateRef,\n untracked,\n viewChild,\n} from '@angular/core';\nimport type { NgDocContentTexts } from '@ng-doc/app/interfaces';\nimport { NG_DOC_TEXTS } from '@ng-doc/app/tokens';\nimport { NgDocOverlayContainerComponent, NgDocOverlayService } from '@ng-doc/ui-kit';\nimport { NgDocOverlayRef } from '@ng-doc/ui-kit/classes';\n\n/** The size of the opened image, in CSS pixels. */\ninterface ZoomSize {\n width: number;\n height: number;\n}\n\n/** Easing of the zoom: fast at first, settling into the final size. */\nconst ZOOM_EASING: string = 'cubic-bezier(0.2, 0, 0, 1)';\n\n/**\n * Wraps an image of the page: clicking it, or pressing Enter or Space on it, opens the image at\n * its natural size, scaled down to fit the window.\n *\n * An image inside a link keeps the link's behaviour, and an image with an empty `alt` is\n * decorative: neither becomes a button.\n */\n@Component({\n selector: 'ng-doc-image-viewer',\n imports: [],\n templateUrl: './image-viewer.component.html',\n styleUrl: './image-viewer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.role]': 'isInteractive() ? \"button\" : null',\n '[attr.tabindex]': 'isInteractive() ? 0 : null',\n '[attr.aria-label]': 'isInteractive() ? texts.openImage({ alt: alt() }) : null',\n '[attr.data-interactive]': 'isInteractive()',\n '[attr.data-opened]': 'opened()',\n '(click)': 'clickEvent()',\n '(keydown.enter)': 'clickEvent()',\n '(keydown.space)': 'onSpace($event)',\n },\n})\nexport class NgDocImageViewerComponent {\n protected readonly texts: NgDocContentTexts = inject(NG_DOC_TEXTS).content;\n\n /** Source of the image. */\n readonly src = input.required<string>();\n\n /** Alternative text of the image. */\n readonly alt = input.required<string>();\n\n protected readonly image = viewChild.required('image', { read: TemplateRef });\n protected readonly overlay = inject(NgDocOverlayService);\n protected readonly element: HTMLElement = inject(ElementRef<HTMLElement>).nativeElement;\n protected readonly window: Window | null = inject(DOCUMENT).defaultView;\n\n /** Whether the scaled image is open. */\n protected readonly opened = signal<boolean>(false);\n\n /** The size of the opened image. */\n protected readonly size = signal<ZoomSize>({ width: 0, height: 0 });\n\n protected overlayRef?: NgDocOverlayRef;\n\n private attempt: number = 0;\n private destroyed: boolean = false;\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.destroyed = true;\n this.overlayRef?.close();\n });\n }\n\n /**\n * Opens the image at its natural size, scaled down to fit the window, unless the image is not\n * interactive. The image grows from its place on the page.\n */\n clickEvent(): void {\n untracked(() => {\n if (this.isInteractive()) {\n void this.open();\n }\n });\n }\n\n /**\n * Whether the image opens: it has a text alternative and is not inside a link. The page\n * processor moves the host into place before change detection, so the check reads the DOM\n * where the image ends up.\n */\n protected isInteractive(): boolean {\n return !!this.alt().trim() && !this.element.parentElement?.closest('a');\n }\n\n /**\n * Opens the image on Space without scrolling the page.\n * @param event - The key press.\n */\n protected onSpace(event: Event): void {\n if (this.isInteractive()) {\n event.preventDefault();\n this.clickEvent();\n }\n }\n\n private async open(): Promise<void> {\n this.overlayRef?.close();\n\n const attempt: number = ++this.attempt;\n const thumbnail: HTMLImageElement | null = this.element.querySelector('img');\n\n await this.decode(thumbnail);\n\n // The reader may have opened the image again, pressed Escape or left the page while it\n // decoded.\n if (attempt !== this.attempt || this.destroyed) {\n return;\n }\n\n // The size is known before anything moves, so the image grows straight to it.\n const source: ZoomSize = this.sourceSize(thumbnail);\n const size: ZoomSize = this.fit(source);\n const zoomedFrame: Keyframe = { transformOrigin: '0 0', transform: 'none' };\n // The close animation reads its keyframes when it runs; a refit updates them in place.\n const closeFrames: Keyframe[] = [zoomedFrame, this.thumbnailFrame(thumbnail, size)];\n const animate: boolean = !this.window?.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\n\n this.size.set(size);\n\n const overlayRef: NgDocOverlayRef = this.overlay.open(this.image(), {\n overlayContainer: NgDocOverlayContainerComponent,\n positionStrategy: this.overlay\n .globalPositionStrategy()\n .centerHorizontally()\n .centerVertically(),\n scrollStrategy: this.overlay.scrollStrategy().block(),\n hasBackdrop: true,\n backdropClass: 'ng-doc-blur-backdrop',\n width: `${size.width}px`,\n height: `${size.height}px`,\n openAnimation: animate\n ? [[closeFrames[1], zoomedFrame], { duration: 300, easing: ZOOM_EASING }]\n : undefined,\n closeAnimation: animate\n ? [closeFrames, { duration: 200, easing: ZOOM_EASING, fill: 'forwards' }]\n : undefined,\n });\n const listeners: AbortController = new AbortController();\n // A resized or rotated window fits the image again.\n const refit = (): void => {\n const fitted: ZoomSize = this.fit(source);\n\n this.size.set(fitted);\n overlayRef.overlayRef.updateSize({\n width: `${fitted.width}px`,\n height: `${fitted.height}px`,\n });\n closeFrames[1] = this.thumbnailFrame(thumbnail, fitted);\n };\n\n this.window?.addEventListener('resize', refit, { signal: listeners.signal });\n this.window?.addEventListener('orientationchange', refit, { signal: listeners.signal });\n\n this.overlayRef = overlayRef;\n this.opened.set(true);\n\n overlayRef.afterClose().subscribe(() => {\n listeners.abort();\n\n if (this.overlayRef === overlayRef) {\n this.overlayRef = undefined;\n this.opened.set(false);\n this.element.focus();\n }\n });\n }\n\n /**\n * Waits until the image is decoded, so its natural size is known. Escape cancels the open\n * meanwhile, as it closes the opened image. A failed decode (a broken or not yet available\n * image) leaves the sizes that are known.\n * @param thumbnail - The image on the page.\n */\n private async decode(thumbnail: HTMLImageElement | null): Promise<void> {\n const listeners: AbortController = new AbortController();\n\n this.window?.document.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => {\n if (event.key === 'Escape') {\n this.attempt++;\n }\n },\n { capture: true, signal: listeners.signal },\n );\n\n try {\n await thumbnail?.decode?.().catch(() => undefined);\n } finally {\n listeners.abort();\n }\n }\n\n /**\n * The size to scale: the natural size of the image, or the size of the thumbnail for an image\n * without one (an SVG without dimensions), which may then grow to fill the window.\n * @param thumbnail - The image on the page.\n */\n private sourceSize(thumbnail: HTMLImageElement | null): ZoomSize & { natural: boolean } {\n const naturalWidth: number = thumbnail?.naturalWidth ?? 0;\n const naturalHeight: number = thumbnail?.naturalHeight ?? 0;\n\n if (naturalWidth > 0 && naturalHeight > 0) {\n return { width: naturalWidth, height: naturalHeight, natural: true };\n }\n\n const rect: DOMRect = (thumbnail ?? this.element).getBoundingClientRect();\n\n return { width: rect.width, height: rect.height, natural: false };\n }\n\n /**\n * The size the image opens at: its natural size, scaled down to fit the viewport with a margin\n * and never scaled up. An image without a natural size fills the available space with the\n * proportions of its thumbnail.\n * @param source - The size to scale.\n */\n private fit(source: ZoomSize & { natural?: boolean }): ZoomSize {\n const viewport: HTMLElement | undefined = this.window?.document.documentElement;\n const viewportWidth: number = viewport?.clientWidth || this.window?.innerWidth || 0;\n const viewportHeight: number = viewport?.clientHeight || this.window?.innerHeight || 0;\n const margin: number = viewportWidth <= 640 ? 16 : 48;\n const maxWidth: number = Math.max(viewportWidth - margin * 2, 1);\n const maxHeight: number = Math.max(viewportHeight - margin * 2, 1);\n const width: number = source.width || maxWidth;\n const height: number = source.height || maxHeight;\n const scale: number = Math.min(\n source.natural ? 1 : Number.POSITIVE_INFINITY,\n maxWidth / width,\n maxHeight / height,\n );\n\n return { width: Math.round(width * scale), height: Math.round(height * scale) };\n }\n\n /**\n * The keyframe that puts the opened image over its thumbnail. The overlay centres the image in\n * the viewport; the frame scales it uniformly to fit the thumbnail's box and centres it there,\n * so an image whose proportions differ from its box's is not distorted.\n * @param thumbnail - The image on the page.\n * @param size - The size of the opened image.\n */\n private thumbnailFrame(thumbnail: HTMLImageElement | null, size: ZoomSize): Keyframe {\n const from: DOMRect = (thumbnail ?? this.element).getBoundingClientRect();\n const viewport: HTMLElement | undefined = this.window?.document.documentElement;\n const left: number = ((viewport?.clientWidth ?? size.width) - size.width) / 2;\n const top: number = ((viewport?.clientHeight ?? size.height) - size.height) / 2;\n const scale: number = Math.min(from.width / size.width, from.height / size.height) || 0;\n const x: number = from.left + (from.width - size.width * scale) / 2 - left;\n const y: number = from.top + (from.height - size.height * scale) / 2 - top;\n\n return { transformOrigin: '0 0', transform: `translate(${x}px, ${y}px) scale(${scale})` };\n }\n}\n","<ng-content></ng-content>\n\n<ng-template #image>\n <div\n class=\"ng-doc-image-container\"\n [style.width.px]=\"size().width\"\n [style.height.px]=\"size().height\"\n (click)=\"overlayRef?.close()\">\n <img class=\"ng-doc-scaled-image\" [src]=\"src()\" [alt]=\"alt()\" />\n </div>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { inject, input, booleanAttribute, viewChild, ElementRef, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { NgDocSearchComponent } from '@ng-doc/app/components/search';
4
4
  import { NgDocSidebarService } from '@ng-doc/app/services/sidebar';
5
+ import { NG_DOC_TEXTS } from '@ng-doc/app/tokens';
5
6
  import { NgDocButtonIconComponent } from '@ng-doc/ui-kit';
6
7
 
7
8
  /**
@@ -22,6 +23,7 @@ import { NgDocButtonIconComponent } from '@ng-doc/ui-kit';
22
23
  */
23
24
  class NgDocNavbarComponent {
24
25
  constructor() {
26
+ this.texts = inject(NG_DOC_TEXTS).navigation;
25
27
  this.sidebarService = inject(NgDocSidebarService);
26
28
  /**
27
29
  * Show search input
@@ -47,14 +49,14 @@ class NgDocNavbarComponent {
47
49
  }
48
50
  }
49
51
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocNavbarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
50
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocNavbarComponent, isStandalone: true, selector: "ng-doc-navbar", inputs: { search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, hamburger: { classPropertyName: "hamburger", publicName: "hamburger", isSignal: true, isRequired: false, transformFunction: null }, glassEffect: { classPropertyName: "glassEffect", publicName: "glassEffect", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "closeSidebar()" }, properties: { "attr.data-glass-effect": "glassEffect()" } }, viewQueries: [{ propertyName: "menuButton", first: true, predicate: ["menuButton"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div class=\"ng-doc-navbar-container\">\n @if (hamburger()) {\n <button\n type=\"button\"\n class=\"ng-doc-menu\"\n ng-doc-button-icon\n size=\"large\"\n [rounded]=\"false\"\n aria-controls=\"ng-doc-sidenav\"\n [attr.aria-expanded]=\"sidebarService.expandedState()\"\n [attr.aria-label]=\"sidebarService.expandedState() ? 'Close navigation' : 'Open navigation'\"\n (click)=\"sidebarService.toggle()\"\n #menuButton>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n </button>\n }\n <div class=\"ng-doc-navbar-left\">\n <ng-content select=\"[ngDocNavbarLeft]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-center\">\n <ng-content select=\"[ngDocNavbarCenter]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-right\">\n @if (search()) {\n <ng-doc-search></ng-doc-search>\n }\n <ng-content select=\"[ngDocNavbarRight]\"></ng-content>\n </div>\n</div>\n", styles: [":host{position:relative;display:flex;justify-content:center;height:100%;background:color-mix(in srgb,var(--ng-doc-navbar-background) 82%,transparent);backdrop-filter:saturate(1.4) blur(12px);border-bottom:var(--ng-doc-navbar-border);--ng-doc-button-color: var(--ng-doc-text-muted);--ng-doc-button-hover-color: var(--ng-doc-heading-color);--ng-doc-button-active-color: var(--ng-doc-heading-color);--ng-doc-button-hover-background: var(--ng-doc-hover-background)}:host[data-glass-effect=false]{background:var(--ng-doc-navbar-background);backdrop-filter:none}@supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)){:host{background:var(--ng-doc-navbar-background)}}.ng-doc-navbar-container{display:flex;align-items:center;gap:var(--ng-doc-space-4);width:100%;max-width:var(--ng-doc-app-max-width);height:100%;padding:0 var(--ng-doc-navbar-horizontal-padding)}.ng-doc-navbar-left,.ng-doc-navbar-center,.ng-doc-navbar-right{display:flex;align-items:center;gap:var(--ng-doc-space-4);min-width:0}.ng-doc-navbar-left{flex:none;max-width:var(--ng-doc-navbar-left-width)}.ng-doc-navbar-center{margin-left:auto}.ng-doc-navbar-right ng-doc-search{margin-left:var(--ng-doc-space-6)}@media(max-width:1024px){.ng-doc-navbar-right ng-doc-search{margin-left:0}}.ng-doc-menu{display:none;margin-left:calc(var(--ng-doc-space-2) * -1)}@media(max-width:1024px){.ng-doc-navbar-center{display:none}.ng-doc-navbar-right{margin-left:auto}}@media(max-width:900px){.ng-doc-menu{display:inline-flex}}@media(max-width:640px){.ng-doc-navbar-container{padding:0 var(--ng-doc-space-4)}}\n"], dependencies: [{ kind: "component", type: NgDocSearchComponent, selector: "ng-doc-search" }, { kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
52
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocNavbarComponent, isStandalone: true, selector: "ng-doc-navbar", inputs: { search: { classPropertyName: "search", publicName: "search", isSignal: true, isRequired: false, transformFunction: null }, hamburger: { classPropertyName: "hamburger", publicName: "hamburger", isSignal: true, isRequired: false, transformFunction: null }, glassEffect: { classPropertyName: "glassEffect", publicName: "glassEffect", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:keydown.escape": "closeSidebar()" }, properties: { "attr.data-glass-effect": "glassEffect()" } }, viewQueries: [{ propertyName: "menuButton", first: true, predicate: ["menuButton"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "<div class=\"ng-doc-navbar-container\">\n @if (hamburger()) {\n <button\n type=\"button\"\n class=\"ng-doc-menu\"\n ng-doc-button-icon\n size=\"large\"\n [rounded]=\"false\"\n aria-controls=\"ng-doc-sidenav\"\n [attr.aria-expanded]=\"sidebarService.expandedState()\"\n [attr.aria-label]=\"sidebarService.expandedState() ? texts.closeMenu : texts.openMenu\"\n (click)=\"sidebarService.toggle()\"\n #menuButton>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n </button>\n }\n <div class=\"ng-doc-navbar-left\">\n <ng-content select=\"[ngDocNavbarLeft]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-center\">\n <ng-content select=\"[ngDocNavbarCenter]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-right\">\n @if (search()) {\n <ng-doc-search></ng-doc-search>\n }\n <ng-content select=\"[ngDocNavbarRight]\"></ng-content>\n </div>\n</div>\n", styles: [":host{position:relative;display:flex;justify-content:center;height:100%;background:color-mix(in srgb,var(--ng-doc-navbar-background) 82%,transparent);backdrop-filter:saturate(1.4) blur(12px);border-bottom:var(--ng-doc-navbar-border);--ng-doc-button-color: var(--ng-doc-text-muted);--ng-doc-button-hover-color: var(--ng-doc-heading-color);--ng-doc-button-active-color: var(--ng-doc-heading-color);--ng-doc-button-hover-background: var(--ng-doc-hover-background)}:host[data-glass-effect=false]{background:var(--ng-doc-navbar-background);backdrop-filter:none}@supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)){:host{background:var(--ng-doc-navbar-background)}}.ng-doc-navbar-container{display:flex;align-items:center;gap:var(--ng-doc-space-4);width:100%;max-width:var(--ng-doc-app-max-width);height:100%;padding:0 var(--ng-doc-navbar-horizontal-padding)}.ng-doc-navbar-left,.ng-doc-navbar-center,.ng-doc-navbar-right{display:flex;align-items:center;gap:var(--ng-doc-space-4);min-width:0}.ng-doc-navbar-left{flex:none;max-width:var(--ng-doc-navbar-left-width)}.ng-doc-navbar-center{margin-left:auto}.ng-doc-navbar-right ng-doc-search{margin-left:var(--ng-doc-space-6)}@media(max-width:1024px){.ng-doc-navbar-right ng-doc-search{margin-left:0}}.ng-doc-menu{display:none;margin-left:calc(var(--ng-doc-space-2) * -1)}@media(max-width:1024px){.ng-doc-navbar-center{display:none}.ng-doc-navbar-right{margin-left:auto}}@media(max-width:900px){.ng-doc-menu{display:inline-flex}}@media(max-width:640px){.ng-doc-navbar-container{padding:0 var(--ng-doc-space-4)}}\n"], dependencies: [{ kind: "component", type: NgDocSearchComponent, selector: "ng-doc-search" }, { kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
51
53
  }
52
54
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocNavbarComponent, decorators: [{
53
55
  type: Component,
54
56
  args: [{ selector: 'ng-doc-navbar', changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgDocSearchComponent, NgDocButtonIconComponent], host: {
55
57
  '[attr.data-glass-effect]': 'glassEffect()',
56
58
  '(document:keydown.escape)': 'closeSidebar()',
57
- }, template: "<div class=\"ng-doc-navbar-container\">\n @if (hamburger()) {\n <button\n type=\"button\"\n class=\"ng-doc-menu\"\n ng-doc-button-icon\n size=\"large\"\n [rounded]=\"false\"\n aria-controls=\"ng-doc-sidenav\"\n [attr.aria-expanded]=\"sidebarService.expandedState()\"\n [attr.aria-label]=\"sidebarService.expandedState() ? 'Close navigation' : 'Open navigation'\"\n (click)=\"sidebarService.toggle()\"\n #menuButton>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n </button>\n }\n <div class=\"ng-doc-navbar-left\">\n <ng-content select=\"[ngDocNavbarLeft]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-center\">\n <ng-content select=\"[ngDocNavbarCenter]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-right\">\n @if (search()) {\n <ng-doc-search></ng-doc-search>\n }\n <ng-content select=\"[ngDocNavbarRight]\"></ng-content>\n </div>\n</div>\n", styles: [":host{position:relative;display:flex;justify-content:center;height:100%;background:color-mix(in srgb,var(--ng-doc-navbar-background) 82%,transparent);backdrop-filter:saturate(1.4) blur(12px);border-bottom:var(--ng-doc-navbar-border);--ng-doc-button-color: var(--ng-doc-text-muted);--ng-doc-button-hover-color: var(--ng-doc-heading-color);--ng-doc-button-active-color: var(--ng-doc-heading-color);--ng-doc-button-hover-background: var(--ng-doc-hover-background)}:host[data-glass-effect=false]{background:var(--ng-doc-navbar-background);backdrop-filter:none}@supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)){:host{background:var(--ng-doc-navbar-background)}}.ng-doc-navbar-container{display:flex;align-items:center;gap:var(--ng-doc-space-4);width:100%;max-width:var(--ng-doc-app-max-width);height:100%;padding:0 var(--ng-doc-navbar-horizontal-padding)}.ng-doc-navbar-left,.ng-doc-navbar-center,.ng-doc-navbar-right{display:flex;align-items:center;gap:var(--ng-doc-space-4);min-width:0}.ng-doc-navbar-left{flex:none;max-width:var(--ng-doc-navbar-left-width)}.ng-doc-navbar-center{margin-left:auto}.ng-doc-navbar-right ng-doc-search{margin-left:var(--ng-doc-space-6)}@media(max-width:1024px){.ng-doc-navbar-right ng-doc-search{margin-left:0}}.ng-doc-menu{display:none;margin-left:calc(var(--ng-doc-space-2) * -1)}@media(max-width:1024px){.ng-doc-navbar-center{display:none}.ng-doc-navbar-right{margin-left:auto}}@media(max-width:900px){.ng-doc-menu{display:inline-flex}}@media(max-width:640px){.ng-doc-navbar-container{padding:0 var(--ng-doc-space-4)}}\n"] }]
59
+ }, template: "<div class=\"ng-doc-navbar-container\">\n @if (hamburger()) {\n <button\n type=\"button\"\n class=\"ng-doc-menu\"\n ng-doc-button-icon\n size=\"large\"\n [rounded]=\"false\"\n aria-controls=\"ng-doc-sidenav\"\n [attr.aria-expanded]=\"sidebarService.expandedState()\"\n [attr.aria-label]=\"sidebarService.expandedState() ? texts.closeMenu : texts.openMenu\"\n (click)=\"sidebarService.toggle()\"\n #menuButton>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n </button>\n }\n <div class=\"ng-doc-navbar-left\">\n <ng-content select=\"[ngDocNavbarLeft]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-center\">\n <ng-content select=\"[ngDocNavbarCenter]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-right\">\n @if (search()) {\n <ng-doc-search></ng-doc-search>\n }\n <ng-content select=\"[ngDocNavbarRight]\"></ng-content>\n </div>\n</div>\n", styles: [":host{position:relative;display:flex;justify-content:center;height:100%;background:color-mix(in srgb,var(--ng-doc-navbar-background) 82%,transparent);backdrop-filter:saturate(1.4) blur(12px);border-bottom:var(--ng-doc-navbar-border);--ng-doc-button-color: var(--ng-doc-text-muted);--ng-doc-button-hover-color: var(--ng-doc-heading-color);--ng-doc-button-active-color: var(--ng-doc-heading-color);--ng-doc-button-hover-background: var(--ng-doc-hover-background)}:host[data-glass-effect=false]{background:var(--ng-doc-navbar-background);backdrop-filter:none}@supports not ((-webkit-backdrop-filter: none) or (backdrop-filter: none)){:host{background:var(--ng-doc-navbar-background)}}.ng-doc-navbar-container{display:flex;align-items:center;gap:var(--ng-doc-space-4);width:100%;max-width:var(--ng-doc-app-max-width);height:100%;padding:0 var(--ng-doc-navbar-horizontal-padding)}.ng-doc-navbar-left,.ng-doc-navbar-center,.ng-doc-navbar-right{display:flex;align-items:center;gap:var(--ng-doc-space-4);min-width:0}.ng-doc-navbar-left{flex:none;max-width:var(--ng-doc-navbar-left-width)}.ng-doc-navbar-center{margin-left:auto}.ng-doc-navbar-right ng-doc-search{margin-left:var(--ng-doc-space-6)}@media(max-width:1024px){.ng-doc-navbar-right ng-doc-search{margin-left:0}}.ng-doc-menu{display:none;margin-left:calc(var(--ng-doc-space-2) * -1)}@media(max-width:1024px){.ng-doc-navbar-center{display:none}.ng-doc-navbar-right{margin-left:auto}}@media(max-width:900px){.ng-doc-menu{display:inline-flex}}@media(max-width:640px){.ng-doc-navbar-container{padding:0 var(--ng-doc-space-4)}}\n"] }]
58
60
  }], propDecorators: { search: [{ type: i0.Input, args: [{ isSignal: true, alias: "search", required: false }] }], hamburger: [{ type: i0.Input, args: [{ isSignal: true, alias: "hamburger", required: false }] }], glassEffect: [{ type: i0.Input, args: [{ isSignal: true, alias: "glassEffect", required: false }] }], menuButton: [{ type: i0.ViewChild, args: ['menuButton', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
59
61
 
60
62
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-navbar.mjs","sources":["../../../../libs/app/components/navbar/navbar.component.ts","../../../../libs/app/components/navbar/navbar.component.html","../../../../libs/app/components/navbar/ng-doc-app-components-navbar.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n viewChild,\n} from '@angular/core';\nimport { NgDocSearchComponent } from '@ng-doc/app/components/search';\nimport { NgDocSidebarService } from '@ng-doc/app/services/sidebar';\nimport { NgDocButtonIconComponent } from '@ng-doc/ui-kit';\n\n/**\n * Navbar of the NgDoc application: the header bar above the sidebar and the page.\n *\n * It lays out, from left to right: the menu button (only where the sidebar is an overlay), the\n * content marked with `ngDocNavbarLeft` (for example the logo), the content marked with\n * `ngDocNavbarCenter` (for example the section links, hidden at 1024px and below), the search, and\n * the content marked with `ngDocNavbarRight` (for example the theme toggle).\n * @example\n * ```html\n * <ng-doc-navbar>\n * <a ngDocNavbarLeft routerLink=\"/\">My library</a>\n * <nav ngDocNavbarCenter aria-label=\"Primary\"><a routerLink=\"/docs\">Guides</a></nav>\n * <ng-doc-theme-toggle ngDocNavbarRight />\n * </ng-doc-navbar>\n * ```\n */\n@Component({\n selector: 'ng-doc-navbar',\n templateUrl: './navbar.component.html',\n styleUrls: ['./navbar.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgDocSearchComponent, NgDocButtonIconComponent],\n host: {\n '[attr.data-glass-effect]': 'glassEffect()',\n '(document:keydown.escape)': 'closeSidebar()',\n },\n})\nexport class NgDocNavbarComponent {\n protected readonly sidebarService = inject(NgDocSidebarService);\n\n /**\n * Show search input\n */\n readonly search = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /**\n * Show the menu button that opens the sidebar where it is an overlay (900px and below).\n */\n readonly hamburger = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /**\n * Use glass effect for navbar\n */\n readonly glassEffect = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n private readonly menuButton = viewChild('menuButton', { read: ElementRef<HTMLButtonElement> });\n\n /**\n * Closes the sidebar overlay and moves focus back to the menu button that opened it.\n */\n protected closeSidebar(): void {\n if (this.sidebarService.expandedState() && this.sidebarService.isMobile) {\n this.sidebarService.hide();\n this.menuButton()?.nativeElement.focus();\n }\n }\n}\n","<div class=\"ng-doc-navbar-container\">\n @if (hamburger()) {\n <button\n type=\"button\"\n class=\"ng-doc-menu\"\n ng-doc-button-icon\n size=\"large\"\n [rounded]=\"false\"\n aria-controls=\"ng-doc-sidenav\"\n [attr.aria-expanded]=\"sidebarService.expandedState()\"\n [attr.aria-label]=\"sidebarService.expandedState() ? 'Close navigation' : 'Open navigation'\"\n (click)=\"sidebarService.toggle()\"\n #menuButton>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n </button>\n }\n <div class=\"ng-doc-navbar-left\">\n <ng-content select=\"[ngDocNavbarLeft]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-center\">\n <ng-content select=\"[ngDocNavbarCenter]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-right\">\n @if (search()) {\n <ng-doc-search></ng-doc-search>\n }\n <ng-content select=\"[ngDocNavbarRight]\"></ng-content>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-navbar.mjs","sources":["../../../../libs/app/components/navbar/navbar.component.ts","../../../../libs/app/components/navbar/navbar.component.html","../../../../libs/app/components/navbar/ng-doc-app-components-navbar.ts"],"sourcesContent":["import {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n inject,\n input,\n viewChild,\n} from '@angular/core';\nimport { NgDocSearchComponent } from '@ng-doc/app/components/search';\nimport type { NgDocNavigationTexts } from '@ng-doc/app/interfaces';\nimport { NgDocSidebarService } from '@ng-doc/app/services/sidebar';\nimport { NG_DOC_TEXTS } from '@ng-doc/app/tokens';\nimport { NgDocButtonIconComponent } from '@ng-doc/ui-kit';\n\n/**\n * Navbar of the NgDoc application: the header bar above the sidebar and the page.\n *\n * It lays out, from left to right: the menu button (only where the sidebar is an overlay), the\n * content marked with `ngDocNavbarLeft` (for example the logo), the content marked with\n * `ngDocNavbarCenter` (for example the section links, hidden at 1024px and below), the search, and\n * the content marked with `ngDocNavbarRight` (for example the theme toggle).\n * @example\n * ```html\n * <ng-doc-navbar>\n * <a ngDocNavbarLeft routerLink=\"/\">My library</a>\n * <nav ngDocNavbarCenter aria-label=\"Primary\"><a routerLink=\"/docs\">Guides</a></nav>\n * <ng-doc-theme-toggle ngDocNavbarRight />\n * </ng-doc-navbar>\n * ```\n */\n@Component({\n selector: 'ng-doc-navbar',\n templateUrl: './navbar.component.html',\n styleUrls: ['./navbar.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [NgDocSearchComponent, NgDocButtonIconComponent],\n host: {\n '[attr.data-glass-effect]': 'glassEffect()',\n '(document:keydown.escape)': 'closeSidebar()',\n },\n})\nexport class NgDocNavbarComponent {\n protected readonly texts: NgDocNavigationTexts = inject(NG_DOC_TEXTS).navigation;\n\n protected readonly sidebarService = inject(NgDocSidebarService);\n\n /**\n * Show search input\n */\n readonly search = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /**\n * Show the menu button that opens the sidebar where it is an overlay (900px and below).\n */\n readonly hamburger = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /**\n * Use glass effect for navbar\n */\n readonly glassEffect = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n private readonly menuButton = viewChild('menuButton', { read: ElementRef<HTMLButtonElement> });\n\n /**\n * Closes the sidebar overlay and moves focus back to the menu button that opened it.\n */\n protected closeSidebar(): void {\n if (this.sidebarService.expandedState() && this.sidebarService.isMobile) {\n this.sidebarService.hide();\n this.menuButton()?.nativeElement.focus();\n }\n }\n}\n","<div class=\"ng-doc-navbar-container\">\n @if (hamburger()) {\n <button\n type=\"button\"\n class=\"ng-doc-menu\"\n ng-doc-button-icon\n size=\"large\"\n [rounded]=\"false\"\n aria-controls=\"ng-doc-sidenav\"\n [attr.aria-expanded]=\"sidebarService.expandedState()\"\n [attr.aria-label]=\"sidebarService.expandedState() ? texts.closeMenu : texts.openMenu\"\n (click)=\"sidebarService.toggle()\"\n #menuButton>\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <path d=\"M4 7h16M4 12h16M4 17h16\" />\n </svg>\n </button>\n }\n <div class=\"ng-doc-navbar-left\">\n <ng-content select=\"[ngDocNavbarLeft]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-center\">\n <ng-content select=\"[ngDocNavbarCenter]\"></ng-content>\n </div>\n <div class=\"ng-doc-navbar-right\">\n @if (search()) {\n <ng-doc-search></ng-doc-search>\n }\n <ng-content select=\"[ngDocNavbarRight]\"></ng-content>\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,12 +1,14 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, input, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { RouterLink } from '@angular/router';
4
+ import { NG_DOC_TEXTS } from '@ng-doc/app/tokens';
4
5
 
5
6
  /**
6
7
  * Links to the previous and the next page, as two cards at the bottom of a guide.
7
8
  */
8
9
  class NgDocPageNavigationComponent {
9
10
  constructor() {
11
+ this.texts = inject(NG_DOC_TEXTS).navigation;
10
12
  /** The page before this one in the sidebar. */
11
13
  this.prevPage = input(/* @ts-ignore */
12
14
  ...(ngDevMode ? [undefined, { debugName: "prevPage" }] : /* istanbul ignore next */ []));
@@ -15,11 +17,11 @@ class NgDocPageNavigationComponent {
15
17
  ...(ngDevMode ? [undefined, { debugName: "nextPage" }] : /* istanbul ignore next */ []));
16
18
  }
17
19
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
18
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageNavigationComponent, isStandalone: true, selector: "ng-doc-page-navigation", inputs: { prevPage: { classPropertyName: "prevPage", publicName: "prevPage", isSignal: true, isRequired: false, transformFunction: null }, nextPage: { classPropertyName: "nextPage", publicName: "nextPage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (prevPage() || nextPage()) {\n <nav class=\"ng-doc-navigation-controls\" aria-label=\"Previous and next page\">\n @if (prevPage(); as page) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M19 12H5m6-6-6 6 6 6\" />\n </svg>\n Previous\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n @if (nextPage(); as page) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n Next\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M5 12h14m-6-6 6 6-6 6\" />\n </svg>\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n </nav>\n}\n", styles: [".ng-doc-navigation-controls{display:grid;grid-template-columns:1fr 1fr;gap:var(--ng-doc-space-4);margin-top:var(--ng-doc-space-16);font-family:var(--ng-doc-font-family)}.ng-doc-navigation-controls a{display:grid;gap:2px;padding:var(--ng-doc-space-4) var(--ng-doc-space-5);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-lg);text-decoration:none;transition:border-color var(--ng-doc-transition)}.ng-doc-navigation-controls a:hover{border-color:var(--ng-doc-primary)}.ng-doc-navigation-controls a:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:2;text-align:right}.ng-doc-navigation-controls .ng-doc-next-page .ng-doc-navigation-page-label{justify-content:flex-end}.ng-doc-navigation-page-label{display:flex;align-items:center;gap:6px;color:var(--ng-doc-text-muted);font-size:13px;line-height:18px}.ng-doc-navigation-page-title{color:var(--ng-doc-link-color);font-size:var(--ng-doc-font-size);line-height:24px;font-weight:600;overflow-wrap:anywhere}@media(max-width:640px){.ng-doc-navigation-controls{grid-template-columns:1fr}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:auto}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
20
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageNavigationComponent, isStandalone: true, selector: "ng-doc-page-navigation", inputs: { prevPage: { classPropertyName: "prevPage", publicName: "prevPage", isSignal: true, isRequired: false, transformFunction: null }, nextPage: { classPropertyName: "nextPage", publicName: "nextPage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (prevPage() || nextPage()) {\n <nav class=\"ng-doc-navigation-controls\" [attr.aria-label]=\"texts.pages\">\n @if (prevPage(); as page) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M19 12H5m6-6-6 6 6 6\" />\n </svg>\n {{ texts.previous }}\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n @if (nextPage(); as page) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n {{ texts.next }}\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M5 12h14m-6-6 6 6-6 6\" />\n </svg>\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n </nav>\n}\n", styles: [".ng-doc-navigation-controls{display:grid;grid-template-columns:1fr 1fr;gap:var(--ng-doc-space-4);margin-top:var(--ng-doc-space-16);font-family:var(--ng-doc-font-family)}.ng-doc-navigation-controls a{display:grid;gap:2px;padding:var(--ng-doc-space-4) var(--ng-doc-space-5);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-lg);text-decoration:none;transition:border-color var(--ng-doc-transition)}.ng-doc-navigation-controls a:hover{border-color:var(--ng-doc-primary)}.ng-doc-navigation-controls a:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:2;text-align:right}.ng-doc-navigation-controls .ng-doc-next-page .ng-doc-navigation-page-label{justify-content:flex-end}.ng-doc-navigation-page-label{display:flex;align-items:center;gap:6px;color:var(--ng-doc-text-muted);font-size:13px;line-height:18px}.ng-doc-navigation-page-title{color:var(--ng-doc-link-color);font-size:var(--ng-doc-font-size);line-height:24px;font-weight:600;overflow-wrap:anywhere}@media(max-width:640px){.ng-doc-navigation-controls{grid-template-columns:1fr}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:auto}}\n"], dependencies: [{ kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
19
21
  }
20
22
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageNavigationComponent, decorators: [{
21
23
  type: Component,
22
- args: [{ selector: 'ng-doc-page-navigation', imports: [RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (prevPage() || nextPage()) {\n <nav class=\"ng-doc-navigation-controls\" aria-label=\"Previous and next page\">\n @if (prevPage(); as page) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M19 12H5m6-6-6 6 6 6\" />\n </svg>\n Previous\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n @if (nextPage(); as page) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n Next\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M5 12h14m-6-6 6 6-6 6\" />\n </svg>\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n </nav>\n}\n", styles: [".ng-doc-navigation-controls{display:grid;grid-template-columns:1fr 1fr;gap:var(--ng-doc-space-4);margin-top:var(--ng-doc-space-16);font-family:var(--ng-doc-font-family)}.ng-doc-navigation-controls a{display:grid;gap:2px;padding:var(--ng-doc-space-4) var(--ng-doc-space-5);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-lg);text-decoration:none;transition:border-color var(--ng-doc-transition)}.ng-doc-navigation-controls a:hover{border-color:var(--ng-doc-primary)}.ng-doc-navigation-controls a:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:2;text-align:right}.ng-doc-navigation-controls .ng-doc-next-page .ng-doc-navigation-page-label{justify-content:flex-end}.ng-doc-navigation-page-label{display:flex;align-items:center;gap:6px;color:var(--ng-doc-text-muted);font-size:13px;line-height:18px}.ng-doc-navigation-page-title{color:var(--ng-doc-link-color);font-size:var(--ng-doc-font-size);line-height:24px;font-weight:600;overflow-wrap:anywhere}@media(max-width:640px){.ng-doc-navigation-controls{grid-template-columns:1fr}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:auto}}\n"] }]
24
+ args: [{ selector: 'ng-doc-page-navigation', imports: [RouterLink], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (prevPage() || nextPage()) {\n <nav class=\"ng-doc-navigation-controls\" [attr.aria-label]=\"texts.pages\">\n @if (prevPage(); as page) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M19 12H5m6-6-6 6 6 6\" />\n </svg>\n {{ texts.previous }}\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n @if (nextPage(); as page) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n {{ texts.next }}\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M5 12h14m-6-6 6 6-6 6\" />\n </svg>\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n </nav>\n}\n", styles: [".ng-doc-navigation-controls{display:grid;grid-template-columns:1fr 1fr;gap:var(--ng-doc-space-4);margin-top:var(--ng-doc-space-16);font-family:var(--ng-doc-font-family)}.ng-doc-navigation-controls a{display:grid;gap:2px;padding:var(--ng-doc-space-4) var(--ng-doc-space-5);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-lg);text-decoration:none;transition:border-color var(--ng-doc-transition)}.ng-doc-navigation-controls a:hover{border-color:var(--ng-doc-primary)}.ng-doc-navigation-controls a:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:2;text-align:right}.ng-doc-navigation-controls .ng-doc-next-page .ng-doc-navigation-page-label{justify-content:flex-end}.ng-doc-navigation-page-label{display:flex;align-items:center;gap:6px;color:var(--ng-doc-text-muted);font-size:13px;line-height:18px}.ng-doc-navigation-page-title{color:var(--ng-doc-link-color);font-size:var(--ng-doc-font-size);line-height:24px;font-weight:600;overflow-wrap:anywhere}@media(max-width:640px){.ng-doc-navigation-controls{grid-template-columns:1fr}.ng-doc-navigation-controls .ng-doc-next-page{grid-column:auto}}\n"] }]
23
25
  }], propDecorators: { prevPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevPage", required: false }] }], nextPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPage", required: false }] }] } });
24
26
 
25
27
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-page-navigation.mjs","sources":["../../../../libs/app/components/page-navigation/page-navigation.component.ts","../../../../libs/app/components/page-navigation/page-navigation.component.html","../../../../libs/app/components/page-navigation/ng-doc-app-components-page-navigation.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { NgDocNavigation, NgDocPageNavigation } from '@ng-doc/app/interfaces';\n\n/**\n * Links to the previous and the next page, as two cards at the bottom of a guide.\n */\n@Component({\n selector: 'ng-doc-page-navigation',\n imports: [RouterLink],\n templateUrl: './page-navigation.component.html',\n styleUrls: ['./page-navigation.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocPageNavigationComponent implements NgDocPageNavigation {\n /** The page before this one in the sidebar. */\n readonly prevPage = input<NgDocNavigation>();\n\n /** The page after this one in the sidebar. */\n readonly nextPage = input<NgDocNavigation>();\n}\n","@if (prevPage() || nextPage()) {\n <nav class=\"ng-doc-navigation-controls\" aria-label=\"Previous and next page\">\n @if (prevPage(); as page) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M19 12H5m6-6-6 6 6 6\" />\n </svg>\n Previous\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n @if (nextPage(); as page) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n Next\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M5 12h14m-6-6 6 6-6 6\" />\n </svg>\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n </nav>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAIA;;AAEG;MAQU,4BAA4B,CAAA;AAPzC,IAAA,WAAA,GAAA;;AASW,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK;gGAAmB;;AAGnC,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK;gGAAmB;AAC7C,IAAA;8GANY,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAA5B,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECdzC,w7CA4CA,EAAA,MAAA,EAAA,CAAA,4qCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDnCY,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAKT,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBAPxC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,WACzB,CAAC,UAAU,CAAC,EAAA,eAAA,EAGJ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,w7CAAA,EAAA,MAAA,EAAA,CAAA,4qCAAA,CAAA,EAAA;;;AEZjD;;AAEG;;;;"}
1
+ {"version":3,"file":"ng-doc-app-components-page-navigation.mjs","sources":["../../../../libs/app/components/page-navigation/page-navigation.component.ts","../../../../libs/app/components/page-navigation/page-navigation.component.html","../../../../libs/app/components/page-navigation/ng-doc-app-components-page-navigation.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';\nimport { RouterLink } from '@angular/router';\nimport { NgDocNavigation, NgDocNavigationTexts, NgDocPageNavigation } from '@ng-doc/app/interfaces';\nimport { NG_DOC_TEXTS } from '@ng-doc/app/tokens';\n\n/**\n * Links to the previous and the next page, as two cards at the bottom of a guide.\n */\n@Component({\n selector: 'ng-doc-page-navigation',\n imports: [RouterLink],\n templateUrl: './page-navigation.component.html',\n styleUrls: ['./page-navigation.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocPageNavigationComponent implements NgDocPageNavigation {\n protected readonly texts: NgDocNavigationTexts = inject(NG_DOC_TEXTS).navigation;\n\n /** The page before this one in the sidebar. */\n readonly prevPage = input<NgDocNavigation>();\n\n /** The page after this one in the sidebar. */\n readonly nextPage = input<NgDocNavigation>();\n}\n","@if (prevPage() || nextPage()) {\n <nav class=\"ng-doc-navigation-controls\" [attr.aria-label]=\"texts.pages\">\n @if (prevPage(); as page) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M19 12H5m6-6-6 6 6 6\" />\n </svg>\n {{ texts.previous }}\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n @if (nextPage(); as page) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"page.route\">\n <span class=\"ng-doc-navigation-page-label\">\n {{ texts.next }}\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M5 12h14m-6-6 6 6-6 6\" />\n </svg>\n </span>\n <span class=\"ng-doc-navigation-page-title\">{{ page.title }}</span>\n </a>\n }\n </nav>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAKA;;AAEG;MAQU,4BAA4B,CAAA;AAPzC,IAAA,WAAA,GAAA;AAQqB,QAAA,IAAA,CAAA,KAAK,GAAyB,MAAM,CAAC,YAAY,CAAC,CAAC,UAAU;;AAGvE,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK;gGAAmB;;AAGnC,QAAA,IAAA,CAAA,QAAQ,GAAG,KAAK;gGAAmB;AAC7C,IAAA;8GARY,4BAA4B,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAA5B,4BAA4B,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,wBAAA,EAAA,MAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,QAAA,EAAA,EAAA,iBAAA,EAAA,UAAA,EAAA,UAAA,EAAA,UAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECfzC,48CA4CA,EAAA,MAAA,EAAA,CAAA,4qCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDlCY,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAKT,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBAPxC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,WACzB,CAAC,UAAU,CAAC,EAAA,eAAA,EAGJ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,48CAAA,EAAA,MAAA,EAAA,CAAA,4qCAAA,CAAA,EAAA;;;AEbjD;;AAEG;;;;"}
@@ -87,7 +87,7 @@ class NgDocPageWrapperComponent {
87
87
  };
88
88
  }
89
89
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
90
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageWrapperComponent, isStandalone: true, selector: "ng-doc-page-wrapper", inputs: { routes: { classPropertyName: "routes", publicName: "routes", isSignal: true, isRequired: true, transformFunction: null }, headerContent: { classPropertyName: "headerContent", publicName: "headerContent", isSignal: true, isRequired: true, transformFunction: null }, headerContentSource: { classPropertyName: "headerContentSource", publicName: "headerContentSource", isSignal: true, isRequired: false, transformFunction: null }, hasBreadcrumb: { classPropertyName: "hasBreadcrumb", publicName: "hasBreadcrumb", isSignal: true, isRequired: false, transformFunction: null }, pageType: { classPropertyName: "pageType", publicName: "pageType", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-ng-doc-page-tabs": "routes().length > 1", "attr.data-ng-doc-fullscreen-route": "fullscreenRoute.active()" } }, viewQueries: [{ propertyName: "pageBreadcrumbs", first: true, predicate: ["pageBreadcrumbs"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "pageToc", first: true, predicate: ["pageToc"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "pageNavigation", first: true, predicate: ["pageNavigation"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: var(--ng-doc-navbar-height)}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);max-width:var(--ng-doc-article-width, var(--ng-doc-content-max-width));margin-left:auto;margin-right:auto;min-width:0}:host article:has(.ng-doc-page-tags),:host article:has(ng-doc-api-list){max-width:var(--ng-doc-article-width, var(--ng-doc-api-content-max-width))}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:var(--ng-doc-navbar-height);margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}:host[data-ng-doc-fullscreen-route=true]{display:block}:host[data-ng-doc-fullscreen-route=true] article{width:100%;max-width:none}:host[data-ng-doc-fullscreen-route=true] ::ng-deep>:not(article),:host[data-ng-doc-fullscreen-route=true] ::ng-deep article>:not(router-outlet+*){display:none}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NgDocTabRouteComponent, selector: "a[ng-doc-tab-route]", inputs: ["isActive"] }, { kind: "component", type: NgDocTabRoutesGroupComponent, selector: "ng-doc-tab-routes-group" }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageHeaderComponent, selector: "ng-doc-page-header", inputs: ["headerContent", "headerContentSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
90
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageWrapperComponent, isStandalone: true, selector: "ng-doc-page-wrapper", inputs: { routes: { classPropertyName: "routes", publicName: "routes", isSignal: true, isRequired: true, transformFunction: null }, headerContent: { classPropertyName: "headerContent", publicName: "headerContent", isSignal: true, isRequired: true, transformFunction: null }, headerContentSource: { classPropertyName: "headerContentSource", publicName: "headerContentSource", isSignal: true, isRequired: false, transformFunction: null }, hasBreadcrumb: { classPropertyName: "hasBreadcrumb", publicName: "hasBreadcrumb", isSignal: true, isRequired: false, transformFunction: null }, pageType: { classPropertyName: "pageType", publicName: "pageType", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-ng-doc-page-tabs": "routes().length > 1", "attr.data-ng-doc-fullscreen-route": "fullscreenRoute.active()" } }, viewQueries: [{ propertyName: "pageBreadcrumbs", first: true, predicate: ["pageBreadcrumbs"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "pageToc", first: true, predicate: ["pageToc"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "pageNavigation", first: true, predicate: ["pageNavigation"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: calc(var(--ng-doc-navbar-height) + var(--ng-doc-layout-top))}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-layout-top) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);max-width:var(--ng-doc-article-width, var(--ng-doc-content-max-width));margin-left:auto;margin-right:auto;min-width:0}:host article:has(.ng-doc-page-tags),:host article:has(ng-doc-api-list){max-width:var(--ng-doc-article-width, var(--ng-doc-api-content-max-width))}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:calc(var(--ng-doc-navbar-height) + var(--ng-doc-layout-top));margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}:host[data-ng-doc-fullscreen-route=true]{display:block}:host[data-ng-doc-fullscreen-route=true] article{width:100%;max-width:none}:host[data-ng-doc-fullscreen-route=true] ::ng-deep>:not(article),:host[data-ng-doc-fullscreen-route=true] ::ng-deep article>:not(router-outlet+*){display:none}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NgDocTabRouteComponent, selector: "a[ng-doc-tab-route]", inputs: ["isActive"] }, { kind: "component", type: NgDocTabRoutesGroupComponent, selector: "ng-doc-tab-routes-group" }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageHeaderComponent, selector: "ng-doc-page-header", inputs: ["headerContent", "headerContentSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
91
91
  }
92
92
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageWrapperComponent, decorators: [{
93
93
  type: Component,
@@ -102,7 +102,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImpor
102
102
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
103
103
  '[attr.data-ng-doc-page-tabs]': 'routes().length > 1',
104
104
  '[attr.data-ng-doc-fullscreen-route]': 'fullscreenRoute.active()',
105
- }, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: var(--ng-doc-navbar-height)}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);max-width:var(--ng-doc-article-width, var(--ng-doc-content-max-width));margin-left:auto;margin-right:auto;min-width:0}:host article:has(.ng-doc-page-tags),:host article:has(ng-doc-api-list){max-width:var(--ng-doc-article-width, var(--ng-doc-api-content-max-width))}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:var(--ng-doc-navbar-height);margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}:host[data-ng-doc-fullscreen-route=true]{display:block}:host[data-ng-doc-fullscreen-route=true] article{width:100%;max-width:none}:host[data-ng-doc-fullscreen-route=true] ::ng-deep>:not(article),:host[data-ng-doc-fullscreen-route=true] ::ng-deep article>:not(router-outlet+*){display:none}\n"] }]
105
+ }, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: calc(var(--ng-doc-navbar-height) + var(--ng-doc-layout-top))}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-layout-top) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);max-width:var(--ng-doc-article-width, var(--ng-doc-content-max-width));margin-left:auto;margin-right:auto;min-width:0}:host article:has(.ng-doc-page-tags),:host article:has(ng-doc-api-list){max-width:var(--ng-doc-article-width, var(--ng-doc-api-content-max-width))}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:calc(var(--ng-doc-navbar-height) + var(--ng-doc-layout-top));margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}:host[data-ng-doc-fullscreen-route=true]{display:block}:host[data-ng-doc-fullscreen-route=true] article{width:100%;max-width:none}:host[data-ng-doc-fullscreen-route=true] ::ng-deep>:not(article),:host[data-ng-doc-fullscreen-route=true] ::ng-deep article>:not(router-outlet+*){display:none}\n"] }]
106
106
  }], propDecorators: { routes: [{ type: i0.Input, args: [{ isSignal: true, alias: "routes", required: true }] }], headerContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerContent", required: true }] }], headerContentSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerContentSource", required: false }] }], hasBreadcrumb: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBreadcrumb", required: false }] }], pageType: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageType", required: false }] }], pageBreadcrumbs: [{ type: i0.ViewChild, args: ['pageBreadcrumbs', { ...{ read: ViewContainerRef }, isSignal: true }] }], pageToc: [{ type: i0.ViewChild, args: ['pageToc', { ...{ read: ViewContainerRef }, isSignal: true }] }], pageNavigation: [{ type: i0.ViewChild, args: ['pageNavigation', { ...{ read: ViewContainerRef }, isSignal: true }] }] } });
107
107
 
108
108
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-page-wrapper.mjs","sources":["../../../../libs/app/components/page-wrapper/page-wrapper.component.ts","../../../../libs/app/components/page-wrapper/page-wrapper.component.html","../../../../libs/app/components/page-wrapper/ng-doc-app-components-page-wrapper.ts"],"sourcesContent":["import {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n inject,\n Injector,\n input,\n OnInit,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n RouterLink,\n RouterLinkActive,\n RouterOutlet,\n Routes,\n} from '@angular/router';\nimport { NgDocPageHeaderComponent } from '@ng-doc/app/components/page-header';\nimport { createComponent } from '@ng-doc/app/helpers';\nimport { NgDocNavigation } from '@ng-doc/app/interfaces';\nimport { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';\nimport { NgDocRoutePreloader } from '@ng-doc/app/services/route-preloader';\nimport { NG_DOC_CONTEXT, NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport { isPresent } from '@ng-doc/core/helpers/is-present';\nimport type { NgDocContentSource } from '@ng-doc/core/interfaces';\nimport { NgDocPageType } from '@ng-doc/core/types';\nimport {\n NgDocIconComponent,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n} from '@ng-doc/ui-kit';\n\n/**\n * Layout of a generated page: the breadcrumbs, the page header, the tabs of a page with several\n * routes, the page itself, the previous and next page links, and the table of contents beside it.\n *\n * The breadcrumbs, the page links and the table of contents are the page skeleton's components,\n * created in the containers this component exposes.\n *\n * While the page shows one of its fullscreen routes (`NgDocFullscreenRouteService`), only the page\n * is shown.\n */\n@Component({\n selector: 'ng-doc-page-wrapper',\n imports: [\n RouterOutlet,\n RouterLink,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n RouterLinkActive,\n NgDocIconComponent,\n NgDocPageHeaderComponent,\n ],\n templateUrl: './page-wrapper.component.html',\n styleUrl: './page-wrapper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-ng-doc-page-tabs]': 'routes().length > 1',\n '[attr.data-ng-doc-fullscreen-route]': 'fullscreenRoute.active()',\n },\n})\nexport class NgDocPageWrapperComponent implements OnInit {\n /** Routes of the page; a page with more than one gets tabs. */\n readonly routes = input.required<Routes>();\n\n /** HTML of the page header. */\n readonly headerContent = input.required<string>();\n\n /** Deferred source of the page header, for generated pages that load it separately. */\n readonly headerContentSource = input<NgDocContentSource>();\n\n /** Whether the page shows breadcrumbs. */\n readonly hasBreadcrumb = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /** Type of the page: guides get previous and next page links, API pages do not. */\n readonly pageType = input<NgDocPageType>('guide');\n\n /** Container of the breadcrumbs. */\n readonly pageBreadcrumbs = viewChild.required('pageBreadcrumbs', { read: ViewContainerRef });\n\n /** Container of the table of contents. */\n readonly pageToc = viewChild.required('pageToc', { read: ViewContainerRef });\n\n /** Container of the previous and next page links. */\n readonly pageNavigation = viewChild.required('pageNavigation', { read: ViewContainerRef });\n\n protected skeleton = inject(NG_DOC_PAGE_SKELETON);\n protected router = inject(Router);\n protected route = inject(ActivatedRoute);\n protected context = inject(NG_DOC_CONTEXT);\n protected readonly fullscreenRoute = inject(NgDocFullscreenRouteService);\n\n private breadcrumbs: string[] = inject(ActivatedRoute)\n .pathFromRoot.filter((route: ActivatedRoute) => !!route.snapshot.url.length)\n .map((route: ActivatedRoute) => route.snapshot.title)\n .filter(isPresent);\n\n private readonly preloader = inject(NgDocRoutePreloader);\n private readonly injector = inject(Injector);\n\n ngOnInit(): void {\n if (this.skeleton.breadcrumbs && this.hasBreadcrumb()) {\n createComponent(this.pageBreadcrumbs(), this.skeleton.breadcrumbs, {\n breadcrumbs: this.breadcrumbs,\n });\n }\n\n if (this.pageType() === 'guide' && this.skeleton.navigation) {\n createComponent(this.pageNavigation(), this.skeleton.navigation, this.adjacentPages());\n }\n\n // Readers often go on to the previous or next guide, so both are preloaded once the browser\n // is idle after this one has rendered. Render hooks never run on the server.\n afterNextRender(\n () => {\n if (this.pageType() !== 'guide') return;\n\n const { prevPage, nextPage } = this.adjacentPages();\n\n this.preloader.preloadWhenIdle([prevPage?.route, nextPage?.route]);\n },\n { injector: this.injector },\n );\n }\n\n private adjacentPages(): { prevPage?: NgDocNavigation; nextPage?: NgDocNavigation } {\n const url =\n '/' +\n this.route.pathFromRoot\n .map((route: ActivatedRoute) => route.snapshot.url)\n .flat()\n .join('/');\n const flatItems = (items: NgDocNavigation[]): NgDocNavigation[] =>\n items\n .map((item: NgDocNavigation) => [item.children?.length ? flatItems(item.children) : item])\n .flat(2);\n const flatPages: NgDocNavigation[] = flatItems(this.context.navigation);\n\n return {\n prevPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) - 1],\n nextPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) + 1],\n };\n }\n}\n","<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-page-wrapper.mjs","sources":["../../../../libs/app/components/page-wrapper/page-wrapper.component.ts","../../../../libs/app/components/page-wrapper/page-wrapper.component.html","../../../../libs/app/components/page-wrapper/ng-doc-app-components-page-wrapper.ts"],"sourcesContent":["import {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n inject,\n Injector,\n input,\n OnInit,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n RouterLink,\n RouterLinkActive,\n RouterOutlet,\n Routes,\n} from '@angular/router';\nimport { NgDocPageHeaderComponent } from '@ng-doc/app/components/page-header';\nimport { createComponent } from '@ng-doc/app/helpers';\nimport { NgDocNavigation } from '@ng-doc/app/interfaces';\nimport { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';\nimport { NgDocRoutePreloader } from '@ng-doc/app/services/route-preloader';\nimport { NG_DOC_CONTEXT, NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport { isPresent } from '@ng-doc/core/helpers/is-present';\nimport type { NgDocContentSource } from '@ng-doc/core/interfaces';\nimport { NgDocPageType } from '@ng-doc/core/types';\nimport {\n NgDocIconComponent,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n} from '@ng-doc/ui-kit';\n\n/**\n * Layout of a generated page: the breadcrumbs, the page header, the tabs of a page with several\n * routes, the page itself, the previous and next page links, and the table of contents beside it.\n *\n * The breadcrumbs, the page links and the table of contents are the page skeleton's components,\n * created in the containers this component exposes.\n *\n * While the page shows one of its fullscreen routes (`NgDocFullscreenRouteService`), only the page\n * is shown.\n */\n@Component({\n selector: 'ng-doc-page-wrapper',\n imports: [\n RouterOutlet,\n RouterLink,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n RouterLinkActive,\n NgDocIconComponent,\n NgDocPageHeaderComponent,\n ],\n templateUrl: './page-wrapper.component.html',\n styleUrl: './page-wrapper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-ng-doc-page-tabs]': 'routes().length > 1',\n '[attr.data-ng-doc-fullscreen-route]': 'fullscreenRoute.active()',\n },\n})\nexport class NgDocPageWrapperComponent implements OnInit {\n /** Routes of the page; a page with more than one gets tabs. */\n readonly routes = input.required<Routes>();\n\n /** HTML of the page header. */\n readonly headerContent = input.required<string>();\n\n /** Deferred source of the page header, for generated pages that load it separately. */\n readonly headerContentSource = input<NgDocContentSource>();\n\n /** Whether the page shows breadcrumbs. */\n readonly hasBreadcrumb = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /** Type of the page: guides get previous and next page links, API pages do not. */\n readonly pageType = input<NgDocPageType>('guide');\n\n /** Container of the breadcrumbs. */\n readonly pageBreadcrumbs = viewChild.required('pageBreadcrumbs', { read: ViewContainerRef });\n\n /** Container of the table of contents. */\n readonly pageToc = viewChild.required('pageToc', { read: ViewContainerRef });\n\n /** Container of the previous and next page links. */\n readonly pageNavigation = viewChild.required('pageNavigation', { read: ViewContainerRef });\n\n protected skeleton = inject(NG_DOC_PAGE_SKELETON);\n protected router = inject(Router);\n protected route = inject(ActivatedRoute);\n protected context = inject(NG_DOC_CONTEXT);\n protected readonly fullscreenRoute = inject(NgDocFullscreenRouteService);\n\n private breadcrumbs: string[] = inject(ActivatedRoute)\n .pathFromRoot.filter((route: ActivatedRoute) => !!route.snapshot.url.length)\n .map((route: ActivatedRoute) => route.snapshot.title)\n .filter(isPresent);\n\n private readonly preloader = inject(NgDocRoutePreloader);\n private readonly injector = inject(Injector);\n\n ngOnInit(): void {\n if (this.skeleton.breadcrumbs && this.hasBreadcrumb()) {\n createComponent(this.pageBreadcrumbs(), this.skeleton.breadcrumbs, {\n breadcrumbs: this.breadcrumbs,\n });\n }\n\n if (this.pageType() === 'guide' && this.skeleton.navigation) {\n createComponent(this.pageNavigation(), this.skeleton.navigation, this.adjacentPages());\n }\n\n // Readers often go on to the previous or next guide, so both are preloaded once the browser\n // is idle after this one has rendered. Render hooks never run on the server.\n afterNextRender(\n () => {\n if (this.pageType() !== 'guide') return;\n\n const { prevPage, nextPage } = this.adjacentPages();\n\n this.preloader.preloadWhenIdle([prevPage?.route, nextPage?.route]);\n },\n { injector: this.injector },\n );\n }\n\n private adjacentPages(): { prevPage?: NgDocNavigation; nextPage?: NgDocNavigation } {\n const url =\n '/' +\n this.route.pathFromRoot\n .map((route: ActivatedRoute) => route.snapshot.url)\n .flat()\n .join('/');\n const flatItems = (items: NgDocNavigation[]): NgDocNavigation[] =>\n items\n .map((item: NgDocNavigation) => [item.children?.length ? flatItems(item.children) : item])\n .flat(2);\n const flatPages: NgDocNavigation[] = flatItems(this.context.navigation);\n\n return {\n prevPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) - 1],\n nextPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) + 1],\n };\n }\n}\n","<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}