igniteui-webcomponents 7.3.2 → 7.4.1

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 (478) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/animations/easings.d.ts +21 -31
  3. package/animations/easings.js +21 -34
  4. package/animations/easings.js.map +1 -1
  5. package/animations/player.d.ts +8 -16
  6. package/animations/player.js +5 -8
  7. package/animations/player.js.map +1 -1
  8. package/animations/view-transition.d.ts +10 -10
  9. package/animations/view-transition.js +26 -37
  10. package/animations/view-transition.js.map +1 -1
  11. package/components/breadcrumb/breadcrumb.d.ts +74 -0
  12. package/components/breadcrumb/breadcrumb.js +107 -0
  13. package/components/breadcrumb/breadcrumb.js.map +1 -0
  14. package/components/breadcrumb/breadcrumbs.d.ts +60 -0
  15. package/components/breadcrumb/breadcrumbs.js +50 -0
  16. package/components/breadcrumb/breadcrumbs.js.map +1 -0
  17. package/components/breadcrumb/themes/breadcrumb.base.css.js +3 -0
  18. package/components/breadcrumb/themes/breadcrumb.base.css.js.map +1 -0
  19. package/components/breadcrumb/themes/breadcrumbs.base.css.d.ts +1 -0
  20. package/components/{resize-container/themes/resize-container.base.css.js → breadcrumb/themes/breadcrumbs.base.css.js} +2 -2
  21. package/components/breadcrumb/themes/breadcrumbs.base.css.js.map +1 -0
  22. package/components/breadcrumb/themes/dark/breadcrumb.bootstrap.css.d.ts +1 -0
  23. package/components/breadcrumb/themes/dark/breadcrumb.bootstrap.css.js +3 -0
  24. package/components/breadcrumb/themes/dark/breadcrumb.bootstrap.css.js.map +1 -0
  25. package/components/breadcrumb/themes/dark/breadcrumb.fluent.css.d.ts +1 -0
  26. package/components/breadcrumb/themes/dark/breadcrumb.fluent.css.js +3 -0
  27. package/components/breadcrumb/themes/dark/breadcrumb.fluent.css.js.map +1 -0
  28. package/components/breadcrumb/themes/dark/breadcrumb.indigo.css.d.ts +1 -0
  29. package/components/breadcrumb/themes/dark/breadcrumb.indigo.css.js +3 -0
  30. package/components/breadcrumb/themes/dark/breadcrumb.indigo.css.js.map +1 -0
  31. package/components/breadcrumb/themes/dark/breadcrumb.material.css.d.ts +1 -0
  32. package/components/breadcrumb/themes/dark/breadcrumb.material.css.js +3 -0
  33. package/components/breadcrumb/themes/dark/breadcrumb.material.css.js.map +1 -0
  34. package/components/breadcrumb/themes/light/breadcrumb.bootstrap.css.d.ts +1 -0
  35. package/components/breadcrumb/themes/light/breadcrumb.bootstrap.css.js +3 -0
  36. package/components/breadcrumb/themes/light/breadcrumb.bootstrap.css.js.map +1 -0
  37. package/components/breadcrumb/themes/light/breadcrumb.fluent.css.d.ts +1 -0
  38. package/components/breadcrumb/themes/light/breadcrumb.fluent.css.js +3 -0
  39. package/components/breadcrumb/themes/light/breadcrumb.fluent.css.js.map +1 -0
  40. package/components/breadcrumb/themes/light/breadcrumb.indigo.css.d.ts +1 -0
  41. package/components/breadcrumb/themes/light/breadcrumb.indigo.css.js +3 -0
  42. package/components/breadcrumb/themes/light/breadcrumb.indigo.css.js.map +1 -0
  43. package/components/breadcrumb/themes/light/breadcrumb.material.css.d.ts +1 -0
  44. package/components/breadcrumb/themes/light/breadcrumb.material.css.js +3 -0
  45. package/components/breadcrumb/themes/light/breadcrumb.material.css.js.map +1 -0
  46. package/components/breadcrumb/themes/light/breadcrumb.shared.css.d.ts +1 -0
  47. package/components/breadcrumb/themes/light/breadcrumb.shared.css.js +3 -0
  48. package/components/breadcrumb/themes/light/breadcrumb.shared.css.js.map +1 -0
  49. package/components/breadcrumb/themes/shared/breadcrumb.bootstrap.css.d.ts +1 -0
  50. package/components/breadcrumb/themes/shared/breadcrumb.bootstrap.css.js +3 -0
  51. package/components/breadcrumb/themes/shared/breadcrumb.bootstrap.css.js.map +1 -0
  52. package/components/breadcrumb/themes/shared/breadcrumb.common.css.d.ts +1 -0
  53. package/components/breadcrumb/themes/shared/breadcrumb.common.css.js +3 -0
  54. package/components/breadcrumb/themes/shared/breadcrumb.common.css.js.map +1 -0
  55. package/components/breadcrumb/themes/shared/breadcrumb.fluent.css.d.ts +1 -0
  56. package/components/breadcrumb/themes/shared/breadcrumb.fluent.css.js +3 -0
  57. package/components/breadcrumb/themes/shared/breadcrumb.fluent.css.js.map +1 -0
  58. package/components/breadcrumb/themes/shared/breadcrumb.indigo.css.d.ts +1 -0
  59. package/components/breadcrumb/themes/shared/breadcrumb.indigo.css.js +3 -0
  60. package/components/breadcrumb/themes/shared/breadcrumb.indigo.css.js.map +1 -0
  61. package/components/breadcrumb/themes/shared/breadcrumb.material.css.d.ts +1 -0
  62. package/components/breadcrumb/themes/shared/breadcrumb.material.css.js +3 -0
  63. package/components/breadcrumb/themes/shared/breadcrumb.material.css.js.map +1 -0
  64. package/components/breadcrumb/themes/themes.d.ts +2 -0
  65. package/components/breadcrumb/themes/themes.js +50 -0
  66. package/components/breadcrumb/themes/themes.js.map +1 -0
  67. package/components/button/button.d.ts +0 -2
  68. package/components/button/button.js.map +1 -1
  69. package/components/button-group/button-group.d.ts +42 -12
  70. package/components/button-group/button-group.js +82 -34
  71. package/components/button-group/button-group.js.map +1 -1
  72. package/components/button-group/toggle-button.d.ts +6 -1
  73. package/components/button-group/toggle-button.js +28 -2
  74. package/components/button-group/toggle-button.js.map +1 -1
  75. package/components/calendar/base.js +2 -1
  76. package/components/calendar/base.js.map +1 -1
  77. package/components/calendar/calendar.d.ts +2 -3
  78. package/components/calendar/calendar.js.map +1 -1
  79. package/components/calendar/days-view/days-view.d.ts +2 -2
  80. package/components/calendar/days-view/days-view.js.map +1 -1
  81. package/components/carousel/carousel-indicator.js +1 -0
  82. package/components/carousel/carousel-indicator.js.map +1 -1
  83. package/components/carousel/carousel-slide.d.ts +1 -1
  84. package/components/carousel/carousel-slide.js.map +1 -1
  85. package/components/carousel/carousel.d.ts +3 -3
  86. package/components/carousel/carousel.js.map +1 -1
  87. package/components/chat/chat-input.d.ts +1 -2
  88. package/components/chat/chat-input.js +1 -1
  89. package/components/chat/chat-input.js.map +1 -1
  90. package/components/chat/chat-state.d.ts +8 -9
  91. package/components/chat/chat-state.js.map +1 -1
  92. package/components/chat/chat.d.ts +1 -3
  93. package/components/chat/chat.js +2 -2
  94. package/components/chat/chat.js.map +1 -1
  95. package/components/chat/message-attachments.d.ts +6 -15
  96. package/components/chat/message-attachments.js.map +1 -1
  97. package/components/chat/utils.d.ts +0 -1
  98. package/components/chat/utils.js +1 -1
  99. package/components/chat/utils.js.map +1 -1
  100. package/components/checkbox/checkbox-base.d.ts +3 -1
  101. package/components/checkbox/checkbox-base.js +4 -0
  102. package/components/checkbox/checkbox-base.js.map +1 -1
  103. package/components/checkbox/checkbox.js +4 -12
  104. package/components/checkbox/checkbox.js.map +1 -1
  105. package/components/checkbox/switch.js +1 -8
  106. package/components/checkbox/switch.js.map +1 -1
  107. package/components/chip/chip.d.ts +2 -2
  108. package/components/chip/chip.js.map +1 -1
  109. package/components/color-picker/color-picker.d.ts +35 -34
  110. package/components/color-picker/color-picker.js +12 -7
  111. package/components/color-picker/color-picker.js.map +1 -1
  112. package/components/color-picker/common.d.ts +0 -2
  113. package/components/color-picker/common.js +2 -2
  114. package/components/color-picker/common.js.map +1 -1
  115. package/components/color-picker/converters.js.map +1 -1
  116. package/components/color-picker/picker-canvas.js.map +1 -1
  117. package/components/combo/combo.d.ts +24 -24
  118. package/components/combo/combo.js +21 -26
  119. package/components/combo/combo.js.map +1 -1
  120. package/components/combo/controllers/data.d.ts +7 -10
  121. package/components/combo/controllers/data.js.map +1 -1
  122. package/components/date-picker/date-picker.base.d.ts +22 -27
  123. package/components/date-picker/date-picker.base.js +9 -3
  124. package/components/date-picker/date-picker.base.js.map +1 -1
  125. package/components/date-picker/date-picker.d.ts +1 -1
  126. package/components/date-picker/date-picker.js +5 -3
  127. package/components/date-picker/date-picker.js.map +1 -1
  128. package/components/date-range-picker/date-range-input.d.ts +0 -2
  129. package/components/date-range-picker/date-range-input.js +0 -6
  130. package/components/date-range-picker/date-range-input.js.map +1 -1
  131. package/components/date-range-picker/date-range-picker.d.ts +22 -31
  132. package/components/date-range-picker/date-range-picker.js +7 -7
  133. package/components/date-range-picker/date-range-picker.js.map +1 -1
  134. package/components/date-range-picker/i18n.d.ts +21 -0
  135. package/components/date-range-picker/i18n.js +10 -0
  136. package/components/date-range-picker/i18n.js.map +1 -0
  137. package/components/date-range-picker/predefined-ranges-area.d.ts +3 -3
  138. package/components/date-range-picker/predefined-ranges-area.js +2 -5
  139. package/components/date-range-picker/predefined-ranges-area.js.map +1 -1
  140. package/components/date-range-picker/validators.d.ts +0 -4
  141. package/components/date-range-picker/validators.js +4 -4
  142. package/components/date-range-picker/validators.js.map +1 -1
  143. package/components/date-time-input/date-time-input.base.d.ts +42 -40
  144. package/components/date-time-input/date-time-input.base.js +9 -5
  145. package/components/date-time-input/date-time-input.base.js.map +1 -1
  146. package/components/date-time-input/date-time-input.d.ts +1 -11
  147. package/components/date-time-input/date-time-input.js +0 -6
  148. package/components/date-time-input/date-time-input.js.map +1 -1
  149. package/components/date-time-input/datetime-mask-parser.d.ts +0 -10
  150. package/components/date-time-input/datetime-mask-parser.js +1 -1
  151. package/components/date-time-input/datetime-mask-parser.js.map +1 -1
  152. package/components/dialog/dialog.js.map +1 -1
  153. package/components/dropdown/dropdown-group.d.ts +2 -10
  154. package/components/dropdown/dropdown-group.js +2 -27
  155. package/components/dropdown/dropdown-group.js.map +1 -1
  156. package/components/dropdown/dropdown.d.ts +17 -23
  157. package/components/dropdown/dropdown.js +5 -17
  158. package/components/dropdown/dropdown.js.map +1 -1
  159. package/components/file-input/file-input.d.ts +7 -2
  160. package/components/file-input/file-input.js +4 -0
  161. package/components/file-input/file-input.js.map +1 -1
  162. package/components/icon/icon.d.ts +1 -1
  163. package/components/icon/icon.registry.d.ts +6 -6
  164. package/components/icon/icon.registry.js.map +1 -1
  165. package/components/input/input-base.d.ts +2 -2
  166. package/components/input/input-base.js +3 -5
  167. package/components/input/input-base.js.map +1 -1
  168. package/components/input/input.d.ts +3 -3
  169. package/components/input/input.js.map +1 -1
  170. package/components/mask-input/mask-history.d.ts +22 -18
  171. package/components/mask-input/mask-history.js.map +1 -1
  172. package/components/mask-input/mask-input.d.ts +1 -1
  173. package/components/mask-input/mask-parser.d.ts +11 -13
  174. package/components/mask-input/mask-parser.js.map +1 -1
  175. package/components/popover/popover.d.ts +45 -34
  176. package/components/popover/popover.js +54 -122
  177. package/components/popover/popover.js.map +1 -1
  178. package/components/popover/position/arrow.d.ts +19 -0
  179. package/components/popover/position/arrow.js +33 -0
  180. package/components/popover/position/arrow.js.map +1 -0
  181. package/components/popover/position/floating.d.ts +40 -0
  182. package/components/popover/position/floating.js +146 -0
  183. package/components/popover/position/floating.js.map +1 -0
  184. package/components/popover/position/native.d.ts +45 -0
  185. package/components/popover/position/native.js +158 -0
  186. package/components/popover/position/native.js.map +1 -0
  187. package/components/popover/position/strategy.d.ts +37 -0
  188. package/components/popover/position/strategy.js +21 -0
  189. package/components/popover/position/strategy.js.map +1 -0
  190. package/components/popover/position/types.d.ts +26 -0
  191. package/components/popover/position/types.js +15 -0
  192. package/components/popover/position/types.js.map +1 -0
  193. package/components/popover/themes/light/popover.base.css.js +1 -1
  194. package/components/popover/themes/light/popover.base.css.js.map +1 -1
  195. package/components/progress/circular-progress.d.ts +0 -5
  196. package/components/progress/circular-progress.js.map +1 -1
  197. package/components/qr-code/qr-code.d.ts +1 -1
  198. package/components/radio/radio.d.ts +6 -4
  199. package/components/radio/radio.js +24 -25
  200. package/components/radio/radio.js.map +1 -1
  201. package/components/radio-group/radio-group.js.map +1 -1
  202. package/components/rating/rating.d.ts +9 -6
  203. package/components/rating/rating.js +17 -18
  204. package/components/rating/rating.js.map +1 -1
  205. package/components/select/select-group.d.ts +5 -10
  206. package/components/select/select-group.js +10 -34
  207. package/components/select/select-group.js.map +1 -1
  208. package/components/select/select.d.ts +12 -20
  209. package/components/select/select.js +5 -15
  210. package/components/select/select.js.map +1 -1
  211. package/components/slider/range-slider.d.ts +0 -1
  212. package/components/slider/range-slider.js +6 -11
  213. package/components/slider/range-slider.js.map +1 -1
  214. package/components/slider/slider-base.d.ts +4 -1
  215. package/components/slider/slider-base.js +20 -18
  216. package/components/slider/slider-base.js.map +1 -1
  217. package/components/slider/slider.d.ts +2 -0
  218. package/components/slider/slider.js +5 -1
  219. package/components/slider/slider.js.map +1 -1
  220. package/components/splitter/splitter.d.ts +6 -6
  221. package/components/splitter/splitter.js.map +1 -1
  222. package/components/textarea/textarea.d.ts +2 -5
  223. package/components/textarea/textarea.js +3 -5
  224. package/components/textarea/textarea.js.map +1 -1
  225. package/components/tile-manager/tile-manager.d.ts +6 -7
  226. package/components/tile-manager/tile-manager.js.map +1 -1
  227. package/components/tile-manager/tile.d.ts +3 -3
  228. package/components/tile-manager/tile.js.map +1 -1
  229. package/components/toast/toast.d.ts +0 -2
  230. package/components/toast/toast.js.map +1 -1
  231. package/components/tooltip/controller.js.map +1 -1
  232. package/components/tooltip/service.js +4 -5
  233. package/components/tooltip/service.js.map +1 -1
  234. package/components/tooltip/tooltip.d.ts +34 -13
  235. package/components/tooltip/tooltip.js +8 -4
  236. package/components/tooltip/tooltip.js.map +1 -1
  237. package/components/tree/tree-item.d.ts +6 -6
  238. package/components/tree/tree-item.js.map +1 -1
  239. package/components/tree/tree.navigation.d.ts +5 -6
  240. package/components/tree/tree.navigation.js.map +1 -1
  241. package/components/tree/tree.selection.js.map +1 -1
  242. package/components/types.d.ts +1 -1
  243. package/components/types.js.map +1 -1
  244. package/components/validation-container/validation-container.js +2 -1
  245. package/components/validation-container/validation-container.js.map +1 -1
  246. package/components/virtualization/engine.d.ts +40 -9
  247. package/components/virtualization/engine.js +126 -61
  248. package/components/virtualization/engine.js.map +1 -1
  249. package/components/virtualization/recycle.d.ts +13 -0
  250. package/components/virtualization/recycle.js +152 -0
  251. package/components/virtualization/recycle.js.map +1 -0
  252. package/components/virtualization/virtualization.d.ts +84 -65
  253. package/components/virtualization/virtualization.js +20 -16
  254. package/components/virtualization/virtualization.js.map +1 -1
  255. package/custom-elements.json +18455 -19551
  256. package/igniteui-webcomponents.css-data.json +2 -2
  257. package/igniteui-webcomponents.html-data.json +1 -1
  258. package/index.d.ts +3 -1
  259. package/index.js +2 -0
  260. package/index.js.map +1 -1
  261. package/internals/abort-handler.d.ts +13 -25
  262. package/internals/abort-handler.js +4 -6
  263. package/internals/abort-handler.js.map +1 -1
  264. package/internals/context.d.ts +13 -7
  265. package/internals/context.js +2 -1
  266. package/internals/context.js.map +1 -1
  267. package/internals/controllers/adopt-styles.d.ts +19 -20
  268. package/internals/controllers/adopt-styles.js +3 -8
  269. package/internals/controllers/adopt-styles.js.map +1 -1
  270. package/internals/controllers/aria-projection.d.ts +100 -61
  271. package/internals/controllers/aria-projection.js +81 -31
  272. package/internals/controllers/aria-projection.js.map +1 -1
  273. package/internals/controllers/async-consumer.js.map +1 -1
  274. package/internals/controllers/command.d.ts +15 -30
  275. package/internals/controllers/command.js +2 -7
  276. package/internals/controllers/command.js.map +1 -1
  277. package/internals/controllers/context-provider.d.ts +7 -13
  278. package/internals/controllers/context-provider.js.map +1 -1
  279. package/internals/controllers/focus-ring.d.ts +10 -30
  280. package/internals/controllers/focus-ring.js +6 -12
  281. package/internals/controllers/focus-ring.js.map +1 -1
  282. package/internals/controllers/fullscreen.d.ts +7 -23
  283. package/internals/controllers/fullscreen.js +3 -9
  284. package/internals/controllers/fullscreen.js.map +1 -1
  285. package/internals/controllers/gestures.d.ts +10 -29
  286. package/internals/controllers/gestures.js +1 -3
  287. package/internals/controllers/gestures.js.map +1 -1
  288. package/internals/controllers/group.d.ts +13 -30
  289. package/internals/controllers/group.js.map +1 -1
  290. package/internals/controllers/host-listeners.d.ts +28 -0
  291. package/internals/controllers/host-listeners.js +27 -0
  292. package/internals/controllers/host-listeners.js.map +1 -0
  293. package/internals/controllers/id-resolver.d.ts +8 -9
  294. package/internals/controllers/id-resolver.js +6 -14
  295. package/internals/controllers/id-resolver.js.map +1 -1
  296. package/internals/controllers/internals.d.ts +53 -104
  297. package/internals/controllers/internals.js +40 -13
  298. package/internals/controllers/internals.js.map +1 -1
  299. package/internals/controllers/key-bindings.d.ts +61 -158
  300. package/internals/controllers/key-bindings.js +68 -67
  301. package/internals/controllers/key-bindings.js.map +1 -1
  302. package/internals/controllers/keys.d.ts +32 -0
  303. package/internals/controllers/keys.js +20 -0
  304. package/internals/controllers/keys.js.map +1 -0
  305. package/internals/controllers/mutation-observer.d.ts +14 -37
  306. package/internals/controllers/mutation-observer.js +1 -1
  307. package/internals/controllers/mutation-observer.js.map +1 -1
  308. package/internals/controllers/resize-observer.d.ts +9 -19
  309. package/internals/controllers/resize-observer.js.map +1 -1
  310. package/internals/controllers/root-click.d.ts +11 -42
  311. package/internals/controllers/root-click.js +4 -6
  312. package/internals/controllers/root-click.js.map +1 -1
  313. package/internals/controllers/roving-focus.d.ts +16 -35
  314. package/internals/controllers/roving-focus.js.map +1 -1
  315. package/internals/controllers/slot.d.ts +25 -54
  316. package/internals/controllers/slot.js +6 -6
  317. package/internals/controllers/slot.js.map +1 -1
  318. package/internals/controllers/toggle.d.ts +44 -48
  319. package/internals/controllers/toggle.js.map +1 -1
  320. package/internals/date/compare.js.map +1 -1
  321. package/internals/date/converters.d.ts +10 -7
  322. package/internals/date/converters.js.map +1 -1
  323. package/internals/date/model.d.ts +9 -16
  324. package/internals/date/model.js +22 -25
  325. package/internals/date/model.js.map +1 -1
  326. package/internals/decorators/blazorAdditionalDependencies.d.ts +4 -2
  327. package/internals/decorators/blazorAdditionalDependencies.js.map +1 -1
  328. package/internals/decorators/blazorDeepImport.d.ts +1 -3
  329. package/internals/decorators/blazorDeepImport.js.map +1 -1
  330. package/internals/decorators/blazorInclude.d.ts +3 -2
  331. package/internals/decorators/blazorInclude.js.map +1 -1
  332. package/internals/decorators/blazorIndirectRender.d.ts +1 -3
  333. package/internals/decorators/blazorIndirectRender.js.map +1 -1
  334. package/internals/decorators/blazorSuppressComponent.d.ts +1 -3
  335. package/internals/decorators/blazorSuppressComponent.js.map +1 -1
  336. package/internals/decorators/coerced-property.d.ts +14 -20
  337. package/internals/decorators/coerced-property.js.map +1 -1
  338. package/internals/decorators/shadow-options.d.ts +2 -5
  339. package/internals/decorators/shadow-options.js.map +1 -1
  340. package/internals/definitions/defineAllComponents.js +2 -0
  341. package/internals/definitions/defineAllComponents.js.map +1 -1
  342. package/internals/directives/drag.d.ts +51 -81
  343. package/internals/directives/drag.js +27 -89
  344. package/internals/directives/drag.js.map +1 -1
  345. package/internals/directives/pointer-operation.d.ts +75 -0
  346. package/internals/directives/pointer-operation.js +92 -0
  347. package/internals/directives/pointer-operation.js.map +1 -0
  348. package/internals/directives/resize.d.ts +36 -64
  349. package/internals/directives/resize.js +18 -85
  350. package/internals/directives/resize.js.map +1 -1
  351. package/internals/i18n/EN/calendar.resources.d.ts +8 -2
  352. package/internals/i18n/EN/calendar.resources.js +2 -2
  353. package/internals/i18n/EN/calendar.resources.js.map +1 -1
  354. package/internals/i18n/EN/chat.resources.d.ts +8 -2
  355. package/internals/i18n/EN/chat.resources.js +3 -10
  356. package/internals/i18n/EN/chat.resources.js.map +1 -1
  357. package/internals/i18n/EN/date-picker.resources.d.ts +6 -4
  358. package/internals/i18n/EN/date-picker.resources.js +1 -7
  359. package/internals/i18n/EN/date-picker.resources.js.map +1 -1
  360. package/internals/i18n/EN/date-range-picker.resources.d.ts +9 -2
  361. package/internals/i18n/EN/date-range-picker.resources.js +2 -2
  362. package/internals/i18n/EN/date-range-picker.resources.js.map +1 -1
  363. package/internals/i18n/i18n-controller.d.ts +44 -46
  364. package/internals/i18n/i18n-controller.js +46 -33
  365. package/internals/i18n/i18n-controller.js.map +1 -1
  366. package/internals/i18n/utils.d.ts +9 -4
  367. package/internals/i18n/utils.js +4 -27
  368. package/internals/i18n/utils.js.map +1 -1
  369. package/internals/mixins/alert.d.ts +10 -25
  370. package/internals/mixins/alert.js.map +1 -1
  371. package/internals/mixins/combo-box.d.ts +21 -11
  372. package/internals/mixins/combo-box.js +16 -22
  373. package/internals/mixins/combo-box.js.map +1 -1
  374. package/internals/mixins/event-emitter.js +9 -11
  375. package/internals/mixins/event-emitter.js.map +1 -1
  376. package/internals/mixins/forms/associated-required.d.ts +4 -4
  377. package/internals/mixins/forms/associated-required.js.map +1 -1
  378. package/internals/mixins/forms/associated.d.ts +4 -2
  379. package/internals/mixins/forms/associated.js +42 -19
  380. package/internals/mixins/forms/associated.js.map +1 -1
  381. package/internals/mixins/forms/form-transformers.js.map +1 -1
  382. package/internals/mixins/forms/types.d.ts +27 -78
  383. package/internals/mixins/forms/types.js.map +1 -1
  384. package/internals/mixins/group.d.ts +18 -0
  385. package/internals/mixins/group.js +37 -0
  386. package/internals/mixins/group.js.map +1 -0
  387. package/internals/mixins/i18n.d.ts +10 -16
  388. package/internals/mixins/i18n.js.map +1 -1
  389. package/internals/mixins/mask-behavior.d.ts +8 -22
  390. package/internals/mixins/mask-behavior.js +1 -2
  391. package/internals/mixins/mask-behavior.js.map +1 -1
  392. package/internals/mixins/option.d.ts +1 -2
  393. package/internals/mixins/option.js +2 -1
  394. package/internals/mixins/option.js.map +1 -1
  395. package/internals/part-map.d.ts +4 -2
  396. package/internals/part-map.js +1 -1
  397. package/internals/part-map.js.map +1 -1
  398. package/internals/templates/input-shell.d.ts +8 -17
  399. package/internals/templates/input-shell.js +4 -1
  400. package/internals/templates/input-shell.js.map +1 -1
  401. package/internals/templates/masked-input.d.ts +7 -8
  402. package/internals/templates/masked-input.js.map +1 -1
  403. package/internals/templates/slotted-icon.d.ts +7 -12
  404. package/internals/templates/slotted-icon.js.map +1 -1
  405. package/internals/templates/toggle-shell.d.ts +19 -19
  406. package/internals/templates/toggle-shell.js +12 -8
  407. package/internals/templates/toggle-shell.js.map +1 -1
  408. package/internals/timing.d.ts +5 -14
  409. package/internals/timing.js.map +1 -1
  410. package/internals/utils/arrays.d.ts +21 -21
  411. package/internals/utils/arrays.js +14 -0
  412. package/internals/utils/arrays.js.map +1 -1
  413. package/internals/utils/dom.d.ts +53 -41
  414. package/internals/utils/dom.js +3 -4
  415. package/internals/utils/dom.js.map +1 -1
  416. package/internals/utils/events.d.ts +29 -16
  417. package/internals/utils/events.js +9 -1
  418. package/internals/utils/events.js.map +1 -1
  419. package/internals/utils/lit.d.ts +5 -2
  420. package/internals/utils/lit.js.map +1 -1
  421. package/internals/utils/math.d.ts +8 -6
  422. package/internals/utils/math.js.map +1 -1
  423. package/internals/utils/objects.d.ts +3 -20
  424. package/internals/utils/objects.js +1 -39
  425. package/internals/utils/objects.js.map +1 -1
  426. package/internals/utils/strings.d.ts +9 -11
  427. package/internals/utils/strings.js.map +1 -1
  428. package/internals/utils/types.d.ts +16 -3
  429. package/internals/utils/types.js +3 -0
  430. package/internals/utils/types.js.map +1 -1
  431. package/internals/validators.d.ts +9 -8
  432. package/internals/validators.js +12 -6
  433. package/internals/validators.js.map +1 -1
  434. package/package.json +1 -1
  435. package/skills/README.md +4 -3
  436. package/skills/igniteui-wc-choose-components/SKILL.md +2 -1
  437. package/skills/igniteui-wc-customize-component-theme/SKILL.md +2 -1
  438. package/skills/igniteui-wc-figma-to-app/SKILL.md +328 -0
  439. package/skills/igniteui-wc-figma-to-app/references/asset-extraction.md +343 -0
  440. package/skills/igniteui-wc-figma-to-app/references/design-provenance.md +199 -0
  441. package/skills/igniteui-wc-figma-to-app/references/design-token-bridge.md +489 -0
  442. package/skills/igniteui-wc-figma-to-app/references/figma-component-map.md +370 -0
  443. package/skills/igniteui-wc-figma-to-app/references/figma-exploration.md +222 -0
  444. package/skills/igniteui-wc-figma-to-app/references/mcp-setup.md +363 -0
  445. package/skills/igniteui-wc-figma-to-app/references/project-setup.md +105 -0
  446. package/skills/igniteui-wc-figma-to-app/references/theme-generation.md +180 -0
  447. package/skills/igniteui-wc-figma-to-app/references/validation-patterns.md +370 -0
  448. package/skills/igniteui-wc-generate-from-image-design/SKILL.md +2 -1
  449. package/skills/igniteui-wc-generate-from-image-design/references/gotchas.md +3 -3
  450. package/skills/igniteui-wc-grids/SKILL.md +133 -0
  451. package/skills/igniteui-wc-integrate-with-framework/SKILL.md +2 -1
  452. package/skills/igniteui-wc-migrate-grid-lite-to-premium/SKILL.md +2 -1
  453. package/skills/igniteui-wc-optimize-bundle-size/SKILL.md +2 -1
  454. package/theming/config.d.ts +14 -5
  455. package/theming/config.js +38 -18
  456. package/theming/config.js.map +1 -1
  457. package/theming/context.d.ts +1 -23
  458. package/theming/context.js.map +1 -1
  459. package/theming/theming-controller.d.ts +2 -32
  460. package/theming/theming-controller.js +15 -21
  461. package/theming/theming-controller.js.map +1 -1
  462. package/theming/theming-event.d.ts +0 -7
  463. package/theming/theming-event.js +0 -13
  464. package/theming/theming-event.js.map +1 -1
  465. package/theming/types.d.ts +1 -8
  466. package/theming/types.js.map +1 -1
  467. package/web-types.json +3 -3
  468. package/animations/presets/slide/index.d.ts +0 -3
  469. package/animations/presets/slide/index.js +0 -16
  470. package/animations/presets/slide/index.js.map +0 -1
  471. package/components/resize-container/themes/resize-container.base.css.js.map +0 -1
  472. package/internals/controllers/root-scroll.d.ts +0 -31
  473. package/internals/controllers/root-scroll.js +0 -71
  474. package/internals/controllers/root-scroll.js.map +0 -1
  475. package/theming/utils.d.ts +0 -11
  476. package/theming/utils.js +0 -20
  477. package/theming/utils.js.map +0 -1
  478. /package/components/{resize-container/themes/resize-container.base.css.d.ts → breadcrumb/themes/breadcrumb.base.css.d.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/components/virtualization/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { clamp } from '#internals/utils/math.js';\nimport type { ScrollAlignment, VisibleRange } from './types.js';\n\n/**\n * The maximum scrollable coordinate of a document does not change.\n * All instances in one document share one probe result.\n */\nconst _maxBrowserSizeCache = new WeakMap<Document, number>();\n\n/**\n * Measures the maximum scrollable coordinate that the browser supports.\n */\nfunction getMaxBrowserSizeProbePx(doc: Document): number {\n const cached = _maxBrowserSizeCache.get(doc);\n if (cached !== undefined) {\n return cached;\n }\n\n const container = doc.body ?? doc.documentElement;\n if (!container) {\n return Number.POSITIVE_INFINITY;\n }\n\n const div = doc.createElement('div');\n div.style.position = 'absolute';\n div.style.top = `${Number.MAX_SAFE_INTEGER}px`;\n div.style.width = '0';\n div.style.height = '0';\n div.style.visibility = 'hidden';\n container.appendChild(div);\n const scrollOffset = doc.documentElement?.scrollTop ?? 0;\n const size = Math.abs(div.getBoundingClientRect().top) + scrollOffset;\n container.removeChild(div);\n\n _maxBrowserSizeCache.set(doc, size);\n return size;\n}\n\n/**\n * Clamps `index` into `[0, length - 1]`. This keeps `prefixSum(index)` and\n * `prefixSum(index + 1)` valid. Callers make sure that `length > 0`.\n */\nfunction clampIndex(index: number, length: number): number {\n return clamp(index, 0, length - 1);\n}\n\n/**\n * Fills `tree` with the partial range sums of `sizes` in one O(N) pass.\n * `tree` is a 1-indexed Fenwick array of `sizes.length + 1` zeroed entries.\n * Returns the total sum.\n */\nfunction buildTree(tree: Float64Array, sizes: Float64Array): number {\n const length = sizes.length;\n let total = 0;\n\n for (let i = 1; i <= length; i++) {\n tree[i] += sizes[i - 1];\n total += sizes[i - 1];\n const j = i + (i & -i);\n if (j <= length) {\n tree[j] += tree[i];\n }\n }\n return total;\n}\n\n/**\n * Binary Indexed Tree (Fenwick tree) over item sizes. Each hot-path operation\n * is O(log N): point update (item measured), prefix sum (scroll offset), and\n * index at offset (scroll to item, through binary lifting).\n */\nclass SizeTree {\n public readonly length: number;\n\n /** A 1-indexed BIT. Each cell holds a partial range sum. */\n private readonly _tree: Float64Array;\n\n /** Raw per-item sizes, 0-indexed. Kept for O(1) reads and delta calculation. */\n private readonly _sizes: Float64Array;\n\n /**\n * Flags the indices that hold a DOM-measured size (`1`) instead of an\n * estimate (`0`). `applyEstimate` changes only the estimated entries.\n */\n private readonly _measured: Uint8Array;\n\n /** Running total. Updated together with the tree in O(1). */\n private _total: number;\n\n /**\n * The highest power of two <= `length`, for the binary lifting in\n * `findIndexAtOffset`. Precomputed because that runs on each scroll event.\n */\n private readonly _topBit: number;\n\n private constructor(\n length: number,\n sizes: Float64Array,\n tree: Float64Array,\n total: number,\n measured: Uint8Array\n ) {\n this.length = length;\n this._sizes = sizes;\n this._tree = tree;\n this._total = total;\n this._measured = measured;\n this._topBit = length > 0 ? 1 << (31 - Math.clz32(length)) : 0;\n }\n\n /**\n * Creates a tree of `length` items, each set to `fillSize` and marked\n * unmeasured. O(N).\n */\n public static filled(length: number, fillSize: number): SizeTree {\n return SizeTree._build(\n new Float64Array(length).fill(fillSize),\n new Uint8Array(length)\n );\n }\n\n /**\n * Builds a tree from a sizes array and its matching measured-flags array. O(N).\n */\n private static _build(sizes: Float64Array, measured: Uint8Array): SizeTree {\n const tree = new Float64Array(sizes.length + 1);\n const total = buildTree(tree, sizes);\n return new SizeTree(sizes.length, sizes, tree, total, measured);\n }\n\n /** Total size of all items. O(1). */\n public get totalSize(): number {\n return this._total;\n }\n\n /**\n * Prefix sum of items [0, i): the virtual scroll offset at the leading\n * edge of item i. O(log N).\n */\n public prefixSum(i: number): number {\n let sum = 0;\n for (let j = i; j > 0; j -= j & -j) {\n sum += this._tree[j];\n }\n return sum;\n }\n\n /**\n * Sets the size of the item at a 0-based index and marks the item as\n * measured. Later `applyEstimate()` calls do not change measured items.\n * Returns true when the size changed. O(log N).\n */\n public update(index: number, newSize: number): boolean {\n if (index < 0 || index >= this.length) return false;\n\n const old = this._sizes[index];\n this._measured[index] = 1;\n if (old === newSize) return false;\n\n const delta = newSize - old;\n this._sizes[index] = newSize;\n this._total += delta;\n for (let i = index + 1; i <= this.length; i += i & -i) {\n this._tree[i] += delta;\n }\n return true;\n }\n\n /**\n * Returns a new tree of `newLength` items in one O(N) pass. Sizes and\n * measured flags are kept up to `min(this.length, newLength, retainCount)`.\n * The remainder is filled with `fillSize` and marked unmeasured. Pass a\n * `retainCount` below the item count when the data behind those indices\n * changed identity.\n */\n public cloneResized(\n newLength: number,\n fillSize: number,\n retainCount = newLength\n ): SizeTree {\n const sizes = new Float64Array(newLength).fill(fillSize);\n const measured = new Uint8Array(newLength);\n const retained = Math.max(0, Math.min(this.length, newLength, retainCount));\n sizes.set(this._sizes.subarray(0, retained));\n measured.set(this._measured.subarray(0, retained));\n return SizeTree._build(sizes, measured);\n }\n\n /**\n * Sets `estimatedSize` on each unmeasured item. Measured items do not\n * change. Returns true when at least one size changed.\n *\n * One estimate change can touch most of the list, so this rebuilds in one\n * O(N) pass instead of one O(log N) `update` per item.\n */\n public applyEstimate(estimatedSize: number): boolean {\n let changed = false;\n for (let i = 0; i < this.length; i++) {\n if (!this._measured[i] && this._sizes[i] !== estimatedSize) {\n this._sizes[i] = estimatedSize;\n changed = true;\n }\n }\n if (!changed) return false;\n\n this._tree.fill(0);\n this._total = buildTree(this._tree, this._sizes);\n return true;\n }\n\n /**\n * Returns the 0-based index of the item that contains the scroll `offset`:\n * the largest i where `prefixSum(i) <= offset < prefixSum(i + 1)`. O(log N).\n */\n public findIndexAtOffset(offset: number): number {\n if (offset <= 0 || this.length === 0) return 0;\n\n let idx = 0;\n let remaining = offset;\n\n for (let bit = this._topBit; bit > 0; bit >>= 1) {\n const next = idx + bit;\n if (next <= this.length && this._tree[next] <= remaining) {\n idx = next;\n remaining -= this._tree[idx];\n }\n }\n return Math.min(this.length - 1, idx);\n }\n}\n\n/**\n * Pure scroll-math engine for one axis of virtual scrolling. A Fenwick tree\n * holds all size state.\n *\n * ### Virtual and DOM coordinates\n *\n * Browsers limit how far an element can scroll. When the total item size is\n * larger than that limit, the engine compresses the *virtual* space\n * (`0…totalSize`) into the *DOM* space the browser can represent\n * (`0…domSize`) by the factor `_virtualRatio`. Each offset that crosses that\n * boundary is scaled: incoming scroll positions are multiplied by the ratio,\n * and outgoing offsets are divided by it. Items render at their real pixel\n * size, so item sizes are always virtual.\n */\nexport class VirtualScrollEngine {\n private _maxBrowserSize = Number.POSITIVE_INFINITY;\n\n /**\n * The ratio `totalSize / maxBrowserSize` when `totalSize` is larger than\n * the maximum DOM coordinate the browser supports; `1` otherwise.\n * Maps virtual scroll positions to DOM scroll positions.\n */\n private _virtualRatio = 1;\n\n /** Binary Indexed Tree for O(log N) size queries and updates. */\n private _tree: SizeTree | null = null;\n\n /**\n * Called when item sizes or the item count change.\n * Example: `() => this.requestUpdate()`.\n */\n public onSizeChange: (() => void) | null = null;\n\n /** Total virtual size of all items in px. */\n public get totalSize(): number {\n return this._tree?.totalSize ?? 0;\n }\n\n /** Total size in DOM space, clamped to the maximum browser size. */\n public get domSize(): number {\n return this._virtualRatio !== 1 ? this._maxBrowserSize : this.totalSize;\n }\n\n /** Measures the maximum browser size for the document and rescales. */\n public initMaxBrowserSize(doc: Document): void {\n this._maxBrowserSize = getMaxBrowserSizeProbePx(doc);\n this._updateVirtualRatio();\n }\n\n /**\n * Resizes the internal sizes array to `length`. Measured sizes below\n * `retainCount` are kept. The remainder is filled with `estimatedSize` and\n * marked unmeasured. Callers that only append can keep the default\n * `retainCount`. Callers whose data changed identity at some index must\n * pass that index, so the stale measurements after it are discarded.\n */\n public resize(\n length: number,\n estimatedSize: number,\n retainCount = length\n ): void {\n if (this._tree?.length === length && retainCount >= length) return;\n\n this._tree = this._tree\n ? this._tree.cloneResized(length, estimatedSize, retainCount)\n : SizeTree.filled(length, estimatedSize);\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /** Records the measured DOM size for a single item. */\n public measureItem(index: number, size: number): void {\n if (!this._tree?.update(index, size)) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /**\n * Applies a new estimated size to each item that is not measured in the\n * DOM. Use this when `estimatedItemSize` changes but the item count does\n * not, because `resize` is then a no-op.\n */\n public updateEstimatedSize(estimatedSize: number): void {\n if (!this._tree?.applyEstimate(estimatedSize)) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /**\n * Returns the DOM scroll offset in px that puts the item at `index` at the\n * leading edge of the viewport.\n */\n public getScrollOffsetForIndex(index: number): number {\n if (!this._tree || index <= 0) return 0;\n\n const clamped = Math.min(index, this._tree.length);\n return this._tree.prefixSum(clamped) / this._virtualRatio;\n }\n\n /**\n * The largest DOM scroll offset the host can reach for the given viewport\n * size. A request beyond it does nothing, so offsets given to a caller\n * that waits for the scroll to settle are clamped to it.\n */\n private _getMaxScrollOffset(viewportSize: number): number {\n return Math.max(0, this.domSize - viewportSize);\n }\n\n /**\n * Returns the DOM scroll offset that positions the item at `index` in a\n * `viewportSize` px viewport, aligned by `align` and clamped to the\n * reachable scroll range.\n *\n * The slack is computed in virtual space against the item's real size and\n * converted to DOM space once, at the end. One DOM pixel equals\n * `_virtualRatio` virtual pixels, so mixed coordinates would scale the\n * slack.\n */\n public getAlignedScrollOffset(\n index: number,\n viewportSize: number,\n align: ScrollAlignment\n ): number {\n if (!this._tree || this._tree.length === 0) return 0;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n let offset = itemStart;\n\n if (align !== 'start') {\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const slack = viewportSize - Math.max(0, itemEnd - itemStart);\n offset -= align === 'center' ? slack / 2 : slack;\n }\n\n return clamp(\n offset / this._virtualRatio,\n 0,\n this._getMaxScrollOffset(viewportSize)\n );\n }\n\n /**\n * Whether the item at `index` is visible without more scrolling at the\n * given DOM scroll position. True when the item is fully inside the\n * viewport, or when it is larger than the viewport and covers it fully.\n * The second case matches native `scrollIntoView({ block: 'nearest' })`.\n */\n public isIndexInView(\n index: number,\n scrollPosition: number,\n viewportSize: number\n ): boolean {\n if (!this._tree || this._tree.length === 0) return false;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const viewStart = Math.max(0, scrollPosition) * this._virtualRatio;\n const viewEnd = viewStart + viewportSize;\n\n const contained = itemStart >= viewStart && itemEnd <= viewEnd;\n const spanning = itemStart <= viewStart && itemEnd >= viewEnd;\n\n return contained || spanning;\n }\n\n /**\n * Returns the visible and over-scanned item range for the given scroll\n * state.\n */\n public getVisibleRange(\n scrollPosition: number,\n viewportSize: number,\n overScan: number\n ): VisibleRange {\n if (!this._tree || this._tree.length === 0 || viewportSize <= 0) {\n return { startIndex: 0, endIndex: -1 };\n }\n\n // The viewport is not scaled by the virtual ratio. Items render at their\n // real pixel size, so a `viewportSize` px viewport always shows that many\n // virtual pixels of items, at any compression of the scroll range.\n const startOffset = Math.max(0, scrollPosition) * this._virtualRatio;\n const first = this._tree.findIndexAtOffset(startOffset);\n const last = this._tree.findIndexAtOffset(startOffset + viewportSize);\n\n return {\n startIndex: Math.max(0, first - overScan),\n endIndex: Math.min(this._tree.length - 1, last + overScan),\n };\n }\n\n /**\n * Sum of the actual sizes of the items in [startIndex, endIndex]. The\n * render pass uses it to clamp the content translate offset, so rendered\n * items do not overflow past `domSize` under coordinate compression.\n */\n public getPhysicalRangeSize(startIndex: number, endIndex: number): number {\n if (!this._tree) return 0;\n\n const start = Math.max(0, startIndex);\n const end = Math.min(Math.max(endIndex + 1, start), this._tree.length);\n return this._tree.prefixSum(end) - this._tree.prefixSum(start);\n }\n\n private _updateVirtualRatio(): void {\n const totalSize = this._tree?.totalSize ?? 0;\n this._virtualRatio =\n totalSize <= this._maxBrowserSize ? 1 : totalSize / this._maxBrowserSize;\n }\n}\n"]}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/components/virtualization/engine.ts"],"names":[],"mappings":"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","sourcesContent":["import { clamp } from '#internals/utils/math.js';\nimport type { ScrollAlignment, VisibleRange } from './types.js';\n\n/**\n * The maximum scrollable coordinate of a document does not change.\n * All instances in one document share one probe result.\n */\nconst _maxBrowserSizeCache = new WeakMap<Document, number>();\n\n/**\n * Measures the maximum scrollable coordinate that the browser supports.\n */\nfunction getMaxBrowserSizeProbePx(doc: Document): number {\n const cached = _maxBrowserSizeCache.get(doc);\n if (cached !== undefined) {\n return cached;\n }\n\n const container = doc.body ?? doc.documentElement;\n if (!container) {\n return Number.POSITIVE_INFINITY;\n }\n\n const div = doc.createElement('div');\n div.style.position = 'absolute';\n div.style.top = `${Number.MAX_SAFE_INTEGER}px`;\n div.style.width = '0';\n div.style.height = '0';\n div.style.visibility = 'hidden';\n container.appendChild(div);\n const scrollOffset = doc.documentElement?.scrollTop ?? 0;\n const size = Math.abs(div.getBoundingClientRect().top) + scrollOffset;\n container.removeChild(div);\n\n _maxBrowserSizeCache.set(doc, size);\n return size;\n}\n\n/**\n * Clamps `index` into `[0, length - 1]`. This keeps `prefixSum(index)` and\n * `prefixSum(index + 1)` valid. Callers make sure that `length > 0`.\n */\nfunction clampIndex(index: number, length: number): number {\n return clamp(index, 0, length - 1);\n}\n\n/** The item holds the estimate. */\nconst UNMEASURED = 0;\n/** The item was measured under an older estimate. */\nconst MEASURED = 1;\n/** The item was measured under the current estimate. */\nconst SAMPLED = 2;\n\n/**\n * Binary Indexed Tree (Fenwick tree) over item sizes. Each hot-path operation\n * is O(log N): point update (item measured), prefix sum (scroll offset), and\n * index at offset (scroll to item, through binary lifting).\n *\n * The tree holds only the measured sizes and the number of measured items.\n * Each unmeasured item counts as `estimate`, so an estimate change is O(1).\n */\nclass SizeTree {\n public readonly length: number;\n\n /** The size of each unmeasured item. */\n public estimate: number;\n\n /** A 1-indexed BIT of the measured sizes. */\n private readonly _sums: Float64Array;\n\n /** A 1-indexed BIT of the number of measured items. */\n private readonly _counts: Int32Array;\n\n /** Raw measured sizes, 0-indexed. Kept for O(1) delta calculation. */\n private readonly _sizes: Float64Array;\n\n /** `UNMEASURED`, `MEASURED` or `SAMPLED` for each item. */\n private readonly _states: Uint8Array;\n\n private _measuredCount = 0;\n private _measuredTotal = 0;\n\n /** Count and size sum of the `SAMPLED` items. */\n private _sampleCount = 0;\n private _sampleTotal = 0;\n\n /**\n * The highest power of two <= `length`, for the binary lifting in\n * `findIndexAtOffset`. Precomputed because that runs on each scroll event.\n */\n private readonly _topBit: number;\n\n /** Builds the tree in one O(N) pass. Without `states`, no item is measured. */\n constructor(\n length: number,\n estimate: number,\n sizes = new Float64Array(length),\n states = new Uint8Array(length)\n ) {\n this.length = length;\n this.estimate = estimate;\n this._sizes = sizes;\n this._states = states;\n this._sums = new Float64Array(length + 1);\n this._counts = new Int32Array(length + 1);\n this._topBit = length > 0 ? 1 << (31 - Math.clz32(length)) : 0;\n\n for (let i = 1; i <= length; i++) {\n const state = states[i - 1];\n\n if (state !== UNMEASURED) {\n const size = sizes[i - 1];\n this._sums[i] += size;\n this._counts[i]++;\n this._measuredCount++;\n this._measuredTotal += size;\n\n if (state === SAMPLED) {\n this._sampleCount++;\n this._sampleTotal += size;\n }\n }\n\n const parent = i + (i & -i);\n if (parent <= length) {\n this._sums[parent] += this._sums[i];\n this._counts[parent] += this._counts[i];\n }\n }\n }\n\n /** Total size of all items. O(1). */\n public get totalSize(): number {\n return (\n this._measuredTotal + (this.length - this._measuredCount) * this.estimate\n );\n }\n\n /** The average size of the `SAMPLED` items, or `0` if there are none. */\n public get sampleAverage(): number {\n return this._sampleCount > 0 ? this._sampleTotal / this._sampleCount : 0;\n }\n\n /** Whether each item before `index` is measured. O(log N). */\n public isMeasuredBefore(index: number): boolean {\n let count = 0;\n for (let j = index; j > 0; j -= j & -j) {\n count += this._counts[j];\n }\n return count === index;\n }\n\n /**\n * Prefix sum of items [0, i): the virtual scroll offset at the leading\n * edge of item i. O(log N).\n */\n public prefixSum(i: number): number {\n let sum = 0;\n let count = 0;\n for (let j = i; j > 0; j -= j & -j) {\n sum += this._sums[j];\n count += this._counts[j];\n }\n return sum + (i - count) * this.estimate;\n }\n\n /**\n * Sets the size of the item at a 0-based index and marks it `SAMPLED`.\n * Returns true when the size changed. O(log N).\n */\n public update(index: number, size: number): boolean {\n if (index < 0 || index >= this.length) return false;\n\n const state = this._states[index];\n const isNew = state === UNMEASURED;\n const old = isNew ? 0 : this._sizes[index];\n const delta = size - old;\n\n this._states[index] = SAMPLED;\n this._sizes[index] = size;\n this._measuredTotal += delta;\n this._sampleTotal += state === SAMPLED ? delta : size;\n if (state !== SAMPLED) this._sampleCount++;\n if (isNew) this._measuredCount++;\n\n if (isNew || delta !== 0) {\n for (let i = index + 1; i <= this.length; i += i & -i) {\n this._sums[i] += delta;\n if (isNew) this._counts[i]++;\n }\n }\n\n return size !== (isNew ? this.estimate : old);\n }\n\n /**\n * Returns a new tree of `newLength` items. Measured sizes are kept up to\n * `min(this.length, newLength, retainCount)`, and the other items are\n * unmeasured. Pass a `retainCount` below the item count when the data\n * behind those indices changed identity. O(N).\n */\n public cloneResized(newLength: number, retainCount = newLength): SizeTree {\n const retained = Math.max(0, Math.min(this.length, newLength, retainCount));\n const sizes = new Float64Array(newLength);\n const states = new Uint8Array(newLength);\n sizes.set(this._sizes.subarray(0, retained));\n states.set(this._states.subarray(0, retained));\n return new SizeTree(newLength, this.estimate, sizes, states);\n }\n\n /**\n * Starts a new sample: `sampleAverage` then counts only the items measured\n * after this call. O(N).\n */\n public startSample(): void {\n for (let i = 0; i < this.length; i++) {\n if (this._states[i] === SAMPLED) {\n this._states[i] = MEASURED;\n }\n }\n this._sampleCount = 0;\n this._sampleTotal = 0;\n }\n\n /**\n * Returns the 0-based index of the item that contains the scroll `offset`:\n * the largest i where `prefixSum(i) <= offset < prefixSum(i + 1)`. O(log N).\n */\n public findIndexAtOffset(offset: number): number {\n if (offset <= 0 || this.length === 0) return 0;\n\n let idx = 0;\n let remaining = offset;\n\n for (let bit = this._topBit; bit > 0; bit >>= 1) {\n const next = idx + bit;\n if (next > this.length) continue;\n\n // Node `next` covers the `bit` items after `idx`.\n const size =\n this._sums[next] + (bit - this._counts[next]) * this.estimate;\n if (size <= remaining) {\n idx = next;\n remaining -= size;\n }\n }\n return Math.min(this.length - 1, idx);\n }\n}\n\n/**\n * Pure scroll-math engine for one axis of virtual scrolling. A Fenwick tree\n * holds all size state.\n *\n * ### Virtual and DOM coordinates\n *\n * Browsers limit how far an element can scroll. When the total item size is\n * larger than that limit, the engine compresses the *virtual* space\n * (`0…totalSize`) into the *DOM* space the browser can represent\n * (`0…domSize`) by the factor `_virtualRatio`. Each offset that crosses that\n * boundary is scaled: incoming scroll positions are multiplied by the ratio,\n * and outgoing offsets are divided by it. Items render at their real pixel\n * size, so item sizes are always virtual.\n */\nexport class VirtualScrollEngine {\n private _maxBrowserSize = Number.POSITIVE_INFINITY;\n\n /**\n * Maps a virtual scroll position to a DOM scroll position. The ratio\n * `totalSize / maxBrowserSize` if `totalSize` is larger than the maximum DOM\n * coordinate of the browser, and `1` in all other cases.\n */\n private _virtualRatio = 1;\n\n /** Binary Indexed Tree for O(log N) size queries and updates. */\n private _tree: SizeTree | null = null;\n\n /** The estimate last given to `resize` or `updateEstimatedSize`. */\n private _configuredEstimate = Number.NaN;\n\n /** Whether `adaptEstimate` has applied a measured average. */\n private _hasAdaptedEstimate = false;\n\n /**\n * Called when item sizes or the item count change.\n * Example: `() => this.requestUpdate()`.\n */\n public onSizeChange: (() => void) | null = null;\n\n /** Total virtual size of all items in px. */\n public get totalSize(): number {\n return this._tree?.totalSize ?? 0;\n }\n\n /** Total size in DOM space, clamped to the maximum browser size. */\n public get domSize(): number {\n return this._virtualRatio !== 1 ? this._maxBrowserSize : this.totalSize;\n }\n\n /** Measures the maximum browser size for the document and rescales. */\n public initMaxBrowserSize(doc: Document): void {\n this._maxBrowserSize = getMaxBrowserSizeProbePx(doc);\n this._updateVirtualRatio();\n }\n\n /**\n * Resizes the internal sizes array to `length`. Measured sizes below\n * `retainCount` are kept, and the other items are unmeasured. Callers that\n * only append can keep the default `retainCount`. Callers whose data\n * changed identity at some index must pass that index, so the stale\n * measurements after it are discarded.\n *\n * Unmeasured items take `estimatedSize`, or the adapted average while\n * `estimatedSize` stays the same: a data change does not make it less\n * accurate.\n */\n public resize(\n length: number,\n estimatedSize: number,\n retainCount = length\n ): void {\n if (this._tree?.length === length && retainCount >= length) return;\n\n const reconfigured = this._configureEstimate(estimatedSize);\n const tree =\n this._tree?.cloneResized(length, retainCount) ??\n new SizeTree(length, estimatedSize);\n\n if (reconfigured) {\n tree.estimate = estimatedSize;\n }\n this._tree = tree;\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /** Records the measured DOM size for a single item. */\n public measureItem(index: number, size: number): void {\n if (!this._tree?.update(index, size)) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n /**\n * Applies a new estimated size to each item that is not measured in the\n * DOM. Use this when `estimatedItemSize` changes but the item count does\n * not, because `resize` is then a no-op.\n */\n public updateEstimatedSize(estimatedSize: number): void {\n if (this._configureEstimate(estimatedSize)) {\n this._applyEstimate(estimatedSize);\n }\n }\n\n /**\n * Sets the estimate of the unmeasured items to the average size measured\n * since the estimate was last configured. Older sizes can be out of date,\n * for example after a density change.\n *\n * The first change applies anywhere. A later one applies only while each\n * item before `windowStart` is measured: the offset of the rendered items\n * then does not depend on the estimate, so the change cannot move them.\n */\n public adaptEstimate(windowStart: number): void {\n const tree = this._tree;\n if (!tree?.sampleAverage) return;\n if (this._hasAdaptedEstimate && !tree.isMeasuredBefore(windowStart)) return;\n\n this._hasAdaptedEstimate = true;\n this._applyEstimate(tree.sampleAverage);\n }\n\n /**\n * Returns the DOM scroll offset in px that puts the item at `index` at the\n * leading edge of the viewport.\n */\n public getScrollOffsetForIndex(index: number): number {\n if (!this._tree || index <= 0) return 0;\n\n const clamped = Math.min(index, this._tree.length);\n return this._tree.prefixSum(clamped) / this._virtualRatio;\n }\n\n /**\n * The largest DOM scroll offset the host can reach for the given viewport\n * size. A request past it does nothing, so an offset given to a caller that\n * waits for the scroll to settle is clamped to this value.\n */\n private _getMaxScrollOffset(viewportSize: number): number {\n return Math.max(0, this.domSize - viewportSize);\n }\n\n /**\n * Returns the DOM scroll offset that positions the item at `index` in a\n * `viewportSize` px viewport, aligned by `align` and clamped to the\n * reachable scroll range.\n *\n * The slack is computed in virtual space against the item's real size and\n * converted to DOM space once, at the end. One DOM pixel equals\n * `_virtualRatio` virtual pixels, so mixed coordinates would scale the\n * slack.\n */\n public getAlignedScrollOffset(\n index: number,\n viewportSize: number,\n align: ScrollAlignment\n ): number {\n if (!this._tree || this._tree.length === 0) return 0;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n let offset = itemStart;\n\n if (align !== 'start') {\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const slack = viewportSize - Math.max(0, itemEnd - itemStart);\n offset -= align === 'center' ? slack / 2 : slack;\n }\n\n return clamp(\n offset / this._virtualRatio,\n 0,\n this._getMaxScrollOffset(viewportSize)\n );\n }\n\n /**\n * Returns the DOM scroll offset that brings the item at `index` into view\n * as `position` asks. `nearest` follows native `scrollIntoView`: an item in\n * view, or one that covers the viewport, keeps `scrollPosition`, and any\n * other item scrolls the smallest distance to an edge alignment.\n */\n public resolveScrollOffset(\n index: number,\n scrollPosition: number,\n viewportSize: number,\n position: ScrollLogicalPosition = 'start'\n ): number {\n if (position === 'nearest') {\n const start = this.getAlignedScrollOffset(index, viewportSize, 'start');\n const end = this.getAlignedScrollOffset(index, viewportSize, 'end');\n return clamp(scrollPosition, Math.min(start, end), Math.max(start, end));\n }\n\n return this.getAlignedScrollOffset(\n index,\n viewportSize,\n position === 'center' || position === 'end' ? position : 'start'\n );\n }\n\n /**\n * Whether the item at `index` is visible without more scrolling at the\n * given DOM scroll position. True when the item is fully inside the\n * viewport, or when it is larger than the viewport and covers it fully.\n * The second case matches native `scrollIntoView({ block: 'nearest' })`.\n */\n public isIndexInView(\n index: number,\n scrollPosition: number,\n viewportSize: number\n ): boolean {\n if (!this._tree || this._tree.length === 0) return false;\n\n const clamped = clampIndex(index, this._tree.length);\n const itemStart = this._tree.prefixSum(clamped);\n const itemEnd = this._tree.prefixSum(clamped + 1);\n const viewStart = Math.max(0, scrollPosition) * this._virtualRatio;\n const viewEnd = viewStart + viewportSize;\n\n const contained = itemStart >= viewStart && itemEnd <= viewEnd;\n const spanning = itemStart <= viewStart && itemEnd >= viewEnd;\n\n return contained || spanning;\n }\n\n /**\n * Returns the visible and over-scanned item range for the given scroll\n * state.\n */\n public getVisibleRange(\n scrollPosition: number,\n viewportSize: number,\n overScan: number\n ): VisibleRange {\n if (!this._tree || this._tree.length === 0 || viewportSize <= 0) {\n return { startIndex: 0, endIndex: -1 };\n }\n\n // The virtual ratio does not scale the viewport. Items render at their real\n // pixel size, so a `viewportSize` px viewport shows that many virtual pixels\n // of items at any compression of the scroll range.\n const startOffset = Math.max(0, scrollPosition) * this._virtualRatio;\n const first = this._tree.findIndexAtOffset(startOffset);\n const last = this._tree.findIndexAtOffset(startOffset + viewportSize);\n\n return {\n startIndex: Math.max(0, first - overScan),\n endIndex: Math.min(this._tree.length - 1, last + overScan),\n };\n }\n\n /**\n * Sum of the actual sizes of the items in [startIndex, endIndex]. The\n * render pass uses it to clamp the content translate offset, so rendered\n * items do not overflow past `domSize` under coordinate compression.\n */\n public getPhysicalRangeSize(startIndex: number, endIndex: number): number {\n if (!this._tree) return 0;\n\n const start = Math.max(0, startIndex);\n const end = Math.min(Math.max(endIndex + 1, start), this._tree.length);\n return this._tree.prefixSum(end) - this._tree.prefixSum(start);\n }\n\n /**\n * Records a changed configured estimate and starts a new sample. Returns\n * false for an unchanged one, which keeps the adapted average.\n */\n private _configureEstimate(estimatedSize: number): boolean {\n if (estimatedSize === this._configuredEstimate) return false;\n\n this._configuredEstimate = estimatedSize;\n this._tree?.startSample();\n return true;\n }\n\n private _applyEstimate(estimatedSize: number): void {\n const tree = this._tree;\n if (!tree) return;\n\n const total = tree.totalSize;\n tree.estimate = estimatedSize;\n if (tree.totalSize === total) return;\n\n this._updateVirtualRatio();\n this.onSizeChange?.();\n }\n\n private _updateVirtualRatio(): void {\n const totalSize = this._tree?.totalSize ?? 0;\n this._virtualRatio =\n totalSize <= this._maxBrowserSize ? 1 : totalSize / this._maxBrowserSize;\n }\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import type { ItemTemplate, KeyFn } from 'lit/directives/repeat.js';
2
+ interface RecycleDirectiveFn {
3
+ <T>(items: readonly T[], keyFn: KeyFn<T>, template: ItemTemplate<T>): unknown;
4
+ }
5
+ /**
6
+ * Renders `items` as `repeat` does, but gives the DOM of a key that leaves to
7
+ * a key that arrives. `repeat` destroys the part of each key that leaves and
8
+ * creates one for each key that arrives, which in a scrolling window is DOM
9
+ * churn on each scroll step. A reused part keeps any DOM state that the
10
+ * template does not bind.
11
+ */
12
+ export declare const recycle: RecycleDirectiveFn;
13
+ export {};
@@ -0,0 +1,152 @@
1
+ import { noChange, nothing, render } from 'lit';
2
+ import { clearPart, getCommittedValue, insertPart, setChildPartValue, setCommittedValue, } from 'lit/directive-helpers.js';
3
+ import { Directive, directive } from 'lit/directive.js';
4
+ import { getRoot } from '#internals/utils/dom.js';
5
+ const KEPT_WEIGHT = 2;
6
+ function heaviestIncreasingSubsequence(values, weights, size) {
7
+ const heaviest = new Int32Array(size + 1);
8
+ const endsAt = new Int32Array(size + 1);
9
+ const previous = new Int32Array(values.length);
10
+ const marked = new Uint8Array(values.length);
11
+ let best = 0;
12
+ let last = -1;
13
+ for (let i = 0; i < values.length; i++) {
14
+ if (values[i] < 0) {
15
+ continue;
16
+ }
17
+ let total = 0;
18
+ let before = -1;
19
+ for (let node = values[i]; node > 0; node -= node & -node) {
20
+ if (heaviest[node] > total) {
21
+ total = heaviest[node];
22
+ before = endsAt[node];
23
+ }
24
+ }
25
+ total += weights[i];
26
+ previous[i] = before;
27
+ for (let node = values[i] + 1; node <= size; node += node & -node) {
28
+ if (total > heaviest[node]) {
29
+ heaviest[node] = total;
30
+ endsAt[node] = i;
31
+ }
32
+ }
33
+ if (total > best) {
34
+ best = total;
35
+ last = i;
36
+ }
37
+ }
38
+ for (let i = last; i >= 0; i = previous[i]) {
39
+ marked[i] = 1;
40
+ }
41
+ return marked;
42
+ }
43
+ function removeItemPart(part) {
44
+ clearPart(part);
45
+ part.startNode.remove();
46
+ part.endNode.remove();
47
+ }
48
+ function focusedPosition(containerPart, parts) {
49
+ const container = containerPart.parentNode;
50
+ let node = getRoot(container).activeElement;
51
+ while (node && node.parentNode !== container) {
52
+ node = node.parentNode;
53
+ }
54
+ if (!node) {
55
+ return -1;
56
+ }
57
+ return parts.findIndex((part) => {
58
+ let n = part.startNode.nextSibling;
59
+ while (n && n !== part.endNode && n !== node) {
60
+ n = n.nextSibling;
61
+ }
62
+ return n === node;
63
+ });
64
+ }
65
+ class RecycleDirective extends Directive {
66
+ constructor() {
67
+ super(...arguments);
68
+ this._keys = [];
69
+ this._pool = [];
70
+ }
71
+ render(items, _keyFn, template) {
72
+ return items.map(template);
73
+ }
74
+ update(containerPart, [items, keyFn, template]) {
75
+ const keys = items.map(keyFn);
76
+ const values = items.map(template);
77
+ const committed = getCommittedValue(containerPart);
78
+ if (!Array.isArray(committed)) {
79
+ this._keys = keys;
80
+ return values;
81
+ }
82
+ setCommittedValue(containerPart, this._reconcile(containerPart, committed, keys, values));
83
+ this._keys = keys;
84
+ return noChange;
85
+ }
86
+ _reconcile(containerPart, oldParts, keys, values) {
87
+ const count = keys.length;
88
+ const parts = new Array(count);
89
+ const from = new Int32Array(count).fill(-1);
90
+ const weights = new Int32Array(count);
91
+ const claimed = new Uint8Array(oldParts.length);
92
+ const oldPositions = new Map();
93
+ const focused = focusedPosition(containerPart, oldParts);
94
+ for (let i = this._keys.length - 1; i >= 0; i--) {
95
+ oldPositions.set(this._keys[i], i);
96
+ }
97
+ for (let i = 0; i < count; i++) {
98
+ const position = oldPositions.get(keys[i]);
99
+ if (position !== undefined && !claimed[position]) {
100
+ claimed[position] = 1;
101
+ from[i] = position;
102
+ weights[i] = position === focused ? KEPT_WEIGHT * count : KEPT_WEIGHT;
103
+ }
104
+ }
105
+ let spare = 0;
106
+ for (let i = 0; i < count; i++) {
107
+ if (from[i] < 0) {
108
+ while (claimed[spare])
109
+ spare++;
110
+ if (spare < oldParts.length) {
111
+ claimed[spare] = 1;
112
+ from[i] = spare;
113
+ weights[i] = 1;
114
+ }
115
+ }
116
+ parts[i] = from[i] < 0 ? this._pool.pop() : oldParts[from[i]];
117
+ }
118
+ oldParts.forEach((part, position) => {
119
+ if (!claimed[position])
120
+ this._release(part);
121
+ });
122
+ const stable = heaviestIncreasingSubsequence(from, weights, oldParts.length);
123
+ let next;
124
+ for (let i = count - 1; i >= 0; i--) {
125
+ let part = parts[i];
126
+ if (!part) {
127
+ part = parts[i] = insertPart(containerPart, next);
128
+ }
129
+ else if (!stable[i]) {
130
+ insertPart(containerPart, next, part);
131
+ }
132
+ setChildPartValue(part, values[i]);
133
+ next = part;
134
+ }
135
+ while (this._pool.length > count) {
136
+ removeItemPart(this._pool.pop());
137
+ }
138
+ return parts;
139
+ }
140
+ _release(part) {
141
+ const doc = part.parentNode.ownerDocument;
142
+ if (this._poolRoot?.parentNode.ownerDocument !== doc) {
143
+ this._poolRoot = render(nothing, doc.createDocumentFragment(), {
144
+ isConnected: false,
145
+ });
146
+ }
147
+ insertPart(this._poolRoot, undefined, part);
148
+ this._pool.push(part);
149
+ }
150
+ }
151
+ export const recycle = directive(RecycleDirective);
152
+ //# sourceMappingURL=recycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recycle.js","sourceRoot":"","sources":["../../../src/components/virtualization/recycle.ts"],"names":[],"mappings":"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","sourcesContent":["import { type ChildPart, noChange, nothing, type RootPart, render } from 'lit';\nimport {\n clearPart,\n getCommittedValue,\n insertPart,\n setChildPartValue,\n setCommittedValue,\n} from 'lit/directive-helpers.js';\nimport { Directive, directive } from 'lit/directive.js';\nimport type { ItemTemplate, KeyFn } from 'lit/directives/repeat.js';\nimport { getRoot } from '#internals/utils/dom.js';\n\n/**\n * The weight of a kept part when the reconciliation selects the parts that do\n * not move. A recycled part weighs 1. A moved element needs a new style and\n * layout, but a recycled element needs a new layout for its new item anyway.\n * So on a scroll, the kept parts move only when they are fewer than half the\n * recycled parts.\n */\nconst KEPT_WEIGHT = 2;\n\n/**\n * Marks the entries of the increasing subsequence of `values` with the largest\n * total weight. The values are distinct integers in `[0, size)`, or negative\n * for the entries to skip. O(n log size).\n */\nfunction heaviestIncreasingSubsequence(\n values: Int32Array,\n weights: Int32Array,\n size: number\n): Uint8Array {\n // A Fenwick tree over the values. Each node holds the weight of the heaviest\n // subsequence that ends at a value in its range, and the entry of its last\n // value.\n const heaviest = new Int32Array(size + 1);\n const endsAt = new Int32Array(size + 1);\n const previous = new Int32Array(values.length);\n const marked = new Uint8Array(values.length);\n let best = 0;\n let last = -1;\n\n for (let i = 0; i < values.length; i++) {\n if (values[i] < 0) {\n continue;\n }\n\n let total = 0;\n let before = -1;\n for (let node = values[i]; node > 0; node -= node & -node) {\n if (heaviest[node] > total) {\n total = heaviest[node];\n before = endsAt[node];\n }\n }\n\n total += weights[i];\n previous[i] = before;\n for (let node = values[i] + 1; node <= size; node += node & -node) {\n if (total > heaviest[node]) {\n heaviest[node] = total;\n endsAt[node] = i;\n }\n }\n if (total > best) {\n best = total;\n last = i;\n }\n }\n\n for (let i = last; i >= 0; i = previous[i]) {\n marked[i] = 1;\n }\n return marked;\n}\n\n/**\n * Removes an item part, its content, and both markers. `removePart` leaves\n * the end marker in the DOM since lit-html 3.3.1 (lit/lit#5010).\n */\nfunction removeItemPart(part: ChildPart): void {\n clearPart(part);\n (part.startNode as ChildNode).remove();\n (part.endNode as ChildNode).remove();\n}\n\n/** Returns the position of the part in `parts` that holds the focus, or -1. */\nfunction focusedPosition(\n containerPart: ChildPart,\n parts: readonly ChildPart[]\n): number {\n const container = containerPart.parentNode;\n let node: Node | null = getRoot(container).activeElement;\n\n while (node && node.parentNode !== container) {\n node = node.parentNode;\n }\n if (!node) {\n return -1;\n }\n\n return parts.findIndex((part) => {\n let n = part.startNode!.nextSibling;\n while (n && n !== part.endNode && n !== node) {\n n = n.nextSibling;\n }\n return n === node;\n });\n}\n\nclass RecycleDirective extends Directive {\n /** The key of each committed item part, in DOM order. */\n private _keys: unknown[] = [];\n\n /** Item parts that no key needed, detached and kept for reuse. */\n private readonly _pool: ChildPart[] = [];\n\n /**\n * The disconnected parent of the pooled parts, in the document of the\n * container. A part that moves to another document is adopted: its custom\n * elements get `adoptedCallback`, and its images load again. `insertPart`\n * notifies the async directives in a part when it moves the part between\n * parents with a different connected state, so a pooled part is\n * disconnected, and a reused one is connected again.\n */\n private _poolRoot?: RootPart;\n\n public render<T>(\n items: readonly T[],\n _keyFn: KeyFn<T>,\n template: ItemTemplate<T>\n ): unknown[] {\n return items.map(template);\n }\n\n public override update<T>(\n containerPart: ChildPart,\n [items, keyFn, template]: [readonly T[], KeyFn<T>, ItemTemplate<T>]\n ): unknown {\n const keys = items.map(keyFn);\n const values = items.map(template);\n const committed = getCommittedValue(containerPart);\n\n // First render, or the part held another value: Lit creates the parts.\n if (!Array.isArray(committed)) {\n this._keys = keys;\n return values;\n }\n\n setCommittedValue(\n containerPart,\n this._reconcile(containerPart, committed as ChildPart[], keys, values)\n );\n this._keys = keys;\n return noChange;\n }\n\n /**\n * Gives each key an item part, puts the parts in key order, and sets their\n * values.\n *\n * 1. A key that stays keeps its part.\n * 2. The other keys take the parts of the keys that left, in DOM order, so\n * a full replacement moves no DOM. Then they take pooled parts. A part\n * is created only when both run out.\n * 3. The parts that no key takes go to the pool, so a window that changes\n * size by an item or two creates no DOM.\n * 4. The reused parts in the heaviest subsequence that keeps its old order\n * do not move, see `KEPT_WEIGHT`. A kept part that holds the focus\n * weighs more than all the other parts together, so it does not move and\n * keeps the focus. Each other part moves in front of its successor,\n * unless it is already there.\n */\n private _reconcile(\n containerPart: ChildPart,\n oldParts: ChildPart[],\n keys: unknown[],\n values: unknown[]\n ): ChildPart[] {\n const count = keys.length;\n const parts: (ChildPart | undefined)[] = new Array(count);\n // The old DOM position (-1 for a pooled or new part) and the weight of the\n // part at each new position.\n const from = new Int32Array(count).fill(-1);\n const weights = new Int32Array(count);\n const claimed = new Uint8Array(oldParts.length);\n const oldPositions = new Map<unknown, number>();\n const focused = focusedPosition(containerPart, oldParts);\n\n for (let i = this._keys.length - 1; i >= 0; i--) {\n oldPositions.set(this._keys[i], i);\n }\n\n for (let i = 0; i < count; i++) {\n const position = oldPositions.get(keys[i]);\n\n if (position !== undefined && !claimed[position]) {\n claimed[position] = 1;\n from[i] = position;\n weights[i] = position === focused ? KEPT_WEIGHT * count : KEPT_WEIGHT;\n }\n }\n\n let spare = 0;\n for (let i = 0; i < count; i++) {\n if (from[i] < 0) {\n while (claimed[spare]) spare++;\n if (spare < oldParts.length) {\n claimed[spare] = 1;\n from[i] = spare;\n weights[i] = 1;\n }\n }\n parts[i] = from[i] < 0 ? this._pool.pop() : oldParts[from[i]];\n }\n\n oldParts.forEach((part, position) => {\n if (!claimed[position]) this._release(part);\n });\n\n const stable = heaviestIncreasingSubsequence(\n from,\n weights,\n oldParts.length\n );\n\n let next: ChildPart | undefined;\n for (let i = count - 1; i >= 0; i--) {\n let part = parts[i];\n\n if (!part) {\n part = parts[i] = insertPart(containerPart, next);\n } else if (!stable[i]) {\n insertPart(containerPart, next, part);\n }\n\n setChildPartValue(part, values[i]);\n next = part;\n }\n\n // Cap the pool at the window size, so a window that shrinks for good\n // frees its parts.\n while (this._pool.length > count) {\n removeItemPart(this._pool.pop()!);\n }\n\n return parts as ChildPart[];\n }\n\n private _release(part: ChildPart): void {\n const doc = part.parentNode.ownerDocument!;\n\n // A new root on the first release, and after the container moves to\n // another document. The parts in an old root move to the new document\n // only when they are reused.\n if (this._poolRoot?.parentNode.ownerDocument !== doc) {\n this._poolRoot = render(nothing, doc.createDocumentFragment(), {\n isConnected: false,\n });\n }\n\n insertPart(this._poolRoot, undefined, part);\n this._pool.push(part);\n }\n}\n\ninterface RecycleDirectiveFn {\n <T>(items: readonly T[], keyFn: KeyFn<T>, template: ItemTemplate<T>): unknown;\n}\n\n/**\n * Renders `items` as `repeat` does, but gives the DOM of a key that leaves to\n * a key that arrives. `repeat` destroys the part of each key that leaves and\n * creates one for each key that arrives, which in a scrolling window is DOM\n * churn on each scroll step. A reused part keeps any DOM state that the\n * template does not bind.\n */\nexport const recycle = directive(RecycleDirective) as RecycleDirectiveFn;\n"]}
@@ -3,6 +3,7 @@ import type { Constructor } from '#internals/mixins/constructor.js';
3
3
  import { VirtualScrollEngine } from './engine.js';
4
4
  import { type VirtualScrollDataRequest, VirtualScrollItemContext, type VirtualScrollState } from './types.js';
5
5
  export type VirtualScrollItemTemplate<T> = (context: VirtualScrollItemContext<T>) => TemplateResult | typeof nothing;
6
+ export type VirtualScrollKeyFunction<T> = (item: T, index: number) => unknown;
6
7
  export interface IgcVirtualScrollComponentEventMap {
7
8
  igcStateChange: CustomEvent<VirtualScrollState>;
8
9
  igcDataRequest: CustomEvent<VirtualScrollDataRequest>;
@@ -32,10 +33,8 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
32
33
  private readonly _itemResizeController;
33
34
  private _currentRange;
34
35
  /**
35
- * The item index each wrapper element was last observed under. Lit reuses
36
- * the wrapper elements across renders. After a scroll, the same element
37
- * can host a different item at an identical size, and a ResizeObserver
38
- * does not report that. See `_scheduleItemMeasurement`.
36
+ * The item index each wrapper element was last observed under. See
37
+ * `_scheduleItemMeasurement`.
39
38
  */
40
39
  private readonly _observedItemIndexes;
41
40
  private _lastEmittedState;
@@ -43,18 +42,18 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
43
42
  private _layoutCompletePromise;
44
43
  private _scrollRequestId;
45
44
  /**
46
- * The `startIndex` of the last emitted `igcDataRequest`, which is also the
47
- * item count at that emit. See `_checkDataRequest`.
45
+ * The `startIndex` of the last `igcDataRequest`, which is also the item count
46
+ * at that emit. See `_checkDataRequest`.
48
47
  *
49
- * Kept across a disconnect, like `_hasPendingDataRequest`: a move in the
50
- * DOM does not undo what the consumer was already asked for. If only one
51
- * of the two were cleared, the request loop would reopen on reconnect.
48
+ * Kept across a disconnect, as `_hasPendingDataRequest` is. A move in the DOM
49
+ * does not cancel what the consumer was already asked for, and clearing only
50
+ * one of the two opens the request loop again on reconnect.
52
51
  */
53
52
  private _lastDataRequestIndex;
54
53
  /**
55
- * The live scroll offset on the active axis. Not reactive by design:
56
- * `render` reads it only through `_currentRange`, so `_handleScroll`
57
- * schedules an update only when the window moves.
54
+ * The live scroll offset on the active axis. Not reactive: `render` reads it
55
+ * only through `_currentRange`, so `_handleScroll` schedules an update only
56
+ * if the window moves.
58
57
  */
59
58
  private _scrollPosition;
60
59
  private _viewportSize;
@@ -82,6 +81,8 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
82
81
  /**
83
82
  * Estimated item size in pixels, used before an item is measured in the DOM.
84
83
  * After the first render of an item, the engine replaces the estimate with the measured size.
84
+ * The average measured size also replaces the estimate of the items that are not measured
85
+ * yet, so the scrollbar follows the real content.
85
86
  * @attr estimated-item-size
86
87
  * @default 50
87
88
  */
@@ -98,16 +99,32 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
98
99
  * infer an item's position from the markup. Templates that render a role
99
100
  * with set semantics (`option`, `listitem`, `row`, ...) should map the
100
101
  * context's `index` and `count` onto `aria-posinset` and `aria-setsize`.
102
+ *
103
+ * Item elements are recycled (see `keyFunction`), so DOM state that the
104
+ * template does not bind moves to another item, for example the state of a
105
+ * checkbox without a `checked` binding. Bind all item state. Lit compares a
106
+ * binding with the value that it set last, not with the element, so bind
107
+ * state that the user changes with Lit's `live` directive. Also write user
108
+ * changes back to the item, or they are lost when the item leaves the window.
109
+ * To get new DOM for each item, wrap the content in Lit's `keyed` directive
110
+ * with the item key: `` html`${keyed(ctx.value.id, content)}` ``.
101
111
  */
102
112
  itemTemplate: VirtualScrollItemTemplate<T> | null;
113
+ /**
114
+ * A function that returns a unique key for an item. Receives the item and its index in `data`.
115
+ *
116
+ * An item keeps its rendered element while its key stays in the rendered window. The elements
117
+ * of keys that leave the window are reused for keys that enter it. Without it, the index is the
118
+ * key, so after a `data` change an index keeps its element and shows its new item. Set it when
119
+ * items move within `data`, for example on sort, insert or remove.
120
+ */
121
+ keyFunction: VirtualScrollKeyFunction<T> | null;
103
122
  private _adoptStyles;
104
123
  constructor();
105
124
  /** @internal */
106
125
  createRenderRoot(): HTMLElement | DocumentFragment;
107
126
  /** @internal */
108
127
  connectedCallback(): void;
109
- /** @internal */
110
- disconnectedCallback(): void;
111
128
  protected willUpdate(changed: PropertyValues<this>): void;
112
129
  protected updated(_changed: PropertyValues<this>): void;
113
130
  protected render(): TemplateResult;
@@ -118,18 +135,17 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
118
135
  private get _normalizedItemSize();
119
136
  /** `data`, guarded against a nullish value set by the consumer. */
120
137
  private get _items();
138
+ /** The key that ties the item at `index` to its rendered element. */
139
+ private _keyOf;
121
140
  /**
122
141
  * The window to render for the current scroll position and viewport. Empty
123
142
  * until an `itemTemplate` is set, because nothing renders without one.
124
143
  */
125
144
  private _computeRange;
126
145
  /**
127
- * The scroll offset that aligns `index` in the viewport according to
128
- * `options`, from the engine's current size data. As more items are
129
- * measured, the same input can give a different, more accurate result.
130
- *
131
- * For `block: 'nearest'` on an item already in view, returns the current
132
- * offset, so no scroll occurs.
146
+ * The scroll offset that aligns `index` in the viewport, as `options` gives,
147
+ * from the current size data of the engine. The same input can give a
148
+ * different result as more items are measured.
133
149
  */
134
150
  private _getAlignedScrollOffset;
135
151
  /** Applies a scroll offset to the correct axis, accounting for RTL. */
@@ -137,84 +153,83 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
137
153
  /** The current real scroll position on the active axis, normalized for RTL. */
138
154
  private _currentAxisScroll;
139
155
  /**
140
- * Applies a scroll offset to the active axis and waits for the scroll,
141
- * instant or smooth, to settle.
156
+ * Applies a scroll offset to the active axis, and waits for the scroll to
157
+ * settle.
142
158
  *
143
- * `scrollend` does not fire when the requested offset does not move the
144
- * scroll position, so that case resolves immediately. The timeout covers
145
- * an event that never arrives, for example when the element disconnects
146
- * mid-scroll.
159
+ * @remarks
160
+ * `scrollend` does not fire if the offset does not move the scroll position,
161
+ * so that case resolves immediately. The timeout covers an event that never
162
+ * arrives, for example when the element disconnects during the scroll.
147
163
  */
148
164
  private _scrollAndWaitForEnd;
149
165
  /**
150
- * Resolves with `task` or with a deadline of `ms`, whichever comes first.
151
- * The signal then tears down the other, so no live timer or dangling
152
- * listener remains.
166
+ * Resolves with `task`, or with a deadline of `ms`, whichever is first. The
167
+ * signal then stops the other, so no timer or listener stays alive.
153
168
  */
154
169
  private _withDeadline;
155
170
  private _waitForScrollEnd;
156
171
  /**
157
- * Resolves when no `scroll` event arrives for `SCROLL_IDLE_MS`: the
158
- * closest replacement for `scrollend`. The first timer starts immediately,
159
- * so a scroll that does not move still settles.
172
+ * Resolves if no `scroll` event arrives for `SCROLL_IDLE_MS`, which is the
173
+ * closest replacement for `scrollend`. The first timer starts immediately, so
174
+ * a scroll that does not move also settles.
160
175
  */
161
176
  private _waitForScrollIdle;
162
177
  private _timeout;
163
178
  private _measureViewport;
164
179
  /**
165
- * Records the new scroll offset. Schedules a render only when the rendered
180
+ * Records the new scroll offset. Schedules a render only if the rendered
166
181
  * window moves.
167
182
  *
168
- * `render` derives the track size, the content translate, and the item
169
- * slice from `_currentRange`, not from the scroll offset. Without the
170
- * guard, a scroll inside one item would re-run each item template for an
171
- * identical result. `willUpdate` still recomputes `_currentRange` for each
172
- * other trigger, so this suppresses only redundant passes, never a needed
173
- * one.
183
+ * @remarks
184
+ * `render` reads `_currentRange`, not the scroll offset. Without the guard,
185
+ * a scroll inside one item runs each item template again for the same
186
+ * result. `willUpdate` recomputes `_currentRange` for the other triggers,
187
+ * so this skips only the redundant passes.
174
188
  */
175
189
  private _handleScroll;
176
190
  /**
177
- * The number of leading items that kept their identity across a `data`
178
- * change: the index of the first item whose measured size no longer
179
- * matches its rendered content. An append (the `igcDataRequest` flow)
180
- * retains all items. A filter or a replacement retains only the unchanged
181
- * prefix.
191
+ * The length of the prefix that a `data` change keeps: the first index at
192
+ * which the old and the new items differ, or the length of the shorter array
193
+ * if neither differs. Measurements below that index stay valid. An append
194
+ * keeps all the previous items. A filter or a replacement keeps fewer.
195
+ *
196
+ * @remarks
197
+ * The test is item identity. An item that changes in place keeps its
198
+ * measured size.
182
199
  */
183
200
  private _firstChangedIndex;
184
201
  private _handleItemResize;
185
202
  /**
186
- * Synchronizes the item observer with the rendered window and applies only
187
- * the difference. A newly observed element gets one initial measurement.
188
- * An `observe` call on an already observed element is a no-op, so a
189
- * re-measurement on demand requires re-registration: unobserve, then
190
- * observe.
203
+ * Syncs the item observer with the rendered window, and applies only the
204
+ * difference.
191
205
  *
192
- * Re-registration is applied to each element whose `data-vs-index`
193
- * changed. Lit reuses the wrapper elements across renders, so after a
194
- * scroll the same element can host a different item at an identical size.
195
- * The observer does not report that, and the new index would keep its
196
- * estimated size.
206
+ * @remarks
207
+ * `observe` on an already observed element does nothing, so a new
208
+ * measurement needs `unobserve` and then `observe`. Do this for each element
209
+ * whose `data-vs-index` changed. The wrapper elements are recycled, so after
210
+ * a scroll one element can hold a different item at the same size. The
211
+ * observer does not report that, and the new index keeps its estimated size.
197
212
  */
198
213
  private _scheduleItemMeasurement;
199
214
  /**
200
- * Emits `igcStateChange`. Skipped when the window is empty or equal to the
201
- * last reported one, because measurement passes re-render without a window
202
- * change.
215
+ * Emits `igcStateChange`. Does nothing if the window is empty or equal to
216
+ * the last reported one, because a measurement pass renders again with no
217
+ * window change.
203
218
  */
204
219
  private _emitStateChange;
205
220
  private _checkDataRequest;
206
221
  /**
207
- * Resolves on the next animation frame, or after `LAYOUT_FRAME_TIMEOUT_MS`
208
- * when no frame arrives. A hidden tab or a disconnected element gets no
209
- * frames, and `layoutComplete` must still settle there. That state has no
210
- * layout to wait for, so an early resolve is safe.
222
+ * Resolves on the next animation frame, or after `LAYOUT_FRAME_TIMEOUT_MS` if
223
+ * no frame arrives. A hidden tab or a disconnected element gets no frames,
224
+ * and `layoutComplete` must still settle. Such a state has no layout to wait
225
+ * for, so an early resolve is safe.
211
226
  */
212
227
  private _nextFrame;
213
228
  /**
214
- * Waits for the current update, then lets ResizeObserver item measurements
215
- * run. When those schedule a follow-up render, for example an estimate
216
- * replaced by a measured size, the wait repeats until nothing is pending,
217
- * up to a safety cap.
229
+ * Waits for the current update, then lets the ResizeObserver measurements
230
+ * run. If those schedule one more render, for example when a measured size
231
+ * replaces an estimate, the wait repeats until nothing is pending, up to a
232
+ * safety cap.
218
233
  */
219
234
  private _resolveLayoutComplete;
220
235
  /**
@@ -230,6 +245,10 @@ export default class IgcVirtualScrollComponent<T = any> extends IgcVirtualScroll
230
245
  /**
231
246
  * Scrolls to the specified item index.
232
247
  *
248
+ * `block` (`inline` in the horizontal orientation) positions the item as in
249
+ * `scrollIntoView`, and defaults to `start`. With `nearest`, the item
250
+ * scrolls the smallest distance that brings it into view.
251
+ *
233
252
  * Items outside the rendered window have only an estimated size, so the
234
253
  * first jump can miss the target. The items at the landing point are then
235
254
  * measured, and the scroll position is corrected. This repeats until the