@aceshooting/lyra-ui 16.0.0 → 17.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/CHANGELOG.md +504 -0
  2. package/custom-elements.json +1 -1
  3. package/dist/cli/migration-contract.json +1 -1
  4. package/dist/components/agent-tools/browser-frame/browser-frame.class.d.ts +3 -3
  5. package/dist/components/agent-tools/browser-frame/browser-frame.class.js +2 -2
  6. package/dist/components/agent-tools/compare-panel/compare-panel.class.d.ts +2 -2
  7. package/dist/components/agent-tools/compare-panel/compare-panel.class.js +3 -3
  8. package/dist/components/agent-tools/confirm-bar/confirm-bar.class.d.ts +37 -13
  9. package/dist/components/agent-tools/confirm-bar/confirm-bar.class.js +2 -2
  10. package/dist/components/agent-tools/task-list/task-list.class.js +2 -2
  11. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.d.ts +4 -0
  12. package/dist/components/agent-tools/tool-call-chip/tool-call-chip.class.js +2 -2
  13. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.d.ts +3 -3
  14. package/dist/components/agent-tools/tool-param-form/tool-param-form.class.js +1 -1
  15. package/dist/components/charts/chart/chart.class.d.ts +117 -17
  16. package/dist/components/charts/chart/chart.class.js +3 -3
  17. package/dist/components/charts/chart/histogram-bin.d.ts +5 -1
  18. package/dist/components/charts/chart/histogram-bin.js +1 -1
  19. package/dist/components/charts/chart/lite-chart.class.d.ts +9 -0
  20. package/dist/components/conversation/code-block/code-block.styles.js +1 -1
  21. package/dist/components/conversation/message-actions/message-actions.styles.js +1 -1
  22. package/dist/components/conversation/model-select/model-select.class.d.ts +13 -4
  23. package/dist/components/conversation/model-select/model-select.class.js +2 -1
  24. package/dist/components/conversation/model-select/model-select.styles.js +1 -1
  25. package/dist/components/conversation/streaming-text/streaming-text-base.class.d.ts +40 -2
  26. package/dist/components/conversation/streaming-text/streaming-text-base.class.js +2 -2
  27. package/dist/components/conversation/streaming-text/streaming-text-core.class.d.ts +5 -3
  28. package/dist/components/conversation/streaming-text/streaming-text-core.class.js +10 -0
  29. package/dist/components/conversation/streaming-text/streaming-text.class.d.ts +9 -3
  30. package/dist/components/conversation/streaming-text/streaming-text.class.js +10 -0
  31. package/dist/components/conversation/suggestion-chips/suggestion-chips.class.d.ts +30 -2
  32. package/dist/components/conversation/suggestion-chips/suggestion-chips.class.js +4 -3
  33. package/dist/components/conversation/suggestion-chips/suggestion-chips.styles.js +1 -1
  34. package/dist/components/conversation/transcript-feed/transcript-feed.class.js +1 -1
  35. package/dist/components/conversation/usage-badge/usage-badge-overlay-runtime.js +1 -1
  36. package/dist/components/conversation/usage-badge/usage-badge.class.d.ts +4 -0
  37. package/dist/components/conversation/voice-picker/voice-picker.class.d.ts +16 -4
  38. package/dist/components/conversation/voice-picker/voice-picker.class.js +2 -1
  39. package/dist/components/conversation/voice-picker/voice-picker.styles.js +1 -1
  40. package/dist/components/data/context-meter/context-meter.class.d.ts +23 -4
  41. package/dist/components/data/context-meter/context-meter.class.js +10 -7
  42. package/dist/components/data/context-meter/context-meter.styles.js +1 -1
  43. package/dist/components/data/data-grid/data-grid.class.d.ts +5 -2
  44. package/dist/components/data/data-grid/data-grid.class.js +1 -1
  45. package/dist/components/data/flow-canvas/flow-canvas.class.d.ts +32 -5
  46. package/dist/components/data/flow-canvas/flow-canvas.class.js +3 -1
  47. package/dist/components/data/flow-canvas/flow-canvas.styles.js +1 -1
  48. package/dist/components/data/flow-canvas/flow-model.js +1 -1
  49. package/dist/components/data/flow-canvas/flow-types.d.ts +10 -1
  50. package/dist/components/data/gauge/gauge.class.d.ts +15 -2
  51. package/dist/components/data/gauge/gauge.class.js +20 -20
  52. package/dist/components/data/gauge/gauge.styles.js +1 -1
  53. package/dist/components/data/graph-query-builder/graph-query-builder.class.d.ts +14 -5
  54. package/dist/components/data/graph-query-builder/graph-query-builder.class.js +2 -2
  55. package/dist/components/data/sequence-strip/sequence-strip.class.d.ts +28 -2
  56. package/dist/components/data/sequence-strip/sequence-strip.class.js +3 -2
  57. package/dist/components/data/sequence-strip/sequence-strip.styles.js +1 -1
  58. package/dist/components/data/table/table.class.d.ts +155 -30
  59. package/dist/components/data/table/table.class.js +6 -4
  60. package/dist/components/data/table/table.styles.js +1 -1
  61. package/dist/components/data/timeline/timeline-item.class.d.ts +9 -1
  62. package/dist/components/data/timeline/timeline-item.class.js +2 -2
  63. package/dist/components/data/word-cloud/word-cloud.class.js +1 -1
  64. package/dist/components/data/word-cloud/word-cloud.styles.js +1 -1
  65. package/dist/components/forms/button/button.class.d.ts +30 -1
  66. package/dist/components/forms/button/button.class.js +2 -2
  67. package/dist/components/forms/checkbox/checkbox.class.d.ts +8 -6
  68. package/dist/components/forms/checkbox/checkbox.class.js +2 -2
  69. package/dist/components/forms/checkbox-group/checkbox-group.class.d.ts +7 -5
  70. package/dist/components/forms/checkbox-group/checkbox-group.class.js +1 -1
  71. package/dist/components/forms/color-picker/color-picker.class.d.ts +16 -2
  72. package/dist/components/forms/color-picker/color-picker.class.js +2 -2
  73. package/dist/components/forms/color-picker/color-picker.styles.js +1 -1
  74. package/dist/components/forms/combobox/combobox.class.d.ts +43 -8
  75. package/dist/components/forms/combobox/combobox.class.js +2 -2
  76. package/dist/components/forms/date-picker/date-input.class.d.ts +4 -0
  77. package/dist/components/forms/date-picker/date-input.class.js +1 -1
  78. package/dist/components/forms/icon-button/icon-button.class.d.ts +20 -3
  79. package/dist/components/forms/icon-button/icon-button.class.js +1 -1
  80. package/dist/components/forms/icon-button/icon-button.styles.js +1 -1
  81. package/dist/components/forms/input/input.class.d.ts +5 -2
  82. package/dist/components/forms/input/input.class.js +1 -1
  83. package/dist/components/forms/input/time-input.class.d.ts +4 -0
  84. package/dist/components/forms/input/time-input.class.js +1 -1
  85. package/dist/components/forms/locale-picker/locale-picker.class.d.ts +11 -5
  86. package/dist/components/forms/locale-picker/locale-picker.class.js +1 -1
  87. package/dist/components/forms/otp-input/otp-input.class.d.ts +7 -2
  88. package/dist/components/forms/otp-input/otp-input.class.js +2 -2
  89. package/dist/components/forms/radio/radio-button.class.d.ts +2 -1
  90. package/dist/components/forms/radio/radio-group.class.d.ts +9 -4
  91. package/dist/components/forms/radio/radio-group.class.js +1 -1
  92. package/dist/components/forms/radio/radio.class.d.ts +13 -7
  93. package/dist/components/forms/radio/radio.class.js +1 -1
  94. package/dist/components/forms/rubric-form/rubric-form.class.d.ts +16 -6
  95. package/dist/components/forms/rubric-form/rubric-form.class.js +2 -2
  96. package/dist/components/forms/select/select.class.d.ts +19 -8
  97. package/dist/components/forms/select/select.class.js +2 -2
  98. package/dist/components/forms/slider/slider.class.d.ts +4 -2
  99. package/dist/components/forms/slider/slider.class.js +1 -1
  100. package/dist/components/forms/switch/switch.class.d.ts +8 -6
  101. package/dist/components/forms/switch/switch.class.js +1 -1
  102. package/dist/components/forms/textarea/textarea.class.d.ts +5 -3
  103. package/dist/components/forms/textarea/textarea.class.js +1 -1
  104. package/dist/components/forms/time-range/time-range.class.d.ts +12 -7
  105. package/dist/components/forms/time-range/time-range.class.js +1 -1
  106. package/dist/components/forms/time-range/time-range.styles.js +1 -1
  107. package/dist/components/forms/token-input/token-input.class.d.ts +6 -4
  108. package/dist/components/forms/token-input/token-input.class.js +1 -1
  109. package/dist/components/layout/app-rail/app-rail-item.class.d.ts +109 -4
  110. package/dist/components/layout/app-rail/app-rail-item.class.js +34 -29
  111. package/dist/components/layout/app-rail/app-rail-item.styles.js +1 -1
  112. package/dist/components/layout/app-rail/app-rail.class.d.ts +25 -3
  113. package/dist/components/layout/app-rail/app-rail.styles.js +1 -1
  114. package/dist/components/layout/app-rail-group/app-rail-group.class.d.ts +2 -2
  115. package/dist/components/layout/app-rail-group/app-rail-group.class.js +2 -2
  116. package/dist/components/layout/carousel/carousel.class.d.ts +1 -1
  117. package/dist/components/layout/carousel/carousel.class.js +1 -1
  118. package/dist/components/layout/details/accordion.class.d.ts +2 -2
  119. package/dist/components/layout/details/accordion.class.js +2 -2
  120. package/dist/components/layout/filter-bar/filter-bar-register.d.ts +1 -0
  121. package/dist/components/layout/filter-bar/filter-bar-register.js +1 -0
  122. package/dist/components/layout/filter-bar/filter-bar.class.d.ts +85 -10
  123. package/dist/components/layout/filter-bar/filter-bar.class.js +7 -4
  124. package/dist/components/layout/menu/menu-item.class.d.ts +3 -3
  125. package/dist/components/layout/menu/menu-item.class.js +3 -3
  126. package/dist/components/layout/menu/menu.class.d.ts +5 -1
  127. package/dist/components/layout/menu/menu.class.js +2 -2
  128. package/dist/components/layout/reorder-list/reorder-item.styles.js +1 -1
  129. package/dist/components/layout/virtual-list/virtual-list.class.js +1 -1
  130. package/dist/components/media/attachment-trigger/attachment-trigger.styles.js +1 -1
  131. package/dist/components/media/avatar-group/avatar-group.class.d.ts +12 -1
  132. package/dist/components/media/avatar-group/avatar-group.class.js +2 -2
  133. package/dist/components/media/drop-zone/drop-zone.class.d.ts +32 -11
  134. package/dist/components/media/drop-zone/drop-zone.class.js +2 -2
  135. package/dist/components/media/file-input/file-input.class.d.ts +40 -19
  136. package/dist/components/media/file-input/file-input.class.js +2 -2
  137. package/dist/components/overlays/callout/callout.styles.js +1 -1
  138. package/dist/components/overlays/dialog/dialog.styles.js +1 -1
  139. package/dist/components/overlays/overlay/dropdown.class.d.ts +13 -3
  140. package/dist/components/overlays/overlay/dropdown.class.js +2 -2
  141. package/dist/components/overlays/overlay/popover.class.d.ts +12 -3
  142. package/dist/components/overlays/overlay/popover.class.js +2 -2
  143. package/dist/components/overlays/rating/rating.class.d.ts +9 -7
  144. package/dist/components/overlays/rating/rating.class.js +1 -1
  145. package/dist/components/retrieval/citation-badge/citation-badge.class.d.ts +5 -1
  146. package/dist/components/retrieval/citation-badge/citation-badge.class.js +1 -1
  147. package/dist/components/retrieval/embedding-explorer/embedding-explorer.styles.js +1 -1
  148. package/dist/components/retrieval/entity-chip/entity-chip.class.d.ts +5 -1
  149. package/dist/components/retrieval/entity-chip/entity-chip.class.js +1 -1
  150. package/dist/components/retrieval/graph-legend/graph-legend.styles.js +1 -1
  151. package/dist/components/retrieval/retrieval-value-format.js +1 -1
  152. package/dist/components/retrieval/source-list/source-list.styles.js +1 -1
  153. package/dist/components/utility/copy-button/copy-button.class.d.ts +23 -11
  154. package/dist/components/utility/copy-button/copy-button.class.js +2 -2
  155. package/dist/components/utility/copy-button/copy-button.styles.js +1 -1
  156. package/dist/components/utility/diff-view/diff-view.styles.js +1 -1
  157. package/dist/components/utility/export-button/export-button.class.d.ts +4 -0
  158. package/dist/components/utility/export-button/export-button.class.js +1 -1
  159. package/dist/components/utility/json-viewer/json-viewer.styles.js +1 -1
  160. package/dist/components/utility/known-date/known-date.class.js +1 -1
  161. package/dist/components/utility/mention-popover/mention-popover.class.d.ts +38 -3
  162. package/dist/components/utility/mention-popover/mention-popover.class.js +2 -1
  163. package/dist/components/utility/mention-popover/mention-popover.styles.js +1 -1
  164. package/dist/components/utility/poll-status/poll-status.styles.js +1 -1
  165. package/dist/components/utility/tour/tour.class.d.ts +4 -0
  166. package/dist/components/utility/tour/tour.class.js +1 -1
  167. package/dist/components/utility/tour/tour.styles.js +1 -1
  168. package/dist/components/viewers/document-preview/document-preview.class.js +2 -2
  169. package/dist/components/viewers/docx-viewer/docx-viewer.class.js +2 -2
  170. package/dist/components/viewers/ebook-viewer/ebook-viewer.class.js +2 -2
  171. package/dist/components/viewers/highlight-layer/highlight-layer.class.js +2 -2
  172. package/dist/components/viewers/notebook-viewer/notebook-viewer.class.js +2 -2
  173. package/dist/components/viewers/pdf-viewer/pdf-viewer.class.js +2 -2
  174. package/dist/components/viewers/pptx-viewer/pptx-viewer.class.js +2 -2
  175. package/dist/components/viewers/xml-viewer/xml-viewer.class.js +2 -2
  176. package/dist/custom-elements-jsx.d.ts +2 -2
  177. package/dist/events.d.ts +13 -12
  178. package/dist/internal/aggregate-file-limits.d.ts +33 -0
  179. package/dist/internal/aggregate-file-limits.js +1 -0
  180. package/dist/internal/catalog-picker.d.ts +15 -2
  181. package/dist/internal/catalog-picker.js +1 -1
  182. package/dist/internal/debounce-controller.d.ts +14 -0
  183. package/dist/internal/debounce-controller.js +1 -1
  184. package/dist/internal/default-strings.generated.d.ts +1 -1
  185. package/dist/internal/default-strings.generated.js +2 -2
  186. package/dist/internal/focus-navigation.d.ts +45 -0
  187. package/dist/internal/focus-navigation.js +1 -1
  188. package/dist/internal/form-associated.js +1 -1
  189. package/dist/internal/initial-slot-collection.d.ts +30 -0
  190. package/dist/internal/initial-slot-collection.js +1 -0
  191. package/dist/internal/intl-cache.js +1 -1
  192. package/dist/internal/invalid-event-alias.d.ts +46 -0
  193. package/dist/internal/invalid-event-alias.js +1 -1
  194. package/dist/internal/localization-runtime.d.ts +24 -0
  195. package/dist/internal/localization-runtime.js +1 -1
  196. package/dist/internal/localization-types.d.ts +1 -1
  197. package/dist/internal/localization.js +1 -1
  198. package/dist/internal/package-metadata.d.ts +1 -1
  199. package/dist/internal/package-metadata.js +1 -1
  200. package/dist/internal/positioning-strategy.d.ts +3 -1
  201. package/dist/internal/state-part.d.ts +49 -0
  202. package/dist/internal/state-part.js +1 -0
  203. package/dist/internal/variants.styles.js +1 -1
  204. package/dist/lyra.d.ts +1 -1
  205. package/dist/svelte.d.ts +2 -2
  206. package/dist/testing/index.d.ts +1 -1
  207. package/dist/testing/index.js +1 -1
  208. package/dist/testing/lyra-tag-event-map.d.ts +2 -2
  209. package/dist/testing/lyra-tag-event-map.js +1 -1
  210. package/dist/testing/wait-for-mount.d.ts +46 -0
  211. package/dist/testing/wait-for-mount.js +1 -0
  212. package/dist/theme/theme-bootstrap.js +1 -1
  213. package/dist/theme/theme.d.ts +11 -2
  214. package/dist/theme/theme.js +1 -1
  215. package/dist/translations/ar/layout.js +1 -1
  216. package/dist/translations/de/layout.js +1 -1
  217. package/dist/translations/es/layout.js +1 -1
  218. package/dist/translations/fa/layout.js +1 -1
  219. package/dist/translations/fr/layout.js +1 -1
  220. package/dist/translations/he/layout.js +1 -1
  221. package/dist/translations/it/layout.js +1 -1
  222. package/dist/translations/ja/layout.js +1 -1
  223. package/dist/translations/pt-BR/layout.js +1 -1
  224. package/dist/translations/ru/layout.js +1 -1
  225. package/dist/translations/zh-CN/layout.js +1 -1
  226. package/dist/utilities/format.d.ts +17 -0
  227. package/dist/utilities/format.js +1 -1
  228. package/dist/vue.d.ts +2 -2
  229. package/llms/components/lr-app-rail-group.md +87 -10
  230. package/llms/components/lr-app-rail-item.md +88 -11
  231. package/llms/components/lr-app-rail.md +88 -11
  232. package/llms/components/lr-attachment-trigger.md +21 -0
  233. package/llms/components/lr-bar-chart.md +3 -2
  234. package/llms/components/lr-bubble-chart.md +3 -2
  235. package/llms/components/lr-callout.md +10 -0
  236. package/llms/components/lr-chart.md +43 -12
  237. package/llms/components/lr-citation-badge.md +7 -1
  238. package/llms/components/lr-code-block.md +21 -0
  239. package/llms/components/lr-color-picker.md +12 -7
  240. package/llms/components/lr-combobox.md +13 -1
  241. package/llms/components/lr-confirm-bar.md +36 -7
  242. package/llms/components/lr-context-meter.md +17 -4
  243. package/llms/components/lr-date-input.md +7 -1
  244. package/llms/components/lr-date-picker.md +6 -0
  245. package/llms/components/lr-dialog.md +21 -0
  246. package/llms/components/lr-doughnut-chart.md +3 -2
  247. package/llms/components/lr-drawer.md +10 -0
  248. package/llms/components/lr-drop-zone.md +16 -7
  249. package/llms/components/lr-dropdown-item.md +7 -0
  250. package/llms/components/lr-entity-chip.md +7 -1
  251. package/llms/components/lr-export-button.md +7 -1
  252. package/llms/components/lr-file-input.md +21 -10
  253. package/llms/components/lr-filter-bar.md +91 -15
  254. package/llms/components/lr-flow-canvas.md +16 -9
  255. package/llms/components/lr-gauge.md +22 -2
  256. package/llms/components/lr-histogram.md +7 -2
  257. package/llms/components/lr-icon-button.md +15 -7
  258. package/llms/components/lr-input.md +3 -1
  259. package/llms/components/lr-line-chart.md +3 -2
  260. package/llms/components/lr-lite-chart.md +13 -0
  261. package/llms/components/lr-locale-picker.md +7 -1
  262. package/llms/components/lr-mention-popover.md +16 -3
  263. package/llms/components/lr-menu-item.md +7 -0
  264. package/llms/components/lr-menu.md +8 -1
  265. package/llms/components/lr-message-actions.md +10 -0
  266. package/llms/components/lr-model-select.md +8 -3
  267. package/llms/components/lr-native-time-input.md +8 -1
  268. package/llms/components/lr-number-input.md +8 -1
  269. package/llms/components/lr-option.md +12 -0
  270. package/llms/components/lr-otp-input.md +6 -0
  271. package/llms/components/lr-pie-chart.md +3 -2
  272. package/llms/components/lr-polar-area-chart.md +3 -2
  273. package/llms/components/lr-prompt-input.md +2 -2
  274. package/llms/components/lr-radar-chart.md +3 -2
  275. package/llms/components/lr-reorder-item.md +12 -0
  276. package/llms/components/lr-reorder-list.md +12 -0
  277. package/llms/components/lr-scatter-chart.md +3 -2
  278. package/llms/components/lr-sequence-strip.md +10 -4
  279. package/llms/components/lr-streaming-text-core.md +21 -8
  280. package/llms/components/lr-streaming-text.md +34 -4
  281. package/llms/components/lr-suggestion-chips.md +8 -4
  282. package/llms/components/lr-table.md +47 -10
  283. package/llms/components/lr-textarea.md +1 -1
  284. package/llms/components/lr-time-input.md +7 -1
  285. package/llms/components/lr-tool-call-chip.md +7 -1
  286. package/llms/components/lr-tour.md +7 -1
  287. package/llms/components/lr-usage-badge.md +7 -1
  288. package/llms/components/lr-voice-picker.md +7 -3
  289. package/llms/shared.md +169 -16
  290. package/llms/tokens.md +17 -1
  291. package/llms-full.txt +941 -147
  292. package/package.json +16 -2
  293. package/registrations.json +1 -1
  294. package/vscode-css-data.json +1 -1
  295. package/vscode-html-data.json +1 -1
  296. package/web-types.json +1 -1
