apex-grid 3.6.0 → 4.0.0-beta.2

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 (151) hide show
  1. package/CHANGELOG.md +301 -0
  2. package/LICENSE.md +2 -1
  3. package/README.md +117 -18
  4. package/components/cell.d.ts +13 -1
  5. package/components/cell.js +28 -13
  6. package/components/cell.js.map +1 -1
  7. package/components/grid.d.ts +175 -28
  8. package/components/grid.js +183 -63
  9. package/components/grid.js.map +1 -1
  10. package/components/header-row.d.ts +0 -6
  11. package/components/header-row.js +1 -19
  12. package/components/header-row.js.map +1 -1
  13. package/components/header.js +39 -2
  14. package/components/header.js.map +1 -1
  15. package/components/paginator.d.ts +20 -5
  16. package/components/paginator.js +54 -17
  17. package/components/paginator.js.map +1 -1
  18. package/components/row.js +149 -40
  19. package/components/row.js.map +1 -1
  20. package/components/toolbar.d.ts +5 -1
  21. package/components/toolbar.js +4 -1
  22. package/components/toolbar.js.map +1 -1
  23. package/components/virtualize-rows.d.ts +38 -0
  24. package/components/virtualize-rows.js +286 -0
  25. package/components/virtualize-rows.js.map +1 -0
  26. package/components/virtualizer.d.ts +71 -1
  27. package/components/virtualizer.js +105 -29
  28. package/components/virtualizer.js.map +1 -1
  29. package/controllers/dom.d.ts +10 -3
  30. package/controllers/dom.js +5 -5
  31. package/controllers/dom.js.map +1 -1
  32. package/controllers/navigation.d.ts +63 -0
  33. package/controllers/navigation.js +295 -21
  34. package/controllers/navigation.js.map +1 -1
  35. package/controllers/pagination.d.ts +7 -6
  36. package/controllers/pagination.js +27 -28
  37. package/controllers/pagination.js.map +1 -1
  38. package/controllers/row-pin.d.ts +6 -0
  39. package/controllers/row-pin.js +8 -2
  40. package/controllers/row-pin.js.map +1 -1
  41. package/controllers/row-reorder.d.ts +12 -4
  42. package/controllers/row-reorder.js +20 -6
  43. package/controllers/row-reorder.js.map +1 -1
  44. package/controllers/selection.d.ts +32 -10
  45. package/controllers/selection.js +33 -10
  46. package/controllers/selection.js.map +1 -1
  47. package/controllers/sort.js +2 -3
  48. package/controllers/sort.js.map +1 -1
  49. package/controllers/state.d.ts +18 -5
  50. package/controllers/state.js +53 -46
  51. package/controllers/state.js.map +1 -1
  52. package/custom-elements.json +1762 -339
  53. package/docs/assets/hierarchy.js +1 -1
  54. package/docs/assets/search.js +1 -1
  55. package/docs/classes/ApexGrid.html +166 -66
  56. package/docs/classes/ApexGridPaginator.html +39 -8
  57. package/docs/classes/ApexGridToolbar.html +9 -5
  58. package/docs/functions/localize.html +2 -2
  59. package/docs/hierarchy.html +1 -1
  60. package/docs/index.html +123 -20
  61. package/docs/interfaces/ApexPageChangedEvent.html +3 -1
  62. package/docs/interfaces/BaseApexCellContext.html +18 -5
  63. package/docs/interfaces/BaseApexEditorContext.html +20 -5
  64. package/docs/interfaces/BaseFilterExpression.html +1 -1
  65. package/docs/interfaces/CSVExportOptions.html +1 -1
  66. package/docs/interfaces/DataPipelineConfiguration.html +4 -9
  67. package/docs/interfaces/ExportOptions.html +1 -1
  68. package/docs/interfaces/GridSelectionConfiguration.html +19 -4
  69. package/docs/interfaces/PaginationConfiguration.html +11 -4
  70. package/docs/interfaces/PaginationState.html +4 -2
  71. package/docs/media/_token-values.scss +42 -16
  72. package/docs/media/package.json +12 -4
  73. package/docs/types/DataPipelineParams.html +2 -2
  74. package/docs/types/PaginationMode.html +5 -4
  75. package/docs/variables/EN_LOCALE.html +2 -2
  76. package/i18n/en.d.ts +2 -0
  77. package/i18n/en.js +2 -0
  78. package/i18n/en.js.map +1 -1
  79. package/i18n/es.js +2 -0
  80. package/i18n/es.js.map +1 -1
  81. package/ignite-ui.d.ts +1 -0
  82. package/ignite-ui.js +4 -0
  83. package/ignite-ui.js.map +1 -0
  84. package/internal/column-types.d.ts +11 -1
  85. package/internal/column-types.js +8 -6
  86. package/internal/column-types.js.map +1 -1
  87. package/internal/design-system.d.ts +32 -0
  88. package/internal/design-system.js +66 -0
  89. package/internal/design-system.js.map +1 -0
  90. package/internal/export.d.ts +6 -0
  91. package/internal/export.js +4 -0
  92. package/internal/export.js.map +1 -1
  93. package/internal/feature-module.d.ts +7 -0
  94. package/internal/feature-module.js.map +1 -1
  95. package/internal/flip.d.ts +28 -16
  96. package/internal/flip.js +42 -10
  97. package/internal/flip.js.map +1 -1
  98. package/internal/icons.d.ts +2 -16
  99. package/internal/icons.js +0 -8
  100. package/internal/icons.js.map +1 -1
  101. package/internal/ignite-ui.d.ts +10 -0
  102. package/internal/ignite-ui.js +118 -0
  103. package/internal/ignite-ui.js.map +1 -0
  104. package/internal/index.d.ts +4 -2
  105. package/internal/index.js +3 -2
  106. package/internal/index.js.map +1 -1
  107. package/internal/types.d.ts +75 -19
  108. package/internal/types.js.map +1 -1
  109. package/operations/filter/types.d.ts +1 -1
  110. package/operations/filter/types.js.map +1 -1
  111. package/package.json +7 -2
  112. package/styles/_token-blocks.css.d.ts +1 -0
  113. package/styles/_token-blocks.css.js +3 -0
  114. package/styles/_token-blocks.css.js.map +1 -0
  115. package/styles/_tokens.css.js +1 -1
  116. package/styles/_tokens.css.js.map +1 -1
  117. package/styles/body-cell/body-cell.css.js +1 -1
  118. package/styles/body-cell/body-cell.css.js.map +1 -1
  119. package/styles/body-cell/cell-renderers.css.js +1 -1
  120. package/styles/body-cell/cell-renderers.css.js.map +1 -1
  121. package/styles/body-row/body-row.css.js +1 -1
  122. package/styles/body-row/body-row.css.js.map +1 -1
  123. package/styles/document-tokens.css.js +1 -1
  124. package/styles/document-tokens.css.js.map +1 -1
  125. package/styles/grid/_grid.base.css.js +1 -1
  126. package/styles/grid/_grid.base.css.js.map +1 -1
  127. package/styles/grid/grid.css.js +1 -1
  128. package/styles/grid/grid.css.js.map +1 -1
  129. package/styles/group-header-row/group-header-row.css.js +1 -1
  130. package/styles/group-header-row/group-header-row.css.js.map +1 -1
  131. package/styles/header-cell/header-cell.css.js +1 -1
  132. package/styles/header-cell/header-cell.css.js.map +1 -1
  133. package/styles/header-row/header-row.base.css.js +1 -1
  134. package/styles/header-row/header-row.base.css.js.map +1 -1
  135. package/styles/ignite-ui/ignite-ui-dark.css.d.ts +1 -0
  136. package/styles/ignite-ui/ignite-ui-dark.css.js +3 -0
  137. package/styles/ignite-ui/ignite-ui-dark.css.js.map +1 -0
  138. package/styles/ignite-ui/ignite-ui-document.css.d.ts +1 -0
  139. package/styles/ignite-ui/ignite-ui-document.css.js +3 -0
  140. package/styles/ignite-ui/ignite-ui-document.css.js.map +1 -0
  141. package/styles/ignite-ui/ignite-ui.css.d.ts +1 -0
  142. package/styles/ignite-ui/ignite-ui.css.js +3 -0
  143. package/styles/ignite-ui/ignite-ui.css.js.map +1 -0
  144. package/styles/paginator/paginator.css.js +1 -1
  145. package/styles/paginator/paginator.css.js.map +1 -1
  146. package/styles/toolbar/toolbar.css.js +1 -1
  147. package/styles/toolbar/toolbar.css.js.map +1 -1
  148. package/tokens.css +14 -15
  149. package/operations/pagination.d.ts +0 -19
  150. package/operations/pagination.js +0 -12
  151. package/operations/pagination.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/components/toolbar.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAwB,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,kCAAkC,CAAC;AAmB1D,MAAM,CAAC,OAAO,OAAO,eAAkC,SAAQ,UAAU;IAAzE;;QAsBS,UAAK,GAAG,EAAE,CAAC;QAUX,gBAAW,GAAG,EAAE,CAAC;QAUjB,aAAQ,GAAG,GAAG,CAAC;QAIf,oBAAe,GAAG,IAAI,CAAC;QAIvB,eAAU,GAAG,KAAK,CAAC;QAInB,mBAAc,GAAG,MAAM,CAAC;QAYrB,mBAAc,GAAG,KAAK,CAAC;QAEjC,oBAAe,GAAyC,IAAI,CAAC;QA4B7D,iBAAY,GAAG,CAAC,KAAY,EAAE,EAAE;YAC9B,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,MAAM,IAAI,GAAI,KAAK,CAAC,MAA2B,CAAC,KAAK,IAAI,EAAE,CAAC;YAC5D,IAAI,IAAI,CAAC,eAAe;gBAAE,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAE7D,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACjB,OAAO;YACT,CAAC;YAED,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,GAAG,EAAE;gBACrC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC,CAAC;QAEF,mBAAc,GAAG,CAAC,KAAoB,EAAE,EAAE;YAExC,KAAK,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBAC/C,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;oBACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC9B,CAAC;gBACD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;QACH,CAAC,CAAC;QAEF,sBAAiB,GAAG,CAAC,KAAa,EAAE,EAAE;YACpC,KAAK,EAAE,eAAe,EAAE,CAAC;YACzB,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC;QAC7C,CAAC,CAAC;QAWF,0BAAqB,GAAG,CAAC,KAAmB,EAAE,EAAE;YAC9C,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE,OAAO;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC;gBAAE,OAAO;YAClF,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,CAAC,CAAC;QAEF,uBAAkB,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC5C,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE,OAAO;YACjC,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC3B,KAAK,CAAC,eAAe,EAAE,CAAC;gBACxB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC;QAEF,kBAAa,GAAG,CAAC,QAAgB,EAAE,EAAE;YACnC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC;YAC9B,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;QAC7D,CAAC,CAAC;QAGF,0BAAqB,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC/C,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;gBACtD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,cAAc;oBAAE,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBACrD,qBAAqB,CAAC,GAAG,EAAE;oBACzB,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,aAAa,CAAc,mBAAmB,CAAC,CAAC;oBACjF,KAAK,EAAE,KAAK,EAAE,CAAC;gBACjB,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC;QAEF,uBAAkB,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CACtB,IAAI,CAAC,YAAY,EAAE,gBAAgB,CAAc,mBAAmB,CAAC,IAAI,EAAE,CAC5E,CAAC;YAGF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,EAAuC,CAAC;YACnF,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,aAA4B,CAAC,CAAC;YAClE,IAAI,KAAK,CAAC,GAAG,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;gBACtD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;YAC/C,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;gBACzD,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,CAAC,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;YAC9D,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,MAAM,EAAE,CAAC;gBAChC,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACpB,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBAC/B,KAAK,CAAC,cAAc,EAAE,CAAC;gBACvB,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;YACnC,CAAC;iBAAM,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBAE/B,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,CAAC;QACH,CAAC,CAAC;IAqFJ,CAAC;IA1RQ,MAAM,KAAK,OAAO;QACvB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;aAEsB,WAAM,GAAG,MAAM,AAAT,CAAU;IAKhC,MAAM,CAAC,QAAQ;QACpB,iBAAiB,CAAC,eAAe,CAAC,CAAC;IACrC,CAAC;IAsBD,IAAc,iBAAiB;QAC7B,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,2BAA2B,CAAC,IAAI,SAAS,CAAC;IAC5F,CAAC;IAgCD,eAAe,CAA8C;IAE7C,iBAAiB;QAC/B,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAC1B,QAAQ,CAAC,gBAAgB,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAC3E,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IACtE,CAAC;IAEe,oBAAoB;QAClC,QAAQ,CAAC,mBAAmB,CAAC,aAAa,EAAE,IAAI,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;QAC9E,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACvE,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC/B,CAAC;IAED,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,aAAa,CAChB,IAAI,WAAW,CAAS,mBAAmB,EAAE;YAC3C,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,IAAI;SACf,CAAC,CACH,CAAC;IACJ,CAAC;IAED,YAAY,CAcV;IAEF,cAAc,CAYZ;IAEF,iBAAiB,CAGf;IAEF,gBAAgB,CAAC,WAAW,GAAG,KAAK;QAClC,IAAI,CAAC,IAAI,CAAC,cAAc;YAAE,OAAO;QACjC,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,WAAW,EAAE,CAAC;YAEhB,qBAAqB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,qBAAqB,CAKnB;IAEF,kBAAkB,CAMhB;IAEF,aAAa,CAKX;IAGF,qBAAqB,CASnB;IAEF,kBAAkB,CAwBhB;IAEQ,iBAAiB;QACzB,IAAI,CAAC,IAAI,CAAC,eAAe;YAAE,OAAO,OAAO,CAAC;QAC1C,OAAO,IAAI,CAAA;;UAEL,UAAU,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;;;;;uBAKhC,IAAI,CAAC,iBAAiB;wBACrB,IAAI,CAAC,iBAAiB;mBAC3B,IAAI,CAAC,KAAK;mBACV,IAAI,CAAC,YAAY;qBACf,IAAI,CAAC,cAAc;;;WAG7B,CAAC;IACV,CAAC;IAES,gBAAgB;QACxB,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO,OAAO,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;QACjC,OAAO,IAAI,CAAA;;;;qBAIM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,gBAAgB,CAAC;;wBAElC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;iBAC9B,IAAI,CAAC,iBAAiB;mBACpB,IAAI,CAAC,qBAAqB;;UAEnC,UAAU,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;UAC/C,UAAU,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;;;;;qBAKzC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,uBAAuB,CAAC;kBAC/C,CAAC,IAAI;mBACJ,IAAI,CAAC,kBAAkB;;UAEhC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAA;;;;;;uBAMH,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;;gBAE1C,MAAM,CAAC,KAAK;;gBAEZ,CACP;;WAEE,CAAC;IACV,CAAC;IAES,oBAAoB;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,cAAc,IAAI,EAAE,CAAC;QACvD,IAAI,CAAC,OAAO,CAAC,MAAM;YAAE,OAAO,OAAO,CAAC;QACpC,OAAO,IAAI,CAAA,GAAG,OAAO,CAAC,GAAG,CACvB,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAA;;;yBAGG,MAAM,CAAC,EAAE,IAAI,EAAE;iBACvB,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE;;UAEzB,MAAM,CAAC,KAAK;gBACN,CACX,EAAE,CAAC;IACN,CAAC;IAEkB,MAAM;QACvB,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO,OAAO,CAAC;QAChC,OAAO,IAAI,CAAA;sDACuC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC;UAChF,IAAI,CAAC,iBAAiB,EAAE;sCACI,IAAI,CAAC,oBAAoB,EAAE,GAAG,IAAI,CAAC,gBAAgB,EAAE;;KAEtF,CAAC;IACJ,CAAC;;AA1QM;IAFN,OAAO,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACvD,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;8CACG;AAM3B;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;8CACT;AAUX;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;oDACH;AAUjB;IADN,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC;iDAC5B;AAIf;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;wDAChB;AAIvB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;mDACpB;AAInB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;uDACd;AAGrB;IADT,KAAK,CAAC,OAAO,CAAC;8CACoB;AAGzB;IADT,KAAK,CAAC,yBAAyB,CAAC;sDACW;AAGlC;IADT,KAAK,CAAC,sBAAsB,CAAC;qDACO;AAG3B;IADT,KAAK,EAAE;uDACyB","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_TOOLBAR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/toolbar/toolbar.css.js';\n\n/**\n * Toolbar shown above the grid's header row. Hosts opt-in toolbar features\n * such as the quick-filter (global search) input and the export menu.\n *\n * @element apex-grid-toolbar\n *\n * @csspart toolbar - The toolbar's container element.\n * @csspart toolbar-search - The quick-filter input wrapper.\n * @csspart search-field - The bordered field containing the icon + input.\n * @csspart search-icon - The leading search icon.\n * @csspart search-input - The text input itself.\n * @csspart toolbar-actions - The trailing actions area (right side).\n * @csspart toolbar-action - A custom host-contributed action button (e.g. \"Create chart\").\n * @csspart export-trigger - The export menu trigger button.\n * @csspart export-menu - The dropdown menu containing export options.\n * @csspart export-menu-item - A single menu item inside the export dropdown.\n */\nexport default class ApexGridToolbar<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_TOOLBAR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-toolbar>` element. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridToolbar);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The current quick-filter value, mirrored from {@link ApexGrid.quickFilter}.\n */\n @property({ type: String })\n public value = '';\n\n /**\n * The placeholder rendered in the search input.\n *\n * @remarks\n * When unset, falls back to the grid's localized `toolbar.searchPlaceholder`\n * text (see {@link ApexGrid.localeText}).\n */\n @property({ type: String })\n public placeholder = '';\n\n protected get searchPlaceholder() {\n return this.placeholder || this.state?.localize('toolbar.searchPlaceholder') || 'Search…';\n }\n\n /**\n * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.\n */\n @property({ type: Number, attribute: 'debounce' })\n public debounce = 200;\n\n /** Whether to render the quick-filter input. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showQuickFilter = true;\n\n /** Whether to render the export menu trigger. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showExport = false;\n\n /** Optional override filename (without extension) for exports. */\n @property({ attribute: false, type: String })\n public exportFilename = 'data';\n\n @query('input')\n protected input!: HTMLInputElement;\n\n @query('[part=\"export-trigger\"]')\n protected exportTrigger!: HTMLButtonElement;\n\n @query('[part=\"export-menu\"]')\n protected exportMenuEl!: HTMLElement;\n\n @state()\n protected exportMenuOpen = false;\n\n #debounceHandle: ReturnType<typeof setTimeout> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.addEventListener('keydown', this.#handleDocumentKey, true);\n }\n\n public override disconnectedCallback(): void {\n document.removeEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.removeEventListener('keydown', this.#handleDocumentKey, true);\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n super.disconnectedCallback();\n }\n\n #emit(value: string) {\n this.dispatchEvent(\n new CustomEvent<string>('apex-quick-filter', {\n detail: value,\n bubbles: true,\n composed: true,\n })\n );\n }\n\n #handleInput = (event: Event) => {\n event.stopPropagation();\n const next = (event.target as HTMLInputElement).value ?? '';\n if (this.#debounceHandle) clearTimeout(this.#debounceHandle);\n\n if (this.debounce <= 0) {\n this.#emit(next);\n return;\n }\n\n this.#debounceHandle = setTimeout(() => {\n this.#debounceHandle = null;\n this.#emit(next);\n }, this.debounce);\n };\n\n #handleKeydown = (event: KeyboardEvent) => {\n // Don't let arrow keys bubble into the grid navigation controller.\n event.stopPropagation();\n if (event.key === 'Escape' && this.input.value) {\n event.preventDefault();\n this.input.value = '';\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n this.#emit('');\n }\n };\n\n #toggleExportMenu = (event?: Event) => {\n event?.stopPropagation();\n this.exportMenuOpen = !this.exportMenuOpen;\n };\n\n #closeExportMenu(returnFocus = false) {\n if (!this.exportMenuOpen) return;\n this.exportMenuOpen = false;\n if (returnFocus) {\n // Return focus to the trigger so keyboard users don't lose their place.\n requestAnimationFrame(() => this.exportTrigger?.focus());\n }\n }\n\n #handleOutsidePointer = (event: PointerEvent) => {\n if (!this.exportMenuOpen) return;\n const path = event.composedPath();\n if (path.includes(this.exportTrigger) || path.includes(this.exportMenuEl)) return;\n this.#closeExportMenu();\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (!this.exportMenuOpen) return;\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.#closeExportMenu(true);\n }\n };\n\n #handleExport = (formatId: string) => {\n this.#closeExportMenu();\n const grid = this.state?.host;\n if (!grid) return;\n grid.exportAs(formatId, { filename: this.exportFilename });\n };\n\n /** Lets keyboard users land in the menu when it opens via arrow-down. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n if (!this.exportMenuOpen) this.exportMenuOpen = true;\n requestAnimationFrame(() => {\n const first = this.exportMenuEl?.querySelector<HTMLElement>('[role=\"menuitem\"]');\n first?.focus();\n });\n }\n };\n\n #handleMenuKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n this.exportMenuEl?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []\n );\n // The menu lives in this shadow root, so `document.activeElement` is only\n // the outermost host; ask the menu's own root for the focused item.\n const root = this.exportMenuEl?.getRootNode() as Document | ShadowRoot | undefined;\n const current = items.indexOf(root?.activeElement as HTMLElement);\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n items[(current + 1) % items.length]?.focus();\n } else if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault();\n items[(current - 1 + items.length) % items.length]?.focus();\n } else if (event.key === 'Home') {\n event.preventDefault();\n items[0]?.focus();\n } else if (event.key === 'End') {\n event.preventDefault();\n items[items.length - 1]?.focus();\n } else if (event.key === 'Tab') {\n // Tab closes the menu so focus moves naturally to the next focusable.\n this.#closeExportMenu();\n }\n };\n\n protected renderQuickFilter() {\n if (!this.showQuickFilter) return nothing;\n return html`<div part=\"toolbar-search\">\n <label part=\"search-field\">\n ${renderIcon('search', { part: 'search-icon' })}\n <input\n part=\"search-input\"\n type=\"search\"\n role=\"searchbox\"\n aria-label=${this.searchPlaceholder}\n placeholder=${this.searchPlaceholder}\n .value=${this.value}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </label>\n </div>`;\n }\n\n protected renderExportMenu() {\n if (!this.showExport) return nothing;\n const open = this.exportMenuOpen;\n return html`<div part=\"export\">\n <button\n type=\"button\"\n part=\"export-trigger\"\n aria-label=${this.state.localize('toolbar.export')}\n aria-haspopup=\"menu\"\n aria-expanded=${open ? 'true' : 'false'}\n @click=${this.#toggleExportMenu}\n @keydown=${this.#handleTriggerKeydown}\n >\n ${renderIcon('download', { part: 'export-icon' })}\n ${renderIcon('chevron-down', { part: 'export-caret' })}\n </button>\n <ul\n part=\"export-menu\"\n role=\"menu\"\n aria-label=${this.state.localize('toolbar.exportOptions')}\n ?hidden=${!open}\n @keydown=${this.#handleMenuKeydown}\n >\n ${(this.state?.host?.exportFormats ?? []).map(\n (format) => html`<li role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n part=\"export-menu-item\"\n tabindex=\"-1\"\n @click=${() => this.#handleExport(format.id)}\n >\n ${format.label}\n </button>\n </li>`\n )}\n </ul>\n </div>`;\n }\n\n protected renderToolbarActions() {\n const actions = this.state?.host?.toolbarActions ?? [];\n if (!actions.length) return nothing;\n return html`${actions.map(\n (action) => html`<button\n type=\"button\"\n part=\"toolbar-action\"\n data-action-id=${action.id ?? ''}\n @click=${() => action.run()}\n >\n ${action.label}\n </button>`\n )}`;\n }\n\n protected override render() {\n if (!this.state) return nothing;\n return html`\n <div part=\"toolbar\" role=\"toolbar\" aria-label=${this.state.localize('toolbar.label')}>\n ${this.renderQuickFilter()}\n <div part=\"toolbar-actions\">${this.renderToolbarActions()}${this.renderExportMenu()}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridToolbar.tagName]: ApexGridToolbar<object>;\n }\n}\n"]}
