@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
@@ -0,0 +1,498 @@
1
+ import { NgTemplateOutlet } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { inject, signal, computed, viewChild, linkedSignal, untracked, ElementRef, afterNextRender, afterRenderEffect, ChangeDetectionStrategy, ViewEncapsulation, Component } from '@angular/core';
4
+ import { rxResource } from '@angular/core/rxjs-interop';
5
+ import { form, FormField } from '@angular/forms/signals';
6
+ import { Router } from '@angular/router';
7
+ import { NgDocSearchEngine } from '@ng-doc/app/classes/search-engine';
8
+ import { NgDocKindIconComponent } from '@ng-doc/app/components/kind-icon';
9
+ import { NgDocApiListIndexService } from '@ng-doc/app/services';
10
+ import { NgDocShortcutsService } from '@ng-doc/app/services/shortcuts';
11
+ import { NG_DOC_DIALOG_DATA, NgDocSelectionComponent, NgDocSelectionHostDirective, NgDocSelectionOriginDirective, NgDocSpinnerComponent } from '@ng-doc/ui-kit';
12
+ import { NgDocOverlayRef } from '@ng-doc/ui-kit/classes';
13
+ import { timer, of } from 'rxjs';
14
+ import { switchMap } from 'rxjs/operators';
15
+
16
+ const SCOPES = [
17
+ { id: 'all', label: 'All' },
18
+ { id: 'guides', label: 'Guides' },
19
+ { id: 'api', label: 'API' },
20
+ { id: 'actions', label: 'Actions' },
21
+ ];
22
+ /**
23
+ * How many declarations whose name starts with the query rank above the guides, and the shortest
24
+ * query that pins them: one or two letters start too many names to single any out.
25
+ */
26
+ const PINNED_LIMIT = 3;
27
+ const PINNED_MIN_QUERY = 3;
28
+ /** How long typing pauses before the search runs, in milliseconds. */
29
+ const SEARCH_DEBOUNCE = 120;
30
+ /**
31
+ * The search palette: a search field with scopes (all, guides, API and actions), a list of
32
+ * results grouped by type (guides first, then the API), a preview of the selected result and the
33
+ * switch for single-key shortcuts. The navbar search opens it with Command+K (Control+K) or the
34
+ * slash key.
35
+ */
36
+ class NgDocCommandPaletteComponent {
37
+ constructor() {
38
+ this.scopes = SCOPES;
39
+ this.shortcuts = inject(NgDocShortcutsService);
40
+ this.data = inject(NG_DOC_DIALOG_DATA, {
41
+ optional: true,
42
+ });
43
+ this.overlayRef = inject(NgDocOverlayRef, { optional: true });
44
+ this.router = inject(Router);
45
+ this.searchEngine = inject(NgDocSearchEngine, { optional: true });
46
+ this.apiLists = inject(NgDocApiListIndexService);
47
+ this.model = signal({ query: this.data?.query ?? '' }, /* @ts-ignore */
48
+ ...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
49
+ this.searchForm = form(this.model);
50
+ this.scope = signal('all', /* @ts-ignore */
51
+ ...(ngDevMode ? [{ debugName: "scope" }] : /* istanbul ignore next */ []));
52
+ this.query = computed(() => this.model().query.trim(), /* @ts-ignore */
53
+ ...(ngDevMode ? [{ debugName: "query" }] : /* istanbul ignore next */ []));
54
+ this.input = viewChild.required('input', /* @ts-ignore */
55
+ ...(ngDevMode ? [{ debugName: "input" }] : /* istanbul ignore next */ []));
56
+ this.list = viewChild.required('list', /* @ts-ignore */
57
+ ...(ngDevMode ? [{ debugName: "list" }] : /* istanbul ignore next */ []));
58
+ this.results = rxResource({
59
+ params: () => this.query() || undefined,
60
+ stream: ({ params }) => timer(SEARCH_DEBOUNCE).pipe(switchMap(() => this.searchEngine?.search(params) ?? of([]))),
61
+ });
62
+ // The last results stay visible while the next query runs, so the list does not flicker.
63
+ this.hits = linkedSignal({ ...(ngDevMode ? { debugName: "hits" } : /* istanbul ignore next */ {}), source: () => ({
64
+ query: this.query(),
65
+ failed: this.results.status() === 'error',
66
+ hits: this.results.hasValue() ? this.results.value() : undefined,
67
+ }),
68
+ // A failed search shows the failure, not the hits of the previous query.
69
+ computation: (source, previous) => source.query && !source.failed ? source.hits ?? previous?.value ?? [] : [] });
70
+ // The generated API lists give the kind and scope of every declaration, and let the palette
71
+ // match declaration names directly. Without them the palette shows search results only.
72
+ this.symbols = this.apiLists.declarations;
73
+ this.symbolsByRoute = computed(() => new Map(this.symbols().map((symbol) => [symbol.route, symbol])), /* @ts-ignore */
74
+ ...(ngDevMode ? [{ debugName: "symbolsByRoute" }] : /* istanbul ignore next */ []));
75
+ this.actions = [
76
+ {
77
+ name: () => 'Toggle dark mode',
78
+ keywords: 'theme dark light mode',
79
+ keys: ['T'],
80
+ run: () => this.shortcuts.run('t'),
81
+ },
82
+ {
83
+ name: () => 'Copy link to this page',
84
+ keywords: 'copy link url share',
85
+ keys: ['L'],
86
+ run: () => this.shortcuts.run('l'),
87
+ },
88
+ {
89
+ name: () => this.shortcuts.enabled() ? 'Turn off single-key shortcuts' : 'Turn on single-key shortcuts',
90
+ keywords: 'keyboard shortcuts keys single',
91
+ keys: [],
92
+ keepOpen: true,
93
+ run: () => this.shortcuts.toggle(),
94
+ },
95
+ ];
96
+ this.sections = computed(() => {
97
+ const scope = this.scope();
98
+ const query = this.query();
99
+ const sections = [];
100
+ let apiRows = (scope === 'all' || scope === 'api') && query ? this.apiRows(query, scope === 'api') : [];
101
+ // Guides rank above the API reference: readers who search a topic usually want the guide
102
+ // that explains it first. A declaration whose name starts with the query is what the reader
103
+ // typed, though: it stays on top, so Enter opens it however the guide search ranks.
104
+ if (scope === 'all' && query) {
105
+ const pinned = apiRows.filter((row) => row.pinned).slice(0, PINNED_LIMIT);
106
+ apiRows = apiRows.filter((row) => !pinned.includes(row));
107
+ sections.push({ key: 'top', type: 'api', title: 'Top matches', rows: pinned });
108
+ }
109
+ if ((scope === 'all' || scope === 'guides') && query) {
110
+ sections.push({
111
+ key: 'guide',
112
+ type: 'guide',
113
+ title: 'Guides',
114
+ rows: this.guideRows(query, scope === 'guides'),
115
+ });
116
+ }
117
+ if (apiRows.length) {
118
+ sections.push({ key: 'api', type: 'api', title: 'API', rows: apiRows });
119
+ }
120
+ if (scope === 'all' || scope === 'actions') {
121
+ sections.push({
122
+ key: 'action',
123
+ type: 'action',
124
+ title: 'Actions',
125
+ rows: this.actionRows(query),
126
+ });
127
+ }
128
+ let index = 0;
129
+ return sections
130
+ .filter((section) => section.rows.length)
131
+ .map((section) => ({
132
+ ...section,
133
+ rows: section.rows.map((row) => ({ ...row, id: `ng-doc-palette-option-${index++}` })),
134
+ }));
135
+ }, /* @ts-ignore */
136
+ ...(ngDevMode ? [{ debugName: "sections" }] : /* istanbul ignore next */ []));
137
+ this.rows = computed(() => this.sections().flatMap((section) => section.rows), /* @ts-ignore */
138
+ ...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
139
+ // Whether the reader moved the selection (with the keyboard or the pointer) since the query or
140
+ // the scope last changed.
141
+ this.moved = linkedSignal({ ...(ngDevMode ? { debugName: "moved" } : /* istanbul ignore next */ {}), source: () => [this.query(), this.scope()],
142
+ computation: () => false });
143
+ // The first result is selected whenever the results change, unless the reader moved the
144
+ // selection: then it stays on the same result while the other source (the declaration names or
145
+ // the asynchronous search) adds rows around it.
146
+ this.active = linkedSignal({ ...(ngDevMode ? { debugName: "active" } : /* istanbul ignore next */ {}), source: this.rows,
147
+ computation: (rows, previous) => {
148
+ const kept = previous && untracked(this.moved) ? previous.source[previous.value] : undefined;
149
+ const index = kept ? rows.findIndex((row) => sameResult(row, kept)) : -1;
150
+ return Math.max(index, 0);
151
+ } });
152
+ this.selected = computed(() => this.rows()[this.active()], /* @ts-ignore */
153
+ ...(ngDevMode ? [{ debugName: "selected" }] : /* istanbul ignore next */ []));
154
+ this.searching = computed(() => !!this.query() && this.results.isLoading() && !this.hits().length, /* @ts-ignore */
155
+ ...(ngDevMode ? [{ debugName: "searching" }] : /* istanbul ignore next */ []));
156
+ this.failed = computed(() => this.results.status() === 'error', /* @ts-ignore */
157
+ ...(ngDevMode ? [{ debugName: "failed" }] : /* istanbul ignore next */ []));
158
+ this.emptyMessage = computed(() => {
159
+ const query = this.query();
160
+ if (query) {
161
+ return `No results for “${query}”`;
162
+ }
163
+ return this.scope() === 'api'
164
+ ? 'Type to search the API.'
165
+ : this.scope() === 'guides'
166
+ ? 'Type to search the guides.'
167
+ : 'Type to search.';
168
+ }, /* @ts-ignore */
169
+ ...(ngDevMode ? [{ debugName: "emptyMessage" }] : /* istanbul ignore next */ []));
170
+ /** What the status region announces: the scope, a running search, no results or a failure. */
171
+ this.status = computed(() => {
172
+ const scope = SCOPES.find(({ id }) => id === this.scope())?.label ?? '';
173
+ const count = this.rows().filter((row) => row.type !== 'action').length;
174
+ if (this.failed()) {
175
+ return 'Search failed.';
176
+ }
177
+ if (this.searching()) {
178
+ return 'Searching…';
179
+ }
180
+ if (!this.query()) {
181
+ return `${scope} scope.`;
182
+ }
183
+ return count
184
+ ? `${scope} scope: ${count} ${count === 1 ? 'result' : 'results'}.`
185
+ : `${scope} scope: no results for “${this.query()}”.`;
186
+ }, /* @ts-ignore */
187
+ ...(ngDevMode ? [{ debugName: "status" }] : /* istanbul ignore next */ []));
188
+ // Increments when the selection moves by keyboard, so only those moves scroll the list.
189
+ this.keyboardMove = signal(0, /* @ts-ignore */
190
+ ...(ngDevMode ? [{ debugName: "keyboardMove" }] : /* istanbul ignore next */ []));
191
+ this.host = inject(ElementRef).nativeElement;
192
+ void this.apiLists.load();
193
+ afterNextRender(() => {
194
+ const input = this.input().nativeElement;
195
+ input.focus();
196
+ input.select();
197
+ });
198
+ afterRenderEffect(() => {
199
+ if (!this.keyboardMove()) {
200
+ return;
201
+ }
202
+ const id = untracked(this.selected)?.id;
203
+ const option = id ? this.list().nativeElement.querySelector(`#${id}`) : null;
204
+ option?.scrollIntoView?.({ block: 'nearest' });
205
+ });
206
+ }
207
+ /**
208
+ * Handles the keys of the search field: the arrow keys move the selection and Enter opens the
209
+ * selected result. Keys that compose text in an input method editor are left alone.
210
+ * @param event - The keyboard event of the search field.
211
+ */
212
+ onKeydown(event) {
213
+ if (event.isComposing || event.keyCode === 229) {
214
+ return;
215
+ }
216
+ untracked(() => {
217
+ switch (event.key) {
218
+ case 'ArrowDown':
219
+ case 'ArrowUp':
220
+ event.preventDefault();
221
+ this.move(event.key === 'ArrowDown' ? 1 : -1);
222
+ break;
223
+ case 'Enter':
224
+ event.preventDefault();
225
+ this.activate(this.selected());
226
+ break;
227
+ }
228
+ });
229
+ }
230
+ /**
231
+ * Handles the keys of the scope tabs: the arrow keys, Home and End select and focus a scope.
232
+ * @param event - The keyboard event of a scope tab.
233
+ */
234
+ onScopeKeydown(event) {
235
+ const index = SCOPES.findIndex(({ id }) => id === untracked(this.scope));
236
+ const next = event.key === 'ArrowRight'
237
+ ? (index + 1) % SCOPES.length
238
+ : event.key === 'ArrowLeft'
239
+ ? (index - 1 + SCOPES.length) % SCOPES.length
240
+ : event.key === 'Home'
241
+ ? 0
242
+ : event.key === 'End'
243
+ ? SCOPES.length - 1
244
+ : -1;
245
+ if (next < 0) {
246
+ return;
247
+ }
248
+ event.preventDefault();
249
+ this.scope.set(SCOPES[next].id);
250
+ this.host.querySelectorAll('[role="tab"]')[next]?.focus();
251
+ }
252
+ /**
253
+ * Keeps Tab inside the palette: from its last tab stop focus wraps to the search field, and
254
+ * Shift+Tab from the search field goes to the last tab stop.
255
+ * @param event - A keyboard event inside the palette.
256
+ */
257
+ onTrapKeydown(event) {
258
+ if (event.key !== 'Tab') {
259
+ return;
260
+ }
261
+ const stops = Array.from(this.host.querySelectorAll('input, button:not([tabindex="-1"])'));
262
+ const first = stops[0];
263
+ const last = stops[stops.length - 1];
264
+ if (!event.shiftKey && event.target === last) {
265
+ event.preventDefault();
266
+ first?.focus();
267
+ }
268
+ else if (event.shiftKey && event.target === first) {
269
+ event.preventDefault();
270
+ last?.focus();
271
+ }
272
+ }
273
+ /**
274
+ * Selects a scope by click and returns the focus to the search field.
275
+ * @param scope - The scope to select.
276
+ */
277
+ selectScope(scope) {
278
+ this.scope.set(scope);
279
+ this.input().nativeElement.focus();
280
+ }
281
+ /**
282
+ * Selects the result under the pointer, without scrolling the list.
283
+ * @param index - The index of the result.
284
+ */
285
+ hover(index) {
286
+ if (untracked(this.active) !== index) {
287
+ this.active.set(index);
288
+ this.moved.set(true);
289
+ }
290
+ }
291
+ /**
292
+ * Opens the given result: navigates to a page or runs an action.
293
+ * @param row - The result to open.
294
+ */
295
+ activate(row) {
296
+ if (!row) {
297
+ return;
298
+ }
299
+ if (row.action) {
300
+ if (!row.action.keepOpen) {
301
+ this.close();
302
+ }
303
+ row.action.run();
304
+ return;
305
+ }
306
+ this.close();
307
+ if (row.url) {
308
+ void this.router.navigateByUrl(row.url);
309
+ }
310
+ }
311
+ move(step) {
312
+ const count = this.rows().length;
313
+ if (count) {
314
+ this.active.set((this.active() + step + count) % count);
315
+ this.moved.set(true);
316
+ this.keyboardMove.update((value) => value + 1);
317
+ }
318
+ }
319
+ close() {
320
+ this.overlayRef?.close();
321
+ }
322
+ apiRows(query, all) {
323
+ const rows = new Map();
324
+ const needle = query.toLowerCase();
325
+ const matches = this.symbols()
326
+ .filter((symbol) => symbol.name.toLowerCase().includes(needle))
327
+ .sort((a, b) => a.name.toLowerCase().indexOf(needle) - b.name.toLowerCase().indexOf(needle) ||
328
+ a.name.length - b.name.length ||
329
+ a.name.localeCompare(b.name));
330
+ for (const symbol of matches) {
331
+ // The summary record of the symbol's page, when the query found it.
332
+ const hit = this.hitsFor(symbol.route);
333
+ rows.set(symbol.route, {
334
+ id: '',
335
+ type: 'api',
336
+ pinned: needle.length >= PINNED_MIN_QUERY && symbol.name.toLowerCase().startsWith(needle),
337
+ title: symbol.name,
338
+ label: highlight(symbol.name, query),
339
+ meta: symbol.scope,
340
+ icon: 'symbol',
341
+ kind: symbol.kind,
342
+ scope: symbol.scope,
343
+ url: `/${symbol.route}`,
344
+ text: hit?.description ?? symbol.description ?? hit?.content,
345
+ signature: hit?.signature ?? symbol.signature,
346
+ });
347
+ }
348
+ for (const hit of this.hits()) {
349
+ const index = hit.index;
350
+ if (index.pageType !== 'api') {
351
+ continue;
352
+ }
353
+ const key = routeKey(index.route) + (index.fragment ? `#${index.fragment}` : '');
354
+ if (rows.has(key) || (!index.fragment && rows.has(routeKey(index.route)))) {
355
+ continue;
356
+ }
357
+ const symbol = this.symbolsByRoute().get(routeKey(index.route));
358
+ const scope = symbol?.scope ?? index.breadcrumbs[1] ?? '';
359
+ // Only one record of a page carries the declaration's summary: a hit on another record of
360
+ // the page takes it from that record (when the query found it too) or from the API list.
361
+ const summary = index.fragment ? undefined : this.hitsFor(routeKey(index.route));
362
+ rows.set(key, {
363
+ id: '',
364
+ type: 'api',
365
+ title: index.title,
366
+ label: highlight(index.title, query),
367
+ meta: index.section ? `${index.section} · ${scope}` : scope,
368
+ icon: 'symbol',
369
+ kind: index.kind ?? summary?.kind ?? symbol?.kind,
370
+ scope,
371
+ url: pageUrl(index),
372
+ text: index.fragment
373
+ ? index.description ?? index.content
374
+ : summary?.description ?? symbol?.description ?? index.content,
375
+ signature: index.fragment ? index.signature : summary?.signature ?? symbol?.signature,
376
+ });
377
+ }
378
+ return [...rows.values()].slice(0, all ? 12 : 6);
379
+ }
380
+ guideRows(query, all) {
381
+ const rows = new Map();
382
+ for (const hit of this.hits()) {
383
+ const index = hit.index;
384
+ if (index.pageType !== 'guide') {
385
+ continue;
386
+ }
387
+ const key = routeKey(index.route) + (index.fragment ? `#${index.fragment}` : '');
388
+ if (rows.has(key)) {
389
+ continue;
390
+ }
391
+ const title = index.section || index.title;
392
+ const path = index.section
393
+ ? index.breadcrumbs
394
+ : index.breadcrumbs.slice(0, Math.max(index.breadcrumbs.length - 1, 0));
395
+ rows.set(key, {
396
+ id: '',
397
+ type: 'guide',
398
+ title,
399
+ label: highlight(title, query),
400
+ meta: path.join(' › '),
401
+ icon: index.fragment ? 'section' : 'page',
402
+ url: pageUrl(index),
403
+ text: index.content,
404
+ });
405
+ }
406
+ return [...rows.values()].slice(0, all ? 12 : 5);
407
+ }
408
+ actionRows(query) {
409
+ const needle = query.toLowerCase();
410
+ return this.actions
411
+ .filter((action) => !needle ||
412
+ action.name().toLowerCase().includes(needle) ||
413
+ action.keywords.split(' ').some((word) => word.startsWith(needle)))
414
+ .map((action) => ({
415
+ id: '',
416
+ type: 'action',
417
+ title: action.name(),
418
+ label: highlight(action.name(), query),
419
+ meta: '',
420
+ icon: 'action',
421
+ keys: action.keys,
422
+ action,
423
+ }));
424
+ }
425
+ /**
426
+ * The hit of a symbol's page that previews it: the record with the declaration's summary (the
427
+ * new engine puts it on one record of the page), or else any record outside a section.
428
+ * @param route - The route of the symbol's page.
429
+ */
430
+ hitsFor(route) {
431
+ const page = this.hits()
432
+ .map((hit) => hit.index)
433
+ .filter((index) => routeKey(index.route) === route && !index.section);
434
+ return (page.find((index) => index.signature !== undefined || !!index.kind) ?? page[0]);
435
+ }
436
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocCommandPaletteComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
437
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocCommandPaletteComponent, isStandalone: true, selector: "ng-doc-command-palette", host: { attributes: { "animate.enter": "ng-doc-command-palette-enter" } }, viewQueries: [{ propertyName: "input", first: true, predicate: ["input"], descendants: true, isSignal: true }, { propertyName: "list", first: true, predicate: ["list"], descendants: true, isSignal: true }], ngImport: i0, template: "@let current = selected();\n<div\n class=\"ng-doc-command-palette\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Search\"\n (keydown)=\"onTrapKeydown($event)\">\n <div class=\"ng-doc-command-palette-input\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n <input\n #input\n type=\"text\"\n role=\"combobox\"\n aria-label=\"Search the documentation\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n aria-controls=\"ng-doc-command-palette-list\"\n [attr.aria-activedescendant]=\"current?.id ?? null\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n placeholder=\"Search guides, API and actions\u2026\"\n [formField]=\"searchForm.query\"\n (keydown)=\"onKeydown($event)\" />\n <div\n class=\"ng-doc-command-palette-scopes ng-doc-command-palette-segments\"\n role=\"tablist\"\n aria-label=\"Search scope\"\n ngDocSelectionHost>\n <ng-doc-selection [align]=\"null\" />\n @for (item of scopes; track item.id) {\n <button\n type=\"button\"\n role=\"tab\"\n aria-controls=\"ng-doc-command-palette-list\"\n [attr.tabindex]=\"scope() === item.id ? 0 : -1\"\n [attr.aria-selected]=\"scope() === item.id\"\n [ngDocSelectionOrigin]=\"scope() === item.id\"\n (mousedown)=\"$event.preventDefault()\"\n (keydown)=\"onScopeKeydown($event)\"\n (click)=\"selectScope(item.id)\">\n {{ item.label }}\n </button>\n }\n </div>\n <kbd class=\"ng-doc-command-palette-kbd\">Esc</kbd>\n </div>\n\n <div class=\"ng-doc-command-palette-body\">\n <div\n #list\n class=\"ng-doc-command-palette-list\"\n id=\"ng-doc-command-palette-list\"\n role=\"listbox\"\n aria-label=\"Results\">\n @for (section of sections(); track section.key) {\n <div class=\"ng-doc-command-palette-group\" role=\"group\" [attr.aria-label]=\"section.title\">\n <div class=\"ng-doc-command-palette-section\" aria-hidden=\"true\">\n <span>{{ section.title }}</span>\n <span class=\"ng-doc-command-palette-count\">{{ section.rows.length }}</span>\n </div>\n @for (row of section.rows; track row.id) {\n <div\n class=\"ng-doc-command-palette-row\"\n role=\"option\"\n [id]=\"row.id\"\n [attr.data-ng-doc-type]=\"row.type\"\n [attr.data-ng-doc-url]=\"row.url ?? null\"\n [attr.aria-selected]=\"row.id === current?.id\"\n (mousedown)=\"$event.preventDefault()\"\n (mousemove)=\"hover(rows().indexOf(row))\"\n (click)=\"activate(row)\">\n <span class=\"ng-doc-command-palette-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"icon\"\n [ngTemplateOutletContext]=\"{ $implicit: row.icon }\"></ng-container>\n </span>\n <span class=\"ng-doc-command-palette-name\" [class.ng-doc-command-palette-mono]=\"row.type === 'api'\">\n <span class=\"ng-doc-command-palette-label\">\n @for (segment of row.label; track $index) {\n @if (segment.match) {\n <mark>{{ segment.text }}</mark>\n } @else {\n <span>{{ segment.text }}</span>\n }\n }\n </span>\n @if (row.meta) {\n <small>{{ row.meta }}</small>\n }\n </span>\n <span class=\"ng-doc-command-palette-end\">\n @if (row.kind) {\n <ng-doc-kind-icon [kind]=\"row.kind\"></ng-doc-kind-icon>\n } @else if (row.type === 'api') {\n <span class=\"ng-doc-command-palette-type\" data-ng-doc-page-type=\"api\">API</span>\n }\n @if (row.keys?.length && shortcuts.enabled()) {\n @for (key of row.keys; track key) {\n <kbd class=\"ng-doc-command-palette-kbd\">{{ key }}</kbd>\n }\n }\n <svg\n class=\"ng-doc-command-palette-return\"\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=\"M20 5v7a3 3 0 0 1-3 3H5\" />\n <path d=\"m9 11-4 4 4 4\" />\n </svg>\n </span>\n </div>\n }\n </div>\n } @empty {\n <div class=\"ng-doc-command-palette-empty\" role=\"presentation\">\n @if (searching()) {\n <ng-doc-spinner size=\"small\"></ng-doc-spinner>\n Searching\u2026\n } @else if (failed()) {\n Search failed. Try again.\n } @else {\n {{ emptyMessage() }}\n }\n </div>\n }\n </div>\n\n <div class=\"ng-doc-command-palette-preview\">\n @if (current) {\n <div class=\"ng-doc-command-palette-preview-top\">\n @switch (current.type) {\n @case ('api') {\n @if (current.kind) {\n <ng-doc-kind-icon [kind]=\"current.kind\"></ng-doc-kind-icon>\n } @else {\n <span class=\"ng-doc-command-palette-type\" data-ng-doc-page-type=\"api\">API</span>\n }\n <span>{{ current.scope }}</span>\n }\n @case ('guide') {\n <span class=\"ng-doc-command-palette-type\" data-ng-doc-page-type=\"guide\">Guide</span>\n <span>{{ current.meta }}</span>\n }\n @default {\n <ng-container\n [ngTemplateOutlet]=\"icon\"\n [ngTemplateOutletContext]=\"{ $implicit: 'action' }\"></ng-container>\n <span>Action</span>\n }\n }\n </div>\n <h2\n class=\"ng-doc-command-palette-preview-title\"\n [class.ng-doc-command-palette-mono]=\"current.type === 'api'\">\n {{ current.title }}\n </h2>\n @if (current.type === 'action') {\n <p class=\"ng-doc-command-palette-muted\">\n {{ current.action?.keepOpen ? 'Changes the setting and keeps the search open.' : 'Runs immediately.' }}\n </p>\n @if (current.keys?.length && shortcuts.enabled()) {\n <div class=\"ng-doc-command-palette-hint\">\n Shortcut\n @for (key of current.keys; track key) {\n <kbd class=\"ng-doc-command-palette-kbd\">{{ key }}</kbd>\n }\n </div>\n }\n } @else {\n @if (current.text) {\n <p class=\"ng-doc-command-palette-text\">{{ current.text }}</p>\n }\n @if (current.signature) {\n <pre class=\"ng-doc-command-palette-signature\"><code>{{ current.signature }}</code></pre>\n }\n <div class=\"ng-doc-command-palette-hint\">\n <kbd class=\"ng-doc-command-palette-kbd\">\u21B5</kbd>\n {{ current.type === 'api' ? 'open symbol page' : 'open' }}\n </div>\n }\n }\n </div>\n </div>\n\n <div class=\"ng-doc-command-palette-announcer\" role=\"status\">{{ status() }}</div>\n\n <div class=\"ng-doc-command-palette-footer\">\n <span>\n <kbd class=\"ng-doc-command-palette-kbd\">\u2191</kbd>\n <kbd class=\"ng-doc-command-palette-kbd\">\u2193</kbd>\n navigate\n </span>\n <span class=\"ng-doc-command-palette-wide\"><kbd class=\"ng-doc-command-palette-kbd\">\u21B5</kbd> open</span>\n <span class=\"ng-doc-command-palette-wide\"\n ><kbd class=\"ng-doc-command-palette-kbd\">Tab</kbd> scopes and settings</span\n >\n @if (shortcuts.enabled()) {\n <span class=\"ng-doc-command-palette-wide\"\n ><kbd class=\"ng-doc-command-palette-kbd\">/</kbd> also opens search</span\n >\n }\n <button\n class=\"ng-doc-command-palette-switch\"\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"shortcuts.enabled()\"\n title=\"Single-character shortcuts: / [ ] F L T\"\n (click)=\"shortcuts.toggle()\">\n Single-key shortcuts\n <span class=\"ng-doc-command-palette-track\" aria-hidden=\"true\"></span>\n </button>\n </div>\n</div>\n\n<ng-template #icon let-name>\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 @switch (name) {\n @case ('symbol') {\n <path d=\"m21 16-9 5-9-5V8l9-5 9 5z\" />\n <path d=\"m3.3 7.5 8.7 5 8.7-5M12 22V12.5\" />\n }\n @case ('section') {\n <path d=\"M4 9h16M4 15h16M10 3 8 21M16 3l-2 18\" />\n }\n @case ('action') {\n <path d=\"M13 2 3 14h9l-1 8 10-12h-9z\" />\n }\n @default {\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 3v5h5M9 13h6M9 17h6\" />\n }\n }\n </svg>\n</ng-template>\n", styles: [".ng-doc-command-palette-backdrop{background:rgb(var(--ng-doc-base-rgb)/.32)}:root[data-theme=dark] .ng-doc-command-palette-backdrop{background:#0000008c}@media(prefers-color-scheme:dark){:root[data-theme=auto] .ng-doc-command-palette-backdrop{background:#0000008c}}ng-doc-command-palette{display:block;width:min(var(--ng-doc-search-dialog-width),100vw - 32px);font-family:var(--ng-doc-font-family);color:var(--ng-doc-text)}ng-doc-command-palette.ng-doc-command-palette-enter{animation:ng-doc-command-palette-enter .15s var(--ng-doc-easing, ease-out)}@media(max-width:640px){ng-doc-command-palette{width:calc(100vw - 16px)}}@keyframes ng-doc-command-palette-enter{0%{opacity:0;transform:scale(.98)}}.ng-doc-command-palette{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr) auto;grid-template-columns:minmax(0,1fr);max-height:min(600px,82vh);overflow:hidden;background:var(--ng-doc-background);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-search-border-radius, var(--ng-doc-radius-xl));box-shadow:var(--ng-doc-shadow-lg)}@media(max-width:640px){.ng-doc-command-palette{max-height:calc(100vh - 16px)}}.ng-doc-command-palette-announcer{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.ng-doc-command-palette-kbd{display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 5px;font:500 12px/1 var(--ng-doc-font-family);color:var(--ng-doc-text-muted);background:var(--ng-doc-kbd-background);border:1px solid var(--ng-doc-kbd-border-color);border-radius:var(--ng-doc-radius-xs)}.ng-doc-command-palette-mono{font-family:var(--ng-doc-code-font)}.ng-doc-command-palette-muted{color:var(--ng-doc-text-muted)}.ng-doc-command-palette-input{display:flex;align-items:center;gap:var(--ng-doc-space-3);height:56px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-4);border-bottom:1px solid var(--ng-doc-border-color);color:var(--ng-doc-text-muted)}.ng-doc-command-palette-input svg{flex:none}.ng-doc-command-palette-input input{flex:1;min-width:0;height:100%;padding:0;border:0;outline:0;background:none;font:400 16px/24px var(--ng-doc-font-family);color:var(--ng-doc-heading-color)}.ng-doc-command-palette-input input::placeholder{color:var(--ng-doc-text-muted);opacity:1}.ng-doc-command-palette-segments{position:relative;display:inline-flex;flex:none;gap:2px;padding:3px;border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-base-2)}.ng-doc-command-palette-segments ng-doc-selection{border-radius:var(--ng-doc-radius-sm);background:var(--ng-doc-background);box-shadow:var(--ng-doc-shadow-xs)}.ng-doc-command-palette-segments button{position:relative;display:inline-flex;align-items:center;height:24px;padding:0 8px;border:0;border-radius:var(--ng-doc-radius-sm);background:none;font:500 12px/1 var(--ng-doc-font-family);color:var(--ng-doc-text-muted);cursor:pointer;white-space:nowrap}.ng-doc-command-palette-segments button:hover,.ng-doc-command-palette-segments button[aria-selected=true]{color:var(--ng-doc-heading-color)}.ng-doc-command-palette-segments button:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}:root[data-theme=dark] .ng-doc-command-palette-segments ng-doc-selection{box-shadow:var(--ng-doc-shadow-xs),inset 0 0 0 1px var(--ng-doc-base-4)}@media(prefers-color-scheme:dark){:root[data-theme=auto] .ng-doc-command-palette-segments ng-doc-selection{box-shadow:var(--ng-doc-shadow-xs),inset 0 0 0 1px var(--ng-doc-base-4)}}.ng-doc-command-palette-body{display:grid;grid-template-columns:minmax(0,1fr) var(--ng-doc-search-preview-width);min-height:0}.ng-doc-command-palette-list{min-height:120px;padding:var(--ng-doc-space-2);overflow:auto;overscroll-behavior:contain;container:ng-doc-command-palette-list/inline-size}.ng-doc-command-palette-empty{display:flex;align-items:center;justify-content:center;gap:var(--ng-doc-space-2);font-size:14px;line-height:20px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-empty{padding:var(--ng-doc-space-8) var(--ng-doc-space-3)}.ng-doc-command-palette-section{display:flex;justify-content:space-between;margin:var(--ng-doc-space-4) var(--ng-doc-space-3) var(--ng-doc-space-2);font:600 11px/16px var(--ng-doc-font-family);letter-spacing:.05em;text-transform:uppercase;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-section .ng-doc-command-palette-count{font-weight:400;letter-spacing:0;font-variant-numeric:tabular-nums}.ng-doc-command-palette-group:first-child .ng-doc-command-palette-section{margin-top:var(--ng-doc-space-2)}.ng-doc-command-palette-row{display:grid;grid-template-columns:20px minmax(0,1fr) auto;align-items:center;column-gap:var(--ng-doc-space-3);min-height:40px;padding:4px var(--ng-doc-space-3);border-radius:var(--ng-doc-radius-md);font-size:14px;line-height:20px;color:var(--ng-doc-text);cursor:pointer}.ng-doc-command-palette-row:hover{background:var(--ng-doc-row-hover-background)}.ng-doc-command-palette-row[aria-selected=true]{background:var(--ng-doc-row-selected-background);box-shadow:inset 0 0 0 1px var(--ng-doc-row-selected-border)}.ng-doc-command-palette-row[aria-selected=true] .ng-doc-command-palette-return{display:block}.ng-doc-command-palette-row mark{background:none;color:var(--ng-doc-primary-strong);text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:3px}.ng-doc-command-palette-icon{display:grid;place-items:center;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-name{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--ng-doc-search-result-header-color, var(--ng-doc-heading-color))}.ng-doc-command-palette-name.ng-doc-command-palette-mono{font-size:13px;font-weight:500}.ng-doc-command-palette-name small{margin-left:var(--ng-doc-space-2);font:400 12px var(--ng-doc-font-family);color:var(--ng-doc-text-muted)}.ng-doc-command-palette-end{display:inline-flex;align-items:center;gap:6px;justify-self:end}.ng-doc-command-palette-return{display:none;color:var(--ng-doc-primary-strong)}@container ng-doc-command-palette-list (max-width: 420px){.ng-doc-command-palette-row{column-gap:var(--ng-doc-space-2);padding:4px var(--ng-doc-space-2)}.ng-doc-command-palette-name small{display:none}}.ng-doc-command-palette-preview{padding:var(--ng-doc-space-4);overflow:auto;border-left:1px solid var(--ng-doc-border-color);background:var(--ng-doc-base-1);font-size:13px;line-height:20px}.ng-doc-command-palette-preview p{margin:0 0 var(--ng-doc-space-3)}.ng-doc-command-palette-preview-top{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ng-doc-space-2);font-size:12px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-preview-title{margin:var(--ng-doc-space-2) 0 var(--ng-doc-space-1);padding:0;border:0;font:600 15px/22px var(--ng-doc-font-family);letter-spacing:0;color:var(--ng-doc-heading-color);overflow-wrap:anywhere}.ng-doc-command-palette-preview-title.ng-doc-command-palette-mono{font-family:var(--ng-doc-code-font)}.ng-doc-command-palette-text{display:-webkit-box;-webkit-line-clamp:8;-webkit-box-orient:vertical;overflow:hidden;color:var(--ng-doc-search-result-color)}.ng-doc-command-palette-type{display:inline-flex;align-items:center;height:18px;padding:0 5px;border-radius:var(--ng-doc-radius-sm);font:600 10.5px/1 var(--ng-doc-font-family);white-space:nowrap}.ng-doc-command-palette-type[data-ng-doc-page-type=api]{color:var(--ng-doc-api-tag-color);background:var(--ng-doc-api-tag-background)}.ng-doc-command-palette-type[data-ng-doc-page-type=guide]{color:var(--ng-doc-guide-tag-color);background:var(--ng-doc-guide-tag-background)}.ng-doc-command-palette-signature{margin:0 0 var(--ng-doc-space-3);padding:var(--ng-doc-space-2) var(--ng-doc-space-3);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);font:400 13px/20px var(--ng-doc-code-font);white-space:pre-wrap;overflow-wrap:anywhere}.ng-doc-command-palette-hint{display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:12px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-footer{display:flex;align-items:center;gap:var(--ng-doc-space-4);min-height:44px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-4);border-top:1px solid var(--ng-doc-border-color);background:var(--ng-doc-base-1);font-size:12px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-footer>span{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.ng-doc-command-palette-switch{display:inline-flex;align-items:center;gap:8px;margin:-4px -4px -4px auto;padding:4px;border:0;border-radius:var(--ng-doc-radius-sm);background:none;font:400 12px/1 var(--ng-doc-font-family);color:var(--ng-doc-text);cursor:pointer;white-space:nowrap}.ng-doc-command-palette-switch:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-command-palette-switch .ng-doc-command-palette-track{position:relative;width:28px;height:16px;border-radius:var(--ng-doc-radius-full);background:var(--ng-doc-base-7);transition:background var(--ng-doc-transition)}.ng-doc-command-palette-switch .ng-doc-command-palette-track:after{content:\"\";position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--ng-doc-background);box-shadow:var(--ng-doc-shadow-xs);transition:transform var(--ng-doc-transition) var(--ng-doc-easing, ease)}.ng-doc-command-palette-switch[aria-checked=true] .ng-doc-command-palette-track{background:var(--ng-doc-primary)}.ng-doc-command-palette-switch[aria-checked=true] .ng-doc-command-palette-track:after{transform:translate(12px)}:root[data-theme=dark] .ng-doc-command-palette-switch:not([aria-checked=true]) .ng-doc-command-palette-track{background:var(--ng-doc-base-8)}@media(prefers-color-scheme:dark){:root[data-theme=auto] .ng-doc-command-palette-switch:not([aria-checked=true]) .ng-doc-command-palette-track{background:var(--ng-doc-base-8)}}@media(max-width:640px){.ng-doc-command-palette-body{grid-template-columns:minmax(0,1fr)}.ng-doc-command-palette-preview,.ng-doc-command-palette-wide{display:none!important}.ng-doc-command-palette-input{flex-wrap:wrap;row-gap:0;height:auto;padding-bottom:var(--ng-doc-space-2)}.ng-doc-command-palette-input input{height:48px}.ng-doc-command-palette-scopes{order:1;flex:1 1 100%}.ng-doc-command-palette-scopes button{flex:1;justify-content:center}.ng-doc-command-palette-footer{gap:var(--ng-doc-space-3);padding-left:var(--ng-doc-space-3)}}@media(prefers-reduced-motion:reduce){ng-doc-command-palette.ng-doc-command-palette-enter{animation:none}.ng-doc-command-palette-switch .ng-doc-command-palette-track,.ng-doc-command-palette-switch .ng-doc-command-palette-track:after{transition:none}}\n"], dependencies: [{ kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgDocKindIconComponent, selector: "ng-doc-kind-icon", inputs: ["kind", "type", "size"] }, { kind: "component", type: NgDocSelectionComponent, selector: "ng-doc-selection", inputs: ["align"] }, { kind: "directive", type: NgDocSelectionHostDirective, selector: "[ngDocSelectionHost]" }, { kind: "directive", type: NgDocSelectionOriginDirective, selector: "[ngDocSelectionOrigin]", inputs: ["ngDocSelectionOrigin"] }, { kind: "component", type: NgDocSpinnerComponent, selector: "ng-doc-spinner", inputs: ["size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
438
+ }
439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocCommandPaletteComponent, decorators: [{
440
+ type: Component,
441
+ args: [{ selector: 'ng-doc-command-palette', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
442
+ FormField,
443
+ NgTemplateOutlet,
444
+ NgDocKindIconComponent,
445
+ NgDocSelectionComponent,
446
+ NgDocSelectionHostDirective,
447
+ NgDocSelectionOriginDirective,
448
+ NgDocSpinnerComponent,
449
+ ], host: {
450
+ 'animate.enter': 'ng-doc-command-palette-enter',
451
+ }, template: "@let current = selected();\n<div\n class=\"ng-doc-command-palette\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Search\"\n (keydown)=\"onTrapKeydown($event)\">\n <div class=\"ng-doc-command-palette-input\">\n <svg\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"m20 20-3.5-3.5\" />\n </svg>\n <input\n #input\n type=\"text\"\n role=\"combobox\"\n aria-label=\"Search the documentation\"\n aria-autocomplete=\"list\"\n aria-expanded=\"true\"\n aria-controls=\"ng-doc-command-palette-list\"\n [attr.aria-activedescendant]=\"current?.id ?? null\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n placeholder=\"Search guides, API and actions\u2026\"\n [formField]=\"searchForm.query\"\n (keydown)=\"onKeydown($event)\" />\n <div\n class=\"ng-doc-command-palette-scopes ng-doc-command-palette-segments\"\n role=\"tablist\"\n aria-label=\"Search scope\"\n ngDocSelectionHost>\n <ng-doc-selection [align]=\"null\" />\n @for (item of scopes; track item.id) {\n <button\n type=\"button\"\n role=\"tab\"\n aria-controls=\"ng-doc-command-palette-list\"\n [attr.tabindex]=\"scope() === item.id ? 0 : -1\"\n [attr.aria-selected]=\"scope() === item.id\"\n [ngDocSelectionOrigin]=\"scope() === item.id\"\n (mousedown)=\"$event.preventDefault()\"\n (keydown)=\"onScopeKeydown($event)\"\n (click)=\"selectScope(item.id)\">\n {{ item.label }}\n </button>\n }\n </div>\n <kbd class=\"ng-doc-command-palette-kbd\">Esc</kbd>\n </div>\n\n <div class=\"ng-doc-command-palette-body\">\n <div\n #list\n class=\"ng-doc-command-palette-list\"\n id=\"ng-doc-command-palette-list\"\n role=\"listbox\"\n aria-label=\"Results\">\n @for (section of sections(); track section.key) {\n <div class=\"ng-doc-command-palette-group\" role=\"group\" [attr.aria-label]=\"section.title\">\n <div class=\"ng-doc-command-palette-section\" aria-hidden=\"true\">\n <span>{{ section.title }}</span>\n <span class=\"ng-doc-command-palette-count\">{{ section.rows.length }}</span>\n </div>\n @for (row of section.rows; track row.id) {\n <div\n class=\"ng-doc-command-palette-row\"\n role=\"option\"\n [id]=\"row.id\"\n [attr.data-ng-doc-type]=\"row.type\"\n [attr.data-ng-doc-url]=\"row.url ?? null\"\n [attr.aria-selected]=\"row.id === current?.id\"\n (mousedown)=\"$event.preventDefault()\"\n (mousemove)=\"hover(rows().indexOf(row))\"\n (click)=\"activate(row)\">\n <span class=\"ng-doc-command-palette-icon\" aria-hidden=\"true\">\n <ng-container\n [ngTemplateOutlet]=\"icon\"\n [ngTemplateOutletContext]=\"{ $implicit: row.icon }\"></ng-container>\n </span>\n <span class=\"ng-doc-command-palette-name\" [class.ng-doc-command-palette-mono]=\"row.type === 'api'\">\n <span class=\"ng-doc-command-palette-label\">\n @for (segment of row.label; track $index) {\n @if (segment.match) {\n <mark>{{ segment.text }}</mark>\n } @else {\n <span>{{ segment.text }}</span>\n }\n }\n </span>\n @if (row.meta) {\n <small>{{ row.meta }}</small>\n }\n </span>\n <span class=\"ng-doc-command-palette-end\">\n @if (row.kind) {\n <ng-doc-kind-icon [kind]=\"row.kind\"></ng-doc-kind-icon>\n } @else if (row.type === 'api') {\n <span class=\"ng-doc-command-palette-type\" data-ng-doc-page-type=\"api\">API</span>\n }\n @if (row.keys?.length && shortcuts.enabled()) {\n @for (key of row.keys; track key) {\n <kbd class=\"ng-doc-command-palette-kbd\">{{ key }}</kbd>\n }\n }\n <svg\n class=\"ng-doc-command-palette-return\"\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=\"M20 5v7a3 3 0 0 1-3 3H5\" />\n <path d=\"m9 11-4 4 4 4\" />\n </svg>\n </span>\n </div>\n }\n </div>\n } @empty {\n <div class=\"ng-doc-command-palette-empty\" role=\"presentation\">\n @if (searching()) {\n <ng-doc-spinner size=\"small\"></ng-doc-spinner>\n Searching\u2026\n } @else if (failed()) {\n Search failed. Try again.\n } @else {\n {{ emptyMessage() }}\n }\n </div>\n }\n </div>\n\n <div class=\"ng-doc-command-palette-preview\">\n @if (current) {\n <div class=\"ng-doc-command-palette-preview-top\">\n @switch (current.type) {\n @case ('api') {\n @if (current.kind) {\n <ng-doc-kind-icon [kind]=\"current.kind\"></ng-doc-kind-icon>\n } @else {\n <span class=\"ng-doc-command-palette-type\" data-ng-doc-page-type=\"api\">API</span>\n }\n <span>{{ current.scope }}</span>\n }\n @case ('guide') {\n <span class=\"ng-doc-command-palette-type\" data-ng-doc-page-type=\"guide\">Guide</span>\n <span>{{ current.meta }}</span>\n }\n @default {\n <ng-container\n [ngTemplateOutlet]=\"icon\"\n [ngTemplateOutletContext]=\"{ $implicit: 'action' }\"></ng-container>\n <span>Action</span>\n }\n }\n </div>\n <h2\n class=\"ng-doc-command-palette-preview-title\"\n [class.ng-doc-command-palette-mono]=\"current.type === 'api'\">\n {{ current.title }}\n </h2>\n @if (current.type === 'action') {\n <p class=\"ng-doc-command-palette-muted\">\n {{ current.action?.keepOpen ? 'Changes the setting and keeps the search open.' : 'Runs immediately.' }}\n </p>\n @if (current.keys?.length && shortcuts.enabled()) {\n <div class=\"ng-doc-command-palette-hint\">\n Shortcut\n @for (key of current.keys; track key) {\n <kbd class=\"ng-doc-command-palette-kbd\">{{ key }}</kbd>\n }\n </div>\n }\n } @else {\n @if (current.text) {\n <p class=\"ng-doc-command-palette-text\">{{ current.text }}</p>\n }\n @if (current.signature) {\n <pre class=\"ng-doc-command-palette-signature\"><code>{{ current.signature }}</code></pre>\n }\n <div class=\"ng-doc-command-palette-hint\">\n <kbd class=\"ng-doc-command-palette-kbd\">\u21B5</kbd>\n {{ current.type === 'api' ? 'open symbol page' : 'open' }}\n </div>\n }\n }\n </div>\n </div>\n\n <div class=\"ng-doc-command-palette-announcer\" role=\"status\">{{ status() }}</div>\n\n <div class=\"ng-doc-command-palette-footer\">\n <span>\n <kbd class=\"ng-doc-command-palette-kbd\">\u2191</kbd>\n <kbd class=\"ng-doc-command-palette-kbd\">\u2193</kbd>\n navigate\n </span>\n <span class=\"ng-doc-command-palette-wide\"><kbd class=\"ng-doc-command-palette-kbd\">\u21B5</kbd> open</span>\n <span class=\"ng-doc-command-palette-wide\"\n ><kbd class=\"ng-doc-command-palette-kbd\">Tab</kbd> scopes and settings</span\n >\n @if (shortcuts.enabled()) {\n <span class=\"ng-doc-command-palette-wide\"\n ><kbd class=\"ng-doc-command-palette-kbd\">/</kbd> also opens search</span\n >\n }\n <button\n class=\"ng-doc-command-palette-switch\"\n type=\"button\"\n role=\"switch\"\n [attr.aria-checked]=\"shortcuts.enabled()\"\n title=\"Single-character shortcuts: / [ ] F L T\"\n (click)=\"shortcuts.toggle()\">\n Single-key shortcuts\n <span class=\"ng-doc-command-palette-track\" aria-hidden=\"true\"></span>\n </button>\n </div>\n</div>\n\n<ng-template #icon let-name>\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 @switch (name) {\n @case ('symbol') {\n <path d=\"m21 16-9 5-9-5V8l9-5 9 5z\" />\n <path d=\"m3.3 7.5 8.7 5 8.7-5M12 22V12.5\" />\n }\n @case ('section') {\n <path d=\"M4 9h16M4 15h16M10 3 8 21M16 3l-2 18\" />\n }\n @case ('action') {\n <path d=\"M13 2 3 14h9l-1 8 10-12h-9z\" />\n }\n @default {\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 3v5h5M9 13h6M9 17h6\" />\n }\n }\n </svg>\n</ng-template>\n", styles: [".ng-doc-command-palette-backdrop{background:rgb(var(--ng-doc-base-rgb)/.32)}:root[data-theme=dark] .ng-doc-command-palette-backdrop{background:#0000008c}@media(prefers-color-scheme:dark){:root[data-theme=auto] .ng-doc-command-palette-backdrop{background:#0000008c}}ng-doc-command-palette{display:block;width:min(var(--ng-doc-search-dialog-width),100vw - 32px);font-family:var(--ng-doc-font-family);color:var(--ng-doc-text)}ng-doc-command-palette.ng-doc-command-palette-enter{animation:ng-doc-command-palette-enter .15s var(--ng-doc-easing, ease-out)}@media(max-width:640px){ng-doc-command-palette{width:calc(100vw - 16px)}}@keyframes ng-doc-command-palette-enter{0%{opacity:0;transform:scale(.98)}}.ng-doc-command-palette{position:relative;display:grid;grid-template-rows:auto minmax(0,1fr) auto;grid-template-columns:minmax(0,1fr);max-height:min(600px,82vh);overflow:hidden;background:var(--ng-doc-background);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-search-border-radius, var(--ng-doc-radius-xl));box-shadow:var(--ng-doc-shadow-lg)}@media(max-width:640px){.ng-doc-command-palette{max-height:calc(100vh - 16px)}}.ng-doc-command-palette-announcer{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.ng-doc-command-palette-kbd{display:inline-grid;place-items:center;min-width:20px;height:20px;padding:0 5px;font:500 12px/1 var(--ng-doc-font-family);color:var(--ng-doc-text-muted);background:var(--ng-doc-kbd-background);border:1px solid var(--ng-doc-kbd-border-color);border-radius:var(--ng-doc-radius-xs)}.ng-doc-command-palette-mono{font-family:var(--ng-doc-code-font)}.ng-doc-command-palette-muted{color:var(--ng-doc-text-muted)}.ng-doc-command-palette-input{display:flex;align-items:center;gap:var(--ng-doc-space-3);height:56px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-4);border-bottom:1px solid var(--ng-doc-border-color);color:var(--ng-doc-text-muted)}.ng-doc-command-palette-input svg{flex:none}.ng-doc-command-palette-input input{flex:1;min-width:0;height:100%;padding:0;border:0;outline:0;background:none;font:400 16px/24px var(--ng-doc-font-family);color:var(--ng-doc-heading-color)}.ng-doc-command-palette-input input::placeholder{color:var(--ng-doc-text-muted);opacity:1}.ng-doc-command-palette-segments{position:relative;display:inline-flex;flex:none;gap:2px;padding:3px;border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-base-2)}.ng-doc-command-palette-segments ng-doc-selection{border-radius:var(--ng-doc-radius-sm);background:var(--ng-doc-background);box-shadow:var(--ng-doc-shadow-xs)}.ng-doc-command-palette-segments button{position:relative;display:inline-flex;align-items:center;height:24px;padding:0 8px;border:0;border-radius:var(--ng-doc-radius-sm);background:none;font:500 12px/1 var(--ng-doc-font-family);color:var(--ng-doc-text-muted);cursor:pointer;white-space:nowrap}.ng-doc-command-palette-segments button:hover,.ng-doc-command-palette-segments button[aria-selected=true]{color:var(--ng-doc-heading-color)}.ng-doc-command-palette-segments button:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}:root[data-theme=dark] .ng-doc-command-palette-segments ng-doc-selection{box-shadow:var(--ng-doc-shadow-xs),inset 0 0 0 1px var(--ng-doc-base-4)}@media(prefers-color-scheme:dark){:root[data-theme=auto] .ng-doc-command-palette-segments ng-doc-selection{box-shadow:var(--ng-doc-shadow-xs),inset 0 0 0 1px var(--ng-doc-base-4)}}.ng-doc-command-palette-body{display:grid;grid-template-columns:minmax(0,1fr) var(--ng-doc-search-preview-width);min-height:0}.ng-doc-command-palette-list{min-height:120px;padding:var(--ng-doc-space-2);overflow:auto;overscroll-behavior:contain;container:ng-doc-command-palette-list/inline-size}.ng-doc-command-palette-empty{display:flex;align-items:center;justify-content:center;gap:var(--ng-doc-space-2);font-size:14px;line-height:20px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-empty{padding:var(--ng-doc-space-8) var(--ng-doc-space-3)}.ng-doc-command-palette-section{display:flex;justify-content:space-between;margin:var(--ng-doc-space-4) var(--ng-doc-space-3) var(--ng-doc-space-2);font:600 11px/16px var(--ng-doc-font-family);letter-spacing:.05em;text-transform:uppercase;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-section .ng-doc-command-palette-count{font-weight:400;letter-spacing:0;font-variant-numeric:tabular-nums}.ng-doc-command-palette-group:first-child .ng-doc-command-palette-section{margin-top:var(--ng-doc-space-2)}.ng-doc-command-palette-row{display:grid;grid-template-columns:20px minmax(0,1fr) auto;align-items:center;column-gap:var(--ng-doc-space-3);min-height:40px;padding:4px var(--ng-doc-space-3);border-radius:var(--ng-doc-radius-md);font-size:14px;line-height:20px;color:var(--ng-doc-text);cursor:pointer}.ng-doc-command-palette-row:hover{background:var(--ng-doc-row-hover-background)}.ng-doc-command-palette-row[aria-selected=true]{background:var(--ng-doc-row-selected-background);box-shadow:inset 0 0 0 1px var(--ng-doc-row-selected-border)}.ng-doc-command-palette-row[aria-selected=true] .ng-doc-command-palette-return{display:block}.ng-doc-command-palette-row mark{background:none;color:var(--ng-doc-primary-strong);text-decoration:underline;text-decoration-thickness:1.5px;text-underline-offset:3px}.ng-doc-command-palette-icon{display:grid;place-items:center;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-name{min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;color:var(--ng-doc-search-result-header-color, var(--ng-doc-heading-color))}.ng-doc-command-palette-name.ng-doc-command-palette-mono{font-size:13px;font-weight:500}.ng-doc-command-palette-name small{margin-left:var(--ng-doc-space-2);font:400 12px var(--ng-doc-font-family);color:var(--ng-doc-text-muted)}.ng-doc-command-palette-end{display:inline-flex;align-items:center;gap:6px;justify-self:end}.ng-doc-command-palette-return{display:none;color:var(--ng-doc-primary-strong)}@container ng-doc-command-palette-list (max-width: 420px){.ng-doc-command-palette-row{column-gap:var(--ng-doc-space-2);padding:4px var(--ng-doc-space-2)}.ng-doc-command-palette-name small{display:none}}.ng-doc-command-palette-preview{padding:var(--ng-doc-space-4);overflow:auto;border-left:1px solid var(--ng-doc-border-color);background:var(--ng-doc-base-1);font-size:13px;line-height:20px}.ng-doc-command-palette-preview p{margin:0 0 var(--ng-doc-space-3)}.ng-doc-command-palette-preview-top{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ng-doc-space-2);font-size:12px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-preview-title{margin:var(--ng-doc-space-2) 0 var(--ng-doc-space-1);padding:0;border:0;font:600 15px/22px var(--ng-doc-font-family);letter-spacing:0;color:var(--ng-doc-heading-color);overflow-wrap:anywhere}.ng-doc-command-palette-preview-title.ng-doc-command-palette-mono{font-family:var(--ng-doc-code-font)}.ng-doc-command-palette-text{display:-webkit-box;-webkit-line-clamp:8;-webkit-box-orient:vertical;overflow:hidden;color:var(--ng-doc-search-result-color)}.ng-doc-command-palette-type{display:inline-flex;align-items:center;height:18px;padding:0 5px;border-radius:var(--ng-doc-radius-sm);font:600 10.5px/1 var(--ng-doc-font-family);white-space:nowrap}.ng-doc-command-palette-type[data-ng-doc-page-type=api]{color:var(--ng-doc-api-tag-color);background:var(--ng-doc-api-tag-background)}.ng-doc-command-palette-type[data-ng-doc-page-type=guide]{color:var(--ng-doc-guide-tag-color);background:var(--ng-doc-guide-tag-background)}.ng-doc-command-palette-signature{margin:0 0 var(--ng-doc-space-3);padding:var(--ng-doc-space-2) var(--ng-doc-space-3);border:1px solid var(--ng-doc-border-color);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);font:400 13px/20px var(--ng-doc-code-font);white-space:pre-wrap;overflow-wrap:anywhere}.ng-doc-command-palette-hint{display:flex;flex-wrap:wrap;align-items:center;gap:6px;font-size:12px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-footer{display:flex;align-items:center;gap:var(--ng-doc-space-4);min-height:44px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-4);border-top:1px solid var(--ng-doc-border-color);background:var(--ng-doc-base-1);font-size:12px;color:var(--ng-doc-text-muted)}.ng-doc-command-palette-footer>span{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}.ng-doc-command-palette-switch{display:inline-flex;align-items:center;gap:8px;margin:-4px -4px -4px auto;padding:4px;border:0;border-radius:var(--ng-doc-radius-sm);background:none;font:400 12px/1 var(--ng-doc-font-family);color:var(--ng-doc-text);cursor:pointer;white-space:nowrap}.ng-doc-command-palette-switch:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-command-palette-switch .ng-doc-command-palette-track{position:relative;width:28px;height:16px;border-radius:var(--ng-doc-radius-full);background:var(--ng-doc-base-7);transition:background var(--ng-doc-transition)}.ng-doc-command-palette-switch .ng-doc-command-palette-track:after{content:\"\";position:absolute;top:2px;left:2px;width:12px;height:12px;border-radius:50%;background:var(--ng-doc-background);box-shadow:var(--ng-doc-shadow-xs);transition:transform var(--ng-doc-transition) var(--ng-doc-easing, ease)}.ng-doc-command-palette-switch[aria-checked=true] .ng-doc-command-palette-track{background:var(--ng-doc-primary)}.ng-doc-command-palette-switch[aria-checked=true] .ng-doc-command-palette-track:after{transform:translate(12px)}:root[data-theme=dark] .ng-doc-command-palette-switch:not([aria-checked=true]) .ng-doc-command-palette-track{background:var(--ng-doc-base-8)}@media(prefers-color-scheme:dark){:root[data-theme=auto] .ng-doc-command-palette-switch:not([aria-checked=true]) .ng-doc-command-palette-track{background:var(--ng-doc-base-8)}}@media(max-width:640px){.ng-doc-command-palette-body{grid-template-columns:minmax(0,1fr)}.ng-doc-command-palette-preview,.ng-doc-command-palette-wide{display:none!important}.ng-doc-command-palette-input{flex-wrap:wrap;row-gap:0;height:auto;padding-bottom:var(--ng-doc-space-2)}.ng-doc-command-palette-input input{height:48px}.ng-doc-command-palette-scopes{order:1;flex:1 1 100%}.ng-doc-command-palette-scopes button{flex:1;justify-content:center}.ng-doc-command-palette-footer{gap:var(--ng-doc-space-3);padding-left:var(--ng-doc-space-3)}}@media(prefers-reduced-motion:reduce){ng-doc-command-palette.ng-doc-command-palette-enter{animation:none}.ng-doc-command-palette-switch .ng-doc-command-palette-track,.ng-doc-command-palette-switch .ng-doc-command-palette-track:after{transition:none}}\n"] }]
452
+ }], ctorParameters: () => [], propDecorators: { input: [{ type: i0.ViewChild, args: ['input', { isSignal: true }] }], list: [{ type: i0.ViewChild, args: ['list', { isSignal: true }] }] } });
453
+ /**
454
+ * Splits a text around the first case-insensitive occurrence of the query.
455
+ * @param text - The text to split.
456
+ * @param query - The query to find.
457
+ */
458
+ function highlight(text, query) {
459
+ const start = query ? text.toLowerCase().indexOf(query.toLowerCase()) : -1;
460
+ if (start < 0) {
461
+ return [{ text, match: false }];
462
+ }
463
+ const end = start + query.length;
464
+ return [
465
+ { text: text.slice(0, start), match: false },
466
+ { text: text.slice(start, end), match: true },
467
+ { text: text.slice(end), match: false },
468
+ ].filter((segment) => segment.text);
469
+ }
470
+ /**
471
+ * Whether two rows open the same result.
472
+ * @param a - A row.
473
+ * @param b - Another row.
474
+ */
475
+ function sameResult(a, b) {
476
+ return a.type === b.type && (a.action ? a.action === b.action : a.url === b.url);
477
+ }
478
+ /**
479
+ * Normalizes a route to compare search records with the API list.
480
+ * @param route - A route with or without the leading slash.
481
+ */
482
+ function routeKey(route) {
483
+ return route.replace(/^\/+/, '');
484
+ }
485
+ /**
486
+ * Builds the URL of a search record.
487
+ * @param index - The search record.
488
+ */
489
+ function pageUrl(index) {
490
+ return `/${routeKey(index.route)}${index.fragment ? `#${index.fragment}` : ''}`;
491
+ }
492
+
493
+ /**
494
+ * Generated bundle index. Do not edit.
495
+ */
496
+
497
+ export { NgDocCommandPaletteComponent };
498
+ //# sourceMappingURL=ng-doc-app-components-command-palette.mjs.map