@@ -1 +1 @@
1
- import{css}from"lit";const styles=css`:host{--_lr-reorder-item-move-bg:var(--lr-icon-button-background,transparent);--_lr-reorder-item-move-bg-hover:var(--lr-icon-button-background-hover,var(--lr-color-brand-quiet));--_lr-reorder-item-move-bg-active:var(--lr-icon-button-background-active,color-mix(in oklab, var(--lr-icon-button-background-hover,var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active)));--_lr-reorder-item-move-color:var(--lr-icon-button-color,var(--lr-color-text-quiet));--_lr-reorder-item-move-color-hover:var(--lr-icon-button-color-hover,var(--lr-color-brand));--_lr-reorder-item-move-color-active:var(--lr-icon-button-color-active,var(--lr-icon-button-color-hover,var(--lr-color-brand)));--_lr-reorder-item-move-radius:var(--lr-icon-button-radius,var(--lr-radius));min-inline-size:0;max-inline-size:100%;display:block}[part=base]{align-items:center;gap:var(--lr-reorder-item-gap,var(--lr-space-xs));min-inline-size:0;max-inline-size:100%;display:flex}[part=move-up-button],[part=move-down-button]{font-size:var(--lr-font-size-m);--lr-icon-button-background:var(--_lr-reorder-item-move-bg);--lr-icon-button-background-hover:var(--lr-reorder-item-move-button-hover-bg,var(--_lr-reorder-item-move-bg-hover));--lr-icon-button-background-active:var(--lr-reorder-item-move-button-active-bg,var(--_lr-reorder-item-move-bg-active));--lr-icon-button-color:var(--_lr-reorder-item-move-color);--lr-icon-button-color-hover:var(--lr-reorder-item-move-button-hover-color,var(--_lr-reorder-item-move-color-hover));--lr-icon-button-color-active:var(--lr-reorder-item-move-button-active-color,var(--_lr-reorder-item-move-color-active));--lr-icon-button-radius:var(--_lr-reorder-item-move-radius);flex:none}[part=move-up-button]{transform:rotate(-90deg)}[part=move-down-button]{transform:rotate(90deg)}[part=move-up-button][disabled],[part=move-down-button][disabled]{--lr-icon-button-background-hover:var(--_lr-reorder-item-move-bg);--lr-icon-button-background-active:var(--_lr-reorder-item-move-bg);--lr-icon-button-color-hover:var(--_lr-reorder-item-move-color);--lr-icon-button-color-active:var(--_lr-reorder-item-move-color)}[part=content]{overflow-wrap:anywhere;flex:auto;min-inline-size:0;max-inline-size:100%}@media (prefers-reduced-motion:reduce){[part=move-up-button],[part=move-down-button]{transition:none!important}}`;export{styles};
1
+ import{css}from"lit";const styles=css`:host{--_lr-reorder-item-move-bg:transparent;--_lr-reorder-item-move-bg-hover:var(--lr-color-brand-quiet);--_lr-reorder-item-move-bg-active:color-mix(in oklab, var(--lr-icon-button-background-hover,var(--lr-color-brand-quiet)), var(--lr-color-mix-partner) var(--lr-color-mix-active));--_lr-reorder-item-move-color:var(--lr-color-text-quiet);--_lr-reorder-item-move-color-hover:var(--lr-color-brand);--_lr-reorder-item-move-color-active:var(--lr-icon-button-color-hover,var(--lr-color-brand));--_lr-reorder-item-move-radius:var(--lr-radius);min-inline-size:0;max-inline-size:100%;display:block}[part=base]{align-items:center;gap:var(--lr-reorder-item-gap,var(--lr-space-xs));min-inline-size:0;max-inline-size:100%;display:flex}[part=move-up-button],[part=move-down-button]{font-size:var(--lr-font-size-m);--_lr-icon-button-background-default:var(--_lr-reorder-item-move-bg);--_lr-icon-button-background-hover-default:var(--lr-reorder-item-move-button-hover-bg,var(--_lr-reorder-item-move-bg-hover));--_lr-icon-button-background-active-default:var(--lr-reorder-item-move-button-active-bg,var(--_lr-reorder-item-move-bg-active));--_lr-icon-button-color-default:var(--_lr-reorder-item-move-color);--_lr-icon-button-color-hover-default:var(--lr-reorder-item-move-button-hover-color,var(--_lr-reorder-item-move-color-hover));--_lr-icon-button-color-active-default:var(--lr-reorder-item-move-button-active-color,var(--_lr-reorder-item-move-color-active));--_lr-icon-button-radius-default:var(--_lr-reorder-item-move-radius);flex:none}[part=move-up-button]{transform:rotate(-90deg)}[part=move-down-button]{transform:rotate(90deg)}[part=move-up-button][disabled],[part=move-down-button][disabled]{--_lr-icon-button-background-hover-default:var(--_lr-reorder-item-move-bg);--_lr-icon-button-background-active-default:var(--_lr-reorder-item-move-bg);--_lr-icon-button-color-hover-default:var(--_lr-reorder-item-move-color);--_lr-icon-button-color-active-default:var(--_lr-reorder-item-move-color)}[part=content]{overflow-wrap:anywhere;flex:auto;min-inline-size:0;max-inline-size:100%}@media (prefers-reduced-motion:reduce){[part=move-up-button],[part=move-down-button]{transition:none!important}}`;export{styles};
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{finiteAdd,finiteCount,finiteInteger,finiteNumber}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{styles}from"./virtual-list.styles.js";const DEFAULT_ROW_ESTIMATE_PX=48,DEFAULT_GROUP_ESTIMATE_PX=32,DEFAULT_OVERSCAN_ROWS=6,MAX_OVERSCAN_ROWS=100,MAX_VIRTUAL_LIST_GROUPS=1e4,EMPTY_VIRTUAL_LIST_GROUPS=Object.freeze([]);function normalizeOverscan(value){if(value===null)return DEFAULT_OVERSCAN_ROWS;const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)?Math.min(MAX_OVERSCAN_ROWS,Math.max(0,Math.floor(numeric))):DEFAULT_OVERSCAN_ROWS}const overscanConverter={fromAttribute(value){return normalizeOverscan(value)}};function virtualListGroupsChanged(value,oldValue){if(value===oldValue)return!1;const next=value,previous=oldValue;if(next==null||previous==null)return next!==previous;if(next.length!==previous.length)return!0;for(let index=0;index<next.length;index+=1){const a=next[index],b=previous[index];if(a.key!==b.key||a.label!==b.label||a.startIndex!==b.startIndex)return!0}return!1}function normalizeRowHeight(value){if(value==="auto")return"auto";const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)&&numeric>0?numeric:"auto"}const rowHeightConverter={fromAttribute(value){return value===null?"auto":normalizeRowHeight(value)}};function isIndexedSource(source){return!Array.isArray(source)}const ELEMENT_NODE_TYPE=1;function isWindowScroller(target){return target.window===target}function domKeyToken(key){if(typeof key=="number"){if(Number.isNaN(key))return"number:NaN";if(Object.is(key,-0))return"number:-0"}return`${typeof key}:${String(key)}`}class LyraVirtualList extends LyraElement{constructor(){super(...arguments),this.items=[],this.renderItem=()=>nothing,this.rowHeight="auto",this.itemRole="listitem",this.rowIndexOffset=0,this.overscan=DEFAULT_OVERSCAN_ROWS,this.activeItemId="",this.loading=!1,this.hasMore=!1,this.containerScrollTop=0,this.viewportHeight=0,this.renderUnmeasuredWindow=!0,this.offsets=[0],this.rowIdentities=[],this.fixedRowHeight=null,this.measuredHeights=new Map,this.measuredIndices=new Map,this.indexedMeasurementIndices=[],this.indexedMeasurementDeltaPrefix=[0],this.indexedMeasurementIndexDirty=!0,this.offsetsDirty=!0,this.itemsChangedPendingPrune=!1,this.renderStart=0,this.renderEnd=-1,this.visibleStart=0,this.visibleEnd=-1,this.lastEmittedStart=-1,this.lastEmittedEnd=-1,this.loadMoreArmed=!0,this.measurementGeneration=0,this.isFirstUpdate=!0,this.stickyHeight=0,this.observedRows=new Map,this.observedRowKeys=new WeakMap,this.observedRowIndices=new WeakMap,this.observedGroups=new Map,this.observedGroupIndices=new WeakMap,this.externalMetricsPending=!1,this.ownerRealmGeneration=0,this.inResizeDelivery=!1,this.deferredRowObservations=new Map,this.deferredGroupObservations=new Map,this.activeIndexForLength=-1,this.activeIndexForId="",this.activeIndexCache=-1,this.pendingScrollTop=null,this.normalizedGroups=EMPTY_VIRTUAL_LIST_GROUPS,this.normalizedGroupByIndex=new Map,this.measuredGroupHeights=new Map,this.groupHeightPrefix=[0],this.onExternalViewportResize=()=>{this.syncExternalScrollMetrics()},this.onUserScrollIntent=event=>{event instanceof KeyboardEvent&&!new Set(["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"," "]).has(event.key)||(this.pendingScrollCorrection=void 0)},this.onScroll=e=>{if(this.externalScroller?(this.pendingScrollTop=null,this.externalMetricsPending=!0):this.pendingScrollTop=e.currentTarget.scrollTop,this.scrollRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected)return;const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(!(this.scrollRafId!==handle||this.scrollRafOwner!==ownerWindow||this.scrollRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))){if(this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.externalMetricsPending){this.externalMetricsPending=!1;const metrics=this.readScrollMetrics();metrics&&(this.pendingScrollTop=metrics.scrollTop,this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight))}if(this.pendingScrollTop!==null){const scrollTop=this.pendingScrollTop;this.pendingScrollTop=null;const moved=this.containerScrollTop!==scrollTop;this.containerScrollTop=scrollTop,moved&&this.emit("lr-virtual-scroll",{scrollTop,viewportHeight:this.viewportHeight})}}});this.scrollRafId=handle,this.scrollRafOwner=ownerWindow,this.scrollRafDocument=ownerDocument},this.onRowsResized=entries=>{if(this.beginResizeDelivery(),this.fixedRowHeight!=null)return;const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const row=entry.target,key=this.observedRowKeys.get(row),index=this.observedRowIndices.get(row);if(key===void 0||index===void 0)continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height,prev=this.measuredHeights.get(key);if(prev===void 0||Math.abs(prev-height)>.5){const oldBottom=this.rowBottomAt(index);this.measuredHeights.set(key,height),this.measuredIndices.set(key,index);const oldHeight=prev??DEFAULT_ROW_ESTIMATE_PX;oldBottom<=oldScrollTop&&(scrollAdjustment+=height-oldHeight),changed=!0}}if(changed){if(this.indexedMeasurementIndexDirty=!0,base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onGroupsResized=entries=>{this.beginResizeDelivery();const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const marker=entry.target,index=this.observedGroupIndices.get(marker);if(index===void 0||!this.normalizedGroupByIndex.has(index))continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height;if(!Number.isFinite(height)||height<0)continue;const previous=this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX;if(Math.abs(previous-height)<=.5)continue;const oldRowTop=this.offsetAt(index);this.measuredGroupHeights.set(index,height),oldRowTop<=oldScrollTop&&(scrollAdjustment+=height-previous),changed=!0}if(changed){if(base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onStickyResized=entries=>{this.beginResizeDelivery();const entry=entries[0];if(!entry)return;const height=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height;Math.abs(this.stickyHeight-height)>.5&&(this.stickyHeight=height)}}static{this.ownedCollectionProperties=Object.freeze(["items","source","groups"])}static{this.identityCollectionProperties=Object.freeze(["items","source"])}static{this.identityCollectionObjectProperties=Object.freeze(["source"])}static{this.styles=[LyraElement.styles,styles]}get scrollContainer(){return this.renderRoot?.querySelector('[part="base"]')??void 0}get renderedRows(){const root=this.renderRoot;return root?[...root.querySelectorAll('[part="row"]')]:[]}get externalScroller(){const target=this.scrollElement;if(target!=null)return isWindowScroller(target)||target.nodeType===ELEMENT_NODE_TYPE?target:void 0}get spacerElement(){return this.renderRoot?.querySelector('[part="spacer"]')??void 0}readScrollMetrics(){const base=this.scrollContainer;if(!base)return null;const external=this.externalScroller;if(!external)return{scrollTop:base.scrollTop,rawScrollTop:base.scrollTop,viewportHeight:base.clientHeight};const spacerTop=(this.spacerElement??base).getBoundingClientRect().top;if(isWindowScroller(external)){const documentHeight=finiteNumber(external.document?.documentElement?.clientHeight??0,0),rawScrollTop2=finiteNumber(-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop2),rawScrollTop:rawScrollTop2,viewportHeight:documentHeight>0?documentHeight:finiteNumber(external.innerHeight,0)}}const scrollerTop=external.getBoundingClientRect().top,rawScrollTop=finiteNumber(scrollerTop-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop),rawScrollTop,viewportHeight:finiteNumber(external.clientHeight,0)}}applyScrollPosition(top,behavior){const external=this.externalScroller;if(!external){const base=this.scrollContainer;if(!base)return;const next2=Math.max(0,finiteNumber(top,0));behavior===void 0?base.scrollTop=next2:base.scrollTo({top:next2,behavior});return}const metrics=this.readScrollMetrics();if(!metrics)return;const delta=finiteNumber(top,metrics.rawScrollTop)-metrics.rawScrollTop;if(isWindowScroller(external)){const options={top:Math.max(0,finiteNumber(external.scrollY+delta,0))};behavior!==void 0&&(options.behavior=behavior),external.scrollTo(options);return}const next=Math.max(0,finiteNumber(external.scrollTop+delta,0));behavior===void 0?external.scrollTop=next:external.scrollTo({top:next,behavior})}syncExternalScrollMetrics(){const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))}get safeRowIndexOffset(){return finiteCount(this.rowIndexOffset)}computedAriaRowIndex(index){return finiteInteger(finiteAdd(index+1,this.safeRowIndexOffset),1,1,Number.MAX_SAFE_INTEGER)}get activeIndex(){if(this.activeItemId==="")return-1;const source=this.effectiveSource,count=this.itemCount;if(this.activeIndexFor===source&&this.activeIndexForLength===count&&Object.is(this.activeIndexForId,this.activeItemId)&&this.activeIndexForKeyFn===this.keyFunction)return this.activeIndexCache;if(this.activeIndexFor=source,this.activeIndexForLength=count,this.activeIndexForId=this.activeItemId,this.activeIndexForKeyFn=this.keyFunction,this.activeIndexCache=-1,isIndexedSource(source)){if(!this.keyFunction&&source.indexOfKey){const candidate=source.indexOfKey(this.activeItemId);Number.isInteger(candidate)&&candidate>=0&&candidate<count&&(this.activeIndexCache=candidate)}return this.activeIndexCache}for(let index=0;index<count;index++){const item=this.itemAt(index);if(Object.is(this.keyOf(item,index),this.activeItemId)){this.activeIndexCache=index;break}}return this.activeIndexCache}connectedCallback(){super.connectedCallback(),this.ownerDocument.defaultView&&this.seedFirstRenderState(()=>{this.renderUnmeasuredWindow=!1,this.requestUpdate()}),this.resetOwnerRealmWork();const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow?.ResizeObserver;if(ResizeObserverCtor){const rowObserver=new ResizeObserverCtor(entries=>{this.rowResizeObserver!==rowObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onRowsResized(entries)}),groupObserver=new ResizeObserverCtor(entries=>{this.groupResizeObserver!==groupObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onGroupsResized(entries)}),stickyObserver=new ResizeObserverCtor(entries=>{this.stickyResizeObserver!==stickyObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onStickyResized(entries)});this.rowResizeObserver=rowObserver,this.groupResizeObserver=groupObserver,this.stickyResizeObserver=stickyObserver}this.hasUpdated&&(this.attachContainerListeners(),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay())}disconnectedCallback(){this.resetOwnerRealmWork(),super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.resetOwnerRealmWork()}isCurrentOwnerWork(ownerDocument,generation){return this.ownerRealmGeneration===generation&&this.isConnected&&this.ownerDocument===ownerDocument}resetOwnerRealmWork(){this.ownerRealmGeneration+=1,this.rowResizeObserver?.disconnect(),this.rowResizeObserver=void 0,this.groupResizeObserver?.disconnect(),this.groupResizeObserver=void 0,this.observedRows.clear(),this.observedGroups.clear(),this.deferredRowObservations.clear(),this.deferredGroupObservations.clear(),this.inResizeDelivery=!1,this.rowObserveRafId!==void 0&&this.rowObserveRafOwner?.cancelAnimationFrame(this.rowObserveRafId),this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.stickyResizeObserver?.disconnect(),this.stickyResizeObserver=void 0,this.observedSticky=void 0,this.scrollRafId!==void 0&&this.scrollRafOwner?.cancelAnimationFrame(this.scrollRafId),this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.pendingScrollTop=null,this.externalMetricsPending=!1,this.pendingScrollCorrection=void 0,this.detachContainerListeners(),this.scrollListenerTarget=void 0}firstUpdated(changed){super.firstUpdated(changed),this.attachContainerListeners()}willUpdate(changed){super.willUpdate(changed),this.isFirstUpdate=!this.hasUpdated,(changed.has("items")||changed.has("source")||changed.has("keyFunction")||changed.has("rowHeight")||changed.has("groups")||changed.has("activeItemId")||changed.has("scrollElement"))&&(this.pendingScrollCorrection=void 0),(changed.has("items")||changed.has("source")||changed.has("rowHeight")||changed.has("keyFunction")||changed.has("groups"))&&(this.offsetsDirty=!0),(changed.has("items")||changed.has("source"))&&(this.itemsChangedPendingPrune=!0),isIndexedSource(this.effectiveSource)&&(changed.has("items")||changed.has("source")||changed.has("keyFunction"))&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0),changed.has("groups")&&this.measuredGroupHeights.clear(),(changed.has("items")||changed.has("source")||changed.has("groups"))&&this.recomputeGroups(),changed.has("rowHeight")&&(this.fixedRowHeight=this.parseRowHeight(this.rowHeight),this.fixedRowHeight!=null&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0)),this.offsetsDirty&&(this.recomputeOffsets(),this.offsetsDirty=!1),this.computeRange()}updated(changed){super.updated(changed),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay(),changed.has("scrollElement")&&!this.isFirstUpdate&&this.attachContainerListeners(),changed.has("activeItemId")&&!this.isFirstUpdate&&this.scrollActiveIntoView(),this.emitRangeChangeIfNeeded(),this.maybeFireLoadMore(),this.maybeCorrectPendingScroll()}parseRowHeight(value){const normalized=normalizeRowHeight(value);return normalized==="auto"?null:normalized}get effectiveSource(){return this.source??this.items}get itemCount(){const source=this.effectiveSource;return isIndexedSource(source)?finiteCount(source.count):source.length}itemAt(index){const source=this.effectiveSource;return isIndexedSource(source)?source.itemAt(index):source[index]}keyOf(item,index){const source=this.effectiveSource,key=this.keyFunction?this.keyFunction(item,index):isIndexedSource(source)?source.keyAt?.(index)??index:index;return typeof key=="string"||typeof key=="number"?key:index}rowIdentity(key,occurrence){const token=domKeyToken(key);return`${token.length}:${token}:${occurrence}`}identityAt(index,item=this.itemAt(index)){return isIndexedSource(this.effectiveSource)?this.rowIdentity(this.keyOf(item,index),index):this.rowIdentities[index]??this.rowIdentity(this.keyOf(item,index),index)}groupHeightAt(index){const group=this.normalizedGroupByIndex.get(index);return!group||group.label===""?0:this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX}rowHeightAt(index){return this.fixedRowHeight!=null?this.fixedRowHeight:this.measuredHeights.get(this.identityAt(index))??DEFAULT_ROW_ESTIMATE_PX}groupContributionThrough(index){let low=0,high=this.normalizedGroups.length;for(;low<high;){const middle=low+high>>1;this.normalizedGroups[middle].startIndex<=index?low=middle+1:high=middle}return this.groupHeightPrefix[low]??0}recomputeGroupHeightPrefix(){const prefix=new Array(this.normalizedGroups.length+1);prefix[0]=0;for(let index=0;index<this.normalizedGroups.length;index++){const group=this.normalizedGroups[index],height=group.label===""?0:this.measuredGroupHeights.get(group.startIndex)??DEFAULT_GROUP_ESTIMATE_PX;prefix[index+1]=finiteAdd(prefix[index],height)}this.groupHeightPrefix=prefix}indexedOffsetForIndex(index){const baseHeight=this.fixedRowHeight??DEFAULT_ROW_ESTIMATE_PX;let offset=index>Number.MAX_VALUE/baseHeight?Number.MAX_VALUE:index*baseHeight;if(this.fixedRowHeight==null){this.rebuildIndexedMeasurementIndex();let low=0,high=this.indexedMeasurementIndices.length;for(;low<high;){const middle=low+high>>1;this.indexedMeasurementIndices[middle]<index?low=middle+1:high=middle}offset=finiteAdd(offset,this.indexedMeasurementDeltaPrefix[low]??0)}return Math.max(0,finiteAdd(offset,this.groupContributionThrough(index)))}rebuildIndexedMeasurementIndex(){if(!this.indexedMeasurementIndexDirty)return;const retained=[];for(const[identity,index]of this.measuredIndices){const height=this.measuredHeights.get(identity);height!==void 0&&retained.push({index,delta:height-DEFAULT_ROW_ESTIMATE_PX})}retained.sort((a,b)=>a.index-b.index);const indices=new Array(retained.length),prefix=new Array(retained.length+1);prefix[0]=0;for(let position=0;position<retained.length;position++){const measurement=retained[position];indices[position]=measurement.index,prefix[position+1]=finiteAdd(prefix[position],measurement.delta)}this.indexedMeasurementIndices=indices,this.indexedMeasurementDeltaPrefix=prefix,this.indexedMeasurementIndexDirty=!1}pruneIndexedMeasurements(){if(!isIndexedSource(this.effectiveSource)||this.fixedRowHeight!=null||this.renderEnd<this.renderStart)return!1;const renderedCount=this.renderEnd-this.renderStart+1,retentionRows=Math.max(renderedCount,normalizeOverscan(this.overscan)*4),firstRetained=Math.max(0,this.renderStart-retentionRows),lastRetained=Math.min(this.itemCount-1,this.renderEnd+retentionRows);let removedDeltaBeforeWindow=0,pruned=!1;for(const[identity,measuredIndex]of this.measuredIndices)if(measuredIndex<firstRetained||measuredIndex>lastRetained){const height=this.measuredHeights.get(identity);height!==void 0&&measuredIndex<firstRetained&&(removedDeltaBeforeWindow=finiteAdd(removedDeltaBeforeWindow,height-DEFAULT_ROW_ESTIMATE_PX)),this.measuredIndices.delete(identity),this.measuredHeights.delete(identity),pruned=!0}if(pruned&&(this.indexedMeasurementIndexDirty=!0,removedDeltaBeforeWindow!==0)){const nextScrollTop=(this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop)-removedDeltaBeforeWindow;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}return pruned}offsetAt(index){return isIndexedSource(this.effectiveSource)?this.indexedOffsetForIndex(index):this.offsets[index]??0}recomputeOffsets(){const n=this.itemCount;if(this.recomputeGroupHeightPrefix(),isIndexedSource(this.effectiveSource)){this.offsets=[0],this.rowIdentities=[],this.itemsChangedPendingPrune=!1;return}const offsets=new Array(n+1);let cursor=0;const liveKeys=this.itemsChangedPendingPrune&&this.fixedRowHeight==null?new Set:null,occurrences=new Map,identities=new Array(n);for(let i=0;i<n;i++){cursor=finiteAdd(cursor,this.groupHeightAt(i)),offsets[i]=cursor;const key=this.keyOf(this.itemAt(i),i),token=domKeyToken(key),occurrence=occurrences.get(token)??0;occurrences.set(token,occurrence+1);const identity=this.rowIdentity(key,occurrence);identities[i]=identity;let h;this.fixedRowHeight!=null?h=this.fixedRowHeight:(liveKeys?.add(identity),h=this.measuredHeights.get(identity)??DEFAULT_ROW_ESTIMATE_PX),cursor=finiteAdd(cursor,h)}if(offsets[n]=cursor,this.offsets=offsets,this.rowIdentities=identities,this.itemsChangedPendingPrune=!1,liveKeys){for(const key of this.measuredHeights.keys())liveKeys.has(key)||(this.measuredHeights.delete(key),this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0);for(const key of this.measuredIndices.keys())liveKeys.has(key)||(this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0)}}groupTopAt(index){return Math.max(0,this.offsetAt(index)-this.groupHeightAt(index))}rowBottomAt(index){return finiteAdd(this.offsetAt(index),this.rowHeightAt(index))}entryTopAt(index){return this.groupTopAt(index)}findIndexAtOrAfter(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.floor((hi-lo)/2);this.rowBottomAt(mid)<=offset?lo=mid+1:hi=mid}return lo}findIndexAtOrBefore(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.ceil((hi-lo)/2);this.entryTopAt(mid)<offset?lo=mid:hi=mid-1}return lo}offsetForIndex(index){const clamped=Math.min(this.itemCount,Math.max(0,Math.trunc(index)||0));return this.offsetAt(clamped)}indexAtOffset(px){const n=this.itemCount;return n===0?-1:Number.isFinite(px)?Math.min(n-1,Math.max(0,this.findIndexAtOrAfter(px))):px>0?n-1:0}computeRange(){const n=this.itemCount;if(n===0){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}if(this.viewportHeight<=0){if(!this.renderUnmeasuredWindow){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}this.visibleStart=0,this.visibleEnd=0,this.renderStart=0,this.renderEnd=Math.min(n-1,normalizeOverscan(this.overscan));return}const viewTop=this.containerScrollTop,viewBottom=viewTop+this.viewportHeight;this.visibleStart=this.findIndexAtOrAfter(viewTop),this.visibleEnd=this.findIndexAtOrBefore(viewBottom);const overscan=normalizeOverscan(this.overscan);this.renderStart=Math.max(0,this.visibleStart-overscan),this.renderEnd=Math.min(n-1,this.visibleEnd+overscan),this.pruneIndexedMeasurements()&&this.computeRange()}attachContainerListeners(){const base=this.scrollContainer,ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!base||!this.isConnected||!ownerWindow)return;this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.detachContainerListeners();const external=this.externalScroller,scrollTarget=external??base,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow.ResizeObserver;if(ResizeObserverCtor){const observer=new ResizeObserverCtor(entries=>{if(this.containerResizeObserver!==observer||this.scrollListenerTarget!==scrollTarget||!this.isCurrentOwnerWork(ownerDocument,generation))return;if(this.beginResizeDelivery(),external){this.syncExternalScrollMetrics();return}const entry=entries[0];entry&&(this.viewportHeight=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height)});this.containerResizeObserver=observer,observer.observe(base),external&&!isWindowScroller(external)&&observer.observe(external)}scrollTarget.addEventListener("scroll",this.onScroll,{passive:!0}),scrollTarget.addEventListener("wheel",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("pointerdown",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("touchstart",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("keydown",this.onUserScrollIntent),this.scrollListenerTarget=scrollTarget,external&&isWindowScroller(external)&&(external.addEventListener("resize",this.onExternalViewportResize,{passive:!0}),this.viewportResizeTarget=external),ownerWindow.queueMicrotask(()=>{if(this.scrollListenerTarget!==scrollTarget||this.scrollContainer!==base||!this.isCurrentOwnerWork(ownerDocument,generation))return;const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))})}detachContainerListeners(){const viewportTarget=this.viewportResizeTarget;viewportTarget&&(viewportTarget.removeEventListener("resize",this.onExternalViewportResize),this.viewportResizeTarget=void 0);const target=this.scrollListenerTarget;target&&(target.removeEventListener("scroll",this.onScroll),target.removeEventListener("wheel",this.onUserScrollIntent),target.removeEventListener("pointerdown",this.onUserScrollIntent),target.removeEventListener("touchstart",this.onUserScrollIntent),target.removeEventListener("keydown",this.onUserScrollIntent))}beginResizeDelivery(){if(this.inResizeDelivery=!0,this.rowObserveRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected){this.inResizeDelivery=!1;return}const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(this.rowObserveRafId!==handle||this.rowObserveRafOwner!==ownerWindow||this.rowObserveRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))return;this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.inResizeDelivery=!1;const ro=this.rowResizeObserver;for(const[identity,el]of this.deferredRowObservations)ro&&this.observedRows.get(identity)===el&&ro.observe(el);this.deferredRowObservations.clear();const groupObserver=this.groupResizeObserver;for(const[index,el]of this.deferredGroupObservations)groupObserver&&this.observedGroups.get(index)===el&&groupObserver.observe(el);this.deferredGroupObservations.clear()});this.rowObserveRafId=handle,this.rowObserveRafOwner=ownerWindow,this.rowObserveRafDocument=ownerDocument}syncRowObservers(){const ro=this.rowResizeObserver;if(!ro)return;if(this.fixedRowHeight!=null){for(const el of this.observedRows.values())ro.unobserve(el);this.observedRows.clear(),this.deferredRowObservations.clear();return}const current=new Map;this.renderRoot.querySelectorAll('[part="row"]').forEach(el=>{const index=Number(el.getAttribute("data-row-index"));if(!Number.isInteger(index)||index<0||index>=this.itemCount)return;const identity=this.identityAt(index);current.set(identity,el),this.observedRowKeys.set(el,identity),this.observedRowIndices.set(el,index)});for(const[identity,el]of this.observedRows)current.get(identity)!==el&&(ro.unobserve(el),this.observedRows.delete(identity),this.deferredRowObservations.delete(identity));for(const[identity,el]of current)this.observedRows.has(identity)||(this.observedRows.set(identity,el),this.inResizeDelivery?this.deferredRowObservations.set(identity,el):ro.observe(el))}syncGroupObservers(){const observer=this.groupResizeObserver;if(!observer)return;const current=new Map;this.renderRoot.querySelectorAll('[part="group"][data-group-index]').forEach(marker=>{const index=Number(marker.dataset.groupIndex);!Number.isInteger(index)||!this.normalizedGroupByIndex.has(index)||(current.set(index,marker),this.observedGroupIndices.set(marker,index))});for(const[index,marker]of this.observedGroups)current.get(index)!==marker&&(observer.unobserve(marker),this.observedGroups.delete(index),this.deferredGroupObservations.delete(index));for(const[index,marker]of current)this.observedGroups.has(index)||(this.observedGroups.set(index,marker),this.inResizeDelivery?this.deferredGroupObservations.set(index,marker):observer.observe(marker))}get stickyInset(){return this.renderStickyGroup?this.stickyHeight:0}scrollActiveIntoView(){const index=this.activeIndex;if(index<0)return;const behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":"smooth";this.performScrollTo(index,"auto",behavior)&&this.beginPendingScrollCorrection(index,"auto",behavior,this.activeItemId)}scrollToIndex(index,options){const n=this.itemCount;if(n===0)return;const clamped=finiteInteger(index,0,0,n-1),align=options?.align??"auto",behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":options?.behavior??"smooth";this.performScrollTo(clamped,align,behavior)?this.beginPendingScrollCorrection(clamped,align,behavior):this.pendingScrollCorrection=void 0}hasUnmeasuredGroupThrough(index){return this.normalizedGroups.some(group=>group.startIndex<=index&&group.label!==""&&!this.measuredGroupHeights.has(group.startIndex))}beginPendingScrollCorrection(index,align,behavior,activeItemId){if(this.fixedRowHeight!=null&&!this.hasUnmeasuredGroupThrough(index)){this.pendingScrollCorrection=void 0;return}this.pendingScrollCorrection={identity:this.identityAt(index),index,align,behavior,source:this.effectiveSource,keyFunction:this.keyFunction,activeItemId:activeItemId===""?void 0:activeItemId,lastMeasurementGeneration:this.measurementGeneration}}performScrollTo(index,align,behavior){const metrics=this.readScrollMetrics();if(!metrics)return!1;const inset=this.stickyInset,top=this.offsetAt(index),bottom=this.rowBottomAt(index),viewTop=metrics.rawScrollTop,viewBottom=viewTop+metrics.viewportHeight;let target=null;return align==="start"?target=top-inset:align==="end"?target=bottom-metrics.viewportHeight:top-inset<viewTop?target=top-inset:bottom>viewBottom&&(target=bottom-metrics.viewportHeight),target===null?!1:(this.applyScrollPosition(target,behavior),!0)}maybeCorrectPendingScroll(){const pending=this.pendingScrollCorrection;if(!pending||pending.lastMeasurementGeneration>=this.measurementGeneration)return;if(pending.source!==this.effectiveSource||pending.keyFunction!==this.keyFunction||pending.activeItemId!==void 0&&!Object.is(pending.activeItemId,this.activeItemId)){this.pendingScrollCorrection=void 0;return}const index=pending.activeItemId!==void 0?this.activeIndex:isIndexedSource(this.effectiveSource)?pending.index:this.rowIdentities.indexOf(pending.identity);if(index<0||index>=this.itemCount||this.identityAt(index)!==pending.identity){this.pendingScrollCorrection=void 0;return}this.performScrollTo(index,pending.align,pending.behavior),pending.index=index,pending.lastMeasurementGeneration=this.measurementGeneration,(this.fixedRowHeight!=null||this.measuredHeights.has(pending.identity))&&!this.hasUnmeasuredGroupThrough(index)&&(this.pendingScrollCorrection=void 0)}emitRangeChangeIfNeeded(){if(this.visibleEnd<this.visibleStart){this.lastEmittedStart=-1,this.lastEmittedEnd=-1;return}this.visibleStart===this.lastEmittedStart&&this.visibleEnd===this.lastEmittedEnd||(this.lastEmittedStart=this.visibleStart,this.lastEmittedEnd=this.visibleEnd,this.emit("lr-visible-range-change",{start:this.visibleStart,end:this.visibleEnd}))}maybeFireLoadMore(){const n=this.itemCount;if(!(n>0&&this.visibleEnd>=n-1)){this.loadMoreArmed=!0;return}!this.hasMore||this.loading||!this.loadMoreArmed||(this.loadMoreArmed=!1,this.emit("lr-load-more"))}renderRow(item,index,total,activeIndex){const key=this.keyOf(item,index),top=this.offsetAt(index),isActive=index===activeIndex,isRowMode=this.itemRole==="row";return html`
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{repeat}from"lit/directives/repeat.js";import{styleMap}from"lit/directives/style-map.js";import{LyraElement}from"../../../internal/lyra-element.js";import{prefersReducedMotion}from"../../../internal/motion.js";import{finiteAdd,finiteCount,finiteInteger,finiteNumber}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{getOwnDataDescriptor,MISSING_OWN_DATA_DESCRIPTOR,UNSAFE_OWN_DATA_DESCRIPTOR}from"../../../internal/data-descriptors.js";import{styles}from"./virtual-list.styles.js";const DEFAULT_ROW_ESTIMATE_PX=48,DEFAULT_GROUP_ESTIMATE_PX=32,DEFAULT_OVERSCAN_ROWS=6,MAX_OVERSCAN_ROWS=100,MAX_VIRTUAL_LIST_GROUPS=1e4,EMPTY_VIRTUAL_LIST_GROUPS=Object.freeze([]);function normalizeOverscan(value){if(value===null)return DEFAULT_OVERSCAN_ROWS;const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)?Math.min(MAX_OVERSCAN_ROWS,Math.max(0,Math.floor(numeric))):DEFAULT_OVERSCAN_ROWS}const overscanConverter={fromAttribute(value){return normalizeOverscan(value)}};function virtualListGroupsChanged(value,oldValue){if(value===oldValue)return!1;const next=value,previous=oldValue;if(next==null||previous==null)return next!==previous;if(next.length!==previous.length)return!0;for(let index=0;index<next.length;index+=1){const a=next[index],b=previous[index];if(a.key!==b.key||a.label!==b.label||a.startIndex!==b.startIndex)return!0}return!1}function normalizeRowHeight(value){if(value==="auto")return"auto";const numeric=typeof value=="number"?value:Number(value);return Number.isFinite(numeric)&&numeric>0?numeric:"auto"}const rowHeightConverter={fromAttribute(value){return value===null?"auto":normalizeRowHeight(value)}};function isIndexedSource(source){return!Array.isArray(source)}const ELEMENT_NODE_TYPE=1;function isWindowScroller(target){return target.window===target}function domKeyToken(key){if(typeof key=="number"){if(Number.isNaN(key))return"number:NaN";if(Object.is(key,-0))return"number:-0"}return`${typeof key}:${String(key)}`}class LyraVirtualList extends LyraElement{constructor(){super(...arguments),this.items=[],this.renderItem=()=>nothing,this.rowHeight="auto",this.itemRole="listitem",this.rowIndexOffset=0,this.overscan=DEFAULT_OVERSCAN_ROWS,this.activeItemId="",this.loading=!1,this.hasMore=!1,this.containerScrollTop=0,this.viewportHeight=0,this.renderUnmeasuredWindow=!0,this.offsets=[0],this.rowIdentities=[],this.fixedRowHeight=null,this.measuredHeights=new Map,this.measuredIndices=new Map,this.indexedMeasurementIndices=[],this.indexedMeasurementDeltaPrefix=[0],this.indexedMeasurementIndexDirty=!0,this.offsetsDirty=!0,this.itemsChangedPendingPrune=!1,this.renderStart=0,this.renderEnd=-1,this.visibleStart=0,this.visibleEnd=-1,this.lastEmittedStart=-1,this.lastEmittedEnd=-1,this.loadMoreArmed=!0,this.measurementGeneration=0,this.isFirstUpdate=!0,this.stickyHeight=0,this.observedRows=new Map,this.observedRowKeys=new WeakMap,this.observedRowIndices=new WeakMap,this.observedGroups=new Map,this.observedGroupIndices=new WeakMap,this.externalMetricsPending=!1,this.ownerRealmGeneration=0,this.inResizeDelivery=!1,this.deferredRowObservations=new Map,this.deferredGroupObservations=new Map,this.activeIndexForLength=-1,this.activeIndexForId="",this.activeIndexCache=-1,this.pendingScrollTop=null,this.normalizedGroups=EMPTY_VIRTUAL_LIST_GROUPS,this.normalizedGroupByIndex=new Map,this.measuredGroupHeights=new Map,this.groupHeightPrefix=[0],this.onExternalViewportResize=()=>{this.syncExternalScrollMetrics()},this.onUserScrollIntent=event=>{event instanceof KeyboardEvent&&!new Set(["ArrowUp","ArrowDown","PageUp","PageDown","Home","End"," "]).has(event.key)||(this.pendingScrollCorrection=void 0)},this.onScroll=e=>{if(this.externalScroller?(this.pendingScrollTop=null,this.externalMetricsPending=!0):this.pendingScrollTop=e.currentTarget.scrollTop,this.scrollRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected)return;const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(!(this.scrollRafId!==handle||this.scrollRafOwner!==ownerWindow||this.scrollRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))){if(this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.externalMetricsPending){this.externalMetricsPending=!1;const metrics=this.readScrollMetrics();metrics&&(this.pendingScrollTop=metrics.scrollTop,this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight))}if(this.pendingScrollTop!==null){const scrollTop=this.pendingScrollTop;this.pendingScrollTop=null;const moved=this.containerScrollTop!==scrollTop;this.containerScrollTop=scrollTop,moved&&this.emit("lr-virtual-scroll",{scrollTop,viewportHeight:this.viewportHeight})}}});this.scrollRafId=handle,this.scrollRafOwner=ownerWindow,this.scrollRafDocument=ownerDocument},this.onRowsResized=entries=>{if(this.beginResizeDelivery(),this.fixedRowHeight!=null)return;const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const row=entry.target,key=this.observedRowKeys.get(row),index=this.observedRowIndices.get(row);if(key===void 0||index===void 0)continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height,prev=this.measuredHeights.get(key);if(prev===void 0||Math.abs(prev-height)>.5){const oldBottom=this.rowBottomAt(index);this.measuredHeights.set(key,height),this.measuredIndices.set(key,index);const oldHeight=prev??DEFAULT_ROW_ESTIMATE_PX;oldBottom<=oldScrollTop&&(scrollAdjustment+=height-oldHeight),changed=!0}}if(changed){if(this.indexedMeasurementIndexDirty=!0,base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onGroupsResized=entries=>{this.beginResizeDelivery();const base=this.scrollContainer,oldScrollTop=this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop;let scrollAdjustment=0,changed=!1;for(const entry of entries){const marker=entry.target,index=this.observedGroupIndices.get(marker);if(index===void 0||!this.normalizedGroupByIndex.has(index))continue;const height=entry.borderBoxSize?.[0]?.blockSize??entry.target.getBoundingClientRect().height;if(!Number.isFinite(height)||height<0)continue;const previous=this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX;if(Math.abs(previous-height)<=.5)continue;const oldRowTop=this.offsetAt(index);this.measuredGroupHeights.set(index,height),oldRowTop<=oldScrollTop&&(scrollAdjustment+=height-previous),changed=!0}if(changed){if(base&&scrollAdjustment!==0){const nextScrollTop=oldScrollTop+scrollAdjustment;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}this.offsetsDirty=!0,this.measurementGeneration+=1,this.requestUpdate()}},this.onStickyResized=entries=>{this.beginResizeDelivery();const entry=entries[0];if(!entry)return;const height=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height;Math.abs(this.stickyHeight-height)>.5&&(this.stickyHeight=height)}}static{this.ownedCollectionProperties=Object.freeze(["items","source","groups"])}static{this.identityCollectionProperties=Object.freeze(["items","source"])}static{this.identityCollectionObjectProperties=Object.freeze(["source"])}static{this.styles=[LyraElement.styles,styles]}get scrollContainer(){return this.renderRoot?.querySelector('[part="base"]')??void 0}get renderedRows(){const root=this.renderRoot;return root?[...root.querySelectorAll('[part="row"]')]:[]}get externalScroller(){const target=this.scrollElement;if(target!=null)return isWindowScroller(target)||target.nodeType===ELEMENT_NODE_TYPE?target:void 0}get spacerElement(){return this.renderRoot?.querySelector('[part="spacer"]')??void 0}readScrollMetrics(){const base=this.scrollContainer;if(!base)return null;const external=this.externalScroller;if(!external)return{scrollTop:base.scrollTop,rawScrollTop:base.scrollTop,viewportHeight:base.clientHeight};const spacerTop=(this.spacerElement??base).getBoundingClientRect().top;if(isWindowScroller(external)){const documentHeight=finiteNumber(external.document?.documentElement?.clientHeight??0,0),rawScrollTop2=finiteNumber(-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop2),rawScrollTop:rawScrollTop2,viewportHeight:documentHeight>0?documentHeight:finiteNumber(external.innerHeight,0)}}const scrollerTop=external.getBoundingClientRect().top,rawScrollTop=finiteNumber(scrollerTop-spacerTop,0);return{scrollTop:Math.max(0,rawScrollTop),rawScrollTop,viewportHeight:finiteNumber(external.clientHeight,0)}}applyScrollPosition(top,behavior){const external=this.externalScroller;if(!external){const base=this.scrollContainer;if(!base)return;const next2=Math.max(0,finiteNumber(top,0));behavior===void 0?base.scrollTop=next2:base.scrollTo({top:next2,behavior});return}const metrics=this.readScrollMetrics();if(!metrics)return;const delta=finiteNumber(top,metrics.rawScrollTop)-metrics.rawScrollTop;if(isWindowScroller(external)){const options={top:Math.max(0,finiteNumber(external.scrollY+delta,0))};behavior!==void 0&&(options.behavior=behavior),external.scrollTo(options);return}const next=Math.max(0,finiteNumber(external.scrollTop+delta,0));behavior===void 0?external.scrollTop=next:external.scrollTo({top:next,behavior})}syncExternalScrollMetrics(){const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))}get safeRowIndexOffset(){return finiteCount(this.rowIndexOffset)}computedAriaRowIndex(index){return finiteInteger(finiteAdd(index+1,this.safeRowIndexOffset),1,1,Number.MAX_SAFE_INTEGER)}get activeIndex(){if(this.activeItemId==="")return-1;const source=this.effectiveSource,count=this.itemCount;if(this.activeIndexFor===source&&this.activeIndexForLength===count&&Object.is(this.activeIndexForId,this.activeItemId)&&this.activeIndexForKeyFn===this.keyFunction)return this.activeIndexCache;if(this.activeIndexFor=source,this.activeIndexForLength=count,this.activeIndexForId=this.activeItemId,this.activeIndexForKeyFn=this.keyFunction,this.activeIndexCache=-1,isIndexedSource(source)){if(!this.keyFunction&&source.indexOfKey){const candidate=source.indexOfKey(this.activeItemId);Number.isInteger(candidate)&&candidate>=0&&candidate<count&&(this.activeIndexCache=candidate)}return this.activeIndexCache}for(let index=0;index<count;index++){const item=this.itemAt(index);if(Object.is(this.keyOf(item,index),this.activeItemId)){this.activeIndexCache=index;break}}return this.activeIndexCache}connectedCallback(){super.connectedCallback(),this.ownerDocument.defaultView&&this.seedFirstRenderState(()=>{this.renderUnmeasuredWindow=!1,this.requestUpdate()}),this.resetOwnerRealmWork();const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow?.ResizeObserver;if(ResizeObserverCtor){const rowObserver=new ResizeObserverCtor(entries=>{this.rowResizeObserver!==rowObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onRowsResized(entries)}),groupObserver=new ResizeObserverCtor(entries=>{this.groupResizeObserver!==groupObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onGroupsResized(entries)}),stickyObserver=new ResizeObserverCtor(entries=>{this.stickyResizeObserver!==stickyObserver||!this.isCurrentOwnerWork(ownerDocument,generation)||this.onStickyResized(entries)});this.rowResizeObserver=rowObserver,this.groupResizeObserver=groupObserver,this.stickyResizeObserver=stickyObserver}this.hasUpdated&&(this.attachContainerListeners(),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay())}disconnectedCallback(){this.resetOwnerRealmWork(),super.disconnectedCallback()}adoptedCallback(){super.adoptedCallback(),this.resetOwnerRealmWork()}isCurrentOwnerWork(ownerDocument,generation){return this.ownerRealmGeneration===generation&&this.isConnected&&this.ownerDocument===ownerDocument}resetOwnerRealmWork(){this.ownerRealmGeneration+=1,this.rowResizeObserver?.disconnect(),this.rowResizeObserver=void 0,this.groupResizeObserver?.disconnect(),this.groupResizeObserver=void 0,this.observedRows.clear(),this.observedGroups.clear(),this.deferredRowObservations.clear(),this.deferredGroupObservations.clear(),this.inResizeDelivery=!1,this.rowObserveRafId!==void 0&&this.rowObserveRafOwner?.cancelAnimationFrame(this.rowObserveRafId),this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.stickyResizeObserver?.disconnect(),this.stickyResizeObserver=void 0,this.observedSticky=void 0,this.scrollRafId!==void 0&&this.scrollRafOwner?.cancelAnimationFrame(this.scrollRafId),this.scrollRafId=void 0,this.scrollRafOwner=void 0,this.scrollRafDocument=void 0,this.pendingScrollTop=null,this.externalMetricsPending=!1,this.pendingScrollCorrection=void 0,this.detachContainerListeners(),this.scrollListenerTarget=void 0}firstUpdated(changed){super.firstUpdated(changed),this.attachContainerListeners()}willUpdate(changed){super.willUpdate(changed),this.isFirstUpdate=!this.hasUpdated,(changed.has("items")||changed.has("source")||changed.has("keyFunction")||changed.has("rowHeight")||changed.has("groups")||changed.has("activeItemId")||changed.has("scrollElement"))&&(this.pendingScrollCorrection=void 0),(changed.has("items")||changed.has("source")||changed.has("rowHeight")||changed.has("keyFunction")||changed.has("groups"))&&(this.offsetsDirty=!0),(changed.has("items")||changed.has("source"))&&(this.itemsChangedPendingPrune=!0),(changed.has("keyFunction")||isIndexedSource(this.effectiveSource)&&(changed.has("items")||changed.has("source")))&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0),changed.has("groups")&&this.measuredGroupHeights.clear(),(changed.has("items")||changed.has("source")||changed.has("groups"))&&this.recomputeGroups(),changed.has("rowHeight")&&(this.fixedRowHeight=this.parseRowHeight(this.rowHeight),this.fixedRowHeight!=null&&(this.measuredHeights.clear(),this.measuredIndices.clear(),this.indexedMeasurementIndexDirty=!0)),this.offsetsDirty&&(this.recomputeOffsets(),this.offsetsDirty=!1),this.computeRange()}updated(changed){super.updated(changed),this.syncRowObservers(),this.syncGroupObservers(),this.syncStickyOverlay(),changed.has("scrollElement")&&!this.isFirstUpdate&&this.attachContainerListeners(),changed.has("activeItemId")&&!this.isFirstUpdate&&this.scrollActiveIntoView(),this.emitRangeChangeIfNeeded(),this.maybeFireLoadMore(),this.maybeCorrectPendingScroll()}parseRowHeight(value){const normalized=normalizeRowHeight(value);return normalized==="auto"?null:normalized}get effectiveSource(){return this.source??this.items}get itemCount(){const source=this.effectiveSource;return isIndexedSource(source)?finiteCount(source.count):source.length}itemAt(index){const source=this.effectiveSource;return isIndexedSource(source)?source.itemAt(index):source[index]}keyOf(item,index){const source=this.effectiveSource,key=this.keyFunction?this.keyFunction(item,index):isIndexedSource(source)?source.keyAt?.(index)??index:index;return typeof key=="string"||typeof key=="number"?key:index}rowIdentity(key,occurrence){const token=domKeyToken(key);return`${token.length}:${token}:${occurrence}`}identityAt(index,item=this.itemAt(index)){return isIndexedSource(this.effectiveSource)?this.rowIdentity(this.keyOf(item,index),index):this.rowIdentities[index]??this.rowIdentity(this.keyOf(item,index),index)}groupHeightAt(index){const group=this.normalizedGroupByIndex.get(index);return!group||group.label===""?0:this.measuredGroupHeights.get(index)??DEFAULT_GROUP_ESTIMATE_PX}rowHeightAt(index){return this.fixedRowHeight!=null?this.fixedRowHeight:this.measuredHeights.get(this.identityAt(index))??DEFAULT_ROW_ESTIMATE_PX}groupContributionThrough(index){let low=0,high=this.normalizedGroups.length;for(;low<high;){const middle=low+high>>1;this.normalizedGroups[middle].startIndex<=index?low=middle+1:high=middle}return this.groupHeightPrefix[low]??0}recomputeGroupHeightPrefix(){const prefix=new Array(this.normalizedGroups.length+1);prefix[0]=0;for(let index=0;index<this.normalizedGroups.length;index++){const group=this.normalizedGroups[index],height=group.label===""?0:this.measuredGroupHeights.get(group.startIndex)??DEFAULT_GROUP_ESTIMATE_PX;prefix[index+1]=finiteAdd(prefix[index],height)}this.groupHeightPrefix=prefix}indexedOffsetForIndex(index){const baseHeight=this.fixedRowHeight??DEFAULT_ROW_ESTIMATE_PX;let offset=index>Number.MAX_VALUE/baseHeight?Number.MAX_VALUE:index*baseHeight;if(this.fixedRowHeight==null){this.rebuildIndexedMeasurementIndex();let low=0,high=this.indexedMeasurementIndices.length;for(;low<high;){const middle=low+high>>1;this.indexedMeasurementIndices[middle]<index?low=middle+1:high=middle}offset=finiteAdd(offset,this.indexedMeasurementDeltaPrefix[low]??0)}return Math.max(0,finiteAdd(offset,this.groupContributionThrough(index)))}rebuildIndexedMeasurementIndex(){if(!this.indexedMeasurementIndexDirty)return;const retained=[];for(const[identity,index]of this.measuredIndices){const height=this.measuredHeights.get(identity);height!==void 0&&retained.push({index,delta:height-DEFAULT_ROW_ESTIMATE_PX})}retained.sort((a,b)=>a.index-b.index);const indices=new Array(retained.length),prefix=new Array(retained.length+1);prefix[0]=0;for(let position=0;position<retained.length;position++){const measurement=retained[position];indices[position]=measurement.index,prefix[position+1]=finiteAdd(prefix[position],measurement.delta)}this.indexedMeasurementIndices=indices,this.indexedMeasurementDeltaPrefix=prefix,this.indexedMeasurementIndexDirty=!1}pruneIndexedMeasurements(){if(!isIndexedSource(this.effectiveSource)||this.fixedRowHeight!=null||this.renderEnd<this.renderStart)return!1;const renderedCount=this.renderEnd-this.renderStart+1,retentionRows=Math.max(renderedCount,normalizeOverscan(this.overscan)*4),firstRetained=Math.max(0,this.renderStart-retentionRows),lastRetained=Math.min(this.itemCount-1,this.renderEnd+retentionRows);let removedDeltaBeforeWindow=0,pruned=!1;for(const[identity,measuredIndex]of this.measuredIndices)if(measuredIndex<firstRetained||measuredIndex>lastRetained){const height=this.measuredHeights.get(identity);height!==void 0&&measuredIndex<firstRetained&&(removedDeltaBeforeWindow=finiteAdd(removedDeltaBeforeWindow,height-DEFAULT_ROW_ESTIMATE_PX)),this.measuredIndices.delete(identity),this.measuredHeights.delete(identity),pruned=!0}if(pruned&&(this.indexedMeasurementIndexDirty=!0,removedDeltaBeforeWindow!==0)){const nextScrollTop=(this.readScrollMetrics()?.rawScrollTop??this.containerScrollTop)-removedDeltaBeforeWindow;this.applyScrollPosition(nextScrollTop),this.containerScrollTop=Math.max(0,nextScrollTop),this.pendingScrollTop=null}return pruned}offsetAt(index){return isIndexedSource(this.effectiveSource)?this.indexedOffsetForIndex(index):this.offsets[index]??0}recomputeOffsets(){const n=this.itemCount;if(this.recomputeGroupHeightPrefix(),isIndexedSource(this.effectiveSource)){this.offsets=[0],this.rowIdentities=[],this.itemsChangedPendingPrune=!1;return}const offsets=new Array(n+1);let cursor=0;const liveKeys=this.itemsChangedPendingPrune&&this.fixedRowHeight==null?new Set:null,occurrences=new Map,identities=new Array(n);for(let i=0;i<n;i++){cursor=finiteAdd(cursor,this.groupHeightAt(i)),offsets[i]=cursor;const key=this.keyOf(this.itemAt(i),i),token=domKeyToken(key),occurrence=occurrences.get(token)??0;occurrences.set(token,occurrence+1);const identity=this.rowIdentity(key,occurrence);identities[i]=identity;let h;this.fixedRowHeight!=null?h=this.fixedRowHeight:(liveKeys?.add(identity),h=this.measuredHeights.get(identity)??DEFAULT_ROW_ESTIMATE_PX),cursor=finiteAdd(cursor,h)}if(offsets[n]=cursor,this.offsets=offsets,this.rowIdentities=identities,this.itemsChangedPendingPrune=!1,liveKeys){for(const key of this.measuredHeights.keys())liveKeys.has(key)||(this.measuredHeights.delete(key),this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0);for(const key of this.measuredIndices.keys())liveKeys.has(key)||(this.measuredIndices.delete(key),this.indexedMeasurementIndexDirty=!0)}}groupTopAt(index){return Math.max(0,this.offsetAt(index)-this.groupHeightAt(index))}rowBottomAt(index){return finiteAdd(this.offsetAt(index),this.rowHeightAt(index))}entryTopAt(index){return this.groupTopAt(index)}findIndexAtOrAfter(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.floor((hi-lo)/2);this.rowBottomAt(mid)<=offset?lo=mid+1:hi=mid}return lo}findIndexAtOrBefore(offset){let lo=0,hi=this.itemCount-1;for(;lo<hi;){const mid=lo+Math.ceil((hi-lo)/2);this.entryTopAt(mid)<offset?lo=mid:hi=mid-1}return lo}offsetForIndex(index){const clamped=Math.min(this.itemCount,Math.max(0,Math.trunc(index)||0));return this.offsetAt(clamped)}indexAtOffset(px){const n=this.itemCount;return n===0?-1:Number.isFinite(px)?Math.min(n-1,Math.max(0,this.findIndexAtOrAfter(px))):px>0?n-1:0}computeRange(){const n=this.itemCount;if(n===0){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}if(this.viewportHeight<=0){if(!this.renderUnmeasuredWindow){this.visibleStart=0,this.visibleEnd=-1,this.renderStart=0,this.renderEnd=-1;return}this.visibleStart=0,this.visibleEnd=0,this.renderStart=0,this.renderEnd=Math.min(n-1,normalizeOverscan(this.overscan));return}const viewTop=this.containerScrollTop,viewBottom=viewTop+this.viewportHeight;this.visibleStart=this.findIndexAtOrAfter(viewTop),this.visibleEnd=this.findIndexAtOrBefore(viewBottom);const overscan=normalizeOverscan(this.overscan);this.renderStart=Math.max(0,this.visibleStart-overscan),this.renderEnd=Math.min(n-1,this.visibleEnd+overscan),this.pruneIndexedMeasurements()&&this.computeRange()}attachContainerListeners(){const base=this.scrollContainer,ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!base||!this.isConnected||!ownerWindow)return;this.containerResizeObserver?.disconnect(),this.containerResizeObserver=void 0,this.detachContainerListeners();const external=this.externalScroller,scrollTarget=external??base,generation=this.ownerRealmGeneration,ResizeObserverCtor=ownerWindow.ResizeObserver;if(ResizeObserverCtor){const observer=new ResizeObserverCtor(entries=>{if(this.containerResizeObserver!==observer||this.scrollListenerTarget!==scrollTarget||!this.isCurrentOwnerWork(ownerDocument,generation))return;if(this.beginResizeDelivery(),external){this.syncExternalScrollMetrics();return}const entry=entries[0];entry&&(this.viewportHeight=entry.borderBoxSize?.[0]?.blockSize??entry.contentRect.height)});this.containerResizeObserver=observer,observer.observe(base),external&&!isWindowScroller(external)&&observer.observe(external)}scrollTarget.addEventListener("scroll",this.onScroll,{passive:!0}),scrollTarget.addEventListener("wheel",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("pointerdown",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("touchstart",this.onUserScrollIntent,{passive:!0}),scrollTarget.addEventListener("keydown",this.onUserScrollIntent),this.scrollListenerTarget=scrollTarget,external&&isWindowScroller(external)&&(external.addEventListener("resize",this.onExternalViewportResize,{passive:!0}),this.viewportResizeTarget=external),ownerWindow.queueMicrotask(()=>{if(this.scrollListenerTarget!==scrollTarget||this.scrollContainer!==base||!this.isCurrentOwnerWork(ownerDocument,generation))return;const metrics=this.readScrollMetrics();metrics&&(this.viewportHeight!==metrics.viewportHeight&&(this.viewportHeight=metrics.viewportHeight),this.containerScrollTop!==metrics.scrollTop&&(this.containerScrollTop=metrics.scrollTop))})}detachContainerListeners(){const viewportTarget=this.viewportResizeTarget;viewportTarget&&(viewportTarget.removeEventListener("resize",this.onExternalViewportResize),this.viewportResizeTarget=void 0);const target=this.scrollListenerTarget;target&&(target.removeEventListener("scroll",this.onScroll),target.removeEventListener("wheel",this.onUserScrollIntent),target.removeEventListener("pointerdown",this.onUserScrollIntent),target.removeEventListener("touchstart",this.onUserScrollIntent),target.removeEventListener("keydown",this.onUserScrollIntent))}beginResizeDelivery(){if(this.inResizeDelivery=!0,this.rowObserveRafId!==void 0)return;const ownerDocument=this.ownerDocument,ownerWindow=ownerDocument.defaultView;if(!ownerWindow||!this.isConnected){this.inResizeDelivery=!1;return}const generation=this.ownerRealmGeneration,handle=ownerWindow.requestAnimationFrame(()=>{if(this.rowObserveRafId!==handle||this.rowObserveRafOwner!==ownerWindow||this.rowObserveRafDocument!==ownerDocument||!this.isCurrentOwnerWork(ownerDocument,generation))return;this.rowObserveRafId=void 0,this.rowObserveRafOwner=void 0,this.rowObserveRafDocument=void 0,this.inResizeDelivery=!1;const ro=this.rowResizeObserver;for(const[identity,el]of this.deferredRowObservations)ro&&this.observedRows.get(identity)===el&&ro.observe(el);this.deferredRowObservations.clear();const groupObserver=this.groupResizeObserver;for(const[index,el]of this.deferredGroupObservations)groupObserver&&this.observedGroups.get(index)===el&&groupObserver.observe(el);this.deferredGroupObservations.clear()});this.rowObserveRafId=handle,this.rowObserveRafOwner=ownerWindow,this.rowObserveRafDocument=ownerDocument}syncRowObservers(){const ro=this.rowResizeObserver;if(!ro)return;if(this.fixedRowHeight!=null){for(const el of this.observedRows.values())ro.unobserve(el);this.observedRows.clear(),this.deferredRowObservations.clear();return}const current=new Map;this.renderRoot.querySelectorAll('[part="row"]').forEach(el=>{const index=Number(el.getAttribute("data-row-index"));if(!Number.isInteger(index)||index<0||index>=this.itemCount)return;const identity=this.identityAt(index);current.set(identity,el),this.observedRowKeys.set(el,identity),this.observedRowIndices.set(el,index)});for(const[identity,el]of this.observedRows)current.get(identity)!==el&&(ro.unobserve(el),this.observedRows.delete(identity),this.deferredRowObservations.delete(identity));for(const[identity,el]of current)this.observedRows.has(identity)||(this.observedRows.set(identity,el),this.inResizeDelivery?this.deferredRowObservations.set(identity,el):ro.observe(el))}syncGroupObservers(){const observer=this.groupResizeObserver;if(!observer)return;const current=new Map;this.renderRoot.querySelectorAll('[part="group"][data-group-index]').forEach(marker=>{const index=Number(marker.dataset.groupIndex);!Number.isInteger(index)||!this.normalizedGroupByIndex.has(index)||(current.set(index,marker),this.observedGroupIndices.set(marker,index))});for(const[index,marker]of this.observedGroups)current.get(index)!==marker&&(observer.unobserve(marker),this.observedGroups.delete(index),this.deferredGroupObservations.delete(index));for(const[index,marker]of current)this.observedGroups.has(index)||(this.observedGroups.set(index,marker),this.inResizeDelivery?this.deferredGroupObservations.set(index,marker):observer.observe(marker))}get stickyInset(){return this.renderStickyGroup?this.stickyHeight:0}scrollActiveIntoView(){const index=this.activeIndex;if(index<0)return;const behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":"smooth";this.performScrollTo(index,"auto",behavior)&&this.beginPendingScrollCorrection(index,"auto",behavior,this.activeItemId)}scrollToIndex(index,options){const n=this.itemCount;if(n===0)return;const clamped=finiteInteger(index,0,0,n-1),align=options?.align??"auto",behavior=prefersReducedMotion(this.ownerDocument.defaultView)?"auto":options?.behavior??"smooth";this.performScrollTo(clamped,align,behavior)?this.beginPendingScrollCorrection(clamped,align,behavior):this.pendingScrollCorrection=void 0}hasUnmeasuredGroupThrough(index){return this.normalizedGroups.some(group=>group.startIndex<=index&&group.label!==""&&!this.measuredGroupHeights.has(group.startIndex))}beginPendingScrollCorrection(index,align,behavior,activeItemId){if(this.fixedRowHeight!=null&&!this.hasUnmeasuredGroupThrough(index)){this.pendingScrollCorrection=void 0;return}this.pendingScrollCorrection={identity:this.identityAt(index),index,align,behavior,source:this.effectiveSource,keyFunction:this.keyFunction,activeItemId:activeItemId===""?void 0:activeItemId,lastMeasurementGeneration:this.measurementGeneration}}performScrollTo(index,align,behavior){const metrics=this.readScrollMetrics();if(!metrics)return!1;const inset=this.stickyInset,top=this.offsetAt(index),bottom=this.rowBottomAt(index),viewTop=metrics.rawScrollTop,viewBottom=viewTop+metrics.viewportHeight;let target=null;return align==="start"?target=top-inset:align==="end"?target=bottom-metrics.viewportHeight:top-inset<viewTop?target=top-inset:bottom>viewBottom&&(target=bottom-metrics.viewportHeight),target===null?!1:(this.applyScrollPosition(target,behavior),!0)}maybeCorrectPendingScroll(){const pending=this.pendingScrollCorrection;if(!pending||pending.lastMeasurementGeneration>=this.measurementGeneration)return;if(pending.source!==this.effectiveSource||pending.keyFunction!==this.keyFunction||pending.activeItemId!==void 0&&!Object.is(pending.activeItemId,this.activeItemId)){this.pendingScrollCorrection=void 0;return}const index=pending.activeItemId!==void 0?this.activeIndex:isIndexedSource(this.effectiveSource)?pending.index:this.rowIdentities.indexOf(pending.identity);if(index<0||index>=this.itemCount||this.identityAt(index)!==pending.identity){this.pendingScrollCorrection=void 0;return}this.performScrollTo(index,pending.align,pending.behavior),pending.index=index,pending.lastMeasurementGeneration=this.measurementGeneration,(this.fixedRowHeight!=null||this.measuredHeights.has(pending.identity))&&!this.hasUnmeasuredGroupThrough(index)&&(this.pendingScrollCorrection=void 0)}emitRangeChangeIfNeeded(){if(this.visibleEnd<this.visibleStart){this.lastEmittedStart=-1,this.lastEmittedEnd=-1;return}this.visibleStart===this.lastEmittedStart&&this.visibleEnd===this.lastEmittedEnd||(this.lastEmittedStart=this.visibleStart,this.lastEmittedEnd=this.visibleEnd,this.emit("lr-visible-range-change",{start:this.visibleStart,end:this.visibleEnd}))}maybeFireLoadMore(){const n=this.itemCount;if(!(n>0&&this.visibleEnd>=n-1)){this.loadMoreArmed=!0;return}!this.hasMore||this.loading||!this.loadMoreArmed||(this.loadMoreArmed=!1,this.emit("lr-load-more"))}renderRow(item,index,total,activeIndex){const key=this.keyOf(item,index),top=this.offsetAt(index),isActive=index===activeIndex,isRowMode=this.itemRole==="row";return html`
2
2
  <div
3
3
  part="row"
4
4
  role=${isRowMode?"row":"listitem"}
@@ -1 +1 @@
1
- import{css}from"lit";const styles=css`:host{display:contents}[part=hidden-input]{display:none}:host{--_lr-attachment-trigger-fill:transparent;--_lr-attachment-trigger-on-fill:var(--lr-color-text-quiet);--_lr-attachment-trigger-edge:0;--_lr-attachment-trigger-bg:var(--lr-icon-button-background,var(--_lr-attachment-trigger-fill));--_lr-attachment-trigger-bg-hover:var(--lr-icon-button-background-hover,color-mix(in oklab, var(--_lr-attachment-trigger-fill), var(--lr-color-mix-partner) var(--lr-color-mix-hover)));--_lr-attachment-trigger-bg-active:var(--lr-icon-button-background-active,color-mix(in oklab, var(--_lr-attachment-trigger-fill), var(--lr-color-mix-partner) var(--lr-color-mix-active)));--_lr-attachment-trigger-color:var(--lr-icon-button-color,var(--_lr-attachment-trigger-on-fill));--_lr-attachment-trigger-color-hover:var(--lr-icon-button-color-hover,var(--_lr-attachment-trigger-on-fill));--_lr-attachment-trigger-color-active:var(--lr-icon-button-color-active,var(--lr-icon-button-color-hover,var(--_lr-attachment-trigger-on-fill)));--_lr-attachment-trigger-border:var(--lr-icon-button-border,var(--_lr-attachment-trigger-edge));--_lr-attachment-trigger-radius:var(--lr-icon-button-radius,calc(var(--lr-radius) * .6));--_lr-attachment-trigger-font-size:var(--lr-font-size-lg)}:host([appearance=filled]){--_lr-attachment-trigger-fill:var(--lr-color-neutral-fill-quiet);--_lr-attachment-trigger-on-fill:var(--lr-color-neutral-on-quiet)}:host([appearance=accent]){--_lr-attachment-trigger-fill:var(--lr-color-neutral-fill-loud);--_lr-attachment-trigger-on-fill:var(--lr-color-neutral-on-loud)}:host([appearance=outlined]){--_lr-attachment-trigger-edge:var(--lr-border-width-thin) solid var(--lr-color-neutral-border-loud)}:host([appearance=filled-outlined]){--_lr-attachment-trigger-fill:var(--lr-color-neutral-fill-quiet);--_lr-attachment-trigger-on-fill:var(--lr-color-neutral-on-quiet);--_lr-attachment-trigger-edge:var(--lr-border-width-thin) solid var(--lr-color-neutral-border-loud)}:host([size="2xs"]),:host([size=xs]),:host([size=s]),:host([size=small]),:host([size=m]),:host([size=medium]),:host([size=l]),:host([size=large]),:host([size=xl]){--_lr-attachment-trigger-font-size:var(--lr-form-control-font-size)}:host([size=m]),:host([size=medium]){--_lr-attachment-trigger-font-size:var(--lr-font-size-lg)}.trigger-button{line-height:var(--lr-line-height-none);--lr-icon-button-background:var(--_lr-attachment-trigger-bg);--lr-icon-button-background-hover:var(--_lr-attachment-trigger-bg-hover);--lr-icon-button-background-active:var(--_lr-attachment-trigger-bg-active);--lr-icon-button-color:var(--_lr-attachment-trigger-color);--lr-icon-button-color-hover:var(--_lr-attachment-trigger-color-hover);--lr-icon-button-color-active:var(--_lr-attachment-trigger-color-active);--lr-icon-button-border:var(--_lr-attachment-trigger-border);--lr-icon-button-radius:var(--_lr-attachment-trigger-radius);font-size:var(--_lr-attachment-trigger-font-size);flex:none}.trigger-button svg{display:block}[part=menu-trigger]::part(button){gap:var(--lr-space-xs)}[part=expand-icon]{font-size:var(--lr-size-0-75em);flex:none;display:inline-flex}[part=expand-icon] svg{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){.trigger-button::part(button){transition:none!important}}`;export{styles};
1
+ import{css}from"lit";const styles=css`:host{display:contents}[part=hidden-input]{display:none}:host{--_lr-attachment-trigger-fill:transparent;--_lr-attachment-trigger-on-fill:var(--lr-color-text-quiet);--_lr-attachment-trigger-edge:0;--_lr-attachment-trigger-bg:var(--_lr-attachment-trigger-fill);--_lr-attachment-trigger-bg-hover:color-mix(in oklab, var(--_lr-attachment-trigger-fill), var(--lr-color-mix-partner) var(--lr-color-mix-hover));--_lr-attachment-trigger-bg-active:color-mix(in oklab, var(--_lr-attachment-trigger-fill), var(--lr-color-mix-partner) var(--lr-color-mix-active));--_lr-attachment-trigger-color:var(--_lr-attachment-trigger-on-fill);--_lr-attachment-trigger-color-hover:var(--_lr-attachment-trigger-on-fill);--_lr-attachment-trigger-color-active:var(--lr-icon-button-color-hover,var(--_lr-attachment-trigger-on-fill));--_lr-attachment-trigger-border:var(--_lr-attachment-trigger-edge);--_lr-attachment-trigger-radius:calc(var(--lr-radius) * .6);--_lr-attachment-trigger-font-size:var(--lr-font-size-lg)}:host([appearance=filled]){--_lr-attachment-trigger-fill:var(--lr-color-neutral-fill-quiet);--_lr-attachment-trigger-on-fill:var(--lr-color-neutral-on-quiet)}:host([appearance=accent]){--_lr-attachment-trigger-fill:var(--lr-color-neutral-fill-loud);--_lr-attachment-trigger-on-fill:var(--lr-color-neutral-on-loud)}:host([appearance=outlined]){--_lr-attachment-trigger-edge:var(--lr-border-width-thin) solid var(--lr-color-neutral-border-loud)}:host([appearance=filled-outlined]){--_lr-attachment-trigger-fill:var(--lr-color-neutral-fill-quiet);--_lr-attachment-trigger-on-fill:var(--lr-color-neutral-on-quiet);--_lr-attachment-trigger-edge:var(--lr-border-width-thin) solid var(--lr-color-neutral-border-loud)}:host([size="2xs"]),:host([size=xs]),:host([size=s]),:host([size=small]),:host([size=m]),:host([size=medium]),:host([size=l]),:host([size=large]),:host([size=xl]){--_lr-attachment-trigger-font-size:var(--lr-form-control-font-size)}:host([size=m]),:host([size=medium]){--_lr-attachment-trigger-font-size:var(--lr-font-size-lg)}.trigger-button{line-height:var(--lr-line-height-none);--_lr-icon-button-background-default:var(--_lr-attachment-trigger-bg);--_lr-icon-button-background-hover-default:var(--_lr-attachment-trigger-bg-hover);--_lr-icon-button-background-active-default:var(--_lr-attachment-trigger-bg-active);--_lr-icon-button-color-default:var(--_lr-attachment-trigger-color);--_lr-icon-button-color-hover-default:var(--_lr-attachment-trigger-color-hover);--_lr-icon-button-color-active-default:var(--_lr-attachment-trigger-color-active);--_lr-icon-button-border-default:var(--_lr-attachment-trigger-border);--_lr-icon-button-radius-default:var(--_lr-attachment-trigger-radius);font-size:var(--_lr-attachment-trigger-font-size);flex:none}.trigger-button svg{display:block}[part=menu-trigger]::part(button){gap:var(--lr-space-xs)}[part=expand-icon]{font-size:var(--lr-size-0-75em);flex:none;display:inline-flex}[part=expand-icon] svg{transform:rotate(90deg)}@media (prefers-reduced-motion:reduce){.trigger-button::part(button){transition:none!important}}`;export{styles};
@@ -78,4 +78,15 @@ variant:LyraVariant;
78
78
  /** The group's own accessible name (`role="group"`'s `aria-label`). A host-level `aria-label`
79
79
  * wins if both are set. Unset (the default) renders no `aria-label` at all — a screen reader
80
80
  * announces "group" with no name, then reads each avatar's own accessible name in turn. */
81
- label:string;private eligibleAvatarCount;private overflowHiddenAvatars;private assignedAvatars;private observedAvatars;private avatarObserver?;private avatarObserverWindow?;private readonly defaultOwnership;private readonly pendingOwnedAttributeWrites;protected willUpdate(changed:PropertyValues<this>):void;connectedCallback():void;protected updated(changed:PropertyValues):void;disconnectedCallback():void;adoptedCallback():void;private get hasOverflow();private get hiddenCount();private isAvatar;private sameAvatars;private reconcileAvatars;private recomputeWindow;private connectAvatarObserver;private disconnectAvatarObserver;private markOwnedAttributeWrite;private consumeOwnedAttributeWrite;private applyGroupDefaults;private applyVisibilityMarkers;private restoreAvatarState;private restoreOwnedState;private onSlotChange;private onOverflowClick;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-avatar-group':LyraAvatarGroup;}}
81
+ label:string;private eligibleAvatarCount;private overflowHiddenAvatars;private avatarsSlot?;private assignedAvatars;private observedAvatars;private avatarObserver?;private avatarObserverWindow?;private readonly defaultOwnership;private readonly pendingOwnedAttributeWrites;protected willUpdate(changed:PropertyValues<this>):void;protected firstUpdated(changed:PropertyValues):void;connectedCallback():void;protected updated(changed:PropertyValues):void;disconnectedCallback():void;adoptedCallback():void;private get hasOverflow();private get hiddenCount();private isAvatar;private sameAvatars;private reconcileAvatars;private recomputeWindow;private connectAvatarObserver;private disconnectAvatarObserver;private markOwnedAttributeWrite;private consumeOwnedAttributeWrite;private applyGroupDefaults;private applyVisibilityMarkers;private restoreAvatarState;private restoreOwnedState;private onSlotChange;
82
+ /**
83
+ * Reads the default slot's currently assigned children (flattened through any forwarding
84
+ * `<slot>`) and reconciles the avatar list -- wired as the `slotchange` handler (via
85
+ * `onSlotChange`) for every later mutation, and called once more from `firstUpdated()` (see
86
+ * `collectInitialSlotAssignment`) to cover a slot-forwarding host, or an environment, where the
87
+ * default slot's initial assignment never fires `slotchange`. `reconcileAvatars()` is already
88
+ * idempotent over an unchanged assigned-element set (it diffs by identity and guards every
89
+ * `@state` write with an equality check), so a real browser firing both this and the following
90
+ * genuine `slotchange` contributes no duplicate side effect.
91
+ */
92
+ private onSlotChangeFromSlot;private onOverflowClick;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-avatar-group':LyraAvatarGroup;}}
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{hostAriaLabel}from"../../../internal/a11y.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{LyraElement}from"../../../internal/lyra-element.js";import{finiteCount}from"../../../internal/numbers.js";import{tag}from"../../../internal/prefix.js";import{styles}from"./avatar-group.styles.js";import{LYRA_DEFAULT_showMoreCollapsed,LYRA_DEFAULT_showMoreCount}from"../../../internal/default-strings.generated.js";class LyraAvatarGroup extends LyraElement{constructor(){super(...arguments),this.size="medium",this.shape="circle",this.variant="neutral",this.label="",this.eligibleAvatarCount=0,this.overflowHiddenAvatars=Object.freeze([]),this.assignedAvatars=Object.freeze([]),this.observedAvatars=Object.freeze([]),this.defaultOwnership=new Map,this.pendingOwnedAttributeWrites=new WeakMap,this.onSlotChange=e=>{const slot=e.target;this.updateBrowserDerivedState(()=>{this.isConnected&&this.reconcileAvatars(slot.assignedElements({flatten:!0}))})},this.onOverflowClick=()=>{const hiddenAvatars=Object.freeze([...this.overflowHiddenAvatars]);this.emit("lr-overflow-click",Object.freeze({hiddenCount:hiddenAvatars.length,hiddenAvatars}))}}static{this.defaultStrings={...super.defaultStrings,showMoreCollapsed:LYRA_DEFAULT_showMoreCollapsed,showMoreCount:LYRA_DEFAULT_showMoreCount}}static{this.immutableEventDetails=Object.freeze(["lr-overflow-click"])}static{this.identityEventDetailProperties=Object.freeze({"lr-overflow-click":Object.freeze(["hiddenAvatars"])})}static{this.styles=[LyraElement.styles,styles]}get max(){return this._max}set max(next){const old=this._max;this._max=next==null?void 0:finiteCount(next),this.requestUpdate("max",old)}willUpdate(changed){super.willUpdate(changed),changed.has("size")&&this.size!=="2xs"&&this.size!=="xs"&&this.size!=="s"&&this.size!=="m"&&this.size!=="l"&&this.size!=="xl"&&this.size!=="small"&&this.size!=="medium"&&this.size!=="large"&&(this.size="medium"),changed.has("shape")&&this.shape!=="circle"&&this.shape!=="rounded"&&this.shape!=="square"&&(this.shape="circle"),changed.has("variant")&&this.variant!=="neutral"&&this.variant!=="brand"&&this.variant!=="success"&&this.variant!=="warning"&&this.variant!=="danger"&&(this.variant="neutral"),this.hasUpdated?changed.has("max")&&this.recomputeWindow():this.seedFirstRenderState(()=>{this.assignedAvatars=Object.freeze(Array.from(this.children).filter(element=>this.isAvatar(element))),this.recomputeWindow()})}connectedCallback(){if(super.connectedCallback(),!this.hasUpdated)return;const slot=this.renderRoot.querySelector("slot");slot?.localName==="slot"&&this.reconcileAvatars(slot.assignedElements({flatten:!0}))}updated(changed){super.updated(changed),this.connectAvatarObserver(this.assignedAvatars),this.applyGroupDefaults(),this.applyVisibilityMarkers()}disconnectedCallback(){this.disconnectAvatarObserver(),this.restoreOwnedState(),super.disconnectedCallback()}adoptedCallback(){if(super.adoptedCallback(),this.disconnectAvatarObserver(),!this.isConnected)return;const slot=this.renderRoot.querySelector("slot");slot?.localName==="slot"&&this.reconcileAvatars(slot.assignedElements({flatten:!0}))}get hasOverflow(){const max=this.max;return max!=null&&this.eligibleAvatarCount>max}get hiddenCount(){return this.overflowHiddenAvatars.length}isAvatar(element){return element.localName===tag("avatar")}sameAvatars(a,b){return a.length===b.length&&a.every((avatar,index)=>avatar===b[index])}reconcileAvatars(elements){if(!this.isConnected)return;const next=Object.freeze(elements.filter(element=>this.isAvatar(element))),nextSet=new Set(next);for(const avatar of this.assignedAvatars)nextSet.has(avatar)||this.restoreAvatarState(avatar);this.assignedAvatars=next,this.connectAvatarObserver(next),this.applyGroupDefaults(),this.recomputeWindow(),this.applyVisibilityMarkers()}recomputeWindow(){const eligible=this.assignedAvatars.filter(avatar=>!avatar.hasAttribute("hidden")&&!avatar.hasAttribute("inert")),hidden=this.max==null?[]:eligible.slice(this.max);this.eligibleAvatarCount!==eligible.length&&(this.eligibleAvatarCount=eligible.length),this.sameAvatars(this.overflowHiddenAvatars,hidden)||(this.overflowHiddenAvatars=Object.freeze([...hidden]))}connectAvatarObserver(avatars){const ownerWindow=this.ownerDocument.defaultView;if(!ownerWindow||!!this.sameAvatars(this.observedAvatars,avatars)&&this.avatarObserverWindow===ownerWindow&&this.avatarObserver)return;this.disconnectAvatarObserver(),this.observedAvatars=Object.freeze([...avatars]),this.avatarObserverWindow=ownerWindow;const observer=new ownerWindow.MutationObserver(records=>{if(!(this.avatarObserver!==observer||!this.isConnected||this.ownerDocument.defaultView!==ownerWindow)){for(const record of records){const attribute=record.attributeName;if(!attribute||attribute!=="size"&&attribute!=="shape"&&attribute!=="variant"||!this.isAvatar(record.target))continue;const avatar=record.target;if(this.consumeOwnedAttributeWrite(avatar,attribute))continue;const ownership=this.defaultOwnership.get(avatar);ownership?.delete(attribute),ownership?.size===0&&this.defaultOwnership.delete(avatar)}this.applyGroupDefaults(),this.recomputeWindow(),this.applyVisibilityMarkers()}});this.avatarObserver=observer;for(const avatar of avatars)observer.observe(avatar,{attributes:!0,attributeFilter:["hidden","inert","size","shape","variant"]})}disconnectAvatarObserver(){this.avatarObserver?.disconnect();for(const avatar of this.observedAvatars)this.pendingOwnedAttributeWrites.delete(avatar);this.avatarObserver=void 0,this.avatarObserverWindow=void 0,this.observedAvatars=Object.freeze([])}markOwnedAttributeWrite(avatar,attribute){if(!this.avatarObserver||!this.observedAvatars.includes(avatar))return;let writes=this.pendingOwnedAttributeWrites.get(avatar);writes||(writes=new Map,this.pendingOwnedAttributeWrites.set(avatar,writes)),writes.set(attribute,(writes.get(attribute)??0)+1)}consumeOwnedAttributeWrite(avatar,attribute){const writes=this.pendingOwnedAttributeWrites.get(avatar),count=writes?.get(attribute)??0;return count===0?!1:(count===1?writes.delete(attribute):writes.set(attribute,count-1),writes.size===0&&this.pendingOwnedAttributeWrites.delete(avatar),!0)}applyGroupDefaults(){const values={size:this.size,shape:this.shape,variant:this.variant};for(const avatar of this.assignedAvatars){let ownership=this.defaultOwnership.get(avatar);for(const attribute of["size","shape","variant"]){const applied=ownership?.get(attribute);applied!=null&&avatar.getAttribute(attribute)!==applied&&ownership.delete(attribute),avatar.hasAttribute(attribute)?ownership?.has(attribute)&&avatar.getAttribute(attribute)===applied&&applied!==values[attribute]&&(ownership.set(attribute,values[attribute]),this.markOwnedAttributeWrite(avatar,attribute),avatar.setAttribute(attribute,values[attribute])):(ownership??=new Map,ownership.set(attribute,values[attribute]),this.markOwnedAttributeWrite(avatar,attribute),avatar.setAttribute(attribute,values[attribute]))}ownership?.size?this.defaultOwnership.set(avatar,ownership):this.defaultOwnership.delete(avatar)}}applyVisibilityMarkers(){const hidden=new Set(this.overflowHiddenAvatars),firstVisible=this.assignedAvatars.find(avatar=>!avatar.hasAttribute("hidden")&&!avatar.hasAttribute("inert")&&!hidden.has(avatar));for(const avatar of this.assignedAvatars)hidden.has(avatar)?avatar.setAttribute("data-lr-avatar-group-hidden",""):avatar.removeAttribute("data-lr-avatar-group-hidden"),avatar===firstVisible?avatar.setAttribute("data-lr-avatar-group-first",""):avatar.removeAttribute("data-lr-avatar-group-first")}restoreAvatarState(avatar){avatar.removeAttribute("data-lr-avatar-group-hidden"),avatar.removeAttribute("data-lr-avatar-group-first");const ownership=this.defaultOwnership.get(avatar);if(ownership){for(const[attribute,applied]of ownership)avatar.getAttribute(attribute)===applied&&avatar.removeAttribute(attribute);this.defaultOwnership.delete(avatar)}}restoreOwnedState(){for(const avatar of this.assignedAvatars)this.restoreAvatarState(avatar);this.assignedAvatars=Object.freeze([]),this.overflowHiddenAvatars=Object.freeze([]),this.eligibleAvatarCount=0}render(){const overflowing=this.hasOverflow,hiddenCount=this.hiddenCount,badgeIsFirstVisible=overflowing&&hiddenCount===this.eligibleAvatarCount,accessibleLabel=hostAriaLabel(this)??(this.label||nothing),localizedHiddenCount=getNumberFormat(this.effectiveLocale).format(hiddenCount);return html`
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,query,state}from"lit/decorators.js";import{hostAriaLabel}from"../../../internal/a11y.js";import{collectInitialSlotAssignment}from"../../../internal/initial-slot-collection.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{LyraElement}from"../../../internal/lyra-element.js";import{finiteCount}from"../../../internal/numbers.js";import{tag}from"../../../internal/prefix.js";import{styles}from"./avatar-group.styles.js";import{LYRA_DEFAULT_showMoreCollapsed,LYRA_DEFAULT_showMoreCount}from"../../../internal/default-strings.generated.js";class LyraAvatarGroup extends LyraElement{constructor(){super(...arguments),this.size="medium",this.shape="circle",this.variant="neutral",this.label="",this.eligibleAvatarCount=0,this.overflowHiddenAvatars=Object.freeze([]),this.assignedAvatars=Object.freeze([]),this.observedAvatars=Object.freeze([]),this.defaultOwnership=new Map,this.pendingOwnedAttributeWrites=new WeakMap,this.onSlotChange=e=>{this.onSlotChangeFromSlot(e.target)},this.onOverflowClick=()=>{const hiddenAvatars=Object.freeze([...this.overflowHiddenAvatars]);this.emit("lr-overflow-click",Object.freeze({hiddenCount:hiddenAvatars.length,hiddenAvatars}))}}static{this.defaultStrings={...super.defaultStrings,showMoreCollapsed:LYRA_DEFAULT_showMoreCollapsed,showMoreCount:LYRA_DEFAULT_showMoreCount}}static{this.immutableEventDetails=Object.freeze(["lr-overflow-click"])}static{this.identityEventDetailProperties=Object.freeze({"lr-overflow-click":Object.freeze(["hiddenAvatars"])})}static{this.styles=[LyraElement.styles,styles]}get max(){return this._max}set max(next){const old=this._max;this._max=next==null?void 0:finiteCount(next),this.requestUpdate("max",old)}willUpdate(changed){super.willUpdate(changed),changed.has("size")&&this.size!=="2xs"&&this.size!=="xs"&&this.size!=="s"&&this.size!=="m"&&this.size!=="l"&&this.size!=="xl"&&this.size!=="small"&&this.size!=="medium"&&this.size!=="large"&&(this.size="medium"),changed.has("shape")&&this.shape!=="circle"&&this.shape!=="rounded"&&this.shape!=="square"&&(this.shape="circle"),changed.has("variant")&&this.variant!=="neutral"&&this.variant!=="brand"&&this.variant!=="success"&&this.variant!=="warning"&&this.variant!=="danger"&&(this.variant="neutral"),this.hasUpdated?changed.has("max")&&this.recomputeWindow():this.seedFirstRenderState(()=>{this.assignedAvatars=Object.freeze(Array.from(this.children).filter(element=>this.isAvatar(element))),this.recomputeWindow()})}firstUpdated(changed){super.firstUpdated(changed);const slot=this.avatarsSlot;queueMicrotask(()=>{collectInitialSlotAssignment(slot,s=>this.onSlotChangeFromSlot(s))})}connectedCallback(){if(super.connectedCallback(),!this.hasUpdated)return;const slot=this.renderRoot.querySelector("slot");slot?.localName==="slot"&&this.reconcileAvatars(slot.assignedElements({flatten:!0}))}updated(changed){super.updated(changed),this.connectAvatarObserver(this.assignedAvatars),this.applyGroupDefaults(),this.applyVisibilityMarkers()}disconnectedCallback(){this.disconnectAvatarObserver(),this.restoreOwnedState(),super.disconnectedCallback()}adoptedCallback(){if(super.adoptedCallback(),this.disconnectAvatarObserver(),!this.isConnected)return;const slot=this.renderRoot.querySelector("slot");slot?.localName==="slot"&&this.reconcileAvatars(slot.assignedElements({flatten:!0}))}get hasOverflow(){const max=this.max;return max!=null&&this.eligibleAvatarCount>max}get hiddenCount(){return this.overflowHiddenAvatars.length}isAvatar(element){return element.localName===tag("avatar")}sameAvatars(a,b){return a.length===b.length&&a.every((avatar,index)=>avatar===b[index])}reconcileAvatars(elements){if(!this.isConnected)return;const next=Object.freeze(elements.filter(element=>this.isAvatar(element))),nextSet=new Set(next);for(const avatar of this.assignedAvatars)nextSet.has(avatar)||this.restoreAvatarState(avatar);this.assignedAvatars=next,this.connectAvatarObserver(next),this.applyGroupDefaults(),this.recomputeWindow(),this.applyVisibilityMarkers()}recomputeWindow(){const eligible=this.assignedAvatars.filter(avatar=>!avatar.hasAttribute("hidden")&&!avatar.hasAttribute("inert")),hidden=this.max==null?[]:eligible.slice(this.max);this.eligibleAvatarCount!==eligible.length&&(this.eligibleAvatarCount=eligible.length),this.sameAvatars(this.overflowHiddenAvatars,hidden)||(this.overflowHiddenAvatars=Object.freeze([...hidden]))}connectAvatarObserver(avatars){const ownerWindow=this.ownerDocument.defaultView;if(!ownerWindow||!!this.sameAvatars(this.observedAvatars,avatars)&&this.avatarObserverWindow===ownerWindow&&this.avatarObserver)return;this.disconnectAvatarObserver(),this.observedAvatars=Object.freeze([...avatars]),this.avatarObserverWindow=ownerWindow;const observer=new ownerWindow.MutationObserver(records=>{if(!(this.avatarObserver!==observer||!this.isConnected||this.ownerDocument.defaultView!==ownerWindow)){for(const record of records){const attribute=record.attributeName;if(!attribute||attribute!=="size"&&attribute!=="shape"&&attribute!=="variant"||!this.isAvatar(record.target))continue;const avatar=record.target;if(this.consumeOwnedAttributeWrite(avatar,attribute))continue;const ownership=this.defaultOwnership.get(avatar);ownership?.delete(attribute),ownership?.size===0&&this.defaultOwnership.delete(avatar)}this.applyGroupDefaults(),this.recomputeWindow(),this.applyVisibilityMarkers()}});this.avatarObserver=observer;for(const avatar of avatars)observer.observe(avatar,{attributes:!0,attributeFilter:["hidden","inert","size","shape","variant"]})}disconnectAvatarObserver(){this.avatarObserver?.disconnect();for(const avatar of this.observedAvatars)this.pendingOwnedAttributeWrites.delete(avatar);this.avatarObserver=void 0,this.avatarObserverWindow=void 0,this.observedAvatars=Object.freeze([])}markOwnedAttributeWrite(avatar,attribute){if(!this.avatarObserver||!this.observedAvatars.includes(avatar))return;let writes=this.pendingOwnedAttributeWrites.get(avatar);writes||(writes=new Map,this.pendingOwnedAttributeWrites.set(avatar,writes)),writes.set(attribute,(writes.get(attribute)??0)+1)}consumeOwnedAttributeWrite(avatar,attribute){const writes=this.pendingOwnedAttributeWrites.get(avatar),count=writes?.get(attribute)??0;return count===0?!1:(count===1?writes.delete(attribute):writes.set(attribute,count-1),writes.size===0&&this.pendingOwnedAttributeWrites.delete(avatar),!0)}applyGroupDefaults(){const values={size:this.size,shape:this.shape,variant:this.variant};for(const avatar of this.assignedAvatars){let ownership=this.defaultOwnership.get(avatar);for(const attribute of["size","shape","variant"]){const applied=ownership?.get(attribute);applied!=null&&avatar.getAttribute(attribute)!==applied&&ownership.delete(attribute),avatar.hasAttribute(attribute)?ownership?.has(attribute)&&avatar.getAttribute(attribute)===applied&&applied!==values[attribute]&&(ownership.set(attribute,values[attribute]),this.markOwnedAttributeWrite(avatar,attribute),avatar.setAttribute(attribute,values[attribute])):(ownership??=new Map,ownership.set(attribute,values[attribute]),this.markOwnedAttributeWrite(avatar,attribute),avatar.setAttribute(attribute,values[attribute]))}ownership?.size?this.defaultOwnership.set(avatar,ownership):this.defaultOwnership.delete(avatar)}}applyVisibilityMarkers(){const hidden=new Set(this.overflowHiddenAvatars),firstVisible=this.assignedAvatars.find(avatar=>!avatar.hasAttribute("hidden")&&!avatar.hasAttribute("inert")&&!hidden.has(avatar));for(const avatar of this.assignedAvatars)hidden.has(avatar)?avatar.setAttribute("data-lr-avatar-group-hidden",""):avatar.removeAttribute("data-lr-avatar-group-hidden"),avatar===firstVisible?avatar.setAttribute("data-lr-avatar-group-first",""):avatar.removeAttribute("data-lr-avatar-group-first")}restoreAvatarState(avatar){avatar.removeAttribute("data-lr-avatar-group-hidden"),avatar.removeAttribute("data-lr-avatar-group-first");const ownership=this.defaultOwnership.get(avatar);if(ownership){for(const[attribute,applied]of ownership)avatar.getAttribute(attribute)===applied&&avatar.removeAttribute(attribute);this.defaultOwnership.delete(avatar)}}restoreOwnedState(){for(const avatar of this.assignedAvatars)this.restoreAvatarState(avatar);this.assignedAvatars=Object.freeze([]),this.overflowHiddenAvatars=Object.freeze([]),this.eligibleAvatarCount=0}onSlotChangeFromSlot(slot){this.updateBrowserDerivedState(()=>{this.isConnected&&this.reconcileAvatars(slot.assignedElements({flatten:!0}))})}render(){const overflowing=this.hasOverflow,hiddenCount=this.hiddenCount,badgeIsFirstVisible=overflowing&&hiddenCount===this.eligibleAvatarCount,accessibleLabel=hostAriaLabel(this)??(this.label||nothing),localizedHiddenCount=getNumberFormat(this.effectiveLocale).format(hiddenCount);return html`
2
2
  <div part="base" role="group" aria-label=${accessibleLabel}>
