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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (215) hide show
  1. package/README.md +20 -29
  2. package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs +363 -0
  3. package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs.map +1 -0
  4. package/fesm2022/ng-doc-app-classes-content-controller.mjs +299 -0
  5. package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -0
  6. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +51 -35
  7. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
  8. package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
  9. package/fesm2022/ng-doc-app-classes-search-engine.mjs.map +1 -1
  10. package/fesm2022/ng-doc-app-classes.mjs +2 -0
  11. package/fesm2022/ng-doc-app-classes.mjs.map +1 -1
  12. package/fesm2022/ng-doc-app-components-api-list.mjs +173 -69
  13. package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
  14. package/fesm2022/ng-doc-app-components-breadcrumb.mjs +13 -10
  15. package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
  16. package/fesm2022/ng-doc-app-components-code.mjs +152 -25
  17. package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
  18. package/fesm2022/ng-doc-app-components-command-palette.mjs +498 -0
  19. package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -0
  20. package/fesm2022/ng-doc-app-components-copy-button.mjs +38 -21
  21. package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
  22. package/fesm2022/ng-doc-app-components-demo-displayer.mjs +36 -29
  23. package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
  24. package/fesm2022/ng-doc-app-components-demo-frame.mjs +96 -0
  25. package/fesm2022/ng-doc-app-components-demo-frame.mjs.map +1 -0
  26. package/fesm2022/ng-doc-app-components-demo-pane.mjs +39 -36
  27. package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
  28. package/fesm2022/ng-doc-app-components-demo.mjs +175 -44
  29. package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
  30. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +12 -9
  31. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
  32. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +79 -0
  33. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -0
  34. package/fesm2022/ng-doc-app-components-heading-anchor.mjs +54 -21
  35. package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
  36. package/fesm2022/ng-doc-app-components-image-viewer.mjs +183 -89
  37. package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
  38. package/fesm2022/ng-doc-app-components-kind-icon.mjs +42 -25
  39. package/fesm2022/ng-doc-app-components-kind-icon.mjs.map +1 -1
  40. package/fesm2022/ng-doc-app-components-link.mjs +12 -9
  41. package/fesm2022/ng-doc-app-components-link.mjs.map +1 -1
  42. package/fesm2022/ng-doc-app-components-members.mjs +30 -0
  43. package/fesm2022/ng-doc-app-components-members.mjs.map +1 -0
  44. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs +61 -20
  45. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs.map +1 -1
  46. package/fesm2022/ng-doc-app-components-navbar.mjs +39 -49
  47. package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
  48. package/fesm2022/ng-doc-app-components-page-header.mjs +73 -10
  49. package/fesm2022/ng-doc-app-components-page-header.mjs.map +1 -1
  50. package/fesm2022/ng-doc-app-components-page-link.mjs +123 -31
  51. package/fesm2022/ng-doc-app-components-page-link.mjs.map +1 -1
  52. package/fesm2022/ng-doc-app-components-page-navigation.mjs +17 -19
  53. package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
  54. package/fesm2022/ng-doc-app-components-page-wrapper.mjs +56 -35
  55. package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
  56. package/fesm2022/ng-doc-app-components-page.mjs +168 -24
  57. package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
  58. package/fesm2022/ng-doc-app-components-playground.mjs +477 -286
  59. package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
  60. package/fesm2022/ng-doc-app-components-root.mjs +48 -31
  61. package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
  62. package/fesm2022/ng-doc-app-components-search-result.mjs +22 -21
  63. package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
  64. package/fesm2022/ng-doc-app-components-search.mjs +64 -33
  65. package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
  66. package/fesm2022/ng-doc-app-components-sidebar.mjs +86 -61
  67. package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
  68. package/fesm2022/ng-doc-app-components-tabs.mjs +35 -11
  69. package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
  70. package/fesm2022/ng-doc-app-components-theme-toggle.mjs +33 -21
  71. package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
  72. package/fesm2022/ng-doc-app-components-toc.mjs +267 -90
  73. package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
  74. package/fesm2022/ng-doc-app-components.mjs +4 -1
  75. package/fesm2022/ng-doc-app-components.mjs.map +1 -1
  76. package/fesm2022/ng-doc-app-defaults-default-processors.mjs +2 -1
  77. package/fesm2022/ng-doc-app-defaults-default-processors.mjs.map +1 -1
  78. package/fesm2022/ng-doc-app-demo-app.mjs +176 -0
  79. package/fesm2022/ng-doc-app-demo-app.mjs.map +1 -0
  80. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs +11 -5
  81. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs.map +1 -1
  82. package/fesm2022/ng-doc-app-directives-members-filter.mjs +276 -0
  83. package/fesm2022/ng-doc-app-directives-members-filter.mjs.map +1 -0
  84. package/fesm2022/ng-doc-app-directives-route-active.mjs +34 -30
  85. package/fesm2022/ng-doc-app-directives-route-active.mjs.map +1 -1
  86. package/fesm2022/ng-doc-app-directives.mjs +1 -0
  87. package/fesm2022/ng-doc-app-directives.mjs.map +1 -1
  88. package/fesm2022/ng-doc-app-helpers.mjs +307 -2
  89. package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
  90. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs +6 -4
  91. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs.map +1 -1
  92. package/fesm2022/ng-doc-app-pipes-extract-value.mjs +6 -4
  93. package/fesm2022/ng-doc-app-pipes-extract-value.mjs.map +1 -1
  94. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs +7 -4
  95. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs.map +1 -1
  96. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs +8 -5
  97. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs.map +1 -1
  98. package/fesm2022/ng-doc-app-processors-page-processor.mjs +86 -23
  99. package/fesm2022/ng-doc-app-processors-page-processor.mjs.map +1 -1
  100. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs +26 -25
  101. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs.map +1 -1
  102. package/fesm2022/ng-doc-app-processors-processors.mjs +42 -10
  103. package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
  104. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +31 -2
  105. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
  106. package/fesm2022/ng-doc-app-providers-title.mjs +129 -0
  107. package/fesm2022/ng-doc-app-providers-title.mjs.map +1 -0
  108. package/fesm2022/ng-doc-app-providers.mjs +1 -0
  109. package/fesm2022/ng-doc-app-providers.mjs.map +1 -1
  110. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +122 -0
  111. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -0
  112. package/fesm2022/ng-doc-app-services-content-state.mjs +57 -0
  113. package/fesm2022/ng-doc-app-services-content-state.mjs.map +1 -0
  114. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs +74 -0
  115. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs.map +1 -0
  116. package/fesm2022/ng-doc-app-services-highlighter.mjs +90 -17
  117. package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
  118. package/fesm2022/ng-doc-app-services-route-preloader.mjs +384 -0
  119. package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -0
  120. package/fesm2022/ng-doc-app-services-shortcuts.mjs +214 -0
  121. package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -0
  122. package/fesm2022/ng-doc-app-services-sidebar.mjs +59 -25
  123. package/fesm2022/ng-doc-app-services-sidebar.mjs.map +1 -1
  124. package/fesm2022/ng-doc-app-services-store.mjs +8 -8
  125. package/fesm2022/ng-doc-app-services-store.mjs.map +1 -1
  126. package/fesm2022/ng-doc-app-services-theme.mjs +32 -12
  127. package/fesm2022/ng-doc-app-services-theme.mjs.map +1 -1
  128. package/fesm2022/ng-doc-app-services.mjs +143 -0
  129. package/fesm2022/ng-doc-app-services.mjs.map +1 -1
  130. package/fesm2022/ng-doc-app-tokens.mjs +7 -28
  131. package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
  132. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs +18 -9
  133. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs.map +1 -1
  134. package/fesm2022/ng-doc-app-type-controls-number-control.mjs +12 -9
  135. package/fesm2022/ng-doc-app-type-controls-number-control.mjs.map +1 -1
  136. package/fesm2022/ng-doc-app-type-controls-string-control.mjs +12 -9
  137. package/fesm2022/ng-doc-app-type-controls-string-control.mjs.map +1 -1
  138. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +59 -18
  139. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
  140. package/package.json +82 -28
  141. package/styles/global.css +1128 -201
  142. package/styles/main.css +1128 -201
  143. package/styles/themes/dark.css +88 -56
  144. package/types/ng-doc-app-classes-content-anchor-controller.d.ts +54 -0
  145. package/types/ng-doc-app-classes-content-controller.d.ts +94 -0
  146. package/types/ng-doc-app-classes-default-search-engine.d.ts +9 -1
  147. package/types/ng-doc-app-classes-root-page.d.ts +14 -1
  148. package/types/ng-doc-app-classes-search-engine.d.ts +5 -0
  149. package/types/ng-doc-app-classes.d.ts +2 -0
  150. package/types/ng-doc-app-components-api-list.d.ts +69 -20
  151. package/types/ng-doc-app-components-breadcrumb.d.ts +8 -3
  152. package/types/ng-doc-app-components-code.d.ts +46 -12
  153. package/types/ng-doc-app-components-command-palette.d.ts +147 -0
  154. package/types/ng-doc-app-components-copy-button.d.ts +18 -6
  155. package/types/ng-doc-app-components-demo-displayer.d.ts +23 -10
  156. package/types/ng-doc-app-components-demo-frame.d.ts +48 -0
  157. package/types/ng-doc-app-components-demo-pane.d.ts +19 -15
  158. package/types/ng-doc-app-components-demo.d.ts +80 -15
  159. package/types/ng-doc-app-components-fullscreen-button.d.ts +4 -2
  160. package/types/ng-doc-app-components-fullscreen-toggle.d.ts +24 -0
  161. package/types/ng-doc-app-components-heading-anchor.d.ts +26 -7
  162. package/types/ng-doc-app-components-image-viewer.d.ts +71 -7
  163. package/types/ng-doc-app-components-kind-icon.d.ts +28 -7
  164. package/types/ng-doc-app-components-link.d.ts +6 -2
  165. package/types/ng-doc-app-components-members.d.ts +13 -0
  166. package/types/ng-doc-app-components-mermaid-viewer.d.ts +21 -6
  167. package/types/ng-doc-app-components-navbar.d.ts +25 -15
  168. package/types/ng-doc-app-components-page-header.d.ts +28 -4
  169. package/types/ng-doc-app-components-page-link.d.ts +34 -15
  170. package/types/ng-doc-app-components-page-navigation.d.ts +10 -5
  171. package/types/ng-doc-app-components-page-wrapper.d.ts +35 -11
  172. package/types/ng-doc-app-components-page.d.ts +57 -6
  173. package/types/ng-doc-app-components-playground.d.ts +167 -78
  174. package/types/ng-doc-app-components-root.d.ts +28 -7
  175. package/types/ng-doc-app-components-search-result.d.ts +14 -6
  176. package/types/ng-doc-app-components-search.d.ts +19 -7
  177. package/types/ng-doc-app-components-tabs.d.ts +24 -5
  178. package/types/ng-doc-app-components-theme-toggle.d.ts +18 -5
  179. package/types/ng-doc-app-components-toc.d.ts +76 -29
  180. package/types/ng-doc-app-components.d.ts +4 -1
  181. package/types/ng-doc-app-demo-app.d.ts +89 -0
  182. package/types/ng-doc-app-directives-code-highlighter.d.ts +8 -4
  183. package/types/ng-doc-app-directives-members-filter.d.ts +61 -0
  184. package/types/ng-doc-app-directives-route-active.d.ts +21 -7
  185. package/types/ng-doc-app-directives.d.ts +1 -0
  186. package/types/ng-doc-app-helpers.d.ts +142 -3
  187. package/types/ng-doc-app-interfaces.d.ts +62 -31
  188. package/types/ng-doc-app-pipes-decode-uri-component.d.ts +3 -0
  189. package/types/ng-doc-app-pipes-extract-value.d.ts +3 -0
  190. package/types/ng-doc-app-pipes-filter-by-text.d.ts +4 -0
  191. package/types/ng-doc-app-pipes-sanitize-html.d.ts +4 -2
  192. package/types/ng-doc-app-processors-page-processor.d.ts +39 -10
  193. package/types/ng-doc-app-processors-processors-tooltip.d.ts +11 -10
  194. package/types/ng-doc-app-processors-processors.d.ts +10 -1
  195. package/types/ng-doc-app-providers-ng-doc-app.d.ts +18 -1
  196. package/types/ng-doc-app-providers-title.d.ts +59 -0
  197. package/types/ng-doc-app-providers.d.ts +1 -0
  198. package/types/ng-doc-app-services-content-scroll-intent.d.ts +52 -0
  199. package/types/ng-doc-app-services-content-state.d.ts +40 -0
  200. package/types/ng-doc-app-services-fullscreen-route.d.ts +35 -0
  201. package/types/ng-doc-app-services-highlighter.d.ts +47 -5
  202. package/types/ng-doc-app-services-route-preloader.d.ts +121 -0
  203. package/types/ng-doc-app-services-shortcuts.d.ts +96 -0
  204. package/types/ng-doc-app-services-sidebar.d.ts +24 -4
  205. package/types/ng-doc-app-services-store.d.ts +24 -1
  206. package/types/ng-doc-app-services-theme.d.ts +19 -3
  207. package/types/ng-doc-app-services.d.ts +77 -0
  208. package/types/ng-doc-app-tokens.d.ts +10 -30
  209. package/types/ng-doc-app-type-controls-boolean-control.d.ts +11 -6
  210. package/types/ng-doc-app-type-controls-number-control.d.ts +5 -3
  211. package/types/ng-doc-app-type-controls-string-control.d.ts +5 -3
  212. package/types/ng-doc-app-type-controls-type-alias-control.d.ts +35 -6
  213. package/fesm2022/ng-doc-app-components-search-dialog.mjs +0 -78
  214. package/fesm2022/ng-doc-app-components-search-dialog.mjs.map +0 -1
  215. package/types/ng-doc-app-components-search-dialog.d.ts +0 -28
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-doc-app-components-command-palette.mjs","sources":["../../../../libs/app/components/command-palette/command-palette.component.ts","../../../../libs/app/components/command-palette/command-palette.component.html","../../../../libs/app/components/command-palette/ng-doc-app-components-command-palette.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport {\n afterNextRender,\n afterRenderEffect,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n linkedSignal,\n Signal,\n signal,\n untracked,\n viewChild,\n ViewEncapsulation,\n} from '@angular/core';\nimport { rxResource } from '@angular/core/rxjs-interop';\nimport { form, FormField } from '@angular/forms/signals';\nimport { Router } from '@angular/router';\nimport { NgDocSearchEngine } from '@ng-doc/app/classes/search-engine';\nimport { NgDocKindIconComponent } from '@ng-doc/app/components/kind-icon';\nimport { NgDocSearchResult } from '@ng-doc/app/interfaces';\nimport { NgDocApiListDeclaration, NgDocApiListIndexService } from '@ng-doc/app/services';\nimport { NgDocShortcutsService } from '@ng-doc/app/services/shortcuts';\nimport type { NgDocPageIndex } from '@ng-doc/core/interfaces';\nimport {\n NG_DOC_DIALOG_DATA,\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n NgDocSelectionOriginDirective,\n NgDocSpinnerComponent,\n} from '@ng-doc/ui-kit';\nimport { NgDocOverlayRef } from '@ng-doc/ui-kit/classes';\nimport { of, timer } from 'rxjs';\nimport { switchMap } from 'rxjs/operators';\n\n/**\n * Data of the search palette dialog.\n */\nexport interface NgDocCommandPaletteData {\n /**\n * The text the search field starts with.\n */\n query?: string;\n}\n\n/**\n * The scope the search palette shows results for.\n */\nexport type NgDocCommandPaletteScope = 'all' | 'guides' | 'api' | 'actions';\n\ntype RowType = 'api' | 'guide' | 'action';\n\ninterface Segment {\n text: string;\n match: boolean;\n}\n\ninterface Row {\n id: string;\n type: RowType;\n label: Segment[];\n title: string;\n meta: string;\n icon: 'symbol' | 'page' | 'section' | 'action';\n kind?: string;\n scope?: string;\n url?: string;\n text?: string;\n signature?: string;\n keys?: string[];\n action?: Action;\n /** Whether the row is a declaration whose name starts with the query. */\n pinned?: boolean;\n}\n\ninterface Section {\n key: string;\n type: RowType;\n title: string;\n rows: Row[];\n}\n\ninterface Action {\n name: () => string;\n keywords: string;\n keys: string[];\n keepOpen?: boolean;\n run: () => void;\n}\n\ntype ApiSymbol = NgDocApiListDeclaration;\n\nconst SCOPES: ReadonlyArray<{ id: NgDocCommandPaletteScope; label: string }> = [\n { id: 'all', label: 'All' },\n { id: 'guides', label: 'Guides' },\n { id: 'api', label: 'API' },\n { id: 'actions', label: 'Actions' },\n];\n\n/**\n * How many declarations whose name starts with the query rank above the guides, and the shortest\n * query that pins them: one or two letters start too many names to single any out.\n */\nconst PINNED_LIMIT = 3;\nconst PINNED_MIN_QUERY = 3;\n\n/** How long typing pauses before the search runs, in milliseconds. */\nconst SEARCH_DEBOUNCE = 120;\n\n/**\n * The search palette: a search field with scopes (all, guides, API and actions), a list of\n * results grouped by type (guides first, then the API), a preview of the selected result and the\n * switch for single-key shortcuts. The navbar search opens it with Command+K (Control+K) or the\n * slash key.\n */\n@Component({\n selector: 'ng-doc-command-palette',\n templateUrl: './command-palette.component.html',\n styleUrl: './command-palette.component.scss',\n // The palette styles the dialog pane and backdrop around it, which sit outside its host.\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n FormField,\n NgTemplateOutlet,\n NgDocKindIconComponent,\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n NgDocSelectionOriginDirective,\n NgDocSpinnerComponent,\n ],\n host: {\n 'animate.enter': 'ng-doc-command-palette-enter',\n },\n})\nexport class NgDocCommandPaletteComponent {\n protected readonly scopes = SCOPES;\n protected readonly shortcuts = inject(NgDocShortcutsService);\n\n private readonly data = inject<NgDocCommandPaletteData | null>(NG_DOC_DIALOG_DATA, {\n optional: true,\n });\n private readonly overlayRef = inject(NgDocOverlayRef, { optional: true });\n private readonly router = inject(Router);\n private readonly searchEngine = inject(NgDocSearchEngine, { optional: true });\n private readonly apiLists = inject(NgDocApiListIndexService);\n\n protected readonly model = signal({ query: this.data?.query ?? '' });\n protected readonly searchForm = form(this.model);\n protected readonly scope = signal<NgDocCommandPaletteScope>('all');\n protected readonly query = computed(() => this.model().query.trim());\n\n private readonly input = viewChild.required<ElementRef<HTMLInputElement>>('input');\n private readonly list = viewChild.required<ElementRef<HTMLElement>>('list');\n\n private readonly results = rxResource({\n params: () => this.query() || undefined,\n stream: ({ params }) =>\n timer(SEARCH_DEBOUNCE).pipe(\n switchMap(() => this.searchEngine?.search(params) ?? of<NgDocSearchResult[]>([])),\n ),\n });\n\n // The last results stay visible while the next query runs, so the list does not flicker.\n private readonly hits = linkedSignal<\n { query: string; failed: boolean; hits?: NgDocSearchResult[] },\n NgDocSearchResult[]\n >({\n source: () => ({\n query: this.query(),\n failed: this.results.status() === 'error',\n hits: this.results.hasValue() ? this.results.value() : undefined,\n }),\n // A failed search shows the failure, not the hits of the previous query.\n computation: (source, previous) =>\n source.query && !source.failed ? source.hits ?? previous?.value ?? [] : [],\n });\n\n // The generated API lists give the kind and scope of every declaration, and let the palette\n // match declaration names directly. Without them the palette shows search results only.\n private readonly symbols: Signal<ApiSymbol[]> = this.apiLists.declarations;\n\n private readonly symbolsByRoute = computed(\n () => new Map(this.symbols().map((symbol: ApiSymbol) => [symbol.route, symbol])),\n );\n\n private readonly actions: Action[] = [\n {\n name: () => 'Toggle dark mode',\n keywords: 'theme dark light mode',\n keys: ['T'],\n run: () => this.shortcuts.run('t'),\n },\n {\n name: () => 'Copy link to this page',\n keywords: 'copy link url share',\n keys: ['L'],\n run: () => this.shortcuts.run('l'),\n },\n {\n name: () =>\n this.shortcuts.enabled() ? 'Turn off single-key shortcuts' : 'Turn on single-key shortcuts',\n keywords: 'keyboard shortcuts keys single',\n keys: [],\n keepOpen: true,\n run: () => this.shortcuts.toggle(),\n },\n ];\n\n protected readonly sections: Signal<Section[]> = computed(() => {\n const scope = this.scope();\n const query = this.query();\n const sections: Section[] = [];\n\n let apiRows: Row[] =\n (scope === 'all' || scope === 'api') && query ? this.apiRows(query, scope === 'api') : [];\n\n // Guides rank above the API reference: readers who search a topic usually want the guide\n // that explains it first. A declaration whose name starts with the query is what the reader\n // typed, though: it stays on top, so Enter opens it however the guide search ranks.\n if (scope === 'all' && query) {\n const pinned = apiRows.filter((row: Row) => row.pinned).slice(0, PINNED_LIMIT);\n\n apiRows = apiRows.filter((row: Row) => !pinned.includes(row));\n sections.push({ key: 'top', type: 'api', title: 'Top matches', rows: pinned });\n }\n if ((scope === 'all' || scope === 'guides') && query) {\n sections.push({\n key: 'guide',\n type: 'guide',\n title: 'Guides',\n rows: this.guideRows(query, scope === 'guides'),\n });\n }\n if (apiRows.length) {\n sections.push({ key: 'api', type: 'api', title: 'API', rows: apiRows });\n }\n if (scope === 'all' || scope === 'actions') {\n sections.push({\n key: 'action',\n type: 'action',\n title: 'Actions',\n rows: this.actionRows(query),\n });\n }\n\n let index = 0;\n\n return sections\n .filter((section: Section) => section.rows.length)\n .map((section: Section) => ({\n ...section,\n rows: section.rows.map((row: Row) => ({ ...row, id: `ng-doc-palette-option-${index++}` })),\n }));\n });\n\n protected readonly rows = computed(() =>\n this.sections().flatMap((section: Section) => section.rows),\n );\n\n // Whether the reader moved the selection (with the keyboard or the pointer) since the query or\n // the scope last changed.\n private readonly moved = linkedSignal({\n source: () => [this.query(), this.scope()],\n computation: () => false,\n });\n\n // The first result is selected whenever the results change, unless the reader moved the\n // selection: then it stays on the same result while the other source (the declaration names or\n // the asynchronous search) adds rows around it.\n protected readonly active = linkedSignal<Row[], number>({\n source: this.rows,\n computation: (rows: Row[], previous?: { source: Row[]; value: number }) => {\n const kept = previous && untracked(this.moved) ? previous.source[previous.value] : undefined;\n const index = kept ? rows.findIndex((row: Row) => sameResult(row, kept)) : -1;\n\n return Math.max(index, 0);\n },\n });\n protected readonly selected = computed(() => this.rows()[this.active()]);\n protected readonly searching = computed(\n () => !!this.query() && this.results.isLoading() && !this.hits().length,\n );\n protected readonly failed = computed(() => this.results.status() === 'error');\n protected readonly emptyMessage = computed(() => {\n const query = this.query();\n\n if (query) {\n return `No results for “${query}”`;\n }\n\n return this.scope() === 'api'\n ? 'Type to search the API.'\n : this.scope() === 'guides'\n ? 'Type to search the guides.'\n : 'Type to search.';\n });\n\n /** What the status region announces: the scope, a running search, no results or a failure. */\n protected readonly status = computed(() => {\n const scope = SCOPES.find(({ id }) => id === this.scope())?.label ?? '';\n const count = this.rows().filter((row: Row) => row.type !== 'action').length;\n\n if (this.failed()) {\n return 'Search failed.';\n }\n if (this.searching()) {\n return 'Searching…';\n }\n if (!this.query()) {\n return `${scope} scope.`;\n }\n\n return count\n ? `${scope} scope: ${count} ${count === 1 ? 'result' : 'results'}.`\n : `${scope} scope: no results for “${this.query()}”.`;\n });\n\n // Increments when the selection moves by keyboard, so only those moves scroll the list.\n private readonly keyboardMove = signal(0);\n private readonly host: HTMLElement = inject(ElementRef).nativeElement;\n\n constructor() {\n void this.apiLists.load();\n\n afterNextRender(() => {\n const input = this.input().nativeElement;\n\n input.focus();\n input.select();\n });\n\n afterRenderEffect(() => {\n if (!this.keyboardMove()) {\n return;\n }\n\n const id = untracked(this.selected)?.id;\n const option = id ? this.list().nativeElement.querySelector(`#${id}`) : null;\n\n option?.scrollIntoView?.({ block: 'nearest' });\n });\n }\n\n /**\n * Handles the keys of the search field: the arrow keys move the selection and Enter opens the\n * selected result. Keys that compose text in an input method editor are left alone.\n * @param event - The keyboard event of the search field.\n */\n protected onKeydown(event: KeyboardEvent): void {\n if (event.isComposing || event.keyCode === 229) {\n return;\n }\n\n untracked(() => {\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n event.preventDefault();\n this.move(event.key === 'ArrowDown' ? 1 : -1);\n break;\n case 'Enter':\n event.preventDefault();\n this.activate(this.selected());\n break;\n }\n });\n }\n\n /**\n * Handles the keys of the scope tabs: the arrow keys, Home and End select and focus a scope.\n * @param event - The keyboard event of a scope tab.\n */\n protected onScopeKeydown(event: KeyboardEvent): void {\n const index = SCOPES.findIndex(({ id }) => id === untracked(this.scope));\n const next =\n event.key === 'ArrowRight'\n ? (index + 1) % SCOPES.length\n : event.key === 'ArrowLeft'\n ? (index - 1 + SCOPES.length) % SCOPES.length\n : event.key === 'Home'\n ? 0\n : event.key === 'End'\n ? SCOPES.length - 1\n : -1;\n\n if (next < 0) {\n return;\n }\n\n event.preventDefault();\n this.scope.set(SCOPES[next].id);\n this.host.querySelectorAll<HTMLElement>('[role=\"tab\"]')[next]?.focus();\n }\n\n /**\n * Keeps Tab inside the palette: from its last tab stop focus wraps to the search field, and\n * Shift+Tab from the search field goes to the last tab stop.\n * @param event - A keyboard event inside the palette.\n */\n protected onTrapKeydown(event: KeyboardEvent): void {\n if (event.key !== 'Tab') {\n return;\n }\n\n const stops = Array.from(\n this.host.querySelectorAll<HTMLElement>('input, button:not([tabindex=\"-1\"])'),\n );\n const first = stops[0];\n const last = stops[stops.length - 1];\n\n if (!event.shiftKey && event.target === last) {\n event.preventDefault();\n first?.focus();\n } else if (event.shiftKey && event.target === first) {\n event.preventDefault();\n last?.focus();\n }\n }\n\n /**\n * Selects a scope by click and returns the focus to the search field.\n * @param scope - The scope to select.\n */\n protected selectScope(scope: NgDocCommandPaletteScope): void {\n this.scope.set(scope);\n this.input().nativeElement.focus();\n }\n\n /**\n * Selects the result under the pointer, without scrolling the list.\n * @param index - The index of the result.\n */\n protected hover(index: number): void {\n if (untracked(this.active) !== index) {\n this.active.set(index);\n this.moved.set(true);\n }\n }\n\n /**\n * Opens the given result: navigates to a page or runs an action.\n * @param row - The result to open.\n */\n protected activate(row: Row | undefined): void {\n if (!row) {\n return;\n }\n\n if (row.action) {\n if (!row.action.keepOpen) {\n this.close();\n }\n\n row.action.run();\n\n return;\n }\n\n this.close();\n\n if (row.url) {\n void this.router.navigateByUrl(row.url);\n }\n }\n\n private move(step: number): void {\n const count = this.rows().length;\n\n if (count) {\n this.active.set((this.active() + step + count) % count);\n this.moved.set(true);\n this.keyboardMove.update((value: number) => value + 1);\n }\n }\n\n private close(): void {\n this.overlayRef?.close();\n }\n\n private apiRows(query: string, all: boolean): Row[] {\n const rows = new Map<string, Row>();\n const needle = query.toLowerCase();\n const matches = this.symbols()\n .filter((symbol: ApiSymbol) => symbol.name.toLowerCase().includes(needle))\n .sort(\n (a: ApiSymbol, b: ApiSymbol) =>\n a.name.toLowerCase().indexOf(needle) - b.name.toLowerCase().indexOf(needle) ||\n a.name.length - b.name.length ||\n a.name.localeCompare(b.name),\n );\n\n for (const symbol of matches) {\n // The summary record of the symbol's page, when the query found it.\n const hit = this.hitsFor(symbol.route);\n\n rows.set(symbol.route, {\n id: '',\n type: 'api',\n pinned: needle.length >= PINNED_MIN_QUERY && symbol.name.toLowerCase().startsWith(needle),\n title: symbol.name,\n label: highlight(symbol.name, query),\n meta: symbol.scope,\n icon: 'symbol',\n kind: symbol.kind,\n scope: symbol.scope,\n url: `/${symbol.route}`,\n text: hit?.description ?? symbol.description ?? hit?.content,\n signature: hit?.signature ?? symbol.signature,\n });\n }\n\n for (const hit of this.hits()) {\n const index: NgDocPageIndex = hit.index;\n\n if (index.pageType !== 'api') {\n continue;\n }\n\n const key = routeKey(index.route) + (index.fragment ? `#${index.fragment}` : '');\n\n if (rows.has(key) || (!index.fragment && rows.has(routeKey(index.route)))) {\n continue;\n }\n\n const symbol = this.symbolsByRoute().get(routeKey(index.route));\n const scope = symbol?.scope ?? index.breadcrumbs[1] ?? '';\n // Only one record of a page carries the declaration's summary: a hit on another record of\n // the page takes it from that record (when the query found it too) or from the API list.\n const summary = index.fragment ? undefined : this.hitsFor(routeKey(index.route));\n\n rows.set(key, {\n id: '',\n type: 'api',\n title: index.title,\n label: highlight(index.title, query),\n meta: index.section ? `${index.section} · ${scope}` : scope,\n icon: 'symbol',\n kind: index.kind ?? summary?.kind ?? symbol?.kind,\n scope,\n url: pageUrl(index),\n text: index.fragment\n ? index.description ?? index.content\n : summary?.description ?? symbol?.description ?? index.content,\n signature: index.fragment ? index.signature : summary?.signature ?? symbol?.signature,\n });\n }\n\n return [...rows.values()].slice(0, all ? 12 : 6);\n }\n\n private guideRows(query: string, all: boolean): Row[] {\n const rows = new Map<string, Row>();\n\n for (const hit of this.hits()) {\n const index = hit.index;\n\n if (index.pageType !== 'guide') {\n continue;\n }\n\n const key = routeKey(index.route) + (index.fragment ? `#${index.fragment}` : '');\n\n if (rows.has(key)) {\n continue;\n }\n\n const title = index.section || index.title;\n const path = index.section\n ? index.breadcrumbs\n : index.breadcrumbs.slice(0, Math.max(index.breadcrumbs.length - 1, 0));\n\n rows.set(key, {\n id: '',\n type: 'guide',\n title,\n label: highlight(title, query),\n meta: path.join(' › '),\n icon: index.fragment ? 'section' : 'page',\n url: pageUrl(index),\n text: index.content,\n });\n }\n\n return [...rows.values()].slice(0, all ? 12 : 5);\n }\n\n private actionRows(query: string): Row[] {\n const needle = query.toLowerCase();\n\n return this.actions\n .filter(\n (action: Action) =>\n !needle ||\n action.name().toLowerCase().includes(needle) ||\n action.keywords.split(' ').some((word: string) => word.startsWith(needle)),\n )\n .map((action: Action) => ({\n id: '',\n type: 'action',\n title: action.name(),\n label: highlight(action.name(), query),\n meta: '',\n icon: 'action',\n keys: action.keys,\n action,\n }));\n }\n\n /**\n * The hit of a symbol's page that previews it: the record with the declaration's summary (the\n * new engine puts it on one record of the page), or else any record outside a section.\n * @param route - The route of the symbol's page.\n */\n private hitsFor(route: string): NgDocPageIndex | undefined {\n const page = this.hits()\n .map((hit: NgDocSearchResult) => hit.index)\n .filter((index: NgDocPageIndex) => routeKey(index.route) === route && !index.section);\n\n return (\n page.find((index: NgDocPageIndex) => index.signature !== undefined || !!index.kind) ?? page[0]\n );\n }\n}\n\n/**\n * Splits a text around the first case-insensitive occurrence of the query.\n * @param text - The text to split.\n * @param query - The query to find.\n */\nfunction highlight(text: string, query: string): Segment[] {\n const start = query ? text.toLowerCase().indexOf(query.toLowerCase()) : -1;\n\n if (start < 0) {\n return [{ text, match: false }];\n }\n\n const end = start + query.length;\n\n return [\n { text: text.slice(0, start), match: false },\n { text: text.slice(start, end), match: true },\n { text: text.slice(end), match: false },\n ].filter((segment: Segment) => segment.text);\n}\n\n/**\n * Whether two rows open the same result.\n * @param a - A row.\n * @param b - Another row.\n */\nfunction sameResult(a: Row, b: Row): boolean {\n return a.type === b.type && (a.action ? a.action === b.action : a.url === b.url);\n}\n\n/**\n * Normalizes a route to compare search records with the API list.\n * @param route - A route with or without the leading slash.\n */\nfunction routeKey(route: string): string {\n return route.replace(/^\\/+/, '');\n}\n\n/**\n * Builds the URL of a search record.\n * @param index - The search record.\n */\nfunction pageUrl(index: NgDocPageIndex): string {\n return `/${routeKey(index.route)}${index.fragment ? `#${index.fragment}` : ''}`;\n}\n","@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…\"\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…\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\">↵</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\">↑</kbd>\n <kbd class=\"ng-doc-command-palette-kbd\">↓</kbd>\n navigate\n </span>\n <span class=\"ng-doc-command-palette-wide\"><kbd class=\"ng-doc-command-palette-kbd\">↵</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","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,59 +1,76 @@
1
1
  import { Clipboard } from '@angular/cdk/clipboard';
2
2
  import * as i0 from '@angular/core';
3
- import { inject, ViewChild, Input, ChangeDetectionStrategy, Component } from '@angular/core';
4
- import { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';
3
+ import { input, viewChild, signal, inject, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
4
+ import { NgDocTooltipDirective, NgDocButtonIconComponent } from '@ng-doc/ui-kit';
5
5
 
6
+ /**
7
+ * An icon button that copies a text to the clipboard and confirms it in a tooltip. Project the
8
+ * icon into it.
9
+ */
6
10
  class NgDocCopyButtonComponent {
7
11
  constructor() {
8
- this.tooltipText = '';
12
+ /** The text to copy, or a function that returns it when the button is pressed. */
13
+ this.text = input.required(/* @ts-ignore */
14
+ ...(ngDevMode ? [{ debugName: "text" }] : /* istanbul ignore next */ []));
15
+ /** Accessible name of the button, also shown in its tooltip. */
16
+ this.label = input('Copy to clipboard', /* @ts-ignore */
17
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
18
+ /** The tooltip of the button. */
19
+ this.tooltip = viewChild.required(NgDocTooltipDirective, /* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "tooltip" }] : /* istanbul ignore next */ []));
21
+ this.tooltipText = signal('', /* @ts-ignore */
22
+ ...(ngDevMode ? [{ debugName: "tooltipText" }] : /* istanbul ignore next */ []));
9
23
  this.clipboard = inject(Clipboard);
10
24
  }
25
+ /** Copies the text and shows the confirmation. */
11
26
  copy() {
12
- this.clipboard.copy(this.text);
13
- this.tooltip.show();
27
+ untracked(() => {
28
+ const text = this.text();
29
+ this.clipboard.copy(typeof text === 'function' ? text() : text);
30
+ this.tooltipText.set('Copied!');
31
+ this.tooltip().show();
32
+ });
14
33
  }
15
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocCopyButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
16
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.6", type: NgDocCopyButtonComponent, isStandalone: true, selector: "ng-doc-copy-button", inputs: { text: "text" }, viewQueries: [{ propertyName: "tooltip", first: true, predicate: NgDocTooltipDirective, descendants: true, static: true }], ngImport: i0, template: `
34
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocCopyButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
35
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.2.1", type: NgDocCopyButtonComponent, isStandalone: true, selector: "ng-doc-copy-button", inputs: { text: { classPropertyName: "text", publicName: "text", isSignal: true, isRequired: true, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "tooltip", first: true, predicate: NgDocTooltipDirective, descendants: true, isSignal: true }], ngImport: i0, template: `
17
36
  <button
37
+ type="button"
18
38
  ng-doc-button-icon
19
39
  [rounded]="false"
20
- (click)="copy(); tooltipText = 'Copied!'"
40
+ [attr.aria-label]="label()"
41
+ (click)="copy()"
21
42
  [ngDocTooltip]="tooltipContent"
22
- (mouseenter)="tooltipText = 'Copy to clipboard'">
43
+ (mouseenter)="tooltipText.set(label())">
23
44
  <ng-template #tooltipContent>
24
- {{ tooltipText }}
45
+ {{ tooltipText() }}
25
46
  </ng-template>
26
47
  <ng-content></ng-content>
27
48
  </button>
28
49
  `, isInline: true, dependencies: [{ kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
29
50
  }
30
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocCopyButtonComponent, decorators: [{
51
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocCopyButtonComponent, decorators: [{
31
52
  type: Component,
32
53
  args: [{
33
54
  selector: 'ng-doc-copy-button',
34
55
  imports: [NgDocButtonIconComponent, NgDocTooltipDirective],
35
56
  template: `
36
57
  <button
58
+ type="button"
37
59
  ng-doc-button-icon
38
60
  [rounded]="false"
39
- (click)="copy(); tooltipText = 'Copied!'"
61
+ [attr.aria-label]="label()"
62
+ (click)="copy()"
40
63
  [ngDocTooltip]="tooltipContent"
41
- (mouseenter)="tooltipText = 'Copy to clipboard'">
64
+ (mouseenter)="tooltipText.set(label())">
42
65
  <ng-template #tooltipContent>
43
- {{ tooltipText }}
66
+ {{ tooltipText() }}
44
67
  </ng-template>
45
68
  <ng-content></ng-content>
46
69
  </button>
47
70
  `,
48
71
  changeDetection: ChangeDetectionStrategy.OnPush,
49
72
  }]
50
- }], propDecorators: { text: [{
51
- type: Input,
52
- args: [{ required: true }]
53
- }], tooltip: [{
54
- type: ViewChild,
55
- args: [NgDocTooltipDirective, { static: true }]
56
- }] } });
73
+ }], propDecorators: { text: [{ type: i0.Input, args: [{ isSignal: true, alias: "text", required: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], tooltip: [{ type: i0.ViewChild, args: [i0.forwardRef(() => NgDocTooltipDirective), { isSignal: true }] }] } });
57
74
 
58
75
  /**
59
76
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-copy-button.mjs","sources":["../../../../libs/app/components/copy-button/copy-button.component.ts","../../../../libs/app/components/copy-button/ng-doc-app-components-copy-button.ts"],"sourcesContent":["import { Clipboard } from '@angular/cdk/clipboard';\nimport { ChangeDetectionStrategy, Component, inject, Input, ViewChild } from '@angular/core';\nimport { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-copy-button',\n imports: [NgDocButtonIconComponent, NgDocTooltipDirective],\n template: `\n <button\n ng-doc-button-icon\n [rounded]=\"false\"\n (click)=\"copy(); tooltipText = 'Copied!'\"\n [ngDocTooltip]=\"tooltipContent\"\n (mouseenter)=\"tooltipText = 'Copy to clipboard'\">\n <ng-template #tooltipContent>\n {{ tooltipText }}\n </ng-template>\n <ng-content></ng-content>\n </button>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocCopyButtonComponent {\n @Input({ required: true })\n text!: string;\n\n @ViewChild(NgDocTooltipDirective, { static: true })\n tooltip!: NgDocTooltipDirective;\n\n protected tooltipText: string = '';\n protected readonly clipboard = inject(Clipboard);\n\n copy(): void {\n this.clipboard.copy(this.text);\n this.tooltip.show();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;MAsBa,wBAAwB,CAAA;AAlBrC,IAAA,WAAA,GAAA;QAyBY,IAAA,CAAA,WAAW,GAAW,EAAE;AACf,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AAMjD,IAAA;IAJC,IAAI,GAAA;QACF,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;AAC9B,QAAA,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;IACrB;8GAbW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAIxB,qBAAqB,EAAA,WAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAnBtB;;;;;;;;;;;;GAYT,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAbS,wBAAwB,uQAAE,qBAAqB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,OAAA,EAAA,eAAA,EAAA,eAAA,EAAA,WAAA,EAAA,SAAA,EAAA,YAAA,EAAA,WAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,UAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAgB9C,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBAlBpC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,OAAO,EAAE,CAAC,wBAAwB,EAAE,qBAAqB,CAAC;AAC1D,oBAAA,QAAQ,EAAE;;;;;;;;;;;;AAYT,EAAA,CAAA;oBACD,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAChD,iBAAA;;sBAEE,KAAK;uBAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;;sBAGxB,SAAS;AAAC,gBAAA,IAAA,EAAA,CAAA,qBAAqB,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE;;;AC1BpD;;AAEG;;;;"}
1
+ {"version":3,"file":"ng-doc-app-components-copy-button.mjs","sources":["../../../../libs/app/components/copy-button/copy-button.component.ts","../../../../libs/app/components/copy-button/ng-doc-app-components-copy-button.ts"],"sourcesContent":["import { Clipboard } from '@angular/cdk/clipboard';\nimport {\n ChangeDetectionStrategy,\n Component,\n inject,\n input,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';\n\n/** The text a copy button copies, or a function that reads it when the button is pressed. */\nexport type NgDocCopyButtonText = string | (() => string);\n\n/**\n * An icon button that copies a text to the clipboard and confirms it in a tooltip. Project the\n * icon into it.\n */\n@Component({\n selector: 'ng-doc-copy-button',\n imports: [NgDocButtonIconComponent, NgDocTooltipDirective],\n template: `\n <button\n type=\"button\"\n ng-doc-button-icon\n [rounded]=\"false\"\n [attr.aria-label]=\"label()\"\n (click)=\"copy()\"\n [ngDocTooltip]=\"tooltipContent\"\n (mouseenter)=\"tooltipText.set(label())\">\n <ng-template #tooltipContent>\n {{ tooltipText() }}\n </ng-template>\n <ng-content></ng-content>\n </button>\n `,\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class NgDocCopyButtonComponent {\n /** The text to copy, or a function that returns it when the button is pressed. */\n readonly text = input.required<NgDocCopyButtonText>();\n\n /** Accessible name of the button, also shown in its tooltip. */\n readonly label = input<string>('Copy to clipboard');\n\n /** The tooltip of the button. */\n readonly tooltip = viewChild.required(NgDocTooltipDirective);\n\n protected readonly tooltipText = signal<string>('');\n protected readonly clipboard = inject(Clipboard);\n\n /** Copies the text and shows the confirmation. */\n copy(): void {\n untracked(() => {\n const text: NgDocCopyButtonText = this.text();\n\n this.clipboard.copy(typeof text === 'function' ? text() : text);\n this.tooltipText.set('Copied!');\n this.tooltip().show();\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAeA;;;AAGG;MAqBU,wBAAwB,CAAA;AApBrC,IAAA,WAAA,GAAA;;QAsBW,IAAA,CAAA,IAAI,GAAG,KAAK,CAAC,QAAQ;iFAAuB;;QAG5C,IAAA,CAAA,KAAK,GAAG,KAAK,CAAS,mBAAmB;kFAAC;;AAG1C,QAAA,IAAA,CAAA,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,qBAAqB;oFAAC;QAEzC,IAAA,CAAA,WAAW,GAAG,MAAM,CAAS,EAAE;wFAAC;AAChC,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;AAYjD,IAAA;;IATC,IAAI,GAAA;QACF,SAAS,CAAC,MAAK;AACb,YAAA,MAAM,IAAI,GAAwB,IAAI,CAAC,IAAI,EAAE;AAE7C,YAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,KAAK,UAAU,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;AAC/D,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC;AAC/B,YAAA,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE;AACvB,QAAA,CAAC,CAAC;IACJ;8GAtBW,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAxB,wBAAwB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,KAAA,EAAA,EAAA,iBAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,WAAA,EAAA,CAAA,EAAA,YAAA,EAAA,SAAA,EAAA,KAAA,EAAA,IAAA,EAAA,SAAA,EAQG,qBAAqB,EAAA,WAAA,EAAA,IAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAzBjD;;;;;;;;;;;;;;GAcT,EAAA,QAAA,EAAA,IAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAfS,wBAAwB,uQAAE,qBAAqB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,cAAA,EAAA,OAAA,EAAA,eAAA,EAAA,eAAA,EAAA,WAAA,EAAA,SAAA,EAAA,YAAA,EAAA,WAAA,EAAA,WAAA,EAAA,QAAA,EAAA,UAAA,EAAA,UAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,YAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,CAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAkB9C,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBApBpC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,OAAO,EAAE,CAAC,wBAAwB,EAAE,qBAAqB,CAAC;AAC1D,oBAAA,QAAQ,EAAE;;;;;;;;;;;;;;AAcT,EAAA,CAAA;oBACD,eAAe,EAAE,uBAAuB,CAAC,MAAM;AAChD,iBAAA;0QASuC,qBAAqB,CAAA,EAAA,EAAA,QAAA,EAAA,IAAA,EAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA;;AC/C7D;;AAEG;;;;"}
@@ -1,27 +1,47 @@
1
1
  import { NgTemplateOutlet } from '@angular/common';
2
2
  import * as i0 from '@angular/core';
3
- import { Input, HostBinding, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { input, model, ChangeDetectionStrategy, Component } from '@angular/core';
4
4
  import { NgDocCodeComponent } from '@ng-doc/app/components/code';
5
5
  import { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';
6
6
  import { NgDocCodeHighlighterDirective } from '@ng-doc/app/directives/code-highlighter';
7
7
  import { NgDocButtonIconComponent, NgDocTooltipDirective, NgDocIconComponent, NgDocExpanderComponent } from '@ng-doc/ui-kit';
8
8
 
9
+ let nextId = 0;
10
+ /**
11
+ * A demo on the dot-grid stage with a copy button and a toggle that reveals its code below it
12
+ * (the rows of a playground use it).
13
+ */
9
14
  class NgDocDemoDisplayerComponent {
10
15
  constructor() {
11
- this.codeContent = '';
12
- this.code = '';
13
- this.language = 'typescript';
14
- this.container = true;
15
- this.border = true;
16
- this.expanded = false;
16
+ /** Content shown when the code is revealed; when empty, the highlighted `code` is shown. */
17
+ this.codeContent = input('', /* @ts-ignore */
18
+ ...(ngDevMode ? [{ debugName: "codeContent" }] : /* istanbul ignore next */ []));
19
+ /** Code of the demo, copied by the copy button and shown when there is no `codeContent`. */
20
+ this.code = input('', /* @ts-ignore */
21
+ ...(ngDevMode ? [{ debugName: "code" }] : /* istanbul ignore next */ []));
22
+ /** Language of `code`. */
23
+ this.language = input('typescript', /* @ts-ignore */
24
+ ...(ngDevMode ? [{ debugName: "language" }] : /* istanbul ignore next */ []));
25
+ /** Whether the demo is shown in the stage with its controls; otherwise it is shown as is. */
26
+ this.container = input(true, /* @ts-ignore */
27
+ ...(ngDevMode ? [{ debugName: "container" }] : /* istanbul ignore next */ []));
28
+ /** Whether the displayer draws its border. */
29
+ this.border = input(true, /* @ts-ignore */
30
+ ...(ngDevMode ? [{ debugName: "border" }] : /* istanbul ignore next */ []));
31
+ /** Whether the code is revealed. */
32
+ this.expanded = model(false, /* @ts-ignore */
33
+ ...(ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []));
34
+ /** Id of the region that holds the code, for the toggle's `aria-controls`. */
35
+ this.codeId = `ng-doc-demo-displayer-code-${nextId++}`;
17
36
  }
18
- get expandTooltipText() {
19
- return this.expanded ? 'Collapse' : 'Expand';
37
+ /** Reveals or hides the code. */
38
+ toggle() {
39
+ this.expanded.update((expanded) => !expanded);
20
40
  }
21
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocDemoDisplayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
22
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.6", type: NgDocDemoDisplayerComponent, isStandalone: true, selector: "ng-doc-demo-displayer", inputs: { codeContent: "codeContent", code: "code", language: "language", container: "container", border: "border", expanded: "expanded" }, host: { properties: { "attr.data-ng-doc-border": "this.border" } }, ngImport: i0, template: "@if (container) {\n <div class=\"ng-doc-demo-wrapper\">\n <div class=\"ng-doc-demo-container\">\n <div class=\"ng-doc-demo\">\n <ng-container *ngTemplateOutlet=\"demoTemplate\"></ng-container>\n </div>\n <div class=\"ng-doc-demo-controls\">\n @if (!codeContent) {\n <ng-doc-copy-button [text]=\"code\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n <button\n ng-doc-button-icon\n [rounded]=\"false\"\n (click)=\"expanded = !expanded\"\n [ngDocTooltip]=\"tooltipContent\">\n <ng-template #tooltipContent>\n {{ expandTooltipText }}\n </ng-template>\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </button>\n </div>\n </div>\n <ng-doc-expander [content]=\"codeContent ? codeContent : expanderContent\" [expanded]=\"expanded\">\n <ng-template #expanderContent>\n <ng-doc-code [copyButton]=\"false\">\n <div [ngDocHighlighter]=\"code\"></div>\n </ng-doc-code>\n </ng-template>\n </ng-doc-expander>\n </div>\n} @else {\n <ng-content></ng-content>\n}\n\n<ng-template #demoTemplate>\n <ng-content></ng-content>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;overflow:hidden;--ng-doc-code-margin: 0;--ng-doc-code-border-radius: 0;--ng-doc-code-border: none}:host[data-ng-doc-border=true]{border:var(--ng-doc-demo-displayer-border);border-radius:var(--ng-doc-demo-displayer-border-radius)}:host .ng-doc-demo-wrapper{overflow:hidden}:host .ng-doc-demo-wrapper .ng-doc-demo-container{display:flex;justify-content:flex-start;width:100%;padding:calc(var(--ng-doc-base-gutter) * 2);background:var(--ng-doc-demo-displayer-background, var(--ng-doc-base-0))}:host .ng-doc-demo-wrapper .ng-doc-demo-container .ng-doc-demo{overflow:hidden;width:100%}:host .ng-doc-demo-wrapper .ng-doc-demo-container .ng-doc-demo-controls{flex-shrink:0;margin-left:auto}:host ng-doc-code{border-top:1px solid var(--ng-doc-border-color)}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocExpanderComponent, selector: "ng-doc-expander", inputs: ["expanded", "content", "collapseMod"] }, { kind: "component", type: NgDocCodeComponent, selector: "ng-doc-code", inputs: ["html", "copyButton", "name", "icon"] }, { kind: "directive", type: NgDocCodeHighlighterDirective, selector: "[ngDocHighlighter]", inputs: ["ngDocHighlighter"] }, { kind: "component", type: NgDocCopyButtonComponent, selector: "ng-doc-copy-button", inputs: ["text"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocDemoDisplayerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
42
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocDemoDisplayerComponent, isStandalone: true, selector: "ng-doc-demo-displayer", inputs: { codeContent: { classPropertyName: "codeContent", publicName: "codeContent", isSignal: true, isRequired: false, transformFunction: null }, code: { classPropertyName: "code", publicName: "code", isSignal: true, isRequired: false, transformFunction: null }, language: { classPropertyName: "language", publicName: "language", isSignal: true, isRequired: false, transformFunction: null }, container: { classPropertyName: "container", publicName: "container", isSignal: true, isRequired: false, transformFunction: null }, border: { classPropertyName: "border", publicName: "border", isSignal: true, isRequired: false, transformFunction: null }, expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange" }, host: { properties: { "attr.data-ng-doc-border": "border()" } }, ngImport: i0, template: "@if (container()) {\n <div class=\"ng-doc-demo-wrapper\">\n <div class=\"ng-doc-demo-container\">\n <div class=\"ng-doc-demo\">\n <ng-container *ngTemplateOutlet=\"demoTemplate\"></ng-container>\n </div>\n <div class=\"ng-doc-demo-controls\">\n @if (!codeContent()) {\n <ng-doc-copy-button [text]=\"code()\" label=\"Copy code\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n <button\n type=\"button\"\n ng-doc-button-icon\n class=\"ng-doc-demo-code-toggle\"\n [rounded]=\"false\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"codeId\"\n [attr.aria-label]=\"expanded() ? 'Hide code' : 'Show code'\"\n (click)=\"toggle()\"\n [ngDocTooltip]=\"expanded() ? 'Hide code' : 'Show code'\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </button>\n </div>\n </div>\n <div\n class=\"ng-doc-demo-code\"\n [id]=\"codeId\"\n [attr.role]=\"expanded() ? 'region' : null\"\n [attr.aria-label]=\"expanded() ? 'Code' : null\">\n <ng-doc-expander\n [content]=\"codeContent() ? codeContent() : expanderContent\"\n [expanded]=\"expanded()\">\n <ng-template #expanderContent>\n <ng-doc-code [copyButton]=\"false\">\n <div [ngDocHighlighter]=\"code()\"></div>\n </ng-doc-code>\n </ng-template>\n </ng-doc-expander>\n </div>\n </div>\n} @else {\n <ng-content></ng-content>\n}\n\n<ng-template #demoTemplate>\n <ng-content></ng-content>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;overflow:hidden;--ng-doc-code-margin: 0;--ng-doc-code-border-radius: 0;--ng-doc-code-border: none}:host[data-ng-doc-border=true]{border:var(--ng-doc-demo-displayer-border);border-radius:var(--ng-doc-demo-displayer-border-radius)}:host[data-ng-doc-border=true] .ng-doc-demo-container{background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-demo-wrapper{display:flex;flex:1 1 auto;flex-direction:column}.ng-doc-demo-container{position:relative;flex:1 1 auto;background-image:radial-gradient(color-mix(in srgb,var(--ng-doc-base-5) 55%,transparent) 1px,transparent 1px);background-size:16px 16px;display:flex;align-items:center;justify-content:center;min-height:64px;padding:var(--ng-doc-space-3) 84px}.ng-doc-demo{display:flex;justify-content:center;min-width:0}.ng-doc-demo-controls{position:absolute;top:var(--ng-doc-space-4);right:var(--ng-doc-space-3);display:flex;gap:2px}.ng-doc-demo-code-toggle[aria-expanded=true]{background:var(--ng-doc-primary-soft);--ng-doc-icon-color: var(--ng-doc-primary-strong)}.ng-doc-demo-code ng-doc-expander{background:var(--ng-doc-code-background)}ng-doc-code{border-top:1px solid var(--ng-doc-border-color)}@container ng-doc-playground (max-width: 640px){.ng-doc-demo-container{justify-content:flex-start;padding:var(--ng-doc-space-3) 84px var(--ng-doc-space-3) var(--ng-doc-space-4)}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocExpanderComponent, selector: "ng-doc-expander", inputs: ["expanded", "content", "collapseMod"], outputs: ["expandedChange"] }, { kind: "component", type: NgDocCodeComponent, selector: "ng-doc-code", inputs: ["html", "copyButton", "name", "icon"] }, { kind: "directive", type: NgDocCodeHighlighterDirective, selector: "[ngDocHighlighter]", inputs: ["ngDocHighlighter"] }, { kind: "component", type: NgDocCopyButtonComponent, selector: "ng-doc-copy-button", inputs: ["text", "label"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
23
43
  }
24
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImport: i0, type: NgDocDemoDisplayerComponent, decorators: [{
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocDemoDisplayerComponent, decorators: [{
25
45
  type: Component,
26
46
  args: [{ selector: 'ng-doc-demo-displayer', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
27
47
  NgTemplateOutlet,
@@ -32,23 +52,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.6", ngImpor
32
52
  NgDocCodeComponent,
33
53
  NgDocCodeHighlighterDirective,
34
54
  NgDocCopyButtonComponent,
35
- ], template: "@if (container) {\n <div class=\"ng-doc-demo-wrapper\">\n <div class=\"ng-doc-demo-container\">\n <div class=\"ng-doc-demo\">\n <ng-container *ngTemplateOutlet=\"demoTemplate\"></ng-container>\n </div>\n <div class=\"ng-doc-demo-controls\">\n @if (!codeContent) {\n <ng-doc-copy-button [text]=\"code\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n <button\n ng-doc-button-icon\n [rounded]=\"false\"\n (click)=\"expanded = !expanded\"\n [ngDocTooltip]=\"tooltipContent\">\n <ng-template #tooltipContent>\n {{ expandTooltipText }}\n </ng-template>\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </button>\n </div>\n </div>\n <ng-doc-expander [content]=\"codeContent ? codeContent : expanderContent\" [expanded]=\"expanded\">\n <ng-template #expanderContent>\n <ng-doc-code [copyButton]=\"false\">\n <div [ngDocHighlighter]=\"code\"></div>\n </ng-doc-code>\n </ng-template>\n </ng-doc-expander>\n </div>\n} @else {\n <ng-content></ng-content>\n}\n\n<ng-template #demoTemplate>\n <ng-content></ng-content>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;overflow:hidden;--ng-doc-code-margin: 0;--ng-doc-code-border-radius: 0;--ng-doc-code-border: none}:host[data-ng-doc-border=true]{border:var(--ng-doc-demo-displayer-border);border-radius:var(--ng-doc-demo-displayer-border-radius)}:host .ng-doc-demo-wrapper{overflow:hidden}:host .ng-doc-demo-wrapper .ng-doc-demo-container{display:flex;justify-content:flex-start;width:100%;padding:calc(var(--ng-doc-base-gutter) * 2);background:var(--ng-doc-demo-displayer-background, var(--ng-doc-base-0))}:host .ng-doc-demo-wrapper .ng-doc-demo-container .ng-doc-demo{overflow:hidden;width:100%}:host .ng-doc-demo-wrapper .ng-doc-demo-container .ng-doc-demo-controls{flex-shrink:0;margin-left:auto}:host ng-doc-code{border-top:1px solid var(--ng-doc-border-color)}\n"] }]
36
- }], propDecorators: { codeContent: [{
37
- type: Input
38
- }], code: [{
39
- type: Input
40
- }], language: [{
41
- type: Input
42
- }], container: [{
43
- type: Input
44
- }], border: [{
45
- type: Input
46
- }, {
47
- type: HostBinding,
48
- args: ['attr.data-ng-doc-border']
49
- }], expanded: [{
50
- type: Input
51
- }] } });
55
+ ], host: {
56
+ '[attr.data-ng-doc-border]': 'border()',
57
+ }, template: "@if (container()) {\n <div class=\"ng-doc-demo-wrapper\">\n <div class=\"ng-doc-demo-container\">\n <div class=\"ng-doc-demo\">\n <ng-container *ngTemplateOutlet=\"demoTemplate\"></ng-container>\n </div>\n <div class=\"ng-doc-demo-controls\">\n @if (!codeContent()) {\n <ng-doc-copy-button [text]=\"code()\" label=\"Copy code\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n <button\n type=\"button\"\n ng-doc-button-icon\n class=\"ng-doc-demo-code-toggle\"\n [rounded]=\"false\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"codeId\"\n [attr.aria-label]=\"expanded() ? 'Hide code' : 'Show code'\"\n (click)=\"toggle()\"\n [ngDocTooltip]=\"expanded() ? 'Hide code' : 'Show code'\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </button>\n </div>\n </div>\n <div\n class=\"ng-doc-demo-code\"\n [id]=\"codeId\"\n [attr.role]=\"expanded() ? 'region' : null\"\n [attr.aria-label]=\"expanded() ? 'Code' : null\">\n <ng-doc-expander\n [content]=\"codeContent() ? codeContent() : expanderContent\"\n [expanded]=\"expanded()\">\n <ng-template #expanderContent>\n <ng-doc-code [copyButton]=\"false\">\n <div [ngDocHighlighter]=\"code()\"></div>\n </ng-doc-code>\n </ng-template>\n </ng-doc-expander>\n </div>\n </div>\n} @else {\n <ng-content></ng-content>\n}\n\n<ng-template #demoTemplate>\n <ng-content></ng-content>\n</ng-template>\n", styles: [":host{display:flex;flex-direction:column;overflow:hidden;--ng-doc-code-margin: 0;--ng-doc-code-border-radius: 0;--ng-doc-code-border: none}:host[data-ng-doc-border=true]{border:var(--ng-doc-demo-displayer-border);border-radius:var(--ng-doc-demo-displayer-border-radius)}:host[data-ng-doc-border=true] .ng-doc-demo-container{background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-demo-wrapper{display:flex;flex:1 1 auto;flex-direction:column}.ng-doc-demo-container{position:relative;flex:1 1 auto;background-image:radial-gradient(color-mix(in srgb,var(--ng-doc-base-5) 55%,transparent) 1px,transparent 1px);background-size:16px 16px;display:flex;align-items:center;justify-content:center;min-height:64px;padding:var(--ng-doc-space-3) 84px}.ng-doc-demo{display:flex;justify-content:center;min-width:0}.ng-doc-demo-controls{position:absolute;top:var(--ng-doc-space-4);right:var(--ng-doc-space-3);display:flex;gap:2px}.ng-doc-demo-code-toggle[aria-expanded=true]{background:var(--ng-doc-primary-soft);--ng-doc-icon-color: var(--ng-doc-primary-strong)}.ng-doc-demo-code ng-doc-expander{background:var(--ng-doc-code-background)}ng-doc-code{border-top:1px solid var(--ng-doc-border-color)}@container ng-doc-playground (max-width: 640px){.ng-doc-demo-container{justify-content:flex-start;padding:var(--ng-doc-space-3) 84px var(--ng-doc-space-3) var(--ng-doc-space-4)}}\n"] }]
58
+ }], propDecorators: { codeContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "codeContent", required: false }] }], code: [{ type: i0.Input, args: [{ isSignal: true, alias: "code", required: false }] }], language: [{ type: i0.Input, args: [{ isSignal: true, alias: "language", required: false }] }], container: [{ type: i0.Input, args: [{ isSignal: true, alias: "container", required: false }] }], border: [{ type: i0.Input, args: [{ isSignal: true, alias: "border", required: false }] }], expanded: [{ type: i0.Input, args: [{ isSignal: true, alias: "expanded", required: false }] }, { type: i0.Output, args: ["expandedChange"] }] } });
52
59
 
