@ng-doc/app 22.0.0-beta.2 → 22.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +20 -29
  2. package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs +363 -0
  3. package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs.map +1 -0
  4. package/fesm2022/ng-doc-app-classes-content-controller.mjs +299 -0
  5. package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -0
  6. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +51 -35
  7. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
  8. package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
  9. package/fesm2022/ng-doc-app-classes-search-engine.mjs.map +1 -1
  10. package/fesm2022/ng-doc-app-classes.mjs +2 -0
  11. package/fesm2022/ng-doc-app-classes.mjs.map +1 -1
  12. package/fesm2022/ng-doc-app-components-api-list.mjs +173 -69
  13. package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
  14. package/fesm2022/ng-doc-app-components-breadcrumb.mjs +13 -10
  15. package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
  16. package/fesm2022/ng-doc-app-components-code.mjs +152 -25
  17. package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
  18. package/fesm2022/ng-doc-app-components-command-palette.mjs +498 -0
  19. package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -0
  20. package/fesm2022/ng-doc-app-components-copy-button.mjs +38 -21
  21. package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
  22. package/fesm2022/ng-doc-app-components-demo-displayer.mjs +36 -29
  23. package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
  24. package/fesm2022/ng-doc-app-components-demo-frame.mjs +96 -0
  25. package/fesm2022/ng-doc-app-components-demo-frame.mjs.map +1 -0
  26. package/fesm2022/ng-doc-app-components-demo-pane.mjs +39 -36
  27. package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
  28. package/fesm2022/ng-doc-app-components-demo.mjs +175 -44
  29. package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
  30. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +12 -9
  31. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
  32. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +79 -0
  33. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -0
  34. package/fesm2022/ng-doc-app-components-heading-anchor.mjs +54 -21
  35. package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
  36. package/fesm2022/ng-doc-app-components-image-viewer.mjs +183 -89
  37. package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
  38. package/fesm2022/ng-doc-app-components-kind-icon.mjs +42 -25
  39. package/fesm2022/ng-doc-app-components-kind-icon.mjs.map +1 -1
  40. package/fesm2022/ng-doc-app-components-link.mjs +12 -9
  41. package/fesm2022/ng-doc-app-components-link.mjs.map +1 -1
  42. package/fesm2022/ng-doc-app-components-members.mjs +30 -0
  43. package/fesm2022/ng-doc-app-components-members.mjs.map +1 -0
  44. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs +61 -20
  45. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs.map +1 -1
  46. package/fesm2022/ng-doc-app-components-navbar.mjs +39 -49
  47. package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
  48. package/fesm2022/ng-doc-app-components-page-header.mjs +73 -10
  49. package/fesm2022/ng-doc-app-components-page-header.mjs.map +1 -1
  50. package/fesm2022/ng-doc-app-components-page-link.mjs +123 -31
  51. package/fesm2022/ng-doc-app-components-page-link.mjs.map +1 -1
  52. package/fesm2022/ng-doc-app-components-page-navigation.mjs +17 -19
  53. package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
  54. package/fesm2022/ng-doc-app-components-page-wrapper.mjs +56 -35
  55. package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
  56. package/fesm2022/ng-doc-app-components-page.mjs +168 -24
  57. package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
  58. package/fesm2022/ng-doc-app-components-playground.mjs +477 -286
  59. package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
  60. package/fesm2022/ng-doc-app-components-root.mjs +48 -31
  61. package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
  62. package/fesm2022/ng-doc-app-components-search-result.mjs +22 -21
  63. package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
  64. package/fesm2022/ng-doc-app-components-search.mjs +64 -33
  65. package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
  66. package/fesm2022/ng-doc-app-components-sidebar.mjs +86 -61
  67. package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
  68. package/fesm2022/ng-doc-app-components-tabs.mjs +35 -11
  69. package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
  70. package/fesm2022/ng-doc-app-components-theme-toggle.mjs +33 -21
  71. package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
  72. package/fesm2022/ng-doc-app-components-toc.mjs +267 -90
  73. package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
  74. package/fesm2022/ng-doc-app-components.mjs +4 -1
  75. package/fesm2022/ng-doc-app-components.mjs.map +1 -1
  76. package/fesm2022/ng-doc-app-defaults-default-processors.mjs +2 -1
  77. package/fesm2022/ng-doc-app-defaults-default-processors.mjs.map +1 -1
  78. package/fesm2022/ng-doc-app-demo-app.mjs +176 -0
  79. package/fesm2022/ng-doc-app-demo-app.mjs.map +1 -0
  80. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs +11 -5
  81. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs.map +1 -1
  82. package/fesm2022/ng-doc-app-directives-members-filter.mjs +276 -0
  83. package/fesm2022/ng-doc-app-directives-members-filter.mjs.map +1 -0
  84. package/fesm2022/ng-doc-app-directives-route-active.mjs +34 -30
  85. package/fesm2022/ng-doc-app-directives-route-active.mjs.map +1 -1
  86. package/fesm2022/ng-doc-app-directives.mjs +1 -0
  87. package/fesm2022/ng-doc-app-directives.mjs.map +1 -1
  88. package/fesm2022/ng-doc-app-helpers.mjs +307 -2
  89. package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
  90. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs +6 -4
  91. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs.map +1 -1
  92. package/fesm2022/ng-doc-app-pipes-extract-value.mjs +6 -4
  93. package/fesm2022/ng-doc-app-pipes-extract-value.mjs.map +1 -1
  94. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs +7 -4
  95. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs.map +1 -1
  96. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs +8 -5
  97. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs.map +1 -1
  98. package/fesm2022/ng-doc-app-processors-page-processor.mjs +86 -23
  99. package/fesm2022/ng-doc-app-processors-page-processor.mjs.map +1 -1
  100. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs +26 -25
  101. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs.map +1 -1
  102. package/fesm2022/ng-doc-app-processors-processors.mjs +42 -10
  103. package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
  104. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +31 -2
  105. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
  106. package/fesm2022/ng-doc-app-providers-title.mjs +129 -0
  107. package/fesm2022/ng-doc-app-providers-title.mjs.map +1 -0
  108. package/fesm2022/ng-doc-app-providers.mjs +1 -0
  109. package/fesm2022/ng-doc-app-providers.mjs.map +1 -1
  110. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +122 -0
  111. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -0
  112. package/fesm2022/ng-doc-app-services-content-state.mjs +57 -0
  113. package/fesm2022/ng-doc-app-services-content-state.mjs.map +1 -0
  114. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs +74 -0
  115. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs.map +1 -0
  116. package/fesm2022/ng-doc-app-services-highlighter.mjs +90 -17
  117. package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
  118. package/fesm2022/ng-doc-app-services-route-preloader.mjs +384 -0
  119. package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -0
  120. package/fesm2022/ng-doc-app-services-shortcuts.mjs +214 -0
  121. package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -0
  122. package/fesm2022/ng-doc-app-services-sidebar.mjs +59 -25
  123. package/fesm2022/ng-doc-app-services-sidebar.mjs.map +1 -1
  124. package/fesm2022/ng-doc-app-services-store.mjs +8 -8
  125. package/fesm2022/ng-doc-app-services-store.mjs.map +1 -1
  126. package/fesm2022/ng-doc-app-services-theme.mjs +32 -12
  127. package/fesm2022/ng-doc-app-services-theme.mjs.map +1 -1
  128. package/fesm2022/ng-doc-app-services.mjs +143 -0
  129. package/fesm2022/ng-doc-app-services.mjs.map +1 -1
  130. package/fesm2022/ng-doc-app-tokens.mjs +7 -28
  131. package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
  132. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs +18 -9
  133. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs.map +1 -1
  134. package/fesm2022/ng-doc-app-type-controls-number-control.mjs +12 -9
  135. package/fesm2022/ng-doc-app-type-controls-number-control.mjs.map +1 -1
  136. package/fesm2022/ng-doc-app-type-controls-string-control.mjs +12 -9
  137. package/fesm2022/ng-doc-app-type-controls-string-control.mjs.map +1 -1
  138. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +59 -18
  139. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
  140. package/package.json +82 -28
  141. package/styles/global.css +1128 -201
  142. package/styles/main.css +1128 -201
  143. package/styles/themes/dark.css +88 -56
  144. package/types/ng-doc-app-classes-content-anchor-controller.d.ts +54 -0
  145. package/types/ng-doc-app-classes-content-controller.d.ts +94 -0
  146. package/types/ng-doc-app-classes-default-search-engine.d.ts +9 -1
  147. package/types/ng-doc-app-classes-root-page.d.ts +14 -1
  148. package/types/ng-doc-app-classes-search-engine.d.ts +5 -0
  149. package/types/ng-doc-app-classes.d.ts +2 -0
  150. package/types/ng-doc-app-components-api-list.d.ts +69 -20
  151. package/types/ng-doc-app-components-breadcrumb.d.ts +8 -3
  152. package/types/ng-doc-app-components-code.d.ts +46 -12
  153. package/types/ng-doc-app-components-command-palette.d.ts +147 -0
  154. package/types/ng-doc-app-components-copy-button.d.ts +18 -6
  155. package/types/ng-doc-app-components-demo-displayer.d.ts +23 -10
  156. package/types/ng-doc-app-components-demo-frame.d.ts +48 -0
  157. package/types/ng-doc-app-components-demo-pane.d.ts +19 -15
  158. package/types/ng-doc-app-components-demo.d.ts +80 -15
  159. package/types/ng-doc-app-components-fullscreen-button.d.ts +4 -2
  160. package/types/ng-doc-app-components-fullscreen-toggle.d.ts +24 -0
  161. package/types/ng-doc-app-components-heading-anchor.d.ts +26 -7
  162. package/types/ng-doc-app-components-image-viewer.d.ts +71 -7
  163. package/types/ng-doc-app-components-kind-icon.d.ts +28 -7
  164. package/types/ng-doc-app-components-link.d.ts +6 -2
  165. package/types/ng-doc-app-components-members.d.ts +13 -0
  166. package/types/ng-doc-app-components-mermaid-viewer.d.ts +21 -6
  167. package/types/ng-doc-app-components-navbar.d.ts +25 -15
  168. package/types/ng-doc-app-components-page-header.d.ts +28 -4
  169. package/types/ng-doc-app-components-page-link.d.ts +34 -15
  170. package/types/ng-doc-app-components-page-navigation.d.ts +10 -5
  171. package/types/ng-doc-app-components-page-wrapper.d.ts +35 -11
  172. package/types/ng-doc-app-components-page.d.ts +57 -6
  173. package/types/ng-doc-app-components-playground.d.ts +167 -78
  174. package/types/ng-doc-app-components-root.d.ts +28 -7
  175. package/types/ng-doc-app-components-search-result.d.ts +14 -6
  176. package/types/ng-doc-app-components-search.d.ts +19 -7
  177. package/types/ng-doc-app-components-tabs.d.ts +24 -5
  178. package/types/ng-doc-app-components-theme-toggle.d.ts +18 -5
  179. package/types/ng-doc-app-components-toc.d.ts +76 -29
  180. package/types/ng-doc-app-components.d.ts +4 -1
  181. package/types/ng-doc-app-demo-app.d.ts +89 -0
  182. package/types/ng-doc-app-directives-code-highlighter.d.ts +8 -4
  183. package/types/ng-doc-app-directives-members-filter.d.ts +61 -0
  184. package/types/ng-doc-app-directives-route-active.d.ts +21 -7
  185. package/types/ng-doc-app-directives.d.ts +1 -0
  186. package/types/ng-doc-app-helpers.d.ts +142 -3
  187. package/types/ng-doc-app-interfaces.d.ts +62 -31
  188. package/types/ng-doc-app-pipes-decode-uri-component.d.ts +3 -0
  189. package/types/ng-doc-app-pipes-extract-value.d.ts +3 -0
  190. package/types/ng-doc-app-pipes-filter-by-text.d.ts +4 -0
  191. package/types/ng-doc-app-pipes-sanitize-html.d.ts +4 -2
  192. package/types/ng-doc-app-processors-page-processor.d.ts +39 -10
  193. package/types/ng-doc-app-processors-processors-tooltip.d.ts +11 -10
  194. package/types/ng-doc-app-processors-processors.d.ts +10 -1
  195. package/types/ng-doc-app-providers-ng-doc-app.d.ts +18 -1
  196. package/types/ng-doc-app-providers-title.d.ts +59 -0
  197. package/types/ng-doc-app-providers.d.ts +1 -0
  198. package/types/ng-doc-app-services-content-scroll-intent.d.ts +52 -0
  199. package/types/ng-doc-app-services-content-state.d.ts +40 -0
  200. package/types/ng-doc-app-services-fullscreen-route.d.ts +35 -0
  201. package/types/ng-doc-app-services-highlighter.d.ts +47 -5
  202. package/types/ng-doc-app-services-route-preloader.d.ts +121 -0
  203. package/types/ng-doc-app-services-shortcuts.d.ts +96 -0
  204. package/types/ng-doc-app-services-sidebar.d.ts +24 -4
  205. package/types/ng-doc-app-services-store.d.ts +24 -1
  206. package/types/ng-doc-app-services-theme.d.ts +19 -3
  207. package/types/ng-doc-app-services.d.ts +77 -0
  208. package/types/ng-doc-app-tokens.d.ts +10 -30
  209. package/types/ng-doc-app-type-controls-boolean-control.d.ts +11 -6
  210. package/types/ng-doc-app-type-controls-number-control.d.ts +5 -3
  211. package/types/ng-doc-app-type-controls-string-control.d.ts +5 -3
  212. package/types/ng-doc-app-type-controls-type-alias-control.d.ts +35 -6
  213. package/fesm2022/ng-doc-app-components-search-dialog.mjs +0 -78
  214. package/fesm2022/ng-doc-app-components-search-dialog.mjs.map +0 -1
  215. package/types/ng-doc-app-components-search-dialog.d.ts +0 -28