3
3
  <slot @slotchange=${this.onSlotChange}></slot>
4
4
  ${overflowing?html`<button
@@ -13,4 +13,4 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
13
13
  >
14
14
  </button>`:nothing}
15
15
  </div>
16
- `}}__decorate([property({type:Number})],LyraAvatarGroup.prototype,"max",null),__decorate([property({reflect:!0})],LyraAvatarGroup.prototype,"size",void 0),__decorate([property({reflect:!0})],LyraAvatarGroup.prototype,"shape",void 0),__decorate([property({reflect:!0})],LyraAvatarGroup.prototype,"variant",void 0),__decorate([property()],LyraAvatarGroup.prototype,"label",void 0),__decorate([state()],LyraAvatarGroup.prototype,"eligibleAvatarCount",void 0),__decorate([state()],LyraAvatarGroup.prototype,"overflowHiddenAvatars",void 0);export{LyraAvatarGroup};
16
+ `}}__decorate([property({type:Number})],LyraAvatarGroup.prototype,"max",null),__decorate([property({reflect:!0})],LyraAvatarGroup.prototype,"size",void 0),__decorate([property({reflect:!0})],LyraAvatarGroup.prototype,"shape",void 0),__decorate([property({reflect:!0})],LyraAvatarGroup.prototype,"variant",void 0),__decorate([property()],LyraAvatarGroup.prototype,"label",void 0),__decorate([state()],LyraAvatarGroup.prototype,"eligibleAvatarCount",void 0),__decorate([state()],LyraAvatarGroup.prototype,"overflowHiddenAvatars",void 0),__decorate([query("slot:not([name])")],LyraAvatarGroup.prototype,"avatarsSlot",void 0);export{LyraAvatarGroup};
@@ -1,4 +1,11 @@
1
- import{type PropertyValues,type TemplateResult}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';export interface LyraDropZoneRejectedFile{readonly file:File;readonly reason:'type'|'count'|'size'|'directory'|'read'|'limit'|'maxFiles'|'maxTotalSize';}export interface LyraDropZoneFilesDetail{readonly files:readonly File[];readonly rejected:readonly LyraDropZoneRejectedFile[];}
1
+ import{type PropertyValues,type TemplateResult}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';export interface LyraDropZoneRejectedFile{readonly file:File;readonly reason:'type'|'count'|'size'|'directory'|'read'|'limit'|'maxFiles'|'maxTotalSize';}export interface LyraDropZoneFilesDetail{readonly files:readonly File[];readonly rejected:readonly LyraDropZoneRejectedFile[];
2
+ /** Remaining allowance under `maxFiles` after this drop, at the control's running count
3
+ * (`heldFileCount`, since this component retains nothing of its own between drops) -- `null`
4
+ * while `maxFiles` is unset (no limit), never negative. */
5
+ readonly remainingFiles:number|null;
6
+ /** Remaining allowance under `maxTotalSize` after this drop, in bytes -- `null` while
7
+ * `maxTotalSize` is unset (no limit), never negative. */
8
+ readonly remainingTotalSize:number|null;}
2
9
  /** `lr-files`' event type on `lr-drop-zone`, narrowing `target`/`currentTarget` to `LyraDropZone`
3
10
  * so a listener reads them without casting -- same convention as `lr-file-input`'s
4
11
  * `LyraFileInputFilesEvent`. */
