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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (203) 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-pane.mjs +39 -36
  25. package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
  26. package/fesm2022/ng-doc-app-components-demo.mjs +129 -44
  27. package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
  28. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +12 -9
  29. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
  30. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +79 -0
  31. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -0
  32. package/fesm2022/ng-doc-app-components-heading-anchor.mjs +54 -21
  33. package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
  34. package/fesm2022/ng-doc-app-components-image-viewer.mjs +183 -89
  35. package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
  36. package/fesm2022/ng-doc-app-components-kind-icon.mjs +42 -25
  37. package/fesm2022/ng-doc-app-components-kind-icon.mjs.map +1 -1
  38. package/fesm2022/ng-doc-app-components-link.mjs +12 -9
  39. package/fesm2022/ng-doc-app-components-link.mjs.map +1 -1
  40. package/fesm2022/ng-doc-app-components-members.mjs +30 -0
  41. package/fesm2022/ng-doc-app-components-members.mjs.map +1 -0
  42. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs +61 -20
  43. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs.map +1 -1
  44. package/fesm2022/ng-doc-app-components-navbar.mjs +39 -49
  45. package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
  46. package/fesm2022/ng-doc-app-components-page-header.mjs +73 -10
  47. package/fesm2022/ng-doc-app-components-page-header.mjs.map +1 -1
  48. package/fesm2022/ng-doc-app-components-page-link.mjs +123 -31
  49. package/fesm2022/ng-doc-app-components-page-link.mjs.map +1 -1
  50. package/fesm2022/ng-doc-app-components-page-navigation.mjs +17 -19
  51. package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
  52. package/fesm2022/ng-doc-app-components-page-wrapper.mjs +56 -35
  53. package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
  54. package/fesm2022/ng-doc-app-components-page.mjs +168 -24
  55. package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
  56. package/fesm2022/ng-doc-app-components-playground.mjs +392 -263
  57. package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
  58. package/fesm2022/ng-doc-app-components-root.mjs +48 -31
  59. package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
  60. package/fesm2022/ng-doc-app-components-search-result.mjs +22 -21
  61. package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
  62. package/fesm2022/ng-doc-app-components-search.mjs +64 -33
  63. package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
  64. package/fesm2022/ng-doc-app-components-sidebar.mjs +86 -61
  65. package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
  66. package/fesm2022/ng-doc-app-components-tabs.mjs +18 -12
  67. package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
  68. package/fesm2022/ng-doc-app-components-theme-toggle.mjs +33 -21
  69. package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
  70. package/fesm2022/ng-doc-app-components-toc.mjs +267 -90
  71. package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
  72. package/fesm2022/ng-doc-app-components.mjs +3 -1
  73. package/fesm2022/ng-doc-app-components.mjs.map +1 -1
  74. package/fesm2022/ng-doc-app-defaults-default-processors.mjs +2 -1
  75. package/fesm2022/ng-doc-app-defaults-default-processors.mjs.map +1 -1
  76. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs +11 -5
  77. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs.map +1 -1
  78. package/fesm2022/ng-doc-app-directives-members-filter.mjs +276 -0
  79. package/fesm2022/ng-doc-app-directives-members-filter.mjs.map +1 -0
  80. package/fesm2022/ng-doc-app-directives-route-active.mjs +34 -30
  81. package/fesm2022/ng-doc-app-directives-route-active.mjs.map +1 -1
  82. package/fesm2022/ng-doc-app-directives.mjs +1 -0
  83. package/fesm2022/ng-doc-app-directives.mjs.map +1 -1
  84. package/fesm2022/ng-doc-app-helpers.mjs +285 -1
  85. package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
  86. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs +6 -4
  87. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs.map +1 -1
  88. package/fesm2022/ng-doc-app-pipes-extract-value.mjs +6 -4
  89. package/fesm2022/ng-doc-app-pipes-extract-value.mjs.map +1 -1
  90. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs +7 -4
  91. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs.map +1 -1
  92. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs +8 -5
  93. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs.map +1 -1
  94. package/fesm2022/ng-doc-app-processors-page-processor.mjs +86 -23
  95. package/fesm2022/ng-doc-app-processors-page-processor.mjs.map +1 -1
  96. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs +26 -25
  97. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs.map +1 -1
  98. package/fesm2022/ng-doc-app-processors-processors.mjs +12 -1
  99. package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
  100. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +31 -2
  101. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
  102. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +122 -0
  103. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -0
  104. package/fesm2022/ng-doc-app-services-content-state.mjs +57 -0
  105. package/fesm2022/ng-doc-app-services-content-state.mjs.map +1 -0
  106. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs +74 -0
  107. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs.map +1 -0
  108. package/fesm2022/ng-doc-app-services-highlighter.mjs +83 -14
  109. package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
  110. package/fesm2022/ng-doc-app-services-route-preloader.mjs +360 -0
  111. package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -0
  112. package/fesm2022/ng-doc-app-services-shortcuts.mjs +214 -0
  113. package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -0
  114. package/fesm2022/ng-doc-app-services-sidebar.mjs +59 -25
  115. package/fesm2022/ng-doc-app-services-sidebar.mjs.map +1 -1
  116. package/fesm2022/ng-doc-app-services-store.mjs +8 -8
  117. package/fesm2022/ng-doc-app-services-store.mjs.map +1 -1
  118. package/fesm2022/ng-doc-app-services-theme.mjs +32 -12
  119. package/fesm2022/ng-doc-app-services-theme.mjs.map +1 -1
  120. package/fesm2022/ng-doc-app-services.mjs +143 -0
  121. package/fesm2022/ng-doc-app-services.mjs.map +1 -1
  122. package/fesm2022/ng-doc-app-tokens.mjs +7 -28
  123. package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
  124. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs +18 -9
  125. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs.map +1 -1
  126. package/fesm2022/ng-doc-app-type-controls-number-control.mjs +12 -9
  127. package/fesm2022/ng-doc-app-type-controls-number-control.mjs.map +1 -1
  128. package/fesm2022/ng-doc-app-type-controls-string-control.mjs +12 -9
  129. package/fesm2022/ng-doc-app-type-controls-string-control.mjs.map +1 -1
  130. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +22 -16
  131. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
  132. package/package.json +69 -28
  133. package/styles/global.css +1125 -201
  134. package/styles/main.css +1125 -201
  135. package/styles/themes/dark.css +78 -56
  136. package/types/ng-doc-app-classes-content-anchor-controller.d.ts +54 -0
  137. package/types/ng-doc-app-classes-content-controller.d.ts +94 -0
  138. package/types/ng-doc-app-classes-default-search-engine.d.ts +9 -1
  139. package/types/ng-doc-app-classes-root-page.d.ts +6 -1
  140. package/types/ng-doc-app-classes-search-engine.d.ts +5 -0
  141. package/types/ng-doc-app-classes.d.ts +2 -0
  142. package/types/ng-doc-app-components-api-list.d.ts +69 -20
  143. package/types/ng-doc-app-components-breadcrumb.d.ts +8 -3
  144. package/types/ng-doc-app-components-code.d.ts +46 -12
  145. package/types/ng-doc-app-components-command-palette.d.ts +147 -0
  146. package/types/ng-doc-app-components-copy-button.d.ts +18 -6
  147. package/types/ng-doc-app-components-demo-displayer.d.ts +23 -10
  148. package/types/ng-doc-app-components-demo-pane.d.ts +19 -15
  149. package/types/ng-doc-app-components-demo.d.ts +62 -15
  150. package/types/ng-doc-app-components-fullscreen-button.d.ts +4 -2
  151. package/types/ng-doc-app-components-fullscreen-toggle.d.ts +24 -0
  152. package/types/ng-doc-app-components-heading-anchor.d.ts +26 -7
  153. package/types/ng-doc-app-components-image-viewer.d.ts +71 -7
  154. package/types/ng-doc-app-components-kind-icon.d.ts +28 -7
  155. package/types/ng-doc-app-components-link.d.ts +6 -2
  156. package/types/ng-doc-app-components-members.d.ts +13 -0
  157. package/types/ng-doc-app-components-mermaid-viewer.d.ts +21 -6
  158. package/types/ng-doc-app-components-navbar.d.ts +25 -15
  159. package/types/ng-doc-app-components-page-header.d.ts +28 -4
  160. package/types/ng-doc-app-components-page-link.d.ts +34 -15
  161. package/types/ng-doc-app-components-page-navigation.d.ts +10 -5
  162. package/types/ng-doc-app-components-page-wrapper.d.ts +35 -11
  163. package/types/ng-doc-app-components-page.d.ts +57 -6
  164. package/types/ng-doc-app-components-playground.d.ts +146 -78
  165. package/types/ng-doc-app-components-root.d.ts +28 -7
  166. package/types/ng-doc-app-components-search-result.d.ts +14 -6
  167. package/types/ng-doc-app-components-search.d.ts +19 -7
  168. package/types/ng-doc-app-components-tabs.d.ts +13 -4
  169. package/types/ng-doc-app-components-theme-toggle.d.ts +18 -5
  170. package/types/ng-doc-app-components-toc.d.ts +76 -29
  171. package/types/ng-doc-app-components.d.ts +3 -1
  172. package/types/ng-doc-app-directives-code-highlighter.d.ts +8 -4
  173. package/types/ng-doc-app-directives-members-filter.d.ts +61 -0
  174. package/types/ng-doc-app-directives-route-active.d.ts +21 -7
  175. package/types/ng-doc-app-directives.d.ts +1 -0
  176. package/types/ng-doc-app-helpers.d.ts +124 -3
  177. package/types/ng-doc-app-interfaces.d.ts +48 -28
  178. package/types/ng-doc-app-pipes-decode-uri-component.d.ts +3 -0
  179. package/types/ng-doc-app-pipes-extract-value.d.ts +3 -0
  180. package/types/ng-doc-app-pipes-filter-by-text.d.ts +4 -0
  181. package/types/ng-doc-app-pipes-sanitize-html.d.ts +4 -2
  182. package/types/ng-doc-app-processors-page-processor.d.ts +39 -10
  183. package/types/ng-doc-app-processors-processors-tooltip.d.ts +11 -10
  184. package/types/ng-doc-app-processors-processors.d.ts +5 -1
  185. package/types/ng-doc-app-providers-ng-doc-app.d.ts +17 -0
  186. package/types/ng-doc-app-services-content-scroll-intent.d.ts +52 -0
  187. package/types/ng-doc-app-services-content-state.d.ts +40 -0
  188. package/types/ng-doc-app-services-fullscreen-route.d.ts +35 -0
  189. package/types/ng-doc-app-services-highlighter.d.ts +40 -5
  190. package/types/ng-doc-app-services-route-preloader.d.ts +109 -0
  191. package/types/ng-doc-app-services-shortcuts.d.ts +96 -0
  192. package/types/ng-doc-app-services-sidebar.d.ts +24 -4
  193. package/types/ng-doc-app-services-store.d.ts +24 -1
  194. package/types/ng-doc-app-services-theme.d.ts +19 -3
  195. package/types/ng-doc-app-services.d.ts +77 -0
  196. package/types/ng-doc-app-tokens.d.ts +10 -30
  197. package/types/ng-doc-app-type-controls-boolean-control.d.ts +11 -6
  198. package/types/ng-doc-app-type-controls-number-control.d.ts +5 -3
  199. package/types/ng-doc-app-type-controls-string-control.d.ts +5 -3
  200. package/types/ng-doc-app-type-controls-type-alias-control.d.ts +13 -6
  201. package/fesm2022/ng-doc-app-components-search-dialog.mjs +0 -78
  202. package/fesm2022/ng-doc-app-components-search-dialog.mjs.map +0 -1
  203. package/types/ng-doc-app-components-search-dialog.d.ts +0 -28
