ngwr 14.7.0 → 14.9.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 (482) hide show
  1. package/README.md +66 -332
  2. package/alert/styles/_index.scss +10 -0
  3. package/avatar/styles/_index.scss +18 -7
  4. package/badge/styles/_index.scss +7 -0
  5. package/badge/styles/_tag.scss +7 -1
  6. package/bar-chart/styles/_index.scss +1 -0
  7. package/button/styles/_index.scss +6 -0
  8. package/calendar-heatmap/styles/_index.scss +1 -0
  9. package/cascader/styles/_rules.scss +87 -15
  10. package/checkbox/styles/_index.scss +4 -0
  11. package/command-palette/styles/_index.scss +1 -1
  12. package/date-picker/styles/_index.scss +30 -0
  13. package/density/styles/_index.scss +4 -2
  14. package/divider/styles/_index.scss +2 -0
  15. package/donut-chart/styles/_index.scss +10 -0
  16. package/dropdown/styles/_index.scss +67 -5
  17. package/editor/styles/_index.scss +441 -0
  18. package/event-calendar/styles/_index.scss +209 -35
  19. package/fesm2022/ngwr-action-sheet-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-action-sheet.mjs +3 -3
  21. package/fesm2022/ngwr-action-sheet.mjs.map +1 -1
  22. package/fesm2022/ngwr-affix.mjs +3 -3
  23. package/fesm2022/ngwr-affix.mjs.map +1 -1
  24. package/fesm2022/ngwr-alert.mjs +3 -3
  25. package/fesm2022/ngwr-alert.mjs.map +1 -1
  26. package/fesm2022/ngwr-anchor.mjs +3 -3
  27. package/fesm2022/ngwr-anchor.mjs.map +1 -1
  28. package/fesm2022/ngwr-aurora.mjs +3 -3
  29. package/fesm2022/ngwr-aurora.mjs.map +1 -1
  30. package/fesm2022/ngwr-avatar.mjs +3 -3
  31. package/fesm2022/ngwr-avatar.mjs.map +1 -1
  32. package/fesm2022/ngwr-back-top.mjs +3 -3
  33. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  34. package/fesm2022/ngwr-badge.mjs +28 -13
  35. package/fesm2022/ngwr-badge.mjs.map +1 -1
  36. package/fesm2022/ngwr-bar-chart-testing.mjs.map +1 -1
  37. package/fesm2022/ngwr-bar-chart.mjs +31 -6
  38. package/fesm2022/ngwr-bar-chart.mjs.map +1 -1
  39. package/fesm2022/ngwr-blur-text-testing.mjs.map +1 -1
  40. package/fesm2022/ngwr-blur-text.mjs +3 -3
  41. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  42. package/fesm2022/ngwr-border-glow-testing.mjs.map +1 -1
  43. package/fesm2022/ngwr-border-glow.mjs +3 -3
  44. package/fesm2022/ngwr-border-glow.mjs.map +1 -1
  45. package/fesm2022/ngwr-breadcrumbs.mjs +6 -6
  46. package/fesm2022/ngwr-breadcrumbs.mjs.map +1 -1
  47. package/fesm2022/ngwr-burger.mjs +3 -3
  48. package/fesm2022/ngwr-burger.mjs.map +1 -1
  49. package/fesm2022/ngwr-button-testing.mjs.map +1 -1
  50. package/fesm2022/ngwr-button.mjs +6 -6
  51. package/fesm2022/ngwr-button.mjs.map +1 -1
  52. package/fesm2022/ngwr-calendar-heatmap-testing.mjs.map +1 -1
  53. package/fesm2022/ngwr-calendar-heatmap.mjs +61 -6
  54. package/fesm2022/ngwr-calendar-heatmap.mjs.map +1 -1
  55. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  56. package/fesm2022/ngwr-calendar.mjs +3 -3
  57. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  58. package/fesm2022/ngwr-card.mjs +9 -9
  59. package/fesm2022/ngwr-card.mjs.map +1 -1
  60. package/fesm2022/ngwr-carousel-testing.mjs.map +1 -1
  61. package/fesm2022/ngwr-carousel.mjs +6 -6
  62. package/fesm2022/ngwr-carousel.mjs.map +1 -1
  63. package/fesm2022/ngwr-cascader-testing.mjs.map +1 -1
  64. package/fesm2022/ngwr-cascader.mjs +4 -4
  65. package/fesm2022/ngwr-cascader.mjs.map +1 -1
  66. package/fesm2022/ngwr-checkbox-testing.mjs.map +1 -1
  67. package/fesm2022/ngwr-checkbox.mjs +18 -8
  68. package/fesm2022/ngwr-checkbox.mjs.map +1 -1
  69. package/fesm2022/ngwr-circular-text-testing.mjs.map +1 -1
  70. package/fesm2022/ngwr-circular-text.mjs +3 -3
  71. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  72. package/fesm2022/ngwr-click-spark.mjs +3 -3
  73. package/fesm2022/ngwr-click-spark.mjs.map +1 -1
  74. package/fesm2022/ngwr-clipboard.mjs +3 -3
  75. package/fesm2022/ngwr-clipboard.mjs.map +1 -1
  76. package/fesm2022/ngwr-collapse-testing.mjs.map +1 -1
  77. package/fesm2022/ngwr-collapse.mjs +9 -9
  78. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  79. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  80. package/fesm2022/ngwr-color-picker.mjs +6 -6
  81. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  82. package/fesm2022/ngwr-command-palette-testing.mjs.map +1 -1
  83. package/fesm2022/ngwr-command-palette.mjs +3 -3
  84. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  85. package/fesm2022/ngwr-compare.mjs +3 -3
  86. package/fesm2022/ngwr-compare.mjs.map +1 -1
  87. package/fesm2022/ngwr-confetti.mjs +3 -3
  88. package/fesm2022/ngwr-confetti.mjs.map +1 -1
  89. package/fesm2022/ngwr-config.mjs.map +1 -1
  90. package/fesm2022/ngwr-context-menu-testing.mjs.map +1 -1
  91. package/fesm2022/ngwr-context-menu.mjs +12 -12
  92. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  93. package/fesm2022/ngwr-cookie.mjs +3 -3
  94. package/fesm2022/ngwr-cookie.mjs.map +1 -1
  95. package/fesm2022/ngwr-counter.mjs +6 -6
  96. package/fesm2022/ngwr-counter.mjs.map +1 -1
  97. package/fesm2022/ngwr-date-adapters-fns.mjs +3 -3
  98. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  99. package/fesm2022/ngwr-date-adapters-luxon.mjs +3 -3
  100. package/fesm2022/ngwr-date-adapters-luxon.mjs.map +1 -1
  101. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  102. package/fesm2022/ngwr-date-picker.mjs +721 -62
  103. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  104. package/fesm2022/ngwr-date.mjs +3 -3
  105. package/fesm2022/ngwr-date.mjs.map +1 -1
  106. package/fesm2022/ngwr-decrypt-text-testing.mjs.map +1 -1
  107. package/fesm2022/ngwr-decrypt-text.mjs +3 -3
  108. package/fesm2022/ngwr-decrypt-text.mjs.map +1 -1
  109. package/fesm2022/ngwr-density.mjs +6 -6
  110. package/fesm2022/ngwr-density.mjs.map +1 -1
  111. package/fesm2022/ngwr-descriptions.mjs +6 -6
  112. package/fesm2022/ngwr-descriptions.mjs.map +1 -1
  113. package/fesm2022/ngwr-dialog-testing.mjs.map +1 -1
  114. package/fesm2022/ngwr-dialog.mjs +15 -15
  115. package/fesm2022/ngwr-dialog.mjs.map +1 -1
  116. package/fesm2022/ngwr-directives.mjs +12 -12
  117. package/fesm2022/ngwr-directives.mjs.map +1 -1
  118. package/fesm2022/ngwr-divider.mjs +3 -3
  119. package/fesm2022/ngwr-divider.mjs.map +1 -1
  120. package/fesm2022/ngwr-donut-chart-testing.mjs.map +1 -1
  121. package/fesm2022/ngwr-donut-chart.mjs +48 -6
  122. package/fesm2022/ngwr-donut-chart.mjs.map +1 -1
  123. package/fesm2022/ngwr-drag-drop.mjs +6 -6
  124. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  125. package/fesm2022/ngwr-drawer-testing.mjs.map +1 -1
  126. package/fesm2022/ngwr-drawer.mjs +18 -18
  127. package/fesm2022/ngwr-drawer.mjs.map +1 -1
  128. package/fesm2022/ngwr-dropdown-testing.mjs.map +1 -1
  129. package/fesm2022/ngwr-dropdown.mjs +174 -25
  130. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  131. package/fesm2022/ngwr-editor-testing.mjs +568 -0
  132. package/fesm2022/ngwr-editor-testing.mjs.map +1 -0
  133. package/fesm2022/ngwr-editor.mjs +2601 -0
  134. package/fesm2022/ngwr-editor.mjs.map +1 -0
  135. package/fesm2022/ngwr-empty.mjs +3 -3
  136. package/fesm2022/ngwr-empty.mjs.map +1 -1
  137. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  138. package/fesm2022/ngwr-event-calendar.mjs +14 -7
  139. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  140. package/fesm2022/ngwr-falling-text-testing.mjs.map +1 -1
  141. package/fesm2022/ngwr-falling-text.mjs +3 -3
  142. package/fesm2022/ngwr-falling-text.mjs.map +1 -1
  143. package/fesm2022/ngwr-file-upload-testing.mjs.map +1 -1
  144. package/fesm2022/ngwr-file-upload.mjs +3 -3
  145. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  146. package/fesm2022/ngwr-form-testing.mjs.map +1 -1
  147. package/fesm2022/ngwr-form.mjs +61 -10
  148. package/fesm2022/ngwr-form.mjs.map +1 -1
  149. package/fesm2022/ngwr-fuzzy-text-testing.mjs.map +1 -1
  150. package/fesm2022/ngwr-fuzzy-text.mjs +3 -3
  151. package/fesm2022/ngwr-fuzzy-text.mjs.map +1 -1
  152. package/fesm2022/ngwr-gauge-testing.mjs.map +1 -1
  153. package/fesm2022/ngwr-gauge.mjs +35 -6
  154. package/fesm2022/ngwr-gauge.mjs.map +1 -1
  155. package/fesm2022/ngwr-glitch-text-testing.mjs.map +1 -1
  156. package/fesm2022/ngwr-glitch-text.mjs +3 -3
  157. package/fesm2022/ngwr-glitch-text.mjs.map +1 -1
  158. package/fesm2022/ngwr-gradient-text-testing.mjs.map +1 -1
  159. package/fesm2022/ngwr-gradient-text.mjs +3 -3
  160. package/fesm2022/ngwr-gradient-text.mjs.map +1 -1
  161. package/fesm2022/ngwr-graph-testing.mjs.map +1 -1
  162. package/fesm2022/ngwr-graph.mjs +6 -6
  163. package/fesm2022/ngwr-graph.mjs.map +1 -1
  164. package/fesm2022/ngwr-hotkey.mjs +6 -6
  165. package/fesm2022/ngwr-hotkey.mjs.map +1 -1
  166. package/fesm2022/ngwr-i18n-ar.mjs +31 -0
  167. package/fesm2022/ngwr-i18n-ar.mjs.map +1 -1
  168. package/fesm2022/ngwr-i18n-cs.mjs +31 -0
  169. package/fesm2022/ngwr-i18n-cs.mjs.map +1 -1
  170. package/fesm2022/ngwr-i18n-de.mjs +31 -0
  171. package/fesm2022/ngwr-i18n-de.mjs.map +1 -1
  172. package/fesm2022/ngwr-i18n-en.mjs +39 -0
  173. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  174. package/fesm2022/ngwr-i18n-es.mjs +31 -0
  175. package/fesm2022/ngwr-i18n-es.mjs.map +1 -1
  176. package/fesm2022/ngwr-i18n-fr.mjs +31 -0
  177. package/fesm2022/ngwr-i18n-fr.mjs.map +1 -1
  178. package/fesm2022/ngwr-i18n-he.mjs +31 -0
  179. package/fesm2022/ngwr-i18n-he.mjs.map +1 -1
  180. package/fesm2022/ngwr-i18n-hi.mjs +31 -0
  181. package/fesm2022/ngwr-i18n-hi.mjs.map +1 -1
  182. package/fesm2022/ngwr-i18n-id.mjs +31 -0
  183. package/fesm2022/ngwr-i18n-id.mjs.map +1 -1
  184. package/fesm2022/ngwr-i18n-it.mjs +31 -0
  185. package/fesm2022/ngwr-i18n-it.mjs.map +1 -1
  186. package/fesm2022/ngwr-i18n-ja.mjs +31 -0
  187. package/fesm2022/ngwr-i18n-ja.mjs.map +1 -1
  188. package/fesm2022/ngwr-i18n-ko.mjs +31 -0
  189. package/fesm2022/ngwr-i18n-ko.mjs.map +1 -1
  190. package/fesm2022/ngwr-i18n-nl.mjs +31 -0
  191. package/fesm2022/ngwr-i18n-nl.mjs.map +1 -1
  192. package/fesm2022/ngwr-i18n-pl.mjs +31 -0
  193. package/fesm2022/ngwr-i18n-pl.mjs.map +1 -1
  194. package/fesm2022/ngwr-i18n-pt.mjs +31 -0
  195. package/fesm2022/ngwr-i18n-pt.mjs.map +1 -1
  196. package/fesm2022/ngwr-i18n-ru.mjs +31 -0
  197. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  198. package/fesm2022/ngwr-i18n-sv.mjs +31 -0
  199. package/fesm2022/ngwr-i18n-sv.mjs.map +1 -1
  200. package/fesm2022/ngwr-i18n-tr.mjs +31 -0
  201. package/fesm2022/ngwr-i18n-tr.mjs.map +1 -1
  202. package/fesm2022/ngwr-i18n-uk.mjs +31 -0
  203. package/fesm2022/ngwr-i18n-uk.mjs.map +1 -1
  204. package/fesm2022/ngwr-i18n-vi.mjs +31 -0
  205. package/fesm2022/ngwr-i18n-vi.mjs.map +1 -1
  206. package/fesm2022/ngwr-i18n-zh-TW.mjs +31 -0
  207. package/fesm2022/ngwr-i18n-zh-TW.mjs.map +1 -1
  208. package/fesm2022/ngwr-i18n-zh.mjs +31 -0
  209. package/fesm2022/ngwr-i18n-zh.mjs.map +1 -1
  210. package/fesm2022/ngwr-i18n.mjs +9 -9
  211. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  212. package/fesm2022/ngwr-icon-adapters-feather.mjs.map +1 -1
  213. package/fesm2022/ngwr-icon-adapters-lucide.mjs.map +1 -1
  214. package/fesm2022/ngwr-icon.mjs +6 -6
  215. package/fesm2022/ngwr-icon.mjs.map +1 -1
  216. package/fesm2022/ngwr-image-cropper-testing.mjs.map +1 -1
  217. package/fesm2022/ngwr-image-cropper.mjs +3 -3
  218. package/fesm2022/ngwr-image-cropper.mjs.map +1 -1
  219. package/fesm2022/ngwr-input-number-testing.mjs.map +1 -1
  220. package/fesm2022/ngwr-input-number.mjs +15 -3
  221. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  222. package/fesm2022/ngwr-input-otp-testing.mjs.map +1 -1
  223. package/fesm2022/ngwr-input-otp.mjs +3 -3
  224. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  225. package/fesm2022/ngwr-input-testing.mjs.map +1 -1
  226. package/fesm2022/ngwr-input.mjs +15 -15
  227. package/fesm2022/ngwr-input.mjs.map +1 -1
  228. package/fesm2022/ngwr-keyboard.mjs +3 -3
  229. package/fesm2022/ngwr-keyboard.mjs.map +1 -1
  230. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  231. package/fesm2022/ngwr-knob.mjs +3 -3
  232. package/fesm2022/ngwr-knob.mjs.map +1 -1
  233. package/fesm2022/ngwr-layout.mjs +15 -15
  234. package/fesm2022/ngwr-layout.mjs.map +1 -1
  235. package/fesm2022/ngwr-lightbox-testing.mjs.map +1 -1
  236. package/fesm2022/ngwr-lightbox.mjs +3 -3
  237. package/fesm2022/ngwr-lightbox.mjs.map +1 -1
  238. package/fesm2022/ngwr-line-chart-testing.mjs.map +1 -1
  239. package/fesm2022/ngwr-line-chart.mjs +18 -7
  240. package/fesm2022/ngwr-line-chart.mjs.map +1 -1
  241. package/fesm2022/ngwr-list.mjs +6 -6
  242. package/fesm2022/ngwr-list.mjs.map +1 -1
  243. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -1
  244. package/fesm2022/ngwr-loading-bar.mjs +6 -6
  245. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  246. package/fesm2022/ngwr-markdown-testing.mjs.map +1 -1
  247. package/fesm2022/ngwr-markdown.mjs +798 -17
  248. package/fesm2022/ngwr-markdown.mjs.map +1 -1
  249. package/fesm2022/ngwr-marquee-testing.mjs.map +1 -1
  250. package/fesm2022/ngwr-marquee.mjs +3 -3
  251. package/fesm2022/ngwr-marquee.mjs.map +1 -1
  252. package/fesm2022/ngwr-media.mjs +3 -3
  253. package/fesm2022/ngwr-media.mjs.map +1 -1
  254. package/fesm2022/ngwr-mention-testing.mjs.map +1 -1
  255. package/fesm2022/ngwr-mention.mjs +6 -6
  256. package/fesm2022/ngwr-mention.mjs.map +1 -1
  257. package/fesm2022/ngwr-meta.mjs +6 -6
  258. package/fesm2022/ngwr-meta.mjs.map +1 -1
  259. package/fesm2022/ngwr-meter-group-testing.mjs +7 -3
  260. package/fesm2022/ngwr-meter-group-testing.mjs.map +1 -1
  261. package/fesm2022/ngwr-meter-group.mjs +26 -6
  262. package/fesm2022/ngwr-meter-group.mjs.map +1 -1
  263. package/fesm2022/ngwr-overlay.mjs +6 -6
  264. package/fesm2022/ngwr-overlay.mjs.map +1 -1
  265. package/fesm2022/ngwr-page-header.mjs +13 -5
  266. package/fesm2022/ngwr-page-header.mjs.map +1 -1
  267. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  268. package/fesm2022/ngwr-pagination.mjs +3 -3
  269. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  270. package/fesm2022/ngwr-pipes.mjs +21 -21
  271. package/fesm2022/ngwr-pipes.mjs.map +1 -1
  272. package/fesm2022/ngwr-platform.mjs +9 -9
  273. package/fesm2022/ngwr-platform.mjs.map +1 -1
  274. package/fesm2022/ngwr-popconfirm-testing.mjs.map +1 -1
  275. package/fesm2022/ngwr-popconfirm.mjs +6 -6
  276. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  277. package/fesm2022/ngwr-popover-testing.mjs.map +1 -1
  278. package/fesm2022/ngwr-popover.mjs +578 -16
  279. package/fesm2022/ngwr-popover.mjs.map +1 -1
  280. package/fesm2022/ngwr-progress.mjs +3 -3
  281. package/fesm2022/ngwr-progress.mjs.map +1 -1
  282. package/fesm2022/ngwr-pull-to-refresh.mjs +3 -3
  283. package/fesm2022/ngwr-pull-to-refresh.mjs.map +1 -1
  284. package/fesm2022/ngwr-qr.mjs +3 -3
  285. package/fesm2022/ngwr-qr.mjs.map +1 -1
  286. package/fesm2022/ngwr-radio-testing.mjs.map +1 -1
  287. package/fesm2022/ngwr-radio.mjs +6 -6
  288. package/fesm2022/ngwr-radio.mjs.map +1 -1
  289. package/fesm2022/ngwr-rating-testing.mjs.map +1 -1
  290. package/fesm2022/ngwr-rating.mjs +3 -3
  291. package/fesm2022/ngwr-rating.mjs.map +1 -1
  292. package/fesm2022/ngwr-result.mjs +12 -12
  293. package/fesm2022/ngwr-result.mjs.map +1 -1
  294. package/fesm2022/ngwr-rotating-text-testing.mjs.map +1 -1
  295. package/fesm2022/ngwr-rotating-text.mjs +3 -3
  296. package/fesm2022/ngwr-rotating-text.mjs.map +1 -1
  297. package/fesm2022/ngwr-schema-form.mjs +3 -3
  298. package/fesm2022/ngwr-schema-form.mjs.map +1 -1
  299. package/fesm2022/ngwr-scroll.mjs +3 -3
  300. package/fesm2022/ngwr-scroll.mjs.map +1 -1
  301. package/fesm2022/ngwr-segmented-testing.mjs.map +1 -1
  302. package/fesm2022/ngwr-segmented.mjs +3 -3
  303. package/fesm2022/ngwr-segmented.mjs.map +1 -1
  304. package/fesm2022/ngwr-select-testing.mjs.map +1 -1
  305. package/fesm2022/ngwr-select.mjs +12 -12
  306. package/fesm2022/ngwr-select.mjs.map +1 -1
  307. package/fesm2022/ngwr-shiny-text-testing.mjs.map +1 -1
  308. package/fesm2022/ngwr-shiny-text.mjs +6 -6
  309. package/fesm2022/ngwr-shiny-text.mjs.map +1 -1
  310. package/fesm2022/ngwr-sidebar.mjs +10 -3
  311. package/fesm2022/ngwr-sidebar.mjs.map +1 -1
  312. package/fesm2022/ngwr-skeleton.mjs +3 -3
  313. package/fesm2022/ngwr-skeleton.mjs.map +1 -1
  314. package/fesm2022/ngwr-slider-testing.mjs.map +1 -1
  315. package/fesm2022/ngwr-slider.mjs +3 -3
  316. package/fesm2022/ngwr-slider.mjs.map +1 -1
  317. package/fesm2022/ngwr-sparkline-testing.mjs.map +1 -1
  318. package/fesm2022/ngwr-sparkline.mjs +84 -10
  319. package/fesm2022/ngwr-sparkline.mjs.map +1 -1
  320. package/fesm2022/ngwr-speed-dial-testing.mjs.map +1 -1
  321. package/fesm2022/ngwr-speed-dial.mjs +3 -3
  322. package/fesm2022/ngwr-speed-dial.mjs.map +1 -1
  323. package/fesm2022/ngwr-spinner.mjs +3 -3
  324. package/fesm2022/ngwr-spinner.mjs.map +1 -1
  325. package/fesm2022/ngwr-splash-cursor-testing.mjs.map +1 -1
  326. package/fesm2022/ngwr-splash-cursor.mjs +3 -3
  327. package/fesm2022/ngwr-splash-cursor.mjs.map +1 -1
  328. package/fesm2022/ngwr-split-text-testing.mjs.map +1 -1
  329. package/fesm2022/ngwr-split-text.mjs +3 -3
  330. package/fesm2022/ngwr-split-text.mjs.map +1 -1
  331. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  332. package/fesm2022/ngwr-splitter.mjs +3 -3
  333. package/fesm2022/ngwr-splitter.mjs.map +1 -1
  334. package/fesm2022/ngwr-spotlight-card-testing.mjs.map +1 -1
  335. package/fesm2022/ngwr-spotlight-card.mjs +6 -6
  336. package/fesm2022/ngwr-spotlight-card.mjs.map +1 -1
  337. package/fesm2022/ngwr-squircle.mjs +6 -6
  338. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  339. package/fesm2022/ngwr-star-border-testing.mjs.map +1 -1
  340. package/fesm2022/ngwr-star-border.mjs +3 -3
  341. package/fesm2022/ngwr-star-border.mjs.map +1 -1
  342. package/fesm2022/ngwr-statistic.mjs +9 -9
  343. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  344. package/fesm2022/ngwr-stepper-testing.mjs.map +1 -1
  345. package/fesm2022/ngwr-stepper.mjs +6 -6
  346. package/fesm2022/ngwr-stepper.mjs.map +1 -1
  347. package/fesm2022/ngwr-storage.mjs +3 -3
  348. package/fesm2022/ngwr-storage.mjs.map +1 -1
  349. package/fesm2022/ngwr-switch-testing.mjs.map +1 -1
  350. package/fesm2022/ngwr-switch.mjs +3 -3
  351. package/fesm2022/ngwr-switch.mjs.map +1 -1
  352. package/fesm2022/ngwr-table-testing.mjs.map +1 -1
  353. package/fesm2022/ngwr-table.mjs +18 -18
  354. package/fesm2022/ngwr-table.mjs.map +1 -1
  355. package/fesm2022/ngwr-tabs-router.mjs +3 -3
  356. package/fesm2022/ngwr-tabs-router.mjs.map +1 -1
  357. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  358. package/fesm2022/ngwr-tabs.mjs +6 -6
  359. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  360. package/fesm2022/ngwr-textarea-testing.mjs.map +1 -1
  361. package/fesm2022/ngwr-textarea.mjs +3 -3
  362. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  363. package/fesm2022/ngwr-theme.mjs +3 -3
  364. package/fesm2022/ngwr-theme.mjs.map +1 -1
  365. package/fesm2022/ngwr-tilt-card-testing.mjs.map +1 -1
  366. package/fesm2022/ngwr-tilt-card.mjs +6 -6
  367. package/fesm2022/ngwr-tilt-card.mjs.map +1 -1
  368. package/fesm2022/ngwr-timeline.mjs +6 -6
  369. package/fesm2022/ngwr-timeline.mjs.map +1 -1
  370. package/fesm2022/ngwr-toast-testing.mjs.map +1 -1
  371. package/fesm2022/ngwr-toast.mjs +9 -9
  372. package/fesm2022/ngwr-toast.mjs.map +1 -1
  373. package/fesm2022/ngwr-toolbar.mjs +10 -3
  374. package/fesm2022/ngwr-toolbar.mjs.map +1 -1
  375. package/fesm2022/ngwr-tour-testing.mjs.map +1 -1
  376. package/fesm2022/ngwr-tour.mjs +6 -6
  377. package/fesm2022/ngwr-tour.mjs.map +1 -1
  378. package/fesm2022/ngwr-transfer-testing.mjs.map +1 -1
  379. package/fesm2022/ngwr-transfer.mjs +3 -3
  380. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  381. package/fesm2022/ngwr-tree-testing.mjs.map +1 -1
  382. package/fesm2022/ngwr-tree.mjs +3 -3
  383. package/fesm2022/ngwr-tree.mjs.map +1 -1
  384. package/fesm2022/ngwr-typewriter-testing.mjs.map +1 -1
  385. package/fesm2022/ngwr-typewriter.mjs +3 -3
  386. package/fesm2022/ngwr-typewriter.mjs.map +1 -1
  387. package/fesm2022/ngwr-typography.mjs +7 -3
  388. package/fesm2022/ngwr-typography.mjs.map +1 -1
  389. package/fesm2022/ngwr-utils.mjs.map +1 -1
  390. package/fesm2022/ngwr-validators.mjs.map +1 -1
  391. package/fesm2022/ngwr-version.mjs +1 -1
  392. package/fesm2022/ngwr-version.mjs.map +1 -1
  393. package/fesm2022/ngwr-virtual-scroll.mjs +3 -3
  394. package/fesm2022/ngwr-virtual-scroll.mjs.map +1 -1
  395. package/fesm2022/ngwr-waves-testing.mjs.map +1 -1
  396. package/fesm2022/ngwr-waves.mjs +3 -3
  397. package/fesm2022/ngwr-waves.mjs.map +1 -1
  398. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  399. package/fesm2022/ngwr-window.mjs +12 -12
  400. package/fesm2022/ngwr-window.mjs.map +1 -1
  401. package/form/styles/_index.scss +16 -1
  402. package/gauge/styles/_index.scss +1 -0
  403. package/i18n/ar.json +32 -1
  404. package/i18n/cs.json +32 -1
  405. package/i18n/de.json +32 -1
  406. package/i18n/en.json +32 -1
  407. package/i18n/es.json +32 -1
  408. package/i18n/fr.json +32 -1
  409. package/i18n/he.json +32 -1
  410. package/i18n/hi.json +32 -1
  411. package/i18n/id.json +32 -1
  412. package/i18n/it.json +32 -1
  413. package/i18n/ja.json +32 -1
  414. package/i18n/ko.json +32 -1
  415. package/i18n/nl.json +32 -1
  416. package/i18n/pl.json +32 -1
  417. package/i18n/pt.json +32 -1
  418. package/i18n/ru.json +32 -1
  419. package/i18n/sv.json +32 -1
  420. package/i18n/tr.json +32 -1
  421. package/i18n/uk.json +32 -1
  422. package/i18n/vi.json +32 -1
  423. package/i18n/zh-TW.json +32 -1
  424. package/i18n/zh.json +32 -1
  425. package/input/styles/_index.scss +24 -1
  426. package/input-number/styles/_index.scss +69 -0
  427. package/input-otp/styles/_index.scss +5 -5
  428. package/line-chart/styles/_index.scss +30 -2
  429. package/llms-full.txt +14 -4
  430. package/llms.txt +188 -132
  431. package/mcp/providers.js +2 -2
  432. package/mcp/server.js +1 -1
  433. package/meter-group/styles/_index.scss +1 -0
  434. package/overlay/styles/_arrow.scss +30 -2
  435. package/package.json +43 -2
  436. package/page-header/styles/_index.scss +37 -1
  437. package/pagination/styles/_index.scss +9 -5
  438. package/popover/styles/_index.scss +73 -5
  439. package/progress/styles/_index.scss +4 -0
  440. package/radio/styles/_index.scss +4 -1
  441. package/schematics/use/symbol-map.json +1 -0
  442. package/select/styles/_index.scss +51 -12
  443. package/sidebar/styles/_index.scss +44 -2
  444. package/skeleton/styles/_index.scss +3 -0
  445. package/skills/ngwr/SKILL.md +5 -5
  446. package/skills/ngwr/references/catalog.md +2 -0
  447. package/skills/ngwr/references/setup.md +3 -3
  448. package/sparkline/styles/_index.scss +19 -0
  449. package/styles.scss +1 -0
  450. package/table/styles/_index.scss +7 -0
  451. package/textarea/styles/_index.scss +12 -3
  452. package/theme/styles/_colors.scss +39 -13
  453. package/theme/styles/_contrast.scss +9 -7
  454. package/toast/styles/_index.scss +4 -0
  455. package/toolbar/styles/_index.scss +35 -1
  456. package/tree/styles/_index.scss +46 -7
  457. package/types/ngwr-badge.d.ts +22 -7
  458. package/types/ngwr-bar-chart.d.ts +19 -1
  459. package/types/ngwr-calendar-heatmap.d.ts +29 -1
  460. package/types/ngwr-checkbox.d.ts +2 -0
  461. package/types/ngwr-config.d.ts +12 -0
  462. package/types/ngwr-date-picker.d.ts +308 -43
  463. package/types/ngwr-donut-chart.d.ts +24 -1
  464. package/types/ngwr-dropdown.d.ts +22 -2
  465. package/types/ngwr-editor-testing.d.ts +378 -0
  466. package/types/ngwr-editor.d.ts +449 -0
  467. package/types/ngwr-event-calendar.d.ts +8 -0
  468. package/types/ngwr-form.d.ts +35 -5
  469. package/types/ngwr-gauge.d.ts +20 -1
  470. package/types/ngwr-input-number.d.ts +7 -0
  471. package/types/ngwr-line-chart.d.ts +9 -1
  472. package/types/ngwr-markdown.d.ts +61 -2
  473. package/types/ngwr-meter-group-testing.d.ts +3 -2
  474. package/types/ngwr-meter-group.d.ts +14 -1
  475. package/types/ngwr-page-header.d.ts +10 -2
  476. package/types/ngwr-popover.d.ts +154 -3
  477. package/types/ngwr-sidebar.d.ts +7 -0
  478. package/types/ngwr-sparkline.d.ts +43 -1
  479. package/types/ngwr-toolbar.d.ts +7 -0
  480. package/types/ngwr-typography.d.ts +4 -0
  481. package/types/ngwr-version.d.ts +1 -1
  482. package/typography/styles/_index.scss +16 -0