@@ -21,10 +28,12 @@ export interface LyraDropZoneFilesEvent extends CustomEvent<LyraDropZoneFilesDet
21
28
  * @slot - The wrapped region. Rendered as ordinary light DOM content; this element adds only the
22
29
  * drag listeners and the overlay layered on top.
23
30
  * @slot overlay - Custom drag-over overlay content, overriding the localized accept/reject text.
24
- * @event lr-files - Frozen `detail: { files, rejected }` with detached readonly sequences and
25
- * rejected-file records, fired on drop. Immutable `File` items retain identity. Typed as
26
- * {@linkcode LyraDropZoneFilesEvent}, so `event.target`/`event.currentTarget` are `LyraDropZone`
27
- * without a cast.
31
+ * @event lr-files - Frozen `detail: { files, rejected, remainingFiles, remainingTotalSize }` with
32
+ * detached readonly sequences and rejected-file records, fired on drop.
33
+ * `remainingFiles`/`remainingTotalSize` report the allowance still left under `maxFiles`/
34
+ * `maxTotalSize` after this drop (`null` while that limit is unset). Immutable `File` items retain
35
+ * identity. Typed as {@linkcode LyraDropZoneFilesEvent}, so
36
+ * `event.target`/`event.currentTarget` are `LyraDropZone` without a cast.
28
37
  * @csspart base - The wrapping element wrapping the default slot and the overlay.
