@ng-doc/app 22.0.0 → 22.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/LICENSE +21 -0
  2. package/fesm2022/ng-doc-app-classes-content-controller.mjs +22 -4
  3. package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -1
  4. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +36 -12
  5. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
  6. package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
  7. package/fesm2022/ng-doc-app-components-api-list.mjs +7 -5
  8. package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
  9. package/fesm2022/ng-doc-app-components-breadcrumb.mjs +5 -3
  10. package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
  11. package/fesm2022/ng-doc-app-components-code.mjs +6 -4
  12. package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
  13. package/fesm2022/ng-doc-app-components-command-palette.mjs +35 -27
  14. package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -1
  15. package/fesm2022/ng-doc-app-components-copy-button.mjs +6 -4
  16. package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
  17. package/fesm2022/ng-doc-app-components-demo-displayer.mjs +19 -4
  18. package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
  19. package/fesm2022/ng-doc-app-components-demo-frame.mjs +279 -0
  20. package/fesm2022/ng-doc-app-components-demo-frame.mjs.map +1 -0
  21. package/fesm2022/ng-doc-app-components-demo-pane.mjs +2 -2
  22. package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
  23. package/fesm2022/ng-doc-app-components-demo.mjs +97 -14
  24. package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
  25. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +5 -3
  26. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
  27. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +4 -2
  28. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -1
  29. package/fesm2022/ng-doc-app-components-heading-anchor.mjs +5 -3
  30. package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
  31. package/fesm2022/ng-doc-app-components-image-viewer.mjs +5 -3
  32. package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
  33. package/fesm2022/ng-doc-app-components-navbar.mjs +4 -2
  34. package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
  35. package/fesm2022/ng-doc-app-components-page-navigation.mjs +5 -3
  36. package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
  37. package/fesm2022/ng-doc-app-components-page-wrapper.mjs +2 -2
  38. package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
  39. package/fesm2022/ng-doc-app-components-page.mjs +83 -16
  40. package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
  41. package/fesm2022/ng-doc-app-components-playground.mjs +838 -141
  42. package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
  43. package/fesm2022/ng-doc-app-components-root.mjs +51 -4
  44. package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
  45. package/fesm2022/ng-doc-app-components-search-result.mjs +8 -6
  46. package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
  47. package/fesm2022/ng-doc-app-components-search.mjs +7 -5
  48. package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
  49. package/fesm2022/ng-doc-app-components-sidebar.mjs +4 -3
  50. package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
  51. package/fesm2022/ng-doc-app-components-tabs.mjs +21 -3
  52. package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
  53. package/fesm2022/ng-doc-app-components-theme-toggle.mjs +7 -5
  54. package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
  55. package/fesm2022/ng-doc-app-components-toc.mjs +4 -2
  56. package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
  57. package/fesm2022/ng-doc-app-components.mjs +1 -0
  58. package/fesm2022/ng-doc-app-components.mjs.map +1 -1
  59. package/fesm2022/ng-doc-app-constants.mjs +11 -1
  60. package/fesm2022/ng-doc-app-constants.mjs.map +1 -1
  61. package/fesm2022/ng-doc-app-demo-app.mjs +779 -0
  62. package/fesm2022/ng-doc-app-demo-app.mjs.map +1 -0
  63. package/fesm2022/ng-doc-app-helpers.mjs +147 -7
  64. package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
  65. package/fesm2022/ng-doc-app-processors-processors.mjs +30 -9
  66. package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
  67. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +29 -18
  68. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
  69. package/fesm2022/ng-doc-app-providers-texts.mjs +53 -0
  70. package/fesm2022/ng-doc-app-providers-texts.mjs.map +1 -0
  71. package/fesm2022/ng-doc-app-providers-title.mjs +129 -0
  72. package/fesm2022/ng-doc-app-providers-title.mjs.map +1 -0
  73. package/fesm2022/ng-doc-app-providers.mjs +2 -0
  74. package/fesm2022/ng-doc-app-providers.mjs.map +1 -1
  75. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +27 -2
  76. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -1
  77. package/fesm2022/ng-doc-app-services-highlighter.mjs +23 -16
  78. package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
  79. package/fesm2022/ng-doc-app-services-route-preloader.mjs +34 -10
  80. package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -1
  81. package/fesm2022/ng-doc-app-services-shortcuts.mjs +38 -4
  82. package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -1
  83. package/fesm2022/ng-doc-app-texts-ar.mjs +238 -0
  84. package/fesm2022/ng-doc-app-texts-ar.mjs.map +1 -0
  85. package/fesm2022/ng-doc-app-texts-de.mjs +205 -0
  86. package/fesm2022/ng-doc-app-texts-de.mjs.map +1 -0
  87. package/fesm2022/ng-doc-app-texts-es.mjs +205 -0
  88. package/fesm2022/ng-doc-app-texts-es.mjs.map +1 -0
  89. package/fesm2022/ng-doc-app-texts-fr.mjs +205 -0
  90. package/fesm2022/ng-doc-app-texts-fr.mjs.map +1 -0
  91. package/fesm2022/ng-doc-app-texts-hi.mjs +219 -0
  92. package/fesm2022/ng-doc-app-texts-hi.mjs.map +1 -0
  93. package/fesm2022/ng-doc-app-texts-ja.mjs +205 -0
  94. package/fesm2022/ng-doc-app-texts-ja.mjs.map +1 -0
  95. package/fesm2022/ng-doc-app-texts-ko.mjs +205 -0
  96. package/fesm2022/ng-doc-app-texts-ko.mjs.map +1 -0
  97. package/fesm2022/ng-doc-app-texts-pt-br.mjs +205 -0
  98. package/fesm2022/ng-doc-app-texts-pt-br.mjs.map +1 -0
  99. package/fesm2022/ng-doc-app-texts-ru.mjs +231 -0
  100. package/fesm2022/ng-doc-app-texts-ru.mjs.map +1 -0
  101. package/fesm2022/ng-doc-app-texts-uk.mjs +231 -0
  102. package/fesm2022/ng-doc-app-texts-uk.mjs.map +1 -0
  103. package/fesm2022/ng-doc-app-texts-zh.mjs +205 -0
  104. package/fesm2022/ng-doc-app-texts-zh.mjs.map +1 -0
  105. package/fesm2022/ng-doc-app-tokens.mjs +214 -1
  106. package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
  107. package/fesm2022/ng-doc-app-type-controls-json-control.mjs +90 -0
  108. package/fesm2022/ng-doc-app-type-controls-json-control.mjs.map +1 -0
  109. package/fesm2022/ng-doc-app-type-controls-list-control.mjs +792 -0
  110. package/fesm2022/ng-doc-app-type-controls-list-control.mjs.map +1 -0
  111. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +45 -8
  112. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
  113. package/fesm2022/ng-doc-app-type-controls.mjs +2 -0
  114. package/fesm2022/ng-doc-app-type-controls.mjs.map +1 -1
  115. package/package.json +73 -4
  116. package/styles/global.css +4 -0
  117. package/styles/main.css +4 -0
  118. package/styles/themes/dark.css +10 -0
  119. package/types/ng-doc-app-classes-default-search-engine.d.ts +11 -0
  120. package/types/ng-doc-app-classes-root-page.d.ts +13 -0
  121. package/types/ng-doc-app-components-api-list.d.ts +3 -1
  122. package/types/ng-doc-app-components-breadcrumb.d.ts +2 -1
  123. package/types/ng-doc-app-components-code.d.ts +2 -0
  124. package/types/ng-doc-app-components-command-palette.d.ts +3 -1
  125. package/types/ng-doc-app-components-copy-button.d.ts +3 -1
  126. package/types/ng-doc-app-components-demo-displayer.d.ts +13 -1
  127. package/types/ng-doc-app-components-demo-frame.d.ts +107 -0
  128. package/types/ng-doc-app-components-demo.d.ts +47 -10
  129. package/types/ng-doc-app-components-fullscreen-button.d.ts +2 -0
  130. package/types/ng-doc-app-components-fullscreen-toggle.d.ts +2 -0
  131. package/types/ng-doc-app-components-heading-anchor.d.ts +2 -0
  132. package/types/ng-doc-app-components-image-viewer.d.ts +2 -0
  133. package/types/ng-doc-app-components-navbar.d.ts +2 -0
  134. package/types/ng-doc-app-components-page-navigation.d.ts +2 -1
  135. package/types/ng-doc-app-components-page.d.ts +10 -1
  136. package/types/ng-doc-app-components-playground.d.ts +260 -42
  137. package/types/ng-doc-app-components-root.d.ts +18 -0
  138. package/types/ng-doc-app-components-search-result.d.ts +2 -0
  139. package/types/ng-doc-app-components-search.d.ts +2 -0
  140. package/types/ng-doc-app-components-sidebar.d.ts +2 -1
  141. package/types/ng-doc-app-components-tabs.d.ts +13 -3
  142. package/types/ng-doc-app-components-theme-toggle.d.ts +4 -1
  143. package/types/ng-doc-app-components-toc.d.ts +2 -1
  144. package/types/ng-doc-app-components.d.ts +1 -0
  145. package/types/ng-doc-app-constants.d.ts +11 -1
  146. package/types/ng-doc-app-demo-app.d.ts +297 -0
  147. package/types/ng-doc-app-helpers.d.ts +75 -4
  148. package/types/ng-doc-app-interfaces.d.ts +635 -6
  149. package/types/ng-doc-app-processors-processors.d.ts +5 -0
  150. package/types/ng-doc-app-providers-ng-doc-app.d.ts +7 -1
  151. package/types/ng-doc-app-providers-texts.d.ts +28 -0
  152. package/types/ng-doc-app-providers-title.d.ts +59 -0
  153. package/types/ng-doc-app-providers.d.ts +2 -0
  154. package/types/ng-doc-app-services-content-scroll-intent.d.ts +11 -1
  155. package/types/ng-doc-app-services-highlighter.d.ts +15 -6
  156. package/types/ng-doc-app-services-route-preloader.d.ts +13 -1
  157. package/types/ng-doc-app-services-shortcuts.d.ts +16 -0
  158. package/types/ng-doc-app-texts-ar.d.ts +13 -0
  159. package/types/ng-doc-app-texts-de.d.ts +12 -0
  160. package/types/ng-doc-app-texts-es.d.ts +12 -0
  161. package/types/ng-doc-app-texts-fr.d.ts +12 -0
  162. package/types/ng-doc-app-texts-hi.d.ts +12 -0
  163. package/types/ng-doc-app-texts-ja.d.ts +12 -0
  164. package/types/ng-doc-app-texts-ko.d.ts +12 -0
  165. package/types/ng-doc-app-texts-pt-br.d.ts +12 -0
  166. package/types/ng-doc-app-texts-ru.d.ts +12 -0
  167. package/types/ng-doc-app-texts-uk.d.ts +12 -0
  168. package/types/ng-doc-app-texts-zh.d.ts +12 -0
  169. package/types/ng-doc-app-tokens.d.ts +21 -2
  170. package/types/ng-doc-app-type-controls-json-control.d.ts +38 -0
  171. package/types/ng-doc-app-type-controls-list-control.d.ts +313 -0
  172. package/types/ng-doc-app-type-controls-type-alias-control.d.ts +28 -5
  173. package/types/ng-doc-app-type-controls.d.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-api-list.mjs","sources":["../../../../libs/app/components/api-list/api-list.component.ts","../../../../libs/app/components/api-list/api-list.component.html","../../../../libs/app/components/api-list/ng-doc-app-components-api-list.ts"],"sourcesContent":["import { httpResource } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n Signal,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { form, FormField } from '@angular/forms/signals';\nimport { ActivatedRoute, ParamMap, Params, Router, RouterLink } from '@angular/router';\nimport { NgDocKindIconComponent, ngDocKindLabel } from '@ng-doc/app/components/kind-icon';\nimport { NgDocApiListIndexService } from '@ng-doc/app/services';\nimport { NgDocShortcutsService } from '@ng-doc/app/services/shortcuts';\nimport { asArray } from '@ng-doc/core/helpers/as-array';\nimport type { NgDocApiList, NgDocApiListItem } from '@ng-doc/core/interfaces';\nimport {\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n NgDocSelectionOriginDirective,\n} from '@ng-doc/ui-kit/components/selection';\nimport { NG_REQUEST_BASE_PATH } from '@ng-doc/ui-kit/tokens';\n\n/**\n * Orders kinds and names in English whatever the locale: `localeCompare` without a locale follows\n * the process locale, so a prerendered index would depend on the machine that built it, and the\n * browser would order a hydrated index differently from its prerendered HTML.\n */\nconst NAME_ORDER = new Intl.Collator('en');\n\n/** How the API index groups declarations. */\ntype GroupBy = 'kind' | 'scope';\n\n/**\n * A declaration of the API list. The generated list may carry a one-line description; the index\n * filters by it and shows it when it is present.\n */\ninterface Declaration extends NgDocApiListItem {\n description?: string;\n scope: string;\n}\n\ninterface Group {\n id: string;\n kind?: string;\n label: string;\n items: Declaration[];\n}\n\ninterface KindFilter {\n kind: string;\n label: string;\n count: number;\n}\n\n/**\n * The index of API declarations: a filter that matches names and descriptions, grouping by kind\n * or by scope, and a kind filter with counts. The filter, kind, scope and grouping are kept in\n * the query parameters (filter, type, scope and group), so a filtered index can be linked.\n */\n@Component({\n selector: 'ng-doc-api-list',\n templateUrl: './api-list.component.html',\n styleUrls: ['./api-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n FormField,\n NgDocKindIconComponent,\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n NgDocSelectionOriginDirective,\n RouterLink,\n ],\n})\nexport class NgDocApiListComponent {\n /** The title of the page. */\n readonly title = input<string>('API References');\n /** The segment of the API list data, when the site has more than one API list. */\n readonly segment = input<string>();\n\n protected readonly shortcuts = inject(NgDocShortcutsService);\n protected readonly model = signal({ filter: '' });\n protected readonly filterForm = form(this.model);\n protected readonly kind = signal('');\n protected readonly scope = signal('');\n protected readonly groupBy = signal<GroupBy>('kind');\n\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly basePath = inject(NG_REQUEST_BASE_PATH);\n private readonly filterInput = viewChild<ElementRef<HTMLInputElement>>('filterInput');\n\n private readonly apiList = httpResource<NgDocApiList[]>(\n () => this.basePath + asArray('assets/ng-doc', this.segment(), 'api-list.json').join('/'),\n );\n\n protected readonly declarations: Signal<Declaration[]> = computed(() =>\n this.apiList.hasValue()\n ? (this.apiList.value() ?? []).flatMap((scope: NgDocApiList) =>\n scope.items.map((item: NgDocApiListItem) => ({ ...item, scope: scope.title })),\n )\n : [],\n );\n\n protected readonly scopes = computed(() =>\n [...new Set(this.declarations().map(({ scope }: Declaration) => scope))].sort(),\n );\n\n protected readonly hasDescriptions = computed(() =>\n this.declarations().some(({ description }: Declaration) => !!description),\n );\n\n /** Declarations in the selected scope, before the text and kind filters. */\n protected readonly inScope = computed(() =>\n this.declarations().filter(({ scope }: Declaration) => !this.scope() || scope === this.scope()),\n );\n\n protected readonly kinds: Signal<KindFilter[]> = computed(() => {\n const counts = new Map<string, number>();\n\n for (const { type } of this.inScope()) {\n counts.set(type, (counts.get(type) ?? 0) + 1);\n }\n\n return [...counts]\n .map(([kind, count]: [string, number]) => ({ kind, label: ngDocKindLabel(kind), count }))\n .sort((a: KindFilter, b: KindFilter) => NAME_ORDER.compare(a.label, b.label));\n });\n\n protected readonly visible = computed(() => {\n const needle = this.model().filter.trim().toLowerCase();\n const kind = this.kind();\n\n return this.inScope().filter(\n (item: Declaration) =>\n (!kind || item.type === kind) &&\n (!needle ||\n item.name.toLowerCase().includes(needle) ||\n !!item.description?.toLowerCase().includes(needle)),\n );\n });\n\n protected readonly groups: Signal<Group[]> = computed(() => {\n const byName = (a: Declaration, b: Declaration) => NAME_ORDER.compare(a.name, b.name);\n\n if (this.groupBy() === 'scope') {\n return this.scopes()\n .map((scope: string) => ({\n id: `scope-${slug(scope)}`,\n label: scope,\n items: this.visible()\n .filter((item: Declaration) => item.scope === scope)\n .sort(\n (a: Declaration, b: Declaration) =>\n NAME_ORDER.compare(ngDocKindLabel(a.type), ngDocKindLabel(b.type)) || byName(a, b),\n ),\n }))\n .filter((group: Group) => group.items.length);\n }\n\n return this.kinds()\n .map(({ kind, label }: KindFilter) => ({\n id: `kind-${slug(kind)}`,\n kind,\n label,\n items: this.visible()\n .filter((item: Declaration) => item.type === kind)\n .sort(byName),\n }))\n .filter((group: Group) => group.items.length);\n });\n\n protected readonly loaded = computed(() => this.apiList.hasValue());\n protected readonly failed = computed(() => this.apiList.status() === 'error');\n\n constructor() {\n this.route.queryParamMap.pipe(takeUntilDestroyed()).subscribe((params: ParamMap) => {\n const filter = params.get('filter') ?? '';\n\n if (untracked(this.model).filter !== filter) {\n this.model.set({ filter });\n }\n this.kind.set(params.get('type') ?? '');\n this.scope.set(params.get('scope') ?? '');\n this.groupBy.set(params.get('group') === 'scope' ? 'scope' : 'kind');\n });\n\n // Writes the state back to the query parameters. It navigates only when they differ, so the\n // navigation it causes does not run it again.\n effect(() => {\n const wanted: Params = {\n filter: this.model().filter || null,\n type: this.kind() || null,\n scope: this.scope() || null,\n group: this.groupBy() === 'scope' ? 'scope' : null,\n };\n\n untracked(() => {\n const current = this.route.snapshot.queryParamMap;\n const changed = Object.keys(wanted).some(\n (key: string) => (current.get(key) ?? null) !== wanted[key],\n );\n\n if (changed) {\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: wanted,\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n }\n });\n });\n\n // The search palette reuses the list this page loaded instead of requesting it again.\n const apiLists = inject(NgDocApiListIndexService);\n\n effect(() => {\n if (this.apiList.hasValue()) {\n const list = this.apiList.value();\n const segment = this.segment() ?? '';\n\n untracked(() => apiLists.remember(segment, list ?? []));\n }\n });\n\n const removeShortcut = this.shortcuts.register({\n key: 'f',\n handler: () => this.filterInput()?.nativeElement.focus(),\n });\n\n inject(DestroyRef).onDestroy(removeShortcut);\n }\n\n /**\n * Shows only the declarations of a kind, or of every kind.\n * @param kind - The kind, or an empty string for every kind.\n */\n protected selectKind(kind: string): void {\n this.kind.set(kind);\n }\n\n /**\n * Groups the declarations by kind or by scope.\n * @param groupBy - The grouping.\n */\n protected selectGroupBy(groupBy: GroupBy): void {\n this.groupBy.set(groupBy);\n }\n\n /** Shows the declarations of every scope. */\n protected clearScope(): void {\n this.scope.set('');\n }\n}\n\n/**\n * An id fragment for a kind or a scope.\n * @param value - The kind or the scope.\n */\nfunction slug(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n}\n","<h1 class=\"ng-doc-api-list-title\">{{ title() }}</h1>\n@if (loaded()) {\n <p class=\"ng-doc-api-list-lead\">\n {{ declarations().length }} declarations in {{ scopes().length }}\n {{ scopes().length === 1 ? 'scope' : 'scopes' }}.\n </p>\n}\n\n<div class=\"ng-doc-api-list-tools\">\n <label class=\"ng-doc-api-list-filter\">\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=\"M3 5h18l-7 8.5V19l-4 2v-7.5z\" />\n </svg>\n <input\n #filterInput\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"hasDescriptions() ? 'Filter by name or description' : 'Filter by name'\"\n [attr.aria-label]=\"\n hasDescriptions()\n ? 'Filter declarations by name or description'\n : 'Filter declarations by name'\n \"\n [attr.aria-keyshortcuts]=\"shortcuts.enabled() ? 'F' : null\"\n [formField]=\"filterForm.filter\" />\n @if (shortcuts.enabled()) {\n <kbd class=\"ng-doc-api-list-kbd\">F</kbd>\n }\n </label>\n <div class=\"ng-doc-api-list-group-by\">\n <span id=\"ng-doc-api-list-group-by\">Group by</span>\n <div\n class=\"ng-doc-api-list-segments\"\n role=\"group\"\n aria-labelledby=\"ng-doc-api-list-group-by\"\n ngDocSelectionHost>\n <ng-doc-selection [align]=\"null\" />\n <button\n type=\"button\"\n [attr.aria-pressed]=\"groupBy() === 'kind'\"\n [ngDocSelectionOrigin]=\"groupBy() === 'kind'\"\n (click)=\"selectGroupBy('kind')\">\n Kind\n </button>\n <button\n type=\"button\"\n [attr.aria-pressed]=\"groupBy() === 'scope'\"\n [ngDocSelectionOrigin]=\"groupBy() === 'scope'\"\n (click)=\"selectGroupBy('scope')\">\n Scope\n </button>\n </div>\n </div>\n</div>\n\n@if (kinds().length) {\n <div class=\"ng-doc-api-list-kinds\" role=\"group\" aria-label=\"Filter by kind\">\n <button type=\"button\" [attr.aria-pressed]=\"!kind()\" (click)=\"selectKind('')\">\n All <span class=\"ng-doc-api-list-count\">{{ inScope().length }}</span>\n </button>\n @for (item of kinds(); track item.kind) {\n <button\n type=\"button\"\n [attr.data-ng-doc-kind]=\"item.kind\"\n [attr.aria-pressed]=\"kind() === item.kind\"\n (click)=\"selectKind(item.kind)\">\n <span class=\"ng-doc-api-list-dot\" [attr.data-ng-doc-kind]=\"item.kind\"></span>\n {{ item.label }}\n <span class=\"ng-doc-api-list-count\">{{ item.count }}</span>\n </button>\n }\n </div>\n}\n\n@if (scope()) {\n <p class=\"ng-doc-api-list-scope-note\">\n Showing {{ scope() }} only.\n <button type=\"button\" (click)=\"clearScope()\">Show every scope</button>\n </p>\n}\n\n@for (group of groups(); track group.id) {\n <section class=\"ng-doc-api-list-group\" [id]=\"group.id\">\n <h2 class=\"ng-doc-api-list-group-title\">\n @if (group.kind) {\n <ng-doc-kind-icon [kind]=\"group.kind\" size=\"medium\"></ng-doc-kind-icon>\n } @else {\n {{ group.label }}\n }\n <span class=\"ng-doc-api-list-count\">{{ group.items.length }}</span>\n </h2>\n <ul class=\"ng-doc-api-list-index\" [class.ng-doc-api-list-described]=\"hasDescriptions()\">\n @for (item of group.items; track item.route) {\n <li>\n <a [routerLink]=\"item.route\">\n <span class=\"ng-doc-api-list-name\">{{ item.name }}</span>\n @if (hasDescriptions()) {\n @if (item.description) {\n <span class=\"ng-doc-api-list-description\" [title]=\"item.description\">{{\n item.description\n }}</span>\n } @else {\n <span class=\"ng-doc-api-list-description ng-doc-api-list-none\">No description</span>\n }\n }\n @if (group.kind) {\n <span class=\"ng-doc-api-list-scope\">{{ item.scope }}</span>\n } @else {\n <ng-doc-kind-icon class=\"ng-doc-api-list-scope\" [kind]=\"item.type\"></ng-doc-kind-icon>\n }\n </a>\n </li>\n }\n </ul>\n </section>\n} @empty {\n @if (loaded()) {\n <p class=\"ng-doc-api-list-empty\">No declarations match.</p>\n } @else if (failed()) {\n <p class=\"ng-doc-api-list-empty\">The API list could not be loaded.</p>\n }\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-api-list.mjs","sources":["../../../../libs/app/components/api-list/api-list.component.ts","../../../../libs/app/components/api-list/api-list.component.html","../../../../libs/app/components/api-list/ng-doc-app-components-api-list.ts"],"sourcesContent":["import { httpResource } from '@angular/common/http';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n input,\n Signal,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { form, FormField } from '@angular/forms/signals';\nimport { ActivatedRoute, ParamMap, Params, Router, RouterLink } from '@angular/router';\nimport { NgDocKindIconComponent, ngDocKindLabel } from '@ng-doc/app/components/kind-icon';\nimport type { NgDocApiListTexts } from '@ng-doc/app/interfaces';\nimport { NgDocApiListIndexService } from '@ng-doc/app/services';\nimport { NgDocShortcutsService } from '@ng-doc/app/services/shortcuts';\nimport { NG_DOC_TEXTS } from '@ng-doc/app/tokens';\nimport { asArray } from '@ng-doc/core/helpers/as-array';\nimport type { NgDocApiList, NgDocApiListItem } from '@ng-doc/core/interfaces';\nimport {\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n NgDocSelectionOriginDirective,\n} from '@ng-doc/ui-kit/components/selection';\nimport { NG_REQUEST_BASE_PATH } from '@ng-doc/ui-kit/tokens';\n\n/**\n * Orders kinds and names in English whatever the locale: `localeCompare` without a locale follows\n * the process locale, so a prerendered index would depend on the machine that built it, and the\n * browser would order a hydrated index differently from its prerendered HTML.\n */\nconst NAME_ORDER = new Intl.Collator('en');\n\n/** How the API index groups declarations. */\ntype GroupBy = 'kind' | 'scope';\n\n/**\n * A declaration of the API list. The generated list may carry a one-line description; the index\n * filters by it and shows it when it is present.\n */\ninterface Declaration extends NgDocApiListItem {\n description?: string;\n scope: string;\n}\n\ninterface Group {\n id: string;\n kind?: string;\n label: string;\n items: Declaration[];\n}\n\ninterface KindFilter {\n kind: string;\n label: string;\n count: number;\n}\n\n/**\n * The index of API declarations: a filter that matches names and descriptions, grouping by kind\n * or by scope, and a kind filter with counts. The filter, kind, scope and grouping are kept in\n * the query parameters (filter, type, scope and group), so a filtered index can be linked.\n */\n@Component({\n selector: 'ng-doc-api-list',\n templateUrl: './api-list.component.html',\n styleUrls: ['./api-list.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n FormField,\n NgDocKindIconComponent,\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n NgDocSelectionOriginDirective,\n RouterLink,\n ],\n})\nexport class NgDocApiListComponent {\n protected readonly texts: NgDocApiListTexts = inject(NG_DOC_TEXTS).apiList;\n\n /** The title of the page. Defaults to the `apiList.title` text. */\n readonly title = input<string>(this.texts.title);\n /** The segment of the API list data, when the site has more than one API list. */\n readonly segment = input<string>();\n\n protected readonly shortcuts = inject(NgDocShortcutsService);\n protected readonly model = signal({ filter: '' });\n protected readonly filterForm = form(this.model);\n protected readonly kind = signal('');\n protected readonly scope = signal('');\n protected readonly groupBy = signal<GroupBy>('kind');\n\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n private readonly basePath = inject(NG_REQUEST_BASE_PATH);\n private readonly filterInput = viewChild<ElementRef<HTMLInputElement>>('filterInput');\n\n private readonly apiList = httpResource<NgDocApiList[]>(\n () => this.basePath + asArray('assets/ng-doc', this.segment(), 'api-list.json').join('/'),\n );\n\n protected readonly declarations: Signal<Declaration[]> = computed(() =>\n this.apiList.hasValue()\n ? (this.apiList.value() ?? []).flatMap((scope: NgDocApiList) =>\n scope.items.map((item: NgDocApiListItem) => ({ ...item, scope: scope.title })),\n )\n : [],\n );\n\n protected readonly scopes = computed(() =>\n [...new Set(this.declarations().map(({ scope }: Declaration) => scope))].sort(),\n );\n\n protected readonly hasDescriptions = computed(() =>\n this.declarations().some(({ description }: Declaration) => !!description),\n );\n\n /** Declarations in the selected scope, before the text and kind filters. */\n protected readonly inScope = computed(() =>\n this.declarations().filter(({ scope }: Declaration) => !this.scope() || scope === this.scope()),\n );\n\n protected readonly kinds: Signal<KindFilter[]> = computed(() => {\n const counts = new Map<string, number>();\n\n for (const { type } of this.inScope()) {\n counts.set(type, (counts.get(type) ?? 0) + 1);\n }\n\n return [...counts]\n .map(([kind, count]: [string, number]) => ({ kind, label: ngDocKindLabel(kind), count }))\n .sort((a: KindFilter, b: KindFilter) => NAME_ORDER.compare(a.label, b.label));\n });\n\n protected readonly visible = computed(() => {\n const needle = this.model().filter.trim().toLowerCase();\n const kind = this.kind();\n\n return this.inScope().filter(\n (item: Declaration) =>\n (!kind || item.type === kind) &&\n (!needle ||\n item.name.toLowerCase().includes(needle) ||\n !!item.description?.toLowerCase().includes(needle)),\n );\n });\n\n protected readonly groups: Signal<Group[]> = computed(() => {\n const byName = (a: Declaration, b: Declaration) => NAME_ORDER.compare(a.name, b.name);\n\n if (this.groupBy() === 'scope') {\n return this.scopes()\n .map((scope: string) => ({\n id: `scope-${slug(scope)}`,\n label: scope,\n items: this.visible()\n .filter((item: Declaration) => item.scope === scope)\n .sort(\n (a: Declaration, b: Declaration) =>\n NAME_ORDER.compare(ngDocKindLabel(a.type), ngDocKindLabel(b.type)) || byName(a, b),\n ),\n }))\n .filter((group: Group) => group.items.length);\n }\n\n return this.kinds()\n .map(({ kind, label }: KindFilter) => ({\n id: `kind-${slug(kind)}`,\n kind,\n label,\n items: this.visible()\n .filter((item: Declaration) => item.type === kind)\n .sort(byName),\n }))\n .filter((group: Group) => group.items.length);\n });\n\n protected readonly loaded = computed(() => this.apiList.hasValue());\n protected readonly failed = computed(() => this.apiList.status() === 'error');\n\n constructor() {\n this.route.queryParamMap.pipe(takeUntilDestroyed()).subscribe((params: ParamMap) => {\n const filter = params.get('filter') ?? '';\n\n if (untracked(this.model).filter !== filter) {\n this.model.set({ filter });\n }\n this.kind.set(params.get('type') ?? '');\n this.scope.set(params.get('scope') ?? '');\n this.groupBy.set(params.get('group') === 'scope' ? 'scope' : 'kind');\n });\n\n // Writes the state back to the query parameters. It navigates only when they differ, so the\n // navigation it causes does not run it again.\n effect(() => {\n const wanted: Params = {\n filter: this.model().filter || null,\n type: this.kind() || null,\n scope: this.scope() || null,\n group: this.groupBy() === 'scope' ? 'scope' : null,\n };\n\n untracked(() => {\n const current = this.route.snapshot.queryParamMap;\n const changed = Object.keys(wanted).some(\n (key: string) => (current.get(key) ?? null) !== wanted[key],\n );\n\n if (changed) {\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: wanted,\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n }\n });\n });\n\n // The search palette reuses the list this page loaded instead of requesting it again.\n const apiLists = inject(NgDocApiListIndexService);\n\n effect(() => {\n if (this.apiList.hasValue()) {\n const list = this.apiList.value();\n const segment = this.segment() ?? '';\n\n untracked(() => apiLists.remember(segment, list ?? []));\n }\n });\n\n const removeShortcut = this.shortcuts.register({\n key: 'f',\n handler: () => this.filterInput()?.nativeElement.focus(),\n });\n\n inject(DestroyRef).onDestroy(removeShortcut);\n }\n\n /**\n * Shows only the declarations of a kind, or of every kind.\n * @param kind - The kind, or an empty string for every kind.\n */\n protected selectKind(kind: string): void {\n this.kind.set(kind);\n }\n\n /**\n * Groups the declarations by kind or by scope.\n * @param groupBy - The grouping.\n */\n protected selectGroupBy(groupBy: GroupBy): void {\n this.groupBy.set(groupBy);\n }\n\n /** Shows the declarations of every scope. */\n protected clearScope(): void {\n this.scope.set('');\n }\n}\n\n/**\n * An id fragment for a kind or a scope.\n * @param value - The kind or the scope.\n */\nfunction slug(value: string): string {\n return value\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n}\n","<h1 class=\"ng-doc-api-list-title\">{{ title() }}</h1>\n@if (loaded()) {\n <p class=\"ng-doc-api-list-lead\">\n {{ texts.summary({ declarations: declarations().length, scopes: scopes().length }) }}\n </p>\n}\n\n<div class=\"ng-doc-api-list-tools\">\n <label class=\"ng-doc-api-list-filter\">\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=\"M3 5h18l-7 8.5V19l-4 2v-7.5z\" />\n </svg>\n <input\n #filterInput\n type=\"text\"\n autocomplete=\"off\"\n spellcheck=\"false\"\n [placeholder]=\"\n hasDescriptions() ? texts.filterPlaceholderWithDescriptions : texts.filterPlaceholder\n \"\n [attr.aria-label]=\"hasDescriptions() ? texts.filterLabelWithDescriptions : texts.filterLabel\"\n [attr.aria-keyshortcuts]=\"shortcuts.enabled() ? 'F' : null\"\n [formField]=\"filterForm.filter\" />\n @if (shortcuts.enabled()) {\n <kbd class=\"ng-doc-api-list-kbd\">F</kbd>\n }\n </label>\n <div class=\"ng-doc-api-list-group-by\">\n <span id=\"ng-doc-api-list-group-by\">{{ texts.groupBy }}</span>\n <div\n class=\"ng-doc-api-list-segments\"\n role=\"group\"\n aria-labelledby=\"ng-doc-api-list-group-by\"\n ngDocSelectionHost>\n <ng-doc-selection [align]=\"null\" />\n <button\n type=\"button\"\n [attr.aria-pressed]=\"groupBy() === 'kind'\"\n [ngDocSelectionOrigin]=\"groupBy() === 'kind'\"\n (click)=\"selectGroupBy('kind')\">\n {{ texts.groupByKind }}\n </button>\n <button\n type=\"button\"\n [attr.aria-pressed]=\"groupBy() === 'scope'\"\n [ngDocSelectionOrigin]=\"groupBy() === 'scope'\"\n (click)=\"selectGroupBy('scope')\">\n {{ texts.groupByScope }}\n </button>\n </div>\n </div>\n</div>\n\n@if (kinds().length) {\n <div class=\"ng-doc-api-list-kinds\" role=\"group\" [attr.aria-label]=\"texts.kindsLabel\">\n <button type=\"button\" [attr.aria-pressed]=\"!kind()\" (click)=\"selectKind('')\">\n {{ texts.allKinds }} <span class=\"ng-doc-api-list-count\">{{ inScope().length }}</span>\n </button>\n @for (item of kinds(); track item.kind) {\n <button\n type=\"button\"\n [attr.data-ng-doc-kind]=\"item.kind\"\n [attr.aria-pressed]=\"kind() === item.kind\"\n (click)=\"selectKind(item.kind)\">\n <span class=\"ng-doc-api-list-dot\" [attr.data-ng-doc-kind]=\"item.kind\"></span>\n {{ item.label }}\n <span class=\"ng-doc-api-list-count\">{{ item.count }}</span>\n </button>\n }\n </div>\n}\n\n@if (scope()) {\n <p class=\"ng-doc-api-list-scope-note\">\n {{ texts.scopeNote({ scope: scope() }) }}\n <button type=\"button\" (click)=\"clearScope()\">{{ texts.showEveryScope }}</button>\n </p>\n}\n\n@for (group of groups(); track group.id) {\n <section class=\"ng-doc-api-list-group\" [id]=\"group.id\">\n <h2 class=\"ng-doc-api-list-group-title\">\n @if (group.kind) {\n <ng-doc-kind-icon [kind]=\"group.kind\" size=\"medium\"></ng-doc-kind-icon>\n } @else {\n {{ group.label }}\n }\n <span class=\"ng-doc-api-list-count\">{{ group.items.length }}</span>\n </h2>\n <ul class=\"ng-doc-api-list-index\" [class.ng-doc-api-list-described]=\"hasDescriptions()\">\n @for (item of group.items; track item.route) {\n <li>\n <a [routerLink]=\"item.route\">\n <span class=\"ng-doc-api-list-name\">{{ item.name }}</span>\n @if (hasDescriptions()) {\n @if (item.description) {\n <span class=\"ng-doc-api-list-description\" [title]=\"item.description\">{{\n item.description\n }}</span>\n } @else {\n <span class=\"ng-doc-api-list-description ng-doc-api-list-none\">{{\n texts.noDescription\n }}</span>\n }\n }\n @if (group.kind) {\n <span class=\"ng-doc-api-list-scope\">{{ item.scope }}</span>\n } @else {\n <ng-doc-kind-icon class=\"ng-doc-api-list-scope\" [kind]=\"item.type\"></ng-doc-kind-icon>\n }\n </a>\n </li>\n }\n </ul>\n </section>\n} @empty {\n @if (loaded()) {\n <p class=\"ng-doc-api-list-empty\">{{ texts.empty }}</p>\n } @else if (failed()) {\n <p class=\"ng-doc-api-list-empty\">{{ texts.failed }}</p>\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { inject, input, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { NG_DOC_TEXTS } from '@ng-doc/app/tokens';
3
4
 
4
5
  /**
5
6
  * The breadcrumbs of a page: a navigation landmark that lists the categories above the page and
@@ -7,16 +8,17 @@ import { input, ChangeDetectionStrategy, Component } from '@angular/core';
7
8
  */
8
9
  class NgDocBreadcrumbComponent {
9
10
  constructor() {
11
+ this.texts = inject(NG_DOC_TEXTS).navigation;
10
12
  /** Titles from the top category down to the page. */
11
13
  this.breadcrumbs = input([], /* @ts-ignore */
12
14
  ...(ngDevMode ? [{ debugName: "breadcrumbs" }] : /* istanbul ignore next */ []));
13
15
  }
14
16
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
15
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocBreadcrumbComponent, isStandalone: true, selector: "ng-doc-breadcrumb", inputs: { breadcrumbs: { classPropertyName: "breadcrumbs", publicName: "breadcrumbs", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<nav aria-label=\"Breadcrumb\">\n <ol class=\"ng-doc-breadcrumbs\">\n @for (item of breadcrumbs(); track $index; let last = $last) {\n <li class=\"ng-doc-breadcrumb\" [attr.aria-current]=\"last ? 'page' : null\">{{ item }}</li>\n @if (!last) {\n <li class=\"ng-doc-breadcrumb-separator\" aria-hidden=\"true\">\u203A</li>\n }\n }\n </ol>\n</nav>\n", styles: [":host{display:block;margin-bottom:var(--ng-doc-space-2);padding-right:100px}.ng-doc-breadcrumbs{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:32px;margin:0;padding:0;list-style:none;color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;line-height:18px}.ng-doc-breadcrumb{display:inline-flex;align-items:center;min-height:24px;margin:0}.ng-doc-breadcrumb-separator{margin:0;opacity:.5}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
17
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocBreadcrumbComponent, isStandalone: true, selector: "ng-doc-breadcrumb", inputs: { breadcrumbs: { classPropertyName: "breadcrumbs", publicName: "breadcrumbs", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<nav [attr.aria-label]=\"texts.breadcrumbs\">\n <ol class=\"ng-doc-breadcrumbs\">\n @for (item of breadcrumbs(); track $index; let last = $last) {\n <li class=\"ng-doc-breadcrumb\" [attr.aria-current]=\"last ? 'page' : null\">{{ item }}</li>\n @if (!last) {\n <li class=\"ng-doc-breadcrumb-separator\" aria-hidden=\"true\">\u203A</li>\n }\n }\n </ol>\n</nav>\n", styles: [":host{display:block;margin-bottom:var(--ng-doc-space-2);padding-right:100px}.ng-doc-breadcrumbs{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:32px;margin:0;padding:0;list-style:none;color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;line-height:18px}.ng-doc-breadcrumb{display:inline-flex;align-items:center;min-height:24px;margin:0}.ng-doc-breadcrumb-separator{margin:0;opacity:.5}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
16
18
  }
17
19
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocBreadcrumbComponent, decorators: [{
18
20
  type: Component,
19
- args: [{ selector: 'ng-doc-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav aria-label=\"Breadcrumb\">\n <ol class=\"ng-doc-breadcrumbs\">\n @for (item of breadcrumbs(); track $index; let last = $last) {\n <li class=\"ng-doc-breadcrumb\" [attr.aria-current]=\"last ? 'page' : null\">{{ item }}</li>\n @if (!last) {\n <li class=\"ng-doc-breadcrumb-separator\" aria-hidden=\"true\">\u203A</li>\n }\n }\n </ol>\n</nav>\n", styles: [":host{display:block;margin-bottom:var(--ng-doc-space-2);padding-right:100px}.ng-doc-breadcrumbs{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:32px;margin:0;padding:0;list-style:none;color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;line-height:18px}.ng-doc-breadcrumb{display:inline-flex;align-items:center;min-height:24px;margin:0}.ng-doc-breadcrumb-separator{margin:0;opacity:.5}\n"] }]
21
+ args: [{ selector: 'ng-doc-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav [attr.aria-label]=\"texts.breadcrumbs\">\n <ol class=\"ng-doc-breadcrumbs\">\n @for (item of breadcrumbs(); track $index; let last = $last) {\n <li class=\"ng-doc-breadcrumb\" [attr.aria-current]=\"last ? 'page' : null\">{{ item }}</li>\n @if (!last) {\n <li class=\"ng-doc-breadcrumb-separator\" aria-hidden=\"true\">\u203A</li>\n }\n }\n </ol>\n</nav>\n", styles: [":host{display:block;margin-bottom:var(--ng-doc-space-2);padding-right:100px}.ng-doc-breadcrumbs{display:flex;flex-wrap:wrap;align-items:center;gap:6px;min-height:32px;margin:0;padding:0;list-style:none;color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;line-height:18px}.ng-doc-breadcrumb{display:inline-flex;align-items:center;min-height:24px;margin:0}.ng-doc-breadcrumb-separator{margin:0;opacity:.5}\n"] }]
20
22
  }], propDecorators: { breadcrumbs: [{ type: i0.Input, args: [{ isSignal: true, alias: "breadcrumbs", required: false }] }] } });
21
23
 
22
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-breadcrumb.mjs","sources":["../../../../libs/app/components/breadcrumb/breadcrumb.component.ts","../../../../libs/app/components/breadcrumb/breadcrumb.component.html","../../../../libs/app/components/breadcrumb/ng-doc-app-components-breadcrumb.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, input } from '@angular/core';\nimport { NgDocPageBreadcrumbs } from '@ng-doc/app/interfaces';\n\n/**\n * The breadcrumbs of a page: a navigation landmark that lists the categories above the page and\n * marks the page itself as the current one.\n */\n@Component({\n selector: 'ng-doc-breadcrumb',\n templateUrl: './breadcrumb.component.html',\n styleUrls: ['./breadcrumb.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocBreadcrumbComponent implements NgDocPageBreadcrumbs {\n /** Titles from the top category down to the page. */\n readonly breadcrumbs = input<string[]>([]);\n}\n","<nav aria-label=\"Breadcrumb\">\n <ol class=\"ng-doc-breadcrumbs\">\n @for (item of breadcrumbs(); track $index; let last = $last) {\n <li class=\"ng-doc-breadcrumb\" [attr.aria-current]=\"last ? 'page' : null\">{{ item }}</li>\n @if (!last) {\n <li class=\"ng-doc-breadcrumb-separator\" aria-hidden=\"true\">›</li>\n }\n }\n </ol>\n</nav>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;AAGA;;;AAGG;MAOU,wBAAwB,CAAA;AANrC,IAAA,WAAA,GAAA;;QAQW,IAAA,CAAA,WAAW,GAAG,KAAK,CAAW,EAAE;wFAAC;AAC3C,IAAA;8GAHY,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAxB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,wBAAwB,mOCbrC,0XAUA,EAAA,MAAA,EAAA,CAAA,ubAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FDGa,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBANpC,SAAS;+BACE,mBAAmB,EAAA,eAAA,EAGZ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,0XAAA,EAAA,MAAA,EAAA,CAAA,ubAAA,CAAA,EAAA;;;AEXjD;;AAEG;;;;"}
1
+ {"version":3,"file":"ng-doc-app-components-breadcrumb.mjs","sources":["../../../../libs/app/components/breadcrumb/breadcrumb.component.ts","../../../../libs/app/components/breadcrumb/breadcrumb.component.html","../../../../libs/app/components/breadcrumb/ng-doc-app-components-breadcrumb.ts"],"sourcesContent":["import { ChangeDetectionStrategy, Component, inject, input } from '@angular/core';\nimport { NgDocNavigationTexts, NgDocPageBreadcrumbs } from '@ng-doc/app/interfaces';\nimport { NG_DOC_TEXTS } from '@ng-doc/app/tokens';\n\n/**\n * The breadcrumbs of a page: a navigation landmark that lists the categories above the page and\n * marks the page itself as the current one.\n */\n@Component({\n selector: 'ng-doc-breadcrumb',\n templateUrl: './breadcrumb.component.html',\n styleUrls: ['./breadcrumb.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocBreadcrumbComponent implements NgDocPageBreadcrumbs {\n protected readonly texts: NgDocNavigationTexts = inject(NG_DOC_TEXTS).navigation;\n\n /** Titles from the top category down to the page. */\n readonly breadcrumbs = input<string[]>([]);\n}\n","<nav [attr.aria-label]=\"texts.breadcrumbs\">\n <ol class=\"ng-doc-breadcrumbs\">\n @for (item of breadcrumbs(); track $index; let last = $last) {\n <li class=\"ng-doc-breadcrumb\" [attr.aria-current]=\"last ? 'page' : null\">{{ item }}</li>\n @if (!last) {\n <li class=\"ng-doc-breadcrumb-separator\" aria-hidden=\"true\">›</li>\n }\n }\n </ol>\n</nav>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAIA;;;AAGG;MAOU,wBAAwB,CAAA;AANrC,IAAA,WAAA,GAAA;AAOqB,QAAA,IAAA,CAAA,KAAK,GAAyB,MAAM,CAAC,YAAY,CAAC,CAAC,UAAU;;QAGvE,IAAA,CAAA,WAAW,GAAG,KAAK,CAAW,EAAE;wFAAC;AAC3C,IAAA;8GALY,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAxB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,wBAAwB,mOCdrC,wYAUA,EAAA,MAAA,EAAA,CAAA,ubAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FDIa,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBANpC,SAAS;+BACE,mBAAmB,EAAA,eAAA,EAGZ,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,wYAAA,EAAA,MAAA,EAAA,CAAA,ubAAA,CAAA,EAAA;;;AEZjD;;AAEG;;;;"}
@@ -5,7 +5,7 @@ import { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';
5
5
  import { NgDocPageProcessorComponent } from '@ng-doc/app/processors/page-processor';
6
6
  import { linkProcessor } from '@ng-doc/app/processors/processors/link';
7
7
  import { tooltipProcessor } from '@ng-doc/app/processors/processors/tooltip';
8
- import { provideMainPageProcessor } from '@ng-doc/app/tokens';
8
+ import { NG_DOC_TEXTS, provideMainPageProcessor } from '@ng-doc/app/tokens';
9
9
  import { NgDocIconComponent } from '@ng-doc/ui-kit';
10
10
 
11
11
  /** Display names of common language ids; other ids are shown capitalized. */
@@ -48,6 +48,7 @@ const PLAIN_LANGUAGES = new Set(['', 'text', 'txt', 'plain', 'plaintext']);
48
48
  */
49
49
  class NgDocCodeComponent {
50
50
  constructor() {
51
+ this.texts = inject(NG_DOC_TEXTS).content;
51
52
  this.elementRef = inject(ElementRef);
52
53
  /** Highlighted HTML of the code. When empty, the projected content is shown instead. */
53
54
  this.html = input('', /* @ts-ignore */
@@ -86,7 +87,7 @@ class NgDocCodeComponent {
86
87
  }, /* @ts-ignore */
87
88
  ...(ngDevMode ? [{ debugName: "language" }] : /* istanbul ignore next */ []));
88
89
  /** The highlighted lines as text, for example "Lines 6–7" or "Lines 2, 5–6". */
89
- this.range = computed(() => describeLines(this.rendered().highlightedLines), /* @ts-ignore */
90
+ this.range = computed(() => describeLines(this.rendered().highlightedLines, this.texts), /* @ts-ignore */
90
91
  ...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
91
92
  /** Reads the text of the rendered code when the copy button is pressed. */
92
93
  this.text = () => this.codeElement()?.textContent ?? '';
@@ -153,9 +154,10 @@ function readProjectedCode(code) {
153
154
  /**
154
155
  * Describes line numbers as ranges.
155
156
  * @param lines - Ascending one-based line numbers.
157
+ * @param texts - The texts of the page content, whose `codeLines` words the ranges.
156
158
  * @returns "Line 3", "Lines 6–7" or "Lines 2, 5–6"; an empty string for no lines.
157
159
  */
158
- function describeLines(lines) {
160
+ function describeLines(lines, texts) {
159
161
  const ranges = [];
160
162
  for (const line of lines) {
161
163
  const last = ranges[ranges.length - 1];
@@ -169,7 +171,7 @@ function describeLines(lines) {
169
171
  const text = ranges
170
172
  .map(([start, end]) => (start === end ? `${start}` : `${start}–${end}`))
171
173
  .join(', ');
172
- return text ? `${lines.length === 1 ? 'Line' : 'Lines'} ${text}` : '';
174
+ return text ? texts.codeLines({ count: lines.length, ranges: text }) : '';
173
175
  }
174
176
 
175
177
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-code.mjs","sources":["../../../../libs/app/components/code/code.component.ts","../../../../libs/app/components/code/code.component.html","../../../../libs/app/components/code/ng-doc-app-components-code.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors/page-processor';\nimport { linkProcessor } from '@ng-doc/app/processors/processors/link';\nimport { tooltipProcessor } from '@ng-doc/app/processors/processors/tooltip';\nimport { provideMainPageProcessor } from '@ng-doc/app/tokens';\nimport { NgDocIconComponent } from '@ng-doc/ui-kit';\n\n/** Display names of common language ids; other ids are shown capitalized. */\nconst LANGUAGE_LABELS: Record<string, string> = {\n 'angular-html': 'HTML',\n 'angular-ts': 'TypeScript',\n bash: 'Shell',\n css: 'CSS',\n diff: 'Diff',\n html: 'HTML',\n javascript: 'JavaScript',\n js: 'JavaScript',\n json: 'JSON',\n jsonc: 'JSON',\n jsx: 'JSX',\n less: 'Less',\n markdown: 'Markdown',\n md: 'Markdown',\n mermaid: 'Mermaid',\n nunjucks: 'Nunjucks',\n sass: 'Sass',\n scss: 'SCSS',\n sh: 'Shell',\n shell: 'Shell',\n ts: 'TypeScript',\n tsx: 'TSX',\n typescript: 'TypeScript',\n xml: 'XML',\n yaml: 'YAML',\n yml: 'YAML',\n};\n\n/** Language ids of plain text, which get no language chip. */\nconst PLAIN_LANGUAGES: ReadonlySet<string> = new Set(['', 'text', 'txt', 'plain', 'plaintext']);\n\n/** What the component reads back from the rendered code. */\ninterface NgDocRenderedCode {\n /** Language id from the `language-*` class of the `code` element. */\n language: string;\n /** One-based numbers of the highlighted lines. */\n highlightedLines: number[];\n}\n\n/**\n * Renders a code block: a header with the file name, the language and the highlighted lines\n * (shown when the block has a name or an icon), line numbers and a copy button.\n *\n * Line numbers are CSS counters, so they are neither copied nor announced. Setting the\n * `code-line-numbers` theme variable to `none` hides them.\n */\n@Component({\n selector: 'ng-doc-code',\n templateUrl: './code.component.html',\n styleUrls: ['./code.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocIconComponent,\n NgDocPageProcessorComponent,\n NgDocCopyButtonComponent,\n NgDocSanitizeHtmlPipe,\n ],\n viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])],\n host: {\n '[attr.data-ng-doc-has-header]': 'hasHeader()',\n },\n})\nexport class NgDocCodeComponent implements AfterViewInit {\n private readonly elementRef: ElementRef<HTMLElement> = inject(ElementRef);\n\n /** Highlighted HTML of the code. When empty, the projected content is shown instead. */\n readonly html = input<string>('');\n\n /** Whether the copy button is shown. */\n readonly copyButton = input<boolean>(true);\n\n /** File name shown in the header. */\n readonly name = input<string | undefined>(undefined);\n\n /** Name of a custom icon shown before the file name. */\n readonly icon = input<string | undefined>(undefined);\n\n /** Whether the header bar is shown: a block with a file name or an icon has one. */\n readonly hasHeader: Signal<boolean> = computed(() => !!this.name() || !!this.icon());\n\n /** Language and highlighted lines of projected code, read from the DOM. */\n private readonly projected = signal<NgDocRenderedCode>({ language: '', highlightedLines: [] });\n\n /**\n * Language and highlighted lines of the code. Highlighted HTML is parsed as a string, so the\n * header is complete in server-rendered and prerendered pages; projected code is read from its\n * DOM, which the server renderer provides too.\n */\n private readonly rendered: Signal<NgDocRenderedCode> = computed(() => {\n const html: string = this.html();\n\n return html ? parseHighlightedCode(html) : this.projected();\n });\n\n /** Display name of the language; empty for plain text. */\n protected readonly language: Signal<string> = computed(() => {\n const id: string = this.rendered().language.toLowerCase();\n\n return PLAIN_LANGUAGES.has(id)\n ? ''\n : LANGUAGE_LABELS[id] ?? id.charAt(0).toUpperCase() + id.slice(1);\n });\n\n /** The highlighted lines as text, for example \"Lines 6–7\" or \"Lines 2, 5–6\". */\n protected readonly range: Signal<string> = computed(() =>\n describeLines(this.rendered().highlightedLines),\n );\n\n /** Reads the text of the rendered code when the copy button is pressed. */\n protected readonly text = (): string => this.codeElement()?.textContent ?? '';\n\n /**\n * Reads projected code once the view has rendered it. The page's code is projected inside a\n * control-flow block, so it is in place only after the first render; this hook also runs on the\n * server, so prerendered pages get the language and the highlighted lines. The page processor\n * relies on that late projection: it replaces the page's `pre` with this component after\n * creating it.\n */\n ngAfterViewInit(): void {\n if (!untracked(this.html)) {\n this.projected.set(readProjectedCode(this.codeElement()));\n }\n }\n\n private codeElement(): HTMLElement | null {\n return this.elementRef.nativeElement.querySelector('pre code');\n }\n}\n\n/**\n * Reads the language and the highlighted lines of highlighted code HTML.\n * @param html - Highlighted HTML: a `pre > code.language-*` with one `span.line` per line.\n */\nfunction parseHighlightedCode(html: string): NgDocRenderedCode {\n const language: string = /<code\\b[^>]*\\bclass=\"[^\"]*\\blanguage-([\\w+#-]+)/.exec(html)?.[1] ?? '';\n const highlightedLines: number[] = [];\n let line: number = 0;\n\n for (const match of html.matchAll(/<span\\b[^>]*\\bclass=\"(line(?:\\s[^\"]*)?)\"/g)) {\n line++;\n\n if (/\\bhighlighted\\b/.test(match[1])) {\n highlightedLines.push(line);\n }\n }\n\n return { language, highlightedLines };\n}\n\n/**\n * Reads the language and the highlighted lines of a rendered `code` element.\n * @param code - The `code` element, if any.\n */\nfunction readProjectedCode(code: HTMLElement | null): NgDocRenderedCode {\n return {\n language:\n Array.from(code?.classList ?? [])\n .find((name: string) => name.startsWith('language-'))\n ?.slice('language-'.length) ?? '',\n highlightedLines: Array.from(code?.querySelectorAll('.line') ?? [])\n .map((line: Element, index: number) =>\n line.classList.contains('highlighted') ? index + 1 : 0,\n )\n .filter(Boolean),\n };\n}\n\n/**\n * Describes line numbers as ranges.\n * @param lines - Ascending one-based line numbers.\n * @returns \"Line 3\", \"Lines 6–7\" or \"Lines 2, 5–6\"; an empty string for no lines.\n */\nfunction describeLines(lines: number[]): string {\n const ranges: Array<[number, number]> = [];\n\n for (const line of lines) {\n const last: [number, number] | undefined = ranges[ranges.length - 1];\n\n if (last && line === last[1] + 1) {\n last[1] = line;\n } else {\n ranges.push([line, line]);\n }\n }\n\n const text: string = ranges\n .map(([start, end]: [number, number]) => (start === end ? `${start}` : `${start}–${end}`))\n .join(', ');\n\n return text ? `${lines.length === 1 ? 'Line' : 'Lines'} ${text}` : '';\n}\n","@if (hasHeader()) {\n <div class=\"ng-doc-code-header\">\n <span class=\"ng-doc-code-file-name\">\n @if (icon(); as icon) {\n <ng-doc-icon [customIcon]=\"icon\"></ng-doc-icon>\n }\n <span class=\"ng-doc-code-file-name-text\">{{ name() }}</span>\n </span>\n @if (language(); as language) {\n <span class=\"ng-doc-code-language\">{{ language }}</span>\n }\n <span class=\"ng-doc-code-header-spacer\"></span>\n @if (range(); as range) {\n <span class=\"ng-doc-code-range\">{{ range }}</span>\n }\n @if (copyButton()) {\n <ng-doc-copy-button class=\"ng-doc-code-header-copy\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n </div>\n}\n<div class=\"ng-doc-code-body\">\n @if (html()) {\n <div class=\"ng-doc-code-wrapper\" [ngDocPageProcessor]=\"html() | ngDocSanitizeHtml\"></div>\n } @else {\n <div class=\"ng-doc-code-wrapper\">\n <ng-content></ng-content>\n </div>\n }\n\n @if (copyButton() && !hasHeader()) {\n <ng-doc-copy-button class=\"ng-doc-copy-button\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-code.mjs","sources":["../../../../libs/app/components/code/code.component.ts","../../../../libs/app/components/code/code.component.html","../../../../libs/app/components/code/ng-doc-app-components-code.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport type { NgDocContentTexts } from '@ng-doc/app/interfaces';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors/page-processor';\nimport { linkProcessor } from '@ng-doc/app/processors/processors/link';\nimport { tooltipProcessor } from '@ng-doc/app/processors/processors/tooltip';\nimport { NG_DOC_TEXTS, provideMainPageProcessor } from '@ng-doc/app/tokens';\nimport { NgDocIconComponent } from '@ng-doc/ui-kit';\n\n/** Display names of common language ids; other ids are shown capitalized. */\nconst LANGUAGE_LABELS: Record<string, string> = {\n 'angular-html': 'HTML',\n 'angular-ts': 'TypeScript',\n bash: 'Shell',\n css: 'CSS',\n diff: 'Diff',\n html: 'HTML',\n javascript: 'JavaScript',\n js: 'JavaScript',\n json: 'JSON',\n jsonc: 'JSON',\n jsx: 'JSX',\n less: 'Less',\n markdown: 'Markdown',\n md: 'Markdown',\n mermaid: 'Mermaid',\n nunjucks: 'Nunjucks',\n sass: 'Sass',\n scss: 'SCSS',\n sh: 'Shell',\n shell: 'Shell',\n ts: 'TypeScript',\n tsx: 'TSX',\n typescript: 'TypeScript',\n xml: 'XML',\n yaml: 'YAML',\n yml: 'YAML',\n};\n\n/** Language ids of plain text, which get no language chip. */\nconst PLAIN_LANGUAGES: ReadonlySet<string> = new Set(['', 'text', 'txt', 'plain', 'plaintext']);\n\n/** What the component reads back from the rendered code. */\ninterface NgDocRenderedCode {\n /** Language id from the `language-*` class of the `code` element. */\n language: string;\n /** One-based numbers of the highlighted lines. */\n highlightedLines: number[];\n}\n\n/**\n * Renders a code block: a header with the file name, the language and the highlighted lines\n * (shown when the block has a name or an icon), line numbers and a copy button.\n *\n * Line numbers are CSS counters, so they are neither copied nor announced. Setting the\n * `code-line-numbers` theme variable to `none` hides them.\n */\n@Component({\n selector: 'ng-doc-code',\n templateUrl: './code.component.html',\n styleUrls: ['./code.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocIconComponent,\n NgDocPageProcessorComponent,\n NgDocCopyButtonComponent,\n NgDocSanitizeHtmlPipe,\n ],\n viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])],\n host: {\n '[attr.data-ng-doc-has-header]': 'hasHeader()',\n },\n})\nexport class NgDocCodeComponent implements AfterViewInit {\n protected readonly texts: NgDocContentTexts = inject(NG_DOC_TEXTS).content;\n\n private readonly elementRef: ElementRef<HTMLElement> = inject(ElementRef);\n\n /** Highlighted HTML of the code. When empty, the projected content is shown instead. */\n readonly html = input<string>('');\n\n /** Whether the copy button is shown. */\n readonly copyButton = input<boolean>(true);\n\n /** File name shown in the header. */\n readonly name = input<string | undefined>(undefined);\n\n /** Name of a custom icon shown before the file name. */\n readonly icon = input<string | undefined>(undefined);\n\n /** Whether the header bar is shown: a block with a file name or an icon has one. */\n readonly hasHeader: Signal<boolean> = computed(() => !!this.name() || !!this.icon());\n\n /** Language and highlighted lines of projected code, read from the DOM. */\n private readonly projected = signal<NgDocRenderedCode>({ language: '', highlightedLines: [] });\n\n /**\n * Language and highlighted lines of the code. Highlighted HTML is parsed as a string, so the\n * header is complete in server-rendered and prerendered pages; projected code is read from its\n * DOM, which the server renderer provides too.\n */\n private readonly rendered: Signal<NgDocRenderedCode> = computed(() => {\n const html: string = this.html();\n\n return html ? parseHighlightedCode(html) : this.projected();\n });\n\n /** Display name of the language; empty for plain text. */\n protected readonly language: Signal<string> = computed(() => {\n const id: string = this.rendered().language.toLowerCase();\n\n return PLAIN_LANGUAGES.has(id)\n ? ''\n : LANGUAGE_LABELS[id] ?? id.charAt(0).toUpperCase() + id.slice(1);\n });\n\n /** The highlighted lines as text, for example \"Lines 6–7\" or \"Lines 2, 5–6\". */\n protected readonly range: Signal<string> = computed(() =>\n describeLines(this.rendered().highlightedLines, this.texts),\n );\n\n /** Reads the text of the rendered code when the copy button is pressed. */\n protected readonly text = (): string => this.codeElement()?.textContent ?? '';\n\n /**\n * Reads projected code once the view has rendered it. The page's code is projected inside a\n * control-flow block, so it is in place only after the first render; this hook also runs on the\n * server, so prerendered pages get the language and the highlighted lines. The page processor\n * relies on that late projection: it replaces the page's `pre` with this component after\n * creating it.\n */\n ngAfterViewInit(): void {\n if (!untracked(this.html)) {\n this.projected.set(readProjectedCode(this.codeElement()));\n }\n }\n\n private codeElement(): HTMLElement | null {\n return this.elementRef.nativeElement.querySelector('pre code');\n }\n}\n\n/**\n * Reads the language and the highlighted lines of highlighted code HTML.\n * @param html - Highlighted HTML: a `pre > code.language-*` with one `span.line` per line.\n */\nfunction parseHighlightedCode(html: string): NgDocRenderedCode {\n const language: string = /<code\\b[^>]*\\bclass=\"[^\"]*\\blanguage-([\\w+#-]+)/.exec(html)?.[1] ?? '';\n const highlightedLines: number[] = [];\n let line: number = 0;\n\n for (const match of html.matchAll(/<span\\b[^>]*\\bclass=\"(line(?:\\s[^\"]*)?)\"/g)) {\n line++;\n\n if (/\\bhighlighted\\b/.test(match[1])) {\n highlightedLines.push(line);\n }\n }\n\n return { language, highlightedLines };\n}\n\n/**\n * Reads the language and the highlighted lines of a rendered `code` element.\n * @param code - The `code` element, if any.\n */\nfunction readProjectedCode(code: HTMLElement | null): NgDocRenderedCode {\n return {\n language:\n Array.from(code?.classList ?? [])\n .find((name: string) => name.startsWith('language-'))\n ?.slice('language-'.length) ?? '',\n highlightedLines: Array.from(code?.querySelectorAll('.line') ?? [])\n .map((line: Element, index: number) =>\n line.classList.contains('highlighted') ? index + 1 : 0,\n )\n .filter(Boolean),\n };\n}\n\n/**\n * Describes line numbers as ranges.\n * @param lines - Ascending one-based line numbers.\n * @param texts - The texts of the page content, whose `codeLines` words the ranges.\n * @returns \"Line 3\", \"Lines 6–7\" or \"Lines 2, 5–6\"; an empty string for no lines.\n */\nfunction describeLines(lines: number[], texts: NgDocContentTexts): string {\n const ranges: Array<[number, number]> = [];\n\n for (const line of lines) {\n const last: [number, number] | undefined = ranges[ranges.length - 1];\n\n if (last && line === last[1] + 1) {\n last[1] = line;\n } else {\n ranges.push([line, line]);\n }\n }\n\n const text: string = ranges\n .map(([start, end]: [number, number]) => (start === end ? `${start}` : `${start}–${end}`))\n .join(', ');\n\n return text ? texts.codeLines({ count: lines.length, ranges: text }) : '';\n}\n","@if (hasHeader()) {\n <div class=\"ng-doc-code-header\">\n <span class=\"ng-doc-code-file-name\">\n @if (icon(); as icon) {\n <ng-doc-icon [customIcon]=\"icon\"></ng-doc-icon>\n }\n <span class=\"ng-doc-code-file-name-text\">{{ name() }}</span>\n </span>\n @if (language(); as language) {\n <span class=\"ng-doc-code-language\">{{ language }}</span>\n }\n <span class=\"ng-doc-code-header-spacer\"></span>\n @if (range(); as range) {\n <span class=\"ng-doc-code-range\">{{ range }}</span>\n }\n @if (copyButton()) {\n <ng-doc-copy-button class=\"ng-doc-code-header-copy\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n </div>\n}\n<div class=\"ng-doc-code-body\">\n @if (html()) {\n <div class=\"ng-doc-code-wrapper\" [ngDocPageProcessor]=\"html() | ngDocSanitizeHtml\"></div>\n } @else {\n <div class=\"ng-doc-code-wrapper\">\n <ng-content></ng-content>\n </div>\n }\n\n @if (copyButton() && !hasHeader()) {\n <ng-doc-copy-button class=\"ng-doc-copy-button\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}