53
60
  /**
54
61
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-demo-displayer.mjs","sources":["../../../../libs/app/components/demo-displayer/demo-displayer.component.ts","../../../../libs/app/components/demo-displayer/demo-displayer.component.html","../../../../libs/app/components/demo-displayer/ng-doc-app-components-demo-displayer.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, HostBinding, Input } from '@angular/core';\nimport { NgDocCodeComponent } from '@ng-doc/app/components/code';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { NgDocCodeHighlighterDirective } from '@ng-doc/app/directives/code-highlighter';\nimport {\n NgDocButtonIconComponent,\n NgDocContent,\n NgDocExpanderComponent,\n NgDocIconComponent,\n NgDocTooltipDirective,\n} from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-demo-displayer',\n templateUrl: './demo-displayer.component.html',\n styleUrls: ['./demo-displayer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgTemplateOutlet,\n NgDocButtonIconComponent,\n NgDocTooltipDirective,\n NgDocIconComponent,\n NgDocExpanderComponent,\n NgDocCodeComponent,\n NgDocCodeHighlighterDirective,\n NgDocCopyButtonComponent,\n ],\n})\nexport class NgDocDemoDisplayerComponent {\n @Input()\n codeContent: NgDocContent = '';\n\n @Input()\n code: string = '';\n\n @Input()\n language: string = 'typescript';\n\n @Input()\n container: boolean = true;\n\n @Input()\n @HostBinding('attr.data-ng-doc-border')\n border: boolean = true;\n\n @Input()\n expanded: boolean = false;\n\n protected get expandTooltipText(): string {\n return this.expanded ? 'Collapse' : 'Expand';\n }\n}\n","@if (container) {\n <div class=\"ng-doc-demo-wrapper\">\n <div class=\"ng-doc-demo-container\">\n <div class=\"ng-doc-demo\">\n <ng-container *ngTemplateOutlet=\"demoTemplate\"></ng-container>\n </div>\n <div class=\"ng-doc-demo-controls\">\n @if (!codeContent) {\n <ng-doc-copy-button [text]=\"code\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n <button\n ng-doc-button-icon\n [rounded]=\"false\"\n (click)=\"expanded = !expanded\"\n [ngDocTooltip]=\"tooltipContent\">\n <ng-template #tooltipContent>\n {{ expandTooltipText }}\n </ng-template>\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </button>\n </div>\n </div>\n <ng-doc-expander [content]=\"codeContent ? codeContent : expanderContent\" [expanded]=\"expanded\">\n <ng-template #expanderContent>\n <ng-doc-code [copyButton]=\"false\">\n <div [ngDocHighlighter]=\"code\"></div>\n </ng-doc-code>\n </ng-template>\n </ng-doc-expander>\n </div>\n} @else {\n <ng-content></ng-content>\n}\n\n<ng-template #demoTemplate>\n <ng-content></ng-content>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ng-doc-app-components-demo-displayer.mjs","sources":["../../../../libs/app/components/demo-displayer/demo-displayer.component.ts","../../../../libs/app/components/demo-displayer/demo-displayer.component.html","../../../../libs/app/components/demo-displayer/ng-doc-app-components-demo-displayer.ts"],"sourcesContent":["import { NgTemplateOutlet } from '@angular/common';\nimport { ChangeDetectionStrategy, Component, input, model } from '@angular/core';\nimport { NgDocCodeComponent } from '@ng-doc/app/components/code';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { NgDocCodeHighlighterDirective } from '@ng-doc/app/directives/code-highlighter';\nimport {\n NgDocButtonIconComponent,\n NgDocContent,\n NgDocExpanderComponent,\n NgDocIconComponent,\n NgDocTooltipDirective,\n} from '@ng-doc/ui-kit';\n\nlet nextId = 0;\n\n/**\n * A demo on the dot-grid stage with a copy button and a toggle that reveals its code below it\n * (the rows of a playground use it).\n */\n@Component({\n selector: 'ng-doc-demo-displayer',\n templateUrl: './demo-displayer.component.html',\n styleUrls: ['./demo-displayer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgTemplateOutlet,\n NgDocButtonIconComponent,\n NgDocTooltipDirective,\n NgDocIconComponent,\n NgDocExpanderComponent,\n NgDocCodeComponent,\n NgDocCodeHighlighterDirective,\n NgDocCopyButtonComponent,\n ],\n host: {\n '[attr.data-ng-doc-border]': 'border()',\n },\n})\nexport class NgDocDemoDisplayerComponent {\n /** Content shown when the code is revealed; when empty, the highlighted `code` is shown. */\n readonly codeContent = input<NgDocContent>('');\n\n /** Code of the demo, copied by the copy button and shown when there is no `codeContent`. */\n readonly code = input<string>('');\n\n /** Language of `code`. */\n readonly language = input<string>('typescript');\n\n /** Whether the demo is shown in the stage with its controls; otherwise it is shown as is. */\n readonly container = input<boolean>(true);\n\n /** Whether the displayer draws its border. */\n readonly border = input<boolean>(true);\n\n /** Whether the code is revealed. */\n readonly expanded = model<boolean>(false);\n\n /** Id of the region that holds the code, for the toggle's `aria-controls`. */\n protected readonly codeId: string = `ng-doc-demo-displayer-code-${nextId++}`;\n\n /** Reveals or hides the code. */\n toggle(): void {\n this.expanded.update((expanded: boolean) => !expanded);\n }\n}\n","@if (container()) {\n <div class=\"ng-doc-demo-wrapper\">\n <div class=\"ng-doc-demo-container\">\n <div class=\"ng-doc-demo\">\n <ng-container *ngTemplateOutlet=\"demoTemplate\"></ng-container>\n </div>\n <div class=\"ng-doc-demo-controls\">\n @if (!codeContent()) {\n <ng-doc-copy-button [text]=\"code()\" label=\"Copy code\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n <button\n type=\"button\"\n ng-doc-button-icon\n class=\"ng-doc-demo-code-toggle\"\n [rounded]=\"false\"\n [attr.aria-expanded]=\"expanded()\"\n [attr.aria-controls]=\"codeId\"\n [attr.aria-label]=\"expanded() ? 'Hide code' : 'Show code'\"\n (click)=\"toggle()\"\n [ngDocTooltip]=\"expanded() ? 'Hide code' : 'Show code'\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </button>\n </div>\n </div>\n <div\n class=\"ng-doc-demo-code\"\n [id]=\"codeId\"\n [attr.role]=\"expanded() ? 'region' : null\"\n [attr.aria-label]=\"expanded() ? 'Code' : null\">\n <ng-doc-expander\n [content]=\"codeContent() ? codeContent() : expanderContent\"\n [expanded]=\"expanded()\">\n <ng-template #expanderContent>\n <ng-doc-code [copyButton]=\"false\">\n <div [ngDocHighlighter]=\"code()\"></div>\n </ng-doc-code>\n </ng-template>\n </ng-doc-expander>\n </div>\n </div>\n} @else {\n <ng-content></ng-content>\n}\n\n<ng-template #demoTemplate>\n <ng-content></ng-content>\n</ng-template>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,96 @@
1
+ import * as i0 from '@angular/core';
2
+ import { input, signal, computed, inject, viewChild, afterNextRender, DestroyRef, ChangeDetectionStrategy, Component } from '@angular/core';
3
+ import { DomSanitizer } from '@angular/platform-browser';
4
+ import { ɵisNgDocDemoSizeMessage as _isNgDocDemoSizeMessage } from '@ng-doc/app/demo-app';
5
+
6
+ /** How long a loaded demo page may take to report its size before the frame reports a failure. */
7
+ const READY_TIMEOUT_MS = 10_000;
8
+ /**
9
+ * Shows a demo page of the demo application in an iframe, as tall as the demo's content: the demo
10
+ * page reports its height with `postMessage`, and only messages from this iframe's window and
11
+ * origin are accepted. The iframe is created in the browser after the first render (the server
12
+ * renders a placeholder with a link to the demo page) and loads lazily. Until the demo reports its
13
+ * size, a placeholder tells that it is loading; a demo page that loads without reporting it within
14
+ * 10 seconds is reported as failed, with the link.
15
+ */
16
+ class NgDocDemoFrameComponent {
17
+ constructor() {
18
+ /** The URL of the demo page, relative to the document or absolute on its origin. */
19
+ this.src = input.required(/* @ts-ignore */
20
+ ...(ngDevMode ? [{ debugName: "src" }] : /* istanbul ignore next */ []));
21
+ /** The accessible title of the iframe. */
22
+ this.frameTitle = input.required(/* @ts-ignore */
23
+ ...(ngDevMode ? [{ debugName: "frameTitle" }] : /* istanbul ignore next */ []));
24
+ /** Whether the iframe fills its container instead of taking the demo's height (fullscreen). */
25
+ this.fill = input(false, /* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "fill" }] : /* istanbul ignore next */ []));
27
+ /** The height the demo reported, in pixels. */
28
+ this.height = signal(undefined, /* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "height" }] : /* istanbul ignore next */ []));
30
+ /** `loading` until the demo reports its size, then `ready`; `failed` when it never does. */
31
+ this.state = computed(() => this.height() !== undefined ? 'ready' : this.failed() ? 'failed' : 'loading', /* @ts-ignore */
32
+ ...(ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []));
33
+ /** Whether the iframe exists: only in the browser, after the first render. */
34
+ this.created = signal(false, /* @ts-ignore */
35
+ ...(ngDevMode ? [{ debugName: "created" }] : /* istanbul ignore next */ []));
36
+ /** The demo page's URL for the iframe. */
37
+ this.frameSrc = computed(() =>
38
+ // The URL comes from the generated demo route and the demo's name: a page of this site.
39
+ this.sanitizer.bypassSecurityTrustResourceUrl(this.src()), /* @ts-ignore */
40
+ ...(ngDevMode ? [{ debugName: "frameSrc" }] : /* istanbul ignore next */ []));
41
+ this.sanitizer = inject(DomSanitizer);
42
+ this.frame = viewChild('frame', /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "frame" }] : /* istanbul ignore next */ []));
44
+ this.failed = signal(false, /* @ts-ignore */
45
+ ...(ngDevMode ? [{ debugName: "failed" }] : /* istanbul ignore next */ []));
46
+ afterNextRender(() => this.created.set(true));
47
+ inject(DestroyRef).onDestroy(() => clearTimeout(this.timer));
48
+ }
49
+ /**
50
+ * Waits for the demo's size once its page has loaded.
51
+ * @internal
52
+ */
53
+ onLoad() {
54
+ clearTimeout(this.timer);
55
+ if (this.height() !== undefined)
56
+ return;
57
+ this.timer = setTimeout(() => this.failed.set(this.height() === undefined), READY_TIMEOUT_MS);
58
+ }
59
+ /**
60
+ * Takes the height a demo page reports, from this iframe only.
61
+ * @param event - A message to the window.
62
+ * @internal
63
+ */
64
+ onMessage(event) {
65
+ const frame = this.frame()?.nativeElement;
66
+ if (!frame?.contentWindow ||
67
+ event.source !== frame.contentWindow ||
68
+ event.origin !== new URL(frame.src, frame.baseURI).origin ||
69
+ !_isNgDocDemoSizeMessage(event.data)) {
70
+ return;
71
+ }
72
+ // The first message comes before the demo has rendered, with no height yet.
73
+ if (event.data.height === 0 && this.height() === undefined)
74
+ return;
75
+ clearTimeout(this.timer);
76
+ this.failed.set(false);
77
+ this.height.set(event.data.height);
78
+ }
79
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocDemoFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
80
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocDemoFrameComponent, isStandalone: true, selector: "ng-doc-demo-frame", inputs: { src: { classPropertyName: "src", publicName: "src", isSignal: true, isRequired: true, transformFunction: null }, frameTitle: { classPropertyName: "frameTitle", publicName: "frameTitle", isSignal: true, isRequired: true, transformFunction: null }, fill: { classPropertyName: "fill", publicName: "fill", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "window:message": "onMessage($event)" }, properties: { "attr.data-ng-doc-state": "state()", "attr.data-ng-doc-fill": "fill()" } }, viewQueries: [{ propertyName: "frame", first: true, predicate: ["frame"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (created()) {\n <iframe\n #frame\n class=\"ng-doc-demo-frame-iframe\"\n loading=\"lazy\"\n [src]=\"frameSrc()\"\n [title]=\"frameTitle()\"\n [style.height.px]=\"fill() ? null : height()\"\n (load)=\"onLoad()\"></iframe>\n}\n@if (state() !== 'ready') {\n <div class=\"ng-doc-demo-frame-status\" role=\"status\" [attr.aria-busy]=\"state() === 'loading'\">\n @if (state() === 'loading') {\n <span class=\"ng-doc-demo-frame-skeleton\" aria-hidden=\"true\"></span>\n <span\n >Loading the demo.\n <a [href]=\"src()\" target=\"_blank\" rel=\"noopener\">Open it in a new tab</a></span\n >\n } @else {\n <span\n >The demo did not load.\n <a [href]=\"src()\" target=\"_blank\" rel=\"noopener\">Open it in a new tab</a></span\n >\n }\n </div>\n}\n", styles: [":host{position:relative;display:block;width:100%}.ng-doc-demo-frame-iframe{display:block;width:100%;border:0;background:transparent;color-scheme:normal}:host(:not([data-ng-doc-state=ready])) .ng-doc-demo-frame-iframe{position:absolute;inset:0;height:100%;opacity:0;pointer-events:none}:host([data-ng-doc-fill=true]){height:100%}:host([data-ng-doc-fill=true]) .ng-doc-demo-frame-iframe{height:100%}.ng-doc-demo-frame-status{display:flex;flex-direction:column;align-items:center;gap:var(--ng-doc-space-3);padding:var(--ng-doc-space-4);font-size:13px;color:var(--ng-doc-text-muted);text-align:center}.ng-doc-demo-frame-skeleton{width:min(240px,100%);height:32px;border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-base-2);animation:ng-doc-demo-frame-pulse 1.2s ease-in-out infinite alternate}@keyframes ng-doc-demo-frame-pulse{0%{opacity:.5}to{opacity:1}}@media(prefers-reduced-motion:reduce){.ng-doc-demo-frame-skeleton{animation:none}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
81
+ }
82
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocDemoFrameComponent, decorators: [{
83
+ type: Component,
84
+ args: [{ selector: 'ng-doc-demo-frame', changeDetection: ChangeDetectionStrategy.OnPush, host: {
85
+ '[attr.data-ng-doc-state]': 'state()',
86
+ '[attr.data-ng-doc-fill]': 'fill()',
87
+ '(window:message)': 'onMessage($event)',
88
+ }, template: "@if (created()) {\n <iframe\n #frame\n class=\"ng-doc-demo-frame-iframe\"\n loading=\"lazy\"\n [src]=\"frameSrc()\"\n [title]=\"frameTitle()\"\n [style.height.px]=\"fill() ? null : height()\"\n (load)=\"onLoad()\"></iframe>\n}\n@if (state() !== 'ready') {\n <div class=\"ng-doc-demo-frame-status\" role=\"status\" [attr.aria-busy]=\"state() === 'loading'\">\n @if (state() === 'loading') {\n <span class=\"ng-doc-demo-frame-skeleton\" aria-hidden=\"true\"></span>\n <span\n >Loading the demo.\n <a [href]=\"src()\" target=\"_blank\" rel=\"noopener\">Open it in a new tab</a></span\n >\n } @else {\n <span\n >The demo did not load.\n <a [href]=\"src()\" target=\"_blank\" rel=\"noopener\">Open it in a new tab</a></span\n >\n }\n </div>\n}\n", styles: [":host{position:relative;display:block;width:100%}.ng-doc-demo-frame-iframe{display:block;width:100%;border:0;background:transparent;color-scheme:normal}:host(:not([data-ng-doc-state=ready])) .ng-doc-demo-frame-iframe{position:absolute;inset:0;height:100%;opacity:0;pointer-events:none}:host([data-ng-doc-fill=true]){height:100%}:host([data-ng-doc-fill=true]) .ng-doc-demo-frame-iframe{height:100%}.ng-doc-demo-frame-status{display:flex;flex-direction:column;align-items:center;gap:var(--ng-doc-space-3);padding:var(--ng-doc-space-4);font-size:13px;color:var(--ng-doc-text-muted);text-align:center}.ng-doc-demo-frame-skeleton{width:min(240px,100%);height:32px;border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-base-2);animation:ng-doc-demo-frame-pulse 1.2s ease-in-out infinite alternate}@keyframes ng-doc-demo-frame-pulse{0%{opacity:.5}to{opacity:1}}@media(prefers-reduced-motion:reduce){.ng-doc-demo-frame-skeleton{animation:none}}\n"] }]
89
+ }], ctorParameters: () => [], propDecorators: { src: [{ type: i0.Input, args: [{ isSignal: true, alias: "src", required: true }] }], frameTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "frameTitle", required: true }] }], fill: [{ type: i0.Input, args: [{ isSignal: true, alias: "fill", required: false }] }], frame: [{ type: i0.ViewChild, args: ['frame', { isSignal: true }] }] } });
90
+
91
+ /**
92
+ * Generated bundle index. Do not edit.
93
+ */
94
+
95
+ export { NgDocDemoFrameComponent };
96
+ //# sourceMappingURL=ng-doc-app-components-demo-frame.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ng-doc-app-components-demo-frame.mjs","sources":["../../../../libs/app/components/demo-frame/demo-frame.component.ts","../../../../libs/app/components/demo-frame/demo-frame.component.html","../../../../libs/app/components/demo-frame/ng-doc-app-components-demo-frame.ts"],"sourcesContent":["import {\n afterNextRender,\n ChangeDetectionStrategy,\n Component,\n computed,\n DestroyRef,\n ElementRef,\n inject,\n input,\n Signal,\n signal,\n viewChild,\n} from '@angular/core';\nimport { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';\nimport { ɵisNgDocDemoSizeMessage } from '@ng-doc/app/demo-app';\n\n/** How long a loaded demo page may take to report its size before the frame reports a failure. */\nconst READY_TIMEOUT_MS = 10_000;\n\n/**\n * Shows a demo page of the demo application in an iframe, as tall as the demo's content: the demo\n * page reports its height with `postMessage`, and only messages from this iframe's window and\n * origin are accepted. The iframe is created in the browser after the first render (the server\n * renders a placeholder with a link to the demo page) and loads lazily. Until the demo reports its\n * size, a placeholder tells that it is loading; a demo page that loads without reporting it within\n * 10 seconds is reported as failed, with the link.\n */\n@Component({\n selector: 'ng-doc-demo-frame',\n templateUrl: './demo-frame.component.html',\n styleUrls: ['./demo-frame.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-ng-doc-state]': 'state()',\n '[attr.data-ng-doc-fill]': 'fill()',\n '(window:message)': 'onMessage($event)',\n },\n})\nexport class NgDocDemoFrameComponent {\n /** The URL of the demo page, relative to the document or absolute on its origin. */\n readonly src = input.required<string>();\n\n /** The accessible title of the iframe. */\n readonly frameTitle = input.required<string>();\n\n /** Whether the iframe fills its container instead of taking the demo's height (fullscreen). */\n readonly fill = input<boolean>(false);\n\n /** The height the demo reported, in pixels. */\n readonly height = signal<number | undefined>(undefined);\n\n /** `loading` until the demo reports its size, then `ready`; `failed` when it never does. */\n readonly state: Signal<'loading' | 'ready' | 'failed'> = computed(() =>\n this.height() !== undefined ? 'ready' : this.failed() ? 'failed' : 'loading',\n );\n\n /** Whether the iframe exists: only in the browser, after the first render. */\n protected readonly created = signal(false);\n\n /** The demo page's URL for the iframe. */\n protected readonly frameSrc: Signal<SafeResourceUrl> = computed(() =>\n // The URL comes from the generated demo route and the demo's name: a page of this site.\n this.sanitizer.bypassSecurityTrustResourceUrl(this.src()),\n );\n\n private readonly sanitizer = inject(DomSanitizer);\n private readonly frame = viewChild<ElementRef<HTMLIFrameElement>>('frame');\n private readonly failed = signal(false);\n private timer?: ReturnType<typeof setTimeout>;\n\n constructor() {\n afterNextRender(() => this.created.set(true));\n inject(DestroyRef).onDestroy(() => clearTimeout(this.timer));\n }\n\n /**\n * Waits for the demo's size once its page has loaded.\n * @internal\n */\n protected onLoad(): void {\n clearTimeout(this.timer);\n if (this.height() !== undefined) return;\n this.timer = setTimeout(() => this.failed.set(this.height() === undefined), READY_TIMEOUT_MS);\n }\n\n /**\n * Takes the height a demo page reports, from this iframe only.\n * @param event - A message to the window.\n * @internal\n */\n protected onMessage(event: MessageEvent): void {\n const frame = this.frame()?.nativeElement;\n\n if (\n !frame?.contentWindow ||\n event.source !== frame.contentWindow ||\n event.origin !== new URL(frame.src, frame.baseURI).origin ||\n !ɵisNgDocDemoSizeMessage(event.data)\n ) {\n return;\n }\n // The first message comes before the demo has rendered, with no height yet.\n if (event.data.height === 0 && this.height() === undefined) return;\n clearTimeout(this.timer);\n this.failed.set(false);\n this.height.set(event.data.height);\n }\n}\n","@if (created()) {\n <iframe\n #frame\n class=\"ng-doc-demo-frame-iframe\"\n loading=\"lazy\"\n [src]=\"frameSrc()\"\n [title]=\"frameTitle()\"\n [style.height.px]=\"fill() ? null : height()\"\n (load)=\"onLoad()\"></iframe>\n}\n@if (state() !== 'ready') {\n <div class=\"ng-doc-demo-frame-status\" role=\"status\" [attr.aria-busy]=\"state() === 'loading'\">\n @if (state() === 'loading') {\n <span class=\"ng-doc-demo-frame-skeleton\" aria-hidden=\"true\"></span>\n <span\n >Loading the demo.\n <a [href]=\"src()\" target=\"_blank\" rel=\"noopener\">Open it in a new tab</a></span\n >\n } @else {\n <span\n >The demo did not load.\n <a [href]=\"src()\" target=\"_blank\" rel=\"noopener\">Open it in a new tab</a></span\n >\n }\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵisNgDocDemoSizeMessage"],"mappings":"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"}