29
38
  * @csspart overlay - The drag-over overlay, layered above the slotted content. Hidden outside an
30
39
  * active drag session.
@@ -72,13 +81,25 @@ accept:string;
72
81
  /** Largest accepted file size in bytes. `0` (the default) disables the check -- identical
73
82
  * contract to `lr-file-input`'s `maxFileSize`, including its invalid-override fallback. */
74
83
  maxFileSize:number;
75
- /** Largest number of files accepted per drop. `0` (the default) disables the check -- identical
76
- * contract to `lr-file-input`'s `maxFiles`. Since this component retains nothing between drops,
77
- * the count always covers only the current drop's files (there is no persisted count to add). */
84
+ /** Largest number of files accepted per drop, counting `heldFileCount` plus the current drop's
85
+ * files. `0` (the default) disables the check -- identical contract to `lr-file-input`'s
86
+ * `maxFiles`. Since this component retains nothing of its own between drops, the count would
87
+ * otherwise always cover only the current drop -- `heldFileCount` is what lets a cumulative cap
88
+ * span separate drops. */
78
89
  maxFiles:number;
79
- /** Largest combined byte size accepted per drop. `0` (the default) disables the check --
80
- * identical contract to `lr-file-input`'s `maxTotalSize`, scoped to the current drop only. */
81
- maxTotalSize:number;private dragState;private rejectedFiles;private resultStatus;private readonly internals;private readonly dropSession;private politeSink?;private assertiveSink?;
90
+ /** Largest combined byte size accepted per drop, summing `heldTotalSize` plus the current
91
+ * drop's files. `0` (the default) disables the check -- identical contract to
92
+ * `lr-file-input`'s `maxTotalSize`. */
93
+ maxTotalSize:number;
94
+ /** Externally held file count added to the running count `maxFiles` evaluates against --
95
+ * identical contract to `lr-file-input`'s `heldFileCount`, letting a cumulative, server-backed
96
+ * cap span separate drops onto this region. `0` (the default) means "nothing held" and
97
+ * reproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to
98
+ * `0` via `finiteCount`. */
99
+ heldFileCount:number;
100
+ /** Externally held byte total added to the running size `maxTotalSize` evaluates against --
101
+ * identical contract to `lr-file-input`'s `heldTotalSize`. */
102
+ heldTotalSize:number;private dragState;private rejectedFiles;private resultStatus;private readonly internals;private readonly dropSession;private politeSink?;private assertiveSink?;
82
103
  /** False until the first render has committed, so mounting never announces a resting state. */