@@ -1,28 +1,26 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { RouterLink } from '@angular/router';
4
- import { NgDocIconComponent, NgDocTextComponent, NgDocTextLeftDirective, NgDocTextRightDirective } from '@ng-doc/ui-kit';
5
4
 
5
+ /**
6
+ * Links to the previous and the next page, as two cards at the bottom of a guide.
7
+ */
6
8
  class NgDocPageNavigationComponent {
7
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPageNavigationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgDocPageNavigationComponent, isStandalone: true, selector: "ng-doc-page-navigation", inputs: { prevPage: "prevPage", nextPage: "nextPage" }, ngImport: i0, template: "<div class=\"ng-doc-navigation-controls\">\n @if (prevPage) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"prevPage.route\">\n <div class=\"ng-doc-navigation-page-label\" ng-doc-text size=\"small\">\n <ng-doc-icon icon=\"arrow-left\" ngDocTextLeft></ng-doc-icon>\n Previous\n </div>\n <div class=\"ng-doc-navigation-page-title\" ng-doc-text>{{ prevPage.title }}</div>\n </a>\n }\n @if (nextPage) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"nextPage.route\">\n <div class=\"ng-doc-navigation-page-label\" ng-doc-text size=\"small\">\n Next\n <ng-doc-icon icon=\"arrow-right\" ngDocTextRight></ng-doc-icon>\n </div>\n <div class=\"ng-doc-navigation-page-title\" ng-doc-text>{{ nextPage.title }}</div>\n </a>\n }\n</div>\n", styles: [":host .ng-doc-navigation-controls{display:flex;margin-top:calc(var(--ng-doc-base-gutter) * 12);border-top:1px solid var(--ng-doc-base-2);padding-top:calc(var(--ng-doc-base-gutter) * 2)}:host .ng-doc-navigation-controls a{display:flex;flex-direction:column;text-decoration:unset;transition:var(--ng-doc-transition);--ng-doc-button-hover-background: var(--ng-doc-base-1);--ng-doc-button-active-background: var(--ng-doc-base-2);--ng-doc-text: var(--ng-doc-base-9);--ng-doc-icon-color: var(--ng-doc-text)}:host .ng-doc-navigation-controls a:hover{opacity:.6}:host .ng-doc-navigation-controls a.ng-doc-next-page{margin-left:auto}:host .ng-doc-navigation-controls a.ng-doc-prev-page{align-items:flex-start}:host .ng-doc-navigation-controls a.ng-doc-next-page{align-items:flex-end}:host .ng-doc-navigation-controls a .ng-doc-navigation-page-title{--ng-doc-text: var(--ng-doc-link-color)}\n"], dependencies: [{ kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocTextComponent, selector: "[ng-doc-text]", inputs: ["size", "color", "align", "absoluteContent"] }, { kind: "directive", type: NgDocTextLeftDirective, selector: "[ngDocTextLeft]" }, { kind: "directive", type: NgDocTextRightDirective, selector: "[ngDocTextRight]" }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9
+ constructor() {
10
+ /** The page before this one in the sidebar. */
11
+ this.prevPage = input(/* @ts-ignore */
12
+ ...(ngDevMode ? [undefined, { debugName: "prevPage" }] : /* istanbul ignore next */ []));
13
+ /** The page after this one in the sidebar. */
14
+ this.nextPage = input(/* @ts-ignore */
15
+ ...(ngDevMode ? [undefined, { debugName: "nextPage" }] : /* istanbul ignore next */ []));
16
+ }
17
+ 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 }); }
9
19
  }