@@ -0,0 +1,568 @@
1
+ import { ComponentHarness, HarnessPredicate, parallel } from '@angular/cdk/testing';
2
+ import { WrButtonHarness } from 'ngwr/button/testing';
3
+ import { WrInputHarness } from 'ngwr/input/testing';
4
+ import { WrPopoverHarness } from 'ngwr/popover/testing';
5
+
6
+ /**
7
+ * @license
8
+ *
9
+ * Use of this source code is governed by an MIT-style license that can be
10
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
11
+ */
12
+ /** The text surface ProseMirror mounts on. */
13
+ const SURFACE = '.wr-editor__surface';
14
+ /** One toolbar button. The separators are `<span>`s and never match. */
15
+ const TOOL = '.wr-editor__tool';
16
+ /**
17
+ * The link tool — the one button that hosts a popover rather than a tooltip, and so
18
+ * the one announcing `aria-haspopup="dialog"`.
19
+ */
20
+ const LINK_TOOL = `${TOOL}[aria-haspopup="dialog"]`;
21
+ /**
22
+ * Every textblock the schema can draw. A list item, a quote and a table cell all hold
23
+ * paragraphs, so this reaches every run of text however deeply it is nested — and
24
+ * nothing else: a task item's box and its screen-reader words sit OUTSIDE the
25
+ * paragraph, beside it.
26
+ */
27
+ const TEXTBLOCKS = `${SURFACE} :is(p, h1, h2, h3, pre)`;
28
+ /**
29
+ * The modifier ProseMirror's keymap reads `Mod` as. It decides from
30
+ * `navigator.platform` itself, once, when `prosemirror-keymap` loads — so this asks
31
+ * the same question the same way rather than guessing from the tooltip, which the
32
+ * component words from the user agent.
33
+ */
34
+ function primaryModifier() {
35
+ const apple = typeof navigator !== 'undefined' && /Mac|iP(hone|[oa]d)/.test(navigator.platform);
36
+ return apple ? { meta: true } : { control: true };
37
+ }
38
+ /**
39
+ * Test harness for `<wr-editor>` — a ProseMirror text surface, the formatting
40
+ * toolbar above it, and the link panel one of its buttons opens.
41
+ *
42
+ * **The value is not read here, and that is the first thing to know.** The model
43
+ * holds an HTML string, a markdown string or a JSON tree depending on `format`, and
44
+ * all three are written by the editor's codec, never by the DOM. What the surface
45
+ * draws is ProseMirror's rendering of the document — a trailing `<br>` in an empty
46
+ * paragraph, a presentational box beside a task item — so a string derived from it
47
+ * would be a fourth format agreeing with none of the three. A spec reads the value
48
+ * from what it bound (`form.body().value()`, the `[(value)]` signal); this harness
49
+ * answers the other question, what is DRAWN ({@link getText}), and a spec on an
50
+ * editor should usually ask both.
51
+ *
52
+ * Four more things are refused, each because jsdom cannot answer it and a method
53
+ * would answer it anyway:
54
+ *
55
+ * - **Typing, character by character.** `sendKeys` dispatches key events and nothing
56
+ * else. In a browser the BROWSER inserts the character into the contenteditable and
57
+ * ProseMirror reads the mutation; jsdom inserts nothing, so a typed string would
58
+ * vanish while the call resolved. {@link setText} writes the surface the way the
59
+ * CDK defines writing a contenteditable, which ProseMirror reads as a real DOM
60
+ * change; {@link paste} inserts at the selection; {@link pressKey} refuses a
61
+ * printable character without a modifier rather than dropping it.
62
+ * - **A caret or a selected range.** Placing either needs a DOM selection inside a
63
+ * text node, which no `TestElement` call can create. {@link selectAll} is the one
64
+ * selection a keyboard makes without a coordinate, and it is the one offered.
65
+ * - **Anything measured** — the height between `--wr-editor-min-height` and
66
+ * `-max-height`, a scroll, how the toolbar wraps, where a tooltip lands. Every box
67
+ * is 0×0 without layout.
68
+ * - **Whether the placeholder is visible.** It is CSS `content` drawn from a data
69
+ * attribute, which no DOM query sees; {@link getPlaceholder} reads what is
70
+ * ANNOUNCED, and that is only there while the document is empty.
71
+ *
72
+ * Toolbar buttons are addressed by the name a screen reader reads — `Bold`,
73
+ * `Heading 2`, `Insert link` in English, the catalog's words otherwise — because the
74
+ * DOM carries nothing else to tell them apart, and that name is the contract anyway.
75
+ * {@link getTool} hands back a `WrButtonHarness`; what that harness does not read
76
+ * (`aria-pressed`, `aria-keyshortcuts`, the roving tab stop) is answered here.
77
+ *
78
+ * Every method reads the MOUNTED surface. ProseMirror takes it over in
79
+ * `afterNextRender`, which the harness's own stabilising lets run; under a server
80
+ * `PLATFORM_ID` it never does, and the static preview the server renders is not
81
+ * something this harness pretends to be the editor.
82
+ *
83
+ * **A spec under jsdom installs one stub first.** After an edit made while the
84
+ * surface has focus, ProseMirror scrolls the selection into view, which measures a
85
+ * `Range` — and jsdom's `Range` has no `getClientRects()`. The throw comes AFTER the
86
+ * document changed but before the model hears of it, from inside a DOM listener, so
87
+ * the model keeps the old value and the error surfaces only as an unhandled one. Empty
88
+ * boxes are the whole stub; nothing here measures anything, so nothing is lost:
89
+ *
90
+ * ```ts
91
+ * beforeEach(() => {
92
+ * Range.prototype.getClientRects = () => [] as unknown as DOMRectList;
93
+ * Range.prototype.getBoundingClientRect = () => new DOMRect();
94
+ * document.elementFromPoint = () => null;
95
+ * });
96
+ * // …and delete all three again in afterEach, so no other file inherits them.
97
+ * ```
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * const loader = TestbedHarnessEnvironment.loader(fixture);
102
+ * const body = await loader.getHarness(WrEditorHarness.with({ label: 'Body' }));
103
+ *
104
+ * await body.setText('Release notes');
105
+ * await body.selectAll();
106
+ * await (await body.getTool('Bold')).click();
107
+ *
108
+ * expect(await body.isToolPressed('Bold')).toBe(true);
109
+ * expect(host.value()).toBe('<p><strong>Release notes</strong></p>');
110
+ * ```
111
+ *
112
+ * @see https://ngwr.dev/guides/testing
113
+ */
114
+ class WrEditorHarness extends ComponentHarness {
115
+ static hostSelector = 'wr-editor';
116
+ /** Build a predicate that narrows the query — pass to `getHarness` / `getAllHarnesses`. */
117
+ static with(options = {}) {
118
+ return new HarnessPredicate(WrEditorHarness, options)
119
+ .addOption('label', options.label, (harness, label) => HarnessPredicate.stringMatches(harness.getLabel(), label))
120
+ .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getText(), text))
121
+ .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)
122
+ .addOption('readonly', options.readonly, async (harness, readonly) => (await harness.isReadonly()) === readonly);
123
+ }
124
+ surface = this.locatorFor(SURFACE);
125
+ // ---------------------------------------------------------------------------
126
+ // The surface
127
+ // ---------------------------------------------------------------------------
128
+ /**
129
+ * Whether ProseMirror owns the surface yet — read from the `contenteditable` it
130
+ * writes there, which nothing else does.
131
+ *
132
+ * `true` in any browser-platform spec by the time a harness method runs. `false`
133
+ * under a server `PLATFORM_ID`, where the editor is the static preview for good —
134
+ * and every other method here throws, rather than answer about a preview as if it
135
+ * were the editor.
136
+ */
137
+ async isMounted() {
138
+ return (await (await this.surface()).getAttribute('contenteditable')) !== null;
139
+ }
140
+ /**
141
+ * The text the surface DRAWS: every textblock (paragraph, heading, code block) in
142
+ * document order, each trimmed, joined with a newline.
143
+ *
144
+ * Joined per textblock rather than read in one go, because a single text read of the
145
+ * surface glues two paragraphs into one word — `Hello` and `world` would come back
146
+ * as `Helloworld`. A list item, a quote and a table cell draw their text in
147
+ * paragraphs too, so a two-item list reads `One\nTwo`. Left out, deliberately: a task
148
+ * item's `Done:` / `To do:` — screen-reader text beside the paragraph, not in it —
149
+ * and a hard break, which is a `<br>` and has no text. An empty document is `''`.
150
+ *
151
+ * This is the drawn half of the two questions an editor answers; the class docs say
152
+ * why the other half, the value, is read from the model instead.
153
+ */
154
+ async getText() {
155
+ await this.mountedSurface('getText');
156
+ const blocks = await this.locatorForAll(TEXTBLOCKS)();
157
+ return (await parallel(() => blocks.map(block => block.text()))).join('\n');
158
+ }
159
+ /**
160
+ * The surface's accessible name — `ariaLabel` when one is bound, else the
161
+ * surrounding `<wr-form-field>`'s label, else the catalog's `editor.label`.
162
+ *
163
+ * A field's label reaches the surface through `aria-labelledby`, never `<label for>`:
164
+ * a contenteditable is not labelable. So the reference is resolved the way assistive
165
+ * technology resolves it — each id's element, its text — and a reference to an
166
+ * element that is not on the page contributes nothing, which is the failure worth
167
+ * catching.
168
+ */
169
+ async getLabel() {
170
+ const surface = await this.surface();
171
+ const labelledBy = await surface.getAttribute('aria-labelledby');
172
+ if (labelledBy) {
173
+ const root = this.documentRootLocatorFactory();
174
+ const labels = await parallel(() => labelledBy
175
+ .split(/\s+/)
176
+ .filter(Boolean)
177
+ .map(async (id) => {
178
+ const element = await root.locatorForOptional(`[id="${id}"]`)();
179
+ return element ? element.text() : '';
180
+ }));
181
+ return labels.filter(Boolean).join(' ') || null;
182
+ }
183
+ return surface.getAttribute('aria-label');
184
+ }
185
+ /**
186
+ * The placeholder as announced — `aria-placeholder` — or `null` when there is none
187
+ * to announce.
188
+ *
189
+ * That is `null` whenever the document holds anything, not only when no
190
+ * `placeholder` is bound: the component publishes it only while the document is
191
+ * empty, the moment it is also drawn. A document holding an empty heading still
192
+ * counts as empty.
193
+ */
194
+ async getPlaceholder() {
195
+ return (await this.surface()).getAttribute('aria-placeholder');
196
+ }
197
+ /**
198
+ * Whether the editor is disabled — the surface's `aria-disabled`.
199
+ *
200
+ * Read from the surface rather than the `wr-editor--disabled` host class, because a
201
+ * contenteditable has no `disabled` property: the attribute is what a screen reader
202
+ * is told, and ProseMirror's own `contenteditable="false"` is what turns the
203
+ * keyboard away. The component sets both.
204
+ */
205
+ async isDisabled() {
206
+ return (await (await this.surface()).getAttribute('aria-disabled')) === 'true';
207
+ }
208
+ /**
209
+ * Whether the editor shows its document and refuses edits — the surface's
210
+ * `aria-readonly`, which `role="textbox"` allows. Read-only keeps the tab stop, so
211
+ * {@link focus} still lands; disabled does not.
212
+ */
213
+ async isReadonly() {
214
+ return (await (await this.surface()).getAttribute('aria-readonly')) === 'true';
215
+ }
216
+ /**
217
+ * Whether the surface is announced invalid — the `aria-invalid` the surrounding
218
+ * `<wr-form-field>` hands it when a bound field fails validation and has been
219
+ * touched. An editor outside a field is never invalid.
220
+ */
221
+ async isInvalid() {
222
+ return (await (await this.surface()).getAttribute('aria-invalid')) === 'true';
223
+ }
224
+ /**
225
+ * Replace the whole document with `text`, as one paragraph of plain text.
226
+ *
227
+ * Written through `TestElement.setContenteditableValue` — the CDK's own definition of
228
+ * writing a contenteditable — which ProseMirror observes as a DOM change and parses
229
+ * back through the schema, exactly as it does the mutation a browser makes for a
230
+ * keystroke. So the write reaches the model through the editor's own path, filters
231
+ * and all. A line break in `text` becomes a hard break inside that one paragraph,
232
+ * the way Shift+Enter makes one; more paragraphs, lists and headings come from the
233
+ * toolbar, {@link pressKey} or {@link pasteHtml}.
234
+ *
235
+ * An empty `text` empties the document, which writes `''` (`null` in `json` format).
236
+ *
237
+ * Throws on a disabled or read-only editor, where no user could change a word — the
238
+ * surface is not contenteditable then, and a write the DOM accepted anyway would be
239
+ * a green spec for something that cannot happen.
240
+ */
241
+ async setText(text) {
242
+ const surface = await this.writableSurface('setText');
243
+ await surface.focus();
244
+ await surface.setContenteditableValue(text);
245
+ await this.forceStabilize();
246
+ }
247
+ /**
248
+ * Paste `text` as plain text at the selection, replacing whatever is selected — a
249
+ * `paste` event carrying `text/plain`, handled by ProseMirror's own paste path.
250
+ *
251
+ * On a READ-ONLY editor the event is still delivered, because a browser delivers it:
252
+ * the refusal is the editor's to make, and asserting the value did not change is how
253
+ * a spec proves it did. Throws on a disabled one, whose surface cannot hold focus for
254
+ * a paste to arrive at.
255
+ */
256
+ async paste(text) {
257
+ await this.dispatchPaste('paste', { 'text/plain': text });
258
+ }
259
+ /**
260
+ * Paste `html` at the selection, the way content copied from a web page arrives —
261
+ * `text/html` with `text` as its `text/plain` twin.
262
+ *
263
+ * This is the path to exercise what the editor strips from untrusted markup: the
264
+ * pasted HTML is parsed without executing anything and rebuilt from the schema,
265
+ * exactly as a bound HTML value is, so `onclick`, a `javascript:` link or an
266
+ * `<iframe>` never reaches the document. Read-only and disabled behave as in
267
+ * {@link paste}.
268
+ */
269
+ async pasteHtml(html, text = '') {
270
+ await this.dispatchPaste('pasteHtml', { 'text/html': html, 'text/plain': text });
271
+ }
272
+ /**
273
+ * Select the whole document with the platform's select-all chord, as ProseMirror's
274
+ * keymap reads it.
275
+ *
276
+ * Throws on a read-only or disabled editor: ProseMirror hands the keyboard back to
277
+ * the browser once the surface is not editable, and the browser's native select-all
278
+ * is exactly what jsdom does not have, so the chord would select nothing and say so
279
+ * to no one.
280
+ */
281
+ async selectAll() {
282
+ if (await this.isReadonly()) {
283
+ throw new Error('WrEditorHarness.selectAll(): the editor is read-only. ProseMirror does not handle the keyboard on a ' +
284
+ 'surface that is not editable — the browser selects natively — and a DOM without layout has no native ' +
285
+ 'selection to make. Assert isReadonly() instead.');
286
+ }
287
+ const surface = await this.writableSurface('selectAll');
288
+ await surface.focus();
289
+ await surface.sendKeys(primaryModifier(), 'a');
290
+ }
291
+ /**
292
+ * Press one key on the surface, with modifiers — Enter, Backspace, an arrow, or a
293
+ * shortcut such as `pressKey('b', { control: true })`.
294
+ *
295
+ * The keys reach ProseMirror's keymap, which is where the shortcuts, the list
296
+ * behaviour of Enter and history live. Under jsdom, ProseMirror reads `Mod` as
297
+ * Control; {@link getToolShortcuts} names the chord each tool answers to.
298
+ *
299
+ * A printable character WITHOUT a Control, Meta or Alt modifier throws: inserting it
300
+ * is the browser's job, not the key event's (see the class docs), so it would be
301
+ * dropped while the call resolved — use {@link setText} or {@link paste}. Throws on a
302
+ * disabled editor, whose surface is out of the tab order. A read-only one takes the
303
+ * key and refuses whatever it would have changed, as it does in a browser.
304
+ */
305
+ async pressKey(key, modifiers = {}) {
306
+ if (typeof key === 'string' && !modifiers.control && !modifiers.meta && !modifiers.alt) {
307
+ throw new Error(`WrEditorHarness.pressKey(): "${key}" would be typed, not pressed. A key event inserts nothing into a ` +
308
+ 'contenteditable — the browser does, and jsdom does not — so the character would be dropped silently. ' +
309
+ 'Use setText() or paste() for text, or pass a modifier for a shortcut.');
310
+ }
311
+ const surface = await this.focusableSurface('pressKey');
312
+ await surface.focus();
313
+ await surface.sendKeys(modifiers, key);
314
+ }
315
+ /**
316
+ * Move focus to the text surface. A read-only editor keeps its tab stop and takes
317
+ * it.
318
+ *
319
+ * Throws on a disabled one rather than focusing it. In a browser its surface cannot
320
+ * take focus — no `tabindex`, and `contenteditable="false"` — but jsdom counts ANY
321
+ * `contenteditable` attribute as focusable, `false` included, so the focus would
322
+ * land in the spec and never in the app.
323
+ */
324
+ async focus() {
325
+ return (await this.focusableSurface('focus')).focus();
326
+ }
327
+ /**
328
+ * Take focus away from the surface — the whole control losing focus, which is what
329
+ * emits `touch` and lets a bound field show its error. Focus moving to the editor's
330
+ * own toolbar or link panel is not a blur of the control, and does not emit it.
331
+ */
332
+ async blur() {
333
+ return (await this.surface()).blur();
334
+ }
335
+ /** Whether the text surface holds focus. A toolbar button holding it is not the surface. */
336
+ async isFocused() {
337
+ return (await this.surface()).isFocused();
338
+ }
339
+ // ---------------------------------------------------------------------------
340
+ // The toolbar
341
+ // ---------------------------------------------------------------------------
342
+ /** Whether a toolbar is drawn — gone with `toolbar="false"`, and with a list holding no tool. */
343
+ async hasToolbar() {
344
+ return (await this.locatorForOptional('[role="toolbar"]')()) !== null;
345
+ }
346
+ /** The toolbar's accessible name — the catalog's `editor.toolbar`. Throws when there is no toolbar. */
347
+ async getToolbarLabel() {
348
+ return (await this.toolbar('getToolbarLabel')).getAttribute('aria-label');
349
+ }
350
+ /**
351
+ * The names of the drawn tools, in order, separators left out.
352
+ *
353
+ * What is DRAWN, which is not always what was bound: `underline` is dropped in
354
+ * `markdown` format, which cannot store it, and a duplicate or a stray separator is
355
+ * dropped too.
356
+ */
357
+ async getToolLabels() {
358
+ const tools = await this.locatorForAll(TOOL)();
359
+ return (await parallel(() => tools.map(tool => tool.getAttribute('aria-label')))).map(label => label ?? '');
360
+ }
361
+ /**
362
+ * The toolbar button named `label`, as a `WrButtonHarness` — click it, focus it, ask
363
+ * whether it is disabled.
364
+ *
365
+ * A tool the current selection cannot use is NATIVELY disabled, so its click never
366
+ * fires; that is the answer to "can bold apply here", read with `isDisabled()`. Its
367
+ * tooltip — the name plus the shortcut — is a `[wrPopover]` in tooltip mode, which
368
+ * `WrPopoverHarness` reads when a spec cares about the wording.
369
+ */
370
+ async getTool(label) {
371
+ const tool = await this.locatorForOptional(WrButtonHarness.with({ selector: TOOL }).add(`label matches ${label}`, async (harness) => HarnessPredicate.stringMatches((await harness.host()).getAttribute('aria-label'), label)))();
372
+ if (tool)
373
+ return tool;
374
+ throw new Error(`WrEditorHarness.getTool(): no tool is named ${label}. The toolbar draws ` +
375
+ `${JSON.stringify(await this.getToolLabels())} — note that underline is not drawn in markdown format.`);
376
+ }
377
+ /**
378
+ * Whether a toggle tool is pressed — its `aria-pressed` — at the current selection.
379
+ *
380
+ * The marks answer for the selection (or, at a caret, for what typing would carry);
381
+ * the block types answer for every textblock the selection touches, so a select-all
382
+ * over a heading and a paragraph presses neither.
383
+ *
384
+ * Throws for a tool that is not a toggle: the link button opens a panel, and undo,
385
+ * redo and the horizontal rule are actions, so none carries `aria-pressed` and a
386
+ * `false` would claim a state they do not have. Whether the selection sits in a link
387
+ * is what the link panel's remove button answers — see {@link removeLink}.
388
+ */
389
+ async isToolPressed(label) {
390
+ const host = await (await this.getTool(label)).host();
391
+ const pressed = await host.getAttribute('aria-pressed');
392
+ if (pressed === null) {
393
+ throw new Error(`WrEditorHarness.isToolPressed(): "${await host.getAttribute('aria-label')}" is not a toggle, so it carries ` +
394
+ 'no aria-pressed. Link opens a panel; undo, redo and the horizontal rule are actions.');
395
+ }
396
+ return pressed === 'true';
397
+ }
398
+ /**
399
+ * The chords a tool answers to, as its `aria-keyshortcuts` states them
400
+ * (`Control+B`, `Control+Shift+Z Control+Y`), or `null` for a tool with none — the
401
+ * horizontal rule.
402
+ *
403
+ * ARIA key names, never localised; `Meta` replaces `Control` where the user agent is
404
+ * Apple's.
405
+ */
406
+ async getToolShortcuts(label) {
407
+ return (await (await this.getTool(label)).host()).getAttribute('aria-keyshortcuts');
408
+ }
409
+ /**
410
+ * The name of the one tool in the tab order, or `null` when there is none.
411
+ *
412
+ * The toolbar is a single tab stop that the arrow keys rove. The stop follows the
413
+ * user, and moves off a tool that stopped applying — so after a click that disables
414
+ * undo, it lands on the first tool that still applies. `null` only when nothing does
415
+ * (read-only, disabled), where there is nothing for the keyboard to reach.
416
+ */
417
+ async getToolbarTabStop() {
418
+ const tools = await this.locatorForAll(TOOL)();
419
+ for (const tool of tools) {
420
+ if ((await tool.getAttribute('tabindex')) === '0' && !(await tool.getProperty('disabled'))) {
421
+ return tool.getAttribute('aria-label');
422
+ }
423
+ }
424
+ return null;
425
+ }
426
+ // ---------------------------------------------------------------------------
427
+ // The link panel
428
+ // ---------------------------------------------------------------------------
429
+ /** Whether the link panel is open, from the link tool's `aria-expanded`. `false` when there is no link tool. */
430
+ async isLinkPanelOpen() {
431
+ const tool = await this.locatorForOptional(LINK_TOOL)();
432
+ return !!tool && (await tool.getAttribute('aria-expanded')) === 'true';
433
+ }
434
+ /**
435
+ * Open the link panel from its toolbar button and hand back the popover — a
436
+ * content container, so `panel.getHarness(WrInputHarness)` reaches the address
437
+ * field without the spec touching the overlay. An open panel is returned as it is.
438
+ *
439
+ * The panel is a portal in the overlay container, reached through the id the
440
+ * button publishes as `aria-controls`, never by its class: two editors can each have
441
+ * one. Mod-K on the surface opens the same panel — `pressKey('k', { control: true })`.
442
+ *
443
+ * Throws when the toolbar draws no link tool, or when the tool is unavailable (a
444
+ * read-only or disabled editor).
445
+ */
446
+ async openLinkPanel() {
447
+ const panel = await this.linkPopover('openLinkPanel');
448
+ if (await panel.isOpen())
449
+ return panel;
450
+ if (await (await panel.host()).getProperty('disabled')) {
451
+ throw new Error('WrEditorHarness.openLinkPanel(): the link tool is disabled — nothing can be linked while the editor ' +
452
+ 'is read-only or disabled.');
453
+ }
454
+ await panel.open();
455
+ return panel;
456
+ }
457
+ /**
458
+ * Link the selection to `url` through the panel: open it, write the address, apply.
459
+ *
460
+ * With text selected, the selection becomes the link; with the caret inside a link,
461
+ * that link's address changes; with nothing selected at all, the address is inserted
462
+ * as its own linked text. An emptied address on an existing link removes it.
463
+ *
464
+ * Resolves whether or not the address was accepted. One the URL policy refuses — a
465
+ * `javascript:` or `data:` scheme — leaves the panel OPEN with its error showing and
466
+ * the document untouched, which is the behaviour a spec most wants to pin; read it
467
+ * with {@link getLinkError} and {@link isLinkPanelOpen}.
468
+ */
469
+ async setLink(url) {
470
+ const panel = await this.openLinkPanel();
471
+ const input = await panel.getHarness(WrInputHarness);
472
+ await input.setValue(url);
473
+ await (await panel.getHarness(WrButtonHarness.with({ selector: '.wr-editor-link__apply' }))).click();
474
+ }
475
+ /**
476
+ * Remove the link the selection sits in or covers, through the panel's remove button.
477
+ *
478
+ * Throws when the selection is in no link: the panel draws the button only then, so
479
+ * its absence IS the answer to "is there a link here".
480
+ */
481
+ async removeLink() {
482
+ const panel = await this.openLinkPanel();
483
+ const remove = await panel.getHarnessOrNull(WrButtonHarness.with({ selector: '.wr-editor-link__remove' }));
484
+ if (!remove) {
485
+ throw new Error('WrEditorHarness.removeLink(): the selection is not in a link, so the panel offers nothing to remove. ' +
486
+ 'Select the linked text first — selectAll() covers a document holding one link.');
487
+ }
488
+ await remove.click();
489
+ }
490
+ /**
491
+ * The message the open panel shows for a refused address, or `null` when it shows
492
+ * none. It is a `role="alert"`, and the address field names it with
493
+ * `aria-describedby` — so the text a screen reader hears is the text read here.
494
+ *
495
+ * Throws while the panel is closed: the message only exists inside it, and a `null`
496
+ * would read as "the address was accepted".
497
+ */
498
+ async getLinkError() {
499
+ if (!(await this.isLinkPanelOpen())) {
500
+ throw new Error('WrEditorHarness.getLinkError(): the link panel is closed, so there is no message to read. An accepted ' +
501
+ 'address closes it — isLinkPanelOpen() tells the two outcomes apart.');
502
+ }
503
+ const id = await (await this.locatorFor(LINK_TOOL)()).getAttribute('aria-controls');
504
+ const error = await this.documentRootLocatorFactory().locatorForOptional(`[id="${id}"] .wr-editor-link__error`)();
505
+ return error ? error.text() : null;
506
+ }
507
+ // ---------------------------------------------------------------------------
508
+ // Internals
509
+ // ---------------------------------------------------------------------------
510
+ /** The surface, or a sentence saying the editor is still the server's static preview. */
511
+ async mountedSurface(method) {
512
+ const surface = await this.surface();
513
+ if ((await surface.getAttribute('contenteditable')) === null) {
514
+ throw new Error(`WrEditorHarness.${method}(): the editor is not mounted. ProseMirror takes the surface over in ` +
515
+ 'afterNextRender, which never runs under a server PLATFORM_ID — what shows there is the static ' +
516
+ 'preview, and this harness does not answer for it as if it were the editor.');
517
+ }
518
+ return surface;
519
+ }
520
+ /** The surface, when a user could still reach it with the keyboard. */
521
+ async focusableSurface(method) {
522
+ const surface = await this.mountedSurface(method);
523
+ if (await this.isDisabled()) {
524
+ throw new Error(`WrEditorHarness.${method}(): the editor is disabled — its surface is out of the tab order, so no key or ` +
525
+ 'paste could arrive there. Assert isDisabled() instead.');
526
+ }
527
+ return surface;
528
+ }
529
+ /** The surface, when a user could change its text. */
530
+ async writableSurface(method) {
531
+ const surface = await this.focusableSurface(method);
532
+ if (await this.isReadonly()) {
533
+ throw new Error(`WrEditorHarness.${method}(): the editor is read-only, so no user could change its text — the surface is ` +
534
+ 'not contenteditable. Write through the bound model instead, or assert isReadonly().');
535
+ }
536
+ return surface;
537
+ }
538
+ async dispatchPaste(method, data) {
539
+ const surface = await this.focusableSurface(method);
540
+ await surface.focus();
541
+ await surface.dispatchEvent('paste', {
542
+ clipboardData: {
543
+ types: Object.keys(data),
544
+ getData: (type) => data[type] ?? '',
545
+ },
546
+ });
547
+ }
548
+ async toolbar(method) {
549
+ const toolbar = await this.locatorForOptional('[role="toolbar"]')();
550
+ if (toolbar)
551
+ return toolbar;
552
+ throw new Error(`WrEditorHarness.${method}(): the editor draws no toolbar — toolbar is false, or lists no tool.`);
553
+ }
554
+ async linkPopover(method) {
555
+ const panel = await this.locatorForOptional(WrPopoverHarness.with({ selector: LINK_TOOL }))();
556
+ if (panel)
557
+ return panel;
558
+ throw new Error(`WrEditorHarness.${method}(): the toolbar draws no link tool. Bind a toolbar that lists 'link' — Mod-K ` +
559
+ 'opens the panel only when the tool is there to host it.');
560
+ }
561
+ }
562
+
563
+ /**
564
+ * Generated bundle index. Do not edit.
565
+ */
566
+
567
+ export { WrEditorHarness };
568
+ //# sourceMappingURL=ngwr-editor-testing.mjs.map