83
104
  private announcementsArmed;constructor();
84
105
  /** Readonly state derived from the current drag session.
@@ -1,4 +1,4 @@
1
- var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{srOnly}from"../../../internal/a11y.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{attachInternalsSafely}from"../../../internal/form-associated.js";import{setCustomState}from"../../../internal/custom-states.js";import{finiteRange}from"../../../internal/numbers.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{fileIcon}from"../../../internal/icons.js";import{DropSessionController}from"../../../internal/drop-session-controller.js";import{matchesAccept}from"../file-input/accept.js";import{styles}from"./drop-zone.styles.js";import{LYRA_DEFAULT_dropzoneRejectedType,LYRA_DEFAULT_dropzoneReleaseToAdd,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_fileInputAcceptedMany,LYRA_DEFAULT_fileInputAcceptedOne,LYRA_DEFAULT_fileInputFolderRejected,LYRA_DEFAULT_fileInputRejectedCount,LYRA_DEFAULT_fileInputRejectedLimit,LYRA_DEFAULT_fileInputRejectedMany,LYRA_DEFAULT_fileInputRejectedMaxFiles,LYRA_DEFAULT_fileInputRejectedMaxTotalSize,LYRA_DEFAULT_fileInputRejectedOne,LYRA_DEFAULT_fileInputRejectedRead,LYRA_DEFAULT_fileInputRejectedSize,LYRA_DEFAULT_fileInputRejectedType}from"../../../internal/default-strings.generated.js";const DEFAULT_MAX_FILE_SIZE_BYTES=25*1024*1024,DEFAULT_MAX_FILES=100,DEFAULT_MAX_TOTAL_SIZE_BYTES=250*1024*1024;class LyraDropZone extends LyraElement{static{this.defaultStrings={...super.defaultStrings,dropzoneRejectedType:LYRA_DEFAULT_dropzoneRejectedType,dropzoneReleaseToAdd:LYRA_DEFAULT_dropzoneReleaseToAdd,fieldRequired:LYRA_DEFAULT_fieldRequired,fileInputAcceptedMany:LYRA_DEFAULT_fileInputAcceptedMany,fileInputAcceptedOne:LYRA_DEFAULT_fileInputAcceptedOne,fileInputFolderRejected:LYRA_DEFAULT_fileInputFolderRejected,fileInputRejectedCount:LYRA_DEFAULT_fileInputRejectedCount,fileInputRejectedLimit:LYRA_DEFAULT_fileInputRejectedLimit,fileInputRejectedMany:LYRA_DEFAULT_fileInputRejectedMany,fileInputRejectedMaxFiles:LYRA_DEFAULT_fileInputRejectedMaxFiles,fileInputRejectedMaxTotalSize:LYRA_DEFAULT_fileInputRejectedMaxTotalSize,fileInputRejectedOne:LYRA_DEFAULT_fileInputRejectedOne,fileInputRejectedRead:LYRA_DEFAULT_fileInputRejectedRead,fileInputRejectedSize:LYRA_DEFAULT_fileInputRejectedSize,fileInputRejectedType:LYRA_DEFAULT_fileInputRejectedType}}static{this.immutableEventDetails=Object.freeze(["lr-files"])}static{this.styles=[LyraElement.styles,styles,srOnly]}constructor(){super(),this.disabled=!1,this.multiple=!0,this.accept="",this.maxFileSize=0,this.maxFiles=0,this.maxTotalSize=0,this.dragState="default",this.rejectedFiles=Object.freeze([]),this.resultStatus="",this.announcementsArmed=!1,this.onDragEnter=e=>this.dropSession.onDragEnter(e),this.onDragOver=e=>this.dropSession.onDragOver(e),this.onDragLeave=e=>this.dropSession.onDragLeave(e),this.onDrop=e=>{const drop=this.dropSession.beginDrop(e);if(!drop)return;const{token,files,folders,overLimit}=drop;if(overLimit&&this.multiple){this.emitFiles([],[this.folderFailure(folders[0]?.name??"","limit")]);return}if(folders.length&&this.multiple){this.dropSession.readFolders(folders,token).then(result=>{if(!this.dropSession.isCurrent(token)||result.status==="cancelled")return;if(result.status==="error"||result.status==="limit"){this.emitFiles([],[this.folderFailure(result.name,result.status==="limit"?"limit":"read")]);return}const allFiles=[...files,...result.files];allFiles.length&&this.emitFiles(allFiles)});return}const rejectedFolders=folders.map(folder=>this.folderFailure(folder.name,"directory"));(files.length||rejectedFolders.length)&&this.emitFiles(files,rejectedFolders)},this.internals=attachInternalsSafely(this),this.dropSession=new DropSessionController(this,{isDisabled:()=>this.disabled,previewRejects:items=>this.classify(items,!0).rejected.length>0,onStateChange:()=>{this.dragState=this.dropSession.state,setCustomState(this.internals,"dragging",this.dropSession.dragging)}})}get dragging(){return this.dragState!=="default"}willUpdate(changed){super.willUpdate(changed),changed.has("disabled")&&this.disabled&&this.dropSession.reset()}connectedCallback(){super.connectedCallback(),this.politeSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this}),this.assertiveSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.politeSink?.release(),this.politeSink=void 0,this.assertiveSink?.release(),this.assertiveSink=void 0,this.announcementsArmed=!1,super.disconnectedCallback()}updated(changed){super.updated(changed),this.announcementsArmed&&(changed.has("dragState")&&this.dragState!=="default"&&this.politeSink?.announce(this.overlayText()),changed.has("resultStatus")&&this.resultStatus&&this.politeSink?.announce(this.resultStatus),changed.has("rejectedFiles")&&this.rejectedFiles.length>0&&this.assertiveSink?.announce(this.rejectedFiles.map(rejected=>this.rejectionMessage(rejected)).join(" "))),this.announcementsArmed=!0}get effectiveMaxFileSize(){const maxFileSize=this.maxFileSize;return maxFileSize===0||maxFileSize===1/0?null:finiteRange(maxFileSize>0?maxFileSize:NaN,DEFAULT_MAX_FILE_SIZE_BYTES,1)}get effectiveMaxFiles(){const maxFiles=this.maxFiles;return maxFiles===0||maxFiles===1/0?null:finiteRange(maxFiles>0?maxFiles:NaN,DEFAULT_MAX_FILES,1)}get effectiveMaxTotalSize(){const maxTotalSize=this.maxTotalSize;return maxTotalSize===0||maxTotalSize===1/0?null:finiteRange(maxTotalSize>0?maxTotalSize:NaN,DEFAULT_MAX_TOTAL_SIZE_BYTES,1)}isAllowed(file,isPreview=!1){if(this.accept&&!matchesAccept(file,this.accept,isPreview))return"type";const maxFileSize=this.effectiveMaxFileSize;return maxFileSize!==null&&file.size>maxFileSize?"size":"ok"}classify(fileList,isPreview=!1){if(!this.multiple&&fileList.length>1)return{files:[],rejected:fileList.map(file=>({file,reason:"count"}))};const files=[],rejected=[],maxFiles=this.effectiveMaxFiles,maxTotalSize=this.effectiveMaxTotalSize;let runningCount=0,runningSize=0;for(const f of fileList){const reason=this.isAllowed(f,isPreview);if(reason!=="ok"){rejected.push({file:f,reason});continue}if(maxFiles!==null&&runningCount+1>maxFiles){rejected.push({file:f,reason:"maxFiles"});continue}if(maxTotalSize!==null&&runningSize+f.size>maxTotalSize){rejected.push({file:f,reason:"maxTotalSize"});continue}files.push(f),runningCount+=1,runningSize+=Number.isFinite(f.size)?f.size:0}return{files,rejected}}rejectionMessage(rejected){const filename=rejected.file.name;switch(rejected.reason){case"type":return this.localize("fileInputRejectedType",void 0,{filename});case"size":return this.localize("fileInputRejectedSize",void 0,{filename});case"count":return this.localize("fileInputRejectedCount",void 0,{filename});case"directory":return this.localize("fileInputFolderRejected",void 0,{filename});case"read":return this.localize("fileInputRejectedRead",void 0,{filename});case"limit":return this.localize("fileInputRejectedLimit",void 0,{filename});case"maxFiles":return this.localize("fileInputRejectedMaxFiles",void 0,{filename});case"maxTotalSize":return this.localize("fileInputRejectedMaxTotalSize",void 0,{filename})}}emitFiles(fileList,additionalRejected=[]){const{files,rejected}=this.classify(fileList);rejected.push(...additionalRejected);const rejectedSnapshot=Object.freeze(rejected.map(item=>Object.freeze({...item}))),filesSnapshot=Object.freeze([...files]);this.rejectedFiles=rejectedSnapshot;const messages=[],numberFormat=getNumberFormat(this.effectiveLocale);files.length&&messages.push(this.localize(files.length===1?"fileInputAcceptedOne":"fileInputAcceptedMany",void 0,{count:numberFormat.format(files.length)})),rejected.length&&messages.push(this.localize(rejected.length===1?"fileInputRejectedOne":"fileInputRejectedMany",void 0,{count:numberFormat.format(rejected.length)})),this.resultStatus=messages.filter(message=>message.length>0).join(" "),this.emit("lr-files",Object.freeze({files:filesSnapshot,rejected:rejectedSnapshot}))}folderFailure(name,reason){const FileCtor=this.ownerDocument.defaultView?.File??globalThis.File;return Object.freeze({file:new FileCtor([],name),reason})}overlayText(){return this.dragState==="accept"?this.localize("dropzoneReleaseToAdd"):this.dragState==="reject"?this.localize("dropzoneRejectedType"):""}statusText(){return this.dragState==="default"?this.resultStatus:this.overlayText()}render(){return html`
1
+ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3?target:desc===null?desc=Object.getOwnPropertyDescriptor(target,key):desc,d;if(typeof Reflect=="object"&&typeof Reflect.decorate=="function")r=Reflect.decorate(decorators,target,key,desc);else for(var i=decorators.length-1;i>=0;i--)(d=decorators[i])&&(r=(c<3?d(r):c>3?d(target,key,r):d(target,key))||r);return c>3&&r&&Object.defineProperty(target,key,r),r};import{html,nothing}from"lit";import{property,state}from"lit/decorators.js";import{LyraElement}from"../../../internal/lyra-element.js";import{srOnly}from"../../../internal/a11y.js";import{acquireAnnouncementSink}from"../../../internal/announcer.js";import{attachInternalsSafely}from"../../../internal/form-associated.js";import{setCustomState}from"../../../internal/custom-states.js";import{finiteCount,finiteRange}from"../../../internal/numbers.js";import{AggregateFileLimitTracker}from"../../../internal/aggregate-file-limits.js";import{getNumberFormat}from"../../../internal/intl-cache.js";import{fileIcon}from"../../../internal/icons.js";import{DropSessionController}from"../../../internal/drop-session-controller.js";import{matchesAccept}from"../file-input/accept.js";import{styles}from"./drop-zone.styles.js";import{LYRA_DEFAULT_dropzoneRejectedType,LYRA_DEFAULT_dropzoneReleaseToAdd,LYRA_DEFAULT_fieldRequired,LYRA_DEFAULT_fileInputAcceptedMany,LYRA_DEFAULT_fileInputAcceptedOne,LYRA_DEFAULT_fileInputFolderRejected,LYRA_DEFAULT_fileInputRejectedCount,LYRA_DEFAULT_fileInputRejectedLimit,LYRA_DEFAULT_fileInputRejectedMany,LYRA_DEFAULT_fileInputRejectedMaxFiles,LYRA_DEFAULT_fileInputRejectedMaxTotalSize,LYRA_DEFAULT_fileInputRejectedOne,LYRA_DEFAULT_fileInputRejectedRead,LYRA_DEFAULT_fileInputRejectedSize,LYRA_DEFAULT_fileInputRejectedType}from"../../../internal/default-strings.generated.js";const DEFAULT_MAX_FILE_SIZE_BYTES=25*1024*1024,DEFAULT_MAX_FILES=100,DEFAULT_MAX_TOTAL_SIZE_BYTES=250*1024*1024;class LyraDropZone extends LyraElement{static{this.defaultStrings={...super.defaultStrings,dropzoneRejectedType:LYRA_DEFAULT_dropzoneRejectedType,dropzoneReleaseToAdd:LYRA_DEFAULT_dropzoneReleaseToAdd,fieldRequired:LYRA_DEFAULT_fieldRequired,fileInputAcceptedMany:LYRA_DEFAULT_fileInputAcceptedMany,fileInputAcceptedOne:LYRA_DEFAULT_fileInputAcceptedOne,fileInputFolderRejected:LYRA_DEFAULT_fileInputFolderRejected,fileInputRejectedCount:LYRA_DEFAULT_fileInputRejectedCount,fileInputRejectedLimit:LYRA_DEFAULT_fileInputRejectedLimit,fileInputRejectedMany:LYRA_DEFAULT_fileInputRejectedMany,fileInputRejectedMaxFiles:LYRA_DEFAULT_fileInputRejectedMaxFiles,fileInputRejectedMaxTotalSize:LYRA_DEFAULT_fileInputRejectedMaxTotalSize,fileInputRejectedOne:LYRA_DEFAULT_fileInputRejectedOne,fileInputRejectedRead:LYRA_DEFAULT_fileInputRejectedRead,fileInputRejectedSize:LYRA_DEFAULT_fileInputRejectedSize,fileInputRejectedType:LYRA_DEFAULT_fileInputRejectedType}}static{this.immutableEventDetails=Object.freeze(["lr-files"])}static{this.styles=[LyraElement.styles,styles,srOnly]}constructor(){super(),this.disabled=!1,this.multiple=!0,this.accept="",this.maxFileSize=0,this.maxFiles=0,this.maxTotalSize=0,this.heldFileCount=0,this.heldTotalSize=0,this.dragState="default",this.rejectedFiles=Object.freeze([]),this.resultStatus="",this.announcementsArmed=!1,this.onDragEnter=e=>this.dropSession.onDragEnter(e),this.onDragOver=e=>this.dropSession.onDragOver(e),this.onDragLeave=e=>this.dropSession.onDragLeave(e),this.onDrop=e=>{const drop=this.dropSession.beginDrop(e);if(!drop)return;const{token,files,folders,overLimit}=drop;if(overLimit&&this.multiple){this.emitFiles([],[this.folderFailure(folders[0]?.name??"","limit")]);return}if(folders.length&&this.multiple){this.dropSession.readFolders(folders,token).then(result=>{if(!this.dropSession.isCurrent(token)||result.status==="cancelled")return;if(result.status==="error"||result.status==="limit"){this.emitFiles([],[this.folderFailure(result.name,result.status==="limit"?"limit":"read")]);return}const allFiles=[...files,...result.files];allFiles.length&&this.emitFiles(allFiles)});return}const rejectedFolders=folders.map(folder=>this.folderFailure(folder.name,"directory"));(files.length||rejectedFolders.length)&&this.emitFiles(files,rejectedFolders)},this.internals=attachInternalsSafely(this),this.dropSession=new DropSessionController(this,{isDisabled:()=>this.disabled,previewRejects:items=>this.classify(items,!0).rejected.length>0,onStateChange:()=>{this.dragState=this.dropSession.state,setCustomState(this.internals,"dragging",this.dropSession.dragging)}})}get dragging(){return this.dragState!=="default"}willUpdate(changed){super.willUpdate(changed),changed.has("disabled")&&this.disabled&&this.dropSession.reset()}connectedCallback(){super.connectedCallback(),this.politeSink??=acquireAnnouncementSink("polite",{document:this.ownerDocument,source:this}),this.assertiveSink??=acquireAnnouncementSink("assertive",{document:this.ownerDocument,source:this})}disconnectedCallback(){this.politeSink?.release(),this.politeSink=void 0,this.assertiveSink?.release(),this.assertiveSink=void 0,this.announcementsArmed=!1,super.disconnectedCallback()}updated(changed){super.updated(changed),this.announcementsArmed&&(changed.has("dragState")&&this.dragState!=="default"&&this.politeSink?.announce(this.overlayText()),changed.has("resultStatus")&&this.resultStatus&&this.politeSink?.announce(this.resultStatus),changed.has("rejectedFiles")&&this.rejectedFiles.length>0&&this.assertiveSink?.announce(this.rejectedFiles.map(rejected=>this.rejectionMessage(rejected)).join(" "))),this.announcementsArmed=!0}get effectiveMaxFileSize(){const maxFileSize=this.maxFileSize;return maxFileSize===0||maxFileSize===1/0?null:finiteRange(maxFileSize>0?maxFileSize:NaN,DEFAULT_MAX_FILE_SIZE_BYTES,1)}get effectiveMaxFiles(){const maxFiles=this.maxFiles;return maxFiles===0||maxFiles===1/0?null:finiteRange(maxFiles>0?maxFiles:NaN,DEFAULT_MAX_FILES,1)}get effectiveMaxTotalSize(){const maxTotalSize=this.maxTotalSize;return maxTotalSize===0||maxTotalSize===1/0?null:finiteRange(maxTotalSize>0?maxTotalSize:NaN,DEFAULT_MAX_TOTAL_SIZE_BYTES,1)}isAllowed(file,isPreview=!1){if(this.accept&&!matchesAccept(file,this.accept,isPreview))return"type";const maxFileSize=this.effectiveMaxFileSize;return maxFileSize!==null&&file.size>maxFileSize?"size":"ok"}classify(fileList,isPreview=!1){const limits={maxFiles:this.effectiveMaxFiles,maxTotalSize:this.effectiveMaxTotalSize},tracker=new AggregateFileLimitTracker(finiteCount(this.heldFileCount,0),finiteCount(this.heldTotalSize,0));if(!this.multiple&&fileList.length>1)return{files:[],rejected:fileList.map(file=>({file,reason:"count"})),...tracker.allowance(limits)};const files=[],rejected=[];for(const f of fileList){const reason=this.isAllowed(f,isPreview);if(reason!=="ok"){rejected.push({file:f,reason});continue}const limitReason=tracker.evaluate(f,limits);if(limitReason){rejected.push({file:f,reason:limitReason});continue}files.push(f)}return{files,rejected,...tracker.allowance(limits)}}rejectionMessage(rejected){const filename=rejected.file.name;switch(rejected.reason){case"type":return this.localize("fileInputRejectedType",void 0,{filename});case"size":return this.localize("fileInputRejectedSize",void 0,{filename});case"count":return this.localize("fileInputRejectedCount",void 0,{filename});case"directory":return this.localize("fileInputFolderRejected",void 0,{filename});case"read":return this.localize("fileInputRejectedRead",void 0,{filename});case"limit":return this.localize("fileInputRejectedLimit",void 0,{filename});case"maxFiles":return this.localize("fileInputRejectedMaxFiles",void 0,{filename});case"maxTotalSize":return this.localize("fileInputRejectedMaxTotalSize",void 0,{filename})}}emitFiles(fileList,additionalRejected=[]){const{files,rejected,remainingFiles,remainingTotalSize}=this.classify(fileList);rejected.push(...additionalRejected);const rejectedSnapshot=Object.freeze(rejected.map(item=>Object.freeze({...item}))),filesSnapshot=Object.freeze([...files]);this.rejectedFiles=rejectedSnapshot;const messages=[],numberFormat=getNumberFormat(this.effectiveLocale);files.length&&messages.push(this.localize(files.length===1?"fileInputAcceptedOne":"fileInputAcceptedMany",void 0,{count:numberFormat.format(files.length)})),rejected.length&&messages.push(this.localize(rejected.length===1?"fileInputRejectedOne":"fileInputRejectedMany",void 0,{count:numberFormat.format(rejected.length)})),this.resultStatus=messages.filter(message=>message.length>0).join(" "),this.emit("lr-files",Object.freeze({files:filesSnapshot,rejected:rejectedSnapshot,remainingFiles,remainingTotalSize}))}folderFailure(name,reason){const FileCtor=this.ownerDocument.defaultView?.File??globalThis.File;return Object.freeze({file:new FileCtor([],name),reason})}overlayText(){return this.dragState==="accept"?this.localize("dropzoneReleaseToAdd"):this.dragState==="reject"?this.localize("dropzoneRejectedType"):""}statusText(){return this.dragState==="default"?this.resultStatus:this.overlayText()}render(){return html`
2
2
  <div
3
3
  part="base"
4
4
  @dragenter=${this.onDragEnter}
@@ -20,4 +20,4 @@ var __decorate=function(decorators,target,key,desc){var c=arguments.length,r=c<3
20
20
  </ul>
21
21
  </div>
22
22
  `:nothing}
23
- `}}__decorate([property({type:Boolean,reflect:!0})],LyraDropZone.prototype,"disabled",void 0),__decorate([property({type:Boolean,reflect:!0})],LyraDropZone.prototype,"multiple",void 0),__decorate([property()],LyraDropZone.prototype,"accept",void 0),__decorate([property({type:Number,attribute:"max-file-size"})],LyraDropZone.prototype,"maxFileSize",void 0),__decorate([property({type:Number,attribute:"max-files"})],LyraDropZone.prototype,"maxFiles",void 0),__decorate([property({type:Number,attribute:"max-total-size"})],LyraDropZone.prototype,"maxTotalSize",void 0),__decorate([state()],LyraDropZone.prototype,"dragState",void 0),__decorate([state()],LyraDropZone.prototype,"rejectedFiles",void 0),__decorate([state()],LyraDropZone.prototype,"resultStatus",void 0);export{LyraDropZone};
23
+ `}}__decorate([property({type:Boolean,reflect:!0})],LyraDropZone.prototype,"disabled",void 0),__decorate([property({type:Boolean,reflect:!0})],LyraDropZone.prototype,"multiple",void 0),__decorate([property()],LyraDropZone.prototype,"accept",void 0),__decorate([property({type:Number,attribute:"max-file-size"})],LyraDropZone.prototype,"maxFileSize",void 0),__decorate([property({type:Number,attribute:"max-files"})],LyraDropZone.prototype,"maxFiles",void 0),__decorate([property({type:Number,attribute:"max-total-size"})],LyraDropZone.prototype,"maxTotalSize",void 0),__decorate([property({type:Number,attribute:"held-file-count"})],LyraDropZone.prototype,"heldFileCount",void 0),__decorate([property({type:Number,attribute:"held-total-size"})],LyraDropZone.prototype,"heldTotalSize",void 0),__decorate([state()],LyraDropZone.prototype,"dragState",void 0),__decorate([state()],LyraDropZone.prototype,"rejectedFiles",void 0),__decorate([state()],LyraDropZone.prototype,"resultStatus",void 0);export{LyraDropZone};
@@ -16,7 +16,14 @@ observedAttributes?:string[];checkValidity:(input:never)=>LyraFileInputObjectVal
16
16
  export declare const DEFAULT_MAX_FILES=100;
17
17
  /** Fallback used by `effectiveMaxTotalSize` for an invalid (negative/`NaN`) `maxTotalSize`
18
18
  * override, mirroring `DEFAULT_MAX_FILE_SIZE_BYTES`'s fail-safe role for `maxFileSize`. */