1
+ {"version":3,"file":"toolbar.js","sourceRoot":"","sources":["../../src/components/toolbar.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { gridStateContext, type StateController } from '../controllers/state.js';\nimport { renderIcon } from '../internal/icons.js';\nimport { registerComponent } from '../internal/register.js';\nimport { GRID_TOOLBAR_TAG } from '../internal/tags.js';\nimport { styles } from '../styles/toolbar/toolbar.css.js';\n\n/**\n * Toolbar shown above the grid's header row. Hosts opt-in toolbar features\n * such as the quick-filter (global search) input and the export menu. The grid\n * re-exports every part, so `apex-grid::part(name)` styles it.\n *\n * @element apex-grid-toolbar\n *\n * @csspart toolbar - The toolbar's container element.\n * @csspart toolbar-search - The quick-filter input wrapper.\n * @csspart search-field - The bordered field containing the icon + input.\n * @csspart search-icon - The leading search icon.\n * @csspart search-input - The text input itself.\n * @csspart toolbar-actions - The trailing actions area (right side).\n * @csspart toolbar-action - A custom host-contributed action button (e.g. \"Create chart\").\n * @csspart export - The export menu wrapper (trigger plus dropdown).\n * @csspart export-trigger - The export menu trigger button.\n * @csspart export-icon - The download icon in the trigger.\n * @csspart export-caret - The caret icon in the trigger.\n * @csspart export-menu - The dropdown menu containing export options.\n * @csspart export-menu-item - A single menu item inside the export dropdown.\n */\nexport default class ApexGridToolbar<T extends object> extends LitElement {\n public static get tagName() {\n return GRID_TOOLBAR_TAG;\n }\n\n public static override styles = styles;\n\n /**\n * Registers the `<apex-grid-toolbar>` element. Idempotent.\n */\n public static register() {\n registerComponent(ApexGridToolbar);\n }\n\n @consume({ context: gridStateContext, subscribe: true })\n @property({ attribute: false })\n public state!: StateController<T>;\n\n /**\n * The current quick-filter value, mirrored from {@link ApexGrid.quickFilter}.\n */\n @property({ type: String })\n public value = '';\n\n /**\n * The placeholder rendered in the search input.\n *\n * @remarks\n * When unset, falls back to the grid's localized `toolbar.searchPlaceholder`\n * text (see {@link ApexGrid.localeText}).\n */\n @property({ type: String })\n public placeholder = '';\n\n protected get searchPlaceholder() {\n return this.placeholder || this.state?.localize('toolbar.searchPlaceholder') || 'Search…';\n }\n\n /**\n * Debounce window (ms) before {@link ApexGrid.quickFilter} updates.\n */\n @property({ type: Number, attribute: 'debounce' })\n public debounce = 200;\n\n /** Whether to render the quick-filter input. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showQuickFilter = true;\n\n /** Whether to render the export menu trigger. Driven by the parent grid. */\n @property({ attribute: false, type: Boolean })\n public showExport = false;\n\n /** Optional override filename (without extension) for exports. */\n @property({ attribute: false, type: String })\n public exportFilename = 'data';\n\n @query('input')\n protected input!: HTMLInputElement;\n\n @query('[part=\"export-trigger\"]')\n protected exportTrigger!: HTMLButtonElement;\n\n @query('[part=\"export-menu\"]')\n protected exportMenuEl!: HTMLElement;\n\n @state()\n protected exportMenuOpen = false;\n\n #debounceHandle: ReturnType<typeof setTimeout> | null = null;\n\n public override connectedCallback(): void {\n super.connectedCallback();\n document.addEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.addEventListener('keydown', this.#handleDocumentKey, true);\n }\n\n public override disconnectedCallback(): void {\n document.removeEventListener('pointerdown', this.#handleOutsidePointer, true);\n document.removeEventListener('keydown', this.#handleDocumentKey, true);\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n super.disconnectedCallback();\n }\n\n #emit(value: string) {\n const applied = this.dispatchEvent(\n new CustomEvent<string>('apex-quick-filter', {\n detail: value,\n bubbles: true,\n composed: true,\n cancelable: true,\n })\n );\n // The grid did not apply this value (a cancelled quickFilterChanging, or a\n // listener substituting its own): show the value in force again. A\n // substitute arrives through `value` on the next render.\n if (!applied && this.input) this.input.value = this.value;\n }\n\n #handleInput = (event: Event) => {\n event.stopPropagation();\n const next = (event.target as HTMLInputElement).value ?? '';\n if (this.#debounceHandle) clearTimeout(this.#debounceHandle);\n\n if (this.debounce <= 0) {\n this.#emit(next);\n return;\n }\n\n this.#debounceHandle = setTimeout(() => {\n this.#debounceHandle = null;\n this.#emit(next);\n }, this.debounce);\n };\n\n #handleKeydown = (event: KeyboardEvent) => {\n // Don't let arrow keys bubble into the grid navigation controller.\n event.stopPropagation();\n if (event.key === 'Escape' && this.input.value) {\n event.preventDefault();\n this.input.value = '';\n if (this.#debounceHandle) {\n clearTimeout(this.#debounceHandle);\n this.#debounceHandle = null;\n }\n this.#emit('');\n }\n };\n\n #toggleExportMenu = (event?: Event) => {\n event?.stopPropagation();\n this.exportMenuOpen = !this.exportMenuOpen;\n };\n\n #closeExportMenu(returnFocus = false) {\n if (!this.exportMenuOpen) return;\n this.exportMenuOpen = false;\n if (returnFocus) {\n // Return focus to the trigger so keyboard users don't lose their place.\n requestAnimationFrame(() => this.exportTrigger?.focus());\n }\n }\n\n #handleOutsidePointer = (event: PointerEvent) => {\n if (!this.exportMenuOpen) return;\n const path = event.composedPath();\n if (path.includes(this.exportTrigger) || path.includes(this.exportMenuEl)) return;\n this.#closeExportMenu();\n };\n\n #handleDocumentKey = (event: KeyboardEvent) => {\n if (!this.exportMenuOpen) return;\n if (event.key === 'Escape') {\n event.stopPropagation();\n this.#closeExportMenu(true);\n }\n };\n\n #handleExport = (formatId: string) => {\n this.#closeExportMenu();\n const grid = this.state?.host;\n if (!grid) return;\n grid.exportAs(formatId, { filename: this.exportFilename });\n };\n\n /** Lets keyboard users land in the menu when it opens via arrow-down. */\n #handleTriggerKeydown = (event: KeyboardEvent) => {\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n if (!this.exportMenuOpen) this.exportMenuOpen = true;\n requestAnimationFrame(() => {\n const first = this.exportMenuEl?.querySelector<HTMLElement>('[role=\"menuitem\"]');\n first?.focus();\n });\n }\n };\n\n #handleMenuKeydown = (event: KeyboardEvent) => {\n const items = Array.from(\n this.exportMenuEl?.querySelectorAll<HTMLElement>('[role=\"menuitem\"]') ?? []\n );\n // The menu lives in this shadow root, so `document.activeElement` is only\n // the outermost host; ask the menu's own root for the focused item.\n const root = this.exportMenuEl?.getRootNode() as Document | ShadowRoot | undefined;\n const current = items.indexOf(root?.activeElement as HTMLElement);\n if (event.key === 'ArrowDown' || event.key === 'Down') {\n event.preventDefault();\n items[(current + 1) % items.length]?.focus();\n } else if (event.key === 'ArrowUp' || event.key === 'Up') {\n event.preventDefault();\n items[(current - 1 + items.length) % items.length]?.focus();\n } else if (event.key === 'Home') {\n event.preventDefault();\n items[0]?.focus();\n } else if (event.key === 'End') {\n event.preventDefault();\n items[items.length - 1]?.focus();\n } else if (event.key === 'Tab') {\n // Tab closes the menu so focus moves naturally to the next focusable.\n this.#closeExportMenu();\n }\n };\n\n protected renderQuickFilter() {\n if (!this.showQuickFilter) return nothing;\n return html`<div part=\"toolbar-search\">\n <label part=\"search-field\">\n ${renderIcon('search', { part: 'search-icon' })}\n <input\n part=\"search-input\"\n type=\"search\"\n role=\"searchbox\"\n aria-label=${this.searchPlaceholder}\n placeholder=${this.searchPlaceholder}\n .value=${this.value}\n @input=${this.#handleInput}\n @keydown=${this.#handleKeydown}\n />\n </label>\n </div>`;\n }\n\n protected renderExportMenu() {\n if (!this.showExport) return nothing;\n const open = this.exportMenuOpen;\n return html`<div part=\"export\">\n <button\n type=\"button\"\n part=\"export-trigger\"\n aria-label=${this.state.localize('toolbar.export')}\n aria-haspopup=\"menu\"\n aria-expanded=${open ? 'true' : 'false'}\n @click=${this.#toggleExportMenu}\n @keydown=${this.#handleTriggerKeydown}\n >\n ${renderIcon('download', { part: 'export-icon' })}\n ${renderIcon('chevron-down', { part: 'export-caret' })}\n </button>\n <ul\n part=\"export-menu\"\n role=\"menu\"\n aria-label=${this.state.localize('toolbar.exportOptions')}\n ?hidden=${!open}\n @keydown=${this.#handleMenuKeydown}\n >\n ${(this.state?.host?.exportFormats ?? []).map(\n (format) => html`<li role=\"none\">\n <button\n type=\"button\"\n role=\"menuitem\"\n part=\"export-menu-item\"\n tabindex=\"-1\"\n @click=${() => this.#handleExport(format.id)}\n >\n ${format.label}\n </button>\n </li>`\n )}\n </ul>\n </div>`;\n }\n\n protected renderToolbarActions() {\n const actions = this.state?.host?.toolbarActions ?? [];\n if (!actions.length) return nothing;\n return html`${actions.map(\n (action) => html`<button\n type=\"button\"\n part=\"toolbar-action\"\n data-action-id=${action.id ?? ''}\n @click=${() => action.run()}\n >\n ${action.label}\n </button>`\n )}`;\n }\n\n protected override render() {\n if (!this.state) return nothing;\n return html`\n <div part=\"toolbar\" role=\"toolbar\" aria-label=${this.state.localize('toolbar.label')}>\n ${this.renderQuickFilter()}\n <div part=\"toolbar-actions\">${this.renderToolbarActions()}${this.renderExportMenu()}</div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n [ApexGridToolbar.tagName]: ApexGridToolbar<object>;\n }\n}\n"]}
@@ -0,0 +1,38 @@
1
+ import { type VirtualizeDirectiveConfig } from '@lit-labs/virtualizer/virtualize.js';
2
+ import { type DirectiveResult } from 'lit/directive.js';
3
+ /**
4
+ * How the directive maps rows to elements. `'item'` is upstream's `repeat` by
5
+ * key, so an element follows its record. `'slot'` re-binds elements by
6
+ * position, so an element shows whatever record its slot holds next.
7
+ */
8
+ export type RowMode = 'item' | 'slot';
9
+ /** The rows directive's config: upstream's, plus the row mapping. */
10
+ export type VirtualizeRowsConfig = VirtualizeDirectiveConfig<unknown> & {
11
+ mode?: RowMode;
12
+ };
13
+ /** What the body virtualizer asks of its rows directive. */
14
+ export interface VirtualizedRows {
15
+ /** Row mapping in use. A field of the one directive, never a second class. */
16
+ mode: RowMode;
17
+ /**
18
+ * Runs `dispatch` (the `rangeChanged` dispatch) with the rows' re-render
19
+ * held back until it returns, so every listener, whenever it registered,
20
+ * still sees the rows of the previous range.
21
+ */
22
+ holdRender<R>(dispatch: () => R): R;
23
+ /**
24
+ * Lets a pending `layoutComplete` settle within two frames when the layout is
25
+ * quiet: no render, children resize or deferred render for two frames.
26
+ * `updatePending` is whether the host has an update queued, which is not quiet.
27
+ */
28
+ armLayoutComplete(updatePending: boolean): void;
29
+ /** Resolves after the latest render has committed and its rows have updated. */
30
+ rendered(): Promise<void>;
31
+ }
32
+ /** The rows directive rendering into `host`, once it has rendered. */
33
+ export declare function virtualizedRows(host: Element): VirtualizedRows | undefined;
34
+ /**
35
+ * The body's `virtualize` directive. Annotated because the inferred type names
36
+ * upstream's private members (TS2742 / TS4094).
37
+ */
38
+ export declare const virtualizeRows: (config: VirtualizeRowsConfig) => DirectiveResult;
@@ -0,0 +1,286 @@
1
+ import { virtualize } from '@lit-labs/virtualizer/virtualize.js';
2
+ import { noChange, nothing, render } from 'lit';
3
+ import { Directive, directive } from 'lit/directive.js';
4
+ import { getCommittedValue, insertPart, removePart, setChildPartValue, setCommittedValue, } from 'lit/directive-helpers.js';
5
+ import { repeat } from 'lit/directives/repeat.js';
6
+ const UpstreamDirective = virtualize()
7
+ ._$litDirective$;
8
+ const SIZER_ATTRIBUTE = 'virtualizer-sizer';
9
+ const SPARE_LIMIT = 32;
10
+ class SlotRowsDirective extends Directive {
11
+ #parts = null;
12
+ #first = 0;
13
+ #spares = [];
14
+ #spareRoot = null;
15
+ render(_values, _first) {
16
+ return noChange;
17
+ }
18
+ update(container, [values, first]) {
19
+ let parts = this.#parts;
20
+ if (!parts) {
21
+ const inherited = getCommittedValue(container);
22
+ if (Array.isArray(inherited)) {
23
+ for (const part of inherited)
24
+ removePart(part);
25
+ }
26
+ parts = [];
27
+ }
28
+ const count = values.length;
29
+ const next = new Array(count);
30
+ const start = Math.max(first, this.#first);
31
+ const end = Math.min(first + count, this.#first + parts.length);
32
+ if (end <= start) {
33
+ const kept = Math.min(parts.length, count);
34
+ for (let i = 0; i < kept; i++)
35
+ next[i] = parts[i];
36
+ for (let i = kept; i < parts.length; i++)
37
+ this.#setAside(parts[i]);
38
+ for (let i = kept; i < count; i++)
39
+ next[i] = this.#take(container, undefined);
40
+ }
41
+ else {
42
+ for (let index = start; index < end; index++) {
43
+ next[index - first] = parts[index - this.#first];
44
+ }
45
+ const leftHead = parts.slice(0, start - this.#first);
46
+ const leftTail = parts.slice(end - this.#first);
47
+ const head = start - first;
48
+ const tail = first + count - end;
49
+ for (let i = 0; i < tail; i++) {
50
+ const part = leftHead.shift();
51
+ next[end - first + i] = part
52
+ ? insertPart(container, undefined, part)
53
+ : this.#take(container, undefined);
54
+ }
55
+ const ref = next[head];
56
+ for (let i = 0; i < head; i++) {
57
+ const part = leftTail.shift();
58
+ next[i] = part
59
+ ? insertPart(container, ref, part)
60
+ : this.#take(container, ref);
61
+ }
62
+ for (const part of leftHead)
63
+ this.#setAside(part);
64
+ for (const part of leftTail)
65
+ this.#setAside(part);
66
+ }
67
+ for (let i = 0; i < count; i++)
68
+ setChildPartValue(next[i], values[i]);
69
+ this.#parts = next;
70
+ this.#first = first;
71
+ setCommittedValue(container, next);
72
+ return noChange;
73
+ }
74
+ #take(container, ref) {
75
+ const spare = this.#spares.pop();
76
+ return insertPart(container, ref, spare);
77
+ }
78
+ #setAside(part) {
79
+ if (this.#spares.length >= SPARE_LIMIT) {
80
+ removePart(part);
81
+ return;
82
+ }
83
+ this.#spareRoot ??= render(nothing, document.createDocumentFragment(), {
84
+ isConnected: false,
85
+ });
86
+ insertPart(this.#spareRoot, undefined, part);
87
+ this.#spares.push(part);
88
+ }
89
+ }
90
+ const slotRows = directive(SlotRowsDirective);
91
+ const directives = new WeakMap();
92
+ export function virtualizedRows(host) {
93
+ return directives.get(host);
94
+ }
95
+ const NOTHING_HELD = Symbol('nothing held');
96
+ class VirtualizeRowsDirective extends UpstreamDirective {
97
+ constructor() {
98
+ super(...arguments);
99
+ this.mode = 'item';
100
+ this.#host = null;
101
+ this.#holding = 0;
102
+ this.#held = NOTHING_HELD;
103
+ this.#rows = [];
104
+ this.#indexOf = new WeakMap();
105
+ this.#observed = null;
106
+ this.#epoch = 0;
107
+ this.#probes = [];
108
+ this.#quiet = -1;
109
+ this.#next = null;
110
+ }
111
+ #host;
112
+ #holding;
113
+ #held;
114
+ #rows;
115
+ #indexOf;
116
+ #observed;
117
+ #epoch;
118
+ #probes;
119
+ #quiet;
120
+ #next;
121
+ render(config) {
122
+ if (config)
123
+ return super.render(config);
124
+ const itemsToRender = [];
125
+ if (this._first >= 0 && this._last >= this._first) {
126
+ for (let i = this._first; i <= this._last; i++) {
127
+ itemsToRender.push(this._items[i]);
128
+ }
129
+ }
130
+ if (this.mode === 'slot') {
131
+ return slotRows(itemsToRender.map((item, i) => this._renderItem(item, i)), this._first);
132
+ }
133
+ return repeat(itemsToRender, this._keyFunction, this._renderItem);
134
+ }
135
+ update(part, args) {
136
+ const host = part.parentNode;
137
+ if (host && host.nodeType === Node.ELEMENT_NODE && host !== this.#host) {
138
+ this.#host = host;
139
+ directives.set(host, this);
140
+ }
141
+ this.mode = args[0].mode ?? 'item';
142
+ const value = super.update(part, args);
143
+ this.#observeLayoutComplete();
144
+ if (value === noChange) {
145
+ this.#epoch++;
146
+ this.#next ??= deferred();
147
+ }
148
+ else {
149
+ queueMicrotask(() => this.#committed());
150
+ }
151
+ return value;
152
+ }
153
+ setValue(value) {
154
+ if (this.#holding) {
155
+ this.#held = value;
156
+ return;
157
+ }
158
+ super.setValue(value);
159
+ this.#committed();
160
+ }
161
+ holdRender(dispatch) {
162
+ this.#holding++;
163
+ try {
164
+ return dispatch();
165
+ }
166
+ finally {
167
+ this.#holding--;
168
+ if (!this.#holding && this.#held !== NOTHING_HELD) {
169
+ const value = this.#held;
170
+ this.#held = NOTHING_HELD;
171
+ this.setValue(value);
172
+ }
173
+ }
174
+ }
175
+ armLayoutComplete(updatePending) {
176
+ if (updatePending)
177
+ return;
178
+ const epoch = this.#epoch;
179
+ if (this.#quiet === epoch || this.#probes.some((probe) => probe.epoch === epoch)) {
180
+ this.#probe();
181
+ }
182
+ }
183
+ async rendered() {
184
+ if (this.#next)
185
+ await this.#next.promise;
186
+ await Promise.all(this.#rows.map((row) => row.updateComplete));
187
+ }
188
+ get #virtualizer() {
189
+ return this._virtualizer;
190
+ }
191
+ #observeLayoutComplete() {
192
+ const virtualizer = this.#virtualizer;
193
+ if (!virtualizer || virtualizer === this.#observed)
194
+ return;
195
+ this.#observed = virtualizer;
196
+ const schedule = virtualizer._scheduleLayoutComplete;
197
+ virtualizer._scheduleLayoutComplete = () => {
198
+ schedule.call(virtualizer);
199
+ this.#epoch++;
200
+ this.#probe();
201
+ };
202
+ }
203
+ #committed() {
204
+ this.#next?.resolve();
205
+ this.#next = null;
206
+ const host = this.#host;
207
+ if (!host)
208
+ return;
209
+ const observer = this.#virtualizer?._childrenRO ?? null;
210
+ const previous = this.#rows;
211
+ const rows = [];
212
+ const slot = this.mode === 'slot';
213
+ const moved = [];
214
+ let changed = false;
215
+ for (let child = host.firstElementChild; child; child = child.nextElementSibling) {
216
+ if (child.hasAttribute(SIZER_ATTRIBUTE))
217
+ continue;
218
+ const index = this._first + rows.length;
219
+ const was = this.#indexOf.get(child);
220
+ if (observer && was !== undefined && was !== index) {
221
+ observer.unobserve(child);
222
+ observer.observe(child);
223
+ }
224
+ if (slot && was !== index)
225
+ moved.push(child);
226
+ this.#indexOf.set(child, index);
227
+ if (previous[rows.length] !== child)
228
+ changed = true;
229
+ rows.push(child);
230
+ }
231
+ if (rows.length !== previous.length)
232
+ changed = true;
233
+ this.#rows = rows;
234
+ if (moved.length)
235
+ void this.#measure(moved);
236
+ this.#epoch++;
237
+ if (!changed)
238
+ this.#probe();
239
+ }
240
+ async #measure(moved) {
241
+ await Promise.all(moved.map((row) => row.updateComplete));
242
+ const virtualizer = this.#virtualizer;
243
+ const host = this.#host;
244
+ if (!virtualizer?._childrenRO || !host?.isConnected)
245
+ return;
246
+ let pending = false;
247
+ for (const row of moved) {
248
+ const index = this.#indexOf.get(row);
249
+ if (index === undefined || this.#rows[index - this._first] !== row)
250
+ continue;
251
+ virtualizer._toBeMeasured.set(row, null);
252
+ pending = true;
253
+ }
254
+ if (pending)
255
+ virtualizer._measureChildren();
256
+ }
257
+ #probe() {
258
+ const epoch = this.#epoch;
259
+ const promise = this.#virtualizer?._layoutCompletePromise ?? null;
260
+ if (this.#probes.some((probe) => probe.epoch === epoch && probe.promise === promise))
261
+ return;
262
+ const probe = { epoch, promise };
263
+ this.#probes.push(probe);
264
+ requestAnimationFrame(() => requestAnimationFrame(() => {
265
+ this.#probes = this.#probes.filter((other) => other !== probe);
266
+ if (epoch !== this.#epoch)
267
+ return;
268
+ this.#quiet = epoch;
269
+ const virtualizer = this.#virtualizer;
270
+ if (promise &&
271
+ virtualizer?._layoutCompletePromise === promise &&
272
+ virtualizer._pendingLayoutComplete === null) {
273
+ virtualizer._resolveLayoutCompletePromise();
274
+ }
275
+ }));
276
+ }
277
+ }
278
+ function deferred() {
279
+ let resolve;
280
+ const promise = new Promise((done) => {
281
+ resolve = done;
282
+ });
283
+ return { promise, resolve };
284
+ }
285
+ export const virtualizeRows = directive(VirtualizeRowsDirective);
286
+ //# sourceMappingURL=virtualize-rows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"virtualize-rows.js","sourceRoot":"","sources":["../../src/components/virtualize-rows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkC,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACjG,OAAO,EAAkB,QAAQ,EAAE,OAAO,EAAiB,MAAM,EAAE,MAAM,KAAK,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAwB,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9E,OAAO,EACL,iBAAiB,EACjB,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAkClD,MAAM,iBAAiB,GAAI,UAAU,EAA6D;KAC/F,eAAe,CAAC;AAoBnB,MAAM,eAAe,GAAG,mBAAmB,CAAC;AAgB5C,MAAM,WAAW,GAAG,EAAE,CAAC;AAsBvB,MAAM,iBAAkB,SAAQ,SAAS;IAEvC,MAAM,GAAuB,IAAI,CAAC;IAElC,MAAM,GAAG,CAAC,CAAC;IACX,OAAO,GAAgB,EAAE,CAAC;IAE1B,UAAU,GAAoB,IAAI,CAAC;IAE5B,MAAM,CAAC,OAAkB,EAAE,MAAc;QAC9C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEe,MAAM,CAAC,SAAoB,EAAE,CAAC,MAAM,EAAE,KAAK,CAAsB;QAC/E,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC7B,KAAK,MAAM,IAAI,IAAI,SAAwB;oBAAE,UAAU,CAAC,IAAI,CAAC,CAAC;YAChE,CAAC;YACD,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,MAAM,IAAI,GAAgB,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;QAEhE,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;YAEjB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;gBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAClD,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;gBAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACnE,KAAK,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;gBAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChF,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,KAAK,GAAG,KAAK,EAAE,KAAK,GAAG,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC7C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACnD,CAAC;YAGD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YACrD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,IAAI,GAAG,KAAK,GAAG,KAAK,CAAC;YAC3B,MAAM,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,GAAG,CAAC;YAGjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI;oBAC1B,CAAC,CAAE,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,CAAe;oBACvD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACvC,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAC9B,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI;oBACZ,CAAC,CAAE,UAAU,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAe;oBACjD,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,QAAQ;gBAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAClD,KAAK,MAAM,IAAI,IAAI,QAAQ;gBAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACpD,CAAC;QAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE;YAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,iBAAiB,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAGD,KAAK,CAAC,SAAoB,EAAE,GAA0B;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QACjC,OAAO,UAAU,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,CAAc,CAAC;IACxD,CAAC;IAGD,SAAS,CAAC,IAAe;QACvB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,WAAW,EAAE,CAAC;YACvC,UAAU,CAAC,IAAI,CAAC,CAAC;YACjB,OAAO;QACT,CAAC;QAGD,IAAI,CAAC,UAAU,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,sBAAsB,EAAE,EAAE;YACrE,WAAW,EAAE,KAAK;SACnB,CAAC,CAAC;QACH,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,QAAQ,GAAG,SAAS,CAAC,iBAAiB,CAAC,CAAC;AAsB9C,MAAM,UAAU,GAAG,IAAI,OAAO,EAA4B,CAAC;AAG3D,MAAM,UAAU,eAAe,CAAC,IAAa;IAC3C,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAGD,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;AAE5C,MAAM,uBAAwB,SAAQ,iBAAiB;IAAvD;;QACS,SAAI,GAAY,MAAM,CAAC;QAE9B,UAAK,GAAmB,IAAI,CAAC;QAG7B,aAAQ,GAAG,CAAC,CAAC;QACb,UAAK,GAAY,YAAY,CAAC;QAG9B,UAAK,GAAc,EAAE,CAAC;QACtB,aAAQ,GAAG,IAAI,OAAO,EAAmB,CAAC;QAG1C,cAAS,GAA+B,IAAI,CAAC;QAM7C,WAAM,GAAG,CAAC,CAAC;QAKX,YAAO,GAA4D,EAAE,CAAC;QAEtE,WAAM,GAAG,CAAC,CAAC,CAAC;QAGZ,UAAK,GAA2D,IAAI,CAAC;IAqNvE,CAAC;IAhPC,KAAK,CAAwB;IAG7B,QAAQ,CAAK;IACb,KAAK,CAAyB;IAG9B,KAAK,CAAiB;IACtB,QAAQ,CAAkC;IAG1C,SAAS,CAAoC;IAM7C,MAAM,CAAK;IAKX,OAAO,CAA+D;IAEtE,MAAM,CAAM;IAGZ,KAAK,CAAgE;IAErD,MAAM,CAAC,MAA2C;QAEhE,IAAI,MAAM;YAAE,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,aAAa,GAAc,EAAE,CAAC;QACpC,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAClD,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,OAAO,QAAQ,CACb,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EACzD,IAAI,CAAC,MAAM,CACZ,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACpE,CAAC;IAEe,MAAM,CAAC,IAAe,EAAE,IAA4B;QAClE,MAAM,IAAI,GAAG,IAAI,CAAC,UAA4B,CAAC;QAC/C,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,YAAY,IAAI,IAAI,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;YACvE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;YAClB,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC7B,CAAC;QAGD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,MAAM,CAAC;QACnC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAC9B,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YAEvB,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,CAAC;aAAM,CAAC;YAEN,cAAc,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAEe,QAAQ,CAAC,KAAc;QACrC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;YACnB,OAAO;QACT,CAAC;QACD,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAEM,UAAU,CAAI,QAAiB;QACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,OAAO,QAAQ,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,KAAK,YAAY,EAAE,CAAC;gBAClD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;gBACzB,IAAI,CAAC,KAAK,GAAG,YAAY,CAAC;gBAC1B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC;IAEM,iBAAiB,CAAC,aAAsB;QAC7C,IAAI,aAAa;YAAE,OAAO;QAI1B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,IAAI,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QACzC,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,KAAK,CAAC,GAAG,CACZ,CAAC,GAAG,EAAE,EAAE,CAAE,GAAuD,CAAC,cAAc,CACjF,CACF,CAAC;IACJ,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,YAAqD,CAAC;IACpE,CAAC;IAMD,sBAAsB;QACpB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,IAAI,CAAC,WAAW,IAAI,WAAW,KAAK,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3D,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC;QAC7B,MAAM,QAAQ,GAAG,WAAW,CAAC,uBAAuB,CAAC;QACrD,WAAW,CAAC,uBAAuB,GAAG,GAAG,EAAE;YACzC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;YAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;YACd,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC;IAGD,UAAU;QACR,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC;QACtB,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,IAAI;YAAE,OAAO;QAOlB,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,WAAW,IAAI,IAAI,CAAC;QACxD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,MAAM,IAAI,GAAc,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;QAClC,MAAM,KAAK,GAAc,EAAE,CAAC;QAC5B,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,kBAAkB,EAAE,CAAC;YACjF,IAAI,KAAK,CAAC,YAAY,CAAC,eAAe,CAAC;gBAAE,SAAS;YAClD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACxC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACrC,IAAI,QAAQ,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;gBACnD,QAAQ,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;gBAC1B,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC1B,CAAC;YACD,IAAI,IAAI,IAAI,GAAG,KAAK,KAAK;gBAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChC,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK;gBAAE,OAAO,GAAG,IAAI,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM;YAAE,OAAO,GAAG,IAAI,CAAC;QACpD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QAClB,IAAI,KAAK,CAAC,MAAM;YAAE,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAE5C,IAAI,CAAC,MAAM,EAAE,CAAC;QAId,IAAI,CAAC,OAAO;YAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IAgBD,KAAK,CAAC,QAAQ,CAAC,KAAgB;QAC7B,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAE,GAAuD,CAAC,cAAc,CAAC,CAC5F,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,WAAW,EAAE,WAAW,IAAI,CAAC,IAAI,EAAE,WAAW;YAAE,OAAO;QAC5D,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YAExB,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACrC,IAAI,KAAK,KAAK,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG;gBAAE,SAAS;YAC7E,WAAW,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YACzC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,OAAO;YAAE,WAAW,CAAC,gBAAgB,EAAE,CAAC;IAC9C,CAAC;IAaD,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,EAAE,sBAAsB,IAAI,IAAI,CAAC;QAClE,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,OAAO,CAAC;YAAE,OAAO;QAC7F,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,qBAAqB,CAAC,GAAG,EAAE,CACzB,qBAAqB,CAAC,GAAG,EAAE;YACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,CAAC;YAC/D,IAAI,KAAK,KAAK,IAAI,CAAC,MAAM;gBAAE,OAAO;YAClC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;YACpB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC;YACtC,IACE,OAAO;gBACP,WAAW,EAAE,sBAAsB,KAAK,OAAO;gBAC/C,WAAW,CAAC,sBAAsB,KAAK,IAAI,EAC3C,CAAC;gBACD,WAAW,CAAC,6BAA6B,EAAE,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AAED,SAAS,QAAQ;IACf,IAAI,OAAoB,CAAC;IACzB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,IAAI,EAAE,EAAE;QACzC,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAMD,MAAM,CAAC,MAAM,cAAc,GACzB,SAAS,CAAC,uBAAuB,CAAC,CAAC","sourcesContent":["import { type VirtualizeDirectiveConfig, virtualize } from '@lit-labs/virtualizer/virtualize.js';\nimport { type ChildPart, noChange, nothing, type RootPart, render } from 'lit';\nimport { Directive, type DirectiveResult, directive } from 'lit/directive.js';\nimport {\n getCommittedValue,\n insertPart,\n removePart,\n setChildPartValue,\n setCommittedValue,\n} from 'lit/directive-helpers.js';\nimport { repeat } from 'lit/directives/repeat.js';\n\n/**\n * The body's fork of the upstream `virtualize` directive.\n *\n * Upstream's directive is the only thing that constructs and drives its\n * `Virtualizer` (layout, scrolling, `rangeChanged`, `layoutComplete`), and the\n * package does not export that class. So the fork keeps the upstream directive\n * for all of that and subclasses it, replacing only what it renders and adding\n * the hooks the body needs around each render:\n *\n * - every `rangeChanged` listener runs before the rows re-render\n * ({@link VirtualizedRows.holdRender});\n * - a row element that stands at a new index after a render is measured again\n * (upstream caches sizes by index and only measures what its children\n * `ResizeObserver` reports);\n * - a render that changed nothing upstream can observe still lets\n * `layoutComplete` settle ({@link VirtualizedRows.armLayoutComplete});\n * - {@link VirtualizedRows.rendered} resolves after the latest render.\n *\n * In `'slot'` mode the rows render through the slot reconciler\n * ({@link SlotRowsDirective}) instead of upstream's keyed `repeat`.\n *\n * Built against `@lit-labs/virtualizer` 2.1.1 exactly (pinned in package.json).\n * The private members it touches are pinned by\n * `test/virtualizer-private-api.test.ts`.\n *\n * @see plans/core/2026-10-27-row-recycling-plan.md, sections 3.1 and 3.5.\n */\n\n/** Upstream's `VirtualizeDirective` class, which the package does not export. */\ntype UpstreamDirectiveClass =\n ReturnType<typeof virtualize> extends DirectiveResult<infer C> ? C : never;\n\nconst UpstreamDirective = (virtualize() as unknown as { _$litDirective$: UpstreamDirectiveClass })\n ._$litDirective$;\n\n/** The private members of upstream's `Virtualizer` this file relies on. */\ninterface UpstreamVirtualizer {\n /** Observes every rendered row; its callback is what measures them. */\n _childrenRO: ResizeObserver | null;\n /** Created lazily by the `layoutComplete` getter; null when nobody waits. */\n _layoutCompletePromise: Promise<void> | null;\n /** The frame upstream already scheduled to resolve the promise, if any. */\n _pendingLayoutComplete: number | null;\n /** Called at the end of every children `ResizeObserver` callback, and only there. */\n _scheduleLayoutComplete(): void;\n _resolveLayoutCompletePromise(): void;\n /** Children `_measureChildren` measures next (it reads only the keys). */\n _toBeMeasured: Map<Element, unknown>;\n /** Measures those children and schedules a reflow with the sizes. */\n _measureChildren(): void;\n}\n\n/** Attribute upstream stamps on its sizer element, which is not a row. */\nconst SIZER_ATTRIBUTE = 'virtualizer-sizer';\n\n/**\n * How the directive maps rows to elements. `'item'` is upstream's `repeat` by\n * key, so an element follows its record. `'slot'` re-binds elements by\n * position, so an element shows whatever record its slot holds next.\n */\nexport type RowMode = 'item' | 'slot';\n\n/** The rows directive's config: upstream's, plus the row mapping. */\nexport type VirtualizeRowsConfig = VirtualizeDirectiveConfig<unknown> & { mode?: RowMode };\n\n/**\n * Most rows a shrinking range sets aside for when it grows again. A guess:\n * plan section 14, open question 6.\n */\nconst SPARE_LIMIT = 32;\n\n/**\n * The slot reconciler: renders `values` (the rows for indexes `first`,\n * `first + 1`, ...) into child parts in index order, with no keys.\n *\n * - A part whose index stays in range keeps its place, so a row that stays\n * on screen is not touched beyond its (usually unchanged) values.\n * - Parts whose index left the range take the indexes entering it, moved as\n * one block to the other end, so a k-row step moves k rows. DOM order stays\n * index order, which upstream relies on to place the i-th child at index\n * `first + i`.\n * - When the old and new ranges do not overlap (a jump), and when they are\n * the same (a sort, a filter that keeps the range), every part is re-bound\n * where it stands: nothing moves.\n * - The range grows with spare parts first, then new ones. Parts a shrinking\n * range drops wait, disconnected, in a detached fragment (up to\n * `SPARE_LIMIT`); the rest are removed.\n *\n * A new instance on a part another directive rendered (a mode switch from\n * `repeat`) removes those rows and builds its own, once.\n */\nclass SlotRowsDirective extends Directive {\n /** Parts in DOM order; null until this instance first updates. */\n #parts: ChildPart[] | null = null;\n /** Item index the first part shows. */\n #first = 0;\n #spares: ChildPart[] = [];\n /** Lit's parent for the spares: disconnected, so their directives are too. */\n #spareRoot: RootPart | null = null;\n\n public render(_values: unknown[], _first: number): unknown {\n return noChange;\n }\n\n public override update(container: ChildPart, [values, first]: [unknown[], number]): unknown {\n let parts = this.#parts;\n if (!parts) {\n const inherited = getCommittedValue(container);\n if (Array.isArray(inherited)) {\n for (const part of inherited as ChildPart[]) removePart(part);\n }\n parts = [];\n }\n\n const count = values.length;\n const next: ChildPart[] = new Array(count);\n const start = Math.max(first, this.#first);\n const end = Math.min(first + count, this.#first + parts.length);\n\n if (end <= start) {\n // No index survives (a jump, or a first render): re-bind in place.\n const kept = Math.min(parts.length, count);\n for (let i = 0; i < kept; i++) next[i] = parts[i];\n for (let i = kept; i < parts.length; i++) this.#setAside(parts[i]);\n for (let i = kept; i < count; i++) next[i] = this.#take(container, undefined);\n } else {\n for (let index = start; index < end; index++) {\n next[index - first] = parts[index - this.#first];\n }\n // At most one end of the range loses parts while the other gains slots\n // (or both shrink, or both grow).\n const leftHead = parts.slice(0, start - this.#first);\n const leftTail = parts.slice(end - this.#first);\n const head = start - first;\n const tail = first + count - end;\n\n // Scrolling down: the parts above the range become the rows below it.\n for (let i = 0; i < tail; i++) {\n const part = leftHead.shift();\n next[end - first + i] = part\n ? (insertPart(container, undefined, part) as ChildPart)\n : this.#take(container, undefined);\n }\n // Scrolling up: the parts below the range become the rows above it.\n const ref = next[head];\n for (let i = 0; i < head; i++) {\n const part = leftTail.shift();\n next[i] = part\n ? (insertPart(container, ref, part) as ChildPart)\n : this.#take(container, ref);\n }\n for (const part of leftHead) this.#setAside(part);\n for (const part of leftTail) this.#setAside(part);\n }\n\n for (let i = 0; i < count; i++) setChildPartValue(next[i], values[i]);\n this.#parts = next;\n this.#first = first;\n setCommittedValue(container, next);\n return noChange;\n }\n\n /** A spare part, or a new one, inserted before `ref` (the end when undefined). */\n #take(container: ChildPart, ref: ChildPart | undefined): ChildPart {\n const spare = this.#spares.pop();\n return insertPart(container, ref, spare) as ChildPart;\n }\n\n /** Keeps a part the range no longer needs as a spare, or removes it. */\n #setAside(part: ChildPart): void {\n if (this.#spares.length >= SPARE_LIMIT) {\n removePart(part);\n return;\n }\n // Inserting into another container reparents the part, and lit notifies\n // its directives that it left the document.\n this.#spareRoot ??= render(nothing, document.createDocumentFragment(), {\n isConnected: false,\n });\n insertPart(this.#spareRoot, undefined, part);\n this.#spares.push(part);\n }\n}\n\nconst slotRows = directive(SlotRowsDirective);\n\n/** What the body virtualizer asks of its rows directive. */\nexport interface VirtualizedRows {\n /** Row mapping in use. A field of the one directive, never a second class. */\n mode: RowMode;\n /**\n * Runs `dispatch` (the `rangeChanged` dispatch) with the rows' re-render\n * held back until it returns, so every listener, whenever it registered,\n * still sees the rows of the previous range.\n */\n holdRender<R>(dispatch: () => R): R;\n /**\n * Lets a pending `layoutComplete` settle within two frames when the layout is\n * quiet: no render, children resize or deferred render for two frames.\n * `updatePending` is whether the host has an update queued, which is not quiet.\n */\n armLayoutComplete(updatePending: boolean): void;\n /** Resolves after the latest render has committed and its rows have updated. */\n rendered(): Promise<void>;\n}\n\nconst directives = new WeakMap<Element, VirtualizedRows>();\n\n/** The rows directive rendering into `host`, once it has rendered. */\nexport function virtualizedRows(host: Element): VirtualizedRows | undefined {\n return directives.get(host);\n}\n\n/** Marks that no re-render is held. */\nconst NOTHING_HELD = Symbol('nothing held');\n\nclass VirtualizeRowsDirective extends UpstreamDirective implements VirtualizedRows {\n public mode: RowMode = 'item';\n\n #host: Element | null = null;\n\n /** `holdRender` nesting depth, and the render it held back. */\n #holding = 0;\n #held: unknown = NOTHING_HELD;\n\n /** The rendered rows in DOM order, and the index each was last rendered at. */\n #rows: Element[] = [];\n #indexOf = new WeakMap<Element, number>();\n\n /** The upstream instance whose children observer callback is wrapped. */\n #observed: UpstreamVirtualizer | null = null;\n\n /**\n * Bumped by everything that may still change the layout: a render, a\n * children `ResizeObserver` callback, an update whose rows render later.\n */\n #epoch = 0;\n /**\n * The two-frame probes in flight: the epoch each waits on and the pending\n * `layoutComplete` promise when it started, the only one it may settle.\n */\n #probes: Array<{ epoch: number; promise: Promise<void> | null }> = [];\n /** The epoch last found quiet: nothing happened for two frames after it. */\n #quiet = -1;\n\n /** Settles when the render an update deferred commits. */\n #next: { promise: Promise<void>; resolve: () => void } | null = null;\n\n public override render(config?: VirtualizeDirectiveConfig<unknown>): unknown {\n // Upstream's own `update()` and range listener never pass a config.\n if (config) return super.render(config);\n const itemsToRender: unknown[] = [];\n if (this._first >= 0 && this._last >= this._first) {\n for (let i = this._first; i <= this._last; i++) {\n itemsToRender.push(this._items[i]);\n }\n }\n if (this.mode === 'slot') {\n return slotRows(\n itemsToRender.map((item, i) => this._renderItem(item, i)),\n this._first\n );\n }\n // Item branch: upstream's render, byte for byte.\n return repeat(itemsToRender, this._keyFunction, this._renderItem);\n }\n\n public override update(part: ChildPart, args: [VirtualizeRowsConfig]): unknown {\n const host = part.parentNode as Element | null;\n if (host && host.nodeType === Node.ELEMENT_NODE && host !== this.#host) {\n this.#host = host;\n directives.set(host, this);\n }\n // A switch renders through the other branch's directive, which rebuilds\n // the rows once. This class (and so upstream's range listener) stays.\n this.mode = args[0].mode ?? 'item';\n const value = super.update(part, args);\n this.#observeLayoutComplete();\n if (value === noChange) {\n // New items: the rows render once the layout reports the range.\n this.#epoch++;\n this.#next ??= deferred();\n } else {\n // Lit commits `value` as soon as this returns.\n queueMicrotask(() => this.#committed());\n }\n return value;\n }\n\n public override setValue(value: unknown): void {\n if (this.#holding) {\n this.#held = value;\n return;\n }\n super.setValue(value);\n this.#committed();\n }\n\n public holdRender<R>(dispatch: () => R): R {\n this.#holding++;\n try {\n return dispatch();\n } finally {\n this.#holding--;\n if (!this.#holding && this.#held !== NOTHING_HELD) {\n const value = this.#held;\n this.#held = NOTHING_HELD;\n this.setValue(value);\n }\n }\n }\n\n public armLayoutComplete(updatePending: boolean): void {\n if (updatePending) return;\n // Quiet already, or a probe of this epoch is in flight but started before\n // this promise existed and so will not settle it: give it two frames of\n // its own. Otherwise the activity since the last quiet epoch starts one.\n const epoch = this.#epoch;\n if (this.#quiet === epoch || this.#probes.some((probe) => probe.epoch === epoch)) {\n this.#probe();\n }\n }\n\n public async rendered(): Promise<void> {\n if (this.#next) await this.#next.promise;\n await Promise.all(\n this.#rows.map(\n (row) => (row as Element & { updateComplete?: Promise<unknown> }).updateComplete\n )\n );\n }\n\n get #virtualizer(): UpstreamVirtualizer | null {\n return this._virtualizer as unknown as UpstreamVirtualizer | null;\n }\n\n /**\n * Counts every children `ResizeObserver` callback as activity. Upstream ends\n * each one with `_scheduleLayoutComplete`, which it calls nowhere else.\n */\n #observeLayoutComplete(): void {\n const virtualizer = this.#virtualizer;\n if (!virtualizer || virtualizer === this.#observed) return;\n this.#observed = virtualizer;\n const schedule = virtualizer._scheduleLayoutComplete;\n virtualizer._scheduleLayoutComplete = () => {\n schedule.call(virtualizer);\n this.#epoch++;\n this.#probe();\n };\n }\n\n /** Runs after every render has committed to the DOM. */\n #committed(): void {\n this.#next?.resolve();\n this.#next = null;\n const host = this.#host;\n if (!host) return;\n\n // Upstream measures only the rows its children observer reports, and\n // caches the result by index. A row already rendered that now stands at\n // another index keeps its box, so nothing reports it and the new index\n // would keep its old (or estimated) size. Observing it afresh makes the\n // observer report it once, which runs upstream's own measure.\n const observer = this.#virtualizer?._childrenRO ?? null;\n const previous = this.#rows;\n const rows: Element[] = [];\n const slot = this.mode === 'slot';\n const moved: Element[] = [];\n let changed = false;\n for (let child = host.firstElementChild; child; child = child.nextElementSibling) {\n if (child.hasAttribute(SIZER_ATTRIBUTE)) continue;\n const index = this._first + rows.length;\n const was = this.#indexOf.get(child);\n if (observer && was !== undefined && was !== index) {\n observer.unobserve(child);\n observer.observe(child);\n }\n if (slot && was !== index) moved.push(child);\n this.#indexOf.set(child, index);\n if (previous[rows.length] !== child) changed = true;\n rows.push(child);\n }\n if (rows.length !== previous.length) changed = true;\n this.#rows = rows;\n if (moved.length) void this.#measure(moved);\n\n this.#epoch++;\n // Rows added, removed or moved are observed (or re-observed) above or by\n // upstream, so its own path settles `layoutComplete`. Only a render that\n // kept every row element where it was can go unobserved.\n if (!changed) this.#probe();\n }\n\n /**\n * Slot mode: measures rows that stand at a new index once they have\n * rendered their new record, before the frame paints.\n *\n * The fresh observation above is not enough on its own here. A render that\n * a children `ResizeObserver` callback set off (a measure that moved the\n * range) observes rows no deeper in the tree than the ones that callback\n * just reported, and the browser holds such observations to the next frame.\n * Under item keys the same round also reports the rows it removed, which\n * sit outside the tree, so the new rows still land in that frame. Re-bound\n * rows have no such luck: through a fling the layout would stay a frame\n * behind, keep its unmeasured anchor, and finally correct the scroll offset.\n * The observation still runs, and is what settles `layoutComplete`.\n */\n async #measure(moved: Element[]): Promise<void> {\n await Promise.all(\n moved.map((row) => (row as Element & { updateComplete?: Promise<unknown> }).updateComplete)\n );\n const virtualizer = this.#virtualizer;\n const host = this.#host;\n if (!virtualizer?._childrenRO || !host?.isConnected) return;\n let pending = false;\n for (const row of moved) {\n // Only rows still where this render put them.\n const index = this.#indexOf.get(row);\n if (index === undefined || this.#rows[index - this._first] !== row) continue;\n virtualizer._toBeMeasured.set(row, null);\n pending = true;\n }\n if (pending) virtualizer._measureChildren();\n }\n\n /**\n * Two frames after the current epoch, with nothing else in between, the\n * layout is quiet: settle the `layoutComplete` promise that was pending when\n * the probe started, if upstream has not already scheduled it. A children\n * observer callback lands within the first of those frames, so this never\n * resolves ahead of a measure the render it follows triggers.\n *\n * A promise created after the probe started (say, read right after a scroll\n * the layout has not seen yet) is not that promise, so it waits for a probe\n * of its own or for upstream.\n */\n #probe(): void {\n const epoch = this.#epoch;\n const promise = this.#virtualizer?._layoutCompletePromise ?? null;\n if (this.#probes.some((probe) => probe.epoch === epoch && probe.promise === promise)) return;\n const probe = { epoch, promise };\n this.#probes.push(probe);\n requestAnimationFrame(() =>\n requestAnimationFrame(() => {\n this.#probes = this.#probes.filter((other) => other !== probe);\n if (epoch !== this.#epoch) return;\n this.#quiet = epoch;\n const virtualizer = this.#virtualizer;\n if (\n promise &&\n virtualizer?._layoutCompletePromise === promise &&\n virtualizer._pendingLayoutComplete === null\n ) {\n virtualizer._resolveLayoutCompletePromise();\n }\n })\n );\n }\n}\n\nfunction deferred(): { promise: Promise<void>; resolve: () => void } {\n let resolve!: () => void;\n const promise = new Promise<void>((done) => {\n resolve = done;\n });\n return { promise, resolve };\n}\n\n/**\n * The body's `virtualize` directive. Annotated because the inferred type names\n * upstream's private members (TS2742 / TS4094).\n */\nexport const virtualizeRows: (config: VirtualizeRowsConfig) => DirectiveResult =\n directive(VirtualizeRowsDirective);\n"]}
@@ -1,5 +1,21 @@
1
1
  import { LitVirtualizer } from '@lit-labs/virtualizer/LitVirtualizer.js';
2
- import type { PropertyValues } from 'lit';
2
+ import { type PropertyValues } from 'lit';
3
+ import { type RowMode } from './virtualize-rows.js';
4
+ /**
5
+ * Rows whose text wraps change height while the grid resizes or scrolls, and
6
+ * the upstream virtualizer answers each measurement by resizing its own host
7
+ * within the same round of resize observations (it also keeps observing the
8
+ * rows it drops, which then report from outside the document). The browser
9
+ * defers those observations to the next frame, where the layout settles, and
10
+ * reports the deferral as an error on the window: Safari logs it, Chrome hands
11
+ * it to page error listeners and error monitoring. It is benign, so the first
12
+ * grid to connect cancels that message (and the older "loop limit exceeded"
13
+ * wording) for the window and keeps it from the listeners added after it
14
+ * (listeners added earlier still see it). Every other error is left alone.
15
+ *
16
+ * @see https://github.com/apexcharts/apex-grid/issues/32
17
+ */
18
+ export declare function quietResizeObserverLoopNotice(): void;
3
19
  /** Space, in px, that sticky chrome covers on each side of the scrollport. */
4
20
  export interface ScrollInsets {
5
21
  top: number;
@@ -11,6 +27,15 @@ export interface ScrollInsets {
11
27
  export type RevealOptions = ScrollIntoViewOptions & {
12
28
  insets?: ScrollInsets;
13
29
  };
30
+ /**
31
+ * How the item branch keys its rows. `'item'` is upstream's default (the
32
+ * record itself). `'spike'` keys by slot, `index % 128`, so a rebind reuses
33
+ * the row elements in place: the measured reference the slot reconciler
34
+ * replaced, kept for the benchmark.
35
+ *
36
+ * @internal Benchmark-only. Not public API.
37
+ */
38
+ export type RowKeying = 'item' | 'spike';
14
39
  /**
15
40
  * Scrolls `el` into view as if `scroller` had `insets` as its scroll-padding.
16
41
  * The padding is set only for the duration of the call. Left in place, the
@@ -21,7 +46,47 @@ export type RevealOptions = ScrollIntoViewOptions & {
21
46
  export declare function revealWithin(scroller: HTMLElement | null, el: Element, { insets, ...options }: RevealOptions): void;
22
47
  export default class ApexVirtualizer extends LitVirtualizer {
23
48
  #private;
49
+ /**
50
+ * Row keying every body built afterwards starts with. Anything other than
51
+ * `'spike'` leaves upstream's item key untouched.
52
+ *
53
+ * @internal Benchmark-only, for its spike reference mode. Not public API.
54
+ */
55
+ static rowKeying: RowKeying;
56
+ /**
57
+ * How rows map to elements: `'item'` keys each row by its record,
58
+ * `'slot'` re-binds row elements by position (the grid's `rowRecycling`).
59
+ * A switch rebuilds the rendered rows once.
60
+ *
61
+ * @internal Set by the grid. Not public API.
62
+ */
63
+ rowMode: RowMode;
24
64
  constructor();
65
+ /** Upstream's own render, with the body's fork of its directive. */
66
+ render(): import("lit-html").TemplateResult<1>;
67
+ /**
68
+ * Holds the rows' re-render until every `rangeChanged` listener has run, so
69
+ * a listener sees the rows of the previous range whatever its registration
70
+ * order. The grid's `bodyRangeChanged` relies on this: it reads which index
71
+ * the focused row showed before the range moved.
72
+ */
73
+ dispatchEvent(event: Event): boolean;
74
+ /**
75
+ * Upstream's promise, which settles only from its children ResizeObserver.
76
+ * A render that re-binds rows in place (a sort or a move under slot keys)
77
+ * resizes nothing, so it would never settle; when nothing has happened for
78
+ * two frames since the last render, the rows directive settles it instead.
79
+ * Anything else is left to upstream untouched.
80
+ */
81
+ get layoutComplete(): Promise<void> | undefined;
82
+ /**
83
+ * Resolves once the rows reflect this element's latest state: a pending
84
+ * update, the render it leads to (new items render a few microtasks later,
85
+ * once the layout reports the range) and every rendered row's own update.
86
+ *
87
+ * @internal For the row FLIP settle step. Not public API.
88
+ */
89
+ rendered(): Promise<void>;
25
90
  /**
26
91
  * Resolves once the layout has settled, or after a bounded wait when no
27
92
  * layout is pending (upstream `layoutComplete` only settles on a layout).
@@ -42,6 +107,11 @@ export default class ApexVirtualizer extends LitVirtualizer {
42
107
  element(index: number): {
43
108
  scrollIntoView: (options?: RevealOptions) => void;
44
109
  } | undefined;
110
+ /**
111
+ * Resolves once the latest scroll to an unrendered item (see
112
+ * {@link element}) has rendered and revealed it, or given up.
113
+ */
114
+ revealed(): Promise<void>;
45
115
  static get tagName(): "apex-virtualizer";
46
116
  static register(): void;
47
117
  scroller: boolean;