@@ -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.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-page.mjs","sources":["../../../../libs/app/components/page/page.component.ts","../../../../libs/app/components/page/page.component.html","../../../../libs/app/components/page/ng-doc-app-components-page.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n inject,\n TemplateRef,\n ViewChild,\n} from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { NgDocRootPage } from '@ng-doc/app/classes/root-page';\nimport { NgDocPageWrapperComponent } from '@ng-doc/app/components/page-wrapper';\nimport { createComponent, generateToc } from '@ng-doc/app/helpers';\nimport { NgDocPageSkeleton } from '@ng-doc/app/interfaces';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors';\nimport { provideTypeControl } from '@ng-doc/app/providers/type-control';\nimport { NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport {\n NgDocBooleanControlComponent,\n NgDocNumberControlComponent,\n NgDocStringControlComponent,\n NgDocTypeAliasControlComponent,\n} from '@ng-doc/app/type-controls';\nimport {\n DialogOutletComponent,\n NgDocButtonIconComponent,\n NgDocIconComponent,\n NgDocTooltipDirective,\n} from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-page',\n templateUrl: './page.component.html',\n styleUrls: ['./page.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocButtonIconComponent,\n NgDocTooltipDirective,\n NgDocIconComponent,\n NgDocPageProcessorComponent,\n RouterOutlet,\n DialogOutletComponent,\n NgDocSanitizeHtmlPipe,\n ],\n providers: [\n provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),\n provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),\n provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),\n provideTypeControl('boolean', NgDocBooleanControlComponent, { hideLabel: true, order: 40 }),\n ],\n host: { ngSkipHydration: 'true' },\n})\nexport class NgDocPageComponent {\n @ViewChild('pageContainer', { read: ElementRef, static: true })\n pageContainer!: ElementRef<HTMLElement>;\n\n @ViewChild('childOutlet')\n childOutlet?: TemplateRef<never>;\n\n protected rootPage: NgDocRootPage = inject(NgDocRootPage);\n protected skeleton: NgDocPageSkeleton = inject(NG_DOC_PAGE_SKELETON);\n protected changeDetectorRef = inject(ChangeDetectorRef);\n\n protected pageWrapper: NgDocPageWrapperComponent = inject(NgDocPageWrapperComponent);\n\n createToc(): void {\n if (this.pageWrapper.pageToc && this.skeleton.toc) {\n createComponent(this.pageWrapper.pageToc, this.skeleton.toc, {\n tableOfContent: generateToc(this.pageContainer.nativeElement) ?? [],\n });\n\n this.changeDetectorRef.detectChanges();\n }\n }\n}\n","<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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-page.mjs","sources":["../../../../libs/app/components/page/page.component.ts","../../../../libs/app/components/page/page.component.html","../../../../libs/app/components/page/ng-doc-app-components-page.ts"],"sourcesContent":["import { Clipboard } from '@angular/cdk/clipboard';\nimport { isPlatformBrowser, LocationStrategy } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n NgZone,\n PLATFORM_ID,\n reflectComponentType,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';\nimport { NgDocContentAnchorController } from '@ng-doc/app/classes/content-anchor-controller';\nimport { NgDocContentController } from '@ng-doc/app/classes/content-controller';\nimport { NgDocRootPage } from '@ng-doc/app/classes/root-page';\nimport { NgDocPageWrapperComponent } from '@ng-doc/app/components/page-wrapper';\nimport {\n createComponent,\n generateToc,\n ɵngDocPageUrl,\n ɵrestoreNgDocHydrationSnapshot,\n} from '@ng-doc/app/helpers';\nimport { NgDocPageSkeleton } from '@ng-doc/app/interfaces';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors';\nimport { provideTypeControl } from '@ng-doc/app/providers/type-control';\nimport { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';\nimport { NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport {\n NgDocBooleanControlComponent,\n NgDocNumberControlComponent,\n NgDocStringControlComponent,\n NgDocTypeAliasControlComponent,\n} from '@ng-doc/app/type-controls';\nimport type { NgDocContentSource } from '@ng-doc/core/interfaces';\nimport { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';\nimport { WA_LOCATION } from '@ng-web-apis/common';\n\n/**\n * A generated page: its rendered content, the page actions (copy link, edit and view the source),\n * the table of contents it fills in, and the outlet of its fullscreen routes.\n *\n * A fullscreen route (a child route of the page, unless the page sets `disableFullscreenRoutes`)\n * replaces the page: it is shown on its own on the canvas of demos, with a link back to the page,\n * and `NgDocFullscreenRouteService` tells the root layout and the page wrapper to hide their\n * chrome.\n */\n@Component({\n selector: 'ng-doc-page',\n templateUrl: './page.component.html',\n styleUrls: ['./page.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocButtonIconComponent,\n NgDocTooltipDirective,\n NgDocPageProcessorComponent,\n RouterLink,\n RouterOutlet,\n NgDocSanitizeHtmlPipe,\n ],\n providers: [\n NgDocContentAnchorController,\n NgDocContentController,\n provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),\n provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),\n provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),\n provideTypeControl('boolean', NgDocBooleanControlComponent, { order: 40 }),\n ],\n host: {\n ngSkipHydration: 'true',\n // Tells the browser that the server-rendered content must be kept until the loaded content\n // renders (ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE).\n '[attr.data-ng-doc-async-content]':\n 'rootPage.pageContentSource && !fullscreenRoute() ? \"\" : null',\n },\n})\nexport class NgDocPageComponent {\n /** The element that holds the rendered page content. */\n readonly pageContainer = viewChild('pageContainer', { read: ElementRef<HTMLElement> });\n\n protected rootPage: NgDocRootPage = inject(NgDocRootPage);\n protected skeleton: NgDocPageSkeleton = inject(NG_DOC_PAGE_SKELETON);\n protected changeDetectorRef = inject(ChangeDetectorRef);\n\n protected pageWrapper: NgDocPageWrapperComponent = inject(NgDocPageWrapperComponent);\n protected readonly contentController = inject(NgDocContentController);\n /** Whether the link to the page was just copied. */\n protected readonly linkCopied = signal(false);\n /** Whether one of the page's fullscreen routes is shown instead of the page. */\n protected readonly fullscreenRoute = signal(false);\n /** URL of the page, for the link back from a fullscreen route. */\n protected readonly pageUrl = signal('/');\n private readonly route = inject(ActivatedRoute);\n private readonly fullscreenRoutes = inject(NgDocFullscreenRouteService);\n private readonly contentAnchorController = inject(NgDocContentAnchorController);\n private readonly clipboard = inject(Clipboard);\n private readonly ngZone = inject(NgZone);\n private readonly location = inject(WA_LOCATION);\n private readonly locationStrategy = inject(LocationStrategy);\n private linkCopiedTimer?: ReturnType<typeof setTimeout>;\n /** Removes the server-rendered copy shown while asynchronous content loads. */\n private snapshot?: () => void;\n\n constructor() {\n // The router state is complete when the page is created, so a fullscreen route opened\n // directly (a new tab) is known before the first render and the page content never renders.\n this.showFullscreenRoute(!!this.route.firstChild);\n\n const source: NgDocContentSource | undefined = this.rootPage.pageContentSource;\n\n if (source && !this.fullscreenRoute()) {\n // Angular empties this host (it skips hydration) and the content loads asynchronously, so\n // the server-rendered page stays visible until the loaded content renders.\n if (isPlatformBrowser(inject(PLATFORM_ID))) {\n this.snapshot = ɵrestoreNgDocHydrationSnapshot(inject(ElementRef).nativeElement);\n }\n this.connectContent(source);\n }\n // A page opened on a fullscreen route loads its content only when the reader goes back to\n // it, because pending content holds the application unstable until it renders. An effect,\n // so a page that is leaving (its route closes as it is destroyed) loads nothing.\n effect(() => {\n if (source && !this.fullscreenRoute()) untracked(() => this.connectContent(source));\n });\n // A load that needs no new pass (its content is already rendered, for example an empty body)\n // or that failed settles without `revealLoaded`.\n effect(() => {\n if (this.contentController.settled()) untracked(() => this.releaseSnapshot());\n });\n effect(() => {\n if (this.contentController.error()) {\n untracked(() => {\n this.releaseSnapshot();\n this.pageWrapper.pageToc().clear();\n this.contentAnchorController.contentFailed();\n });\n }\n });\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.linkCopiedTimer);\n this.releaseSnapshot();\n this.fullscreenRoutes.set(this, false);\n });\n }\n\n /**\n * Shows one of the page's fullscreen routes instead of the page, or the page again. The outlet\n * of the fullscreen routes calls it when a route opens or closes.\n * @param shown - Whether a fullscreen route is shown.\n */\n protected showFullscreenRoute(shown: boolean): void {\n // Pages that disable fullscreen routes render their child routes themselves.\n const fullscreen: boolean = shown && !this.rootPage.page?.disableFullscreenRoutes;\n\n if (fullscreen) {\n this.pageUrl.set(\n '/' +\n this.route.pathFromRoot\n .flatMap((route: ActivatedRoute) => route.snapshot.url)\n .map((segment) => segment.path)\n .join('/'),\n );\n }\n this.fullscreenRoute.set(fullscreen);\n this.fullscreenRoutes.set(this, fullscreen);\n }\n\n /**\n * Creates the table of contents from the headings of the rendered page.\n */\n createToc(): void {\n const container = this.pageContainer();\n const pageToc = this.pageWrapper.pageToc();\n\n pageToc.clear();\n if (container && this.skeleton.toc) {\n const inputs: Record<string, unknown> = {\n tableOfContent: generateToc(container.nativeElement) ?? [],\n };\n // Only components that declare the input get it: a custom table of contents may not.\n const declared = reflectComponentType(this.skeleton.toc)?.inputs ?? [];\n\n if (declared.some(({ templateName }) => templateName === 'editSourceFileUrl')) {\n inputs['editSourceFileUrl'] = this.rootPage.editSourceFileUrl;\n }\n\n // API pages carry their symbol details for the rail, hidden in the content.\n const details = container.nativeElement.querySelector('[data-ng-doc-rail-details]');\n\n if (details && declared.some(({ templateName }) => templateName === 'details')) {\n details.removeAttribute('hidden');\n inputs['details'] = details;\n }\n\n createComponent(pageToc, this.skeleton.toc, inputs);\n\n this.changeDetectorRef.detectChanges();\n }\n if (this.rootPage.pageContentSource) this.contentAnchorController.contentProcessed();\n }\n\n /**\n * Shows the page's own content in place of the server-rendered copy when a pass of the loaded\n * content is about to render, in the same task, so its components render and measure visible.\n * The pass of the empty content before the source has loaded keeps the copy.\n * @param version - The content version of the pass.\n * @internal\n */\n protected revealLoaded(version: number): void {\n if (version === this.contentController.loadedVersion()) this.releaseSnapshot();\n }\n\n /**\n * Copies the link to the page, without its query and fragment.\n */\n copyLink(): void {\n this.clipboard.copy(ɵngDocPageUrl(this.locationStrategy, this.location));\n this.linkCopied.set(true);\n clearTimeout(this.linkCopiedTimer);\n // The label timer must not hold the application unstable, so it runs outside the zone.\n this.linkCopiedTimer = this.ngZone.runOutsideAngular(() =>\n setTimeout(() => this.linkCopied.set(false), 1400),\n );\n }\n\n private connectContent(source: NgDocContentSource): void {\n // Both calls do nothing once the source is connected.\n this.contentAnchorController.activate();\n this.contentController.connect(source);\n }\n\n private releaseSnapshot(): void {\n const release = this.snapshot;\n\n this.snapshot = undefined;\n release?.();\n }\n}\n","@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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵrestoreNgDocHydrationSnapshot","ɵngDocPageUrl"],"mappings":"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"}