19
- export declare const DEFAULT_MAX_TOTAL_SIZE_BYTES:number;export interface LyraFileInputRejectedFile{readonly file:File;readonly reason:'type'|'count'|'size'|'directory'|'read'|'limit'|'maxFiles'|'maxTotalSize';}export interface LyraFileInputFilesDetail{readonly files:readonly File[];readonly rejected:readonly LyraFileInputRejectedFile[];}
19
+ export declare const DEFAULT_MAX_TOTAL_SIZE_BYTES:number;export interface LyraFileInputRejectedFile{readonly file:File;readonly reason:'type'|'count'|'size'|'directory'|'read'|'limit'|'maxFiles'|'maxTotalSize';}export interface LyraFileInputFilesDetail{readonly files:readonly File[];readonly rejected:readonly LyraFileInputRejectedFile[];
20
+ /** Remaining allowance under `maxFiles` after this batch, at the control's running count
21
+ * (retained files, unless `nonRetaining`, plus `heldFileCount`) -- `null` while `maxFiles` is
22
+ * unset (no limit), never negative. */
23
+ readonly remainingFiles:number|null;
24
+ /** Remaining allowance under `maxTotalSize` after this batch, in bytes -- `null` while
25
+ * `maxTotalSize` is unset (no limit), never negative. */
26
+ readonly remainingTotalSize:number|null;}
20
27
  /** `lr-files`' event type, narrowing `target`/`currentTarget` to `LyraFileInput` so a listener
21
28
  * reads them without casting. */