10
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPageNavigationComponent, decorators: [{
20
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageNavigationComponent, decorators: [{
11
21
  type: Component,
12
- args: [{ selector: 'ng-doc-page-navigation', imports: [
13
- NgDocIconComponent,
14
- NgDocTextComponent,
15
- NgDocTextLeftDirective,
16
- NgDocTextRightDirective,
17
- RouterLink,
18
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ng-doc-navigation-controls\">\n @if (prevPage) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"prevPage.route\">\n <div class=\"ng-doc-navigation-page-label\" ng-doc-text size=\"small\">\n <ng-doc-icon icon=\"arrow-left\" ngDocTextLeft></ng-doc-icon>\n Previous\n </div>\n <div class=\"ng-doc-navigation-page-title\" ng-doc-text>{{ prevPage.title }}</div>\n </a>\n }\n @if (nextPage) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"nextPage.route\">\n <div class=\"ng-doc-navigation-page-label\" ng-doc-text size=\"small\">\n Next\n <ng-doc-icon icon=\"arrow-right\" ngDocTextRight></ng-doc-icon>\n </div>\n <div class=\"ng-doc-navigation-page-title\" ng-doc-text>{{ nextPage.title }}</div>\n </a>\n }\n</div>\n", styles: [":host .ng-doc-navigation-controls{display:flex;margin-top:calc(var(--ng-doc-base-gutter) * 12);border-top:1px solid var(--ng-doc-base-2);padding-top:calc(var(--ng-doc-base-gutter) * 2)}:host .ng-doc-navigation-controls a{display:flex;flex-direction:column;text-decoration:unset;transition:var(--ng-doc-transition);--ng-doc-button-hover-background: var(--ng-doc-base-1);--ng-doc-button-active-background: var(--ng-doc-base-2);--ng-doc-text: var(--ng-doc-base-9);--ng-doc-icon-color: var(--ng-doc-text)}:host .ng-doc-navigation-controls a:hover{opacity:.6}:host .ng-doc-navigation-controls a.ng-doc-next-page{margin-left:auto}:host .ng-doc-navigation-controls a.ng-doc-prev-page{align-items:flex-start}:host .ng-doc-navigation-controls a.ng-doc-next-page{align-items:flex-end}:host .ng-doc-navigation-controls a .ng-doc-navigation-page-title{--ng-doc-text: var(--ng-doc-link-color)}\n"] }]
19
- }], propDecorators: { prevPage: [{
20
- type: Input,
21
- args: [{ required: true }]
22
- }], nextPage: [{
23
- type: Input,
24
- args: [{ required: true }]
25
- }] } });
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"] }]
23
+ }], propDecorators: { prevPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "prevPage", required: false }] }], nextPage: [{ type: i0.Input, args: [{ isSignal: true, alias: "nextPage", required: false }] }] } });
26
24
 