22
29
  export interface LyraFileInputFilesEvent extends CustomEvent<LyraFileInputFilesDetail>{readonly target:LyraFileInput;readonly currentTarget:LyraFileInput;}export interface LyraFileInputEventMap{blur:FocusEvent;focus:FocusEvent;input:Event;change:Event;'lr-invalid':CustomEvent<null>;'lr-files':LyraFileInputFilesEvent;}
@@ -34,11 +41,13 @@ export interface LyraFileInputFilesEvent extends CustomEvent<LyraFileInputFilesD
34
41
  * @slot hint - Custom form-control hint content.
35
42
  * @slot error - Custom validation error content. Use `with-error` when this slot is populated in
36
43
  * server-rendered declarative shadow DOM before light-DOM slot assignment is observable.
37
- * @event lr-files - Frozen `detail: { files, rejected }` with detached readonly sequences and
38
- * rejected-file records, fired on drop and manual selection. Immutable `File` items retain
39
- * identity. Typed as {@linkcode LyraFileInputFilesEvent}, so `event.target`/`event.currentTarget` are
40
- * `LyraFileInput` without a cast. Still fires while `nonRetaining` is set, even though `files`
41
- * itself is never written in that mode.
44
+ * @event lr-files - Frozen `detail: { files, rejected, remainingFiles, remainingTotalSize }` with
45
+ * detached readonly sequences and rejected-file records, fired on drop and manual selection.
46
+ * `remainingFiles`/`remainingTotalSize` report the allowance still left under `maxFiles`/
47
+ * `maxTotalSize` after this batch (`null` while that limit is unset). Immutable `File` items
48
+ * retain identity. Typed as {@linkcode LyraFileInputFilesEvent}, so
49
+ * `event.target`/`event.currentTarget` are `LyraFileInput` without a cast. Still fires while
50
+ * `nonRetaining` is set, even though `files` itself is never written in that mode.
42
51
  * @event {Event} input - Native event fired before `change` when user interaction changes `files`;
43
52
  * bubbling, composed, and non-cancelable.
44
53
  * @event {Event} change - Native event fired after `input` when user interaction changes `files`;
@@ -89,7 +98,8 @@ export interface LyraFileInputFilesEvent extends CustomEvent<LyraFileInputFilesD
89
98
  * touched anything. Neither this nor `user-invalid` matches while the control is barred from
90
99
  * constraint validation (disabled, or inside a disabled fieldset).
91
100
  * @cssstate user-valid - `valid`, but only after the user has interacted: choosing or dropping
92
- * files, removing one, a blur, or a `reportValidity()` call (which is what a submit attempt runs).
101
+ * files, removing one, a blur, `reportValidity()`, or a submission attempt. Not after a silent
102
+ * `checkValidity()` alone.
93
103
  * @cssstate user-invalid - `invalid` after that same interaction. Style validation errors with this
94
104
  * rather than `invalid`: a pristine required file input is genuinely invalid, but colouring it red
95
105
  * before the user has done anything is hostile.
@@ -159,19 +169,30 @@ get forbiddenMimeTypes():readonly string[];set forbiddenMimeTypes(next:readonly
159
169
  /** Largest accepted file size in bytes. `0` (the default) disables the size check entirely --
160
170
  * see `effectiveMaxFileSize` for how an invalid override is handled. */
161
171
  maxFileSize:number;
162
- /** Largest total number of files accepted, counting retained files plus the current batch. `0`
163
- * (the default) disables the check. Same rejection-UI shape as `maxFileSize`: an excess file in
164
- * the batch is rejected with reason `'maxFiles'` and appears in `[part="rejection"]` alongside
165
- * any other rejection, rather than failing the whole selection. An invalid override (negative,
166
- * `NaN`) falls back to a sane cap rather than silently accepting an unlimited count -- see
167
- * `effectiveMaxFiles`. While `nonRetaining` is set, the count only covers the current batch,
168
- * since the control does not track an externally-held count. */
172
+ /** Largest total number of files accepted, counting retained files (unless `nonRetaining`) plus
173
+ * `heldFileCount` plus the current batch. `0` (the default) disables the check. Same
174
+ * rejection-UI shape as `maxFileSize`: an excess file in the batch is rejected with reason
175
+ * `'maxFiles'` and appears in `[part="rejection"]` alongside any other rejection, rather than
176
+ * failing the whole selection. An invalid override (negative, `NaN`) falls back to a sane cap
177
+ * rather than silently accepting an unlimited count -- see `effectiveMaxFiles`. */
169
178
  maxFiles:number;
170
- /** Largest combined byte size accepted, summing retained files plus the current batch. `0` (the
171
- * default) disables the check. Same rejection-UI shape and invalid-override fallback as
172
- * `maxFileSize` -- see `effectiveMaxTotalSize`. While `nonRetaining` is set, the total only
173
- * covers the current batch. */
179
+ /** Largest combined byte size accepted, summing retained files (unless `nonRetaining`) plus
180
+ * `heldTotalSize` plus the current batch. `0` (the default) disables the check. Same
181
+ * rejection-UI shape and invalid-override fallback as `maxFileSize` -- see
182
+ * `effectiveMaxTotalSize`. */
174
183
  maxTotalSize:number;
184
+ /** Externally held file count added to the running count `maxFiles` evaluates against, in both
185
+ * retaining and `nonRetaining` modes -- the numeric counterpart of `valuePresent`, for a
186
+ * cumulative cap that spans separate picker sessions (e.g. a server-backed upload limit) rather
187
+ * than resetting to what this control alone can see. `0` (the default) means "nothing held" and
188
+ * reproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to `0`
189
+ * via `finiteCount` -- an invalid baseline degrades to "nothing held" rather than corrupting
190
+ * every later comparison or permanently blocking every future file. */
191
+ heldFileCount:number;
192
+ /** Externally held byte total added to the running size `maxTotalSize` evaluates against, in
193
+ * both retaining and `nonRetaining` modes. Same contract, default, and invalid-input
194
+ * normalization as `heldFileCount`. */
195
+ heldTotalSize:number;
175
196
  /** Opt-in mode where an accepted selection still fires `lr-files`/`input`/`change` but is never
176
197
  * written to `files` or rendered as a built-in `[part="file"]` row -- for a host that persists
177
198
  * files elsewhere and renders its own list, so assigning `files` (even to reset it) never fights
@@ -283,7 +304,7 @@ private validatorResult;
283
304
  private syncValidatorAttributeObserver;private disconnectValidatorAttributeObserver;private updateValidity;
284
305
  /** Whether the control has a value for `required`/`blank` purposes: real retained files, or --
285
306
  * while `nonRetaining` is set -- the host's own `valuePresent` signal. */
286
- private get hasEffectiveValue();private publishCustomStates;checkValidity():boolean;reportValidity():boolean;setCustomValidity(message:string):void;resetValidity():void;formResetCallback():void;formStateRestoreCallback(state:string|File|FormData|null,reason:'autocomplete'|'restore'):void;private readFormDataFiles;formDisabledCallback(disabled:boolean):void;private syncThumbnailUrls;
307
+ private get hasEffectiveValue();private publishCustomStates;private markInteracted;checkValidity():boolean;reportValidity():boolean;setCustomValidity(message:string):void;resetValidity():void;formResetCallback():void;formStateRestoreCallback(state:string|File|FormData|null,reason:'autocomplete'|'restore'):void;private readFormDataFiles;formDisabledCallback(disabled:boolean):void;private syncThumbnailUrls;
287
308
  /** `maxFileSize` normalized: `0` (explicitly set, or left at the default) or `Infinity`
288
309
  * (explicitly set) both mean "no limit" verbatim -- `null` here signals that. Anything else
289
310
  * that isn't a positive, finite override -- a `NaN` from an invalid `max-file-size` attribute,