27
25
  /**
28
26
  * Generated bundle index. Do not edit.
@@ -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';\nimport {\n NgDocIconComponent,\n NgDocTextComponent,\n NgDocTextLeftDirective,\n NgDocTextRightDirective,\n} from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-page-navigation',\n imports: [\n NgDocIconComponent,\n NgDocTextComponent,\n NgDocTextLeftDirective,\n NgDocTextRightDirective,\n RouterLink,\n ],\n templateUrl: './page-navigation.component.html',\n styleUrls: ['./page-navigation.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocPageNavigationComponent implements NgDocPageNavigation {\n @Input({ required: true })\n prevPage?: NgDocNavigation;\n\n @Input({ required: true })\n nextPage?: NgDocNavigation;\n}\n","<div class=\"ng-doc-navigation-controls\">\n @if (prevPage) {\n <a class=\"ng-doc-prev-page\" [routerLink]=\"prevPage.route\">\n <div class=\"ng-doc-navigation-page-label\" ng-doc-text size=\"small\">\n <ng-doc-icon icon=\"arrow-left\" ngDocTextLeft></ng-doc-icon>\n Previous\n </div>\n <div class=\"ng-doc-navigation-page-title\" ng-doc-text>{{ prevPage.title }}</div>\n </a>\n }\n @if (nextPage) {\n <a class=\"ng-doc-next-page\" [routerLink]=\"nextPage.route\">\n <div class=\"ng-doc-navigation-page-label\" ng-doc-text size=\"small\">\n Next\n <ng-doc-icon icon=\"arrow-right\" ngDocTextRight></ng-doc-icon>\n </div>\n <div class=\"ng-doc-navigation-page-title\" ng-doc-text>{{ nextPage.title }}</div>\n </a>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAuBa,4BAA4B,CAAA;8GAA5B,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,UAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,ECvBzC,kyBAoBA,EAAA,MAAA,EAAA,CAAA,o3BAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDPI,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,kBAAkB,EAAA,QAAA,EAAA,eAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,OAAA,EAAA,OAAA,EAAA,iBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,sBAAsB,EAAA,QAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,uBAAuB,EAAA,QAAA,EAAA,kBAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACvB,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;;2FAMD,4BAA4B,EAAA,UAAA,EAAA,CAAA;kBAbxC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,wBAAwB,EAAA,OAAA,EACzB;wBACP,kBAAkB;wBAClB,kBAAkB;wBAClB,sBAAsB;wBACtB,uBAAuB;wBACvB,UAAU;qBACX,EAAA,eAAA,EAGgB,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,kyBAAA,EAAA,MAAA,EAAA,CAAA,o3BAAA,CAAA,EAAA;;sBAG9C,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;sBAGxB,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;;AE3B3B;;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, 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,38 +1,77 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ViewContainerRef, ViewChild, Input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, booleanAttribute, viewChild, ViewContainerRef, inject, Injector, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { Router, ActivatedRoute, RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
4
4
  import { NgDocPageHeaderComponent } from '@ng-doc/app/components/page-header';
5
5
  import { createComponent } from '@ng-doc/app/helpers';
6
+ import { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';
7
+ import { NgDocRoutePreloader } from '@ng-doc/app/services/route-preloader';
6
8
  import { NG_DOC_PAGE_SKELETON, NG_DOC_CONTEXT } from '@ng-doc/app/tokens';
7
9
  import { isPresent } from '@ng-doc/core/helpers/is-present';
8
10
  import { NgDocTabRouteComponent, NgDocTabRoutesGroupComponent, NgDocIconComponent } from '@ng-doc/ui-kit';
9
11
 
12
+ /**
13
+ * Layout of a generated page: the breadcrumbs, the page header, the tabs of a page with several
14
+ * routes, the page itself, the previous and next page links, and the table of contents beside it.
15
+ *
16
+ * The breadcrumbs, the page links and the table of contents are the page skeleton's components,
17
+ * created in the containers this component exposes.
18
+ *
19
+ * While the page shows one of its fullscreen routes (`NgDocFullscreenRouteService`), only the page
20
+ * is shown.
21
+ */
10
22
  class NgDocPageWrapperComponent {
11
23
  constructor() {
12
- this.hasBreadcrumb = true;
13
- this.pageType = 'guide';
24
+ /** Routes of the page; a page with more than one gets tabs. */
25
+ this.routes = input.required(/* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "routes" }] : /* istanbul ignore next */ []));
27
+ /** HTML of the page header. */
28
+ this.headerContent = input.required(/* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "headerContent" }] : /* istanbul ignore next */ []));
30
+ /** Deferred source of the page header, for generated pages that load it separately. */
31
+ this.headerContentSource = input(/* @ts-ignore */
32
+ ...(ngDevMode ? [undefined, { debugName: "headerContentSource" }] : /* istanbul ignore next */ []));
33
+ /** Whether the page shows breadcrumbs. */
34
+ this.hasBreadcrumb = input(true, { ...(ngDevMode ? { debugName: "hasBreadcrumb" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
35
+ /** Type of the page: guides get previous and next page links, API pages do not. */
36
+ this.pageType = input('guide', /* @ts-ignore */
37
+ ...(ngDevMode ? [{ debugName: "pageType" }] : /* istanbul ignore next */ []));
38
+ /** Container of the breadcrumbs. */
39
+ this.pageBreadcrumbs = viewChild.required('pageBreadcrumbs', { ...(ngDevMode ? { debugName: "pageBreadcrumbs" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
40
+ /** Container of the table of contents. */
41
+ this.pageToc = viewChild.required('pageToc', { ...(ngDevMode ? { debugName: "pageToc" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
42
+ /** Container of the previous and next page links. */
43
+ this.pageNavigation = viewChild.required('pageNavigation', { ...(ngDevMode ? { debugName: "pageNavigation" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
14
44
  this.skeleton = inject(NG_DOC_PAGE_SKELETON);
15
45
  this.router = inject(Router);
16
46
  this.route = inject(ActivatedRoute);
17
47
  this.context = inject(NG_DOC_CONTEXT);
48
+ this.fullscreenRoute = inject(NgDocFullscreenRouteService);
18
49
  this.breadcrumbs = inject(ActivatedRoute)
19
50
  .pathFromRoot.filter((route) => !!route.snapshot.url.length)
20
51
  .map((route) => route.snapshot.title)
21
52
  .filter(isPresent);
53
+ this.preloader = inject(NgDocRoutePreloader);
54
+ this.injector = inject(Injector);
22
55
  }
23
56
  ngOnInit() {
24
- if (this.skeleton.breadcrumbs && this.hasBreadcrumb) {
25
- createComponent(this.pageBreadcrumbs, this.skeleton.breadcrumbs, {
57
+ if (this.skeleton.breadcrumbs && this.hasBreadcrumb()) {
58
+ createComponent(this.pageBreadcrumbs(), this.skeleton.breadcrumbs, {
26
59
  breadcrumbs: this.breadcrumbs,
27
60
  });
28
61
  }
29
- if (this.pageType === 'guide') {
30
- if (this.skeleton.navigation) {
31
- createComponent(this.pageNavigation, this.skeleton.navigation, this.navigationInputs());
32
- }
62
+ if (this.pageType() === 'guide' && this.skeleton.navigation) {
63
+ createComponent(this.pageNavigation(), this.skeleton.navigation, this.adjacentPages());
33
64
  }
65
+ // Readers often go on to the previous or next guide, so both are preloaded once the browser
66
+ // is idle after this one has rendered. Render hooks never run on the server.
67
+ afterNextRender(() => {
68
+ if (this.pageType() !== 'guide')
69
+ return;
70
+ const { prevPage, nextPage } = this.adjacentPages();
71
+ this.preloader.preloadWhenIdle([prevPage?.route, nextPage?.route]);
72
+ }, { injector: this.injector });
34
73
  }
35
- navigationInputs() {
74
+ adjacentPages() {
36
75
  const url = '/' +
37
76
  this.route.pathFromRoot
38
77
  .map((route) => route.snapshot.url)
@@ -47,10 +86,10 @@ class NgDocPageWrapperComponent {
47
86
  nextPage: flatPages[flatPages.findIndex((item) => url === item.route) + 1],
48
87
  };
49
88
  }
50
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPageWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
51
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgDocPageWrapperComponent, isStandalone: true, selector: "ng-doc-page-wrapper", inputs: { routes: "routes", headerContent: "headerContent", hasBreadcrumb: "hasBreadcrumb", pageType: "pageType" }, host: { properties: { "attr.data-ng-doc-page-tabs": "routes.length > 1" } }, viewQueries: [{ propertyName: "pageBreadcrumbs", first: true, predicate: ["pageBreadcrumbs"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "pageToc", first: true, predicate: ["pageToc"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "pageNavigation", first: true, predicate: ["pageNavigation"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header [headerContent]=\"headerContent\" />\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%);margin-left:auto;margin-right:auto;min-width:0}: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)}\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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
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 }); }
52
91
  }
53
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPageWrapperComponent, decorators: [{
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageWrapperComponent, decorators: [{
54
93
  type: Component,
55
94
  args: [{ selector: 'ng-doc-page-wrapper', imports: [
56
95
  RouterOutlet,
@@ -61,28 +100,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
61
100
  NgDocIconComponent,
62
101
  NgDocPageHeaderComponent,
63
102
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
64
- '[attr.data-ng-doc-page-tabs]': 'routes.length > 1',
65
- }, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header [headerContent]=\"headerContent\" />\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%);margin-left:auto;margin-right:auto;min-width:0}: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)}\n"] }]
66
- }], propDecorators: { routes: [{
67
- type: Input,
68
- args: [{ required: true }]
69
- }], headerContent: [{
70
- type: Input,
71
- args: [{ required: true }]
72
- }], hasBreadcrumb: [{
73
- type: Input
74
- }], pageType: [{
75
- type: Input
76
- }], pageBreadcrumbs: [{
77
- type: ViewChild,
78
- args: ['pageBreadcrumbs', { read: ViewContainerRef, static: true }]
79
- }], pageToc: [{
80
- type: ViewChild,
81
- args: ['pageToc', { read: ViewContainerRef, static: true }]
82
- }], pageNavigation: [{
83
- type: ViewChild,
84
- args: ['pageNavigation', { read: ViewContainerRef, static: true }]
85
- }] } });
103
+ '[attr.data-ng-doc-page-tabs]': 'routes().length > 1',
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"] }]
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 }] }] } });
86
107
 
87
108
  /**
88
109
  * Generated bundle index. Do not edit.
@@ -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 ChangeDetectionStrategy,\n Component,\n inject,\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, NgDocPageNavigation } from '@ng-doc/app/interfaces';\nimport { NG_DOC_CONTEXT, NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport { isPresent } from '@ng-doc/core/helpers/is-present';\nimport { NgDocPageType } from '@ng-doc/core/types';\nimport {\n NgDocIconComponent,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n} from '@ng-doc/ui-kit';\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 },\n})\nexport class NgDocPageWrapperComponent implements OnInit {\n @Input({ required: true })\n routes!: Routes;\n\n @Input({ required: true })\n headerContent!: string;\n\n @Input()\n hasBreadcrumb = true;\n\n @Input()\n pageType: NgDocPageType = 'guide';\n\n @ViewChild('pageBreadcrumbs', { read: ViewContainerRef, static: true })\n pageBreadcrumbs!: ViewContainerRef;\n\n @ViewChild('pageToc', { read: ViewContainerRef, static: true })\n pageToc?: ViewContainerRef;\n\n @ViewChild('pageNavigation', { read: ViewContainerRef, static: true })\n pageNavigation!: 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\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 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') {\n if (this.skeleton.navigation) {\n createComponent(this.pageNavigation, this.skeleton.navigation, this.navigationInputs());\n }\n }\n }\n\n private navigationInputs(): NgDocPageNavigation {\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 [headerContent]=\"headerContent\" />\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":";;;;;;;;;MA+Ca,yBAAyB,CAAA;AAlBtC,IAAA,WAAA,GAAA;QA0BE,IAAA,CAAA,aAAa,GAAG,IAAI;QAGpB,IAAA,CAAA,QAAQ,GAAkB,OAAO;AAWvB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,oBAAoB,CAAC;AACvC,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AACvB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AAC9B,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,cAAc,CAAC;AAElC,QAAA,IAAA,CAAA,WAAW,GAAa,MAAM,CAAC,cAAc;AAClD,aAAA,YAAY,CAAC,MAAM,CAAC,CAAC,KAAqB,KAAK,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM;aAC1E,GAAG,CAAC,CAAC,KAAqB,KAAK,KAAK,CAAC,QAAQ,CAAC,KAAK;aACnD,MAAM,CAAC,SAAS,CAAC;AAkCrB,IAAA;IAhCC,QAAQ,GAAA;QACN,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,EAAE;YACnD,eAAe,CAAC,IAAI,CAAC,eAAe,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE;gBAC/D,WAAW,EAAE,IAAI,CAAC,WAAW;AAC9B,aAAA,CAAC;QACJ;AAEA,QAAA,IAAI,IAAI,CAAC,QAAQ,KAAK,OAAO,EAAE;AAC7B,YAAA,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;AAC5B,gBAAA,eAAe,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACzF;QACF;IACF;IAEQ,gBAAgB,GAAA;QACtB,MAAM,GAAG,GACP,GAAG;YACH,IAAI,CAAC,KAAK,CAAC;iBACR,GAAG,CAAC,CAAC,KAAqB,KAAK,KAAK,CAAC,QAAQ,CAAC,GAAG;AACjD,iBAAA,IAAI;iBACJ,IAAI,CAAC,GAAG,CAAC;AACd,QAAA,MAAM,SAAS,GAAG,CAAC,KAAwB,KACzC;aACG,GAAG,CAAC,CAAC,IAAqB,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;aACxF,IAAI,CAAC,CAAC,CAAC;QACZ,MAAM,SAAS,GAAsB,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QAEvE,OAAO;YACL,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAqB,KAAK,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3F,QAAQ,EAAE,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,IAAqB,KAAK,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;SAC5F;IACH;8GA/DW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAzB,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,EAAA,MAAA,EAAA,QAAA,EAAA,aAAA,EAAA,eAAA,EAAA,aAAA,EAAA,eAAA,EAAA,QAAA,EAAA,UAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,4BAAA,EAAA,mBAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,iBAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,iBAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EAaE,gBAAgB,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,SAAA,CAAA,EAAA,WAAA,EAAA,IAAA,EAAA,IAAA,EAGxB,gBAAgB,yHAGT,gBAAgB,EAAA,MAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EClEvD,y0BA8BA,EAAA,MAAA,EAAA,CAAA,2wBAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDEI,YAAY,+KACZ,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,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACV,sBAAsB,EAAA,QAAA,EAAA,qBAAA,EAAA,MAAA,EAAA,CAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EACtB,4BAA4B,oEAC5B,gBAAgB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,yBAAA,EAAA,uBAAA,EAAA,kBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,gBAAA,CAAA,EAAA,QAAA,EAAA,CAAA,kBAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAChB,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,wBAAwB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,eAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FASf,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBAlBrC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,qBAAqB,EAAA,OAAA,EACtB;wBACP,YAAY;wBACZ,UAAU;wBACV,sBAAsB;wBACtB,4BAA4B;wBAC5B,gBAAgB;wBAChB,kBAAkB;wBAClB,wBAAwB;qBACzB,EAAA,eAAA,EAGgB,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC;AACJ,wBAAA,8BAA8B,EAAE,mBAAmB;AACpD,qBAAA,EAAA,QAAA,EAAA,y0BAAA,EAAA,MAAA,EAAA,CAAA,2wBAAA,CAAA,EAAA;;sBAGA,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;sBAGxB,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;sBAGxB;;sBAGA;;sBAGA,SAAS;uBAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE;;sBAGrE,SAAS;uBAAC,SAAS,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE;;sBAG7D,SAAS;uBAAC,gBAAgB,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,MAAM,EAAE,IAAI,EAAE;;;AElEvE;;AAEG;;;;"}
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,62 +1,206 @@
1
+ import { Clipboard } from '@angular/cdk/clipboard';
2
+ import { LocationStrategy, isPlatformBrowser } from '@angular/common';
1
3
  import * as i0 from '@angular/core';
2
- import { inject, ChangeDetectorRef, ElementRef, ViewChild, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { RouterOutlet } from '@angular/router';
4
+ import { viewChild, ElementRef, inject, ChangeDetectorRef, signal, NgZone, PLATFORM_ID, effect, untracked, DestroyRef, reflectComponentType, ChangeDetectionStrategy, Component } from '@angular/core';
5
+ import { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';
6
+ import { NgDocContentAnchorController } from '@ng-doc/app/classes/content-anchor-controller';
7
+ import { NgDocContentController } from '@ng-doc/app/classes/content-controller';
4
8
  import { NgDocRootPage } from '@ng-doc/app/classes/root-page';
5
9
  import { NgDocPageWrapperComponent } from '@ng-doc/app/components/page-wrapper';
6
- import { createComponent, generateToc } from '@ng-doc/app/helpers';
10
+ import { ɵrestoreNgDocHydrationSnapshot as _restoreNgDocHydrationSnapshot, generateToc, createComponent, ɵngDocPageUrl as _ngDocPageUrl } from '@ng-doc/app/helpers';
7
11
  import { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';
8
12
  import { NgDocPageProcessorComponent } from '@ng-doc/app/processors';
9
13
  import { provideTypeControl } from '@ng-doc/app/providers/type-control';
14
+ import { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';
10
15
  import { NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';
11
16
  import { NgDocTypeAliasControlComponent, NgDocStringControlComponent, NgDocNumberControlComponent, NgDocBooleanControlComponent } from '@ng-doc/app/type-controls';
12
- import { NgDocButtonIconComponent, NgDocTooltipDirective, NgDocIconComponent, DialogOutletComponent } from '@ng-doc/ui-kit';
17
+ import { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';
18
+ import { WA_LOCATION } from '@ng-web-apis/common';
13
19
 
20
+ /**
21
+ * A generated page: its rendered content, the page actions (copy link, edit and view the source),
22
+ * the table of contents it fills in, and the outlet of its fullscreen routes.
23
+ *
24
+ * A fullscreen route (a child route of the page, unless the page sets `disableFullscreenRoutes`)
25
+ * replaces the page: it is shown on its own on the canvas of demos, with a link back to the page,
26
+ * and `NgDocFullscreenRouteService` tells the root layout and the page wrapper to hide their
27
+ * chrome.
28
+ */
14
29
  class NgDocPageComponent {
15
30
  constructor() {
31
+ /** The element that holds the rendered page content. */
32
+ this.pageContainer = viewChild('pageContainer', { ...(ngDevMode ? { debugName: "pageContainer" } : /* istanbul ignore next */ {}), read: (ElementRef) });
16
33
  this.rootPage = inject(NgDocRootPage);
17
34
  this.skeleton = inject(NG_DOC_PAGE_SKELETON);
18
35
  this.changeDetectorRef = inject(ChangeDetectorRef);
19
36
  this.pageWrapper = inject(NgDocPageWrapperComponent);
37
+ this.contentController = inject(NgDocContentController);
38
+ /** Whether the link to the page was just copied. */
39
+ this.linkCopied = signal(false, /* @ts-ignore */
40
+ ...(ngDevMode ? [{ debugName: "linkCopied" }] : /* istanbul ignore next */ []));
41
+ /** Whether one of the page's fullscreen routes is shown instead of the page. */
42
+ this.fullscreenRoute = signal(false, /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "fullscreenRoute" }] : /* istanbul ignore next */ []));
44
+ /** URL of the page, for the link back from a fullscreen route. */
45
+ this.pageUrl = signal('/', /* @ts-ignore */
46
+ ...(ngDevMode ? [{ debugName: "pageUrl" }] : /* istanbul ignore next */ []));
47
+ this.route = inject(ActivatedRoute);
48
+ this.fullscreenRoutes = inject(NgDocFullscreenRouteService);
49
+ this.contentAnchorController = inject(NgDocContentAnchorController);
50
+ this.clipboard = inject(Clipboard);
51
+ this.ngZone = inject(NgZone);
52
+ this.location = inject(WA_LOCATION);
53
+ this.locationStrategy = inject(LocationStrategy);
54
+ // The router state is complete when the page is created, so a fullscreen route opened
55
+ // directly (a new tab) is known before the first render and the page content never renders.
56
+ this.showFullscreenRoute(!!this.route.firstChild);
57
+ const source = this.rootPage.pageContentSource;
58
+ if (source && !this.fullscreenRoute()) {
59
+ // Angular empties this host (it skips hydration) and the content loads asynchronously, so
60
+ // the server-rendered page stays visible until the loaded content renders.
61
+ if (isPlatformBrowser(inject(PLATFORM_ID))) {
62
+ this.snapshot = _restoreNgDocHydrationSnapshot(inject(ElementRef).nativeElement);
63
+ }
64
+ this.connectContent(source);
65
+ }
66
+ // A page opened on a fullscreen route loads its content only when the reader goes back to
67
+ // it, because pending content holds the application unstable until it renders. An effect,
68
+ // so a page that is leaving (its route closes as it is destroyed) loads nothing.
69
+ effect(() => {
70
+ if (source && !this.fullscreenRoute())
71
+ untracked(() => this.connectContent(source));
72
+ });
73
+ // A load that needs no new pass (its content is already rendered, for example an empty body)
74
+ // or that failed settles without `revealLoaded`.
75
+ effect(() => {
76
+ if (this.contentController.settled())
77
+ untracked(() => this.releaseSnapshot());
78
+ });
79
+ effect(() => {
80
+ if (this.contentController.error()) {
81
+ untracked(() => {
82
+ this.releaseSnapshot();
83
+ this.pageWrapper.pageToc().clear();
84
+ this.contentAnchorController.contentFailed();
85
+ });
86
+ }
87
+ });
88
+ inject(DestroyRef).onDestroy(() => {
89
+ clearTimeout(this.linkCopiedTimer);
90
+ this.releaseSnapshot();
91
+ this.fullscreenRoutes.set(this, false);
92
+ });
93
+ }
94
+ /**
95
+ * Shows one of the page's fullscreen routes instead of the page, or the page again. The outlet
96
+ * of the fullscreen routes calls it when a route opens or closes.
97
+ * @param shown - Whether a fullscreen route is shown.
98
+ */
99
+ showFullscreenRoute(shown) {
100
+ // Pages that disable fullscreen routes render their child routes themselves.
101
+ const fullscreen = shown && !this.rootPage.page?.disableFullscreenRoutes;
102
+ if (fullscreen) {
103
+ this.pageUrl.set('/' +
104
+ this.route.pathFromRoot
105
+ .flatMap((route) => route.snapshot.url)
106
+ .map((segment) => segment.path)
107
+ .join('/'));
108
+ }
109
+ this.fullscreenRoute.set(fullscreen);
110
+ this.fullscreenRoutes.set(this, fullscreen);
20
111
  }
112
+ /**
113
+ * Creates the table of contents from the headings of the rendered page.
114
+ */
21
115
  createToc() {
22
- if (this.pageWrapper.pageToc && this.skeleton.toc) {
23
- createComponent(this.pageWrapper.pageToc, this.skeleton.toc, {
24
- tableOfContent: generateToc(this.pageContainer.nativeElement) ?? [],
25
- });
116
+ const container = this.pageContainer();
117
+ const pageToc = this.pageWrapper.pageToc();
118
+ pageToc.clear();
119
+ if (container && this.skeleton.toc) {
120
+ const inputs = {
121
+ tableOfContent: generateToc(container.nativeElement) ?? [],
122
+ };
123
+ // Only components that declare the input get it: a custom table of contents may not.
124
+ const declared = reflectComponentType(this.skeleton.toc)?.inputs ?? [];
125
+ if (declared.some(({ templateName }) => templateName === 'editSourceFileUrl')) {
126
+ inputs['editSourceFileUrl'] = this.rootPage.editSourceFileUrl;
127
+ }
128
+ // API pages carry their symbol details for the rail, hidden in the content.
129
+ const details = container.nativeElement.querySelector('[data-ng-doc-rail-details]');
130
+ if (details && declared.some(({ templateName }) => templateName === 'details')) {
131
+ details.removeAttribute('hidden');
132
+ inputs['details'] = details;
133
+ }
134
+ createComponent(pageToc, this.skeleton.toc, inputs);
26
135
  this.changeDetectorRef.detectChanges();
27
136
  }
137
+ if (this.rootPage.pageContentSource)
138
+ this.contentAnchorController.contentProcessed();
139
+ }
140
+ /**
141
+ * Shows the page's own content in place of the server-rendered copy when a pass of the loaded
142
+ * content is about to render, in the same task, so its components render and measure visible.
143
+ * The pass of the empty content before the source has loaded keeps the copy.
144
+ * @param version - The content version of the pass.
145
+ * @internal
146
+ */
147
+ revealLoaded(version) {
148
+ if (version === this.contentController.loadedVersion())
149
+ this.releaseSnapshot();
150
+ }
151
+ /**
152
+ * Copies the link to the page, without its query and fragment.
153
+ */
154
+ copyLink() {
155
+ this.clipboard.copy(_ngDocPageUrl(this.locationStrategy, this.location));
156
+ this.linkCopied.set(true);
157
+ clearTimeout(this.linkCopiedTimer);
158
+ // The label timer must not hold the application unstable, so it runs outside the zone.
159
+ this.linkCopiedTimer = this.ngZone.runOutsideAngular(() => setTimeout(() => this.linkCopied.set(false), 1400));
160
+ }
161
+ connectContent(source) {
162
+ // Both calls do nothing once the source is connected.
163
+ this.contentAnchorController.activate();
164
+ this.contentController.connect(source);
165
+ }
166
+ releaseSnapshot() {
167
+ const release = this.snapshot;
168
+ this.snapshot = undefined;
169
+ release?.();
28
170
  }
29
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
30
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgDocPageComponent, isStandalone: true, selector: "ng-doc-page", host: { attributes: { "ngSkipHydration": "true" } }, providers: [
171
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
172
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageComponent, isStandalone: true, selector: "ng-doc-page", host: { attributes: { "ngSkipHydration": "true" }, properties: { "attr.data-ng-doc-async-content": "rootPage.pageContentSource && !fullscreenRoute() ? \"\" : null" } }, providers: [
173
+ NgDocContentAnchorController,
174
+ NgDocContentController,
31
175
  provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),
32
176
  provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),
33
177
  provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),
34
- provideTypeControl('boolean', NgDocBooleanControlComponent, { hideLabel: true, order: 40 }),
35
- ], viewQueries: [{ propertyName: "pageContainer", first: true, predicate: ["pageContainer"], descendants: true, read: ElementRef, static: true }, { propertyName: "childOutlet", first: true, predicate: ["childOutlet"], descendants: true }], ngImport: i0, template: "<div class=\"ng-doc-page-controls\">\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"Suggest Edits\">\n <ng-doc-icon icon=\"edit-2\"></ng-doc-icon>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"View Source\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </a>\n }\n</div>\n\n<div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <ng-doc-dialog-outlet [config]=\"{ width: '100vw', height: '100vh' }\">\n <div class=\"ng-doc-fullscreen-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </ng-doc-dialog-outlet>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;display:flex;grid-gap:var(--ng-doc-base-gutter);top:0;right:0}.ng-doc-fullscreen-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}\n"], dependencies: [{ 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"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageProcessorComponent, selector: "[ngDocPageProcessor]", inputs: ["ngDocPageProcessor"], outputs: ["afterRender"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: DialogOutletComponent, selector: "ng-doc-dialog-outlet", inputs: ["config"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
178
+ provideTypeControl('boolean', NgDocBooleanControlComponent, { order: 40 }),
179
+ ], viewQueries: [{ propertyName: "pageContainer", first: true, predicate: ["pageContainer"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "@if (!fullscreenRoute()) {\n <div class=\"ng-doc-page-controls\">\n <button\n type=\"button\"\n ng-doc-button-icon\n [rounded]=\"false\"\n [attr.aria-label]=\"linkCopied() ? 'Link copied' : 'Copy link to this page'\"\n [ngDocTooltip]=\"linkCopied() ? 'Copied' : 'Copy link'\"\n [attr.data-ng-doc-copied]=\"linkCopied()\"\n (click)=\"copyLink()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7\" />\n <path d=\"M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7\" />\n </svg>\n </button>\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"Edit this page\"\n ngDocTooltip=\"Edit this page\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"View the page source\"\n ngDocTooltip=\"View source\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"m8 7-5 5 5 5m8-10 5 5-5 5\" />\n </svg>\n </a>\n }\n </div>\n\n @if (rootPage.pageContentSource) {\n @if (contentController.error(); as error) {\n <div class=\"ng-doc-page-wrapper\" role=\"alert\">{{ error.message }}</div>\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"contentController.html() | ngDocSanitizeHtml\"\n [contentVersion]=\"contentController.version()\"\n (beforeRender)=\"revealLoaded($event)\"\n (contentProcessed)=\"contentController.processed($event)\"\n (processingError)=\"contentController.processingFailed($event)\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n}\n\n<!-- A fullscreen route replaces the page; the outlet stays, so it can open and close in place. -->\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <div class=\"ng-doc-fullscreen-route\" [hidden]=\"!fullscreenRoute()\">\n @if (fullscreenRoute()) {\n <a\n class=\"ng-doc-fullscreen-route-back\"\n [routerLink]=\"pageUrl()\"\n [attr.aria-label]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\"\n [ngDocTooltip]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M19 12H5m7 7-7-7 7-7\" />\n </svg>\n <span class=\"ng-doc-fullscreen-route-back-label\">{{ rootPage.page?.title ?? 'Back' }}</span>\n </a>\n }\n <router-outlet\n (activate)=\"showFullscreenRoute(true)\"\n (deactivate)=\"showFullscreenRoute(false)\" />\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;top:0;right:0;display:flex;gap:2px;--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 .ng-doc-page-controls [data-ng-doc-copied=true]{--ng-doc-button-color: var(--ng-doc-success-strong)}.ng-doc-fullscreen-route{background-image:radial-gradient(color-mix(in srgb,var(--ng-doc-base-5) 55%,transparent) 1px,transparent 1px);background-size:16px 16px;display:grid;place-items:center;min-height:100vh;min-height:100dvh;padding:var(--ng-doc-space-16) var(--ng-doc-space-4);background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-fullscreen-route[hidden]{display:none}.ng-doc-fullscreen-route>router-outlet{display:none}.ng-doc-fullscreen-route-back{position:fixed;top:var(--ng-doc-space-4);left:var(--ng-doc-space-4);z-index:1;display:inline-flex;align-items:center;gap:var(--ng-doc-space-2);max-width:calc(100% - var(--ng-doc-space-8));height:32px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-2);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);box-shadow:0 0 0 1px var(--ng-doc-border-color),var(--ng-doc-shadow-xs);color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;font-weight:500;line-height:18px;text-decoration:none}.ng-doc-fullscreen-route-back:hover{color:var(--ng-doc-heading-color)}.ng-doc-fullscreen-route-back:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-fullscreen-route-back svg{flex:none;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.ng-doc-fullscreen-route-back-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host[data-ng-doc-hydration-snapshot]>:not(.ng-doc-hydration-snapshot){display:none!important}\n"], dependencies: [{ 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"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocPageProcessorComponent, selector: "[ngDocPageProcessor]", inputs: ["ngDocPageProcessor", "contentVersion"], outputs: ["beforeRender", "afterRender", "contentProcessed", "processingError"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
36
180
  }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocPageComponent, decorators: [{
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageComponent, decorators: [{
38
182
  type: Component,
39
183
  args: [{ selector: 'ng-doc-page', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
40
184
  NgDocButtonIconComponent,
41
185
  NgDocTooltipDirective,
42
- NgDocIconComponent,
43
186
  NgDocPageProcessorComponent,
187
+ RouterLink,
44
188
  RouterOutlet,
45
- DialogOutletComponent,
46
189
  NgDocSanitizeHtmlPipe,
47
190
  ], providers: [
191
+ NgDocContentAnchorController,
192
+ NgDocContentController,
48
193
  provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),
49
194
  provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),
50
195
  provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),
51
- provideTypeControl('boolean', NgDocBooleanControlComponent, { hideLabel: true, order: 40 }),
52
- ], host: { ngSkipHydration: 'true' }, template: "<div class=\"ng-doc-page-controls\">\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"Suggest Edits\">\n <ng-doc-icon icon=\"edit-2\"></ng-doc-icon>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"View Source\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </a>\n }\n</div>\n\n<div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <ng-doc-dialog-outlet [config]=\"{ width: '100vw', height: '100vh' }\">\n <div class=\"ng-doc-fullscreen-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </ng-doc-dialog-outlet>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;display:flex;grid-gap:var(--ng-doc-base-gutter);top:0;right:0}.ng-doc-fullscreen-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}\n"] }]
53
- }], propDecorators: { pageContainer: [{
54
- type: ViewChild,
55
- args: ['pageContainer', { read: ElementRef, static: true }]
56
- }], childOutlet: [{
57
- type: ViewChild,
58
- args: ['childOutlet']
59
- }] } });
196
+ provideTypeControl('boolean', NgDocBooleanControlComponent, { order: 40 }),
197
+ ], host: {
198
+ ngSkipHydration: 'true',
199
+ // Tells the browser that the server-rendered content must be kept until the loaded content
200
+ // renders (ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE).
201
+ '[attr.data-ng-doc-async-content]': 'rootPage.pageContentSource && !fullscreenRoute() ? "" : null',
202
+ }, template: "@if (!fullscreenRoute()) {\n <div class=\"ng-doc-page-controls\">\n <button\n type=\"button\"\n ng-doc-button-icon\n [rounded]=\"false\"\n [attr.aria-label]=\"linkCopied() ? 'Link copied' : 'Copy link to this page'\"\n [ngDocTooltip]=\"linkCopied() ? 'Copied' : 'Copy link'\"\n [attr.data-ng-doc-copied]=\"linkCopied()\"\n (click)=\"copyLink()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7\" />\n <path d=\"M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7\" />\n </svg>\n </button>\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"Edit this page\"\n ngDocTooltip=\"Edit this page\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"View the page source\"\n ngDocTooltip=\"View source\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"m8 7-5 5 5 5m8-10 5 5-5 5\" />\n </svg>\n </a>\n }\n </div>\n\n @if (rootPage.pageContentSource) {\n @if (contentController.error(); as error) {\n <div class=\"ng-doc-page-wrapper\" role=\"alert\">{{ error.message }}</div>\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"contentController.html() | ngDocSanitizeHtml\"\n [contentVersion]=\"contentController.version()\"\n (beforeRender)=\"revealLoaded($event)\"\n (contentProcessed)=\"contentController.processed($event)\"\n (processingError)=\"contentController.processingFailed($event)\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n}\n\n<!-- A fullscreen route replaces the page; the outlet stays, so it can open and close in place. -->\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <div class=\"ng-doc-fullscreen-route\" [hidden]=\"!fullscreenRoute()\">\n @if (fullscreenRoute()) {\n <a\n class=\"ng-doc-fullscreen-route-back\"\n [routerLink]=\"pageUrl()\"\n [attr.aria-label]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\"\n [ngDocTooltip]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M19 12H5m7 7-7-7 7-7\" />\n </svg>\n <span class=\"ng-doc-fullscreen-route-back-label\">{{ rootPage.page?.title ?? 'Back' }}</span>\n </a>\n }\n <router-outlet\n (activate)=\"showFullscreenRoute(true)\"\n (deactivate)=\"showFullscreenRoute(false)\" />\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;top:0;right:0;display:flex;gap:2px;--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 .ng-doc-page-controls [data-ng-doc-copied=true]{--ng-doc-button-color: var(--ng-doc-success-strong)}.ng-doc-fullscreen-route{background-image:radial-gradient(color-mix(in srgb,var(--ng-doc-base-5) 55%,transparent) 1px,transparent 1px);background-size:16px 16px;display:grid;place-items:center;min-height:100vh;min-height:100dvh;padding:var(--ng-doc-space-16) var(--ng-doc-space-4);background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-fullscreen-route[hidden]{display:none}.ng-doc-fullscreen-route>router-outlet{display:none}.ng-doc-fullscreen-route-back{position:fixed;top:var(--ng-doc-space-4);left:var(--ng-doc-space-4);z-index:1;display:inline-flex;align-items:center;gap:var(--ng-doc-space-2);max-width:calc(100% - var(--ng-doc-space-8));height:32px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-2);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);box-shadow:0 0 0 1px var(--ng-doc-border-color),var(--ng-doc-shadow-xs);color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;font-weight:500;line-height:18px;text-decoration:none}.ng-doc-fullscreen-route-back:hover{color:var(--ng-doc-heading-color)}.ng-doc-fullscreen-route-back:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-fullscreen-route-back svg{flex:none;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.ng-doc-fullscreen-route-back-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host[data-ng-doc-hydration-snapshot]>:not(.ng-doc-hydration-snapshot){display:none!important}\n"] }]
203
+ }], ctorParameters: () => [], propDecorators: { pageContainer: [{ type: i0.ViewChild, args: ['pageContainer', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
60
204
 
61
205
  /**
62
206
  * Generated bundle index. Do not edit.